text:
/*
  Copyright (c) 2017 DataStax

  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 <string>

#include <boost/test/unit_test.hpp>
#include <boost/test/debug.hpp>
#include <boost/chrono.hpp>
#include <boost/cstdint.hpp>
#include <boost/format.hpp>
#include <boost/thread.hpp>

#include "cassandra.h"
#include "execute_request.hpp"
#include "statement.hpp"
#include "test_utils.hpp"
#include "testing.hpp"

/**
 * Test harness for prepare on up or add host functionality.
 */
struct PrepareOnUpOrAddHostTests : public test_utils::SingleSessionTest {

  /**
   * Create a basic schema (system table queries won't always prepare properly)
   * and initialize prepared query strings.
   */
  PrepareOnUpOrAddHostTests()
    : SingleSessionTest(1, 0)
    , keyspace(str(boost::format("ks_%s") % test_utils::generate_unique_str(uuid_gen))) {
    test_utils::execute_query(session, str(boost::format(test_utils::CREATE_KEYSPACE_SIMPLE_FORMAT)
                                           % keyspace
                                           % "1"));
    test_utils::execute_query(session, str(boost::format("USE %s") % keyspace));

    for (int i = 1; i <= 3; ++i) {
      test_utils::execute_query(session, str(boost::format("CREATE TABLE test%d (k text PRIMARY KEY, v text)") % i));
      prepared_queries_.push_back(str(boost::format("SELECT * FROM %s.test%d") % keyspace % i));
    }

    // Make sure we equally try all available hosts
    cass_cluster_set_load_balance_round_robin(cluster);
  }

  /**
   * Get a session that is only connected to the given node.
   *
   * @param node The node the session should be connected to
   * @return The connected session
   */
  const test_utils::CassSessionPtr& session_for_node(int node) {
    if (node >= static_cast<int>(sessions.size()) || !sessions[node]) {
      sessions.resize(node + 1);

      std::stringstream ip_address;
      ip_address << ccm->get_ip_prefix() << node;

      test_utils::CassClusterPtr cluster(cass_cluster_new());
      cass_cluster_set_contact_points(cluster.get(), ip_address.str().c_str());
      cass_cluster_set_whitelist_filtering(cluster.get(), ip_address.str().c_str());
      sessions[node] = test_utils::create_session(cluster.get());
    }

    return sessions[node];
  }

  /**
   * Truncate the "system.prepared_statements" table on a given node
   *
   * @param node The node to truncate
   */
  void truncate_prepared_statements(int node) {
    test_utils::execute_query(session_for_node(node).get(),
                              "TRUNCATE TABLE system.prepared_statements");
  }

  /**
   * Verify that a nodes "system.prepared_statements" table is empty.
   *
   * @param node The node to check
   */
  void prepared_statements_is_empty(int node) {
    test_utils::CassResultPtr result;
    test_utils::execute_query(session_for_node(node).get(), "SELECT * FROM system.prepared_statements", &result);
    BOOST_REQUIRE_EQUAL(cass_result_row_count(result.get()), 0u);
  }

  /**
   * Check to see if a query has been prepared on a given node.
   *
   * @param node The node to check
   * @param query A query string
   * @return true if the query has been prepared on the node, otherwise false
   */
  bool prepared_statement_is_present(int node, const std::string& query) {
    test_utils::CassResultPtr result;
    test_utils::execute_query(session_for_node(node).get(), "SELECT * FROM system.prepared_statements", &result);

    test_utils::CassIteratorPtr iterator(cass_iterator_from_result(result.get()));
    while (cass_iterator_next(iterator.get())) {
      const CassRow* row = cass_iterator_get_row(iterator.get());
      BOOST_REQUIRE(row);

      const CassValue* query_column = cass_row_get_column_by_name(row, "query_string");
      const char* query_string;
      size_t query_string_len;
      BOOST_REQUIRE_EQUAL(cass_value_get_string(query_column, &query_string, &query_string_len), CASS_OK);

      if (query == std::string(query_string, query_string_len)) {
        return true;
      }
    }

    return false;
  }

  /**
   * Verify that all prepared queries are available on the specifed node.
   *
   * @param node The node to verify
   */
  void prepared_statements_are_present(int node) {
    for (std::vector<std::string>::const_iterator it = prepared_queries_.begin();
         it != prepared_queries_.end();
         ++it) {
      BOOST_CHECK(prepared_statement_is_present(node, (*it)));
    }
  }

  /**
   * Verify that all prepared queries are not available on the specifed node.
   *
   * @param node The node to verify
   */
  void prepared_statements_are_not_present(int node) {
    for (std::vector<std::string>::const_iterator it = prepared_queries_.begin();
         it != prepared_queries_.end();
         ++it) {
      BOOST_CHECK(!prepared_statement_is_present(node, (*it)));
    }
  }

  /**
   * Prepare all queries on a given session.
   *
   * @param session The session to prepare the queries on
   */
  void prepare_all_queries(test_utils::CassSessionPtr session) {
    for (std::vector<std::string>::const_iterator it = prepared_queries_.begin();
         it != prepared_queries_.end();
         ++it) {
      test_utils::CassFuturePtr future(cass_session_prepare(session.get(), it->c_str()));
      BOOST_REQUIRE_EQUAL(cass_future_error_code(future.get()), CASS_OK);
    }
  }

  /**
   * Wait for a session to reconnect to a node.
   *
   * @param session The session to use for waiting
   * @param node The node to wait for
   */
  void wait_for_node(test_utils::CassSessionPtr session, int node) {
    std::stringstream ip_address;
    ip_address << ccm->get_ip_prefix() << node;

    for (int i = 0; i < 30; ++i) {
      test_utils::CassStatementPtr statement(cass_statement_new("SELECT * FROM system.peers", 0));
      test_utils::CassFuturePtr future(cass_session_execute(session.get(),
                                                            statement.get()));
      std::string host(cass::get_host_from_future(future.get()).c_str());
      if (cass_future_error_code(future.get()) == CASS_OK && host == ip_address.str()) {
        return;
      }
      boost::this_thread::sleep_for(boost::chrono::seconds(1));
    }
    BOOST_REQUIRE_MESSAGE(false,
                          "Failed to wait for node " <<
                          ip_address.str() <<
                          " to become availble");
  }

  /**
   * A vector of sessions that are only connected to a single host (via the
   * whitelist policy).
   */
  std::vector<test_utils::CassSessionPtr> sessions;

  /**
   * The test's keyspace
   */
  std::string keyspace;

  /**
   * A vector of query strings to be prepared.
   */
  std::vector<std::string> prepared_queries_;
};

BOOST_FIXTURE_TEST_SUITE(prepare_on_up_or_add_host, PrepareOnUpOrAddHostTests)

/**
 * Verify that statements are not prepared when a node becomes available and
 * the prepare on up/add feature is disabled.
 *
 * @since 2.8
 * @test_category prepared
 *
 */
BOOST_AUTO_TEST_CASE(statements_should_not_be_prepared_on_up_when_disabled) {
  if (!check_version("3.10")) return;

  // Disable the prepare on up/add setting
  cass_cluster_set_prepare_on_up_or_add_host(cluster, cass_false);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster));

  // Verify that there are no statements prepared
  truncate_prepared_statements(1);
  prepared_statements_is_empty(1);

  // Populate the driver's prepared metadata cache
  prepare_all_queries(session);
  prepared_statements_are_present(1);

  // Clear all prepared queries on the server-side
  truncate_prepared_statements(1);
  prepared_statements_is_empty(1);

  // Simulate an UP event
  ccm->stop_node(1);
  ccm->start_node(1);

  // Wait for the node to become available and verify no statements have been
  // prepared
  wait_for_node(session, 1);
  prepared_statements_are_not_present(1);
}

/**
 * Verify that statements are prepared properly when a node becomes available
 * and the prepare on up/add feature is enabled.
 *
 * @since 2.8
 * @test_category prepared
 *
 */
BOOST_AUTO_TEST_CASE(statements_should_be_prepared_on_up) {
  if (!check_version("3.10")) return;

  // Enable the prepare on up/add setting
  cass_cluster_set_prepare_on_up_or_add_host(cluster, cass_true);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster));

  // Verify that there are no statements prepared
  truncate_prepared_statements(1);
  prepared_statements_is_empty(1);

  // Populate the driver's prepared metadata cache
  prepare_all_queries(session);
  prepared_statements_are_present(1);

  // Clear all prepared queries on the server-side
  truncate_prepared_statements(1);
  prepared_statements_is_empty(1);

  // Simulate an UP event
  ccm->stop_node(1);
  ccm->start_node(1);

  // Wait for the node to become available and verify that the statements
  // in the prepared metadata cache have been prepared
  wait_for_node(session, 1);
  prepared_statements_are_present(1);
}

/**
 * Verify that statements are not prepared when a new node is added to a cluster
 * and the prepare on up/add feature is disabled.
 *
 * @since 2.8
 * @test_category prepared
 *
 */
BOOST_AUTO_TEST_CASE(statements_should_not_be_prepared_on_add_when_disabled) {
  if (!check_version("3.10")) return;

  // Disable the prepare on up/add setting
  cass_cluster_set_prepare_on_up_or_add_host(cluster, cass_false);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster));

  // Verify that there are no statements prepared
  truncate_prepared_statements(1);
  prepared_statements_is_empty(1);

  // Populate the driver's prepared metadata cache
  prepare_all_queries(session);
  prepared_statements_are_present(1);

  // Add a new node
  int node = ccm->bootstrap_node();

  // Wait for the new node to become available and verify no statements have
  // been prepared
  wait_for_node(session, node);
  prepared_statements_are_not_present(node);
}

/**
 * Verify that statements are prepared properly when a new node is added to a
 * cluster and the prepare on up/add feature is enabled.
 *
 * @since 2.8
 * @test_category prepared
 *
 */
BOOST_AUTO_TEST_CASE(statements_should_be_prepared_on_add) {
  if (!check_version("3.10")) return;

  // Enable the prepare on up/add setting
  cass_cluster_set_prepare_on_up_or_add_host(cluster, cass_true);

  test_utils::CassSessionPtr session(test_utils::create_session(cluster));

  // Verify that there are no statements prepared
  truncate_prepared_statements(1);
  prepared_statements_is_empty(1);

  // Populate the driver's prepared metadata cache
  prepare_all_queries(session);
  prepared_statements_are_present(1);

  // Add a new node
  int node = ccm->bootstrap_node();

  // Wait for the new node to become available and verify that the statements
  // in the prepared metadata cache have been prepared
  wait_for_node(session, node);
  prepared_statements_are_present(node);
}

BOOST_AUTO_TEST_SUITE_END()

ext: cpp

max_stars_repo_name: spolitov/cassandra-cpp-driver

max_issues_repo_name: spolitov/cassandra-cpp-driver

max_forks_repo_name: spolitov/cassandra-cpp-driver


text: #include <boost/metaparse/v1/last_of.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <common/test/test_home_dir.hpp>
#include <common/utime.hpp>
#include <common/merkle_trie.hpp>
#include <common/hex.hpp>
#include <common/random.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <boost/filesystem.hpp>
#include <db/triedb.hpp>

using namespace epilog::common;
using namespace epilog::db;

