<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////

#include "RocksDBTransactionState.h"
#include "Aql/QueryCache.h"
#include "Basics/Exceptions.h"
#include "Cache/CacheManagerFeature.h"
#include "Cache/Manager.h"
#include "Cache/Transaction.h"
#include "Logger/Logger.h"
#include "RestServer/TransactionManagerFeature.h"
#include "RocksDBEngine/RocksDBCollection.h"
#include "RocksDBEngine/RocksDBCommon.h"
#include "RocksDBEngine/RocksDBCounterManager.h"
#include "RocksDBEngine/RocksDBEngine.h"
#include "RocksDBEngine/RocksDBTransactionCollection.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
#include "StorageEngine/TransactionCollection.h"
#include "Transaction/Methods.h"
#include "VocBase/LogicalCollection.h"
#include "VocBase/TransactionManager.h"
#include "VocBase/modes.h"
#include "VocBase/ticks.h"

#include <rocksdb/db.h>
#include <rocksdb/options.h>
#include <rocksdb/status.h>
#include <rocksdb/utilities/optimistic_transaction_db.h>
#include <rocksdb/utilities/transaction.h>

using namespace arangodb;

struct RocksDBTransactionData final : public TransactionData {};

RocksDBSavePoint::RocksDBSavePoint(rocksdb::Transaction* trx)
    : _trx(trx), _committed(false) {
  _trx->SetSavePoint();
}

RocksDBSavePoint::~RocksDBSavePoint() {
  if (!_committed) {
    rollback();
  }
}

void RocksDBSavePoint::commit() {
  _committed = true;  // this will prevent the rollback
}

void RocksDBSavePoint::rollback() {
  _trx->RollbackToSavePoint();
  _committed = true;  // in order to not roll back again by accident
}

/// @brief transaction type
RocksDBTransactionState::RocksDBTransactionState(
    TRI_vocbase_t* vocbase, uint64_t maxTransSize,
    bool intermediateTransactionEnabled, uint64_t intermediateTransactionSize,
    uint64_t intermediateTransactionNumber)
    : TransactionState(vocbase),
      _rocksReadOptions(),
      _cacheTx(nullptr),
      _transactionSize(0),
      _maxTransactionSize(maxTransSize),
      _intermediateTransactionSize(intermediateTransactionSize),
      _intermediateTransactionNumber(intermediateTransactionNumber),
      _numInserts(0),
      _numUpdates(0),
      _numRemoves(0),
      _intermediateTransactionEnabled(intermediateTransactionEnabled) {}

/// @brief free a transaction container
RocksDBTransactionState::~RocksDBTransactionState() {
  if (_cacheTx != nullptr) {
    // note: endTransaction() will delete _cacheTrx!
    CacheManagerFeature::MANAGER->endTransaction(_cacheTx);
    _cacheTx = nullptr;
  }
}

/// @brief start a transaction
Result RocksDBTransactionState::beginTransaction(transaction::Hints hints) {
  LOG_TRX(this, _nestingLevel) << "beginning " << AccessMode::typeString(_type)
                               << " transaction";
  if (_nestingLevel == 0) {
    TRI_ASSERT(_status == transaction::Status::CREATED);

    // get a new id
    _id = TRI_NewTickServer();

    // register a protector
    auto data =
        std::make_unique<RocksDBTransactionData>();  // intentionally empty
    TransactionManagerFeature::MANAGER->registerTransaction(_id,
                                                            std::move(data));

    TRI_ASSERT(_rocksTransaction == nullptr);
    TRI_ASSERT(_cacheTx == nullptr);

    // start cache transaction
    _cacheTx =
        CacheManagerFeature::MANAGER->beginTransaction(isReadOnlyTransaction());

    // start rocks transaction
    StorageEngine* engine = EngineSelectorFeature::ENGINE;
    rocksdb::TransactionDB* db = static_cast<RocksDBEngine*>(engine)->db();
    _rocksTransaction.reset(db->BeginTransaction(
        _rocksWriteOptions, rocksdb::TransactionOptions()));
    _rocksTransaction->SetSnapshot();
    _rocksReadOptions.snapshot = _rocksTransaction->GetSnapshot();
  } else {
    TRI_ASSERT(_status == transaction::Status::RUNNING);
  }

  Result result = useCollections(_nestingLevel);

  if (result.ok()) {
    // all valid
    if (_nestingLevel == 0) {
      updateStatus(transaction::Status::RUNNING);
    }
  } else {
    // something is wrong
    if (_nestingLevel == 0) {
      updateStatus(transaction::Status::ABORTED);
    }

    // free what we have got so far
    unuseCollections(_nestingLevel);
  }

  return result;
}

/// @brief commit a transaction
Result RocksDBTransactionState::commitTransaction(
    transaction::Methods* activeTrx) {
  LOG_TRX(this, _nestingLevel) << "committing " << AccessMode::typeString(_type)
                               << " transaction";

  TRI_ASSERT(_status == transaction::Status::RUNNING);
  TRI_IF_FAILURE("TransactionWriteCommitMarker") {
    return Result(TRI_ERROR_DEBUG);
  }

  arangodb::Result result;

  if (_nestingLevel == 0) {
    if (_rocksTransaction != nullptr) {
      // set wait for sync flag if required
      if (waitForSync()) {
        _rocksWriteOptions.sync = true;
      }

      // TODO wait for response on github issue to see how we can use the
      // sequence number
      result = rocksutils::convertStatus(_rocksTransaction->Commit());
      rocksdb::SequenceNumber latestSeq =
          rocksutils::globalRocksDB()->GetLatestSequenceNumber();
      if (!result.ok()) {
        abortTransaction(activeTrx);
        return result;
      }

      if (_cacheTx != nullptr) {
        // note: endTransaction() will delete _cacheTx!
        CacheManagerFeature::MANAGER->endTransaction(_cacheTx);
        _cacheTx = nullptr;
      }

      // LOG_TOPIC(ERR, Logger::FIXME) << "#" << _id << " COMMIT";

      rocksdb::Snapshot const* snap = this->_rocksReadOptions.snapshot;
      TRI_ASSERT(snap != nullptr);

      for (auto& trxCollection : _collections) {
        RocksDBTransactionCollection* collection =
            static_cast<RocksDBTransactionCollection*>(trxCollection);
        int64_t adjustment =
            collection->numInserts() - collection->numRemoves();

        if (collection->numInserts() != 0 || collection->numRemoves() != 0 ||
            collection->revision() != 0) {
          RocksDBCollection* coll = static_cast<RocksDBCollection*>(
              trxCollection->collection()->getPhysical());
          coll->adjustNumberDocuments(adjustment);
          coll->setRevision(collection->revision());
          RocksDBEngine* engine =
              static_cast<RocksDBEngine*>(EngineSelectorFeature::ENGINE);

          RocksDBCounterManager::CounterAdjustment update(latestSeq,
                                                      collection->numInserts(),
                                                      collection->numRemoves(),
                                                      collection->revision());
          engine->counterManager()->updateCounter(coll->objectId(), update);
        }
      }

      _rocksTransaction.reset();
    }

    updateStatus(transaction::Status::COMMITTED);

    // if a write query, clear the query cache for the participating collections
    if (AccessMode::isWriteOrExclusive(_type) && !_collections.empty() &&
        arangodb::aql::QueryCache::instance()->mayBeActive()) {
      clearQueryCache();
    }
  }

  unuseCollections(_nestingLevel);

  return result;
}

/// @brief abort and rollback a transaction
Result RocksDBTransactionState::abortTransaction(
    transaction::Methods* activeTrx) {
  LOG_TRX(this, _nestingLevel) << "aborting " << AccessMode::typeString(_type)
                               << " transaction";
  TRI_ASSERT(_status == transaction::Status::RUNNING);
  Result result;

  if (_nestingLevel == 0) {
    if (_rocksTransaction != nullptr) {
      rocksdb::Status status = _rocksTransaction->Rollback();
      result = rocksutils::convertStatus(status);
      _rocksTransaction.reset();
    }

    if (_cacheTx != nullptr) {
      // note: endTransaction() will delete _cacheTx!
      CacheManagerFeature::MANAGER->endTransaction(_cacheTx);
      _cacheTx = nullptr;
    }

    // LOG_TOPIC(ERR, Logger::FIXME) << "#" << _id << " ABORT";

    updateStatus(transaction::Status::ABORTED);

    if (hasOperations()) {
      // must clean up the query cache because the transaction
      // may have queried something via AQL that is now rolled back
      clearQueryCache();
    }
  }

  unuseCollections(_nestingLevel);

  return result;
}

/// @brief add an operation for a transaction collection
RocksDBOperationResult RocksDBTransactionState::addOperation(
    TRI_voc_cid_t cid, TRI_voc_rid_t revisionId,
    TRI_voc_document_operation_e operationType, uint64_t operationSize,
    uint64_t keySize) {
  RocksDBOperationResult res;

  uint64_t newSize = _transactionSize + operationSize + keySize;
  if (_maxTransactionSize < newSize) {
    // we hit the transaction size limit
    std::string message = "maximal transaction size limit of " + std::to_string(_maxTransactionSize) + " bytes reached!";
    res.reset(TRI_ERROR_RESOURCE_LIMIT, message);
    return res;
  }

  auto collection =
      static_cast<RocksDBTransactionCollection*>(findCollection(cid));

  if (collection == nullptr) {
    std::string message = "collection '" + collection->collectionName() + "' not found in transaction state";
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, message);
  }

  // should not fail or fail with exception
  collection->addOperation(operationType, operationSize, revisionId);

  switch (operationType) {
    case TRI_VOC_DOCUMENT_OPERATION_UNKNOWN:
      break;
    case TRI_VOC_DOCUMENT_OPERATION_INSERT:
      ++_numInserts;
      break;
    case TRI_VOC_DOCUMENT_OPERATION_UPDATE:
    case TRI_VOC_DOCUMENT_OPERATION_REPLACE:
      ++_numUpdates;
      break;
    case TRI_VOC_DOCUMENT_OPERATION_REMOVE:
      ++_numRemoves;
      break;
  }

  _transactionSize = newSize;
  auto numOperations = _numInserts + _numUpdates + _numRemoves;

  // signal if intermediate commit is required
  // this will be done if intermediate transactions are enabled
  // and either the "number of operations" or the "transaction size"
  // has reached the limit
  if (_intermediateTransactionEnabled &&
      (_intermediateTransactionNumber <= numOperations ||
       _intermediateTransactionSize <= newSize)) {
    res.commitRequired(true);
  }

  return res;
}

