<commit_before>/// ParameterSampler.cpp
/// Shaun Harker
/// 2016-03-07

#include <iostream>

#include "DSGRN.h"

std::string help_message =
  "ParameterSampler                                                  \n"
  "    Reads parameter node indices from standard input and outputs  \n"
  "    Gibbs sampled parameters to standard output.                  \n"
  "  Usage:                                                          \n"
  "    ParameterSampler <networkspace_file>                         \n"
  "  Example:                                                        \n"
  "    cat parameter_index_list.txt | ./bin/ParameterSampler ../../networks/13D_p53.txt \n";

/// Load_CAD_Databases
///   This function loads the CAD databases associated with
///   each network node of the provided network.
///   Inputs:   network -- the Network object
///   Objects:  std::vector<json> -- a vector of json objects in
///             one-to-one correspondence with network nodes
std::vector<json>
Load_CAD_Databases ( Network const& network ) {
  std::vector<json> result;
  // Obtain folder path containing CAD databases
  std::string path = std::string(INSTALLPREFIX) + "/share/DSGRN/CAD";
  // Load the CAD databases one by one
  uint64_t D = network . size ();
  for ( uint64_t d = 0; d < D; ++ d ) {
    // Construct CAD database file name for network node
    uint64_t n = network . inputs ( d ) . size ();
    uint64_t m = network . outputs ( d ) . size ();
    std::vector<std::vector<uint64_t>> const& logic_struct = network . logic ( d );
    std::stringstream ss;
    ss << path << "/" << n <<  "_" << m;
    for ( auto const& p : logic_struct ) ss <<  "_" << p.size();
    ss << ".json";
    // Make a new json object to store the file into
    result . push_back ( json () );
    json & J = result . back ();
    // Load the file into the json object
    std::ifstream infile (ss.str());
    infile >> J;
    infile.close();
    // BEGIN DEBUG
    // inspect our work to make sure it worked
    std::cout << J << "\n";
    // END DEBUG
  }
  return result;
}

typedef std::string HexCode;
typedef std::string Variable;
typedef std::map<Variable, double> Instance;

/// Construct_Instance_Lookups
// typedefs of string to make code easier to follow
std::map<HexCode, Instance>
Construct_Instance_Lookups ( Network const& network,
                             std::vector<json> const& CAD_Databases ) {

}
/// Lookup_Initial_Point
///   Search through databases
Instance
Lookup_Initial_Point ( Network const& network,
                       Parameter const& p,
                       std::map<HexCode, Instance> const& Instance_Lookups ) {

}

///
Instance
GibbsSampler ( HexCode const& hex,
               uint64_t n,
               uint64_t m,
               Instance const& initial ) {
  // Here is the magic
}

/// main
///   Entry point for program
///   Does the following:
///   (1) Check input arguments; if not satisfactory return help message
///   (2) Load the network and the associated CAD database files

int main ( int argc, char * argv [] ) {
  std::cout << "Hello world! (not exactly a Gibbs sampler yet.)\n";
  // Check arguments
  if ( argc != 2 ) {
    std::cout << "Received " << argc - 1 << " command line arguments, expected 1. Displaying help message.\n";
    std::cout << help_message << "\n";
    return 1;
  }
  Network network ( argv[1] );
  ParameterGraph pg ( network );

  std::cout << "ParameterGraph size = " << pg . size () << "\n";
  // Load the CAD Databases
  std::vector<json> CAD_Databases = Load_CAD_Databases ( network );
  // Build Instance Lookup tables from the CAD Databases
  std::map<HexCode, Instance> Instance_Lookups = Construct_Instance_Lookups ( network, CAD_Databases );

  while ( 1 ) {
    // Read from standard input
    uint64_t pi;
    std::cin >> pi;
    // If no standard input to read, break loop
    if ( not std::cin . good () ) break;
    // Compute the parameter associated with the parameter index pi
    Parameter p = pg . parameter ( pi );

    // Output to standard output

    // TODO
  }
  return 0;
}
<commit_msg>working on faster gibbs sampling<commit_after>/// ParameterSampler.cpp
/// Shaun Harker
/// 2016-03-07

#include <iostream>

#include "DSGRN.h"

std::string help_message =
  "ParameterSampler                                                  \n"
  "    Reads parameter node indices from standard input and outputs  \n"
  "    Gibbs sampled parameters to standard output.                  \n"
  "  Usage:                                                          \n"
  "    ParameterSampler <networkspace_file>                         \n"
  "  Example:                                                        \n"
  "    cat parameter_index_list.txt | ./bin/ParameterSampler ../../networks/13D_p53.txt \n";

typedef std::string HexCode;
typedef std::string Variable;
typedef std::map<Variable, double> Instance;
typedef std::map<HexCode, Instance> InstanceLookup;

/// Load_CAD_Databases
///   This function loads the CAD databases associated with
///   each network node of the provided network.
///   Inputs:   network -- the Network object
///   Objects:  std::vector<json> -- a vector of json objects in
///             one-to-one correspondence with network nodes
std::vector<json>
Load_CAD_Databases ( Network const& network ) {
  std::cout << "Loading databases.\n";
  std::vector<json> result;
  // Obtain folder path containing CAD databases
  std::string path = std::string(INSTALLPREFIX) + "/share/DSGRN/CAD";
  // Load the CAD databases one by one
  uint64_t D = network . size ();
  for ( uint64_t d = 0; d < D; ++ d ) {
    // Construct CAD database file name for network node
    uint64_t n = network . inputs ( d ) . size ();
    uint64_t m = network . outputs ( d ) . size ();
    std::vector<std::vector<uint64_t>> const& logic_struct = network . logic ( d );
    std::stringstream ss;
    ss << path << "/" << n <<  "_" << m;
    for ( auto const& p : logic_struct ) ss <<  "_" << p.size();
    ss << ".json";
    // Make a new json object to store the file into
    result . push_back ( json () );
    json & J = result . back ();
    // Load the file into the json object
    std::cout << "Reading " << ss.str () << "\n";
    std::ifstream infile (ss.str());
    infile >> J;
    infile.close();
    std::cout << "File read.\n";
  }
  std::cout << "Databases loaded.\n";
  return result;
}

/// Construct_Instance_Lookups
std::vector<InstanceLookup>
Construct_Instance_Lookups ( Network const& network,
                             std::vector<json> const& CAD_Databases ) {
  uint64_t D = CAD_Databases.size();
  std::vector<InstanceLookup> instancelookups ( D );
  for ( uint64_t d = 0; d < D; ++ d ) {
    for ( auto const& entry : CAD_Databases[d] ) {
      // Obtain hex code from database entry
      std::string hex = entry["Hex"];
      // Obtain instance from database entry
      Instance instance;
      auto json_instance = entry["Instance"];
      for (json::iterator it = json_instance.begin(); it != json_instance.end(); ++it) {
        instance[it.key()] = it.value();
      }
      // Enter instance lookup table entry
      instancelookups[d][hex] = instance;
    }
  }
  return instancelookups;
}

std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0.0,1.0);

/// Gibbs_Sampler
Instance
Gibbs_Sampler ( HexCode const& hex,
               uint64_t n,
               uint64_t m,
               Instance const& initial ) {
  // Here is the magic
  Instance result;

  uint64_t N = 1 << n;
  const double Inf = std::numeric_limits<double>::infinity();

  // sample
  //   Sample according to exponential distribution conditioned on being
  //   in the interval (min, max)
  auto sample = [](std::pair<double,double> const& pair) {
      double A = std::exp(-pair.first);
      double B = std::exp(-pair.second);
      double mu = distribution(generator);
      return std::log(A - mu *(A-B));
  };
  // Read initial instance into faster data structure
  std::vector<double> L ( n );
  std::vector<double> U ( n );
  std::vector<double> T ( m );
  for ( auto const& pair : initial ) {
    uint64_t i = std::stoll(pair.first.substr(2,pair.first.size()-3));
    switch ( pair.first[0] ) {
      case 'L':
        L[i-1] = pair.second;
        break;
      case 'U':
        U[i-1] = pair.second;
        break;
      case 'T':
        T[i-1] = pair.second;
        break;
    }
  }
  // Initialize "computational tableau" to enable rapid iterations
  // sums[j][k] gives the sum of the terms of the kth factor in the jth L/U formula
  // products[j] gives the product of factors in the jth L/U formula
  // which_factor[i] tells us which factor the ith L (or U) variable is in
  // lower[j] tells us which threshold is the greatest lower bound of the jth L/U formula. m indicates no lower bound
  // upper[j] tells us which threshold is the least upper bound  of the jth L/U formula. m+1 indicates no upper bound
  // we set T[m] = - \infty and T[m+1] = \infty
  //  a * (b + x)
  std::vector<std::vector<double>> sums;
  std::vector<double> products;
  std::vector<uint64_t> which_factor;
  std::vector<double> cofactor;
  std::vector<double> cosum;

  // TODO, get those sabove ducks in a row

  typedef std::pair<double,double> Interval;

  auto scan = [&](Interval & interval, uint64_t k, double var) {
    double & min = interval.first;
    double & max = interval.second;
    for ( uint64_t j = 0; j < N; ++ j ) {
      cofactor[j] = products[j]/sums[j][k];
      cosum[j] = sums[j][k] - var;
      min = std::max ( min, T[lower[j]]/cofactor[j] - cosum[j]);
      max = std::min ( max, T[upper[j]]/cofactor[j] - cosum[j]);
    }
  }

  auto fix = [&](uint64_t k, double var) {
    for ( uint64_t j = 0; j < N; ++ j ) {
      sums[j][k] = cosum[j] + var;
      products[j] = cofactor[j] * sums[j][k];
    }
  }

  for ( uint64_t burn_in = 0; burn_in < 10; ++ burn_in ) {
    // Update L's
    for ( uint64_t i = 0; i < n; ++ i ) {
      uint64_t k = which_factor[i];
      Interval interval = {0, U[i]};
      scan(interval, k, L[i]);
      L[i] = sample(interval);
      fix(k, L[i]);
    }
    // Update U's
    for ( uint64_t i = 0; i < n; ++ i ) {
      uint64_t k = which_factor[i];
      Interval interval = {L[i], Inf};
      scan(interval, k, U[i]);
      U[i] = sample(interval);
      fix(k, U[i]);
    }
    // Update T's
    for ( uint64_t i = 0; i < m; ++ i ) {
      Interval interval;
      double & min = interval.first;
      double & max = interval.second;
      min = ( i == 0 ) ? 0 : T[i-1];
      max = ( i == (m-1) ) ? Inf : T[i+1];
      for ( uint64_t j = 0; j < N; ++ j ) {
        if ( lower[j] == i ) max = std::min(max,products[j]);
        if ( upper[j] == i ) min = std::max(min,products[j]);
      }
      T[i] = sample(interval);
    }
  }
  return initial;
}

