text:
/*
 * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3, as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "anbox/platform/sdl/window.h"
#include "anbox/wm/window_state.h"
#include "anbox/graphics/density.h"
#include "anbox/logger.h"

#include <boost/throw_exception.hpp>

#if defined(MIR_SUPPORT)
#include <mir_toolkit/mir_client_library.h>
#endif

namespace {
constexpr const int window_resize_border{10};
constexpr const int top_drag_area{42};
constexpr const int button_size{32};
constexpr const int button_margin{5};
constexpr const int button_padding{0};
}

namespace anbox {
namespace platform {
namespace sdl {
Window::Id Window::Invalid{-1};

Window::Observer::~Observer() {}

Window::Window(const std::shared_ptr<Renderer> &renderer,
               const Id &id, const wm::Task::Id &task,
               const std::shared_ptr<Observer> &observer,
               const graphics::Rect &frame,
               const std::string &title,
               bool resizable,
               bool borderless)
    : wm::Window(renderer, task, frame, title),
      id_(id),
      observer_(observer),
      native_display_(0),
      native_window_(0) {
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);

  // NOTE: We don't furce GL initialization of the window as this will
  // be take care of by the Renderer when we attach to it. On EGL
  // initializing GL here will cause a surface to be created and the
  // renderer will attempt to create one too which will not work as
  // only a single surface per EGLNativeWindowType is supported.
  std::uint32_t flags = 0;
  if (borderless)
    flags |= SDL_WINDOW_BORDERLESS;
  if (resizable)
    flags |= SDL_WINDOW_RESIZABLE;

  window_ = SDL_CreateWindow(title.c_str(),
                             frame.left(), frame.top(),
                             frame.width(), frame.height(),
                             flags);
  if (!window_) {
    const auto message = utils::string_format("Failed to create window: %s", SDL_GetError());
    BOOST_THROW_EXCEPTION(std::runtime_error(message));
  }

  // If we create a window with border (server-side decoration), We
  // should not set hit test handler beacuse we don't need to simulate
  // the behavior of the title bar and resize area.
  if (borderless && utils::get_env_value("ANBOX_NO_SDL_WINDOW_HIT_TEST", "false") == "false")
    if (SDL_SetWindowHitTest(window_, &Window::on_window_hit, this) < 0)
      BOOST_THROW_EXCEPTION(std::runtime_error("Failed to register for window hit test"));

  SDL_SysWMinfo info;
  SDL_VERSION(&info.version);
  SDL_GetWindowWMInfo(window_, &info);
  switch (info.subsystem) {
#if defined(X11_SUPPORT)
    case SDL_SYSWM_X11:
      native_display_ = static_cast<EGLNativeDisplayType>(info.info.x11.display);
      native_window_ = static_cast<EGLNativeWindowType>(info.info.x11.window);
      break;
#endif
#if defined(WAYLAND_SUPPORT)
    case SDL_SYSWM_WAYLAND:
      native_display_ = reinterpret_cast<EGLNativeDisplayType>(info.info.wl.display);
      native_window_ = reinterpret_cast<EGLNativeWindowType>(info.info.wl.surface);
      break;
#endif
#if defined(MIR_SUPPORT)
    case SDL_SYSWM_MIR: {
      native_display_ = static_cast<EGLNativeDisplayType>(mir_connection_get_egl_native_display(info.info.mir.connection));
      auto buffer_stream = mir_surface_get_buffer_stream(info.info.mir.surface);
      native_window_ = reinterpret_cast<EGLNativeWindowType>(mir_buffer_stream_get_egl_native_window(buffer_stream));
      break;
    }
#endif
    default:
      ERROR("Unknown subsystem (%d)", info.subsystem);
      BOOST_THROW_EXCEPTION(std::runtime_error("SDL subsystem not supported"));
  }

  SDL_ShowWindow(window_);
}

Window::~Window() {
  if (window_) SDL_DestroyWindow(window_);
}

SDL_HitTestResult Window::on_window_hit(SDL_Window *window, const SDL_Point *pt, void *data) {
  auto platform_window = reinterpret_cast<Window*>(data);

  int w = 0, h = 0;
  SDL_GetWindowSize(window, &w, &h);

  const auto border_size = graphics::dp_to_pixel(window_resize_border);
  const auto top_drag_area_height = graphics::dp_to_pixel(top_drag_area);
  const auto button_area_width = graphics::dp_to_pixel(button_size + button_padding * 2 + button_margin * 2);
  const auto flags = SDL_GetWindowFlags(window);

  if (flags & SDL_WINDOW_FULLSCREEN)
      return SDL_HITTEST_NORMAL;

  if (!(flags & SDL_WINDOW_RESIZABLE)) {
    if (pt->y < border_size)
      return SDL_HITTEST_DRAGGABLE;
    else
      return SDL_HITTEST_NORMAL;
  }

  if (pt->y < top_drag_area_height) {
    if (pt->x > w - button_area_width && pt->x < w) {
      platform_window->close();
      return SDL_HITTEST_NORMAL;
    } else if (pt->x > w - button_area_width * 2 && pt->x < w - button_area_width) {
      platform_window->switch_window_state();
      return SDL_HITTEST_NORMAL;
    }
    return SDL_HITTEST_DRAGGABLE;
  }

  if (flags & SDL_WINDOW_MAXIMIZED)
    return SDL_HITTEST_NORMAL;

  if (pt->x < border_size && pt->y < border_size)
      return SDL_HITTEST_RESIZE_TOPLEFT;
  else if (pt->x > border_size && pt->x < w - border_size && pt->y < border_size)
      return SDL_HITTEST_RESIZE_TOP;
  else if (pt->x > w - border_size && pt->y < border_size)
      return SDL_HITTEST_RESIZE_TOPRIGHT;
  else if (pt->x > w - border_size && pt->y > border_size && pt->y < h - border_size)
      return SDL_HITTEST_RESIZE_RIGHT;
  else if (pt->x > w - border_size && pt->y > h - border_size)
      return SDL_HITTEST_RESIZE_BOTTOMRIGHT;
  else if (pt->x < w - border_size && pt->x > border_size && pt->y > h - border_size)
      return SDL_HITTEST_RESIZE_BOTTOM;
  else if (pt->x < border_size && pt->y > h - border_size)
      return SDL_HITTEST_RESIZE_BOTTOMLEFT;
  else if (pt->x < border_size && pt->y < h - border_size && pt->y > border_size)
      return SDL_HITTEST_RESIZE_LEFT;

  return SDL_HITTEST_NORMAL;
}

void Window::close() {
  if (observer_)
    observer_->window_deleted(id_);
}

void Window::switch_window_state() {
  const auto flags = SDL_GetWindowFlags(window_);
  if (flags & SDL_WINDOW_MAXIMIZED)
    SDL_RestoreWindow(window_);
  else
    SDL_MaximizeWindow(window_);
}

void Window::process_event(const SDL_Event &event) {
  switch (event.window.event) {
    case SDL_WINDOWEVENT_FOCUS_GAINED:
      if (observer_) observer_->window_wants_focus(id_);
      break;
    case SDL_WINDOWEVENT_FOCUS_LOST:
      break;
    // Not need to listen for SDL_WINDOWEVENT_RESIZED here as the
    // SDL_WINDOWEVENT_SIZE_CHANGED is always sent.
    case SDL_WINDOWEVENT_SIZE_CHANGED:
      if (observer_)
        observer_->window_resized(id_, event.window.data1, event.window.data2);
      break;
    case SDL_WINDOWEVENT_MOVED:
      if (observer_)
        observer_->window_moved(id_, event.window.data1, event.window.data2);
      break;
    case SDL_WINDOWEVENT_SHOWN:
      break;
    case SDL_WINDOWEVENT_HIDDEN:
      break;
    case SDL_WINDOWEVENT_CLOSE:
      close();
      break;
    default:
      break;
  }
}

EGLNativeWindowType Window::native_handle() const { return native_window_; }

Window::Id Window::id() const { return id_; }

std::uint32_t Window::window_id() const { return SDL_GetWindowID(window_); }
} // namespace sdl
} // namespace platform
} // namespace anbox

max_stars_repo_name: akraino-edge-stack/iec

max_issues_repo_name: akraino-edge-stack/iec

max_forks_repo_name: akraino-edge-stack/iec


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_BITWISE_XOR_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_BITWISE_XOR_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

 /*!

    @ingroup group-bitwise
    Function object implementing bitwise_xor capabilities

    return the bitwise xor of the two parameters

    The operands must share the same bit size.

    The result type is the one of the first operand.

    Infix notation can be used with operator '^',
    but this will not work in scalar mode if any
    operand is floating point because of C++ limitations.

    @par Semantic:

    For every parameters @c x of type @c T0 @c y of type @c T1:

    @code
    T0 r = bitwise_xor(x,y);
    @endcode

    is similar to:

    @code
    T0 r = x^y;
    @endcode

    @see  bitwise_or, bitwise_and, bitwise_notand,
    bitwise_andnot, bitwise_notor, bitwise_ornot, complement

  **/
  T0 bitwise_xor(T0 const &x, T1 const& y);
} }
#endif

#include <boost/simd/function/scalar/bitwise_xor.hpp>
#include <boost/simd/function/simd/bitwise_xor.hpp>

#endif

ext: hpp

max_stars_repo_name: xmar/pythran

max_issues_repo_name: xmar/pythran

max_forks_repo_name: xmar/pythran


text:
// ====================================================================
// This file is part of FlexibleSUSY.
//
// FlexibleSUSY is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// FlexibleSUSY 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FlexibleSUSY.  If not, see
// <http://www.gnu.org/licenses/>.
// ====================================================================

#include "build_info.hpp"
#include "config.h"

#include <boost/version.hpp>
#include <Eigen/Core>
#include <gsl/gsl_version.h>

#include <iostream>