void RocksDBTransactionState::reset() {
  //only reset when already commited
  TRI_ASSERT(_status == transaction::Status::COMMITTED);
  //reset count
  _transactionSize = 0;
  _numInserts = 0;
  _numUpdates = 0;
  _numRemoves = 0;
  unuseCollections(_nestingLevel);
  for (auto it = _collections.rbegin(); it != _collections.rend(); ++it) {
    (static_cast<RocksDBTransactionCollection*>(*it))->resetCounts();
  }
  _nestingLevel = 0;

  updateStatus(transaction::Status::CREATED);

  // start new transaction
  beginTransaction(transaction::Hints());
}
<commit_msg>fix query cache invalidation<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////

#include "RocksDBTransactionState.h"
#include "Aql/QueryCache.h"
#include "Basics/Exceptions.h"
#include "Cache/CacheManagerFeature.h"
#include "Cache/Manager.h"
#include "Cache/Transaction.h"
#include "Logger/Logger.h"
#include "RestServer/TransactionManagerFeature.h"
#include "RocksDBEngine/RocksDBCollection.h"
#include "RocksDBEngine/RocksDBCommon.h"
#include "RocksDBEngine/RocksDBCounterManager.h"
#include "RocksDBEngine/RocksDBEngine.h"
#include "RocksDBEngine/RocksDBTransactionCollection.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
#include "StorageEngine/TransactionCollection.h"
#include "Transaction/Methods.h"
#include "VocBase/LogicalCollection.h"
#include "VocBase/TransactionManager.h"
#include "VocBase/modes.h"
#include "VocBase/ticks.h"

#include <rocksdb/db.h>
#include <rocksdb/options.h>
#include <rocksdb/status.h>
#include <rocksdb/utilities/optimistic_transaction_db.h>
#include <rocksdb/utilities/transaction.h>

using namespace arangodb;

struct RocksDBTransactionData final : public TransactionData {};

RocksDBSavePoint::RocksDBSavePoint(rocksdb::Transaction* trx)
    : _trx(trx), _committed(false) {
  _trx->SetSavePoint();
}

RocksDBSavePoint::~RocksDBSavePoint() {
  if (!_committed) {
    rollback();
  }
}

void RocksDBSavePoint::commit() {
  _committed = true;  // this will prevent the rollback
}

void RocksDBSavePoint::rollback() {
  _trx->RollbackToSavePoint();
  _committed = true;  // in order to not roll back again by accident
}

/// @brief transaction type
RocksDBTransactionState::RocksDBTransactionState(
    TRI_vocbase_t* vocbase, uint64_t maxTransSize,
    bool intermediateTransactionEnabled, uint64_t intermediateTransactionSize,
    uint64_t intermediateTransactionNumber)
    : TransactionState(vocbase),
      _rocksReadOptions(),
      _cacheTx(nullptr),
      _transactionSize(0),
      _maxTransactionSize(maxTransSize),
      _intermediateTransactionSize(intermediateTransactionSize),
      _intermediateTransactionNumber(intermediateTransactionNumber),
      _numInserts(0),
      _numUpdates(0),
      _numRemoves(0),
      _intermediateTransactionEnabled(intermediateTransactionEnabled) {}

/// @brief free a transaction container
RocksDBTransactionState::~RocksDBTransactionState() {
  if (_cacheTx != nullptr) {
    // note: endTransaction() will delete _cacheTrx!
    CacheManagerFeature::MANAGER->endTransaction(_cacheTx);
    _cacheTx = nullptr;
  }
}

/// @brief start a transaction
Result RocksDBTransactionState::beginTransaction(transaction::Hints hints) {
  LOG_TRX(this, _nestingLevel) << "beginning " << AccessMode::typeString(_type)
                               << " transaction";
  if (_nestingLevel == 0) {
    TRI_ASSERT(_status == transaction::Status::CREATED);

    // get a new id
    _id = TRI_NewTickServer();

    // register a protector
    auto data =
        std::make_unique<RocksDBTransactionData>();  // intentionally empty
    TransactionManagerFeature::MANAGER->registerTransaction(_id,
                                                            std::move(data));

    TRI_ASSERT(_rocksTransaction == nullptr);
    TRI_ASSERT(_cacheTx == nullptr);

    // start cache transaction
    _cacheTx =
        CacheManagerFeature::MANAGER->beginTransaction(isReadOnlyTransaction());

    // start rocks transaction
    StorageEngine* engine = EngineSelectorFeature::ENGINE;
    rocksdb::TransactionDB* db = static_cast<RocksDBEngine*>(engine)->db();
    _rocksTransaction.reset(db->BeginTransaction(
        _rocksWriteOptions, rocksdb::TransactionOptions()));
    _rocksTransaction->SetSnapshot();
    _rocksReadOptions.snapshot = _rocksTransaction->GetSnapshot();
  } else {
    TRI_ASSERT(_status == transaction::Status::RUNNING);
  }

  Result result = useCollections(_nestingLevel);

  if (result.ok()) {
    // all valid
    if (_nestingLevel == 0) {
      updateStatus(transaction::Status::RUNNING);
    }
  } else {
    // something is wrong
    if (_nestingLevel == 0) {
      updateStatus(transaction::Status::ABORTED);
    }

    // free what we have got so far
    unuseCollections(_nestingLevel);
  }

  return result;
}

/// @brief commit a transaction
Result RocksDBTransactionState::commitTransaction(
    transaction::Methods* activeTrx) {
  LOG_TRX(this, _nestingLevel) << "committing " << AccessMode::typeString(_type)
                               << " transaction";

  TRI_ASSERT(_status == transaction::Status::RUNNING);
  TRI_IF_FAILURE("TransactionWriteCommitMarker") {
    return Result(TRI_ERROR_DEBUG);
  }

  arangodb::Result result;

  if (_nestingLevel == 0) {
    if (_rocksTransaction != nullptr) {
      // set wait for sync flag if required
      if (waitForSync()) {
        _rocksWriteOptions.sync = true;
      }

      // TODO wait for response on github issue to see how we can use the
      // sequence number
      result = rocksutils::convertStatus(_rocksTransaction->Commit());
      rocksdb::SequenceNumber latestSeq =
          rocksutils::globalRocksDB()->GetLatestSequenceNumber();
      if (!result.ok()) {
        abortTransaction(activeTrx);
        return result;
      }

      if (_cacheTx != nullptr) {
        // note: endTransaction() will delete _cacheTx!
        CacheManagerFeature::MANAGER->endTransaction(_cacheTx);
        _cacheTx = nullptr;
      }

      rocksdb::Snapshot const* snap = this->_rocksReadOptions.snapshot;
      TRI_ASSERT(snap != nullptr);

      for (auto& trxCollection : _collections) {
        RocksDBTransactionCollection* collection =
            static_cast<RocksDBTransactionCollection*>(trxCollection);
        int64_t adjustment =
            collection->numInserts() - collection->numRemoves();

        if (collection->numInserts() != 0 || collection->numRemoves() != 0 ||
            collection->revision() != 0) {
          RocksDBCollection* coll = static_cast<RocksDBCollection*>(
              trxCollection->collection()->getPhysical());
          coll->adjustNumberDocuments(adjustment);
          coll->setRevision(collection->revision());
          RocksDBEngine* engine =
              static_cast<RocksDBEngine*>(EngineSelectorFeature::ENGINE);

          RocksDBCounterManager::CounterAdjustment update(latestSeq,
                                                      collection->numInserts(),
                                                      collection->numRemoves(),
                                                      collection->revision());
          engine->counterManager()->updateCounter(coll->objectId(), update);
        }
      }

      _rocksTransaction.reset();
    }

    updateStatus(transaction::Status::COMMITTED);
  }

  unuseCollections(_nestingLevel);

  return result;
}

/// @brief abort and rollback a transaction
Result RocksDBTransactionState::abortTransaction(
    transaction::Methods* activeTrx) {
  LOG_TRX(this, _nestingLevel) << "aborting " << AccessMode::typeString(_type)
                               << " transaction";
  TRI_ASSERT(_status == transaction::Status::RUNNING);
  Result result;

  if (_nestingLevel == 0) {
    if (_rocksTransaction != nullptr) {
      rocksdb::Status status = _rocksTransaction->Rollback();
      result = rocksutils::convertStatus(status);
      _rocksTransaction.reset();
    }

    if (_cacheTx != nullptr) {
      // note: endTransaction() will delete _cacheTx!
      CacheManagerFeature::MANAGER->endTransaction(_cacheTx);
      _cacheTx = nullptr;
    }

    updateStatus(transaction::Status::ABORTED);

    if (hasOperations()) {
      // must clean up the query cache because the transaction
      // may have queried something via AQL that is now rolled back
      clearQueryCache();
    }
  }

  unuseCollections(_nestingLevel);

  return result;
}

/// @brief add an operation for a transaction collection
RocksDBOperationResult RocksDBTransactionState::addOperation(
    TRI_voc_cid_t cid, TRI_voc_rid_t revisionId,
    TRI_voc_document_operation_e operationType, uint64_t operationSize,
    uint64_t keySize) {
  RocksDBOperationResult res;

  uint64_t newSize = _transactionSize + operationSize + keySize;
  if (_maxTransactionSize < newSize) {
    // we hit the transaction size limit
    std::string message = "aborting transaction because maximal transaction size limit of " + std::to_string(_maxTransactionSize) + " bytes is reached";
    res.reset(TRI_ERROR_RESOURCE_LIMIT, message);
    return res;
  }

  auto collection =
      static_cast<RocksDBTransactionCollection*>(findCollection(cid));

  if (collection == nullptr) {
    std::string message = "collection '" + collection->collectionName() + "' not found in transaction state";
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, message);
  }

  // should not fail or fail with exception
  collection->addOperation(operationType, operationSize, revisionId);

  // clear the query cache for this collection
  if (arangodb::aql::QueryCache::instance()->mayBeActive()) {
    arangodb::aql::QueryCache::instance()->invalidate(
        _vocbase, collection->collectionName());
  }

  switch (operationType) {
    case TRI_VOC_DOCUMENT_OPERATION_UNKNOWN:
      break;
    case TRI_VOC_DOCUMENT_OPERATION_INSERT:
      ++_numInserts;
      break;
    case TRI_VOC_DOCUMENT_OPERATION_UPDATE:
    case TRI_VOC_DOCUMENT_OPERATION_REPLACE:
      ++_numUpdates;
      break;
    case TRI_VOC_DOCUMENT_OPERATION_REMOVE:
      ++_numRemoves;
      break;
  }

  _transactionSize = newSize;
  auto numOperations = _numInserts + _numUpdates + _numRemoves;

  // signal if intermediate commit is required
  // this will be done if intermediate transactions are enabled
  // and either the "number of operations" or the "transaction size"
  // has reached the limit
  if (_intermediateTransactionEnabled &&
      (_intermediateTransactionNumber <= numOperations ||
       _intermediateTransactionSize <= newSize)) {
    res.commitRequired(true);
  }

  return res;
}