/// Name_Parameters
///   Given a network, a parameter node, a chosen instances for each network node
///   determine the parameter names corresponding to each parameter in the instances
///   and construct a Instance suitable for export
Instance
Name_Parameters ( Network const& network,
                  Parameter const& p,
                  std::vector<Instance> const& instances ) {
  uint64_t D = network . size ();
  std::vector<OrderParameter> const& order = p . order ();
  Instance result;
  for ( uint64_t d = 0; d < D; ++ d ) {
    Instance const& instance = instances[d];
    std::string const& name = network . name ( d );
    // Handle input parameters (i.e. L and U)
    uint64_t n = network . inputs ( d ) . size ();
    for ( uint64_t i = 0; i < n; ++ i ) {
      uint64_t input = network . inputs(d) [ i ];
      std::string const& input_name = network . name ( input );
      result[ "L[" + input_name + ", " + name + "]" ] = instance . at ("L[" + std::to_string(i+1) + "]");
      result[ "U[" + input_name + ", " + name + "]" ] = instance . at ("U[" + std::to_string(i+1) + "]");
    }
    // Handle output parameter (i.e. T)
    uint64_t m = network . outputs ( d ) . size ();
    for ( uint64_t i = 0; i < m; ++ i ) {
      uint64_t output = network . outputs(d) [ order[d](i) ];
      std::string const& output_name = network . name ( output );
      result[ "T[" + name + ", " + output_name + "]" ] = instance . at ("T[" + std::to_string(i+1) + "]");
    }
  }
  return result;
}

/// main
///   Entry point for program
///   Does the following:
///   (1) Check input arguments; if not satisfactory return help message
///   (2) Load the network and the associated CAD database files

int main ( int argc, char * argv [] ) {
  // Check arguments
  if ( argc != 2 ) {
    std::cout << "Received " << argc - 1 << " command line arguments, expected 1. Displaying help message.\n";
    std::cout << help_message << "\n";
    return 1;
  }
  Network network ( argv[1] );
  uint64_t D = network . size ();
  ParameterGraph pg ( network );
  // Load the CAD Databases
  std::vector<json> CAD_Databases =
    Load_CAD_Databases ( network );
  // Build Instance Lookup tables from the CAD Databases
  std::vector<InstanceLookup> Instance_Lookups =
    Construct_Instance_Lookups ( network, CAD_Databases );
  // Main loop
  while ( 1 ) {
    // Read from standard input
    uint64_t pi;
    std::cin >> pi;
    // If no standard input to read, break loop
    if ( not std::cin . good () ) break;
    // Compute the parameter associated with the parameter index pi
    Parameter p = pg . parameter ( pi );
    std::vector<LogicParameter> const& logic = p . logic ();
    // Loop through network nodes and extract a sample
    std::vector<Instance> instances;
    for ( uint64_t d = 0; d < D; ++ d ) {
      // Obtain hex code
      HexCode const& hex = logic[d].hex();
      // Obtain initial instance to seed Gibbs sampling with
      Instance const& instance = Instance_Lookups[d][hex];
      // Perform Gibbs sampling
      Instance sampled = Gibbs_Sampler ( hex, network.inputs(d).size(),
                                         network.outputs(d).size(), instance );
      // Record parameters for network node
      instances . push_back ( sampled );
    }
    // Combine instances into single instance with named parameters
    Instance named_parameters = Name_Parameters ( network, p, instances );
    // Output to standard output
    std::cout << "{";
    bool first = true;
    for ( auto const& pair : named_parameters ) {
      if ( first ) first = false; else std::cout << ", ";
      std::cout << "\"" << pair.first << "\" : " << pair.second;
    }
    std::cout << "}\n";
  }
  return 0;
}
<|endoftext|>


<commit_before>#include <vector>
#include <sstream> // std::ostringstream
#include <boost/test/unit_test.hpp>
#include <boost/test/parameterized_test.hpp>
#include <boost/program_options.hpp>
#include <boost/foreach.hpp>

#include <glog/logging.h>

#include "IndexerTestFixture.h"
#include "t_IndexReader.h"
#include "t_BarrelsInfo.h"
#include "t_TermDocFreqs.h"

using namespace std;
using namespace boost::unit_test;
namespace po = boost::program_options;

namespace {
/** the parameters for each test case */
const IndexerTestConfig INDEXER_TEST_CONFIGS[] = {
    {0, 1, 1, "default", true},
    {1, 1, 1, "realtime", true},
    {2, 5, 3, "default", true},
    {3, 5, 3, "realtime", true},
    {4, 10, 6, "default", true},
    {5, 10, 6, "realtime", true},
    {6, 100, 23, "default", true},
    {7, 100, 23, "realtime", true},
    {8, 1000, 10, "default", true},
    {9, 1000, 10, "realtime", true},
};

/** the parameter number */
const int INDEXER_TEST_CONFIG_NUM = sizeof(INDEXER_TEST_CONFIGS) / sizeof(IndexerTestConfig);

/** the command option to specify a list of config numbers, such as "--run_config_list 0 1 2 3" */
const char* OPTION_CONFIG_LIST = "run_config_list";

/** the command option to specify a range of config numbers, such as "--run_config_range 4 7" */
const char* OPTION_CONFIG_RANGE = "run_config_range";
}

/**
 * Load command line option "run_config_list" or "run_config_range" to decide which configs to run.
 * @param configVec the loaded configs to run
 * @return true for load success, false for fail
 */
bool loadConfigOption(vector<IndexerTestConfig>& configVec)
{
    try
    {
        vector<int> runConfigListVec;
        vector<int> runConfigRangeVec;
        po::options_description desp("Allowed options");
        desp.add_options()
            (OPTION_CONFIG_LIST, po::value<std::vector<int> >(&runConfigListVec)->multitoken(), "specify the list of config parameters to run")
            (OPTION_CONFIG_RANGE, po::value<std::vector<int> >(&runConfigRangeVec)->multitoken(), "specify the range of config parameters to run")
            ;

        po::options_description cmdline_options;
        cmdline_options.add(desp);

        po::variables_map vm;
        store(po::command_line_parser(framework::master_test_suite().argc, framework::master_test_suite().argv).options(cmdline_options).run(), vm);
        po::notify(vm);

        if(vm.count(OPTION_CONFIG_LIST))
        {
            cout << OPTION_CONFIG_LIST << ": ";
            BOOST_FOREACH(int i, runConfigListVec)
            {
                cout << i << ", ";
                if(i >= 0 && i < INDEXER_TEST_CONFIG_NUM)
                    configVec.push_back(INDEXER_TEST_CONFIGS[i]);
                else
                {
                    cout << endl;
                    ostringstream oss;
                    oss << "unknown config number " << i;
                    throw std::runtime_error(oss.str());
                }
            }
            cout << endl;
        }
        else if(vm.count(OPTION_CONFIG_RANGE))
        {
            cout << OPTION_CONFIG_RANGE << ": ";
            BOOST_FOREACH(int i, runConfigRangeVec)
                cout << i << ", ";
            cout << endl;

            if(runConfigRangeVec.size() == 2
                    && runConfigRangeVec[0] >= 0
                    && runConfigRangeVec[0] <= runConfigRangeVec[1]
                    && runConfigRangeVec[1] < INDEXER_TEST_CONFIG_NUM)
                configVec.insert(configVec.begin(), INDEXER_TEST_CONFIGS + runConfigRangeVec[0],
                                                    INDEXER_TEST_CONFIGS + runConfigRangeVec[1] + 1);
            else
            {
                ostringstream oss;
                oss << "the config range is invalid";
                throw std::runtime_error(oss.str());
            }
        }
        else
        {
            cout << "run all configs" << endl;
            configVec.insert(configVec.begin(), INDEXER_TEST_CONFIGS,
                                                INDEXER_TEST_CONFIGS + INDEXER_TEST_CONFIG_NUM);
        }
    }
    catch(std::exception& e)
    {
        cerr << "error: " << e.what() << endl;
        return false;
    }

    return true;
}

/**
 * Boost test module initialize function, it regsiters the test cases to run.
 * @return true for success, false for failure
 */
bool my_init_unit_test()
{
    vector<IndexerTestConfig> configVec;
    if(! loadConfigOption(configVec))
        return false;

    const IndexerTestConfig* const pConfigStart = &configVec[0];
    const IndexerTestConfig* const pConfigEnd = pConfigStart + configVec.size();

    test_suite* tsIndexReader = BOOST_TEST_SUITE("t_IndexReader");
    tsIndexReader->add(BOOST_PARAM_TEST_CASE(&t_IndexReader::index, pConfigStart, pConfigEnd));
    tsIndexReader->add(BOOST_PARAM_TEST_CASE(&t_IndexReader::update, pConfigStart, pConfigEnd));
    tsIndexReader->add(BOOST_PARAM_TEST_CASE(&t_IndexReader::remove, pConfigStart, pConfigEnd));
    framework::master_test_suite().add(tsIndexReader);

    test_suite* tsBarrelsInfo = BOOST_TEST_SUITE("t_BarrelsInfo");
    tsBarrelsInfo->add(BOOST_PARAM_TEST_CASE(&t_BarrelsInfo::index, pConfigStart, pConfigEnd));
    tsBarrelsInfo->add(BOOST_PARAM_TEST_CASE(&t_BarrelsInfo::optimize, pConfigStart, pConfigEnd));
    tsBarrelsInfo->add(BOOST_PARAM_TEST_CASE(&t_BarrelsInfo::createAfterOptimize, pConfigStart, pConfigEnd));
    tsBarrelsInfo->add(BOOST_PARAM_TEST_CASE(&t_BarrelsInfo::pauseResumeMerge, pConfigStart, pConfigEnd));
    framework::master_test_suite().add(tsBarrelsInfo);

    test_suite* tsTermDocFreqs = BOOST_TEST_SUITE("t_TermDocFreqs");
    tsTermDocFreqs->add(BOOST_PARAM_TEST_CASE(&t_TermDocFreqs::index, pConfigStart, pConfigEnd));
    tsTermDocFreqs->add(BOOST_PARAM_TEST_CASE(&t_TermDocFreqs::update, pConfigStart, pConfigEnd));
    tsTermDocFreqs->add(BOOST_PARAM_TEST_CASE(&t_TermDocFreqs::remove, pConfigStart, pConfigEnd));
    framework::master_test_suite().add(tsTermDocFreqs);

    return true;
}

