text:
#include "ssf/system/system_routers.h"

#include <cstdint>

#include <map>
#include <string>
#include <unordered_set>

#include <boost/asio/io_service.hpp>

#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/system/error_code.hpp>

#include "ssf/error/error.h"
#include "ssf/layer/parameters.h"

#include "ssf/layer/data_link/basic_circuit_protocol.h"
#include "ssf/layer/data_link/simple_circuit_policy.h"
#include "ssf/layer/data_link/circuit_helpers.h"
#include "ssf/layer/interface_layer/basic_interface_protocol.h"
#include "ssf/layer/physical/tcp.h"
#include "ssf/layer/physical/tlsotcp.h"

namespace ssf {
namespace system {

SystemRouters::SystemRouters(boost::asio::io_service& io_service)
    : io_service_(io_service),
      system_interfaces_(io_service),
      p_routers_(),
      mount_infos_mutex_(),
      mount_infos_() {}

uint32_t SystemRouters::AsyncConfig(
    const std::string& interfaces_config_filepath,
    const std::string& routers_config_filepath, boost::system::error_code& ec,
    SystemRouters::AllRoutersUpHandler all_up_handler) {
  PropertyTree pt;

  try {
    boost::property_tree::read_json(routers_config_filepath, pt);
  } catch (const std::exception&) {
    ec.assign(ssf::error::bad_file_descriptor, ssf::error::get_ssf_category());
    io_service_.post(boost::asio::detail::binder1<AllRoutersUpHandler,
                                                  boost::system::error_code>(
        all_up_handler, ec));
    return 0;
  }

  std::unordered_set<std::string> added_routers;

  for (auto& config_router : pt) {
    auto given_router_name = config_router.second.get_child_optional("router");
    if (!given_router_name) {
      ec.assign(ssf::error::missing_config_parameters,
                ssf::error::get_ssf_category());
      break;
    }

    std::string router_name = given_router_name->data().c_str();
    auto p_router = RoutedProtocol::get_router(router_name);

    // A router already exists with this name, stop
    if (p_router) {
      ec.assign(ssf::error::device_or_resource_busy,
                ssf::error::get_ssf_category());
      break;
    }

    RoutedProtocol::StartRouter(router_name, io_service_);
    added_routers.insert(router_name);
    p_router = RoutedProtocol::get_router(router_name);
    p_routers_[router_name] = p_router;

    const auto& given_networks = config_router.second.get_child_optional("networks");
    const auto& given_routes = config_router.second.get_child_optional("routes");

    if (!given_networks && !given_routes) {
      ec.assign(ssf::error::missing_config_parameters,
                ssf::error::get_ssf_category());
      break;
    }

    if (given_networks) {
      AddNetworksFromPropertyTree(router_name, *given_networks, ec);
    }

    if (!ec) {
      if (given_routes) {
        AddRoutesFromPropertyTree(p_router.get(), *given_routes, ec);
      }
    }

    if (ec) {
      break;
    }
  }

  // If an error occured, stop all previous routers configured
  if (ec) {
    BOOST_LOG_TRIVIAL(error) << "Error when configuring router";
    for (auto& router_name : added_routers) {
      BOOST_LOG_TRIVIAL(error) << " * Remove router " << router_name;
      StopRouter(router_name);
    }
    added_routers.clear();
    io_service_.post(boost::asio::detail::binder1<AllRoutersUpHandler,
                                                  boost::system::error_code>(
        all_up_handler, ec));
  }

  system_interfaces_.AsyncMount(interfaces_config_filepath,
                                boost::bind(&SystemRouters::InterfaceUpHandler,
                                            this, _1, _2, all_up_handler));

  return static_cast<uint32_t>(added_routers.size());
}

void SystemRouters::Start(int remount_delay) {
  using TCPProtocol = ssf::layer::physical::TCPPhysicalLayer;
  using TLSoTCPProtocol =
      ssf::layer::physical::TLSboTCPPhysicalLayer;
  using CircuitTCPProtocol =
      ssf::layer::data_link::basic_CircuitProtocol<
          TCPProtocol, ssf::layer::data_link::CircuitPolicy>;
  using CircuitTLSoTCPProtocol =
      ssf::layer::data_link::basic_CircuitProtocol<
          TLSoTCPProtocol, ssf::layer::data_link::CircuitPolicy>;

  system_interfaces_.RegisterInterfacesCollection<TCPProtocol>();
  system_interfaces_.RegisterInterfacesCollection<TLSoTCPProtocol>();
  system_interfaces_.RegisterInterfacesCollection<CircuitTCPProtocol>();
  system_interfaces_.RegisterInterfacesCollection<CircuitTLSoTCPProtocol>();

  system_interfaces_.Start(remount_delay);
}

void SystemRouters::Stop() {
  StopAllRouters();
  system_interfaces_.Stop();
  system_interfaces_.UnregisterAllInterfacesCollection();
}

void SystemRouters::StopAllRouters() {
  auto p_router_it = p_routers_.begin();
  auto end_router_it = p_routers_.end();
  while (p_router_it != end_router_it) {
    boost::system::error_code ec;
    RoutedProtocol::StopRouter(p_router_it->first, ec);
    p_router_it = p_routers_.erase(p_router_it);
  }
}

void SystemRouters::StopRouter(const std::string& router_name) {
  auto p_router_it = p_routers_.find(router_name);
  if (p_router_it != p_routers_.end()) {
    boost::system::error_code ec;
    RoutedProtocol::StopRouter(router_name, ec);
    p_routers_.erase(router_name);
  }
}

void SystemRouters::AddNetworksFromPropertyTree(const std::string& router_name,
                                                const PropertyTree& networks_pt,
                                                boost::system::error_code& ec) {
  for (auto& network_pt : networks_pt) {
    network_address_type network_id =
        RoutedProtocol::ResolveToNetworkAddress(network_pt.first.c_str(), ec);
    if (ec) {
      return;
    }
    std::string interface_id = network_pt.second.data().c_str();
    ssf::layer::LayerParameters network_parameters;
    network_parameters["network_id"] = network_pt.first.c_str();
    ssf::layer::LayerParameters interface_parameters;
    interface_parameters["interface_id"] = interface_id;

    ssf::layer::ParameterStack network_query;
    network_query.push_back(network_parameters);
    network_query.push_back(interface_parameters);

    MountNetworkInfo mount_info;
    mount_info.network_id = network_id;
    mount_info.network_query = network_query;
    mount_info.router_name = router_name;

    {
      boost::recursive_mutex::scoped_lock lock_mount_infos(mount_infos_mutex_);
      mount_infos_.emplace(interface_id, mount_info);
    }
  }
}

void SystemRouters::AddRoutesFromPropertyTree(SystemRouters::Router* p_router,
                                              const PropertyTree& routes_pt,
                                              boost::system::error_code& ec) {
  for (auto& route_pt : routes_pt) {
    network_address_type from_network_id =
        RoutedProtocol::ResolveToNetworkAddress(route_pt.first.c_str(), ec);

    network_address_type to_network_id =
        RoutedProtocol::ResolveToNetworkAddress(route_pt.second.data().c_str(),
                                                ec);
    if (ec) {
      return;
    }
    p_router->add_route(from_network_id, to_network_id, ec);
    if (ec) {
      return;
    }
  }
}

void SystemRouters::InterfaceUpHandler(
    const boost::system::error_code& ec,
    const SystemRouters::interface_id& interface_name,
    SystemRouters::AllRoutersUpHandler all_up_handler) {
  boost::recursive_mutex::scoped_lock lock_mount_infos(mount_infos_mutex_);
  auto mount_info_it = mount_infos_.find(interface_name);
  if (mount_info_it == mount_infos_.end()) {
    return;
  }

  auto& mount_info = mount_info_it->second;

  if (ec) {
    BOOST_LOG_TRIVIAL(error) << " * Interface " << interface_name
                             << " error : " << ec.message();
    mount_infos_.erase(interface_name);
    PostAllUpHandler(ec, all_up_handler);
    return;
  }

  auto p_router = RoutedProtocol::get_router(mount_info_it->second.router_name);
  if (!p_router) {
    mount_infos_.erase(mount_info_it);
    PostAllUpHandler(boost::system::error_code(ssf::error::identifier_removed,
                                               ssf::error::get_ssf_category()),
                     all_up_handler);
    return;
  }

  NetworkProtocol::resolver network_resolver(io_service_);
  boost::system::error_code add_network_ec;
  auto network_ep_it =
      network_resolver.resolve(mount_info.network_query, add_network_ec);
  if (ec) {
    mount_infos_.erase(mount_info_it);
    PostAllUpHandler(
        boost::system::error_code(ssf::error::cannot_resolve_endpoint,
                                  ssf::error::get_ssf_category()),
        all_up_handler);
    return;
  }

  p_router->add_network(mount_info.network_id, *network_ep_it, add_network_ec);
  mount_infos_.erase(mount_info_it);

  PostAllUpHandler(boost::system::error_code(ssf::error::success,
                                             ssf::error::get_ssf_category()),
                   all_up_handler);
}

void SystemRouters::PostAllUpHandler(const boost::system::error_code& all_up_ec,
                                     AllRoutersUpHandler all_up_handler) {
  boost::recursive_mutex::scoped_lock lock_mount_infos(mount_infos_mutex_);
  if (mount_infos_.empty()) {
    io_service_.post(boost::asio::detail::binder1<AllRoutersUpHandler,
                                                  boost::system::error_code>(
        all_up_handler, all_up_ec));
  }
}

}  // system
}  // ssf

max_stars_repo_name: securesocketfunneling/ssf-framework

max_issues_repo_name: securesocketfunneling/ssf-framework

max_forks_repo_name: securesocketfunneling/ssf-framework


text:
// ======================================================================
/*!
 * \file
 * \brief Regression tests for class NFmiQueryInfo
 */
// ======================================================================

#include "NFmiMultiQueryInfo.h"
#include "NFmiProducerName.h"
#include "NFmiQueryData.h"
#include "NFmiStringTools.h"
#include <regression/tframe.h>
#include <fstream>
#include <stdexcept>
#include <string>

#include <boost/shared_ptr.hpp>

using namespace std;

// The test data

NFmiMultiQueryInfo* qi;

