text:
/*
 *          Copyright Andrey Semashev 2007 - 2020.
 * 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)
 */
/*!
 * \file   syslog_backend.cpp
 * \author Andrey Semashev
 * \date   08.01.2008
 *
 * \brief  This header is the Boost.Log library implementation, see the library documentation
 *         at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
 */

#include <boost/log/detail/config.hpp>

#ifndef BOOST_LOG_WITHOUT_SYSLOG

#include <ctime>
#include <algorithm>
#include <stdexcept>
#include <boost/limits.hpp>
#include <boost/assert.hpp>
#include <boost/smart_ptr/weak_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/throw_exception.hpp>
#if !defined(BOOST_LOG_NO_ASIO)
#include <boost/asio/buffer.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/host_name.hpp>
#include <boost/asio/ip/resolver_base.hpp>
#endif
#include <boost/system/error_code.hpp>
#include <boost/date_time/c_time.hpp>
#include <boost/log/sinks/syslog_backend.hpp>
#include <boost/log/sinks/syslog_constants.hpp>
#include <boost/log/detail/singleton.hpp>
#include <boost/log/detail/snprintf.hpp>
#include <boost/log/exceptions.hpp>
#if !defined(BOOST_LOG_NO_THREADS)
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#endif
#include "unique_ptr.hpp"

#ifdef BOOST_LOG_USE_NATIVE_SYSLOG
#include <syslog.h>
#endif // BOOST_LOG_USE_NATIVE_SYSLOG

#include <boost/log/detail/header.hpp>

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace sinks {

namespace syslog {

    //! The function constructs log record level from an integer
    BOOST_LOG_API level make_level(int lev)
    {
        if (BOOST_UNLIKELY(static_cast< unsigned int >(lev) >= 8u))
            BOOST_THROW_EXCEPTION(std::out_of_range("syslog level value is out of range"));
        return static_cast< level >(lev);
    }

    //! The function constructs log source facility from an integer
    BOOST_LOG_API facility make_facility(int fac)
    {
        if (BOOST_UNLIKELY((static_cast< unsigned int >(fac) & 7u) != 0u
            || static_cast< unsigned int >(fac) > (23u * 8u)))
        {
            BOOST_THROW_EXCEPTION(std::out_of_range("syslog facility code value is out of range"));
        }
        return static_cast< facility >(fac);
    }

} // namespace syslog

////////////////////////////////////////////////////////////////////////////////
//! Syslog sink backend implementation
////////////////////////////////////////////////////////////////////////////////
struct syslog_backend::implementation
{
#ifdef BOOST_LOG_USE_NATIVE_SYSLOG
    struct native;
#endif // BOOST_LOG_USE_NATIVE_SYSLOG
#if !defined(BOOST_LOG_NO_ASIO)
    struct udp_socket_based;
#endif

    //! Level mapper
    severity_mapper_type m_LevelMapper;

    //! Logging facility (portable or native, depending on the backend implementation)
    const int m_Facility;

    //! Constructor
    explicit implementation(int facility) :
        m_Facility(facility)
    {
    }
    //! Virtual destructor
    virtual ~implementation() {}

    //! The method sends the formatted message to the syslog host
    virtual void send(syslog::level lev, string_type const& formatted_message) = 0;
};

////////////////////////////////////////////////////////////////////////////////
//  Native syslog API support
////////////////////////////////////////////////////////////////////////////////

#ifdef BOOST_LOG_USE_NATIVE_SYSLOG

BOOST_LOG_ANONYMOUS_NAMESPACE {

    //! Syslog service initializer (implemented as a weak singleton)
#if !defined(BOOST_LOG_NO_THREADS)
    class native_syslog_initializer :
        private log::aux::lazy_singleton< native_syslog_initializer, mutex >
#else
    class native_syslog_initializer
#endif
    {
#if !defined(BOOST_LOG_NO_THREADS)
        friend class log::aux::lazy_singleton< native_syslog_initializer, mutex >;
        typedef log::aux::lazy_singleton< native_syslog_initializer, mutex > mutex_holder;
#endif

    private:
        /*!
         * \brief Application identification string
         *
         * \note We have to keep it as an immutable member because some syslog implementations (e.g. glibc)
         *       do not deep-copy the ident string to internal storage when \c openlog is called
         *       and instead save a pointer to the user-provided string. This means the user-provided
         *       string needs to remain accessible for the whole duration of logging.
         *
         *       https://github.com/boostorg/log/issues/97
         *       https://sourceware.org/bugzilla/show_bug.cgi?id=25442
         */
        const std::string m_Ident;

    public:
        native_syslog_initializer(std::string const& ident, int facility) :
            m_Ident(ident)
        {
            ::openlog((m_Ident.empty() ? static_cast< const char* >(NULL) : m_Ident.c_str()), 0, facility);
        }
        ~native_syslog_initializer()
        {
            ::closelog();
        }

        static shared_ptr< native_syslog_initializer > get_instance(std::string const& ident, int facility)
        {
#if !defined(BOOST_LOG_NO_THREADS)
            lock_guard< mutex > lock(mutex_holder::get());
#endif
            static weak_ptr< native_syslog_initializer > instance;
            shared_ptr< native_syslog_initializer > p(instance.lock());
            if (!p)
            {
                p = boost::make_shared< native_syslog_initializer >(ident, facility);
                instance = p;
            }
            return p;
        }

        BOOST_DELETED_FUNCTION(native_syslog_initializer(native_syslog_initializer const&))
        BOOST_DELETED_FUNCTION(native_syslog_initializer& operator= (native_syslog_initializer const&))
    };

} // namespace

struct syslog_backend::implementation::native :
    public implementation
{
    //! Reference to the syslog service initializer
    const shared_ptr< native_syslog_initializer > m_pSyslogInitializer;

    //! Constructor
    native(syslog::facility const& fac, std::string const& ident) :
        implementation(convert_facility(fac)),
        m_pSyslogInitializer(native_syslog_initializer::get_instance(ident, this->m_Facility))
    {
    }

    //! The method sends the formatted message to the syslog host
    void send(syslog::level lev, string_type const& formatted_message) BOOST_OVERRIDE
    {
        int native_level;
        switch (lev)
        {
        case syslog::emergency:
            native_level = LOG_EMERG; break;
        case syslog::alert:
            native_level = LOG_ALERT; break;
        case syslog::critical:
            native_level = LOG_CRIT; break;
        case syslog::error:
            native_level = LOG_ERR; break;
        case syslog::warning:
            native_level = LOG_WARNING; break;
        case syslog::notice:
            native_level = LOG_NOTICE; break;
        case syslog::debug:
            native_level = LOG_DEBUG; break;
        default:
            native_level = LOG_INFO; break;
        }

        ::syslog(this->m_Facility | native_level, "%s", formatted_message.c_str());
    }

private:
    //! The function converts portable facility codes to the native codes
    static int convert_facility(syslog::facility const& fac)
    {
        // POSIX does not specify anything except for LOG_USER and LOG_LOCAL*
        #ifndef LOG_KERN
        #define LOG_KERN LOG_USER
        #endif
        #ifndef LOG_DAEMON
        #define LOG_DAEMON LOG_KERN
        #endif
        #ifndef LOG_MAIL
        #define LOG_MAIL LOG_USER
        #endif
        #ifndef LOG_AUTH
        #define LOG_AUTH LOG_DAEMON
        #endif
        #ifndef LOG_SYSLOG
        #define LOG_SYSLOG LOG_DAEMON
        #endif
        #ifndef LOG_LPR
        #define LOG_LPR LOG_DAEMON
        #endif
        #ifndef LOG_NEWS
        #define LOG_NEWS LOG_USER
        #endif
        #ifndef LOG_UUCP
        #define LOG_UUCP LOG_USER
        #endif
        #ifndef LOG_CRON
        #define LOG_CRON LOG_DAEMON
        #endif
        #ifndef LOG_AUTHPRIV
        #define LOG_AUTHPRIV LOG_AUTH
        #endif
        #ifndef LOG_FTP
        #define LOG_FTP LOG_DAEMON
        #endif

        static const int native_facilities[24] =
        {
            LOG_KERN,
            LOG_USER,
            LOG_MAIL,
            LOG_DAEMON,
            LOG_AUTH,
            LOG_SYSLOG,
            LOG_LPR,
            LOG_NEWS,
            LOG_UUCP,
            LOG_CRON,
            LOG_AUTHPRIV,
            LOG_FTP,

            // reserved values
            LOG_USER,
            LOG_USER,
            LOG_USER,
            LOG_USER,

            LOG_LOCAL0,
            LOG_LOCAL1,
            LOG_LOCAL2,
            LOG_LOCAL3,
            LOG_LOCAL4,
            LOG_LOCAL5,
            LOG_LOCAL6,
            LOG_LOCAL7
        };

        std::size_t n = static_cast< unsigned int >(fac) / 8u;
        BOOST_ASSERT(n < sizeof(native_facilities) / sizeof(*native_facilities));
        return native_facilities[n];
    }
};

#endif // BOOST_LOG_USE_NATIVE_SYSLOG

////////////////////////////////////////////////////////////////////////////////
//  Socket-based implementation
////////////////////////////////////////////////////////////////////////////////

#if !defined(BOOST_LOG_NO_ASIO)

BOOST_LOG_ANONYMOUS_NAMESPACE {

    //! The shared UDP socket
    struct syslog_udp_socket
    {
    private:
        //! The socket primitive
        asio::ip::udp::socket m_Socket;

    public:
        //! The constructor creates a socket bound to the specified local address and port
        explicit syslog_udp_socket(asio::io_context& io_ctx, asio::ip::udp const& protocol, asio::ip::udp::endpoint const& local_address) :
            m_Socket(io_ctx)
        {
            m_Socket.open(protocol);
            m_Socket.set_option(asio::socket_base::reuse_address(true));
            m_Socket.bind(local_address);
        }
        //! The destructor closes the socket
        ~syslog_udp_socket()
        {
            boost::system::error_code ec;
            m_Socket.shutdown(asio::socket_base::shutdown_both, ec);
            m_Socket.close(ec);
        }

        //! The method sends the syslog message to the specified endpoint
        void send_message(int pri, const char* local_host_name, asio::ip::udp::endpoint const& target, const char* message);

        BOOST_DELETED_FUNCTION(syslog_udp_socket(syslog_udp_socket const&))
        BOOST_DELETED_FUNCTION(syslog_udp_socket& operator= (syslog_udp_socket const&))
    };

    //! The class contains the UDP service for syslog sockets to function
    class syslog_udp_service :
        public log::aux::lazy_singleton< syslog_udp_service, shared_ptr< syslog_udp_service > >
    {
        friend class log::aux::lazy_singleton< syslog_udp_service, shared_ptr< syslog_udp_service > >;
        typedef log::aux::lazy_singleton< syslog_udp_service, shared_ptr< syslog_udp_service > > base_type;

    public:
        //! The IO context instance
        asio::io_context m_IOContext;
        //! The local host name to put into log message
        std::string m_LocalHostName;

#if !defined(BOOST_LOG_NO_THREADS)
        //! A synchronization primitive to protect the host name resolver
        mutex m_Mutex;
        //! The resolver is used to acquire connection endpoints
        asio::ip::udp::resolver m_HostNameResolver;
#endif // !defined(BOOST_LOG_NO_THREADS)

    private:
        //! Default constructor
        syslog_udp_service()
#if !defined(BOOST_LOG_NO_THREADS)
            : m_HostNameResolver(m_IOContext)
#endif // !defined(BOOST_LOG_NO_THREADS)
        {
            boost::system::error_code err;
            m_LocalHostName = asio::ip::host_name(err);
        }
        //! Initializes the singleton instance
        static void init_instance()
        {
            base_type::get_instance().reset(new syslog_udp_service());
        }
    };

    //! The method sends the syslog message to the specified endpoint
    void syslog_udp_socket::send_message(
        int pri, const char* local_host_name, asio::ip::udp::endpoint const& target, const char* message)
    {
        std::time_t t = std::time(NULL);
        std::tm ts;
        std::tm* time_stamp = boost::date_time::c_time::localtime(&t, &ts);

        // Month will have to be injected separately, as involving locale won't do here
        static const char months[12][4] =
        {
            "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
        };

        // The packet size is mandated in RFC3164, plus one for the terminating zero
        char packet[1025];
        int n = boost::log::aux::snprintf
        (
            packet,
            sizeof(packet),
            "<%d>%s %2d %02d:%02d:%02d %s %s",
            pri,
            months[time_stamp->tm_mon],
            time_stamp->tm_mday,
            time_stamp->tm_hour,
            time_stamp->tm_min,
            time_stamp->tm_sec,
            local_host_name,
            message
        );
        if (BOOST_LIKELY(n > 0))
        {
            std::size_t packet_size = static_cast< std::size_t >(n) >= sizeof(packet) ? sizeof(packet) - 1u : static_cast< std::size_t >(n);
            m_Socket.send_to(asio::buffer(packet, packet_size), target);
        }
    }

} // namespace

struct syslog_backend::implementation::udp_socket_based :
    public implementation
{
    //! Protocol to be used
    asio::ip::udp m_Protocol;
    //! Pointer to the list of sockets
    shared_ptr< syslog_udp_service > m_pService;
    //! Pointer to the socket being used
    log::aux::unique_ptr< syslog_udp_socket > m_pSocket;
    //! The target host to send packets to
    asio::ip::udp::endpoint m_TargetHost;

    //! Constructor
    explicit udp_socket_based(syslog::facility const& fac, asio::ip::udp const& protocol) :
        implementation(fac),
        m_Protocol(protocol),
        m_pService(syslog_udp_service::get())
    {
        if (m_Protocol == asio::ip::udp::v4())
        {
            m_TargetHost = asio::ip::udp::endpoint(asio::ip::address_v4(0x7F000001), 514); // 127.0.0.1:514
        }
        else
        {
            // ::1, port 514
            asio::ip::address_v6::bytes_type addr;
            std::fill_n(addr.data(), addr.size() - 1u, static_cast< unsigned char >(0u));
            addr[addr.size() - 1u] = 1u;
            m_TargetHost = asio::ip::udp::endpoint(asio::ip::address_v6(addr), 514);
        }
    }

    //! The method sends the formatted message to the syslog host
    void send(syslog::level lev, string_type const& formatted_message) BOOST_OVERRIDE
    {
        if (!m_pSocket.get())
        {
            asio::ip::udp::endpoint any_local_address;
            m_pSocket.reset(new syslog_udp_socket(m_pService->m_IOContext, m_Protocol, any_local_address));
        }

        m_pSocket->send_message(
            this->m_Facility | static_cast< int >(lev),
            m_pService->m_LocalHostName.c_str(),
            m_TargetHost,
            formatted_message.c_str());
    }
};

#endif // !defined(BOOST_LOG_NO_ASIO)

////////////////////////////////////////////////////////////////////////////////
//  Sink backend implementation
////////////////////////////////////////////////////////////////////////////////
BOOST_LOG_API syslog_backend::syslog_backend()
{
    construct(log::aux::empty_arg_list());
}

//! Destructor
BOOST_LOG_API syslog_backend::~syslog_backend()
{
    delete m_pImpl;
}

//! The method installs the function object that maps application severity levels to Syslog levels
BOOST_LOG_API void syslog_backend::set_severity_mapper(severity_mapper_type const& mapper)
{
    m_pImpl->m_LevelMapper = mapper;
}

//! The method writes the message to the sink
BOOST_LOG_API void syslog_backend::consume(record_view const& rec, string_type const& formatted_message)
{
    m_pImpl->send(
        m_pImpl->m_LevelMapper.empty() ? syslog::info : m_pImpl->m_LevelMapper(rec),
        formatted_message);
}

//! The method creates the backend implementation
BOOST_LOG_API void syslog_backend::construct(syslog::facility fac, syslog::impl_types use_impl, ip_versions ip_version, std::string const& ident)
{
#ifdef BOOST_LOG_USE_NATIVE_SYSLOG
    if (use_impl == syslog::native)
    {
        typedef implementation::native native_impl;
        m_pImpl = new native_impl(fac, ident);
        return;
    }
#endif // BOOST_LOG_USE_NATIVE_SYSLOG

#if !defined(BOOST_LOG_NO_ASIO)
    typedef implementation::udp_socket_based udp_socket_based_impl;
    asio::ip::udp protocol = asio::ip::udp::v4();
    switch (ip_version)
    {
    case v4:
        break;
    case v6:
        protocol = asio::ip::udp::v6();
        break;
    default:
        BOOST_LOG_THROW_DESCR(setup_error, "Incorrect IP version specified");
    }

    m_pImpl = new udp_socket_based_impl(fac, protocol);
#endif
}

#if !defined(BOOST_LOG_NO_ASIO)

//! The method sets the local address which log records will be sent from.
BOOST_LOG_API void syslog_backend::set_local_address(std::string const& addr, unsigned short port)
{
#if !defined(BOOST_LOG_NO_THREADS)
    typedef implementation::udp_socket_based udp_socket_based_impl;
    if (udp_socket_based_impl* impl = dynamic_cast< udp_socket_based_impl* >(m_pImpl))
    {
        char service_name[std::numeric_limits< unsigned int >::digits10 + 3];
        boost::log::aux::snprintf(service_name, sizeof(service_name), "%u", static_cast< unsigned int >(port));

        asio::ip::udp::endpoint local_address;
        {
            lock_guard< mutex > lock(impl->m_pService->m_Mutex);
            asio::ip::udp::resolver::results_type results = impl->m_pService->m_HostNameResolver.resolve
            (
                impl->m_Protocol,
                addr,
                service_name,
                asio::ip::resolver_base::address_configured | asio::ip::resolver_base::passive
            );

            local_address = *results.cbegin();
        }

        impl->m_pSocket.reset(new syslog_udp_socket(impl->m_pService->m_IOContext, impl->m_Protocol, local_address));
    }
#else
    // Boost.ASIO requires threads for the host name resolver,
    // so without threads we simply assume the string already contains IP address
    set_local_address(boost::asio::ip::address::from_string(addr), port);
#endif // !defined(BOOST_LOG_NO_THREADS)
}
//! The method sets the local address which log records will be sent from.
BOOST_LOG_API void syslog_backend::set_local_address(boost::asio::ip::address const& addr, unsigned short port)
{
    typedef implementation::udp_socket_based udp_socket_based_impl;
    if (udp_socket_based_impl* impl = dynamic_cast< udp_socket_based_impl* >(m_pImpl))
    {
        if ((impl->m_Protocol == asio::ip::udp::v4() && !addr.is_v4()) || (impl->m_Protocol == asio::ip::udp::v6() && !addr.is_v6()))
            BOOST_LOG_THROW_DESCR(setup_error, "Incorrect IP version specified in the local address");

        impl->m_pSocket.reset(new syslog_udp_socket(
            impl->m_pService->m_IOContext, impl->m_Protocol, asio::ip::udp::endpoint(addr, port)));
    }
}

//! The method sets the address of the remote host where log records will be sent to.
BOOST_LOG_API void syslog_backend::set_target_address(std::string const& addr, unsigned short port)
{
#if !defined(BOOST_LOG_NO_THREADS)
    typedef implementation::udp_socket_based udp_socket_based_impl;
    if (udp_socket_based_impl* impl = dynamic_cast< udp_socket_based_impl* >(m_pImpl))
    {
        char service_name[std::numeric_limits< unsigned int >::digits10 + 3];
        boost::log::aux::snprintf(service_name, sizeof(service_name), "%u", static_cast< unsigned int >(port));

        asio::ip::udp::endpoint remote_address;
        {
            lock_guard< mutex > lock(impl->m_pService->m_Mutex);
            asio::ip::udp::resolver::results_type results = impl->m_pService->m_HostNameResolver.resolve
            (
                impl->m_Protocol,
                addr,
                service_name,
                asio::ip::resolver_query_base::address_configured
            );

            remote_address = *results.cbegin();
        }

        impl->m_TargetHost = remote_address;
    }
#else
    // Boost.ASIO requires threads for the host name resolver,
    // so without threads we simply assume the string already contains IP address
    set_target_address(boost::asio::ip::address::from_string(addr), port);
#endif // !defined(BOOST_LOG_NO_THREADS)
}
//! The method sets the address of the remote host where log records will be sent to.
BOOST_LOG_API void syslog_backend::set_target_address(boost::asio::ip::address const& addr, unsigned short port)
{
    typedef implementation::udp_socket_based udp_socket_based_impl;
    if (udp_socket_based_impl* impl = dynamic_cast< udp_socket_based_impl* >(m_pImpl))
    {
        if ((impl->m_Protocol == asio::ip::udp::v4() && !addr.is_v4()) || (impl->m_Protocol == asio::ip::udp::v6() && !addr.is_v6()))
            BOOST_LOG_THROW_DESCR(setup_error, "Incorrect IP version specified in the target address");

        impl->m_TargetHost = asio::ip::udp::endpoint(addr, port);
    }
}

#endif // !defined(BOOST_LOG_NO_ASIO)

} // namespace sinks

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // !defined(BOOST_LOG_WITHOUT_SYSLOG)