int main( int argc, char* argv[] )
{
    google::InitGoogleLogging(argv[0]);

    return ::boost::unit_test::unit_test_main( &my_init_unit_test, argc, argv );
}
<commit_msg>in "t_integration_Indexer", set default configs range to run.<commit_after>#include <vector>
#include <sstream> // std::ostringstream
#include <boost/test/unit_test.hpp>
#include <boost/test/parameterized_test.hpp>
#include <boost/program_options.hpp>
#include <boost/foreach.hpp>

#include <glog/logging.h>

#include "IndexerTestFixture.h"
#include "t_IndexReader.h"
#include "t_BarrelsInfo.h"
#include "t_TermDocFreqs.h"

using namespace std;
using namespace boost::unit_test;
namespace po = boost::program_options;

namespace {
/** the parameters for each test case */
const IndexerTestConfig INDEXER_TEST_CONFIGS[] = {
    {0, 1, 1, "default", true},
    {1, 1, 1, "realtime", true},
    {2, 5, 3, "default", true},
    {3, 5, 3, "realtime", true},
    {4, 10, 6, "default", true},
    {5, 10, 6, "realtime", true},
    {6, 100, 23, "default", true},
    {7, 100, 23, "realtime", true},
    {8, 1000, 10, "default", true},
    {9, 1000, 10, "realtime", true},
};

/** the parameter number */
const int INDEXER_TEST_CONFIG_NUM = sizeof(INDEXER_TEST_CONFIGS) / sizeof(IndexerTestConfig);

/** if the command options of "--run_config_list" or "--run_config_range" are not specified, run configs of range [0, DEFAULT_CONFIG_RANGE] */
const int DEFAULT_CONFIG_RANGE = 5;

/** the command option to specify a list of config numbers, such as "--run_config_list 0 1 2 3" */
const char* OPTION_CONFIG_LIST = "run_config_list";

/** the command option to specify a range of config numbers, such as "--run_config_range 4 7" */
const char* OPTION_CONFIG_RANGE = "run_config_range";
}

/**
 * Load command line option "run_config_list" or "run_config_range" to decide which configs to run.
 * @param configVec the loaded configs to run
 * @return true for load success, false for fail
 */
bool loadConfigOption(vector<IndexerTestConfig>& configVec)
{
    try
    {
        vector<int> runConfigListVec;
        vector<int> runConfigRangeVec;
        po::options_description desp("Allowed options");
        desp.add_options()
            (OPTION_CONFIG_LIST, po::value<std::vector<int> >(&runConfigListVec)->multitoken(), "specify the list of config parameters to run")
            (OPTION_CONFIG_RANGE, po::value<std::vector<int> >(&runConfigRangeVec)->multitoken(), "specify the range of config parameters to run")
            ;

        po::options_description cmdline_options;
        cmdline_options.add(desp);

        po::variables_map vm;
        store(po::command_line_parser(framework::master_test_suite().argc, framework::master_test_suite().argv).options(cmdline_options).run(), vm);
        po::notify(vm);

        if(vm.count(OPTION_CONFIG_LIST))
        {
            cout << OPTION_CONFIG_LIST << ": ";
            BOOST_FOREACH(int i, runConfigListVec)
            {
                cout << i << ", ";
                if(i >= 0 && i < INDEXER_TEST_CONFIG_NUM)
                    configVec.push_back(INDEXER_TEST_CONFIGS[i]);
                else
                {
                    cout << endl;
                    ostringstream oss;
                    oss << "unknown config number " << i;
                    throw std::runtime_error(oss.str());
                }
            }
            cout << endl;
        }
        else if(vm.count(OPTION_CONFIG_RANGE))
        {
            cout << OPTION_CONFIG_RANGE << ": ";
            BOOST_FOREACH(int i, runConfigRangeVec)
                cout << i << ", ";
            cout << endl;

            if(runConfigRangeVec.size() == 2
                    && runConfigRangeVec[0] >= 0
                    && runConfigRangeVec[0] <= runConfigRangeVec[1]
                    && runConfigRangeVec[1] < INDEXER_TEST_CONFIG_NUM)
                configVec.insert(configVec.begin(), INDEXER_TEST_CONFIGS + runConfigRangeVec[0],
                                                    INDEXER_TEST_CONFIGS + runConfigRangeVec[1] + 1);
            else
            {
                ostringstream oss;
                oss << "the config range is invalid";
                throw std::runtime_error(oss.str());
            }
        }
        else
        {
            cout << "run default configs range: [0, " << DEFAULT_CONFIG_RANGE << "]" << endl;
            configVec.insert(configVec.begin(), INDEXER_TEST_CONFIGS,
                                                INDEXER_TEST_CONFIGS + DEFAULT_CONFIG_RANGE + 1);
        }
    }
    catch(std::exception& e)
    {
        cerr << "error: " << e.what() << endl;
        return false;
    }

    return true;
}

/**
 * Boost test module initialize function, it regsiters the test cases to run.
 * @return true for success, false for failure
 */
bool my_init_unit_test()
{
    vector<IndexerTestConfig> configVec;
    if(! loadConfigOption(configVec))
        return false;

    const IndexerTestConfig* const pConfigStart = &configVec[0];
    const IndexerTestConfig* const pConfigEnd = pConfigStart + configVec.size();

    test_suite* tsIndexManager = BOOST_TEST_SUITE("index_manager");

    test_suite* tsIndexReader = BOOST_TEST_SUITE("t_IndexReader");
    tsIndexReader->add(BOOST_PARAM_TEST_CASE(&t_IndexReader::index, pConfigStart, pConfigEnd));
    tsIndexReader->add(BOOST_PARAM_TEST_CASE(&t_IndexReader::update, pConfigStart, pConfigEnd));
    tsIndexReader->add(BOOST_PARAM_TEST_CASE(&t_IndexReader::remove, pConfigStart, pConfigEnd));
    tsIndexManager->add(tsIndexReader);

    test_suite* tsBarrelsInfo = BOOST_TEST_SUITE("t_BarrelsInfo");
    tsBarrelsInfo->add(BOOST_PARAM_TEST_CASE(&t_BarrelsInfo::index, pConfigStart, pConfigEnd));
    tsBarrelsInfo->add(BOOST_PARAM_TEST_CASE(&t_BarrelsInfo::optimize, pConfigStart, pConfigEnd));
    tsBarrelsInfo->add(BOOST_PARAM_TEST_CASE(&t_BarrelsInfo::createAfterOptimize, pConfigStart, pConfigEnd));
    tsBarrelsInfo->add(BOOST_PARAM_TEST_CASE(&t_BarrelsInfo::pauseResumeMerge, pConfigStart, pConfigEnd));
    tsIndexManager->add(tsBarrelsInfo);

    test_suite* tsTermDocFreqs = BOOST_TEST_SUITE("t_TermDocFreqs");
    tsTermDocFreqs->add(BOOST_PARAM_TEST_CASE(&t_TermDocFreqs::index, pConfigStart, pConfigEnd));
    tsTermDocFreqs->add(BOOST_PARAM_TEST_CASE(&t_TermDocFreqs::update, pConfigStart, pConfigEnd));
    tsTermDocFreqs->add(BOOST_PARAM_TEST_CASE(&t_TermDocFreqs::remove, pConfigStart, pConfigEnd));
    tsIndexManager->add(tsTermDocFreqs);

    framework::master_test_suite().add(tsIndexManager);
    return true;
}

int main( int argc, char* argv[] )
{
    google::InitGoogleLogging(argv[0]);

    return ::boost::unit_test::unit_test_main( &my_init_unit_test, argc, argv );
}
<|endoftext|>


<commit_before>/**\file
 * \brief Test cases for the static range sequencer
 *
 * Test cases in this file verify that the code in the range.h header work
 * correctly.
 *
 * \copyright
 * Copyright (c) 2013, ef.gy Project Members
 * \copyright
 * 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:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * 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.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: http://git.becquerel.org/jyujin/libefgy.git
 */

#include <iostream>
#include <string>

#include <ef.gy/test-case.h>
#include <ef.gy/range.h>
#include <algorithm>

using namespace efgy;

/**\brief Test case for the static ranged sequence generator
 * \test Creates a series of ranged sequences and verifies they're correct by
 *       comparing the results to reference data.
 *
 * \param[out] log A stream for test cases to log messages to.
 *
 * \return Zero when everything went as expected, nonzero otherwise.
 */
int testRange (std::ostream &log)
{
    if (range<int,5>::get() != std::array<int,5>({{ 0, 1, 2, 3, 4 }}))
    {
        log << "5-element sequence does not have the expected value.\n";
        return -1;
    }

    if (range<int,5>::get(1000) != std::array<int,5>({{ 1000, 1001, 1002, 1003, 1004 }}))
    {
        log << "5-element sequence does not have the expected value.\n";
        return -2;
    }

    if (sequence<int,49,42>() != std::array<int,8>({{ 49, 48, 47, 46, 45, 44, 43, 42 }}))
    {
        log << "8-element sequence does not have the expected value.\n";
        return -3;
    }

    std::array<int,8> a1 = sequence<int,42,49>();
    std::size_t p = 0;

    for (int i : range<int,8>(42))
    {
        if (i != a1[p])
        {
            log << "range iterator did not produce the expected results.\n";
            return -4;
        }

        p++;
    }

    if (!std::equal (a1.begin(), a1.end(), range<int,8>(42).begin()))
    {
        log << "range iterator did not produce the expected results.\n";
        return -5;
    }

    std::array<int,8> a2 = sequence<int,49,42>();

    if (!std::equal (a2.begin(), a2.end(), range<int,8>(49,42).begin()))
    {
        log << "range iterator did not produce the expected results.\n";
        return -6;
    }

    if (!std::equal (a2.begin(), a2.end(), range<int>(49,42,8,true).begin()))
    {
        log << "range iterator did not produce the expected results.\n";
        return -7;
    }

    return 0;
}

TEST_BATCH(testRange)
<commit_msg>odd, this test case ought to have failed<commit_after>/**\file
 * \brief Test cases for the static range sequencer
 *
 * Test cases in this file verify that the code in the range.h header work
 * correctly.
 *
 * \copyright
 * Copyright (c) 2013, ef.gy Project Members
 * \copyright
 * 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:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * 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.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: http://git.becquerel.org/jyujin/libefgy.git
 */

