<commit_before>#ifndef PROTOZERO_VARINT_HPP
#define PROTOZERO_VARINT_HPP

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

protozero - Minimalistic protocol buffer decoder and encoder in C++.

This file is from https://github.com/mapbox/protozero where you can find more
documentation.

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

/**
 * @file varint.hpp
 *
 * @brief Contains low-level varint and zigzag encoding and decoding functions.
 */

#include <cstdint>

#include <protozero/exception.hpp>

namespace protozero {

/**
 * The maximum length of a 64 bit varint.
 */
constexpr const int8_t max_varint_length = sizeof(uint64_t) * 8 / 7 + 1;

// from https://github.com/facebook/folly/blob/master/folly/Varint.h
inline uint64_t decode_varint_impl(const char** data, const char* end) {
    const int8_t* begin = reinterpret_cast<const int8_t*>(*data);
    const int8_t* iend = reinterpret_cast<const int8_t*>(end);
    const int8_t* p = begin;
    uint64_t val = 0;

    if (iend - begin >= max_varint_length) {  // fast path
        do {
            int64_t b;
            b = *p++; val  = uint64_t((b & 0x7f)      ); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) <<  7); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) << 14); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) << 21); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) << 28); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) << 35); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) << 42); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) << 49); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) << 56); if (b >= 0) break;
            b = *p++; val |= uint64_t((b & 0x7f) << 63); if (b >= 0) break;
            throw varint_too_long_exception();
        } while (false);
    } else {
        int shift = 0;
        while (p != iend && *p < 0) {
            val |= uint64_t(*p++ & 0x7f) << shift;
            shift += 7;
        }
        if (p == iend) {
            throw end_of_buffer_exception();
        }
        val |= uint64_t(*p++) << shift;
    }

    *data = reinterpret_cast<const char*>(p);
    return val;
}

/**
 * Decode a 64 bit varint.
 *
 * Strong exception guarantee: if there is an exception the data pointer will
 * not be changed.
 *
 * @param[in,out] data Pointer to pointer to the input data. After the function
 *        returns this will point to the next data to be read.
 * @param[in] end Pointer one past the end of the input data.
 * @returns The decoded integer
 * @throws varint_too_long_exception if the varint is longer then the maximum
 *         length that would fit in a 64 bit int. Usually this means your data
 *         is corrupted or you are trying to read something as a varint that
 *         isn't.
 * @throws end_of_buffer_exception if the *end* of the buffer was reached
 *         before the end of the varint.
 */
inline uint64_t decode_varint(const char** data, const char* end) {
    // If this is a one-byte varint, decode it here.
    if (end != *data && ((**data & 0x80) == 0)) {
        uint64_t val = uint64_t(**data);
        ++(*data);
        return val;
    }
    // If this varint is more than one byte, defer to complete implementation.
    return decode_varint_impl(data, end);
}

/**
 * Skip over a varint.
 *
 * Strong exception guarantee: if there is an exception the data pointer will
 * not be changed.
 *
 * @param[in,out] data Pointer to pointer to the input data. After the function
 *        returns this will point to the next data to be read.
 * @param[in] end Pointer one past the end of the input data.
 * @throws end_of_buffer_exception if the *end* of the buffer was reached
 *         before the end of the varint.
 */
inline void skip_varint(const char** data, const char* end) {
    const int8_t* p = reinterpret_cast<const int8_t*>(*data);
    const int8_t* iend = reinterpret_cast<const int8_t*>(end);

    while (p != iend && *p < 0) {
        ++p;
    }

    if (p == iend) {
        throw end_of_buffer_exception();
    }

    ++p;

    *data = reinterpret_cast<const char*>(p);
}

/**
 * Varint encode a 64 bit integer.
 *
 * @tparam T Output iterator the varint encoded value will be written to
 *           byte by byte.
 * @param value The integer that will be encoded.
 * @throws Any exception thrown by increment or dereference operator on data.
 */
template <typename T>
inline int write_varint(T data, uint64_t value) {
    int n=1;

    while (value >= 0x80) {
        *data++ = char((value & 0x7f) | 0x80);
        value >>= 7;
        ++n;
    }
    *data++ = char(value);

    return n;
}

/**
 * ZigZag encodes a 32 bit integer.
 */
inline uint32_t encode_zigzag32(int32_t value) noexcept {
    return (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
}

/**
 * ZigZag encodes a 64 bit integer.
 */
inline uint64_t encode_zigzag64(int64_t value) noexcept {
    return (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
}

/**
 * Decodes a 32 bit ZigZag-encoded integer.
 */
inline int32_t decode_zigzag32(uint32_t value) noexcept {
    return int32_t(value >> 1) ^ -int32_t(value & 1);
}

/**
 * Decodes a 64 bit ZigZag-encoded integer.
 */
inline int64_t decode_zigzag64(uint64_t value) noexcept {
    return int64_t(value >> 1) ^ -int64_t(value & 1);
}

} // end namespace protozero

#endif // PROTOZERO_VARINT_HPP
<commit_msg>Move decode_varint_impl() function into detail namespace.<commit_after>#ifndef PROTOZERO_VARINT_HPP
#define PROTOZERO_VARINT_HPP

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

protozero - Minimalistic protocol buffer decoder and encoder in C++.

This file is from https://github.com/mapbox/protozero where you can find more
documentation.

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

/**
 * @file varint.hpp
 *
 * @brief Contains low-level varint and zigzag encoding and decoding functions.
 */

#include <cstdint>

#include <protozero/exception.hpp>

namespace protozero {

/**
 * The maximum length of a 64 bit varint.
 */
constexpr const int8_t max_varint_length = sizeof(uint64_t) * 8 / 7 + 1;

namespace detail {

    // from https://github.com/facebook/folly/blob/master/folly/Varint.h
    inline uint64_t decode_varint_impl(const char** data, const char* end) {
        const int8_t* begin = reinterpret_cast<const int8_t*>(*data);
        const int8_t* iend = reinterpret_cast<const int8_t*>(end);
        const int8_t* p = begin;
        uint64_t val = 0;

        if (iend - begin >= max_varint_length) {  // fast path
            do {
                int64_t b;
                b = *p++; val  = uint64_t((b & 0x7f)      ); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) <<  7); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) << 14); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) << 21); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) << 28); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) << 35); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) << 42); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) << 49); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) << 56); if (b >= 0) break;
                b = *p++; val |= uint64_t((b & 0x7f) << 63); if (b >= 0) break;
                throw varint_too_long_exception();
            } while (false);
        } else {
            int shift = 0;
            while (p != iend && *p < 0) {
                val |= uint64_t(*p++ & 0x7f) << shift;
                shift += 7;
            }
            if (p == iend) {
                throw end_of_buffer_exception();
            }
            val |= uint64_t(*p++) << shift;
        }

        *data = reinterpret_cast<const char*>(p);
        return val;
    }

} // end namespace detail

/**
 * Decode a 64 bit varint.
 *
 * Strong exception guarantee: if there is an exception the data pointer will
 * not be changed.
 *
 * @param[in,out] data Pointer to pointer to the input data. After the function
 *        returns this will point to the next data to be read.
 * @param[in] end Pointer one past the end of the input data.
 * @returns The decoded integer
 * @throws varint_too_long_exception if the varint is longer then the maximum
 *         length that would fit in a 64 bit int. Usually this means your data
 *         is corrupted or you are trying to read something as a varint that
 *         isn't.
 * @throws end_of_buffer_exception if the *end* of the buffer was reached
 *         before the end of the varint.
 */
inline uint64_t decode_varint(const char** data, const char* end) {
    // If this is a one-byte varint, decode it here.
    if (end != *data && ((**data & 0x80) == 0)) {
        uint64_t val = uint64_t(**data);
        ++(*data);
        return val;
    }
    // If this varint is more than one byte, defer to complete implementation.
    return detail::decode_varint_impl(data, end);
}

/**
 * Skip over a varint.
 *
 * Strong exception guarantee: if there is an exception the data pointer will
 * not be changed.
 *
 * @param[in,out] data Pointer to pointer to the input data. After the function
 *        returns this will point to the next data to be read.
 * @param[in] end Pointer one past the end of the input data.
 * @throws end_of_buffer_exception if the *end* of the buffer was reached
 *         before the end of the varint.
 */
inline void skip_varint(const char** data, const char* end) {
    const int8_t* p = reinterpret_cast<const int8_t*>(*data);
    const int8_t* iend = reinterpret_cast<const int8_t*>(end);

    while (p != iend && *p < 0) {
        ++p;
    }

    if (p == iend) {
        throw end_of_buffer_exception();
    }

    ++p;

    *data = reinterpret_cast<const char*>(p);
}

/**
 * Varint encode a 64 bit integer.
 *
 * @tparam T Output iterator the varint encoded value will be written to
 *           byte by byte.
 * @param value The integer that will be encoded.
 * @throws Any exception thrown by increment or dereference operator on data.
 */
template <typename T>
inline int write_varint(T data, uint64_t value) {
    int n=1;

    while (value >= 0x80) {
        *data++ = char((value & 0x7f) | 0x80);
        value >>= 7;
        ++n;
    }
    *data++ = char(value);

    return n;
}

/**
 * ZigZag encodes a 32 bit integer.
 */