std::string home_dir;
std::string test_dir;

static void header( const std::string &str )
{
    std::cout << "\n";
    std::cout << "--- [" + str + "] " + std::string(60 - str.length(), '-') << "\n";
    std::cout << "\n";
}

const size_t TEST_NUM_ENTRIES = 10000;

static void test_basic_check(triedb &db, uint64_t entries[], size_t n)
{
    uint64_t *sorted_entries(new uint64_t[n]);
    uint64_t *half_sorted_entries(new uint64_t[n/2]);
    std::copy(entries, entries + n, sorted_entries);
    std::copy(entries, entries + n/2, half_sorted_entries);
    std::sort(&sorted_entries[0], &sorted_entries[0] + n);
    std::sort(&half_sorted_entries[0], &half_sorted_entries[0] + n/2);

    std::cout << "Check if entries can be found through direct query..." << std::endl;
    auto n_root = db.find_root(n-1);
    for (size_t i = 0; i < n; i++) {
        if (i >= 9990) {
	    db.set_debug(true);
	}
        auto *leaf = db.find(n_root, entries[i]);
	if (leaf == nullptr) {
	    std::cout << "Could not find entry #" << i << ": key=" << entries[i] << std::endl;
	    assert(leaf != nullptr && leaf->key() == entries[i]);
	}
    }

    db.set_debug(false);

    std::cout << "Compare with expected baseline..." << std::endl;

    size_t i = 0;

    triedb_iterator it = db.begin(n_root);
    triedb_iterator it_end = db.end(n_root);
    for (; it != it_end; ++it, ++i) {
        auto &leaf = *it;
	uint64_t expect_key = sorted_entries[i];
	if (expect_key != leaf.key()) {
	    std::cout << "Error at index " << i << std::endl;
	    std::cout << "Actual key: " << leaf.key() << std::endl;
	    std::cout << "Expect key: " << expect_key << std::endl;
	    assert(expect_key == leaf.key());
	}
    }

    std::cout << "Compare with expected baseline at half the height..." << std::endl;

    // Check how the triedb looks at half height
    // (only half of the entries are inserted)

    auto n2_root = db.find_root(n/2 -1);
    it = db.begin(n2_root);
    it_end = db.end(n2_root);
    i = 0;
    for (; it != it_end; ++it, ++i) {
        auto &leaf = *it;
	uint64_t expect_key = half_sorted_entries[i];
	if (expect_key != leaf.key()) {
	    std::cout << "Error at index " << i << std::endl;
	    std::cout << "Actual key: " << leaf.key() << std::endl;
	    std::cout << "Expect key: " << expect_key << std::endl;
	    assert(expect_key == leaf.key());
	}
    }

    //
    // Reverse iteration
    //
    std::cout << "Reverse iteration check..." << std::endl;
    auto n1_root = db.find_root(n-1);
    it_end = db.end(n1_root);
    it = it_end -1 ;
    i = n - 1;
    for (; it != it_end; --it, --i) {
        auto &leaf = *it;
	uint64_t expect_key = sorted_entries[i];
	if (expect_key != leaf.key()) {
	    std::cout << "Error at index " << i << std::endl;
	    std::cout << "Actual key: " << leaf.key() << std::endl;
	    std::cout << "Expect key: " << expect_key << std::endl;
	    assert(expect_key == leaf.key());
	}
    }

    //
    // Reverse iteration
    //
    std::cout << "Reverse iteration check from half height..." << std::endl;
    n2_root = db.find_root(n/2-1);
    it_end = db.end(n2_root);
    it = it_end - 1;
    i = n/2 - 1;
    for (; it != it_end; --it, --i) {
        auto &leaf = *it;
	uint64_t expect_key = half_sorted_entries[i];
	if (expect_key != leaf.key()) {
	    std::cout << "Error at index " << i << std::endl;
	    std::cout << "Actual key: " << leaf.key() << std::endl;
	    std::cout << "Expect key: " << expect_key << std::endl;
	    assert(expect_key == leaf.key());
	}
    }

    std::cout << "Nearby searching..." << std::endl;
    //
    // Start iteration from key - 10000
    // check 10 elements (or end of iteration)
    //
    n1_root = db.find_root(n-1);
    it_end = db.end(n1_root);
    for (i = 0; i < n; i++) {
       uint64_t from_key = sorted_entries[i] - 10000;
       it = db.begin(n1_root, from_key);
       auto it_expect = std::lower_bound(&sorted_entries[0], &sorted_entries[n], from_key);
       for (size_t j = 0; j < 10; j++, ++it, ++it_expect) {
	   if (it == it_end) {
	       break;
  	   }
	   if (it->key() != *it_expect) {
	       std::cout << "Error at index " << i << "," << j << std::endl;
	       std::cout << "Actual key: " << it->key() << std::endl;
	       std::cout << "Expect key: " << *it_expect << std::endl;
	       assert(it->key() == *it_expect);
	   }
	}
    }

    delete [] sorted_entries;
    delete [] half_sorted_entries;
}

static void test_basic()
{
    header("test_basic");

    std::cout << "Test directory: " << test_dir << std::endl;

    uint64_t *entries(new uint64_t[TEST_NUM_ENTRIES]);
    for (size_t i = 0; i < TEST_NUM_ENTRIES; i++) {
        entries[i] = random::next_int(static_cast<uint64_t>(100000000));
    }

    triedb_params params;
    params.set_bucket_size(65536);
    params.set_cache_num_streams(4);
    params.set_cache_num_nodes(1024);

    try {
	triedb::erase_all(test_dir);

        triedb db(params, test_dir);

	// Create genesis
	root_id root = db.new_root();

	// Set block sizes to be smaller to create more files...

	std::cout << "Create " << TEST_NUM_ENTRIES << " entries..." << std::endl;

	std::cout << "Insert entries..." << std::endl;

        for (size_t i = 0; i < TEST_NUM_ENTRIES; i++) {
	    db.insert(root, entries[i], nullptr, 0);
	    root = db.new_root(root);
	}

	test_basic_check(db, entries, TEST_NUM_ENTRIES);

    } catch (triedb_exception &ex) {
        std::cout << "Exception: " << ex.what() << std::endl;
	throw ex;
    }

    try {
        triedb db(test_dir);
	db.set_cache_num_streams(4);
	db.set_cache_num_nodes(1024);
	test_basic_check(db, entries, TEST_NUM_ENTRIES);
    } catch (triedb_exception &ex) {
        std::cout << "Exception: " << ex.what() << std::endl;
	throw ex;
    }

    delete [] entries;
}

static void test_increasing_check(triedb &db, size_t n)
{
    std::cout << "Testing finding keys directly..." << std::endl;
    for (size_t i = 0; i < n; i++) {
	auto i_root = db.find_root(i);
        auto *leaf = db.find(i_root, i);
	assert(leaf->key() == i);
	auto *not_found = db.find(i_root, i+1);
	assert(not_found == nullptr);
    }

    std::cout << "Iteration check..." << std::endl;
    auto n_root = db.find_root(n);
    auto it = db.begin(n_root, 0);
    auto it_end = db.end(n_root);
    size_t i = 0;
    for (; it != it_end; ++it, ++i) {
        auto &leaf = *it;
	if (leaf.key() != i) {
	    std::cout << "Error at index " << i << std::endl;
	    std::cout << "Actual key: " << leaf.key() << std::endl;
	    std::cout << "Expect key: " << i << std::endl;
	}
	assert(leaf.key() == i);
    }

    std::cout << "Reverse iteration check..." << std::endl;
    it_end = db.end(n_root);
    it = it_end - 1;
    i = 9999;
    for (; it != it_end; --it, --i) {
        auto &leaf = *it;
	if (leaf.key() != i) {
	    std::cout << "Error at index " << i << std::endl;
	    std::cout << "Actual key: " << leaf.key() << std::endl;
	    std::cout << "Expect key: " << i << std::endl;
	}
	assert(leaf.key() == i);
    }
}

static void test_increasing()
{
    header("test_increasing");

    std::cout << "Test directory: " << test_dir << std::endl;
    std::cout << "Remove any exisint files..." << std::endl;
    triedb::erase_all(test_dir);

    triedb_params params;
    params.set_bucket_size(65536);
    params.set_cache_num_streams(4);
    params.set_cache_num_nodes(1024);

    try {
        triedb db(params, test_dir);
	std::cout << "Create " << TEST_NUM_ENTRIES << " entries as 0, 1, 2, 3, ..." << std::endl;

	std::cout << "Insert entries..." << std::endl;

	auto at_root = db.new_root();

        for (size_t i = 0; i < TEST_NUM_ENTRIES; i++) {
	    db.insert(at_root, i, nullptr, 0);
	    at_root = db.new_root(at_root);

	    // Zero presence check...

	    auto *zero_check = db.find(at_root, 0);
	    assert(zero_check->key() == 0);
	}

	test_increasing_check(db, TEST_NUM_ENTRIES);

    } catch (triedb_exception &ex) {
        std::cout << "Exception: " << ex.what() << std::endl;
	throw ex;
    }

    // Open the database again

    try {
        triedb db(test_dir);
	db.set_cache_num_streams(4);
	db.set_cache_num_nodes(1024);
	test_increasing_check(db, TEST_NUM_ENTRIES);
    } catch (triedb_exception &ex) {
        std::cout << "Exception: " << ex.what() << std::endl;
	throw ex;
    }

    // Open the database again and remove every odd number

    try {
        size_t at_height = TEST_NUM_ENTRIES-1;
        triedb db(test_dir);
	auto at_root = db.find_root(at_height);
	std::cout << "Remove 1, 3, 5, ... up to 9999" << std::endl;
	for (size_t i = 1; i < TEST_NUM_ENTRIES; i += 2) {
	    db.remove(at_root, i);
	}
	std::cout << "Check database integrity..." << std::endl;

	for (size_t i = 0; i < TEST_NUM_ENTRIES; i++) {
	    auto *leaf = db.find(at_root, i);
	    if (i % 2 == 0) {
	        assert(leaf != nullptr && leaf->key() == i);
  	    } else {
	        assert(leaf == nullptr);
	    }
	}

	std::cout << "Remove a range of values..." << std::endl;

	for (size_t i = 1000; i < 2000; i += 2) {
	    db.remove(at_root, i);
	}

	std::cout << "Check database integrity again..." << std::endl;

	for (size_t i = 0; i < TEST_NUM_ENTRIES; i++) {
	    auto *leaf = db.find(at_root, i);
	    if (i % 2 == 0) {
	        if (i < 1000 || i >= 2000) {
		    assert(leaf != nullptr && leaf->key() == i);
	        } else {
		    assert(leaf == nullptr);
		}
  	    } else {
	        assert(leaf == nullptr);
	    }
	}

	std::cout << "Check database integrity through iteration..." << std::endl;
	auto it = db.begin(at_root, 0);
	auto it_end = db.end(at_root);

	size_t i = 0;
	for (; it != it_end; ++it) {
	    assert(it->key() == i);
	    ++i;
	    if (i % 2 == 1) ++i;
	    while (i >= 1000 && i < 2000) ++i;
	}
	assert(i == TEST_NUM_ENTRIES);

    } catch (triedb_exception &ex) {
        std::cout << "Exception: " << ex.what() << std::endl;
	throw ex;
    }

}