text:
//
// Copyright (c) 2018 CNRS
//

#include "pinocchio/fwd.hpp"
#include "pinocchio/spatial/se3.hpp"
#include "pinocchio/spatial/motion.hpp"
#include "pinocchio/spatial/explog.hpp"

#include <iostream>

#include <boost/test/unit_test.hpp>
#include <boost/utility/binary.hpp>

BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)

template<typename Vector3Like>
Eigen::Matrix<typename Vector3Like::Scalar,3,3,0>
computeV(const Eigen::MatrixBase<Vector3Like> & v3)
{
  typedef typename Vector3Like::Scalar Scalar;
  typedef Eigen::Matrix<Scalar,3,3,0> ReturnType;
  typedef ReturnType Matrix3;

  Scalar t2 = v3.squaredNorm();
  const Scalar t = pinocchio::math::sqrt(t2);
  Scalar alpha, beta, zeta;

  if (t < 1e-4)
  {
    alpha = Scalar(1) + t2/Scalar(6) - t2*t2/Scalar(120);
    beta = Scalar(1)/Scalar(2) - t2/Scalar(24);
    zeta = Scalar(1)/Scalar(6) - t2/Scalar(120);
  }
  else
  {
    Scalar st,ct; pinocchio::SINCOS(t,&st,&ct);
    alpha = st/t;
    beta = (1-ct)/t2;
    zeta = (1 - alpha)/(t2);
  }

  Matrix3 V
  = alpha * Matrix3::Identity()
  + beta * pinocchio::skew(v3)
  + zeta * v3 * v3.transpose();

  return V;
}

