<commit_before>
// Copyright 2020 John Hanley.
//
// 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.

#include <chrono>
#include <iostream>
using namespace std;

void bench_cout(const uint n) {
    cout << "cout!" << endl;
}

void bench_printf(const uint n) {
    cout << "printf!" << endl;
}

void usage() {
    cerr << "usage:" << endl;
    cerr << "  Specify --cout or --printf" << endl;
    exit(1);
}
void usage1(const uint n) {
    usage();
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        usage();
    }
    void (*fn)(const uint) = usage1;
    string opt = argv[1];
    if (opt == "--cout") {
        fn = bench_cout;
    } else if (opt == "--printf") {
        fn = bench_printf;
    } else {
        usage();
    }
    chrono::steady_clock::time_point t0 = chrono::steady_clock::now();

    fn(10);

    float elapsed = chrono::duration_cast<chrono::milliseconds>(
         chrono::steady_clock::now() - t0).count() / 1e3;
    cerr << elapsed << " seconds" << endl;
}
<commit_msg>Add bench loops<commit_after>
// Copyright 2020 John Hanley.
//
// 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.

#include <chrono>
#include <iostream>
using namespace std;

#define VAL 100

void bench_cout(const uint n) {  // 10x slower than printf
    for (uint i = 0; i < n; i++) {
        cout << VAL << " " << VAL << " " << VAL << " " << endl;
    }
}

void bench_printf(const uint n) {
    for (uint i = 0; i < n; i++) {
        printf("%u %u %u\n", VAL, VAL, VAL);
    }
}

void usage() {
    cerr << "usage:" << endl;
    cerr << "  Specify --cout or --printf" << endl;
    exit(1);
}
void usage1(const uint n) {
    usage();
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        usage();
    }
    void (*fn)(const uint) = usage1;
    string opt = argv[1];
    if (opt == "--cout") {
        fn = bench_cout;
    } else if (opt == "--printf") {
        fn = bench_printf;
    } else {
        usage();
    }
    chrono::steady_clock::time_point t0 = chrono::steady_clock::now();

    fn(1e6);

    float elapsed = chrono::duration_cast<chrono::milliseconds>(
         chrono::steady_clock::now() - t0).count() / 1e3;
    cerr << elapsed << " seconds for " << opt << endl;
}
<|endoftext|>


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

#define BOOST_TEST_MODULE Bitcoin Test Suite

#include "test_bitcoin.h"

#include "chainparams.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
#include "fs.h"
#include "crypto/sha256.h"
#include "key.h"
#include "main.h"
#include "miner.h"
#include "parallel.h"
#include "pubkey.h"
#include "random.h"
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
#include "rpc/server.h"
#include "rpc/register.h"
#include "test/testutil.h"

#include <boost/test/unit_test.hpp>

#include <memory>

#include <boost/thread.hpp>

CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h

extern bool fPrintToConsole;
extern void noui_connect();

BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
{
        SHA256AutoDetect();
        ECC_Start();
        SetupEnvironment();
        SetupNetworking();
        fPrintToDebugLog = false; // don't want to write to debug.log file
        fCheckBlockIndex = true;
        SelectParams(chainName);
        noui_connect();
}

BasicTestingSetup::~BasicTestingSetup()
{
        ECC_Stop();
}

TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
    const CChainParams& chainparams = Params();
        // Ideally we'd move all the RPC tests to the functional testing framework
        // instead of unit tests, but for now we need these here.
        RegisterAllCoreRPCCommands(tableRPC);
        ClearDatadirCache();
        pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
        fs::create_directories(pathTemp);
        pblocktree = new CBlockTreeDB(1 << 20, true);
        pcoinsdbview = new CCoinsViewDB(1 << 23, true);
        pcoinsTip = new CCoinsViewCache(pcoinsdbview);
        bool worked = InitBlockIndex(chainparams);
        assert(worked);

        PV.reset(new CParallelValidation(3, &threadGroup));
        RegisterNodeSignals(GetNodeSignals());
}

TestingSetup::~TestingSetup()
{
        UnregisterNodeSignals(GetNodeSignals());
        threadGroup.interrupt_all();
        threadGroup.join_all();
        UnloadBlockIndex();
        delete pcoinsTip;
        delete pcoinsdbview;
        delete pblocktree;
        fs::remove_all(pathTemp);
}

TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST)
{
    // Generate a 100-block chain:
    coinbaseKey.MakeNewKey(true);
    CScript scriptPubKey = CScript() <<  ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
    for (int i = 0; i < COINBASE_MATURITY; i++)
    {
        std::vector<CMutableTransaction> noTxns;
        CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey);
        coinbaseTxns.push_back(b.vtx[0]);
    }
}

//
// Create a new block with just given transactions, coinbase paying to
// scriptPubKey, and try to add it to the current chain.
//
CBlock
TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey)
{
    const CChainParams& chainparams = Params();
    CBlockTemplate *pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
    CBlock& block = pblocktemplate->block;

    // Replace mempool-selected txns with just coinbase plus passed-in txns:
    block.vtx.resize(1);
    BOOST_FOREACH(const CMutableTransaction& tx, txns)
        block.vtx.push_back(tx);
    // IncrementExtraNonce creates a valid coinbase and merkleRoot
    unsigned int extraNonce = 0;
    IncrementExtraNonce(&block, extraNonce);

    while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;

    CValidationState state;
    ProcessNewBlock(state, chainparams, NULL, &block, true, NULL, false);

    CBlock result = block;
    delete pblocktemplate;
    return result;
}

TestChain100Setup::~TestChain100Setup()
{
}

CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) {
    CTransaction txn(tx);
    bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies;
    // Hack to assume either its completely dependent on other mempool txs or not at all
    CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;

    return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
                           hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount, lp);
}

void Shutdown(void* parg)
{
  exit(0);
}

void StartShutdown()
{
  exit(0);
}

bool ShutdownRequested()
{
  return false;
}

struct SetupCleanup {
    SetupCleanup()   { std::cout << "setup\n"; }
    ~SetupCleanup()
    {
        std::cout << "teardown\n";
        UnlimitedCleanup();
    }
};

BOOST_GLOBAL_FIXTURE(SetupCleanup);
<commit_msg>trigger travis rerun<commit_after>// Copyright (c) 2011-2015 The Bitcoin Core developers
// Copyright (c) 2015-2017 The Bitcoin Unlimited developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#define BOOST_TEST_MODULE Bitcoin Test Suite

#include "test_bitcoin.h"

#include "chainparams.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
#include "fs.h"
#include "crypto/sha256.h"
#include "key.h"
#include "main.h"
#include "miner.h"
#include "parallel.h"
#include "pubkey.h"
#include "random.h"
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
#include "rpc/server.h"
#include "rpc/register.h"
#include "test/testutil.h"

#include <boost/test/unit_test.hpp>

#include <memory>

#include <boost/thread.hpp>

CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h

extern bool fPrintToConsole;
extern void noui_connect();

BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
{
        SHA256AutoDetect();
        ECC_Start();
        SetupEnvironment();
        SetupNetworking();
        fPrintToDebugLog = false; // don't want to write to debug.log file
        fCheckBlockIndex = true;
        SelectParams(chainName);
        noui_connect();
}

BasicTestingSetup::~BasicTestingSetup()
{
        ECC_Stop();
}

TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
    const CChainParams& chainparams = Params();
        // Ideally we'd move all the RPC tests to the functional testing framework
        // instead of unit tests, but for now we need these here.
        RegisterAllCoreRPCCommands(tableRPC);
        ClearDatadirCache();
        pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
        fs::create_directories(pathTemp);
        pblocktree = new CBlockTreeDB(1 << 20, true);
        pcoinsdbview = new CCoinsViewDB(1 << 23, true);
        pcoinsTip = new CCoinsViewCache(pcoinsdbview);
        bool worked = InitBlockIndex(chainparams);
        assert(worked);

        PV.reset(new CParallelValidation(3, &threadGroup));
        RegisterNodeSignals(GetNodeSignals());
}

TestingSetup::~TestingSetup()
{
        UnregisterNodeSignals(GetNodeSignals());
        threadGroup.interrupt_all();
        threadGroup.join_all();
        UnloadBlockIndex();
        delete pcoinsTip;
        delete pcoinsdbview;
        delete pblocktree;
        fs::remove_all(pathTemp);
}

TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST)
{
    // Generate a 100-block chain:
    coinbaseKey.MakeNewKey(true);
    CScript scriptPubKey = CScript() <<  ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
    for (int i = 0; i < COINBASE_MATURITY; i++)
    {
        std::vector<CMutableTransaction> noTxns;
        CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey);
        coinbaseTxns.push_back(b.vtx[0]);
    }
}

//
// Create a new block with just given transactions, coinbase paying to
// scriptPubKey, and try to add it to the current chain.
//
CBlock
TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey)
{
    const CChainParams& chainparams = Params();
    CBlockTemplate *pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
    CBlock& block = pblocktemplate->block;

    // Replace mempool-selected txns with just coinbase plus passed-in txns:
    block.vtx.resize(1);
    BOOST_FOREACH(const CMutableTransaction& tx, txns)
        block.vtx.push_back(tx);
    // IncrementExtraNonce creates a valid coinbase and merkleRoot
    unsigned int extraNonce = 0;
    IncrementExtraNonce(&block, extraNonce);

    while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;

    CValidationState state;
    ProcessNewBlock(state, chainparams, NULL, &block, true, NULL, false);

    CBlock result = block;
    delete pblocktemplate;
    return result;
}

TestChain100Setup::~TestChain100Setup()
{
}

CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) {
    CTransaction txn(tx);
    bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies;
    // Hack to assume either its completely dependent on other mempool txs or not at all
    CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;

    return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
                           hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount, lp);
}

void Shutdown(void* parg)
{
  exit(0);
}

void StartShutdown()
{
  exit(0);
}

bool ShutdownRequested()
{
  return false;
}

struct SetupCleanup
{
    SetupCleanup()   { std::cout << "setup\n"; }
    ~SetupCleanup()
    {
        std::cout << "teardown\n";
        UnlimitedCleanup();
    }
};

BOOST_GLOBAL_FIXTURE(SetupCleanup);
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "mesh_resource_marker.h"