void RocksDBTransactionState::reset() {
  //only reset when already commited
  TRI_ASSERT(_status == transaction::Status::COMMITTED);
  //reset count
  _transactionSize = 0;
  _numInserts = 0;
  _numUpdates = 0;
  _numRemoves = 0;
  unuseCollections(_nestingLevel);
  for (auto it = _collections.rbegin(); it != _collections.rend(); ++it) {
    (static_cast<RocksDBTransactionCollection*>(*it))->resetCounts();
  }
  _nestingLevel = 0;

  updateStatus(transaction::Status::CREATED);

  // start new transaction
  beginTransaction(transaction::Hints());
}
<|endoftext|>


<commit_before>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbVectorDataTransformFilterApplication.h"

#include <iostream>
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbVectorDataTransformFilter.h"
#include "otbVectorData.h"
#include "otbVectorDataFileWriter.h"
#include "otbVectorDataFileReader.h"
#include "otbVectorDataProjectionFilter.h"
#include "itkCenteredSimilarity2DTransform.h"
#include "otbMath.h"

namespace otb
{

int VectorDataTransformFilterApplication::Describe(ApplicationDescriptor* descriptor)
{
  descriptor->SetName("VectorDataTransformFilterApplication");
  descriptor->SetDescription("Apply a transform to each vertex of the input VectorData");
  descriptor->AddOption("Input","Support image","in", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("InputVectorData","Input vector data","vd", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("Output","Output vector data","out", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("TanslationX","Translation in the X direction","tx", 1, false, ApplicationDescriptor::Real);
  descriptor->AddOption("TanslationY","Translation in the Y direction","ty", 1, false, ApplicationDescriptor::Real);
  descriptor->AddOption("Angle",
                        "Angle of the rotation to apply in degrees","rot",
                        1, false, ApplicationDescriptor::Real);
  descriptor->AddOption("CenterX","The first coordinate of the rotation center","cx", 1,
                        false, ApplicationDescriptor::Real);
  descriptor->AddOption("CenterY","The second coordinate of the rotation center","cy", 1,
                        false, ApplicationDescriptor::Real);
  descriptor->AddOption("Scale","The scale to apply ","sc", 1, false, ApplicationDescriptor::Real);

  return EXIT_SUCCESS;
}

int VectorDataTransformFilterApplication::Execute(otb::ApplicationOptionsResult* parseResult)
{
  try
    {
    typedef otb::VectorData<>                         VectorDataType;
    typedef otb::VectorDataFileReader<VectorDataType> VectorDataFileReaderType;
    typedef otb::VectorDataFileWriter<VectorDataType> VectorDataFileWriterType;
    typedef otb::VectorDataTransformFilter
      <VectorDataType, VectorDataType>              VectorDataTransformType;
    typedef otb::VectorDataProjectionFilter<VectorDataType,
      VectorDataType>                                 VDProjectionFilterType;

    typedef otb::VectorImage<double, 2>                ImageType;
    typedef otb::ImageFileReader<ImageType>           ReaderType;

    // Instanciate the image reader
    ReaderType::Pointer      reader = ReaderType::New();
    reader->SetFileName(parseResult->GetParameterString("Input"));
    reader->UpdateOutputInformation();

    VectorDataFileReaderType::Pointer  vdreader = VectorDataFileReaderType::New();
    vdreader->SetFileName(parseResult->GetParameterString("InputVectorData"));
    vdreader->Update();

    // Reproject the VectorData In the image coordinate system
    VDProjectionFilterType::Pointer  vdproj = VDProjectionFilterType::New();
    vdproj->SetInput(vdreader->GetOutput());
    vdproj->SetInputProjectionRef(vdreader->GetOutput()->GetProjectionRef());
    vdproj->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist());
    vdproj->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef());

    // Set up the transform (Apply a translation of 8 pixels in the y
    // direction)
    typedef itk::CenteredSimilarity2DTransform<double> TransformType;
    TransformType::Pointer transform = TransformType::New();

    TransformType::ParametersType parameters(6);
    parameters[0] = 1;                  // Scale
    parameters[1] = 0.;                 // Rotation Angle in radian
    parameters[2] = 0;          // Center of the rotation (X)
    parameters[3] = 0;          // Center of the rotation (Y)
    parameters[4] = 0;                  // Translation (X)
    parameters[5] = 0;                  // Translation (Y)

    // Get parameters if any
    if(parseResult->IsOptionPresent("Scale"))
      parameters[0] = parseResult->GetParameterFloat("Scale");

    if(parseResult->IsOptionPresent("Angle"))
      parameters[1] = CONST_PI*parseResult->GetParameterFloat("Angle")/180.;

    if(parseResult->IsOptionPresent("CenterX"))
      parameters[2] = parseResult->GetParameterFloat("CenterX");

    if(parseResult->IsOptionPresent("CenterY"))
      parameters[3] = parseResult->GetParameterFloat("CenterY");

    if(parseResult->IsOptionPresent("TanslationX"))
      parameters[4] = parseResult->GetParameterFloat("TanslationX");

    if(parseResult->IsOptionPresent("TanslationY"))
      parameters[5] = parseResult->GetParameterFloat("TanslationY");

    // Set the parameters to the transform
    transform->SetParameters(parameters);

    VectorDataTransformType::Pointer transformFilter = VectorDataTransformType::New();
    transformFilter->SetInput(vdproj->GetOutput());
    transformFilter->SetTransform(transform);

    // retransform int the input vector projection
    VDProjectionFilterType::Pointer  reverseVdProj = VDProjectionFilterType::New();
    reverseVdProj->SetInput(transformFilter->GetOutput());
    reverseVdProj->SetOutputProjectionRef(vdreader->GetOutput()->GetProjectionRef());
    reverseVdProj->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist());
    reverseVdProj->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef());

    //Write the vectordata
    VectorDataFileWriterType::Pointer vdwriter = VectorDataFileWriterType::New();
    vdwriter->SetInput(reverseVdProj->GetOutput());
    vdwriter->SetFileName(parseResult->GetParameterString("Output"));
    vdwriter->Update();

    }
  catch ( itk::ExceptionObject & err )
    {
    std::cout << "Following otbException caught :" << std::endl;
    std::cout << err << std::endl;
    return EXIT_FAILURE;
    }
  catch ( std::bad_alloc & err )
    {
    std::cout << "Exception bad_alloc : "<<(char*)err.what()<< std::endl;
    return EXIT_FAILURE;
    }
  catch ( ... )
    {
    std::cout << "Unknown Exception found !" << std::endl;
    return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}
}
<commit_msg>STYLE<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbVectorDataTransformFilterApplication.h"

#include <iostream>
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbVectorDataTransformFilter.h"
#include "otbVectorData.h"
#include "otbVectorDataFileWriter.h"
#include "otbVectorDataFileReader.h"
#include "otbVectorDataProjectionFilter.h"
#include "itkCenteredSimilarity2DTransform.h"
#include "otbMath.h"

namespace otb
{

int VectorDataTransformFilterApplication::Describe(ApplicationDescriptor* descriptor)
{
  descriptor->SetName("VectorDataTransformFilterApplication");
  descriptor->SetDescription("Apply a transform to each vertex of the input VectorData");
  descriptor->AddOption("Input","Support image","in", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("InputVectorData","Input vector data","vd", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("Output","Output vector data","out", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("TanslationX","Translation in the X direction","tx", 1, false, ApplicationDescriptor::Real);
  descriptor->AddOption("TanslationY","Translation in the Y direction","ty", 1, false, ApplicationDescriptor::Real);
  descriptor->AddOption("Angle",
                        "Angle of the rotation to apply in degrees","rot",
                        1, false, ApplicationDescriptor::Real);
  descriptor->AddOption("CenterX","The first coordinate of the rotation center","cx", 1,
                        false, ApplicationDescriptor::Real);
  descriptor->AddOption("CenterY","The second coordinate of the rotation center","cy", 1,
                        false, ApplicationDescriptor::Real);
  descriptor->AddOption("Scale","The scale to apply ","sc", 1, false, ApplicationDescriptor::Real);

  return EXIT_SUCCESS;
}

int VectorDataTransformFilterApplication::Execute(otb::ApplicationOptionsResult* parseResult)
{
  try
    {
    typedef otb::VectorData<>                         VectorDataType;
    typedef otb::VectorDataFileReader<VectorDataType> VectorDataFileReaderType;
    typedef otb::VectorDataFileWriter<VectorDataType> VectorDataFileWriterType;
    typedef otb::VectorDataTransformFilter
      <VectorDataType, VectorDataType>                VectorDataTransformType;
    typedef otb::VectorDataProjectionFilter<VectorDataType,
      VectorDataType>                                 VDProjectionFilterType;

    typedef otb::VectorImage<double, 2>               ImageType;
    typedef otb::ImageFileReader<ImageType>           ReaderType;

    // Instanciate the image reader
    ReaderType::Pointer      reader = ReaderType::New();
    reader->SetFileName(parseResult->GetParameterString("Input"));
    reader->UpdateOutputInformation();

    VectorDataFileReaderType::Pointer  vdreader = VectorDataFileReaderType::New();
    vdreader->SetFileName(parseResult->GetParameterString("InputVectorData"));
    vdreader->Update();

    // Reproject the VectorData In the image coordinate system
    VDProjectionFilterType::Pointer  vdproj = VDProjectionFilterType::New();
    vdproj->SetInput(vdreader->GetOutput());
    vdproj->SetInputProjectionRef(vdreader->GetOutput()->GetProjectionRef());
    vdproj->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist());
    vdproj->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef());

    // Set up the transform (Apply a translation of 8 pixels in the y
    // direction)
    typedef itk::CenteredSimilarity2DTransform<double> TransformType;
    TransformType::Pointer transform = TransformType::New();

    TransformType::ParametersType parameters(6);
    parameters[0] = 1;                  // Scale
    parameters[1] = 0.;                 // Rotation Angle in radian
    parameters[2] = 0;          // Center of the rotation (X)
    parameters[3] = 0;          // Center of the rotation (Y)
    parameters[4] = 0;                  // Translation (X)
    parameters[5] = 0;                  // Translation (Y)

    // Get parameters if any
    if(parseResult->IsOptionPresent("Scale"))
      parameters[0] = parseResult->GetParameterFloat("Scale");

    if(parseResult->IsOptionPresent("Angle"))
      parameters[1] = CONST_PI*parseResult->GetParameterFloat("Angle")/180.;

    if(parseResult->IsOptionPresent("CenterX"))
      parameters[2] = parseResult->GetParameterFloat("CenterX");

    if(parseResult->IsOptionPresent("CenterY"))
      parameters[3] = parseResult->GetParameterFloat("CenterY");

    if(parseResult->IsOptionPresent("TanslationX"))
      parameters[4] = parseResult->GetParameterFloat("TanslationX");

    if(parseResult->IsOptionPresent("TanslationY"))
      parameters[5] = parseResult->GetParameterFloat("TanslationY");

    // Set the parameters to the transform
    transform->SetParameters(parameters);

    VectorDataTransformType::Pointer transformFilter = VectorDataTransformType::New();
    transformFilter->SetInput(vdproj->GetOutput());
    transformFilter->SetTransform(transform);

    // retransform int the input vector projection
    VDProjectionFilterType::Pointer  reverseVdProj = VDProjectionFilterType::New();
    reverseVdProj->SetInput(transformFilter->GetOutput());
    reverseVdProj->SetOutputProjectionRef(vdreader->GetOutput()->GetProjectionRef());
    reverseVdProj->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist());
    reverseVdProj->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef());

    //Write the vectordata
    VectorDataFileWriterType::Pointer vdwriter = VectorDataFileWriterType::New();
    vdwriter->SetInput(reverseVdProj->GetOutput());
    vdwriter->SetFileName(parseResult->GetParameterString("Output"));
    vdwriter->Update();

    }
  catch ( itk::ExceptionObject & err )
    {
    std::cout << "Following otbException caught :" << std::endl;
    std::cout << err << std::endl;
    return EXIT_FAILURE;
    }
  catch ( std::bad_alloc & err )
    {
    std::cout << "Exception bad_alloc : "<<(char*)err.what()<< std::endl;
    return EXIT_FAILURE;
    }
  catch ( ... )
    {
    std::cout << "Unknown Exception found !" << std::endl;
    return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}
}
<|endoftext|>


