text:
//
// Copyright (c) 2019-2020 Ruben Perez Hidalgo (rubenperez038 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)
//

#include "boost/mysql/mysql.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/system/system_error.hpp>
#include <iostream>

/**
 * For this example, we will be using the 'boost_mysql_examples' database.
 * You can get this database by running db_setup.sql.
 * This example assumes you are connecting to MySQL server using
 * a UNIX socket. The socket path can be configured using command line
 * arguments, and defaults to /var/run/mysqld/mysqld.sock
 *
 * This example uses synchronous functions and handles errors using exceptions.
 */

void print_employee(const boost::mysql::row& employee)
{
    std::cout << "Employee '"
              << employee.values()[0] << " "                   // first_name (type std::string_view)
              << employee.values()[1] << "' earns "            // last_name  (type std::string_view)
              << employee.values()[2] << " dollars yearly\n";  // salary     (type double)
}

// UNIX sockets are only available in, er, UNIX systems. Typedefs for
// UNIX socket-based connections are only available in UNIX systems.
// Check for BOOST_ASIO_HAS_LOCAL_SOCKETS to know if UNIX socket
// typedefs are available in your system.
#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS

void main_impl(int argc, char** argv)
{
    if (argc != 3 && argc != 4)
    {
        std::cerr << "Usage: " << argv[0] << " <username> <password> [<socket-path>]\n";
        exit(1);
    }

    const char* socket_path = "/var/run/mysqld/mysqld.sock";
    if (argc == 4)
    {
        socket_path = argv[3];
    }

    /**
     * Connection parameters that tell us where and how to connect to the MySQL server.
     * There are two types of parameters:
     *   - UNIX-level connection parameters, identifying the UNIX socket to connect to.
     *   - MySQL level parameters: database credentials and schema to use.
     */
    boost::asio::local::stream_protocol::endpoint ep (socket_path);
    boost::mysql::connection_params params (
        argv[1],               // username
        argv[2],               // password
        "boost_mysql_examples" // database to use; leave empty or omit the parameter for no database
    );
    // Note: by default, SSL will be used if the server supports it.
    // connection_params accepts an optional ssl_options argument
    // determining whether to use SSL or not. See ssl_options and ssl_mode
    // documentation for further details on SSL.

    boost::asio::io_context ctx;

    // Connection to the MySQL server, over a UNIX socket
    boost::mysql::unix_connection conn (ctx);
    conn.connect(ep, params); // UNIX socket connect and MySQL handshake

    const char* sql = "SELECT first_name, last_name, salary FROM employee WHERE company_id = 'HGS'";
    boost::mysql::unix_resultset result = conn.query(sql);

    // Get all the rows in the resultset
    std::vector<boost::mysql::owning_row> employees = result.fetch_all();
    for (const auto& employee: employees)
    {
        print_employee(employee);
    }

    // We can issue any SQL statement, not only SELECTs. In this case, the returned
    // resultset will have no fields and no rows
    sql = "UPDATE employee SET salary = 10000 WHERE first_name = 'Underpaid'";
    result = conn.query(sql);
    assert(result.fields().size() == 0); // fields() returns a vector containing metadata about the query fields

    // Check we have updated our poor intern salary
    result = conn.query("SELECT salary FROM employee WHERE first_name = 'Underpaid'");
    auto rows = result.fetch_all();
    assert(rows.size() == 1);
    [[maybe_unused]] double salary = rows[0].values()[0].get<double>();
    assert(salary == 10000);

    // Notify the MySQL server we want to quit, then close the underlying connection.
    conn.close();
}

#else

void main_impl(int, char**)
{
    std::cout << "Sorry, your system does not support UNIX sockets" << std::endl;
}

#endif

int main(int argc, char** argv)
{
    try
    {
        main_impl(argc, argv);
    }
    catch (const boost::system::system_error& err)
    {
        std::cerr << "Error: " << err.what() << ", error code: " << err.code() << std::endl;
        return 1;
    }
    catch (const std::exception& err)
    {
        std::cerr << "Error: " << err.what() << std::endl;
        return 1;
    }
}

max_stars_repo_name: AlexAndDad/mysql-asio

max_issues_repo_name: AlexAndDad/mysql-asio

max_forks_repo_name: AlexAndDad/mysql-asio


