<commit_before>#include "FirehoseLibraryClient.h"
#include <aws/core/Aws.h>
#include <aws/core/client/CoreErrors.h>
#include <aws/core/auth/AWSCredentialsProviderChain.h>

#include <aws/core/utils/Outcome.h>
#include <aws/access-management/AccessManagementClient.h>
#include <aws/iam/IAMClient.h>
#include <aws/cognito-identity/CognitoIdentityClient.h>

#include <aws/core/client/ClientConfiguration.h>

#include <aws/core/utils/memory/stl/AWSStringStream.h>
#include <aws/firehose/FirehoseClient.h>
#include <aws/firehose/model/CreateDeliveryStreamRequest.h>
#include <aws/firehose/model/S3DestinationConfiguration.h>

#include <aws/firehose/model/PutRecordRequest.h>

#define DEBUG_INFO

using namespace std;
using namespace Aws;
using namespace Aws::Http;
using namespace Aws::Auth;
using namespace Aws::Client;
using namespace Aws::Firehose;
using namespace Aws::Firehose::Model;
using namespace Aws::Utils::Json;

//Constructor
FirehoseLibraryClient::FirehoseLibraryClient(string streamName, std::string bucketName) :
  m_firehoseClient(nullptr),
  m_config(new ClientConfiguration()),
  m_streamName(streamName),
  m_bucketName(bucketName),
  m_options(new Aws::SDKOptions()),
  m_initialized(false)
{
  //m_options = new Aws::SDKOptions;
  m_options->loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
  Aws::InitAPI(*m_options);

  m_config->scheme = Scheme::HTTPS;
  m_config->region = Region::US_EAST_1;

  m_firehoseClient = new FirehoseClient(*m_config);
}

//destructor
FirehoseLibraryClient::~FirehoseLibraryClient()
{
	Aws::ShutdownAPI(*m_options);
}

bool FirehoseLibraryClient::initQueue(std::string bucketPrefix)
{
  auto cognitoClient = Aws::MakeShared<Aws::CognitoIdentity::CognitoIdentityClient>("QueueOperationTest", *m_config);
  auto iamClient = Aws::MakeShared<Aws::IAM::IAMClient>("QueueOperationTest", *m_config);
  Aws::AccessManagement::AccessManagementClient accessManagementClient(iamClient, cognitoClient);

  Aws::String accountId = accessManagementClient.GetAccountId();

  Aws::String user;
  Aws::IAM::Model::User data;

  accessManagementClient.GetUser(user, data);
#ifdef DEBUG_INFO
  cout << "Account ID : " << accountId << user <<endl;
#endif

  CreateDeliveryStreamRequest request;

  request.SetDeliveryStreamName(m_streamName.c_str());

  S3DestinationConfiguration s3Config;

  //TBD; role is fixed now...
  Aws::String roleARN = "arn:aws:iam::" + accountId + ":role/firehose_delivery_role";
  string bucketARN("arn:aws:s3:::" + m_bucketName);
  Aws::String _bucketPrefix = bucketPrefix.c_str();

  s3Config.SetRoleARN(roleARN);
  s3Config.SetBucketARN(bucketARN.c_str());
  s3Config.SetPrefix(_bucketPrefix);
  s3Config.SetBufferingHints(BufferingHints());
  s3Config.SetCompressionFormat(CompressionFormat::UNCOMPRESSED);
  s3Config.SetEncryptionConfiguration(EncryptionConfiguration());
  request.SetS3DestinationConfiguration(s3Config);

  CreateDeliveryStreamOutcome outcome = m_firehoseClient->CreateDeliveryStream(request);
  if (outcome.IsSuccess())
  {
    cout << "Succesfull created new deliverystream [" << m_streamName << "]" << endl ;
    m_initialized = true;
    return true;
  }else if (outcome.GetError().GetErrorType() == FirehoseErrors::RESOURCE_IN_USE){
#ifdef DEBUG_INFO
    cout << "Resource in use, stream [" << m_streamName << "] exists already"<< endl;
#endif
    m_initialized = true;
    return true;
  }else if (outcome.GetError().GetErrorType() == FirehoseErrors::LIMIT_EXCEEDED){
    cout << "Limit Exceeded "<< endl;
  }else if (outcome.GetError().GetErrorType() == FirehoseErrors::ACCESS_DENIED){
    cout << "Access Denied "<< endl;
  }else{
    cout << "Other error.... [" << outcome.GetError().GetMessage() << "]" << endl;
  }
  return false;
}

bool FirehoseLibraryClient::sendMessage(const ifstream& data, int repetitions/* = 0*/)
{
  if(!m_initialized)
  {
	cout << "Not Initialized." << endl;
	return false;
  }

  PutRecordRequest request;
  //set stream name;
  Aws::String __streamName("TMP");
  request.SetDeliveryStreamName(m_streamName.c_str());

  Record record;

  Aws::StringStream dataStream;
  dataStream << data.rdbuf();

#ifdef DEBUG_INFO
  cout << "Buff Size to transfer: [" << dataStream.str().length() << "]" << endl;
#endif
  Aws::Utils::ByteBuffer buff((unsigned char*)dataStream.str().c_str(), dataStream.str().length());

  //apply stream data to record buffer Data
  record.SetData(buff);

  //set record to request
  request.SetRecord(record);
  //for loop is for testing purposes only
  for(int i = 0; i <= repetitions; i++)
  {
    //send request to cloud
    Model::PutRecordOutcome outcome = m_firehoseClient->PutRecord(request);
    if(!outcome.IsSuccess())
    {
      cout << "Error sending message " << i + 1 << "." << endl;
      i = repetitions;
      return false;
    }
  }
  return true;
}

bool FirehoseLibraryClient::sendMessage(const std::vector<char>& dataVector)
{
  if(!m_initialized)
  {
	cout << "Not Initialized." << endl;
	return false;
  }

  PutRecordRequest request;
  //set stream name;
  Aws::String __streamName("TMP");
  request.SetDeliveryStreamName(m_streamName.c_str());

  Record record;

  //Aws::StringStream dataStream;
  //dataStream << data.rdbuf();

#ifdef DEBUG_INFO
  cout << "Buff Size to transfer: [" << dataVector.size() << "]" << endl;
#endif
  Aws::Utils::ByteBuffer buff((unsigned char*)&dataVector[0], dataVector.size());

  //apply stream data to record buffer Data
  record.SetData(buff);

  //set record to request
  request.SetRecord(record);
  //for loop is for testing purposes only
  //send request to cloud
  Model::PutRecordOutcome outcome = m_firehoseClient->PutRecord(request);
  if(!outcome.IsSuccess())
  {
    cout << "Error sending message ." << endl;
    return false;
  }
  return true;
}
<commit_msg>add underscore to prefix<commit_after>#include "FirehoseLibraryClient.h"
#include <aws/core/Aws.h>
#include <aws/core/client/CoreErrors.h>
#include <aws/core/auth/AWSCredentialsProviderChain.h>

#include <aws/core/utils/Outcome.h>
#include <aws/access-management/AccessManagementClient.h>
#include <aws/iam/IAMClient.h>
#include <aws/cognito-identity/CognitoIdentityClient.h>

#include <aws/core/client/ClientConfiguration.h>

#include <aws/core/utils/memory/stl/AWSStringStream.h>
#include <aws/firehose/FirehoseClient.h>
#include <aws/firehose/model/CreateDeliveryStreamRequest.h>
#include <aws/firehose/model/S3DestinationConfiguration.h>

#include <aws/firehose/model/PutRecordRequest.h>

#define DEBUG_INFO

using namespace std;
using namespace Aws;
using namespace Aws::Http;
using namespace Aws::Auth;
using namespace Aws::Client;
using namespace Aws::Firehose;
using namespace Aws::Firehose::Model;
using namespace Aws::Utils::Json;

//Constructor
FirehoseLibraryClient::FirehoseLibraryClient(string streamName, std::string bucketName) :
  m_firehoseClient(nullptr),
  m_config(new ClientConfiguration()),
  m_streamName(streamName),
  m_bucketName(bucketName),
  m_options(new Aws::SDKOptions()),
  m_initialized(false)
{
  //m_options = new Aws::SDKOptions;
  m_options->loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
  Aws::InitAPI(*m_options);

  m_config->scheme = Scheme::HTTPS;
  m_config->region = Region::US_EAST_1;

  m_firehoseClient = new FirehoseClient(*m_config);
}

//destructor
FirehoseLibraryClient::~FirehoseLibraryClient()
{
	Aws::ShutdownAPI(*m_options);
}

bool FirehoseLibraryClient::initQueue(std::string bucketPrefix)
{
  auto cognitoClient = Aws::MakeShared<Aws::CognitoIdentity::CognitoIdentityClient>("QueueOperationTest", *m_config);
  auto iamClient = Aws::MakeShared<Aws::IAM::IAMClient>("QueueOperationTest", *m_config);
  Aws::AccessManagement::AccessManagementClient accessManagementClient(iamClient, cognitoClient);

  Aws::String accountId = accessManagementClient.GetAccountId();

  //Aws::String user;
  //Aws::IAM::Model::User data;

  //accessManagementClient.GetUser(user, data);
#ifdef DEBUG_INFO
  cout << "Account ID : " << accountId << /*user <<*/ endl;
#endif

  CreateDeliveryStreamRequest request;

  request.SetDeliveryStreamName(m_streamName.c_str());

  S3DestinationConfiguration s3Config;

  //TBD; role is fixed now...
  Aws::String roleARN = "arn:aws:iam::" + accountId + ":role/firehose_delivery_role";
  string bucketARN("arn:aws:s3:::" + m_bucketName);
  Aws::String _bucketPrefix = bucketPrefix.c_str();
  _bucketPrefix += "_";

  s3Config.SetRoleARN(roleARN);
  s3Config.SetBucketARN(bucketARN.c_str());
  s3Config.SetPrefix(_bucketPrefix);
  s3Config.SetBufferingHints(BufferingHints());
  s3Config.SetCompressionFormat(CompressionFormat::UNCOMPRESSED);
  s3Config.SetEncryptionConfiguration(EncryptionConfiguration());
  request.SetS3DestinationConfiguration(s3Config);

  CreateDeliveryStreamOutcome outcome = m_firehoseClient->CreateDeliveryStream(request);
  if (outcome.IsSuccess())
  {
    cout << "Succesfull created new deliverystream [" << m_streamName << "]" << endl ;
    m_initialized = true;
    return true;
  }else if (outcome.GetError().GetErrorType() == FirehoseErrors::RESOURCE_IN_USE){
#ifdef DEBUG_INFO
    cout << "Resource in use, stream [" << m_streamName << "] exists already"<< endl;
#endif
    m_initialized = true;
    return true;
  }else if (outcome.GetError().GetErrorType() == FirehoseErrors::LIMIT_EXCEEDED){
    cout << "Limit Exceeded "<< endl;
  }else if (outcome.GetError().GetErrorType() == FirehoseErrors::ACCESS_DENIED){
    cout << "Access Denied "<< endl;
  }else{
    cout << "Other error.... [" << outcome.GetError().GetMessage() << "]" << endl;
  }
  return false;
}