//! Protection against conflicts with global functions
namespace NFmiMultiQueryInfoTest
{
// Note! All other tests depend on the success of this test!

void reading()
{
  qi = new NFmiMultiQueryInfo("data/hiladata.sqd");

  TEST_PASSED();
}

void constructing()
{
  std::vector<boost::shared_ptr<NFmiQueryData> > qdv;
  std::vector<boost::shared_ptr<NFmiQueryData> > qdv_gzipped;
  std::vector<boost::shared_ptr<NFmiQueryData> > qdv_bzipped;
  NFmiMultiQueryInfo qd("data/hiladata.sqd");
  NFmiMultiQueryInfo qd_gzipped("data/hiladata.sqd.gz");
  NFmiMultiQueryInfo qd_bzipped("data/hiladata.sqd.bz2");

  TEST_PASSED();
}

void nextparam()
{
  using NFmiStringTools::Convert;

  unsigned long id;

  qi->Reset();

  if ((id = qi->Param().GetParamIdent()) != kFmiTemperature)
    TEST_FAILED("Param after reset should be Temperature, not " + Convert(id));

  if (!qi->NextParam()) TEST_FAILED("Expecting next parameter to be Temperature");

  if ((id = qi->Param().GetParamIdent()) != kFmiTemperature)
    TEST_FAILED("First param should be Temperature, not " + Convert(id));

  if (!qi->NextParam()) TEST_FAILED("Expecting next parameter to be DewPoint");

  if ((id = qi->Param().GetParamIdent()) != kFmiDewPoint)
    TEST_FAILED("Second param should be DewPoint, not " + Convert(id));

  if (!qi->NextParam()) TEST_FAILED("Expecting next parameter to be DewPoint");

  if ((id = qi->Param().GetParamIdent()) != kFmiTotalWindMS)
    TEST_FAILED("Third param should be TotalWindMS, not " + Convert(id));

  if (!qi->NextParam()) TEST_FAILED("Expecting next parameter to be WeatherAndCloudiness");

  if ((id = qi->Param().GetParamIdent()) != kFmiWeatherAndCloudiness)
    TEST_FAILED("Fourth param should be WeatherAndCloudiness, not " + Convert(id));

  if (qi->NextParam()) TEST_FAILED("Not expecting more parameters after WeatherAndCloudiness");

  TEST_PASSED();
}

void nexttime()
{
  using NFmiStringTools::Convert;

  NFmiMetTime t;

  qi->Reset();

  try
  {
    t = qi->ValidTime();
    TEST_FAILED("Should not get ValidTime after Reset");
  }
  catch (...)
  {
  }

  if (!qi->NextTime()) TEST_FAILED("Expecting more than 1 timestep in test data");

  if ((t = qi->ValidTime()) != NFmiMetTime(2002, 10, 9, 6, 0, 0))
    TEST_FAILED("ValidTime after 1 nexttime should be 2002 10 9 6 0 0, not " + Convert(t));

  if (!qi->NextTime()) TEST_FAILED("Expecting more than 2 timesteps in test data");

  if ((t = qi->ValidTime()) != NFmiMetTime(2002, 10, 9, 7, 0, 0))
    TEST_FAILED("ValidTime after 2 nexttimes should be 2002 10 9 7 0 0, not " + Convert(t));

  TEST_PASSED();
}

void islocation()
{
  if (qi->IsLocation()) TEST_FAILED("Should return false for gridded data");

  TEST_PASSED();
}

void islevel()
{
  if (!qi->IsLevel()) TEST_FAILED("Should return true for the test data");

  TEST_PASSED();
}

void isarea()
{
  if (qi->IsArea()) TEST_FAILED("Should return false for gridded data");

  TEST_PASSED();
}

void isgrid()
{
  if (!qi->IsGrid()) TEST_FAILED("Should return true for gridded data");

  TEST_PASSED();
}

void isvalidtime()
{
  if (!qi->IsValidTime()) TEST_FAILED("Should return true for the test data");

  TEST_PASSED();
}

void isorigintime()
{
  if (qi->IsOriginTime()) TEST_FAILED("Should return false for the test data");

  TEST_PASSED();
}

void param()
{
  if (!qi->Param(NFmiDataIdent(NFmiParam(kFmiTemperature), NFmiProducer(kFmiMETEOR))))
    TEST_FAILED("Failed to set Temperature parameter on");

  if (!qi->Param(NFmiDataIdent(NFmiParam(kFmiDewPoint), NFmiProducer(kFmiMETEOR))))
    TEST_FAILED("Failed to set DewPoint parameter on");

  if (!qi->Param(NFmiDataIdent(NFmiParam(kFmiTotalWindMS), NFmiProducer(kFmiMETEOR))))
    TEST_FAILED("Failed to set TotalWindMS parameter on");

  if (!qi->Param(NFmiDataIdent(NFmiParam(kFmiPrecipitation1h), NFmiProducer(kFmiMETEOR))))
    TEST_FAILED("Failed to set Precipitation1h parameter on");

  if (qi->Param(NFmiDataIdent(NFmiParam(kFmiPrecipitation1h), NFmiProducer(kFmiSYNOP))))
    TEST_FAILED("Should fail to set Precipitation1h parameter on with wrong producer");

  if (qi->Param(NFmiDataIdent(NFmiParam(kFmiPoP), NFmiProducer(kFmiMETEOR))))
    TEST_FAILED("Should have failed to set PoP parameter on");

  TEST_PASSED();
}

void level()
{
  using NFmiStringTools::Convert;

  qi->First();
  const NFmiLevel& lev = *qi->Level();

  unsigned long l;

  if ((l = lev.LevelTypeId()) != kFmiAnyLevelType)
    TEST_FAILED("Level typeid should be kFmiAnyLevelType, not " + Convert(l));

  if ((l = lev.LevelValue()) != 0) TEST_FAILED("Level value should be 0, not " + Convert(l));

  TEST_PASSED();
}

void time()
{
  using NFmiStringTools::Convert;

  qi->Reset();

  NFmiMetTime t;

  if (!qi->NextTime()) TEST_FAILED("Data should have more than 1 timestep");

  if ((t = qi->Time()) != NFmiMetTime(2002, 10, 9, 6))
    TEST_FAILED("Second time should be 9.10.2002 06:00, not " + Convert(t));

  TEST_PASSED();
}

void validtime()
{
  using NFmiStringTools::Convert;

  qi->Reset();

  NFmiMetTime t;

  if (!qi->NextTime()) TEST_FAILED("Data should have more than 1 timestep");

  if ((t = qi->ValidTime()) != NFmiMetTime(2002, 10, 9, 6))
    TEST_FAILED("First time should be 9.10.2002 06:00, not " + Convert(t));

  TEST_PASSED();
}

void origintime()
{
  using NFmiStringTools::Convert;

  NFmiMetTime t;

  if ((t = qi->OriginTime()) != NFmiMetTime(2002, 10, 9, 6))
    TEST_FAILED("Origin time should be 9.10.2002 06:00, not " + Convert(t));

  TEST_PASSED();
}

void forecastperiod()
{
  using NFmiStringTools::Convert;

  unsigned long p;

  if ((p = qi->ForecastPeriod()) != 0)
    TEST_FAILED("Forecast period should be 0, not " + Convert(p));

  TEST_PASSED();
}

void floatvalue()
{
  using NFmiStringTools::Convert;

  qi->First();

  float val;

  val = qi->FloatValue();
  if (abs(val - 5.9) > 1e-5)
    TEST_FAILED("First param first time value should be 5.9, not " + Convert(val));

  qi->NextTime();
  val = qi->FloatValue();
  if (abs(val - 6.42002) > 1e-5)
    TEST_FAILED("First param second time value should be 6.42002, not " + Convert(val));

  qi->NextTime();
  val = qi->FloatValue();
  if (abs(val - 6.64012) > 1e-5)
    TEST_FAILED("First param third time value should be 6.64012, not " + Convert(val));

  qi->First();
  qi->NextParam();

  val = qi->FloatValue();
  if (abs(val - 1.44126) > 1e-5)
    TEST_FAILED("Second param first time value should be 1.44126, not " + Convert(val));

  qi->NextTime();
  val = qi->FloatValue();
  if (abs(val - 2.32046) > 1e-5)
    TEST_FAILED("Second param second time value should be 2.32046, not " + Convert(val));

  qi->NextTime();
  val = qi->FloatValue();
  if (abs(val - 1.56875) > 1e-5)
    TEST_FAILED("Second param third time value should be 1.56875, not " + Convert(val));

  TEST_PASSED();
}

void interpolatedvalue()
{
  using NFmiStringTools::Convert;

  qi->First();
  qi->Param(kFmiTemperature);
  float value = qi->InterpolatedValue(NFmiPoint(25, 60));
  if (abs(value - 1.80367) > 1e-5)
    TEST_FAILED("Expected t2m 1.80367 for 25,60 at time 1, got " + Convert(value));

  qi->NextTime();
  value = qi->InterpolatedValue(NFmiPoint(25, 60));
  if (abs(value - 2.27819) > 1e-5)
    TEST_FAILED("Expected t2m 2.27819 for 25,60 at time 2, got " + Convert(value));

  value = qi->InterpolatedValue(NFmiPoint(27, 62));
  if (abs(value - 0.226417) > 1e-5)
    TEST_FAILED("Expected t2m 0.226417 for 27,62 at time 2, got " + Convert(value));

  qi->First();
  qi->Param(kFmiPrecipitation1h);

  value = qi->InterpolatedValue(NFmiPoint(25, 60));
  if (abs(value - 0) > 1e-5)
    TEST_FAILED("Expected rr1h 0 for 25,60 at time 1, got " + Convert(value));

  qi->NextTime();
  value = qi->InterpolatedValue(NFmiPoint(25, 60));
  if (abs(value - 0) > 1e-5)
    TEST_FAILED("Expected rr1h 0 for 25,60 at time 2, got " + Convert(value));

  value = qi->InterpolatedValue(NFmiPoint(22, 65));
  if (abs(value - 0.252077) > 1e-5)
    TEST_FAILED("Expected rr1h 0.252077 for 22,65 at time 2, got " + Convert(value));

  {
    // special tests for fixing UV interpolation bug

    NFmiMultiQueryInfo qinfo("data/uv.sqd");

    qinfo.First();
    qinfo.Param(kFmiUVIndexMax);

    for (int h = 0; h <= 23; h++)
    {
      value = qinfo.InterpolatedValue(NFmiPoint(25, 60), NFmiTime(2009, 4, 21, h, 0), 6 * 60);
      if (h == 12)
      {
        if (abs(value - 3.35) > 1e-5)
          TEST_FAILED("Expected uv 3.35 at 12 UTC, got " + Convert(value));
      }
      else
      {
        if (value != kFloatMissing)
          TEST_FAILED("Expected uv kFloatMissing at " + Convert(h) + " UTC, got " + Convert(value));
      }
    }
  }

  TEST_PASSED();
}

void classid()
{
  using NFmiStringTools::Convert;

  unsigned long id = qi->ClassId();

  if (qi->ClassId() != kNFmiQueryInfo)
    TEST_FAILED("Class id should be kNFmiQueryInfo, not " + Convert(id));

  TEST_PASSED();
}

void infoversion()
{
  using NFmiStringTools::Convert;

  double version = qi->InfoVersion();
  if (version != 6) TEST_FAILED("Info Version should be 6, not " + Convert(version));

  TEST_PASSED();
}

void multifile_non_overlapping()
{
  using NFmiStringTools::Convert;

  std::list<std::string> files;
  files.push_back("data/201309110600_tutka_suomi_rr.sqd");
  files.push_back("data/201309110605_tutka_suomi_rr.sqd");
  files.push_back("data/201309110610_tutka_suomi_rr.sqd");
  files.push_back("data/201309110615_tutka_suomi_rr.sqd");

  NFmiMultiQueryInfo mqi(files);
  mqi.ResetTime();
  mqi.Param(kFmiPrecipitationRate);
  mqi.Location(NFmiLocation(25.7333, 60.8083));

  vector<float> result_vector;

  // testing NextTime()
  while (mqi.NextTime())
  {
    result_vector.push_back(mqi.InterpolatedValue(mqi.ValidTime(), 0));
  }
  if (result_vector.size() != 4)
    TEST_FAILED("Not enough result values: expected 4, got " + Convert(result_vector.size()));

  if (Convert(result_vector[0]) != "0.71" || Convert(result_vector[1]) != "0.27" ||
      Convert(result_vector[2]) != "0" || Convert(result_vector[3]) != "0")
  {
    std::string result_str;
    result_str.append(Convert(result_vector[0]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[1]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[2]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[3]));
    TEST_FAILED("Expected PrecipitationRate 0.71, 0.27, 0, 0, got " + result_str);
  }
  // testing ResetTime()
  result_vector.clear();
  mqi.ResetTime();
  while (mqi.NextTime())
  {
    result_vector.push_back(mqi.InterpolatedValue(mqi.ValidTime(), 0));
  }
  if (result_vector.size() != 4)
    TEST_FAILED("Not enough result values after ResetTime(): expected 4, got " +
                Convert(result_vector.size()));
  if (Convert(result_vector[0]) != "0.71" || Convert(result_vector[1]) != "0.27" ||
      Convert(result_vector[2]) != "0" || Convert(result_vector[3]) != "0")
  {
    std::string result_str;
    result_str.append(Convert(result_vector[0]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[1]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[2]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[3]));
    TEST_FAILED("Expected PrecipitationRate 0.71, 0.27, 0, 0, got " + result_str);
  }
  // testing LastTime()
  mqi.ResetTime();
  mqi.LastTime();
  float value = mqi.InterpolatedValue(mqi.ValidTime(), 0);
  if (Convert(value) != "0") TEST_FAILED("Expected PrecipitationRate 0 got " + Convert(value));

  // testing FirstTime()
  mqi.ResetTime();
  mqi.FirstTime();
  value = mqi.InterpolatedValue(mqi.ValidTime(), 0);
  if (Convert(value) != "0.71")
    TEST_FAILED("Expected PrecipitationRate 0.71 got " + Convert(value));

  NFmiTime tim;
  // testing PreviousTime()
  result_vector.clear();
  mqi.LastTime();
  result_vector.push_back(mqi.InterpolatedValue(mqi.ValidTime(), 0));
  while (mqi.PreviousTime())
  {
    if (result_vector.size() == 2) tim = mqi.ValidTime();
    result_vector.push_back(mqi.InterpolatedValue(mqi.ValidTime(), 0));
  }
  if (Convert(result_vector[0]) != "0" || Convert(result_vector[1]) != "0" ||
      Convert(result_vector[2]) != "0.27" || Convert(result_vector[3]) != "0.71")
  {
    std::string result_str;
    result_str.append(Convert(result_vector[0]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[1]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[2]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[3]));
    TEST_FAILED("Expected PrecipitationRate 0, 0, 0.27, 0.71, got " + result_str);
  }

  /*
  mqi.FirstTime();
  NFmiMetTime mytime(mqi.ValidTime());
  mytime.ChangeBySeconds(120);

  NFmiDataMatrix<NFmiLocationCache> locationCache;

  mqi.CalcLatlonCachePoints(mqi, locationCache);

  NFmiTimeCache timeCache = mqi.CalcTimeCache(mytime);

  NFmiGrid grid = *mqi.Grid();
  unsigned long xs = grid.XNumber();

  for( grid.Reset(); grid.Next(); )
    {
          NFmiLocationCache & lc = locationCache[grid.Index() % xs][grid.Index() / xs];
          mqi.CachedInterpolation(lc, timeCache);
    }
*/
  /*
  std::cout << "ANSSI0: " << tim << endl;
  std::cout << "ANSSI1: " << mqi.ValidTime() << endl;
  std::cout << "ANSSI2: " << mqi.Time() << endl;
  std::cout << "ANSSI3: " << mqi.OriginTime() << endl;
  */

  TEST_PASSED();
}

void multifile_overlapping()
{
  using NFmiStringTools::Convert;

  std::list<std::string> files;
  files.push_back("data/201309120708_pal_skandinavia_maanpinta.sqd");
  files.push_back("data/201309111610_pal_skandinavia_maanpinta.sqd");

  NFmiMultiQueryInfo mqi(files);
  mqi.ResetTime();
  mqi.Param(kFmiGroundTemperature);
  mqi.Location(NFmiLocation(24.9375, 60.1708));
  vector<float> result_vector;

  // testing NextTime()
  while (mqi.NextTime())
  {
    float value = mqi.InterpolatedValue(mqi.ValidTime(), 0);
    result_vector.push_back(value);
  }
  if (result_vector.size() != 10)
    TEST_FAILED("Not enough result values: expected 10, got " + Convert(result_vector.size()));
  if (Convert(result_vector[0]) != "8.51755" || Convert(result_vector[1]) != "7.63031" ||
      Convert(result_vector[2]) != "9.33667" || Convert(result_vector[3]) != "10.4724" ||
      Convert(result_vector[4]) != "12.3766" || Convert(result_vector[5]) != "9.70439" ||
      Convert(result_vector[6]) != "9.00446" || Convert(result_vector[7]) != "9.86303" ||
      Convert(result_vector[8]) != "11.807" || Convert(result_vector[9]) != "12.9554")
  {
    std::string result_str;
    result_str.append(Convert(result_vector[0]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[1]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[2]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[3]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[4]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[5]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[6]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[7]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[8]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[9]));
    TEST_FAILED(
        "Expected GroudTemperature 8.51755, 7.63031, 9.33667, 10.4724, 12.3766, 9.70439, 9.00446, "
        "9.86303, 11.807, 12.9554 got " +
        result_str);
  }

  // testing ResetTime()
  result_vector.clear();
  mqi.ResetTime();
  while (mqi.NextTime())
  {
    result_vector.push_back(mqi.InterpolatedValue(mqi.ValidTime(), 0));
  }
  if (result_vector.size() != 10)
    TEST_FAILED("Not enough result values: expected 10, got " + Convert(result_vector.size()));
  if (Convert(result_vector[0]) != "8.51755" || Convert(result_vector[1]) != "7.63031" ||
      Convert(result_vector[2]) != "9.33667" || Convert(result_vector[3]) != "10.4724" ||
      Convert(result_vector[4]) != "12.3766" || Convert(result_vector[5]) != "9.70439" ||
      Convert(result_vector[6]) != "9.00446" || Convert(result_vector[7]) != "9.86303" ||
      Convert(result_vector[8]) != "11.807" || Convert(result_vector[9]) != "12.9554")
  {
    std::string result_str;
    result_str.append(Convert(result_vector[0]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[1]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[2]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[3]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[4]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[5]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[6]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[7]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[8]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[9]));
    TEST_FAILED(
        "Expected GroudTemperature 8.51755, 7.63031, 9.33667, 10.4724, 12.3766, 9.70439, 9.00446, "
        "9.86303, 11.807, 12.9554 got " +
        result_str);
  }

  // testing LastTime()
  mqi.ResetTime();
  mqi.LastTime();
  float value = mqi.InterpolatedValue(mqi.ValidTime(), 0);
  if (Convert(value) != "12.9554")
    TEST_FAILED("Expected PrecipitationRate 12.9554 got " + Convert(value));

  // testing FirstTime()
  mqi.ResetTime();
  mqi.FirstTime();
  value = mqi.InterpolatedValue(mqi.ValidTime(), 0);
  if (Convert(value) != "8.51755")
    TEST_FAILED("Expected PrecipitationRate 8.51755 got " + Convert(value));

  // testing PreviousTime()
  result_vector.clear();
  mqi.LastTime();
  result_vector.push_back(mqi.InterpolatedValue(mqi.ValidTime(), 0));
  while (mqi.PreviousTime())
  {
    result_vector.push_back(mqi.InterpolatedValue(mqi.ValidTime(), 0));
  }

  /*
  qi->FirstTime();
  while(qi->NextTime())
    {
          std::cout << "qi->Time(): " << qi->Time() << endl;
          std::cout << "qi->ValidTime(): " << qi->ValidTime() << endl;
          std::cout << "qi->IsValidTime(): " << qi->IsValidTime() << endl;
    }
  if(!qi->NextTime())
    {
          std::cout << "qi->IsValidTime()2: " << qi->IsValidTime() << endl;
          qi->FirstTime();
          qi->NextTime();
          NFmiMetTime tim(qi->ValidTime());
          std::cout << "timmi: " << tim << endl;
          qi->ResetTime();
          std::cout << "qi->IsValidTime()3: " << qi->IsValidTime() << endl;
          std::cout << "qi->ValidTime()3: " << qi->ValidTime() << endl;
          qi->Time(tim);
          std::cout << "qi->IsValidTime()4: " << qi->IsValidTime() << endl;
          std::cout << "qi->Time()4: " << qi->Time() << endl;
          std::cout << "qi->ValidTime()4: " << qi->ValidTime() << endl;
    }
  std::cout << "qi->IsValidTime()5: " << qi->IsValidTime() << endl;
  std::cout << "qi->Time()5: " << qi->ValidTime() << endl;
  std::cout << "qi->ValidTime()5: " << qi->ValidTime() << endl;

  qi->Time(NFmiMetTime(2013,9,9,10,10,0,0));
  std::cout << "qi->IsValidTime()6: " << qi->IsValidTime() << endl;
  std::cout << "qi->ValidTime()6: " << qi->ValidTime() << endl;
  std::cout << "qi->Time()6: " << qi->Time() << endl;
  */

  if (Convert(result_vector[0]) != "12.9554" || Convert(result_vector[1]) != "11.807" ||
      Convert(result_vector[2]) != "9.86303" || Convert(result_vector[3]) != "9.00446" ||
      Convert(result_vector[4]) != "9.70439" || Convert(result_vector[5]) != "12.3766" ||
      Convert(result_vector[6]) != "10.4724" || Convert(result_vector[7]) != "9.33667" ||
      Convert(result_vector[8]) != "7.63031" || Convert(result_vector[9]) != "8.51755")
  {
    std::string result_str;
    result_str.append(Convert(result_vector[0]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[1]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[2]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[3]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[4]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[5]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[6]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[7]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[8]));
    result_str.append(", ");
    result_str.append(Convert(result_vector[9]));
    TEST_FAILED(
        "Expected PrecipitationRate 12.9554, 11.807, 9.86303, 9.00446, 9.70439, 12.3766, 10.4724, "
        "9.33667, 7.63031, 8.51755 got " +
        result_str);
  }

  TEST_PASSED();
}

void multifile_grid_interpolation()
{
  using NFmiStringTools::Convert;

  std::list<std::string> files;
  files.push_back("data/201309110600_tutka_suomi_rr.sqd");
  files.push_back("data/201309110605_tutka_suomi_rr.sqd");

  NFmiMultiQueryInfo mqi(files);
  mqi.ResetTime();
  mqi.Param(kFmiPrecipitationRate);
  mqi.Location(NFmiLocation(25.7333, 60.8083));
  vector<float> result_vector;

  /*
  NFmiDataMatrix<float> dataMatrix;

  NFmiFastQueryInfo& fqi = mqi;
  mqi.Values(dataMatrix);
  fqi->Values(dataMatrix);
  */

  /*
  std::cout << "dataMatrix.size()1: " << dataMatrix.NX() << ", " << dataMatrix.NY() << endl;

  mqi.FirstTime();
  mqi.Values(dataMatrix, mqi.ValidTime());
  std::cout << "dataMatrix.size()2: " << dataMatrix.NX() << ", " << dataMatrix.NY() << endl;
  dataMatrix = NFmiDataMatrix<float>();
  std::cout << "dataMatrix.size()3: " << dataMatrix.NX() << ", " << dataMatrix.NY() << endl;
  mqi.ResetTime();
  std::cout << "dataMatrix.size()31: " << mqi.ValidTime() << endl;
  mqi.LastTime();
  std::cout << "dataMatrix.size()32: " << mqi.ValidTime() << endl;
  mqi.Values(dataMatrix, mqi.ValidTime());
  std::cout << "dataMatrix.size()4: " << dataMatrix.NX() << ", " << dataMatrix.NY() << endl;
  std::cout << "dataMatrix.value4: " << dataMatrix[0][0] << ", " << dataMatrix[0][1] << endl;
  dataMatrix = NFmiDataMatrix<float>();
  std::cout << "dataMatrix.size()5: " << dataMatrix.NX() << ", " << dataMatrix.NY() << endl;

  NFmiMetTime intermediateTime(2013,9,11,6,3,0,1);
  mqi.Values(dataMatrix, intermediateTime);
  std::cout << "dataMatrix.size()6: " << dataMatrix.NX() << ", " << dataMatrix.NY() << endl;
  std::cout << "dataMatrix.value6: " << dataMatrix[0][0] << ", " << dataMatrix[0][1] << endl;
  */

  TEST_PASSED();
}

// ----------------------------------------------------------------------
/*!
 * The actual test suite
 */
// ----------------------------------------------------------------------

class tests : public tframe::tests
{
  virtual const char* error_message_prefix() const { return "\n\t"; }
  void test(void)
  {
    TEST(reading);
    TEST(constructing);
    TEST(nextparam);
    TEST(nexttime);
    TEST(islocation);
    TEST(islevel);
    TEST(isarea);
    TEST(isgrid);
    TEST(isvalidtime);
    TEST(isorigintime);
    TEST(param);
    TEST(level);
    TEST(time);
    TEST(validtime);
    TEST(origintime);
    TEST(forecastperiod);
    TEST(floatvalue);
    TEST(interpolatedvalue);
    TEST(classid);
    TEST(infoversion);
    TEST(multifile_non_overlapping);
    TEST(multifile_overlapping);
    TEST(multifile_grid_interpolation);
  }
};

}  // namespace NFmiMultiQueryInfoTest