namespace flexiblesusy {

void print_all_info(std::ostream& ostr)
{
   ostr <<
      "Version information\n"
      "===================\n\n";
   print_version_info(ostr);

   ostr <<
      "\n"
      "System information\n"
      "==================\n\n";
   print_system_info(ostr);

   ostr <<
      "\n"
      "Build information\n"
      "=================\n\n";
   print_build_info(ostr);
}

void print_flexiblesusy_version(std::ostream& ostr)
{
   ostr << FLEXIBLESUSY_VERSION;
}

void print_version_info(std::ostream& ostr)
{
   const int boost_major = BOOST_VERSION / 100000;
   const int boost_minor = (BOOST_VERSION / 100) % 1000;
   const int boost_patch = BOOST_VERSION % 100;

   ostr <<
      "FlexibleSUSY version:                   " FLEXIBLESUSY_VERSION "\n"
      "FlexibleSUSY git commit:                " GIT_COMMIT "\n"
      "SARAH version:                          " SARAH_VERSION "\n"
      "Mathematica version:                    " << MATHEMATICA_VERSION << "\n"
      "Boost version:                          "
        << boost_major << '.' << boost_minor << '.' << boost_patch << "\n"
      "Eigen version:                          " << EIGEN_WORLD_VERSION
        << '.' << EIGEN_MAJOR_VERSION << '.' << EIGEN_MINOR_VERSION << "\n"
      "GSL version:                            " << GSL_VERSION "\n"
      "GM2Calc version:                        " << GM2CALC_VERSION "\n"
      "Himalaya version:                       " << HIMALAYA_VERSION "\n"
      ;
}

void print_build_info(std::ostream& ostr)
{
   ostr <<
      "C++ compiler (CXX):                     " CXX "\n"
      "C++ compiler flags (CXXFLAGS):          " CXXFLAGS "\n"
      "C preprocessor flags (CPPFLAGS):        " CPPFLAGS "\n"
      "Fortran compiler (FC):                  " FC "\n"
      "Fortran compiler flags (FFLAGS):        " FFLAGS "\n"
      "Fortran libraries (FLIBS):              " FLIBS "\n"
      "BLAS library (BLASLIBS):                " BLASLIBS "\n"
      "Boost flags (BOOSTFLAGS):               " BOOSTFLAGS "\n"
      "Boost libraries:                        " BOOSTTESTLIBS " " BOOSTTHREADLIBS "\n"
      "Eigen flags (EIGENFLAGS):               " EIGENFLAGS "\n"
      "Himalaya flags (HIMALAYAFLAGS):         " HIMALAYAFLAGS "\n"
      "Himalaya libraries (HIMALAYALIBS):      " HIMALAYALIBS "\n"
      "GSL flags (GSLFLAGS):                   " GSLFLAGS "\n"
      "GSL libraries (GSLLIBS):                " GSLLIBS "\n"
      "LAPACK library (LAPACKLIBS):            " LAPACKLIBS "\n"
      "Loop function flags (LOOPFUNCFLAGS):    " LOOPFUNCFLAGS "\n"
      "Loop function libraries (LOOPFUNCLIBS): " LOOPFUNCLIBS "\n"
      "Additional flags (LDFLAGS):             " LDFLAGS "\n"
      "Additional libraries (LDLIBS):          " LDLIBS "\n"
      "SQLite3 flags (SQLITEFLAGS):            " SQLITEFLAGS "\n"
      "SQLite3 libraries (SQLITELIBS):         " SQLITELIBS "\n"
      "TSIL flags (TSILFLAGS):                 " TSILFLAGS "\n"
      "TSIL libraries (TSILLIBS):              " TSILLIBS "\n"
      "Thread libraries (THREADLIBS):          " THREADLIBS "\n"
      "\n"
      "Two-scale solver:                       "
#ifdef ENABLE_TWO_SCALE_SOLVER
      "enabled"
#else
      "disabled"
#endif
      "\n"
      "Semi-analytic solver:                   "
#ifdef ENABLE_SEMI_ANALYTIC_SOLVER
      "enabled"
#else
      "disabled"
#endif
      "\n"
      "Colored output:                         "
#ifdef ENABLE_COLORS
      "yes"
#else
      "no"
#endif
      "\n"
      "Debug output:                           "
#ifdef ENABLE_DEBUG
      "yes"
#else
      "no"
#endif
      "\n"
      "Silent output:                          "
#ifdef ENABLE_SILENT
      "yes"
#else
      "no"
#endif
      "\n"
      "Verbose output:                         "
#ifdef ENABLE_VERBOSE
      "yes"
#else
      "no"
#endif
      "\n"
      "Use Boost.Numeric.Odeint:               "
#ifdef ENABLE_ODEINT
      "yes"
#else
      "no"
#endif
      "\n"
      "Use FFlite:                             "
#ifdef ENABLE_FFLITE
      "yes"
#else
      "no"
#endif
      "\n"
      "Use GM2Calc:                            "
#ifdef ENABLE_GM2Calc
      "yes"
#else
      "no"
#endif
      "\n"
      "Use Himalaya:                           "
#ifdef ENABLE_HIMALAYA
      "yes"
#else
      "no"
#endif
      "\n"
      "Use LAPACK:                             "
#ifdef ENABLE_LAPACK
      "yes"
#else
      "no"
#endif
      "\n"
      "Use LibraryLink:                        "
#ifdef ENABLE_LIBRARYLINK
      "yes"
#else
      "no"
#endif
      "\n"
      "Use LoopTools:                          "
#ifdef ENABLE_LOOPTOOLS
      "yes"
#else
      "no"
#endif
      "\n"
      "Use MKL ILP64 workaround:               "
#ifdef ENABLE_ILP64MKL_WORKAROUND
      "yes"
#else
      "no"
#endif
      "\n"
      "Use multi-threading:                    "
#ifdef ENABLE_THREADS
      "yes"
#else
      "no"
#endif
      "\n"
      "Use <random> header:                    "
#ifdef ENABLE_RANDOM
      "yes"
#else
      "no"
#endif
      "\n"
      "Use SQLite3:                            "
#ifdef ENABLE_SQLITE
      "yes"
#else
      "no"
#endif
      "\n"
      "Use TSIL:                               "
#ifdef ENABLE_TSIL
      "yes"
#else
      "no"
#endif
      "\n"
      "Mass eigenvalue error check:            "
#ifdef CHECK_EIGENVALUE_ERROR
      "yes"
#else
      "no"
#endif
      "\n"
      ;
}

void print_system_info(std::ostream& ostr)
{
   ostr <<
      "Operating system (uname -s):            " OPERATING_SYSTEM "\n"
      "Kernel version (uname -r):              " KERNEL_VERSION "\n"
      ;
}

} // namespace flexiblesusy

ext: cpp


text:
#include "orwell/game/Robot.hpp"

#include <iostream>
#include <exception>
#include <system_error>
#include <fstream>
#include <signal.h>

#include <boost/lexical_cast.hpp>

#include <zmq.hpp>

#include "orwell/game/Team.hpp"
#include "orwell/game/Player.hpp"
#include "orwell/com/ConnectionMode.hpp"
#include "orwell/support/GlobalLogger.hpp"
#include "orwell/support/ISystemProxy.hpp"

namespace orwell
{
namespace game
{

std::shared_ptr< Robot> Robot::MakeRobot(
		support::ISystemProxy const & iSystemProxy,
		std::string const & iName,
		std::string const & iRobotId,
		Team & ioTeam,
		uint16_t const & iVideoRetransmissionPort,
		uint16_t const & iServerCommandPort)
{
	std::shared_ptr< Robot > aRobot = std::make_shared< Robot >(
			iSystemProxy,
			iName,
			iRobotId,
			ioTeam,
			iVideoRetransmissionPort,
			iServerCommandPort);
	ioTeam.addRobot(aRobot);
	return aRobot;
}

Robot::Robot(
		support::ISystemProxy const & iSystemProxy,
		std::string const & iName,
		std::string const & iRobotId,
		Team & ioTeam,
		uint16_t const & iVideoRetransmissionPort,
		uint16_t const & iServerCommandPort)
	: m_systemProxy(iSystemProxy)
	, m_name(iName)
	, m_robotId(iRobotId)
	, m_team(ioTeam)
	, m_videoRetransmissionPort(iVideoRetransmissionPort)
	, m_serverCommandPort(iServerCommandPort)
	, m_hasRealRobot(false)
	, m_zmqContext(1) // maybe this will have to be increased for each robot ?
{
}

Robot::~Robot()
{
}

Team & Robot::getTeam()
{
	return m_team;
}

Team const & Robot::getTeam() const
{
	return m_team;
}

void Robot::setHasRealRobot(bool const iHasRealRobot)
{
	m_hasRealRobot = iHasRealRobot;
}

bool Robot::getHasRealRobot() const
{
	return m_hasRealRobot;
}

void Robot::setPlayer(std::shared_ptr< Player > const iPlayer)
{
	m_player = iPlayer;
}

std::shared_ptr< Player > Robot::getPlayer() const
{
	return m_player.lock();
}

bool Robot::getHasPlayer() const
{
	return not m_player.expired();
}

void Robot::setVideoUrl(std::string const & iVideoUrl)
{
	m_videoUrl = iVideoUrl;
}

std::string const & Robot::getVideoUrl() const
{
	return m_videoUrl;
}

std::string const & Robot::getName() const
{
	return m_name;
}

uint16_t Robot::getVideoRetransmissionPort() const
{
	return m_videoRetransmissionPort;
}

uint16_t Robot::getServerCommandPort() const
{
	return m_serverCommandPort;
}

std::string const & Robot::getRobotId() const
{
	return m_robotId;
}

bool Robot::getIsAvailable() const
{
	return ((m_hasRealRobot) and (not getHasPlayer()));
}

void Robot::fire()
{
}

void Robot::stop()
{
}

void Robot::readImage()
{
}

void Robot::startVideo()
{
	if (m_videoUrl.empty())
	{
		ORWELL_LOG_WARN("Robot " << m_name << " has wrong connection parameters : url='" << m_videoUrl << "'");
		return;
	}
	if (m_videoUrl.find("nc:") == 0)
	{
		ORWELL_LOG_INFO("No need to start the video from the game server with nc.");
	}
	else
	{
		ORWELL_LOG_INFO("Do not know what to do for anything else than url starting with nc:");
	}
}

std::string Robot::getAsString() const
{
	std::string aReply = "Robot ";
	aReply += "name = " + m_name + " ; ";
	if (not m_hasRealRobot)
	{
		aReply += "not ";
	}
	aReply += "registered ; ";
	aReply += "video_url = " + m_videoUrl + " ; ";
	auto const & aPlayer = getPlayer();
	bool aHasPlayer(aPlayer);
	aReply += "player = ";
	if (aHasPlayer)
	{
		aReply += aPlayer->getName();
	}
	return aReply;
}

//void fillRobotStateMessage( messages::RobotState & oMessage )
//{
//	//todo
//	//those are just bullshit hardcoded values to have the syntax
//	oMessage.set_life(1);
//	oMessage.mutable_move()->set_left(0);
//	oMessage.mutable_move()->set_right(0);
//	oMessage.set_active(true);
//}

}
}

max_stars_repo_name: orwell-int/server-game

max_issues_repo_name: orwell-int/server-game

max_forks_repo_name: orwell-int/server-game


text: #include <boost/mpl/aux_/preprocessed/gcc/inherit.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text: #include <boost/wave/grammars/cpp_expression_value.hpp>


text:
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/db/generic_index.hpp>
#include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain {

class temporary_active_object : public graphene::db::abstract_object<temporary_active_object>
   {
      public:
        static const uint8_t space_id = extension_id_for_nico;
        static const uint8_t type_id  = temporary_authority;
        account_id_type owner;
        flat_map<public_key_type,weight_type> temporary_active;
        string describe;
        time_point_sec expiration_time;
        temporary_active_object_id_tyep get_id(){return id;}
    };
/*********************************************合约索引表***********************************************/
struct by_account_id_type{};
struct by_account_and_describe{};
struct by_id;
struct by_expiration;
   typedef multi_index_container<
      temporary_active_object,
      indexed_by<
         ordered_unique<
                        tag<by_id>,
                        member< object, object_id_type, &object::id >
                        >,
         ordered_unique<
                        tag<by_account_id_type>,
                        member<temporary_active_object, account_id_type, &temporary_active_object::owner >
                        >,
        ordered_unique
            <
                tag<by_account_and_describe>,
                composite_key
                <
                        temporary_active_object ,
                        member<temporary_active_object , account_id_type, &temporary_active_object::owner>,
                        member<temporary_active_object , std::string, &temporary_active_object::describe>
                >
            >,
         ordered_non_unique<
                tag<by_expiration>,
                member<temporary_active_object, time_point_sec, &temporary_active_object::expiration_time  >
            >
      >
   > temporary_active_multi_index_type;

   /**
    * @ingroup object_index
    */
   typedef generic_index<temporary_active_object, temporary_active_multi_index_type> temporary_active_index;

} }

FC_REFLECT_DERIVED(graphene::chain::temporary_active_object,
                    (graphene::db::object),
                    (owner)(temporary_active)(describe)(expiration_time)
                    )

max_issues_repo_name: CocosBlockchainExpedition/cocos-mainnet

max_forks_repo_name: CocosBlockchainExpedition/cocos-mainnet


text:
/*!
@file
Defines an equivalent to `std::is_integral`.

@copyright Louis Dionne 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
 */

#ifndef BOOST_HANA_DETAIL_STD_IS_INTEGRAL_HPP
#define BOOST_HANA_DETAIL_STD_IS_INTEGRAL_HPP

#include <boost/hana/detail/std/integral_constant.hpp>

namespace boost { namespace hana { namespace detail { namespace std {
    template <typename T> struct is_integral : false_type { };
    template <typename T> struct is_integral<T const> : is_integral<T> { };
    template <typename T> struct is_integral<T volatile> : is_integral<T> { };
    template <typename T> struct is_integral<T const volatile> : is_integral<T> { };
    template <> struct is_integral<bool>               : true_type { };
    template <> struct is_integral<char>               : true_type { };
    template <> struct is_integral<signed char>        : true_type { };
    template <> struct is_integral<unsigned char>      : true_type { };
    template <> struct is_integral<wchar_t>            : true_type { };
    template <> struct is_integral<char16_t>           : true_type { };
    template <> struct is_integral<char32_t>           : true_type { };
    template <> struct is_integral<short>              : true_type { };
    template <> struct is_integral<unsigned short>     : true_type { };
    template <> struct is_integral<int>                : true_type { };
    template <> struct is_integral<unsigned int>       : true_type { };
    template <> struct is_integral<long>               : true_type { };
    template <> struct is_integral<unsigned long>      : true_type { };
    template <> struct is_integral<long long>          : true_type { };
    template <> struct is_integral<unsigned long long> : true_type { };