text:
/*!
@file
Forward declares `boost::hana::Comparable`.

@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_FWD_COMPARABLE_HPP
#define BOOST_HANA_FWD_COMPARABLE_HPP

#include <boost/hana/detail/create.hpp>
#include <boost/hana/detail/std/forward.hpp>
#include <boost/hana/fwd/core/datatype.hpp>
#include <boost/hana/fwd/core/operators.hpp>

namespace boost { namespace hana {
    //! @ingroup group-concepts
    //! The `Comparable` concept defines equality and inequality.
    //!
    //! Intuitively, `Comparable` objects must define a binary predicate named
    //! `equal` that returns whether both objects represent the same abstract
    //! value. In other words, `equal` must check for deep equality. Since
    //! "representing the same abstract value" is difficult to express
    //! formally, the exact meaning of equality is partially left to
    //! interpretation by the programmer with the following guidelines:\n
    //! 1. Equality should be compatible with copy construction; copy
    //!    constructing a value yields an `equal` value.
    //! 2. Equality should be independent of representation; an object
    //!    representing the fraction `0/2` should be `equal` to an object
    //!    representing `0/4`, because they both represent the mathematical
    //!    object `0`.
    //!
    //! Moreover, `equal` must exhibit properties that make it intuitive to
    //! use for determining the equivalence of objects, which is formalized
    //! by the following laws.
    //!
    //!
    //! Laws
    //! ----
    //! `equal` must define an [equivalence relation][1], and `not_equal` must
    //! be its complement. In other words, for all objects `a`, `b`, `c` of a
    //! `Comparable` data type, the following must be true (where `x == y` and
    //! `x != y` denote `equal(x, y)` and `not_equal(x, y)`, respectively):
    //! @code
    //!     a == a                          // Reflexivity
    //!     if a == b then b == a           // Symmetry
    //!     if a == b && b == c then a == c // Transitivity
    //!     a != b is equivalent to !(a == b)
    //! @endcode
    //!
    //!
    //! Minimal complete definition
    //! ---------------------------
    //! 1. `equal`\n
    //! When `equal` is defined, `not_equal` is implemented by default as its
    //! complement. For all objects `x`, `y` of a `Comparable` data type,
    //! @code
    //!     not_equal(x, y) == not_(equal(x, y))
    //! @endcode
    //!
    //!
    //! Provided models
    //! ---------------
    //! 1. For `EqualityComparable` data types\n
    //! Two data types `T` and `U` that model the cross-type EqualityComparable
    //! concept presented in [N3351][2] automatically model the `Comparable`
    //! concept by setting
    //! @code
    //!     equal(x, y) = (x == y)
    //! @endcode
    //! Note that this also makes EqualityComparable types in the
    //! [usual sense][3] models of `Comparable` in the same way.
    //!
    //!
    //! Operators
    //! ---------
    //! For convenience, the following operators are provided as an
    //! equivalent way of calling the corresponding method:
    //! @code
    //!     ==  ->  equal
    //!     !=  ->  not_equal
    //! @endcode
    //!
    //!
    //! Equality-preserving functions
    //! -----------------------------
    //! Let `A` and `B` be two `Comparable` data types. A function
    //! @f$ f : A \to B @f$ is said to be equality-preserving if it preserves
    //! the structure of the `Comparable` concept, which can be rigorously
    //! stated as follows. For all objects `x`, `y` of data type `A`,
    //! @code
    //!     if  equal(x, y)  then  equal(f(x), f(y))
    //! @endcode
    //! Equivalently, we simply require that `f` is a function in the usual
    //! mathematical sense. Another property is [injectivity][4], which can be
    //! viewed as being a "lossless" mapping. This property can be stated as
    //! @code
    //!     if  equal(f(x), f(y))  then  equal(x, y)
    //! @endcode
    //! This is equivalent to saying that `f` maps distinct elements to
    //! distinct elements, hence the "lossless" analogy. In other words, `f`
    //! will not collapse distinct elements from its domain into a single
    //! element in its image, thus losing information.
    //!
    //! These functions are very important, especially equality-preserving
    //! ones, because they allow us to reason simply about programs. Also
    //! note that the property of being equality-preserving is taken for
    //! granted in mathematics because it is part of the definition of a
    //! function. We feel it is important to make the distinction here
    //! because programming has evolved differently and as a result
    //! programmers are used to work with functions that do not preserve
    //! equality.
    //!
    //!
    //! Cross-type version of the methods
    //! ---------------------------------
    //! The `equal` and `not_equal` methods are "overloaded" to handle
    //! distinct data types with certain properties. Specifically, they
    //! are defined for _distinct_ data types `A` and `B` such that
    //! 1. `A` and `B` share a common data type `C`, as determined by the
    //!    `common` metafunction
    //! 2. `A`, `B` and `C` are all `Comparable` when taken individually
    //! 3. @f$ \mathrm{to<C>} : A \to C @f$ and @f$\mathrm{to<C>} : B \to C@f$
    //!    are both equality-preserving and injective (i.e. they are embeddings),
    //!    as determined by the `is_embedding` metafunction.
    //!
    //! The method definitions for data types satisfying the above
    //! properties are
    //! @code
    //!     equal(x, y)     = equal(to<C>(x), to<C>(y))
    //!     not_equal(x, y) = not_equal(to<C>(x), to<C>(y))
    //! @endcode
    //!
    //!
    //! Important note: special behavior of `equal`
    //! -------------------------------------------
    //! In the context of programming with heterogeneous values, it is useful
    //! to have unrelated objects compare `false` instead of triggering an
    //! error. For this reason, `equal` adopts a special behavior for
    //! unrelated objects of data types `T` and `U` that do not satisfy the
    //! above requirements for the cross-type overloads. Specifically, when
    //! `T` and `U` are unrelated (i.e. `T` can't be converted to `U` and
    //! vice-versa), comparing objects of those data types yields a
    //! compile-time false value. This has the effect that unrelated objects
    //! like `float` and `std::string` will compare false, while comparing
    //! related objects that can not be safely embedded into the same super
    //! structure (like `long long` and `float` because of the precision loss)
    //! will trigger a compile-time assertion. Also note that for any data type
    //! `T` for which the minimial complete definition of `Comparable` is not
    //! provided, a compile-time assertion will also be triggered because `T`
    //! and `T` trivially share the common data type `T`, which is the expected
    //! behavior. This design choice aims to provide more flexibility for
    //! comparing objects, while still rejecting usage patterns that are
    //! most likely programming errors.
    //!
    //!
    //! @todo
    //! - Make sure no circularity issue with our provided operators can
    //! arise when checking for the EqualityComparable concept.
    //! - We could do some data type checks at the interface level,
    //! but those checks would be a bit hairy because of the cross-type
    //! methods. How should we handle that?
    //!
    //!
    //! [1]: http://en.wikipedia.org/wiki/Equivalence_relation#Definition
    //! [2]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf
    //! [3]: http://en.cppreference.com/w/cpp/concept/EqualityComparable
    //! [4]: http://en.wikipedia.org/wiki/Injective_function
    struct Comparable { };

    //! Returns a `Logical` representing whether `x` is equal to `y`.
    //! @relates Comparable
    //!
    //! The `equal` function can be called in two different ways. First, it
    //! can be called like a normal function:
    //! @code
    //!     equal(x, y)
    //! @endcode
    //!
    //! However, it may also be partially applied to an argument by using
    //! `equal.to`:
    //! @code
    //!     equal.to(x)(y) == equal(x, y)
    //! @endcode
    //!
    //! In other words, `equal.to(x)` is a function object that is equivalent
    //! to `partial(equal, x)`. This is provided to enhance the readability of
    //! some constructs, especially when using higher order algorithms.
    //!
    //!
    //! Signature
    //! ---------
    //! Given a Logical `Bool` and two Comparables `A` and `B` that
    //! share a common embedding, the signature is
    //! @f$ \mathrm{equal} : A \times B \to Bool @f$.
    //!
    //! @param x, y
    //! Two objects to compare for equality.
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/comparable.cpp equal
    //!
    //!
    //! > #### Rationale for the arity of `equal`
    //! > It is a valid question whether `equal` should accept more than 2
    //! > arguments and have semantics matching those of Python's `==`. This
    //! > is not supported right now for the following reasons:
    //! > - It was implemented in the MPL11, but it was not shown to be useful
    //! >   so far.
    //! > - It does not make sense for `not_equal` to have an arity of more
    //! >   than 2, only `equal` could maybe have those semantics, which would
    //! >   break symmetry.
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto equal = [](auto&& x, auto&& y) -> decltype(auto) {
        return tag-dispatched;
    };
#else
    template <typename T, typename U, typename = void>
    struct equal_impl;

    struct _equal {
        template <typename X, typename Y>
        constexpr decltype(auto) operator()(X&& x, Y&& y) const {
            return equal_impl<
                typename datatype<X>::type, typename datatype<Y>::type
            >::apply(
                detail::std::forward<X>(x),
                detail::std::forward<Y>(y)
            );
        }

        struct _to {
            template <typename X>
            constexpr decltype(auto) operator()(X&& x) const;
        };
        static constexpr _to to{};
    };
    constexpr _equal::_to _equal::to;

    constexpr _equal equal{};
#endif

    //! Returns a `Logical` representing whether `x` is not equal to `y`.
    //! @relates Comparable
    //!
    //! The `not_equal` function can be called in two different ways. First,
    //! it can be called like a normal function:
    //! @code
    //!     not_equal(x, y)
    //! @endcode
    //!
    //! However, it may also be partially applied to an argument by using
    //! `not_equal.to`:
    //! @code
    //!     not_equal.to(x)(y) == not_equal(x, y)
    //! @endcode
    //!
    //! In other words, `not_equal.to(x)` is a function object that is
    //! equivalent to `partial(not_equal, x)`. This is provided to enhance
    //! the readability of some constructs, especially when using higher
    //! order algorithms.
    //!
    //!
    //! Signature
    //! ---------
    //! Given a Logical `Bool` and two Comparables `A` and `B` that
    //! share a common embedding, the signature is
    //! @f$ \mathrm{not\_equal} : A \times B \to Bool @f$.
    //!
    //! @param x, y
    //! Two objects to compare for inequality.
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/comparable.cpp not_equal
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto not_equal = [](auto&& x, auto&& y) -> decltype(auto) {
        return tag-dispatched;
    };
#else
    template <typename T, typename U, typename = void>
    struct not_equal_impl;

    struct _not_equal {
        template <typename X, typename Y>
        constexpr decltype(auto) operator()(X&& x, Y&& y) const {
            return not_equal_impl<
                typename datatype<X>::type, typename datatype<Y>::type
            >::apply(
                detail::std::forward<X>(x),
                detail::std::forward<Y>(y)
            );
        }

        struct _to {
            template <typename X>
            constexpr decltype(auto) operator()(X&& x) const;
        };
        static constexpr _to to{};
    };
    constexpr _not_equal::_to _not_equal::to;

    constexpr _not_equal not_equal{};
#endif

    //! Returns a function performing `equal` after applying a transformation
    //! to both arguments.
    //! @relates Comparable
    //!
    //! `comparing` creates an equivalence relation based on the result of
    //! applying a function to some objects, which is especially useful in
    //! conjunction with algorithms that accept a custom predicate that must
    //! represent an equivalence relation.
    //!
    //! Specifically, `comparing` is such that
    //! @code
    //!     comparing(f) == equal ^on^ f
    //! @endcode
    //! or, equivalently,
    //! @code
    //!     comparing(f)(x, y) == equal(f(x), f(y))
    //! @endcode
    //!
    //! @note
    //! This is not a tag-dispatched method (hence it can't be customized),
    //! but just a convenience function provided with the `Comparable` concept.
    //!
    //!
    //! Signature
    //! ---------
    //! Given a Logical `Bool` and a Comparable `B`, the signature is
    //! @f$ \mathrm{comparing} : (A \to B) \to (A \times A \to Bool) @f$.
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/comparable.cpp comparing
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto comparing = [](auto&& f) {
        return [perfect-capture](auto&& x, auto&& y) -> decltype(auto) {
            return equal(f(forwarded(x)), f(forwarded(y)));
        };
    };
#else
    template <typename F>
    struct _comparing;

    constexpr detail::create<_comparing> comparing{};
#endif

    template <>
    struct operators::of<Comparable>
        : decltype(equal), decltype(not_equal)
    { };
}} // end namespace boost::hana

#endif // !BOOST_HANA_FWD_COMPARABLE_HPP

ext: hpp

max_stars_repo_name: josephwinston/hana

max_issues_repo_name: josephwinston/hana

max_forks_repo_name: josephwinston/hana


text:
/**
   @file streamchannel.cpp
   @brief This file is part of Kalinka mediaserver.
   @author Ivan Murashko <ivan.murashko@gmail.com>

   Copyright (c) 2007-2012 Kalinka Team

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

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

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

   CHANGE HISTORY

   @date
   - 2008/11/03 created by ipp (Ivan Murashko)
   - 2009/01/04 some exceptions were added by ipp (Ivan Murashko)
   - 2009/06/19 Tuned channel staff was removed
   - 2009/08/02 header was changed by header.py script
   - 2010/01/06 header was changed by header.py script
   - 2011/01/01 header was changed by header.py script
   - 2012/02/03 header was changed by header.py script
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <boost/bind.hpp>

#include "streamchannel.h"
#include "log.h"
#include "dev.h"
#include "utils.h"
#include "traps.h"
#include "dvbdev.h"
#include "exception.h"

using namespace klk;
using namespace klk::dvb;

//
// StreamChannel class
//

// Constructor
StreamChannel::StreamChannel(const std::string& type,
                             const std::string& source,
                             IFactory* factory) :
    m_factory(factory),
    m_channel_id(""),
    m_type(type), m_source(source),
    m_name(""), m_number(""),
    m_dev()
{
    BOOST_ASSERT(m_factory);
}

// Destructor
StreamChannel::~StreamChannel()
{
}

// Sets the data
void StreamChannel::setData(const std::string& channel_id)
{
    m_channel_id = channel_id;
    BOOST_ASSERT(m_type.getValue().empty() == false);
    if (m_type == dev::DVB_S)
    {
        setTune4DVBS();
    }
    else if (m_type == dev::DVB_T)
    {
        setTune4DVBT();
    }
    else
    {
        // not supported type
        NOTIMPLEMENTED;
    }

    BOOST_ASSERT(m_name.getValue().empty() == false);
    BOOST_ASSERT(m_number.getValue().empty() == false);
}

// tune DVB-S dev
void StreamChannel::setTune4DVBS()
{
    BOOST_ASSERT(m_channel_id.getValue().empty() == false);
    BOOST_ASSERT(m_type.getValue() == dev::DVB_S);

    // retrive info from DB
    db::Parameters params;
    params.add("@channel", m_channel_id);
    const std::string spname = "klk_dvb_s_channel_get";
    // IN channel VARCHAR(40),
    // OUT signal_source VARCHAR(40),
    // OUT name VARCHAR(50),
    // OUT provider VARCHAR(50),
    // OUT diseqc_source TINYINT,
    // OUT frequency INT,
    // OUT polarity TINYINT,
    // OUT symbol_rate INT,
    // OUT code_rate_hp TINYINT,
    // OUT channel_no INTEGER,
    // OUT return_value INT
    params.add("@signal_source");
    params.add("@name");
    params.add("@provider");
    params.add("@diseqc_source");
    params.add("@frequency");
    params.add("@polarity");
    params.add("@symbol_rate");
    params.add("@code_rate_hp");
    params.add("@channel_no");
    params.add("@return_value");
    db::DB db(m_factory);
    db.connect();
    db::Result result = db.callSimple(spname, params);
    if (result["@return_value"].toInt() != 0)
    {
        throw Exception(
            __FILE__, __LINE__,
            "Cannot retrive info for DVB-S channel with id '" +
            m_channel_id.getValue() + "'");
    }
    // parameters
    const int frequency = result["@frequency"].toInt();
    const int code_rate_hp = result["@code_rate_hp"].toInt();
    const std::string polarity = result["@polarity"].toString();
    BOOST_ASSERT(polarity.empty() == false);
    const int symbol_rate = result["@symbol_rate"].toInt();
    const int diseqc_src = result["@diseqc_source"].toInt();
    BOOST_ASSERT(m_dev == NULL);
    findWorkingDev(frequency);
    if (m_dev)
    {
        // found something
        // check it
        BOOST_ASSERT(frequency == m_dev->getIntParam(dev::FREQUENCY));
        BOOST_ASSERT(code_rate_hp == m_dev->getIntParam(dev::CODE_RATE_HP));
        BOOST_ASSERT(polarity == m_dev->getStringParam(dev::POLARITY));
        BOOST_ASSERT(symbol_rate == m_dev->getIntParam(dev::SYMBOL_RATE));
        BOOST_ASSERT(diseqc_src == m_dev->getIntParam(dev::DISEQC_SRC));
    }
    else
    {
        findFreeDev();
        if (m_dev)
        {
            m_dev->setParam(dev::FREQUENCY, frequency);
            m_dev->setParam(dev::CODE_RATE_HP, code_rate_hp);
            m_dev->setParam(dev::POLARITY, polarity);
            m_dev->setParam(dev::SYMBOL_RATE, symbol_rate);
            m_dev->setParam(dev::DISEQC_SRC, diseqc_src);
        }
    }

    if (!m_dev)
    {
        // we could not find the dev
        throw Exception(__FILE__, __LINE__,
                             "There is no any free DVB-S card for channel "
                             "with ID: " +
                             m_channel_id.getValue());
    }

    // final setup
    m_name = result["@name"].toString();
    BOOST_ASSERT(m_name.getValue().empty() == false);
    m_number = result["@channel_no"].toString();
    BOOST_ASSERT(m_number.getValue().empty() == false);
}

// tune DVB-T dev
void StreamChannel::setTune4DVBT()
{
    BOOST_ASSERT(m_channel_id.getValue().empty() == false);
    BOOST_ASSERT(m_type.getValue() == dev::DVB_T);

    // retrive info from DB
    db::Parameters params;
    params.add("@channel", m_channel_id);
    const std::string spname = "klk_dvb_t_channel_get";
    // IN channel VARCHAR(40),
    // OUT signal_source VARCHAR(40),
    // OUT name VARCHAR(50),
    // OUT provider VARCHAR(50),
    // OUT frequency INT,
    // OUT code_rate_hp TINYINT,
    // OUT code_rate_lp TINYINT,
    // OUT modulation TINYINT,
    // OUT transmode TINYINT,
    // OUT channel_no INTEGER,
    // OUT guard TINYINT,
    // OUT hierarchy TINYINT,
    // OUT bandwidth TINYINT,
    // OUT return_value INT
    params.add("@signal_source");
    params.add("@name");
    params.add("@provider");
    params.add("@frequency");
    params.add("@code_rate_hp");
    params.add("@code_rate_lp");
    params.add("@modulation");
    params.add("@transmode");
    params.add("@channel_no");
    params.add("@guard");
    params.add("@hierarchy");
    params.add("@bandwidth");
    params.add("@return_value");

    db::DB db(m_factory);
    db.connect();
    db::Result result = db.callSimple(spname, params);
    if (result["@return_value"].toInt() != 0)
    {
        throw Exception(
            __FILE__, __LINE__,
            "Cannot retrive info for DVB-T channel with id '" +
            m_channel_id.getValue() + "'");
    }
    // parameters
    const int frequency = result["@frequency"].toInt();
    const int code_rate_hp = result["@code_rate_hp"].toInt();
    const int code_rate_lp = result["@code_rate_lp"].toInt();
    const int modulation = result["@modulation"].toInt();
    const int transmode = result["@transmode"].toInt();
    const int guard = result["@guard"].toInt();
    const int hierarchy = result["@hierarchy"].toInt();
    const int bandwidth = result["@bandwidth"].toInt();

    BOOST_ASSERT(m_dev == NULL);
    findWorkingDev(frequency);
    if (m_dev)
    {
        // found something
        // check it
        BOOST_ASSERT(frequency == m_dev->getIntParam(dev::FREQUENCY));
        BOOST_ASSERT(code_rate_hp == m_dev->getIntParam(dev::CODE_RATE_HP));
        BOOST_ASSERT(code_rate_lp == m_dev->getIntParam(dev::CODE_RATE_LP));
        BOOST_ASSERT(modulation == m_dev->getIntParam(dev::MODULATION));
        BOOST_ASSERT(transmode == m_dev->getIntParam(dev::TRANSMODE));
        BOOST_ASSERT(guard == m_dev->getIntParam(dev::GUARD));
        BOOST_ASSERT(hierarchy == m_dev->getIntParam(dev::HIERARCHY));
        BOOST_ASSERT(bandwidth == m_dev->getIntParam(dev::DVBBANDWIDTH));
    }
    else
    {
        findFreeDev();
        if (m_dev)
        {
            m_dev->setParam(dev::FREQUENCY, frequency);
            m_dev->setParam(dev::CODE_RATE_HP, code_rate_hp);
            m_dev->setParam(dev::CODE_RATE_LP, code_rate_lp);
            m_dev->setParam(dev::MODULATION, modulation);
            m_dev->setParam(dev::TRANSMODE, transmode);
            m_dev->setParam(dev::GUARD, guard);
            m_dev->setParam(dev::HIERARCHY, hierarchy);
            m_dev->setParam(dev::DVBBANDWIDTH, bandwidth);
        }
    }

    if (!m_dev)
    {
        // we could not find the dev
        throw Exception(__FILE__, __LINE__,
                             "There is no any free DVB-T card for channel "
                             "with ID: " +
                             m_channel_id.getValue());
    }

    // final setup
    m_name = result["@name"].toString();
    BOOST_ASSERT(m_name.getValue().empty() == false);
    m_number = result["@channel_no"].toString();
    BOOST_ASSERT(m_number.getValue().empty() == false);
}

// equlance functor
struct CheckDevByFrequency
{
    inline bool operator()(const IDevPtr dev, int freq,
                           std::string source)
    {
        if (dev->hasParam(dev::SOURCE) == false)
            return false;

        if (dev->getIntParam(dev::LOSTLOCK) != 0)
        {
            klk_log(KLKLOG_DEBUG, "DVB dev '%s' has lost lock "
                    "and was ignored for continue streaming",
                    dev->getStringParam(dev::NAME).c_str());
            return false; // the dev lost lock
        }

        // look only STREAMMING
        if (!dev->hasParam(dev::DVBACTIVITY))
            return false; // ignore without activity
        if (dev->getStringParam(dev::DVBACTIVITY) != dev::STREAMING)
            return false; // ignore not streaming
        // Frequency should be set
        BOOST_ASSERT(dev->hasParam(dev::FREQUENCY) == true);
        return (dev->getIntParam(dev::FREQUENCY) == freq &&
                dev->getStringParam(dev::SOURCE) == source);
    }
};

// Finds a dev by frequency
void StreamChannel::findWorkingDev(const int frequency)
{
    IDevList devs = m_factory->getResources()->getResourceByType(m_type);
    IDevList::iterator find =
        std::find_if(devs.begin(), devs.end(),
                     boost::bind<bool>(CheckDevByFrequency(), _1,
                                       frequency, m_source.getValue()));
    if (find != devs.end())
    {
        m_dev = *find;
    }
}

struct CheckFreeDev
{
    inline bool operator()(const IDevPtr dev, const std::string source)
    {
        if (dev->hasParam(dev::SOURCE) == false)
            return false;

        if (dev->getIntParam(dev::LOSTLOCK) != 0)
        {
            klk_log(KLKLOG_DEBUG, "DVB dev '%s' has lost lock "
                    "and was ignored for new streaming",
                    dev->getStringParam(dev::NAME).c_str());
            return false; // the dev lost lock
        }

        return (dev->getState() == dev::IDLE &&
                dev->getStringParam(dev::SOURCE) == source);
    }
};

// Finds a not used dev
void StreamChannel::findFreeDev()
{
    IDevList devs = m_factory->getResources()->getResourceByType(m_type);
    IDevList::iterator find =
        std::find_if(devs.begin(), devs.end(),
                     boost::bind<bool>(CheckFreeDev(), _1,
                                       m_source.getValue()));
    if (find != devs.end())
    {
        m_dev = *find;
    }
}

// Gets resource (device)
const IDevPtr StreamChannel::getDev() const
{
    BOOST_ASSERT(m_dev);
    return m_dev;
}

// Gets name
const std::string StreamChannel::getName() const throw()
{
    return m_name.getValue();
}

// Gets number
const std::string StreamChannel::getNumber() const throw()
{
    return m_number.getValue();
}

// Gets the channel id
const std::string StreamChannel::getID() const throw()
{
    return m_channel_id.getValue();
}

//
// StreamContainer class
//

/**
   Functor to find a channel by id
*/
struct FindChannelByChannel :
    public std::binary_function<StreamChannelPtr, StreamChannelPtr, bool>
{
    /**
       Finder itself by channel
    */
    inline bool operator()(const StreamChannelPtr channel1,
                           const StreamChannelPtr channel2)
    {
        BOOST_ASSERT(channel1);
        BOOST_ASSERT(channel2);

        return (channel1->getID() == channel2->getID());
    }
};