inline uint32_t encode_zigzag32(int32_t value) noexcept {
    return (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
}

/**
 * ZigZag encodes a 64 bit integer.
 */
inline uint64_t encode_zigzag64(int64_t value) noexcept {
    return (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
}

/**
 * Decodes a 32 bit ZigZag-encoded integer.
 */
inline int32_t decode_zigzag32(uint32_t value) noexcept {
    return int32_t(value >> 1) ^ -int32_t(value & 1);
}

/**
 * Decodes a 64 bit ZigZag-encoded integer.
 */
inline int64_t decode_zigzag64(uint64_t value) noexcept {
    return int64_t(value >> 1) ^ -int64_t(value & 1);
}

} // end namespace protozero

#endif // PROTOZERO_VARINT_HPP
<|endoftext|>


<commit_before>/*
 * MIT License
 *
 * Copyright (c) [2017] [Edvard S. Pettersen] <edvard.pettersen@gmail.com>
 *
 * 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.
 */

#pragma once

#include <memory>
#include <tuple>
#include <vector>

#include <proxc/config.hpp>

#include <proxc/channel/sync.hpp>
#include <proxc/channel/tx.hpp>
#include <proxc/channel/rx.hpp>

PROXC_NAMESPACE_BEGIN
namespace channel {

template<typename T>
using TxVec = std::vector< Tx< T > >;
template<typename T>
using RxVec = std::vector< Rx< T > >;

template<typename T>
Tx< T > get_tx( std::tuple< Tx< T >, Rx< T > > & tpl )
{
    return std::move( std::get< 0 >( tpl ) );
}

template<typename T>
TxVec< T > get_tx( std::tuple< TxVec< T >, RxVec< T > > & tpl )
{
    return std::move( std::get< 0 >( tpl ) );
}

template<typename T>
Tx< T > get_tx_ind( TxVec< T > & tx_vec, std::size_t ind )
{
    return std::move( tx_vec[ ind ] );
}

template<typename T>
Tx< T > get_tx_ind( std::tuple< TxVec< T >, RxVec< T > > & tpl, std::size_t ind )
{
    return std::move( std::get< 0 >( tpl )[ ind ] );
}

template<typename T>
Rx< T > get_rx( std::tuple< Tx< T >, Rx< T > > & tpl )
{
    return std::move( std::get< 1 >( tpl ) );
}

template<typename T>
RxVec< T > get_rx( std::tuple< TxVec< T >, RxVec< T > > & tpl )
{
    return std::move( std::get< 1 >( tpl ) );
}

template<typename T>
Rx< T > get_rx_ind( RxVec< T > & rx_vec, std::size_t ind )
{
    return std::move( rx_vec[ ind ] );
}

template<typename T>
Rx< T > get_rx_ind( std::tuple< TxVec< T >, RxVec< T > > & tpl, std::size_t ind )
{
    return std::move( std::get< 1 >( tpl )[ ind ] );
}

template<typename T>
std::tuple< Tx< T >, Rx< T > > create() noexcept
{
    auto channel = std::make_shared< detail::ChannelImpl< T > >();
    return std::make_tuple( Tx< T >{ channel }, Rx< T >{ channel } );
}

template<typename T>
std::tuple< TxVec< T >, RxVec< T > >
create_n( const std::size_t n ) noexcept
{
    std::vector< Tx< T > > txs;
    std::vector< Rx< T > > rxs;
    txs.reserve( n );
    rxs.reserve( n );
    Tx< T > tx;
    Rx< T > rx;
    for( std::size_t i = 0; i < n; ++i ) {
        std::tie( tx, rx ) = create< T >();
        txs.push_back( std::move( tx ) );
        rxs.push_back( std::move( rx ) );
    }
    return std::make_tuple( std::move( txs ), std::move( rxs ) );
}

} // namespace channel
PROXC_NAMESPACE_END

<commit_msg>Created much more ergonomic types of channels and arrays of channels.<commit_after>/*
 * MIT License
 *
 * Copyright (c) [2017] [Edvard S. Pettersen] <edvard.pettersen@gmail.com>
 *
 * 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.
 */

#pragma once

#include <array>
#include <memory>
#include <tuple>
#include <vector>

#include <proxc/config.hpp>

#include <proxc/channel/sync.hpp>
#include <proxc/channel/tx.hpp>
#include <proxc/channel/rx.hpp>

PROXC_NAMESPACE_BEGIN
namespace channel {

template<typename T>
using TxVec = std::vector< Tx< T > >;
template<typename T>
using RxVec = std::vector< Rx< T > >;

template<typename T>
Tx< T > get_tx( std::tuple< Tx< T >, Rx< T > > & tpl )
{
    return std::move( std::get< 0 >( tpl ) );
}

template<typename T>
TxVec< T > get_tx( std::tuple< TxVec< T >, RxVec< T > > & tpl )
{
    return std::move( std::get< 0 >( tpl ) );
}

template<typename T>
Tx< T > get_tx_ind( TxVec< T > & tx_vec, std::size_t ind )
{
    return std::move( tx_vec[ ind ] );
}

template<typename T>
Tx< T > get_tx_ind( std::tuple< TxVec< T >, RxVec< T > > & tpl, std::size_t ind )
{
    return std::move( std::get< 0 >( tpl )[ ind ] );
}

template<typename T>
Rx< T > get_rx( std::tuple< Tx< T >, Rx< T > > & tpl )
{
    return std::move( std::get< 1 >( tpl ) );
}

template<typename T>
RxVec< T > get_rx( std::tuple< TxVec< T >, RxVec< T > > & tpl )
{
    return std::move( std::get< 1 >( tpl ) );
}

template<typename T>
Rx< T > get_rx_ind( RxVec< T > & rx_vec, std::size_t ind )
{
    return std::move( rx_vec[ ind ] );
}

template<typename T>
Rx< T > get_rx_ind( std::tuple< TxVec< T >, RxVec< T > > & tpl, std::size_t ind )
{
    return std::move( std::get< 1 >( tpl )[ ind ] );
}

template<typename T>
std::tuple< Tx< T >, Rx< T > > create() noexcept
{
    auto channel = std::make_shared< detail::ChannelImpl< T > >();
    return std::make_tuple( Tx< T >{ channel }, Rx< T >{ channel } );
}

template<typename T>
std::tuple< TxVec< T >, RxVec< T > >
create_n( const std::size_t n ) noexcept
{
    std::vector< Tx< T > > txs;
    std::vector< Rx< T > > rxs;
    txs.reserve( n );
    rxs.reserve( n );
    Tx< T > tx;
    Rx< T > rx;
    for( std::size_t i = 0; i < n; ++i ) {
        std::tie( tx, rx ) = create< T >();
        txs.push_back( std::move( tx ) );
        rxs.push_back( std::move( rx ) );
    }
    return std::make_tuple( std::move( txs ), std::move( rxs ) );
}

} // namespace channel

template<typename T>
struct Chan : public std::tuple< channel::Tx< T >, channel::Rx< T > >
{
    using Tx = channel::Tx< T >;
    using Rx = channel::Rx< T >;

    using TplT = std::tuple< Tx, Rx >;
    using TplT::TplT;

    Chan() : TplT{ channel::create< T >() }
    {}

    Tx & ref_tx() noexcept
    {
        return std::get< 0 >( *this );
    }

    Rx & ref_rx() noexcept
    {
        return std::get< 1 >( *this );
    }

    Tx move_tx() noexcept
    {
        return std::move( std::get< 0 >( *this ) );
    }

    Rx move_rx() noexcept
    {
        return std::move( std::get< 1 >( *this ) );
    }
};

template<typename T, std::size_t N>
struct ChanArr : public std::array< Chan< T >, N >
{
    using Tx = typename Chan< T >::Tx;
    using Rx = typename Chan< T >::Rx;

    using ArrT = std::array< Chan< T >, N >;
    using ArrT::ArrT;

    using ArrTxT = std::array< Tx, N >;
    using ArrRxT = std::array< Rx, N >;

    ChanArr() : ArrT()
    {}

    ArrTxT collect_tx() noexcept
    {
        ArrTxT txs;
        auto ch_it = this->begin();
        std::generate( txs.begin(), txs.end(),
            [&ch_it]{ return (ch_it++)->move_tx(); } );
        return std::move( txs );
    }

    ArrRxT collect_rx() noexcept
    {
        ArrRxT rxs;
        auto ch_it = this->begin();
        std::generate( rxs.begin(), rxs.end(),
            [&ch_it]{ return (ch_it++)->move_rx(); } );
        return std::move( rxs );
    }
};

template<typename T>
struct ChanVec : public std::vector< Chan< T > >
{
    using Tx = typename Chan< T >::Tx;
    using Rx = typename Chan< T >::Rx;

    using VecT = std::vector< Chan< T > >;
    using VecT::VecT;

    using VecTxT = std::vector< Tx >;
    using VecRxT = std::vector< Rx >;

    ChanVec() = delete;
    ChanVec( std::size_t n ) : VecT( n )
    {}

    VecTxT collect_tx() noexcept
    {
        VecTxT txs;
        txs.reserve( this->size() );
        std::for_each( this->begin(), this->end(),
            [&txs]( auto& ch ){ txs.push_back( std::move( ch.move_tx() ) ); } );
        return std::move( txs );
    }

    VecRxT collect_rx() noexcept
    {
        VecRxT rxs;
        rxs.reserve( this->size() );
        std::for_each( this->begin(), this->end(),
            [&rxs]( auto& ch ){ rxs.push_back( std::move( ch.move_rx() ) ); } );
        return std::move( rxs );
    }
};

PROXC_NAMESPACE_END

<|endoftext|>


<commit_before>//
// Copyright (c) 2014 Christoph Malek
// See LICENSE for more information.
//

#ifndef TWEC_DATA_PARSER_HPP
#define TWEC_DATA_PARSER_HPP

#include "player_info.hpp"

#include <mlk/tools/stl_string_utl.h>

#include <string>

namespace twec
{
	class data_parser
	{
		const std::string& m_inputstr;

	public:
		data_parser(const std::string& inputstr) :
			m_inputstr{inputstr}
		{ }

		bool is_login_reply() const
		{return mlk::stl_string::contains("Authentication successful. External console access granted.", m_inputstr);}

		// TODO: use std::regex when its impled right
		bool is_player_reply() const
		{
			return mlk::stl_string::contains("id=", m_inputstr) && mlk::stl_string::contains("addr=", m_inputstr) &&
				   mlk::stl_string::contains("name=", m_inputstr) && mlk::stl_string::contains("id=", m_inputstr) && !mlk::stl_string::contains("cid", m_inputstr);
		}

		// hackish parser
		player_infos get_player_info() const
		{
			auto cpy(m_inputstr);
			auto num_players(mlk::stl_string::count_of('\n', cpy));
			player_infos result;

			for(std::size_t i{0}; i < num_players; ++i)
			{
				auto id_pos(cpy.find("id="));
				auto addr_pos(cpy.find("addr="));
				auto name_pos(cpy.find("name="));
				auto score_pos(cpy.find("score="));
				auto linebreak(cpy.find('\n'));

				result.emplace_back(
				player_info
				{
					cpy.substr(id_pos + 3, addr_pos - id_pos - 4),
					cpy.substr(addr_pos + 5, name_pos - addr_pos - 6),
					cpy.substr(name_pos + 6, score_pos - name_pos - 8),
					cpy.substr(score_pos + 6, linebreak - score_pos - 8)
				});

				cpy.erase(0, linebreak + 1);
			}
			return result;
		}
	};
}

#endif // TWEC_DATA_PARSER_HPP
<commit_msg>data_parser: mingw/gcc dont gets that const ref<commit_after>//
// Copyright (c) 2014 Christoph Malek
// See LICENSE for more information.
//

#ifndef TWEC_DATA_PARSER_HPP
#define TWEC_DATA_PARSER_HPP

#include "player_info.hpp"

#include <mlk/tools/stl_string_utl.h>

#include <string>

namespace twec
{
	class data_parser
	{
		//const std::string& m_inputstr; mingw dont likes that const ref...
		std::string m_inputstr;

	public:
		data_parser(const std::string& inputstr) :
			m_inputstr{inputstr}
		{ }

		bool is_login_reply() const
		{return mlk::stl_string::contains("Authentication successful. External console access granted.", m_inputstr);}

		// TODO: use std::regex when its impled right
		bool is_player_reply() const
		{
			return mlk::stl_string::contains("id=", m_inputstr) && mlk::stl_string::contains("addr=", m_inputstr) &&
				   mlk::stl_string::contains("name=", m_inputstr) && mlk::stl_string::contains("id=", m_inputstr) && !mlk::stl_string::contains("cid", m_inputstr);
		}

		// hackish parser
		player_infos get_player_info() const
		{
			auto cpy(m_inputstr);
			auto num_players(mlk::stl_string::count_of('\n', cpy));
			player_infos result;

			for(std::size_t i{0}; i < num_players; ++i)
			{
				auto id_pos(cpy.find("id="));
				auto addr_pos(cpy.find("addr="));
				auto name_pos(cpy.find("name="));
				auto score_pos(cpy.find("score="));
				auto linebreak(cpy.find('\n'));

				result.emplace_back(
				player_info
				{
					cpy.substr(id_pos + 3, addr_pos - id_pos - 4),
					cpy.substr(addr_pos + 5, name_pos - addr_pos - 6),
					cpy.substr(name_pos + 6, score_pos - name_pos - 8),
					cpy.substr(score_pos + 6, linebreak - score_pos - 8)
				});

				cpy.erase(0, linebreak + 1);
			}
			return result;
		}
	};
}

#endif // TWEC_DATA_PARSER_HPP
<|endoftext|>


<commit_before>// Copyright 2012-2013 Luis Pedro Coelho <luis@luispedro.org>
// License: MIT (see COPYING.MIT file)

#include "base.h"
#include "_tiff.h"
#include "tools.h"

#include <sstream>
#include <iostream>

extern "C" {
   #include <tiffio.h>
}

namespace {
tsize_t tiff_read(thandle_t handle, void* data, tsize_t n) {
    byte_source* s = static_cast<byte_source*>(handle);
    return s->read(static_cast<byte*>(data), n);
}
tsize_t tiff_write(thandle_t handle, void* data, tsize_t n) {
    byte_sink* s = static_cast<byte_sink*>(handle);
    return s->write(static_cast<byte*>(data), n);
}

tsize_t tiff_no_read(thandle_t, void*, tsize_t) {
    throw ProgrammingError("imread._tiff: tiff_read called when saving");
}

tsize_t tiff_no_write(thandle_t, void*, tsize_t) {
    throw ProgrammingError("imread._tiff: tiff_write called when reading");
}

template<typename T>
toff_t tiff_seek(thandle_t handle, toff_t off, int whence) {
    T* s = static_cast<T*>(handle);
    switch (whence) {
        case SEEK_SET: return s->seek_absolute(off);
        case SEEK_CUR: return s->seek_relative(off);
        case SEEK_END: return s->seek_end(off);
    }
    return -1;
}
int tiff_close(thandle_t handle) { return 0; }
template<typename T>
toff_t tiff_size(thandle_t handle) {
    T* s = static_cast<T*>(handle);
    const size_t curpos = s->seek_relative(0);
    const size_t size = s->seek_end(0);
    s->seek_absolute(curpos);
    return size;
}

void tiff_error(const char* module, const char* fmt, va_list ap) {
    char buffer[4096];
    vsnprintf(buffer, sizeof(buffer), fmt, ap);
    std::string error_message(buffer);
    throw CannotReadError(std::string("imread._tiff: libtiff error: `") + buffer + std::string("`"));
}

struct tif_holder {
    tif_holder(TIFF* tif)
        :tif(tif)
        { }
    ~tif_holder() { TIFFClose(tif); }
    TIFF* tif;
};

template <typename T>
inline
T tiff_get(const tif_holder& t, const int tag) {
    T val;
    if (!TIFFGetField(t.tif, tag, &val)) {
        std::stringstream out;
        out << "imread.imread._tiff: Cannot find necessary tag (" << tag << ")";
        throw CannotReadError(out.str());
    }
    return val;
}

template <>
inline
std::string tiff_get<std::string>(const tif_holder& t, const int tag) {
    char* val;
    if (!TIFFGetField(t.tif, tag, &val)) {
        std::stringstream out;
        out << "imread.imread._tiff: Cannot find necessary tag (" << tag << ")";
        throw CannotReadError(out.str());
    }
    return val;
}

template <typename T>
inline
T tiff_get(const tif_holder& t, const int tag, const T def) {
    T val;
    if (!TIFFGetField(t.tif, tag, &val)) return def;
    return val;
}

template <>
inline
std::string tiff_get<std::string>(const tif_holder& t, const int tag, const std::string def) {
    char* val;
    if (!TIFFGetField(t.tif, tag, &val)) return def;
    return val;
}

TIFF* read_client(byte_source* src) {
    TIFFSetErrorHandler(tiff_error);
    return TIFFClientOpen(
                    "internal",
                    "r",
                    src,
                    tiff_read,
                    tiff_no_write,
                    tiff_seek<byte_source>,
                    tiff_close,
                    tiff_size<byte_source>,
                    NULL,
                    NULL);
}

const int UIC1Tag = 33628;
const int UIC2Tag = 33629;
const int UIC3Tag = 33630;
const int UIC4Tag = 33631;

const TIFFFieldInfo stkTags[] = {
    { UIC1Tag, -1,-1, TIFF_LONG, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC1Tag") },
    { UIC1Tag, -1,-1, TIFF_RATIONAL, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC1Tag") },
    //{ UIC2Tag, -1, -1, TIFF_RATIONAL, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC2Tag") },
    { UIC2Tag, -1, -1, TIFF_LONG, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC2Tag") },
    { UIC3Tag, -1,-1, TIFF_RATIONAL, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC3Tag") },
    { UIC4Tag, -1,-1, TIFF_LONG, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC4Tag") },
};

void set_stk_tags(TIFF* tif) {
    TIFFMergeFieldInfo(tif, stkTags, sizeof(stkTags)/sizeof(stkTags[0]));
}

class shift_source : public byte_source {
    public:
        explicit shift_source(byte_source* s)
            :s(s)
            ,shift_(0)
            { }

        virtual size_t read(byte* buf, size_t n) { return s->read(buf, n); }

        virtual size_t seek_absolute(size_t pos) { return s->seek_absolute(pos + shift_)-shift_; }
        virtual size_t seek_relative(int n) { return s->seek_relative(n)-shift_; }
        virtual size_t seek_end(int n) { return s->seek_end(n+shift_)-shift_; }

        void shift(int nshift) {
            s->seek_relative(nshift - shift_);
            shift_ = nshift;
        }

        byte_source* s;
        int shift_;
};

struct stk_extend {
    stk_extend()
        :proc(TIFFSetTagExtender(set_stk_tags)) { }
    ~stk_extend() {
        TIFFSetTagExtender(proc);
    }
    TIFFExtendProc proc;
};

} // namespace

std::auto_ptr<image_list> STKFormat::read_multi(byte_source* src, ImageFactory* factory) {
    shift_source moved(src);
    stk_extend ext;
    tif_holder t = read_client(&moved);
    std::auto_ptr<image_list> images(new image_list);
    const uint32 h = tiff_get<uint32>(t, TIFFTAG_IMAGELENGTH);
    const uint32 w = tiff_get<uint32>(t, TIFFTAG_IMAGEWIDTH);

    const uint16 nr_samples = tiff_get<uint16>(t, TIFFTAG_SAMPLESPERPIXEL, 1);
    const uint16 bits_per_sample = tiff_get<uint16>(t, TIFFTAG_BITSPERSAMPLE, 8);
    const int depth = nr_samples > 1 ? nr_samples : -1;

    const int strip_size = TIFFStripSize(t.tif);
    const int n_strips = TIFFNumberOfStrips(t.tif);
    int32_t n_planes;
    void* data;
    TIFFGetField(t.tif, UIC3Tag, &n_planes, &data);
    int raw_strip_size = 0;
    for (int st = 0; st != n_strips; ++st) {
        raw_strip_size += TIFFRawStripSize(t.tif, st);
    }
    for (int z = 0; z < n_planes; ++z) {
        // Monkey patch strip offsets. This is very hacky, but it seems to work!
        moved.shift(z * raw_strip_size);

        std::auto_ptr<Image> output(factory->create(bits_per_sample, h, w, depth));
        uint8_t* start = output->rowp_as<uint8_t>(0);
        for (int st = 0; st != n_strips; ++st) {
            const int offset = TIFFReadEncodedStrip(t.tif, st, start, strip_size);
            if (offset == -1) {
                throw CannotReadError("imread.imread._tiff.stk: Error reading strip");
            }
            start += offset;
        }
        images->push_back(output);
    }
    return images;
}

std::auto_ptr<image_list> TIFFFormat::do_read(byte_source* src, ImageFactory* factory, bool is_multi) {
    tif_holder t = read_client(src);
    std::auto_ptr<image_list> images(new image_list);
    do {
        const uint32 h = tiff_get<uint32>(t, TIFFTAG_IMAGELENGTH);
        const uint32 w = tiff_get<uint32>(t, TIFFTAG_IMAGEWIDTH);
        const uint16 nr_samples = tiff_get<uint16>(t, TIFFTAG_SAMPLESPERPIXEL);
        const uint16 bits_per_sample = tiff_get<uint16>(t, TIFFTAG_BITSPERSAMPLE);
        const int depth = nr_samples > 1 ? nr_samples : -1;

        std::auto_ptr<Image> output = factory->create(bits_per_sample, h, w, depth);
        if (ImageWithMetadata* metaout = dynamic_cast<ImageWithMetadata*>(output.get())) {
            std::string description = tiff_get<std::string>(t, TIFFTAG_IMAGEDESCRIPTION, "");
            metaout->set_meta(description);
        }
        for (uint32 r = 0; r != h; ++r) {
            if(TIFFReadScanline(t.tif, output->rowp_as<byte>(r), r) == -1) {
                throw CannotReadError("imread.imread._tiff: Error reading scanline");
            }
        }
        images->push_back(output);
    } while (is_multi && TIFFReadDirectory(t.tif));
    return images;
}

void TIFFFormat::write_with_metadata(Image* input, byte_sink* output, const char* meta) {
    TIFFSetErrorHandler(tiff_error);
    tif_holder t = TIFFClientOpen(
                    "internal",
                    "w",
                    output,
                    tiff_no_read,
                    tiff_write,
                    tiff_seek<byte_sink>,
                    tiff_close,
                    tiff_size<byte_sink>,
                    NULL,
                    NULL);

    const uint32 h = input->dim(0);
    const uint16 photometric = ((input->ndims() == 3 && input->dim(2)) ?
                                                    PHOTOMETRIC_RGB :
                                                    PHOTOMETRIC_MINISBLACK);

    TIFFSetField(t.tif, TIFFTAG_IMAGELENGTH, uint32(h));
    TIFFSetField(t.tif, TIFFTAG_IMAGEWIDTH, uint32(input->dim(1)));

    TIFFSetField(t.tif, TIFFTAG_BITSPERSAMPLE, uint16(input->nbits()));
    TIFFSetField(t.tif, TIFFTAG_SAMPLESPERPIXEL, uint16(input->dim_or(2, 1)));

    TIFFSetField(t.tif, TIFFTAG_PHOTOMETRIC, uint16(photometric));
    TIFFSetField(t.tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

    TIFFSetField(t.tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
    TIFFSetField(t.tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
    if (meta) {
        TIFFSetField(t.tif, TIFFTAG_IMAGEDESCRIPTION, meta);
    }

    for (uint32 r = 0; r != h; ++r) {
        if (TIFFWriteScanline(t.tif, input->rowp(r), r) == -1) {
            throw CannotWriteError("imread.imsave._tiff: Error writing TIFF file");
        }
    }
    TIFFFlush(t.tif);
}
<commit_msg>ENH Work around old libTIFF bug<commit_after>// Copyright 2012-2013 Luis Pedro Coelho <luis@luispedro.org>
// License: MIT (see COPYING.MIT file)

#include "base.h"
#include "_tiff.h"
#include "tools.h"

#include <sstream>
#include <iostream>

extern "C" {
   #include <tiffio.h>
}

namespace {
tsize_t tiff_read(thandle_t handle, void* data, tsize_t n) {
    byte_source* s = static_cast<byte_source*>(handle);
    return s->read(static_cast<byte*>(data), n);
}
tsize_t tiff_write(thandle_t handle, void* data, tsize_t n) {
    byte_sink* s = static_cast<byte_sink*>(handle);
    return s->write(static_cast<byte*>(data), n);
}

tsize_t tiff_no_read(thandle_t, void*, tsize_t) {
    return 0;
}

tsize_t tiff_no_write(thandle_t, void*, tsize_t) {
    throw ProgrammingError("imread._tiff: tiff_write called when reading");
}

template<typename T>
toff_t tiff_seek(thandle_t handle, toff_t off, int whence) {
    T* s = static_cast<T*>(handle);
    switch (whence) {
        case SEEK_SET: return s->seek_absolute(off);
        case SEEK_CUR: return s->seek_relative(off);
        case SEEK_END: return s->seek_end(off);
    }
    return -1;
}
int tiff_close(thandle_t handle) { return 0; }
template<typename T>
toff_t tiff_size(thandle_t handle) {
    T* s = static_cast<T*>(handle);
    const size_t curpos = s->seek_relative(0);
    const size_t size = s->seek_end(0);
    s->seek_absolute(curpos);
    return size;
}

void tiff_error(const char* module, const char* fmt, va_list ap) {
    char buffer[4096];
    vsnprintf(buffer, sizeof(buffer), fmt, ap);
    std::string error_message(buffer);
    throw CannotReadError(std::string("imread._tiff: libtiff error: `") + buffer + std::string("`"));
}

struct tif_holder {
    tif_holder(TIFF* tif)
        :tif(tif)
        { }
    ~tif_holder() { TIFFClose(tif); }
    TIFF* tif;
};

template <typename T>
inline
T tiff_get(const tif_holder& t, const int tag) {
    T val;
    if (!TIFFGetField(t.tif, tag, &val)) {
        std::stringstream out;
        out << "imread.imread._tiff: Cannot find necessary tag (" << tag << ")";
        throw CannotReadError(out.str());
    }
    return val;
}

template <>
inline
std::string tiff_get<std::string>(const tif_holder& t, const int tag) {
    char* val;
    if (!TIFFGetField(t.tif, tag, &val)) {
        std::stringstream out;
        out << "imread.imread._tiff: Cannot find necessary tag (" << tag << ")";
        throw CannotReadError(out.str());
    }
    return val;
}

template <typename T>
inline
T tiff_get(const tif_holder& t, const int tag, const T def) {
    T val;
    if (!TIFFGetField(t.tif, tag, &val)) return def;
    return val;
}

template <>
inline
std::string tiff_get<std::string>(const tif_holder& t, const int tag, const std::string def) {
    char* val;
    if (!TIFFGetField(t.tif, tag, &val)) return def;
    return val;
}

TIFF* read_client(byte_source* src) {
    TIFFSetErrorHandler(tiff_error);
    return TIFFClientOpen(
                    "internal",
                    "r",
                    src,
                    tiff_read,
                    tiff_no_write,
                    tiff_seek<byte_source>,
                    tiff_close,
                    tiff_size<byte_source>,
                    NULL,
                    NULL);
}

const int UIC1Tag = 33628;
const int UIC2Tag = 33629;
const int UIC3Tag = 33630;
const int UIC4Tag = 33631;

const TIFFFieldInfo stkTags[] = {
    { UIC1Tag, -1,-1, TIFF_LONG, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC1Tag") },
    { UIC1Tag, -1,-1, TIFF_RATIONAL, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC1Tag") },
    //{ UIC2Tag, -1, -1, TIFF_RATIONAL, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC2Tag") },
    { UIC2Tag, -1, -1, TIFF_LONG, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC2Tag") },
    { UIC3Tag, -1,-1, TIFF_RATIONAL, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC3Tag") },
    { UIC4Tag, -1,-1, TIFF_LONG, FIELD_CUSTOM, true, true,   const_cast<char*>("UIC4Tag") },
};

void set_stk_tags(TIFF* tif) {
    TIFFMergeFieldInfo(tif, stkTags, sizeof(stkTags)/sizeof(stkTags[0]));
}

class shift_source : public byte_source {
    public:
        explicit shift_source(byte_source* s)
            :s(s)
            ,shift_(0)
            { }

        virtual size_t read(byte* buf, size_t n) { return s->read(buf, n); }

        virtual size_t seek_absolute(size_t pos) { return s->seek_absolute(pos + shift_)-shift_; }
        virtual size_t seek_relative(int n) { return s->seek_relative(n)-shift_; }
        virtual size_t seek_end(int n) { return s->seek_end(n+shift_)-shift_; }

        void shift(int nshift) {
            s->seek_relative(nshift - shift_);
            shift_ = nshift;
        }

        byte_source* s;
        int shift_;
};

struct stk_extend {
    stk_extend()
        :proc(TIFFSetTagExtender(set_stk_tags)) { }
    ~stk_extend() {
        TIFFSetTagExtender(proc);
    }
    TIFFExtendProc proc;
};

} // namespace

std::auto_ptr<image_list> STKFormat::read_multi(byte_source* src, ImageFactory* factory) {
    shift_source moved(src);
    stk_extend ext;
    tif_holder t = read_client(&moved);
    std::auto_ptr<image_list> images(new image_list);
    const uint32 h = tiff_get<uint32>(t, TIFFTAG_IMAGELENGTH);
    const uint32 w = tiff_get<uint32>(t, TIFFTAG_IMAGEWIDTH);

    const uint16 nr_samples = tiff_get<uint16>(t, TIFFTAG_SAMPLESPERPIXEL, 1);
    const uint16 bits_per_sample = tiff_get<uint16>(t, TIFFTAG_BITSPERSAMPLE, 8);
    const int depth = nr_samples > 1 ? nr_samples : -1;

    const int strip_size = TIFFStripSize(t.tif);
    const int n_strips = TIFFNumberOfStrips(t.tif);
    int32_t n_planes;
    void* data;
    TIFFGetField(t.tif, UIC3Tag, &n_planes, &data);
    int raw_strip_size = 0;
    for (int st = 0; st != n_strips; ++st) {
        raw_strip_size += TIFFRawStripSize(t.tif, st);
    }
    for (int z = 0; z < n_planes; ++z) {
        // Monkey patch strip offsets. This is very hacky, but it seems to work!
        moved.shift(z * raw_strip_size);

        std::auto_ptr<Image> output(factory->create(bits_per_sample, h, w, depth));
        uint8_t* start = output->rowp_as<uint8_t>(0);
        for (int st = 0; st != n_strips; ++st) {
            const int offset = TIFFReadEncodedStrip(t.tif, st, start, strip_size);
            if (offset == -1) {
                throw CannotReadError("imread.imread._tiff.stk: Error reading strip");
            }
            start += offset;
        }
        images->push_back(output);
    }
    return images;
}

std::auto_ptr<image_list> TIFFFormat::do_read(byte_source* src, ImageFactory* factory, bool is_multi) {
    tif_holder t = read_client(src);
    std::auto_ptr<image_list> images(new image_list);
    do {
        const uint32 h = tiff_get<uint32>(t, TIFFTAG_IMAGELENGTH);
        const uint32 w = tiff_get<uint32>(t, TIFFTAG_IMAGEWIDTH);
        const uint16 nr_samples = tiff_get<uint16>(t, TIFFTAG_SAMPLESPERPIXEL);
        const uint16 bits_per_sample = tiff_get<uint16>(t, TIFFTAG_BITSPERSAMPLE);
        const int depth = nr_samples > 1 ? nr_samples : -1;

        std::auto_ptr<Image> output = factory->create(bits_per_sample, h, w, depth);
        if (ImageWithMetadata* metaout = dynamic_cast<ImageWithMetadata*>(output.get())) {
            std::string description = tiff_get<std::string>(t, TIFFTAG_IMAGEDESCRIPTION, "");
            metaout->set_meta(description);
        }
        for (uint32 r = 0; r != h; ++r) {
            if(TIFFReadScanline(t.tif, output->rowp_as<byte>(r), r) == -1) {
                throw CannotReadError("imread.imread._tiff: Error reading scanline");
            }
        }
        images->push_back(output);
    } while (is_multi && TIFFReadDirectory(t.tif));
    return images;
}

void TIFFFormat::write_with_metadata(Image* input, byte_sink* output, const char* meta) {
    TIFFSetErrorHandler(tiff_error);
    tif_holder t = TIFFClientOpen(
                    "internal",
                    "w",
                    output,
                    tiff_no_read,
                    tiff_write,
                    tiff_seek<byte_sink>,
                    tiff_close,
                    tiff_size<byte_sink>,
                    NULL,
                    NULL);

    const uint32 h = input->dim(0);
    const uint16 photometric = ((input->ndims() == 3 && input->dim(2)) ?
                                                    PHOTOMETRIC_RGB :
                                                    PHOTOMETRIC_MINISBLACK);

    TIFFSetField(t.tif, TIFFTAG_IMAGELENGTH, uint32(h));
    TIFFSetField(t.tif, TIFFTAG_IMAGEWIDTH, uint32(input->dim(1)));

    TIFFSetField(t.tif, TIFFTAG_BITSPERSAMPLE, uint16(input->nbits()));
    TIFFSetField(t.tif, TIFFTAG_SAMPLESPERPIXEL, uint16(input->dim_or(2, 1)));

    TIFFSetField(t.tif, TIFFTAG_PHOTOMETRIC, uint16(photometric));
    TIFFSetField(t.tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

    TIFFSetField(t.tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
    TIFFSetField(t.tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
    if (meta) {
        TIFFSetField(t.tif, TIFFTAG_IMAGEDESCRIPTION, meta);
    }

    for (uint32 r = 0; r != h; ++r) {
        if (TIFFWriteScanline(t.tif, input->rowp(r), r) == -1) {
            throw CannotWriteError("imread.imsave._tiff: Error writing TIFF file");
        }
    }
    TIFFFlush(t.tif);
}
<|endoftext|>


<commit_before>/*!
 *
 * \author Zonciu
 * Contact: zonciu@zonciu.com
 *
 * \brief
 * Random
 * \note
*/
#ifndef ZONCIU_SINGKETON_HPP
#define ZONCIU_SINGKETON_HPP
#include <atomic>
namespace zonciu
{
namespace singleton
{
template<class T>
class Singleton
{
private:
    struct Creator
    {
        template<class...Args>
        Creator(Args&&...args) { init(std::forward<Args>(args)...); }
    };
    struct GC
    {
        ~GC() { Singleton<T>::destroy(); }
    };
    struct Instance
    {
        T* instance{ nullptr };
        std::atomic_flag flag{ ATOMIC_FLAG_INIT };
    };
public:
    template<class...Args>
    static T& init(Args&&...args)
    {
        static GC _gc;
        if (!_get().flag.test_and_set())
            _get().instance = new T(std::forward<Args>(args)...);
        return *_get().instance;
    }
    static T& get()
    {
        while (!_get().instance) {}
        assert(_get().instance != nullptr);
        return *_get().instance;
    }
    static void destroy()
    {
        delete _get().instance;
        _get().instance = nullptr;
        _get().flag.clear();
    }
private:
    static Instance& _get()
    {
        static Instance ins_;
        return ins_;
    }
    Singleton();
    ~Singleton();
    Singleton(const Singleton&) = delete;
    const Singleton& operator=(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    static Creator creator_;
};
// SINGLETON_INIT_BEFORE_MAIN(class,param_1,param_2,...);
#define SINGLETON_INIT_BEFORE_MAIN(type,...) \
template<> typename zonciu::singleton::Singleton<type>::Creator zonciu::singleton::Singleton<type>::creator_ = {__VA_ARGS__}
} // namespace singleton
} // namespace zonciu
#endif
<commit_msg>Remove namespace singleton.<commit_after>/*!
 *
 * \author Zonciu
 * Contact: zonciu@zonciu.com
 *
 * \brief
 * Random
 * \note
*/
#ifndef ZONCIU_SINGKETON_HPP
#define ZONCIU_SINGKETON_HPP
#include <atomic>
namespace zonciu
{
template<class T>
class Singleton
{
private:
    struct Creator
    {
        template<class...Args>
        Creator(Args&&...args) { init(std::forward<Args>(args)...); }
    };
    struct GC
    {
        ~GC() { Singleton<T>::destroy(); }
    };
    struct Instance
    {
        T* instance{ nullptr };
        std::atomic_flag flag{ ATOMIC_FLAG_INIT };
    };
public:
    template<class...Args>
    static T& init(Args&&...args)
    {
        static GC _gc;
        if (!_get().flag.test_and_set())
            _get().instance = new T(std::forward<Args>(args)...);
        return *_get().instance;
    }
    static T& get()
    {
        while (!_get().instance) {}
        assert(_get().instance != nullptr);
        return *_get().instance;
    }
    static void destroy()
    {
        delete _get().instance;
        _get().instance = nullptr;
        _get().flag.clear();
    }
private:
    static Instance& _get()
    {
        static Instance ins_;
        return ins_;
    }
    Singleton();
    ~Singleton();
    Singleton(const Singleton&) = delete;
    const Singleton& operator=(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    static Creator creator_;
};
// SINGLETON_INIT_BEFORE_MAIN(class,param_1,param_2,...);
#define SINGLETON_INIT_BEFORE_MAIN(type,...) \
template<> typename zonciu::singleton::Singleton<type>::Creator zonciu::singleton::Singleton<type>::creator_ = {__VA_ARGS__}
} // namespace zonciu
#endif
<|endoftext|>


<commit_before>#include <getopt.h>

#include <string>
#include <vector>

#include "subcommand.hpp"

#include "../vg.hpp"
#include "../haplotype_extracter.hpp"

using namespace vg;
using namespace std;
using namespace vg::subcommand;

using thread_t = vector<xg::XG::ThreadMapping>;

void help_trace(char** argv) {
    cerr << "usage: " << argv[0] << " trace [options]" << endl
         << "Trace and extract haplotypes from an index" << endl
         << endl
         << "options:" << endl
         << "    -x, --index FILE           use this xg index" << endl
         << "    -G, --gbwt-name            use this GBWT haplotype index instead of the xg's embedded gPBWT" << endl
         << "    -n, --start-node INT       start at this node" << endl
        //TODO: implement backwards iteration over graph
        // << "    -b, --backwards            iterate backwards over graph" << endl
         << "    -d, --extend-distance INT  extend search this many nodes [default=50]" << endl
         << "    -a, --annotation-path      output file for haplotype frequency annotations" << endl
         << "    -j, --json                 output subgraph in json instead of protobuf" << endl;
}

int main_trace(int argc, char** argv) {
  if (argc == 2) {
      help_trace(argv);
      return 1;
  }

  string xg_name;
  string gbwt_name;
  string annotation_path;
  int64_t start_node = 0;
  int extend_distance = 50;
  bool backwards = false;
  bool json = false;

  int c;
  optind = 2; // force optind past command positional argument
  while (true) {
    static struct option long_options[] =
        {
            /* These options set a flag. */
            //{"verbose", no_argument,       &verbose_flag, 1},
            {"index", required_argument, 0, 'x'},
            {"gbwt-name", required_argument, 0, 'G'},
            {"annotation-path", required_argument, 0, 'a'},
            {"start-node", required_argument, 0, 'n'},
            {"extend-distance", required_argument, 0, 'd'},
            {"json", no_argument, 0, 'j'},
            //{"backwards", no_argument, 0, 'b'},
            {0, 0, 0, 0}
        };

    int option_index = 0;
    c = getopt_long (argc, argv, "x:G:a:n:d:jh",
                     long_options, &option_index);

    /* Detect the end of the options. */
    if (c == -1)
        break;

    switch (c)
    {
    case 'x':
        xg_name = optarg;
        break;

    case 'G':
        gbwt_name = optarg;
        break;

    case 'a':
        annotation_path = optarg;
        break;

    case 'n':
        start_node = atoi(optarg);
        break;

    case 'd':
        extend_distance = atoi(optarg);
        break;

    case 'j':
        json = true;
        break;

    //case 'b':
        //backwards = true;
        //break;

    case '?':
    case 'h':
        help_trace(argv);
        return 1;

    default:
        help_trace(argv);
        abort();
    }
  }

  if (xg_name.empty()) {
    cerr << "error:[vg trace] xg index must be specified with -x" << endl;
    return 1;
  }
  if (start_node < 1) {
    cerr << "error:[vg trace] start node must be specified with -n" << endl;
    return 1;
  }
  xg::XG xindex;
  ifstream in(xg_name.c_str());
  xindex.load(in);

  // Now load the haplotype data
  unique_ptr<gbwt::GBWT> gbwt_index;
  if (!gbwt_name.empty()) {
    // We are tracing haplotypes, and we want to use the GBWT instead of the old gPBWT.
    gbwt_index = unique_ptr<gbwt::GBWT>(new gbwt::GBWT());

    // Open up the index
    ifstream in(gbwt_name.c_str());
    if (!in) {
      cerr << "error:[vg trace] unable to load gbwt index file" << endl;
      return 1;
    }

    // And load it
    gbwt_index->load(in);
  }

  // trace out our graph and paths from the start node
  Graph trace_graph;
  map<string, int> haplotype_frequences;
  trace_haplotypes_and_paths(xindex, gbwt_index.get(), start_node, extend_distance,
                             trace_graph, haplotype_frequences);

  // dump our graph to stdout
  if (json) {
    cout << pb2json(trace_graph);
  } else {
    VG vg_graph;
    vg_graph.extend(trace_graph);
    vg_graph.serialize_to_ostream(cout);
  }

  // if requested, write thread frequencies to a file
  if (!annotation_path.empty()) {
    ofstream annotation_file(annotation_path);
    for (auto tf : haplotype_frequences) {
      annotation_file << tf.first << "\t" << tf.second << endl;
    }
  }

  return 0;
}

static Subcommand vg_trace("trace", "trace haplotypes", main_trace);
<commit_msg>Improve trace options<commit_after>#include <getopt.h>

#include <string>
#include <vector>

#include "subcommand.hpp"

#include "../vg.hpp"
#include "../haplotype_extracter.hpp"

using namespace vg;
using namespace std;
using namespace vg::subcommand;

using thread_t = vector<xg::XG::ThreadMapping>;

void help_trace(char** argv) {
    cerr << "usage: " << argv[0] << " trace [options]" << endl
         << "Trace and extract haplotypes from an index" << endl
         << endl
         << "options:" << endl
         << "    -x, --index FILE           use this xg index" << endl
         << "    -G, --gbwt-name FILE       use this GBWT haplotype index instead of the xg's embedded gPBWT" << endl
         << "    -n, --start-node INT       start at this node" << endl
        //TODO: implement backwards iteration over graph
        // << "    -b, --backwards            iterate backwards over graph" << endl
         << "    -d, --extend-distance INT  extend search this many nodes [default=50]" << endl
         << "    -a, --annotation-path FILE output file for haplotype frequency annotations" << endl
         << "    -j, --json                 output subgraph in json instead of protobuf" << endl;
}

int main_trace(int argc, char** argv) {
  if (argc == 2) {
      help_trace(argv);
      return 1;
  }

  string xg_name;
  string gbwt_name;
  string annotation_path;
  int64_t start_node = 0;
  int extend_distance = 50;
  bool backwards = false;
  bool json = false;

  int c;
  optind = 2; // force optind past command positional argument
  while (true) {
    static struct option long_options[] =
        {
            /* These options set a flag. */
            //{"verbose", no_argument,       &verbose_flag, 1},
            {"index", required_argument, 0, 'x'},
            {"gbwt-name", required_argument, 0, 'G'},
            {"annotation-path", required_argument, 0, 'a'},
            {"start-node", required_argument, 0, 'n'},
            {"extend-distance", required_argument, 0, 'd'},
            {"json", no_argument, 0, 'j'},
            //{"backwards", no_argument, 0, 'b'},
            {0, 0, 0, 0}
        };

    int option_index = 0;
    c = getopt_long (argc, argv, "x:G:a:n:d:jh",
                     long_options, &option_index);

    /* Detect the end of the options. */
    if (c == -1)
        break;

    switch (c)
    {
    case 'x':
        xg_name = optarg;
        break;

    case 'G':
        gbwt_name = optarg;
        break;

    case 'a':
        annotation_path = optarg;
        break;

    case 'n':
        start_node = atoi(optarg);
        break;

    case 'd':
        extend_distance = atoi(optarg);
        break;

    case 'j':
        json = true;
        break;

    //case 'b':
        //backwards = true;
        //break;

    case '?':
    case 'h':
        help_trace(argv);
        return 1;

    default:
        help_trace(argv);
        abort();
    }
  }

  if (xg_name.empty()) {
    cerr << "error:[vg trace] xg index must be specified with -x" << endl;
    return 1;
  }
  if (start_node < 1) {
    cerr << "error:[vg trace] start node must be specified with -n" << endl;
    return 1;
  }
  xg::XG xindex;
  ifstream in(xg_name.c_str());
  xindex.load(in);

  // Now load the haplotype data
  unique_ptr<gbwt::GBWT> gbwt_index;
  if (!gbwt_name.empty()) {
    // We are tracing haplotypes, and we want to use the GBWT instead of the old gPBWT.
    gbwt_index = unique_ptr<gbwt::GBWT>(new gbwt::GBWT());

    // Open up the index
    ifstream in(gbwt_name.c_str());
    if (!in) {
      cerr << "error:[vg trace] unable to load gbwt index file" << endl;
      return 1;
    }

    // And load it
    gbwt_index->load(in);
  }

  // trace out our graph and paths from the start node
  Graph trace_graph;
  map<string, int> haplotype_frequences;
  trace_haplotypes_and_paths(xindex, gbwt_index.get(), start_node, extend_distance,
                             trace_graph, haplotype_frequences);

  // dump our graph to stdout
  if (json) {
    cout << pb2json(trace_graph);
  } else {
    VG vg_graph;
    vg_graph.extend(trace_graph);
    vg_graph.serialize_to_ostream(cout);
  }

  // if requested, write thread frequencies to a file
  if (!annotation_path.empty()) {
    ofstream annotation_file(annotation_path);
    for (auto tf : haplotype_frequences) {
      annotation_file << tf.first << "\t" << tf.second << endl;
    }
  }

  return 0;
}

static Subcommand vg_trace("trace", "trace haplotypes", main_trace);
<|endoftext|>


<commit_before>#include "augs/window_framework/create_process.h"

#if PLATFORM_UNIX
#include <unistd.h>
#endif

#include "augs/window_framework/shell.h"
#include "augs/ensure.h"

#if PLATFORM_WINDOWS
#include <Windows.h>
#endif

namespace augs {
	bool spawn_detached_process(const std::string& executable, const std::string& arguments) {
#if PLATFORM_UNIX
		(void)executable;
		(void)arguments;

		const auto cmd = "nohup \"" + executable + "\" " + arguments + " &";
		augs::shell(cmd);

#if NDEBUG
		// TODO IMPLEMENT THIS IN A WAY THAT WORKS!!!
		ensure(false && "NOT IMPLEMENTED!!");
#endif
		return true;

#elif PLATFORM_WINDOWS
		STARTUPINFO si;
		PROCESS_INFORMATION pi;

		ZeroMemory( &si, sizeof(si) );
		si.cb = sizeof(si);
		ZeroMemory( &pi, sizeof(pi) );

		const auto cmd = "\"" + executable + "\" " + arguments;

		// Start the child process.
		const auto result = CreateProcess(
			NULL,   // No module name (use command line)
			cmd.c_str(),        // Command line
			NULL,           // Process handle not inheritable
			NULL,           // Thread handle not inheritable
			FALSE,          // Set handle inheritance to FALSE
			0,              // No creation flags
			NULL,           // Use parent's environment block
			NULL,           // Use parent's starting directory
			&si,            // Pointer to STARTUPINFO structure
			&pi            // Pointer to PROCESS_INFORMATION structure
		);

		return result;
#else
		(void)executable;
		(void)arguments;
		return false;
#endif
	}
}
<commit_msg>Build fix<commit_after>#include "augs/window_framework/create_process.h"

#if PLATFORM_UNIX
#include <unistd.h>
#endif

#include "augs/window_framework/shell.h"
#include "augs/ensure.h"

#if PLATFORM_WINDOWS
#include <Windows.h>
#endif

namespace augs {
#elif PLATFORM_WINDOWS
	std::wstring widen(const std::string& s) {
		return std::wstring(s.begin(), s.end());
	}
#endif

	bool spawn_detached_process(const std::string& executable, const std::string& arguments) {
#if PLATFORM_UNIX
		(void)executable;
		(void)arguments;

		const auto cmd = "nohup \"" + executable + "\" " + arguments + " &";
		augs::shell(cmd);

#if NDEBUG
		// TODO IMPLEMENT THIS IN A WAY THAT WORKS!!!
		ensure(false && "NOT IMPLEMENTED!!");
#endif
		return true;

#elif PLATFORM_WINDOWS
		STARTUPINFO si;
		PROCESS_INFORMATION pi;

		ZeroMemory( &si, sizeof(si) );
		si.cb = sizeof(si);
		ZeroMemory( &pi, sizeof(pi) );

		const auto cmd = "\"" + executable + "\" " + arguments;

		const auto cmd_wide = widen(cmd);

		// Start the child process.
		const auto result = CreateProcess(
			NULL,   // No module name (use command line)
			cmd_wide.c_str(),        // Command line
			NULL,           // Process handle not inheritable
			NULL,           // Thread handle not inheritable
			FALSE,          // Set handle inheritance to FALSE
			0,              // No creation flags
			NULL,           // Use parent's environment block
			NULL,           // Use parent's starting directory
			&si,            // Pointer to STARTUPINFO structure
			&pi            // Pointer to PROCESS_INFORMATION structure
		);

		return result;
#else
		(void)executable;
		(void)arguments;
		return false;
#endif
	}
}
<|endoftext|>


<commit_before>/*
 * File:   Scene.cpp
 * Author: iMer
 *
 * Created on 3. Juli 2014, 01:01
 */

#include "Scene.hpp"
#include "Game.hpp"
#include "Light.hpp"
#include <iostream>
#include <mutex>
#include "Light.hpp"
#include "Engine/Factory.hpp"
namespace engine {
    b2Vec2 Scene::default_gravity(0, 0);

    SceneContactListener::SceneContactListener(Scene* scene) : m_scene(scene) {

    }

    void SceneContactListener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold){
        m_scene->OnContactPreSolve.Fire(contact, oldManifold);
    }
    void SceneContactListener::BeginContact(b2Contact* contact) {
        m_scene->OnContact.Fire(contact, true);
    }

    void SceneContactListener::EndContact(b2Contact* contact) {
        m_scene->OnContact.Fire(contact, false);
    }
    void SceneContactListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse){
        m_scene->OnContactPostSolve.Fire(contact, impulse);
    }

    Scene::Scene(Game* game) : Node(this), m_game(game), m_pixToM(80.0f), m_debugDraw(this), m_lightSystem(this), m_debug(false), m_ui(nullptr), m_contactListener(this) {
        m_world = new b2World(default_gravity);
        m_world->SetContactListener(&m_contactListener);
        m_world->SetDebugDraw(&m_debugDraw);
        m_debugDraw.SetFlags(b2Draw::e_shapeBit);
    }

    LightSystem* Scene::GetLightSystem() {
        return &m_lightSystem;
    }

    void Scene::SetDebug(bool debug) {
        m_debug = debug;
    }

    bool Scene::IsDebug() const {
        return m_debug;
    }

    Scene::~Scene() {
        while (m_children.size()) {
            delete m_children.front();
        }
        m_children.clear();
        delete m_world;
        m_world = nullptr;
    }

    void Scene::SetGame(Game* game) {
        m_game = game;
    }

    Game* Scene::GetGame() const {
        return m_game;
    }

    b2World* Scene::GetWorld() {
        return m_world;
    }

    float Scene::MeterToPixel(float m) {
        return m_pixToM*m;
    }

    float Scene::GetPixelMeterRatio() const {
        return m_pixToM;
    }

    void Scene::PostDraw(sf::RenderTarget& target, sf::RenderStates states, float delta) {
        if (m_debug) {
            m_mutexDebug.lock();
            if (m_debugDraw.IsInitialized()) {
                m_debugDraw.draw(target, states);
            }
            m_mutexDebug.unlock();
        }
        m_lightSystem.draw(target, states);
        // Keep UI in the screen
        // Keep UI in the screen
        auto view = m_scene->GetGame()->GetWindow()->getView();
		if (m_ui){
			m_ui->SetPosition(view.getCenter().x - (view.getSize().x / 2), view.getCenter().y - (view.getSize().y / 2));
			m_ui->draw(target, states, delta);
		}
    }

    void Scene::OnUpdate(sf::Time interval) {
        m_world->Step(interval.asSeconds(), 8, 3); // TODO: tweakable iterations? currently the box2d recommended ones
        if (m_debug) {
            m_mutexDebug.lock();
            m_debugDraw.Begin();
            m_world->DrawDebugData();
            m_debugDraw.End();
            m_mutexDebug.unlock();
        }
        m_lightSystem.update(interval);
        if (m_ui) {
			m_ui->update(interval);
		}
    }

    uint8_t Scene::GetType() const {
        return NT_SCENE;
    }

    bool Scene::initialize(Json::Value& root) {
        if (root.isMember("size")) {
            auto size = root["size"];
            if (size.isArray()) {
                m_size.x = size.get(0u, 0).asFloat();
                m_size.y = size.get(1u, 0).asFloat();
            } else {
                m_size.x = size.get("x", 0).asFloat();
                m_size.y = size.get("y", 0).asFloat();
            }
        }
        if (root["gravity"].isArray()) {
            m_world->SetGravity(b2Vec2(root["gravity"].get(0u, 0).asFloat(), root["gravity"].get(1u, 0).asFloat()));
        } else if (root["gravity"].isObject()) {
            m_world->SetGravity(b2Vec2(root["gravity"].get("x", 0).asFloat(), root["gravity"].get("y", 0).asFloat()));
        }
        m_pixToM = root.get("pixelToMeter", 80).asFloat();
        m_debug = root.get("debug", false).asBool();
        auto light = root["light"];
        if (!light.empty() && !light.isNull()) {
            m_lightSystem.SetEnabled(light.get("enabled", true).asBool());
            if (light["ambient"].isArray()) {
                m_lightSystem.SetAmbientColor(sf::Color(light["ambient"].get(0u, 255).asInt(), light["ambient"].get(1u, 255).asInt(), light["ambient"].get(2u, 255).asInt(), light["ambient"].get(3u, 255).asInt()));
            } else if (light["ambient"].isInt()) {
                unsigned int lc = light["ambient"].asInt();
                m_lightSystem.SetAmbientColor(sf::Color(lc & 0xFF0000, lc & 0xFF00, lc & 0xFF, lc & 0xFF000000));
            }
        }
		// Easy way to fill the ui layer
		auto ui = root["ui"];
		if (ui.isArray()) {
			if (!m_ui) {
				m_ui = new Node(this);
			}
			Factory::MakeChildren(ui, m_ui);
		}
        return true;
    }
}

<commit_msg>Also delete Scene::m_ui<commit_after>/*
 * File:   Scene.cpp
 * Author: iMer
 *
 * Created on 3. Juli 2014, 01:01
 */

#include "Scene.hpp"
#include "Game.hpp"
#include "Light.hpp"
#include <iostream>
#include <mutex>
#include "Light.hpp"
#include "Engine/Factory.hpp"
namespace engine {
    b2Vec2 Scene::default_gravity(0, 0);

    SceneContactListener::SceneContactListener(Scene* scene) : m_scene(scene) {

    }

    void SceneContactListener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold){
        m_scene->OnContactPreSolve.Fire(contact, oldManifold);
    }
    void SceneContactListener::BeginContact(b2Contact* contact) {
        m_scene->OnContact.Fire(contact, true);
    }

    void SceneContactListener::EndContact(b2Contact* contact) {
        m_scene->OnContact.Fire(contact, false);
    }
    void SceneContactListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse){
        m_scene->OnContactPostSolve.Fire(contact, impulse);
    }

    Scene::Scene(Game* game) : Node(this), m_game(game), m_pixToM(80.0f), m_debugDraw(this), m_lightSystem(this), m_debug(false), m_ui(nullptr), m_contactListener(this) {
        m_world = new b2World(default_gravity);
        m_world->SetContactListener(&m_contactListener);
        m_world->SetDebugDraw(&m_debugDraw);
        m_debugDraw.SetFlags(b2Draw::e_shapeBit);
    }

    LightSystem* Scene::GetLightSystem() {
        return &m_lightSystem;
    }

    void Scene::SetDebug(bool debug) {
        m_debug = debug;
    }

    bool Scene::IsDebug() const {
        return m_debug;
    }

    Scene::~Scene() {
        while (m_children.size()) {
            delete m_children.front();
        }
        m_children.clear();
        delete m_ui;
        delete m_world;
        m_world = nullptr;
    }

    void Scene::SetGame(Game* game) {
        m_game = game;
    }

    Game* Scene::GetGame() const {
        return m_game;
    }

    b2World* Scene::GetWorld() {
        return m_world;
    }

    float Scene::MeterToPixel(float m) {
        return m_pixToM*m;
    }

    float Scene::GetPixelMeterRatio() const {
        return m_pixToM;
    }

    void Scene::PostDraw(sf::RenderTarget& target, sf::RenderStates states, float delta) {
        if (m_debug) {
            m_mutexDebug.lock();
            if (m_debugDraw.IsInitialized()) {
                m_debugDraw.draw(target, states);
            }
            m_mutexDebug.unlock();
        }
        m_lightSystem.draw(target, states);
        // Keep UI in the screen
        // Keep UI in the screen
        auto view = m_scene->GetGame()->GetWindow()->getView();
		if (m_ui){
			m_ui->SetPosition(view.getCenter().x - (view.getSize().x / 2), view.getCenter().y - (view.getSize().y / 2));
			m_ui->draw(target, states, delta);
		}
    }

    void Scene::OnUpdate(sf::Time interval) {
        m_world->Step(interval.asSeconds(), 8, 3); // TODO: tweakable iterations? currently the box2d recommended ones
        if (m_debug) {
            m_mutexDebug.lock();
            m_debugDraw.Begin();
            m_world->DrawDebugData();
            m_debugDraw.End();
            m_mutexDebug.unlock();
        }
        m_lightSystem.update(interval);
        if (m_ui) {
			m_ui->update(interval);
		}
    }

    uint8_t Scene::GetType() const {
        return NT_SCENE;
    }

    bool Scene::initialize(Json::Value& root) {
        if (root.isMember("size")) {
            auto size = root["size"];
            if (size.isArray()) {
                m_size.x = size.get(0u, 0).asFloat();
                m_size.y = size.get(1u, 0).asFloat();
            } else {
                m_size.x = size.get("x", 0).asFloat();
                m_size.y = size.get("y", 0).asFloat();
            }
        }
        if (root["gravity"].isArray()) {
            m_world->SetGravity(b2Vec2(root["gravity"].get(0u, 0).asFloat(), root["gravity"].get(1u, 0).asFloat()));
        } else if (root["gravity"].isObject()) {
            m_world->SetGravity(b2Vec2(root["gravity"].get("x", 0).asFloat(), root["gravity"].get("y", 0).asFloat()));
        }
        m_pixToM = root.get("pixelToMeter", 80).asFloat();
        m_debug = root.get("debug", false).asBool();
        auto light = root["light"];
        if (!light.empty() && !light.isNull()) {
            m_lightSystem.SetEnabled(light.get("enabled", true).asBool());
            if (light["ambient"].isArray()) {
                m_lightSystem.SetAmbientColor(sf::Color(light["ambient"].get(0u, 255).asInt(), light["ambient"].get(1u, 255).asInt(), light["ambient"].get(2u, 255).asInt(), light["ambient"].get(3u, 255).asInt()));
            } else if (light["ambient"].isInt()) {
                unsigned int lc = light["ambient"].asInt();
                m_lightSystem.SetAmbientColor(sf::Color(lc & 0xFF0000, lc & 0xFF00, lc & 0xFF, lc & 0xFF000000));
            }
        }
		// Easy way to fill the ui layer
		auto ui = root["ui"];
		if (ui.isArray()) {
			if (!m_ui) {
				m_ui = new Node(this);
			}
			Factory::MakeChildren(ui, m_ui);
		}
        return true;
    }
}

<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef HTTP_REQUEST_LINE_HPP
#define HTTP_REQUEST_LINE_HPP

#include <cctype>
#include <regex>
#include "common.hpp"
#include "methods.hpp"
#include "version.hpp"

namespace http {

/**
 * @brief This class represents the {Request-Line}
 * of an HTTP request message
 */
class Request_Line {
public:
  /**
   * @brief Default constructor
   */
  explicit Request_Line() = default;

  /**
   * @brief Constructor to construct a {Request-Line}
   * from the incoming character stream of data which
   * is a {std::string} object
   *
   * @tparam T request - The character stream of data
   */
  template
  <
    typename T,
    typename = std::enable_if_t
               <std::is_same
               <std::string, std::remove_reference_t
               <std::remove_const_t<T>>>::value>
  >
  explicit Request_Line(T&& request);

  // Default lifetime operations
  Request_Line(Request_Line&)  = default;
  Request_Line(Request_Line&&) = default;
  Request_Line& operator = (Request_Line&)  = default;
  Request_Line& operator = (Request_Line&&) = default;
  ~Request_Line() = default;

  /**
   * @brief Get the method of the message
   *
   * @return - The method of the message
   */
  const Method& get_method() const noexcept;

  /**
   * @brief Set the method of the message
   *
   * @param method - The method of the message
   */
  void set_method(const Method& method);

  /**
   * @brief Get the URI of the message
   *
   * @return - The URI of the message
   */
  const URI& get_uri() const noexcept;

  /**
   * @brief Set the URI of the message
   *
   * @param uri - The URI of the message
   */
  void set_uri(const URI& uri);

  /**
   * @brief Get the version of the message
   *
   * @return - The version of the message
   */
  const Version& get_version() const noexcept;

  /**
   * @brief Set the version of the message
   *
   * @param version - The version of the message
   */
  void set_version(const Version& version) noexcept;

  /**
   * @brief Get a string representation of this
   * class
   *
   * @return - A string representation
   */
  std::string to_string() const;

  /**
   * @brief Operator to transform this class
   * into string form
   */
  operator std::string () const;
  //-----------------------------------
private:
  //-----------------------------------
  // Class data members
  //-----------------------------------
  Method  method_  { GET };
  URI     uri_     {"/"};
  Version version_ {1U, 1U};
}; //< class Request_Line

  class Request_line_error : public std::runtime_error {
    using runtime_error::runtime_error;
  };

/**--v----------- Implementation Details -----------v--**/

template <typename T, typename>
inline Request_Line::Request_Line(T&& request) {
  if (request.empty() or request.size() < 15 /*<-(15) minimum request length */) {
    throw Request_line_error("Invalid request line: " + request_line);
  }

  // Extract {Request-Line} from request
  std::string request_line;
  std::size_t index;

  if ((index = request.find("\r\n")) not_eq std::string::npos) {
    request_line = {request.substr(0, index)};
  } else if ((index = request.find('\n')) not_eq std::string::npos) {
    request_line = {request.substr(0, index)};
  } else {
    throw Request_line_error("Invalid line-ending");
  }

  // Should identify strings according to RFC 2616 sect.5.1
  // https://tools.ietf.org/html/rfc2616#section-5.1
  const static std::regex request_line_pattern
  {
    "\\s*(GET|POST|PUT|DELETE|OPTIONS|HEAD|TRACE|CONNECT) " // Method
    "(\\S+) " // URI
    "HTTP/(\\d+)\\.(\\d+)" // Version Major.Minor
  };

  std::smatch m;
  auto matched = std::regex_match(request_line, m, request_line_pattern);

  if (not matched) {
    throw Request_line_error("Invalid request line: " + request_line);
  }

  method_ = method::code(m[1]);

  new (&uri_) URI(m[2]);

  unsigned maj = static_cast<unsigned>(std::stoul(m[3]));
  unsigned min = static_cast<unsigned>(std::stoul(m[4]));
  version_ = Version{maj, min};

  // Trim the request for further processing
  request = request.substr(index + 2);
}

inline const Method& Request_Line::get_method() const noexcept {
  return method_;
}

inline void Request_Line::set_method(const Method& method) {
  method_ = method;
}

inline const URI& Request_Line::get_uri() const noexcept {
  return uri_;
}

inline void Request_Line::set_uri(const URI& uri) {
  //uri_ = uri;
  new (&uri_) URI(uri);
}

inline const Version& Request_Line::get_version() const noexcept {
  return version_;
}

inline void Request_Line::set_version(const Version& version) noexcept {
  version_ = version;
}

inline std::string Request_Line::to_string() const {
  return method::str(method_)+" "+uri_.to_string()+" "
    +version_.to_string();
}

inline Request_Line::operator std::string () const {
  std::ostringstream req_line;
  //-----------------------------
  req_line << method_  << " "
           << uri_     << " "
           << version_ << "\r\n";
 //------------------------------
  return req_line.str();
}

inline std::ostream& operator << (std::ostream& output_device, const Request_Line& req_line) {
  return output_device << req_line.to_string();
}

/**--^----------- Implementation Details -----------^--**/

} //< namespace http

#endif //< HTTP_REQUEST_LINE_HPP
<commit_msg>Removed dead code<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef HTTP_REQUEST_LINE_HPP
#define HTTP_REQUEST_LINE_HPP

#include <cctype>
#include <regex>
#include "common.hpp"
#include "methods.hpp"
#include "version.hpp"

namespace http {

/**
 * @brief This class represents the {Request-Line}
 * of an HTTP request message
 */
class Request_Line {
public:
  /**
   * @brief Default constructor
   */
  explicit Request_Line() = default;

  /**
   * @brief Constructor to construct a {Request-Line}
   * from the incoming character stream of data which
   * is a {std::string} object
   *
   * @tparam T request - The character stream of data
   */
  template
  <
    typename T,
    typename = std::enable_if_t
               <std::is_same
               <std::string, std::remove_reference_t
               <std::remove_const_t<T>>>::value>
  >
  explicit Request_Line(T&& request);

  // Default lifetime operations
  Request_Line(Request_Line&)  = default;
  Request_Line(Request_Line&&) = default;
  Request_Line& operator = (Request_Line&)  = default;
  Request_Line& operator = (Request_Line&&) = default;
  ~Request_Line() = default;

  /**
   * @brief Get the method of the message
   *
   * @return - The method of the message
   */
  const Method& get_method() const noexcept;

  /**
   * @brief Set the method of the message
   *
   * @param method - The method of the message
   */
  void set_method(const Method& method);

  /**
   * @brief Get the URI of the message
   *
   * @return - The URI of the message
   */
  const URI& get_uri() const noexcept;

  /**
   * @brief Set the URI of the message
   *
   * @param uri - The URI of the message
   */
  void set_uri(const URI& uri);

  /**
   * @brief Get the version of the message
   *
   * @return - The version of the message
   */
  const Version& get_version() const noexcept;

  /**
   * @brief Set the version of the message
   *
   * @param version - The version of the message
   */
  void set_version(const Version& version) noexcept;

  /**
   * @brief Get a string representation of this
   * class
   *
   * @return - A string representation
   */
  std::string to_string() const;

  /**
   * @brief Operator to transform this class
   * into string form
   */
  operator std::string () const;
  //-----------------------------------
private:
  //-----------------------------------
  // Class data members
  //-----------------------------------
  Method  method_  { GET };
  URI     uri_     {"/"};
  Version version_ {1U, 1U};
}; //< class Request_Line

  class Request_line_error : public std::runtime_error {
    using runtime_error::runtime_error;
  };

/**--v----------- Implementation Details -----------v--**/

template <typename T, typename>
inline Request_Line::Request_Line(T&& request) {
  if (request.empty() or request.size() < 15 /*<-(15) minimum request length */) {
    throw Request_line_error("Invalid request line: " + request_line);
  }

  // Extract {Request-Line} from request
  std::string request_line;
  std::size_t index;

  if ((index = request.find("\r\n")) not_eq std::string::npos) {
    request_line = {request.substr(0, index)};
  } else if ((index = request.find('\n')) not_eq std::string::npos) {
    request_line = {request.substr(0, index)};
  } else {
    throw Request_line_error("Invalid line-ending");
  }

  // Should identify strings according to RFC 2616 sect.5.1
  // https://tools.ietf.org/html/rfc2616#section-5.1
  const static std::regex request_line_pattern
  {
    "\\s*(GET|POST|PUT|DELETE|OPTIONS|HEAD|TRACE|CONNECT) " // Method
    "(\\S+) " // URI
    "HTTP/(\\d+)\\.(\\d+)" // Version Major.Minor
  };

  std::smatch m;
  auto matched = std::regex_match(request_line, m, request_line_pattern);

  if (not matched) {
    throw Request_line_error("Invalid request line: " + request_line);
  }

  method_ = method::code(m[1]);

  new (&uri_) URI(m[2]);

  unsigned maj = static_cast<unsigned>(std::stoul(m[3]));
  unsigned min = static_cast<unsigned>(std::stoul(m[4]));
  version_ = Version{maj, min};

  // Trim the request for further processing
  request = request.substr(index + 2);
}

inline const Method& Request_Line::get_method() const noexcept {
  return method_;
}

inline void Request_Line::set_method(const Method& method) {
  method_ = method;
}

inline const URI& Request_Line::get_uri() const noexcept {
  return uri_;
}

inline void Request_Line::set_uri(const URI& uri) {
  new (&uri_) URI(uri);
}

inline const Version& Request_Line::get_version() const noexcept {
  return version_;
}

inline void Request_Line::set_version(const Version& version) noexcept {
  version_ = version;
}

inline std::string Request_Line::to_string() const {
  return method::str(method_)+" "+uri_.to_string()+" "
    +version_.to_string();
}

inline Request_Line::operator std::string () const {
  std::ostringstream req_line;
  //-----------------------------
  req_line << method_  << " "
           << uri_     << " "
           << version_ << "\r\n";
 //------------------------------
  return req_line.str();
}

inline std::ostream& operator << (std::ostream& output_device, const Request_Line& req_line) {
  return output_device << req_line.to_string();
}

/**--^----------- Implementation Details -----------^--**/

} //< namespace http

#endif //< HTTP_REQUEST_LINE_HPP
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// string_functions_proxy.cpp
//
// Identification: src/codegen/proxy/string_functions_proxy.cpp
//
// Copyright (c) 2015-2017, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "codegen/proxy/string_functions_proxy.h"

#include "codegen/proxy/type_builder.h"
#include "function/string_functions.h"

namespace peloton {
namespace codegen {

DEFINE_METHOD(peloton::function, StringFunctions, Ascii);
DEFINE_METHOD(peloton::function, StringFunctions, Like);

DEFINE_METHOD(peloton::function, StringFunctions, Length);

}  // namespace codegen
}  // namespace peloton
<commit_msg>Small cleanup<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// string_functions_proxy.cpp
//
// Identification: src/codegen/proxy/string_functions_proxy.cpp
//
// Copyright (c) 2015-2017, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "codegen/proxy/string_functions_proxy.h"

#include "codegen/proxy/type_builder.h"
#include "function/string_functions.h"

namespace peloton {
namespace codegen {

DEFINE_METHOD(peloton::function, StringFunctions, Ascii);
DEFINE_METHOD(peloton::function, StringFunctions, Like);
DEFINE_METHOD(peloton::function, StringFunctions, Length);

}  // namespace codegen
}  // namespace peloton
<|endoftext|>


<commit_before>
#include "au/mutex/TokenTaker.h"

#include "samson/network/DelilahNetwork.h"

#include "DelilahBaseConnection.h" // Own interface

size_t delilah_random_code = 0;

namespace samson
{

    // Manual network interface ( mainly samsonLocal )
    void DelilahBaseConnection::setNetwork( NetworkInterface* _network )
    {
        au::TokenTaker tt(&token);

        // Do not replace a previous network
        if( network )
            return;

        network = _network;		     // Keep a pointer to our network interface element
        if( network )
            network->setReceiver(this);
    }

    void DelilahBaseConnection::delilah_disconnect( au::ErrorManager * error )
    {
        au::TokenTaker tt(&token);
        au::ErrorContext c( error , "DelilahConnection" ); // Context of the error

        if( !network )
        {
            error->add_error("Not connected to any SAMSON Cluster");
            return;
        }

        // Schedule destruction of this element in the main engine
        engine::Engine::shared()->add( new DelilahNetworkRemove( (DelilahNetwork*) network ) );

        network = NULL;
    }

    void DelilahBaseConnection::stop()
    {
        au::TokenTaker tt(&token);
        if( network )
        {
            network->stop();
            delete network;
            network = NULL;
        }
    }

    void DelilahBaseConnection::delilah_connect( std::string connection_type
                                  , std::string host
                                  , int port
                                  , std::string user
                                  , std::string password
                                  , au::ErrorManager* error)
    {
        au::TokenTaker tt(&token);

        if( network )
        {
            error->set( au::str("Currently connected to %s" , network->getLoginInfo().c_str() ) );
            return;
        }

        samson::DelilahNetwork * _network = new samson::DelilahNetwork( connection_type , delilah_random_code );

        // Set the network element
        network = _network;
        network->setReceiver(this);

        // Add main delilah connection with specified worker
        samson::Status s = _network->addMainDelilahConnection( host , port , user , password );

        if( s != samson::OK )
        {
            error->set(au::str("Not possible to open connection with %s:%d (%s)" , host.c_str() , port , samson::status(s) ));
            // TODO: Wait for unfinished threads in _network?

            network = NULL;
            delete _network;
        }

    }

    size_t DelilahBaseConnection::getNextWorkerId()
    {
        au::TokenTaker tt(&token);

        if( !network )
            return 0;

        std::vector<size_t> workers = network->getWorkerIds();

        if( next_worker == -1 )
        {
            int max = workers.size();
            int r = rand();
            next_worker = r%max;

        }

        next_worker++;
        if( next_worker == (int)workers.size() )
            next_worker = 0;

        return workers[ next_worker ];
    }

    void DelilahBaseConnection::send( Packet* packet , au::ErrorManager *error )
    {
        if( network )
            network->send( packet );
        else
            error->set( au::str("Not connected to any SAMSON System") );
    }

    std::vector<size_t> DelilahBaseConnection::getConnectedWorkerIds( au::ErrorManager * error )
    {
        au::TokenTaker tt(&token);

        if( network )
            return network->getConnectedWorkerIds();
        else
        {
            error->set( au::str("Not connected to any SAMSON System") );
            return std::vector<size_t>();
        }
    }

    std::vector<size_t> DelilahBaseConnection::getWorkerIds( au::ErrorManager * error )
    {
        au::TokenTaker tt(&token);

        if( network )
            return network->getWorkerIds();
        else
        {
            error->set( au::str("Not connected to any SAMSON System") );
            return std::vector<size_t>();
        }
    }

    bool DelilahBaseConnection::isConnected()
    {
        au::TokenTaker tt(&token);

        return network != NULL;
    }

    bool DelilahBaseConnection::isConnectionReady()
    {
        au::TokenTaker tt(&token);

        if( !network)
            return false;
        return network->ready();
    }

    std::string DelilahBaseConnection::getConnectionInformation()
    {
        au::TokenTaker tt(&token);

        if( network )
            return network->getLoginInfo();
        else
            return "Unconnected";
    }

    std::string DelilahBaseConnection::runClusterCommand( std::string command , au::ErrorManager* error )
    {
        au::TokenTaker tt(&token);

        if( network )
            return network->cluster_command( command );
        else
        {
            error->set( au::str("Not connected to any SAMSON System") );
            return "";
        }

    }

}<commit_msg>Fix divide by 0 error seen with unitTesting and prevent the end of the universe<commit_after>
#include "au/mutex/TokenTaker.h"

#include "samson/network/DelilahNetwork.h"

#include "DelilahBaseConnection.h" // Own interface

size_t delilah_random_code = 0;

namespace samson
{

    // Manual network interface ( mainly samsonLocal )
    void DelilahBaseConnection::setNetwork( NetworkInterface* _network )
    {
        au::TokenTaker tt(&token);

        // Do not replace a previous network
        if( network )
            return;

        network = _network;		     // Keep a pointer to our network interface element
        if( network )
            network->setReceiver(this);
    }

    void DelilahBaseConnection::delilah_disconnect( au::ErrorManager * error )
    {
        au::TokenTaker tt(&token);
        au::ErrorContext c( error , "DelilahConnection" ); // Context of the error

        if( !network )
        {
            error->add_error("Not connected to any SAMSON Cluster");
            return;
        }

        // Schedule destruction of this element in the main engine
        engine::Engine::shared()->add( new DelilahNetworkRemove( (DelilahNetwork*) network ) );

        network = NULL;
    }

    void DelilahBaseConnection::stop()
    {
        au::TokenTaker tt(&token);
        if( network )
        {
            network->stop();
            delete network;
            network = NULL;
        }
    }

    void DelilahBaseConnection::delilah_connect( std::string connection_type
                                  , std::string host
                                  , int port
                                  , std::string user
                                  , std::string password
                                  , au::ErrorManager* error)
    {
        au::TokenTaker tt(&token);

        if( network )
        {
            error->set( au::str("Currently connected to %s" , network->getLoginInfo().c_str() ) );
            return;
        }

        samson::DelilahNetwork * _network = new samson::DelilahNetwork( connection_type , delilah_random_code );

        // Set the network element
        network = _network;
        network->setReceiver(this);

        // Add main delilah connection with specified worker
        samson::Status s = _network->addMainDelilahConnection( host , port , user , password );

        if( s != samson::OK )
        {
            error->set(au::str("Not possible to open connection with %s:%d (%s)" , host.c_str() , port , samson::status(s) ));
            // TODO: Wait for unfinished threads in _network?

            network = NULL;
            delete _network;
        }

    }

    size_t DelilahBaseConnection::getNextWorkerId()
    {
        au::TokenTaker tt(&token);

        if( !network )
            return 0;

        std::vector<size_t> workers = network->getWorkerIds();

        if( next_worker == -1 )
        {
            int max = workers.size();
            int r = rand();
            if ( max != 0 )
              next_worker = r%max;
        }

        next_worker++;
        if( next_worker == (int)workers.size() )
            next_worker = 0;

        return workers[ next_worker ];
    }

    void DelilahBaseConnection::send( Packet* packet , au::ErrorManager *error )
    {
        if( network )
            network->send( packet );
        else
            error->set( au::str("Not connected to any SAMSON System") );
    }

    std::vector<size_t> DelilahBaseConnection::getConnectedWorkerIds( au::ErrorManager * error )
    {
        au::TokenTaker tt(&token);

        if( network )
            return network->getConnectedWorkerIds();
        else
        {
            error->set( au::str("Not connected to any SAMSON System") );
            return std::vector<size_t>();
        }
    }

    std::vector<size_t> DelilahBaseConnection::getWorkerIds( au::ErrorManager * error )
    {
        au::TokenTaker tt(&token);

        if( network )
            return network->getWorkerIds();
        else
        {
            error->set( au::str("Not connected to any SAMSON System") );
            return std::vector<size_t>();
        }
    }

    bool DelilahBaseConnection::isConnected()
    {
        au::TokenTaker tt(&token);

        return network != NULL;
    }

    bool DelilahBaseConnection::isConnectionReady()
    {
        au::TokenTaker tt(&token);

        if( !network)
            return false;
        return network->ready();
    }

    std::string DelilahBaseConnection::getConnectionInformation()
    {
        au::TokenTaker tt(&token);

        if( network )
            return network->getLoginInfo();
        else
            return "Unconnected";
    }

    std::string DelilahBaseConnection::runClusterCommand( std::string command , au::ErrorManager* error )
    {
        au::TokenTaker tt(&token);

        if( network )
            return network->cluster_command( command );
        else
        {
            error->set( au::str("Not connected to any SAMSON System") );
            return "";
        }

    }

}
<|endoftext|>