<commit_before>//      2_fibonacci.cpp
//
//      Copyright 2010 Luis Carlin <luis@luis-laptop>
//
//      This program 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 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 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 <iostream>
using namespace std;

int main()
{

	int num_2 = 1;
	int num_1 = 2;

	int sum = 2; //2 from the start

	for (int num = 3; num<4000000; num = num_2 + num_1)
	{
		if (num%2 == 0)
		{
			sum = sum + num;
		}
		num_2 = num_1;
		num_1 = num;
	}
	cout << "The sum of all the even-valued terms in the sequence which do not exceed four million is " << sum << endl;

	return 0;
}
<commit_msg>Update 2_fibonacci.cpp<commit_after>#include <iostream>
using namespace std;

int main()
{

	int num_2 = 1;
	int num_1 = 2;

	int sum = 2; //2 from the start

	for (int num = 3; num<4000000; num = num_2 + num_1)
	{
		if (num%2 == 0)
		{
			sum = sum + num;
		}
		num_2 = num_1;
		num_1 = num;
	}
	cout << "The sum of all the even-valued terms in the sequence which do not exceed four million is " << sum << endl;

	return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/dispatcher_host.h"

#include "base/logging.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/nw/src/api/api_messages.h"
#include "content/nw/src/api/app/app.h"
#include "content/nw/src/api/base/base.h"
#include "content/nw/src/api/clipboard/clipboard.h"
#include "content/nw/src/api/menu/menu.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/nw/src/api/shell/shell.h"
#include "content/nw/src/api/tray/tray.h"
#include "content/nw/src/api/window/window.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/shell_browser_context.h"
#include "content/nw/src/nw_shell.h"
#include "content/public/browser/render_process_host.h"

using content::WebContents;
using content::ShellBrowserContext;
using content::Shell;

namespace api {

IDMap<Base, IDMapOwnPointer> api::DispatcherHost::objects_registry_;
int api::DispatcherHost::next_object_id_ = 1;
static std::map<content::RenderViewHost*, DispatcherHost*> g_dispatcher_host_map;

DispatcherHost::DispatcherHost(content::RenderViewHost* render_view_host)
    : content::RenderViewHostObserver(render_view_host) {
  g_dispatcher_host_map[render_view_host] = this;
}

DispatcherHost::~DispatcherHost() {
  g_dispatcher_host_map.erase(render_view_host());
}

DispatcherHost*
FindDispatcherHost(content::RenderViewHost* render_view_host) {
  std::map<content::RenderViewHost*, DispatcherHost*>::iterator it
    = g_dispatcher_host_map.find(render_view_host);
  if (it == g_dispatcher_host_map.end())
    return NULL;
  return it->second;
}

Base* DispatcherHost::GetApiObject(int id) {
  return objects_registry_.Lookup(id);
}

int DispatcherHost::AllocateId() {
  return next_object_id_++;
}

void DispatcherHost::SendEvent(Base* object,
                               const std::string& event,
                               const base::ListValue& arguments) {
  Send(new ShellViewMsg_Object_On_Event(
       routing_id(), object->id(), event, arguments));
}

bool DispatcherHost::Send(IPC::Message* message) {
  return content::RenderViewHostObserver::Send(message);
}

bool DispatcherHost::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  base::ThreadRestrictions::ScopedAllowIO allow_io;
  base::ThreadRestrictions::ScopedAllowWait allow_wait;
  IPC_BEGIN_MESSAGE_MAP(DispatcherHost, message)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Allocate_Object, OnAllocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Deallocate_Object, OnDeallocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method, OnCallObjectMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method_Sync,
                        OnCallObjectMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method, OnCallStaticMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method_Sync,
                        OnCallStaticMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_UncaughtException,
                        OnUncaughtException);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GetShellId, OnGetShellId);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_CreateShell, OnCreateShell);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GrantUniversalPermissions, OnGrantUniversalPermissions);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_AllocateId, OnAllocateId);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void DispatcherHost::OnAllocateObject(int object_id,
                                      const std::string& type,
                                      const base::DictionaryValue& option) {
  DVLOG(1) << "OnAllocateObject: object_id:" << object_id
             << " type:" << type
             << " option:" << option;

  if (type == "Menu") {
    objects_registry_.AddWithID(new Menu(object_id, this, option), object_id);
  } else if (type == "MenuItem") {
    objects_registry_.AddWithID(
        new MenuItem(object_id, this, option), object_id);
  } else if (type == "Tray") {
    objects_registry_.AddWithID(new Tray(object_id, this, option), object_id);
  } else if (type == "Clipboard") {
    objects_registry_.AddWithID(
        new Clipboard(object_id, this, option), object_id);
  } else if (type == "Window") {
    objects_registry_.AddWithID(new Window(object_id, this, option), object_id);
  } else {
    LOG(ERROR) << "Allocate an object of unknown type: " << type;
    objects_registry_.AddWithID(new Base(object_id, this, option), object_id);
  }
}

void DispatcherHost::OnDeallocateObject(int object_id) {
  DLOG(INFO) << "OnDeallocateObject: object_id:" << object_id;
  objects_registry_.Remove(object_id);
}

void DispatcherHost::OnCallObjectMethod(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallObjectMethod: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  DLOG(WARNING) << "Unknown object: " << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;
  if (object)
    object->Call(method, arguments);
}

void DispatcherHost::OnCallObjectMethodSync(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallObjectMethodSync: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  CHECK(object) << "Unknown object: " << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;
  if (object)
    object->CallSync(method, arguments, result);
}

void DispatcherHost::OnCallStaticMethod(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallStaticMethod: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "Shell") {
    api::Shell::Call(method, arguments);
    return;
  } else if (type == "App") {
    api::App::Call(method, arguments);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnCallStaticMethodSync(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallStaticMethodSync: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "App") {
    content::Shell* shell =
        content::Shell::FromRenderViewHost(render_view_host());
    api::App::Call(shell, method, arguments, result);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnUncaughtException(const std::string& err) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  shell->PrintCriticalError("Uncaught node.js Error", err);
}

void DispatcherHost::OnGetShellId(int* id) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  *id = shell->id();
}

void DispatcherHost::OnCreateShell(const std::string& url,
                                   const base::DictionaryValue& manifest,
                                   int* routing_id) {
  WebContents* base_web_contents =
      content::Shell::FromRenderViewHost(render_view_host())->web_contents();
  ShellBrowserContext* browser_context =
      static_cast<ShellBrowserContext*>(base_web_contents->GetBrowserContext());
  scoped_ptr<base::DictionaryValue> new_manifest(manifest.DeepCopy());
  bool new_renderer = false;
  if (new_manifest->GetBoolean(switches::kmNewInstance,
                               &new_renderer) && new_renderer)
    browser_context->set_pinning_renderer(false);

  WebContents::CreateParams create_params(browser_context,
                                          new_renderer ? NULL : base_web_contents->GetSiteInstance());

  WebContents* web_contents = content::WebContentsImpl::CreateWithOpener(
      create_params,
      static_cast<content::WebContentsImpl*>(base_web_contents));
  content::Shell::Create(base_web_contents,
                         GURL(url),
                         new_manifest.get(),
                         web_contents);

  if (new_renderer)
    browser_context->set_pinning_renderer(true);

  *routing_id = web_contents->GetRoutingID();

  int object_id = 0;
  if (new_manifest->GetInteger("object_id", &object_id)) {
    DispatcherHost* dhost = FindDispatcherHost(web_contents->GetRenderViewHost());
    dhost->OnAllocateObject(object_id, "Window", *new_manifest.get());
  }
}

void DispatcherHost::OnGrantUniversalPermissions(int *ret) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  if (shell->nodejs()) {
    content::ChildProcessSecurityPolicy::GetInstance()->GrantUniversalAccess(shell->web_contents()->GetRenderProcessHost()->GetID());
    *ret = 1;
  }else
    *ret = 0;
}

void DispatcherHost::OnAllocateId(int * ret) {
  *ret = AllocateId();
}

}  // namespace api
<commit_msg>Do not quit on API call on invalid object<commit_after>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/dispatcher_host.h"

#include "base/logging.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/nw/src/api/api_messages.h"
#include "content/nw/src/api/app/app.h"
#include "content/nw/src/api/base/base.h"
#include "content/nw/src/api/clipboard/clipboard.h"
#include "content/nw/src/api/menu/menu.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/nw/src/api/shell/shell.h"
#include "content/nw/src/api/tray/tray.h"
#include "content/nw/src/api/window/window.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/shell_browser_context.h"
#include "content/nw/src/nw_shell.h"
#include "content/public/browser/render_process_host.h"

using content::WebContents;
using content::ShellBrowserContext;
using content::Shell;