template<typename Vector3Like>
Eigen::Matrix<typename Vector3Like::Scalar,3,3,0>
computeVinv(const Eigen::MatrixBase<Vector3Like> & v3)
{
  typedef typename Vector3Like::Scalar Scalar;
  typedef Eigen::Matrix<Scalar,3,3,0> ReturnType;
  typedef ReturnType Matrix3;

  Scalar t2 = v3.squaredNorm();
  const Scalar t = pinocchio::math::sqrt(t2);

  Scalar alpha, beta;
  if (t < 1e-4)
  {
    alpha = Scalar(1) - t2/Scalar(12) - t2*t2/Scalar(720);
    beta = Scalar(1)/Scalar(12) + t2/Scalar(720);
  }
  else
  {
    Scalar st,ct; pinocchio::SINCOS(t,&st,&ct);
    alpha = t*st/(Scalar(2)*(Scalar(1)-ct));
    beta = Scalar(1)/t2 - st/(Scalar(2)*t*(Scalar(1)-ct));
  }

  Matrix3 Vinv
  = alpha * Matrix3::Identity()
  - 0.5 * pinocchio::skew(v3)
  + beta * v3 * v3.transpose();

  return Vinv;
}

BOOST_AUTO_TEST_CASE(test_log3)
{
  using CppAD::AD;
  using CppAD::NearEqual;

  typedef double Scalar;
  typedef AD<Scalar> ADScalar;

  typedef pinocchio::SE3Tpl<Scalar> SE3;
  typedef pinocchio::MotionTpl<Scalar> Motion;
  typedef pinocchio::SE3Tpl<ADScalar> ADSE3;
  typedef pinocchio::MotionTpl<ADScalar> ADMotion;

  Motion v(Motion::Zero());
  SE3 M(SE3::Random()); M.translation().setZero();

  SE3::Matrix3 rot_next = M.rotation() * pinocchio::exp3(v.angular());

  SE3::Matrix3 Jlog3;
  pinocchio::Jlog3(M.rotation(), Jlog3);

  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> Matrix;
  typedef Eigen::Matrix<ADScalar,Eigen::Dynamic,1> ADVector;

  ADMotion ad_v(v.cast<ADScalar>());
  ADSE3 ad_M(M.cast<ADScalar>());
  ADSE3::Matrix3 rot = ad_M.rotation();

  ADVector X(3);

  X = ad_v.angular();

  CppAD::Independent(X);
  ADMotion::Vector3 X_ = X;

  ADSE3::Matrix3 ad_rot_next = rot * pinocchio::exp3(X_);
  ADMotion::Vector3 log_R_next = pinocchio::log3(ad_rot_next);

  ADVector Y(3);
  Y = log_R_next;

  CppAD::ADFun<Scalar> map(X,Y);

  CPPAD_TESTVECTOR(Scalar) x(3);
  Eigen::Map<Motion::Vector3>(x.data()).setZero();

  CPPAD_TESTVECTOR(Scalar) nu_next_vec = map.Forward(0,x);
  Motion::Vector3 nu_next(Eigen::Map<Motion::Vector3>(nu_next_vec.data()));

  SE3::Matrix3 rot_next_from_map = pinocchio::exp3(nu_next);

  CPPAD_TESTVECTOR(Scalar) jac = map.Jacobian(x);

  Matrix jacobian = Eigen::Map<PINOCCHIO_EIGEN_PLAIN_ROW_MAJOR_TYPE(Matrix)>(jac.data(),3,3);

  BOOST_CHECK(rot_next_from_map.isApprox(rot_next));
  BOOST_CHECK(jacobian.isApprox(Jlog3));
}

BOOST_AUTO_TEST_CASE(test_explog_translation)
{
  using CppAD::AD;
  using CppAD::NearEqual;

  typedef double Scalar;
  typedef AD<Scalar> ADScalar;

  typedef pinocchio::SE3Tpl<Scalar> SE3;
  typedef pinocchio::MotionTpl<Scalar> Motion;
  typedef pinocchio::SE3Tpl<ADScalar> ADSE3;
  typedef pinocchio::MotionTpl<ADScalar> ADMotion;

  Motion v(Motion::Zero());
  SE3 M(SE3::Random()); //M.rotation().setIdentity();

  {
    Motion::Vector3 v3_test; v3_test.setRandom();
    SE3::Matrix3 V = computeV(v3_test);
    SE3::Matrix3 Vinv = computeVinv(v3_test);

    BOOST_CHECK((V*Vinv).isIdentity());
  }

  SE3 M_next = M * pinocchio::exp6(v);
//  BOOST_CHECK(M_next.rotation().isIdentity());

  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> Matrix;
  typedef Eigen::Matrix<ADScalar,Eigen::Dynamic,1> ADVector;

  ADMotion ad_v(v.cast<ADScalar>());
  ADSE3 ad_M(M.cast<ADScalar>());

  ADVector X(6);

  X = ad_v.toVector();

  CppAD::Independent(X);
  ADMotion::Vector6 X_ = X;

  pinocchio::MotionRef<ADMotion::Vector6> ad_v_ref(X_);
  ADSE3 ad_M_next = ad_M * pinocchio::exp6(ad_v_ref);

  ADVector Y(6);
  Y.head<3>() = ad_M_next.translation();
  Y.tail<3>() = ad_M.translation() + ad_M.rotation() * computeV(ad_v_ref.angular()) * ad_v_ref.linear();

  CppAD::ADFun<Scalar> map(X,Y);

  CPPAD_TESTVECTOR(Scalar) x((size_t)X.size());
  Eigen::Map<Motion::Vector6>(x.data()).setZero();

  CPPAD_TESTVECTOR(Scalar) translation_vec = map.Forward(0,x);
  Motion::Vector3 translation1(Eigen::Map<Motion::Vector3>(translation_vec.data()));
  Motion::Vector3 translation2(Eigen::Map<Motion::Vector3>(translation_vec.data()+3));
  BOOST_CHECK(translation1.isApprox(M_next.translation()));
  BOOST_CHECK(translation2.isApprox(M_next.translation()));

  CPPAD_TESTVECTOR(Scalar) jac = map.Jacobian(x);

  Matrix jacobian = Eigen::Map<PINOCCHIO_EIGEN_PLAIN_ROW_MAJOR_TYPE(Matrix)>(jac.data(),Y.size(),X.size());

  BOOST_CHECK(jacobian.topLeftCorner(3,3).isApprox(M.rotation()));

}

BOOST_AUTO_TEST_CASE(test_explog)
{
  using CppAD::AD;
  using CppAD::NearEqual;

  typedef double Scalar;
  typedef AD<Scalar> ADScalar;

  typedef pinocchio::SE3Tpl<Scalar> SE3;
  typedef pinocchio::MotionTpl<Scalar> Motion;
  typedef pinocchio::SE3Tpl<ADScalar> ADSE3;
  typedef pinocchio::MotionTpl<ADScalar> ADMotion;

  Motion v(Motion::Zero());
  SE3 M(SE3::Random()); //M.translation().setZero();

  SE3::Matrix6 Jlog6;
  pinocchio::Jlog6(M, Jlog6);

  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> Matrix;
  typedef Eigen::Matrix<ADScalar,Eigen::Dynamic,1> ADVector;

  ADMotion ad_v(v.cast<ADScalar>());
  ADSE3 ad_M(M.cast<ADScalar>());

  ADVector X(6);

  X.segment<3>(Motion::LINEAR) = ad_v.linear();
  X.segment<3>(Motion::ANGULAR) = ad_v.angular();

  CppAD::Independent(X);
  ADMotion::Vector6 X_ = X;
  pinocchio::MotionRef< ADMotion::Vector6> v_X(X_);

  ADSE3 ad_M_next = ad_M * pinocchio::exp6(v_X);
  ADMotion ad_log_M_next = pinocchio::log6(ad_M_next);

  ADVector Y(6);
  Y.segment<3>(Motion::LINEAR) = ad_log_M_next.linear();
  Y.segment<3>(Motion::ANGULAR) = ad_log_M_next.angular();

  CppAD::ADFun<Scalar> map(X,Y);

  CPPAD_TESTVECTOR(Scalar) x(6);
  Eigen::Map<Motion::Vector6>(x.data()).setZero();

  CPPAD_TESTVECTOR(Scalar) nu_next_vec = map.Forward(0,x);
  Motion nu_next(Eigen::Map<Motion::Vector6>(nu_next_vec.data()));

  CPPAD_TESTVECTOR(Scalar) jac = map.Jacobian(x);

  Matrix jacobian = Eigen::Map<PINOCCHIO_EIGEN_PLAIN_ROW_MAJOR_TYPE(Matrix)>(jac.data(),6,6);

  // Check using finite differencies
  Motion dv(Motion::Zero());
  typedef Eigen::Matrix<Scalar,6,6> Matrix6;
  Matrix6 Jlog6_fd(Matrix6::Zero());
  Motion v_plus, v0(log6(M));

  const Scalar eps = 1e-8;
  for(int k = 0; k < 6; ++k)
  {
    dv.toVector()[k] = eps;
    SE3 M_plus = M * exp6(dv);
    v_plus = log6(M_plus);
    Jlog6_fd.col(k) = (v_plus-v0).toVector()/eps;
    dv.toVector()[k] = 0;
  }

  SE3::Matrix6 Jlog6_analytic;
  pinocchio::Jlog6(M, Jlog6_analytic);

  BOOST_CHECK(Jlog6.isApprox(Jlog6_analytic));
  BOOST_CHECK(Jlog6_fd.isApprox(Jlog6,pinocchio::math::sqrt(eps)));
}

BOOST_AUTO_TEST_SUITE_END()

ext: cpp

max_stars_repo_name: mkatliar/pinocchio

max_issues_repo_name: mkatliar/pinocchio

max_forks_repo_name: mkatliar/pinocchio