bool FirehoseLibraryClient::sendMessage(const ifstream& data, int repetitions/* = 0*/)
{
  if(!m_initialized)
  {
	cout << "Not Initialized." << endl;
	return false;
  }

  PutRecordRequest request;
  //set stream name;
  Aws::String __streamName("TMP");
  request.SetDeliveryStreamName(m_streamName.c_str());

  Record record;

  Aws::StringStream dataStream;
  dataStream << data.rdbuf();

#ifdef DEBUG_INFO
  cout << "Buff Size to transfer: [" << dataStream.str().length() << "]" << endl;
#endif
  Aws::Utils::ByteBuffer buff((unsigned char*)dataStream.str().c_str(), dataStream.str().length());

  //apply stream data to record buffer Data
  record.SetData(buff);

  //set record to request
  request.SetRecord(record);
  //for loop is for testing purposes only
  for(int i = 0; i <= repetitions; i++)
  {
    //send request to cloud
    Model::PutRecordOutcome outcome = m_firehoseClient->PutRecord(request);
    if(!outcome.IsSuccess())
    {
      cout << "Error sending message " << i + 1 << "." << endl;
      i = repetitions;
      return false;
    }
  }
  return true;
}

bool FirehoseLibraryClient::sendMessage(const std::vector<char>& dataVector)
{
  if(!m_initialized)
  {
	cout << "Not Initialized." << endl;
	return false;
  }

  PutRecordRequest request;
  //set stream name;
  Aws::String __streamName("TMP");
  request.SetDeliveryStreamName(m_streamName.c_str());

  Record record;

  //Aws::StringStream dataStream;
  //dataStream << data.rdbuf();

#ifdef DEBUG_INFO
  cout << "Buff Size to transfer: [" << dataVector.size() << "]" << endl;
#endif
  Aws::Utils::ByteBuffer buff((unsigned char*)&dataVector[0], dataVector.size());

  //apply stream data to record buffer Data
  record.SetData(buff);

  //set record to request
  request.SetRecord(record);
  //for loop is for testing purposes only
  //send request to cloud
  Model::PutRecordOutcome outcome = m_firehoseClient->PutRecord(request);
  if(!outcome.IsSuccess())
  {
    cout << "Error sending message ." << endl;
    return false;
  }
  return true;
}
<|endoftext|>


<commit_before>#pragma once

#include <avr/io.h>
#include <avr/interrupt.h>

static volatile unsigned overflowCount = 0;

// Timer0 ticks every 64 cycles
// Overflow happens every 256 ticks
ISR(TIMER0_OVF_vect)
{
    ++overflowCount;
}

// returns milliseconds
static unsigned long now()
{
    return overflowCount * (unsigned long)(64LL * 256 * 1000 / CLOCK);
}

static void delay(unsigned ms)
{
    unsigned long end = now()+ms;
    while (now() < end);
}
<commit_msg>Fix time bugs.<commit_after>#pragma once

#include <avr/io.h>
#include <avr/interrupt.h>

static volatile uint32_t overflowCount = 0;

// Timer0 ticks every 64 cycles
// Overflow happens every 256 ticks
ISR(TIMER0_OVF_vect)
{
    ++overflowCount;
}

static uint32_t now_nonstandard()
{
    return overflowCount * 2 / (CLOCK / 8000000);
}

static void delay_nonstandard(unsigned time)
{
    uint32_t end = now_nonstandard() + time;
    while (now_nonstandard() < end);
}

#define delay(ms) delay_nonstandard(ms*1024ULL/1000);
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by Tobias Koenig <tokoe@kde.org>                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/

#include "fetch.h"

#include "akonadi.h"
#include "akonadiconnection.h"
#include "imapparser.h"
#include "response.h"
#include "storage/selectquerybuilder.h"
#include "resourceinterface.h"

#include <QtCore/QStringList>
#include <QtCore/QUuid>
#include <QtCore/QVariant>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQuery>

using namespace Akonadi;

Fetch::Fetch()
  : Handler()
{
}

Fetch::~Fetch()
{
}

bool Fetch::handleLine( const QByteArray& line )
{
  // parse the command
  QByteArray buffer;
  int pos = ImapParser::parseString( line, buffer );

  // command
  bool isUidFetch = false;
  pos = ImapParser::parseString( line, buffer, pos );
  if ( buffer == "UID" ) {
    isUidFetch = true;
    pos = ImapParser::parseString( line, buffer, pos );
  }

  // sequence set
  ImapSet set;
  pos = ImapParser::parseSequenceSet( line, set, pos );
  if ( set.isEmpty() )
    return failureResponse( "Invalid sequence set" );

  // macro vs. attribute list
  pos = ImapParser::stripLeadingSpaces( line, pos );
  if ( pos >= line.count() )
    return failureResponse( "Premature end of command" );
  QList<QByteArray> attrList;
  bool allParts = false;
  if ( line[pos] == '(' ) {
    pos = ImapParser::parseParenthesizedList( line, attrList, pos );
  } else {
    pos = ImapParser::parseString( line, buffer, pos );
    if ( buffer == "AKALL" ) {
      allParts = true;
    } else if ( buffer == "ALL" ) {
      attrList << "FLAGS" << "INTERNALDATE" << "RFC822.SIZE" << "ENVELOPE";
    } else if ( buffer == "FULL" ) {
      attrList << "FLAGS" << "INTERNALDATE" << "RFC822.SIZE";
    } else if ( buffer == "FAST" ) {
      attrList << "FLAGS" << "INTERNALDATE" << "RFC822.SIZE" << "ENVELOPE" << "BODY";
    } else {
      return failureResponse( "Unsupported macro" );
    }
  }

  triggerOnDemandFetch( isUidFetch );

  // build item query
  QueryBuilder itemQuery;
  itemQuery.addTable( PimItem::tableName() );
  itemQuery.addTable( MimeType::tableName() );
  itemQuery.addTable( Location::tableName() );
  itemQuery.addTable( Resource::tableName() );
  itemQuery.addColumn( PimItem::idFullColumnName() );
  itemQuery.addColumn( PimItem::revFullColumnName() );
  itemQuery.addColumn( PimItem::remoteIdFullColumnName() );
  itemQuery.addColumn( MimeType::nameFullColumnName() );
  itemQuery.addColumn( Resource::nameFullColumnName() );
  itemQuery.addColumnCondition( PimItem::mimeTypeIdFullColumnName(), Query::Equals, MimeType::idFullColumnName() );
  itemQuery.addColumnCondition( PimItem::locationIdFullColumnName(), Query::Equals, Location::idFullColumnName() );
  itemQuery.addColumnCondition( Location::resourceIdFullColumnName(), Query::Equals, Resource::idFullColumnName() );
  imapSetToQuery( set, isUidFetch, itemQuery );
  itemQuery.addSortColumn( PimItem::idFullColumnName(), Query::Ascending );
  const int itemQueryIdColumn = 0;
  const int itemQueryRevColumn = 1;
  const int itemQueryRidColumn = 2;
  const int itemQueryMimeTypeColumn = 3;
  const int itemQueryResouceColumn = 4;

  if ( !itemQuery.exec() )
    return failureResponse( "Unable to list items" );
  itemQuery.query().next();

  // build flag query if needed
  QueryBuilder flagQuery;
  if ( attrList.contains( "FLAGS" ) || allParts ) {
    flagQuery.addTable( PimItem::tableName() );
    flagQuery.addTable( PimItemFlagRelation::tableName() );
    flagQuery.addTable( Flag::tableName() );
    flagQuery.addColumn( PimItem::idFullColumnName() );
    flagQuery.addColumn( Flag::nameFullColumnName() );
    flagQuery.addColumnCondition( PimItem::idFullColumnName(), Query::Equals, PimItemFlagRelation::leftFullColumnName() );
    flagQuery.addColumnCondition( Flag::idFullColumnName(), Query::Equals, PimItemFlagRelation::rightFullColumnName() );
    imapSetToQuery( set, isUidFetch, flagQuery );
    flagQuery.addSortColumn( PimItem::idFullColumnName(), Query::Ascending );

    if ( !flagQuery.exec() )
      return failureResponse( "Unable to retrieve item flags" );
    flagQuery.query().next();
  }
  const int flagQueryIdColumn = 0;
  const int flagQueryNameColumn = 1;

  // build part query if needed
  QueryBuilder partQuery;
  QStringList partList;
  foreach( const QByteArray b, attrList ) {
    // filter out non-part attributes
    if ( b == "REV" || b == "FLAGS" || b == "UID" || b == "REMOTEID" )
      continue;
    if ( b == "RFC822.SIZE" )
      partList << QString::fromLatin1( "RFC822" );
    else
      partList << QString::fromLatin1( b );
  }
  if ( !partList.isEmpty() || allParts || attrList.contains( "RFC822.SIZE" ) ) {
    partQuery.addTable( PimItem::tableName() );
    partQuery.addTable( Part::tableName() );
    partQuery.addColumn( PimItem::idFullColumnName() );
    partQuery.addColumn( Part::nameFullColumnName() );
    partQuery.addColumn( Part::dataFullColumnName() );
    partQuery.addColumnCondition( PimItem::idFullColumnName(), Query::Equals, Part::pimItemIdFullColumnName() );
    if ( !allParts )
      partQuery.addValueCondition( Part::nameFullColumnName(), Query::In, partList );
    imapSetToQuery( set, isUidFetch, partQuery );
    partQuery.addSortColumn( PimItem::idFullColumnName(), Query::Ascending );

    if ( !partQuery.exec() )
      return failureResponse( "Unable to retrieve item parts" );
    partQuery.query().next();
  }
  const int partQueryIdColumn = 0;
  const int partQueryNameColumn = 1;
  const int partQueryDataColumn = 2;

  // fetch not yet cached item parts
  // TODO: I'm sure this can be done with a single query instead of manually
  DataStore *store = connection()->storageBackend();
  if ( !partList.isEmpty() || allParts ) {
    while ( itemQuery.query().isValid() ) {
      const int pimItemId = itemQuery.query().value( itemQueryIdColumn ).toInt();
      QStringList missingParts = partList;
      while ( partQuery.query().isValid() ) {
        const int id = partQuery.query().value( partQueryIdColumn ).toInt();
        if ( id < pimItemId ) {
          partQuery.query().next();
          continue;
        } else if ( id > pimItemId ) {
          break;
        }
        const QString partName = partQuery.query().value( partQueryNameColumn ).toString();
        if ( partQuery.query().value( partQueryDataColumn ).toByteArray().isNull() ) {
          if ( allParts )
            missingParts << partName;
        } else {
          missingParts.removeAll( partName );
        }
        partQuery.query().next();
      }
      if ( !missingParts.isEmpty() ) {
        store->retrieveDataFromResource( pimItemId, itemQuery.query().value( itemQueryRidColumn ).toString().toUtf8(),
                                         itemQuery.query().value( itemQueryResouceColumn ).toString(), missingParts );
      }
      itemQuery.query().next();
    }

    // re-exec part query, rewind item query
    itemQuery.query().first();
    if ( !partQuery.query().exec() )
      return failureResponse( "Unable to retrieve item parts" );
    partQuery.query().next();
  }

  // build responses
  Response response;
  response.setUntagged();
  while ( itemQuery.query().isValid() ) {
    const int pimItemId = itemQuery.query().value( itemQueryIdColumn ).toInt();
    const int pimItemRev = itemQuery.query().value( itemQueryRevColumn ).toInt();
    QList<QByteArray> attributes;
    attributes.append( "UID " + QByteArray::number( pimItemId ) );
    attributes.append( "REV " + QByteArray::number( pimItemRev ) );
    attributes.append( "REMOTEID " + ImapParser::quote( itemQuery.query().value( itemQueryRidColumn ).toString().toUtf8() ) );
    attributes.append( "MIMETYPE " + ImapParser::quote( itemQuery.query().value( itemQueryMimeTypeColumn ).toString().toUtf8() ) );

    if ( attrList.contains( "FLAGS" ) ) {
      QList<QByteArray> flags;
      while ( flagQuery.query().isValid() ) {
        const int id = flagQuery.query().value( flagQueryIdColumn ).toInt();
        if ( id < pimItemId ) {
          flagQuery.query().next();
          continue;
        } else if ( id > pimItemId ) {
          break;
        }
        flags << flagQuery.query().value( flagQueryNameColumn ).toString().toUtf8();
        flagQuery.query().next();
      }
      attributes.append( "FLAGS (" + ImapParser::join( flags, " " ) + ')' );
    }

    while ( partQuery.query().isValid() ) {
      const int id = partQuery.query().value( partQueryIdColumn ).toInt();
      if ( id < pimItemId ) {
        partQuery.query().next();
        continue;
      } else if ( id > pimItemId ) {
        break;
      }
      QByteArray partName = partQuery.query().value( partQueryNameColumn ).toString().toUtf8();
      QByteArray part = partQuery.query().value( partQueryNameColumn ).toString().toUtf8();
      QByteArray data = partQuery.query().value( partQueryDataColumn ).toByteArray();
      if ( data.isNull() ) {
        part += " NIL";
      } else if ( data.isEmpty() ) {
        part += " \"\"";
      } else {
        part += " {" + QByteArray::number( data.length() ) + "}\n";
        part += data;
      }
      // return only requested parts (when RFC822.SIZE is requested, RFC822 is retrieved, but should not be returned)
      if ( attrList.contains( partName ) || allParts )
        attributes << part;

      if ( partName == "RFC822" && attrList.contains( "RFC822.SIZE" ) )
        attributes.append( "RFC822.SIZE " + QByteArray::number( data.length() ) );

      partQuery.query().next();
    }

    // IMAP protocol violation: should actually be the sequence number
    QByteArray attr = QByteArray::number( pimItemId ) + " FETCH (";
    attr += ImapParser::join( attributes, " " ) + ')';
    response.setUntagged();
    response.setString( attr );
    emit responseAvailable( response );

    itemQuery.query().next();
  }

  // update atime
  updateItemAccessTime( set, isUidFetch );

  response.setTag( tag() );
  response.setSuccess();
  if ( isUidFetch )
    response.setString( "UID FETCH completed" );
  else
    response.setString( "FETCH completed" );
  emit responseAvailable( response );
  deleteLater();
  return true;
}