#include "marker_selection_handler.h"
#include "rviz/default_plugin/marker_display.h"
#include "rviz/selection/selection_manager.h"

#include "rviz/display_context.h"
#include "rviz/mesh_loader.h"
#include "marker_display.h"

#include <OGRE/OgreSceneNode.h>
#include <OGRE/OgreSceneManager.h>
#include <OGRE/OgreEntity.h>
#include <OGRE/OgreSubEntity.h>
#include <OGRE/OgreMaterialManager.h>
#include <OGRE/OgreTextureManager.h>

namespace rviz
{

MeshResourceMarker::MeshResourceMarker(MarkerDisplay* owner, DisplayContext* context, Ogre::SceneNode* parent_node)
: MarkerBase(owner, context, parent_node)
, entity_(0)
{
}

MeshResourceMarker::~MeshResourceMarker()
{
  reset();
}

void MeshResourceMarker::reset()
{
  //destroy entity
  if (entity_)
  {
    context_->getSceneManager()->destroyEntity( entity_ );
    entity_ = 0;
  }

  // destroy all the materials we've created
  S_MaterialPtr::iterator it;
  for ( it = materials_.begin(); it!=materials_.end(); it++ )
  {
    Ogre::MaterialPtr material = *it;
    if (!material.isNull())
    {
      material->unload();
      Ogre::MaterialManager::getSingleton().remove(material->getName());
    }
  }
  materials_.clear();
}

void MeshResourceMarker::onNewMessage(const MarkerConstPtr& old_message, const MarkerConstPtr& new_message)
{
  ROS_ASSERT(new_message->type == visualization_msgs::Marker::MESH_RESOURCE);

  bool need_color = false;

  scene_node_->setVisible(false);

  if( !entity_ ||
      old_message->mesh_resource != new_message->mesh_resource ||
      old_message->mesh_use_embedded_materials != new_message->mesh_use_embedded_materials )
  {
    reset();

    if (new_message->mesh_resource.empty())
    {
      return;
    }

    if (loadMeshFromResource(new_message->mesh_resource).isNull())
    {
      std::stringstream ss;
      ss << "Mesh resource marker [" << getStringID() << "] could not load [" << new_message->mesh_resource << "]";
      if ( owner_ )
      {
        owner_->setMarkerStatus(getID(), StatusProperty::Error, ss.str());
      }
      ROS_DEBUG("%s", ss.str().c_str());
      return;
    }

    static uint32_t count = 0;
    std::stringstream ss;
    ss << "mesh_resource_marker_" << count++;
    std::string id = ss.str();
    entity_ = context_->getSceneManager()->createEntity(id, new_message->mesh_resource);
    scene_node_->attachObject(entity_);
    need_color = true;

    // create a default material for any sub-entities which don't have their own.
    ss << "Material";
    Ogre::MaterialPtr default_material = Ogre::MaterialManager::getSingleton().create( ss.str(), ROS_PACKAGE_NAME );
    default_material->setReceiveShadows(false);
    default_material->getTechnique(0)->setLightingEnabled(true);
    default_material->getTechnique(0)->setAmbient( 0.5, 0.5, 0.5 );
    materials_.insert( default_material );

    if ( new_message->mesh_use_embedded_materials )
    {
      // make clones of all embedded materials so selection works correctly
      S_MaterialPtr materials = getMaterials();

      S_MaterialPtr::iterator it;
      for ( it = materials.begin(); it!=materials.end(); it++ )
      {
        if( (*it)->getName() != "BaseWhiteNoLighting" )
        {
          Ogre::MaterialPtr new_material = (*it)->clone( id + (*it)->getName() );
          materials_.insert( new_material );
        }
      }

      // make sub-entities use cloned materials
      for (uint32_t i = 0; i < entity_->getNumSubEntities(); ++i)
      {
        std::string mat_name = entity_->getSubEntity(i)->getMaterialName();
        if( mat_name != "BaseWhiteNoLighting" )
        {
          entity_->getSubEntity(i)->setMaterialName( id + mat_name );
        }
        else
        {
          // BaseWhiteNoLighting is the default material Ogre uses
          // when it sees a mesh with no material.  Here we replace
          // that with our default_material which gets colored with
          // new_message->color.
          entity_->getSubEntity(i)->setMaterial( default_material );
        }
      }
    }
    else
    {
      entity_->setMaterial( default_material );
    }

    handler_.reset( new MarkerSelectionHandler( this, MarkerID( new_message->ns, new_message->id ), context_ ));
    handler_->addTrackedObject( entity_ );
  }

  if( need_color ||
      old_message->color.r != new_message->color.r ||
      old_message->color.g != new_message->color.g ||
      old_message->color.b != new_message->color.b ||
      old_message->color.a != new_message->color.a )
  {
    float r = new_message->color.r;
    float g = new_message->color.g;
    float b = new_message->color.b;
    float a = new_message->color.a;

    // Old way was to ignore the color and alpha when using embedded
    // materials, which meant you could leave them unset, which means
    // 0.  Since we now USE the color and alpha values, leaving them
    // all 0 will mean the object will be invisible.  Therefore detect
    // the situation where RGBA are all 0 and treat that the same as
    // all 1 (full white).
    if( new_message->mesh_use_embedded_materials && r == 0 && g == 0 && b == 0 && a == 0 )
    {
      r = 1; g = 1; b = 1; a = 1;
    }

    Ogre::SceneBlendType blending;
    bool depth_write;

    if ( a < 0.9998 )
    {
      blending = Ogre::SBT_TRANSPARENT_ALPHA;
      depth_write = false;
    }
    else
    {
      blending = Ogre::SBT_REPLACE;
      depth_write = true;
    }

    S_MaterialPtr::iterator it;
    for( it = materials_.begin(); it != materials_.end(); it++ )
    {
      Ogre::Technique* technique = (*it)->getTechnique( 0 );

      technique->setAmbient( r*0.5, g*0.5, b*0.5 );
      technique->setDiffuse( r, g, b, a );
      technique->setSceneBlending( blending );
      technique->setDepthWriteEnabled( depth_write );
      technique->setLightingEnabled( !depth_write );
    }
  }

  Ogre::Vector3 pos, scale;
  Ogre::Quaternion orient;
  transform(new_message, pos, orient, scale);

  scene_node_->setVisible(true);
  setPosition(pos);
  setOrientation(orient);

  // In Ogre, mesh surface normals are not normalized if object is not
  // scaled.  This forces the surface normals to be renormalized by
  // invisibly tweaking the scale.
  if( scale.x == 1.0 && scale.y == 1.0 && scale.z == 1.0 )
  {
    scale.z = 1.0001;
  }
  scene_node_->setScale(scale);
}

S_MaterialPtr MeshResourceMarker::getMaterials()
{
  S_MaterialPtr materials;
  if( entity_ )
  {
    extractMaterials( entity_, materials );
  }
  return materials;
}

}

<commit_msg>[bugfix] Always enable lighting, otherwise mesh coloring doesn't work when alpha=1<commit_after>/*
 * Copyright (c) 2010, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "mesh_resource_marker.h"

#include "marker_selection_handler.h"
#include "rviz/default_plugin/marker_display.h"
#include "rviz/selection/selection_manager.h"

#include "rviz/display_context.h"
#include "rviz/mesh_loader.h"
#include "marker_display.h"

#include <OGRE/OgreSceneNode.h>
#include <OGRE/OgreSceneManager.h>
#include <OGRE/OgreEntity.h>
#include <OGRE/OgreSubEntity.h>
#include <OGRE/OgreMaterialManager.h>
#include <OGRE/OgreTextureManager.h>