    template <typename T>
    struct is_non_boolean_integral : is_integral<T> { };
    template <>
    struct is_non_boolean_integral<bool> : false_type { };
}}}} // end namespace boost::hana::detail::std

#endif // !BOOST_HANA_DETAIL_STD_IS_INTEGRAL_HPP

max_stars_repo_name: josephwinston/hana

max_issues_repo_name: josephwinston/hana

max_forks_repo_name: josephwinston/hana


text:
//EuropeanOption.hpp
//
//Modification date: 6/17/15

#ifndef EuropeanOption_hpp
#define EuropeanOption_hpp

#include "Option.hpp"
#include "GlobalFunctions.hpp"
#include <boost/math/distributions/normal.hpp>
#include <vector>

class EuropeanOption : public Option
{
protected:
	double T;			//time till maturity

public:
	//Constructors
	EuropeanOption() : Option(), T(0.25)	{	}
	EuropeanOption(double new_S, double new_K, double new_T, double new_r, double new_sig) : Option(new_S,new_K,new_r,new_sig), T(new_T)	{	}		//default b=r Black and Scholes stock option model (1973)
	EuropeanOption(double new_S, double new_K, double new_T, double new_r, double new_sig, double new_b) : Option(new_S, new_K, new_r, new_sig, new_b), T(new_T)	{	}
	EuropeanOption(const EuropeanOption& source) : Option(source), T(source.T)	{	}

	//Destructor
	virtual ~EuropeanOption() {}

	//Operator overloads
	EuropeanOption& operator = (const EuropeanOption& source);

	//Getters
	double get_T() { return T; }

	virtual void Print()const = 0;

	//Setters
	void set_T(double new_T) { T = new_T; }

	//Pricers (pure virtual functions)
	virtual double Price()const = 0;
	virtual double PricePCP(double PC)const = 0;
	virtual double Price_S(double S1) = 0;
	virtual double Price_K(double K1) = 0;
	virtual double Price_T(double T1) = 0;
	virtual double Price_r(double r1) = 0;
	virtual double Price_sig(double sig1) = 0;
	virtual double Price_b(double b1) = 0;

	//Checkers
	bool PutCallParity(double C, double P)const;

	//Greeks
	virtual double Delta() const = 0;
	double Gamma() { return GammaGF(S, K, T, r, sig, b); }		//Gamma is the same for put and call options
	double Gamma(double h) { return GammaGF(S, h, K, T, r, sig, b); }
	double Vega() { return VegaGF(S, K, T, r, sig, b); }		//Vega is the same for put and call options, no need to define it in derived classes
	virtual double Theta() const = 0;
	virtual double Rho() const = 0;

};

class EuropeanCallOption : public EuropeanOption
{
public:
	//Constructors
	EuropeanCallOption() : EuropeanOption() {}
	EuropeanCallOption(double new_S, double new_K, double new_T, double new_r, double new_sig) : EuropeanOption(new_S, new_K, new_T, new_r, new_sig) {}
	EuropeanCallOption(double new_S, double new_K, double new_T, double new_r, double new_sig, double new_b) : EuropeanOption(new_S, new_K, new_T, new_r, new_sig, new_b) {}
	EuropeanCallOption(const EuropeanOption& source) : EuropeanOption(source) {}

	//Destructor
	virtual ~EuropeanCallOption() {}

	EuropeanOption& operator = (const EuropeanOption& source);

	void Print()const;

	//Pricers
	double Price()const	{	return CallPrice(S, K, T, r, sig, b);	}
	double Price_S(double S1)	{ return CallPrice(S1, K, T, r, sig, b); }
	double Price_K(double K1)	{ return CallPrice(S, K1, T, r, sig, b); }
	double Price_T(double T1)	{ return CallPrice(S, K, T1, r, sig, b); }
	double Price_r(double r1)	{ return CallPrice(S, K, T, r1, sig, b); }
	double Price_sig(double sig1)	{ return CallPrice(S, K, T, r, sig1, b); }
	double Price_b(double b1)	{ return CallPrice(S, K, T, r, sig, b1); }
	double PricePCP(double P)const	{ return CallPricePCP(P, S, K, T, r, b); }

	//Pricing function that returns vector. Used in combination with function pointer for better versatility
	typedef double(EuropeanCallOption::*FunctionPointer)(double);
	std::vector<double> Price(double LowerLimit, double UpperLimit, int Num, FunctionPointer Ptr );

	//Greeks
	double Delta()const { return CallDelta( S, K, T, r, sig, b); }
	double Delta_S(double S1) { return CallDelta(S1, K, T, r, sig, b); }		//function to override spot price
	double Theta() const { return CallTheta(S, K, T, r, sig, b); }
	double Rho() const { return CallRho(S, K, T, r, sig, b); }
	double Delta(double h)const { return CallDelta(S, h, K, T, r, sig, b); }
	//double Gamma() { return GammaGF(S, K, T, r, sig, b); }
	//double Gamma(double h) { return GammaGF(S, h, K, T, r, sig, b); }

};

class EuropeanPutOption : public EuropeanOption
{
public:
	//Constructors
	EuropeanPutOption() : EuropeanOption() {}
	EuropeanPutOption(double new_S, double new_K, double new_T, double new_r, double new_sig) : EuropeanOption(new_S, new_K, new_T, new_r, new_sig) {}
	EuropeanPutOption(double new_S, double new_K, double new_T, double new_r, double new_sig, double new_b) : EuropeanOption(new_S, new_K, new_T, new_r, new_sig, new_b) {}
	EuropeanPutOption(const EuropeanOption& source) : EuropeanOption(source) {}

	//Destructor
	virtual ~EuropeanPutOption() {}

	EuropeanOption& operator = (const EuropeanOption& source);

	void Print()const;

	//Pricers
	double Price()const		{	return PutPrice(S, K, T, r, sig, b);	}
	double PricePCP(double C)const		{	return PutPricePCP(C, S, K, T, r, b);	}
	double Price_S(double S1)	{ return PutPrice(S1, K, T, r, sig, b); }
	double Price_K(double K1)	{ return PutPrice(S, K1, T, r, sig, b); }
	double Price_T(double T1)	{ return PutPrice(S, K, T1, r, sig, b); }
	double Price_r(double r1)	{ return PutPrice(S, K, T, r1, sig, b); }
	double Price_sig(double sig1)	{ return PutPrice(S, K, T, r, sig1, b); }
	double Price_b(double b1)	{ return PutPrice(S, K, T, r, sig, b1); }

	//Pricing function that returns vector. Used in combination with function pointer for better versatility
	typedef double(EuropeanPutOption::*FunctionPointer)(double);
	std::vector<double> Price(double LowerLimit, double UpperLimit, int Num,const FunctionPointer Ptr);

	//Greeks
	double Delta()const { return PutDelta(S, K, T, r, sig, b); }
	double Delta_S(double S1) { return PutDelta(S1, K, T, r, sig, b); }																		//function to override spot price
	double Theta() const { return PutTheta(S, K, T, r, sig, b); }
	double Rho() const { return PutRho(S, K, T, r, sig, b); }
	double Delta(double h)const { return PutDelta(S, h, K, T, r, sig, b); }

};

#endif

max_stars_repo_name: IlyaKul/OptionPricers

max_issues_repo_name: IlyaKul/OptionPricers

max_forks_repo_name: IlyaKul/OptionPricers


text: #include <boost/asio/ts/buffer.hpp>


text:
//  example/stopwatch_example.cpp  ---------------------------------------------------//
//  Copyright Beman Dawes 2006, 2008
//  Copyright 2009-2011 Vicente J. Botet Escriba
//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt
//  See http://www.boost.org/libs/chrono/stopwatches for documentation.

//#include <iostream>
#include <boost/chrono/stopwatches/strict_stopwatch.hpp>
#include <boost/chrono/stopwatches/reporters/stopwatch_reporter.hpp>
#include <boost/chrono/stopwatches/reporters/system_default_formatter.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <cmath>

using namespace boost::chrono;

int f1(long j)
{
  std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
  stopwatch_reporter<strict_stopwatch<> > sw;
  std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;

  for ( long i = 0; i < j; ++i )
    std::sqrt( 123.456L );  // burn some time

  std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
  return 0;
}
int main()
{
  std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
  stopwatch_reporter<strict_stopwatch<> > sw;
  std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;

  f1(1000);
  std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
  f1(2000);
  std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
  f1(3000);
  std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
  return 0;
}

max_stars_repo_name: ZCube/boost-cmake

max_issues_repo_name: ZCube/boost-cmake

max_forks_repo_name: ZCube/boost-cmake


text:
//
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot 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/boostorg/beast
//

// Test that header file is self-contained.
#include <boost/beast/core/close_socket.hpp>

#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <boost/beast/_experimental/test/stream.hpp>
#include <boost/beast/core/stream_traits.hpp>
#include <boost/beast/core/string.hpp>

#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/write.hpp>
#include <utility>

namespace boost {
namespace beast {

class close_socket_test : public beast::unit_test::suite
{
public:
    template<class T>
    struct layer
    {
        T t;

        template<class U>
        explicit
        layer(U&& u)
            : t(std::forward<U>(u))
        {
        }

        T& next_layer()
        {
            return t;
        }
    };

    void
    testClose()
    {
        net::io_context ioc;
        {
            net::ip::tcp::socket sock(ioc);
            sock.open(net::ip::tcp::v4());
            BEAST_EXPECT(sock.is_open());
            close_socket(get_lowest_layer(sock));
            BEAST_EXPECT(! sock.is_open());
        }
        {
            using type = layer<net::ip::tcp::socket>;
            type layer(ioc);
            layer.next_layer().open(net::ip::tcp::v4());
            BEAST_EXPECT(layer.next_layer().is_open());
            BOOST_STATIC_ASSERT(detail::has_next_layer<type>::value);
            BOOST_STATIC_ASSERT((std::is_same<
                typename std::decay<decltype(get_lowest_layer(layer))>::type,
                lowest_layer_type<decltype(layer)>>::value));
            BOOST_STATIC_ASSERT(std::is_same<net::ip::tcp::socket&,
                decltype(get_lowest_layer(layer))>::value);
            BOOST_STATIC_ASSERT(std::is_same<net::ip::tcp::socket,
                lowest_layer_type<decltype(layer)>>::value);
            close_socket(get_lowest_layer(layer));
            BEAST_EXPECT(! layer.next_layer().is_open());
        }
        {
            test::stream ts(ioc);
            close_socket(ts);
        }
    }

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

    template <class WriteStream>
    void hello_and_close (WriteStream& stream)
    {
        net::write(stream, net::const_buffer("Hello, world!", 13));
        close_socket(get_lowest_layer(stream));
    }

    class my_socket
    {
        net::ip::tcp::socket sock_;

    public:
        my_socket(net::io_context& ioc)
            : sock_(ioc)
        {
        }

        friend void beast_close_socket(my_socket& s)
        {
            error_code ec;
            s.sock_.close(ec);
            // ignore the error
        }
    };

    void
    testJavadocs()
    {
        BEAST_EXPECT(&close_socket_test::template hello_and_close<net::ip::tcp::socket>);
        {
            net::io_context ioc;
            my_socket s(ioc);
            close_socket(s);
        }
    }

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

    void
    run() override
    {
        testClose();
        testJavadocs();
    }
};

BEAST_DEFINE_TESTSUITE(beast,core,close_socket);

} // beast
} // boost

max_stars_repo_name: bebuch/beast

max_issues_repo_name: bebuch/beast

max_forks_repo_name: bebuch/beast


text:
#include <fstream>
#include <thread>
#include <stdexcept>
#include <boost/serialization/export.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/vector.hpp>
#include "StraightforwardNeuralNetwork.hpp"
#include "../tools/ExtendedExpection.hpp"

using namespace std;
using namespace snn;
using namespace internal;

BOOST_CLASS_EXPORT(StraightforwardNeuralNetwork)

StraightforwardNeuralNetwork::~StraightforwardNeuralNetwork()
{
    this->stopTrainingAsync();
}