#include <iostream>
#include <string>

#include <ef.gy/test-case.h>
#include <ef.gy/range.h>
#include <algorithm>

using namespace efgy;

/**\brief Test case for the static ranged sequence generator
 * \test Creates a series of ranged sequences and verifies they're correct by
 *       comparing the results to reference data.
 *
 * \param[out] log A stream for test cases to log messages to.
 *
 * \return Zero when everything went as expected, nonzero otherwise.
 */
int testRange (std::ostream &log)
{
    if (range<int,5>::get() != std::array<int,5>({{ 0, 1, 2, 3, 4 }}))
    {
        log << "5-element sequence does not have the expected value.\n";
        return -1;
    }

    if (range<int,5>::get(1000) != std::array<int,5>({{ 1000, 1001, 1002, 1003, 1004 }}))
    {
        log << "5-element sequence does not have the expected value.\n";
        return -2;
    }

    if (sequence<int,49,42>() != std::array<int,8>({{ 49, 48, 47, 46, 45, 44, 43, 42 }}))
    {
        log << "8-element sequence does not have the expected value.\n";
        return -3;
    }

    std::array<int,8> a1 = sequence<int,42,49>();
    std::size_t p = 0;

    for (int i : range<int,8>(42))
    {
        if (i != a1[p])
        {
            log << "range iterator did not produce the expected results.\n";
            return -4;
        }

        p++;
    }

    if (!std::equal (a1.begin(), a1.end(), range<int,8>(42).begin()))
    {
        log << "range iterator did not produce the expected results.\n";
        return -5;
    }

    std::array<int,8> a2 = sequence<int,49,42>();

    if (!std::equal (a2.begin(), a2.end(), range<int,8>(49,42).begin()))
    {
        log << "range iterator did not produce the expected results.\n";
        return -6;
    }

    if (!std::equal (a2.begin(), a2.end(), range<int>(49,42,8,true).begin()))
    {
        log << "range iterator did not produce the expected results.\n";
        return -7;
    }

    if (!std::equal (a1.begin(), a1.end(), range<int>(42,49,true).begin()))
    {
        log << "range iterator did not produce the expected results.\n";
        return -8;
    }

    return 0;
}

TEST_BATCH(testRange)
<|endoftext|>


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

#include "hash.h"
#include "utilstrencodings.h"
#include "test/test_bitcoin.h"
#include "test/test_random.h"

#include <vector>

#include <boost/test/unit_test.hpp>

using namespace std;

BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(murmurhash3)
{

#define T(expected, seed, data) BOOST_CHECK_EQUAL(MurmurHash3(seed, ParseHex(data)), expected)

    // Test MurmurHash3 with various inputs. Of course this is retested in the
    // bloom filter tests - they would fail if MurmurHash3() had any problems -
    // but is useful for those trying to implement Bitcoin libraries as a
    // source of test data for their MurmurHash3() primitive during
    // development.
    //
    // The magic number 0xFBA4C795 comes from CBloomFilter::Hash()

    T(0x00000000u, 0x00000000u, "");
    T(0x6a396f08u, 0xFBA4C795u, "");
    T(0x81f16f39u, 0xffffffffu, "");

    T(0x514e28b7u, 0x00000000u, "00");
    T(0xea3f0b17u, 0xFBA4C795u, "00");
    T(0xfd6cf10du, 0x00000000u, "ff");

    T(0x16c6b7abu, 0x00000000u, "0011");
    T(0x8eb51c3du, 0x00000000u, "001122");
    T(0xb4471bf8u, 0x00000000u, "00112233");
    T(0xe2301fa8u, 0x00000000u, "0011223344");
    T(0xfc2e4a15u, 0x00000000u, "001122334455");
    T(0xb074502cu, 0x00000000u, "00112233445566");
    T(0x8034d2a0u, 0x00000000u, "0011223344556677");
    T(0xb4698defu, 0x00000000u, "001122334455667788");

#undef T
}

/*
   SipHash-2-4 output with
   k = 00 01 02 ...
   and
   in = (empty string)
   in = 00 (1 byte)
   in = 00 01 (2 bytes)
   in = 00 01 02 (3 bytes)
   ...
   in = 00 01 02 ... 3e (63 bytes)

   from: https://131002.net/siphash/siphash24.c
*/
uint64_t siphash_4_2_testvec[] = {
    0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d,
    0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137,
    0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
    0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5,
    0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd,
    0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
    0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad,
    0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342,
    0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
    0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c,
    0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95,
    0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
    0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a,
    0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499,
    0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
    0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572
};