void Fetch::updateItemAccessTime(const ImapSet & set, bool isUidFetch)
{
  QueryBuilder qb( QueryBuilder::Update );
  qb.addTable( PimItem::tableName() );
  qb.updateColumnValue( PimItem::atimeColumn(), QDateTime::currentDateTime() );
  imapSetToQuery( set, isUidFetch, qb );
  if ( !qb.exec() )
    qWarning() << "Unable to update item access time";
}

void Fetch::triggerOnDemandFetch(bool isUidFetch)
{
  if ( isUidFetch || connection()->selectedCollection() <= 0 )
    return;
  Location loc = connection()->selectedLocation();
  // HACK: don't trigger on-demand syncing if the resource is the one triggering it
  if ( connection()->sessionId() == loc.resource().name().toLatin1() )
    return;
  DataStore *store = connection()->storageBackend();
  store->activeCachePolicy( loc );
  if ( !loc.cachePolicySyncOnDemand() )
    return;
  store->triggerCollectionSync( loc );
}
<commit_msg>Special parts prefixed by "akonadi-" will never be fetched in the ressource. This is useful for agent-specific configuration for instance.<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by Tobias Koenig <tokoe@kde.org>                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/

#include "fetch.h"

#include "akonadi.h"
#include "akonadiconnection.h"
#include "imapparser.h"
#include "response.h"
#include "storage/selectquerybuilder.h"
#include "resourceinterface.h"

#include <QtCore/QStringList>
#include <QtCore/QUuid>
#include <QtCore/QVariant>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQuery>

using namespace Akonadi;

Fetch::Fetch()
  : Handler()
{
}

Fetch::~Fetch()
{
}

bool Fetch::handleLine( const QByteArray& line )
{
  // parse the command
  QByteArray buffer;
  int pos = ImapParser::parseString( line, buffer );

  // command
  bool isUidFetch = false;
  pos = ImapParser::parseString( line, buffer, pos );
  if ( buffer == "UID" ) {
    isUidFetch = true;
    pos = ImapParser::parseString( line, buffer, pos );
  }

  // sequence set
  ImapSet set;
  pos = ImapParser::parseSequenceSet( line, set, pos );
  if ( set.isEmpty() )
    return failureResponse( "Invalid sequence set" );

  // macro vs. attribute list
  pos = ImapParser::stripLeadingSpaces( line, pos );
  if ( pos >= line.count() )
    return failureResponse( "Premature end of command" );
  QList<QByteArray> attrList;
  bool allParts = false;
  if ( line[pos] == '(' ) {
    pos = ImapParser::parseParenthesizedList( line, attrList, pos );
  } else {
    pos = ImapParser::parseString( line, buffer, pos );
    if ( buffer == "AKALL" ) {
      allParts = true;
    } else if ( buffer == "ALL" ) {
      attrList << "FLAGS" << "INTERNALDATE" << "RFC822.SIZE" << "ENVELOPE";
    } else if ( buffer == "FULL" ) {
      attrList << "FLAGS" << "INTERNALDATE" << "RFC822.SIZE";
    } else if ( buffer == "FAST" ) {
      attrList << "FLAGS" << "INTERNALDATE" << "RFC822.SIZE" << "ENVELOPE" << "BODY";
    } else {
      return failureResponse( "Unsupported macro" );
    }
  }

  triggerOnDemandFetch( isUidFetch );

  // build item query
  QueryBuilder itemQuery;
  itemQuery.addTable( PimItem::tableName() );
  itemQuery.addTable( MimeType::tableName() );
  itemQuery.addTable( Location::tableName() );
  itemQuery.addTable( Resource::tableName() );
  itemQuery.addColumn( PimItem::idFullColumnName() );
  itemQuery.addColumn( PimItem::revFullColumnName() );
  itemQuery.addColumn( PimItem::remoteIdFullColumnName() );
  itemQuery.addColumn( MimeType::nameFullColumnName() );
  itemQuery.addColumn( Resource::nameFullColumnName() );
  itemQuery.addColumnCondition( PimItem::mimeTypeIdFullColumnName(), Query::Equals, MimeType::idFullColumnName() );
  itemQuery.addColumnCondition( PimItem::locationIdFullColumnName(), Query::Equals, Location::idFullColumnName() );
  itemQuery.addColumnCondition( Location::resourceIdFullColumnName(), Query::Equals, Resource::idFullColumnName() );
  imapSetToQuery( set, isUidFetch, itemQuery );
  itemQuery.addSortColumn( PimItem::idFullColumnName(), Query::Ascending );
  const int itemQueryIdColumn = 0;
  const int itemQueryRevColumn = 1;
  const int itemQueryRidColumn = 2;
  const int itemQueryMimeTypeColumn = 3;
  const int itemQueryResouceColumn = 4;

  if ( !itemQuery.exec() )
    return failureResponse( "Unable to list items" );
  itemQuery.query().next();

  // build flag query if needed
  QueryBuilder flagQuery;
  if ( attrList.contains( "FLAGS" ) || allParts ) {
    flagQuery.addTable( PimItem::tableName() );
    flagQuery.addTable( PimItemFlagRelation::tableName() );
    flagQuery.addTable( Flag::tableName() );
    flagQuery.addColumn( PimItem::idFullColumnName() );
    flagQuery.addColumn( Flag::nameFullColumnName() );
    flagQuery.addColumnCondition( PimItem::idFullColumnName(), Query::Equals, PimItemFlagRelation::leftFullColumnName() );
    flagQuery.addColumnCondition( Flag::idFullColumnName(), Query::Equals, PimItemFlagRelation::rightFullColumnName() );
    imapSetToQuery( set, isUidFetch, flagQuery );
    flagQuery.addSortColumn( PimItem::idFullColumnName(), Query::Ascending );

    if ( !flagQuery.exec() )
      return failureResponse( "Unable to retrieve item flags" );
    flagQuery.query().next();
  }
  const int flagQueryIdColumn = 0;
  const int flagQueryNameColumn = 1;

  // build part query if needed
  QueryBuilder partQuery;
  QStringList partList;
  foreach( const QByteArray b, attrList ) {
    // filter out non-part attributes
    if ( b == "REV" || b == "FLAGS" || b == "UID" || b == "REMOTEID" || b.startsWith( "akonadi-" ) )
      continue;
    if ( b == "RFC822.SIZE" )
      partList << QString::fromLatin1( "RFC822" );
    else
      partList << QString::fromLatin1( b );
  }
  if ( !partList.isEmpty() || allParts || attrList.contains( "RFC822.SIZE" ) ) {
    partQuery.addTable( PimItem::tableName() );
    partQuery.addTable( Part::tableName() );
    partQuery.addColumn( PimItem::idFullColumnName() );
    partQuery.addColumn( Part::nameFullColumnName() );
    partQuery.addColumn( Part::dataFullColumnName() );
    partQuery.addColumnCondition( PimItem::idFullColumnName(), Query::Equals, Part::pimItemIdFullColumnName() );
    if ( !allParts )
      partQuery.addValueCondition( Part::nameFullColumnName(), Query::In, partList );
    imapSetToQuery( set, isUidFetch, partQuery );
    partQuery.addSortColumn( PimItem::idFullColumnName(), Query::Ascending );

    if ( !partQuery.exec() )
      return failureResponse( "Unable to retrieve item parts" );
    partQuery.query().next();
  }
  const int partQueryIdColumn = 0;
  const int partQueryNameColumn = 1;
  const int partQueryDataColumn = 2;

  // fetch not yet cached item parts
  // TODO: I'm sure this can be done with a single query instead of manually
  DataStore *store = connection()->storageBackend();
  if ( !partList.isEmpty() || allParts ) {
    while ( itemQuery.query().isValid() ) {
      const int pimItemId = itemQuery.query().value( itemQueryIdColumn ).toInt();
      QStringList missingParts = partList;
      while ( partQuery.query().isValid() ) {
        const int id = partQuery.query().value( partQueryIdColumn ).toInt();
        if ( id < pimItemId ) {
          partQuery.query().next();
          continue;
        } else if ( id > pimItemId ) {
          break;
        }
        const QString partName = partQuery.query().value( partQueryNameColumn ).toString();
        if ( partQuery.query().value( partQueryDataColumn ).toByteArray().isNull() ) {
          if ( allParts )
            missingParts << partName;
        } else {
          missingParts.removeAll( partName );
        }
        partQuery.query().next();
      }
      if ( !missingParts.isEmpty() ) {
        store->retrieveDataFromResource( pimItemId, itemQuery.query().value( itemQueryRidColumn ).toString().toUtf8(),
                                         itemQuery.query().value( itemQueryResouceColumn ).toString(), missingParts );
      }
      itemQuery.query().next();
    }

    // re-exec part query, rewind item query
    itemQuery.query().first();
    if ( !partQuery.query().exec() )
      return failureResponse( "Unable to retrieve item parts" );
    partQuery.query().next();
  }

  // build responses
  Response response;
  response.setUntagged();
  while ( itemQuery.query().isValid() ) {
    const int pimItemId = itemQuery.query().value( itemQueryIdColumn ).toInt();
    const int pimItemRev = itemQuery.query().value( itemQueryRevColumn ).toInt();
    QList<QByteArray> attributes;
    attributes.append( "UID " + QByteArray::number( pimItemId ) );
    attributes.append( "REV " + QByteArray::number( pimItemRev ) );
    attributes.append( "REMOTEID " + ImapParser::quote( itemQuery.query().value( itemQueryRidColumn ).toString().toUtf8() ) );
    attributes.append( "MIMETYPE " + ImapParser::quote( itemQuery.query().value( itemQueryMimeTypeColumn ).toString().toUtf8() ) );

    if ( attrList.contains( "FLAGS" ) ) {
      QList<QByteArray> flags;
      while ( flagQuery.query().isValid() ) {
        const int id = flagQuery.query().value( flagQueryIdColumn ).toInt();
        if ( id < pimItemId ) {
          flagQuery.query().next();
          continue;
        } else if ( id > pimItemId ) {
          break;
        }
        flags << flagQuery.query().value( flagQueryNameColumn ).toString().toUtf8();
        flagQuery.query().next();
      }
      attributes.append( "FLAGS (" + ImapParser::join( flags, " " ) + ')' );
    }

    while ( partQuery.query().isValid() ) {
      const int id = partQuery.query().value( partQueryIdColumn ).toInt();
      if ( id < pimItemId ) {
        partQuery.query().next();
        continue;
      } else if ( id > pimItemId ) {
        break;
      }
      QByteArray partName = partQuery.query().value( partQueryNameColumn ).toString().toUtf8();
      QByteArray part = partQuery.query().value( partQueryNameColumn ).toString().toUtf8();
      QByteArray data = partQuery.query().value( partQueryDataColumn ).toByteArray();
      if ( data.isNull() ) {
        part += " NIL";
      } else if ( data.isEmpty() ) {
        part += " \"\"";
      } else {
        part += " {" + QByteArray::number( data.length() ) + "}\n";
        part += data;
      }
      // return only requested parts (when RFC822.SIZE is requested, RFC822 is retrieved, but should not be returned)
      if ( attrList.contains( partName ) || allParts )
        attributes << part;

      if ( partName == "RFC822" && attrList.contains( "RFC822.SIZE" ) )
        attributes.append( "RFC822.SIZE " + QByteArray::number( data.length() ) );

      partQuery.query().next();
    }

    // IMAP protocol violation: should actually be the sequence number
    QByteArray attr = QByteArray::number( pimItemId ) + " FETCH (";
    attr += ImapParser::join( attributes, " " ) + ')';
    response.setUntagged();
    response.setString( attr );
    emit responseAvailable( response );

    itemQuery.query().next();
  }

  // update atime
  updateItemAccessTime( set, isUidFetch );

  response.setTag( tag() );
  response.setSuccess();
  if ( isUidFetch )
    response.setString( "UID FETCH completed" );
  else
    response.setString( "FETCH completed" );
  emit responseAvailable( response );
  deleteLater();
  return true;
}