StraightforwardNeuralNetwork::StraightforwardNeuralNetwork(vector<LayerModel> architecture, NeuralNetworkOptimizerModel optimizer)
    : NeuralNetwork(architecture, optimizer)
{
    int err = this->isValid();
    if (err != 0)
    {
        string message = string("Error ") + to_string(err) + ": Wrong parameter in the creation of neural networks";
        throw runtime_error(message);
    }
}

StraightforwardNeuralNetwork::StraightforwardNeuralNetwork(const StraightforwardNeuralNetwork& neuralNetwork)
    : NeuralNetwork(neuralNetwork)
{
    if (!this->isIdle)
        throw std::runtime_error("StraightforwardNeuralNetwork must be idle to be copy");
    this->autoSaveFilePath = neuralNetwork.autoSaveFilePath;
    this->autoSaveWhenBetter = neuralNetwork.autoSaveWhenBetter;
    this->index = neuralNetwork.index;
    this->epoch = neuralNetwork.epoch;
    this->numberOfTrainingsBetweenTwoEvaluations = neuralNetwork.numberOfTrainingsBetweenTwoEvaluations;
}

vector<float> StraightforwardNeuralNetwork::computeOutput(const vector<float>& inputs, bool temporalReset)
{
    return this->output(inputs, temporalReset);
}

int StraightforwardNeuralNetwork::computeCluster(const vector<float>& inputs, bool temporalReset)
{
    const auto outputs = this->output(inputs, temporalReset);
    float maxOutputValue = -2;
    int maxOutputIndex = -1;
    for (int i = 0; i < (int)outputs.size(); i++)
    {
        if (maxOutputValue < outputs[i])
        {
            maxOutputValue = outputs[i];
            maxOutputIndex = i;
        }
    }
    return maxOutputIndex;
}

bool StraightforwardNeuralNetwork::isTraining() const
{
    return !this->isIdle;
}

void StraightforwardNeuralNetwork::startTrainingAsync(Data& data, int batchSize, int evaluationFrequency)
{
    this->validData(data, batchSize);
    this->stopTrainingAsync();
    log<complete>("Start a new thread");
    this->thread = std::thread(&StraightforwardNeuralNetwork::trainSync, this, std::ref(data), Wait(), batchSize, evaluationFrequency);
}

void StraightforwardNeuralNetwork::train(Data& data, Wait wait, int batchSize, int evaluationFrequency)
{
    this->validData(data, batchSize);
    if (!this->isIdle)
        throw std::runtime_error("Neural network is already training");
    this->stopTrainingAsync();
    wait.startClock();
    this->trainSync(data, wait, batchSize, evaluationFrequency);
}

void StraightforwardNeuralNetwork::trainSync(Data& data, Wait wait, const int batchSize, const int evaluationFrequency)
{
    log<minimal>("Start training");
    this->numberOfTrainingsBetweenTwoEvaluations = data.sets[training].size;
    this->wantToStopTraining = false;
    this->isIdle = false;

    if (evaluationFrequency > 0)
        this->evaluate(data);

    for (this->epoch = 0; this->continueTraining(wait); this->epoch++)
    {
        log<minimal>("Epoch: " + std::to_string(this->epoch));
        data.shuffle();
        for (this->index = 0; index + batchSize <= this->numberOfTrainingsBetweenTwoEvaluations && this->continueTraining(wait);
             this->index += batchSize)
        {
            if (this->hasNan())
            {
                this->setResultsAsNan();
                this->resetTrainingValues();
                return;
            }

            if (data.needToLearnOnTrainingData(this->index))
                this->trainOnce(data.getTrainingData(this->index, batchSize),
                                data.getTrainingOutputs(this->index, batchSize), data.isFirstTrainingDataOfTemporalSequence(this->index));
            else
                this->output(data.getTrainingData(this->index, batchSize), data.isFirstTrainingDataOfTemporalSequence(this->index));
        }
        if (evaluationFrequency > 0 && this->epoch % evaluationFrequency == 0)
            this->evaluate(data);
    }
    this->resetTrainingValues();
    log<minimal>("Stop training");
}

void StraightforwardNeuralNetwork::evaluate(const Data& data)
{
    this->startTesting();
    for (this->index = 0; this->index < data.sets[testing].size; this->index++)
    {
        if (this->hasNan())
        {
            this->setResultsAsNan();
            this->resetTrainingValues();
            return;
        }

        if (data.needToEvaluateOnTestingData(this->index))
            this->evaluateOnce(data);
        else
            this->output(data.getTestingData(this->index), data.isFirstTestingDataOfTemporalSequence(this->index));
    }
    this->stopTesting();
    log<minimal>("Accuracy: " + std::to_string(this->getGlobalClusteringRate()));
    log<minimal>("MAE: " + std::to_string(this->getMeanAbsoluteError()));
    if (this->autoSaveWhenBetter && this->globalClusteringRateIsBetterThanPreviously)
    {
        this->saveSync(autoSaveFilePath);
    }
}

inline
void StraightforwardNeuralNetwork::evaluateOnce(const Data& data)
{
    switch (data.typeOfProblem)
    {
    case problem::classification:
        this->evaluateOnceForClassification(data.getTestingData(this->index),
                                            data.getTestingLabel(this->index),
                                            data.getSeparator(),
                                            data.isFirstTestingDataOfTemporalSequence(this->index));
        break;
    case problem::multipleClassification:
        this->evaluateOnceForMultipleClassification(data.getTestingData(this->index),
                                                    data.getTestingOutputs(this->index),
                                                    data.getSeparator(),
                                                    data.isFirstTestingDataOfTemporalSequence(this->index));
        break;
    case problem::regression:
        this->evaluateOnceForRegression(data.getTestingData(this->index),
                                        data.getTestingOutputs(this->index),
                                        data.getPrecision(),
                                        data.isFirstTestingDataOfTemporalSequence(this->index));
        break;
    default:
        throw NotImplementedException();
    }
}

void StraightforwardNeuralNetwork::stopTrainingAsync()
{
    this->wantToStopTraining = true;
    if (this->thread.joinable())
    {
        log<minimal>("Stop training");
        this->thread.join();
        log<complete>("Thread closed");
    }
}

void StraightforwardNeuralNetwork::resetTrainingValues()
{
    this->index = 0;
    this->epoch = 0;
    this->wantToStopTraining = false;
    this->isIdle = true;
}

inline
bool StraightforwardNeuralNetwork::continueTraining(Wait wait) const
{
    const auto epochs = this->getCurrentEpoch();
    const auto accuracy = this->getGlobalClusteringRate();
    const auto mae = this->getMeanAbsoluteError();

    return !this->wantToStopTraining && !wait.isOver(epochs, accuracy, mae) && !this->hasNan();
}

void StraightforwardNeuralNetwork::waitFor(Wait wait) const
{
    wait.startClock();
    while (!this->hasNan())
    {
        this_thread::sleep_for(1ms);

        const auto epochs = this->getCurrentEpoch();
        const auto accuracy = this->getGlobalClusteringRate();
        const auto mae = this->getMeanAbsoluteError();

        if (wait.isOver(epochs, accuracy, mae))
            break;
    }
}

int StraightforwardNeuralNetwork::isValid() const
{
    return this->NeuralNetwork::isValid();
}

void StraightforwardNeuralNetwork::validData(const Data& data, int batchSize) const
{
    if (data.numberOfLabels != this->getNumberOfOutputs() || data.sizeOfData != this->getNumberOfInputs())
        throw std::runtime_error("Data has not the same format as the neural network");
    if (batchSize != 1 && data.typeOfTemporal != nature::nonTemporal)
        throw std::runtime_error("Non temporal data cannot have batch size");
    if (batchSize < 1)
        throw std::runtime_error("Wrong batch size");
    if (batchSize > data.sets[training].size)
        throw std::runtime_error("Batch size is too large");
}

void StraightforwardNeuralNetwork::saveAs(const string filePath)
{
    if(!this->isIdle)
        throw std::runtime_error("Neural network cannot be saved during training, stop training before saving or use auto save");
    saveSync(filePath);
}

void StraightforwardNeuralNetwork::saveSync(const string filePath)
{
    this->autoSaveFilePath = filePath;
    ofstream ofs(filePath);
    boost::archive::text_oarchive archive(ofs);
    archive << this;
            log<minimal>("Neural network saved: ", filePath);
}

StraightforwardNeuralNetwork& StraightforwardNeuralNetwork::loadFrom(const string filePath)
{
    StraightforwardNeuralNetwork* neuralNetwork = nullptr;
    ifstream ifs(filePath);
    boost::archive::text_iarchive archive(ifs);
    archive >> neuralNetwork;
    return *neuralNetwork;
}

bool StraightforwardNeuralNetwork::operator==(const StraightforwardNeuralNetwork& neuralNetwork) const
{
    return this->NeuralNetwork::operator==(neuralNetwork)
        && this->autoSaveFilePath == neuralNetwork.autoSaveFilePath
        && this->autoSaveWhenBetter == neuralNetwork.autoSaveWhenBetter
        && this->wantToStopTraining == neuralNetwork.wantToStopTraining
        && this->index == neuralNetwork.index
        && this->isIdle == neuralNetwork.isIdle
        && this->epoch == neuralNetwork.epoch
        && this->numberOfTrainingsBetweenTwoEvaluations == neuralNetwork.numberOfTrainingsBetweenTwoEvaluations;
}

bool StraightforwardNeuralNetwork::operator!=(const StraightforwardNeuralNetwork& neuralNetwork) const
{
    return !(*this == neuralNetwork);
}

max_stars_repo_name: sehe/StraightforwardNeuralNetwork

max_issues_repo_name: sehe/StraightforwardNeuralNetwork

max_forks_repo_name: sehe/StraightforwardNeuralNetwork


text:
#pragma once
/**
   @file Options.hpp
   @brief Program options class for parsing user arguments to application.
*/

#include <cinttypes>
#include <functional>
#include <string>

#include <boost/program_options.hpp>

namespace mimir {

  /**
     @brief Helper class for program options

     This class holds the implementation of program options and arguments.

  */
  class Options
  {
  protected:
    /// Helper function for checking a range.
    template<typename T>
    static std::function<void(T)> check_range(
        char const * const opt_name,
        const T& min,
        const T& max)
    {
      return [opt_name, min, max](T value)
             {
               if ( value < min || value > max)
               {
                 throw boost::program_options::validation_error(
                     boost::program_options::validation_error::invalid_option_value,
                     opt_name,
                     std::to_string(value));
               }
             };
    }

  public:
    /**
       @brief Constructor for mimir options.

       @param [in] program_descriptor String to print to the user on the command line.
    */
    Options(const std::string& program_descriptor);
    /**
       @brief Parse input arguments

       Parses program arguments into variables.

       @param [in] argc Number of arguments passed from main()
       @param [in] argv Aarguments passed from main()
       @return bool Whether parsing was successful.
    */
    bool parse(int argc , char *argv[]);

  private:
    /// Prints a usage string in case of help or wrong use.
    std::string make_usage_string(
        const std::string& program_name,
        const boost::program_options::options_description& desc,
        boost::program_options::positional_options_description& p);

  public:
    std::string filename; ///< YAML config filename
    std::uint16_t severity, ///< Print severity.
      log_severity; ///< Log file severity. (NOTE: unused.)
  private:
    const std::string m_progDesc; ///< Program description string.
  };

}

max_stars_repo_name: sintef-ocean/mimir

max_issues_repo_name: sintef-ocean/mimir

max_forks_repo_name: sintef-ocean/mimir


text:
#include "irods/rcMisc.h"
#include "irods/genQuery.h"
#include "irods/icatHighLevelRoutines.hpp"
#include "irods/miscUtil.h"
#include "irods/rodsErrorTable.h"
#include "irods/rsGenQuery.hpp"
#include "irods/rsGlobalExtern.hpp"
#include "irods/miscServerFunct.hpp"
#include "irods/irods_resource_manager.hpp"
#include "irods/irods_server_properties.hpp"
#include "irods/irods_lexical_cast.hpp"
#include "irods/rodsGenQueryNames.h"

#include <boost/format.hpp>
#include <boost/regex.hpp>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string/predicate.hpp>