//! The main program
int main(void)
{
  using namespace std;
  cout << endl << "NFmiMultiQueryInfo tester" << endl << "====================" << endl;
  NFmiMultiQueryInfoTest::tests t;
  return t.run();
}

// ======================================================================

ext: cpp

max_stars_repo_name: fmidev/smartmet-workstation-vtk

max_issues_repo_name: fmidev/smartmet-workstation-vtk

max_forks_repo_name: fmidev/smartmet-workstation-vtk


text:
/*
 * Copyright 2014, Andrea Del Prete, LAAS-CNRS
 *
 * This file is part of sot-torque-control.
 * sot-torque-control is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * sot-torque-control is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.  You should
 * have received a copy of the GNU Lesser General Public License along
 * with sot-torque-control.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __sot_torque_control_NumericalDifference_H__
#define __sot_torque_control_NumericalDifference_H__
/* --------------------------------------------------------------------- */
/* --- API ------------------------------------------------------------- */
/* --------------------------------------------------------------------- */

#if defined (WIN32)
#  if defined (numerical_difference_EXPORTS)
#    define SOTNUMERICALDIFFERENCE_EXPORT __declspec(dllexport)
#  else
#    define SOTNUMERICALDIFFERENCE_EXPORT __declspec(dllimport)
#  endif
#else
#  define SOTNUMERICALDIFFERENCE_EXPORT
#endif