BOOST_AUTO_TEST_CASE(siphash)
{
    CSipHasher hasher(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x726fdb47dd0e0e31ull);
    static const unsigned char t0[1] = {0};
    hasher.Write(t0, 1);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x74f839c593dc67fdull);
    static const unsigned char t1[7] = {1,2,3,4,5,6,7};
    hasher.Write(t1, 7);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x93f5f5799a932462ull);
    hasher.Write(0x0F0E0D0C0B0A0908ULL);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x3f2acc7f57c29bdbull);
    static const unsigned char t2[2] = {16,17};
    hasher.Write(t2, 2);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x4bc1b3f0968dd39cull);
    static const unsigned char t3[9] = {18,19,20,21,22,23,24,25,26};
    hasher.Write(t3, 9);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x2f2e6163076bcfadull);
    static const unsigned char t4[5] = {27,28,29,30,31};
    hasher.Write(t4, 5);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x7127512f72f27cceull);
    hasher.Write(0x2726252423222120ULL);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x0e3ea96b5304a7d0ull);
    hasher.Write(0x2F2E2D2C2B2A2928ULL);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0xe612a3cb9ecba951ull);

    BOOST_CHECK_EQUAL(SipHashUint256(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL, uint256S("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100")), 0x7127512f72f27cceull);

    // Check test vectors from spec, one byte at a time
    CSipHasher hasher2(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
    for (uint8_t x=0; x<ARRAYLEN(siphash_4_2_testvec); ++x)
    {
        BOOST_CHECK_EQUAL(hasher2.Finalize(), siphash_4_2_testvec[x]);
        hasher2.Write(&x, 1);
    }
    // Check test vectors from spec, eight bytes at a time
    CSipHasher hasher3(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
    for (uint8_t x=0; x<ARRAYLEN(siphash_4_2_testvec); x+=8)
    {
        BOOST_CHECK_EQUAL(hasher3.Finalize(), siphash_4_2_testvec[x]);
        hasher3.Write(uint64_t(x)|(uint64_t(x+1)<<8)|(uint64_t(x+2)<<16)|(uint64_t(x+3)<<24)|
                     (uint64_t(x+4)<<32)|(uint64_t(x+5)<<40)|(uint64_t(x+6)<<48)|(uint64_t(x+7)<<56));
    }

    CHashWriter ss(SER_DISK, CLIENT_VERSION);
    ss << CTransaction();
    BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL);

    // Check consistency between CSipHasher and SipHashUint256[Extra].
    FastRandomContext ctx;
    for (int i = 0; i < 16; ++i) {
        uint64_t k1 = ctx.rand64();
        uint64_t k2 = ctx.rand64();
        uint256 x = GetRandHash();
        uint32_t n = ctx.rand32();
        uint8_t nb[4];
        WriteLE32(nb, n);
        CSipHasher sip256(k1, k2);
        sip256.Write(x.begin(), 32);
        CSipHasher sip288 = sip256;
        sip288.Write(nb, 4);
        BOOST_CHECK_EQUAL(SipHashUint256(k1, k2, x), sip256.Finalize());
        BOOST_CHECK_EQUAL(SipHashUint256Extra(k1, k2, x, n), sip288.Finalize());
    }
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Preserve tx version=1 for certain tests<commit_after>// Copyright (c) 2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "hash.h"
#include "utilstrencodings.h"
#include "test/test_bitcoin.h"
#include "test/test_random.h"

#include <vector>

#include <boost/test/unit_test.hpp>

using namespace std;

BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(murmurhash3)
{

#define T(expected, seed, data) BOOST_CHECK_EQUAL(MurmurHash3(seed, ParseHex(data)), expected)

    // Test MurmurHash3 with various inputs. Of course this is retested in the
    // bloom filter tests - they would fail if MurmurHash3() had any problems -
    // but is useful for those trying to implement Bitcoin libraries as a
    // source of test data for their MurmurHash3() primitive during
    // development.
    //
    // The magic number 0xFBA4C795 comes from CBloomFilter::Hash()

    T(0x00000000u, 0x00000000u, "");
    T(0x6a396f08u, 0xFBA4C795u, "");
    T(0x81f16f39u, 0xffffffffu, "");

    T(0x514e28b7u, 0x00000000u, "00");
    T(0xea3f0b17u, 0xFBA4C795u, "00");
    T(0xfd6cf10du, 0x00000000u, "ff");

    T(0x16c6b7abu, 0x00000000u, "0011");
    T(0x8eb51c3du, 0x00000000u, "001122");
    T(0xb4471bf8u, 0x00000000u, "00112233");
    T(0xe2301fa8u, 0x00000000u, "0011223344");
    T(0xfc2e4a15u, 0x00000000u, "001122334455");
    T(0xb074502cu, 0x00000000u, "00112233445566");
    T(0x8034d2a0u, 0x00000000u, "0011223344556677");
    T(0xb4698defu, 0x00000000u, "001122334455667788");

#undef T
}

/*
   SipHash-2-4 output with
   k = 00 01 02 ...
   and
   in = (empty string)
   in = 00 (1 byte)
   in = 00 01 (2 bytes)
   in = 00 01 02 (3 bytes)
   ...
   in = 00 01 02 ... 3e (63 bytes)

   from: https://131002.net/siphash/siphash24.c
*/
uint64_t siphash_4_2_testvec[] = {
    0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d,
    0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137,
    0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
    0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5,
    0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd,
    0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
    0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad,
    0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342,
    0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
    0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c,
    0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95,
    0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
    0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a,
    0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499,
    0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
    0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572
};

BOOST_AUTO_TEST_CASE(siphash)
{
    CSipHasher hasher(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x726fdb47dd0e0e31ull);
    static const unsigned char t0[1] = {0};
    hasher.Write(t0, 1);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x74f839c593dc67fdull);
    static const unsigned char t1[7] = {1,2,3,4,5,6,7};
    hasher.Write(t1, 7);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x93f5f5799a932462ull);
    hasher.Write(0x0F0E0D0C0B0A0908ULL);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x3f2acc7f57c29bdbull);
    static const unsigned char t2[2] = {16,17};
    hasher.Write(t2, 2);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x4bc1b3f0968dd39cull);
    static const unsigned char t3[9] = {18,19,20,21,22,23,24,25,26};
    hasher.Write(t3, 9);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x2f2e6163076bcfadull);
    static const unsigned char t4[5] = {27,28,29,30,31};
    hasher.Write(t4, 5);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x7127512f72f27cceull);
    hasher.Write(0x2726252423222120ULL);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0x0e3ea96b5304a7d0ull);
    hasher.Write(0x2F2E2D2C2B2A2928ULL);
    BOOST_CHECK_EQUAL(hasher.Finalize(),  0xe612a3cb9ecba951ull);

    BOOST_CHECK_EQUAL(SipHashUint256(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL, uint256S("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100")), 0x7127512f72f27cceull);

    // Check test vectors from spec, one byte at a time
    CSipHasher hasher2(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
    for (uint8_t x=0; x<ARRAYLEN(siphash_4_2_testvec); ++x)
    {
        BOOST_CHECK_EQUAL(hasher2.Finalize(), siphash_4_2_testvec[x]);
        hasher2.Write(&x, 1);
    }
    // Check test vectors from spec, eight bytes at a time
    CSipHasher hasher3(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
    for (uint8_t x=0; x<ARRAYLEN(siphash_4_2_testvec); x+=8)
    {
        BOOST_CHECK_EQUAL(hasher3.Finalize(), siphash_4_2_testvec[x]);
        hasher3.Write(uint64_t(x)|(uint64_t(x+1)<<8)|(uint64_t(x+2)<<16)|(uint64_t(x+3)<<24)|
                     (uint64_t(x+4)<<32)|(uint64_t(x+5)<<40)|(uint64_t(x+6)<<48)|(uint64_t(x+7)<<56));
    }

    CHashWriter ss(SER_DISK, CLIENT_VERSION);
    CMutableTransaction tx;
    // Note these tests were originally written with tx.nVersion=1
    // and the test would be affected by default tx version bumps if not fixed.
    tx.nVersion = 1;
    ss << tx;
    BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL);

    // Check consistency between CSipHasher and SipHashUint256[Extra].
    FastRandomContext ctx;
    for (int i = 0; i < 16; ++i) {
        uint64_t k1 = ctx.rand64();
        uint64_t k2 = ctx.rand64();
        uint256 x = GetRandHash();
        uint32_t n = ctx.rand32();
        uint8_t nb[4];
        WriteLE32(nb, n);
        CSipHasher sip256(k1, k2);
        sip256.Write(x.begin(), 32);
        CSipHasher sip288 = sip256;
        sip288.Write(nb, 4);
        BOOST_CHECK_EQUAL(SipHashUint256(k1, k2, x), sip256.Finalize());
        BOOST_CHECK_EQUAL(SipHashUint256Extra(k1, k2, x, n), sip288.Finalize());
    }
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: clipboardctl.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 18:32:12 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#ifndef _SFXAPP_HXX
#include <sfx2/app.hxx>
#endif
#ifndef _SFXTBXCTRL_HXX
#include <sfx2/tbxctrl.hxx>
#endif
#ifndef _SFX_BINDINGS_HXX
#include <sfx2/bindings.hxx>
#endif
#ifndef _SFXDISPATCH_HXX
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef _SFXINTITEM_HXX
#include <svtools/intitem.hxx>
#endif
#ifndef _SOT_EXCHANGE_HXX
#include <sot/exchange.hxx>
#endif
#ifndef _SFXENUMITEM_HXX
#include <svtools/eitem.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX
#include <vcl/toolbox.hxx>
#endif

#ifndef _SVX_CLIPBOARDCTL_HXX_
#include <clipboardctl.hxx>
#endif
#ifndef _SVX_CLIPFMTITEM_HXX
#include <clipfmtitem.hxx>
#endif

#include <svtools/insdlg.hxx>
#include <svx/svxids.hrc>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;

/////////////////////////////////////////////////////////////////

SFX_IMPL_TOOLBOX_CONTROL( SvxClipBoardControl, SfxVoidItem /*SfxUInt16Item*/ );

SvxClipBoardControl::SvxClipBoardControl(
        USHORT nSlotId, USHORT nId, ToolBox& rTbx ) :

    SfxToolBoxControl( nSlotId, nId, rTbx ),
    pClipboardFmtItem( 0 ),
     pPopup     (0),
    nItemId     (nId),
    bDisabled( FALSE )
{
    addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ClipboardFormatItems" )));
    ToolBox& rBox = GetToolBox();
    rBox.SetItemBits( nId, TIB_DROPDOWN | rBox.GetItemBits( nId ) );
    rBox.Invalidate();
}

SvxClipBoardControl::~SvxClipBoardControl()
{
    DelPopup();
    delete pClipboardFmtItem;
}

SfxPopupWindow* SvxClipBoardControl::CreatePopupWindow()
{
    const SvxClipboardFmtItem* pFmtItem = PTR_CAST( SvxClipboardFmtItem, pClipboardFmtItem );
    if ( pFmtItem )
    {
        if (pPopup)
            pPopup->Clear();
        else
            pPopup = new PopupMenu;

        USHORT nCount = pFmtItem->Count();
        for (USHORT i = 0;  i < nCount;  ++i)
        {
            ULONG nFmtID =  pFmtItem->GetClipbrdFormatId( i );
            String aFmtStr( pFmtItem->GetClipbrdFormatName( i ) );
            if (!aFmtStr.Len())
              aFmtStr = SvPasteObjectHelper::GetSotFormatUIName( nFmtID );
            pPopup->InsertItem( (USHORT)nFmtID, aFmtStr );
        }

        ToolBox& rBox = GetToolBox();
        USHORT nId = GetId();
        rBox.SetItemDown( nId, TRUE );

        pPopup->Execute( &rBox, rBox.GetItemRect( nId ),
            (rBox.GetAlign() == WINDOWALIGN_TOP || rBox.GetAlign() == WINDOWALIGN_BOTTOM) ?
                POPUPMENU_EXECUTE_DOWN : POPUPMENU_EXECUTE_RIGHT );

        rBox.SetItemDown( nId, FALSE );

        SfxUInt32Item aItem( SID_CLIPBOARD_FORMAT_ITEMS, pPopup->GetCurItemId() );

        Any a;
        Sequence< PropertyValue > aArgs( 1 );
        aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectedFormat" ));
        aItem.QueryValue( a );
        aArgs[0].Value = a;
        Dispatch( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ClipboardFormatItems" )),
                  aArgs );
    }

    GetToolBox().EndSelection();
    DelPopup();
    return 0;
}

SfxPopupWindowType SvxClipBoardControl::GetPopupWindowType() const
{
    return SFX_POPUPWINDOW_ONTIMEOUT;
}

void SvxClipBoardControl::StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState )
{
    if ( SID_CLIPBOARD_FORMAT_ITEMS == nSID )
    {
        DELETEZ( pClipboardFmtItem );
        if ( eState >= SFX_ITEM_AVAILABLE )
        {
            pClipboardFmtItem = pState->Clone();
            GetToolBox().SetItemBits( GetId(), GetToolBox().GetItemBits( GetId() ) | TIB_DROPDOWN );
        }
        else if ( !bDisabled )
            GetToolBox().SetItemBits( GetId(), GetToolBox().GetItemBits( GetId() ) & ~TIB_DROPDOWN );
        GetToolBox().Invalidate( GetToolBox().GetItemRect( GetId() ) );
    }
    else
    {
        // enable the item as a whole
        bDisabled = (GetItemState(pState) == SFX_ITEM_DISABLED);
        GetToolBox().EnableItem( GetId(), (GetItemState(pState) != SFX_ITEM_DISABLED) );
    }
}

void SvxClipBoardControl::DelPopup()
{
    if(pPopup)
    {
        delete pPopup;
        pPopup = 0;
    }
}

/////////////////////////////////////////////////////////////////

<commit_msg>INTEGRATION: CWS changefileheader (1.14.368); FILE MERGED 2008/04/01 15:51:19 thb 1.14.368.3: #i85898# Stripping all external header guards 2008/04/01 12:49:17 thb 1.14.368.2: #i85898# Stripping all external header guards 2008/03/31 14:22:50 rt 1.14.368.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: clipboardctl.cxx,v $
 * $Revision: 1.15 $
 *
 * 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.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <sfx2/app.hxx>
#include <sfx2/tbxctrl.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <tools/gen.hxx>
#include <svtools/intitem.hxx>
#include <sot/exchange.hxx>
#include <svtools/eitem.hxx>
#include <vcl/toolbox.hxx>
#include <clipboardctl.hxx>
#include <clipfmtitem.hxx>

#include <svtools/insdlg.hxx>
#include <svx/svxids.hrc>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;

/////////////////////////////////////////////////////////////////

SFX_IMPL_TOOLBOX_CONTROL( SvxClipBoardControl, SfxVoidItem /*SfxUInt16Item*/ );

SvxClipBoardControl::SvxClipBoardControl(
        USHORT nSlotId, USHORT nId, ToolBox& rTbx ) :

    SfxToolBoxControl( nSlotId, nId, rTbx ),
    pClipboardFmtItem( 0 ),
     pPopup     (0),
    nItemId     (nId),
    bDisabled( FALSE )
{
    addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ClipboardFormatItems" )));
    ToolBox& rBox = GetToolBox();
    rBox.SetItemBits( nId, TIB_DROPDOWN | rBox.GetItemBits( nId ) );
    rBox.Invalidate();
}

SvxClipBoardControl::~SvxClipBoardControl()
{
    DelPopup();
    delete pClipboardFmtItem;
}