#include <cstring>
#include <string>
#include <string_view>

namespace {
    std::string
    get_column_name(int j) {
        const int n = sizeof(columnNames)/sizeof(columnNames[0]);
        for (int i=0; i<n; ++i) {
            if (columnNames[i].columnId == j) {
                return std::string(columnNames[i].columnName);
            }
        }

        std::stringstream ss;
        ss << j;
        return std::string("COLUMN_NAME_NOT_FOUND_") + ss.str();
    }

    struct option_element{
        int key;
        const char* cpp_macro;
        const char* token;
    };

    option_element queryWideOptionsMap[] = {
        {RETURN_TOTAL_ROW_COUNT, "RETURN_TOTAL_ROW_COUNT", "return_total_row_count"},
        {NO_DISTINCT,            "NO_DISTINCT",            "no_distinct"},
        {QUOTA_QUERY,            "QUOTA_QUERY",            "quota_query"},
        {AUTO_CLOSE,             "AUTO_CLOSE",             "auto_close"},
        {UPPER_CASE_WHERE,       "UPPER_CASE_WHERE",       "upper_case_where"}
    };

    option_element selectInpOptionsMap[] = {
        {ORDER_BY,      "ORDER_BY",      "order"},
        {ORDER_BY_DESC, "ORDER_BY_DESC", "order_desc"}
    };

    option_element selectInpFunctionMap[] = {
        {SELECT_MIN,   "SELECT_MIN",   "min"},
        {SELECT_MAX,   "SELECT_MAX",   "max"},
        {SELECT_SUM,   "SELECT_SUM",   "sum"},
        {SELECT_AVG,   "SELECT_AVG",   "avg"},
        {SELECT_COUNT, "SELECT_COUNT", "count"}
    };

    std::string
    format_selected_column(int columnIndex, int columnOption) {
        std::string ret = get_column_name(columnIndex);
        if (columnOption == 0 || columnOption == 1) {
            return ret;
        }

        for (size_t i=0; i<sizeof(selectInpOptionsMap)/sizeof(selectInpOptionsMap[0]); ++i) {
            if (columnOption == selectInpOptionsMap[i].key) {
                ret = std::string(selectInpOptionsMap[i].token) + "(" + ret + ")";
                return ret;
            }
        }
        for (size_t i=0; i<sizeof(selectInpFunctionMap)/sizeof(selectInpFunctionMap[0]); ++i) {
            if (columnOption == selectInpFunctionMap[i].key) {
                ret = std::string(selectInpFunctionMap[i].token) + "(" + ret + ")";
                return ret;
            }
        }

        std::stringstream ss;
        ss << columnOption;
        ret = std::string("combo_func_") + ss.str() + "(" + ret + ")";
        return ret;
    }

    template <typename OutStream>
    void
    insert_genquery_inp_into_stream(const genQueryInp_t *genQueryInp, OutStream& f) {
        f << "maxRows: " << genQueryInp->maxRows << " continueInx: " << genQueryInp->continueInx << " rowOffset: " << genQueryInp->rowOffset << '\n';
        f << "options: " << genQueryInp->options;
        for (size_t i=0; i<sizeof(queryWideOptionsMap)/sizeof(queryWideOptionsMap[0]); ++i) {
            if (genQueryInp->options & queryWideOptionsMap[i].key) {
                f << " " << queryWideOptionsMap[i].cpp_macro;
            }
        }
        f << '\n';

        f << "selectInp.len: " << genQueryInp->selectInp.len << '\n';
        for (int i=0; i<genQueryInp->selectInp.len; ++i) {
            f << "    column: " << genQueryInp->selectInp.inx[i] << " " << get_column_name(genQueryInp->selectInp.inx[i]) << '\n';
            f << "    options: " << genQueryInp->selectInp.value[i];
            for (size_t j=0; j<sizeof(selectInpOptionsMap)/sizeof(selectInpOptionsMap[0]); ++j) {
                if (genQueryInp->selectInp.value[i] & selectInpOptionsMap[j].key) {
                    f << " " << selectInpOptionsMap[j].cpp_macro;
                }
            }
            for (size_t j=0; j<sizeof(selectInpFunctionMap)/sizeof(selectInpFunctionMap[0]); ++j) {
                if ((genQueryInp->selectInp.value[i] & 0x7) == selectInpFunctionMap[j].key) {
                    f << " " << selectInpFunctionMap[j].cpp_macro;
                }
            }
            f << '\n';
        }

        f << "sqlCondInp.len: " << genQueryInp->sqlCondInp.len << '\n';
        for (int i=0; i<genQueryInp->sqlCondInp.len; ++i) {
            f << "    column: " << genQueryInp->sqlCondInp.inx[i] << " " << get_column_name(genQueryInp->sqlCondInp.inx[i]) << '\n';
            f << "    condition: " << genQueryInp->sqlCondInp.value[i] << '\n';
        }
        f << '\n';
    }

}

std::string
genquery_inp_to_diagnostic_string(const genQueryInp_t *q) {
    std::stringstream ss;
    insert_genquery_inp_into_stream(q, ss);
    return ss.str();
}

std::string
genquery_inp_to_iquest_string(const genQueryInp_t *q) {
    // TODO: handle queryWideOptionsMap
    std::stringstream ss;
    ss << "select ";
    {
        const int n = q->selectInp.len;
        if (n<=0) {
            ss << "ERROR: 0 columns selected, printing query contents instead of iquest string\n";
            insert_genquery_inp_into_stream(q, ss);
            return ss.str();
        }

        ss << format_selected_column(q->selectInp.inx[0], q->selectInp.value[0]);
        for (int i=1; i<n; ++i) {
            ss << ", ";
            ss << format_selected_column(q->selectInp.inx[i], q->selectInp.value[i]);
        }
    }

    {
        const int n = q->sqlCondInp.len;
        if (n>0) {
            ss << " where ";
            ss << get_column_name(q->sqlCondInp.inx[0]) << " " << q->sqlCondInp.value[0];
            for (int i=1; i<n; ++i) {
                ss << " and ";
                ss << get_column_name(q->sqlCondInp.inx[i]) << " " << q->sqlCondInp.value[i];
            }
        }
    }
    return ss.str();
}

irods::GenQueryInpWrapper::GenQueryInpWrapper(void) {
    memset(&genquery_inp_, 0, sizeof(genquery_inp_));
}
irods::GenQueryInpWrapper::~GenQueryInpWrapper(void) {
    clearGenQueryInp(&genquery_inp_);
}
genQueryInp_t& irods::GenQueryInpWrapper::get(void) {
    return genquery_inp_;
}
irods::GenQueryOutPtrWrapper::GenQueryOutPtrWrapper(void) {
    genquery_out_ptr_ = nullptr;
}
irods::GenQueryOutPtrWrapper::~GenQueryOutPtrWrapper(void) {
    freeGenQueryOut(&genquery_out_ptr_);
}
genQueryOut_t*& irods::GenQueryOutPtrWrapper::get(void) {
    return genquery_out_ptr_;
}

static
irods::error strip_new_query_terms(
    genQueryInp_t* _inp ) {
    // =-=-=-=-=-=-=-
    // cache pointers to the incoming inxIvalPair
    inxIvalPair_t tmp;
    tmp.len   = _inp->selectInp.len;
    tmp.inx   = _inp->selectInp.inx;
    tmp.value = _inp->selectInp.value;

    // =-=-=-=-=-=-=-
    // zero out the selectInp to copy
    // fresh community indices and values
    std::memset(&_inp->selectInp, 0, sizeof(_inp->selectInp));

    // =-=-=-=-=-=-=-
    // iterate over the tmp and only copy community values
    for ( int i = 0; i < tmp.len; ++i ) {
        if ( tmp.inx[ i ] == COL_R_RESC_CHILDREN ||
                tmp.inx[ i ] == COL_R_RESC_CONTEXT  ||
                tmp.inx[ i ] == COL_R_RESC_PARENT   ||
                tmp.inx[ i ] == COL_R_RESC_PARENT_CONTEXT   ||
                tmp.inx[ i ] == COL_D_RESC_HIER ) {
            continue;
        }
        else {
            addInxIval( &_inp->selectInp, tmp.inx[ i ], tmp.value[ i ] );
        }

    } // for i

    return SUCCESS();

} // strip_new_query_terms

static
irods::error strip_resc_grp_name_from_query_inp( genQueryInp_t* _inp, int& _pos ) {

    const int COL_D_RESC_GROUP_NAME  = 408;

    // sanity check
    if ( !_inp ) {
        return CODE( SYS_INTERNAL_NULL_INPUT_ERR );
    }

    // =-=-=-=-=-=-=-
    // cache pointers to the incoming inxIvalPair
    inxIvalPair_t tmp;
    tmp.len   = _inp->selectInp.len;
    tmp.inx   = _inp->selectInp.inx;
    tmp.value = _inp->selectInp.value;

    // =-=-=-=-=-=-=-
    // zero out the selectInp to copy
    // fresh indices and values
    std::memset(&_inp->selectInp, 0, sizeof(_inp->selectInp));

    // =-=-=-=-=-=-=-
    // iterate over tmp and replace resource group with resource name
    for ( int i = 0; i < tmp.len; ++i ) {
        if ( tmp.inx[i] == COL_D_RESC_GROUP_NAME ) {
            addInxIval( &_inp->selectInp, COL_D_RESC_NAME, tmp.value[i] );
            _pos = i;
        }
        else {
            addInxIval( &_inp->selectInp, tmp.inx[i], tmp.value[i] );
        }
    } // for i

    // cleanup
    if ( tmp.inx ) { free( tmp.inx ); }
    if ( tmp.value ) { free( tmp.value ); }

    return SUCCESS();

} // strip_resc_grp_name_from_query_inp

static
irods::error add_resc_grp_name_to_query_out( genQueryOut_t *_out, int& _pos ) {

    const int COL_D_RESC_GROUP_NAME  = 408;

    // =-=-=-=-=-=-=-
    // Sanity checks
    if ( !_out ) {
        return CODE( SYS_INTERNAL_NULL_INPUT_ERR );
    }

    if ( _pos < 0 || _pos > MAX_SQL_ATTR - 1 ) {
        return CODE( SYS_INVALID_INPUT_PARAM );
    }

    sqlResult_t *sqlResult = &_out->sqlResult[_pos];
    if ( !sqlResult || sqlResult->attriInx != COL_D_RESC_NAME ) {
        return CODE( SYS_INTERNAL_ERR );
    }

    // =-=-=-=-=-=-=-
    // Swap attribute indices back
    sqlResult->attriInx = COL_D_RESC_GROUP_NAME;

    return SUCCESS();

} // add_resc_grp_name_to_query_out

static
irods::error get_resc_id_cond_for_hier_cond(
        const char*  _cond,
        std::string& _new_cond ) {
    const std::string in_cond( _cond );
    const std::string::size_type p0 = in_cond.find_first_of( "'" );
    const std::string::size_type p1 = in_cond.find_last_of( "'" );
    if ( p1 == p0 ) {
        return ERROR( SYS_INVALID_INPUT_PARAM, _cond );
    }

    std::string hier = in_cond.substr( p0 + 1, p1 - p0 - 1);

    /*
     * If query condition uses "=", look for exact matches.
     * Since % is not allowed in resource names, error out if found.
     */
    if ( std::string::npos != in_cond.find( "=" ) &&
         std::string::npos != hier.find( "%" ) ) {
        return ERROR( SYS_RESC_DOES_NOT_EXIST, hier );
    }

    /*
     * Convert input condition to regex syntax and filter list of
     * hierarchies. For each matching result, get the leaf ID and
     * add it to the list of results. Generate 'IN' condition with
     * the resulting leaf IDs. Return early if none found.
     */
    std::string::size_type pos( hier.find_first_of( "%" ) );
    std::string hierRegex( hier );
    while ( std::string::npos != pos ) {
        hierRegex.replace( pos, 1, "(.*)" );
        pos = hierRegex.find_first_of( "%" );
    }

    std::vector<rodsLong_t> leaf_ids;
    try {
        const std::vector<std::string> hier_list = resc_mgr.get_all_resc_hierarchies();
        for ( const auto& hier_ : hier_list ) {
            if ( boost::regex_match( hier_, boost::regex( hierRegex ) ) ) {
                rodsLong_t leaf_id{};
                irods::error ret = resc_mgr.hier_to_leaf_id( hier_, leaf_id );
                if ( !ret.ok() ) {
                    return PASS( ret );
                }
                leaf_ids.push_back( leaf_id );
            }
        }
    }
    catch ( const irods::exception& e ) {
        return irods::error( e );
    }

    if ( leaf_ids.empty() ) {
        return ERROR( SYS_RESC_DOES_NOT_EXIST, hier );
    }

    _new_cond = "IN (";
    for ( const auto& leaf_id : leaf_ids ) {
        std::stringstream current_cond;
        current_cond << "'" << leaf_id << "'";
        if( leaf_id != leaf_ids.back() ) {
            current_cond << ",";
        }
        _new_cond += current_cond.str();
    }
    _new_cond += ")";
    return SUCCESS();

} // get_resc_id_cond_for_hier_cond