namespace rviz
{

MeshResourceMarker::MeshResourceMarker(MarkerDisplay* owner, DisplayContext* context, Ogre::SceneNode* parent_node)
: MarkerBase(owner, context, parent_node)
, entity_(0)
{
}

MeshResourceMarker::~MeshResourceMarker()
{
  reset();
}

void MeshResourceMarker::reset()
{
  //destroy entity
  if (entity_)
  {
    context_->getSceneManager()->destroyEntity( entity_ );
    entity_ = 0;
  }

  // destroy all the materials we've created
  S_MaterialPtr::iterator it;
  for ( it = materials_.begin(); it!=materials_.end(); it++ )
  {
    Ogre::MaterialPtr material = *it;
    if (!material.isNull())
    {
      material->unload();
      Ogre::MaterialManager::getSingleton().remove(material->getName());
    }
  }
  materials_.clear();
}

void MeshResourceMarker::onNewMessage(const MarkerConstPtr& old_message, const MarkerConstPtr& new_message)
{
  ROS_ASSERT(new_message->type == visualization_msgs::Marker::MESH_RESOURCE);

  bool need_color = false;

  scene_node_->setVisible(false);

  if( !entity_ ||
      old_message->mesh_resource != new_message->mesh_resource ||
      old_message->mesh_use_embedded_materials != new_message->mesh_use_embedded_materials )
  {
    reset();

    if (new_message->mesh_resource.empty())
    {
      return;
    }

    if (loadMeshFromResource(new_message->mesh_resource).isNull())
    {
      std::stringstream ss;
      ss << "Mesh resource marker [" << getStringID() << "] could not load [" << new_message->mesh_resource << "]";
      if ( owner_ )
      {
        owner_->setMarkerStatus(getID(), StatusProperty::Error, ss.str());
      }
      ROS_DEBUG("%s", ss.str().c_str());
      return;
    }

    static uint32_t count = 0;
    std::stringstream ss;
    ss << "mesh_resource_marker_" << count++;
    std::string id = ss.str();
    entity_ = context_->getSceneManager()->createEntity(id, new_message->mesh_resource);
    scene_node_->attachObject(entity_);
    need_color = true;

    // create a default material for any sub-entities which don't have their own.
    ss << "Material";
    Ogre::MaterialPtr default_material = Ogre::MaterialManager::getSingleton().create( ss.str(), ROS_PACKAGE_NAME );
    default_material->setReceiveShadows(false);
    default_material->getTechnique(0)->setLightingEnabled(true);
    default_material->getTechnique(0)->setAmbient( 0.5, 0.5, 0.5 );
    materials_.insert( default_material );

    if ( new_message->mesh_use_embedded_materials )
    {
      // make clones of all embedded materials so selection works correctly
      S_MaterialPtr materials = getMaterials();

      S_MaterialPtr::iterator it;
      for ( it = materials.begin(); it!=materials.end(); it++ )
      {
        if( (*it)->getName() != "BaseWhiteNoLighting" )
        {
          Ogre::MaterialPtr new_material = (*it)->clone( id + (*it)->getName() );
          materials_.insert( new_material );
        }
      }

      // make sub-entities use cloned materials
      for (uint32_t i = 0; i < entity_->getNumSubEntities(); ++i)
      {
        std::string mat_name = entity_->getSubEntity(i)->getMaterialName();
        if( mat_name != "BaseWhiteNoLighting" )
        {
          entity_->getSubEntity(i)->setMaterialName( id + mat_name );
        }
        else
        {
          // BaseWhiteNoLighting is the default material Ogre uses
          // when it sees a mesh with no material.  Here we replace
          // that with our default_material which gets colored with
          // new_message->color.
          entity_->getSubEntity(i)->setMaterial( default_material );
        }
      }
    }
    else
    {
      entity_->setMaterial( default_material );
    }

    handler_.reset( new MarkerSelectionHandler( this, MarkerID( new_message->ns, new_message->id ), context_ ));
    handler_->addTrackedObject( entity_ );
  }

  if( need_color ||
      old_message->color.r != new_message->color.r ||
      old_message->color.g != new_message->color.g ||
      old_message->color.b != new_message->color.b ||
      old_message->color.a != new_message->color.a )
  {
    float r = new_message->color.r;
    float g = new_message->color.g;
    float b = new_message->color.b;
    float a = new_message->color.a;

    // Old way was to ignore the color and alpha when using embedded
    // materials, which meant you could leave them unset, which means
    // 0.  Since we now USE the color and alpha values, leaving them
    // all 0 will mean the object will be invisible.  Therefore detect
    // the situation where RGBA are all 0 and treat that the same as
    // all 1 (full white).
    if( new_message->mesh_use_embedded_materials && r == 0 && g == 0 && b == 0 && a == 0 )
    {
      r = 1; g = 1; b = 1; a = 1;
    }

    Ogre::SceneBlendType blending;
    bool depth_write;

    if ( a < 0.9998 )
    {
      blending = Ogre::SBT_TRANSPARENT_ALPHA;
      depth_write = false;
    }
    else
    {
      blending = Ogre::SBT_REPLACE;
      depth_write = true;
    }

    S_MaterialPtr::iterator it;
    for( it = materials_.begin(); it != materials_.end(); it++ )
    {
      Ogre::Technique* technique = (*it)->getTechnique( 0 );

      technique->setAmbient( r*0.5, g*0.5, b*0.5 );
      technique->setDiffuse( r, g, b, a );
      technique->setSceneBlending( blending );
      technique->setDepthWriteEnabled( depth_write );
      technique->setLightingEnabled( true );
    }
  }

  Ogre::Vector3 pos, scale;
  Ogre::Quaternion orient;
  transform(new_message, pos, orient, scale);

  scene_node_->setVisible(true);
  setPosition(pos);
  setOrientation(orient);

  // In Ogre, mesh surface normals are not normalized if object is not
  // scaled.  This forces the surface normals to be renormalized by
  // invisibly tweaking the scale.
  if( scale.x == 1.0 && scale.y == 1.0 && scale.z == 1.0 )
  {
    scale.z = 1.0001;
  }
  scene_node_->setScale(scale);
}

S_MaterialPtr MeshResourceMarker::getMaterials()
{
  S_MaterialPtr materials;
  if( entity_ )
  {
    extractMaterials( entity_, materials );
  }
  return materials;
}

}

<|endoftext|>


<commit_before>#include <map>

#include <ros/ros.h>
#include <control_msgs/FollowJointTrajectoryAction.h>
#include <actionlib/server/simple_action_server.h>
#include <std_msgs/Float32.h>

typedef actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> Server;

std::map<std::string, ros::Publisher> g_gripper_servo_angle_pub;

void execute(const control_msgs::FollowJointTrajectoryGoalConstPtr& goal, Server* as_, std::string side)
{
  bool success = true;
  std::string node_name(ros::this_node::getName());

  ROS_INFO("%s: Executing requested joint trajectory for %s gripper", node_name.c_str(), side.c_str());

  for (int i = 0; i < goal->trajectory.points.size(); i++)
  {
    if (as_->isPreemptRequested())
    {
      ROS_INFO("%s: Preempted for %s gripper", node_name.c_str(), side.c_str());
      as_->setPreempted();
      success = false;
      break;
    }

    if (!ros::ok())
    {
      ROS_INFO("%s: Aborted for %s gripper", node_name.c_str(), side.c_str());
      as_->setAborted();
      return;
    }

    float rad = goal->trajectory.points[i].positions[0];
    std_msgs::Float32 angle_msg;
    angle_msg.data = rad;
    g_gripper_servo_angle_pub[side].publish(angle_msg);

    control_msgs::FollowJointTrajectoryFeedback feedback_;

    feedback_.joint_names.push_back(goal->trajectory.joint_names[0]);
    feedback_.desired.positions.resize(1);
    feedback_.actual.positions.resize(1);
    feedback_.error.positions.resize(1);

    feedback_.desired.positions[0] = rad;
    feedback_.actual.positions[0] = rad;
    feedback_.error.positions[0] = 0;

    ros::Duration wait =
        (goal->trajectory.header.stamp + goal->trajectory.points[i].time_from_start) - ros::Time::now();
    if (wait > ros::Duration(0))
      wait.sleep();
    feedback_.header.stamp = ros::Time::now();
    as_->publishFeedback(feedback_);
  }

  control_msgs::FollowJointTrajectoryResult result_;
  if (success)
  {
    ROS_INFO("%s: Succeeded for %s gripper", node_name.c_str(), side.c_str());
    result_.error_code = result_.SUCCESSFUL;
    as_->setSucceeded(result_);
  }
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "gripper_joint_trajectory_action_server");
  ros::NodeHandle n;
  g_gripper_servo_angle_pub["right"] = n.advertise<std_msgs::Float32>("gripper_front/limb/right/servo/angle", 10);
  Server server(n, "gripper_front/limb/right/follow_joint_trajectory", boost::bind(&execute, _1, &server, "right"),
                false);
  server.start();
  ros::spin();
  return 0;
}
<commit_msg>Publish feedbacks continuously among command points<commit_after>#include <map>

#include <ros/ros.h>
#include <control_msgs/FollowJointTrajectoryAction.h>
#include <actionlib/server/simple_action_server.h>
#include <std_msgs/Float32.h>

typedef actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> Server;

std::map<std::string, ros::Publisher> g_gripper_servo_angle_pub;

void execute(const control_msgs::FollowJointTrajectoryGoalConstPtr& goal, Server* as_, std::string side)
{
  bool success = true;
  std::string node_name(ros::this_node::getName());

  ROS_INFO("%s: Executing requested joint trajectory for %s gripper", node_name.c_str(), side.c_str());

  for (int i = 0; i < goal->trajectory.points.size(); i++)
  {
    if (as_->isPreemptRequested())
    {
      ROS_INFO("%s: Preempted for %s gripper", node_name.c_str(), side.c_str());
      as_->setPreempted();
      success = false;
      break;
    }

    if (!ros::ok())
    {
      ROS_INFO("%s: Aborted for %s gripper", node_name.c_str(), side.c_str());
      as_->setAborted();
      return;
    }

    float rad = goal->trajectory.points[i].positions[0];
    std_msgs::Float32 angle_msg;
    angle_msg.data = rad;
    g_gripper_servo_angle_pub[side].publish(angle_msg);

    // Publish feedbacks until next point
    ros::Rate feedback_rate(100);
    do
    {
      feedback_rate.sleep();

      control_msgs::FollowJointTrajectoryFeedback feedback_;

      feedback_.joint_names.push_back(goal->trajectory.joint_names[0]);
      feedback_.desired.positions.resize(1);
      feedback_.actual.positions.resize(1);
      feedback_.error.positions.resize(1);

      feedback_.desired.positions[0] = rad;
      feedback_.actual.positions[0] = rad;
      feedback_.error.positions[0] = 0;

      feedback_.header.stamp = ros::Time::now();
      as_->publishFeedback(feedback_);
    } while (ros::ok() && i < (goal->trajectory.points.size() - 1) &&
             ros::Time::now() < (goal->trajectory.header.stamp + goal->trajectory.points[i + 1].time_from_start));
  }

  control_msgs::FollowJointTrajectoryResult result_;
  if (success)
  {
    ROS_INFO("%s: Succeeded for %s gripper", node_name.c_str(), side.c_str());
    result_.error_code = result_.SUCCESSFUL;
    as_->setSucceeded(result_);
  }
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "gripper_joint_trajectory_action_server");
  ros::NodeHandle n;
  g_gripper_servo_angle_pub["right"] = n.advertise<std_msgs::Float32>("gripper_front/limb/right/servo/angle", 10);
  Server server(n, "gripper_front/limb/right/follow_joint_trajectory", boost::bind(&execute, _1, &server, "right"),
                false);
  server.start();
  ros::spin();
  return 0;
}
<|endoftext|>


<commit_before>/*
* (C) 2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "test_runner.h"
#include "tests.h"

#include <botan/version.h>
#include <botan/rotate.h>
#include <botan/loadstor.h>

namespace Botan_Tests {

Test_Runner::Test_Runner(std::ostream& out) : m_output(out) {}

namespace {

/*
* This is a fast, simple, deterministic PRNG that's used for running
* the tests. It is not intended to be cryptographically secure.
*/
class Testsuite_RNG final : public Botan::RandomNumberGenerator
   {
   public:
      std::string name() const override { return "Testsuite_RNG"; }

      void clear() override
         {
         m_a = m_b = m_c = m_d = 0;
         }

      void add_entropy(const uint8_t data[], size_t len) override
         {
         for(size_t i = 0; i != len; ++i)
            {
            m_a ^= data[i];
            m_b ^= i;
            mix();
            }
         }

      bool is_seeded() const override
         {
         return true;
         }

      void randomize(uint8_t out[], size_t len) override
         {
         for(size_t i = 0; i != len; ++i)
            {
            out[i] = static_cast<uint8_t>(m_a);
            mix();
            }
         }

      Testsuite_RNG(const std::vector<uint8_t>& seed, size_t test_counter = 0)
         {
         m_d = static_cast<uint32_t>(test_counter);

         add_entropy(seed.data(), seed.size());
         }
   private:
      void mix()
         {
         const size_t ROUNDS = 3;

         for(size_t i = 0; i != ROUNDS; ++i)
            {
            m_a += i;

            m_a = Botan::rotl<9>(m_a);
            m_b ^= m_a;
            m_d ^= m_c;

            m_a += m_d;
            m_c += m_b;
            m_c = Botan::rotl<23>(m_c);
            }
         }

      uint32_t m_a = 0, m_b = 0, m_c = 0, m_d = 0;
   };

}