text:
/*
    This file is part of WARG's computer-vision

    Copyright (c) 2015, Waterloo Aerial Robotics Group (WARG)
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
    3. Usage of this code MUST be explicitly referenced to WARG and this code
       cannot be used in any competition against WARG.
    4. Neither the name of the WARG nor the names of its contributors may be used
       to endorse or promote products derived from this software without specific
       prior written permission.

    THIS SOFTWARE IS PROVIDED BY WARG ''AS IS'' AND ANY
    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL WARG BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE TargetIdentification
#include <boost/test/unit_test.hpp>
#include <boost/log/trivial.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <iostream>
#include "target_identifier.h"
#include "canny_contour_creator.h"
#include "k_means_filter.h"
#include "frame.h"
#include "benchmark.h"
#include "contour_comparison.h"
#include "object_detector.h"
#include "pixel_object.h"

using namespace cv;
using namespace std;
using namespace boost;

ostream & operator<<(ostream & out, vector<Point_<int> > & contour) {
    for(int i = 0; i < contour.size(); i++) {
        out << contour.at(i);
    }
    return out;
}

ostream & operator<<(ostream & out, vector<vector<Point_<int> > > & contour) {
    for(int i = 0; i < contour.size(); i++) {
        out << "{" << endl;
        out << "    " << contour.at(i) << endl;
        out << "}" << endl;
    }
    return out;
}

BOOST_AUTO_TEST_CASE(KMeansAndCanny) {
    vector<vector<Point> > * expected = new vector<vector<Point> >({vector<Point>({Point(1445, 480), Point(1458, 405), Point(1535, 423), Point(1518, 496), Point(1445, 480)})});
    if (boost::unit_test::framework::master_test_suite().argc < 2) {
        BOOST_ERROR("Invalid number of arguments");
    }
    Mat * input = new Mat(imread(boost::unit_test::framework::master_test_suite().argv[1], cv::IMREAD_COLOR));
    Camera camera = Camera::TestCamera();
    Frame f(input, "Test Image", Metadata(), camera);
    KMeansFilter * filter = new KMeansFilter();
    CannyContourCreator * ccreator = new CannyContourCreator();
    ObjectDetector detector(filter, ccreator);

    detector.process_frame(&f);
    vector<vector<Point> > results;
    for (PixelObject * o : f.get_objects()) {
        results.push_back(o->get_contour());
        BOOST_TEST_MESSAGE("Found object of size " << o->get_area());
        BOOST_TEST_MESSAGE("Perimeter: " << o->get_perimeter());
        BOOST_TEST_MESSAGE("Colour: " << o->get_colour());
    }

    double diff = compare_contours(results, *expected);
    BOOST_CHECK(diff > 0.01); // ensures that at least something is detected
    BOOST_TEST_MESSAGE("RESULT: " << diff);

    benchmark_function("k_means", [&]() { filter->filter(f.get_img()); }, 10);
    Mat * filtered = filter->filter(f.get_img());
    benchmark_function("Canny", [&]() { ccreator->get_contours(*filtered); }, 10);
    delete filtered;
    delete filter;
    delete ccreator;
    delete expected;
}

max_stars_repo_name: UWARG/computer-vision

max_stars_repo_licenses: IJG FSFAP

max_issues_repo_name: permikomnaskaltara/computer-vision

max_issues_repo_licenses: IJG FSFAP

max_forks_repo_name: permikomnaskaltara/computer-vision

max_forks_repo_licenses: IJG FSFAP


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

// stdc
#include <sys/stat.h>

// stdc++
#include <iostream>
#include <fstream>
#include <memory>
#include <random>
#include <set>
#include <thread>

// boost
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <boost/version.hpp>

// asl
#include <adobe/string.hpp>
#include <adobe/iomanip_asl_cel.hpp>
#include <adobe/fnv.hpp>

// stlab
#include <stlab/scope.hpp>

// application
#include <binspector/analyzer.hpp>
#include <binspector/parser.hpp>
#include <binspector/fuzz_generators.hpp>
#include <binspector/ostream.hpp>

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

namespace {

typedef tsos<boost::filesystem::ofstream> tsofstream_t;

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

void rest() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
}

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

template <typename T>
T block_on(const stlab::future<T>& f) {
    while (!f.get_try())
        rest();

    return *f.get_try();
}

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

inline stlab::future<rawbytes_t> read(async_bitreader reader, const node_t& node) {
    return reader(node.location_m, node.bit_count_m);
}

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

inline rawbytes_t read_sync(async_bitreader reader, const node_t& node) {
    return block_on(read(reader, node));
}

/****************************************************************************************************/
// might want to make this into a standalone struct that can be owned by the fuzzer, so the
// set isn't shared across multiple fuzzes (if we ever get there.)
bool validate_unique_outfile(const boost::filesystem::path& file, tsofstream_t& output) {
    static std::set<boost::filesystem::path> file_set;
    static std::mutex                        m;

    return stlab::scope<std::lock_guard<std::mutex>>(m, [&] {
        if (file_set.find(file) != file_set.end()) {
            // oops. Don't want to redo an file we've already made.
            // Figure out why you got here and fix it, yo!

            output << "    ! Internal error: duplicate file: " << file.c_str() << '\n';

            return false;
        }

        // Track this file location to make sure it's unique across the files generated.
        file_set.insert(file);

        return true;
    });
};

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

bool duplicate_file(const boost::filesystem::path& src,
                    const boost::filesystem::path& dst,
                    tsofstream_t&                  output) {
    if (!validate_unique_outfile(dst, output))
        return false;

    boost::system::error_code ec;

    copy_file(src, dst, boost::filesystem::copy_option::fail_if_exists, ec);

    if (ec) {
        output << "    ! Could not replace " << dst.c_str() << '\n';

        return false;
    }

// gotta set the right permissions; we probably need a chmod equivalent
// on windows before this will function over there.

#if BOOST_WINDOWS
// necessary for windows?
#else
    if (chmod(dst.c_str(), S_IRUSR | S_IWUSR)) {
        return false;
    }
#endif

    return true;
}

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

inline void rawbytes_out(std::ofstream& output, const rawbytes_t& data) {
    if (data.empty())
        return;

    output.write(reinterpret_cast<const char*>(&data[0]), data.size());
}

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

struct fuzzer_t {
    fuzzer_t(async_bitreader                reader,
             const boost::filesystem::path& input_path,
             const boost::filesystem::path& output_root,
             bool                           path_hash,
             bool                           recurse);

    void fuzz(const inspection_forest_t& forest);

private:
    typedef std::vector<const_inspection_branch_t> node_set_t;

    boost::optional<std::string> fuzz_location_with_opt(const boost::filesystem::path& input_path,
                                                        const inspection_position_t&   location,
                                                        const fuzz_generator_t&        generator);

    std::size_t fuzz_location_with(const boost::filesystem::path& input_path,
                                   const inspection_position_t&   location,
                                   const fuzz_generator_t&        generator) {
        return fuzz_location_with_opt(input_path, location, generator) ? 1 : 0;
    }

    std::size_t fuzz_location_with_enumeration(const inspection_position_t& location,
                                               const attack_vector_t&       entry);

    std::size_t attack_chunk_array_with(const node_set_t& node_set);

    std::size_t attack_chunk_array(const attack_vector_t& entry);

    std::size_t attack_used_value(const attack_vector_t& entry);

    void usage_entry_report(const attack_vector_t& entry);

    bool should_recurse() const;

    std::size_t fuzz_round(boost::filesystem::path    input_path,
                           const inspection_forest_t& forest,
                           const attack_vector_set_t& attack_vector_set);

    void fuzz_recursive(const inspection_forest_t& forest,
                        const attack_vector_set_t& attack_vector_set);

    void fuzz_flat(const inspection_forest_t& forest, const attack_vector_set_t& attack_vector_set);

    async_bitreader         reader_m;
    boost::filesystem::path input_path_m;
    boost::filesystem::path base_output_path_m;
    std::string             basename_m;
    std::string             extension_m;
    tsofstream_t            output_m; // summary output
    bool                    path_hash_m;
    bool                    recurse_m;
};

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

boost::optional<std::string> fuzzer_t::fuzz_location_with_opt(
    const boost::filesystem::path& input_path,
    const inspection_position_t&   location,
    const fuzz_generator_t&        generator) {
    std::size_t bit_count = generator.bit_count();

    if (bit_count % 8 != 0 || !location.byte_aligned()) {
        output_m
            << "    ! Bit-level/byte-unaligned fuzzing is not yet supported. Location skipped.\n";

        return boost::optional<std::string>();
    }

    std::string attack_id = basename_m + "_" + serialize(location);

    if (path_hash_m) {
        if (recurse_m) {
            // append the input path so recursive fuzzes will have different
            // file names if they wind up attacking the same location.
            attack_id += input_path.string();
        }

        attack_id = to_string_fmt(adobe::fnv1a<64>(attack_id), "%llx");
    }

    // REVISIT (fbrereto) : String concatenation here.
    std::string id       = generator.identifier();
    std::string cur_name = attack_id + "_" + std::move(id) + extension_m;

    boost::filesystem::path output_path(base_output_path_m / cur_name);

    if (!duplicate_file(input_path, output_path, output_m))
        return boost::optional<std::string>();

    boost::filesystem::fstream fuzzed(output_path, std::ios::binary | std::ios::in | std::ios::out);

    // std::cerr << canonical(output_path).string() << '\n';

    if (!fuzzed) {
        perror("!");

        throw std::runtime_error("Could not open file for fuzzed output.");
    }

    std::fstream::pos_type pos(location.bytes());

    fuzzed.seekp(pos);

    std::size_t byte_count(bit_count / 8);
    rawbytes_t  fuzz_data(generator());

    fuzzed.write(reinterpret_cast<const char*>(&fuzz_data[0]), byte_count);

    output_m << "    > " << cur_name << '\n';

    return boost::optional<std::string>(cur_name);
}

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

std::size_t fuzzer_t::fuzz_location_with_enumeration(const inspection_position_t& location,
                                                     const attack_vector_t&       entry) {
    if (entry.node_m.get_flag(is_array_element_k))
        std::cerr << "WARNING: fuzzing an array entry; the forest may not be set up properly.\n";

    const adobe::array_t& enumerated_option_set(entry.node_m.option_set_m);
    std::size_t           result(0);

    for (const adobe::any_regular_t& enum_option : enumerated_option_set)
        result +=
            fuzz_location_with(input_path_m,
                               location,
                               make_enum_generator(enum_option,
                                                   entry.node_m.type_m,
                                                   entry.node_m.get_flag(atom_is_big_endian_k),
                                                   entry.node_m.bit_count_m));

    return result;
}

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

std::size_t fuzzer_t::attack_chunk_array_with(const node_set_t& node_set) {
    std::size_t count(node_set.size());

    // no sense in proceeding in these cases.
    if (count == 0 || count == 1)
        return 0;

    std::vector<rawbytes_t>     element_byte_set;
    boost::filesystem::ifstream bfinput(input_path_m, std::ios::binary);
    bitreader_t                 input(bfinput);
    inspection_position_t       startpos(invalid_position_k);
    inspection_position_t       endpos(invalid_position_k);

    // First we get the raw bytes of each element in the array, which we'll later
    // shuffle around and write out in their shuffled sequence starting at the
    // earliest starting offset found among the nodes.
    //
    // NOTE (fbrereto) : It is assumed all data from the beginning of the first
    //                   node to the end of the last node is in a contiguous block
    //                   in the file, and that the shuffling will be done within
    //                   this block.
    for (std::size_t i(0); i < count; ++i) {
        inspection_position_t start_offset(node_set[i]->start_offset_m);
        inspection_position_t end_offset(node_set[i]->end_offset_m);

        if (start_offset == invalid_position_k || end_offset == invalid_position_k ||
            !start_offset.byte_aligned() || !end_offset.byte_aligned() ||
            start_offset > end_offset) {
            output_m << "    ! invalid child node position(s)\n";

            return 0;
        }

        element_byte_set.push_back(input.read(start_offset, end_offset));

        // std::cerr << "element " << i << " : [" << start_offset << ".."
        //           << end_offset << "], size: "
        //           << element_byte_set.back().size() << '\n';

        if (startpos == invalid_position_k || start_offset < startpos)
            startpos = start_offset;

        if (endpos == invalid_position_k || end_offset > endpos)
            endpos = end_offset;
    }

    if (startpos == invalid_position_k || endpos == invalid_position_k) {
        output_m << "    ! bad blocking\n";

        return 0;
    }

    rawbytes_t file_prefix(input.read(bytepos(0), startpos - inspection_byte_k));
    rawbytes_t file_suffix(
        input.read(endpos + inspection_byte_k, input.size() - inspection_byte_k));

    // std::cerr << "prefix is : " << file_prefix.size() << '\n';
    // std::cerr << "suffix is : " << file_suffix.size() << '\n';

    // we start at 1 instead of 0 to reflect the fact we're avoiding the
    // 'no shift' option; each result will be different than the source file.
    for (std::size_t i(1); i < count; ++i) {
        // shift the blocks one to the left.
        std::rotate(element_byte_set.begin(), element_byte_set.begin() + 1, element_byte_set.end());

        std::string cur_name(basename_m);

        cur_name += "_s_" + boost::lexical_cast<std::string>(i) + extension_m;

        boost::filesystem::path output_path(base_output_path_m / cur_name);

        if (!validate_unique_outfile(output_path, output_m))
            continue;

        if (exists(output_path) && !remove(output_path))
            throw std::runtime_error("Could not replace file for fuzzed output.");

        boost::filesystem::ofstream output(output_path, std::ios::binary);

        rawbytes_out(output, file_prefix);

        for (std::size_t j(0); j < count; ++j)
            rawbytes_out(output, element_byte_set[j]);

        rawbytes_out(output, file_suffix);

        output_m << "    > " << cur_name << '\n';
    }

    return (count - 1);
}

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