static
irods::error strip_resc_hier_name_from_query_inp( genQueryInp_t* _inp, int& _pos ) {
    // sanity check
    if ( !_inp ) {
        return CODE( SYS_INTERNAL_NULL_INPUT_ERR );
    }

    // =-=-=-=-=-=-=-
    // cache pointers to the incoming inxIvalPair
    inxIvalPair_t tmpI;
    tmpI.len   = _inp->selectInp.len;
    tmpI.inx   = _inp->selectInp.inx;
    tmpI.value = _inp->selectInp.value;

    // =-=-=-=-=-=-=-
    // zero out the selectInp to copy
    // fresh indices and values
    std::memset(&_inp->selectInp, 0, sizeof(_inp->selectInp));

    // =-=-=-=-=-=-=-
    // iterate over tmp and replace resource group with resource name
    for ( int i = 0; i < tmpI.len; ++i ) {
        if ( tmpI.inx[i] == COL_D_RESC_HIER ) {
            addInxIval( &_inp->selectInp, COL_D_RESC_ID, tmpI.value[i] );
            _pos = i;
        }
        else {
            addInxIval( &_inp->selectInp, tmpI.inx[i], tmpI.value[i] );
        }
    } // for i

    // cleanup
    if ( tmpI.inx ) { free( tmpI.inx ); }
    if ( tmpI.value ) { free( tmpI.value ); }

    // =-=-=-=-=-=-=-
    // cache pointers to the incoming inxIvalPair
    inxValPair_t tmpV;
    tmpV.len   = _inp->sqlCondInp.len;
    tmpV.inx   = _inp->sqlCondInp.inx;
    tmpV.value = _inp->sqlCondInp.value;

    // =-=-=-=-=-=-=-
    // zero out the selectInp to copy
    // fresh indices and values
    std::memset(&_inp->sqlCondInp, 0, sizeof(_inp->selectInp));

    // =-=-=-=-=-=-=-
    // iterate over tmp and replace resource group with resource name
    for ( int i = 0; i < tmpV.len; ++i ) {
        if ( tmpV.inx[i] == COL_D_RESC_HIER ) {
            std::string new_cond = "='0'";
            irods::error ret = get_resc_id_cond_for_hier_cond(
                                   tmpV.value[i],
                                   new_cond);
            if(!ret.ok()) {
                irods::log(PASS(ret));
            }

            addInxVal( &_inp->sqlCondInp, COL_D_RESC_ID, new_cond.c_str() );
        }
        else {
            addInxVal( &_inp->sqlCondInp, tmpV.inx[i], tmpV.value[i] );
        }
    } // for i

    // cleanup
    clearInxVal(&tmpV);

    return SUCCESS();

} // strip_resc_hier_name_from_query_inp

static
irods::error add_resc_hier_name_to_query_out( genQueryOut_t *_out, int& _pos ) {
    // =-=-=-=-=-=-=-
    // Sanity checks
    if ( !_out ) {
        return CODE( SYS_INTERNAL_NULL_INPUT_ERR );
    }

    if ( _pos < 0 || _pos > MAX_SQL_ATTR - 1 ) {
        return CODE( SYS_INVALID_INPUT_PARAM );
    }

    sqlResult_t *sqlResult = &_out->sqlResult[_pos];
    if ( !sqlResult || sqlResult->attriInx != COL_D_RESC_ID ) {
        return CODE( SYS_INTERNAL_ERR );
    }

    // =-=-=-=-=-=-=-
    // Swap attribute indices back
    sqlResult->attriInx = COL_D_RESC_HIER;

    // =-=-=-=-=-=-=-
    // cache hier strings for leaf id
    size_t max_len = 0;
    std::vector<std::string> resc_hiers(_out->rowCnt);
    for ( int i = 0; i < _out->rowCnt; ++i ) {
        char* leaf_id_str = &sqlResult->value[i*sqlResult->len];

        rodsLong_t leaf_id = 0;
        irods::error ret = irods::lexical_cast<rodsLong_t>(
                               leaf_id_str,
                               leaf_id);
        if(!ret.ok()) {
            irods::log(PASS(ret));
            continue;
        }

        std::string hier;
        ret = resc_mgr.leaf_id_to_hier( leaf_id, resc_hiers[i] );
        if(!ret.ok()) {
            irods::log(PASS(ret));
            continue;
        }

        if(resc_hiers[i].size() > max_len ) {
            max_len = resc_hiers[i].size();
        }

    } // for i

    free( sqlResult->value );

    // =-=-=-=-=-=-=-
    // craft new result string with the hiers
    sqlResult->len = max_len+1;
    sqlResult->value = (char*)malloc(sqlResult->len*_out->rowCnt);
    for( std::size_t i = 0; i < resc_hiers.size(); ++i ) {
        snprintf(
            &sqlResult->value[i*sqlResult->len],
            sqlResult->len,
            "%s",
            resc_hiers[i].c_str() );
    }

    return SUCCESS();

} // add_resc_hier_name_to_query_out

static bool is_zone_name_valid(const std::string& _zone_hint)
{
    // Extract zone name from zone hint.
    boost::char_separator<char> sep("/");
    boost::tokenizer<boost::char_separator<char>> tokens(_zone_hint, sep);

    if (tokens.begin() == tokens.end()) {
        return false;
    }

    const std::string_view zone_name = *tokens.begin();

    for (const auto* tmp_zone = ZoneInfoHead; tmp_zone; tmp_zone = tmp_zone->next) {
        if (boost::iequals(zone_name, tmp_zone->zoneName)) {
            return true;
        }
    }

    return false;
} // is_zone_name_valid

static
irods::error process_query_terms_for_pre_irods4_server(const std::string& _zone_hint,
                                                       genQueryInp_t* _inp)
{
    // extract zone name from zone hint
    boost::char_separator<char> sep("/");
    boost::tokenizer<boost::char_separator<char>> tokens(_zone_hint, sep);
    if (tokens.begin() == tokens.end()) {
        return ERROR(SYS_INVALID_ZONE_NAME, "No zone name parsed from zone hint");
    }

    const std::string_view zone_name = *tokens.begin();
    zoneInfo_t* tmp_zone = ZoneInfoHead;

    // grind through the zones and find the match to the kw
    while (tmp_zone) {
        if (boost::iequals(zone_name, tmp_zone->zoneName) && tmp_zone->primaryServerHost->conn &&
            tmp_zone->primaryServerHost->conn->svrVersion &&
            tmp_zone->primaryServerHost->conn->svrVersion->cookie < 301)
        {
            return strip_new_query_terms(_inp);
        }

        tmp_zone = tmp_zone->next;
    }

    return SUCCESS();
} // process_query_terms_for_pre_irods4_server

#if 0 // debug code
int
print_gen_query_input(
    genQueryInp_t *genQueryInp ) {
    if(!genQueryInp) return 0;

    int i = 0, len = 0;
    int *ip1 = 0, *ip2 = 0;
    char *cp = 0;
    char **cpp = 0;

    printf( "maxRows=%d\n", genQueryInp->maxRows );

    len = genQueryInp->selectInp.len;
    printf( "sel len=%d\n", len );

    ip1 = genQueryInp->selectInp.inx;
    ip2 = genQueryInp->selectInp.value;
    if( ip1 && ip2 ) {
            for ( i = 0; i < len; i++ ) {
                printf( "sel inx [%d]=%d\n", i, *ip1 );
                printf( "sel val [%d]=%d\n", i, *ip2 );
                ip1++;
                ip2++;
            }
    }

    len = genQueryInp->sqlCondInp.len;
    printf( "sqlCond len=%d\n", len );
    ip1 = genQueryInp->sqlCondInp.inx;
    cpp = genQueryInp->sqlCondInp.value;
    if(cpp) {
        cp = *cpp;
    }
    if( ip1 && cp ) {
            for ( i = 0; i < len; i++ ) {
                printf( "sel inx [%d]=%d\n", i, *ip1 );
                printf( "sel val [%d]=:%s:\n", i, cp );
                ip1++;
                cpp++;
                cp = *cpp;
            }
    }

    return 0;
}
#endif

/* can be used for debug: */
/* extern int printGenQI( genQueryInp_t *genQueryInp); */

int
rsGenQuery( rsComm_t *rsComm, genQueryInp_t *genQueryInp,
            genQueryOut_t **genQueryOut ) {

    rodsServerHost_t *rodsServerHost;
    int status;
    char *zoneHint;
    zoneHint = getZoneHintForGenQuery( genQueryInp );

    std::string zone_hint_str;
    if ( zoneHint ) {
        zone_hint_str = zoneHint;

        // clean up path separator(s) and trailing '
        if('/' == zone_hint_str[0]) {
            zone_hint_str = zone_hint_str.substr(1);

            std::string::size_type pos = zone_hint_str.find_first_of("/");
            if(std::string::npos != pos ) {
                zone_hint_str = zone_hint_str.substr(0,pos);
            }
        }
        if('\'' == zone_hint_str[zone_hint_str.size()-1]) {
            zone_hint_str = zone_hint_str.substr(0,zone_hint_str.size()-1);
        }

    }

    status = getAndConnRcatHost(rsComm, SECONDARY_RCAT, zone_hint_str.c_str(), &rodsServerHost);

    if ( status < 0 ) {
        return status;
    }

    if (!zone_hint_str.empty()) {
        // If the ZONE_KW is set, that means the client targeted a specific zone.
        // The zone name check only applies to this case. Checking the validity of
        // the zone name must be skipped when getZoneHintForGenQuery() derives it.
        if (getValByKey(&genQueryInp->condInput, ZONE_KW)) {
            if (!is_zone_name_valid(zone_hint_str)) {
                rodsLog(LOG_ERROR, "%s:%d :: Unknown zone name [%s].", __func__, __LINE__, zone_hint_str.data());
                return SYS_INVALID_ZONE_NAME;
            }
        }

        // Handle connections with iRODS 3 or earlier.
        irods::error ret = process_query_terms_for_pre_irods4_server( zone_hint_str, genQueryInp );
        if (!ret.ok()) {
            irods::log(PASS(ret));
        }
    }

    if ( rodsServerHost->localFlag == LOCAL_HOST ) {
        std::string svc_role;
        irods::error ret = get_catalog_service_role(svc_role);
        if(!ret.ok()) {
            irods::log(PASS(ret));
            return ret.code();
        }

        if( irods::KW_CFG_SERVICE_ROLE_PROVIDER == svc_role ) {
            status = _rsGenQuery( rsComm, genQueryInp, genQueryOut );
        } else if( irods::KW_CFG_SERVICE_ROLE_CONSUMER == svc_role ) {
            rodsLog( LOG_NOTICE,
                     "rsGenQuery error. RCAT is not configured on this host" );
            return SYS_NO_RCAT_SERVER_ERR;
        } else {
            rodsLog(
                LOG_ERROR,
                "role not supported [%s]",
                svc_role.c_str() );
            status = SYS_SERVICE_ROLE_NOT_SUPPORTED;
        }
    }
    else {
        // =-=-=-=-=-=-=-
        // strip disable strict acl flag if the agent conn flag is missing
        char* dis_kw = getValByKey( &genQueryInp->condInput, DISABLE_STRICT_ACL_KW );
        if ( dis_kw ) {
            if (!irods::server_property_exists(irods::AGENT_CONN_KW)) {
                rmKeyVal( &genQueryInp->condInput, DISABLE_STRICT_ACL_KW );
            }
        } // if dis_kw

        status = rcGenQuery( rodsServerHost->conn,
                             genQueryInp, genQueryOut );
    }
    if ( status < 0  && status != CAT_NO_ROWS_FOUND ) {
        std::string prefix = ( rodsServerHost->localFlag == LOCAL_HOST ) ? "_rs" : "rc";
        rodsLog( LOG_NOTICE,
                 "rsGenQuery: %sGenQuery failed, status = %d", prefix.c_str(), status );
    }
    return status;
}