SfxPopupWindow* SvxClipBoardControl::CreatePopupWindow()
{
    const SvxClipboardFmtItem* pFmtItem = PTR_CAST( SvxClipboardFmtItem, pClipboardFmtItem );
    if ( pFmtItem )
    {
        if (pPopup)
            pPopup->Clear();
        else
            pPopup = new PopupMenu;

        USHORT nCount = pFmtItem->Count();
        for (USHORT i = 0;  i < nCount;  ++i)
        {
            ULONG nFmtID =  pFmtItem->GetClipbrdFormatId( i );
            String aFmtStr( pFmtItem->GetClipbrdFormatName( i ) );
            if (!aFmtStr.Len())
              aFmtStr = SvPasteObjectHelper::GetSotFormatUIName( nFmtID );
            pPopup->InsertItem( (USHORT)nFmtID, aFmtStr );
        }

        ToolBox& rBox = GetToolBox();
        USHORT nId = GetId();
        rBox.SetItemDown( nId, TRUE );

        pPopup->Execute( &rBox, rBox.GetItemRect( nId ),
            (rBox.GetAlign() == WINDOWALIGN_TOP || rBox.GetAlign() == WINDOWALIGN_BOTTOM) ?
                POPUPMENU_EXECUTE_DOWN : POPUPMENU_EXECUTE_RIGHT );

        rBox.SetItemDown( nId, FALSE );

        SfxUInt32Item aItem( SID_CLIPBOARD_FORMAT_ITEMS, pPopup->GetCurItemId() );

        Any a;
        Sequence< PropertyValue > aArgs( 1 );
        aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectedFormat" ));
        aItem.QueryValue( a );
        aArgs[0].Value = a;
        Dispatch( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ClipboardFormatItems" )),
                  aArgs );
    }

    GetToolBox().EndSelection();
    DelPopup();
    return 0;
}

SfxPopupWindowType SvxClipBoardControl::GetPopupWindowType() const
{
    return SFX_POPUPWINDOW_ONTIMEOUT;
}

void SvxClipBoardControl::StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState )
{
    if ( SID_CLIPBOARD_FORMAT_ITEMS == nSID )
    {
        DELETEZ( pClipboardFmtItem );
        if ( eState >= SFX_ITEM_AVAILABLE )
        {
            pClipboardFmtItem = pState->Clone();
            GetToolBox().SetItemBits( GetId(), GetToolBox().GetItemBits( GetId() ) | TIB_DROPDOWN );
        }
        else if ( !bDisabled )
            GetToolBox().SetItemBits( GetId(), GetToolBox().GetItemBits( GetId() ) & ~TIB_DROPDOWN );
        GetToolBox().Invalidate( GetToolBox().GetItemRect( GetId() ) );
    }
    else
    {
        // enable the item as a whole
        bDisabled = (GetItemState(pState) == SFX_ITEM_DISABLED);
        GetToolBox().EnableItem( GetId(), (GetItemState(pState) != SFX_ITEM_DISABLED) );
    }
}

void SvxClipBoardControl::DelPopup()
{
    if(pPopup)
    {
        delete pPopup;
        pPopup = 0;
    }
}

/////////////////////////////////////////////////////////////////

<|endoftext|>


<commit_before>// Copyright 2011 Google Inc.
//
// 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.
//
// Decomposes an image, then dumps the blocks and references to stdout.
#include <iostream>
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/string_util.h"
#include "syzygy/core/block_graph.h"
#include "syzygy/pe/decomposer.h"
#include "syzygy/pe/pe_file.h"

using core::BlockGraph;
using core::RelativeAddress;
using pe::Decomposer;
using pe::PEFile;

bool DumpImageToText(const FilePath& image_path,
                     std::ostream& str,
                     bool basic_block_decomposition) {
  // Load the image file.
  PEFile image_file;
  if (!image_file.Init(image_path)) {
    LOG(ERROR) << "Unable to initialize image " << image_path.value();
    return false;
  }

  // And decompose it to a DecomposedImage instance.
  Decomposer decomposer(image_file, image_path);
  Decomposer::DecomposedImage decomposed;
  Decomposer::Mode mode =
      basic_block_decomposition ? Decomposer::BASIC_BLOCK_DECOMPOSITION :
                                  Decomposer::STANDARD_DECOMPOSITION;
  if (!decomposer.Decompose(&decomposed, NULL, mode)) {
    LOG(ERROR) << "Unable to decompose image " << image_path.value();
    return false;
  }

  // Then dump the image instance data.
  size_t num_refs = 0;
  BlockGraph::AddressSpace::RangeMap::const_iterator block_it(
      decomposed.address_space.address_space_impl().ranges().begin());
  BlockGraph::AddressSpace::RangeMap::const_iterator block_end(
      decomposed.address_space.address_space_impl().ranges().end());
  for (; block_it != block_end; ++block_it) {
    const BlockGraph::Block* block = block_it->second;
    RelativeAddress addr = block_it->first.start();

    str << StringPrintf("0x%08X(%d): %s\n",
                        addr.value(),
                        block->size(),
                        block->name());

    BlockGraph::Block::LabelMap::const_iterator
        label_it(block->labels().begin());
    for (; label_it != block->labels().end(); ++label_it) {
      str << "\t" << StringPrintf("+0x%04X: %s\n",
                                  label_it->first,
                                  label_it->second.c_str());
    }

    BlockGraph::Block::ReferenceMap::const_iterator ref_it(
        block->references().begin());
    for (; ref_it != block->references().end(); ++ref_it) {
      ++num_refs;
      const BlockGraph::Reference& ref = ref_it->second;
      if (ref.offset() == 0) {
        str << StringPrintf("\t+0x%04X->%s(%d)\n",
                            ref_it->first,
                            ref.referenced()->name(),
                            ref.size());
      } else {
        // See if there's a label at the desination's offset, and if so
        // use that in preference to a raw numeric offset.
        BlockGraph::Block::LabelMap::const_iterator label =
            ref.referenced()->labels().find(ref.offset());
        if (label != ref.referenced()->labels().end()) {
          str << StringPrintf("\t+0x%04X->%s:%s(%d)\n",
                              ref_it->first,
                              ref.referenced()->name(),
                              label->second.c_str(),
                              ref.size());
        } else {
          str << StringPrintf("\t+0x%04X->%s+0x%04X(%d)\n",
                              ref_it->first,
                              ref.referenced()->name(),
                              ref.offset(),
                              ref.size());
        }
      }
    }
  }

  str << "Discovered: " << decomposed.image.blocks().size() << " blocks\n"
      << "and " << num_refs << " references.";

  return true;
}

int Usage(char** argv, const char* message) {
  if (message != NULL) {
    std::cout << message << std::endl << std::endl;
  }

  std::cout <<
      "Usage: " << argv[0] << " [options]" << std::endl;
  std::cout <<
      "  A tool that uses symbol information and disassembly to decompose a\n"
      "  PE image file into discrete blocks of code (and data), and to infer\n"
      "  the references between them.\n"
      "\n"
      "Available options\n"
      "  --image=<image file>\n"
      "  --bb\t(Enables basic block decomposition)\n";

  return 1;
}

int main(int argc, char** argv) {
  HRESULT hr = ::CoInitialize(NULL);
  if (FAILED(hr)) {
    LOG(ERROR) << "CoInitialize failed with " << hr;
    return 1;
  }

  base::AtExitManager at_exit_manager;
  CommandLine::Init(argc, argv);

  CommandLine* cmd_line = CommandLine::ForCurrentProcess();
  DCHECK(cmd_line != NULL);

  std::wstring image_file = cmd_line->GetSwitchValueNative("image");
  if (image_file.empty())
    return Usage(argv, "You must provide the path to an image file.");

  bool basic_block_decomposition = cmd_line->HasSwitch("bb");

  return DumpImageToText(FilePath(image_file),
                         std::cout,
                         basic_block_decomposition) ? 0 : 1;
}
<commit_msg>Change decomposer to allow dumping basic block decomposition as well. Review URL: http://codereview.appspot.com/4538116<commit_after>// Copyright 2011 Google Inc.
//
// 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.
//
// Decomposes an image, then dumps the blocks and references to stdout.
#include <iostream>
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/string_util.h"
#include "syzygy/core/block_graph.h"
#include "syzygy/pe/decomposer.h"
#include "syzygy/pe/pe_file.h"

using core::BlockGraph;
using core::RelativeAddress;
using pe::Decomposer;
using pe::PEFile;

// Given @p address_space, dump it in text format to @p str. Also, increment
// @p num_refs with the count of the number of block references in the address
// space if @p num_refs is not NULL.
void DumpAddressSpaceToText(const BlockGraph::AddressSpace& address_space,
                            std::ostream& str,
                            size_t* num_refs) {
  BlockGraph::AddressSpace::RangeMap::const_iterator block_it(
      address_space.address_space_impl().ranges().begin());
  BlockGraph::AddressSpace::RangeMap::const_iterator block_end(
      address_space.address_space_impl().ranges().end());

  size_t refs = 0;
  for (; block_it != block_end; ++block_it) {
    const BlockGraph::Block* block = block_it->second;
    RelativeAddress addr = block_it->first.start();

    str << StringPrintf("0x%08X(%d): %s\n",
                        addr.value(),
                        block->size(),
                        block->name());

    BlockGraph::Block::LabelMap::const_iterator
        label_it(block->labels().begin());
    for (; label_it != block->labels().end(); ++label_it) {
      str << "\t" << StringPrintf("+0x%04X: %s\n",
                                  label_it->first,
                                  label_it->second.c_str());
    }

    BlockGraph::Block::ReferenceMap::const_iterator ref_it(
        block->references().begin());
    for (; ref_it != block->references().end(); ++ref_it) {
      ++refs;
      const BlockGraph::Reference& ref = ref_it->second;
      if (ref.offset() == 0) {
        str << StringPrintf("\t+0x%04X->%s(%d)\n",
                            ref_it->first,
                            ref.referenced()->name(),
                            ref.size());
      } else {
        // See if there's a label at the desination's offset, and if so
        // use that in preference to a raw numeric offset.
        BlockGraph::Block::LabelMap::const_iterator label =
            ref.referenced()->labels().find(ref.offset());
        if (label != ref.referenced()->labels().end()) {
          str << StringPrintf("\t+0x%04X->%s:%s(%d)\n",
                              ref_it->first,
                              ref.referenced()->name(),
                              label->second.c_str(),
                              ref.size());
        } else {
          str << StringPrintf("\t+0x%04X->%s+0x%04X(%d)\n",
                              ref_it->first,
                              ref.referenced()->name(),
                              ref.offset(),
                              ref.size());
        }
      }
    }
  }
  if (num_refs != NULL)
    *num_refs = refs;
}