std::size_t fuzzer_t::attack_chunk_array(const attack_vector_t& entry) {
    std::size_t size = static_cast<std::size_t>(entry.node_m.cardinal_m);

    output_m << entry.path_m << '\n';
    output_m << "    ? attack_type : shuffle\n";
    output_m << "    ? array_size  : " << size << '\n';

    // There are N! possible permutations of shuffledness... so with a
    // decently-sized array you're looking at an intractably large set
    // of fuzzed documents. (e.g., 25 elements = 25! = 1.551121e25
    // possible permutations.) As such our current attack scheme will
    // be a simple rotation, so each array element gets a chance to be
    // at every position within the document. This will give us N - 1
    // files upon output and is a good start for an attack of this type.

    typedef std::vector<const_inspection_branch_t> child_node_set_t;
    //typedef child_node_set_t::iterator             iterator;

    child_node_set_t                          node_set;
    inspection_forest_t::const_child_iterator iter(adobe::child_begin(entry.branch_m));
    inspection_forest_t::const_child_iterator last(adobe::child_end(entry.branch_m));

    for (; iter != last; ++iter)
        node_set.push_back(iter.base());

    if (entry.node_m.cardinal_m != node_set.size()) {
        output_m << "    ! cardinality/node_count mismatch!\n";

        return 0;
    }

    return attack_chunk_array_with(node_set);
}

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

void fuzzer_t::usage_entry_report(const attack_vector_t& entry) {
    // output_m << " > fuzzing " << bit_count << "b @ " << location << '\n';

    inspection_position_t location(entry.node_m.location_m);
    boost::uint64_t       bit_count(entry.node_m.bit_count_m);

    output_m << entry.path_m << '\n';

    if (recurse_m)
        output_m << "    ? base_input  : " << input_path_m.leaf().string() << "\n";

    output_m << "    ? attack_type : usage\n";
    output_m << "    ? use_count   : " << entry.count_m << '\n';
    output_m << "    ? offset      : " << location << '\n';
    output_m << "    ? bits        : " << bit_count << '\n';
    output_m << "    ? type        : ";

    if (entry.node_m.type_m == atom_signed_k)
        output_m << "signed";
    else if (entry.node_m.type_m == atom_unsigned_k)
        output_m << "unsigned";
    else if (entry.node_m.type_m == atom_float_k)
        output_m << "float";
    else // (entry.node_m.type_m == atom_unknown_k)
        output_m << "unknown";

    output_m << '\n';

    output_m << "    ? big_endian  : " << std::boolalpha
             << entry.node_m.get_flag(atom_is_big_endian_k) << '\n';

    if (!entry.node_m.option_set_m.empty())
        output_m << "    ? enum_count  : " << entry.node_m.option_set_m.size() << '\n';
}

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

std::size_t fuzzer_t::attack_used_value(const attack_vector_t& entry) {
    usage_entry_report(entry);

    inspection_position_t location(entry.node_m.location_m);
    boost::uint64_t       bit_count(entry.node_m.bit_count_m);
    std::size_t           result(0);

    result += fuzz_location_with(input_path_m, location, make_zero_generator(bit_count));

    result += fuzz_location_with(input_path_m, location, make_ones_generator(bit_count));

    rawbytes_t raw{read_sync(reader_m, entry.node_m)};

    result += fuzz_location_with(input_path_m, location, make_less_generator(entry.node_m, raw));

    result += fuzz_location_with(input_path_m, location, make_more_generator(entry.node_m, raw));

    result += fuzz_location_with(input_path_m, location, make_rand_generator(bit_count));

    if (!entry.node_m.option_set_m.empty()) {
        // We're looking at an enumerated value. Each of the options
        // in the set are values to which we can set this enumeration,
        // so let's go and do that just to see what breaks.

        result += fuzz_location_with_enumeration(location, entry);
    }

    return result;
}

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

void fuzzer_t::fuzz_recursive(const inspection_forest_t& forest,
                              const attack_vector_set_t& attack_vector_set) {
    std::size_t result(0);
    std::size_t progress(0);

    std::cerr << "Fuzzing random weak points ";

    typedef stlab::future<std::size_t>   future_t;
    typedef std::vector<future_t>        futures_t;
    typedef typename futures_t::iterator iterator;

    futures_t futures;

    constexpr std::size_t n_k{1000};
    const std::size_t     p_k{std::thread::hardware_concurrency()};

    while (true) {
        while (futures.size() < p_k) {
            futures.push_back(
                stlab::async(stlab::default_executor,
                             [ _this = this, &_forest = forest, &_avs = attack_vector_set ] {
                                 return _this->fuzz_round(_this->input_path_m, _forest, _avs);
                             }));
        }

        iterator mid = std::partition(
            begin(futures), end(futures), [](stlab::future<std::size_t> f) { return static_cast<bool>(f.get_try()); });

        for (iterator iter(begin(futures)); iter != mid; ++iter) {
            result += *iter->get_try();
        }

        futures.erase(begin(futures), mid);

        if (result > n_k)
            break;

        std::size_t next_progress(static_cast<double>(result) / n_k * 100);

        if (progress != next_progress)
            std::cerr << '.';

        progress = next_progress;

        rest();
    }

    for (const future_t& f : futures) {
        result += block_on(f);
    }

    std::cerr << " done. Generated " << result << " files\n";
}

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

bool fuzzer_t::should_recurse() const {
    static thread_local std::mt19937                     gen{std::random_device()()};
    static thread_local std::uniform_real_distribution<> r_dist(0, 1);

    return r_dist(gen) < 0.8;
}

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

std::size_t fuzzer_t::fuzz_round(boost::filesystem::path    input_path,
                                 const inspection_forest_t& forest,
                                 const attack_vector_set_t& attack_vector_set) {
    static thread_local std::mt19937 gen{std::random_device()()};

    std::uniform_int_distribution<std::size_t> dist(0, attack_vector_set.size() - 1);
    std::size_t                                attack_index(dist(gen));
    const attack_vector_t&                     attack(attack_vector_set[attack_index]);
    std::size_t                                result(0);

    if (attack.type_m == attack_vector_t::type_atom_usage_k) {
        std::size_t                                options_count(attack.node_m.option_set_m.size());
        std::uniform_int_distribution<std::size_t> dist(0, options_count + 4);
        std::size_t                                selected(dist(gen));
        fuzz_generator_t                           g;

        if (selected == 0) {
            g = fuzz_generator_t(make_zero_generator(attack.node_m.bit_count_m));
        } else if (selected == 1) {
            g = fuzz_generator_t(make_ones_generator(attack.node_m.bit_count_m));
        } else if (selected == 2) {
            g = fuzz_generator_t(
                make_less_generator(attack.node_m, read_sync(reader_m, attack.node_m)));
        } else if (selected == 3) {
            g = fuzz_generator_t(
                make_more_generator(attack.node_m, read_sync(reader_m, attack.node_m)));
        } else if (selected == 4) {
            g = fuzz_generator_t(make_rand_generator(attack.node_m.bit_count_m));
        } else {
            selected -= 5;

            g = make_enum_generator(attack.node_m.option_set_m[selected],
                                    attack.node_m.type_m,
                                    attack.node_m.get_flag(atom_is_big_endian_k),
                                    attack.node_m.bit_count_m);
        }

        usage_entry_report(attack);

        boost::optional<std::string> new_path(
            fuzz_location_with_opt(input_path, attack.node_m.location_m, g));

        if (new_path) {
            ++result;

            if (should_recurse()) {
                result += fuzz_round(base_output_path_m / *new_path, forest, attack_vector_set);
            }
        }
    }

    return result;
}

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

void fuzzer_t::fuzz_flat(const inspection_forest_t& forest,
                         const attack_vector_set_t& attack_vector_set) {
    std::size_t count(attack_vector_set.size());
    std::size_t progress(0);
    std::size_t result(0);

    std::cerr << "Fuzzing " << count << " weak points ";

    for (std::size_t i(0); i < count; ++i) {
        const attack_vector_t& attack(attack_vector_set[i]);

        if (attack.type_m == attack_vector_t::type_atom_usage_k)
            result += attack_used_value(attack);
        else if (attack.type_m == attack_vector_t::type_array_shuffle_k)
            result += attack_chunk_array(attack);
        else
            output_m << "    ! ERROR: Unknown attack vector type.\n";

        std::size_t next_progress(static_cast<double>(i) / count * 100);

        if (progress != next_progress)
            std::cerr << '.';

        progress = next_progress;
    }

    std::cerr << " done. Generated " << result << " files\n";
}

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

void fuzzer_t::fuzz(const inspection_forest_t& forest) {
    if (!is_directory(base_output_path_m))
        throw std::runtime_error(
            adobe::make_string("Output directory failure: ", base_output_path_m.string().c_str()));

    attack_vector_set_t attack_vector_set(build_attack_vector_set(forest));

    if (!recurse_m)
        fuzz_flat(forest, attack_vector_set);
    else
        fuzz_recursive(forest, attack_vector_set);
}

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

boost::filesystem::path get_base_output_path(const boost::filesystem::path& input_path,
                                             const boost::filesystem::path& output_root) {
    boost::filesystem::path result;

    if (exists(output_root))
        result = output_root;
    else
        result = input_path.parent_path();

    result /= "fuzzed";

    if (!exists(result))
        boost::filesystem::create_directory(result);

    return result;
}

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

fuzzer_t::fuzzer_t(async_bitreader                reader,
                   const boost::filesystem::path& input_path,
                   const boost::filesystem::path& output_root,
                   bool                           path_hash,
                   bool                           recurse)
    : reader_m(reader), input_path_m(input_path),
      base_output_path_m(get_base_output_path(input_path_m, output_root)),
      basename_m(input_path_m.stem().string()), extension_m(input_path_m.extension().string()),
      output_m(base_output_path_m / (basename_m + "_fuzzing_summary.txt")), path_hash_m(path_hash),
      recurse_m(recurse) {}

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

} // namespace

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

void fuzz(const inspection_forest_t&     forest,
          const boost::filesystem::path& input_path,
          const boost::filesystem::path& output_root,
          bool                           path_hash,
          bool                           recurse) {
    fuzzer_t(make_async_bitreader(input_path), input_path, output_root, path_hash, recurse)
        .fuzz(forest);
}

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


text:
/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>
#include <canvas/canvastools.hxx>

#include <boost/shared_ptr.hpp>

#include "appletshape.hxx"
#include "externalshapebase.hxx"
#include "vieweventhandler.hxx"
#include "viewappletshape.hxx"
#include "tools.hxx"

#include <boost/bind.hpp>
#include <algorithm>

using namespace ::com::sun::star;

namespace slideshow
{
    namespace internal
    {
        /** Represents an applet shape.

            This implementation offers support for applet shapes (both
            Java applets, and Netscape plugins). Such shapes need
            special treatment.
         */
        class AppletShape : public ExternalShapeBase
        {
        public:
            /** Create a shape for the given XShape for a applet object

            	@param xShape
                The XShape to represent.

                @param nPrio
                Externally-determined shape priority (used e.g. for
                paint ordering). This number _must be_ unique!

                @param rServiceName
                Service name to use, when creating the actual viewer
                component

                @param pPropCopyTable
                Table of plain ASCII property names, to copy from
                xShape to applet.

                @param nNumPropEntries
                Number of property table entries (in pPropCopyTable)
             */
            AppletShape( const ::com::sun::star::uno::Reference<
                       		::com::sun::star::drawing::XShape >&	xShape,
                         double										nPrio,
                         const ::rtl::OUString&                     rServiceName,
                         const char**                               pPropCopyTable,
                         sal_Size                                   nNumPropEntries,
                         const SlideShowContext&                    rContext ); // throw ShapeLoadFailedException;