int main(int argc, char *argv[])
{
    home_dir = find_home_dir(argv[0]);
    test_dir = home_dir;
    test_dir = (boost::filesystem::path(test_dir) / "bin" / "test" / "db" / "triedb").string();

    random::set_for_testing(true);

    test_basic();
    test_increasing();

    return 0;
}

max_stars_repo_name: datavetaren/epilog

max_issues_repo_name: datavetaren/epilog

max_forks_repo_name: datavetaren/epilog


text:
#if !defined(BOOST_PP_IS_ITERATING)

///// header body

#ifndef BOOST_MPL_BIND_HPP_INCLUDED
#define BOOST_MPL_BIND_HPP_INCLUDED

// Copyright Peter Dimov 2001
// Copyright Aleksey Gurtovoy 2001-2004
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/mpl for documentation.

// $Source: /cvsroot/boost/boost/boost/mpl/bind.hpp,v $
// $Date: 2004/10/26 14:51:04 $
// $Revision: 1.13 $

#if !defined(BOOST_MPL_PREPROCESSING_MODE)
#   include <boost/mpl/bind_fwd.hpp>
#   include <boost/mpl/placeholders.hpp>
#   include <boost/mpl/next.hpp>
#   include <boost/mpl/protect.hpp>
#   include <boost/mpl/apply_wrap.hpp>
#   include <boost/mpl/limits/arity.hpp>
#   include <boost/mpl/aux_/na.hpp>
#   include <boost/mpl/aux_/arity_spec.hpp>
#   include <boost/mpl/aux_/type_wrapper.hpp>
#   include <boost/mpl/aux_/yes_no.hpp>
#   if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#       include <boost/type_traits/is_reference.hpp>
#   endif
#endif

#include <boost/mpl/aux_/config/bind.hpp>
#include <boost/mpl/aux_/config/static_constant.hpp>
#include <boost/mpl/aux_/config/use_preprocessed.hpp>

#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
    && !defined(BOOST_MPL_PREPROCESSING_MODE)

#   if defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
#       define BOOST_MPL_PREPROCESSED_HEADER basic_bind.hpp
#   else
#       define BOOST_MPL_PREPROCESSED_HEADER bind.hpp
#   endif
#   include <boost/mpl/aux_/include_preprocessed.hpp>

#else

#   include <boost/mpl/aux_/preprocessor/params.hpp>
#   include <boost/mpl/aux_/preprocessor/default_params.hpp>
#   include <boost/mpl/aux_/preprocessor/def_params_tail.hpp>
#   include <boost/mpl/aux_/preprocessor/partial_spec_params.hpp>
#   include <boost/mpl/aux_/preprocessor/ext_params.hpp>
#   include <boost/mpl/aux_/preprocessor/repeat.hpp>
#   include <boost/mpl/aux_/preprocessor/enum.hpp>
#   include <boost/mpl/aux_/preprocessor/add.hpp>
#   include <boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp>
#   include <boost/mpl/aux_/config/ctps.hpp>
#   include <boost/mpl/aux_/config/ttp.hpp>
#   include <boost/mpl/aux_/config/dtp.hpp>
#   include <boost/mpl/aux_/nttp_decl.hpp>

#   include <boost/preprocessor/iterate.hpp>
#   include <boost/preprocessor/comma_if.hpp>
#   include <boost/preprocessor/cat.hpp>
#   include <boost/preprocessor/inc.hpp>

namespace boost { namespace mpl {

// local macros, #undef-ined at the end of the header
#   define AUX778076_APPLY \
    BOOST_PP_CAT(apply_wrap,BOOST_MPL_LIMIT_METAFUNCTION_ARITY) \
    /**/

#   if defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS)
#       define AUX778076_DMC_PARAM() , int dummy_
#   else
#       define AUX778076_DMC_PARAM()
#   endif

#   define AUX778076_BIND_PARAMS(param) \
    BOOST_MPL_PP_PARAMS( \
          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
        , param \
        ) \
    /**/

#   define AUX778076_BIND_DEFAULT_PARAMS(param, value) \
    BOOST_MPL_PP_DEFAULT_PARAMS( \
          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
        , param \
        , value \
        ) \
    /**/

#   define AUX778076_BIND_N_PARAMS(n, param) \
    BOOST_PP_COMMA_IF(n) BOOST_MPL_PP_PARAMS(n, param) \
    /**/

#   define AUX778076_BIND_N_SPEC_PARAMS(n, param, def) \
    BOOST_PP_COMMA_IF(n) \
    BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(n, param, def) \
    /**/

#if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
#   define AUX778076_BIND_NESTED_DEFAULT_PARAMS(param, value) \
    AUX778076_BIND_DEFAULT_PARAMS(param, value) \
    /**/
#else
#   define AUX778076_BIND_NESTED_DEFAULT_PARAMS(param, value) \
    AUX778076_BIND_PARAMS(param) \
    /**/
#endif

namespace aux {

#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

template<
      typename T, AUX778076_BIND_PARAMS(typename U)
    >
struct resolve_bind_arg
{
    typedef T type;
};

#   if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)

template<
      typename T
    , typename Arg
    >
struct replace_unnamed_arg
{
    typedef Arg next;
    typedef T type;
};

template<
      typename Arg
    >
struct replace_unnamed_arg< arg<-1>,Arg >
{
    typedef typename Arg::next next;
    typedef Arg type;
};

#   endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT

template<
      BOOST_MPL_AUX_NTTP_DECL(int, N), AUX778076_BIND_PARAMS(typename U)
    >
struct resolve_bind_arg< arg<N>,AUX778076_BIND_PARAMS(U) >
{
    typedef typename AUX778076_APPLY<mpl::arg<N>, AUX778076_BIND_PARAMS(U)>::type type;
};

#if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
template<
      typename F, AUX778076_BIND_PARAMS(typename T), AUX778076_BIND_PARAMS(typename U)
    >
struct resolve_bind_arg< bind<F,AUX778076_BIND_PARAMS(T)>,AUX778076_BIND_PARAMS(U) >
{
    typedef bind<F,AUX778076_BIND_PARAMS(T)> f_;
    typedef typename AUX778076_APPLY<f_, AUX778076_BIND_PARAMS(U)>::type type;
};
#endif

#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

// agurt, 15/jan/02: it's not a intended to be used as a function class, and
// MSVC6.5 has problems with 'apply' name here (the code compiles, but doesn't
// work), so I went with the 'result_' here, and in all other similar cases
template< bool >
struct resolve_arg_impl
{
    template< typename T, AUX778076_BIND_PARAMS(typename U) > struct result_
    {
        typedef T type;
    };
};

template<>
struct resolve_arg_impl<true>
{
    template< typename T, AUX778076_BIND_PARAMS(typename U) > struct result_
    {
        typedef typename AUX778076_APPLY<
              T
            , AUX778076_BIND_PARAMS(U)
            >::type type;
    };
};

// for 'resolve_bind_arg'
template< typename T > struct is_bind_template;

template<
      typename T, AUX778076_BIND_PARAMS(typename U)
    >
struct resolve_bind_arg
    : resolve_arg_impl< is_bind_template<T>::value >
            ::template result_< T,AUX778076_BIND_PARAMS(U) >
{
};

#   if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)

template< typename T >
struct replace_unnamed_arg_impl
{
    template< typename Arg > struct result_
    {
        typedef Arg next;
        typedef T type;
    };
};

template<>
struct replace_unnamed_arg_impl< arg<-1> >
{
    template< typename Arg > struct result_
    {
        typedef typename next<Arg>::type next;
        typedef Arg type;
    };
};

template< typename T, typename Arg >
struct replace_unnamed_arg
    : replace_unnamed_arg_impl<T>::template result_<Arg>
{
};

#   endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT

// agurt, 10/mar/02: the forward declaration has to appear before any of
// 'is_bind_helper' overloads, otherwise MSVC6.5 issues an ICE on it
template< BOOST_MPL_AUX_NTTP_DECL(int, arity_) > struct bind_chooser;

aux::no_tag is_bind_helper(...);
template< typename T > aux::no_tag is_bind_helper(protect<T>*);

// overload for "main" form
// agurt, 15/mar/02: MSVC 6.5 fails to properly resolve the overload
// in case if we use 'aux::type_wrapper< bind<...> >' here, and all
// 'bind' instantiations form a complete type anyway
#if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
template<
      typename F, AUX778076_BIND_PARAMS(typename T)
    >
aux::yes_tag is_bind_helper(bind<F,AUX778076_BIND_PARAMS(T)>*);
#endif

template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
aux::yes_tag is_bind_helper(arg<N>*);

template< bool is_ref_ = true >
struct is_bind_template_impl
{
    template< typename T > struct result_
    {
        BOOST_STATIC_CONSTANT(bool, value = false);
    };
};

template<>
struct is_bind_template_impl<false>
{
    template< typename T > struct result_
    {
        BOOST_STATIC_CONSTANT(bool, value =
              sizeof(aux::is_bind_helper(static_cast<T*>(0)))
                == sizeof(aux::yes_tag)
            );
    };
};

template< typename T > struct is_bind_template
    : is_bind_template_impl< ::boost::detail::is_reference_impl<T>::value >
        ::template result_<T>
{
};

#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

} // namespace aux

#define BOOST_PP_ITERATION_PARAMS_1 \
    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/bind.hpp>))
#include BOOST_PP_ITERATE()

#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
    && !defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS)
/// if_/eval_if specializations
#   define AUX778076_SPEC_NAME if_
#   define BOOST_PP_ITERATION_PARAMS_1 (3,(3, 3, <boost/mpl/bind.hpp>))
#   include BOOST_PP_ITERATE()

#if !defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS)
#   define AUX778076_SPEC_NAME eval_if
#   define BOOST_PP_ITERATION_PARAMS_1 (3,(3, 3, <boost/mpl/bind.hpp>))
#   include BOOST_PP_ITERATE()
#endif
#endif

// real C++ version is already taken care of
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
    && !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)

namespace aux {
// apply_count_args
#define AUX778076_COUNT_ARGS_PREFIX bind
#define AUX778076_COUNT_ARGS_DEFAULT na
#define AUX778076_COUNT_ARGS_ARITY BOOST_MPL_LIMIT_METAFUNCTION_ARITY
#include <boost/mpl/aux_/count_args.hpp>
}

// bind
template<
      typename F, AUX778076_BIND_PARAMS(typename T) AUX778076_DMC_PARAM()
    >
struct bind
    : aux::bind_chooser<
          aux::bind_count_args<AUX778076_BIND_PARAMS(T)>::value
        >::template result_< F,AUX778076_BIND_PARAMS(T) >::type
{
};

BOOST_MPL_AUX_ARITY_SPEC(
      BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
    , bind
    )

BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(
      BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
    , bind
    )

#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

#   undef AUX778076_BIND_NESTED_DEFAULT_PARAMS
#   undef AUX778076_BIND_N_SPEC_PARAMS
#   undef AUX778076_BIND_N_PARAMS
#   undef AUX778076_BIND_DEFAULT_PARAMS
#   undef AUX778076_BIND_PARAMS
#   undef AUX778076_DMC_PARAM
#   undef AUX778076_APPLY

}}