int
_rsGenQuery( rsComm_t *rsComm, genQueryInp_t *genQueryInp,
             genQueryOut_t **genQueryOut ) {
    int status;
    int resc_grp_attr_pos = -1;
    int resc_hier_attr_pos = -1;

    static int ruleExecuted = 0;
    ruleExecInfo_t rei;

    static int PrePostProcForGenQueryFlag = -2;
    int i, argc;
    ruleExecInfo_t rei2;
    const char *args[MAX_NUM_OF_ARGS_IN_ACTION];

    // =-=-=-=-=-=-=-
    // handle queries from older clients
    std::string client_rel_version = rsComm->cliVersion.relVersion;
    std::string local_rel_version = RODS_REL_VERSION;
    if ( client_rel_version != local_rel_version ) {	// skip if version strings match
        irods::error err = strip_resc_grp_name_from_query_inp( genQueryInp, resc_grp_attr_pos );
        if ( !err.ok() ) {
            irods::log( PASS( err ) );
        }
    }

    irods::error err = strip_resc_hier_name_from_query_inp( genQueryInp, resc_hier_attr_pos );
    if ( !err.ok() ) {
        irods::log( PASS( err ) );
    }

    if ( PrePostProcForGenQueryFlag < 0 ) {
        if ( getenv( "PREPOSTPROCFORGENQUERYFLAG" ) != NULL ) {
            PrePostProcForGenQueryFlag = 1;
        }
        else {
            PrePostProcForGenQueryFlag = 0;
        }
    }

    memset( ( char* )&rei2, 0, sizeof( ruleExecInfo_t ) );
    rei2.rsComm = rsComm;

    /*  printGenQI(genQueryInp);  for debug */

    *genQueryOut = ( genQueryOut_t* )malloc( sizeof( genQueryOut_t ) );
    memset( ( char * )*genQueryOut, 0, sizeof( genQueryOut_t ) );

    if ( ruleExecuted == 0 ) {
        memset( ( char* )&rei, 0, sizeof( rei ) );
        /* Include the user info for possible use by the rule.  Note
        that when this is called (as the agent is initializing),
        this user info is not confirmed yet.  For password
        authentication though, the agent will soon exit if this
        is not valid.  But for GSI, the user information may not
        be present and/or may be changed when the authentication
        completes, so it may not be safe to use this in a GSI
        enabled environment.  This addition of user information
        was requested by ARCS/IVEC (Sean Fleming) to avoid a
        local patch.
        */
        rei.uoic = &rsComm->clientUser;
        rei.uoip = &rsComm->proxyUser;

        status = applyRule( "acAclPolicy", NULL, &rei, NO_SAVE_REI );
        if ( status == 0 ) {

            ruleExecuted = 1; /* No need to retry next time since it
                             succeeded.  Since this is called at
                             startup, the Rule Engine may not be
                             initialized yet, in which case the
                             default setting is fine and we should
                             retry next time. */
        }
    }

    // =-=-=-=-=-=-=-
    // verify that we are running a query for another agent connection
    const bool agent_conn_flag = irods::server_property_exists(irods::AGENT_CONN_KW);

    // =-=-=-=-=-=-=-
    // detect if a request for disable of strict acls is made
    int acl_val = -1;
    char* dis_kw = getValByKey( &genQueryInp->condInput, DISABLE_STRICT_ACL_KW );
    if ( agent_conn_flag && dis_kw ) {
        acl_val = 0;
    }

    // =-=-=-=-=-=-=-
    // cache the old acl value for reuse later if necessary
    int old_acl_val =  chlGenQueryAccessControlSetup(
                           rsComm->clientUser.userName,
                           rsComm->clientUser.rodsZone,
                           rsComm->clientAddr,
                           rsComm->clientUser.authInfo.authFlag,
                           acl_val );

    if ( PrePostProcForGenQueryFlag == 1 ) {
        std::string arg = str( boost::format( "%ld" ) % ( ( long )genQueryInp ) );
        args[0] = arg.c_str();
        argc = 1;
        i =  applyRuleArg( "acPreProcForGenQuery", args, argc, &rei2, NO_SAVE_REI );
        if ( i < 0 ) {
            rodsLog( LOG_ERROR,
                     "rsGenQuery:acPreProcForGenQuery error,stat=%d", i );
            if ( i != NO_MICROSERVICE_FOUND_ERR ) {
                return i;
            }
        }
    }
    /**  June 1 2009 for pre-post processing rule hooks **/

    status = chlGenQuery( *genQueryInp, *genQueryOut );

    // =-=-=-=-=-=-=-
    // if a disable was requested, repave with old value immediately
    if ( agent_conn_flag && dis_kw ) {
        chlGenQueryAccessControlSetup(
            rsComm->clientUser.userName,
            rsComm->clientUser.rodsZone,
            rsComm->clientAddr,
            rsComm->clientUser.authInfo.authFlag,
            old_acl_val );
    }

    /**  June 1 2009 for pre-post processing rule hooks **/
    if ( PrePostProcForGenQueryFlag == 1 ) {
        std::string in_string = str( boost::format( "%ld" ) % ( ( long )genQueryInp ) );
        std::string out_string = str( boost::format( "%ld" ) % ( ( long )genQueryOut ) );
        std::string status_string = str( boost::format( "%d" ) % ( ( long )status ) );
        args[0] = in_string.c_str();
        args[1] = out_string.c_str();
        args[2] = status_string.c_str();
        argc = 3;
        i =  applyRuleArg( "acPostProcForGenQuery", args, argc, &rei2, NO_SAVE_REI );
        if ( i < 0 ) {
            rodsLog( LOG_ERROR,
                     "rsGenQuery:acPostProcForGenQuery error,stat=%d", i );
            if ( i != NO_MICROSERVICE_FOUND_ERR ) {
                return i;
            }
        }
    }
    /**  June 1 2009 for pre-post processing rule hooks **/

    // =-=-=-=-=-=-=-
    // handle queries from older clients
    if ( status >= 0 && resc_grp_attr_pos >= 0 ) {
        irods::error err = add_resc_grp_name_to_query_out( *genQueryOut, resc_grp_attr_pos );
        if ( !err.ok() ) {
            irods::log( PASS( err ) );
        }
    }

    if ( status >= 0 && resc_hier_attr_pos >= 0 ) {
        // restore COL_D_RESC_HIER in select index
        genQueryInp->selectInp.inx[resc_hier_attr_pos] = COL_D_RESC_HIER;

        // replace resc ids with resc hier strings in output
        irods::error err = add_resc_hier_name_to_query_out( *genQueryOut, resc_hier_attr_pos );
        if ( !err.ok() ) {
            irods::log( PASS( err ) );
        }
    }

    if ( status < 0 ) {
        if ( status != CAT_NO_ROWS_FOUND ) {
            rodsLog( LOG_NOTICE,
                     "_rsGenQuery: genQuery status = %d", status );
        }
        return status;
    }
    return status;
}

max_stars_repo_name: stefan-wolfsheimer/irods

max_issues_repo_name: stefan-wolfsheimer/irods

max_forks_repo_name: stefan-wolfsheimer/irods


text:
/**
 * @author Alessandro Bianco
 */

/**
 * @addtogroup DFNs
 * @{
 */

#include "LeastSquaresMinimization.hpp"

#include <Errors/Assert.hpp>
#include <Macros/YamlcppMacros.hpp>

#include <opencv2/calib3d.hpp>
#include <Eigen/Geometry>

#include <stdlib.h>
#include <fstream>

using namespace PoseWrapper;
using namespace MatrixWrapper;
using namespace CorrespondenceMap3DWrapper;
using namespace Helpers;
using namespace BaseTypesWrapper;

namespace CDFF
{
namespace DFN
{
namespace Transform3DEstimation
{

LeastSquaresMinimization::LeastSquaresMinimization()
{
        parameters = DEFAULT_PARAMETERS;

	parametersHelper.AddParameter<float>("GeneralParameters", "MaximumAllowedError", parameters.maximumAllowedError, DEFAULT_PARAMETERS.maximumAllowedError);

	configurationFilePath = "";
	SetPosition(emptyPose, 0, 0, 0);
	SetOrientation(emptyPose, 0, 0, 0, 0);
}

LeastSquaresMinimization::~LeastSquaresMinimization()
{
}

void LeastSquaresMinimization::configure()
{
	parametersHelper.ReadFile(configurationFilePath);
	ValidateParameters();
}

void LeastSquaresMinimization::process()
{
	int numberOfCorrespondences = GetNumberOfCorrespondenceMaps(inMatches);
	Clear(outTransforms);
	for(int mapIndex = 0; mapIndex < numberOfCorrespondences; mapIndex++)
		{
		const CorrespondenceMap3D& map = GetCorrespondenceMap(inMatches, mapIndex);

		cv::Mat coefficientMatrix, valueMatrix;
		bool success = CreateLinearSystem(map, coefficientMatrix, valueMatrix);

		cv::Mat transformMatrix;
		if (success)
			{
			transformMatrix = SolveLinearSystem(coefficientMatrix, valueMatrix, outError);
			}

		if (!success || outError > parameters.maximumAllowedError)
			{
			if (numberOfCorrespondences == 1)
				{
				outSuccess = false;
				return;
				}
			else
				{
				AddPose(outTransforms, emptyPose);
				}
			}
		else
			{
			AddTransformOutput(transformMatrix);
			}
		}
	outSuccess = true;
}

bool LeastSquaresMinimization::CreateLinearSystem(const CorrespondenceMap3D& map, cv::Mat& coefficientMatrix, cv::Mat& valueMatrix)
	{
	const float EPSILON = 0.00001;
	const int NUMBER_OF_DEGREES_OF_FREEDOM = 6;
	const int NUMBER_OF_VARIABLES = 12;

	coefficientMatrix = cv::Mat();
	valueMatrix = cv::Mat();
	for(int correspondenceIndex = 0; correspondenceIndex < GetNumberOfCorrespondences(map); correspondenceIndex++)
		{
		Point3D source = GetSource(map, correspondenceIndex);
		Point3D sink = GetSink(map, correspondenceIndex);

		if (source.x != source.x || source.y != source.y || source.z != source.z || sink.x != sink.x || sink.y != sink.y || sink.z != sink.z)
			{
			continue;
			}

		cv::Mat coefficientMatrixPart = ( cv::Mat_<float>(3, 12) <<
			source.x, source.y, source.z, 1,    0, 0, 0, 0,    0, 0, 0, 0,
			0, 0, 0, 0,   source.x, source.y, source.z, 1,     0, 0, 0, 0,
			0, 0, 0, 0,   0, 0, 0, 0,     source.x, source.y, source.z, 1 );
		cv::Mat valueMatrixPart = ( cv::Mat_<float>(3, 1) << sink.x, sink.y, sink.z);

		if (coefficientMatrix.rows == 0)
			{
			coefficientMatrix = coefficientMatrixPart;
			valueMatrix = valueMatrixPart;
			}
		else
			{
			cv::Mat matrixList[2] = {coefficientMatrix, coefficientMatrixPart};
			cv::vconcat(matrixList, 2, coefficientMatrix);
			matrixList[0] = valueMatrix;
			matrixList[1] = valueMatrixPart;
			cv::vconcat(matrixList, 2, valueMatrix);
			}
		}

	if ( coefficientMatrix.rows < NUMBER_OF_VARIABLES )
		{
		return false;
		}

	cv::Mat singulaValueMatrix;
	cv::SVD::compute(coefficientMatrix, singulaValueMatrix);
	int rank = cv::countNonZero( singulaValueMatrix > EPSILON );
	return ( rank >= NUMBER_OF_DEGREES_OF_FREEDOM );
	}

cv::Mat LeastSquaresMinimization::SolveLinearSystem(cv::Mat coefficientMatrix, cv::Mat valueMatrix, float& error)
	{
	cv::Mat pseudoInverse;
	cv::invert(coefficientMatrix, pseudoInverse, cv::DECOMP_SVD);
	cv::Mat transformMatrix = pseudoInverse * valueMatrix;

	cv::Mat errorMatrix = coefficientMatrix * transformMatrix - valueMatrix;
	error = cv::norm(errorMatrix);
	return transformMatrix;
	}

void LeastSquaresMinimization::AddTransformOutput(cv::Mat transformMatrix)
	{
	cv::Mat rotationMatrix = (cv::Mat_<float>(3, 3) <<
		transformMatrix.at<float>(0), transformMatrix.at<float>(1), transformMatrix.at<float>(2),
		transformMatrix.at<float>(4), transformMatrix.at<float>(5), transformMatrix.at<float>(6),
		transformMatrix.at<float>(8), transformMatrix.at<float>(9), transformMatrix.at<float>(10) );
	cv::Mat translationVector = (cv::Mat_<float>(3,1) << transformMatrix.at<float>(3), transformMatrix.at<float>(7), transformMatrix.at<float>(11));

	cv::Mat position = - rotationMatrix.inv() * translationVector;

	Pose3D pose;
	SetPosition(pose, position.at<float>(0, 0), position.at<float>(1, 0), position.at<float>(2, 0) );

	float qw = std::sqrt(1.00 + rotationMatrix.at<float>(0,0) + rotationMatrix.at<float>(1,1) + rotationMatrix.at<float>(2,2)) / 2;
	float qx = (rotationMatrix.at<float>(2,1) - rotationMatrix.at<float>(1,2)) / ( 4 * qw );
	float qy = (rotationMatrix.at<float>(0,2) - rotationMatrix.at<float>(2,0)) / ( 4 * qw );
	float qz = (rotationMatrix.at<float>(1,0) - rotationMatrix.at<float>(0,1)) / ( 4 * qw );
	SetOrientation(pose, qx, qy, qz, qw);

	AddPose(outTransforms, pose);
	}

const LeastSquaresMinimization::LeastSquaresMinimizationOptionsSet LeastSquaresMinimization::DEFAULT_PARAMETERS =
{
	/*.maximumAllowedError =*/ 0.001
};

void LeastSquaresMinimization::ValidateParameters()
{
	ASSERT(parameters.maximumAllowedError > 0, "LeastSquaresMinimization Configuration Error: maximumAllowedError has to be positive");
}

void LeastSquaresMinimization::ValidateInputs(const CorrespondenceMap3D& map)
{

}

}
}
}