void Fetch::updateItemAccessTime(const ImapSet & set, bool isUidFetch)
{
  QueryBuilder qb( QueryBuilder::Update );
  qb.addTable( PimItem::tableName() );
  qb.updateColumnValue( PimItem::atimeColumn(), QDateTime::currentDateTime() );
  imapSetToQuery( set, isUidFetch, qb );
  if ( !qb.exec() )
    qWarning() << "Unable to update item access time";
}

void Fetch::triggerOnDemandFetch(bool isUidFetch)
{
  if ( isUidFetch || connection()->selectedCollection() <= 0 )
    return;
  Location loc = connection()->selectedLocation();
  // HACK: don't trigger on-demand syncing if the resource is the one triggering it
  if ( connection()->sessionId() == loc.resource().name().toLatin1() )
    return;
  DataStore *store = connection()->storageBackend();
  store->activeCachePolicy( loc );
  if ( !loc.cachePolicySyncOnDemand() )
    return;
  store->triggerCollectionSync( loc );
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2019 The Syscoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <validation.h>
#include <services/asset.h>
#include <services/assetconsensus.h>
#include <consensus/validation.h>
#include <consensus/dbwrapper.h>

std::string stringFromSyscoinTx(const int &nVersion) {
    switch (nVersion) {
    case SYSCOIN_TX_VERSION_ASSET_ACTIVATE:
		return "assetactivate";
    case SYSCOIN_TX_VERSION_ASSET_UPDATE:
		return "assetupdate";
	case SYSCOIN_TX_VERSION_ASSET_SEND:
		return "assetsend";
	case SYSCOIN_TX_VERSION_ALLOCATION_SEND:
		return "assetallocationsend";
	case SYSCOIN_TX_VERSION_ALLOCATION_BURN_TO_ETHEREUM:
		return "assetallocationburntoethereum";
	case SYSCOIN_TX_VERSION_ALLOCATION_BURN_TO_SYSCOIN:
		return "assetallocationburntosyscoin";
	case SYSCOIN_TX_VERSION_SYSCOIN_BURN_TO_ALLOCATION:
		return "syscoinburntoassetallocation";
    case SYSCOIN_TX_VERSION_ALLOCATION_MINT:
        return "assetallocationmint";
    default:
        return "<unknown assetallocation op>";
    }
}

std::vector<unsigned char> vchFromString(const std::string &str) {
	unsigned char *strbeg = (unsigned char*)str.c_str();
	return std::vector<unsigned char>(strbeg, strbeg + str.size());
}
std::string stringFromVch(const std::vector<unsigned char> &vch) {
	std::string res;
	std::vector<unsigned char>::const_iterator vi = vch.begin();
	while (vi != vch.end()) {
		res += (char)(*vi);
		vi++;
	}
	return res;
}

bool CAsset::UnserializeFromData(const std::vector<unsigned char> &vchData) {
    try {
		CDataStream dsAsset(vchData, SER_NETWORK, PROTOCOL_VERSION);
		Unserialize(dsAsset);
    } catch (std::exception &e) {
		SetNull();
        return false;
    }
	return true;
}

bool CAsset::UnserializeFromTx(const CTransaction &tx) {
	std::vector<unsigned char> vchData;
	int nOut;
	if (!GetSyscoinData(tx, vchData, nOut))
	{
		SetNull();
		return false;
	}
	if(!UnserializeFromData(vchData))
	{
		SetNull();
		return false;
	}
    return true;
}

int32_t GenerateSyscoinGuid(const COutPoint& outPoint) {
    const arith_uint256 &txidArith = UintToArith256(outPoint.hash);
    int32_t low32 = (int32_t)txidArith.GetLow64();
    low32 += outPoint.n;
    if(low32 < 0){
        low32 *= -1;
    }
    if(low32 <= SYSCOIN_TX_VERSION_ALLOCATION_SEND*10){
        low32 = SYSCOIN_TX_VERSION_ALLOCATION_SEND*10;
    }
    return low32;
}

void CAsset::SerializeData( std::vector<unsigned char> &vchData) {
    CDataStream dsAsset(SER_NETWORK, PROTOCOL_VERSION);
    Serialize(dsAsset);
	vchData = std::vector<unsigned char>(dsAsset.begin(), dsAsset.end());
}

bool GetAsset(const int32_t &nAsset,
        CAsset& txPos) {
    if (passetdb == nullptr || !passetdb->ReadAsset(nAsset, txPos))
        return false;
    return true;
}

bool ReserializeAssetCommitment(CMutableTransaction& mtx) {
    // load tx.voutAssets from tx.vout.assetInfo info
    // when change is added this function should be called and preceding this the vout.assetInfo
    // should all be in sync with the asset commitment in OP_RETURN. This will resync that commitment
    // because when change is added the vout.assetInfo is filled and we should capture that in LoadAssetsFromVout as it
    // re-orders tx->voutAssets if change address was somewhere before the last asset output
    mtx.LoadAssetsFromVout();
    // store tx.voutAssets into OP_RETURN data overwriting previous commitment
    const CTransactionRef& tx = MakeTransactionRef(mtx);
    std::vector<unsigned char> data;
    if(IsSyscoinMintTx(tx->nVersion)) {
        CMintSyscoin mintSyscoin(*tx);
        mintSyscoin.assetAllocation.voutAssets = tx->voutAssets;
        mintSyscoin.SerializeData(data);
    } else if(tx->nVersion == SYSCOIN_TX_VERSION_ALLOCATION_BURN_TO_SYSCOIN) {
        CBurnSyscoin burnSyscoin(*tx);
        burnSyscoin.assetAllocation.voutAssets = tx->voutAssets;
        burnSyscoin.SerializeData(data);
    } else if(IsAssetTx(tx->nVersion)) {
        CAsset asset(*tx);
        asset.assetAllocation.voutAssets = tx->voutAssets;
        asset.SerializeData(data);
    } else if(IsAssetAllocationTx(tx->nVersion)) {
        CAssetAllocation allocation(*tx);
        allocation.voutAssets = tx->voutAssets;
        allocation.SerializeData(data);
    }
    // find previous commitment (OP_RETURN) and replace script
    CScript scriptData;
    scriptData << OP_RETURN << data;
    bool bFoundData = false;
    for(auto& vout: mtx.vout) {
        if(vout.scriptPubKey.IsUnspendable()) {
            vout.scriptPubKey = scriptData;
            bFoundData = true;
            break;
        }
    }
    if(!bFoundData) {
        return false;
    }
    return true;
}
<commit_msg>typo<commit_after>// Copyright (c) 2013-2019 The Syscoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <validation.h>
#include <services/asset.h>
#include <services/assetconsensus.h>
#include <consensus/validation.h>
#include <dbwrapper.h>

std::string stringFromSyscoinTx(const int &nVersion) {
    switch (nVersion) {
    case SYSCOIN_TX_VERSION_ASSET_ACTIVATE:
		return "assetactivate";
    case SYSCOIN_TX_VERSION_ASSET_UPDATE:
		return "assetupdate";
	case SYSCOIN_TX_VERSION_ASSET_SEND:
		return "assetsend";
	case SYSCOIN_TX_VERSION_ALLOCATION_SEND:
		return "assetallocationsend";
	case SYSCOIN_TX_VERSION_ALLOCATION_BURN_TO_ETHEREUM:
		return "assetallocationburntoethereum";
	case SYSCOIN_TX_VERSION_ALLOCATION_BURN_TO_SYSCOIN:
		return "assetallocationburntosyscoin";
	case SYSCOIN_TX_VERSION_SYSCOIN_BURN_TO_ALLOCATION:
		return "syscoinburntoassetallocation";
    case SYSCOIN_TX_VERSION_ALLOCATION_MINT:
        return "assetallocationmint";
    default:
        return "<unknown assetallocation op>";
    }
}

std::vector<unsigned char> vchFromString(const std::string &str) {
	unsigned char *strbeg = (unsigned char*)str.c_str();
	return std::vector<unsigned char>(strbeg, strbeg + str.size());
}
std::string stringFromVch(const std::vector<unsigned char> &vch) {
	std::string res;
	std::vector<unsigned char>::const_iterator vi = vch.begin();
	while (vi != vch.end()) {
		res += (char)(*vi);
		vi++;
	}
	return res;
}

bool CAsset::UnserializeFromData(const std::vector<unsigned char> &vchData) {
    try {
		CDataStream dsAsset(vchData, SER_NETWORK, PROTOCOL_VERSION);
		Unserialize(dsAsset);
    } catch (std::exception &e) {
		SetNull();
        return false;
    }
	return true;
}

bool CAsset::UnserializeFromTx(const CTransaction &tx) {
	std::vector<unsigned char> vchData;
	int nOut;
	if (!GetSyscoinData(tx, vchData, nOut))
	{
		SetNull();
		return false;
	}
	if(!UnserializeFromData(vchData))
	{
		SetNull();
		return false;
	}
    return true;
}

int32_t GenerateSyscoinGuid(const COutPoint& outPoint) {
    const arith_uint256 &txidArith = UintToArith256(outPoint.hash);
    int32_t low32 = (int32_t)txidArith.GetLow64();
    low32 += outPoint.n;
    if(low32 < 0){
        low32 *= -1;
    }
    if(low32 <= SYSCOIN_TX_VERSION_ALLOCATION_SEND*10){
        low32 = SYSCOIN_TX_VERSION_ALLOCATION_SEND*10;
    }
    return low32;
}

void CAsset::SerializeData( std::vector<unsigned char> &vchData) {
    CDataStream dsAsset(SER_NETWORK, PROTOCOL_VERSION);
    Serialize(dsAsset);
	vchData = std::vector<unsigned char>(dsAsset.begin(), dsAsset.end());
}

bool GetAsset(const int32_t &nAsset,
        CAsset& txPos) {
    if (passetdb == nullptr || !passetdb->ReadAsset(nAsset, txPos))
        return false;
    return true;
}

bool ReserializeAssetCommitment(CMutableTransaction& mtx) {
    // load tx.voutAssets from tx.vout.assetInfo info
    // when change is added this function should be called and preceding this the vout.assetInfo
    // should all be in sync with the asset commitment in OP_RETURN. This will resync that commitment
    // because when change is added the vout.assetInfo is filled and we should capture that in LoadAssetsFromVout as it
    // re-orders tx->voutAssets if change address was somewhere before the last asset output
    mtx.LoadAssetsFromVout();
    // store tx.voutAssets into OP_RETURN data overwriting previous commitment
    const CTransactionRef& tx = MakeTransactionRef(mtx);
    std::vector<unsigned char> data;
    if(IsSyscoinMintTx(tx->nVersion)) {
        CMintSyscoin mintSyscoin(*tx);
        mintSyscoin.assetAllocation.voutAssets = tx->voutAssets;
        mintSyscoin.SerializeData(data);
    } else if(tx->nVersion == SYSCOIN_TX_VERSION_ALLOCATION_BURN_TO_SYSCOIN) {
        CBurnSyscoin burnSyscoin(*tx);
        burnSyscoin.assetAllocation.voutAssets = tx->voutAssets;
        burnSyscoin.SerializeData(data);
    } else if(IsAssetTx(tx->nVersion)) {
        CAsset asset(*tx);
        asset.assetAllocation.voutAssets = tx->voutAssets;
        asset.SerializeData(data);
    } else if(IsAssetAllocationTx(tx->nVersion)) {
        CAssetAllocation allocation(*tx);
        allocation.voutAssets = tx->voutAssets;
        allocation.SerializeData(data);
    }
    // find previous commitment (OP_RETURN) and replace script
    CScript scriptData;
    scriptData << OP_RETURN << data;
    bool bFoundData = false;
    for(auto& vout: mtx.vout) {
        if(vout.scriptPubKey.IsUnspendable()) {
            vout.scriptPubKey = scriptData;
            bFoundData = true;
            break;
        }
    }
    if(!bFoundData) {
        return false;
    }
    return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/counters_table.h"

#include "src/trace_processor/storage_cursor.h"
#include "src/trace_processor/table_utils.h"

namespace perfetto {
namespace trace_processor {

CountersTable::CountersTable(sqlite3*, const TraceStorage* storage)
    : storage_(storage) {
  ref_types_.resize(RefType::kMax);
  ref_types_[RefType::kCpuId] = "cpu";
  ref_types_[RefType::kUtid] = "utid";
  ref_types_[RefType::kNoRef] = "";
  ref_types_[RefType::kIrq] = "irq";
  ref_types_[RefType::kSoftIrq] = "softirq";
}

void CountersTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<CountersTable>(db, storage, "counters");
}

Table::Schema CountersTable::CreateSchema(int, const char* const*) {
  const auto& counters = storage_->counters();
  std::unique_ptr<StorageSchema::Column> cols[] = {
      StorageSchema::NumericColumnPtr("ts", &counters.timestamps(),
                                      false /* hidden */, true /* ordered */),
      StorageSchema::StringColumnPtr("name", &counters.name_ids(),
                                     &storage_->string_pool()),
      StorageSchema::NumericColumnPtr("value", &counters.values()),
      StorageSchema::NumericColumnPtr("dur", &counters.durations()),
      StorageSchema::NumericColumnPtr("ref", &counters.refs()),
      StorageSchema::StringColumnPtr("ref_type", &counters.types(),
                                     &ref_types_)};
  schema_ = StorageSchema({
      std::make_move_iterator(std::begin(cols)),
      std::make_move_iterator(std::end(cols)),
  });
  return schema_.ToTableSchema({"name", "ts", "ref"});
}

std::unique_ptr<Table::Cursor> CountersTable::CreateCursor(
    const QueryConstraints& qc,
    sqlite3_value** argv) {
  uint32_t count = static_cast<uint32_t>(storage_->counters().counter_count());
  auto it = table_utils::CreateBestRowIteratorForGenericSchema(schema_, count,
                                                               qc, argv);
  return std::unique_ptr<Table::Cursor>(
      new StorageCursor(std::move(it), schema_.ToColumnReporters()));
}

int CountersTable::BestIndex(const QueryConstraints&, BestIndexInfo* info) {
  info->estimated_cost =
      static_cast<uint32_t>(storage_->counters().counter_count());

  // We should be able to handle any constraint and any order by clause given
  // to us.
  info->order_by_consumed = true;
  std::fill(info->omit.begin(), info->omit.end(), true);

  return SQLITE_OK;
}

}  // namespace trace_processor
}  // namespace perfetto
<commit_msg>trace_processor: Allow sqlite to handle string filtering<commit_after>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/counters_table.h"

#include "src/trace_processor/storage_cursor.h"
#include "src/trace_processor/table_utils.h"

namespace perfetto {
namespace trace_processor {

CountersTable::CountersTable(sqlite3*, const TraceStorage* storage)
    : storage_(storage) {
  ref_types_.resize(RefType::kMax);
  ref_types_[RefType::kCpuId] = "cpu";
  ref_types_[RefType::kUtid] = "utid";
  ref_types_[RefType::kNoRef] = "";
  ref_types_[RefType::kIrq] = "irq";
  ref_types_[RefType::kSoftIrq] = "softirq";
}

void CountersTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<CountersTable>(db, storage, "counters");
}

Table::Schema CountersTable::CreateSchema(int, const char* const*) {
  const auto& counters = storage_->counters();
  std::unique_ptr<StorageSchema::Column> cols[] = {
      StorageSchema::NumericColumnPtr("ts", &counters.timestamps(),
                                      false /* hidden */, true /* ordered */),
      StorageSchema::StringColumnPtr("name", &counters.name_ids(),
                                     &storage_->string_pool()),
      StorageSchema::NumericColumnPtr("value", &counters.values()),
      StorageSchema::NumericColumnPtr("dur", &counters.durations()),
      StorageSchema::NumericColumnPtr("ref", &counters.refs()),
      StorageSchema::StringColumnPtr("ref_type", &counters.types(),
                                     &ref_types_)};
  schema_ = StorageSchema({
      std::make_move_iterator(std::begin(cols)),
      std::make_move_iterator(std::end(cols)),
  });
  return schema_.ToTableSchema({"name", "ts", "ref"});
}

std::unique_ptr<Table::Cursor> CountersTable::CreateCursor(
    const QueryConstraints& qc,
    sqlite3_value** argv) {
  uint32_t count = static_cast<uint32_t>(storage_->counters().counter_count());
  auto it = table_utils::CreateBestRowIteratorForGenericSchema(schema_, count,
                                                               qc, argv);
  return std::unique_ptr<Table::Cursor>(
      new StorageCursor(std::move(it), schema_.ToColumnReporters()));
}

int CountersTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
  info->estimated_cost =
      static_cast<uint32_t>(storage_->counters().counter_count());

  // Only the string columns are handled by SQLite
  info->order_by_consumed = true;
  size_t name_index = schema_.ColumnIndexFromName("name");
  size_t ref_type_index = schema_.ColumnIndexFromName("ref_type");
  for (size_t i = 0; i < qc.constraints().size(); i++) {
    info->omit[i] =
        qc.constraints()[i].iColumn != static_cast<int>(name_index) &&
        qc.constraints()[i].iColumn != static_cast<int>(ref_type_index);
  }

  return SQLITE_OK;
}

}  // namespace trace_processor
}  // namespace perfetto
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/extensions/extension_dialog.h"