// Constructor
StreamContainer::StreamContainer() :
    m_lock(), m_list()
{
}

// Destructor
StreamContainer::~StreamContainer()
{
}

// Copy constructor
StreamContainer::StreamContainer(const StreamContainer& value) :
    m_lock(), m_list()
{
    Locker lock(&value.m_lock);
    m_list = value.m_list;
}

// Removes stream channel
void StreamContainer::removeStreamChannel(const StreamChannelPtr& channel)
{
    BOOST_ASSERT(channel);

    Locker lock(&m_lock);
    StreamChannelList::iterator find =
        std::find_if(m_list.begin(), m_list.end(),
                     boost::bind(FindChannelByChannel(), _1, channel));
    if (find != m_list.end())
        m_list.erase(find);
}

// Insert stream channel
void StreamContainer::insertStreamChannel(const StreamChannelPtr& channel)
{
    BOOST_ASSERT(channel);

    Locker lock(&m_lock);
    StreamChannelList::iterator find =
        std::find_if(m_list.begin(), m_list.end(),
                     boost::bind(FindChannelByChannel(), _1, channel));
    if (find != m_list.end())
    {
        throw Exception(__FILE__, __LINE__,
                             "Channel '%s' with id '%s' "
                             "has been already added",
                             (*find)->getName().c_str(),
                             (*find)->getID().c_str());
    }

    m_list.push_back(channel);
}

// Retrives stream channels list for the specified device
const StreamChannelList
StreamContainer::getStreamChannels(const IDevPtr& dev) const
{
    BOOST_ASSERT(dev);

    StreamChannelList list;
    Locker lock(&m_lock);
    for (StreamChannelList::const_iterator i = m_list.begin();
         i != m_list.end(); i++)
    {
        if ((*i)->getDev() == dev)
        {
            // we should add it
            list.push_back(*i);
        }
    }

    return list;
}

// Clears the list
void StreamContainer::clear() throw()
{
    Locker lock(&m_lock);
    m_list.clear();
}

/**
   Functor to find a channel by id
*/
struct FindChannelByID :
    public std::binary_function<StreamChannelPtr, std::string, bool>
{
    /**
       Finder itself by channel
    */
    inline bool operator()(const StreamChannelPtr channel,
                           const std::string id)
    {
        BOOST_ASSERT(channel);

        return (channel->getID() == id);
    }
};

// Retrives stream channel
const StreamChannelPtr
StreamContainer::getStreamChannel(const std::string& id) const
{
    Locker lock(&m_lock);
    StreamChannelList::const_iterator find =
        std::find_if(m_list.begin(), m_list.end(),
                     boost::bind(FindChannelByID(), _1, id));

    if (find == m_list.end())
    {
        // nothing was find
        return StreamChannelPtr();
    }

    return *find;
}

// Check is there empty container or not
bool StreamContainer::empty() const throw()
{
    Locker lock(&m_lock);
    return m_list.empty();
}

ext: cpp

max_stars_repo_name: ivanmurashko/kalinka

max_issues_repo_name: ivanmurashko/kalinka

max_forks_repo_name: ivanmurashko/kalinka


text:
//
// Copyright (c) 2016-2017 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
//

#ifndef BOOST_BEAST_HANDLER_ALLOC_HPP
#define BOOST_BEAST_HANDLER_ALLOC_HPP

#include <boost/beast/config.hpp>
#include <boost/asio/handler_alloc_hook.hpp>
#include <boost/config.hpp>
#include <cstddef>
#include <cstdlib>
#include <memory>
#include <type_traits>
#include <utility>

namespace boost {
namespace beast {

// Guidance from
// http://howardhinnant.github.io/allocator_boilerplate.html

/** An allocator that uses handler customizations.

    This allocator uses the handler customizations `asio_handler_allocate`
    and `asio_handler_deallocate` to manage memory. It meets the requirements
    of @b Allocator and can be used anywhere a `std::allocator` is
    accepted.

    @tparam T The type of objects allocated by the allocator.

    @tparam Handler The type of handler.

    @note Memory allocated by this allocator must be freed before
    the handler is invoked or undefined behavior results. This behavior
    is described as the "deallocate before invocation" Asio guarantee.
*/
#if BOOST_BEAST_DOXYGEN
template<class T, class Handler>
class handler_alloc;
#else
template<class T, class Handler>
class handler_alloc
{
private:
    // We want a partial template specialization as a friend
    // but that isn't allowed so we friend all versions. This
    // should produce a compile error if Handler is not
    // constructible from H.
    //
    template<class U, class H>
    friend class handler_alloc;

    Handler& h_;

public:
    using value_type = T;
    using is_always_equal = std::true_type;
    using pointer = T*;
    using reference = T&;
    using const_pointer = T const*;
    using const_reference = T const&;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    template<class U>
    struct rebind
    {
        using other = handler_alloc<U, Handler>;
    };

    handler_alloc() = delete;
    handler_alloc(handler_alloc&&) = default;
    handler_alloc(handler_alloc const&) = default;
    handler_alloc& operator=(handler_alloc&&) = default;
    handler_alloc& operator=(handler_alloc const&) = default;

    /** Construct the allocator.

        A reference of the handler is stored. The handler must
        remain valid for at least the lifetime of the allocator.
    */
    explicit
    handler_alloc(Handler& h)
        : h_(h)
    {
    }

    /// Copy constructor
    template<class U>
    handler_alloc(
            handler_alloc<U, Handler> const& other)
        : h_(other.h_)
    {
    }

    value_type*
    allocate(size_type n)
    {
        auto const size = n * sizeof(T);
        using boost::asio::asio_handler_allocate;
        return static_cast<value_type*>(
            asio_handler_allocate(size, std::addressof(h_)));
    }

    void
    deallocate(value_type* p, size_type n)
    {
        auto const size = n * sizeof(T);
        using boost::asio::asio_handler_deallocate;
        asio_handler_deallocate(p, size, std::addressof(h_));
    }

//#if BOOST_WORKAROUND(BOOST_GCC, < 60000) // Works, but too coarse

#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000
    template<class U, class... Args>
    void
    construct(U* ptr, Args&&... args)
    {
        ::new((void*)ptr) U(std::forward<Args>(args)...);
    }