int Test_Runner::run(const std::vector<std::string>& requested_tests,
                     const std::string& data_dir,
                     const std::string& pkcs11_lib,
                     const std::string& provider,
                     bool log_success,
                     bool run_online_tests,
                     bool run_long_tests,
                     const std::string& drbg_seed,
                     size_t runs)
   {
   std::vector<std::string> req = requested_tests;

   if(req.empty())
      {
      /*
      If nothing was requested on the command line, run everything. First
      run the "essentials" to smoke test, then everything else in
      alphabetical order.
      */
      req = {"block", "stream", "hash", "mac", "modes", "aead",
             "kdf", "pbkdf", "hmac_drbg", "util"
      };

      std::set<std::string> all_others = Botan_Tests::Test::registered_tests();

      if(pkcs11_lib.empty())
         {
         // do not run pkcs11 tests by default unless pkcs11-lib set
         for(std::set<std::string>::iterator iter = all_others.begin(); iter != all_others.end();)
            {
            if((*iter).find("pkcs11") != std::string::npos)
               {
               iter = all_others.erase(iter);
               }
            else
               {
               ++iter;
               }
            }
         }

      for(auto f : req)
         {
         all_others.erase(f);
         }

      req.insert(req.end(), all_others.begin(), all_others.end());
      }
   else if(req.size() == 1 && req.at(0) == "pkcs11")
      {
      req = {"pkcs11-manage", "pkcs11-module", "pkcs11-slot", "pkcs11-session", "pkcs11-object", "pkcs11-rsa",
             "pkcs11-ecdsa", "pkcs11-ecdh", "pkcs11-rng", "pkcs11-x509"
      };
      }
   else
      {
      std::set<std::string> all = Botan_Tests::Test::registered_tests();
      for(auto const& r : req)
         {
         if(all.find(r) == all.end())
            {
            throw Botan_Tests::Test_Error("Unknown test suite: " + r);
            }
         }
      }

   output() << "Testing " << Botan::version_string() << "\n";
   output() << "Starting tests";

   if(!pkcs11_lib.empty())
      {
      output() << " pkcs11 library:" << pkcs11_lib;
      }

   Botan_Tests::Provider_Filter pf;
   if(!provider.empty())
      {
      output() << " provider:" << provider;
      pf.set(provider);
      }

   std::vector<uint8_t> seed = Botan::hex_decode(drbg_seed);
   if(seed.empty())
      {
      const uint64_t ts = Botan_Tests::Test::timestamp();
      seed.resize(8);
      Botan::store_be(ts, seed.data());
      }

   output() << " drbg_seed:" << Botan::hex_encode(seed) << "\n";

   Botan_Tests::Test::set_test_options(log_success,
                                       run_online_tests,
                                       run_long_tests,
                                       data_dir,
                                       pkcs11_lib,
                                       pf);

   for(size_t i = 0; i != runs; ++i)
      {
      std::unique_ptr<Botan::RandomNumberGenerator> rng =
         std::unique_ptr<Botan::RandomNumberGenerator>(new Testsuite_RNG(seed, i));

      Botan_Tests::Test::set_test_rng(std::move(rng));

      const size_t failed = run_tests(req, i, runs);
      if(failed > 0)
         return failed;
      }

   return 0;
   }

namespace {

std::string report_out(const std::vector<Botan_Tests::Test::Result>& results,
                       size_t& tests_failed,
                       size_t& tests_ran)
   {
   std::ostringstream out;

   std::map<std::string, Botan_Tests::Test::Result> combined;
   for(auto const& result : results)
      {
      const std::string who = result.who();
      auto i = combined.find(who);
      if(i == combined.end())
         {
         combined.insert(std::make_pair(who, Botan_Tests::Test::Result(who)));
         i = combined.find(who);
         }

      i->second.merge(result);
      }

   for(auto const& result : combined)
      {
      const bool verbose = false;
      out << result.second.result_string(verbose);
      tests_failed += result.second.tests_failed();
      tests_ran += result.second.tests_run();
      }

   return out.str();
   }

}

size_t Test_Runner::run_tests(const std::vector<std::string>& tests_to_run,
                              size_t test_run,
                              size_t tot_test_runs)
   {
   size_t tests_ran = 0, tests_failed = 0;

   const uint64_t start_time = Botan_Tests::Test::timestamp();

   for(auto const& test_name : tests_to_run)
      {
      output() << test_name << ':' << std::endl;

      std::vector<Test::Result> results;

      try
         {
         if(Test* test = Test::get_test(test_name))
            {
            std::vector<Test::Result> test_results = test->run();
            results.insert(results.end(), test_results.begin(), test_results.end());
            }
         else
            {
            results.push_back(Test::Result::Note(test_name, "Test missing or unavailable"));
            }
         }
      catch(std::exception& e)
         {
         results.push_back(Test::Result::Failure(test_name, e.what()));
         }
      catch(...)
         {
         results.push_back(Test::Result::Failure(test_name, "unknown exception"));
         }

      output() << report_out(results, tests_failed, tests_ran) << std::flush;
      }

   const uint64_t total_ns = Botan_Tests::Test::timestamp() - start_time;

   if(test_run == 0 && tot_test_runs == 1)
      output() << "Tests";
   else
      output() << "Test run " << (1+test_run) << "/" << tot_test_runs;

   output() << " complete ran " << tests_ran << " tests in "
            << Botan_Tests::Test::format_time(total_ns) << " ";

   if(tests_failed > 0)
      {
      output() << tests_failed << " tests failed";
      }
   else if(tests_ran > 0)
      {
      output() << "all tests ok";
      }

   output() << std::endl;

   return tests_failed;
   }

}

<commit_msg>Avoid calling run() on SIMD tests if SIMD instructions not available.<commit_after>/*
* (C) 2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "test_runner.h"
#include "tests.h"

#include <botan/version.h>
#include <botan/rotate.h>
#include <botan/loadstor.h>
#include <botan/cpuid.h>

namespace Botan_Tests {

Test_Runner::Test_Runner(std::ostream& out) : m_output(out) {}

namespace {

/*
* This is a fast, simple, deterministic PRNG that's used for running
* the tests. It is not intended to be cryptographically secure.
*/
class Testsuite_RNG final : public Botan::RandomNumberGenerator
   {
   public:
      std::string name() const override { return "Testsuite_RNG"; }

      void clear() override
         {
         m_a = m_b = m_c = m_d = 0;
         }

      void add_entropy(const uint8_t data[], size_t len) override
         {
         for(size_t i = 0; i != len; ++i)
            {
            m_a ^= data[i];
            m_b ^= i;
            mix();
            }
         }

      bool is_seeded() const override
         {
         return true;
         }

      void randomize(uint8_t out[], size_t len) override
         {
         for(size_t i = 0; i != len; ++i)
            {
            out[i] = static_cast<uint8_t>(m_a);
            mix();
            }
         }

      Testsuite_RNG(const std::vector<uint8_t>& seed, size_t test_counter = 0)
         {
         m_d = static_cast<uint32_t>(test_counter);

         add_entropy(seed.data(), seed.size());
         }
   private:
      void mix()
         {
         const size_t ROUNDS = 3;

         for(size_t i = 0; i != ROUNDS; ++i)
            {
            m_a += i;

            m_a = Botan::rotl<9>(m_a);
            m_b ^= m_a;
            m_d ^= m_c;

            m_a += m_d;
            m_c += m_b;
            m_c = Botan::rotl<23>(m_c);
            }
         }

      uint32_t m_a = 0, m_b = 0, m_c = 0, m_d = 0;
   };

}

int Test_Runner::run(const std::vector<std::string>& requested_tests,
                     const std::string& data_dir,
                     const std::string& pkcs11_lib,
                     const std::string& provider,
                     bool log_success,
                     bool run_online_tests,
                     bool run_long_tests,
                     const std::string& drbg_seed,
                     size_t runs)
   {
   std::vector<std::string> req = requested_tests;

   if(req.empty())
      {
      /*
      If nothing was requested on the command line, run everything. First
      run the "essentials" to smoke test, then everything else in
      alphabetical order.
      */
      req = {"block", "stream", "hash", "mac", "modes", "aead",
             "kdf", "pbkdf", "hmac_drbg", "util"
      };

      std::set<std::string> all_others = Botan_Tests::Test::registered_tests();

      if(pkcs11_lib.empty())
         {
         // do not run pkcs11 tests by default unless pkcs11-lib set
         for(std::set<std::string>::iterator iter = all_others.begin(); iter != all_others.end();)
            {
            if((*iter).find("pkcs11") != std::string::npos)
               {
               iter = all_others.erase(iter);
               }
            else
               {
               ++iter;
               }
            }
         }

      for(auto f : req)
         {
         all_others.erase(f);
         }

      req.insert(req.end(), all_others.begin(), all_others.end());
      }
   else if(req.size() == 1 && req.at(0) == "pkcs11")
      {
      req = {"pkcs11-manage", "pkcs11-module", "pkcs11-slot", "pkcs11-session", "pkcs11-object", "pkcs11-rsa",
             "pkcs11-ecdsa", "pkcs11-ecdh", "pkcs11-rng", "pkcs11-x509"
      };
      }
   else
      {
      std::set<std::string> all = Botan_Tests::Test::registered_tests();
      for(auto const& r : req)
         {
         if(all.find(r) == all.end())
            {
            throw Botan_Tests::Test_Error("Unknown test suite: " + r);
            }
         }
      }

   output() << "Testing " << Botan::version_string() << "\n";
   output() << "Starting tests";

   if(!pkcs11_lib.empty())
      {
      output() << " pkcs11 library:" << pkcs11_lib;
      }

   Botan_Tests::Provider_Filter pf;
   if(!provider.empty())
      {
      output() << " provider:" << provider;
      pf.set(provider);
      }

   std::vector<uint8_t> seed = Botan::hex_decode(drbg_seed);
   if(seed.empty())
      {
      const uint64_t ts = Botan_Tests::Test::timestamp();
      seed.resize(8);
      Botan::store_be(ts, seed.data());
      }

   output() << " drbg_seed:" << Botan::hex_encode(seed) << "\n";

   Botan_Tests::Test::set_test_options(log_success,
                                       run_online_tests,
                                       run_long_tests,
                                       data_dir,
                                       pkcs11_lib,
                                       pf);

   for(size_t i = 0; i != runs; ++i)
      {
      std::unique_ptr<Botan::RandomNumberGenerator> rng =
         std::unique_ptr<Botan::RandomNumberGenerator>(new Testsuite_RNG(seed, i));

      Botan_Tests::Test::set_test_rng(std::move(rng));

      const size_t failed = run_tests(req, i, runs);
      if(failed > 0)
         return failed;
      }

   return 0;
   }