/** @} */


text:
#include <thread>
#include <functional>
#include <deque>
#include <iostream>

#include "ThreadPool.h"

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE C_SYNC_QUEUE_TEST
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(Thread_Pool_Test)
{
    unsigned int n = 400000;
    ThreadPool pool(4);
    bool answers[n];
    for(int i = 0; i < n; ++i)
        answers[i] = false;
    for(int i = 0; i < n; ++i)
    {
       pool.AddTask([=, &answers]()
        {
            answers[i] = true;
        });
    }
    pool.Terminate();
    for(int i = 0; i < n; ++i)
    {
        if(!answers[i])
            std::cout << i << std::endl;
        BOOST_CHECK(answers[i] == true);
    }
}

max_stars_repo_name: IKholopov/RayTracing

max_issues_repo_name: IKholopov/RayTracing

max_forks_repo_name: IKholopov/RayTracing


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

#ifndef __SCARPHASE_PROFILER_HPP
#define __SCARPHASE_PROFILER_HPP

#include <map>
#include <set>
#include <list>

#include <boost/date_time.hpp>
#include <boost/program_options.hpp>

#include <boost/unordered_map.hpp>

#include <boost/scoped_ptr.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

#include <scarphase.h>
#include <scarphase/scarphase_debug.h>
#include <scarphase/scarphase_perfevent.h>

#include <scarphase/internal/util/perf_event_wrapper.hpp>

#include <libunwind-ptrace.h>

#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/coded_stream.h>

#include "scarphase/proto/data.pb.h"
#include "scarphase/proto/meta.pb.h"

#include "scarphase/multiplexer/multiplexer.hpp"

namespace scarphase {

/**
 * @brief
 */
class Profiler
{

public:

    /**
     * @brief C-tor.
     */
    Profiler(boost::program_options::variables_map &vm);

    /**
     * @brief Start profiling.
     */
    int Profile(char *path, char *argv[]);

private:

    /**
     * @briefvoid
Profiler::HandleNewThread(pid_t tid)
{
     */
    typedef scarphase::internal::util::perf_event_wrapper::Event PerfEvent;

    /**
     * @brief
     */
    struct _Conf
    {

        /**
         * @brief If verbose output.
         */
        bool verbose;

        /**
         * @brief Program options.
         */
        boost::program_options::variables_map vm;

        /**
         * @brief Scarphase settings.
         */
        scarphase_monitor_attr_t attr;

        /**
         * @brief Scarphase perfevent data accessor settings.
         */
        scarphase_perfevent_attr_t perfevent_attr;

    } conf;

    /**
     * @brief
     */
    struct ThreadControlBlock
    {

        /**
         * @brief The thread id.
         */
        pid_t tid;

        /**
         * @brief
         */
        scarphase::proto::meta::ThreadInfo *proto;

        /**
         * @brief Handle to scarphase.
         */
        scarphase_handle_t scarphase_handle;

        /**
         * @brief
         */
        scarphase_data_accessor_t *scarhase_data_accessor;

        /**
         * @brief
         */
        void *libunwind_handle;

        /**
         * @brief
         */
        struct _Protobuf
        {

            /**
             * @brief
             */
            scarphase::proto::data::Header header;

            /**
             * @brief
             */
            scarphase::proto::data::WindowData window;

            /**
             * @brief
             */
            boost::scoped_ptr<google::protobuf::io::FileOutputStream> fos;

            /**
             * @brief
             */
            boost::scoped_ptr<google::protobuf::io::CodedOutputStream> cos;

        } proto_data;

        struct _Event
        {

            /**
             * @brief event_schedule
             */
            std::vector<int> active;

            /**
             * @brief
             */
            std::vector<uint64_t> values;

            /**
             * @brief
             */
            std::vector<int> cids;

            /**
             * @brief
             */
            boost::ptr_vector<PerfEvent> events;

        } event;

        /**
         * @brief
         */
        boost::scoped_ptr<scarphase::multiplexer::Multiplexer> multiplexer;

    };

    /**
     * @brief
     */
    struct ProcessControlBlock
    {

        /**
         * @brief The process id.
         */
        pid_t pid;

        /**
         * @brief
         */
        scarphase::proto::meta::ProcessInfo *proto;

    };

    /**
     * @brief
     */
    struct _Stats
    {

        /**
         * @brief
         */
        int no_phases;

        /**
         * @brief
         */
        uint64_t no_windows;

    } stats;

    /**
     * @brief Measure the execution time.
     */
    boost::posix_time::ptime time_0, time_1;

    /**
     * @brief The process id of the main thread.
     */
    pid_t root_process;

    /**
     * @brief A set of all running threads.
     */
    std::set<pid_t> tracked_threads;

    /**
     * @brief
     */
    std::set<pid_t> untracked_threads;

    /**
     * @brief All threads ever created.
     */
    std::map<pid_t, pid_t> thread2process_map;

    /**
     * @brief All threads ever created.
     */
    std::map<pid_t, ThreadControlBlock*> thread_table;

    /**
     * @brief All threads ever created.
     */
    std::map<pid_t, ProcessControlBlock*> proc_table;

    /**
     * @brief Profile.
     */
    unw_addr_space_t unw_addr_space;

    /**
     * @brief Profile.
     */
    scarphase::proto::meta::ProfileInfo proto;

    /**
     * @brief Fork a new process and execute command.
     */
    int ForkAndRun(char *path, char *argv[]);

    /**
     * @brief
     */
    ThreadControlBlock* ConfigureNewThread(pid_t tid);

    /**
     * @brief
     */
    void HandleNewUntrackedThread(pid_t tid);

    /**
     * @brief
     */
    void HandleNewThread(pid_t tid);

    /**
     * @brief
     */
    void LinkThreadAndProcess(pid_t tid, pid_t pid);

    /**
     * @brief
     */
    void HandleThreadExit(pid_t tid);

    /**
     * @brief
     */
    void HandleThreadExited(pid_t tid);

    /**
     * @brief
     */
    void HandleNewProcess(pid_t pid, pid_t parent);

    /**
     * @brief
     */
    void HandleExec(pid_t pid);

    /**
     * @brief
     */
    void HandleWindow(ThreadControlBlock *tcb, scarphase_event_info_t *info);

    /**
     * @brief Dump profile to a file.
     */
    void SaveProfile();

    /**
     * @brief
     */
    void LoadScarPhaseSettingsFromFile(const std::string &file);

    /**
     * @brief
     */
    void LoadPerformanceCountersFromFile(const std::string &file);

};

} /* namespace scarphase */

#endif /* __SCARPHASE_PROFILER_HPP */

max_stars_repo_name: emosy/scarphase

max_issues_repo_name: emosy/scarphase

max_forks_repo_name: emosy/scarphase


text:
#include "engine/sounds/streamable.h"

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>

engine::VorbisStreamable::VorbisStreamable(const std::filesystem::path & file):
  _file(fopen(file.c_str(), "rb"), &fclose),
  _vorbisFilePtr(nullptr, &ov_clear)
{
  if(ov_open_callbacks(_file.get(), &_vorbisFile, nullptr, 0, OV_CALLBACKS_NOCLOSE) != 0)
    throw std::runtime_error("Failed to open Vorbis file" + file.native());
  _vorbisFilePtr.reset(&_vorbisFile);

  _vorbisInfo = ov_info(&_vorbisFile, -1);
  _vorbisComment = ov_comment(&_vorbisFile, -1);

  BOOST_LOG_TRIVIAL(debug) << "Ogg/Vorbis" << file << " properties:";
  BOOST_LOG_TRIVIAL(debug) << "version         " << _vorbisInfo->version;
  BOOST_LOG_TRIVIAL(debug) << "channels        " << _vorbisInfo->channels;
  BOOST_LOG_TRIVIAL(debug) << "rate (hz)       " << _vorbisInfo->rate;
  BOOST_LOG_TRIVIAL(debug) << "bitrate upper   " << _vorbisInfo->bitrate_upper;
  BOOST_LOG_TRIVIAL(debug) << "bitrate nominal " << _vorbisInfo->bitrate_nominal;
  BOOST_LOG_TRIVIAL(debug) << "bitrate lower   " << _vorbisInfo->bitrate_lower;
  BOOST_LOG_TRIVIAL(debug) << "bitrate window  " << _vorbisInfo->bitrate_window;
  BOOST_LOG_TRIVIAL(debug) << "vendor " << _vorbisComment->vendor;
}

size_t engine::VorbisStreamable::stream(char * buffer, size_t bufferSize)
{
  int section = 0;
  size_t totalRead = 0;

  while(bufferSize > 0)
  {
    int result = ov_read(&_vorbisFile, buffer, bufferSize, 0, 2, 1, &section);
    if(result == 0)
    {
      break;
    }
    else if(result >= 0)
    {
      bufferSize -= result;
      buffer += result;
      totalRead += result;
    }
    else if(result == OV_HOLE)
      throw std::runtime_error("Data interruption");
    else if(result == OV_EBADLINK)
      throw std::runtime_error("Invalid stream section");
    else if(result == OV_EINVAL)
      throw std::runtime_error("Invalid file headers");
    else
      throw std::runtime_error("Unknown error");
  }
  return totalRead;
}

int engine::VorbisStreamable::getBitrate() const
{
  return _vorbisInfo->rate;
}

int engine::VorbisStreamable::getNominalBitrate() const
{
  return _vorbisInfo->bitrate_nominal;
}

int engine::VorbisStreamable::getNumChannels() const
{
  return _vorbisInfo->channels;
}

max_stars_repo_name: smallduckinette/engine

max_issues_repo_name: smallduckinette/engine

max_forks_repo_name: smallduckinette/engine