    template<class U>
    void
    destroy(U* ptr)
    {
        ptr->~U();
    }
#endif

    template<class U>
    friend
    bool
    operator==(
        handler_alloc const&,
        handler_alloc<U, Handler> const&)
    {
        return true;
    }

    template<class U>
    friend
    bool
    operator!=(
        handler_alloc const& lhs,
        handler_alloc<U, Handler> const& rhs)
    {
        return ! (lhs == rhs);
    }
};
#endif

} // beast
} // boost

#endif

max_stars_repo_name: Voultapher/Presentations

max_issues_repo_name: ceph/Beast


text:
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/chrono.hpp>
#include <boost/shared_ptr.hpp>

#include <iostream>
#include <cstdint>

#include "func.h"

#include <boost/version.hpp>
#if BOOST_VERSION < 105000
#define TIME_UTC_ TIME_UTC
#endif

struct thread_alarm
{
    thread_alarm(int secs) : m_secs(secs) { exit_code = IntPtr( new int(0) ); }
    void operator()()
    {
        boost::xtime xt;
        boost::xtime_get(&xt, boost::TIME_UTC_);
        xt.sec += m_secs;

        boost::thread::sleep(xt);

        std::cout << "alarm sounded..." << std::endl;

        *exit_code = 0xDEADBEEF;
    }

    int m_secs;

    typedef boost::shared_ptr<int> IntPtr;
    IntPtr exit_code;
};

int main(int argc, char* argv[])
{
    using namespace std;

    // int secs = WAIT_FOR_SECOND;
    // std::cout << "setting alarm for " << WAIT_FOR_SECOND << " seconds..." << std::endl;
    // thread_alarm alarm(secs);
    // boost::thread thrd(alarm);

    boost::thread waitfile(waitfile_thread, WAIT_REPEAT);
    waitfile.join();
    //std::cout << "exit code == 0x" << std::hex << *(alarm.exit_code) << std::endl;
    cout << "end of main\n";

    return 0;
}

max_stars_repo_name: ericosur/ccbox

max_issues_repo_name: ericosur/ccbox

max_forks_repo_name: ericosur/ccbox


text:
//==============================================================================
//         Copyright 2003 - 2012 LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012 LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_SIMD_SWAR_FUNCTIONS_SIMD_SSE_SSE2_DEINTERLEAVE_FIRST_HPP_INCLUDED
#define BOOST_SIMD_SWAR_FUNCTIONS_SIMD_SSE_SSE2_DEINTERLEAVE_FIRST_HPP_INCLUDED
#ifdef BOOST_SIMD_HAS_SSE2_SUPPORT

#include <boost/simd/swar/functions/deinterleave_first.hpp>
#include <boost/simd/swar/functions/details/shuffle.hpp>

namespace boost { namespace simd { namespace ext
{
  BOOST_DISPATCH_IMPLEMENT         ( deinterleave_first_
                                   , boost::simd::tag::sse2_
                                   , (A0)
                                   , ((simd_<single_<A0>,boost::simd::tag::sse_>))
                                     ((simd_<single_<A0>,boost::simd::tag::sse_>))
                                   )
  {
    typedef A0 result_type;

    BOOST_FORCEINLINE result_type operator()(A0 const& a0, A0 const& a1) const
    {
      return details::shuffle<0, 2, 0, 2>(a0,a1);
    }
  };

  BOOST_DISPATCH_IMPLEMENT         ( deinterleave_first_
                                   , boost::simd::tag::sse2_
                                   , (A0)
                                   , ((simd_<double_<A0>,boost::simd::tag::sse_>))
                                     ((simd_<double_<A0>,boost::simd::tag::sse_>))
                                   )
  {
    typedef A0 result_type;

    BOOST_FORCEINLINE result_type operator()(A0 const& a0, A0 const& a1) const
    {
      return _mm_unpacklo_pd(a0,a1);
    }
  };

  BOOST_DISPATCH_IMPLEMENT         ( deinterleave_first_
                                   , boost::simd::tag::sse2_
                                   , (A0)
                                   , ((simd_<ints16_<A0>,boost::simd::tag::sse_>))
                                     ((simd_<ints16_<A0>,boost::simd::tag::sse_>))
                                   )
  {
    typedef A0 result_type;

    BOOST_FORCEINLINE result_type operator()(A0 const& a0, A0 const& a1) const
    {
      result_type x = _mm_unpacklo_epi16(a0,a1);
      result_type y = _mm_unpackhi_epi16(a0,a1);

      return _mm_unpacklo_epi16 ( _mm_unpacklo_epi16(x,y)
                                , _mm_unpackhi_epi16(x,y)
                                );
    }
  };

  BOOST_DISPATCH_IMPLEMENT         ( deinterleave_first_
                                   , boost::simd::tag::sse2_
                                   , (A0)
                                   , ((simd_<ints32_<A0>,boost::simd::tag::sse_>))
                                     ((simd_<ints32_<A0>,boost::simd::tag::sse_>))
                                   )
  {
    typedef A0 result_type;

    BOOST_FORCEINLINE result_type operator()(A0 const& a0, A0 const& a1) const
    {
      return details::shuffle<0, 2, 0, 2>(a0,a1);
    }
  };

  BOOST_DISPATCH_IMPLEMENT         ( deinterleave_first_
                                   , boost::simd::tag::sse2_
                                   , (A0)
                                   , ((simd_<ints64_<A0>,boost::simd::tag::sse_>))
                                     ((simd_<ints64_<A0>,boost::simd::tag::sse_>))
                                   )
  {
    typedef A0 result_type;

    BOOST_FORCEINLINE result_type operator()(A0 const& a0, A0 const& a1) const
    {
      return  _mm_unpacklo_epi64( a0, a1 );
    }
  };

} } }

#endif
#endif


text:
/*
 * Copyright (C) 2022 Philippe Proulx <eepp.ca>
 *
 * This software may be modified and distributed under the terms
 * of the MIT license. See the LICENSE file for details.
 */

#ifndef _YACTFR_INTERNAL_METADATA_JSON_JSON_VAL_REQ_HPP
#define _YACTFR_INTERNAL_METADATA_JSON_JSON_VAL_REQ_HPP

#include <cassert>
#include <string>
#include <memory>
#include <regex>
#include <unordered_map>
#include <set>
#include <limits>
#include <sstream>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>

#include <yactfr/text-parse-error.hpp>

#include "json-val.hpp"