#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/extensions/extension_dialog_observer.h"
#include "chrome/browser/ui/views/window.h"  // CreateViewsWindow
#include "chrome/common/chrome_notification_types.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
#include "googleurl/src/gurl.h"
#include "views/widget/widget.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/frame/bubble_window.h"
#endif

namespace {

views::Widget* CreateWindow(gfx::NativeWindow parent,
                            views::WidgetDelegate* delegate) {
#if defined(OS_CHROMEOS)
  // On Chrome OS we need to override the style to suppress padding around
  // the borders.
  return chromeos::BubbleWindow::Create(parent,
      chromeos::STYLE_FLUSH, delegate);
#else
  return browser::CreateViewsWindow(parent, delegate);
#endif
}

}  // namespace

ExtensionDialog::ExtensionDialog(ExtensionHost* host,
                                 ExtensionDialogObserver* observer)
    : window_(NULL),
      extension_host_(host),
      observer_(observer) {
  AddRef();  // Balanced in DeleteDelegate();

  // Listen for the containing view calling window.close();
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
                 Source<Profile>(host->profile()));
}

ExtensionDialog::~ExtensionDialog() {
}

// static
ExtensionDialog* ExtensionDialog::Show(
    const GURL& url,
    Browser* browser,
    TabContents* tab_contents,
    int width,
    int height,
    ExtensionDialogObserver* observer) {
  CHECK(browser);
  ExtensionHost* host = CreateExtensionHost(url, browser);
  if (!host)
    return NULL;
  host->set_associated_tab_contents(tab_contents);

  ExtensionDialog* dialog = new ExtensionDialog(host, observer);
  dialog->InitWindow(browser, width, height);
  // Ensure the DOM JavaScript can respond immediately to keyboard shortcuts.
  host->render_view_host()->view()->Focus();
  return dialog;
}