        private:

            // View layer methods
            //------------------------------------------------------------------

            virtual void addViewLayer( const ViewLayerSharedPtr& 	rNewLayer,
                                       bool							bRedrawLayer );
            virtual bool removeViewLayer( const ViewLayerSharedPtr& rNewLayer );
            virtual bool clearAllViewLayers();

            // ExternalShapeBase methods
            //------------------------------------------------------------------

            virtual bool implRender( const ::basegfx::B2DRange& rCurrBounds ) const;
            virtual void implViewChanged( const UnoViewSharedPtr& rView );
            virtual void implViewsChanged();
            virtual bool implStartIntrinsicAnimation();
            virtual bool implEndIntrinsicAnimation();
            virtual bool implPauseIntrinsicAnimation();
            virtual bool implIsIntrinsicAnimationPlaying() const;
            virtual void implSetIntrinsicAnimationTime(double);

            const ::rtl::OUString                           maServiceName;
            const char**                                    mpPropCopyTable;
            const sal_Size                                  mnNumPropEntries;

            /// the list of active view shapes (one for each registered view layer)
            typedef ::std::vector< ViewAppletShapeSharedPtr > ViewAppletShapeVector;
            ViewAppletShapeVector                           maViewAppletShapes;
            bool                                             mbIsPlaying;
        };

        AppletShape::AppletShape( const uno::Reference< drawing::XShape >& xShape,
                                  double                                   nPrio,
                                  const ::rtl::OUString&                   rServiceName,
                                  const char**                             pPropCopyTable,
                                  sal_Size                                 nNumPropEntries,
                                  const SlideShowContext&                  rContext ) :
            ExternalShapeBase( xShape, nPrio, rContext ),
            maServiceName( rServiceName ),
            mpPropCopyTable( pPropCopyTable ),
            mnNumPropEntries( nNumPropEntries ),
            maViewAppletShapes(),
            mbIsPlaying(false)
        {
        }

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

        void AppletShape::implViewChanged( const UnoViewSharedPtr& rView )
        {
            // determine ViewAppletShape that needs update
            ViewAppletShapeVector::const_iterator       aIter(maViewAppletShapes.begin());
            ViewAppletShapeVector::const_iterator const aEnd (maViewAppletShapes.end());
            while( aIter != aEnd )
            {
                if( (*aIter)->getViewLayer()->isOnView(rView) )
                    (*aIter)->resize(getBounds());

                ++aIter;
            }
        }

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

        void AppletShape::implViewsChanged()
        {
            // resize all ViewShapes
            ::std::for_each( maViewAppletShapes.begin(),
                             maViewAppletShapes.end(),
                             ::boost::bind(
                                 &ViewAppletShape::resize,
                                 _1,
                                 ::boost::cref( AppletShape::getBounds())) );
        }

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

        void AppletShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer,
                                        bool                      bRedrawLayer )
        {
            try
            {
                maViewAppletShapes.push_back(
                    ViewAppletShapeSharedPtr( new ViewAppletShape( rNewLayer,
                                                                   getXShape(),
                                                                   maServiceName,
                                                                   mpPropCopyTable,
                                                                   mnNumPropEntries,
                                                                   mxComponentContext )));

                // push new size to view shape
                maViewAppletShapes.back()->resize( getBounds() );

                // render the Shape on the newly added ViewLayer
                if( bRedrawLayer )
                    maViewAppletShapes.back()->render( getBounds() );
            }
            catch(uno::Exception&)
            {
                // ignore failed shapes - slideshow should run with
                // the remaining content
            }
        }

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

        bool AppletShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
        {
            const ViewAppletShapeVector::iterator aEnd( maViewAppletShapes.end() );

            OSL_ENSURE( ::std::count_if(maViewAppletShapes.begin(),
                                        aEnd,
                                        ::boost::bind<bool>(
                                            ::std::equal_to< ViewLayerSharedPtr >(),
                                            ::boost::bind( &ViewAppletShape::getViewLayer, _1 ),
                                            ::boost::cref( rLayer ) ) ) < 2,
                        "AppletShape::removeViewLayer(): Duplicate ViewLayer entries!" );

            ViewAppletShapeVector::iterator aIter;

            if( (aIter=::std::remove_if( maViewAppletShapes.begin(),
                                         aEnd,
                                         ::boost::bind<bool>(
                                             ::std::equal_to< ViewLayerSharedPtr >(),
                                             ::boost::bind( &ViewAppletShape::getViewLayer,
                                                            _1 ),
                                             ::boost::cref( rLayer ) ) )) == aEnd )
            {
                // view layer seemingly was not added, failed
                return false;
            }

            // actually erase from container
            maViewAppletShapes.erase( aIter, aEnd );

            return true;
        }

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

        bool AppletShape::clearAllViewLayers()
        {
            maViewAppletShapes.clear();
            return true;
        }

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

        bool AppletShape::implRender( const ::basegfx::B2DRange& rCurrBounds ) const
        {
            // redraw all view shapes, by calling their update() method
            if( ::std::count_if( maViewAppletShapes.begin(),
                                 maViewAppletShapes.end(),
                                 ::boost::bind<bool>(
                                     ::boost::mem_fn( &ViewAppletShape::render ),
                                     _1,
                                     ::boost::cref( rCurrBounds ) ) )
                != static_cast<ViewAppletShapeVector::difference_type>(maViewAppletShapes.size()) )
            {
                // at least one of the ViewShape::update() calls did return
                // false - update failed on at least one ViewLayer
                return false;
            }

            return true;
        }

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

        bool AppletShape::implStartIntrinsicAnimation()
        {
            ::std::for_each( maViewAppletShapes.begin(),
                             maViewAppletShapes.end(),
                             ::boost::bind( &ViewAppletShape::startApplet,
                                            _1,
                                            ::boost::cref( getBounds() )));
            mbIsPlaying = true;

            return true;
        }

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

        bool AppletShape::implEndIntrinsicAnimation()
        {
            ::std::for_each( maViewAppletShapes.begin(),
                             maViewAppletShapes.end(),
                             ::boost::mem_fn( &ViewAppletShape::endApplet ) );

            mbIsPlaying = false;

            return true;
        }

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

        bool AppletShape::implPauseIntrinsicAnimation()
        {
            // TODO(F1): any way of temporarily disabling/deactivating
            // applets?
            return true;
        }

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

        bool AppletShape::implIsIntrinsicAnimationPlaying() const
        {
            return mbIsPlaying;
        }

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

        void AppletShape::implSetIntrinsicAnimationTime(double)
        {
            // No way of doing this, or?
        }

        boost::shared_ptr<Shape> createAppletShape(
            const uno::Reference< drawing::XShape >& xShape,
            double                                   nPrio,
            const ::rtl::OUString&                   rServiceName,
            const char**                             pPropCopyTable,
            sal_Size                                 nNumPropEntries,
            const SlideShowContext&                  rContext )
        {
            boost::shared_ptr< AppletShape > pAppletShape(
                new AppletShape(xShape,
                                nPrio,
                                rServiceName,
                                pPropCopyTable,
                                nNumPropEntries,
                                rContext) );

            return pAppletShape;
        }
    }
}

ext: cxx

max_stars_repo_name: Grosskopf/openoffice

max_issues_repo_name: Grosskopf/openoffice

max_forks_repo_name: Grosskopf/openoffice


text:
/*
 * Data:                2019-04-08
 * Autor:               Jakub Markowski
 * Kompilacja:          g++ ping.cpp -o ping.run -std=c++14 -lpthread
 *                      Zamiast g++ można użyć clang++
 *                      Do skompilowaniu programu potrzebna jest biblioteka Boost.Asio oraz Boost.LexicalCast
 * Uruchamianie:        ./ping.run <adres IP lub nazwa domenowa>
 */

#include <boost/asio/generic/raw_protocol.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
#include "../header/icmp.hpp"
#include "../header/ipv4.hpp"
#include "../header/ipv6.hpp"
#include <boost/asio/ip/icmp.hpp>
#include <boost/asio/ip/unicast.hpp>
#include <boost/asio/streambuf.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

namespace asio = boost::asio;
using boost::system::error_code;

void error(const std::string& what, error_code err)
{
    if(err == asio::error::operation_aborted) return;

    std::cerr << what << ": " << err.message() << std::endl;
}