namespace yactfr {
namespace internal {

/*
 * JSON value requirement.
 *
 * This is the base of any JSON requirement class.
 *
 * An instance of this class validates that a JSON value has a given
 * type.
 */
class JsonValReq :
    boost::noncopyable
{
public:
    // shared pointer to constant JSON value requirement
    using SP = std::shared_ptr<const JsonValReq>;

public:
    /*
     * Builds a JSON value requirement: if `kind` is set, then
     * validate() validates that the kind of the JSON value is `*kind`.
     */
    explicit JsonValReq(boost::optional<JsonVal::Kind> kind = boost::none);

    virtual ~JsonValReq() = default;

    /*
     * Validates that `jsonVal` satisfies this requirement.
     */
    void validate(const JsonVal& jsonVal) const;

    /*
     * Returns a shared pointer to JSON value requirement, forwarding
     * the parameter to the constructor.
     */
    static SP shared(boost::optional<JsonVal::Kind> kind);

protected:
    /*
     * Requirement-specific validation.
     */
    virtual void _validate(const JsonVal& jsonVal) const;

private:
    // required JSON value kind
    boost::optional<JsonVal::Kind> _kind;
};

/*
 * JSON integer value in range requirement template.
 *
 * An instance of this class validates that, given a JSON value V of
 * type `JsonValT`:
 *
 * * V has the kind `KindV`.
 * * The raw value of V is within a given range.
 */
template <typename JsonValT, JsonVal::Kind KindV>
class JsonIntValInRangeReq :
    public JsonValReq
{
private:
    // raw value type
    using _Val = typename JsonValT::Val;

public:
    /*
     * Builds a JSON integer value in range requirement: _validate()
     * validates that the raw value of the JSON integer value is:
     *
     * * If `minVal` is set: greater than or equal to `*minVal`.
     * * If `maxVal` is set: less than or equal to `*maxVal`.
     */
    explicit JsonIntValInRangeReq(const boost::optional<_Val>& minVal,
                                  const boost::optional<_Val>& maxVal) :
        JsonValReq {KindV},
        _minVal {minVal ? *minVal : std::numeric_limits<_Val>::min()},
        _maxVal {maxVal ? *maxVal : std::numeric_limits<_Val>::max()}
    {
    }

    /*
     * Builds a JSON integer value in range requirement: _validate()
     * validates that the raw value of the JSON integer value is exactly
     * `exactVal`.
     */
    explicit JsonIntValInRangeReq(const _Val exactVal) :
        JsonIntValInRangeReq {exactVal, exactVal}
    {
    }

    /*
     * Returns a shared pointer to JSON integer value in range
     * requirement, forwarding the parameters to the constructor.
     */
    static SP shared(const boost::optional<_Val>& minVal, const boost::optional<_Val>& maxVal)
    {
        return std::make_shared<JsonIntValInRangeReq>(minVal, maxVal);
    }

    /*
     * Returns a shared pointer to JSON integer value in range
     * requirement, forwarding the parameter to the constructor.
     */
    static SP shared(const _Val exactVal)
    {
        return std::make_shared<JsonIntValInRangeReq>(exactVal);
    }

protected:
    void _validate(const JsonVal& jsonVal) const override
    {
        auto& jsonIntVal = static_cast<const JsonValT&>(jsonVal);

        if (*jsonIntVal < _minVal) {
            std::ostringstream ss;

            ss << "Integer " << *jsonIntVal << " is too small: " <<
                  "expecting at least " << _minVal << ".";
            throwTextParseError(ss.str(), jsonVal.loc());
        }

        if (*jsonIntVal > _maxVal) {
            std::ostringstream ss;

            ss << "Integer " << *jsonIntVal << " is too large: " <<
                  "expecting at most " << _maxVal << ".";
            throwTextParseError(ss.str(), jsonVal.loc());
        }
    }

private:
    // minimum raw value
    _Val _minVal;

    // maximum raw value
    _Val _maxVal;
};

/*
 * JSON unsigned integer value in range requirement.
 */
using JsonUIntValInRangeReq = JsonIntValInRangeReq<JsonUIntVal, JsonVal::Kind::UINT>;

/*
 * JSON signed integer value in range requirement.
 */
using JsonSIntValInRangeReq = JsonIntValInRangeReq<JsonSIntVal, JsonVal::Kind::SINT>;

template <typename ValT>
void writeRawVal(std::ostringstream& ss, const ValT& val)
{
    ss << val;
}

template <>
inline void writeRawVal<std::string>(std::ostringstream& ss, const std::string& val)
{
    ss << '`' << val << '`';
}

template <>
inline void writeRawVal<bool>(std::ostringstream& ss, const bool& val)
{
    writeRawVal(ss, std::string {val ? "true" : "false"});
}

/*
 * JSON scalar value in set requirement template.
 *
 * An instance of this class validates that, given a JSON value V of
 * type `JsonValT`:
 *
 * * V has the kind `KindV`.
 * * The raw value of V is an element of a given set.
 */
template <typename JsonValT, JsonVal::Kind KindV>
class JsonScalarValInSetReq :
    public JsonValReq
{
private:
    // raw value type
    using _Val = typename JsonValT::Val;

public:
    // raw value set type
    using Set = std::set<_Val>;

public:
    /*
     * Builds a JSON scalar value set requirement: _validate() validates
     * that the raw value of the JSON scalar value is an element of
     * `set`.
     */
    explicit JsonScalarValInSetReq(Set set) :
        JsonValReq {KindV},
        _set {std::move(set)}
    {
    }

    /*
     * Builds a JSON scalar value set requirement: _validate() validates
     * that the raw value of the JSON scalar value is exactly `val`.
     */
    explicit JsonScalarValInSetReq(_Val val) :
        JsonScalarValInSetReq {Set {std::move(val)}}
    {
    }

    /*
     * Returns a shared pointer to JSON scalar value in set requirement,
     * forwarding the parameter to the constructor.
     */
    static SP shared(Set set)
    {
        return std::make_shared<JsonScalarValInSetReq>(std::move(set));
    }

    /*
     * Returns a shared pointer to JSON scalar value in set requirement,
     * forwarding the parameter to the constructor.
     */
    static SP shared(_Val val)
    {
        return std::make_shared<JsonScalarValInSetReq>(std::move(val));
    }

protected:
    void _validate(const JsonVal& jsonVal) const override
    {
        auto& specJsonVal = static_cast<const JsonValT&>(jsonVal);

        if (_set.find(*specJsonVal) == _set.end()) {
            std::ostringstream ss;

            ss << "Unexpected value ";
            writeRawVal(ss, *specJsonVal);
            ss << ": expecting " << this->_setStr() << '.';
            throwTextParseError(ss.str(), jsonVal.loc());
        }
    }

    /*
     * Serializes the raw values of `_set` and returns the resulting
     * string.
     */
    std::string _setStr() const
    {
        std::ostringstream ss;

        if (_set.size() == 1) {
            // special case: direct value
            writeRawVal(ss, *_set.begin());
            return ss.str();
        } else if (_set.size() == 2) {
            // special case: "or" word without any comma
            writeRawVal(ss, *_set.begin());
            ss << " or ";
            writeRawVal(ss, *std::next(_set.begin()));
            return ss.str();
        }

        // enumeration with at least one comma
        const auto lastIt = std::prev(_set.end());

        for (auto it = _set.begin(); it != lastIt; ++it) {
            writeRawVal(ss, *it);
            ss << ", ";
        }

        ss << "or ";
        writeRawVal(ss, *lastIt);
        return ss.str();
    }

private:
    // set of expected raw values
    Set _set;
};

/*
 * JSON boolean value in set requirement template.
 */
using JsonBoolValInSetReq = JsonScalarValInSetReq<JsonBoolVal, JsonVal::Kind::BOOL>;

/*
 * JSON unsigned integer value in set requirement template.
 */
using JsonUIntValInSetReq = JsonScalarValInSetReq<JsonUIntVal, JsonVal::Kind::UINT>;

/*
 * JSON signed integer value in set requirement template.
 */
using JsonSIntValInSetReq = JsonScalarValInSetReq<JsonSIntVal, JsonVal::Kind::SINT>;

/*
 * JSON string value in set requirement template.
 */
using JsonStrValInSetReq = JsonScalarValInSetReq<JsonStrVal, JsonVal::Kind::STR>;

/*
 * JSON unsigned integer value is alignment requirement.
 *
 * An instance of this class validates that, given a JSON value V:
 *
 * * V is a JSON unsigned integer value.
 *
 * * The raw value of V is a valid alignment (greater than zero, power
 *   of two).
 */
class JsonUIntValIsAlignReq :
    public JsonValReq
{
public:
    /*
     * Builds a JSON unsigned integer value alignment requirement:
     * _validate() validates that the raw value of the JSON unsigned
     * integer value is a valid alignment.
     */
    explicit JsonUIntValIsAlignReq();

    /*
     * Returns a shared pointer to JSON unsigned integer value alignment
     * requirement.
     */
    static SP shared();

protected:
    void _validate(const JsonVal& jsonVal) const override;
};

/*
 * JSON string value matches regular expression requirement.
 *
 * An instance of this class validates that, given a JSON value V:
 *
 * * V is a JSON string value.
 * * The raw value of V matches a given regular expression.
 */
class JsonStrValMatchesRegexReq :
    public JsonValReq
{
public:
    /*
     * Builds a JSON string value matches regular expression
     * requirement: _validate() validates that the raw value of the JSON
     * string value matches the regular expression `regex`.
     */
    explicit JsonStrValMatchesRegexReq(std::regex regex);

    /*
     * Builds a JSON string value matches regular expression
     * requirement: _validate() validates that the raw value of the JSON
     * string value matches the regular expression `regex` (ECMAScript
     * engine).
     */
    explicit JsonStrValMatchesRegexReq(const char *regex);

    /*
     * Returns a shared pointer to JSON string value matches regular
     * expression requirement, forwarding the parameter to the
     * constructor.
     */
    static SP shared(std::regex regex);

    /*
     * Returns a shared pointer to JSON string value matches regular
     * expression requirement, forwarding the parameter to the
     * constructor.
     */
    static SP shared(const char *regex);

protected:
    void _validate(const JsonVal& jsonVal) const override;

private:
    std::regex _regex;
};

/*
 * JSON array value requirement.
 *
 * An instance of this class validates that, given a JSON value V:
 *
 * * V is a JSON array value.
 * * The size of V is within a given range.
 * * All the elements of V satisfy a given JSON value requirement.
 */
class JsonArrayValReq :
    public JsonValReq
{
public:
    /*
     * Builds a JSON array value requirement: _validate() validates
     * that, for a given JSON array value V:
     *
     * * If `minSize` is set: the size of V is greater than or equal to
     *   `*minSize`.
     *
     * * If `maxSize` is set: the size of V is less than or equal to
     *   `*maxSize`.
     *
     * * If `elemValReq` is not `nullptr`: all the elements of V satisfy
     *   `*elemValReq`.
     */
    explicit JsonArrayValReq(const boost::optional<Size>& minSize,
                             const boost::optional<Size>& maxSize,
                             JsonValReq::SP elemValReq = nullptr);

    /*
     * Builds a JSON array value requirement: _validate() validates
     * that, for a given JSON array value V:
     *
     * * The size of V is exactly `exactSize`.
     *
     * * If `elemValReq` is not `nullptr`: all the elements of V satisfy
     *   `*elemValReq`.
     */
    explicit JsonArrayValReq(Size exactSize, JsonValReq::SP elemValReq = nullptr);

    /*
     * Builds a JSON array value requirement: _validate() validates
     * that, if `elemValReq` is not `nullptr`, all the elements of a
     * given JSON array value satisfy `*elemValReq`.
     */
    explicit JsonArrayValReq(JsonValReq::SP elemValReq = nullptr);

    /*
     * Returns a shared pointer to JSON array value requirement,
     * forwarding the parameters to the constructor.
     */
    static SP shared(const boost::optional<Size>& minSize, const boost::optional<Size>& maxSize,
                     JsonValReq::SP elemValReq = nullptr);

    /*
     * Returns a shared pointer to JSON array value requirement,
     * forwarding the parameters to the constructor.
     */
    static SP shared(Size exactSize, JsonValReq::SP elemValReq = nullptr);

    /*
     * Returns a shared pointer to JSON array value requirement,
     * forwarding the parameter to the constructor.
     */
    static SP shared(JsonValReq::SP elemValReq = nullptr);

protected:
    void _validate(const JsonVal& jsonVal) const override;

private:
    Size _minSize;
    Size _maxSize;
    JsonValReq::SP _elemValReq;
};

/*
 * JSON object value property requirement.
 *
 * An instance of this class contains the requirements of a single
 * JSON object value property, that is:
 *
 * * Whether or not it's required.
 * * The requirement of the JSON value of the property.
 */
class JsonObjValPropReq final
{
public:
    /*
     * Builds a JSON object value property requirement, required if
     * `isRequired` is true: if `valReq` is set, then validate()
     * validates that a JSON value satisfies `*valReq`.
     *
     * Not `explicit` to make building `JsonObjValReq` lighter.
     */
    JsonObjValPropReq(JsonValReq::SP valReq = nullptr, bool isRequired = false);

    // default copy/move operations
    JsonObjValPropReq(const JsonObjValPropReq&) = default;
    JsonObjValPropReq(JsonObjValPropReq&&) = default;
    JsonObjValPropReq& operator=(const JsonObjValPropReq&) = default;
    JsonObjValPropReq& operator=(JsonObjValPropReq&&) = default;

    /*
     * Whether or not the property is required.
     */
    bool isRequired() const noexcept
    {
        return _isRequired;
    }

    /*
     * Validates that `jsonVal` satisfies this requirement.
     */
    void validate(const JsonVal& jsonVal) const;

private:
    // whether or not this property is required
    bool _isRequired = false;

    // requirement of the JSON value
    JsonValReq::SP _valReq;
};

/*
 * JSON object value requirement.
 *
 * An instance of this class validates that, given a JSON value V:
 *
 * * V is a JSON object value.
 *
 * * The properties of V satisfy a given set of JSON object value
 *   property requirements.
 */
class JsonObjValReq :
    public JsonValReq
{
public:
    // property name to property requirement mapping
    using PropReqs = std::unordered_map<std::string, JsonObjValPropReq>;

    // single entry (pair) of `PropReqs`
    using PropReqsEntry = PropReqs::value_type;

public:
    /*
     * Builds a JSON object value requirement: _validate() validates
     * that, for a given JSON object value V:
     *
     * * If `allowUnknownProps` is false, then V has no value of which
     *   the key is not an element of the keys of `propReqs`.
     *
     * * For each property requirement PR having the key K in
     *   `propReqs`: if `PR.isRequired()`, then a value having the key K
     *   exists in V.
     *
     * * For each value VV having the key K in V: VV satisfies the JSON
     *   value requirement, if any, of `propReqs[K]`.
     */
    explicit JsonObjValReq(PropReqs propReqs, bool allowUnknownProps = false);

    /*
     * Returns a shared pointer to JSON object value requirement,
     * forwarding the parameters to the constructor.
     */
    static SP shared(PropReqs propReqs, bool allowUnknownProps = false);

protected:
    void _validate(const JsonVal& jsonVal) const override;

private:
    PropReqs _propReqs;
    bool _allowUnknownProps;
};

} // namespace internal
} // namespace yactfr

#endif // _YACTFR_INTERNAL_METADATA_JSON_JSON_VAL_REQ_HPP

max_stars_repo_name: eepp/yactfr

max_issues_repo_name: eepp/yactfr

max_forks_repo_name: eepp/yactfr


text:
// Copyright 2014 Jonathan Graehl - http://graehl.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRAEHL_SHARED__ARRAY_HPP
#define GRAEHL_SHARED__ARRAY_HPP

// note: tests in dynamic_array.hpp

#include <boost/config.hpp> // STATIC_CONSTANT
#include <algorithm> //swap
#include <graehl/shared/indices_after.hpp>