//#define VP_DEBUG 1        /// enable debug output
//#define VP_DEBUG_MODE 20

/* --------------------------------------------------------------------- */
/* --- INCLUDE --------------------------------------------------------- */
/* --------------------------------------------------------------------- */

/* HELPER */
#include <boost/circular_buffer.hpp>
#include <dynamic-graph/signal-helper.h>
#include <sot/core/matrix-geometry.hh>
#include <sot/torque_control/utils/vector-conversions.hh>
#include <sot/torque_control/utils/stop-watch.hh>

/* Polynomial estimators */
#include <sot/torque_control/utils/lin-estimator.hh>
#include <sot/torque_control/utils/quad-estimator.hh>

namespace dynamicgraph {
  namespace sot {
    namespace torque_control {

      /**
        * This Entity takes as inputs a signal and estimates its first two time derivatives.
        */
      class SOTNUMERICALDIFFERENCE_EXPORT NumericalDifference
          :public ::dynamicgraph::Entity
      {
        DYNAMIC_GRAPH_ENTITY_DECL();

      public:  /* --- SIGNALS --- */
        DECLARE_SIGNAL_IN(x,                 dynamicgraph::Vector);
        DECLARE_SIGNAL_OUT(x_filtered,       dynamicgraph::Vector);
        DECLARE_SIGNAL_OUT(dx,               dynamicgraph::Vector);
        DECLARE_SIGNAL_OUT(ddx,              dynamicgraph::Vector);

        /// The following inner signals are used because this entity has some output signals
        /// whose related quantities are computed at the same time by the same algorithm
        /// To avoid the risk of recomputing the same things twice, we create an inner signal that groups together
        /// all the quantities that are computed together. Then the single output signals will depend
        /// on this inner signal, which is the one triggering the computations.
        /// Inner signals are not exposed, so that nobody can access them.

        /// This signal contains the estimated positions, velocities and accelerations.
        DECLARE_SIGNAL_INNER(x_dx_ddx,              dynamicgraph::Vector);

      protected:

        double m_dt;      /// sampling timestep of the input signal
        double m_delay;   /// delay introduced by the estimation
        int x_size;
        /// std::vector to use with the filters
        /// All the variables whose name contains 'filter' are outputs of the filters
        std::vector<double> m_ddx_filter_std;  /// 2nd derivative
        std::vector<double> m_dx_filter_std;   /// 1st derivative
        std::vector<double> m_x_filter_std;    /// filtered output
        std::vector<double> m_x_std;           /// x signal

        /// polynomial-fitting filters
        PolyEstimator* m_filter;

      public:
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW

        /** --- CONSTRUCTOR ---- */
        NumericalDifference( const std::string & name );

        /** Initialize the NumericalDifference.
         * @param timestep Period (in seconds) after which the sensors' data are updated.
         * @param sigSize  Size of the input signal.
         * @param delay    Delay (in seconds) introduced by the estimation.
         *                 This should be a multiple of timestep.
         * @param polyOrder Order of the approximation polynomial. int 1 or 2.
         * @note The estimationDelay is half of the length of the window used for the
         * polynomial fitting. The larger the delay, the smoother the estimations.
         */
        void init(const double &timestep, const int& sigSize,
                  const double &delay, const int& polyOrder);

      protected:
        void sendMsg(const std::string& msg, MsgType t=MSG_TYPE_INFO, const char* file="", int line=0)
        {
	  Entity::sendMsg("["+name+"] "+msg, t, file, line);
        }

      public: /* --- ENTITY INHERITANCE --- */
        virtual void display( std::ostream& os ) const;

      }; // class NumericalDifference

    } // namespace torque_control
  } // namespace sot
} // namespace dynamicgraph

#endif // #ifndef __sot_torque_control_NumericalDifference_H__

ext: hh

max_stars_repo_name: NoelieRamuzat/sot-torque-control

max_issues_repo_name: NoelieRamuzat/sot-torque-control

max_forks_repo_name: NoelieRamuzat/sot-torque-control


text:
//Copyright (c) 2014-2019, The Monero Project
//Copyright (c) 2018-2020, The Scala Network
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
//    conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 HOLDER 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.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers

#include "checkpoints.h"

#include "common/dns_utils.h"
#include "string_tools.h"
#include "storages/portable_storage_template_helper.h" // epee json include
#include "serialization/keyvalue_serialization.h"
#include <vector>
#include <boost/random.hpp>
#include <iostream>
#include <ctime>
#include <cstdint>
#include <sstream>
#include <string>
#include <boost/algorithm/string.hpp>
#include <algorithm>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/join.hpp>

using namespace boost::property_tree;
using namespace boost::algorithm;
using namespace epee;

#undef SCALA_DEFAULT_LOG_CATEGORY
#define SCALA_DEFAULT_LOG_CATEGORY "checkpoints"

namespace cryptonote
{
  /**
   * @brief struct for loading a checkpoint from json
   */
  struct t_hashline
  {
    uint64_t height; //!< the height of the checkpoint
    std::string hash; //!< the hash for the checkpoint
        BEGIN_KV_SERIALIZE_MAP()
          KV_SERIALIZE(height)
          KV_SERIALIZE(hash)
        END_KV_SERIALIZE_MAP()
  };

  /**
   * @brief struct for loading many checkpoints from json
   */
  struct t_hash_json {
    std::vector<t_hashline> hashlines; //!< the checkpoint lines from the file
        BEGIN_KV_SERIALIZE_MAP()
          KV_SERIALIZE(hashlines)
        END_KV_SERIALIZE_MAP()
  };

  //---------------------------------------------------------------------------
  checkpoints::checkpoints()
  {
  }
  //---------------------------------------------------------------------------
  bool checkpoints::add_checkpoint(uint64_t height, const std::string& hash_str)
  {
    crypto::hash h = crypto::null_hash;
    bool r = epee::string_tools::hex_to_pod(hash_str, h);
    CHECK_AND_ASSERT_MES(r, false, "Failed to parse checkpoint hash string into binary representation!");

    // return false if adding at a height we already have AND the hash is different
    if (m_points.count(height))
    {
      CHECK_AND_ASSERT_MES(h == m_points[height], false, "Checkpoint at given height already exists, and hash for new checkpoint was different!");
    }
    m_points[height] = h;
    return true;
  }
  //---------------------------------------------------------------------------
   bool checkpoints::get_request_ldpow(const std::string& request_url, std::string& response, const std::string& log_message)
   {
     epee::net_utils::http::http_simple_client client;
     epee::net_utils::http::url_content u_c;

     if (!epee::net_utils::parse_url(request_url, u_c)){
        MERROR("Failed to parse URL " << request_url);
        return false;
     }

     if (u_c.host.empty()){
				MERROR("Failed to determine address from URL " << request_url);
        return false;
     }

     epee::net_utils::ssl_support_t ssl_requirement = u_c.schema == "https" ? epee::net_utils::ssl_support_t::e_ssl_support_enabled : epee::net_utils::ssl_support_t::e_ssl_support_disabled;
     uint16_t port = u_c.port ? u_c.port : ssl_requirement == epee::net_utils::ssl_support_t::e_ssl_support_enabled ? 443 : 80;

     client.set_server(u_c.host, std::to_string(port), boost::none, ssl_requirement);
     epee::net_utils::http::fields_list fields;
     const epee::net_utils::http::http_response_info *info = NULL;

		 if (!client.invoke_get(u_c.uri, std::chrono::seconds(5), "", &info, fields)){
				LOG_PRINT_L0(request_url << " is not responding, skipping.");
				return false;
		 }else{
     LOG_PRINT_L1(log_message);
     response = std::string(info->m_body);
     return true;
     }
   }
  //---------------------------------------------------------------------------
  bool checkpoints::is_in_checkpoint_zone(uint64_t height) const
  {
    return !m_points.empty() && (height <= (--m_points.end())->first);
  }
  //---------------------------------------------------------------------------
  bool checkpoints::check_block(uint64_t height, const crypto::hash& h, bool& is_a_checkpoint) const
  {
    auto it = m_points.find(height);
    is_a_checkpoint = it != m_points.end();
    if(!is_a_checkpoint)
      return true;

    if(it->second == h)
    {
      MINFO("CHECKPOINT PASSED FOR HEIGHT " << height << " " << h);
      return true;
    }else
    {
      MWARNING("CHECKPOINT FAILED FOR HEIGHT " << height << ". EXPECTED HASH: " << it->second << ", FETCHED HASH: " << h);
      return false;
    }
  }
  //---------------------------------------------------------------------------
  bool checkpoints::check_block(uint64_t height, const crypto::hash& h) const
  {
    bool ignored;
    return check_block(height, h, ignored);
  }
  //---------------------------------------------------------------------------
  //FIXME: is this the desired behavior?
  bool checkpoints::is_alternative_block_allowed(uint64_t blockchain_height, uint64_t block_height) const
  {
    if (0 == block_height)
      return false;

    auto it = m_points.upper_bound(blockchain_height);
    // Is blockchain_height before the first checkpoint?
    if (it == m_points.begin())
      return true;

    --it;
    uint64_t checkpoint_height = it->first;
    return checkpoint_height < block_height;
  }
  //---------------------------------------------------------------------------
  uint64_t checkpoints::get_max_height() const
  {
    if (m_points.empty())
      return 0;
    return m_points.rbegin()->first;
  }
  //---------------------------------------------------------------------------
  const std::map<uint64_t, crypto::hash>& checkpoints::get_points() const
  {
    return m_points;
  }