namespace {

std::string report_out(const std::vector<Botan_Tests::Test::Result>& results,
                       size_t& tests_failed,
                       size_t& tests_ran)
   {
   std::ostringstream out;

   std::map<std::string, Botan_Tests::Test::Result> combined;
   for(auto const& result : results)
      {
      const std::string who = result.who();
      auto i = combined.find(who);
      if(i == combined.end())
         {
         combined.insert(std::make_pair(who, Botan_Tests::Test::Result(who)));
         i = combined.find(who);
         }

      i->second.merge(result);
      }

   for(auto const& result : combined)
      {
      const bool verbose = false;
      out << result.second.result_string(verbose);
      tests_failed += result.second.tests_failed();
      tests_ran += result.second.tests_run();
      }

   return out.str();
   }

}

size_t Test_Runner::run_tests(const std::vector<std::string>& tests_to_run,
                              size_t test_run,
                              size_t tot_test_runs)
   {
   size_t tests_ran = 0, tests_failed = 0;

   const uint64_t start_time = Botan_Tests::Test::timestamp();

   for(auto const& test_name : tests_to_run)
      {
      output() << test_name << ':' << std::endl;

      std::vector<Test::Result> results;

      try
         {
         if(test_name == "simd_32" && Botan::CPUID::has_simd_32() == false)
            {
            results.push_back(Test::Result::Note(test_name, "SIMD not available on this platform"));
            }
         else if(Test* test = Test::get_test(test_name))
            {
            std::vector<Test::Result> test_results = test->run();
            results.insert(results.end(), test_results.begin(), test_results.end());
            }
         else
            {
            results.push_back(Test::Result::Note(test_name, "Test missing or unavailable"));
            }
         }
      catch(std::exception& e)
         {
         results.push_back(Test::Result::Failure(test_name, e.what()));
         }
      catch(...)
         {
         results.push_back(Test::Result::Failure(test_name, "unknown exception"));
         }

      output() << report_out(results, tests_failed, tests_ran) << std::flush;
      }

   const uint64_t total_ns = Botan_Tests::Test::timestamp() - start_time;

   if(test_run == 0 && tot_test_runs == 1)
      output() << "Tests";
   else
      output() << "Test run " << (1+test_run) << "/" << tot_test_runs;

   output() << " complete ran " << tests_ran << " tests in "
            << Botan_Tests::Test::format_time(total_ns) << " ";

   if(tests_failed > 0)
      {
      output() << tests_failed << " tests failed";
      }
   else if(tests_ran > 0)
      {
      output() << "all tests ok";
      }

   output() << std::endl;

   return tests_failed;
   }

}

<|endoftext|>


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

#include <iostream>
#include <fstream>
#include <boost/format.hpp>
#include <votca/csg/csgapplication.h>

using namespace votca::csg;
using namespace std;
using boost::format;

/**
    \brief class for writing dlpoly topology files

    This class encapsulates the dlpoly topology writing functions

*/

class DLPTopolApp
    : public CsgApplication
{
public:
    string ProgramName() { return "csg_dlptopol"; }
    void HelpText(ostream &out) {
        out << "Create a dlpoly topology template based on an existing (atomistic) topology and \n"
	    << "a mapping xml-file. The conventional file extensions of other simulation engines, \n"
            << "e.g. Gromacs, are recognized in the input (option --top), whereas <name>.dlpf must \n"
            << "be used for DL_POLY topology files. By convention, <name> can be omitted, in which \n"
            << "case '.dlpf' implies 'using standard naming': FIELD as input or FIELD_CGV as output. \n"
	    << "- NOTE: the created template file needs to be inspected and amended by the user!\n\n"
	    << "Examples:\n"
	    << "* csg_dlptopol --top .dlpf --out .dlpf --cg cg-map.xml\n  - convert FIELD to FIELD_CGV using cg-map.xml\n"
	    << "* csg_dlptopol --top FA-dlpoly.dlpf --out CG-dlpoly.dlpf --cg cg-map.xml\n  - convert FA-dlpoly.dlpf to CG-dlpoly.dlpf\n"
	    << "* csg_dlptopol --top FA-gromacs.tpr --out FA-dlpoly.dlpf --no-map\n  - convert FA-gromacs.tpr to FA-dlpoly.dlpf";
    }

    bool DoMapping(void) { return true; }

    void Initialize(void);
    bool EvaluateOptions(void) {
        CsgApplication::EvaluateOptions();
        CheckRequired("out", "no output topology specified");
        return true;
    }
    bool EvaluateTopology(Topology *top, Topology *top_ref);

protected:
    void WriteMoleculeAtoms(ostream &out, Molecule &cg);
    void WriteMoleculeInteractions(ostream &out, Molecule &cg);
    void WriteVDWInteractions(ostream &out, Molecule &cg);
    void WriteMolecularType(ostream &out, Molecule &cg, int nummol);
};

void DLPTopolApp::Initialize(void)
{
    CsgApplication::Initialize();
    //AddProgramOptions()
    //("top", boost::program_options::value<string>(),
    //"  input topology in any known format:\n  <name>.dlpf for dlpoly, <name>.tpr for gromacs\n  (convention: '.dlpf'='use FIELD')");
    AddProgramOptions()
      ("out", boost::program_options::value<string>(),
       "  output topology in dlpoly format; examples:\n"
       "  - <name>.dlpf, .dlpf (convention: '.dlpf'='use FIELD_CGV')");
}

bool DLPTopolApp::EvaluateTopology(Topology *top, Topology *top_ref)
{
  // check the file names from options

  string fname=OptionsMap()["top"].as<string>();

  if( fname == ".dlpf" ) {
    fname = "FIELD";
  }

  cout << "input  file-name: " << fname << endl;

  fname=OptionsMap()["out"].as<string>();

#ifdef DEBUG
  cout << "output file-name given: " << fname << endl;
#endif

  if( fname == ".dlpf" ) {
    fname = "FIELD_CGV";
  }

#ifdef DEBUG
  cout << "output file-name actual: " << fname << endl;
#else
  cout << "output file-name: " << fname << endl;
#endif

  // do CG mapping

  MoleculeContainer &mols = top->Molecules();
  MoleculeContainer MolecularTypes;
  MoleculeContainer::iterator iter;

  int prv_mol_number = 1;
  string prv_mol_name;
  vector<int> nummols;

  vector<string> vdw_pairs;

  // find all unique molecular types

  for(iter=mols.begin(); iter!=mols.end(); ++iter) {
    Molecule *mol = *iter;

    // molecules are ignored during the mapping stage
    // i.e. the ignored ones do not enter the CG topology (*top) - ?
    //if( IsIgnored(mol->getName()) ) continue;

    if( mol->getName()==prv_mol_name ) {
      prv_mol_number++;
      continue;
    }

    nummols.push_back(prv_mol_number);
    prv_mol_number = 1;
    prv_mol_name   = mol->getName();

    //#ifdef DEBUG
    cout << "'" << mol->getName() << "' added to CG molecular types" << endl;
    //#endif

    MolecularTypes.push_back(mol);

    // collect unique bead pairs over all molecular types found

    for(int ib1=0; ib1<mol->BeadCount(); ib1++) {
      string bead_name1 = mol->getBead(ib1)->getType()->getName();
      bead_name1 = bead_name1.substr(0,bead_name1.find_first_of("#")); // skip #index of atom from its name

      for(int imt=0; imt<MolecularTypes.size(); imt++) {

	for(int ib2=0; ib2<MolecularTypes[imt]->BeadCount(); ib2++) {

	  string bead_name2 = MolecularTypes[imt]->getBead(ib2)->getType()->getName();
	  bead_name2 = bead_name2.substr(0,bead_name2.find_first_of("#")); // skip #index of atom from its name

	  stringstream ss_bp1,ss_bp2;

	  ss_bp1 << format("%8s%8s" ) % bead_name1 % bead_name2;
	  ss_bp2 << format("%8s%8s" ) % bead_name2 % bead_name1;

          bool is_new_pair=true;

	  for(int ibp=0; ibp<vdw_pairs.size(); ibp++) {
	    if( ss_bp1.str()==vdw_pairs[ibp] || ss_bp2.str()==vdw_pairs[ibp] ) {
	      is_new_pair=false;
	      break;
	    }
	  }
	  if( is_new_pair ) {
	    vdw_pairs.push_back(ss_bp1.str());
#ifdef DEBUG
	    cout << "'" << ss_bp1.str() << "' added to CG vdw pairs" << endl;
#endif
	  }
	}
      }
    }
  }
  nummols.push_back(prv_mol_number);

  if(MolecularTypes.size() > 1)
    cout << "WARNING: creation of topology for multiple molecular types "
      "is experimental at this stage\n";

  ofstream fl;
  fl.open(fname.c_str());

  fl << "From VOTCA with love" << " # check/amend this file if needed!\n";
  fl << "units kJ\n";
  fl << "molecular types " << MolecularTypes.size() << endl;

  for(int i=0; i<MolecularTypes.size(); i++) {
    WriteMolecularType(fl, *(MolecularTypes[i]), nummols[i+1]);
  }

  // vdw seciton (pairwise vdw/CG interactions)

  if( vdw_pairs.size()>0 ) {

    fl << "vdw "<< vdw_pairs.size() << endl;

    for(int ibp=0; ibp<vdw_pairs.size(); ibp++) {
      fl << vdw_pairs[ibp] << " tab   1.00000  0.00000\n";
    }
  }

  fl << "close" << endl;

  cout << "Created template for dlpoly topology - please, check & amend if needed!" << endl;

  fl.close();
  return true;
}

