text:
#include "cryptonote_config.h"
#include "common/loki.h"
#include "int-util.h"
#include <vector>
#include <boost/lexical_cast.hpp>
#include <cfenv>

#include "service_node_rules.h"

namespace service_nodes {

uint64_t get_staking_requirement(cryptonote::network_type m_nettype, uint64_t height, uint8_t hf_version)
{
  if (m_nettype == cryptonote::TESTNET || m_nettype == cryptonote::FAKECHAIN)
      return COIN * 100;

  uint64_t base = 0, variable = 0;
  if (hf_version >= cryptonote::network_version_13_enforce_checkpoints)
  {
    base     = 950000 * COIN;
    variable = 0; // no floating
    uint64_t result = base + variable;
    return static_cast<uint64_t>(result);
  }

  uint64_t hardfork_height = m_nettype == cryptonote::MAINNET ?  5 : 5 /* stagenet */; // SEEME
  if (height < hardfork_height) height = hardfork_height;

  uint64_t height_adjusted = height - hardfork_height;
  std::fesetround(FE_TONEAREST);

  if (hf_version >= cryptonote::network_version_11_infinite_staking)
  {
    base     = 9000000 * COIN;
    variable = (25007.0 * COIN) / loki::exp2(height_adjusted/129600.0);
  }
  else
  {
    base      = 9000000 * COIN;
    variable  = (35000.0 * COIN) / loki::exp2(height_adjusted/129600.0);
  }

  uint64_t result = base + variable;
  return result;
}

uint64_t portions_to_amount(uint64_t portions, uint64_t staking_requirement)
{
  uint64_t hi, lo, resulthi, resultlo;
  lo = mul128(staking_requirement, portions, &hi);
  div128_64(hi, lo, STAKING_PORTIONS, &resulthi, &resultlo);
  return resultlo;
}

bool check_service_node_portions(uint8_t hf_version, const std::vector<uint64_t>& portions)
{
  if (portions.size() > MAX_NUMBER_OF_CONTRIBUTORS) return false;

  uint64_t reserved = 0;
  for (auto i = 0u; i < portions.size(); ++i)
  {
    const uint64_t min_portions = get_min_node_contribution(hf_version, STAKING_PORTIONS, reserved, i);
    if (portions[i] < min_portions) return false;
    reserved += portions[i];
  }

  return reserved <= STAKING_PORTIONS;
}

crypto::hash generate_request_stake_unlock_hash(uint32_t nonce)
{
  crypto::hash result   = {};
  char const *nonce_ptr = (char *)&nonce;
  char *hash_ptr        = result.data;
  static_assert(sizeof(result) % sizeof(nonce) == 0, "The nonce should be evenly divisible into the hash");
  for (size_t i = 0; i < sizeof(result) / sizeof(nonce); ++i)
  {
    memcpy(hash_ptr, nonce_ptr, sizeof(nonce));
    hash_ptr += sizeof(nonce);
  }

  assert(hash_ptr == (char *)result.data + sizeof(result));
  return result;
}

uint64_t get_locked_key_image_unlock_height(cryptonote::network_type nettype, uint64_t node_register_height, uint64_t curr_height)
{
  uint64_t blocks_to_lock = staking_num_lock_blocks(nettype);
  uint64_t result         = curr_height + (blocks_to_lock / 2);
  return result;
}

static uint64_t get_min_node_contribution_pre_v11(uint64_t staking_requirement, uint64_t total_reserved)
{
  return std::min(staking_requirement - total_reserved, staking_requirement / MAX_NUMBER_OF_CONTRIBUTORS);
}

uint64_t get_min_node_contribution(uint8_t version, uint64_t staking_requirement, uint64_t total_reserved, size_t num_contributions)
{
  if (version < cryptonote::network_version_11_infinite_staking)
    return get_min_node_contribution_pre_v11(staking_requirement, total_reserved);

  const uint64_t needed = staking_requirement - total_reserved;
  assert(MAX_NUMBER_OF_CONTRIBUTORS > num_contributions);
  if (MAX_NUMBER_OF_CONTRIBUTORS <= num_contributions) return UINT64_MAX;

  const size_t num_contributions_remaining_avail = MAX_NUMBER_OF_CONTRIBUTORS - num_contributions;
  return needed / num_contributions_remaining_avail;
}

uint64_t get_min_node_contribution_in_portions(uint8_t version, uint64_t staking_requirement, uint64_t total_reserved, size_t num_contributions)
{
  uint64_t atomic_amount = get_min_node_contribution(version, staking_requirement, total_reserved, num_contributions);
  uint64_t result        = (atomic_amount == UINT64_MAX) ? UINT64_MAX : (get_portions_to_make_amount(staking_requirement, atomic_amount));
  return result;
}

uint64_t get_portions_to_make_amount(uint64_t staking_requirement, uint64_t amount)
{
  uint64_t lo, hi, resulthi, resultlo;
  lo = mul128(amount, STAKING_PORTIONS, &hi);
  if (lo > UINT64_MAX - (staking_requirement - 1))
    hi++;
  lo += staking_requirement-1;
  div128_64(hi, lo, staking_requirement, &resulthi, &resultlo);
  return resultlo;
}

static bool get_portions_from_percent(double cur_percent, uint64_t& portions) {
  if(cur_percent < 0.0 || cur_percent > 100.0) return false;

  // Fix for truncation issue when operator cut = 100 for a pool Service Node.
  if (cur_percent == 100.0)
  {
    portions = STAKING_PORTIONS;
  }
  else
  {
    portions = (cur_percent / 100.0) * STAKING_PORTIONS;
  }

  return true;
}

bool get_portions_from_percent_str(std::string cut_str, uint64_t& portions) {

  if(!cut_str.empty() && cut_str.back() == '%')
  {
    cut_str.pop_back();
  }

  double cut_percent;
  try
  {
    cut_percent = boost::lexical_cast<double>(cut_str);
  }
  catch(...)
  {
    return false;
  }

  return get_portions_from_percent(cut_percent, portions);
}

} // namespace service_nodes

max_stars_repo_name: bittoro/bittoro

max_issues_repo_name: contentnetwork/blogcoin

max_forks_repo_name: contentnetwork/blogcoin


text:
/*
 The MIT License (MIT)

 Copyright (C) 2017 RSK Labs Ltd.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
#include "GwMaker.h"
#include "Utils.h"

#include <limits.h>
#include <glog/logging.h>
#include <boost/thread.hpp>

#include <event2/http.h>
#include <event2/http_struct.h>
#include <event2/buffer.h>
#include <event2/buffer_compat.h>
#include <event2/keyvalq_struct.h>

#include <chrono>
#include <thread>

///////////////////////////////GwMaker////////////////////////////////////
GwMaker::GwMaker(shared_ptr<GwMakerHandler> handler, const string &kafkaBrokers)
  : handler_(handler)
  , running_(true)
  , kafkaProducer_(
        kafkaBrokers.c_str(),
        handler->def().rawGwTopic_.c_str(),
        0 /* partition */) {
}

GwMaker::~GwMaker() {
}

bool GwMaker::init() {
  map<string, string> options;
  // set to 1 (0 is an illegal value here), deliver msg as soon as possible.
  options["queue.buffering.max.ms"] = "1";
  if (!kafkaProducer_.setup(&options)) {
    LOG(ERROR) << "kafka producer setup failure";
    return false;
  }

  // setup kafka and check if it's alive
  if (!kafkaProducer_.checkAlive()) {
    LOG(ERROR) << "kafka is NOT alive";
    return false;
  }

  if (handler_->def().notifyHost_.length() > 0) {
    auto callback = [&]() -> void { submitRawGwMsg(); };
    notification_ = make_shared<GwNotification>(
        callback, handler_->def().notifyHost_, handler_->def().notifyPort_);
    notification_->setupHttpd();
  }

  // TODO: check rskd is alive in a similar way as done for btcd

  return true;
}