// static
ExtensionHost* ExtensionDialog::CreateExtensionHost(const GURL& url,
                                                    Browser* browser) {
  ExtensionProcessManager* manager =
      browser->profile()->GetExtensionProcessManager();
  DCHECK(manager);
  if (!manager)
    return NULL;
  return manager->CreateDialogHost(url, browser);
}

void ExtensionDialog::InitWindow(Browser* browser, int width, int height) {
  gfx::NativeWindow parent = browser->window()->GetNativeHandle();
  window_ = CreateWindow(parent, this /* views::WidgetDelegate */);

  // Center the window over the browser.
  gfx::Point center = browser->window()->GetBounds().CenterPoint();
  int x = center.x() - width / 2;
  int y = center.y() - height / 2;
  window_->SetBounds(gfx::Rect(x, y, width, height));

  window_->Show();
  window_->Activate();
}

void ExtensionDialog::ObserverDestroyed() {
  observer_ = NULL;
}

void ExtensionDialog::Close() {
  if (!window_)
    return;

  if (observer_)
    observer_->ExtensionDialogIsClosing(this);

  window_->Close();
  window_ = NULL;
}

/////////////////////////////////////////////////////////////////////////////
// views::WidgetDelegate overrides.

bool ExtensionDialog::CanResize() const {
  return false;
}

bool ExtensionDialog::IsModal() const {
  return true;
}

bool ExtensionDialog::ShouldShowWindowTitle() const {
  return false;
}

void ExtensionDialog::DeleteDelegate() {
  // The window has finished closing.  Allow ourself to be deleted.
  Release();
}

views::Widget* ExtensionDialog::GetWidget() {
  return extension_host_->view()->GetWidget();
}

const views::Widget* ExtensionDialog::GetWidget() const {
  return extension_host_->view()->GetWidget();
}

views::View* ExtensionDialog::GetContentsView() {
  return extension_host_->view();
}

/////////////////////////////////////////////////////////////////////////////
// NotificationObserver overrides.

void ExtensionDialog::Observe(int type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE:
      // If we aren't the host of the popup, then disregard the notification.
      if (Details<ExtensionHost>(host()) != details)
        return;
      Close();
      break;
    default:
      NOTREACHED() << L"Received unexpected notification";
      break;
  }
}
<commit_msg>Aura: Fix crash when opening CrOS file picker<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/extensions/extension_dialog.h"

#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/extensions/extension_dialog_observer.h"
#include "chrome/browser/ui/views/window.h"  // CreateViewsWindow
#include "chrome/common/chrome_notification_types.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
#include "googleurl/src/gurl.h"
#include "views/widget/widget.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/frame/bubble_window.h"
#endif

namespace {

views::Widget* CreateWindow(gfx::NativeWindow parent,
                            views::WidgetDelegate* delegate) {
#if defined(OS_CHROMEOS) && defined(TOOLKIT_USES_GTK)
  // TODO(msw): revert to BubbleWindow for all ChromeOS cases when CL
  // for crbug.com/98322 is landed.
  // On Chrome OS we need to override the style to suppress padding around
  // the borders.
  return chromeos::BubbleWindow::Create(parent,
      chromeos::STYLE_FLUSH, delegate);
#else
  return browser::CreateViewsWindow(parent, delegate);
#endif
}

}  // namespace

ExtensionDialog::ExtensionDialog(ExtensionHost* host,
                                 ExtensionDialogObserver* observer)
    : window_(NULL),
      extension_host_(host),
      observer_(observer) {
  AddRef();  // Balanced in DeleteDelegate();

  // Listen for the containing view calling window.close();
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
                 Source<Profile>(host->profile()));
}

ExtensionDialog::~ExtensionDialog() {
}

// static
ExtensionDialog* ExtensionDialog::Show(
    const GURL& url,
    Browser* browser,
    TabContents* tab_contents,
    int width,
    int height,
    ExtensionDialogObserver* observer) {
  CHECK(browser);
  ExtensionHost* host = CreateExtensionHost(url, browser);
  if (!host)
    return NULL;
  host->set_associated_tab_contents(tab_contents);

  ExtensionDialog* dialog = new ExtensionDialog(host, observer);
  dialog->InitWindow(browser, width, height);
  // Ensure the DOM JavaScript can respond immediately to keyboard shortcuts.
  host->render_view_host()->view()->Focus();
  return dialog;
}

// static
ExtensionHost* ExtensionDialog::CreateExtensionHost(const GURL& url,
                                                    Browser* browser) {
  ExtensionProcessManager* manager =
      browser->profile()->GetExtensionProcessManager();
  DCHECK(manager);
  if (!manager)
    return NULL;
  return manager->CreateDialogHost(url, browser);
}

void ExtensionDialog::InitWindow(Browser* browser, int width, int height) {
  gfx::NativeWindow parent = browser->window()->GetNativeHandle();
  window_ = CreateWindow(parent, this /* views::WidgetDelegate */);

  // Center the window over the browser.
  gfx::Point center = browser->window()->GetBounds().CenterPoint();
  int x = center.x() - width / 2;
  int y = center.y() - height / 2;
  window_->SetBounds(gfx::Rect(x, y, width, height));

  window_->Show();
  window_->Activate();
}

void ExtensionDialog::ObserverDestroyed() {
  observer_ = NULL;
}

void ExtensionDialog::Close() {
  if (!window_)
    return;

  if (observer_)
    observer_->ExtensionDialogIsClosing(this);

  window_->Close();
  window_ = NULL;
}

/////////////////////////////////////////////////////////////////////////////
// views::WidgetDelegate overrides.

bool ExtensionDialog::CanResize() const {
  return false;
}

bool ExtensionDialog::IsModal() const {
  return true;
}

bool ExtensionDialog::ShouldShowWindowTitle() const {
  return false;
}

void ExtensionDialog::DeleteDelegate() {
  // The window has finished closing.  Allow ourself to be deleted.
  Release();
}

views::Widget* ExtensionDialog::GetWidget() {
  return extension_host_->view()->GetWidget();
}

const views::Widget* ExtensionDialog::GetWidget() const {
  return extension_host_->view()->GetWidget();
}

views::View* ExtensionDialog::GetContentsView() {
  return extension_host_->view();
}

/////////////////////////////////////////////////////////////////////////////
// NotificationObserver overrides.

void ExtensionDialog::Observe(int type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE:
      // If we aren't the host of the popup, then disregard the notification.
      if (Details<ExtensionHost>(host()) != details)
        return;
      Close();
      break;
    default:
      NOTREACHED() << L"Received unexpected notification";
      break;
  }
}
<|endoftext|>


<commit_before>/*
    WPN-XM Server Control Panel

    WPN-XM SCP is a tool to manage Nginx, PHP and MariaDb daemons under windows.
    It's a fork of Easy WEMP originally written by Yann Le Moigne and (c) 2010.
    WPN-XM SCP is written by Jens-Andre Koch and (c) 2011 - onwards.

    This file is part of WPN-XM Serverpack for Windows.

    WPN-XM SCP is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    WPN-XM SCP is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with WPN-XM SCP. If not, see <http://www.gnu.org/licenses/>.
*/

// QT includes
#include <QApplication>
#include <QObject>
#include <QSystemTrayIcon>
#include <QMessageBox>
#include <QSharedMemory>
#include <QtGui>

// WPN-XM SCP includes
#include "main.h"
#include "mainwindow.h"

// main method
int main(int argc, char * argv[])
{
    // Single Instance Check
    exitIfAlreadyRunning();

    Q_INIT_RESOURCE(Resources);

    QApplication application(argc, argv);

    // Application Meta Data
    application.setApplicationName(APP_NAME);
    application.setApplicationVersion(APP_VERSION);
    application.setOrganizationName("Jens-Andr Koch");
    application.setOrganizationDomain("http://wpn-xm.org/");
    application.setWindowIcon(QIcon(":/wpnxm"));

    // if setStyle() is not used, the submenus are not displayed properly. bug?
    application.setStyle("windowsxp");

    // do not leave until Quit is clicked in the tray menu
    application.setQuitOnLastWindowClosed(false);

    MainWindow mainWindow;
    mainWindow.show();

    qDebug() << APP_NAME;
    qDebug() << APP_VERSION;

    // enter the Qt Event loop here
    return application.exec();
}

/*
 * Single Instance Check
 * Although some people tend to solve this problem by using QtSingleApplication,
 * this approach uses a GUID stored into shared memory.
 */
void exitIfAlreadyRunning()
{
      // Set GUID for WPN-XM Server Control Panel to memory
      QSharedMemory shared("004d54f6-7d00-4478-b612-f242f081b023");

      // already running
      if( !shared.create( 512, QSharedMemory::ReadWrite) )
      {
          QMessageBox msgBox;
          msgBox.setWindowTitle(APP_NAME);
          msgBox.setText( QObject::tr("Application is already running.  Exiting.") );
          msgBox.setIcon( QMessageBox::Critical );
          msgBox.exec();

          exit(0);
      }
      else
      {
        qDebug() << "Application started and not already running.";
      }
}
<commit_msg>better already running message<commit_after>/*
    WPN-XM Server Control Panel

    WPN-XM SCP is a tool to manage Nginx, PHP and MariaDb daemons under windows.
    It's a fork of Easy WEMP originally written by Yann Le Moigne and (c) 2010.
    WPN-XM SCP is written by Jens-Andre Koch and (c) 2011 - onwards.

    This file is part of WPN-XM Serverpack for Windows.

    WPN-XM SCP is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    WPN-XM SCP is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with WPN-XM SCP. If not, see <http://www.gnu.org/licenses/>.
*/