namespace api {

IDMap<Base, IDMapOwnPointer> api::DispatcherHost::objects_registry_;
int api::DispatcherHost::next_object_id_ = 1;
static std::map<content::RenderViewHost*, DispatcherHost*> g_dispatcher_host_map;

DispatcherHost::DispatcherHost(content::RenderViewHost* render_view_host)
    : content::RenderViewHostObserver(render_view_host) {
  g_dispatcher_host_map[render_view_host] = this;
}

DispatcherHost::~DispatcherHost() {
  g_dispatcher_host_map.erase(render_view_host());
}

DispatcherHost*
FindDispatcherHost(content::RenderViewHost* render_view_host) {
  std::map<content::RenderViewHost*, DispatcherHost*>::iterator it
    = g_dispatcher_host_map.find(render_view_host);
  if (it == g_dispatcher_host_map.end())
    return NULL;
  return it->second;
}

Base* DispatcherHost::GetApiObject(int id) {
  return objects_registry_.Lookup(id);
}

int DispatcherHost::AllocateId() {
  return next_object_id_++;
}

void DispatcherHost::SendEvent(Base* object,
                               const std::string& event,
                               const base::ListValue& arguments) {
  Send(new ShellViewMsg_Object_On_Event(
       routing_id(), object->id(), event, arguments));
}

bool DispatcherHost::Send(IPC::Message* message) {
  return content::RenderViewHostObserver::Send(message);
}

bool DispatcherHost::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  base::ThreadRestrictions::ScopedAllowIO allow_io;
  base::ThreadRestrictions::ScopedAllowWait allow_wait;
  IPC_BEGIN_MESSAGE_MAP(DispatcherHost, message)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Allocate_Object, OnAllocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Deallocate_Object, OnDeallocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method, OnCallObjectMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method_Sync,
                        OnCallObjectMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method, OnCallStaticMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method_Sync,
                        OnCallStaticMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_UncaughtException,
                        OnUncaughtException);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GetShellId, OnGetShellId);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_CreateShell, OnCreateShell);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GrantUniversalPermissions, OnGrantUniversalPermissions);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_AllocateId, OnAllocateId);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void DispatcherHost::OnAllocateObject(int object_id,
                                      const std::string& type,
                                      const base::DictionaryValue& option) {
  DVLOG(1) << "OnAllocateObject: object_id:" << object_id
             << " type:" << type
             << " option:" << option;

  if (type == "Menu") {
    objects_registry_.AddWithID(new Menu(object_id, this, option), object_id);
  } else if (type == "MenuItem") {
    objects_registry_.AddWithID(
        new MenuItem(object_id, this, option), object_id);
  } else if (type == "Tray") {
    objects_registry_.AddWithID(new Tray(object_id, this, option), object_id);
  } else if (type == "Clipboard") {
    objects_registry_.AddWithID(
        new Clipboard(object_id, this, option), object_id);
  } else if (type == "Window") {
    objects_registry_.AddWithID(new Window(object_id, this, option), object_id);
  } else {
    LOG(ERROR) << "Allocate an object of unknown type: " << type;
    objects_registry_.AddWithID(new Base(object_id, this, option), object_id);
  }
}

void DispatcherHost::OnDeallocateObject(int object_id) {
  DLOG(INFO) << "OnDeallocateObject: object_id:" << object_id;
  objects_registry_.Remove(object_id);
}

void DispatcherHost::OnCallObjectMethod(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallObjectMethod: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  DLOG(WARNING) << "Unknown object: " << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;
  if (object)
    object->Call(method, arguments);
}

void DispatcherHost::OnCallObjectMethodSync(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallObjectMethodSync: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  LOG(WARNING) << "Unknown object: " << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;
  if (object)
    object->CallSync(method, arguments, result);
}

void DispatcherHost::OnCallStaticMethod(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallStaticMethod: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "Shell") {
    api::Shell::Call(method, arguments);
    return;
  } else if (type == "App") {
    api::App::Call(method, arguments);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnCallStaticMethodSync(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallStaticMethodSync: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "App") {
    content::Shell* shell =
        content::Shell::FromRenderViewHost(render_view_host());
    api::App::Call(shell, method, arguments, result);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnUncaughtException(const std::string& err) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  shell->PrintCriticalError("Uncaught node.js Error", err);
}

void DispatcherHost::OnGetShellId(int* id) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  *id = shell->id();
}

void DispatcherHost::OnCreateShell(const std::string& url,
                                   const base::DictionaryValue& manifest,
                                   int* routing_id) {
  WebContents* base_web_contents =
      content::Shell::FromRenderViewHost(render_view_host())->web_contents();
  ShellBrowserContext* browser_context =
      static_cast<ShellBrowserContext*>(base_web_contents->GetBrowserContext());
  scoped_ptr<base::DictionaryValue> new_manifest(manifest.DeepCopy());
  bool new_renderer = false;
  if (new_manifest->GetBoolean(switches::kmNewInstance,
                               &new_renderer) && new_renderer)
    browser_context->set_pinning_renderer(false);

  WebContents::CreateParams create_params(browser_context,
                                          new_renderer ? NULL : base_web_contents->GetSiteInstance());

  WebContents* web_contents = content::WebContentsImpl::CreateWithOpener(
      create_params,
      static_cast<content::WebContentsImpl*>(base_web_contents));
  content::Shell::Create(base_web_contents,
                         GURL(url),
                         new_manifest.get(),
                         web_contents);

  if (new_renderer)
    browser_context->set_pinning_renderer(true);

  *routing_id = web_contents->GetRoutingID();

  int object_id = 0;
  if (new_manifest->GetInteger("object_id", &object_id)) {
    DispatcherHost* dhost = FindDispatcherHost(web_contents->GetRenderViewHost());
    dhost->OnAllocateObject(object_id, "Window", *new_manifest.get());
  }
}

void DispatcherHost::OnGrantUniversalPermissions(int *ret) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  if (shell->nodejs()) {
    content::ChildProcessSecurityPolicy::GetInstance()->GrantUniversalAccess(shell->web_contents()->GetRenderProcessHost()->GetID());
    *ret = 1;
  }else
    *ret = 0;
}

void DispatcherHost::OnAllocateId(int * ret) {
  *ret = AllocateId();
}

}  // namespace api
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cx_idlco.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 18:58:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef LUIDL_CX_IDLCO_HXX
#define LUIDL_CX_IDLCO_HXX

// USED SERVICES
    // BASE CLASSES
#include <tokens/tkpcont2.hxx>
    // COMPONENTS
#include <tokens/tkpstam2.hxx>
    // PARAMETERS

namespace csi
{
namespace uidl
{

class Token_Receiver;
class Token;

/**
*/
class Context_UidlCode : public TkpContext,
                         private StateMachineContext
{
  public:
    //  LIFECYCLE
                        Context_UidlCode(
                            Token_Receiver &    o_rReceiver,
                            DYN TkpDocuContext &
                                                let_drContext_Docu  );
                        ~Context_UidlCode();
    //  OPERATORS

    //  OPERATIONS
    virtual void        ReadCharChain(
                            CharacterSource &   io_rText );
    virtual bool        PassNewToken();

    //  INQUIRY
    virtual TkpContext &
                        FollowUpContext();
  private:
    //  SERVICE FUNCTIONS
    void                PerformStatusFunction(
                            uintt               i_nStatusSignal,
                            UINT16              i_nTokenId,
                            CharacterSource &   io_rText );
    void                SetupStateMachine();

    //  DATA
    StateMachin2        aStateMachine;
    Token_Receiver *    pReceiver;

        // Contexts
    Dyn<TkpDocuContext> pDocuContext;

    Dyn<TkpContext>    dpContext_MLComment;
    Dyn<TkpContext>    dpContext_SLComment;
    Dyn<TkpContext>    dpContext_Preprocessor;
    Dyn<TkpContext>    dpContext_Assignment;

        // Temporary data, used during ReadCharChain()
    Dyn<Token>          pNewToken;
    ::TkpContext *      pFollowUpContext;
};

}   // namespace uidl
}   // namespace csi

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.3.80); FILE MERGED 2008/03/28 16:02:56 rt 1.3.80.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: cx_idlco.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef LUIDL_CX_IDLCO_HXX
#define LUIDL_CX_IDLCO_HXX

// USED SERVICES
    // BASE CLASSES
#include <tokens/tkpcont2.hxx>
    // COMPONENTS
#include <tokens/tkpstam2.hxx>
    // PARAMETERS

namespace csi
{
namespace uidl
{

class Token_Receiver;
class Token;

/**
*/
class Context_UidlCode : public TkpContext,
                         private StateMachineContext
{
  public:
    //  LIFECYCLE
                        Context_UidlCode(
                            Token_Receiver &    o_rReceiver,
                            DYN TkpDocuContext &
                                                let_drContext_Docu  );
                        ~Context_UidlCode();
    //  OPERATORS

    //  OPERATIONS
    virtual void        ReadCharChain(
                            CharacterSource &   io_rText );
    virtual bool        PassNewToken();

    //  INQUIRY
    virtual TkpContext &
                        FollowUpContext();
  private:
    //  SERVICE FUNCTIONS
    void                PerformStatusFunction(
                            uintt               i_nStatusSignal,
                            UINT16              i_nTokenId,
                            CharacterSource &   io_rText );
    void                SetupStateMachine();

    //  DATA
    StateMachin2        aStateMachine;
    Token_Receiver *    pReceiver;

        // Contexts
    Dyn<TkpDocuContext> pDocuContext;

    Dyn<TkpContext>    dpContext_MLComment;
    Dyn<TkpContext>    dpContext_SLComment;
    Dyn<TkpContext>    dpContext_Preprocessor;
    Dyn<TkpContext>    dpContext_Assignment;

        // Temporary data, used during ReadCharChain()
    Dyn<Token>          pNewToken;
    ::TkpContext *      pFollowUpContext;
};

}   // namespace uidl
}   // namespace csi

#endif
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2011 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <boost/filesystem/path.hpp>
namespace fs = boost::filesystem;

#include <vw/Image.h>
#include <vw/FileIO.h>
#include <vw/Cartography/GeoReference.h>

using namespace vw;

// Functors
template <class Arg1T, class Arg2T>
struct ReplaceChannelFunc: public ReturnFixedType<Arg1T> {
private:
  int m_channel;
public:
  ReplaceChannelFunc( int const& channel ) : m_channel(channel) {}

  inline Arg1T operator()( Arg1T const& arg1,
                           Arg2T const& arg2 ) const {
    Arg1T t( arg1 );
    t[m_channel] = arg2;
    return t;
  }
};

template <class Image1T, class Image2T>
inline BinaryPerPixelView<Image1T, Image2T, ReplaceChannelFunc<typename Image1T::pixel_type, typename Image2T::pixel_type> >
replace_channel( ImageViewBase<Image1T> const& image1,
                 int const& channel,
                 ImageViewBase<Image2T> const& image2 ) {
  typedef ReplaceChannelFunc<typename Image1T::pixel_type, typename Image2T::pixel_type> func_type;
  return BinaryPerPixelView<Image1T, Image2T, func_type >( image1.impl(), image2.impl(), func_type(channel));
}

// Standard Arguments
struct Options {
  std::string input_rgb, input_gray;
  std::string output_file;
};