  bool checkpoints::check_for_conflicts(const checkpoints& other) const
  {
    for (auto& pt : other.get_points())
    {
      if (m_points.count(pt.first))
      {
        CHECK_AND_ASSERT_MES(pt.second == m_points.at(pt.first), false, "Checkpoint at given height already exists, and hash for new checkpoint was different!");
      }
    }
    return true;
  }
  //---------------------------------------------------------------------------
  bool checkpoints::init_default_checkpoints(network_type nettype)
  {
    if (nettype == TESTNET)
    {
      return true;
    }
    if (nettype == STAGENET)
    {
      return true;
    }
    std::string request_url_serverless = "http://checkpoint.scalaproject.io/";
    std::string response_serverless = "";
    std::string log_message_serverless = "Sending request to GET IPFS hash for big checkpoint.";

    bool big_checkpoint_request_SL = get_request_ldpow(request_url_serverless, response_serverless, log_message_serverless);
    if(big_checkpoint_request_SL == true){
      std::string request_url_ipfs_gateway = "https://ipfs.io/ipfs/" + response_serverless;
      std::string response_ipfs_gateway = "";
      std::string log_message_ipfs_gateway = "Sending request to GET big checkpoint from IPFS Gateway.";
      bool ipfs_checkpoint = get_request_ldpow(request_url_ipfs_gateway, response_ipfs_gateway, log_message_ipfs_gateway);
      if(ipfs_checkpoint == true){
        std::string hash_string = "hash";
        if (response_ipfs_gateway.find(hash_string) != std::string::npos){
        std::stringstream string_stream(response_ipfs_gateway);
        ptree stree;
        read_json(string_stream, stree);
        uint64_t height;
        std::string hash;

        BOOST_FOREACH(const boost::property_tree::ptree::value_type &v, stree) {
          height = v.second.get<int>("height");
          hash = v.second.get<std::string>("hash");
	  int isTh = height % 1000;
	  if(isTh == 0){
          MGINFO("Height " << height << " hash " << hash << " from IPFS.");
	  }
          ADD_CHECKPOINT(height, hash);
        }
        return true;
        }else{
          	MERROR("Skipping initializing IPFS checkpoints, something went wrong.");
				    return true;
        }
      }
    }else{
          	MERROR("Skipping initializing IPFS checkpoints, something went wrong.");
				    return true;
    }
    return true;
  }
  //---------------------------------------------------------------------------

  bool checkpoints::load_checkpoints_from_json(const std::string &json_hashfile_fullpath)
  {
    boost::system::error_code errcode;
    if (! (boost::filesystem::exists(json_hashfile_fullpath, errcode)))
    {
      LOG_PRINT_L1("Blockchain checkpoints file not found");
      return true;
    }

    LOG_PRINT_L1("Adding checkpoints from blockchain hashfile");

    uint64_t prev_max_height = get_max_height();
    LOG_PRINT_L1("Hard-coded max checkpoint height is " << prev_max_height);
    t_hash_json hashes;
    if (!epee::serialization::load_t_from_json_file(hashes, json_hashfile_fullpath))
    {
      MERROR("Error loading checkpoints from " << json_hashfile_fullpath);
      return false;
    }
    for (std::vector<t_hashline>::const_iterator it = hashes.hashlines.begin(); it != hashes.hashlines.end(); )
    {
      uint64_t height;
      height = it->height;
      if (height <= prev_max_height) {
	LOG_PRINT_L1("ignoring checkpoint height " << height);
      } else {
	std::string blockhash = it->hash;
	LOG_PRINT_L1("Adding checkpoint height " << height << ", hash=" << blockhash);
	ADD_CHECKPOINT(height, blockhash);
      }
      ++it;
    }

    return true;
  }
  //---------------------------------------------------------------------------
  bool checkpoints::load_checkpoints_from_ldpow_network(uint64_t height){
    std::time_t now = std::time(0);
    boost::random::mt19937 gen{static_cast<std::uint32_t>(now)};
    boost::random::uniform_int_distribution<> dist{0, 15};

    std::vector<std::string> two_nodes;
    two_nodes.push_back(cryptonote::ldpow_nodes.at(dist(gen)));
    two_nodes.push_back(cryptonote::ldpow_nodes.at(dist(gen)));

    LOG_PRINT_L1("Pulling from the following nodes this LdPoW round.");
    LOG_PRINT_L1(two_nodes.at(0));
    LOG_PRINT_L1(two_nodes.at(1));

    /* Don't LdPoW before 800th block */
    if (height > 800){
            std::vector<std::string> block_hashes;
            std::vector<std::string> block_hashes_reversed;
            uint64_t height_to_checkpoint = height - 20;
            std::string block_height_string = std::to_string(height_to_checkpoint);

            for (const auto &value: two_nodes){
                      std::string request_url_ldpow = value + "get_block/" + block_height_string;
                      std::string response_ldpow = "";
                      std::string log_message = "Getting block from " + value + " node now.";

                      bool ldpow_request = get_request_ldpow(request_url_ldpow, response_ldpow, log_message);
                      if(ldpow_request == true){
                              LOG_PRINT_L1("Request for node " << value << " went through.");
                              LOG_PRINT_L1("Response from LdPoW " << response_ldpow);

                              std::string good_response("hash");
                              bool b = boost::algorithm::contains(response_ldpow, good_response);
                              if(b == true){
                         			  std::stringstream string_stream(response_ldpow);
			                          ptree strTree;
			                          read_json(string_stream, strTree);
                                std::string block_hash = strTree.get<std::string> ("hash");
				                        LOG_PRINT_L1("Request seems to have passed, " << block_hash << " recieved from LdPoW node "<< value <<" for block height : " << block_height_string << '\n');
          				                block_hashes.push_back(block_hash);	// Push the block hash we got from LdPoW node into a list.

                              }else{
      	                                    LOG_PRINT_L1("Block height of " << block_height_string << " not available with " << value);
				                                    return true;
		                          }
                      }else{
                        LOG_PRINT_L0("Something went wrong with LdPoW, skipping!");
                        return true;
                      }
            }
            int list_size = block_hashes.size();
            if (list_size < 2){
                /* This would never occur as the above loop will return true if there are nodes that doesn't reply to our requests*/
                LOG_PRINT_L0("No response from some of the lDPoW nodes, not adding any checkpoints now.");
                return true;
            }else{
                block_hashes_reversed = block_hashes;
                std::reverse(block_hashes_reversed.begin(), block_hashes_reversed.end());

                if (block_hashes == block_hashes_reversed){
                  MGINFO("LdPoW has reported the same hash for block " << block_height_string << " adding as checkpoint!");
                  ADD_CHECKPOINT(height_to_checkpoint, block_hashes.back());
                }else{
                  MERROR("Node have not reported the same hash for block " << block_height_string << " network split detected!");
                }
            }
            return true;
    }else{
      /* Not yet time for enabling LdPoW */
      return true;
    }
    return true;
  }
  //---------------------------------------------------------------------------
  bool checkpoints::load_checkpoints_from_dns(network_type nettype)
  {
    std::vector<std::string> records;

    // All four ScalaPulse domains have DNSSEC on and valid
    static const std::vector<std::string> dns_urls = { "checkpointsdns.scalaproject.io" };

    static const std::vector<std::string> testnet_dns_urls = { "testcheckpointsdns.scalaproject.io" };

    static const std::vector<std::string> stagenet_dns_urls = { "stagecheckpointsdns.scalaproject.io" };

    if (!tools::dns_utils::load_txt_records_from_dns(records, nettype == TESTNET ? testnet_dns_urls : nettype == STAGENET ? stagenet_dns_urls : dns_urls))
      return true; // why true ?

    for (const auto& record : records)
    {
      auto pos = record.find(":");
      if (pos != std::string::npos)
      {
        uint64_t height;
        crypto::hash hash;

        // parse the first part as uint64_t,
        // if this fails move on to the next record
        std::stringstream ss(record.substr(0, pos));
        if (!(ss >> height))
        {
    continue;
        }

        // parse the second part as crypto::hash,
        // if this fails move on to the next record
        std::string hashStr = record.substr(pos + 1);
        if (!epee::string_tools::hex_to_pod(hashStr, hash))
        {
    continue;
        }

        ADD_CHECKPOINT(height, hashStr);
      }
    }
    return true;
  }

  bool checkpoints::load_new_checkpoints(const std::string &json_hashfile_fullpath, network_type nettype, bool dns)
  {
    bool result;

    result = load_checkpoints_from_json(json_hashfile_fullpath);
    if (dns)
    {
      result &= load_checkpoints_from_dns(nettype);
    }

    return result;
  }
}

max_stars_repo_name: stellitecoin/Stellite

max_issues_repo_name: pirasathv/Scala

max_forks_repo_name: pirasathv/Scala


text:
#include "include/seastarkv.hh"
#include "include/req_server.hh"
#include "include/net_server.hh"
#include "include/scheduler.hh"
#include "include/db.hh"
#include "v8/src/runtime/runtime.h"
#include <iostream>
#include <cstdio>
#include <condition_variable>
#include <thread>
#include <fstream>
#include <string>
#include <functional>
#include <boost/uuid/detail/sha1.hpp>
#include <boost/beast/core/detail/base64.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <stdlib.h>

using namespace std;
using namespace seastar;
using namespace v8;
using namespace shredder;
using namespace boost::uuids;

distributed<req_service> req_server;
extern mongocxx::pool *pool;

static const char* ToCString(const v8::String::Utf8Value& value) {
    return *value ? *value : "<string conversion failed>";
}

future<> req_service::start(void) {
    create_params.array_buffer_allocator =
        v8::ArrayBuffer::Allocator::NewDefaultAllocator();
    isolate = Isolate::New(create_params);

    if (this_shard_id() >= HW_Q_COUNT)
        big_core = true;

    return make_ready_future<>();
}

future<> req_service::stop() {
    return make_ready_future<>();
}

future<> req_service::register_service(std::string service) {
    v8::Locker locker{isolate};
    Isolate::Scope isolate_scope(isolate);
    {
        HandleScope handle_scope(isolate);

	v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
        // Set C++ bindings
        global->Set(
            v8::String::NewFromUtf8(isolate, "DBGet", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, db_get)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "DBSet", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, db_set)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "DBDel", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, db_del)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "print", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, js_print)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "GetHashTable", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, get_hash_table)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "Call", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, call_function)
        );
	global->Set(
            v8::String::NewFromUtf8(isolate, "NewDB", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, new_database)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "Reply", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, shredder::reply)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "Sha1", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, shredder::sha1)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "Base64Decode", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, shredder::base64_decode)
        );
	global->Set(
            v8::String::NewFromUtf8(isolate, "ServiceName", v8::NewStringType::kNormal)
                .ToLocalChecked(),
	    String::NewFromUtf8(isolate, service.c_str(), NewStringType::kNormal)
                .ToLocalChecked()
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "MongoGet", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::FunctionTemplate::New(isolate, shredder::mongo_get)
        );
        global->Set(
            v8::String::NewFromUtf8(isolate, "CoreID", v8::NewStringType::kNormal)
                .ToLocalChecked(),
            v8::Integer::NewFromUnsigned(isolate, engine().cpu_id())
        );

        Local<Context> c = Context::New(isolate, NULL, global);
        Context::Scope contextScope(c);

	Local<String> source;
        // Read the JS script file.
        if (!read_file(isolate, "services/" + service).ToLocal(&source)) {
            fprintf(stderr, "Error reading file\n");
        }

        Local<Script> s =
          Script::Compile(c, source).ToLocalChecked();

        Local<Value> result;
        if (!s->Run(c).ToLocal(&result)) {
          printf("run script error\n");
        }

        ctx_map[service] = unallocated_ctx;
        contexts[unallocated_ctx].Reset(isolate, c);
	unallocated_ctx++;
    }
    create_db(service);
    get_local_sched()->new_service(service);
    return make_ready_future<>();
}

void req_service::run_callback(std::string call_id, std::string service, sstring ret) {
    v8::Locker locker{isolate};
    Isolate::Scope isolate_scope(isolate);
    HandleScope handle_scope(isolate);

    // Switch to V8 context of this service
    Local<Context> context = Local<Context>::New(isolate, contexts[ctx_map[service]]);
    Context::Scope context_scope(context);
    current_context = &context;

    auto key = service + call_id + "cb";
    auto states = (struct callback_states*)get_local_sched()->get_req_states(key);
    Local<Function> callback = Local<Function>::New(isolate, states->callback);
    const int argc = 2;
    Local<Value> argv[argc];
    argv[0] = v8::Null(isolate);
    argv[1] = String::NewFromUtf8(isolate, ret.c_str(), NewStringType::kNormal)
                                 .ToLocalChecked();;

    Local<Value> result;
    if (!callback->Call(context, context->Global(), argc, argv).ToLocal(&result)) {

    } else {
    }
    get_local_sched()->del_req_states(key);
}