// QT includes
#include <QApplication>
#include <QObject>
#include <QSystemTrayIcon>
#include <QMessageBox>
#include <QSharedMemory>
#include <QtGui>

// WPN-XM SCP includes
#include "main.h"
#include "mainwindow.h"

// main method
int main(int argc, char * argv[])
{
    // Single Instance Check
    exitIfAlreadyRunning();

    Q_INIT_RESOURCE(Resources);

    QApplication application(argc, argv);

    // Application Meta Data
    application.setApplicationName(APP_NAME);
    application.setApplicationVersion(APP_VERSION);
    application.setOrganizationName("Jens-Andr Koch");
    application.setOrganizationDomain("http://wpn-xm.org/");
    application.setWindowIcon(QIcon(":/wpnxm"));

    // if setStyle() is not used, the submenus are not displayed properly. bug?
    application.setStyle("windowsxp");

    // do not leave until Quit is clicked in the tray menu
    application.setQuitOnLastWindowClosed(false);

    MainWindow mainWindow;
    mainWindow.show();

    qDebug() << APP_NAME;
    qDebug() << APP_VERSION;

    // enter the Qt Event loop here
    return application.exec();
}

/*
 * Single Instance Check
 * Although some people tend to solve this problem by using QtSingleApplication,
 * this approach uses a GUID stored into shared memory.
 */
void exitIfAlreadyRunning()
{
      // Set GUID for WPN-XM Server Control Panel to memory
      QSharedMemory shared("004d54f6-7d00-4478-b612-f242f081b023");

      // already running
      if( !shared.create( 512, QSharedMemory::ReadWrite) )
      {
          QMessageBox msgBox;
          msgBox.setWindowTitle(APP_NAME);
          msgBox.setText( QObject::tr("WPN-XM is already running.") );
          msgBox.setIcon( QMessageBox::Critical );
          msgBox.exec();

          exit(0);
      }
      else
      {
        qDebug() << "Application started and not already running.";
      }
}
<|endoftext|>


<commit_before>// -*- coding: us-ascii-unix -*-
// Copyright 2014 Lukas Kemmer
//
// Licensed under the Apache License, Version 2.0 (the "License"); you
// may not use this file except in compliance with the License. You
// may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.

#ifndef FAINT_TEST_HH
#define FAINT_TEST_HH
#include <cmath>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>

extern std::stringstream TEST_OUT;
extern bool TEST_FAILED;
extern int NUM_KNOWN_ERRORS;

class AbortTestException{};

// Add braces around the arguments, to get past preprocessor not
// understanding initializer-lists.
#define LIST(...){__VA_ARGS__}

#define MESSAGE(MSG) TEST_OUT << "  Message(" << __LINE__ << ") " << MSG << std::endl;

#define TIME_MESSAGE(MSG) TEST_OUT << "  " << MSG << std::endl;

template<typename T1, typename T2>
std::string str_not_equal_hex(T1 v1, T2 v2){
  std::stringstream ss;
  ss << std::hex;
  ss << static_cast<unsigned int>(v1) << " != " << static_cast<unsigned int>(v2);
  return ss.str();
}

#define EQUAL_HEX(A,B) if ((A) != (B)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << str_not_equal_hex(A, B) << ")" << std::endl; TEST_FAILED=true;}

#define EQUAL(A,B) if (!((A) == (B))){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << A << " != " << B << ")" << std::endl; TEST_FAILED=true;}

#define EQUALF(A,B,FMT)if (!((A) == (B))){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << FMT(A) << " != " << FMT(B) << ")" << std::endl; TEST_FAILED=true;}

#define NOT_EQUAL(A,B) if ((A) == (B)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " == " << #B << " (" << A << " == " << B << ")" << std::endl; TEST_FAILED=true;}

#define ASSERT_EQUAL(A,B) if ((A) != (B)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << A << " != " << B << ")" << std::endl; TEST_FAILED=true; throw AbortTestException();}

class Epsilon{
public:
  explicit constexpr Epsilon(double v)
    : value(v)
  {}

  operator double() const{
    return value;
  }

  double value;
};

namespace test{

// Helper to make the static_assert dependent on T.
template<typename T>
struct TypeDependentFalse{
  static const bool value = false;
};

template<typename T>
double to_double(const T&){
  static_assert(TypeDependentFalse<T>::value,
    "to_double not overloaded for type.");
  return 0.0;
}

inline double to_double(double v){
  return v;
}

} // namespace

template<typename T>
bool test_near(const T& a, const T& b, const Epsilon& e){
  return std::fabs(test::to_double(a) - test::to_double(b)) < e;
}

constexpr Epsilon operator "" _eps(long double v){
  return Epsilon(static_cast<double>(v));
}

#define NEAR(A,B,EPS) if (!test_near(A, B, EPS)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << A << " != " << B << ")" << std::endl; TEST_FAILED=true;}

inline bool test_write_error(const char* file, int line, const char* text){
  // Error-syntax recognized by emacs Compilation mode
  TEST_OUT << file << "(" << line << "): error: " << text << std::endl;

  TEST_FAILED = true;
  return false;
}

#define VERIFY(C) ((C) ? true : test_write_error(__FILE__, __LINE__, #C " failed."))

#define NOT(C) ((!C) ? true : test_write_error(__FILE__, __LINE__, "NOT " #C " failed."))

#define ASSERT(C) if ((C)){}else{ TEST_OUT << "  Error(" << __LINE__ << "): " << #C << " failed." << std::endl; TEST_FAILED=true; throw AbortTestException();}

#define ABORT_IF(C) if (!(C)){}else{ TEST_OUT << "  Error(" << __LINE__ << "): " << #C << " failed." << std::endl; TEST_FAILED=true; throw AbortTestException();}

inline void fail_test(){}

inline void fail_test(const char* message){
  TEST_OUT << "  " << message << std::endl;
  fail_test();
}

template<typename ...T>
void fail_test(const char* message, const T&... args){
  TEST_OUT << message << " ";
  fail_test(args...);
}

// TODO: Rename to e.g. ABORT_TEST
#define FAIL(...) TEST_OUT << "  FAIL triggered on line " << __LINE__ << std::endl; TEST_FAILED=true; fail_test(__VA_ARGS__); throw AbortTestException();

#define SET_FAIL() TEST_OUT << "  SET_FAIL triggered on line " << __LINE__ << std::endl; TEST_FAILED=true

#define KNOWN_ERROR(C) if ((C)){TEST_OUT << "  Error(" << __LINE__ << "): KNOWN_ERROR \"" << #C << "\"..\n" << "  ..evaluated OK. Test not updated?" << std::endl; TEST_FAILED=true;}else{ TEST_OUT << "  Known error(" << __LINE__ << "): " << #C << std::endl; NUM_KNOWN_ERRORS += 1;}

#define KNOWN_INEQUAL(A,B) if ((A) == (B)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " == " << #B << " (" << A << " != " << B << ")" << " ..evaluated OK. Test not updated?" << std::endl; TEST_FAILED=true;}else{ TEST_OUT << "  Known error(" << __LINE__ << "): " << A << "!=" << B << std::endl; NUM_KNOWN_ERRORS += 1;}

struct FailIfCalled{
  FailIfCalled(int line, bool abort=false)
    : m_line(line),
      m_abort(abort)
  {}

  template<typename... Args>
  void operator()(Args...) const{
    TEST_OUT << "  FailIfCalled was called on line " << m_line << std::endl;
    TEST_FAILED = true;
    if (m_abort){
      throw AbortTestException();
    }
  }
  int m_line;
  bool m_abort;
};

class Checkable{
public:
  virtual ~Checkable() = default;
  virtual bool Check() const = 0;
};

extern std::vector<Checkable*> POST_CHECKS;

class FailUnlessCalled : public Checkable{
public:
  FailUnlessCalled(int line)
    : m_called(false),
      m_line(line)
  {}

  template<typename... Args>
  void operator()(Args...) const {
    m_called = true;
  }

  bool Check() const override{
    if (!m_called){
      TEST_OUT << "  FAIL_UNLESS_CALLED on line " << m_line << " was not called." << std::endl;
      TEST_FAILED = true;
    }
    return m_called;
  }
private:
  mutable bool m_called;
  int m_line;
};

#define FWD(CALL);{try{bool alreadyFailed = TEST_FAILED;CALL;if (TEST_FAILED && !alreadyFailed){TEST_OUT << " ... called via FWD on line " << __LINE__ << std::endl;}}catch(const AbortTestException&){TEST_OUT << " ... called via FWD on line " << __LINE__ << std::endl; throw;}}

template<typename FUNC>
class FailUnlessCalledFwd : public Checkable{
public:
  FailUnlessCalledFwd(FUNC fwd, int line)
    : m_called(false),
      m_line(line),
      m_fwd(fwd)
  {}

  template<typename... Args>
  void operator()(Args...args) const {
    m_called = true;
    bool alreadyFailed = TEST_FAILED;
    m_fwd(args...);
    if (TEST_FAILED && !alreadyFailed){
      TEST_OUT << "  ... called via FAIL_UNLESS_CALLED_FWD on line " << m_line << std::endl;
    }
  }

  bool Check() const override{
    if (!m_called){
      TEST_OUT << "  FAIL_UNLESS_CALLED on line " << m_line << " was not called." << std::endl;
      TEST_FAILED = true;
    }
    return m_called;
  }
private:
  mutable bool m_called;
  int m_line;
  FUNC m_fwd;
};

template<typename FUNC>
class FailIfCalledFwd : public Checkable{
public:
  FailIfCalledFwd(FUNC fwd, int line)
    : m_called(false),
      m_line(line),
      m_fwd(fwd)
  {}

  template<typename... Args>
  void operator()(Args...args) const {
    m_called = true;
    bool alreadyFailed = TEST_FAILED;
    m_fwd(args...);
    if (TEST_FAILED && !alreadyFailed){
      TEST_OUT << "  ... called via FAIL_IF_CALLED_FWD on line " << m_line << std::endl;
    }
  }

  bool Check() const override{
    if (m_called){
      TEST_OUT << "  FAIL_IF_CALLED on line " << m_line << " was called." << std::endl;
      TEST_FAILED = true;
    }
    return m_called;
  }
private:
  mutable bool m_called;
  int m_line;
  FUNC m_fwd;
};

inline FailUnlessCalled& create_fail_unless_called(int line){
  FailUnlessCalled* f = new FailUnlessCalled(line);
  POST_CHECKS.push_back(f);
  return *f;
}