// Image Operations
template <class ChannelT>
void do_merge(Options const& opt) {
  DiskImageView<PixelGray<ChannelT> > shaded_image( opt.input_gray );
  DiskImageView<PixelRGB<ChannelT> > rgb_image( opt.input_rgb );
  cartography::GeoReference georef;
  cartography::read_georeference(georef, opt.input_rgb);

  ImageViewRef<PixelRGB<ChannelT> > result = pixel_cast<PixelRGB<ChannelT> >(replace_channel(pixel_cast<PixelHSV<ChannelT> >(rgb_image),2,shaded_image));

  cartography::write_georeferenced_image( opt.output_file, result, georef,
                                          TerminalProgressCallback("tools.hsv_merge","Writing:") );
}

// Handle input
int main( int argc, char *argv[] ) {

  Options opt;

  po::options_description desc("Description: Mimicks hsv_merge.py by Frank Warmerdam and Trent Hare. Use it to combine results from gdaldem.");
  desc.add_options()
    ("input-rgb", po::value<std::string>(&opt.input_rgb), "Explicitly specify the input rgb image.")
    ("input-gray", po::value<std::string>(&opt.input_gray), "Explicitly specify the input gray image.")
    ("output-file,o", po::value<std::string>(&opt.output_file), "Specify the output file.")
    ("help,h", "Display this help message");
  po::positional_options_description p;
  p.add("input-rgb", 1 );
  p.add("input-gray", 1 );

  po::variables_map vm;
  try {
    po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
    po::notify( vm );
  } catch ( po::error const& e ) {
    std::cout << "An error occured while parsing command line arguments.\n";
    std::cout << "\t" << e.what() << "\n\n";
    std::cout << desc << std::endl;
    return 1;
  }

  if( vm.count("help") ||
      (opt.input_rgb == "" && opt.input_gray == "" ) ) {
    std::cout << desc << std::endl;
    return 1;
  }

  try {
    // Get the input RGB's type
    DiskImageResource *rsrc = DiskImageResource::open(opt.input_rgb);
    ChannelTypeEnum channel_type = rsrc->channel_type();
    delete rsrc;

    switch( channel_type ) {
    case VW_CHANNEL_UINT8: do_merge<uint8>( opt ); break;
    case VW_CHANNEL_INT16: do_merge<int16>( opt ); break;
    case VW_CHANNEL_UINT16: do_merge<uint16>( opt ); break;
    default: do_merge<float32>( opt );
    }

  } catch ( Exception const& e ) {
    std::cerr << "Error: " << e.what() << std::endl;
  }
  return 0;
}
<commit_msg>Have hsv_merge using check_command_line<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2011 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#include <asp/Core/Macros.h>
#include <asp/Core/Common.h>

#include <boost/program_options.hpp>
namespace po = boost::program_options;
#include <boost/filesystem/path.hpp>
namespace fs = boost::filesystem;

#include <vw/Image.h>
#include <vw/FileIO.h>
#include <vw/Cartography/GeoReference.h>

using namespace vw;

// Functors
template <class Arg1T, class Arg2T>
struct ReplaceChannelFunc: public ReturnFixedType<Arg1T> {
private:
  int m_channel;
public:
  ReplaceChannelFunc( int const& channel ) : m_channel(channel) {}

  inline Arg1T operator()( Arg1T const& arg1,
                           Arg2T const& arg2 ) const {
    Arg1T t( arg1 );
    t[m_channel] = arg2;
    return t;
  }
};

template <class Image1T, class Image2T>
inline BinaryPerPixelView<Image1T, Image2T, ReplaceChannelFunc<typename Image1T::pixel_type, typename Image2T::pixel_type> >
replace_channel( ImageViewBase<Image1T> const& image1,
                 int const& channel,
                 ImageViewBase<Image2T> const& image2 ) {
  typedef ReplaceChannelFunc<typename Image1T::pixel_type, typename Image2T::pixel_type> func_type;
  return BinaryPerPixelView<Image1T, Image2T, func_type >( image1.impl(), image2.impl(), func_type(channel));
}

// Standard Arguments
struct Options : public asp::BaseOptions {
  std::string input_rgb, input_gray;
  std::string output_file;
};

// Image Operations
template <class ChannelT>
void do_merge(Options const& opt) {
  DiskImageView<PixelGray<ChannelT> > shaded_image( opt.input_gray );
  DiskImageView<PixelRGB<ChannelT> > rgb_image( opt.input_rgb );
  cartography::GeoReference georef;
  cartography::read_georeference(georef, opt.input_rgb);

  ImageViewRef<PixelRGB<ChannelT> > result =
    pixel_cast<PixelRGB<ChannelT> >(replace_channel(pixel_cast<PixelHSV<ChannelT> >(rgb_image),2,shaded_image));

  block_write_gdal_image( opt.output_file, result, georef, opt,
                          TerminalProgressCallback("tools.hsv_merge","Writing:") );
}

// Handle input
int main( int argc, char *argv[] ) {

  Options opt;

  try {
    po::options_description desc("Description: Mimicks hsv_merge.py by Frank Warmerdam and Trent Hare. Use it to combine results from gdaldem.");
    desc.add_options()
      ("output-file,o", po::value(&opt.output_file), "Specify the output file.");
    desc.add( asp::BaseOptionsDescription(opt) );

    po::options_description hidden("");
    hidden.add_options()
      ("input-rgb", po::value(&opt.input_rgb), "Explicitly specify the input rgb image.")
      ("input-gray", po::value(&opt.input_gray), "Explicitly specify the input gray image.");

    po::positional_options_description p;
    p.add("input-rgb", 1 );
    p.add("input-gray", 1 );

    std::string usage("[options] <input rgb> <input gray>");
    po::variables_map vm =
      asp::check_command_line( argc, argv, opt, desc,
                               hidden, p, usage );

    if ( opt.input_rgb.empty() || opt.input_gray.empty() )
      vw_throw( ArgumentErr() << "Missing required input files.\n"
                << usage << desc );

    // Get the input RGB's type
    DiskImageResource *rsrc = DiskImageResource::open(opt.input_rgb);
    ChannelTypeEnum channel_type = rsrc->channel_type();
    delete rsrc;

    switch( channel_type ) {
    case VW_CHANNEL_UINT8: do_merge<uint8>( opt ); break;
    case VW_CHANNEL_INT16: do_merge<int16>( opt ); break;
    case VW_CHANNEL_UINT16: do_merge<uint16>( opt ); break;
    default: do_merge<float32>( opt );
    }

  } catch ( Exception const& e ) {
    std::cerr << "Error: " << e.what() << std::endl;
  }
  return 0;
}
<|endoftext|>


<commit_before>/// Le Plan:
/// 1. Proof of concept.
/// 2. ???
/// 3. PROFIT!

// blackhole/sink/asynchronous.hpp

#include <atomic>
#include <thread>

#include <cds/container/vyukov_mpmc_cycle_queue.h>

#include "blackhole/sink.hpp"

#include "blackhole/detail/recordbuf.hpp"

namespace blackhole {
inline namespace v1 {
namespace experimental {
namespace sink {

using detail::recordbuf_t;

class asynchronous_t : public sink_t {
    struct value_type {
        recordbuf_t record;
        std::string message;
    };

    typedef cds::container::VyukovMPSCCycleQueue<value_type> queue_type;

    queue_type queue;
    std::atomic<bool> running;
    std::unique_ptr<sink_t> wrapped;

    std::thread thread;

public:
    /// \param factor queue capacity factor from which the queue capacity will be generated as
    ///     a value of `2 << factor`. Must fit in [0; 20] range (64 MB).
    /// \param queue_type
    /// \param overflow_policy [drop silently, drop with error, block]
    ///
    /// \throw std::invalid_argument if the factor is greater than 20.
    asynchronous_t(std::unique_ptr<sink_t> wrapped, std::size_t factor = 10);

    ~asynchronous_t();

    auto emit(const record_t& record, const string_view& message) -> void;

private:
    auto run() -> void;
};

}  // namespace sink
}  // namespace experimental
}  // namespace v1
}  // namespace blackhole

// src/sink/asynchronous.cpp

#include <unistd.h>

#include <cmath>

namespace blackhole {
inline namespace v1 {
namespace experimental {
namespace sink {
namespace {

static auto exp2(std::size_t factor) -> std::size_t {
    if (factor > 20) {
        throw std::invalid_argument("factor should fit in [0; 20] range");
    }

    return std::exp2(factor);
}

}  // namespace

asynchronous_t::asynchronous_t(std::unique_ptr<sink_t> wrapped, std::size_t factor) :
    queue(exp2(factor)),
    running(true),
    wrapped(std::move(wrapped)),
    thread(std::bind(&asynchronous_t::run, this))
{}

asynchronous_t::~asynchronous_t() {
    running.store(false);
    thread.join();
}

auto asynchronous_t::emit(const record_t& record, const string_view& message) -> void {
    if (!running) {
        return;
    }

    const auto enqueued = queue.enqueue_with([&](value_type& value) {
        value = {recordbuf_t(record), message.to_string()};
    });

    // TODO: If failed, some kind of overflow policy is immediately involved.
}

auto asynchronous_t::run() -> void {
    while (true) {
        value_type result;
        const auto dequeued = queue.dequeue_with([&](value_type& value) {
            result = std::move(value);
        });

        // std::cout << std::boolalpha << dequeued << ":" << result.message << std::endl;
        if (dequeued) {
            // TODO: What to do with exceptions?
            wrapped->emit(result.record.into_view(), result.message);
        } else {
            // Sleep or CV.
            ::usleep(1000);
        }

        if (!(running || dequeued)) {
            return;
        }
    }
}

}  // namespace sink
}  // namespace experimental
}  // namespace v1
}  // namespace blackhole

// unit/sink/asynchronous.cpp

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "mocks/sink.hpp"

namespace blackhole {
inline namespace v1 {
namespace experimental {
namespace sink {
namespace {

using ::testing::_;

namespace mock = testing::mock;

TEST(asynchronous_t, DelegatesEmit) {
    std::unique_ptr<mock::sink_t> wrapped(new mock::sink_t);

    EXPECT_CALL(*wrapped, emit(_, string_view("formatted message")))
        .Times(1);

    asynchronous_t sink(std::move(wrapped));

    const string_view message("");
    const attribute_pack pack;
    record_t record(42, message, pack);

    sink.emit(record, "formatted message");
}

}  // namespace
}  // namespace sink
}  // namespace experimental
}  // namespace v1
}  // namespace blackhole
<commit_msg>feat(tests): extend asynchronous sink test<commit_after>/// Le Plan:
/// 1. Proof of concept.
/// 2. ???
/// 3. PROFIT!

// blackhole/sink/asynchronous.hpp

#include <atomic>
#include <thread>

#include <cds/container/vyukov_mpmc_cycle_queue.h>

#include "blackhole/sink.hpp"