void req_service::run_func(std::string req_id, std::string call_id, std::string service, std::string function, std::string jsargs, struct func_states* function_states) {
    v8::Locker locker{isolate};
    Isolate::Scope isolate_scope(isolate);
    HandleScope handle_scope(isolate);

    // Switch to V8 context of this service
    Local<Context> context = Local<Context>::New(isolate, contexts[ctx_map[service]]);
    Context::Scope context_scope(context);
    current_context = &context;

    Local<Function> process_fun;
    Local<String> process_name = String::NewFromUtf8(isolate, function.c_str(), NewStringType::kNormal)
                                 .ToLocalChecked();
    Local<Value> process_val;
    if (!context->Global()->Get(context, process_name).ToLocal(&process_val) ||
        !process_val->IsFunction()) {
         printf("get function fail\n");
    }
    process_fun = Local<Function>::Cast(process_val);

    Local<Value> result;

    const int argc = 3;
    Local<Value> argv[argc];
    argv[0] = String::NewFromUtf8(isolate, req_id.c_str(), NewStringType::kNormal)
                                 .ToLocalChecked();
    argv[1] = String::NewFromUtf8(isolate, call_id.c_str(), NewStringType::kNormal)
                                 .ToLocalChecked();
    argv[2] = String::NewFromUtf8(isolate, jsargs.c_str(), NewStringType::kNormal)
                                 .ToLocalChecked();

    auto start_time = rdtsc();
    if (!process_fun->Call(context, context->Global(), argc, argv).ToLocal(&result)) {
	 auto cstr = "error\n";
	 get_local_sched()->reply(req_id, call_id, service, to_sstring(cstr));

    } else {
    }

    //function_states->mu->lock();
    auto count = function_states->count->load() + 1;
    function_states->count->store(count);
    auto now = rdtsc();
    auto total = function_states->total_exec_time->load() + (now - start_time);
    function_states->total_exec_time->store(total);
    function_states->exec_time->store(total/count);
    if (count >= 100) {
	function_states->count->store(0);
	function_states->total_exec_time->store(0);
    }
    //function_states->mu->unlock();
//    cout << service << function << " " << function_states->exec_time << endl;
}

enum AllocationSpace {
  NEW_SPACE,   // Semispaces collected with copying collector.
  OLD_SPACE,   // May contain pointers to new space.
  CODE_SPACE,  // No pointers to new space, marked executable.
  MAP_SPACE,   // Only and all map objects.
  LO_SPACE,    // Promoted large objects.

  FIRST_SPACE = NEW_SPACE,
  LAST_SPACE = LO_SPACE,
  FIRST_PAGED_SPACE = OLD_SPACE,
  LAST_PAGED_SPACE = MAP_SPACE
};

// The JS thread. Keep this thread although it's doing nothing, because
// performance is better with this thread around, maybe because it keeps
// some V8 states from garbage collectioned or something.
future<> req_service::js() {
    async([this]
    {
        v8::Locker locker{isolate};
        Isolate::Scope isolate_scope(isolate);

        while (true) {
            HandleScope handle_scope(isolate);
            sem.wait(1).get();
        }
    });
    return make_ready_future<>();
}

namespace shredder {
// C++ binding for JS functions to get data from hashtable
void db_get(const v8::FunctionCallbackInfo<v8::Value>& args) {
    auto ctx = args.GetIsolate()->GetCurrentContext();

    v8::String::Utf8Value str(args.GetIsolate(), args[0]);
    auto name = std::string(*str);
    auto db = get_db(name);

    uint32_t key;
    if (args[1]->IsString()) {
        v8::String::Utf8Value s(args.GetIsolate(), args[1]);
	auto k = std::string(*s);
	std::hash<std::string> hasher;
	auto hashed = hasher(k);
	key = static_cast<int>(hashed % numeric_limits<uint32_t>::max());
    } else {
        key = args[1]->Uint32Value(ctx).ToChecked();
    }

    db_val* val = db->ht_get(key);
    if (!val) {
        val = (db_val*)malloc(sizeof(db_val));
	val->data = NULL;
        val->length = 0;
    }

    Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(args.GetIsolate(), val->data, val->length);

    args.GetReturnValue().Set(ab);
    free(val);
}

// C++ binding for JS functions to set data to hashtable
void db_set(const v8::FunctionCallbackInfo<v8::Value>& args) {
    auto ctx = args.GetIsolate()->GetCurrentContext();
    v8::String::Utf8Value str(args.GetIsolate(), args[0]);
    auto name = std::string(*str);
    auto db = get_db(name);

    uint32_t key;
    if (args[1]->IsString()) {
        v8::String::Utf8Value s(args.GetIsolate(), args[1]);
	auto k = std::string(*s);
	std::hash<std::string> hasher;
	auto hashed = hasher(k);
	key = static_cast<int>(hashed % numeric_limits<uint32_t>::max());
    } else {
        key = args[1]->Uint32Value(ctx).ToChecked();
    }

    auto content = args[2].As<v8::ArrayBuffer>()->Externalize();

    auto version = args[3]->Uint32Value(ctx).ToChecked();

    db_val* val = (db_val*)malloc(sizeof(db_val));
    auto tmp = malloc(content.ByteLength() + sizeof(int));
    auto p = (int*)tmp;
    *p = rand();
    p++;
    memcpy(p, content.Data(), content.ByteLength());
    val->data = tmp;
    val->length = content.ByteLength() + sizeof(int);
    val->key = key;

    free(content.Data());

    if (db->ht_set(val, version)) {
        args.GetReturnValue().Set(
            v8::String::NewFromUtf8(args.GetIsolate(), "ok",
                                    v8::NewStringType::kNormal).ToLocalChecked());
    } else {
         args.GetReturnValue().Set(
            v8::String::NewFromUtf8(args.GetIsolate(), "abort",
                                    v8::NewStringType::kNormal).ToLocalChecked());
    }
}

void db_del(const v8::FunctionCallbackInfo<v8::Value>& args) {
}

// C++ binding for JS functions to print messages
void js_print(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Isolate * isolate = args.GetIsolate();
    HandleScope handle_scope(isolate);

    v8::String::Utf8Value str(args.GetIsolate(), args[0]);
    const char* cstr = ToCString(str);
    std::cout << cstr << '\n';
}

// C++ binding for JS functions to get hashtable
void get_hash_table(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Isolate * isolate = args.GetIsolate();
    HandleScope handle_scope(isolate);

    v8::String::Utf8Value str(args.GetIsolate(), args[0]);
    auto name = std::string(*str);
    auto db = get_db(name);

    auto table = db->get_table_direct();
    Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(args.GetIsolate(), table, 1024*1024);
    args.GetReturnValue().Set(ab);
}

void call_function(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Isolate * isolate = args.GetIsolate();
    HandleScope handle_scope(isolate);
    auto context = args.GetIsolate()->GetCurrentContext();

    v8::String::Utf8Value num1(isolate, args[0]);
    auto req_id = std::string(*num1);

    v8::String::Utf8Value num2(isolate, args[1]);
    auto caller = std::string(*num2);

    v8::String::Utf8Value str1(args.GetIsolate(), args[2]);
    auto service = std::string(*str1);
    v8::String::Utf8Value str2(args.GetIsolate(), args[3]);
    auto function = std::string(*str2);

    Local<Function> callback = Local<Function>::Cast(args[4]);

    v8::String::Utf8Value str3(args.GetIsolate(), args[5]);
    auto jsargs = std::string(*str3);

    auto states = new callback_states;

    auto gen = random_generator();
    auto callee = to_string(gen());

    states->callback.Reset(isolate, callback);
    auto key = service + callee + "cb";
    get_local_sched()->set_req_states(key, (void*)states);

    auto cpu = engine().cpu_id();
    get_local_sched()->schedule(cpu, req_id, callee, service, function, jsargs);
}

void new_database(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Isolate * isolate = args.GetIsolate();
    HandleScope handle_scope(isolate);

    v8::String::Utf8Value str(isolate, args[0]);
    auto ret = create_db(std::string(*str));
    args.GetReturnValue().Set(v8::Boolean::New(isolate, ret));
}

void reply(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Isolate * isolate = args.GetIsolate();
    HandleScope handle_scope(isolate);

    v8::String::Utf8Value num1(isolate, args[0]);
    auto req_id = std::string(*num1);

    v8::String::Utf8Value num2(isolate, args[1]);
    auto call_id = std::string(*num2);
    v8::String::Utf8Value str1(isolate, args[2]);
    auto service = std::string(*str1);
    v8::String::Utf8Value str2(isolate, args[3]);
    auto ret = std::string(*str2);
    get_local_sched()->reply(req_id, call_id, service, ret);
}

void sha1(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Isolate * isolate = args.GetIsolate();
    HandleScope handle_scope(isolate);

    v8::String::Utf8Value arg(isolate, args[0]);
    auto str = std::string(*arg);

    boost::uuids::detail::sha1 s;
    char hash[41] = {0};
    s.process_bytes(str.c_str(), str.size());
    unsigned int digest[5];
    s.get_digest(digest);
    for (int i = 0; i < 5; i++)
    {
        std::sprintf(hash + (i << 3), "%08x", digest[i]);
    }

    args.GetReturnValue().Set(
    v8::String::NewFromUtf8(args.GetIsolate(), hash,
                            v8::NewStringType::kNormal).ToLocalChecked());
}

void base64_decode(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Isolate * isolate = args.GetIsolate();
    HandleScope handle_scope(isolate);

    v8::String::Utf8Value arg(isolate, args[0]);
    auto tmp = std::string(*arg);
    std::string dest;
    dest.resize(boost::beast::detail::base64::decoded_size(tmp.size()));
    boost::beast::detail::base64::decode(&dest[0], tmp.c_str(), tmp.size());

    args.GetReturnValue().Set(
    v8::String::NewFromUtf8(args.GetIsolate(), dest.c_str(),
                            v8::NewStringType::kNormal).ToLocalChecked());
}

void mongo_get(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Isolate * isolate = args.GetIsolate();
    HandleScope handle_scope(isolate);

    v8::String::Utf8Value arg0(isolate, args[0]);
    auto db = std::string(*arg0);
    v8::String::Utf8Value arg1(isolate, args[1]);
    auto collection = std::string(*arg1);
    v8::String::Utf8Value arg2(isolate, args[2]);
    auto username= std::string(*arg2);

    auto cli = pool->acquire();
    auto col = cli->database(db)[collection];
    bsoncxx::stdx::optional<bsoncxx::document::value> maybe_result =
      col.find_one(bsoncxx::builder::stream::document{}
		      << "username"
		      << username
		      << bsoncxx::builder::stream::finalize);

    args.GetReturnValue().Set(
    v8::String::NewFromUtf8(args.GetIsolate(), bsoncxx::to_json(*maybe_result).c_str(),
                            v8::NewStringType::kNormal).ToLocalChecked());
}
}

ext: cc

max_stars_repo_name: utah-scs/nanoservices

max_issues_repo_name: utah-scs/nanoservices

max_forks_repo_name: utah-scs/nanoservices


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/CPPAlliance/http_proto
//

#ifndef BOOST_HTTP_PROTO_IMPL_SERIALIZER_IPP
#define BOOST_HTTP_PROTO_IMPL_SERIALIZER_IPP

#include <boost/http_proto/serializer.hpp>