void GwMaker::stop() {
  if (!running_) {
    return;
  }
  running_ = false;
  LOG(INFO) << "stop GwMaker " << handler_->def().chainType_
            << ", topic: " << handler_->def().rawGwTopic_;
}

void GwMaker::kafkaProduceMsg(const void *payload, size_t len) {
  kafkaProducer_.produce(payload, len);
}

string GwMaker::makeRawGwMsg() {
  return handler_->makeRawGwMsg();
}

void GwMaker::submitRawGwMsg() {

  const string rawGwMsg = makeRawGwMsg();
  if (rawGwMsg.length() == 0) {
    LOG(ERROR) << "get rawGw failure";
    return;
  }

  // submit to Kafka
  LOG(INFO) << "submit to Kafka msg len: " << rawGwMsg.length();
  kafkaProduceMsg(rawGwMsg.c_str(), rawGwMsg.length());
}

void GwMaker::run() {

  while (running_) {
    std::this_thread::sleep_for(
        std::chrono::milliseconds{handler_->def().rpcInterval_});
    submitRawGwMsg();
  }

  LOG(INFO) << "GwMaker " << handler_->def().chainType_
            << ", topic: " << handler_->def().rawGwTopic_ << " stopped";
}

///////////////////////////////GwNotification////////////////////////////////////
/*
 * https://wiki.parity.io/Mining.html
 * Parity HTTP Notification
 */
GwNotification::GwNotification(
    std::function<void(void)> callback,
    const string &httpdHost,
    unsigned short httpdPort)
  : callback_(callback)
  , base_(nullptr)
  , httpdHost_(httpdHost)
  , httpdPort_(httpdPort) {
}

GwNotification::~GwNotification() {
  stop();
}

void GwNotification::httpdNotification(struct evhttp_request *req, void *arg) {
  struct evbuffer *evb = evbuffer_new();
  Strings::EvBufferAdd(evb, "{\"err_no\":0,\"err_msg\":\"notify success\"}");
  evhttp_send_reply(req, HTTP_OK, "OK", evb);
  evbuffer_free(evb);

  string postData = string(
      (char *)EVBUFFER_DATA(req->input_buffer),
      EVBUFFER_LENGTH(req->input_buffer));
  LOG(INFO) << "GwNotification: makeRawGwMsg for notify " << postData;

  GwNotification *notification = (GwNotification *)arg;
  notification->callback_();
}

void GwNotification::setupHttpd() {
  boost::thread t(boost::bind(&GwNotification::runHttpd, this));
  t.detach();
}

void GwNotification::runHttpd() {
  struct evhttp_bound_socket *handle;
  struct evhttp *httpd;

  base_ = event_base_new();
  httpd = evhttp_new(base_);

  evhttp_set_allowed_methods(
      httpd, EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_HEAD);
  evhttp_set_timeout(httpd, 5 /* timeout in seconds */);

  evhttp_set_cb(httpd, "/notify", GwNotification::httpdNotification, this);

  handle =
      evhttp_bind_socket_with_handle(httpd, httpdHost_.c_str(), httpdPort_);
  if (!handle) {
    LOG(ERROR) << "couldn't bind to port: " << httpdPort_
               << ", host: " << httpdHost_ << ", exiting.";
    return;
  }
  event_base_dispatch(base_);
}

void GwNotification::stop() {
  LOG(INFO) << "stop Notification ...";

  event_base_loopexit(base_, NULL);
}

///////////////////////////////GwMakerHandler////////////////////////////////////
GwMakerHandler::~GwMakerHandler() {
}

string GwMakerHandler::makeRawGwMsg() {
  string gw;
  if (!callRpcGw(gw)) {
    return "";
  }
  LOG(INFO) << "getwork len=" << gw.length() << ", msg: " << gw.substr(0, 500)
            << (gw.size() > 500 ? "..." : "");
  return processRawGw(gw);
}

bool GwMakerHandler::callRpcGw(string &response) {
  string request = getRequestData();
  string userAgent = getUserAgent();

  bool res = rpcCall(
      def_.rpcAddr_.c_str(),
      def_.rpcUserPwd_.c_str(),
      request.empty() ? nullptr : request.c_str(),
      request.length(),
      response,
      userAgent.c_str());

  if (!res) {
    LOG(ERROR) << "call RPC failure";
    return false;
  }
  return true;
}

///////////////////////////////GwMakerHandlerJson///////////////////////////////////
string GwMakerHandlerJson::processRawGw(const string &msg) {
  JsonNode r;
  if (!JsonNode::parse(msg.c_str(), msg.c_str() + msg.length(), r)) {
    LOG(ERROR) << "decode gw failure: " << msg;
    return "";
  }

  // check fields
  if (!checkFields(r)) {
    LOG(ERROR) << "gw check fields failure";
    return "";
  }

  return constructRawMsg(r);
}

ext: cc

max_stars_repo_name: ngoctrantl/btcpool

max_issues_repo_name: ngoctrantl/btcpool

max_forks_repo_name: ngoctrantl/btcpool


text:
//        Copyright The Authors 2018.
//    Distributed under the 3-Clause BSD License.
//    (See accompanying file LICENSE or copy at
//   https://opensource.org/licenses/BSD-3-Clause)

#include <gtest/gtest.h>

#include <forward_list>

#include <boost/multiprecision/cpp_int.hpp>

#include <p2p/kademlia/node.h>

using namespace boost::multiprecision;

namespace blocxxi {
namespace p2p {
namespace kademlia {

namespace {

using uint256_t =
    number<cpp_int_backend<256, 256, unsigned_magnitude, unchecked, void>>;

}  // anonymous namespace

TEST(NodeTest, Construction) {
  auto n1 = Node(Node::IdType::RandomHash(), "1.1.1.1", 3030);
  auto n2 = Node(n1);
  ASSERT_EQ(n1.Id(), n2.Id());
  ASSERT_EQ(n1.Endpoint(), n2.Endpoint());
  ASSERT_EQ(n1.ToString(), n2.ToString());

  auto n3 = std::move(n1);
  ASSERT_EQ(n2.Id(), n3.Id());
  ASSERT_EQ(n2.Endpoint(), n3.Endpoint());
  ASSERT_EQ(n2.ToString(), n3.ToString());

  auto n4(std::move(n3));
  ASSERT_EQ(n2.Id(), n4.Id());
  ASSERT_EQ(n2.Endpoint(), n4.Endpoint());
  ASSERT_EQ(n2.ToString(), n4.ToString());

  auto n5 = n4;
  ASSERT_EQ(n4.Id(), n5.Id());
  ASSERT_EQ(n4.Endpoint(), n5.Endpoint());
  ASSERT_EQ(n4.ToString(), n5.ToString());
}

TEST(NodeTest, LogDistance) {
  // LogDistance same id is -1
  auto ah = Node::IdType::RandomHash();
  auto an = Node(ah, "::1", 1);
  auto dist = LogDistance(an, an);
  ASSERT_EQ(-1, dist);

  // LogDistance first bits are different = 159
  auto bh = ah;
  bh[0] = ah[0] ^ 0x80;
  auto bn = Node(bh, "::1", 2);
  dist = LogDistance(an, bn);
  ASSERT_EQ(159, dist);

  for (int i = 0; i < 10; ++i) {
    auto a = Node(Node::IdType::RandomHash(), "::1", 0);
    auto b = Node(Node::IdType::RandomHash(), "::1", 0);

    auto logdist = LogDistance(a, b);

    auto distanceRaw = Distance(a, b);
    uint256_t distance;
    import_bits(distance, distanceRaw.begin(), distanceRaw.end());

    auto kbucket = logdist;

    uint256_t two_k;
    bit_set(two_k, kbucket);
    ASSERT_TRUE(two_k < distance);
    bit_unset(two_k, kbucket);
    bit_set(two_k, kbucket + 1);
    ASSERT_TRUE(two_k > distance);
  }
}

TEST(NodeTest, FromUrlString) {
  auto id = Node::IdType::RandomHash().ToHex();
  auto address = "192.168.1.35";
  auto port = "4242";
  auto str = std::string("knode://")
                 .append(id)
                 .append("@")
                 .append(address)
                 .append(":")
                 .append(port);

  Node node;
  ASSERT_NO_THROW(node = Node::FromUrlString(str));
  ASSERT_EQ(id, node.Id().ToHex());
  ASSERT_EQ(address, node.Endpoint().Address().to_string());
  ASSERT_EQ(port, std::to_string(node.Endpoint().Port()));
}

}  // namespace kademlia
}  // namespace p2p
}  // namespace blocxxi