void DLPTopolApp::WriteMoleculeAtoms(ostream &out, Molecule &cg)
{
  out << "atoms " << cg.BeadCount() << endl;
    out << "# name  mass  charge  nrept  ifrozen (optional: ngroup, index, name/type, type/residue, index/res-ID) \n";
    for(int i=0; i<cg.BeadCount(); ++i) {
        Bead *b=cg.getBead(i);

        string bname=b->getName();
        string btype=b->getType()->getName();

        bname = bname.substr(0,bname.find_first_of("#")); // skip #index of atom from its name
        btype = btype.substr(0,btype.find_first_of("#")); // skip #index of atom from its type

        out << format("%8s  %10f  %10f     1     0     1 %10d  %8s  %8s %10d \n")
            % bname % b->getM() % b->getQ() % (i+1) % btype % bname % (i+1);
	//% b->getType()->getName() % b->getM() % b->getQ() % (i+1) % b->getType()->getName() % b->getName() % (i+1);
    }
}

void DLPTopolApp::WriteMoleculeInteractions(ostream &out, Molecule &cg)
{
    InteractionContainer ics=cg.Interactions();
    vector<Interaction *>::iterator iter;

    stringstream sout;

    int n_entries = 0;
    int nb=-1;

    for(iter=ics.begin(); iter!=ics.end(); ++iter) {
        Interaction *ic = *iter;
        if(nb != ic->BeadCount()) {

	    if(sout.str()!="")
	      out << n_entries << endl << sout.str();

	    sout.str("");
	    n_entries = 0;

            nb=ic->BeadCount();
            switch(nb) {
                case 2:
		  out << "bonds ";
                    break;
                case 3:
                    out << "angles ";
                    break;
                case 4:
                    out << "dihedrals ";
                    break;
                default:
                    throw runtime_error(string("cannot handle number of beads in interaction:") +
                            ic->getName());
            }
        }
	n_entries++;
	// to do: is it possible to use bond/angle/dihedral function types for 1:1 mapping? (CG map overwrites ic->Group anyway)
        //sout << ic->getInteractionFunc(); // something like that (only for 1:1 mapping!)
        sout << " tab ";
        for(int i=0; i<nb; ++i)
	  sout << ic->getBeadId(i)+1 << " ";
        sout << "   1.00000  0.00000" << " # " << ic->getName() << endl;
        //sout << "   1.00000  0.00000" << " # " << ic->getGroup() << endl;
    }
    if(sout.str()!="") out << n_entries << endl << sout.str();
}

void DLPTopolApp::WriteMolecularType(ostream &out, Molecule &cg, int nummol)
{
    out << cg.getName() << endl;
    out << "nummols " << nummol << endl;

    WriteMoleculeAtoms(out, cg);
    WriteMoleculeInteractions(out, cg);

    out << "finish" << endl;
}

int main(int argc, char** argv)
{
    DLPTopolApp app;
    return app.Exec(argc, argv);
}

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

#include <iostream>
#include <fstream>
#include <boost/format.hpp>
#include <votca/csg/csgapplication.h>

using namespace votca::csg;
using namespace std;
using boost::format;

/**
    \brief class for writing dlpoly topology files

    This class encapsulates the dlpoly topology writing functions

*/

class DLPTopolApp
    : public CsgApplication
{
public:
    string ProgramName() { return "csg_dlptopol"; }
    void HelpText(ostream &out) {
        out << "Create a dlpoly topology template based on an existing (atomistic) topology and \n"
	    << "a mapping xml-file. The created template file needs to be inspected and amended by the user!\n\n"
	    << "Examples:\n"
	    << "* csg_dlptopol --top .dlpf --out .dlpf --cg cg-map.xml\n  convert FIELD to FIELD_CGV using cg-map.xml\n"
	    << "* csg_dlptopol --top FA-dlpoly.dlpf --out CG-dlpoly.dlpf --cg cg-map.xml\n"
	    << "* csg_dlptopol --top FA-gromacs.tpr --out FA-dlpoly.dlpf --no-map\n";
    }

    bool DoMapping(void) { return true; }

    void Initialize(void);
    bool EvaluateOptions(void) {
        CsgApplication::EvaluateOptions();
        CheckRequired("out", "no output topology specified");
        return true;
    }
    bool EvaluateTopology(Topology *top, Topology *top_ref);

protected:
    void WriteMoleculeAtoms(ostream &out, Molecule &cg);
    void WriteMoleculeInteractions(ostream &out, Molecule &cg);
    void WriteVDWInteractions(ostream &out, Molecule &cg);
    void WriteMolecularType(ostream &out, Molecule &cg, int nummol);
};

void DLPTopolApp::Initialize(void)
{
    CsgApplication::Initialize();
    //AddProgramOptions()
    //("top", boost::program_options::value<string>(),
    //"  input topology in any known format:\n  <name>.dlpf for dlpoly, <name>.tpr for gromacs\n  (convention: '.dlpf'='use FIELD')");
    AddProgramOptions()
      ("out", boost::program_options::value<string>(),
       "  output topology in dlpoly format");
}

bool DLPTopolApp::EvaluateTopology(Topology *top, Topology *top_ref)
{
  // check the file names from options

  string fname=OptionsMap()["top"].as<string>();

  if( fname == ".dlpf" ) {
    fname = "FIELD";
  }

  cout << "input  file-name: " << fname << endl;

  fname=OptionsMap()["out"].as<string>();

#ifdef DEBUG
  cout << "output file-name given: " << fname << endl;
#endif

  if( fname == ".dlpf" ) {
    fname = "FIELD_CGV";
  }

#ifdef DEBUG
  cout << "output file-name actual: " << fname << endl;
#else
  cout << "output file-name: " << fname << endl;
#endif

  // do CG mapping

  MoleculeContainer &mols = top->Molecules();
  MoleculeContainer MolecularTypes;
  MoleculeContainer::iterator iter;

  int prv_mol_number = 1;
  string prv_mol_name;
  vector<int> nummols;

  vector<string> vdw_pairs;

  // find all unique molecular types

  for(iter=mols.begin(); iter!=mols.end(); ++iter) {
    Molecule *mol = *iter;

    // molecules are ignored during the mapping stage
    // i.e. the ignored ones do not enter the CG topology (*top) - ?
    //if( IsIgnored(mol->getName()) ) continue;

    if( mol->getName()==prv_mol_name ) {
      prv_mol_number++;
      continue;
    }

    nummols.push_back(prv_mol_number);
    prv_mol_number = 1;
    prv_mol_name   = mol->getName();

    //#ifdef DEBUG
    cout << "'" << mol->getName() << "' added to CG molecular types" << endl;
    //#endif

    MolecularTypes.push_back(mol);

    // collect unique bead pairs over all molecular types found

    for(int ib1=0; ib1<mol->BeadCount(); ib1++) {
      string bead_name1 = mol->getBead(ib1)->getType()->getName();
      bead_name1 = bead_name1.substr(0,bead_name1.find_first_of("#")); // skip #index of atom from its name

      for(int imt=0; imt<MolecularTypes.size(); imt++) {

	for(int ib2=0; ib2<MolecularTypes[imt]->BeadCount(); ib2++) {

	  string bead_name2 = MolecularTypes[imt]->getBead(ib2)->getType()->getName();
	  bead_name2 = bead_name2.substr(0,bead_name2.find_first_of("#")); // skip #index of atom from its name

	  stringstream ss_bp1,ss_bp2;

	  ss_bp1 << format("%8s%8s" ) % bead_name1 % bead_name2;
	  ss_bp2 << format("%8s%8s" ) % bead_name2 % bead_name1;

          bool is_new_pair=true;

	  for(int ibp=0; ibp<vdw_pairs.size(); ibp++) {
	    if( ss_bp1.str()==vdw_pairs[ibp] || ss_bp2.str()==vdw_pairs[ibp] ) {
	      is_new_pair=false;
	      break;
	    }
	  }
	  if( is_new_pair ) {
	    vdw_pairs.push_back(ss_bp1.str());
#ifdef DEBUG
	    cout << "'" << ss_bp1.str() << "' added to CG vdw pairs" << endl;
#endif
	  }
	}
      }
    }
  }
  nummols.push_back(prv_mol_number);

  if(MolecularTypes.size() > 1)
    cout << "WARNING: creation of topology for multiple molecular types "
      "is experimental at this stage\n";

  ofstream fl;
  fl.open(fname.c_str());

  fl << "From VOTCA with love" << " # check/amend this file if needed!\n";
  fl << "units kJ\n";
  fl << "molecular types " << MolecularTypes.size() << endl;

  for(int i=0; i<MolecularTypes.size(); i++) {
    WriteMolecularType(fl, *(MolecularTypes[i]), nummols[i+1]);
  }

  // vdw seciton (pairwise vdw/CG interactions)

  if( vdw_pairs.size()>0 ) {

    fl << "vdw "<< vdw_pairs.size() << endl;

    for(int ibp=0; ibp<vdw_pairs.size(); ibp++) {
      fl << vdw_pairs[ibp] << " tab   1.00000  0.00000\n";
    }
  }

  fl << "close" << endl;

  cout << "Created template for dlpoly topology - please, check & amend if needed!" << endl;

  fl.close();
  return true;
}

void DLPTopolApp::WriteMoleculeAtoms(ostream &out, Molecule &cg)
{
  out << "atoms " << cg.BeadCount() << endl;
    out << "# name  mass  charge  nrept  ifrozen (optional: ngroup, index, name/type, type/residue, index/res-ID) \n";
    for(int i=0; i<cg.BeadCount(); ++i) {
        Bead *b=cg.getBead(i);

        string bname=b->getName();
        string btype=b->getType()->getName();

        bname = bname.substr(0,bname.find_first_of("#")); // skip #index of atom from its name
        btype = btype.substr(0,btype.find_first_of("#")); // skip #index of atom from its type

        out << format("%8s  %10f  %10f     1     0     1 %10d  %8s  %8s %10d \n")
            % bname % b->getM() % b->getQ() % (i+1) % btype % bname % (i+1);
	//% b->getType()->getName() % b->getM() % b->getQ() % (i+1) % b->getType()->getName() % b->getName() % (i+1);
    }
}