#include "blackhole/detail/recordbuf.hpp"

namespace blackhole {
inline namespace v1 {
namespace experimental {
namespace sink {

using detail::recordbuf_t;

class asynchronous_t : public sink_t {
    struct value_type {
        recordbuf_t record;
        std::string message;
    };

    typedef cds::container::VyukovMPSCCycleQueue<value_type> queue_type;

    queue_type queue;
    std::atomic<bool> running;
    std::unique_ptr<sink_t> wrapped;

    std::thread thread;

public:
    /// \param factor queue capacity factor from which the queue capacity will be generated as
    ///     a value of `2 << factor`. Must fit in [0; 20] range (64 MB).
    /// \param queue_type
    /// \param overflow_policy [drop silently, drop with error, block]
    ///
    /// \throw std::invalid_argument if the factor is greater than 20.
    asynchronous_t(std::unique_ptr<sink_t> wrapped, std::size_t factor = 10);

    ~asynchronous_t();

    auto emit(const record_t& record, const string_view& message) -> void;

private:
    auto run() -> void;
};

}  // namespace sink
}  // namespace experimental
}  // namespace v1
}  // namespace blackhole

// src/sink/asynchronous.cpp

#include <unistd.h>

#include <cmath>

namespace blackhole {
inline namespace v1 {
namespace experimental {
namespace sink {
namespace {

static auto exp2(std::size_t factor) -> std::size_t {
    if (factor > 20) {
        throw std::invalid_argument("factor should fit in [0; 20] range");
    }

    return std::exp2(factor);
}

}  // namespace

asynchronous_t::asynchronous_t(std::unique_ptr<sink_t> wrapped, std::size_t factor) :
    queue(exp2(factor)),
    running(true),
    wrapped(std::move(wrapped)),
    thread(std::bind(&asynchronous_t::run, this))
{}

asynchronous_t::~asynchronous_t() {
    running.store(false);
    thread.join();
}

auto asynchronous_t::emit(const record_t& record, const string_view& message) -> void {
    if (!running) {
        return;
    }

    const auto enqueued = queue.enqueue_with([&](value_type& value) {
        value = {recordbuf_t(record), message.to_string()};
    });

    // TODO: If failed, some kind of overflow policy is immediately involved.
}

auto asynchronous_t::run() -> void {
    while (true) {
        value_type result;
        const auto dequeued = queue.dequeue_with([&](value_type& value) {
            result = std::move(value);
        });

        // std::cout << std::boolalpha << dequeued << ":" << result.message << std::endl;
        if (dequeued) {
            // TODO: What to do with exceptions?
            wrapped->emit(result.record.into_view(), result.message);
        } else {
            // Sleep or CV.
            ::usleep(1000);
        }

        if (!(running || dequeued)) {
            return;
        }
    }
}

}  // namespace sink
}  // namespace experimental
}  // namespace v1
}  // namespace blackhole

// unit/sink/asynchronous.cpp

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "mocks/sink.hpp"

namespace blackhole {
inline namespace v1 {
namespace experimental {
namespace sink {
namespace {

using ::testing::_;
using ::testing::Invoke;

namespace mock = testing::mock;

TEST(asynchronous_t, DelegatesEmit) {
    std::unique_ptr<mock::sink_t> wrapped(new mock::sink_t);

    EXPECT_CALL(*wrapped, emit(_, string_view("formatted message")))
        .Times(1)
        .WillOnce(Invoke([](const record_t& record, string_view) {
            ASSERT_EQ(1, record.attributes().size());
            EXPECT_EQ((attribute_list{{"key#1", {"value#1"}}}), record.attributes().at(0).get());
        }));

    asynchronous_t sink(std::move(wrapped));

    const string_view message("unformatted message");
    const attribute_list attributes{{"key#1", {"value#1"}}};
    const attribute_pack pack({attributes});
    record_t record(42, message, pack);

    sink.emit(record, "formatted message");
}

}  // namespace
}  // namespace sink
}  // namespace experimental
}  // namespace v1
}  // namespace blackhole
<|endoftext|>


<commit_before>#ident "Copyright (c) 2012-2013 Tokutek Inc.  All rights reserved."
#ident "$Id$"

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "backup_test_helpers.h"

static char *src;
static char *dst;

int test_main(int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) {
    src = get_src();
    dst = get_dst();
    setup_source();
    setup_destination();
    setup_dirs();
    pthread_t thread;
    const int N = 2;
    char fname[N][1000];
    int fds[N];
    unsigned char buf[1024];
    for (size_t i=0; i<sizeof(buf); i++) buf[i]=i%256;
    for (int i=0; i<N; i++) {
        {
            int r = snprintf(fname[i], sizeof(fname[i]), "%s/f%d", src, i);
            printf("r=%d fname[%d]=%s\n", r, i, fname[i]);
            check(r<(int)sizeof(fname[i]));
        }
        fds[i] = open(fname[i], O_WRONLY|O_CREAT, 0777);
        check(fds[i]>=0);
        for (int j=0; j<1024; j++) {
            ssize_t r = write(fds[i], buf, sizeof(buf));
            check(r==sizeof(buf));
        }
    }
    tokubackup_throttle_backup(1L<<19); // half a mebibyte per second, so that's 2 seconds.
    start_backup_thread(&thread);
    for (int i=0; i<N; i++) {
        int r = unlink(fname[i]);
        check(r==0);
    }
    finish_backup_thread(thread);
    for (int i=0; i<N; i++) {
        int r = close(fds[i]);
        check(r==0);
    }
    {
        int status = systemf("diff -r %s %s", src, dst);
        check(status!=-1);
        check(WIFEXITED(status));
        check(WEXITSTATUS(status)==0);
    }
    free(src);
    free(dst);
    return 0;
}
<commit_msg>Refs #6515.  Slight cleanup of test.<commit_after>#ident "Copyright (c) 2012-2013 Tokutek Inc.  All rights reserved."
#ident "$Id$"

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "backup_test_helpers.h"

int test_main(int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) {
    char *src = get_src();
    char *dst = get_dst();
    setup_source();
    setup_destination();
    setup_dirs();
    pthread_t thread;
    const int N = 2;
    char fname[N][1000];
    int fds[N];
    unsigned char buf[1024];
    for (size_t i=0; i<sizeof(buf); i++) buf[i]=i%256;
    for (int i=0; i<N; i++) {
        {
            int r = snprintf(fname[i], sizeof(fname[i]), "%s/f%d", src, i);
            printf("r=%d fname[%d]=%s\n", r, i, fname[i]);
            check(r<(int)sizeof(fname[i]));
        }
        fds[i] = open(fname[i], O_WRONLY|O_CREAT, 0777);
        check(fds[i]>=0);
        for (int j=0; j<1024; j++) {
            ssize_t r = write(fds[i], buf, sizeof(buf));
            check(r==sizeof(buf));
        }
    }
    tokubackup_throttle_backup(1L<<19); // half a mebibyte per second, so that's 2 seconds.
    start_backup_thread(&thread);
    for (int i=0; i<N; i++) {
        int r = unlink(fname[i]);
        check(r==0);
    }
    finish_backup_thread(thread);
    for (int i=0; i<N; i++) {
        int r = close(fds[i]);
        check(r==0);
    }
    {
        int status = systemf("diff -r %s %s", src, dst);
        check(status!=-1);
        check(WIFEXITED(status));
        check(WEXITSTATUS(status)==0);
    }
    free(src);
    free(dst);
    return 0;
}
<|endoftext|>


<commit_before>/*
 * zsummerX License
 * -----------
 *
 * zsummerX is licensed under the terms of the MIT license reproduced below.
 * This means that zsummerX is free software and can be used for both academic
 * and commercial purposes at absolutely no cost.
 *
 *
 * ===============================================================================
 *
 * Copyright (C) 2010-2014 YaweiZhang <yawei_zhang@foxmail.com>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * ===============================================================================
 *
 * (end of COPYRIGHT)
 */

#include <zsummerX/zsummer.h>
#include <zsummerX/tcpaccept.h>
#include <zsummerX/tcpsocket.h>
#include <zsummerX/udpsocket.h>

#include <iostream>
#include <queue>
#include <chrono>
#include <iomanip>
#include <string.h>
#include <signal.h>
#include <log4z/log4z.h>
#include <proto4z/proto4z.h>
using namespace std;
using namespace zsummer::log4z;
using namespace zsummer::network;

std::string g_remoteIP = "0.0.0.0";
unsigned short g_remotePort = 81;
unsigned short g_startType = 0;  //0 listen, 1 connect
bool g_runing = true;
bool g_safeexit = true;
CZSummerPtr summer;
CTcpAcceptPtr accepter;
CTcpSocketPtr ts;
CTcpSocketPtr usedSocket;
int maxAcceptCount = 1;
int curAcceptCount = 0;
char recvBuffer[1024]; //recv buffer
int recvBufferLen = 1024;
char sendBuffer[1024]; //send buffer
int sendBufferLen = 1024;

void Close()
{
	if (usedSocket)
	{
		usedSocket->DoClose();
	}
	g_runing = false;
}
void signalFun(int sig)
{
	if (summer)
	{
		summer->Post(&Close);
	}
}

void OnSocektSend(ErrorCode ec, int recvLength)
{
	if (ec)
	{
		curAcceptCount = 0;
		return;
	}
	if (recvLength != sendBufferLen)
	{
		LOGW("safe warning, need translate remaining data.");
		return; //warning; ignore the warning because this a simple test.
	}
	return;
};

void OnServerSocektRecv(ErrorCode ec, int recvLength)
{
	if (ec != EC_SUCCESS)
	{
		curAcceptCount = 0;
		g_safeexit = true;
		return;
	}
	LOGI("recv client msg len = " << recvLength << ", msg :" << recvBuffer);
	memcpy(sendBuffer, recvBuffer, recvLength);
	sendBufferLen = recvLength;
	bool ret = usedSocket->DoSend(sendBuffer, sendBufferLen, OnSocektSend);// safe-warning: can't call this methon again before receive last DoSend callback.
	if (!ret)
	{
		g_safeexit = true;
		curAcceptCount = 0;
		return;
	}
	ret = usedSocket->DoRecv(recvBuffer, recvBufferLen, OnServerSocektRecv);
	if (!ret)
	{
		g_safeexit = true;
		curAcceptCount = 0;
		return;
	}
};

void OnAcceptSocket(ErrorCode ec, CTcpSocketPtr s)
{
	if (ec != EC_SUCCESS)
	{
		return;
	}
	if (curAcceptCount >= maxAcceptCount)
	{
		LOGW("max client limit is " << maxAcceptCount << ", curCount is" << curAcceptCount);
		return;
	}
	g_safeexit = false;
	curAcceptCount++;
	usedSocket = s;
	usedSocket->Initialize(summer);
	usedSocket->DoRecv(recvBuffer, recvBufferLen, OnServerSocektRecv);
	ts = std::shared_ptr<CTcpSocket>(new CTcpSocket);
	accepter->DoAccept(ts, OnAcceptSocket);

};