#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
#endif // BOOST_MPL_BIND_HPP_INCLUDED

///// iteration, depth == 1

#elif BOOST_PP_ITERATION_DEPTH() == 1

#   define i_ BOOST_PP_FRAME_ITERATION(1)

#if defined(AUX778076_SPEC_NAME)

// lazy metafunction specialization
template< template< BOOST_MPL_PP_PARAMS(i_, typename T) > class F, typename Tag >
struct BOOST_PP_CAT(quote,i_);

template< BOOST_MPL_PP_PARAMS(i_, typename T) > struct AUX778076_SPEC_NAME;

template<
      typename Tag AUX778076_BIND_N_PARAMS(i_, typename T)
    >
struct BOOST_PP_CAT(bind,i_)<
      BOOST_PP_CAT(quote,i_)<AUX778076_SPEC_NAME,Tag>
    AUX778076_BIND_N_PARAMS(i_,T)
    >
{
    template<
          AUX778076_BIND_NESTED_DEFAULT_PARAMS(typename U, na)
        >
    struct apply
    {
     private:
        typedef mpl::arg<1> n1;
#       define BOOST_PP_ITERATION_PARAMS_2 (3,(1, i_, <boost/mpl/bind.hpp>))
#       include BOOST_PP_ITERATE()

        typedef typename AUX778076_SPEC_NAME<
              typename t1::type
            , BOOST_MPL_PP_EXT_PARAMS(2, BOOST_PP_INC(i_), t)
            >::type f_;

     public:
        typedef typename f_::type type;
    };
};

#undef AUX778076_SPEC_NAME

#else // AUX778076_SPEC_NAME

template<
      typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
    >
struct BOOST_PP_CAT(bind,i_)
{
    template<
          AUX778076_BIND_NESTED_DEFAULT_PARAMS(typename U, na)
        >
    struct apply
    {
     private:
#   if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)

        typedef aux::replace_unnamed_arg< F,mpl::arg<1> > r0;
        typedef typename r0::type a0;
        typedef typename r0::next n1;
        typedef typename aux::resolve_bind_arg<a0,AUX778076_BIND_PARAMS(U)>::type f_;
        ///
#   else
        typedef typename aux::resolve_bind_arg<F,AUX778076_BIND_PARAMS(U)>::type f_;

#   endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT

#   if i_ > 0
#       define BOOST_PP_ITERATION_PARAMS_2 (3,(1, i_, <boost/mpl/bind.hpp>))
#       include BOOST_PP_ITERATE()
#   endif

     public:

#   define AUX778076_ARG(unused, i_, t) \
    BOOST_PP_COMMA_IF(i_) \
    typename BOOST_PP_CAT(t,BOOST_PP_INC(i_))::type \
/**/

        typedef typename BOOST_PP_CAT(apply_wrap,i_)<
              f_
            BOOST_PP_COMMA_IF(i_) BOOST_MPL_PP_REPEAT(i_, AUX778076_ARG, t)
            >::type type;

#   undef AUX778076_ARG
    };
};

namespace aux {

#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

template<
      typename F AUX778076_BIND_N_PARAMS(i_, typename T), AUX778076_BIND_PARAMS(typename U)
    >
struct resolve_bind_arg<
      BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)>,AUX778076_BIND_PARAMS(U)
    >
{
    typedef BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)> f_;
    typedef typename AUX778076_APPLY<f_, AUX778076_BIND_PARAMS(U)>::type type;
};

#else

template<
      typename F AUX778076_BIND_N_PARAMS(i_, typename T)
    >
aux::yes_tag
is_bind_helper(BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)>*);

#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

} // namespace aux

BOOST_MPL_AUX_ARITY_SPEC(BOOST_PP_INC(i_), BOOST_PP_CAT(bind,i_))
BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(BOOST_PP_INC(i_), BOOST_PP_CAT(bind,i_))

#   if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
#   if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

#if i_ == BOOST_MPL_LIMIT_METAFUNCTION_ARITY
/// primary template (not a specialization!)
template<
      typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
    >
struct bind
    : BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T) >
{
};
#else
template<
      typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
    >
struct bind< F AUX778076_BIND_N_SPEC_PARAMS(i_, T, na) >
    : BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T) >
{
};
#endif

#   else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

namespace aux {

template<>
struct bind_chooser<i_>
{
    template<
          typename F, AUX778076_BIND_PARAMS(typename T)
        >
    struct result_
    {
        typedef BOOST_PP_CAT(bind,i_)< F AUX778076_BIND_N_PARAMS(i_,T) > type;
    };
};

} // namespace aux

#   endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#   endif // BOOST_MPL_CFG_NO_BIND_TEMPLATE

#endif // AUX778076_SPEC_NAME

#   undef i_

///// iteration, depth == 2

#elif BOOST_PP_ITERATION_DEPTH() == 2

#   define j_ BOOST_PP_FRAME_ITERATION(2)
#   if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)

        typedef aux::replace_unnamed_arg< BOOST_PP_CAT(T,j_),BOOST_PP_CAT(n,j_) > BOOST_PP_CAT(r,j_);
        typedef typename BOOST_PP_CAT(r,j_)::type BOOST_PP_CAT(a,j_);
        typedef typename BOOST_PP_CAT(r,j_)::next BOOST_PP_CAT(n,BOOST_PP_INC(j_));
        typedef aux::resolve_bind_arg<BOOST_PP_CAT(a,j_), AUX778076_BIND_PARAMS(U)> BOOST_PP_CAT(t,j_);
        ///
#   else
        typedef aux::resolve_bind_arg< BOOST_PP_CAT(T,j_),AUX778076_BIND_PARAMS(U)> BOOST_PP_CAT(t,j_);

#   endif
#   undef j_

#endif // BOOST_PP_IS_ITERATING

max_stars_repo_name: dstrigl/mcotf

max_issues_repo_name: dstrigl/mcotf

max_forks_repo_name: dstrigl/mcotf


text:
/*
* Copyright (c) 2016 Baidu, Inc. All Rights Reserved.
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/

/**
 * @brief Stub of device management server.
 *
 * @authors Zhao Bo
 */
#include "device_management_stub.h"
#include <regex>
#include <MQTTClient.h>

#include <cjson/cJSON.h>
#include <boost/format.hpp>
#include <mutex>
#include <list>

#include "test_conf.h"
#include "test_util.h"

class DeviceManagementStubImpl : public DeviceManagementStub {
public:
    DeviceManagementStubImpl(const std::string &broker, const std::string &username, const std::string &password,
                             const std::string &clientId);

    virtual ~DeviceManagementStubImpl();

    void start();

    virtual void setAutoResponse(bool value) override;

    virtual void addListener(CallBack f) override;

    virtual void clearListeners() override;

private:
    std::string username;
    std::string password;
    MQTTClient client;

    bool autoRespond;
    std::list<CallBack> callbacks;
    std::mutex callbackMutex;

    static const std::regex topicRegex;
    static const std::string update;
    static const std::string requestIdKey;
    static const std::string acceptedFormat;
    static const std::string rejectedFormat;

    // MQTT callbacks
    static void connection_lost(void *context, char *cause);

    static int message_arrived(void *context, char *topicName, int topicLen, MQTTClient_message *message);

    static void delivery_complete(void *context, MQTTClient_deliveryToken dt);

    // Business logic
    void processUpdate(const std::string &device, const std::string requestId, cJSON *document);
};

// First group matches device name and second group matches action.
const std::regex DeviceManagementStubImpl::topicRegex = std::regex(std::string("\\$baidu/iot/shadow/") + "([^/]*)/([^/]*)");

const std::string DeviceManagementStubImpl::update = "update";

const std::string DeviceManagementStubImpl::requestIdKey = "requestId";

const std::string DeviceManagementStubImpl::acceptedFormat = TestConf::getTopicPrefix() + "%s/%s/accepted";

const std::string DeviceManagementStubImpl::rejectedFormat = TestConf::getTopicPrefix() + "%s/%s/rejected";

DeviceManagementStubImpl::DeviceManagementStubImpl(const std::string &broker, const std::string &username,
                                                   const std::string &password, const std::string &clientId) :
        username(username), password(password) {
    MQTTClient_create(&client, broker.data(), clientId.data(), MQTTCLIENT_PERSISTENCE_NONE, NULL);
    autoRespond = true;
}

DeviceManagementStubImpl::~DeviceManagementStubImpl() {
    if (client != NULL) {
        MQTTClient_disconnect(client, 10);
        MQTTClient_destroy(&client);
    }
}

void DeviceManagementStubImpl::start() {
    MQTTClient_connectOptions options = MQTTClient_connectOptions_initializer;
    options.username = username.data();
    options.password = password.data();
    MQTTClient_setCallbacks(client, this, connection_lost, message_arrived, delivery_complete);
    MQTTClient_connect(client, &options);
    std::string topicFilter = TestConf::getTopicPrefix() + "+/update";
    MQTTClient_subscribe(client, topicFilter.data(), 1);
}

void DeviceManagementStubImpl::setAutoResponse(bool value) {
    autoRespond = value;
}

void DeviceManagementStubImpl::addListener(CallBack f) {
    std::lock_guard<std::mutex> lock(callbackMutex);
    callbacks.push_back(f);
}

void DeviceManagementStubImpl::clearListeners() {
    std::lock_guard<std::mutex> lock(callbackMutex);
    callbacks.clear();
}

int DeviceManagementStubImpl::message_arrived(void *context, char *topicName, int topicLen,
                                              MQTTClient_message *message) {
    DeviceManagementStubImpl *impl = static_cast<DeviceManagementStubImpl *>(context);
    std::cmatch results;
    bool matched = std::regex_match(topicName, results, topicRegex, std::regex_constants::match_default);
    if (matched) {
        const std::string &device = results[1];
        const std::string &action = results[2];
        char *payload = static_cast<char *>(message->payload);
        char *jsonString = payload;
        if (jsonString[message->payloadlen - 1] != '\0') {
            // Make a copy
            jsonString = static_cast<char *>(malloc(message->payloadlen + 1));
            strncpy(jsonString, payload, message->payloadlen);
            jsonString[message->payloadlen] = '\0';
        }

        cJSON *document = cJSON_Parse(jsonString);
        if (jsonString != payload) {
            free(jsonString);
        }
        const std::string requestId(cJSON_GetObjectItem(document, requestIdKey.data())->valuestring);
        if (action == DeviceManagementStubImpl::update) {
            impl->processUpdate(device, requestId, document);
        }

        for (CallBack &callback : impl->callbacks) {
            callback.operator()(device, action);
        }

        cJSON_Delete(document);

    }

    MQTTClient_free(topicName);
    MQTTClient_freeMessage(&message);
    return 1;
}

void DeviceManagementStubImpl::connection_lost(void *context, char *cause) {
    DeviceManagementStubImpl *impl = static_cast<DeviceManagementStubImpl *>(context);
}

void DeviceManagementStubImpl::delivery_complete(void *context, MQTTClient_deliveryToken tok) {

}