//funkcja generująca losowe alfanumeryczne stringi
//https://stackoverflow.com/questions/440133/how-do-i-create-a-random-alpha-numeric-string-in-c
std::string random_string( size_t length )
{
    auto randchar = []() -> char
    {
        const char charset[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
        const size_t max_index = (sizeof(charset) - 1);
        return charset[ rand() % max_index ];
    };
    std::string str(length,0);
    std::generate_n( str.begin(), length, randchar );
    return str;
}

asio::io_context context;
asio::ip::icmp::socket receiving_socket(context);

asio::streambuf buff(256);
std::istream istr(&buff);
asio::ip::icmp::endpoint remote;

/*
.##.....##....###....##....##.########..##.......########.########.
.##.....##...##.##...###...##.##.....##.##.......##.......##.....##
.##.....##..##...##..####..##.##.....##.##.......##.......##.....##
.#########.##.....##.##.##.##.##.....##.##.......######...########.
.##.....##.#########.##..####.##.....##.##.......##.......##...##..
.##.....##.##.....##.##...###.##.....##.##.......##.......##....##.
.##.....##.##.....##.##....##.########..########.########.##.....##
*/
int received_counter = 4;
//TODO: sprawdzanie typu pakietu icmp
/* Funkcja obsługująca odebrany pakiet icmp
sprawdza typ odebranego pakietu, a następnie wypełnia struktury nagłówków i odczytuje z nich interesujące nas informacje. */
void async_receive_from_handler(const error_code &err, size_t bytes)
{
    if(err)
    {
        error("receive_from", err);
        return;
    }

    std::cout << "Pong received: ";

    buff.commit(256);
    if(remote.address().is_v6())
    {
        /* header::ipv6 hipv6;
        istr >> hipv6;
        in6_addr temp_daddr = hipv6.daddr();
        char daddr[INET6_ADDRSTRLEN];
        inet_ntop(AF_INET6, &temp_daddr, daddr, INET6_ADDRSTRLEN);
        std::cout << "v6 " << "hop limit:" << int(hipv6.hlim()) << " length:" << hipv6.length() << " destination address:" <<  daddr << " "; */

    }
    else
    {
        header::ipv4 hipv4;

        istr >> hipv4;
        std::cout << "v4 " << "hop limit:" << int(hipv4.ttl()) << " length:" << hipv4.length() << " destination address:" <<  header::address_to_string(hipv4.daddr()) << " ";

    }

    header::icmp hicmp;
    istr >> hicmp;
    std::cout << "type:" << hicmp.type() << " code:" << hicmp.code() << " id:" << hicmp.id() << " sequence:" << hicmp.sequence();

    buff.consume(256);
    std::cout << std::endl << std::flush;
    received_counter--;
    if(received_counter>0) receiving_socket.async_receive_from(buff.prepare(256), remote, async_receive_from_handler);
}

/*
..######..########.##....##.########.....##.....##....###....##....##.########..##.......########.########.
.##....##.##.......###...##.##.....##....##.....##...##.##...###...##.##.....##.##.......##.......##.....##
.##.......##.......####..##.##.....##....##.....##..##...##..####..##.##.....##.##.......##.......##.....##
..######..######...##.##.##.##.....##....#########.##.....##.##.##.##.##.....##.##.......######...########.
.......##.##.......##..####.##.....##....##.....##.#########.##..####.##.....##.##.......##.......##...##..
.##....##.##.......##...###.##.....##....##.....##.##.....##.##...###.##.....##.##.......##.......##....##.
..######..########.##....##.########.....##.....##.##.....##.##....##.########..########.########.##.....##
*/
void timer_handler(const error_code &err);

uint16_t sent_counter = 1;
asio::deadline_timer tmr(context, boost::posix_time::seconds(1));
/* Funkcja obsługująca wysłanie pakietu
Uruchamia oczekiwanie 1 sek na wysłanie kolejnego */
void async_send_handler(const error_code &err, const size_t sent)
{
    if(sent_counter++<5)
        tmr.async_wait(timer_handler);

}

/*
.########.####.##.....##.########.########.....##.....##....###....##....##.########..##.......########.########.
....##.....##..###...###.##.......##.....##....##.....##...##.##...###...##.##.....##.##.......##.......##.....##
....##.....##..####.####.##.......##.....##....##.....##..##...##..####..##.##.....##.##.......##.......##.....##
....##.....##..##.###.##.######...########.....#########.##.....##.##.##.##.##.....##.##.......######...########.
....##.....##..##.....##.##.......##...##......##.....##.#########.##..####.##.....##.##.......##.......##...##..
....##.....##..##.....##.##.......##....##.....##.....##.##.....##.##...###.##.....##.##.......##.......##....##.
....##....####.##.....##.########.##.....##....##.....##.##.....##.##....##.########..########.########.##.....##
*/
uint16_t ping_type = 8;
asio::ip::icmp::endpoint endpoint;
asio::ip::icmp::socket sending_socket(context);
/* Funkcja obsługująca zdarzenie minięcia sekundy
Buduje pakiet icmp, a następnie wysyła go */
void timer_handler(const error_code &err)
{

    header::icmp icmp_hdr;
    icmp_hdr.type(ping_type);
    icmp_hdr.code(0);
    uint32_t pid = getpid();
    uint16_t lower_pid = (uint16_t) pid & 0x0000FFFF;

    icmp_hdr.id(htons(lower_pid));
    icmp_hdr.sequence(htons(sent_counter));

    std::string data = random_string(22);

    icmp_hdr.compute_checksum(data.data(), data.length());

    asio::streambuf request_buffer;
    std::ostream os(&request_buffer);

    os << icmp_hdr << data;

    tmr.expires_from_now(boost::posix_time::seconds(1));
    sending_socket.async_send(request_buffer.data(), async_send_handler);

}

/*
.##.....##....###....####.##....##
.###...###...##.##....##..###...##
.####.####..##...##...##..####..##
.##.###.##.##.....##..##..##.##.##
.##.....##.#########..##..##..####
.##.....##.##.....##..##..##...###
.##.....##.##.....##.####.##....##
*/

int main(int argc, char** argv)
{
    if (argc != 2 && argc != 3)
    {
        std::cerr << "Invocation: " << argv[0] << "<HOSTNAME OR IP ADDRESS> <INTERFACE>(optional for link-local addresses" << std::endl;
        return 1;
    }

    header::icmp icmp_hdr;

    error_code err;
    asio::ip::icmp::resolver resolver(context);

    // Rozwiązywanie nazwy
    auto result = resolver.resolve(argv[1], nullptr, err);
    if(err)
    {
        error("resolve", err);
        return 1;
    }

    for(auto&& i : result)
        endpoint = i.endpoint();

    sending_socket.open(endpoint.protocol());

    // Ustawienie ttl
    asio::ip::unicast::hops ttl(64);
    sending_socket.set_option(ttl);

    asio::ip::icmp::endpoint final_endpoint;
    /* Zbudowanie odpowiedniego adresu jeżeli jest link-local, oraz uruchomienie nasłuchiwania na odpowiednim protokole */
    if(endpoint.address().is_v6())
    {
        if(endpoint.address().to_v6().is_link_local())
        {
            final_endpoint = asio::ip::icmp::endpoint(asio::ip::make_address_v6(endpoint.address().to_v6().to_string()+"%"+argv[2]), boost::lexical_cast<unsigned short>(argv[2]));
        }
        else
        {
            final_endpoint = endpoint;
        }
        receiving_socket.open(asio::ip::icmp::v6());
        receiving_socket.bind(asio::ip::icmp::endpoint(asio::ip::icmp::v6(), 0));
        ping_type += 120;
    }
    else
    {
        final_endpoint = endpoint;
        receiving_socket.open(asio::ip::icmp::v4());
        receiving_socket.bind(asio::ip::icmp::endpoint(asio::ip::icmp::v4(), 0));
    }

    receiving_socket.async_receive_from(buff.prepare(256), remote, async_receive_from_handler);

    sending_socket.connect(final_endpoint);

    icmp_hdr.type(ping_type);
    icmp_hdr.code(0);
    uint32_t pid = getpid();
    uint16_t lower_pid = (uint16_t) pid & 0x0000FFFF;

    icmp_hdr.id(htons(lower_pid));
    icmp_hdr.sequence(htons(sent_counter));

    std::string data = random_string(22);

    icmp_hdr.compute_checksum(data.data(), data.length());

    asio::streambuf request_buffer;
    std::ostream os(&request_buffer);

    os << icmp_hdr << data;

    sending_socket.async_send(request_buffer.data(), async_send_handler);

    context.run();
    sending_socket.close();
    receiving_socket.close();

    return 1;
}


text:
#include <string>
#include <vector>
#include <iostream>
#include <fstream>

#include <boost/filesystem.hpp>

#include "mapsforge_map_reader.hpp"
#include "theme.hpp"
#include "renderer.hpp"
#include "tile_key.hpp"

using namespace std ;
namespace fs = boost::filesystem ;

void printUsageAndExit()
{
    cerr << "Usage: render_tile --map <map_file> --theme <map_theme> --layer <layer_name> --out <out_file> <tx> <ty> <tz> " << endl ;
    exit(1) ;
}

int main(int argc, char *argv[])
{
    string map_file, map_theme, mapLayer, out_file ;

    int i = 1;
    for( ; i<argc ; i++ )
    {
        string arg = argv[i] ;

        if ( arg == "--map" ) {
            if ( ++i < argc )
                map_file = argv[i] ;
        }
        else if ( arg == "--theme" ) {
            if ( ++i < argc )
                map_theme = argv[i] ;
        }
        else if ( arg == "--layer" ) {
            if ( ++i < argc )
                mapLayer = argv[i] ;
        }
        else if ( arg == "--out" ) {
            if ( ++i < argc )
                out_file = argv[i] ;
        }
        else break ;
    }

    if ( i != argc - 3 || map_file.empty() || map_theme.empty() || out_file.empty() )
        printUsageAndExit() ;

    uint tx = stoi(argv[i++]) ;
    uint ty = stoi(argv[i++]) ;
    uint tz = stoi(argv[i++]) ;

//    MapFileReader::initTileCache(100000) ;
    MapFileReader reader ;

    try {
        reader.open(map_file) ;
    }
    catch ( std::runtime_error &e ) {
        cerr << e.what() << endl ;
        exit(1) ;
    }

    TileKey key(tx, ty, tz, false) ;

    VectorTile tile = reader.readTile(key, 1);

    std::shared_ptr<RenderTheme> theme(new RenderTheme) ;
    if ( !theme->read(map_theme) ) {
        cerr << "Can't read theme file: " << map_theme << endl ;
        exit(1) ;
    }

    Renderer r(theme, "en", false) ;

    ImageBuffer buf(256, 256) ;

    r.render(key, buf, tile, mapLayer.empty() ? theme->defaultLayer() : mapLayer, 256) ;

    buf.saveToPNG(out_file) ;

    return 0 ;
}

max_stars_repo_name: malasiot/maplite

max_issues_repo_name: malasiot/mftools

max_forks_repo_name: malasiot/mftools


text:
/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <marcin.kolny@gmail.com> wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.       Marcin Kolny
 * ----------------------------------------------------------------------------
 */
#include "pluginloader.h"

#include "wtcommon/logger.h"

#include <boost/filesystem.hpp>

namespace WT {

PluginLoader::PluginLoader(const std::vector<std::string> &plugin_dir_paths)
{
    for (const auto &path : plugin_dir_paths)
    {
        WT_LOG_D << "Loading plugins from " << path;
        load_handlers(path);
    }
}

void PluginLoader::load_handlers(const std::string &plugin_dir_path)
{
    namespace fs = boost::filesystem;
    if (!fs::exists(plugin_dir_path) || !fs::is_directory(plugin_dir_path))
    {
        return;
    }

    fs::directory_iterator it(plugin_dir_path);
    fs::directory_iterator endit;

    while (it != endit)
    {
        try_load_plugin(it->path().string());
        ++it;
    }
}

std::vector<std::shared_ptr<PluginWrapper>> PluginLoader::get_plugins() const
{
    return plugins;
}

void PluginLoader::try_load_plugin(const std::string &path)
{
    boost::filesystem::path pt = path;
    if (!boost::filesystem::is_regular_file(pt) || pt.extension() != boost::dll::shared_library::suffix())
    {
        return;
    }

    try
    {
        WT_LOG_D << "Trying to load plugin: " << pt;

        auto wrapper = std::make_shared<PluginWrapper>(std::make_shared<boost::dll::shared_library>(pt));
        if (wrapper->get_version() != WT_VERSION_MAJOR)
        {
            WT_LOG_D << "Found symbol, but version doesn't match(expected " << WT_VERSION_MAJOR << " but is " << wrapper->get_version() << ")";
            return;
        }

        if (plugins.end() != std::find_if(plugins.begin(), plugins.end(),
                                          [wrapper] (const std::shared_ptr<PluginWrapper>& plugin_wrapper) {
                                          return strcmp(wrapper->get_name(), plugin_wrapper->get_name()) == 0;
    }))
        {
            WT_LOG_W << "Plugin has not been added because plugin with the same name (" << wrapper->get_name() << ") already exists.";
            return;
        }

        plugins.push_back(wrapper);

        WT_LOG_I << "Added pluign " << plugins.back()->get_name();
    }
    catch (const boost::system::system_error& err)
    {
        WT_LOG_W << "cannot load plugin " << pt << ": "<< err.what();
    }
}

bool PluginWrapper::update_data_entry(char in_out_app_name[WT_MAX_APP_NAME_LEN],
                                      char in_out_window_title[WT_MAX_WIN_TITLE_LEN])
{
    if (plugin_info.update_data_func)
    {
        return plugin_info.update_data_func(plugin, in_out_app_name, in_out_window_title);
    }
    return false;
}

bool PluginWrapper::suspend_logging(char in_out_app_name[WT_MAX_APP_NAME_LEN],
                                    char in_out_window_title[WT_MAX_WIN_TITLE_LEN])
{
    if (plugin_info.suspend_tracking_func)
    {
        return plugin_info.suspend_tracking_func(plugin, in_out_app_name, in_out_window_title);
    }
    return false;
}

}

ext: cc

max_stars_repo_name: loganek/workertracker

max_issues_repo_name: loganek/workertracker

max_forks_repo_name: loganek/workertracker


text: #include <boost/units/systems/cgs/velocity.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
The MIT License

Copyright 2019 hiratake26to

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

/**
 * \file Address.cpp
 * \author hiratake26to@gmail
 * \date 2019
 */

#include "net/Address.hpp"

#include <iostream>
#include <string>
#include <boost/algorithm/string.hpp>
#include <tao/pegtl.hpp>
using std::string;
using std::optional;

static string toStrAddr(uint32_t addr) {
  uint8_t oct[4];
  // [0].[1].[2].[3]
  oct[0] = 0xFF & (addr >> 24);
  oct[1] = 0xFF & (addr >> 16);
  oct[2] = 0xFF & (addr >>  8);
  oct[3] = 0xFF & (addr);

  string str_addr
    = std::to_string(oct[0]) + "."
    + std::to_string(oct[1]) + "."
    + std::to_string(oct[2]) + "."
    + std::to_string(oct[3]);

  return str_addr;
}

static uint32_t toBinAddr(string s) {
  uint32_t ret = 0;
  string buf = "";
  int i = 0;
  for (const char& c : s) {
    if (c >= '0' && c <= '9') buf += c;
    else {
      int num = std::atoi(buf.c_str());
      ret |= num << (24-8*i);
      buf = "";
      ++i;
    }
  }
  int num = std::atoi(buf.c_str());
  ret |= num;
  return ret;
}

namespace pegtl = tao::pegtl;

namespace Address {
  using std::string;
  using namespace tao::pegtl;

  struct octet
    : pegtl::rep_min_max<1, 3, pegtl::digit> {};
  struct dot
    : pegtl::one<'.'> {};
  struct local
    : pegtl::seq<octet, dot, octet, dot, octet, dot, octet> {};
  struct mask_cidr
    : pegtl::rep_min_max<1, 2, pegtl::digit> {};
  struct cidr
    : pegtl::seq<local, one<'/'>, mask_cidr> {};
  struct mask
    : pegtl::seq<octet, dot, octet, dot, octet, dot, octet> {};
  struct address_with_mask
    : pegtl::seq<local, one<','>, mask> {};
  struct grammer
    : pegtl::sor<pegtl::seq<cidr,eof>, pegtl::seq<address_with_mask,eof>> {};

  const char *cidr_mask_tbl[] = {
    "000.000.000.000",
    "128.000.000.000",
    "192.000.000.000",
    "224.000.000.000",
    "240.000.000.000",
    "248.000.000.000",
    "252.000.000.000",
    "254.000.000.000",
    "255.000.000.000",
    "255.128.000.000",
    "255.192.000.000",
    "255.224.000.000",
    "255.240.000.000",
    "255.248.000.000",
    "255.252.000.000",
    "255.254.000.000",
    "255.255.000.000",
    "255.255.128.000",
    "255.255.192.000",
    "255.255.224.000",
    "255.255.240.000",
    "255.255.248.000",
    "255.255.252.000",
    "255.255.254.000",
    "255.255.255.000",
    "255.255.255.128",
    "255.255.255.192",
    "255.255.255.224",
    "255.255.255.240",
    "255.255.255.248",
    "255.255.255.252",
    "255.255.255.254",
    "255.255.255.255"
  };

  template< typename Rule >
  struct action
    : pegtl::nothing< Rule >
  {};

  template<>
  struct action< local >
  {
    template< typename Input >
    static void apply( const Input& in, string& local, string& mask, bool &ok)
    {
      local = in.string();
    }
  };

  template<>
  struct action< mask_cidr >
  {
    template< typename Input >
    static void apply( const Input& in, string& local, string& mask, bool &ok)
    {
      int n = std::stol(in.string());
      if (n > 32 || n < 0) {
        //mask = "255.255.255.255";
        throw std::runtime_error("Invalid mask number: " + in.string() + ", CIDR");
      } else {
        mask = cidr_mask_tbl[n];
      }
    }
  };

  template<>
  struct action< mask >
  {
    template< typename Input >
    static void apply( const Input& in, string& local, string& mask, bool &ok)
    {
      mask = in.string();
    }
  };

  template<>
  struct action< grammer >
  {
    template< typename Input >
    static void apply( const Input& in, string& local, string& mask, bool &ok)
    {
      ok = true;
    }
  };
}

namespace {
  // netaddress : last local address
  std::map<string, string> assign_address_list;
}

//////////////////////////////////////////////////
/// AddressValue
void AddressValue::parse_and_set(const string& value) {
  string local;
  string mask;
  bool ok = false;
  try {
    string buff;
    pegtl::string_input<> in(value, buff);
    pegtl::parse< Address::grammer, Address::action>( in, local, mask, ok );
    if (!ok) throw std::runtime_error("not ok");

  } catch(const std::exception& e) {
    std::cerr << "Exception in parse address: \"" << value << "\"" << std::endl;
    std::cerr << "what: " << e.what() << std::endl;
    const char* msg
      = "Wrong Address format, it must be \"<Local>,<Mask>\" or \"<CIDR format>\"";
    std::cerr << __FILE__ << ":" << __LINE__ << ":" << msg << std::endl;
    throw std::runtime_error(msg);
  }

  /*
  std::cout << "local : " << local << std::endl;
  std::cout << "mask : " << mask << std::endl;
  std::cout << "ok : " << ok << std::endl;
  */

  m_local = toBinAddr(local);
  m_mask = toBinAddr(mask);
}

AddressValue::AddressValue(const string& value) {
  parse_and_set(value);
}
// do not return, network/bloadcast address
AddressValue AddressValue::GetNextHost() const {
  //std::cout << "[DEBUG] AddressValue::GetNextHost, GetLocal=" << GetLocal() << std::endl;
  AddressValue next = *this;
  next.m_local += 1;
  // check reach to bload cast address
  if (next.m_local == ((next.m_local & next.m_mask) | ~next.m_mask)) {
    throw std::runtime_error("Exception at AddressValue::GetNextHost , "
        "could not increment address due to reach to broadcast address");
  }
  return next;
}
AddressValue AddressValue::GetNextNetwork() const {
  //std::cout << "[DEBUG] AddressValue::GetNextNetwork, GetLocal=" << GetLocal() << std::endl;
  AddressValue next = *this;
  next.m_local += ~m_mask + 1;
  next.m_local &= next.m_mask;
  next.m_local += 1;
  // check reach to upper limit
  if (next.GetNetworkAddress() == "0.0.0.0") {
    throw std::runtime_error("Exception at AddressValue::GetNextNetwork , "
        "could not increment address due to reach to upper limit");
  }
  return next;
}
string AddressValue::GetLocal() const {
  return toStrAddr(m_local);
}
string AddressValue::GetNetworkAddress() const {
  return toStrAddr(m_local & m_mask);
}
string AddressValue::GetHost() const {
  return toStrAddr(m_local & ~m_mask);
}
string AddressValue::GetMask() const {
  return toStrAddr(m_mask);
}
bool AddressValue::operator==(const AddressValue& value) const {
  if (m_local == value.m_local && m_mask == value.m_mask) return true;
  return false;
};

//
//
//

//////////////////////////////////////////////////
/// AddressAllocator
std::list<AddrAllocCell> AddressAllocator::cell_list_;

//void AddressAllocator::SetDefault() {
//  SetBase(AddressValue("10.0.0.0/8"), AddressType::NetworkUnique);
//}
//void AddressAllocator::Init() {
//  address_net   = 0xC0A80000;
//  address_mask  = 0xFFFFFF00;
//  address_last  = address_net + ~address_mask + 1;
//}

// find cell that has same network-address(base-address)
optional<std::reference_wrapper<AddrAllocCell>>
AddressAllocator::FindCell(AddressValue base_addr) {
  for (auto&& i : cell_list_) {
    if (i.GetBase().GetNetworkAddress() == base_addr.GetNetworkAddress()) {
      return i;
    }
  }
  return {};
}

bool AddressAllocator::IsConsistent(AddrAllocCell cell) {
  AddressValue base = cell.GetBase();
  AddressType type = cell.GetType();
  if (const auto& result = FindCell(base)) {
    if (result.value().get().GetType() != type) return false;
  }
  return true;
}

AddrAllocCell
AddressAllocator::Alloc(size_t size, AddressType type, AddressValue base) {
  AddrAllocCell cell(0, size, type, base);

  // validation
  if (not IsConsistent(cell)) {
    throw std::runtime_error("Exception at AddressAllocator::Alloc, could not set base address.\n"
        "for same network address, must be specified different type");
  }

  // check cache
  if (auto result = FindCell(base)) {
    std::cout << "reallocate: " << base.GetNetworkAddress() << std::endl;
    auto&& ref_cell = result.value().get();
    auto ret = ref_cell;
    ref_cell = AddrAllocCell{ret.GetOffset()+size, size, type, base};
    return ret;
  } else {
    std::cout << "new allocate: " << base.GetNetworkAddress() << std::endl;
    cell_list_.push_back( AddrAllocCell{0, size, type, base} );
    return Alloc(size, type, base);
  }

}
AddrAllocCell
AddressAllocator::Alloc(size_t size, nlohmann::json config) {
  auto type = AddressType::NetworkUnique;
  optional<AddressValue> base;

  //std::cout << "[DEBUG] AddressAllocator::Alloc, config=" << config.dump() << std::endl;
  // set base-address if it find on config
  if (config["Address"].is_string())
  {
    type = AddressType::ChannelUnique;
    base = config["Address"].get<string>();
  }
  else if (config["Address"].is_object())
  {
    try {
      base = AddressValue{config["Address"]["Base"].get<string>()};
      //if (AddressValue{"10.0.0.1/8"} == base.value()) {
      //  throw std::runtime_error(
      //      "error: `config.Address.Base` setting, address \"10.0.0.1/8\" could be specified,"
      //      " because the generator uses it\n"
      //      "please change base address to other address");
      //}

      string str_type = config["Address"]["Type"].get<string>();
      if (str_type == "ChannelUnique") {
        type = AddressType::ChannelUnique;
      } else if (str_type == "NetworkUnique") {
        type = AddressType::NetworkUnique;
      } else {
        throw std::runtime_error("`config.Address.Type` is invalid");
      }

    } catch (const std::exception& e) {
      throw std::runtime_error(string{}+"`config.Address` is invalid object\n"+e.what());
    }

  }

  // auto config base-address(network address)
  if (not base) {
    //std::cout << "[DEBUG] AddressAllocator::Alloc, auto address" << std::endl;
    base = AddressValue{"10.0.0.1/8"}; // the address where search starts
    while (auto result = FindCell(base.value())) {
      try {
        base = base.value().GetNextNetwork();
      } catch (const std::exception &e) {
        std::cout << e.what() << std::endl;
        throw std::runtime_error("Error at AddressAllocator::Alloc, due to no rest address to allocate");
      }
    }
  }

  return Alloc(size, type, base.value());
}

//////////////////////////////////////////////////
/// AddrAllocCell
AddrAllocCell::AddrAllocCell(size_t offset, size_t size, AddressType type, AddressValue base)
: offset_(offset), size_(size), addr_type_(type), addr_base_(base)
{
  // initialize
}
size_t AddrAllocCell::GetOffset() const {
  return offset_;
}
size_t AddrAllocCell::GetSize() const {
  return size_;
}
AddressValue AddrAllocCell::GetBase() const {
  return addr_base_;
}
AddressType AddrAllocCell::GetType() const {
  return addr_type_;
}
AddressValue AddrAllocCell::At(size_t idx) const {
  AddressValue ret = addr_base_;
  for (size_t i = 0; i < (offset_+idx); ++i) {
    ret = ret.GetNextHost();
  }
  return ret;
}