namespace boost {
namespace http_proto {

/*

38 chars:
Content-Length: 18446744073709551615rn
12345678901234567890123456789012345678
         1         2         3       3

Transfer-Encoding:
*/

//------------------------------------------------

bool
serializer::
is_complete() const noexcept
{
    return
        hs_.empty() &&
        bs_.empty();
}

void
serializer::
reset(header_info const& hi)
{
    hs_ = { hi.data, hi.size };
}

const_buffers
serializer::
prepare(error_code& ec)
{
    ec.clear();
    auto p = &v_[0];
    if(! hs_.empty())
    {
        *p = { hs_.data(), hs_.size() };
        ++p;
    }
    if(! bs_.empty())
    {
        *p = { bs_.data(), bs_.size() };
        ++p;
    }
    return const_buffers(v_, p - &v_[0]);
}

void
serializer::
consume(std::size_t n)
{
    if(n <= hs_.size())
    {
        hs_.remove_prefix(n);
        n = 0;
    }
    else
    {
        n -= hs_.size();
        hs_ = {};
    }

    if(n < bs_.size())
    {
        bs_.remove_prefix(n);
        n = 0;
    }
    else
    {
        n -= bs_.size();
        bs_ = {};
    }
}

#if 0
void
serializer::
clear() noexcept
{
    hs_ = {};
}

void
serializer::
reserve(std::size_t bytes)
{
    (void)bytes;
}

void
serializer::
reset_for_head(
    header_info const& hi)
{
    // TODO
    hs_ = { hi.data, hi.size };
}

void
serializer::
attach_body(string_view body)
{
    bs_ = body;
}

void
serializer::
attach_extensions(
    string_view extensions)
{
    // TODO
    (void)extensions;
}

void
serializer::
attach_end_of_body()
{
    // TODO
}

void
serializer::
attach_end_of_body(
    fields_view const& trailers)
{
    // TODO
    (void)trailers;
}

void
serializer::
flush()
{
    // TODO
    // VFALCO What do we flush here?
}

void
serializer::
consume(std::size_t bytes)
{
    if(! hs_.empty())
    {
        if(bytes < hs_.size())
        {
            hs_.remove_prefix(bytes);
            return;
        }
        bytes -= hs_.size();
        hs_ = {};
    }

    BOOST_ASSERT(bytes <= bs_.size());
    if(bytes < bs_.size())
    {
        bs_.remove_prefix(bytes);
        return;
    }
    bs_ = {};

    // is_complete_ = true; ?
}

const_buffers
serializer::
prepare(error_code& ec)
{
    // TODO
    (void)ec;
    return {};
}

const_buffers
serializer::
prepare(
    std::size_t bytes,
    error_code& ec)
{
    // TODO
    (void)bytes;
    (void)ec;
    return {};
}

string_view
serializer::
peek_output() const noexcept
{
    // TODO
    return {};
}
#endif

} // http_proto
} // boost

#endif

ext: ipp


text:
/**
 * @file ValueSymbolTable.hpp
 * @author Minmin Gong
 *
 * @section DESCRIPTION
 *
 * This source file is part of Dilithium
 * For the latest info, see https://github.com/gongminmin/Dilithium
 *
 * @section LICENSE
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Minmin Gong. All rights reserved.
 *
 * 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.
 */

#ifndef _DILITHIUM_VALUE_SYMBOL_TABLE_HPP
#define _DILITHIUM_VALUE_SYMBOL_TABLE_HPP

#pragma once

#include <Dilithium/CXX17/string_view.hpp>
#include <Dilithium/Value.hpp>

#include <unordered_map>

#include <boost/core/noncopyable.hpp>

namespace Dilithium
{
	class ValueSymbolTable
	{
		friend class Value;
		friend class BasicBlock;
		friend class Function;
		template <typename NodeType>
		friend void AddToSymbolTableList(NodeType*, typename NodeType::ParentType*);
		template <typename NodeType>
		friend void RemoveFromSymbolTableList(NodeType*);

	public:
		typedef std::unordered_map<uint64_t, Value*> ValueMap;
		typedef ValueMap::iterator iterator;
		typedef ValueMap::const_iterator const_iterator;

	public:
		ValueSymbolTable()
			: vmap_(0), last_unique_(0)
		{
		}
		~ValueSymbolTable();

		bool empty() const
		{
			return vmap_.empty();
		}
		size_t size() const
		{
			return vmap_.size();
		}

		iterator begin()
		{
			return vmap_.begin();
		}
		const_iterator begin() const
		{
			return vmap_.begin();
		}
		iterator end()
		{
			return vmap_.end();
		}
		const_iterator end() const
		{
			return vmap_.end();
		}

	private:
		void ReinsertValue(Value* val);
		std::string CreateValueName(std::string_view name, Value* val);
		void RemoveValueName(uint64_t name_hash);

	private:
		ValueMap vmap_;
		mutable uint32_t last_unique_;
	};
}

#endif		// _DILITHIUM_VALUE_SYMBOL_TABLE_HPP

ext: hpp

max_stars_repo_name: gongminmin/Dilithium

max_issues_repo_name: gongminmin/Dilithium

max_forks_repo_name: gongminmin/Dilithium


text:
//Copyright (c) 2013 Singapore-MIT Alliance for Research and Technology
//Licensed under the terms of the MIT License, as described in the file:
//   license.txt   (http://opensource.org/licenses/MIT)

#pragma once

/**
 * \file Log.hpp
 *
 * Contains a more flexible logging framework than util/OutputUtil.hpp and is intended to
 * eventually replace it.
 *
 * \note
 * The functionality here is still untested; once it's stable we will remove OutputUtil and
 * replace it with this.
 */

//This is a minimal header file, so please keep includes to a minimum.
#include "conf/settings/DisableOutput.h"

#include <iostream>
#include <fstream>
#include <string>
#include <map>

#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/format.hpp>

#include "util/LangHelpers.hpp"

namespace sim_mob {

/**
 * Used to record an event that should be logged. This generally includes simulation output
 * and other saved messages (including some profiling information).
 *
 * \author Seth N. Hetu
 *
 * The general usage pattern for this class is as follows. We use the subclass "Warn"
 *   as an example, since StaticLogManager() cannot be used directly.
 *
 *   \code
 *   //Do this once for each subclass of StaticLogManager, at the top of Main:
 *   if ( someConfigCheck() ) { //Should logging be enabled?
 *     Warn::Init("warnings.log")
 *   } else {
 *     Warn::Ignore()
 *   }
 *
 *   //Now use it:
 *   Warn() <<"Testing: " <<x <<"," <<y <<std::endl;
 *   Warn() <<"Using a newline instead of endl is fine too.\n";
 *   \endcode
 *
 * If Init() or Ignore() have not been called on a particular subclass, a default, non-synchronized stream
 * will be used (usually std::cout). If Ignore() has been called, then the system will silently ignore all
 * output, and no locking will take place. Some processing time is still wasted, so we recommend using the
 * macros (e.g., WarnLine("Test:" <<x <<"\n");) in areas where performance is crucial. Static functions
 * such as Warn::IsEnabled() can be used to check if logging on a particular subclass has been Ignored.
 *
 * Once Init() has been called with reasonable input (either a file name or "<stdout>" or "<stderr>" to
 * redirect to the standard streams), then the StaticLogManager subclasses function as follows. First, a mutex is
 * seized during construction of the temporary StaticLogManager object. Calls to operator<< are redirected to
 * the stream's operator of the same name. Finally, when the StaticLogManager temporary is destructed, the output
 * buffer is flushed and the mutex is released.
 *
 * It is functionally possible to create a StaticLogManager object that does not lock, but this is considered useless,
 * since the user would have to know that locking is not required to use that function, and mutexes which
 * are only seized by one entity incur almost no overhead. If overhead is a proble, it is likely that one
 * actually intended to disable output entirely anyway.
 *
 * StaticLogManagers which access the same stream are locked with the same mutex. As a result, it is not currently
 * possible to change the log location at runtime (calling Init() multiple times is risky, although it
 * is not explicitly wrong).
 *
 * \note
 * The StaticLogManager class provides only basic (static) functionality; you should use objects of its subclass
 * to accomplish your logging needs.
 */
class StaticLogManager : private boost::noncopyable {
protected:
    ///Used for reference; each stream has one associated mutex. The keys (ostream pointers) are not allocated;
    /// they are just pointers to existing statically-scoped objects (or cout/cerr).
    static std::map<const std::ostream*, boost::shared_ptr<boost::mutex> > stream_locks;

    ///Helper function for subclasses: registers an ostream with stream_locks, skipping if it's already been
    ///  registered. Returns the associated mutex regardless.
    static boost::shared_ptr<boost::mutex> RegisterStream(const std::ostream* str);

    ///Helper function for subclasses: If the associated filename is not "<stdout>" or "<stderr>", then
    ///  open the ofstream object passed by reference and return a pointer to it. Else, return
    ///  a pointer to std::cout or std::cerr. On error (if the file can't be created), silently
    ///  return a pointer to cout.
    static std::ostream* OpenStream(const std::string& path, std::ofstream& file);

public:
    //Type of cout.
    typedef std::basic_ostream<char, std::char_traits<char> > CoutType;

    //Type of std::endl and some other manipulators.
    typedef CoutType& (*StandardEndLine)(CoutType&);
};

/**
 * Logging functionality for Warnings. See the StaticLogManager class for general details about how logging works.
 * A "Warn" item includes non-fatal items that may threaten the validity of the simulation (but will not cause it to crash).
 *
 * To be used like so:
 *
 *   \code
 *   Warn() <<"There was a warning: " <<str <<std::endl;
 *   \endcode
 *
 * ...or, if performance is critical:
 *
 *   \code
 *   WarnOut("There was a warning: " <<str <<std::endl);
 *   \endcode
 *
 * Don't forget to call Warn::Init() or Warn::Ignore() at the beginning of main().
 */
class Warn : private StaticLogManager {
public:
    ///Construct a new Warn() object. It is best to use this object immediately, by chaining to calls of operator<<.
    Warn();

    ///Destroy a Warn() object. Logging is mutually exclusive on a given output stream until the Warn object
    /// has been destroyed.
    ~Warn();

    ///Log a given item; this simply forwards the call to operator<< of the given logger.
    ///NOTE: I am assuming that return-by-reference keeps the object alive until all chained
    ///      operator<<'s are done. Should check the standard on this. ~Seth
    template <typename T>
    Warn& operator<< (const T& val);

    ///Hack to get manipulators (std::endl) to work.
    ///NOTE: I have *no* idea if this is extremely stupid or not. ~Seth
    Warn& operator<<(StandardEndLine manip) {
        if (log_handle) {
            manip(*log_handle);
        }
        return *this;
    }

    ///Ininitialize this StaticLogManager subclass. If "path" is "<stdout>" or "<stderr>", then bind to
    ///std::cout or std::cerr. Else, attempt to open the file pointed to by "path".
    ///On failure, bind to std::cout.
    ///
    ///\note
    ///Multiple calls to Init() *might* work, and the system should default to cout
    /// if Init() has not been called. Either way, you should plan to call Init() once.
    static void Init(const std::string& path);

    ///Disable logging for this StaticLogManager subclass.
    static void Ignore();

    ///Is this StaticLogManager subclass enabled for writing? If not, calls to operator<< will be ignored.
    static bool IsEnabled();

private:
    ///A pointer to the mutex (managed in StaticLogManager::stream_locks) used for locking the output stream.
    static boost::shared_ptr<boost::mutex> log_mutex;

    ///Where to send logging events. May point to std::cout, std::cerr,
    /// or a file stream located in a subclass.
    static std::ostream* log_handle;

    ///The actual file used for logging. If stdout or stderr are used for logging, this
    /// file will be un-opened. After main() terminates, this file will be destroyed and
    /// closed automatically.
    static std::ofstream log_file;

    ///A scoped lock on the log_mutex. May be null, in which case output is not locked.
    boost::mutex::scoped_lock local_lock;
};

/**
 * Logging functionality for Printed output. See the StaticLogManager class for general details about how logging works.
 * A "Print" item includes console (cout) output, and is used to inform the user of the state of the simulation.
 * This should (almost always) point to cout.
 *
 * To be used like so:
 *
 *   \code
 *   Print() <<"Simulation is " <<x <<"% done.\n";
 *   \endcode
 *
 * ...or, if performance is critical:
 *
 *   \code
 *   PrintOut("Simulation is " <<x <<"% done.\n");
 *   \endcode
 *
 * Don't forget to call Print::Init() or Print::Ignore() at the beginning of main().
 */
class Print : private StaticLogManager {
public:
    ///Construct a new Print() object. It is best to use this object immediately, by chaining to calls of operator<<.
    Print();

    ///Destroy a Print() object. Logging is mutually exclusive on a given output stream until the Warn object
    /// has been destroyed.
    ~Print();