namespace graehl {

///WARNING: only use for std::vector and similar
template <class Vec>
typename Vec::value_type * array_begin(Vec & v)
{
  return &*v.begin();
}

template <class Vec>
typename Vec::value_type const* array_begin(Vec const& v)
{
  return &*v.begin();
}

template <class Vec>
unsigned index_of(Vec const& v, typename Vec::value_type const* p)
{
  return p-array_begin(v);
}

template <class C> inline
void resize_up_for_index(C &c, std::size_t i)
{
  const std::size_t newsize = i+1;
  if (newsize > c.size())
    c.resize(newsize);
}

template <class Vec>
void remove_marked_swap(Vec & v, bool marked[]) {
  using std::swap;
  unsigned sz = v.size();
  if ( !sz ) return;
  unsigned to, i = 0;
  while ( i < sz && !marked[i] ) ++i;
  to = i; // find first marked (don't need to move anything below it)
  while (i<sz)
    if (!marked[i]) {
      swap(v[to++], v[i++]);
    } else {
      ++i;
    }
  v.resize(to);
}

// return index of one past last rewritten element.  moves (safely) all v[i] to v[ttable[i]], and calls Rewrite(v[ttable[i]],t) where ttable[i] is the new index in v.  if ttable[i] == -1, then swaps v[i] to the end, calling Rewrite(v[ttable[i]])
// note: does the movements in a safe order (assigning to a dest. only after it's already been used as a source).
template <class T, class Rewrite>
unsigned shuffle_removing(T *v, indices_after_removing const& ttable, Rewrite &r)
{
  using std::swap;
  unsigned to, i = 0, sz= ttable.n_mapped;
  //    if (sz==0) return 0;
  for ( ; i < sz && !ttable.removing(i) ; ++i )
    r(v[i], ttable);

  to = i; // find first marked (don't need to move anything below it)
  while (i<sz) {
    if (ttable.removing(i)) {
      r(v[i]); // rewrite for deletion
      ++i;
    } else {
      r(v[i], ttable);
      swap(v[to++], v[i++]);
    }
  }
  return to;
}

template <class Vec, class P>
void remove_if_swap(Vec & v, P const& pred) {
  using std::swap;
  unsigned sz = v.size();
  if ( !sz ) return;
  unsigned to, i = 0;
  while ( i < sz && !pred(v[i]) ) ++i;
  to = i; // find first marked (don't need to move anything below it)
  while (i<sz)
    if (pred(v[i])) {
      swap(v[to++], v[i++]);
    } else {
      ++i;
    }
  v.resize(to);
}

template <class C>
void push_back(C &c)
{
  c.push_back(typename C::value_type());
}

}

#endif

max_stars_repo_name: graehl/carmel

max_issues_repo_name: graehl/carmel

max_forks_repo_name: graehl/carmel


text:
//
// file cad.cc
// David Cosgrove
// AstraZeneca
// 4th February 2010
//
// Takes an existing set of clusters, with fingerprints, and computes the average
// tanimoto distance in each cluster.

#include <fstream>
#include <iterator>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/tuple/tuple.hpp>

#include "CadSettings.H"
#include "FileExceptions.H"
#include "FingerprintBase.H"
#include "HashedFingerprint.H"

using namespace boost;
using namespace std;
using namespace DAC_FINGERPRINTS;

extern string BUILD_TIME;

// ****************************************************************************
void read_samples_file( istream &is ,
                        vector<vector<string> > &clusters ) {
  string input_line;
  getline( is , input_line ); // first line is headings
  while( 1 ) {
    getline( is , input_line );
    if( is.eof() )
      break;
    istringstream iss( input_line );
    string tmp;
    iss >> tmp >> tmp >> tmp >> tmp;
    clusters.push_back( vector<string>( istream_iterator<string>( iss ) ,
                                        istream_iterator<string>() ) );
  }

}

// ****************************************************************************
void read_csv_file( istream &is ,
                    vector<vector<string> > &clusters ) {

  string next_line;
  while( 1 ) {
    getline( is , next_line );
    if( is.eof() )
      break;
    vector<string> splits;
    boost::algorithm::split( splits , next_line , boost::algorithm::is_any_of( "," ) );
    unsigned int clus_num = boost::lexical_cast<int>( splits.front() );
    while( clus_num > clusters.size() )
      clusters.push_back( vector<string>() );
    --clus_num; // file counts from 1
    clusters[clus_num].push_back( splits[3] );
  }

}

// ****************************************************************************
void read_cluster_file( const string &cluster_input_file ,
                        CLUS_FILE_FORMAT clus_format ,
                        vector<vector<string> > &clusters ) {

  ifstream ifs( cluster_input_file.c_str() );
  if( !ifs.good() ) {
    cerr << "Error reading " << cluster_input_file << " for reading."
	 << endl;
    exit( 1 );
  }

  if( SAMPLES_FORMAT == clus_format ) {
    read_samples_file( ifs , clusters );
  } else if( CSV_FORMAT == clus_format ) {
    read_csv_file( ifs , clusters );
  }

}

// ****************************************************************************
FingerprintBase *find_fingerprint( vector<FingerprintBase *> &fps ,
                                   const string &fp_name ) {

  // equal_range needs a pointer to an actual fingerprint, and FingerprintBase is
  // abstract.
  boost::scoped_ptr<FingerprintBase> search_fp( new HashedFingerprint( fp_name ) );
  pair<vector<FingerprintBase *>::iterator,vector<FingerprintBase *>::iterator > seed_fp =
    equal_range( fps.begin() , fps.end() , search_fp ,
                 bind( greater<string>() ,
                       bind( &FingerprintBase::get_name , _1 ) ,
                       bind( &FingerprintBase::get_name , _2 ) ) );

  if( seed_fp.first == seed_fp.second ) {
    cerr << "Program cad error : fingerprint for member " << fp_name << " not found."
        << endl
        << "Program aborts with error." << endl;
    exit( 1 );
  }

  if( fp_name == (*seed_fp.first)->get_name() )
    return *seed_fp.first;
  else
    return *seed_fp.second;

}

// ****************************************************************************
void get_cluster_fps( vector<FingerprintBase *> &cluster_fps ,
                      const vector<string> &cluster ,
                      vector<FingerprintBase *> &clus_fps ) {

  clus_fps.clear();
  for( int i = 0 , is = cluster.size() ; i < is ; ++i ) {
    clus_fps.push_back( find_fingerprint( cluster_fps , cluster[i] ) );
  }

}

// ****************************************************************************
void generate_cads( vector<FingerprintBase *> &cluster_fps ,
                    const vector<vector<string> > &clusters ,
                    vector<boost::tuple<double,double,double> > &cads ) {

  vector<FingerprintBase *> curr_clus;
  for( int i = 0 , is = clusters.size() ; i < is ; ++i ) {
    if( clusters[i].size() > 1 ) {
      get_cluster_fps( cluster_fps , clusters[i] , curr_clus );
      int num_dists = 0;
      double sum_dist = 0.0 , min_dist = 1.0 , max_dist = 0.0;
      for( int j = 0 , js = curr_clus.size() - 1 ; j < js ; ++j ) {
        for( int k = j + 1 , ks = js + 1 ; k < ks ; ++k , ++num_dists ) {
          double dist = curr_clus[j]->calc_distance( *curr_clus[k] );
          sum_dist += dist;
          if( dist > max_dist ) {
            max_dist = dist;
          }
          if( dist < min_dist ) {
            min_dist = dist;
          }
        }
      }
      cads.push_back( boost::make_tuple( sum_dist / double( num_dists ) , min_dist , max_dist ) );
    } else {
      cads.push_back( boost::make_tuple(0.0, 0.0, 0.0) );
    }
  }

}

// ****************************************************************************
void write_cads( const vector<boost::tuple<double,double,double> > &cads ,
                 const vector<vector<string> > &clusters ,
                 const string &filename ) {

  ofstream ofs( filename.c_str() );
  if( !ofs || !ofs.good() ) {
    throw DACLIB::FileReadOpenError( filename.c_str() );
  }

  for( int i = 0 , is = cads.size() ; i < is ; ++i ) {
    ofs << i << " " << clusters[i].front() << " " << cads[i].get<0>()
        << " " << cads[i].get<1>() << " " << cads[i].get<2>()
        << " " << clusters[i].size() << endl;
  }

}

// ****************************************************************************
int main( int argc , char **argv ) {

  cout << "cad - built " << BUILD_TIME << endl;

  CadSettings cs( argc , argv );
  if( !cs ) {
    cout << cs.error_message() << endl << cs.usage_text() << endl;
    cerr << cs.error_message() << endl << cs.usage_text() << endl;
  }

  vector<vector<string> > clusters;

  read_cluster_file( cs.cluster_file() , cs.clus_file_format() , clusters );

  vector<FingerprintBase *> cluster_fps;
  try {
    read_fp_file( cs.cluster_fp_file() , cs.input_format() ,
                  cs.bitstring_separator() , cluster_fps );
  } catch( DACLIB::FileReadOpenError &e ) {
    cerr << e.what() << endl;
    cout << e.what() << endl;
    exit( 1 );
  } catch( FingerprintFileError &e ) {
    cerr << e.what() << endl;
    cout << e.what() << endl;
    exit( 1 );
  }
  sort( cluster_fps.begin() , cluster_fps.end() ,
        bind( &FingerprintBase::get_name , _1 ) >
        bind( &FingerprintBase::get_name , _2 ) );

  vector<boost::tuple<double,double,double> > cads; // mean, min, max
  generate_cads( cluster_fps , clusters , cads );

  write_cads( cads , clusters , cs.output_file() );

}

ext: cc

max_stars_repo_name: OpenEye-Contrib/Flush

max_issues_repo_name: OpenEye-Contrib/Flush

max_forks_repo_name: OpenEye-Contrib/Flush


text:
// Copyright (c) 2014 The Bitcoin Core developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2017 The PIVX developers
// Copyright (c) 2015-2017 The MRI developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "primitives/transaction.h"
#include "main.h"

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(main_tests)

CAmount nMoneySupplyPoWEnd = 57879300 * COIN;

BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
    CAmount nSum = 0;
    for (int nHeight = 0; nHeight < 1; nHeight += 1) {
        /* premine in block 1 */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 100001 * COIN);
        nSum += nSubsidy;
    }

    for (int nHeight = 1; nHeight < 86400; nHeight += 1) {
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 200 * COIN);
        nSum += nSubsidy;
    }
    for (int nHeight = 86400; nHeight < 151200; nHeight += 1) {
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 150 * COIN);
        nSum += nSubsidy;
    }
    for (int nHeight = 151200; nHeight < 302400; nHeight += 1) {
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 125 * COIN);
        nSum += nSubsidy;
    }
    for (int nHeight = 302400; nHeight < 345600; nHeight += 1) {
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 100 * COIN);
        nSum += nSubsidy;
    }
    for (int nHeight = 345600; nHeight < 388800; nHeight += 1) {
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 75 * COIN);
        nSum += nSubsidy;
    }
    for (int nHeight = 388800; nHeight < 475200; nHeight += 1) {
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 50 * COIN);
        nSum += nSubsidy;
    }

	BOOST_CHECK(nSum > 0 && nSum <= nMoneySupplyPoWEnd);
}

BOOST_AUTO_TEST_SUITE_END()


text: #include <boost/spirit/home/classic/core/composite/difference.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include "UscxmlClibBase.h"

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>

#include <uscxml/util/String.h>

#include "UscxmlClibLogger.h"
#include "UscxmlLuaDataModelEx.h"

ScxmlBase::ScxmlBase(const std::vector<std::string> &ACMDArgs, const ScxmlBaseOptions &AScxmlBaseOptions, const bool bHttpEnabled/* = false*/):
	_options(AScxmlBaseOptions), _httpEnabled(bHttpEnabled), _CMDArgs(ACMDArgs) {

	if (_options.Monitor) {
		std::stringstream ss;
		for (auto it = _options.MonitorMsgTypes.begin(); it != _options.MonitorMsgTypes.end(); ++it) {
			if (it != _options.MonitorMsgTypes.begin())
				ss << "|";
			ss << ScxmlMsgTypeToString(*it);
		}
		CLOG(DEBUG) << "Monitor:[" << ss.str() << "]";
	}
}

ScxmlBase::~ScxmlBase(void)
{
	close();

	// there were caught AccessViolation in microstepper (state chart with multiple invoked state charts)
	// if '_interpreter' was not deleted before clearing '_monitor_ptr'
	// clearing '_monitor_ptr' here does not solve the problem
	_interpreter = Interpreter();
}