void SendOneMsg()
{
	if (usedSocket && summer && g_runing && !g_safeexit)
	{
		sprintf(sendBuffer, "%s", "hellow");
		sendBufferLen = strlen(sendBuffer) + 1;
		// safe-warning: can't call this methon again before receive last DoSend callback.
		usedSocket->DoSend(sendBuffer, sendBufferLen, OnSocektSend);
	}
}
void OnClientSocektRecv(ErrorCode ec, int recvLength)
{
	if (ec != EC_SUCCESS)
	{
		g_runing = false;
		g_safeexit = true;
		curAcceptCount = 0;
		return;
	}
	LOGI("recv server msg len = " << recvLength << ", msg :" << recvBuffer);
	summer->CreateTimer(1000, SendOneMsg);
	bool ret = usedSocket->DoRecv(recvBuffer, recvBufferLen, OnClientSocektRecv);
	if (!ret) { g_safeexit = true; return; };
};

void OnConnect(ErrorCode ec)
{
	if (ec != EC_SUCCESS)
	{
		LOGE("connect error");
		return;
	}
	g_safeexit = false;
	usedSocket->DoRecv(recvBuffer, recvBufferLen, OnClientSocektRecv);
	summer->CreateTimer(1000, SendOneMsg);
};

int main(int argc, char* argv[])
{
	signal(SIGINT, signalFun);
	if (argc == 2 &&
		(strcmp(argv[1], "--help") == 0
		|| strcmp(argv[1], "/?") == 0))
	{
		cout << "please input like example:" << endl;
		cout << "tcpTest remoteIP remotePort startType" << endl;
		cout << "./tcpTest 0.0.0.0 81 0" << endl;
		cout << "startType: 0 server, 1 client" << endl;
		return 0;
	}
	if (argc > 1)
	{
		g_remoteIP = argv[1];
	}
	if (argc > 2)
	{
		g_remotePort = atoi(argv[2]);
	}
	if (argc > 3)
	{
		g_startType = atoi(argv[3]);
	}

	if (g_startType == 0)
	{
		//! 启动日志服务
		ILog4zManager::GetInstance()->Config("server.cfg");
		ILog4zManager::GetInstance()->Start();
	}
	else
	{
				//! 启动日志服务
		ILog4zManager::GetInstance()->Config("client.cfg");
		ILog4zManager::GetInstance()->Start();
	}

	LOGI("g_remoteIP=" << g_remoteIP << ", g_remotePort=" << g_remotePort << ", g_startType=" << g_startType );

	//! 启动调度器
	summer = std::shared_ptr<CZSummer>(new CZSummer);
	summer->Initialize();

	if (g_startType == 0)
	{
		accepter = std::shared_ptr<CTcpAccept>(new CTcpAccept(summer));
		ts = std::shared_ptr<CTcpSocket>(new CTcpSocket);
		if (!accepter->OpenAccept(g_remoteIP.c_str(), g_remotePort))
		{
			return 0;
		}

		accepter->DoAccept(ts, OnAcceptSocket);
	}
	else
	{
		usedSocket = std::shared_ptr<CTcpSocket>(new CTcpSocket);
		usedSocket->Initialize(summer);
		usedSocket->DoConnect(g_remoteIP.c_str(), g_remotePort, OnConnect);
	}

	while (g_runing || !g_safeexit)
	{
		summer->RunOnce();
	}
	//warning: be safe close :  1.all socket call close. 2. all socket receive recv callback. 3 stop runonce and safe exit.
	//current test will  output some safety warning with error log because the test not safe exit. but no problem.

	return 0;
}

<commit_msg>comments<commit_after>/*
 * zsummerX License
 * -----------
 *
 * zsummerX is licensed under the terms of the MIT license reproduced below.
 * This means that zsummerX is free software and can be used for both academic
 * and commercial purposes at absolutely no cost.
 *
 *
 * ===============================================================================
 *
 * Copyright (C) 2010-2014 YaweiZhang <yawei_zhang@foxmail.com>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * ===============================================================================
 *
 * (end of COPYRIGHT)
 */

#include <zsummerX/zsummer.h>
#include <zsummerX/tcpaccept.h>
#include <zsummerX/tcpsocket.h>
#include <zsummerX/udpsocket.h>

#include <iostream>
#include <queue>
#include <chrono>
#include <iomanip>
#include <string.h>
#include <signal.h>
#include <log4z/log4z.h>
#include <proto4z/proto4z.h>
using namespace std;
using namespace zsummer::log4z;
using namespace zsummer::network;

std::string g_remoteIP = "0.0.0.0";
unsigned short g_remotePort = 81;
unsigned short g_startType = 0;  //0 listen, 1 connect
bool g_runing = true;
bool g_safeexit = true;
CZSummerPtr summer;
CTcpAcceptPtr accepter;
CTcpSocketPtr ts;
CTcpSocketPtr usedSocket;
int maxAcceptCount = 1;
int curAcceptCount = 0;
char recvBuffer[1024]; //recv buffer
int recvBufferLen = 1024;
char sendBuffer[1024]; //send buffer
int sendBufferLen = 1024;

void Close()
{
	if (usedSocket)
	{
		usedSocket->DoClose();
	}
	g_runing = false;
}
void signalFun(int sig)
{
	if (summer)
	{
		summer->Post(&Close);
	}
}

void OnSocektSend(ErrorCode ec, int recvLength)
{
	if (ec)
	{
		curAcceptCount = 0;
		return;
	}
	if (recvLength != sendBufferLen)
	{
		LOGW("safe warning, need translate remaining data.");
		return; //warning; ignore the warning because this a simple test.
	}
	return;
};

void OnServerSocektRecv(ErrorCode ec, int recvLength)
{
	if (ec != EC_SUCCESS)
	{
		curAcceptCount = 0;
		g_safeexit = true;
		return;
	}
	LOGI("recv client msg len = " << recvLength << ", msg :" << recvBuffer);
	memcpy(sendBuffer, recvBuffer, recvLength);
	sendBufferLen = recvLength;
	bool ret = usedSocket->DoSend(sendBuffer, sendBufferLen, OnSocektSend);// safe-warning: can't call this method again when last DoSend request not return.
	if (!ret)
	{
		g_safeexit = true;
		curAcceptCount = 0;
		return;
	}
	ret = usedSocket->DoRecv(recvBuffer, recvBufferLen, OnServerSocektRecv);
	if (!ret)
	{
		g_safeexit = true;
		curAcceptCount = 0;
		return;
	}
};

void OnAcceptSocket(ErrorCode ec, CTcpSocketPtr s)
{
	if (ec != EC_SUCCESS)
	{
		return;
	}
	if (curAcceptCount >= maxAcceptCount)
	{
		LOGW("max client limit is " << maxAcceptCount << ", curCount is" << curAcceptCount);
		return;
	}
	g_safeexit = false;
	curAcceptCount++;
	usedSocket = s;
	usedSocket->Initialize(summer);
	usedSocket->DoRecv(recvBuffer, recvBufferLen, OnServerSocektRecv);
	ts = std::shared_ptr<CTcpSocket>(new CTcpSocket);
	accepter->DoAccept(ts, OnAcceptSocket);

};

void SendOneMsg()
{
	if (usedSocket && summer && g_runing && !g_safeexit)
	{
		sprintf(sendBuffer, "%s", "hellow");
		sendBufferLen = strlen(sendBuffer) + 1;
		// safe-warning: can't call this method again when last DoSend request not return.
		usedSocket->DoSend(sendBuffer, sendBufferLen, OnSocektSend);
	}
}
void OnClientSocektRecv(ErrorCode ec, int recvLength)
{
	if (ec != EC_SUCCESS)
	{
		g_runing = false;
		g_safeexit = true;
		curAcceptCount = 0;
		return;
	}
	LOGI("recv server msg len = " << recvLength << ", msg :" << recvBuffer);
	summer->CreateTimer(1000, SendOneMsg);
	bool ret = usedSocket->DoRecv(recvBuffer, recvBufferLen, OnClientSocektRecv);
	if (!ret) { g_safeexit = true; return; };
};

void OnConnect(ErrorCode ec)
{
	if (ec != EC_SUCCESS)
	{
		LOGE("connect error");
		return;
	}
	g_safeexit = false;
	usedSocket->DoRecv(recvBuffer, recvBufferLen, OnClientSocektRecv);
	summer->CreateTimer(1000, SendOneMsg);
};

int main(int argc, char* argv[])
{
	signal(SIGINT, signalFun);
	if (argc == 2 &&
		(strcmp(argv[1], "--help") == 0
		|| strcmp(argv[1], "/?") == 0))
	{
		cout << "please input like example:" << endl;
		cout << "tcpTest remoteIP remotePort startType" << endl;
		cout << "./tcpTest 0.0.0.0 81 0" << endl;
		cout << "startType: 0 server, 1 client" << endl;
		return 0;
	}
	if (argc > 1)
	{
		g_remoteIP = argv[1];
	}
	if (argc > 2)
	{
		g_remotePort = atoi(argv[2]);
	}
	if (argc > 3)
	{
		g_startType = atoi(argv[3]);
	}

	if (g_startType == 0)
	{
		ILog4zManager::GetInstance()->Config("server.cfg");
		ILog4zManager::GetInstance()->Start();
	}
	else
	{
		ILog4zManager::GetInstance()->Config("client.cfg");
		ILog4zManager::GetInstance()->Start();
	}

	LOGI("g_remoteIP=" << g_remoteIP << ", g_remotePort=" << g_remotePort << ", g_startType=" << g_startType );

	summer = std::shared_ptr<CZSummer>(new CZSummer);
	summer->Initialize();

	if (g_startType == 0)
	{
		accepter = std::shared_ptr<CTcpAccept>(new CTcpAccept(summer));
		ts = std::shared_ptr<CTcpSocket>(new CTcpSocket);
		if (!accepter->OpenAccept(g_remoteIP.c_str(), g_remotePort))
		{
			return 0;
		}

		accepter->DoAccept(ts, OnAcceptSocket);
	}
	else
	{
		usedSocket = std::shared_ptr<CTcpSocket>(new CTcpSocket);
		usedSocket->Initialize(summer);
		usedSocket->DoConnect(g_remoteIP.c_str(), g_remotePort, OnConnect);
	}

	while (g_runing || !g_safeexit)
	{
		summer->RunOnce();
	}
	//warning: be safe close need:  1.close all established socket. 2. wait all socket recv callback. 3 stop runonce and safe exit.
	//current test will  output some safety warning with error log because the test not safe exit. but no problem.

	return 0;
}

<|endoftext|>