void DLPTopolApp::WriteMoleculeInteractions(ostream &out, Molecule &cg)
{
    InteractionContainer ics=cg.Interactions();
    vector<Interaction *>::iterator iter;

    stringstream sout;

    int n_entries = 0;
    int nb=-1;

    for(iter=ics.begin(); iter!=ics.end(); ++iter) {
        Interaction *ic = *iter;
        if(nb != ic->BeadCount()) {

	    if(sout.str()!="")
	      out << n_entries << endl << sout.str();

	    sout.str("");
	    n_entries = 0;

            nb=ic->BeadCount();
            switch(nb) {
                case 2:
		  out << "bonds ";
                    break;
                case 3:
                    out << "angles ";
                    break;
                case 4:
                    out << "dihedrals ";
                    break;
                default:
                    throw runtime_error(string("cannot handle number of beads in interaction:") +
                            ic->getName());
            }
        }
	n_entries++;
	// to do: is it possible to use bond/angle/dihedral function types for 1:1 mapping? (CG map overwrites ic->Group anyway)
        //sout << ic->getInteractionFunc(); // something like that (only for 1:1 mapping!)
        sout << " tab ";
        for(int i=0; i<nb; ++i)
	  sout << ic->getBeadId(i)+1 << " ";
        sout << "   1.00000  0.00000" << " # " << ic->getName() << endl;
        //sout << "   1.00000  0.00000" << " # " << ic->getGroup() << endl;
    }
    if(sout.str()!="") out << n_entries << endl << sout.str();
}

void DLPTopolApp::WriteMolecularType(ostream &out, Molecule &cg, int nummol)
{
    out << cg.getName() << endl;
    out << "nummols " << nummol << endl;

    WriteMoleculeAtoms(out, cg);
    WriteMoleculeInteractions(out, cg);

    out << "finish" << endl;
}

int main(int argc, char** argv)
{
    DLPTopolApp app;
    return app.Exec(argc, argv);
}

<|endoftext|>


<commit_before>/*
 * InputStreamMgr.cpp
 *
 *  Created on: Mar 21, 2013
 *      Author: nek3d
 */

#include "InputStreamMgr.h"
#include <cstring> //for memset
#include "gzstream.h"
#include "CompressionTools.h"

const char *InputStreamMgr::FIFO_STRING_LITERAL = "/dev/fd";

InputStreamMgr::InputStreamMgr(const QuickString &filename, bool buildScanBuffer)
:
 _filename(filename),
 _pushBackStreamBuf(NULL),
 _inputFileStream(NULL),
 _infStreamBuf(NULL),
 _oldInputStream(NULL),
 _isStdin(false),
 _isGzipped(false),
 _isBam(false),
 _isBgzipped(false),
 _bamRuledOut(false),
 _numBytesInBuffer(0),
 _bamReader(NULL),
 _bgStream(NULL)
{
	_possibleBamCode.resize(4, 0);
}

InputStreamMgr::~InputStreamMgr() {
	if (_pushBackStreamBuf != NULL) {
		delete _pushBackStreamBuf;
		_pushBackStreamBuf = NULL;
	}
	if (_inputFileStream != NULL) {
		delete _inputFileStream;
		_inputFileStream = NULL;
	}
	if (_oldInputStream != NULL) {
		delete _oldInputStream;
		_oldInputStream = NULL;
	}
	if (_infStreamBuf != NULL) {
		delete _infStreamBuf;
		_infStreamBuf = NULL;
	}
	if (_bamReader != NULL) {
		delete _bamReader;
		_bgStream = NULL;
	}
	if (_bgStream != NULL) {
		delete _bgStream;
		_bgStream = NULL;
	}
}

bool InputStreamMgr::init()
{
	if (_filename == "-" || _filename == "stdin") { //stdin
		_isStdin = true;
		//peek at the first char of stdin to see if this is gzipped.
		if ((unsigned char)cin.peek()  == 0x1f) {
			_isGzipped = true;
		}
		_pushBackStreamBuf = new PushBackStreamBuf(cin.rdbuf());
	} else {
		if (strncmp(_filename.c_str(), FIFO_STRING_LITERAL, strlen(FIFO_STRING_LITERAL)) == 0) {
			_isStdin = true;
		}
		_inputFileStream = new ifstream(_filename.c_str());
		if (_inputFileStream->fail()) {
			cerr << "Error: Unable to open file " << _filename << ". Exiting." << endl;
			delete _inputFileStream;
			_inputFileStream = NULL;
			exit(1);
		}
		//peek at the first char of stdin to see if this is gzipped.
		if ((unsigned char)_inputFileStream->peek()  == 0x1f) {
			_isGzipped = true;
		}
		_pushBackStreamBuf = new PushBackStreamBuf(_inputFileStream->rdbuf());
	}
	//now we have a PushBackStreamBuf. Make a new stream.
	_finalInputStream = new istream(_pushBackStreamBuf);
	populateScanBuffer();
	return true;
}

int InputStreamMgr::read(char *data, size_t dataSize)
{
	if (_isBgzipped) {
		return (int)(_bgStream->Read(data, dataSize));
	}
	_finalInputStream->read(data, dataSize);
	return _finalInputStream->gcount();
}

void InputStreamMgr::populateScanBuffer()
{
	_scanBuffer.clear();
	int numChars=0;
	int currChar = 0;
	bool mustAppend = true;
	while (1) {
		mustAppend = true;
		currChar = _pushBackStreamBuf->sbumpc();
		//Stop when EOF hit.
		if (currChar == EOF) {
			break;
		}
		numChars++;
		_scanBuffer.push_back(currChar);
		if (_isGzipped) {
			if (!_bamRuledOut && detectBamOrBgzip(numChars, currChar, mustAppend)) {
				return;
			}
			if (numChars == 0) {
				continue; //this will only happen when we've just discovered that this
				//is definitely not BAM, and want to start over.
			}
			if (mustAppend) {
				_compressedSaveData.push_back(currChar);
			}
		}

		//For non-gzip, also stop if we have the minimum number of bytes and newline is hit.
		//For gzip, stop at SCAN_BUFFER_SIZE.
		if ((!_isGzipped && (currChar == '\n' && numChars >= MIN_SCAN_BUFFER_SIZE )) || (_isGzipped && numChars >= SCAN_BUFFER_SIZE)) {
			break;
		}
	}
	_numBytesInBuffer = _scanBuffer.size();

	//append it to the savedDataStr. If it's gzipped, decompress it first.
	if (_isGzipped) {
		decompressBuffer();
	} else {
		_scanBuffer.toStr(_saveDataStr, true);
	}
}

bool InputStreamMgr::detectBamOrBgzip(int &numChars, int currChar, bool &mustAppend)
{
	//Look for the BAM magic string "BAM\1" in the first fouur characters of the input stream.
	//In compressed form, the first char is the gzip signifier, which was already found.
	//The next three are the integers 139, 8, and 4.
	if (numChars < 5) {
		_possibleBamCode[numChars -1] = currChar;
		//special: test for BAM
		if (numChars == 4 && _possibleBamCode[1] == 139 && _possibleBamCode[2] == 8 && _possibleBamCode[3] == 4) {
			//BAM magic string detected.This is either a BAM or bgzip file. To find out which, we have to try and
			//open the file as BAM, with a BAM reader, and see if the header and references are both non-empty.
			//However, if they are empty, we will have had to save all bytes consumed in the attempt, meaning still
			//fill the scanBuffer and push it back onto the pushBackStream as normal.
			for (; numChars < BAM_SCAN_BUFFER_SIZE; numChars++) {
				currChar = _pushBackStreamBuf->sbumpc();
				//Stop when EOF hit.
				if (currChar == EOF) {
					break;
				}
				_scanBuffer.push_back(currChar);

			}
			_pushBackStreamBuf->pushBack(_scanBuffer);

			//ok, now all the data read so far is saved in the scan buffer, and pushbackstream is reset.
			//now we make a BamReader and try to open the file.

			_bamReader = new BamTools::BamReader();
			_bamReader->OpenStream(_finalInputStream);
			QuickString bamHeader(_bamReader->GetHeaderText());
			BamTools::RefVector bamRefs(_bamReader->GetReferenceData());

			if (bamHeader.empty() || bamRefs.empty()) {
				//This is NOT a bam file.
				_pushBackStreamBuf->clear();
				_compressedSaveData.clear();
				//Put all bytes read so far back onto the scan buffer, then reset
				//everything so that we're effectively starting over.
				_pushBackStreamBuf->pushBack(_scanBuffer);
				_scanBuffer.clear();
				mustAppend = false;
				numChars = 0;
				_isBam = false;
				_isBgzipped = true;
				_bamRuledOut = true;
				_numBytesInBuffer = 0;
				delete _bamReader;
				_bamReader = NULL;
				return false;
			}
			_isBam = true;
			_numBytesInBuffer = _scanBuffer.size();
			return true;
		}
	}
	return false;
}

void InputStreamMgr::decompressBuffer()
{
	//allocate an array to hold uncompressed data.
	uInt maxDecompressSize = 20 * _numBytesInBuffer;
	unsigned char *newScanBuffer = new unsigned char[maxDecompressSize];
	memset(newScanBuffer, 0, maxDecompressSize);

	unsigned int numDecompressChars = inflateGzippedArray(_scanBuffer, newScanBuffer, maxDecompressSize, _numBytesInBuffer);

	// newScanBuffer should now contain uncompressed data.
	//delete old buffer, point it at new buffer.
	_saveDataStr.append((char *)newScanBuffer, numDecompressChars);

	delete [] newScanBuffer;
}