void DeviceManagementStubImpl::processUpdate(const std::string &device, const std::string requestId, cJSON *document) {
    if (autoRespond) {
        boost::format format(acceptedFormat);
        std::string topic = boost::str(format % device % update);
        cJSON *json = cJSON_CreateObject();
        cJSON_AddStringToObject(json, "requestId", requestId.data());
        cJSON_AddNumberToObject(json, "profileVersion", 1);
        char *payload = cJSON_Print(json);
        // Send ack
        MQTTClient_publish(client, topic.data(), strlen(payload) + 1, payload, 1, 0, NULL);
        free(payload);
    }
}

std::shared_ptr<DeviceManagementStub> DeviceManagementStub::create() {
    return std::shared_ptr<DeviceManagementStub>(
            new DeviceManagementStubImpl(TestConf::getTestMqttBroker(),
                                         TestConf::getTestMqttUsername(),
                                         TestConf::getTestMqttPassword(),
                                         TestUtil::uuid()));
}


text:
//          Copyright Carl Philipp Reh 2009 - 2016.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#include <fcppt/container/tree/object_impl.hpp>
#include <fcppt/preprocessor/disable_gcc_warning.hpp>
#include <fcppt/preprocessor/pop_warning.hpp>
#include <fcppt/preprocessor/push_warning.hpp>
#include <fcppt/config/external_begin.hpp>
#include <boost/test/unit_test.hpp>
#include <fcppt/config/external_end.hpp>

FCPPT_PP_PUSH_WARNING
FCPPT_PP_DISABLE_GCC_WARNING(-Weffc++)

BOOST_AUTO_TEST_CASE(
	container_tree_swap
)
{
FCPPT_PP_POP_WARNING

	typedef
	fcppt::container::tree::object<
		int
	>
	i_tree;

	i_tree tree1(
		10
	);

	tree1.push_back(
		20
	);

	i_tree tree2(
		30
	);

	swap(
		tree1,
		tree2
	);

	BOOST_CHECK_EQUAL(
		tree1.value(),
		30
	);

	BOOST_CHECK_EQUAL(
		tree2.value(),
		10
	);

	BOOST_REQUIRE(
		!tree2.empty()
	);

	BOOST_CHECK_EQUAL(
		tree2.front().value(),
		20
	);
}

max_stars_repo_name: vinzenz/fcppt

max_issues_repo_name: vinzenz/fcppt

max_forks_repo_name: vinzenz/fcppt


text:
/*! @file transform.cc
 *  @brief Transform parent class definition.
 *  @author Markovtsev Vadim <v.markovtsev@samsung.com>
 *  @version 1.0
 *
 *  @section Notes
 *  This code partially conforms to Google C++ Style Guide.
 *
 *  @section Copyright
 *  Copyright © 2013 Samsung R&D Institute Russia
 *
 *  @section License
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */

#include "src/transform.h"
#include <cassert>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <boost/algorithm/string/replace.hpp>
#pragma GCC diagnostic pop
#include "src/transform_registry.h"

using boost::algorithm::replace_all_copy;

namespace sound_feature_extraction {

bool Transform::BufferInvariant() const noexcept {
  return false;
}

std::shared_ptr<Transform> Transform::Clone() const noexcept {
  auto copy = TransformFactory::Instance().Map()
      .find(this->Name())->second
      .find(this->InputFormat()->Id())->second();
  copy->SetParameters(this->GetParameters());
  return copy;
}

bool Transform::operator==(const Transform& other) const noexcept {
  if (this->Name() != other.Name()) return false;
  assert(GetParameters().size() == other.GetParameters().size());
  for (auto p : GetParameters()) {
    if (other.GetParameters().find(p.first)->second != p.second) {
      return false;
    }
  }
  return true;
}

std::string Transform::SafeName() const noexcept {
  return replace_all_copy(replace_all_copy(replace_all_copy(replace_all_copy(
      replace_all_copy(replace_all_copy(
      Name(), " ", ""), "->", "To"), "!", ""), ">", "_"), "<", "_"),
      "*", "Array");
}

std::string Transform::HtmlEscapedName() const noexcept {
  return replace_all_copy(replace_all_copy(replace_all_copy(replace_all_copy(
      Name(), "&", "&"), ">", ">"), "<", "<"), "!", "");
}

}  // namespace sound_feature_extraction

ext: cc


text:
#define BOOST_USE_WINDOWS_H
#include <QApplication>
#include <QDebug>
#include <QOpenGLTimerQuery>
#include <iostream>
#include <render/qGLWidget/oglwidget.h>
#include <utility/helpers/arguments.h>
#include <utility/identifier/uniform.h>
#include <render/qGLWidget/base_renderer.h>
#include <render/boundaryRender/bounds.h>
#include <render/particleRender/particle_render.h>
#include <render/volumeRender/volume_render.h>
#include <render/vdbPolyRender/vdb_poly_render.h>
#include <render/quadRender/quadRender.h>
#include <render/mlmRender/mlmRender.h>
#include <utility/template/tuple_for_each.h>
#include <boost/format.hpp>
#include <boost/type_traits/is_assignable.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <chrono>
#include <mutex>
#include <simulation/particleSystem.h>
#include <sstream>
#include <utility/helpers/arguments.h>
#include <utility/helpers/timer.h>
#include <utility/identifier/arrays.h>
#include <utility/identifier/uniform.h>
#include <utility/math.h>
#include <render/qGLWidget/base_renderer.h>

RTXRender::RTXRender(QGLWidget* p) {
	if (get<parameters::rayTracing>() == false) return;
	auto parent = dynamic_cast<OGLWidget*>(p);
	static const char *vertexShaderSource = R"(#version 450
in vec3 vertexPosition_modelspace;
out vec2 UV;

void main(){
	gl_Position =  vec4(vertexPosition_modelspace,1);
	UV = (vertexPosition_modelspace.xy+vec2(1,1))/2.0;
	UV.y = 1.f - UV.y;
}
)";

	static const char *fragmentShaderSource = R"(#version 450
uniform sampler2D renderedTexture;

in vec2 UV;
out vec3 color;

void main(){
	vec4 col = texture( renderedTexture, UV);
	color = vec3(col.xyz) ;
	//gl_FragDepth = col.w;
}
)";

	initialFrame = get<parameters::frame>();
	auto h_scene = hostScene();
	cudaMalloc(&accumulatebuffer, h_scene.width * h_scene.height * sizeof(float3));
	initializeOpenGLFunctions();
	quad_programID = new QOpenGLShaderProgram(parent);
	quad_programID->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
	quad_programID->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);

	glGenVertexArrays(1, &defer_VAO);
	glBindVertexArray(defer_VAO);
	quad_programID->link();
	parent->bind(quad_programID);
	quad_programID->bind();

	auto m_posAttr = quad_programID->attributeLocation("vertexPosition_modelspace");
	glGenTextures(1, &renderedTextureOut);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, renderedTextureOut);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, h_scene.width, h_scene.height, 0, GL_RGBA, GL_FLOAT, 0);
	cudaGraphicsGLRegisterImage(&renderedResourceOut, renderedTextureOut, GL_TEXTURE_2D,
		cudaGraphicsRegisterFlagsSurfaceLoadStore);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glActiveTexture(GL_TEXTURE0);
	static const GLfloat g_quad_vertex_bufferdata[] = {
		-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
	};

	GLuint quad_vertexbuffer;
	glGenBuffers(1, &quad_vertexbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_bufferdata), g_quad_vertex_bufferdata, GL_STATIC_DRAW);

	glEnableVertexAttribArray(m_posAttr);
	glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glBindVertexArray(0);
	quad_programID->setUniformValue("renderedTexture", 0);

	quad_programID->release();
	//prepCUDAscene();
	//update();

}

void RTXRender::update() {
	updateRTX();
}
bool RTXRender::valid() {
	return bValid;
}
void RTXRender::render(bool pretty) {
	static std::random_device r;
	static std::default_random_engine e1(r());
	static std::uniform_int_distribution<int32_t> uniform_dist(INT_MIN, INT_MAX);

	if (get<parameters::frame>() == initialFrame) {
		return;
	}
	if (get<parameters::rayTracing>() == false) return;
	auto h_scene = hostScene();
	if (h_scene.dirty || frame != get<parameters::frame>() || dirty) {
		frame = get<parameters::frame>();
		cudaMemset(accumulatebuffer, 1, h_scene.width * h_scene.height * sizeof(float3));
		framenumber = 0;
		dirty = false;
	}
	if (!bValid) return;
	int32_t iterations = 1;
	if (pretty)
		iterations = 50;

	for (int32_t i = 0; i < iterations; ++i) {
		framenumber++;
		renderRTX(pretty, framenumber, uniform_dist(e1));
	}
		glBindVertexArray(defer_VAO);
		quad_programID->bind();
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, renderedTextureOut);
		glDrawArrays(GL_TRIANGLES, 0, 6);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, 0);
		quad_programID->release();
		glBindVertexArray(0);
}
void RTXRender::prepCUDAscene() {

}

max_stars_repo_name: chenjiunfeng/openMaelstrom

max_issues_repo_name: chenjiunfeng/openMaelstrom

max_forks_repo_name: chenjiunfeng/openMaelstrom


text:
#include "dbus_sensor_object.hpp"

#include <boost/asio.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/bus.hpp>

namespace stubs
{

DbusSensorObject::DbusSensorObject(
    boost::asio::io_context& ioc,
    const std::shared_ptr<sdbusplus::asio::connection>& bus,
    const std::shared_ptr<sdbusplus::asio::object_server>& objServer) :
    ioc(ioc),
    bus(bus), objServer(objServer)
{
    sensorIface = objServer->add_unique_interface(
        path(), interface(), [this](auto& iface) {
            iface.register_property_r(
                property.value(), value,
                sdbusplus::vtable::property_::emits_change,
                [this](const auto&) { return value; });
        });
}

void DbusSensorObject::setValue(double v)
{
    value = v;

    sensorIface->signal_property(property.value());
}

double DbusSensorObject::getValue() const
{
    return value;
}

const char* DbusSensorObject::path()
{
    return "/telemetry/ut/DbusSensorObject";
}

const char* DbusSensorObject::interface()
{
    return "xyz.openbmc_project.Sensor.Value";
}

const char* DbusSensorObject::Properties::value()
{
    return "Value";
}

} // namespace stubs


text:
/*
    Copyright 2013 Adobe
    Distributed under the Boost Software License, Version 1.0.
    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/**************************************************************************************************/

#ifndef ADOBE_dancing_links_t_HPP
#define ADOBE_dancing_links_t_HPP

/**************************************************************************************************/

#include <adobe/config.hpp>

#include <vector>

#if ADOBE_STD_SERIALIZATION
#include <iostream>
#endif

#include <boost/function.hpp>
#include <boost/noncopyable.hpp>

#include <adobe/implementation/toroid.hpp>

#define ADOBE_DLX_VERBOSE 0

#if ADOBE_STD_SERIALIZATION && ADOBE_DLX_VERBOSE
#include <adobe/iomanip.hpp>
#endif

/**************************************************************************************************/