bool DumpImageToText(const FilePath& image_path,
                     std::ostream& str,
                     bool basic_block_decomposition) {
  // Load the image file.
  PEFile image_file;
  if (!image_file.Init(image_path)) {
    LOG(ERROR) << "Unable to initialize image " << image_path.value();
    return false;
  }

  // And decompose it to a DecomposedImage instance.
  Decomposer decomposer(image_file, image_path);
  Decomposer::DecomposedImage decomposed;
  Decomposer::Mode mode =
      basic_block_decomposition ? Decomposer::BASIC_BLOCK_DECOMPOSITION :
                                  Decomposer::STANDARD_DECOMPOSITION;
  if (!decomposer.Decompose(&decomposed, NULL, mode)) {
    LOG(ERROR) << "Unable to decompose image " << image_path.value();
    return false;
  }

  size_t num_refs = 0;
  DumpAddressSpaceToText(decomposed.address_space, str, &num_refs);

  str << "Discovered: " << decomposed.image.blocks().size() << " blocks\n"
      << "and " << num_refs << " references.";

  if (basic_block_decomposition) {
    str << "\n\nBASIC BLOCKS:\n\n";
    DumpAddressSpaceToText(decomposed.basic_block_address_space, str, NULL);

    str << "Discovered: " << decomposed.basic_block_graph.blocks().size()
        << " basic blocks.";
  }

  return true;
}

int Usage(char** argv, const char* message) {
  if (message != NULL) {
    std::cout << message << std::endl << std::endl;
  }

  std::cout <<
      "Usage: " << argv[0] << " [options]" << std::endl;
  std::cout <<
      "  A tool that uses symbol information and disassembly to decompose a\n"
      "  PE image file into discrete blocks of code (and data), and to infer\n"
      "  the references between them.\n"
      "\n"
      "Available options\n"
      "  --image=<image file>\n"
      "  --bb\t(Enables basic block decomposition)\n";

  return 1;
}

int main(int argc, char** argv) {
  HRESULT hr = ::CoInitialize(NULL);
  if (FAILED(hr)) {
    LOG(ERROR) << "CoInitialize failed with " << hr;
    return 1;
  }

  base::AtExitManager at_exit_manager;
  CommandLine::Init(argc, argv);

  CommandLine* cmd_line = CommandLine::ForCurrentProcess();
  DCHECK(cmd_line != NULL);

  std::wstring image_file = cmd_line->GetSwitchValueNative("image");
  if (image_file.empty())
    return Usage(argv, "You must provide the path to an image file.");

  bool basic_block_decomposition = cmd_line->HasSwitch("bb");

  return DumpImageToText(FilePath(image_file),
                         std::cout,
                         basic_block_decomposition) ? 0 : 1;
}
<|endoftext|>


<commit_before>//
// $Id: $

# include <sys/types.h>
# include <sys/socket.h>
# include <sys/ioctl.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <fcntl.h>
# include <errno.h>
# include <unistd.h>

# include "avmthane.h"

namespace thane
{
	BEGIN_NATIVE_MAP(SocketClass)
        NATIVE_METHOD(flash_net_Socket_private_nb_connect,       SocketObject::connect)
        NATIVE_METHOD(flash_net_Socket_private_nb_disconnect,    SocketObject::disconnect)
        NATIVE_METHOD(flash_net_Socket_private_nb_read,          SocketObject::read)
        NATIVE_METHOD(flash_net_Socket_private_nb_write,         SocketObject::write)
	END_NATIVE_MAP()

	//
	// Socket
	//

	Socket::Socket()
	{
        m_descriptor = -1;
	}

	Socket::~Socket()
	{
 		if (m_descriptor >= 0) {
            close(m_descriptor);
            m_descriptor = -1;
 		}
	}

    /**
     * Returns -1 for error, 0 for keep trying, 1 for success.
     *
     * Note: No DNS lookup. Send in 127.0.0.1.
     */
    int Socket::connect (const char *host, int port)
    {
        if (-1 == m_descriptor) {
            memset(&m_host, 0, sizeof(m_host));
            m_host.sin_family = AF_INET;
            m_host.sin_port = htons(port);
            m_host.sin_addr.s_addr = inet_addr(host);
            if (m_host.sin_addr.s_addr == INADDR_NONE) {
                // TODO: throw an error instead
                return -1;
            }
            m_descriptor = socket(AF_INET, SOCK_STREAM, 0);
            if (-1 == m_descriptor) {
                // TODO: throw an error instead
                return -1;
            }
            int flags = fcntl(m_descriptor, F_GETFL, 0);
            fcntl(m_descriptor, F_SETFL, (flags > 0 ? flags : 0) | O_NONBLOCK);

            // fall through to connect
        }
        if (-1 == ::connect(m_descriptor, (struct sockaddr*) &m_host, sizeof(m_host))) {
            if (errno == EALREADY || errno == EINPROGRESS) {
                // tell caller to try us again later
                return 0;
            }
            if (errno != EISCONN) {
                // anything else is a real error
                disconnect();
                return -1;
            }
        }
        // success!
        return 1;
    }

    void Socket::disconnect ()
    {
        if (-1 != m_descriptor) {
            close(m_descriptor);
            m_descriptor = -1;
        }
    }

    int Socket::read (ByteArrayFile &bytes)
    {
        if (m_descriptor < 0) {
            return -1;
        }
        int tot_bytes = 0;

        while (true) {
            int size = ::read(m_descriptor, m_buffer, SOCK_BUF_SZ);
            if (size == 0) {
                // nothing more to read
                return tot_bytes;
            }
            if (size == -1) {
                // TODO: throw an error
                return -1;
            }
            bytes.Push(m_buffer, size);
            tot_bytes += size;
        }
    }

    int Socket::write (ByteArrayFile &bytes)
    {
        if (m_descriptor < 0) {
            return -1;
        }

        int tot_bytes = 0;
        while (true) {
            int ptr = bytes.GetFilePointer();
            int size = ::write(m_descriptor, bytes.GetBuffer() + ptr, bytes.Available());
            if (size == -1) {
                // TODO: throw an error
                return -1;
            }
            if (size == 0) {
                return tot_bytes;
            }
            bytes.Seek(ptr + size);
            tot_bytes += size;
        }
    }

	void Socket::ThrowMemoryError()
	{
		// todo throw out of memory exception
		// m_toplevel->memoryError->throwError(kOutOfMemoryError);
	}

	//
	// SocketObject
	//

	SocketObject::SocketObject(VTable *ivtable,
                               ScriptObject *delegate)
		: ScriptObject(ivtable, delegate),
		  m_socket()
	{
		c.set(&m_socket, sizeof(Socket));
	}

    int SocketObject::connect (String *host, int port)
    {
        return m_socket.connect(host->toUTF8String()->c_str(), port);
    }

    void SocketObject::disconnect ()
    {
        m_socket.disconnect();
    }

    int SocketObject::write (ByteArrayObject *bytes)
    {
        return m_socket.write(bytes->GetByteArrayFile());
    }

    int SocketObject::read (ByteArrayObject *bytes)
	{
        return m_socket.read(bytes->GetByteArrayFile());
	}

	//
	// SocketClass
	//

	SocketClass::SocketClass(VTable *vtable)
		: ClassClosure(vtable)
    {
        prototype = toplevel()->objectClass->construct();
	}

	ScriptObject* SocketClass::createInstance(VTable *ivtable,
												 ScriptObject *prototype)
    {
        return new (core()->GetGC(), ivtable->getExtraSize()) SocketObject(ivtable, prototype);
    }
}

<commit_msg>Wait, err, there's no reason to do that in a loop. Whatever it wrote it wrote, we're done.<commit_after>//
// $Id: $

# include <sys/types.h>
# include <sys/socket.h>
# include <sys/ioctl.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <fcntl.h>
# include <errno.h>
# include <unistd.h>

# include "avmthane.h"

namespace thane
{
	BEGIN_NATIVE_MAP(SocketClass)
        NATIVE_METHOD(flash_net_Socket_private_nb_connect,       SocketObject::connect)
        NATIVE_METHOD(flash_net_Socket_private_nb_disconnect,    SocketObject::disconnect)
        NATIVE_METHOD(flash_net_Socket_private_nb_read,          SocketObject::read)
        NATIVE_METHOD(flash_net_Socket_private_nb_write,         SocketObject::write)
	END_NATIVE_MAP()

	//
	// Socket
	//

	Socket::Socket()
	{
        m_descriptor = -1;
	}

	Socket::~Socket()
	{
 		if (m_descriptor >= 0) {
            close(m_descriptor);
            m_descriptor = -1;
 		}
	}

    /**
     * Returns -1 for error, 0 for keep trying, 1 for success.
     *
     * Note: No DNS lookup. Send in 127.0.0.1.
     */
    int Socket::connect (const char *host, int port)
    {
        if (-1 == m_descriptor) {
            memset(&m_host, 0, sizeof(m_host));
            m_host.sin_family = AF_INET;
            m_host.sin_port = htons(port);
            m_host.sin_addr.s_addr = inet_addr(host);
            if (m_host.sin_addr.s_addr == INADDR_NONE) {
                // TODO: throw an error instead
                return -1;
            }
            m_descriptor = socket(AF_INET, SOCK_STREAM, 0);
            if (-1 == m_descriptor) {
                // TODO: throw an error instead
                return -1;
            }
            int flags = fcntl(m_descriptor, F_GETFL, 0);
            fcntl(m_descriptor, F_SETFL, (flags > 0 ? flags : 0) | O_NONBLOCK);

            // fall through to connect
        }
        if (-1 == ::connect(m_descriptor, (struct sockaddr*) &m_host, sizeof(m_host))) {
            if (errno == EALREADY || errno == EINPROGRESS) {
                // tell caller to try us again later
                return 0;
            }
            if (errno != EISCONN) {
                // anything else is a real error
                disconnect();
                return -1;
            }
        }
        // success!
        return 1;
    }

    void Socket::disconnect ()
    {
        if (-1 != m_descriptor) {
            close(m_descriptor);
            m_descriptor = -1;
        }
    }

    int Socket::read (ByteArrayFile &bytes)
    {
        if (m_descriptor < 0) {
            return -1;
        }
        int tot_bytes = 0;

        while (true) {
            int size = ::read(m_descriptor, m_buffer, SOCK_BUF_SZ);
            if (size == 0) {
                // nothing more to read
                return tot_bytes;
            }
            if (size == -1) {
                // TODO: throw an error
                return -1;
            }
            bytes.Push(m_buffer, size);
            tot_bytes += size;
        }
    }

    int Socket::write (ByteArrayFile &bytes)
    {
        if (m_descriptor < 0) {
            return -1;
        }

        int avail = bytes.Available();
        if (avail == 0) {
            return 0;
        }
        int ptr = bytes.GetFilePointer();
        int size = ::write(m_descriptor, bytes.GetBuffer() + ptr, avail);
        if (size == -1) {
            // TODO: throw an error
            return -1;
        }

        if (size > 0) {
            bytes.Seek(ptr + size);
        }
        return size;
    }

	void Socket::ThrowMemoryError()
	{
		// todo throw out of memory exception
		// m_toplevel->memoryError->throwError(kOutOfMemoryError);
	}