ext: cpp


text:
#ifndef SQL_PARSER_FUSION_SQL_STMT_HPP
#define SQL_PARSER_FUSION_SQL_STMT_HPP

#include "sql/ast/sql_stmt.hpp"

#include <boost/fusion/include/adapt_struct.hpp>

BOOST_FUSION_ADAPT_STRUCT(sql::ast::explain_clause,
                         (bool, explain)
                         (bool, query_plan)
)

BOOST_FUSION_ADAPT_STRUCT(sql::ast::sql_stmt,
                         (sql::ast::explain_clause, explain)
                         (sql::ast::sql_stmt_variant, stmt)
)

#endif //SQL_PARSER_FUSION_SQL_STMT_HPP

ext: hpp

max_stars_repo_name: cviebig/lib-sql

max_issues_repo_name: cviebig/lib-sql

max_forks_repo_name: cviebig/lib-sql


text:
/**
 * @file
 * @author  Mamadou Babaei <info@babaei.net>
 * @version 0.1.0
 *
 * @section LICENSE
 *
 * (The MIT License)
 *
 * Copyright (c) 2016 - 2021 Mamadou Babaei
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * @section DESCRIPTION
 *
 * Database accessibility wrapper on top of libpqxx and libpq with support
 * for PostgreSQL.
 */

#include <sstream>
#include <unordered_map>
#include <vector>
#include <cstring>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
#include <libpq-fe.h>
#include <pqxx/pqxx>
#include "make_unique.hpp"
#include "Database.hpp"
#include "Log.hpp"
#include "SharedObjectPool.hpp"

#define     MAX_DATABASE_CONNECTIONS    16
#define     QUERY_SUCCEED               "CoreLib::Database ==>  Query succeed!"
#define     UNKNOWN_ERROR               "Unknow database error!"

using namespace std;
using namespace boost;
using namespace CoreLib;

struct Database::Impl
{
    typedef std::unordered_map<std::string, std::string> EnumNamesHashTable;
    typedef std::unordered_map<std::string, std::vector<std::string>> EnumeratorsHashTable;

    typedef std::unordered_map<std::string, std::string> TableNamesHashTable;
    typedef std::unordered_map<std::string, std::string> TableFieldsHashTable;

    SharedObjectPool<pqxx::connection> Connections;
    boost::mutex ConnectionsMutex;

    EnumNamesHashTable EnumNames;
    EnumeratorsHashTable Enumerators;

    TableNamesHashTable TableNames;
    TableFieldsHashTable TableFields;
};

std::string Database::Escape(const char *begin, const char *end)
{
    std::string result;
    result.reserve(static_cast<size_t>(end - begin));

    for(; begin != end; ++begin) {
        char c = *begin;

        if(c == '\'') {
            result += "''";
        } else {
            result += c;
        }
    }

    return result;
}

std::string Database::Escape(const char *str)
{
    return Escape(str, str + strlen(str));
}

std::string Database::Escape(const std::string &str)
{
    return Escape(str.c_str(), str.c_str() + str.size());
}

bool Database::IsTrue(const std::string &value)
{
    if (value == "TRUE"
            || value == "t"
            || value == "true"
            || value == "y"
            || value == "yes"
            || value == "on"
            || value == "1") {
        return true;
    }

    return false;
}

Database::Database(const std::string &connectionString) :
    m_pimpl(make_unique<Database::Impl>())
{
    boost::lock_guard<boost::mutex> lock(m_pimpl->ConnectionsMutex);
    (void)lock;

    LOG_INFO("Setting up database connections...");

    for (int i = 0; i < MAX_DATABASE_CONNECTIONS; ++i) {
        try {
            std::unique_ptr<pqxx::connection> c(
                        std::make_unique<pqxx::connection>(connectionString));

            LOG_INFO((format("Database connection #%1% succeed!") % i).str(), (boost::format("Backend PID: %1%") % c->backendpid()).str(), (boost::format("Socket: %1%") % c->sock()).str(), (boost::format("Host Name: %1%") % c->hostname()).str(), (boost::format("Port Number: %1%") % c->port()).str(), (boost::format("Database Name: %1%") % c->dbname()).str(), (boost::format("User Name: %1%") % c->username()).str());

            m_pimpl->Connections.Add(c);
        } catch (const pqxx::sql_error &ex) {
            LOG_FATAL((format("Database connection #%1% failed!") % i).str(), ex.what());
        } catch (const std::exception &ex) {
            LOG_FATAL((format("Database connection #%1% failed!") % i).str(), ex.what());
        } catch (...) {
            LOG_FATAL((format("Database connection #%1% failed!") % i).str(), UNKNOWN_ERROR);
        }
    }

    LOG_INFO("Database connections setup successfully!");
}

Database::~Database()
{
    boost::lock_guard<boost::mutex> lock(m_pimpl->ConnectionsMutex);
    (void)lock;

    size_t i = 0;
    while (!m_pimpl->Connections.Empty()) {
        try {
            auto c(m_pimpl->Connections.Pool().top().release());

            LOG_INFO((format("Database connection #%1% disconnected successfully!") % i).str(), (boost::format("Backend PID: %1%") % c->backendpid()).str(), (boost::format("Socket: %1%") % c->sock()).str(), (boost::format("Host Name: %1%") % c->hostname()).str(), (boost::format("Port Number: %1%") % c->port()).str(), (boost::format("Database Name: %1%") % c->dbname()).str(), (boost::format("User Name: %1%") % c->username()).str());

            m_pimpl->Connections.Pool().pop();
            ++i;
        } catch (const pqxx::sql_error &ex) {
            LOG_ERROR((format("Failed to disconnect from connection #%1%!") % i).str(), ex.what());
        } catch (const std::exception &ex) {
            LOG_ERROR((format("Failed to disconnect from connection #%1%!") % i).str(), ex.what());
        } catch (...) {
            LOG_ERROR((format("Failed to disconnect from connection #%1%!") % i).str(), UNKNOWN_ERROR);
        }
    }
}