namespace adobe {

/**************************************************************************************************/

#ifndef ADOBE_NO_DOCUMENTATION

/**************************************************************************************************/

namespace implementation {

/**************************************************************************************************/

struct do_nothing_callback_t {
    inline void operator()(std::size_t, bool) const {}
};

/**************************************************************************************************/

struct select_right_heuristic_t {
    inline toroid_header_t* operator()(byte_toroid_t& toroid) const {
        return toroid.right_of(&toroid.header_m);
    }
};

/**************************************************************************************************/

struct select_most_constrained_heuristic_t {
    inline toroid_header_t* operator()(byte_toroid_t& toroid) const {
        toroid_header_t* c(toroid.right_of(&toroid.header_m));
        std::size_t sz(c->size_m);

        for (toroid_header_t* p(toroid.right_of(c)); p != &toroid.header_m;
             p = toroid.right_of(p)) {
            if (p->size_m < sz) {
                c = p;
                sz = p->size_m;
            }

            if (sz == 1)
                break;
        }

        return c;
    }
};

/**************************************************************************************************/

} // namespace implementation

/**************************************************************************************************/

#endif

/**************************************************************************************************/

class dancing_links_t : boost::noncopyable {
public:
#ifndef ADOBE_NO_DOCUMENTATION
    dancing_links_t(std::size_t row_count, std::size_t column_count)
        : toroid_m(row_count, column_count), output_m(column_count, 0), solutions_m(0)
#if ADOBE_DLX_VERBOSE
          ,
          tab_count_m(0)
#endif
    {
    }
#endif

    inline void set(std::size_t row, std::size_t col, char color = 0) {
        toroid_m.set(row, col, color);
    }

    inline void set_secondary_column(std::size_t col) { toroid_m.set_secondary_column(col); }

    template <typename ResultCallback, typename SearchHeuristic>
    inline std::size_t search(std::size_t max_solutions, ResultCallback callback,
                              SearchHeuristic heuristic) {
        max_solutions_m = max_solutions;

        toroid_m.finalize();

        do_search(0, callback, heuristic);

        return solutions_m;
    }

    inline std::size_t search(std::size_t max_solutions) {
        return search(max_solutions, implementation::do_nothing_callback_t(),
                      implementation::select_most_constrained_heuristic_t());
    }

#if ADOBE_STD_SERIALIZATION
    friend std::ostream& operator<<(std::ostream& s, const dancing_links_t& dancing_links_t) {
        return s << dancing_links_t.toroid_m;
    }
#endif

private:
    template <typename ResultCallback, typename SearchHeuristic>
    void do_search(std::size_t k, ResultCallback callback, SearchHeuristic heuristic) {
        if (toroid_m.right_of(&toroid_m.header_m) == &toroid_m.header_m) {
            ++solutions_m;

#if ADOBE_DLX_VERBOSE
            std::cout << adobe::indents(tab_count_m) << "<solved/>" << std::endl;
#endif

            for (std::size_t i(0); i < k; ++i)
                callback(toroid_m.row_index_of(output_m[i]), i + 1 == k);

            return;
        }

        std::size_t next_k(k + 1);

        toroid_header_t* c(heuristic(toroid_m));

#if ADOBE_DLX_VERBOSE
        ++tab_count_m;
        std::cout << adobe::indents(tab_count_m) << "<c"
                  << toroid_m.column_index_of(toroid_m.down_of(c)) << ">" << std::endl;
#endif

        toroid_m.cover_column(c);

        // branch on each node in this column
        for (toroid_node_t* r(toroid_m.down_of(c)); r != c; r = toroid_m.down_of(r)) {
#if ADOBE_DLX_VERBOSE
            std::cout << adobe::indents(tab_count_m) << "<r" << toroid_m.row_index_of(r) << ">"
                      << std::endl;
#endif

            output_m[k] = r;

            // cover or purify each node on the same row as the node we're branching on
            for (toroid_node_t* j(toroid_m.right_of(r)); j != r; j = toroid_m.right_of(j)) {
                if (j->color_m == 0) {
#if ADOBE_DLX_VERBOSE
                    std::cout << adobe::indents(tab_count_m) << "<c" << toroid_m.column_index_of(j)
                              << ">" << std::endl;
#endif
                    toroid_m.cover_column(toroid_m.column_of(j));
                } else if (j->color_m > 0) {
#if ADOBE_DLX_VERBOSE
                    std::cout << adobe::indents(tab_count_m) << "<p" << toroid_m.column_index_of(j)
                              << ">" << std::endl;
#endif
                    toroid_m.purify(j);
                }
            }

#if ADOBE_DLX_VERBOSE
// std::cout << *this << std::endl;
#endif

            do_search(next_k, callback, heuristic);

            if (solutions_m >= max_solutions_m)
                return;

            r = output_m[k];

            c = toroid_m.column_of(r);

            // undo the cover/purify
            for (toroid_node_t* j(toroid_m.left_of(r)); j != r; j = toroid_m.left_of(j)) {
                if (j->color_m == 0) {
#if ADOBE_DLX_VERBOSE
                    std::cout << adobe::indents(tab_count_m) << "</c" << toroid_m.column_index_of(j)
                              << ">" << std::endl;
#endif
                    toroid_m.uncover_column(toroid_m.column_of(j));
                } else if (j->color_m > 0) {
#if ADOBE_DLX_VERBOSE
                    std::cout << adobe::indents(tab_count_m) << "</p" << toroid_m.column_index_of(j)
                              << ">" << std::endl;
#endif
                    toroid_m.unpurify(j);
                }
            }

#if ADOBE_DLX_VERBOSE
            std::cout << adobe::indents(tab_count_m) << "</r" << toroid_m.row_index_of(r) << ">"
                      << std::endl;
#endif
        }

        toroid_m.uncover_column(c);

#if ADOBE_DLX_VERBOSE
        std::cout << adobe::indents(tab_count_m) << "</c"
                  << toroid_m.column_index_of(toroid_m.down_of(c)) << ">" << std::endl;
        --tab_count_m;
#endif
    };

    byte_toroid_t toroid_m;
    std::vector<toroid_node_t*> output_m;
    std::size_t solutions_m;
    std::size_t max_solutions_m;
#if ADOBE_DLX_VERBOSE
    std::size_t tab_count_m;
#endif
};

/**************************************************************************************************/

} // namespace adobe

/**************************************************************************************************/

#endif

/**************************************************************************************************/


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

#include "Listener.hh"
#include "Logger.hh"
#include "Engine.hh"
#include "EventJSON.hh"
#include "Trace.hh"
#include "Utility.hh"
#include <cstdlib>
#include <cctype>
#include <sstream>
#include <boost/date_time/posix_time/conversion.hpp>
#include <cpprest/pplx/threadpool.h>

extern "C" {
#include "cJSON.h"
#include <unistd.h>
}

// Set default checkpoint time to 1/2 the default dupe-detection window. The default window
// is one hour.
unsigned int Listener::checkpointSeconds = 60 * 60 / 2;

// Thread startproc. If and when the specific ProcessLoop() method returns, cleanup and exit.
// The pthread interface requires this method to both accept and return a void*.
void *
Listener::handler(void * obj)
{
        Trace trace(Trace::EventIngest, "Listener::handler");

        // Create a shared_ptr to own the Listener object
        auto listener = std::shared_ptr<Listener>((Listener*)obj);

        trace.NOTE("Start timer for " + listener->Name());
        // Start the timer running
        listener->Timer().expires_from_now(boost::posix_time::seconds(checkpointSeconds));
        listener->Timer().async_wait(boost::bind(&Listener::timerhandler, listener, TimerTask::rotate));

        auto result = listener->ProcessLoop();
        trace.NOTE("Returned from ProcessLoop for " + listener->Name());

        listener->Shutdown();

        return result;
}

// Upon receiving an indication from the sender that the session is over, call this method to
// shutdown our end of it. This method should be called synchronously on the listening thread;
// the only expected race is against the timer handler. Once we set _finished, the timer handler
// will do its own cleanup the next time it runs. If the timer handler runs between the moment
// Shutdown sets _finished and the moment it calls _timer.cancel(), we'll be cancelling a timer
// that wasn't set, but that is perfectly fine.
void
Listener::Shutdown()
{
        Trace trace(Trace::EventIngest, "Listener::Shutdown");
        trace.NOTE("Shutting down " + Name());
        close(clientfd);
        _finished = true;
        _timer.cancel();
}

// Parse one or more objects out of a range of characters in the half-open range [start, end).
// Return a pointer to the character immediately following the last object successfully parsed
// (and skipping any trailing whitespace).
// This return value is guaranteed to be <= end. If no message was successfully parsed, a null
// pointer (0) will be returned.
// The parser assumes *end is a NUL byte so it can treat the range as a C string.
const char *
Listener::ParseBuffer(const char* start, const char* end)
{
        Trace trace(Trace::EventIngest, "Listener::ParseBuffer");
        const char * parse_end = 0;
        const char * lkg_parse_end = 0;
        cJSON * event;

        if (*end != '\0') {
                std::ostringstream msg;
                size_t n = end - start + 1;
                msg << "ParseBuffer " << Name() << " got a non-NUL terminated range, length = " << n << "\n";
                DumpBuffer(msg, start, end);
                throw Listener::exception(msg);
        }

        while ((start < end) && (event = cJSON_ParseWithOpts(start, &parse_end, 0))) {
                if (parse_end > end) {
                        std::ostringstream msg;
                        msg << "ParseBuffer found an object longer than the input buffer. Start " << (void *)start << ", end ";
                        msg << (void *)end << ", parse_end " << (void *)parse_end << "\n";
                        if (*end != '\0') {
                                msg << "Range is no longer NUL-terminated.\n";
                        }
                        DumpBuffer(msg, start, end);
                        throw Listener::exception(msg);
                }

                bool status = TryParseEvent(event) || TryParseEcho(event);
                if (!status) {
                        LogBadJSON(event, Name() + " ignored unknown JSON message");
                }

                // Free the parsed event
                cJSON_Delete(event);

                // Advance past the object we just parsed, skip trailing whitespace.
                // I don't really have to do this; cJSON handles leading whitespace. But it's better
                // if I can consume a full buffer; that reduces copying of useless characters.
                while ((parse_end < end) && (isspace(*parse_end))) {
                        parse_end++;
                }
                start = lkg_parse_end = parse_end;
        }
        if (lkg_parse_end != parse_end) {
                TRACEINFO(trace, "parse_end (" << (void*)parse_end << ") != lkg (" << (void*)lkg_parse_end << ")");
        }
        return lkg_parse_end;
}

bool
Listener::TryParseEvent(cJSON* event)
{
    Trace trace(Trace::EventIngest, "Listener::TryParseEvent");

    cJSON* jsTAG = cJSON_GetObjectItem(event, "TAG");
    if (!jsTAG || jsTAG->type != cJSON_String) {
        return false;
    }

    cJSON* jsSOURCE = cJSON_GetObjectItem(event, "SOURCE");
    cJSON* jsDATA = cJSON_GetObjectItem(event, "DATA");
    if ((jsSOURCE && jsSOURCE->type == cJSON_String) && (jsDATA && jsDATA->type == cJSON_Array)) {
        // That's plenty of validation for now.
        if (trace.IsActive()) {
            char *rendering = cJSON_Print(event);
            auto len = strlen(rendering);
            TRACEINFO(trace, "Got event from source " << jsSOURCE->valuestring << " of total size " << len);
            if (trace.IsAlsoActive(Trace::IngestContents)) {
                std::ostringstream msg;
                std::string body(rendering, (len>1024?1024:len));
                msg << Name() << " received JSON event " << body;
                if (len > 1024) {
                    msg << " ... }";
                }
                trace.NOTE(msg.str());
            }
            free(rendering);
        }
        if (IsNewTag(jsTAG)) {
            // Process the event...
            EventJSON evt(event);
            Engine::GetEngine()->ProcessEvent(evt);
        }
        // Inform the client we've processed the event
        EchoTag(jsTAG->valuestring);
    }
    else {
        LogBadJSON(event, Name() + " received incomplete JSON-encoded event");
    }
    return true;
}