    ///Log a given item; this simply forwards the call to operator<< of the given logger.
    ///NOTE: I am assuming that return-by-reference keeps the object alive until all chained
    ///      operator<<'s are done. Should check the standard on this. ~Seth
    template <typename T>
    Print& operator<< (const T& val);

    ///Hack to get manipulators (std::endl) to work.
    ///NOTE: I have *no* idea if this is extremely stupid or not. ~Seth
    Print& operator<<(StandardEndLine manip) {
        if (log_handle) {
            manip(*log_handle);
        }
        return *this;
    }

    ///Ininitialize this StaticLogManager subclass. If "path" is "<stdout>" or "<stderr>", then bind to
    ///std::cout or std::cerr. Else, attempt to open the file pointed to by "path".
    ///On failure, bind to std::cout.
    ///
    ///\note
    ///Multiple calls to Init() *might* work, and the system should default to cout
    /// if Init() has not been called. Either way, you should plan to call Init() once.
    static void Init(const std::string& path);

    ///Disable logging for this StaticLogManager subclass.
    static void Ignore();

    ///Is this StaticLogManager subclass enabled for writing? If not, calls to operator<< will be ignored.
    static bool IsEnabled();

private:
    ///A pointer to the mutex (managed in StaticLogManager::stream_locks) used for locking the output stream.
    static boost::shared_ptr<boost::mutex> log_mutex;

    ///Where to send logging events. May point to std::cout, std::cerr,
    /// or a file stream located in a subclass.
    static std::ostream* log_handle;

    ///The actual file used for logging. If stdout or stderr are used for logging, this
    /// file will be un-opened. After main() terminates, this file will be destroyed and
    /// closed automatically.
    static std::ofstream log_file;

    ///A scoped lock on the log_mutex. May be null, in which case output is not locked.
    boost::mutex::scoped_lock local_lock;
};

class PassengerInfoPrint : private StaticLogManager {
public:
    ///Construct a new Warn() object. It is best to use this object immediately, by chaining to calls of operator<<.
    PassengerInfoPrint();

    ///Destroy a Warn() object. Logging is mutually exclusive on a given output stream until the Warn object
    /// has been destroyed.
    ~PassengerInfoPrint();

    ///Log a given item; this simply forwards the call to operator<< of the given logger.
    ///NOTE: I am assuming that return-by-reference keeps the object alive until all chained
    ///      operator<<'s are done. Should check the standard on this. ~Seth
    template <typename T>
    PassengerInfoPrint& operator<< (const T& val);

    ///Hack to get manipulators (std::endl) to work.
    ///NOTE: I have *no* idea if this is extremely stupid or not. ~Seth
    PassengerInfoPrint& operator<<(StandardEndLine manip) {
        if (log_handle) {
            manip(*log_handle);
        }
        return *this;
    }

    ///Ininitialize this StaticLogManager subclass. If "path" is "<stdout>" or "<stderr>", then bind to
    ///std::cout or std::cerr. Else, attempt to open the file pointed to by "path".
    ///On failure, bind to std::cout.
    ///
    ///\note
    ///Multiple calls to Init() *might* work, and the system should default to cout
    /// if Init() has not been called. Either way, you should plan to call Init() once.
    static void Init(const std::string& path);

    ///Disable logging for this StaticLogManager subclass.
    static void Ignore();

    ///Is this StaticLogManager subclass enabled for writing? If not, calls to operator<< will be ignored.
    static bool IsEnabled();

private:
    ///A pointer to the mutex (managed in StaticLogManager::stream_locks) used for locking the output stream.
    static boost::shared_ptr<boost::mutex> log_mutex;

    ///Where to send logging events. May point to std::cout, std::cerr,
    /// or a file stream located in a subclass.
    static std::ostream* log_handle;

    ///The actual file used for logging. If stdout or stderr are used for logging, this
    /// file will be un-opened. After main() terminates, this file will be destroyed and
    /// closed automatically.
    static std::ofstream log_file;

    ///A scoped lock on the log_mutex. May be null, in which case output is not locked.
    boost::mutex::scoped_lock local_lock;
};

class HeadwayAtBusStopInfoPrint : private StaticLogManager {
public:
    ///Construct a new Warn() object. It is best to use this object immediately, by chaining to calls of operator<<.
    HeadwayAtBusStopInfoPrint();

    ///Destroy a Warn() object. Logging is mutually exclusive on a given output stream until the Warn object
    /// has been destroyed.
    ~HeadwayAtBusStopInfoPrint();

    ///Log a given item; this simply forwards the call to operator<< of the given logger.
    ///NOTE: I am assuming that return-by-reference keeps the object alive until all chained
    ///      operator<<'s are done. Should check the standard on this. ~Seth
    template <typename T>
    HeadwayAtBusStopInfoPrint& operator<< (const T& val);

    ///Hack to get manipulators (std::endl) to work.
    ///NOTE: I have *no* idea if this is extremely stupid or not. ~Seth
    HeadwayAtBusStopInfoPrint& operator<<(StandardEndLine manip) {
        if (log_handle) {
            manip(*log_handle);
        }
        return *this;
    }

    ///Ininitialize this StaticLogManager subclass. If "path" is "<stdout>" or "<stderr>", then bind to
    ///std::cout or std::cerr. Else, attempt to open the file pointed to by "path".
    ///On failure, bind to std::cout.
    ///
    ///\note
    ///Multiple calls to Init() *might* work, and the system should default to cout
    /// if Init() has not been called. Either way, you should plan to call Init() once.
    static void Init(const std::string& path);

    ///Disable logging for this StaticLogManager subclass.
    static void Ignore();

    ///Is this StaticLogManager subclass enabled for writing? If not, calls to operator<< will be ignored.
    static bool IsEnabled();

private:
    ///A pointer to the mutex (managed in StaticLogManager::stream_locks) used for locking the output stream.
    static boost::shared_ptr<boost::mutex> log_mutex;

    ///Where to send logging events. May point to std::cout, std::cerr,
    /// or a file stream located in a subclass.
    static std::ostream* log_handle;

    ///The actual file used for logging. If stdout or stderr are used for logging, this
    /// file will be un-opened. After main() terminates, this file will be destroyed and
    /// closed automatically.
    static std::ofstream log_file;

    ///A scoped lock on the log_mutex. May be null, in which case output is not locked.
    boost::mutex::scoped_lock local_lock;
};

} //End sim_mob namespace

//////////////////////////////////////////////////////////////
// Macros for each StaticLogManager subclass.
//////////////////////////////////////////////////////////////

#ifdef SIMMOB_DISABLE_OUTPUT

//Simply destroy this text; no logging; no locking
#define WarnOut( strm )  DO_NOTHING
#define PrintOut( strm )  DO_NOTHING

//TODO: Describe in detail later.
#define LogOut( strm )  DO_NOTHING

#else

/**
 * Exactly the same as LogOut(), but for Warnings.
 * TODO: Describe better.
 */
#define WarnOut( strm ) \
    do \
    { \
        sim_mob::Warn() << strm; \
    } \
    while (0)

/**
 * Exactly the same as LogOut(), but for Print statements.
 */

//This PrintOut will append the date, time,filename and line number in front of the log message.
#define PrintOutV( strm ) \
    do \
    { \
      time_t current_time = time(NULL);\
      std::string timeString = std::string(ctime(&current_time));\
      sim_mob::Print() << "[" << timeString.substr(0, timeString.size()-1) << "][" << std::string(__FILE__).substr(std::string(__FILE__).find_last_of("//") + 1, std::string(__FILE__).length()) << ":" << __LINE__ << "] " << strm;\
    } \
    while (0)

//This printOut will append the filename and line number in front of the log message
#define PrintOutF( strm ) \
    do \
    { \
        sim_mob::Print() << "[" << std::string(__FILE__).substr(std::string(__FILE__).find_last_of("//") + 1, std::string(__FILE__).length()) << ":" << __LINE__ << "] " << strm; \
    } \
    while (0)

#define PrintOut( strm ) \
    do \
    { \
        sim_mob::Print() << strm; \
    } \
    while (0)

/**
 * Write a message (statement_list) using "Log() <<statement_list"; Compiles to nothing if output is disabled.
 *
 * Usage:
 *   \code
 *   //This:
 *   LogOut("The total cost of " << count << " apples is " << count * unit_price);
 *
 *   //Is equivalent to this:
 *   Log() <<"The total cost of " << count << " apples is " << count * unit_price;
 *   \endcode
 *
 * \note
 * If SIMMOB_DISABLE_OUTPUT is defined, this macro will discard its arguments. Thus, it is safe to
 * call this function without #ifdef guards and let cmake handle whether or not to display output.
 * In some cases, it is still wise to check SIMMOB_DISABLE_OUTPUT; for example, if you are building up
 * an output std::stringstream. However, in this case you should call Log::IsEnabled().
 */
#define LogOut( strm ) \
    do \
    { \
        Log() << strm; \
    } \
    while (0)

#endif //SIMMOB_DISABLE_OUTPUT

//////////////////////////////////////////////////////////////
// Template function implementation.
//////////////////////////////////////////////////////////////

template <typename T>
sim_mob::Warn& sim_mob::Warn::operator<< (const T& val)
{
    if (log_handle) {
        (*log_handle) <<val;
    }
    return *this;
}

template <typename T>
sim_mob::Print& sim_mob::Print::operator<< (const T& val)
{
    if (log_handle) {
        (*log_handle) <<val;
    }
    return *this;
}

template <typename T>
sim_mob::PassengerInfoPrint& sim_mob::PassengerInfoPrint::operator<< (const T& val)
{
    if (log_handle) {
        (*log_handle) <<val;
    }
    return *this;
}

template <typename T>
sim_mob::HeadwayAtBusStopInfoPrint& sim_mob::HeadwayAtBusStopInfoPrint::operator<< (const T& val)
{
    if (log_handle) {
        (*log_handle) <<val;
    }
    return *this;
}


text:
#include <boost/python.hpp>
#include <boost/cstdint.hpp>

#include <Magick++/Include.h>

using namespace boost::python;

void __StyleType()
{
    enum_< Magick::StyleType >("StyleType")
        .value("NormalStyle", Magick::NormalStyle)
        .value("ItalicStyle", Magick::ItalicStyle)
        .value("ObliqueStyle", Magick::ObliqueStyle)
        .value("AnyStyle", Magick::AnyStyle)
    ;
}

max_stars_repo_name: veryhappythings/pgmagick

max_issues_repo_name: veryhappythings/pgmagick

max_forks_repo_name: veryhappythings/pgmagick


text:
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/local_function

#include <boost/local_function.hpp>
#include <boost/function.hpp>
#include <boost/detail/lightweight_test.hpp>

void intermediate(boost::function<void (int, int)> store_func, int size) {
    store_func(size - 1, -1);
}

void hack(int* array, int size) {
    void BOOST_LOCAL_FUNCTION(bind array, int index, int value) {
        array[index] = value;
    } BOOST_LOCAL_FUNCTION_NAME(store)

    intermediate(store, size);
}

int main(void) {
    int nums[] = {1, 2, 3};
    hack(nums, 3);

    BOOST_TEST(nums[0] == 1);
    BOOST_TEST(nums[1] == 2);
    BOOST_TEST(nums[2] == -1);
    return boost::report_errors();
}


text:
#include <boost/test/unit_test.hpp>

#include "pigpiodpp/piavailable.hpp"

BOOST_AUTO_TEST_SUITE( PiAvailable )

BOOST_AUTO_TEST_CASE( Smoke )
{
#ifdef PIGPIODPP_HAVE_PIGPIO
  BOOST_CHECK_EQUAL( PiGPIOdpp::piAvailable, true );
#else
  BOOST_CHECK_EQUAL( PiGPIOdpp::piAvailable, false );
#endif
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: freesurfer-rge/linesidecabinet

max_issues_repo_name: freesurfer-rge/linesidecabinet

max_forks_repo_name: freesurfer-rge/linesidecabinet