SharedObjectPool<pqxx::connection>::ptrType Database::Connection()
{
    for (;;) {
        size_t connectionNumber = MAX_DATABASE_CONNECTIONS - m_pimpl->Connections.Size();

        try {
            if (!m_pimpl->Connections.Empty()) {
                auto c(m_pimpl->Connections.Acquire());

                LOG_INFO((format("Acquired connection #%1% successfully!") % connectionNumber).str(), (boost::format("Backend PID: %1%") % c->backendpid()).str(), (boost::format("Socket: %1%") % c->sock()).str(), (boost::format("Host Name: %1%") % c->hostname()).str(), (boost::format("Port Number: %1%") % c->port()).str(), (boost::format("Database Name: %1%") % c->dbname()).str(), (boost::format("User Name: %1%") % c->username()).str());

                return c;
            } else {
                LOG_WARNING("No free connection is available! Retrying...");
            }
        } catch (const pqxx::sql_error &ex) {
            LOG_ERROR((format("Connection #%1% acquisition failed!") % connectionNumber).str(), ex.what());
        } catch (const std::exception &ex) {
            LOG_ERROR((format("Connection #%1% acquisition failed!") % connectionNumber).str(), ex.what());
        } catch (const char &ex) {
            /// To make Clang stop spitting out warnings about the unreached code below
            (void)ex;
            break;
        } catch (...) {
            LOG_ERROR((format("Connection #%1% acquisition failed!") % connectionNumber).str(), UNKNOWN_ERROR);
        }
    }

    /// The execution should never reach here
    /// Return an empty connection
    SharedObjectPool<pqxx::connection>::ptrType c;
    return c;
}

bool Database::CreateEnum(const std::string &id)
{
    try {
        auto c = this->Connection();
        pqxx::work txn(*c.get());

        pqxx::result r = txn.exec((format("SELECT EXISTS ( SELECT typname FROM pg_type WHERE typname = %1% );")
                                   % txn.quote(m_pimpl->EnumNames[id])).str());

        LOG_INFO(QUERY_SUCCEED, r.query());

        if (!r.empty()) {
            std::string exists(r[0][0].as<string>());

            if (exists == "f") {
                std::string ph;
                for (size_t i = 0; i < m_pimpl->Enumerators[id].size(); ++i) {
                    if (i != 0)
                        ph += ", ";
                    ph += txn.quote(m_pimpl->Enumerators[id][i]);
                }

                r = txn.exec((format("CREATE TYPE \"%1%\" AS ENUM ( %2% );")
                          % txn.esc(m_pimpl->EnumNames[id])
                          % ph).str());

                LOG_INFO(QUERY_SUCCEED, r.query());

                txn.commit();
            }

            return true;
        }
    } catch (const pqxx::sql_error &ex) {
        LOG_ERROR(ex.what(), ex.query());
    } catch (const std::exception &ex) {
        LOG_ERROR(ex.what());
    } catch (...) {
        LOG_ERROR(UNKNOWN_ERROR);
    }

    return false;
}

bool Database::CreateTable(const std::string &id)
{
    try {
        auto c = this->Connection();
        pqxx::work txn(*c.get());

        pqxx::result r = txn.exec((format("CREATE TABLE IF NOT EXISTS \"%1%\" ( %2% );")
                  % txn.esc(m_pimpl->TableNames[id])
                  % m_pimpl->TableFields[id]).str());

        LOG_INFO(QUERY_SUCCEED, r.query());

        txn.commit();

        return true;
    } catch (const pqxx::sql_error &ex) {
        LOG_ERROR(ex.what(), ex.query());
    } catch (const std::exception &ex) {
        LOG_ERROR(ex.what());
    } catch (...) {
        LOG_ERROR(UNKNOWN_ERROR);
    }

    return false;
}

bool Database::DropTable(const std::string &id)
{
    try {
        auto c = this->Connection();
        pqxx::work txn(*c.get());

        pqxx::result r = txn.exec((format("DROP TABLE IF EXISTS \"%1%\";")
                  % txn.esc(m_pimpl->TableNames[id])).str());

        LOG_INFO(QUERY_SUCCEED, r.query());

        txn.commit();

        return true;
    } catch (const pqxx::sql_error &ex) {
        LOG_ERROR(ex.what(), ex.query());
    } catch (const std::exception &ex) {
        LOG_ERROR(ex.what());
    } catch (...) {
        LOG_ERROR(UNKNOWN_ERROR);
    }

    return false;
}

bool Database::RenameTable(const std::string &id, const std::string &newName)
{
    try {
        auto it = m_pimpl->TableNames.find(id);
        if (it != m_pimpl->TableNames.end()) {
            auto c = this->Connection();
            pqxx::work txn(*c.get());

            pqxx::result r = txn.exec((format("ALTER TABLE \"%1%\" RENAME TO \"%2%\";")
                      % txn.esc(m_pimpl->TableNames[id])
                      % txn.esc(newName)).str());

            LOG_INFO(QUERY_SUCCEED, r.query());

            txn.commit();

            it->second = newName;

            return true;
        }
    } catch (const pqxx::sql_error &ex) {
        LOG_ERROR(ex.what(), ex.query());
    } catch (const std::exception &ex) {
        LOG_ERROR(ex.what());
    } catch (...) {
        LOG_ERROR(UNKNOWN_ERROR);
    }

    return false;
}

bool Database::Insert(const std::string &id,
                      const std::string &fields,
                      const std::initializer_list<std::string> &args)
{
    try {
        auto c = this->Connection();
        pqxx::work txn(*c.get());

        stringstream ss;
        ss << (format("INSERT INTO \"%1%\" ( %2% ) VALUES ( ")
               % txn.esc(m_pimpl->TableNames[id])
               % txn.esc(fields)).str();

        size_t i = 0;
        for(const auto &arg : args) {
            if (i != 0) {
                ss << ", ";
            }
            ss << txn.quote(arg);
            ++i;
        }

        ss << ");";

        pqxx::result r = txn.exec(ss.str());

        LOG_INFO(QUERY_SUCCEED, r.query());

        txn.commit();

        return true;
    } catch (const pqxx::sql_error &ex) {
        LOG_ERROR(ex.what(), ex.query());
    } catch (const std::exception &ex) {
        LOG_ERROR(ex.what());
    } catch (...) {
        LOG_ERROR(UNKNOWN_ERROR);
    }

    return false;
}

bool Database::Update(const std::string &id,
                      const std::string &where,
                      const std::string &value,
                      const std::string &set,
                      const std::initializer_list<std::string> &args)
{
    try {
        auto c = this->Connection();
        pqxx::work txn(*c.get());

        string processedSet;
        for(const auto &arg : args) {
            processedSet = boost::replace_nth_copy(set, "?", 0, txn.quote(arg));
        }

        pqxx::result r = txn.exec((format("UPDATE ONLY \"%1%\" SET %2% WHERE \"%3%\" = %4%;")
                  % txn.esc(m_pimpl->TableNames[id])
                  % processedSet
                  % txn.esc(where)
                  % txn.quote(value)).str());

        LOG_INFO(QUERY_SUCCEED, r.query());

        txn.commit();

        return true;
    } catch (const pqxx::sql_error &ex) {
        LOG_ERROR(ex.what(), ex.query());
    } catch (const std::exception &ex) {
        LOG_ERROR(ex.what());
    } catch (...) {
        LOG_ERROR(UNKNOWN_ERROR);
    }

    return false;
}

bool Database::Delete(const std::string &id,
                      const std::string &where,
                      const std::string &value)
{
    try {
        auto c = this->Connection();
        pqxx::work txn(*c.get());

        pqxx::result r = txn.exec((format("DELETE FROM ONLY \"%1%\" WHERE \"%2%\"=%3%;")
                  % txn.esc(m_pimpl->TableNames[id])
                  % txn.esc(where)
                  % txn.quote(value)).str());

        LOG_INFO(QUERY_SUCCEED, r.query());

        txn.commit();

        return true;
    } catch (const pqxx::sql_error &ex) {
        LOG_ERROR(ex.what(), ex.query());
    } catch (const std::exception &ex) {
        LOG_ERROR(ex.what());
    } catch (...) {
        LOG_ERROR(UNKNOWN_ERROR);
    }

    return false;
}