bool
Listener::TryParseEcho(cJSON* event)
{
    Trace trace(Trace::EventIngest, "Listener::TryParseEcho");

    cJSON* jsECHO = cJSON_GetObjectItem(event, "ECHO");
    if (jsECHO && jsECHO->type == cJSON_String) {
            EchoTag(jsECHO->valuestring);
            return true;
    }
    return false;
}

void
Listener::LogBadJSON(cJSON* event, const std::string& prefix)
{
        char *rendering = cJSON_Print(event);
        Logger::LogError(prefix + " {" + rendering + "}");
        free(rendering);
}

// Echo the tag, followed by a newline, back to the client.
void
Listener::EchoTag(char * tagptr)
{
        try {
                MdsdUtil::WriteBufferAndNewline(clientfd, tagptr);
        }
        catch (const MdsdUtil::would_block& e) {
                std::ostringstream msg;
                msg << "Event source tag-reader is slow; dropping tag " << tagptr;
                Logger::LogWarn(msg);
        }
        catch (const std::system_error& e) {
                if (EPIPE == e.code().value()) {
                        throw Listener::exception(std::string("Event sender closed connection: ") + e.what());
                }
                else {
                        Logger::LogError(std::string("Listener failed to echo TAG: ") + e.what());
                }
        }
        catch (const std::runtime_error& e) {
                Logger::LogError(std::string("Listener failed to echo TAG: ") + e.what());
        }
}

Listener::Listener(int fd) : clientfd(fd),
                tagsAgedOut(0), tagsOldest(new tag_set()), tagsOld(new tag_set()), tagsCurr(new tag_set()),
                _timer(crossplat::threadpool::shared_instance().service()), _finished(false)
{
        Trace trace(Trace::EventIngest, "Listener::Listener");

        std::ostringstream msg;
        msg << this;
        _name = msg.str();

        trace.NOTE("Constructed Listener " + Name());
}

Listener::~Listener()
{
        Trace trace(Trace::EventIngest, "Listener::~Listener");

        Logger::LogWarn("Closing fd in ~Listener()");
        trace.NOTE("Destroying Listener " + Name());
        close(clientfd);
        if (tagsAgedOut) {
                delete tagsAgedOut;
                tagsAgedOut = 0;
        }
        if (tagsOldest) {
                delete tagsOldest;
                tagsOldest = nullptr;
        }
        if (tagsOld) {
                delete tagsOld;
                tagsOld = nullptr;
        }
        if (tagsCurr) {
                delete tagsCurr;
                tagsCurr = nullptr;
        }
}

bool Listener::IsNewTag(cJSON* jsTAG)
{
        Trace trace(Trace::EventIngest, "Listener::IsNewTag");
        if (nullptr == jsTAG)
        {
                trace.NOTE("Got a NULL JSON object pointer");
                return false;
        } else if (nullptr == jsTAG->valuestring) {
                trace.NOTE("JSON object had NULL valuestring");
                return false;
        } else if (0 == *(jsTAG->valuestring)) {
                trace.NOTE("JSON object had zero-length valuestring");
                return false;
        }

        trace.NOTE("Checking tag \"" + std::string(jsTAG->valuestring) + "\"");

        bool isNewTag = true;
        std::string tagstr(jsTAG->valuestring);

        // Capture the tag sets to check. We're racing against the timer handler which will
        // rotate the grandparent to great-grandparent, parent to grandparent, current to
        // parent, and an empty set into current. When we capture current/parent/grand during
        // the rotation operation, we might wind up with empty/current/parent or
        // current/current/parent or current/parent/parent, but since we're checking right
        // on the "rotation" time, the relevant time window really does encompass just current
        // and parent at the instant we start looking. We might wind up checking a tag set
        // twice, but we won't segfault and we won't miss checking a relevant tag set.

        auto currentSet = tagsCurr;
        auto parentSet = tagsOld;
        auto grandparentSet = tagsOldest;

        if (currentSet->end() != currentSet->find(tagstr) ||
                parentSet->end() != parentSet->find(tagstr) ||
                grandparentSet->end() != grandparentSet->find(tagstr))
        {
                isNewTag = false;
                trace.NOTE("Tag is a duplicate");
        }
        else
        {
                // Yes, I really mean tagsCurr. If rotation happened between the time this
                // thread grabbed the set pointers and now, currentSet points to tagsOld, so
                // putting this tag into currentSet might leave the tag active for just a hair
                // less than the guaranteed interval. Better too long than too short.
                tagsCurr->insert(tagstr);
                trace.NOTE("Tag is new");
        }

        return isNewTag;
}

void
Listener::RotateTagSets()
{
        Trace trace(Trace::EventIngest, "Listener::RotateTagSets");

        if (trace.IsActive())
        {
                std::ostringstream msg;
                msg << Name() << " Tagset sizes: Curr=" << tagsCurr->size() << "; Old=" << tagsOld->size();
                msg << "; Oldest=" << tagsOldest->size();
                trace.NOTE(msg.str());
        }

        tagsAgedOut = tagsOldest;
        tagsOldest = tagsOld;
        tagsOld = tagsCurr;
        tagsCurr = new tag_set();
}

void
Listener::ScrubTagSets()
{
        Trace trace(Trace::EventIngest, "Listener::ScrubTagSets");

        if (tagsAgedOut) {
                if (trace.IsActive()) {
                        std::ostringstream msg;
                        msg << Name() << " releasing " << tagsAgedOut->size() << " tags";
                        trace.NOTE(msg.str());
                }
                delete tagsAgedOut;
                tagsAgedOut = 0;
        }
}

void
Listener::timerhandler(std::shared_ptr<Listener> listener, Listener::TimerTask job)
{
        Trace trace(Trace::EventIngest, "Listener::timerhandler");

        if (listener->IsFinished()) {
                // Do nothing; especially, do not reschedule the timer. The deadline_timer code
                // will allow its copy of the shared_ptr for this instance to go out of scope,
                // triggering a safe delete of the Listener class instance. If we were cancelled,
                // we'll want to do exactly the same thing, and Listener::handler is careful to set
                // _socketClosed before it tries to cancel the timer. As a result, there's no need
                // to check to see if we're being cancelled or not; if _socketClosed is set,
                // just return.
                trace.NOTE(listener->Name() + " IsFinished is true");
                return;
        }

        switch (job) {
        case TimerTask::rotate:
                listener->RotateTagSets();
                listener->Timer().expires_from_now(boost::posix_time::seconds(15));
                listener->Timer().async_wait(boost::bind(&Listener::timerhandler, listener, TimerTask::cleanup));
                break;

        case TimerTask::cleanup:
                listener->ScrubTagSets();
                listener->Timer().expires_from_now(boost::posix_time::seconds(checkpointSeconds - 15));
                listener->Timer().async_wait(boost::bind(&Listener::timerhandler, listener, TimerTask::rotate));
                break;

        default:
                Logger::LogError("Listener::timerhandler saw unexpected state " + std::to_string(job));
                listener->Timer().expires_from_now(boost::posix_time::seconds(checkpointSeconds));
                listener->Timer().async_wait(boost::bind(&Listener::timerhandler, listener, TimerTask::rotate));
                break;
        }
}

void
Listener::DumpBuffer(std::ostream& os, const char* start, const char* end)
{
        size_t n = end - start + 1;
        if (n < 1024*1024) {
                os << "Buffer contents [" << std::string(start, n) << "]";
        } else {
                os << "Partial buffer contents [" << std::string(start, 1024*1024) << "]";
        }
}

// vim: set ai sw=8 expandtab :

max_stars_repo_name: shridpant/azure-linux-extensions

max_issues_repo_name: shridpant/azure-linux-extensions

max_forks_repo_name: shridpant/azure-linux-extensions


text:
// Copyright (c) 2008 Michael B. Edwin Rickert
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt )
//
// $LastChangedBy$ - $LastChangedDate$

#include <industry/enum.hpp>
#include <boost/test/auto_unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <string>

namespace {
	INDUSTRY_ENUM( day, (is)(os)(duplicate_constants_in_outer_scope), (sunday)(monday)(tuesday)(wednesday)(thursday)(friday)(saturday) );

	bool overloaded_right( day ) { return true;  }
	bool overloaded_right( int ) { return false; }
}

BOOST_AUTO_TEST_CASE( test_enum ) {
	const day day1 = day::monday;
	const day day2 = day::tuesday;

	BOOST_CHECK_EQUAL( day1.value, day::monday  );
	BOOST_CHECK_EQUAL( day2.value, day::tuesday );

	BOOST_CHECK_EQUAL( day1       , day1        );
	BOOST_CHECK_EQUAL( day1       , day::monday );
	BOOST_CHECK_EQUAL( day::monday, day1        );

	BOOST_CHECK( day1         != day2         );
	BOOST_CHECK( day::tuesday != day1         );
	BOOST_CHECK( day1         != day::tuesday );

	BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(day1), "monday"    );
	BOOST_CHECK_EQUAL( boost::lexical_cast<day>    ("monday"), day::monday );
	BOOST_CHECK_EQUAL( boost::lexical_cast<day>    ("mOnDaY"), day::monday );

	BOOST_CHECK_THROW( boost::lexical_cast<day>("monda")  , boost::bad_lexical_cast );
	BOOST_CHECK_THROW( boost::lexical_cast<day>("mondayz"), boost::bad_lexical_cast );
	BOOST_CHECK_THROW( boost::lexical_cast<day>("monday "), boost::bad_lexical_cast );

	BOOST_CHECK( overloaded_right(day1) );
	BOOST_CHECK( overloaded_right(day::monday) );
}

BOOST_AUTO_TEST_CASE( test_enum_raw ) {
	const day day1 = day::_monday;
	const day day2 = day::_tuesday;

	BOOST_CHECK_EQUAL( day1.value, day::_monday  );
	BOOST_CHECK_EQUAL( day2.value, day::_tuesday );

	BOOST_CHECK_EQUAL( day1       , day1        );
	BOOST_CHECK_EQUAL( day1       , day::_monday );
	BOOST_CHECK_EQUAL( day::_monday, day1        );

	BOOST_CHECK( day1          != day2         );
	BOOST_CHECK( day::_tuesday != day1         );
	BOOST_CHECK( day1          != day::_tuesday );

	BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(day1), "monday"     );
	BOOST_CHECK_EQUAL( boost::lexical_cast<day>    ("monday"), day::_monday );
	BOOST_CHECK_EQUAL( boost::lexical_cast<day>    ("mOnDaY"), day::_monday );

	BOOST_CHECK_THROW( boost::lexical_cast<day>("monda")  , boost::bad_lexical_cast );
	BOOST_CHECK_THROW( boost::lexical_cast<day>("mondayz"), boost::bad_lexical_cast );
	BOOST_CHECK_THROW( boost::lexical_cast<day>("monday "), boost::bad_lexical_cast );

	BOOST_CHECK( overloaded_right(day1) );
	BOOST_CHECK(!overloaded_right(day::_monday) ); // We can't get this right since it's an actual enum.
}