void InputStreamMgr::reset()
{
	if (_isBam) {
		return;
	}
	if (!_isStdin) {
		//For file input, just re-open the file.
		_oldInputStream = _finalInputStream;
		_finalInputStream = new ifstream(_filename.c_str());
	} else {
		if (_isBgzipped) {
			for (BTlist<int>::const_iterator_type iter = _pushBackStreamBuf->_buffer.begin();
					iter != _pushBackStreamBuf->_buffer.end(); iter = _pushBackStreamBuf->_buffer.next()) {
				_compressedSaveData.push_back(iter->value());
			}
			_pushBackStreamBuf->clear();
			_pushBackStreamBuf->pushBack(_compressedSaveData);
		} else if (_isGzipped) {
			_pushBackStreamBuf->pushBack(_compressedSaveData);
		} else {
			_pushBackStreamBuf->pushBack(BTlist<int>(_saveDataStr));
		}
//		_finalInputStream = new istream(_pushBackStreamBuf);
	}
	if (_isBgzipped) {
		//The file is bgzipped, but not BAM.
		_bgStream = new BamTools::Internal::BgzfStream();
		_bgStream->OpenStream(_finalInputStream, BamTools::IBamIODevice::ReadOnly);
	} else if (_isGzipped) {
		//the file is gzipped, but is not bgzipped or BAM.
		_infStreamBuf = new InflateStreamBuf(_finalInputStream);
		if (_oldInputStream != NULL) {
			delete _oldInputStream;
		}
		_oldInputStream = _finalInputStream;
		_finalInputStream = new istream(_infStreamBuf);
	}
}

<commit_msg>Fixed test for Bam vs Bgzip to allow for empty references.<commit_after>/*
 * InputStreamMgr.cpp
 *
 *  Created on: Mar 21, 2013
 *      Author: nek3d
 */

#include "InputStreamMgr.h"
#include <cstring> //for memset
#include "gzstream.h"
#include "CompressionTools.h"

const char *InputStreamMgr::FIFO_STRING_LITERAL = "/dev/fd";

InputStreamMgr::InputStreamMgr(const QuickString &filename, bool buildScanBuffer)
:
 _filename(filename),
 _pushBackStreamBuf(NULL),
 _inputFileStream(NULL),
 _infStreamBuf(NULL),
 _oldInputStream(NULL),
 _isStdin(false),
 _isGzipped(false),
 _isBam(false),
 _isBgzipped(false),
 _bamRuledOut(false),
 _numBytesInBuffer(0),
 _bamReader(NULL),
 _bgStream(NULL)
{
	_possibleBamCode.resize(4, 0);
}

InputStreamMgr::~InputStreamMgr() {
	if (_pushBackStreamBuf != NULL) {
		delete _pushBackStreamBuf;
		_pushBackStreamBuf = NULL;
	}
	if (_inputFileStream != NULL) {
		delete _inputFileStream;
		_inputFileStream = NULL;
	}
	if (_oldInputStream != NULL) {
		delete _oldInputStream;
		_oldInputStream = NULL;
	}
	if (_infStreamBuf != NULL) {
		delete _infStreamBuf;
		_infStreamBuf = NULL;
	}
	if (_bamReader != NULL) {
		delete _bamReader;
		_bgStream = NULL;
	}
	if (_bgStream != NULL) {
		delete _bgStream;
		_bgStream = NULL;
	}
}

bool InputStreamMgr::init()
{
	if (_filename == "-" || _filename == "stdin") { //stdin
		_isStdin = true;
		//peek at the first char of stdin to see if this is gzipped.
		if ((unsigned char)cin.peek()  == 0x1f) {
			_isGzipped = true;
		}
		_pushBackStreamBuf = new PushBackStreamBuf(cin.rdbuf());
	} else {
		if (strncmp(_filename.c_str(), FIFO_STRING_LITERAL, strlen(FIFO_STRING_LITERAL)) == 0) {
			_isStdin = true;
		}
		_inputFileStream = new ifstream(_filename.c_str());
		if (_inputFileStream->fail()) {
			cerr << "Error: Unable to open file " << _filename << ". Exiting." << endl;
			delete _inputFileStream;
			_inputFileStream = NULL;
			exit(1);
		}
		//peek at the first char of stdin to see if this is gzipped.
		if ((unsigned char)_inputFileStream->peek()  == 0x1f) {
			_isGzipped = true;
		}
		_pushBackStreamBuf = new PushBackStreamBuf(_inputFileStream->rdbuf());
	}
	//now we have a PushBackStreamBuf. Make a new stream.
	_finalInputStream = new istream(_pushBackStreamBuf);
	populateScanBuffer();
	return true;
}

int InputStreamMgr::read(char *data, size_t dataSize)
{
	if (_isBgzipped) {
		return (int)(_bgStream->Read(data, dataSize));
	}
	_finalInputStream->read(data, dataSize);
	return _finalInputStream->gcount();
}

void InputStreamMgr::populateScanBuffer()
{
	_scanBuffer.clear();
	int numChars=0;
	int currChar = 0;
	bool mustAppend = true;
	while (1) {
		mustAppend = true;
		currChar = _pushBackStreamBuf->sbumpc();
		//Stop when EOF hit.
		if (currChar == EOF) {
			break;
		}
		numChars++;
		_scanBuffer.push_back(currChar);
		if (_isGzipped) {
			if (!_bamRuledOut && detectBamOrBgzip(numChars, currChar, mustAppend)) {
				return;
			}
			if (numChars == 0) {
				continue; //this will only happen when we've just discovered that this
				//is definitely not BAM, and want to start over.
			}
			if (mustAppend) {
				_compressedSaveData.push_back(currChar);
			}
		}

		//For non-gzip, also stop if we have the minimum number of bytes and newline is hit.
		//For gzip, stop at SCAN_BUFFER_SIZE.
		if ((!_isGzipped && (currChar == '\n' && numChars >= MIN_SCAN_BUFFER_SIZE )) || (_isGzipped && numChars >= SCAN_BUFFER_SIZE)) {
			break;
		}
	}
	_numBytesInBuffer = _scanBuffer.size();

	//append it to the savedDataStr. If it's gzipped, decompress it first.
	if (_isGzipped) {
		decompressBuffer();
	} else {
		_scanBuffer.toStr(_saveDataStr, true);
	}
}

bool InputStreamMgr::detectBamOrBgzip(int &numChars, int currChar, bool &mustAppend)
{
	//Look for the BAM magic string "BAM\1" in the first fouur characters of the input stream.
	//In compressed form, the first char is the gzip signifier, which was already found.
	//The next three are the integers 139, 8, and 4.
	if (numChars < 5) {
		_possibleBamCode[numChars -1] = currChar;
		//special: test for BAM
		if (numChars == 4 && _possibleBamCode[1] == 139 && _possibleBamCode[2] == 8 && _possibleBamCode[3] == 4) {
			//BAM magic string detected.This is either a BAM or bgzip file. To find out which, we have to try and
			//open the file as BAM, with a BAM reader, and see if the header and references are both non-empty.
			//However, if they are empty, we will have had to save all bytes consumed in the attempt, meaning still
			//fill the scanBuffer and push it back onto the pushBackStream as normal.
			for (; numChars < BAM_SCAN_BUFFER_SIZE; numChars++) {
				currChar = _pushBackStreamBuf->sbumpc();
				//Stop when EOF hit.
				if (currChar == EOF) {
					break;
				}
				_scanBuffer.push_back(currChar);

			}
			_pushBackStreamBuf->pushBack(_scanBuffer);

			//ok, now all the data read so far is saved in the scan buffer, and pushbackstream is reset.
			//now we make a BamReader and try to open the file.

			_bamReader = new BamTools::BamReader();
			_bamReader->OpenStream(_finalInputStream);
			QuickString bamHeader(_bamReader->GetHeaderText());

			if (bamHeader.empty()) {
				//This is NOT a bam file.
				_pushBackStreamBuf->clear();
				_compressedSaveData.clear();
				//Put all bytes read so far back onto the scan buffer, then reset
				//everything so that we're effectively starting over.
				_pushBackStreamBuf->pushBack(_scanBuffer);
				_scanBuffer.clear();
				mustAppend = false;
				numChars = 0;
				_isBam = false;
				_isBgzipped = true;
				_bamRuledOut = true;
				_numBytesInBuffer = 0;
				delete _bamReader;
				_bamReader = NULL;
				return false;
			}
			_isBam = true;
			_numBytesInBuffer = _scanBuffer.size();
			return true;
		}
	}
	return false;
}

void InputStreamMgr::decompressBuffer()
{
	//allocate an array to hold uncompressed data.
	uInt maxDecompressSize = 20 * _numBytesInBuffer;
	unsigned char *newScanBuffer = new unsigned char[maxDecompressSize];
	memset(newScanBuffer, 0, maxDecompressSize);

	unsigned int numDecompressChars = inflateGzippedArray(_scanBuffer, newScanBuffer, maxDecompressSize, _numBytesInBuffer);

	// newScanBuffer should now contain uncompressed data.
	//delete old buffer, point it at new buffer.
	_saveDataStr.append((char *)newScanBuffer, numDecompressChars);

	delete [] newScanBuffer;
}

void InputStreamMgr::reset()
{
	if (_isBam) {
		return;
	}
	if (!_isStdin) {
		//For file input, just re-open the file.
		_oldInputStream = _finalInputStream;
		_finalInputStream = new ifstream(_filename.c_str());
	} else {
		if (_isBgzipped) {
			for (BTlist<int>::const_iterator_type iter = _pushBackStreamBuf->_buffer.begin();
					iter != _pushBackStreamBuf->_buffer.end(); iter = _pushBackStreamBuf->_buffer.next()) {
				_compressedSaveData.push_back(iter->value());
			}
			_pushBackStreamBuf->clear();
			_pushBackStreamBuf->pushBack(_compressedSaveData);
		} else if (_isGzipped) {
			_pushBackStreamBuf->pushBack(_compressedSaveData);
		} else {
			_pushBackStreamBuf->pushBack(BTlist<int>(_saveDataStr));
		}
//		_finalInputStream = new istream(_pushBackStreamBuf);
	}
	if (_isBgzipped) {
		//The file is bgzipped, but not BAM.
		_bgStream = new BamTools::Internal::BgzfStream();
		_bgStream->OpenStream(_finalInputStream, BamTools::IBamIODevice::ReadOnly);
	} else if (_isGzipped) {
		//the file is gzipped, but is not bgzipped or BAM.
		_infStreamBuf = new InflateStreamBuf(_finalInputStream);
		if (_oldInputStream != NULL) {
			delete _oldInputStream;
		}
		_oldInputStream = _finalInputStream;
		_finalInputStream = new istream(_infStreamBuf);
	}
}

<|endoftext|>