void Database::RegisterEnum(const std::string &id,
                            const std::string &name,
                            const std::initializer_list<std::string> &enumerators)
{
    m_pimpl->EnumNames[id] = name;
    m_pimpl->Enumerators[id] = enumerators;
}

void Database::RegisterTable(const std::string &id,
                             const std::string &name,
                             const std::string &fields)
{
    m_pimpl->TableNames[id] = name;
    m_pimpl->TableFields[id] = fields;
}

std::string Database::GetTableName(const std::string &id) const
{
    if (m_pimpl->TableNames.find(id) != m_pimpl->TableNames.end()) {
        return m_pimpl->TableNames[id];
    }

    return "{?}";
}

std::string Database::GetTableFields(const std::string &id) const
{
    if (m_pimpl->TableFields.find(id) != m_pimpl->TableFields.end()) {
        return m_pimpl->TableFields[id];
    }

    return "{?}";
}

bool Database::SetTableName(const std::string &id, const std::string &name)
{
    auto it = m_pimpl->TableNames.find(id);
    if (it != m_pimpl->TableNames.end()) {
        it->second = name;
        return true;
    }

    return false;
}

bool Database::SetTableFields(const std::string &id, const std::string &fields)
{
    auto it = m_pimpl->TableFields.find(id);
    if (it != m_pimpl->TableFields.end()) {
        it->second = fields;
        return true;
    }

    return false;
}

bool Database::Initialize()
{
    LOG_INFO("Initializing CoreLib::Database...");

    try {
        for (const auto &e : m_pimpl->EnumNames) {
            CreateEnum(e.first);
        }

        for (const auto &t : m_pimpl->TableNames) {
            CreateTable(t.first);
        }

        LOG_INFO("CoreLib::Crypto initialized successfully!");

        return true;
    } catch (const pqxx::sql_error &ex) {
        LOG_ERROR(ex.what(), ex.query());
    } catch (const std::exception &ex) {
        LOG_ERROR(ex.what());
    } catch (...) {
        LOG_ERROR(UNKNOWN_ERROR);
    }

    return false;
}


text:
/*
Copyright (c) Members of the EGEE Collaboration. 2004.
See http://www.eu-egee.org/partners for details on the
copyright holders.

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.
*/

//**************************************************************************
//  Filename  : url.cpp
//  Authors   : Elisabetta Ronchieri
//              Francesco Giacomini
//              Marco Cecchi
//**************************************************************************

//Formalization of URI in BNF according to RFC #3986 Jan 2005
// (restricted to our own needs)

//URI           = scheme ":" hier-part
//hier-part     = "//" authority path-abempty
//               / path-absolute
//               / path-rootless
//               / path-empty
//scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
//authority     = host [ ":" port ]
//host          = IP-literal / IPv4address / reg-name
//port          = *DIGIT
//path-abempty  = *( "/" segment )
//path-absolute = "/" [ segment-nz *( "/" segment ) ]
//path-noscheme = segment-nz-nc *( "/" segment )
//path-rootless = segment-nz *( "/" segment )
//path-empty    = 0<pchar>
//segment       = *pchar
//segment-nz    = 1*pchar
//segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
//; non-zero-length segment without any colon ":"
//pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
//query         = *( pchar / "/" / "?" )
//fragment      = *( pchar / "/" / "?" )
//pct-encoded   = "%" HEXDIG HEXDIG
//unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
//sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
//
//Some examples:
//"http://www.cnaf.infn.it"                   = Valid
//"http://www.cnaf.infn.it:"                  = Valid (port = *DIGIT)
//"h ttp://www.cnaf.infn.it"                  = Not valid
//"http://www.c naf.infn.it"                  = Not valid
//"http://www.ics.uci.edu:8080/pub/ietf/uri/" = Valid
//"http://www.ics.uci.edu:8080/pub/ietf/uri"  = Valid
//"http://www.ics.uci.edu:8080"               = Valid
//"http://www.ics.uci.edu:8080:16"            = Not valid
//"http://www.ics.uci.edu:8080/pub/i:etf/uri" = Not valid
//"http://www.ics.uci.edu:8080/pub/i%20f/uri" = Valid
//"http://www.ics.uci.edu:8080/pub/i%2tf/uri" = Not valid
//""                                          = Not valid

#include <string>
#include <iostream>
#include <boost/regex.hpp>

#include "url.h"

namespace glite {
namespace wms {
namespace helper {
namespace jobadapter {

InvalidURL::InvalidURL(std::string const& url)
  : m_message("Invalid URL: " + url)
{
}

InvalidURL::~InvalidURL() throw()
{
}

char const* InvalidURL::what() const throw()
{
  return m_message.c_str();
}

URL::URL(std::string const& url)
{

  static const boost::regex valid_url(
    "([[:alpha:]][[:alnum:]+.-]*)" // scheme
    "://"
    "(([[:alnum:]_.~!$&'()-]|%[[:xdigit:]]{2})+)" // host
    "(:([[:digit:]]*))?" // port
    "((/([[:alpha:][:digit:]_.~!$&'()-]|%[[:xdigit:]]{2})+)*)/?" // path
  );

  try {
    boost::smatch pieces;
    if (boost::regex_match(url, pieces, valid_url)) {
      m_protocol.assign(pieces[1].first, pieces[1].second);
      m_host.assign(pieces[2].first, pieces[2].second);
      m_port.assign(pieces[5].first, pieces[5].second);
      m_path.assign(pieces[6].first, pieces[6].second);
    } else {
      throw InvalidURL(url);
    }
  } catch (std::runtime_error& e) {
    throw InvalidURL(url);
  }
}

std::string
URL::protocol() const
{
  return m_protocol;
}

std::string
URL::host() const
{
  return m_host;
}

std::string
URL::port() const
{
  return m_port;
}

std::string
URL::path() const
{
  return m_path;
}

std::string
URL::as_string() const
{
  return m_protocol
    + "://"
    + m_host
    + (!m_port.empty() ? ":" + m_port : "")
    + m_path;
}

}}}} // namespace glite::wms::helper::jobadapter

max_stars_repo_name: italiangrid/wms

max_issues_repo_name: italiangrid/wms

max_forks_repo_name: italiangrid/wms


text:
//
// fumarole_data_io.cpp
// Contains functions for loading fumarole data from disk
//

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <boost/filesystem.hpp>

#include "config/config.hpp"
#include "io/fumarole_data_io.hpp"

namespace IO
{
    // Read all greyscale data
    void GetGreyscaleHeatMaps(std::map<std::string, std::string>& files)
    {
        std::string filename;
        boost::filesystem::path path;
        boost::filesystem::directory_iterator end;

        for (boost::filesystem::directory_iterator itr(Config::THERMAL_IMAGES_DIR); itr != end; itr++)
        {
            path = std::move(boost::filesystem::path(*itr));

            // remove the Camthermal prefix and extract the filename
            filename = path.stem().string();
            size_t index = filename.find(Config::THERMAL_IMAGE_PREFIX);
            if (index != std::string::npos) {
                filename = filename.substr(Config::THERMAL_IMAGE_PREFIX.size(), filename.size() - Config::THERMAL_IMAGE_PREFIX.size());
            }

            files[filename] = path.string();
        }
    }

    // Get the thermal image for the given file id
    bool GetThermalImage(const std::string& fileID, cv::Mat& image, bool readAsRGB)
    {
        const std::string filePath {Config::THERMAL_IMAGES_DIR + Config::THERMAL_IMAGE_PREFIX + fileID + Config::THERMAL_IMAGE_FILE_EXT };
        image = cv::imread(filePath, readAsRGB ? cv::IMREAD_COLOR : cv::IMREAD_GRAYSCALE);
        return (image.data != nullptr);
    }