BOOST_AUTO_TEST_CASE( test_enum_outer_scope ) {
	const day day1 = monday;
	const day day2 = tuesday;

	BOOST_CHECK_EQUAL( day1.value, monday  );
	BOOST_CHECK_EQUAL( day2.value, tuesday );

	BOOST_CHECK_EQUAL( day1  , day1   );
	BOOST_CHECK_EQUAL( day1  , monday );
	BOOST_CHECK_EQUAL( monday, day1   );

	BOOST_CHECK( day1         != day2         );
	BOOST_CHECK( day::tuesday != day1         );
	BOOST_CHECK( day1         != day::tuesday );

	BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(day1), "monday"    );
	BOOST_CHECK_EQUAL( boost::lexical_cast<day>    ("monday"), monday );
	BOOST_CHECK_EQUAL( boost::lexical_cast<day>    ("mOnDaY"), monday );

	BOOST_CHECK_THROW( boost::lexical_cast<day>("monda")  , boost::bad_lexical_cast );
	BOOST_CHECK_THROW( boost::lexical_cast<day>("mondayz"), boost::bad_lexical_cast );
	BOOST_CHECK_THROW( boost::lexical_cast<day>("monday "), boost::bad_lexical_cast );

	BOOST_CHECK( overloaded_right(day1)   );
	BOOST_CHECK( overloaded_right(monday) );
}

max_stars_repo_name: MaulingMonkey/libindustry

max_issues_repo_name: MaulingMonkey/libindustry

max_forks_repo_name: MaulingMonkey/libindustry


text:
// -----------------------------------------------------------------------
// RTToolbox - DKFZ radiotherapy quantitative evaluation library
//
// Copyright (c) German Cancer Research Center (DKFZ),
// Software development for Integrated Diagnostics and Therapy (SIDT).
// ALL RIGHTS RESERVED.
// See rttbCopyright.txt or
// http://www.dkfz.de/en/sidt/projects/rttb/copyright.html
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.  See the above copyright notices for more information.
//
//------------------------------------------------------------------------

#include <boost/make_shared.hpp>

#include "rttbDicomHelaxIODVecDoseAccessorGenerator.h"
#include "rttbDicomHelaxDoseAccessor.h"

namespace rttb
{
	namespace io
	{
		namespace helax
		{

			DicomHelaxIODVecDoseAccessorGenerator::~DicomHelaxIODVecDoseAccessorGenerator() = default;

			DicomHelaxIODVecDoseAccessorGenerator::DicomHelaxIODVecDoseAccessorGenerator(
			    std::vector<DRTDoseIODPtr>&
			    aDICOMRTDoseVector)
			{
				_dosePtrVector = aDICOMRTDoseVector;

			}

			core::DoseAccessorGeneratorInterface::DoseAccessorPointer
			DicomHelaxIODVecDoseAccessorGenerator::generateDoseAccessor()
			{
				_doseAccessor = boost::make_shared<io::helax::DicomHelaxDoseAccessor>(_dosePtrVector);
				return _doseAccessor;
			}

		}
	}
}

max_stars_repo_name: MIC-DKFZ/RTTB

max_issues_repo_name: MIC-DKFZ/RTTB

max_forks_repo_name: MIC-DKFZ/RTTB


text:
#include <iostream>

#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>

#include <onmt/Tokenizer.h>

namespace po = boost::program_options;

int main(int argc, char* argv[])
{
  po::options_description desc("Tokenization");
  desc.add_options()
    ("help,h", "display available options")
    ("mode,m", po::value<std::string>()->default_value("conservative"), "Define how aggressive should the tokenization be: 'aggressive' only keeps sequences of letters/numbers, 'conservative' allows mix of alphanumeric as in: '2,000', 'E65', 'soft-landing'")
    ("joiner_annotate,j", po::bool_switch()->default_value(false), "include joiner annotation using 'joiner' character")
    ("joiner", po::value<std::string>()->default_value(onmt::Tokenizer::joiner_marker), "character used to annotate joiners")
    ("joiner_new", po::bool_switch()->default_value(false), "in joiner_annotate mode, 'joiner' is an independent token")
    ("case_feature,c", po::bool_switch()->default_value(false), "lowercase corpus and generate case feature")
    ("segment_case", po::bool_switch()->default_value(false), "Segment case feature, splits AbC to Ab C to be able to restore case")
    ("segment_numbers", po::bool_switch()->default_value(false), "Segment numbers into single digits")
    ("segment_alphabet", po::value<std::string>()->default_value(""), "comma-separated list of alphabets on which to segment all letters.")
    ("segment_alphabet_change", po::bool_switch()->default_value(false), "Segment if the alphabet changes between 2 letters.")
    ("bpe_model,bpe", po::value<std::string>()->default_value(""), "path to the BPE model")
    ;

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help"))
  {
    std::cerr << desc << std::endl;
    return 1;
  }

  int flags = 0;
  if (vm["case_feature"].as<bool>())
    flags |= onmt::Tokenizer::Flags::CaseFeature;
  if (vm["joiner_annotate"].as<bool>())
    flags |= onmt::Tokenizer::Flags::JoinerAnnotate;
  if (vm["joiner_new"].as<bool>())
    flags |= onmt::Tokenizer::Flags::JoinerNew;
  if (vm["segment_case"].as<bool>())
    flags |= onmt::Tokenizer::Flags::SegmentCase;
  if (vm["segment_numbers"].as<bool>())
    flags |= onmt::Tokenizer::Flags::SegmentNumbers;
  if (vm["segment_alphabet_change"].as<bool>())
    flags |= onmt::Tokenizer::Flags::SegmentAlphabetChange;

  std::vector<std::string> alphabets_to_segment;
  boost::split(alphabets_to_segment,
               vm["segment_alphabet"].as<std::string>(),
               boost::is_any_of(","));

  onmt::Tokenizer* tokenizer = new onmt::Tokenizer(
    onmt::Tokenizer::mapMode.at(vm["mode"].as<std::string>()),
    flags,
    vm["bpe_model"].as<std::string>(),
    vm["joiner"].as<std::string>());

  for (const auto& alphabet : alphabets_to_segment)
  {
    if (!alphabet.empty() && !tokenizer->add_alphabet_to_segment(alphabet))
      std::cerr << "WARNING: " << alphabet << " alphabet is not supported" << std::endl;
  }

  std::string line;

  while (std::getline(std::cin, line))
  {
    if (!line.empty())
      std::cout << reinterpret_cast<onmt::ITokenizer*>(tokenizer)->tokenize(line);

    std::cout << std::endl;
  }

  return 0;
}

max_stars_repo_name: monsieurzhang/Tokenizer

max_issues_repo_name: monsieurzhang/Tokenizer

max_forks_repo_name: monsieurzhang/Tokenizer


text:
// Copyright (C) 2014 The Regents of the University of California (Regents).
// 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 Regents or University of California 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 HOLDERS 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.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include "theia/io/sift_text_file.h"

#include <Eigen/Core>
#include <glog/logging.h>
#include <stdint.h>

#include <cstdio>
#include <cstdlib>
#include <fstream>  // NOLINT
#include <iostream>  // NOLINT
#include <string>
#include <vector>

namespace theia {

// The sift key file has the following format:
//
// number_of_keypoints sift_descriptor_dimensions (both as ints)
// for each descriptor:
//   row col scale orientation (all as floats)
//   128 ints describing sift descriptor. Normalizing this 128-vector to unit
//     length will yield the true sift descriptor.
// NOTE: We use getline and strtof which should be much faster than letting the
// stream parse the string with operator >>.
bool ReadSiftKeyTextFile(const std::string& sift_key_file,
                         std::vector<Eigen::VectorXf>* descriptor,
                         std::vector<Keypoint>* keypoint) {
  CHECK_NOTNULL(descriptor)->clear();
  CHECK_NOTNULL(keypoint)->clear();

  FILE* fp = fopen(sift_key_file.c_str(), "r");
  int num_descriptors, len;

  if (fscanf(fp, "%d %d", &num_descriptors, &len) != 2) {
    printf("Invalid keypoint file\n");
    return 0;
  }

  CHECK_EQ(len, 128);

  descriptor->reserve(num_descriptors);
  keypoint->reserve(num_descriptors);

  for (int i = 0; i < num_descriptors; i++) {
    float x, y, scale, ori;

    if (fscanf(fp, "%f %f %f %f\n", &y, &x, &scale, &ori) != 4) {
      printf("Invalid keypoint file format.");
      return 0;
    }

    Keypoint kp(x, y, Keypoint::SIFT);
    kp.set_scale(scale);
    kp.set_orientation(ori);
    keypoint->push_back(kp);

    char buf[1024];
    Eigen::Matrix<uint8_t, Eigen::Dynamic, 1> int_descriptor(128);
    uint8_t* p = int_descriptor.data();
    for (int line = 0; line < 6; line++) {
      CHECK_NOTNULL(fgets(buf, 1024, fp));
      sscanf(buf, "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu "
             "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu",
             p + 0, p + 1, p + 2, p + 3, p + 4, p + 5, p + 6, p + 7, p + 8,
             p + 9, p + 10, p + 11, p + 12, p + 13, p + 14, p + 15, p + 16,
             p + 17, p + 18, p + 19);

      p += 20;
    }
    CHECK_NOTNULL(fgets(buf, 1024, fp));
    sscanf(buf, "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu", p + 0, p + 1,
           p + 2, p + 3, p + 4, p + 5, p + 6, p + 7);

    Eigen::VectorXf float_descriptor = int_descriptor.cast<float>();
    float_descriptor /= 255.0;
    descriptor->push_back(float_descriptor);
  }

  fclose(fp);
  return true;
}

}  // namespace theia


text:
/*
 * Copyright 2020 OmniSci, 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.
 */

#include "OSDependent/omnisci_path.h"

#include <boost/filesystem/path.hpp>

#include "Logger/Logger.h"

#include "Shared/clean_windows.h"

namespace omnisci {

std::string get_root_abs_path() {
  char abs_exe_path[MAX_PATH];
  auto path_len = GetModuleFileNameA(NULL, abs_exe_path, MAX_PATH);
  CHECK_GT(path_len, 0u);
  CHECK_LT(static_cast<size_t>(path_len), sizeof(abs_exe_path));
  boost::filesystem::path abs_exe_dir(std::string(abs_exe_path, path_len));
  abs_exe_dir.remove_filename();
  const auto mapd_root = abs_exe_dir.parent_path();

  return mapd_root.string();
}

}  // namespace omnisci

max_stars_repo_name: Pahandrovich/omniscidb

max_issues_repo_name: Pahandrovich/omniscidb

max_forks_repo_name: Pahandrovich/omniscidb