void  ScxmlBase::start(const std::string &sTextOrFile, const bool bIsText) {
	/// possible deadlock - think in future how to replace,
	/// but we should be sure that previous interpreter stopped!
	waitForStopped();

	if (bIsText) {
		_interpreter = Interpreter::fromXML(sTextOrFile, "");
	}
	else {
		_scxmlurl = sTextOrFile;
		_interpreter = Interpreter::fromURL(_scxmlurl);
	}

	if (!_interpreter)
		throw std::exception("Interpreter initialization FAILED!");

	setState(USCXML_UNDEF);

	/* We are setting custom factory per Intepreter */
	_factory_ptr.reset(new FactoryDynamic(&Factory::getInstance()));

	std::set<Factory::PluginType> FACTORY_TYPES{
		Factory::PluginType::ptSCXMLIOProcessor,
		Factory::PluginType::ptLuaDataModel,
		Factory::PluginType::ptJSCDataModel,
		Factory::PluginType::ptNullDataModel,
		Factory::PluginType::ptUSCXMLInvoker
	};

	if (_httpEnabled) {
		FACTORY_TYPES.insert(Factory::PluginType::ptBasicHTTPIOProcessor);
	}

	_factory_ptr->registerCustomPlugins(FACTORY_TYPES);

	_factory_ptr->registerExecutableContent(std::shared_ptr<SetValueExecutableContent>(new SetValueExecutableContent(this)));
	_factory_ptr->registerIOProcessor(std::shared_ptr<GlobalDataIOProcessor>(new GlobalDataIOProcessor(this)));
	_factory_ptr->registerDataModel(std::shared_ptr<LuaDataModelEx>(new LuaDataModelEx(this)));

	_interpreter.setFactory(_factory_ptr.get());

	_queue_ptr.reset(new PausableDelayedEventQueue(_interpreter.getImpl().get(),this));
	_lang.delayQueue = DelayedEventQueue(_queue_ptr);
	/* intercept native logger in any case */
	_lang.logger = std::shared_ptr<LoggerImpl>(new CLibLogger(_options.Monitor, this, _OnInterpreterLog, _OnInterpreterLogUser));
	_interpreter.setActionLanguage(_lang);

	/* Validate for SCXML and script syntax errors */
	if (_options.Validate) {
		std::list<InterpreterIssue> issues = _interpreter.validate();

		bool bIsError = false;

		for (std::list<InterpreterIssue>::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) {
			switch (issueIter->severity) {
			case InterpreterIssue::USCXML_ISSUE_FATAL: {
				std::stringstream ss;
				ss << *issueIter;
				LOG(_interpreter.getLogger(), USCXML_ERROR) << ss.str();
				bIsError = true;
			} break;
			case InterpreterIssue::USCXML_ISSUE_INFO: {
				std::stringstream ss;
				ss << *issueIter;
				LOG(_interpreter.getLogger(), USCXML_INFO) << ss.str();
			} break;
			case InterpreterIssue::USCXML_ISSUE_WARNING: {
				std::stringstream ss;
				ss << *issueIter;
				LOG(_interpreter.getLogger(), USCXML_WARN) << ss.str();
			} break;
			}
		}
		if (bIsError && _options.TerminateNotValidated)
			throw std::runtime_error("Fatal SCXML validation error(s)! Interpreter stopped!");
	}

	_monitor_ptr.reset(new SequenceCheckingMonitor(this, _lang.logger));
	_monitor_ptr->copyToInvokers(true);
	_interpreter.addMonitor(_monitor_ptr.get());

	_AppTimer.start();

	/*
		if state chart is to large and you do not want to wait while it reaches the stable state,
		you may use 'AsyncStart' option
	*/
	if (!_options.AsyncStart) {
		/* synchronized load */
		auto state_temp = USCXML_UNDEF;
		const std::set<InterpreterState> AStableStates{ USCXML_FINISHED, USCXML_CANCELLED, USCXML_MACROSTEPPED };
		do {
			state_temp = _interpreter.step();
			setState(state_temp);
		} while (AStableStates.find(state_temp) == AStableStates.end());
	}

	/* check that state chart is not finished yet */
	const std::set<InterpreterState> AFinishedStates{ USCXML_FINISHED, USCXML_CANCELLED };
	if (AFinishedStates.find(getState()) == AFinishedStates.end()) {
		_interpreter_thread_ptr = new std::thread(std::bind(&ScxmlBase::blockingQueue, this));
	}
	else {
		if (_OnInterpreterStopped) {
			_OnInterpreterStopped(this, _OnInterpreterStoppedUser);
		}
	}
}

void ScxmlBase::close()
{
	const std::set<InterpreterState> ASkippedStates{ USCXML_UNDEF, USCXML_CANCELLED, USCXML_FINISHED };
	auto state = this->getState();
	if (_interpreter && _interpreter_thread_ptr && ASkippedStates.find(state) == ASkippedStates.end()) {
		_interpreter.cancel();
	}

	waitForStopped();
}

void ScxmlBase::waitForStopped(void)
{
	if (_interpreter_thread_ptr) {
		_interpreter_thread_ptr->join();
		delete _interpreter_thread_ptr;
		_interpreter_thread_ptr = nullptr;
	}
}

void ScxmlBase::pause()
{
	_AppTimer.pause();

	auto it = _nestedDelayQueue.begin();
	while (it != _nestedDelayQueue.end()) {
		std::shared_ptr<PausableDelayedEventQueue> AQueuePtr = it->lock();
		if (!AQueuePtr) {
			_nestedDelayQueue.erase(it++);
		}
		else {
			AQueuePtr->pause();
			it++;
		}
	}
	if (_queue_ptr)
		_queue_ptr->pause();
}

void ScxmlBase::resume()
{
	auto it = _nestedDelayQueue.begin();
	while (it != _nestedDelayQueue.end()) {
		std::shared_ptr<PausableDelayedEventQueue> AQueuePtr = it->lock();
		if (!AQueuePtr) {
			_nestedDelayQueue.erase(it++);
		}
		else {
			AQueuePtr->resume();
			it++;
		}
	}
	if (_queue_ptr)
		_queue_ptr->resume();

	_AppTimer.resume();
}

void ScxmlBase::receive(const Event& event) {
	// while interpreter is not initialized EventQueue is NULL !
	if (_interpreter && getState()!=USCXML_UNDEF) {
		_interpreter.receive(event);
	}
	else
		throw std::runtime_error("Interpereter is not ready to receive event [" + event.name + "]");
}

const std::string ScxmlBase::getExeDir() const
{
	return _CMDArgs.size() ? boost::filesystem::path(_CMDArgs[0]).parent_path().string() : "";
}

void ScxmlBase::blockingQueue()
{
	InterpreterState state_temp = InterpreterState::USCXML_UNDEF;

	try {

		do {
			state_temp = _interpreter.step();
			setState(state_temp);
		} while (state_temp != InterpreterState::USCXML_FINISHED && state_temp != InterpreterState::USCXML_CANCELLED);

	}
	catch (uscxml::ErrorEvent &e) {
		LOG(_interpreter.getLogger(), USCXML_ERROR) << "InterpreterEventsQueue> " << e;
	}

	if (_OnInterpreterStopped) {
		_OnInterpreterStopped(this, _OnInterpreterStoppedUser);
	}
}

uscxml::InterpreterState ScxmlBase::getState() const
{
	std::shared_lock< std::shared_mutex > lock(_mutex);
	return _state;
}

void ScxmlBase::setState(InterpreterState AState)
{
	std::unique_lock<std::shared_mutex> lock(_mutex);
	_state = AState;
}

uscxml::Data ScxmlBase::getGlobal(const std::string & sScxmlName, const std::string &sPath) const
{
	std::shared_lock<std::shared_mutex> lock(_mutex);

	auto it = _global_data_storage.find(sScxmlName);
	if (it != _global_data_storage.end()) {

		const uscxml::Data *dataptr = &it->second;

		if (!sPath.empty()) {
			using namespace boost::algorithm;

			std::vector<std::string> VecStr;
			split(VecStr, sPath, is_any_of("."));

			for (const auto &elem : VecStr) {
				if (isNumeric(elem.c_str(), 10)) {
					auto it_array_elem = dataptr->array.find(std::stoi(elem));
					if (it_array_elem != dataptr->array.end()) {
						dataptr = &it_array_elem->second;
					}
					else
						return uscxml::Data();
				}
				else {
					auto it_compaund_elem = dataptr->compound.find(elem);
					if (it_compaund_elem != dataptr->compound.end()) {
						dataptr = &it_compaund_elem->second;
					}
					else
						return uscxml::Data();
				}
			}
		}

		return *dataptr;
	}

	return uscxml::Data();
}

void ScxmlBase::setGlobal(const std::string & sScxmlName, const std::string &sPath, const uscxml::Data &data, const int iType)
{
	{
		std::unique_lock<std::shared_mutex> lock(_mutex);

		if (sPath.empty()) {
			_global_data_storage[sScxmlName] = data;
		}
		else {
			uscxml::Data *dataptr = nullptr;
			auto it_global = _global_data_storage.find(sScxmlName);
			if (it_global != _global_data_storage.end()) {
				dataptr = &it_global->second;
			}
			else {
				_global_data_storage.insert(std::make_pair(sScxmlName, uscxml::Data()));
				dataptr = &_global_data_storage[sScxmlName];
			}

			using namespace boost::algorithm;

			std::vector<std::string> VecStr;
			split(VecStr, sPath, is_any_of("."));

			for (const auto &elem : VecStr) {
				if (isNumeric(elem.c_str(), 10)) {
					const int elemIndex = std::stoi(elem);
					auto it_array_elem = dataptr->array.find(elemIndex);
					if (it_array_elem != dataptr->array.end()) {
						dataptr = &it_array_elem->second;
					}
					else {
						dataptr->array.insert(std::make_pair(elemIndex, uscxml::Data()));
						dataptr = &dataptr->array[elemIndex];
					}
				}
				else {
					auto it_compaund_elem = dataptr->compound.find(elem);
					if (it_compaund_elem != dataptr->compound.end()) {
						dataptr = &it_compaund_elem->second;
					}
					else
					{
						dataptr->compound.insert(std::make_pair(elem, uscxml::Data()));
						dataptr = &dataptr->compound[elem];
					}
				}
			}

			*dataptr = data;
		}
	}

	if (_OnInterpreterGlobalDataChange) {
		_OnInterpreterGlobalDataChange(this, sScxmlName.c_str(), sPath.c_str(),
			_OnInterpreterGlobalDataChangeAtomOrJson ? data.atom.c_str() : data.asJSON().c_str(),
			_OnInterpreterGlobalDataChangeAtomOrJson, iType, _OnInterpreterGlobalDataChangeUser);
	}
}

std::string ScxmlBase::getProjectPath() const
{
	return boost::filesystem::path(_scxmlurl).parent_path().string();
}

/************************************************************************/
/*                      SequenceCheckingMonitor                         */
/************************************************************************/

SequenceCheckingMonitor::SequenceCheckingMonitor(ScxmlBase *AScxmlBase, const Logger &logger) :
	_out_socket(_io_service), _ScxmlBase(AScxmlBase)
{
	if (!_ScxmlBase)
		throw std::exception("_ScxmlBase==NULL!");

	_logger = logger;

	if (_ScxmlBase->useRemoteMonitor()) {
		_endpoint = udp::endpoint(boost::asio::ip::address::from_string(_ScxmlBase->_options.RemoteMonitorHost),
			_ScxmlBase->_options.RemoteMonitorPort);
		_out_socket.open(_endpoint.protocol());

		CLOG(INFO) << "Remote monitor started on host:[" << _ScxmlBase->_options.RemoteMonitorHost
			<< "] port:[" << _ScxmlBase->_options.RemoteMonitorPort << "]";

		_out_socket.send_to(boost::asio::buffer("@@@"), _endpoint);
	}
}

void SequenceCheckingMonitor::sendMessage(const std::string &sInterpreterName, const std::string &sMsg, const TScxmlMsgType AType, const std::string &sId) {
	_out_socket.send_to(boost::asio::buffer(uscxml::fromLocaleToUtf8(
		std::to_string((long long)AType) + "@" + sInterpreterName + "@" + sMsg + (sId.empty() ? sId : ("@" + sId))
	)), _endpoint);
}