    // Get cam image
    bool GetFullResCamImage(const std::string fileID, cv::Mat& image)
    {
        const std::string filePath { Config::FULL_RES_IMAGE_LEFT_CAM_DIR + Config::FULL_RES_IMAGE_PREFIX + "_" + fileID + Config::FULL_RES_IMAGE_FILE_EXT };
        image = cv::imread(filePath, cv::IMREAD_COLOR);
        return (image.data != nullptr);
    }
}


text:
#include <boost/parameter.hpp>

namespace boost { namespace python {

    namespace tag {

        struct class_type;  // keyword tag type
    }

    template <typename T>
    struct class_type
      : boost::parameter::template_keyword<boost::python::tag::class_type,T>
    {
    };
}}


text:
void some_function(unsigned short param);
int foo();

void foo1() {
    // Some compilers may warn, that int is being converted to
    // unsigned short and that there is a possibility of loosing
    // data.
    some_function(foo());
}

void foo2() {
    // Warning suppressed.
    some_function(
        static_cast<unsigned short>(foo())
    );
}

#include <boost/numeric/conversion/cast.hpp>
void correct_implementation() {
    // 100% correct.
    some_function(
        boost::numeric_cast<unsigned short>(foo())
    );
}

#include <iostream>

void test_function() {
    for (unsigned int i = 0; i < 100; ++i) {
        try {
            correct_implementation();
        } catch (const boost::numeric::bad_numeric_cast& e) {
            std::cout << '#' << i << ' ' << e.what() << std::endl;
        }
    }
}

void test_function1() {
   for (unsigned int i = 0; i < 100; ++i) {
       try {
           correct_implementation();
       } catch (const boost::numeric::positive_overflow& e) {
           // Do something specific for positive overflow.
           std::cout << "POS OVERFLOW in #" << i << ' '
                     << e.what() << std::endl;
       } catch (const boost::numeric::negative_overflow& e) {
           // Do something specific for negative overflow.
           std::cout <<"NEG OVERFLOW in #" << i << ' '
                     << e.what() << std::endl;
       }
   }
}

#include <stdexcept>

template <class SourceT, class TargetT>
struct mythrow_overflow_handler {
    void operator() (boost::numeric::range_check_result r) {
        if (r != boost::numeric::cInRange) {
            throw std::logic_error("Not in range!");
        }
    }
};

template <class TargetT, class SourceT>
TargetT my_numeric_cast(const SourceT& in) {
    typedef boost::numeric::conversion_traits<
        TargetT, SourceT
    > conv_traits;
    typedef boost::numeric::converter <
        TargetT,
        SourceT,
        conv_traits, // default conversion traits
        mythrow_overflow_handler<SourceT, TargetT> // !!!
    > converter;

    return converter::convert(in);
}

void example_with_my_numeric_cast() {
    short v = 0;
    try {
        v = my_numeric_cast<short>(100000);
    } catch (const std::logic_error& e) {
        std::cout << "It works! " << e.what() << std::endl;
    }
    (void)v;
}

int main() {
    foo1();
    foo2();

    test_function();
    std::cout << "\n\n\n";

    test_function1();
    std::cout << "\n\n\n";

    example_with_my_numeric_cast();
}

void some_function(unsigned short param) {
    (void)param;
}

bool some_extremely_rare_condition() {
    static int i = 0;
    ++ i;

    if (i == 50 || i == 150) {
        return true;
    }

    return false;
}

bool another_extremely_rare_condition() {
    static int i = 0;
    ++ i;

    if (i == 60 || i == 160) {
        return true;
    }

    return false;

}

// Returns -1 if error occurred.
int foo() {
    if (some_extremely_rare_condition()) {
        return -1;
    } else if (another_extremely_rare_condition()) {
        return 1000000;
    }

    return 65535;
}

max_stars_repo_name: apolukhin/boost-cookbook

max_issues_repo_name: apolukhin/boost-cookbook

max_forks_repo_name: apolukhin/boost-cookbook


text:
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// 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)
//
// Official repository: https://github.com/vinniefalco/json
//

#ifndef BOOST_JSON_BASIC_PARSER_HPP
#define BOOST_JSON_BASIC_PARSER_HPP

#include <boost/json/config.hpp>
#include <boost/json/error.hpp>
#include <boost/json/detail/number.hpp>
#include <boost/json/detail/static_stack.hpp>
#include <string>
#include <vector>

namespace boost {
namespace json {

/** An incremental SAX parser for serialized JSON.

    This implements a SAX-style parser. The serialized
    JSON is presented to the parser by calling to
    @ref write_some, @ref write, and @ref finish.
    The parsing events are realized through calls of
    protected virtual functions, whose implementations
    are in the derived class.

    The parser may dynamically allocate intermediate
    storage as needed to accommodate the nesting level
    of the JSON being parsed. This storage is freed
    when the parser is destroyed, allowing the parser
    to cheaply re-use this memory when parsing
    subsequent JSONs, improving performance.

    @note

    The parser is strict: no extensions are supported.
    Only compliant JSON is recognized.

    @see @ref parse, @ref parser
*/
class basic_parser
{
    enum class state : char;

    detail::static_stack<state, 8> st_;
    detail::number_parser np_;
    std::size_t depth_ = 0;
    std::size_t max_depth_ = 32;
    char const* lit_;
    error ev_;
    long u0_;
    unsigned short u_;
    bool is_key_;

    inline
    bool
    is_control(char c) noexcept;

    inline
    char
    hex_digit(char c) noexcept;

public:
    //------------------------------------------------------

    /** Destructor.

        All dynamically allocated internal memory is freed.
    */
    virtual
    ~basic_parser()
    {
        // VFALCO defaulting this causes link
        // link errors on some older toolchains.
    }

    /** Return true if a complete JSON has been parsed.

        This function returns `true` when all of these
        conditions are met:

        @li A complete serialized JSON has been
            presented to the parser, and

        @li No error has occurred since the parser
            was constructed, or since the last call
            to @ref reset,

        @par Complexity

        Constant.
    */
    bool
    is_done() const noexcept
    {
        return static_cast<
            char>(*st_) == 0;
    }

    /** Returns the current depth of the JSON being parsed.

        The parsing depth is the total current nesting
        level of arrays and objects.
    */
    std::size_t
    depth() const noexcept
    {
        return depth_;
    }

    /** Returns the maximum allowed depth of input JSON.

        The maximum allowed depth may be configured.
    */
    std::size_t
    max_depth() const noexcept
    {
        return max_depth_;
    }

    /** Set the maximum allowed depth of input JSON.

        When the maximum depth is exceeded, parser
        operations will return @ref error::too_deep.

        @param levels The maximum depth.
    */
    void
    max_depth(unsigned long levels) noexcept
    {
        max_depth_ = levels;
    }

    /** Parse JSON incrementally.

        This function parses the JSON in the specified
        buffer, emitting SAX parsing events by calling
        the derived class. The parse proceeds from the
        current state, which is at the beginning of a
        new JSON or in the middle of the current JSON
        if any characters were already parsed.

        The characters in the buffer are processed
        starting from the beginning, until one of the
        following conditions is met:

        @li All of the characters in the buffer have been
        parsed, or

        @li Some of the characters in the buffer have been
        parsed and the JSON is complete, or

        @li A parsing error occurs.

        The supplied buffer does not need to contain the
        entire JSON. Subsequent calls can provide more
        serialized data, allowing JSON to be processed
        incrementally. The end of the serialized JSON
        can be indicated by calling @ref finish().

        @par Complexity

        Linear in `size`.

        @param data A pointer to a buffer of `size`
        characters to parse.

        @param size The number of characters pointed to
        by `data`.

        @param ec Set to the error, if any occurred.

        @return The number of characters successfully
        parsed, which may be smaller than `size`.
    */
    BOOST_JSON_DECL
    std::size_t
    write_some(
        char const* data,
        std::size_t size,
        error_code& ec);