template<typename FUNC>
inline FailUnlessCalledFwd<FUNC>& create_fail_unless_called_fwd(FUNC func,
  int line)
{
  FailUnlessCalledFwd<FUNC>* f = new FailUnlessCalledFwd<FUNC>(func, line);
  POST_CHECKS.push_back(f);
  return *f;
}

template<typename FUNC>
inline FailIfCalledFwd<FUNC>& create_fail_if_called_fwd(FUNC func,
  int line)
{
  FailIfCalledFwd<FUNC>* f = new FailIfCalledFwd<FUNC>(func, line);
  POST_CHECKS.push_back(f);
  return *f;
}

#define FAIL_IF_CALLED()(FailIfCalled(__LINE__))
#define FAIL_UNLESS_CALLED()(create_fail_unless_called(__LINE__))
#define FAIL_UNLESS_CALLED_FWD(FUNC)(create_fail_unless_called_fwd(FUNC, __LINE__))
#define FAIL_IF_CALLED_FWD(FUNC)(create_fail_if_called_fwd(FUNC, __LINE__))

enum class TestPlatform{
  LINUX,
  WINDOWS
};

TestPlatform get_test_platform();

#endif
<commit_msg>Emacs syntax for ASSERT, ABORT_IF<commit_after>// -*- coding: us-ascii-unix -*-
// Copyright 2014 Lukas Kemmer
//
// Licensed under the Apache License, Version 2.0 (the "License"); you
// may not use this file except in compliance with the License. You
// may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.

#ifndef FAINT_TEST_HH
#define FAINT_TEST_HH
#include <cmath>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>

extern std::stringstream TEST_OUT;
extern bool TEST_FAILED;
extern int NUM_KNOWN_ERRORS;

class AbortTestException{};

// Add braces around the arguments, to get past preprocessor not
// understanding initializer-lists.
#define LIST(...){__VA_ARGS__}

#define MESSAGE(MSG) TEST_OUT << "  Message(" << __LINE__ << ") " << MSG << std::endl;

#define TIME_MESSAGE(MSG) TEST_OUT << "  " << MSG << std::endl;

template<typename T1, typename T2>
std::string str_not_equal_hex(T1 v1, T2 v2){
  std::stringstream ss;
  ss << std::hex;
  ss << static_cast<unsigned int>(v1) << " != " << static_cast<unsigned int>(v2);
  return ss.str();
}

#define EQUAL_HEX(A,B) if ((A) != (B)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << str_not_equal_hex(A, B) << ")" << std::endl; TEST_FAILED=true;}

#define EQUAL(A,B) if (!((A) == (B))){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << A << " != " << B << ")" << std::endl; TEST_FAILED=true;}

#define EQUALF(A,B,FMT)if (!((A) == (B))){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << FMT(A) << " != " << FMT(B) << ")" << std::endl; TEST_FAILED=true;}

#define NOT_EQUAL(A,B) if ((A) == (B)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " == " << #B << " (" << A << " == " << B << ")" << std::endl; TEST_FAILED=true;}

#define ASSERT_EQUAL(A,B) if ((A) != (B)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << A << " != " << B << ")" << std::endl; TEST_FAILED=true; throw AbortTestException();}

class Epsilon{
public:
  explicit constexpr Epsilon(double v)
    : value(v)
  {}

  operator double() const{
    return value;
  }

  double value;
};

namespace test{

// Helper to make the static_assert dependent on T.
template<typename T>
struct TypeDependentFalse{
  static const bool value = false;
};

template<typename T>
double to_double(const T&){
  static_assert(TypeDependentFalse<T>::value,
    "to_double not overloaded for type.");
  return 0.0;
}

inline double to_double(double v){
  return v;
}

} // namespace

template<typename T>
bool test_near(const T& a, const T& b, const Epsilon& e){
  return std::fabs(test::to_double(a) - test::to_double(b)) < e;
}

constexpr Epsilon operator "" _eps(long double v){
  return Epsilon(static_cast<double>(v));
}

#define NEAR(A,B,EPS) if (!test_near(A, B, EPS)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " != " << #B << " (" << A << " != " << B << ")" << std::endl; TEST_FAILED=true;}

inline bool test_write_error(const char* file, int line, const char* text){
  // Error-syntax recognized by emacs Compilation mode
  TEST_OUT << file << "(" << line << "): error: " << text << std::endl;

  TEST_FAILED = true;
  return false;
}

inline bool test_abort(const char* file, int line, const char* text){
  test_write_error(file, line, text);
  TEST_FAILED = true;
  throw AbortTestException();
}

#define VERIFY(C) ((C) ? true : test_write_error(__FILE__, __LINE__, "VERIFY " #C))

#define NOT(C) ((!C) ? true : test_write_error(__FILE__, __LINE__, "NOT " #C))

#define ASSERT(C) ((C) ? true : test_abort(__FILE__, __LINE__, "ASSERT "#C))

#define ABORT_IF(C) ((!C) ? true : test_abort(__FILE__, __LINE__, "ABORT_IF " #C))

inline void fail_test(){}

inline void fail_test(const char* message){
  TEST_OUT << "  " << message << std::endl;
  fail_test();
}

template<typename ...T>
void fail_test(const char* message, const T&... args){
  TEST_OUT << message << " ";
  fail_test(args...);
}

// TODO: Rename to e.g. ABORT_TEST
#define FAIL(...) TEST_OUT << "  FAIL triggered on line " << __LINE__ << std::endl; TEST_FAILED=true; fail_test(__VA_ARGS__); throw AbortTestException();

#define SET_FAIL() TEST_OUT << "  SET_FAIL triggered on line " << __LINE__ << std::endl; TEST_FAILED=true

#define KNOWN_ERROR(C) if ((C)){TEST_OUT << "  Error(" << __LINE__ << "): KNOWN_ERROR \"" << #C << "\"..\n" << "  ..evaluated OK. Test not updated?" << std::endl; TEST_FAILED=true;}else{ TEST_OUT << "  Known error(" << __LINE__ << "): " << #C << std::endl; NUM_KNOWN_ERRORS += 1;}

#define KNOWN_INEQUAL(A,B) if ((A) == (B)){ TEST_OUT << "  Error(" << __LINE__ << "): " << #A << " == " << #B << " (" << A << " != " << B << ")" << " ..evaluated OK. Test not updated?" << std::endl; TEST_FAILED=true;}else{ TEST_OUT << "  Known error(" << __LINE__ << "): " << A << "!=" << B << std::endl; NUM_KNOWN_ERRORS += 1;}

struct FailIfCalled{
  FailIfCalled(int line, bool abort=false)
    : m_line(line),
      m_abort(abort)
  {}

  template<typename... Args>
  void operator()(Args...) const{
    TEST_OUT << "  FailIfCalled was called on line " << m_line << std::endl;
    TEST_FAILED = true;
    if (m_abort){
      throw AbortTestException();
    }
  }
  int m_line;
  bool m_abort;
};

class Checkable{
public:
  virtual ~Checkable() = default;
  virtual bool Check() const = 0;
};

extern std::vector<Checkable*> POST_CHECKS;

class FailUnlessCalled : public Checkable{
public:
  FailUnlessCalled(int line)
    : m_called(false),
      m_line(line)
  {}

  template<typename... Args>
  void operator()(Args...) const {
    m_called = true;
  }

  bool Check() const override{
    if (!m_called){
      TEST_OUT << "  FAIL_UNLESS_CALLED on line " << m_line << " was not called." << std::endl;
      TEST_FAILED = true;
    }
    return m_called;
  }
private:
  mutable bool m_called;
  int m_line;
};

#define FWD(CALL);{try{bool alreadyFailed = TEST_FAILED;CALL;if (TEST_FAILED && !alreadyFailed){TEST_OUT << " ... called via FWD on line " << __LINE__ << std::endl;}}catch(const AbortTestException&){TEST_OUT << " ... called via FWD on line " << __LINE__ << std::endl; throw;}}

template<typename FUNC>
class FailUnlessCalledFwd : public Checkable{
public:
  FailUnlessCalledFwd(FUNC fwd, int line)
    : m_called(false),
      m_line(line),
      m_fwd(fwd)
  {}

  template<typename... Args>
  void operator()(Args...args) const {
    m_called = true;
    bool alreadyFailed = TEST_FAILED;
    m_fwd(args...);
    if (TEST_FAILED && !alreadyFailed){
      TEST_OUT << "  ... called via FAIL_UNLESS_CALLED_FWD on line " << m_line << std::endl;
    }
  }

  bool Check() const override{
    if (!m_called){
      TEST_OUT << "  FAIL_UNLESS_CALLED on line " << m_line << " was not called." << std::endl;
      TEST_FAILED = true;
    }
    return m_called;
  }
private:
  mutable bool m_called;
  int m_line;
  FUNC m_fwd;
};

template<typename FUNC>
class FailIfCalledFwd : public Checkable{
public:
  FailIfCalledFwd(FUNC fwd, int line)
    : m_called(false),
      m_line(line),
      m_fwd(fwd)
  {}

  template<typename... Args>
  void operator()(Args...args) const {
    m_called = true;
    bool alreadyFailed = TEST_FAILED;
    m_fwd(args...);
    if (TEST_FAILED && !alreadyFailed){
      TEST_OUT << "  ... called via FAIL_IF_CALLED_FWD on line " << m_line << std::endl;
    }
  }

  bool Check() const override{
    if (m_called){
      TEST_OUT << "  FAIL_IF_CALLED on line " << m_line << " was called." << std::endl;
      TEST_FAILED = true;
    }
    return m_called;
  }
private:
  mutable bool m_called;
  int m_line;
  FUNC m_fwd;
};

inline FailUnlessCalled& create_fail_unless_called(int line){
  FailUnlessCalled* f = new FailUnlessCalled(line);
  POST_CHECKS.push_back(f);
  return *f;
}

template<typename FUNC>
inline FailUnlessCalledFwd<FUNC>& create_fail_unless_called_fwd(FUNC func,
  int line)
{
  FailUnlessCalledFwd<FUNC>* f = new FailUnlessCalledFwd<FUNC>(func, line);
  POST_CHECKS.push_back(f);
  return *f;
}

template<typename FUNC>
inline FailIfCalledFwd<FUNC>& create_fail_if_called_fwd(FUNC func,
  int line)
{
  FailIfCalledFwd<FUNC>* f = new FailIfCalledFwd<FUNC>(func, line);
  POST_CHECKS.push_back(f);
  return *f;
}

#define FAIL_IF_CALLED()(FailIfCalled(__LINE__))
#define FAIL_UNLESS_CALLED()(create_fail_unless_called(__LINE__))
#define FAIL_UNLESS_CALLED_FWD(FUNC)(create_fail_unless_called_fwd(FUNC, __LINE__))
#define FAIL_IF_CALLED_FWD(FUNC)(create_fail_if_called_fwd(FUNC, __LINE__))

enum class TestPlatform{
  LINUX,
  WINDOWS
};

TestPlatform get_test_platform();

#endif
<|endoftext|>