	//
	// SocketObject
	//

	SocketObject::SocketObject(VTable *ivtable,
                               ScriptObject *delegate)
		: ScriptObject(ivtable, delegate),
		  m_socket()
	{
		c.set(&m_socket, sizeof(Socket));
	}

    int SocketObject::connect (String *host, int port)
    {
        return m_socket.connect(host->toUTF8String()->c_str(), port);
    }

    void SocketObject::disconnect ()
    {
        m_socket.disconnect();
    }

    int SocketObject::write (ByteArrayObject *bytes)
    {
        return m_socket.write(bytes->GetByteArrayFile());
    }

    int SocketObject::read (ByteArrayObject *bytes)
	{
        return m_socket.read(bytes->GetByteArrayFile());
	}

	//
	// SocketClass
	//

	SocketClass::SocketClass(VTable *vtable)
		: ClassClosure(vtable)
    {
        prototype = toplevel()->objectClass->construct();
	}

	ScriptObject* SocketClass::createInstance(VTable *ivtable,
												 ScriptObject *prototype)
    {
        return new (core()->GetGC(), ivtable->getExtraSize()) SocketObject(ivtable, prototype);
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017-2018 Muhammad Tayyab Akram
 *
 * 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 <cstddef>
#include <cstdint>
#include <jni.h>

#include "JavaBridge.h"
#include "Raw.h"

using namespace Tehreer;

static jint sizeOfIntPtr(JNIEnv *env, jobject obj)
{
    return sizeof(size_t);
}

static jbyte getInt8Value(JNIEnv *env, jobject obj, jlong pointer)
{
    int8_t *buffer = reinterpret_cast<int8_t *>(pointer);
    jbyte value = static_cast<jbyte>(*buffer);

    return value;
}

static jshort getInt16Value(JNIEnv *env, jobject obj, jlong pointer)
{
    int16_t *buffer = reinterpret_cast<int16_t *>(pointer);
    jshort value = static_cast<jshort>(*buffer);

    return value;
}

static jint getInt32Value(JNIEnv *env, jobject obj, jlong pointer)
{
    int32_t *buffer = reinterpret_cast<int32_t *>(pointer);
    jint value = static_cast<jint>(*buffer);

    return value;
}

static jlong getIntPtrValue(JNIEnv *env, jobject obj, jlong pointer)
{
    size_t *buffer = reinterpret_cast<size_t *>(pointer);
    jlong value = static_cast<jlong>(*buffer);

    return value;
}

static void copyInt8Buffer(JNIEnv *env, jobject obj, jlong pointer, jbyteArray destination, jint start, jint length)
{
    int8_t *buffer = reinterpret_cast<int8_t *>(pointer);
    env->SetByteArrayRegion(destination, start, length, buffer);
}

static void copyUInt16Buffer(JNIEnv *env, jobject obj, jlong pointer, jintArray destination, jint start, jint length)
{
    uint16_t *buffer = reinterpret_cast<uint16_t *>(pointer);
    void *raw = env->GetPrimitiveArrayCritical(destination, nullptr);
    jint *values = static_cast<jint *>(raw) + start;

    for (jint i = 0; i < length; i++) {
        values[i] = static_cast<jint>(buffer[i]);
    }

    env->ReleasePrimitiveArrayCritical(destination, raw, 0);
}

static void copyUIntPtrBuffer(JNIEnv *env, jobject obj, jlong pointer, jintArray destination, jint start, jint length)
{
    size_t *buffer = reinterpret_cast<size_t *>(pointer);
    void *raw = env->GetPrimitiveArrayCritical(destination, nullptr);
    jint *values = static_cast<jint *>(raw) + start;

    for (jint i = 0; i < length; i++) {
        values[i] = static_cast<jint>(buffer[i]);
    }

    env->ReleasePrimitiveArrayCritical(destination, raw, 0);
}

static void copyInt32Buffer(JNIEnv *env, jobject obj, jlong pointer, jfloatArray destination, jint start, jint length, jfloat scale)
{
    int32_t *buffer = reinterpret_cast<int32_t *>(pointer);
    void *raw = env->GetPrimitiveArrayCritical(destination, nullptr);
    jfloat *values = static_cast<jfloat *>(raw) + start;

    for (jint i = 0; i < length; i++) {
        values[i] = buffer[i] * scale;
    }

    env->ReleasePrimitiveArrayCritical(destination, raw, 0);
}

static JNINativeMethod JNI_METHODS[] = {
    { "sizeOfIntPtr", "()I", (void *)sizeOfIntPtr },
    { "getInt8Value", "(J)B", (void *)getInt8Value },
    { "getInt16Value", "(J)S", (void *)getInt16Value },
    { "getInt32Value", "(J)I", (void *)getInt32Value },
    { "getIntPtrValue", "(J)J", (void *)getIntPtrValue },
    { "copyInt8Buffer", "(J[BII)V", (void *)copyInt8Buffer },
    { "copyUInt16Buffer", "(J[III)V", (void *)copyUInt16Buffer },
    { "copyUIntPtrBuffer", "(J[III)V", (void *)copyUIntPtrBuffer },
    { "copyInt32Buffer", "(J[FIIF)V", (void *)copyInt32Buffer },
};

jint register_com_mta_tehreer_internal_Raw(JNIEnv *env)
{
    return JavaBridge::registerClass(env, "com/mta/tehreer/internal/Raw", JNI_METHODS, sizeof(JNI_METHODS) / sizeof(JNI_METHODS[0]));
}
<commit_msg>[jni] Added implementation for copying UInt8 buffer<commit_after>/*
 * Copyright (C) 2017-2018 Muhammad Tayyab Akram
 *
 * 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 <cstddef>
#include <cstdint>
#include <jni.h>

#include "JavaBridge.h"
#include "Raw.h"

using namespace Tehreer;

static jint sizeOfIntPtr(JNIEnv *env, jobject obj)
{
    return sizeof(size_t);
}

static jbyte getInt8Value(JNIEnv *env, jobject obj, jlong pointer)
{
    int8_t *buffer = reinterpret_cast<int8_t *>(pointer);
    jbyte value = static_cast<jbyte>(*buffer);

    return value;
}

static jshort getInt16Value(JNIEnv *env, jobject obj, jlong pointer)
{
    int16_t *buffer = reinterpret_cast<int16_t *>(pointer);
    jshort value = static_cast<jshort>(*buffer);

    return value;
}

static jint getInt32Value(JNIEnv *env, jobject obj, jlong pointer)
{
    int32_t *buffer = reinterpret_cast<int32_t *>(pointer);
    jint value = static_cast<jint>(*buffer);

    return value;
}

static jlong getIntPtrValue(JNIEnv *env, jobject obj, jlong pointer)
{
    size_t *buffer = reinterpret_cast<size_t *>(pointer);
    jlong value = static_cast<jlong>(*buffer);

    return value;
}

static void copyInt8Buffer(JNIEnv *env, jobject obj, jlong pointer, jbyteArray destination, jint start, jint length)
{
    int8_t *buffer = reinterpret_cast<int8_t *>(pointer);
    env->SetByteArrayRegion(destination, start, length, buffer);
}

static void copyInt32Buffer(JNIEnv *env, jobject obj, jlong pointer, jfloatArray destination, jint start, jint length, jfloat scale)
{
    int32_t *buffer = reinterpret_cast<int32_t *>(pointer);
    void *raw = env->GetPrimitiveArrayCritical(destination, nullptr);
    jfloat *values = static_cast<jfloat *>(raw) + start;

    for (jint i = 0; i < length; i++) {
        values[i] = buffer[i] * scale;
    }

    env->ReleasePrimitiveArrayCritical(destination, raw, 0);
}

static void copyUInt8Buffer(JNIEnv *env, jobject obj, jlong pointer, jintArray destination, jint start, jint length)
{
    uint8_t *buffer = reinterpret_cast<uint8_t *>(pointer);
    void *raw = env->GetPrimitiveArrayCritical(destination, nullptr);
    jint *values = static_cast<jint *>(raw) + start;

    for (jint i = 0; i < length; i++) {
        values[i] = static_cast<jint>(buffer[i]);
    }

    env->ReleasePrimitiveArrayCritical(destination, raw, 0);
}

static void copyUInt16Buffer(JNIEnv *env, jobject obj, jlong pointer, jintArray destination, jint start, jint length)
{
    uint16_t *buffer = reinterpret_cast<uint16_t *>(pointer);
    void *raw = env->GetPrimitiveArrayCritical(destination, nullptr);
    jint *values = static_cast<jint *>(raw) + start;

    for (jint i = 0; i < length; i++) {
        values[i] = static_cast<jint>(buffer[i]);
    }

    env->ReleasePrimitiveArrayCritical(destination, raw, 0);
}

static void copyUIntPtrBuffer(JNIEnv *env, jobject obj, jlong pointer, jintArray destination, jint start, jint length)
{
    size_t *buffer = reinterpret_cast<size_t *>(pointer);
    void *raw = env->GetPrimitiveArrayCritical(destination, nullptr);
    jint *values = static_cast<jint *>(raw) + start;

    for (jint i = 0; i < length; i++) {
        values[i] = static_cast<jint>(buffer[i]);
    }

    env->ReleasePrimitiveArrayCritical(destination, raw, 0);
}

static JNINativeMethod JNI_METHODS[] = {
    { "sizeOfIntPtr", "()I", (void *)sizeOfIntPtr },
    { "getInt8Value", "(J)B", (void *)getInt8Value },
    { "getInt16Value", "(J)S", (void *)getInt16Value },
    { "getInt32Value", "(J)I", (void *)getInt32Value },
    { "getIntPtrValue", "(J)J", (void *)getIntPtrValue },
    { "copyInt8Buffer", "(J[BII)V", (void *)copyInt8Buffer },
    { "copyInt32Buffer", "(J[FIIF)V", (void *)copyInt32Buffer },
    { "copyUInt8Buffer", "(J[III)V", (void *)copyUInt8Buffer },
    { "copyUInt16Buffer", "(J[III)V", (void *)copyUInt16Buffer },
    { "copyUIntPtrBuffer", "(J[III)V", (void *)copyUIntPtrBuffer },
};

jint register_com_mta_tehreer_internal_Raw(JNIEnv *env)
{
    return JavaBridge::registerClass(env, "com/mta/tehreer/internal/Raw", JNI_METHODS, sizeof(JNI_METHODS) / sizeof(JNI_METHODS[0]));
}
<|endoftext|>