    /** Parse JSON incrementally.

        This function parses the JSON in the specified
        buffer, emitting SAX parsing events by calling
        the derived class. The parse proceeds from the
        current state, which is at the beginning of a
        new JSON or in the middle of the current JSON
        if any characters were already parsed.

        The characters in the buffer are processed
        starting from the beginning, until one of the
        following conditions is met:

        @li All of the characters in the buffer have been
        parsed, or

        @li Some of the characters in the buffer have been
        parsed and the JSON is complete, or

        @li A parsing error occurs.

        The supplied buffer does not need to contain the
        entire JSON. Subsequent calls can provide more
        serialized data, allowing JSON to be processed
        incrementally. The end of the serialized JSON
        can be indicated by calling @ref finish().

        @par Complexity

        Linear in `size`.

        @param data A pointer to a buffer of `size`
        characters to parse.

        @param size The number of characters pointed to
        by `data`.

        @throw system_error Thrown on failure.

        @return The number of characters successfully
        parsed, which may be smaller than `size`.
    */
    BOOST_JSON_DECL
    std::size_t
    write_some(
        char const* data,
        std::size_t size);

    /** Parse JSON incrementally.

        This function parses the JSON in the specified
        buffer, emitting SAX parsing events by calling
        the derived class. The parse proceeds from the
        current state, which is at the beginning of a
        new JSON or in the middle of the current JSON
        if any characters were already parsed.

        The characters in the buffer are processed
        starting from the beginning, until one of the
        following conditions is met:

        @li All of the characters in the buffer have been
        parsed, or

        @li A parsing error occurs.

        The supplied buffer does not need to contain the
        entire JSON. Subsequent calls can provide more
        serialized data, allowing JSON to be processed
        incrementally. The end of the serialized JSON
        can be indicated by calling @ref finish().

        @par Complexity

        Linear in `size`.

        @param data A pointer to a buffer of `size`
        characters to parse.

        @param size The number of characters pointed to
        by `data`.

        @param ec Set to the error, if any occurred.
    */
    BOOST_JSON_DECL
    void
    write(
        char const* data,
        std::size_t size,
        error_code& ec);

    /** Parse JSON incrementally.

        This function parses the JSON in the specified
        buffer, emitting SAX parsing events by calling
        the derived class. The parse proceeds from the
        current state, which is at the beginning of a
        new JSON or in the middle of the current JSON
        if any characters were already parsed.

        The characters in the buffer are processed
        starting from the beginning, until one of the
        following conditions is met:

        @li All of the characters in the buffer have been
        parsed, or

        @li A parsing error occurs.

        The supplied buffer does not need to contain the
        entire JSON. Subsequent calls can provide more
        serialized data, allowing JSON to be processed
        incrementally. The end of the serialized JSON
        can be indicated by calling @ref finish().

        @par Complexity

        Linear in `size`.

        @param data A pointer to a buffer of `size`
        characters to parse.

        @param size The number of characters pointed to
        by `data`.

        @throw system_error Thrown on failure.
    */
    BOOST_JSON_DECL
    void
    write(
        char const* data,
        std::size_t size);

    /** Parse JSON incrementally.

        This function parses the JSON in the specified
        buffer, emitting SAX parsing events by calling
        the derived class. The parse proceeds from the
        current state, which is at the beginning of a
        new JSON or in the middle of the current JSON
        if any characters were already parsed.

        The characters in the buffer are processed
        starting from the beginning, until one of the
        following conditions is met:

        @li All of the characters in the buffer have been
        parsed and form a complete JSON, or

        @li A parsing error occurs.

        The caller uses this function to inform the
        parser that there is no more serialized JSON
        available. If the entire buffer is not consumed
        or if a complete JSON is not available after
        consuming the entire buffer, the error is
        set to indicate failure.

        @par Complexity

        Linear in `size`.

        @param data A pointer to a buffer of `size`
        characters to parse.

        @param size The number of characters pointed to
        by `data`.

        @param ec Set to the error, if any occurred.
    */
    BOOST_JSON_DECL
    void
    finish(
        char const* data,
        std::size_t size,
        error_code& ec);

    /** Parse JSON incrementally.

        This function parses the JSON in the specified
        buffer, emitting SAX parsing events by calling
        the derived class. The parse proceeds from the
        current state, which is at the beginning of a
        new JSON or in the middle of the current JSON
        if any characters were already parsed.

        The characters in the buffer are processed
        starting from the beginning, until one of the
        following conditions is met:

        @li All of the characters in the buffer have been
        parsed and form a complete JSON, or

        @li A parsing error occurs.

        The caller uses this function to inform the
        parser that there is no more serialized JSON
        available. If the entire buffer is not consumed
        or if a complete JSON is not available after
        consuming the entire buffer, the error is
        set to indicate failure.

        @par Complexity

        Linear in `size`.

        @param data A pointer to a buffer of `size`
        characters to parse.

        @param size The number of characters pointed to
        by `data`.

        @throw system_error Thrown on failure.
    */
    BOOST_JSON_DECL
    void
    finish(
        char const* data,
        std::size_t size);

    /** Parse JSON incrementally.

        This function finishes parsing the current JSON,
        emitting SAX parsing events by calling the derived
        class. The parse is finalized according to the
        current state, which includes all previously
        parsed data since the last reset.

        The caller uses this function to inform the
        parser that there is no more serialized JSON
        available. If a complete JSON is not available
        the error is set to indicate failure.

        @par Complexity

        Constant.

        @param ec Set to the error, if any occurred.
    */
    BOOST_JSON_DECL
    void
    finish(error_code& ec);

    /** Parse JSON incrementally.

        This function finishes parsing the current JSON,
        emitting SAX parsing events by calling the derived
        class. The parse is finalized according to the
        current state, which includes all previously
        parsed data since the last reset.

        The caller uses this function to inform the
        parser that there is no more serialized JSON
        available. If a complete JSON is not available
        the error is set to indicate failure.

        @par Complexity

        Constant.

        @throw system_error Thrown on failure.
    */
    BOOST_JSON_DECL
    void
    finish();

protected:
    using saved_state = char;

    /// Constructor (default)
    BOOST_JSON_DECL
    basic_parser();

    /** Reset the state, to parse a new document.
    */
    BOOST_JSON_DECL
    void
    reset() noexcept;

    saved_state
    save_state() noexcept
    {
        auto ss = *st_;
        st_.pop();
        return static_cast<
            saved_state>(ss);
    }

    void
    restore_state(
        saved_state ss) noexcept
    {
        st_.push(static_cast<
            state>(ss));
    }