void SequenceCheckingMonitor::sendClearInterpreterMessage(const std::string & sInterpreterName, const std::string &sId)
{
	std::stringstream ss;
	ss << "@@@" << sInterpreterName;
	if (!sId.empty()) {
		ss << "@" << sId;
	}

	_out_socket.send_to(boost::asio::buffer(uscxml::fromLocaleToUtf8(ss.str())), _endpoint);
}

std::string SequenceCheckingMonitor::getInvokeIdFromInterpreter(Interpreter& interpreter) {
	std::string sInvokeId = "";
	if (interpreter) {
		const auto impl = interpreter.getImpl();
		if (impl) {
			sInvokeId = impl->getInvokeId();
		}
	}

	return sInvokeId;
}

void SequenceCheckingMonitor::beforeExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state)
{
	const bool bMonitor = _ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttBeforeExit) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end());
	if (bMonitor || _ScxmlBase->_OnInterpreterEnterExit) {

		std::lock_guard<std::recursive_mutex> lock(_mutex);

		const std::string sId = HAS_ATTR(state, kXMLCharId) ? ATTR(state, kXMLCharId) : DOMUtils::xPathForNode(state);

		if (bMonitor) {
			LOG(_logger, USCXML_VERBATIM) << "Exiting: " << sId << ", interpreter [" << interpreter.getImpl()->getName() << "]" << std::endl;

			if (_ScxmlBase->useRemoteMonitor()) {
				sendMessage(interpreter.getImpl()->getName(), sId, smttBeforeExit,
					getInvokeIdFromInterpreter(interpreter));
			}
		}

		if (_ScxmlBase->_OnInterpreterEnterExit) {
			_ScxmlBase->_OnInterpreterEnterExit(_ScxmlBase,
				interpreter.getImpl()->getName().c_str(), sId.c_str(), false/*exit*/, _ScxmlBase->_OnInterpreterEnterExitUser);
		}
	}
}

void SequenceCheckingMonitor::afterExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state)
{
	const bool bMonitor = _ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttAfterExit) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end());
	if (bMonitor) {

		std::lock_guard<std::recursive_mutex> lock(_mutex);

		const std::string sId = HAS_ATTR(state, kXMLCharId) ? ATTR(state, kXMLCharId) : DOMUtils::xPathForNode(state);

		LOG(_logger, USCXML_VERBATIM) << "After Exiting: " << sId << ", interpreter [" << interpreter.getImpl()->getName() << "]" << std::endl;

		if (_ScxmlBase->useRemoteMonitor()) {
			sendMessage(interpreter.getImpl()->getName(), sId, smttAfterExit, getInvokeIdFromInterpreter(interpreter));
		}
	}
}

void SequenceCheckingMonitor::beforeEnteringState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state)
{
	const bool bMonitor = _ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttBeforeEnter) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end());
	if (bMonitor || _ScxmlBase->_OnInterpreterEnterExit) {

		std::lock_guard<std::recursive_mutex> lock(_mutex);

		const std::string sId = HAS_ATTR(state, kXMLCharId) ? ATTR(state, kXMLCharId) : DOMUtils::xPathForNode(state);

		if (bMonitor) {
			LOG(_logger, USCXML_VERBATIM) << "Entering: " << sId << ", interpreter [" << interpreter.getImpl()->getName() << "]" << std::endl;

			if (_ScxmlBase->useRemoteMonitor()) {
				sendMessage(interpreter.getImpl()->getName(), sId, smttBeforeEnter, getInvokeIdFromInterpreter(interpreter));
			}
		}

		if (_ScxmlBase->_OnInterpreterEnterExit) {
			_ScxmlBase->_OnInterpreterEnterExit(_ScxmlBase,
				interpreter.getImpl()->getName().c_str(), sId.c_str(), true/*enter*/, _ScxmlBase->_OnInterpreterEnterExitUser);
		}
	}
}

void SequenceCheckingMonitor::afterEnteringState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state)
{
	const bool bMonitor = _ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttAfterEnter) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end());
	if (bMonitor) {

		std::lock_guard<std::recursive_mutex> lock(_mutex);

		const std::string sId = HAS_ATTR(state, kXMLCharId) ? ATTR(state, kXMLCharId) : DOMUtils::xPathForNode(state);

		LOG(_logger, USCXML_VERBATIM) << "After Entering: " << sId << ", interpreter [" << interpreter.getImpl()->getName() << "]" << std::endl;

		if (_ScxmlBase->useRemoteMonitor()) {
			sendMessage(interpreter.getImpl()->getName(), sId, smttAfterEnter, getInvokeIdFromInterpreter(interpreter));
		}
	}
}

void SequenceCheckingMonitor::beforeExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* execContent)
{
	if (_ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttBeforeExecContent) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end())) {

		StateTransitionMonitor::beforeExecutingContent(interpreter, execContent);

		if (_ScxmlBase->useRemoteMonitor()) {
			std::lock_guard<std::recursive_mutex> lock(_mutex);
			sendMessage(interpreter.getImpl()->getName(), DOMUtils::xPathForNode(execContent), smttBeforeExecContent, getInvokeIdFromInterpreter(interpreter));
		}
	}
}

void SequenceCheckingMonitor::afterExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* execContent)
{
	if (_ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttAfterExecContent) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end())) {

		StateTransitionMonitor::afterExecutingContent(interpreter, execContent);

		if (_ScxmlBase->useRemoteMonitor()) {
			std::lock_guard<std::recursive_mutex> lock(_mutex);
			sendMessage(interpreter.getImpl()->getName(), DOMUtils::xPathForNode(execContent), smttAfterExecContent,
				getInvokeIdFromInterpreter(interpreter));
		}
	}
}

void SequenceCheckingMonitor::beforeUninvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid)
{
	const bool bMonitor = _ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttBeforeUnInvoke) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end());
	if (bMonitor || _ScxmlBase->_OnInterpreterInvoke) {

		std::lock_guard<std::recursive_mutex> lock(_mutex);

		if (bMonitor) {
			LOG(_logger, USCXML_VERBATIM) << "Uninvoking: " << invokeid << ", interpreter [" << interpreter.getImpl()->getName() << "]" << std::endl;

			if (_ScxmlBase->useRemoteMonitor()) {
				auto impl = interpreter.getImpl();
				if (impl) {
					const std::string &sSubName = impl->getInvokedScxmlName(invokeid);
					sendMessage(interpreter.getImpl()->getName(), sSubName, smttBeforeUnInvoke, invokeid);
					sendClearInterpreterMessage(sSubName, invokeid);
				}
			}
		}

		if (_ScxmlBase->_OnInterpreterInvoke) {
			_ScxmlBase->_OnInterpreterInvoke(_ScxmlBase,
				interpreter.getImpl()->getName().c_str(), invokeid.c_str(), false/*UnInvoke*/, _ScxmlBase->_OnInterpreterInvokeUser);
		}
	}
}

void SequenceCheckingMonitor::afterUninvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid)
{
	if (_ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttAfterUnInvoke) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end())) {

		StateTransitionMonitor::afterUninvoking(interpreter, invokeElem, invokeid);

		if (_ScxmlBase->useRemoteMonitor()) {
			std::lock_guard<std::recursive_mutex> lock(_mutex);
			sendMessage(interpreter.getImpl()->getName(), invokeid, smttAfterUnInvoke, invokeid);
		}
	}
}

void SequenceCheckingMonitor::beforeInvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid)
{
	const bool bMonitor = _ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttBeforeInvoke) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end());
	if (bMonitor || _ScxmlBase->_OnInterpreterInvoke) {

		std::lock_guard<std::recursive_mutex> lock(_mutex);

		if (bMonitor) {
			LOG(_logger, USCXML_VERBATIM) << "Invoking: " << invokeid << ", interpreter [" << interpreter.getImpl()->getName() << "]" << std::endl;

			if (_ScxmlBase->useRemoteMonitor()) {
				sendMessage(interpreter.getImpl()->getName(), invokeid, smttBeforeInvoke, invokeid);
			}
		}

		if (_ScxmlBase->_OnInterpreterInvoke) {
			_ScxmlBase->_OnInterpreterInvoke(_ScxmlBase,
				interpreter.getImpl()->getName().c_str(), invokeid.c_str(), true/*Invoke*/, _ScxmlBase->_OnInterpreterInvokeUser);
		}
	}
}

void SequenceCheckingMonitor::afterInvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid)
{
	if (_ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttAfterInvoke) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end())) {

		StateTransitionMonitor::afterInvoking(interpreter, invokeElem, invokeid);

		if (_ScxmlBase->useRemoteMonitor()) {
			std::lock_guard<std::recursive_mutex> lock(_mutex);
			sendMessage(interpreter.getImpl()->getName(), invokeid, smttAfterInvoke, invokeid);
		}
	}
}

void SequenceCheckingMonitor::beforeTakingTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition)
{
	if (_ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttBeforeTakingTransition) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end())) {

		StateTransitionMonitor::beforeTakingTransition(interpreter, transition);

		if (_ScxmlBase->useRemoteMonitor()) {
			std::lock_guard<std::recursive_mutex> lock(_mutex);
			std::string s_event = "*";
			if (transition->hasAttribute(X("event"))) {
				s_event = X(transition->getAttribute(X("event")));
			}
			sendMessage(interpreter.getImpl()->getName(), s_event, smttBeforeTakingTransition,
				getInvokeIdFromInterpreter(interpreter));
		}
	}
}

void SequenceCheckingMonitor::afterTakingTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition)
{
	if (_ScxmlBase->_options.Monitor &&
		(_ScxmlBase->_options.MonitorMsgTypes.find(smttAfterTakingTransition) != _ScxmlBase->_options.MonitorMsgTypes.end() ||
		_ScxmlBase->_options.MonitorMsgTypes.find(smttMAXSIZE) != _ScxmlBase->_options.MonitorMsgTypes.end())) {

		StateTransitionMonitor::afterTakingTransition(interpreter, transition);

		if (_ScxmlBase->useRemoteMonitor()) {
			std::lock_guard<std::recursive_mutex> lock(_mutex);
			std::string s_event = "*";
			if (transition->hasAttribute(X("event"))) {
				s_event = X(transition->getAttribute(X("event")));
			}
			sendMessage(interpreter.getImpl()->getName(), s_event, smttAfterTakingTransition,
				getInvokeIdFromInterpreter(interpreter));
		}
	}
}

void SequenceCheckingMonitor::beforeProcessingEvent(Interpreter & interpreter, const uscxml::Event & event)
{
	if (_ScxmlBase->_OnInterpreterEvent) {
		std::lock_guard<std::recursive_mutex> lock(_mutex);
		if (event.params.size()) {
			for (const auto &it : event.params) {
				const std::string s_eventname_with_param = event.name + "." + it.first;
				_ScxmlBase->_OnInterpreterEvent(_ScxmlBase, interpreter.getImpl()->getName().c_str(), s_eventname_with_param.c_str(),
					_ScxmlBase->_OnInterpreterEventAtomOrJson ? it.second.atom.c_str() : it.second.asJSON().c_str(),
					_ScxmlBase->_OnInterpreterEventAtomOrJson,
					_ScxmlBase->_OnInterpreterEventUser);
			}
		}
		else {
			_ScxmlBase->_OnInterpreterEvent(_ScxmlBase, interpreter.getImpl()->getName().c_str(), event.name.c_str(),
				_ScxmlBase->_OnInterpreterEventAtomOrJson ? event.data.atom.c_str() : event.data.asJSON().c_str(),
				_ScxmlBase->_OnInterpreterEventAtomOrJson,
				_ScxmlBase->_OnInterpreterEventUser);
		}

	}
}

max_stars_repo_name: alexzhornyak/UscxmlCLib

max_issues_repo_name: alexzhornyak/UscxmlCLib

max_forks_repo_name: alexzhornyak/UscxmlCLib