    /** Called once when the JSON parsing begins.

        This function is invoked at the beginning of
        parsing a new JSON document, when data is first
        presented. The call happens before any other
        events.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_document_begin(
        error_code& ec) = 0;

    /** Called when the JSON parsing is done.

        This function is invoked once when a complete
        JSON document has been parsed without errors.
        The call happens last; no other calls are made
        before the parser is reset.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_document_end(
        error_code& ec) = 0;

    /** Called when the beginning of an object is encountered.

        This function is called during parsing when a new
        object is started.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_object_begin(
        error_code& ec) = 0;

    /** Called when the end of the current object is encountered.

        This function is called during parsing after all of
        the elements of an object have been parsed, and the
        closing brace for the object is reached.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_object_end(
        error_code& ec) = 0;

    /** Called when the beginning of an array is encountered.

        This function is called during parsing when a new
        array is started.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_array_begin(
        error_code& ec) = 0;

    /** Called when the end of the current array is encountered.

        This function is called during parsing after all of
        the elements of an array have been parsed, and the
        closing bracket for the array is reached.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_array_end(
        error_code& ec) = 0;

    /** Called with characters corresponding to part of the current key.

        This function is called during parsing to provide
        the characters corresponding to the key being parsed
        as part of an object. More key data may be provided
        by zero or more calls to @ref on_key_part, followed
        by a final call to @ref on_key.

        @param s The string view holding the next buffer of
        key data, with escapes converted to their actual
        characters.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_key_part(
        string_view s,
        error_code& ec) = 0;

    /** Called with the last characters corresponding to the current key.

        This function is called during parsing to provide
        the final character string corresponding to the key
        being parsed as part of an object. The key is
        considered complete with these characters.

        @param s The string view holding the final buffer of
        key data, with escapes converted to their actual
        characters.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_key(
        string_view s,
        error_code& ec) = 0;

    /** Called with characters corresponding to part of the current string.

        This function is called during parsing to provide
        the characters corresponding to a string value being
        parsed. More string data may be provided by zero or
        more calls to @ref on_string_part, followed by a
        final call to @ref on_string.

        @param s The string view holding the next buffer of
        string data, with escapes converted to their actual
        characters.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_string_part(
        string_view s,
        error_code& ec) = 0;

    /** Called with the last characters corresponding to the current string.

        This function is called during parsing to provide
        the final character string corresponding to the
        string being parsed. The string element is
        considered complete with these characters.

        @param s The string view holding the final buffer of
        string data, with escapes converted to their actual
        characters.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_string(
        string_view s,
        error_code& ec) = 0;

    /** Called when a `std::int64_t` is parsed.

        This function is called when a suitable
        number is parsed.

        @param i The number encountered.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_int64(
        int64_t i,
        error_code& ec) = 0;

    /** Called when a `std::uint64_t` is parsed.

        This function is called when a suitable
        number is parsed.

        @param u The number encountered.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_uint64(
        uint64_t u,
        error_code& ec) = 0;

    /** Called when a `double` is parsed.

        This function is called when a suitable
        number is parsed.

        @param d The number encountered.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_double(
        double d,
        error_code& ec) = 0;

    /** Called when a `bool` is parsed.

        This function is called when a
        boolean value is encountered.

        @param b The boolean value.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_bool(bool b, error_code& ec) = 0;

    /** Called when a null is parsed.

        This function is called when a null is encountered.

        @param ec The error, if any, which will be
        returned by the current invocation of
        @ref write_some, @ref write, or @ref finish.
    */
    virtual
    void
    on_null(error_code& ec) = 0;
};

} // json
} // boost

#ifdef BOOST_JSON_HEADER_ONLY
#include <boost/json/impl/basic_parser.ipp>
#endif

#endif

max_stars_repo_name: ayounes-synaptics/json

max_issues_repo_name: ayounes-synaptics/json

max_forks_repo_name: ayounes-synaptics/json


text:
// Copyright (c) 2020 Graphcore Ltd. All rights reserved.
#define BOOST_TEST_MODULE NumericsInplaceVsNot0Test

#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
#include <filereader.hpp>
#include <popart/builder.hpp>
#include <popart/dataflow.hpp>
#include <popart/devicemanager.hpp>
#include <popart/inputshapeinfo.hpp>
#include <popart/ir.hpp>
#include <popart/names.hpp>
#include <popart/ndarraywrapper.hpp>
#include <popart/op/l1.hpp>
#include <popart/session.hpp>
#include <popart/tensordata.hpp>
#include <popart/testdevice.hpp>

#include <chrono>
#include <complex>
#include <iostream>
#include <random>

using namespace popart;

//           input
//         /   |   \
//   scale1 scale2 scale3
//
//   x = (scale1 + scale2) + scale3
//   y = (scale3 * scale2) * scale1
//
//   output = x - y

BOOST_AUTO_TEST_CASE(Inplace_numericsIpNip0) {
  auto getValue = [](bool outline, bool inplace) {
    Shape inShape{2, 2};
    TensorInfo inInfo{"FLOAT", inShape};

    std::vector<float> vInData{2.0, 0.5, 7.0, 3.125};

    // Build an onnx model
    auto builder     = Builder::create();
    auto aiOnnx      = builder->aiOnnxOpset9();
    auto aiGraphcore = builder->aiGraphcoreOpset1();

    auto in0  = builder->addInputTensor(inInfo);
    auto s1   = aiGraphcore.scale({in0}, 1.0);
    auto s2   = aiGraphcore.scale({in0}, 2.0);
    auto s3   = aiGraphcore.scale({in0}, 3.0);
    auto add0 = aiOnnx.add({s1, s2});
    auto x    = aiOnnx.add({add0, s3});
    auto mul0 = aiOnnx.mul({s3, s2});
    auto y    = aiOnnx.mul({mul0, s1});
    auto sub  = aiOnnx.sub({x, y});
    auto out  = aiOnnx.reducesum({sub}, std::vector<int64_t>{{0, 1}}, false);
    builder->addOutputTensor(out);

    auto proto      = builder->getModelProto();
    auto modelProto = io::getModelFromString(proto);

    // Create the IR, adding outId as an anchor
    auto art      = AnchorReturnType("All");
    auto dataFlow = DataFlow(1, {{out, art}});

    auto opts = SessionOptions();
    opts.dotChecks.insert(DotCheck::Bwd0);
    opts.dotChecks.insert(DotCheck::Fwd0);
    opts.dotChecks.insert(DotCheck::Final);
    opts.dotOpNames       = false;
    opts.logDir           = "./dotfiles_ip_with_outlining";
    opts.enableOutlining  = outline;
    opts.outlineThreshold = 0.0f;
    if (!boost::filesystem::exists(opts.logDir)) {
      boost::filesystem::create_directories(opts.logDir);
    }

    auto device = popart::createTestDevice(TEST_TARGET);

    auto session = popart::InferenceSession::createFromOnnxModel(
        proto,
        dataFlow,
        device,
        popart::InputShapeInfo(),
        opts,
        popart::Patterns(PatternsLevel::NoPatterns)
            .enableRuntimeAsserts(false)
            .enableInPlace(inplace));

    // prepare the anchors
    float rawOutputData;
    Shape outShape{};
    popart::NDArrayWrapper<float> outData(&rawOutputData, outShape);

    std::map<popart::TensorId, popart::IArray &> anchors = {
        {out, outData},
    };

    session->prepareDevice();

    popart::NDArrayWrapper<float> inData(vInData.data(), inShape);
    std::map<popart::TensorId, popart::IArray &> inputs = {{in0, inData}};

    popart::StepIO stepio(inputs, anchors);

    session->run(stepio);

    return rawOutputData;
  };

  // no outlining, no inplacing
  auto vBase = getValue(false, false);
  // outlining, no inplacing
  auto vOutline = getValue(true, false);
  // no outlining, inplacing
  auto vInplace = getValue(false, true);
  // outlining, inplacing
  auto vAll = getValue(true, true);

  std::cout << vBase << "  == " << vOutline << " == " << vInplace
            << " == " << vAll << " ?" << std::endl;
  BOOST_CHECK(vBase - vOutline == 0.0);
  BOOST_CHECK(vOutline - vInplace == 0.0);
  BOOST_CHECK(vInplace - vAll == 0.0);
}