text:
#include "terrainstorage.hpp"

#include <boost/algorithm/string.hpp>

#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/esmstore.hpp"

namespace MWRender
{

    void TerrainStorage::getBounds(float& minX, float& maxX, float& minY, float& maxY)
    {
        minX = 0, minY = 0, maxX = 0, maxY = 0;

        const MWWorld::ESMStore &esmStore =
            MWBase::Environment::get().getWorld()->getStore();

        MWWorld::Store<ESM::Cell>::iterator it = esmStore.get<ESM::Cell>().extBegin();
        for (; it != esmStore.get<ESM::Cell>().extEnd(); ++it)
        {
            if (it->getGridX() < minX)
                minX = it->getGridX();
            if (it->getGridX() > maxX)
                maxX = it->getGridX();
            if (it->getGridY() < minY)
                minY = it->getGridY();
            if (it->getGridY() > maxY)
                maxY = it->getGridY();
        }

        // since grid coords are at cell origin, we need to add 1 cell
        maxX += 1;
        maxY += 1;
    }

    ESM::Land* TerrainStorage::getLand(int cellX, int cellY)
    {
        const MWWorld::ESMStore &esmStore =
            MWBase::Environment::get().getWorld()->getStore();
        ESM::Land* land = esmStore.get<ESM::Land>().search(cellX, cellY);
        return land;
    }

    const ESM::LandTexture* TerrainStorage::getLandTexture(int index, short plugin)
    {
        const MWWorld::ESMStore &esmStore =
            MWBase::Environment::get().getWorld()->getStore();
        return esmStore.get<ESM::LandTexture>().find(index, plugin);
    }

}

max_stars_repo_name: Bodillium/openmw

max_issues_repo_name: Bodillium/openmw

max_forks_repo_name: Bodillium/openmw


text:
// ------------------------------------------------------------------------------
// libs/format/test/format_test1.cpp :  test constructing objects and basic parsing
// ------------------------------------------------------------------------------

//  Copyright Samuel Krempp 2003. Use, modification, and distribution are
//  subject to the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/format for library home page

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

#include <boost/detail/lightweight_test.hpp>
#include <boost/format.hpp>

int main(int, char* [])
{
  using boost::format;
  using boost::str;

  if(str( format("  %%  ") ) != "  %  ")
      BOOST_ERROR("Basic parsing without arguments Failed");
  if(str( format("nothing") ) != "nothing")
      BOOST_ERROR("Basic parsing without arguments Failed");
  if(str( format("%%  ") ) != "%  ")
      BOOST_ERROR("Basic parsing without arguments Failed");
  if(str( format("  %%") ) != "  %")
      BOOST_ERROR("Basic parsing without arguments Failed");
  if(str( format("  %n  ") ) != "    ")
      BOOST_ERROR("Basic parsing without arguments Failed");
  if(str( format("%n  ") ) != "  ")
      BOOST_ERROR("Basic parsing without arguments Failed");
  if(str( format("  %n") ) != "  ")
      BOOST_ERROR("Basic parsing without arguments Failed");

  if(str( format("%%##%%##%%1 %1%00") % "Escaped OK" ) != "%##%##%1 Escaped OK00")
      BOOST_ERROR("Basic parsing Failed");
  if(str( format("%%##%#x ##%%1 %s00") % 20 % "Escaped OK" ) != "%##0x14 ##%1 Escaped OK00")
      BOOST_ERROR("Basic p-parsing Failed") ;

  return boost::report_errors();
}

ext: cpp


text:
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2006, 2007 Eric Ehlers

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

/*! \file
    \brief Class RangeReference - Parse range references in string format
*/

#include <ohxl/ohxldefines.hpp>
#include <boost/regex.hpp>
#include <string>

namespace ObjectHandler {

    //! A utility class for parsing range references in string format.
    /*! The constructor to this class accepts strings returned from
        Excel functions such as xlfGetName and xlfReftext.  Strings are
        parsed and their tokens stored in separate variables to facilitate
        comparisons such as determing whether one range contains another.

        Excel returns a variety of strings to represent references.
        The following formats are supported:

        Normal:
        \code
            "[Book1.xls]Sheet1!R1C1"
        \endcode

        Some excel functions prepend an '=' sign:
        \code
            "=[Book1.xls]Sheet1!R1C1"
        \endcode

        If book or sheet name contains spaces then Excel encloses the text
        in single quotes:
        \code
            "'[Bo ok1.xls]Sheet1'!R1C1"
        \endcode

        If book name contains dots then Excel encloses the text
        in single quotes:
        \code
            "'[Bo.ok1.xls]Sheet1'!R1C1"
        \endcode

        For a new book that hasn't yet been saved, excel omits the .xls suffix:
        \code
            "[Book1]Sheet1!R1C1"
        \endcode

        Sometimes the string includes the filesystem path:
        \code
            "='C:\\path\\to\\[Book1.xls]Sheet1'!R1C1"
        \endcode

        If the book contains a single sheet with the same name as the book,
        then the sheet name is omitted altogether and the book name is not
        enclosed in []s:
        \code
            "same_name.xls!R1C1"
            "'same name.xls'!R1C1"
        \endcode

        In all cases, the cell reference, represented above as R1C1, may also
        be given as R1C1:R9C9 i.e. a range consisting of multiple cells, in
        which case the RangeReference constructor sets multicell_ to true.
    */
    class RangeReference {
        friend std::ostream &operator<<(std::ostream&, const RangeReference&);
    public:
        //! \name Structors and static members
        //@{
        //! Constructor - initialize the RangeReference object.
        /*! Parse the input string and store its component tokens in separate
            variables e.g. bookName_, sheetName_, etc.
        */
        RangeReference(const std::string &address);
        //@}

        //! \name Operators and Comparisons
        //@{
        //! Test two RangeReference objects for equality.
        /*! The two objects may in fact represent the same range even if they
            were initialized with different strings and this operator handles
            that case.
        */
        bool operator==(const RangeReference&) const;
        //! Determine whether this range contains the given one.
        /*! This functionality is presently used for processing error messages -
            An error message may be associated with a multi-cell range and the
            user can query any subset of that range and still get the relevant
            error message.
        */
        bool contains(const RangeReference&) const;
        //@}

        //! \name Error Messages
        //@{
        //! Assign an error message to this range.
        void setErrorMessage(const std::string &errorMessage);
        //! Retrieve the error message associated with this range.
        /*! This function is wrapped by end user function ohRangeRetrieveError().
        */
        const std::string errorMessage() const { return errorMessage_; }
        //@}

    private:
        static void initializeRegexes();
        bool initStandard();
        bool initSpecial();

        std::string address_;
        std::string bookName_;
        std::string sheetName_;
        bool multicell_;
        int rowStartNum_;
        int colStartNum_;
        int rowEndNum_;
        int colEndNum_;
        std::string errorMessage_;
        static boost::regex regexStandard_;
        static boost::regex regexSpecial_;
        static bool regexesInitialized_;
    };

    std::ostream &operator<<(std::ostream&, const RangeReference&);

}

ext: hpp


text:
#include "MatrixMultiply.hpp"

#include <exception>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <numeric>

scottgs::MatrixMultiply::MatrixMultiply()
{
	;
}

scottgs::MatrixMultiply::~MatrixMultiply()
{
	;
}

scottgs::FloatMatrix scottgs::MatrixMultiply::operator()(const scottgs::FloatMatrix& lhs, const scottgs::FloatMatrix& rhs) const
{
	// Verify acceptable dimensions
	if (lhs.size2() != rhs.size1())
		throw std::logic_error("matrix incompatible lhs.size2() != rhs.size1()");

	scottgs::FloatMatrix result(lhs.size1(),rhs.size2());

	// YOUR ALGORIHM WITH COMMENTS GOES HERE:

	/*
		##### Method 3 #####
        Based on Method 2 store the sizes into variables
    */

	int r = lhs.size1();
	int c = rhs.size2();
	int size = lhs.size2();	// get the size for multiplication
	scottgs::FloatMatrix rhs_trans = boost::numeric::ublas::trans(rhs);

	for (int i = 0; i < r*c; i++) {
		float val = 0;
		for (int s = 0; s < size; s++) {
			val += (lhs.data()[(i/c)*size + s] * rhs_trans.data()[(i%c)*size + s]);
		}
		result.data()[i] = val;
	}

	/*
		##### Method 2 #####
        Transposed right hand side matrix, and using data() to access values
    */
	// scottgs::FloatMatrix rhs_trans = boost::numeric::ublas::trans(rhs);

	// for (int i = 0; i < lhs.size1()*rhs.size2(); i++) {
	// 	float val = 0;
	// 	for (int s = 0; s < lhs.size2(); s++) {
	// 		val += (lhs.data()[(i/rhs.size2())*lhs.size2() + s] * rhs_trans.data()[(i%rhs.size2())*lhs.size2() + s]);
	// 	}
	// 	result.data()[i] = val;
	// }

	/*
		##### Method 1 #####
        Use simple three nested loop to implement
    */

	// for (int r = 0; r < result.size1(); r++) {
	// 	for (int c = 0; c < result.size2(); c ++) {
	// 		float val {0};

	// 		// Start to compute
	// 		for (int s = 0; s < lhs.size2(); s++) {
	// 			val += (lhs(r, s) * rhs(s, c));
	// 		}
	// 		result(r, c) = val;
	// 	}
	// }

	return result;
}

scottgs::FloatMatrix scottgs::MatrixMultiply::multiply(const scottgs::FloatMatrix& lhs, const scottgs::FloatMatrix& rhs) const
{
	// Verify acceptable dimensions
	if (lhs.size2() != rhs.size1())
		throw std::logic_error("matrix incompatible lhs.size2() != rhs.size1()");

	return boost::numeric::ublas::prod(lhs,rhs);
}


text:
/**
 * Copyright (c) 2017 Melown Technologies SE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * *  Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef vtslibs_vts_metatile_hpp
#define vtslibs_vts_metatile_hpp

#include <memory>
#include <cstdint>
#include <iosfwd>
#include <vector>
#include <new>
#include <limits>

#include <boost/optional.hpp>
#include <boost/filesystem/path.hpp>

#include "math/geometry_core.hpp"
#include "half/half.hpp"

#include "../storage/error.hpp"
#include "../storage/credits.hpp"
#include "../storage/range.hpp"

#include "basetypes.hpp"
#include "tileop.hpp"
#include "geomextents.hpp"

typedef half_float::half hfloat;

namespace vtslibs { namespace vts {

struct MetaNode {
    struct Flag {
        typedef std::uint16_t value_type;
        enum : value_type {
            geometryPresent = 0x01
            , navtilePresent = 0x02
            , applyTexelSize = 0x04
            , applyDisplaySize = 0x08

            , ulChild = 0x10
            , urChild = 0x20
            , llChild = 0x40
            , lrChild = 0x80

            , alien = 0x100

            , allChildren = (ulChild | urChild | llChild | lrChild)
            , nonChildren = value_type(~allChildren)
            , none = 0x00

            // tile is real if it contains geometry
            , real = geometryPresent
        };
    };

    bool real() const { return check(Flag::real); }

    bool real(bool alien) const {
        if (alien) {
            return check(Flag::real | Flag::alien
                         , Flag::real | Flag::alien);
        }
        return check(Flag::real | Flag::alien, Flag::real);
    }

    bool geometry() const { return check(Flag::geometryPresent); }
    MetaNode& geometry(bool value) {
        return set(Flag::geometryPresent, value);
    }

    bool navtile() const { return check(Flag::navtilePresent); }
    MetaNode& navtile(bool value) {
        return set(Flag::navtilePresent, value);
    }

    bool applyTexelSize() const { return check(Flag::applyTexelSize); }
    MetaNode& applyTexelSize(bool value) {
        return set(Flag::applyTexelSize, value);
    }

    bool applyDisplaySize() const { return check(Flag::applyDisplaySize); }
    MetaNode& applyDisplaySize(bool value) {
        return set(Flag::applyDisplaySize, value);
    }

    bool ulChild() const { return check(Flag::ulChild); }
    MetaNode& ulChild(bool value) { return set(Flag::ulChild, value); }

    bool urChild() const { return check(Flag::urChild); }
    MetaNode& urChild(bool value) { return set(Flag::urChild, value); }

    bool llChild() const { return check(Flag::llChild); }
    MetaNode& llChild(bool value) { return set(Flag::llChild, value); }

    bool lrlChild() const { return check(Flag::lrChild); }
    MetaNode& lrChild(bool value) { return set(Flag::lrChild, value); }

    bool alien() const { return check(Flag::alien); }
    MetaNode& alien(bool value) {
        return set(Flag::alien, value);
    }

    void update(Flag::value_type flags) { flags_ |= flags; }

    void reset(Flag::value_type flags) { flags_ &= ~flags; }

    math::Extents3 extents;
    GeomExtents geomExtents;

    float texelSize;

    std::uint16_t displaySize;

    Range<std::int16_t> heightRange;

    typedef std::uint16_t SourceReference;

    SourceReference sourceReference;

    MetaNode()
        : texelSize(), displaySize(), heightRange(), sourceReference()
        , flags_(), internalTextureCount_()
    {}

    Flag::value_type flags() const { return flags_; }
    void flags(Flag::value_type flags) { flags_ = flags; }

    Flag::value_type childFlags() const { return flags_ & Flag::allChildren; }
    void childFlags(Flag::value_type flags) {
        flags_ = (flags_ & Flag::nonChildren) | (flags & Flag::allChildren);
    }

    Flag::value_type nonChildFlags() const {
        return flags_ & Flag::nonChildren;
    }
    void nonChildFlags(Flag::value_type flags) {
        flags_ = (flags_ & Flag::allChildren) | (flags & Flag::nonChildren);
    }

    void update(const MetaNode &other);

    /** Sets/unsets child flag based on LSB of tileId.
     */
    MetaNode& setChildFromId(const TileId &tileId, bool value = true);

    /** Sets/unsets child flag based on LSB of tileId in external flags.
     */
    static void setChildFromId(Flag::value_type &flags, const TileId &tileId
                               , bool value = true);

    /** Merge-in child flags. Combines current and new flags.
     */
    void mergeChildFlags(Flag::value_type cf);

    MetaNode& mergeExtents(const MetaNode &other);
    MetaNode& mergeExtents(const math::Extents3 &other);
    MetaNode& mergeExtents(const GeomExtents &other);

    unsigned int internalTextureCount() const { return internalTextureCount_; }
    void internalTextureCount(unsigned int value) {
        const unsigned int max(std::numeric_limits<std::uint8_t>::max());
        if (value > max) {
            internalTextureCount_ = max;
        } else {
            internalTextureCount_ = value;
        }
    }

    const storage::CreditIds& credits() const {  return credits_; }

    template <typename CreditIdsType>
    void updateCredits(const CreditIdsType &credits) {
        credits_.insert(credits.begin(), credits.end());
    }

    template <typename CreditIdType>
    void addCredit(const CreditIdType &creditId) {
        credits_.insert(creditId);
    }

    template <typename CreditIdsType>
    void setCredits(const CreditIdsType &credits) {
        credits_.clear();
        credits_.insert(credits.begin(), credits.end());
    }

    enum class BackingType { none, uint8, uint16 };

    struct StoreParams {
        Lod lod;
        BackingType sourceReference;

        StoreParams(Lod lod, BackingType sourceReference)
            : lod(lod), sourceReference(sourceReference) {}
    };

    void load(std::istream &in, const StoreParams &sp
              , std::uint16_t version);
    void save(std::ostream &out, const StoreParams &sp) const;

private:
    bool check(Flag::value_type flag) const { return flags_ & flag; }
    bool check(Flag::value_type flag, Flag::value_type value) const {
        return (flags_ & flag) == value;
    }

    MetaNode& set(Flag::value_type flag, bool value) {
        if (value) {
            flags_ |= flag;
        } else {
            flags_ &= ~flag;
        }
        return *this;
    }

    Flag::value_type flags_;

    storage::CreditIds credits_;

    std::uint8_t internalTextureCount_;
};

class MetaTile {
public:
    typedef std::vector<MetaTile> list;
    typedef std::shared_ptr<MetaTile> pointer;

    typedef std::uint32_t size_type;
    typedef math::Point2_<size_type> point_type;
    typedef math::Size2_<size_type> size2_type;
    typedef math::Extents2_<size_type> extents_type;

    MetaTile(const TileId &origin, std::uint8_t binaryOrder)
        : origin_(origin), binaryOrder_(binaryOrder)
        , size_(1 << binaryOrder)
        , grid_(size_ * size_, MetaNode())
        , valid_(math::InvalidExtents{})
    {}

    const MetaNode* set(const TileId &tileId, const MetaNode &node);

    const MetaNode* get(const TileId &tileId, std::nothrow_t) const;
    const MetaNode& get(const TileId &tileId) const;

    void update(const TileId &tileId, const MetaNode &mn);

    void save(std::ostream &out) const;

    void load(std::istream &in
              , const boost::filesystem::path &path = "unknown");

    const TileId& origin() const { return origin_; }

    const size_type& size() const { return size_; }

    extents_type validExtents() const;

    /** Runs given function for every real tile.
     */
    template <typename F> void for_each(F f) const;

    /** Runs given function for every real tile.
     */
    template <typename F> void for_each(F f);

    typedef std::vector<int> Indices;

    /** Updates this metatile with data from input metatiles while resolving
     *  references.
     *
     *  Existing real nodes are not touched except updating geometry extents
     *  from virtual nodes.
     *
     *  NB: child flags are not copied, it is up to the user to obtain values
     *  from another source.
     *
     *  Flag alien:
     *     false: take only non-alien nodes into account
     *     true: take only alien nodes into account
     *
     * \param in input metatile
     * \param alien marks processing of regular or alien nodes
     */
    void update(const MetaTile &in, bool alien = false);

    /** Sets expected reference in metanode at tileId.
     */
    void expectReference(const TileId &tileId
                         , MetaNode::SourceReference sourceReference);

    /** Update this metatile with another metatile honoring references.
     *
     *  NB: child flags are merged (union) and alien flag is always cleared.
     *
     * \param sourceReference update metatile's source reference
     * \param in update metatile
     */
    void update(MetaNode::SourceReference sourceReference, const MetaTile &in);

    bool empty() const { return !math::valid(valid_); }

    /** Current metatile version.
     */
    static int currentVersion();

    static int loadVersion(std::istream &in
                           , const boost::filesystem::path &path = "unknown");

protected:
    size_type index(const TileId &tileId, bool checkValidity = true) const;

    boost::optional<size_type>
    index(const TileId &tileId, std::nothrow_t, bool checkValidity = true)
        const;

    boost::optional<point_type>
    gridIndex(const TileId &tileId, std::nothrow_t, bool checkValidity = true)
        const;

    point_type gridIndex(const TileId &tileId, bool checkValidity = true)
        const;

    size_type index(const point_type &gi) const;

    /** Metatile ID, origin of first node in the metatile.
     */
    TileId origin_;

    std::uint8_t binaryOrder_;

    size_type size_;

    /** Contains (1 << binaryOrder_) * (1 << binaryOrder_) meta nodes
     */
    std::vector<MetaNode> grid_;

    /** Extents of valid area.
     */
    extents_type valid_;
};

void saveMetaTile(const boost::filesystem::path &path
                  , const MetaTile &meta);

MetaTile loadMetaTile(const boost::filesystem::path &path
                      , std::uint8_t binaryOrder);

MetaTile loadMetaTile(std::istream &in, std::uint8_t binaryOrder
                      , const boost::filesystem::path &path = "unknown");

MetaTile::pointer loadMetaTile(const boost::filesystem::path *path
                               , std::uint8_t binaryOrder);

MetaTile::pointer loadMetaTile(std::istream *in
                               , std::uint8_t binaryOrder
                               , const boost::filesystem::path
                               &path = "unknown");

std::vector<TileId> children(const MetaNode &node
                             , const TileId &tileId);

void loadCreditsFromMetaTile(std::istream &in, registry::IdSet &credits
                             , const boost::filesystem::path
                             &path = "unknown");

typedef std::pair<double, std::size_t> TexelSizeAggregator;

double average(const TexelSizeAggregator &aa);

void add(TexelSizeAggregator &aa, const MetaNode &node);

void add(TexelSizeAggregator &aa, const MetaNode &node
         , const MetaNode &oldNode);

// inlines

inline MetaTile::size_type MetaTile::index(const math::Point2_<size_type> &gi)
    const
{
    return gi(1) * size_ + gi(0);
}

inline boost::optional<MetaTile::size_type>
MetaTile::index(const TileId &tileId, std::nothrow_t
                , bool checkValidity) const
{
    if (auto gi = gridIndex(tileId, std::nothrow, checkValidity)) {
        return index(*gi);
    }
    return boost::none;
}

inline MetaTile::size_type MetaTile::index(const TileId &tileId
                                           , bool checkValidity) const
{
    return index(gridIndex(tileId, checkValidity));
}

inline const MetaNode* MetaTile::get(const TileId &tileId, std::nothrow_t)
    const
{
    if (auto i = index(tileId, std::nothrow)) {
        return &grid_[*i];
    }
    return nullptr;
}

inline const MetaNode& MetaTile::get(const TileId &tileId)
    const
{
    return grid_[index(tileId)];
}

template <typename F>
inline void MetaTile::for_each(F f)
{
    for (auto j(valid_.ll(1)); j <= valid_.ur(1); ++j) {
        for (auto i(valid_.ll(0)); i <= valid_.ur(0); ++i) {
            auto &node(grid_[j * size_ + i]);
            f(TileId(origin_.lod, origin_.x + i, origin_.y + j), node);
        }
    }
}

template <typename F>
inline void MetaTile::for_each(F f) const
{
    for (auto j(valid_.ll(1)); j <= valid_.ur(1); ++j) {
        for (auto i(valid_.ll(0)); i <= valid_.ur(0); ++i) {
            const auto &node(grid_[j * size_ + i]);
            f(TileId(origin_.lod, origin_.x + i, origin_.y + j), node);
        }
    }
}

inline std::vector<TileId> children(const MetaNode &node
                                    , const TileId &tileId)
{
    std::vector<TileId> c;
    std::uint8_t mask(MetaNode::Flag::ulChild);
    for (const auto &child : vts::children(tileId)) {
        if (mask & node.flags()) {
            c.push_back(child);
        }
        mask <<= 1;
    }
    return c;
}

inline double average(const TexelSizeAggregator &aa) {
    if (!aa.second) { return 0.0; }
    return aa.first / aa.second;
}

inline void add(TexelSizeAggregator &aa, const MetaNode &node) {
    if (node.applyTexelSize()) {
        aa.first += node.texelSize;
        ++aa.second;
    }
}

inline void add(TexelSizeAggregator &aa, const MetaNode &node
                , const MetaNode &oldNode)
{
    // remove old node first
    if (oldNode.applyTexelSize()) {
        aa.first -= oldNode.texelSize;
        --aa.second;
    }

    // and add this node
    add(aa, node);
}

} } // namespace vtslibs::vts

#endif // vtslibs_vts_metatile_hpp

max_stars_repo_name: HanochZhu/vts-browser-unity-plugin

max_issues_repo_name: HanochZhu/vts-browser-unity-plugin

max_forks_repo_name: HanochZhu/vts-browser-unity-plugin


text:
#include <NTL/pair_lzz_pX_long.h>

#include <NTL/new.h>

NTL_START_IMPL

NTL_pair_impl(zz_pX,long,pair_zz_pX_long)
NTL_pair_io_impl(zz_pX,long,pair_zz_pX_long)
NTL_pair_eq_impl(zz_pX,long,pair_zz_pX_long)

NTL_vector_impl(pair_zz_pX_long,vec_pair_zz_pX_long)
NTL_io_vector_impl(pair_zz_pX_long,vec_pair_zz_pX_long)
NTL_eq_vector_impl(pair_zz_pX_long,vec_pair_zz_pX_long)

NTL_END_IMPL

max_stars_repo_name: vshesh/RUNEtag

max_issues_repo_name: vshesh/RUNEtag

max_forks_repo_name: vshesh/RUNEtag


text:
/*
 * Copyright Andrey Semashev 2020
 *
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or copy at
 * https://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file countl_zero.hpp
 *
 * This header defines \c countl_zero algorithm, which counts the number of consecutive
 * most significant zero bits in an integer.
 */

#ifndef BOOST_BIT_OPS_COUNTING_COUNTL_ZERO_HPP_INCLUDED_
#define BOOST_BIT_OPS_COUNTING_COUNTL_ZERO_HPP_INCLUDED_

#include <limits>
#include <boost/bit_ops/detail/config.hpp>
#include <boost/bit_ops/detail/int_sizes.hpp>
#include <boost/bit_ops/detail/type_traits/enable_if.hpp>
#include <boost/bit_ops/detail/type_traits/integral_constant.hpp>
#include <boost/bit_ops/detail/type_traits/is_integral.hpp>
#include <boost/bit_ops/detail/type_traits/is_unsigned.hpp>

#if defined(__GNUC__)
#if defined(BOOST_BIT_OPS_DETAIL_HAS_LZCNT)
#include <x86intrin.h>
#endif
#elif defined(_MSC_VER)
#include <intrin.h>
#endif

namespace boost {
namespace bit_ops {

namespace detail {

#if defined(BOOST_BIT_OPS_DETAIL_HAS_BUILTIN_CLZ)

template< typename T, unsigned int N >
inline typename bit_ops::detail::enable_if< N <= BOOST_BIT_OPS_DETAIL_SIZEOF_INT, unsigned int >::type countl_zero_nz(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
    return static_cast< unsigned int >(__builtin_clz(value) - (std::numeric_limits< unsigned int >::digits - std::numeric_limits< T >::digits));
}

#if BOOST_BIT_OPS_DETAIL_SIZEOF_LONG > BOOST_BIT_OPS_DETAIL_SIZEOF_INT

template< typename T, unsigned int N >
inline typename bit_ops::detail::enable_if< N == BOOST_BIT_OPS_DETAIL_SIZEOF_LONG, unsigned int >::type countl_zero_nz(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
    return static_cast< unsigned int >(__builtin_clzl(value));
}

#endif // BOOST_BIT_OPS_DETAIL_SIZEOF_LONG > BOOST_BIT_OPS_DETAIL_SIZEOF_INT

#if BOOST_BIT_OPS_DETAIL_SIZEOF_LLONG > BOOST_BIT_OPS_DETAIL_SIZEOF_LONG

template< typename T, unsigned int N >
inline typename bit_ops::detail::enable_if< N == BOOST_BIT_OPS_DETAIL_SIZEOF_LLONG, unsigned int >::type countl_zero_nz(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
    return static_cast< unsigned int >(__builtin_clzll(value));
}

#endif // BOOST_BIT_OPS_DETAIL_SIZEOF_LLONG > BOOST_BIT_OPS_DETAIL_SIZEOF_LONG

#elif defined(BOOST_BIT_OPS_DETAIL_HAS_BIT_SCAN_REVERSE)

template< typename T, unsigned int N >
inline typename bit_ops::detail::enable_if< N <= BOOST_BIT_OPS_DETAIL_SIZEOF_LONG, unsigned int >::type countl_zero_nz(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
    unsigned long pos;
    _BitScanReverse(&pos, value);
    return static_cast< unsigned int >((std::numeric_limits< T >::digits - 1u) - pos);
}

#if BOOST_BIT_OPS_DETAIL_SIZEOF_LLONG > BOOST_BIT_OPS_DETAIL_SIZEOF_LONG

template< typename T, unsigned int N >
inline typename bit_ops::detail::enable_if< N == BOOST_BIT_OPS_DETAIL_SIZEOF_LLONG, unsigned int >::type countl_zero_nz(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
#if defined(_M_AMD64) || defined(_M_ARM64)
    unsigned long pos;
    _BitScanReverse64(&pos, value);
    return static_cast< unsigned int >((std::numeric_limits< T >::digits - 1u) - pos);
#else
    unsigned long upper_pos = 31u;
    unsigned long pos;
    if (!_BitScanReverse(&pos, static_cast< unsigned int >(value >> 32u)))
    {
        _BitScanReverse(&pos, static_cast< unsigned int >(value));
        upper_pos = std::numeric_limits< T >::digits - 1u;
    }
    return static_cast< unsigned int >(upper_pos - pos);
#endif
}

#endif // BOOST_BIT_OPS_DETAIL_SIZEOF_LLONG > BOOST_BIT_OPS_DETAIL_SIZEOF_LONG

#else

template< typename T, unsigned int N >
inline unsigned int countl_zero_nz(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
    unsigned int count = 0u;
    unsigned int digits = std::numeric_limits< T >::digits / 2u;
    T mask = ~((static_cast< T >(1u) << digits) - 1u);
    for (; digits > 0u; digits >>= 1u, mask <<= digits)
    {
        if ((value & mask) == 0u)
        {
            count += digits;
            value <<= digits;
        }
    }

    return count;
}

#endif

#if defined(BOOST_BIT_OPS_DETAIL_HAS_LZCNT)

template< typename T, unsigned int N >
inline typename bit_ops::detail::enable_if< N <= 2u, unsigned int >::type countl_zero(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
    return static_cast< unsigned int >(__lzcnt16(value) - (16u - std::numeric_limits< T >::digits));
}

template< typename T, unsigned int N >
inline typename bit_ops::detail::enable_if< N == 4u, unsigned int >::type countl_zero(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
    return static_cast< unsigned int >(__lzcnt(value));
}

template< typename T, unsigned int N >
inline typename bit_ops::detail::enable_if< N == 8u, unsigned int >::type countl_zero(T value, bit_ops::detail::integral_constant< unsigned int, N >) BOOST_NOEXCEPT
{
#if defined(__x86_64__) || defined(_M_AMD64)
    return static_cast< unsigned int >(__lzcnt64(value));
#else
    unsigned int count = static_cast< unsigned int >(__lzcnt(static_cast< unsigned int >(value >> 32u)));
    if (count >= 32u)
        count += static_cast< unsigned int >(__lzcnt(static_cast< unsigned int >(value)));
    return count;
#endif
}

#endif // defined(BOOST_BIT_OPS_DETAIL_HAS_LZCNT)

} // namespace detail

/*!
 * \brief Returns the number of consecutive most significant zero bits in \a value
 *
 * \pre \a value must not be zero
 */
template< typename T >
inline typename bit_ops::detail::enable_if<
    bit_ops::detail::is_integral< T >::value && bit_ops::detail::is_unsigned< T >::value,
    unsigned int
>::type countl_zero_nz(T value) BOOST_NOEXCEPT
{
    return bit_ops::detail::countl_zero_nz(value, bit_ops::detail::integral_constant< unsigned int, sizeof(T) >());
}

//! Returns the number of consecutive most significant zero bits in \a value
template< typename T >
inline typename bit_ops::detail::enable_if<
    bit_ops::detail::is_integral< T >::value && bit_ops::detail::is_unsigned< T >::value,
    unsigned int
>::type countl_zero(T value) BOOST_NOEXCEPT
{
#if defined(BOOST_BIT_OPS_DETAIL_HAS_LZCNT)
    return bit_ops::detail::countl_zero(value, bit_ops::detail::integral_constant< unsigned int, sizeof(T) >());
#else
    return value == 0u ? static_cast< unsigned int >(std::numeric_limits< T >::digits) : bit_ops::countl_zero_nz(value);
#endif
}

} // namespace bit_ops
} // namespace boost

#endif // BOOST_BIT_OPS_COUNTING_COUNTL_ZERO_HPP_INCLUDED_


text:
//
// The MIT License(MIT)
//
// Copyright(c) 2014 Demonsaw LLC
//
// 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.

#include <boost/format.hpp>

#include "command/download_command.h"

#include "component/endpoint_component.h"
#include "component/callback/callback_action.h"
#include "component/callback/callback_type.h"
#include "component/client/client_io_component.h"
#include "component/client/client_network_component.h"
#include "component/client/client_service_component.h"
#include "component/io/download_component.h"
#include "component/io/file_component.h"
#include "component/io/transfer_component.h"
#include "component/io/upload_component.h"
#include "component/group/group_component.h"
#include "component/status/status_component.h"
#include "component/time/timeout_component.h"
#include "component/time/timer_component.h"
#include "component/transfer/transfer_service_component.h"

#include "data/data_packer.h"
#include "data/data_unpacker.h"
#include "data/transfer_data.h"

#include "entity/entity.h"
#include "entity/entity_factory.h"
#include "message/message_packer.h"
#include "message/message_unpacker.h"
#include "message/request/request_message.h"
#include "message/response/response_message.h"
#include "security/security.h"
#include "utility/value.h"

namespace eja
{
	// Client
	void client_download_command::stop(const entity::ptr entity, const eja::status value, const bool stop /*= true*/)
	{
		bool done = true;
		const auto transfer = entity->get<transfer_component>();
		const auto download_multimap = m_entity->get<download_multimap_component>();
		{
			thread_lock(download_multimap);
			const auto range = download_multimap->equal_range(entity->get_id());
			auto it = range.first;

			if (it != download_multimap->end())
			{
				download_multimap->erase(it++);

				if (it != range.second)
				{
					// Transfer
					if (transfer->valid())
						transfer->sub_shards(1);
				}
				else
				{
					const auto download_map = m_entity->get<download_map_component>();
					{
						thread_lock(download_map);
						download_map->erase(entity->get_id());
					}

					// Transfer
					if (stop)
						transfer->stop();
					else if (transfer->valid())
						transfer->sub_shards(1);

					// Status
					const auto status = entity->get<status_component>();
					status->set_status(value);

					// Callback
					const auto e = entity_factory::create_statusbar(statusbar::download);
					m_entity->call(callback_type::status, callback_action::remove, e);
				}
			}
		}
	}

	download_request_message::ptr client_download_command::execute(const entity::ptr router, const entity::ptr entity)
	{
		// Verify
		if (unlikely(!entity->has_id()))
			return nullptr;

		// Index
		const auto service = m_entity->get<client_service_component>();
		const auto transfer_list = service->get_transfer_list();
		if (transfer_list->empty())
			return nullptr;

		const auto transfer_index = find_index(*transfer_list, router);
		if (transfer_index == npos)
			return nullptr;

		// Request
		const auto request = download_request_message::create();
		request->set_id(entity->get_id());

		// Chunks
		const auto transfer = entity->get<transfer_component>();
		if (transfer->valid())
		{
			// Timeout
			const auto timeout = entity->get<timeout_component>();
			const auto network = m_entity->get<client_network_component>();

			if (!timeout->expired(network->get_timeout()))
			{
				// Chunks
				std::vector<u32> chunks;
				const auto download_array = entity->get<download_index_array_component>();
				{
					thread_lock(download_array);

					if (!download_array->empty())
					{
						// 1) SPEED OPTIMIZATION: Send as large a window as possible to minimize uploader waits
						// But... this wastes network bandwidth :/
						const auto window = std::min(network->get_window(), download_array->size());

						// 2) BANDIWDTH OPTIMIZATION: Only send a window of chunks
						// But.. this makes transfer much slower (50% the speed) :/
						//const auto window = clamp(network::min_window, download_array->size() / transfer_list->size(), network->get_window());
						chunks.reserve(window);

						auto chunk_index = (transfer_index * (download_array->size() / transfer_list->size()));
						size_t chunk_end = chunk_index + window;

						if (chunk_end < download_array->size())
						{
							chunks.insert(chunks.end(), download_array->cbegin() + chunk_index, download_array->cbegin() + chunk_end);
						}
						else
						{
							chunks.insert(chunks.end(), download_array->cbegin() + chunk_index, download_array->cend());

							chunk_end -= download_array->size();
							if (chunk_end <= chunk_index)
								chunks.insert(chunks.end(), download_array->cbegin(), download_array->cbegin() + chunk_end);
						}

						// DEBUG
						assert(!chunks.empty());
					}
				}

				request->set_chunks(chunks);
			}
			else
			{
				// Status
				const auto status = entity->get<status_component>();
				status->set_status(eja::status::cancelled);
			}
		}
		else
		{
			const auto value = transfer->complete() ? eja::status::success : eja::status::cancelled;
			stop(entity, value, true);
		}

		return request;
	}

	void client_download_command::execute(const entity::ptr router, const download_response_message::ptr response)
	{
		// Verify
		if (unlikely(!response->has_id()))
			return;

		// Entity
		entity::ptr entity;
		const auto download_map = m_entity->get<download_map_component>();
		{
			thread_lock(download_map);
			const auto it = download_map->find(response->get_id());
			if (it == download_map->cend())
				return;

			entity = it->second;
		}

		// Status
		const auto status = entity->get<status_component>();
		const auto transfer = entity->get<transfer_component>();

		if (!response->has_status())
		{
			const auto value = transfer->complete() ? eja::status::success : eja::status::cancelled;
			stop(entity, value, true);

			return;
		}

		// Data
		if (!response->has_data())
		{
			// Status
			if (!transfer->empty())
			{
				const auto timeout = entity->get<timeout_component>();
				status->set_status(!timeout->expired(milliseconds::progress) ? eja::status::success : eja::status::pending);
			}
			else
			{
				status->set_status(eja::status::pending);
			}

			const auto service = router->get<transfer_service_component>();
			service->wait(milliseconds::download, [service, entity]() { service->async_download(entity); });

			return;
		}

		// Unpack
		const auto unpacker = get_data_unpacker(response);

		for (const auto& data : *unpacker)
		{
			switch (data->get_type())
			{
				case data_type::transfer:
				{
					const auto response_data = std::static_pointer_cast<transfer_data>(data);

					// Chunks
					auto index = response_data->get_index();
					const auto download_array = entity->get<download_index_array_component>();
					{
						thread_lock(download_array);
						const auto it = std::find(download_array->begin(), download_array->end(), index);
						if (it == download_array->cend())
						{
							const auto service = router->get<transfer_service_component>();
							service->async_download(entity);
							continue;
						}

						download_array->erase(it);
					}

					// File
					const u64 offset = index * transfer->get_chunk();
					const auto timeout = entity->get<timeout_component>();
					const auto network = m_entity->get<client_network_component>();

					const auto file = entity->get<file_component>();
					const auto& file_data = response_data->get_data();
					auto bytes = file->write(file_data.data(), file_data.size(), offset);

					// Try up to 10 times, then abort
					// TODO: Perhaps queue up and retry later (inefficient to re-download bytes)
					//
					for (auto i = 0; !bytes && (i < 10); ++i)
					{
						// Status
						status->set_status(eja::status::warning);

						// Log
						const auto parent = router->get_parent();
						const auto str = boost::str(boost::format("Unable to write to file: %s") % file->get_name());
						parent->log(str);

						// Sleep
						std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds::file));

						// Retry
						bytes = file->write(file_data.data(), file_data.size(), offset);
					}

					if (bytes)
					{
						// Status
						status->set_status(eja::status::success);

						// Transfer
						transfer->add_size(static_cast<u32>(file_data.size()));

						// Timeout
						timeout->update();

						// Next
						const auto service = router->get<transfer_service_component>();
						service->async_download(entity);
					}
					else
					{
						thread_lock(download_array);
						download_array->push_front(index);
					}

					break;
				}
				default:
				{
					assert(false);
				}
			}
		}
	}

	// Router
	download_response_message::ptr router_download_command::execute(const entity::ptr client, const download_request_message::ptr request)
	{
		// Verify
		if (unlikely(!request->has_id()))
			return nullptr;

		// Response
		const auto response = download_response_message::create();
		response->set_id(request->get_id());

		// Entity
		entity::ptr entity;
		const auto download_map = m_entity->get<download_map_component>();
		{
			thread_lock(download_map);
			const auto it = download_map->find(request->get_id());
			if (it == download_map->cend())
			{
				entity = entity_factory::create_transfer_download(m_entity);
				entity->set_id(request->get_id());

				const auto pair = std::make_pair(request->get_id(), entity);
				download_map->insert(pair);

				// File
				const auto file = entity->get<file_component>();
				file->set_id(request->get_id());

				// Callback
				m_entity->call(callback_type::download, callback_action::add, entity);
			}
			else
			{
				entity = it->second;
			}
		}

		// Done/Timeout
		const auto timeout = entity->get<timeout_component>();

		if (!request->has_chunks() || timeout->expired(milliseconds::transfer))
		{
			const auto download_map = m_entity->get<download_map_component>();
			{
				thread_lock(download_map);
				download_map->erase(request->get_id());

				// Callback
				m_entity->call(callback_type::download, callback_action::remove, entity);
			}

			return response;
		}

		// Chunks
		const auto& chunks = request->get_chunks();
		std::list<u32> chunk_list(chunks.begin(), chunks.end());

		// Uploaded?
		{
			const auto upload_list = entity->get<upload_data_list_component>();
			thread_lock(upload_list);

			for (auto it = upload_list->begin(); it != upload_list->end(); )
			{
				const auto& item = *it;
				const auto index = item->index;

				const auto it2 = std::find(chunk_list.begin(), chunk_list.end(), index);
				if (it2 != chunk_list.end())
				{
					chunk_list.erase(it2);
					++it;
				}
				else
				{
					upload_list->sub_buffer(item->data.size());
					it = upload_list->erase(it);
				}
			}

			if (!upload_list->empty())
			{
				// Data
				auto& item = upload_list->front();
				upload_list->sub_buffer(item->data.size());

				response->set_data(std::move(item->data));
				upload_list->pop_front();

				// Timer
				timeout->update();
			}
		}

		// Downloaded?
		{
			const auto download_list = entity->get<download_index_list_component>();
			thread_lock(download_list);

			for (auto it = download_list->begin(); it != download_list->end(); )
			{
				const auto index = *it;

				const auto it2 = std::find(chunk_list.begin(), chunk_list.end(), index);
				if (it2 != chunk_list.end())
				{
					chunk_list.erase(it2);
					++it;
				}
				else
				{
					it = download_list->erase(it);
				}
			}

			// New chunks
			std::copy(chunk_list.begin(), chunk_list.end(), std::back_inserter(*download_list));
		}

		// Status
		response->set_success();

		return response;
	}
}

max_stars_repo_name: demonsaw/Code

max_issues_repo_name: demonsaw/Code

max_forks_repo_name: demonsaw/Code


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

#include "AsyncTaskGroup.h"
#include "AsyncTaskBase.h"
#include "Exception.h"

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

#include <vector>

using namespace std;
using namespace boost;
using namespace boost::posix_time;

namespace apl
{

AsyncTaskScheduler::AsyncTaskScheduler(ITimerSource* apTimerSrc, ITimeSource* apTimeSrc) :
	mpTimerSrc(apTimerSrc),
	mpTimeSrc(apTimeSrc)
{

}

AsyncTaskScheduler::~AsyncTaskScheduler()
{
	BOOST_FOREACH(AsyncTaskGroup * p, mGroupSet) {
		delete p;
	}
}

AsyncTaskGroup* AsyncTaskScheduler::CreateNewGroup()
{
	CriticalSection cs(&mLock);
	AsyncTaskGroup* pGroup = new AsyncTaskGroup(mpTimerSrc, mpTimeSrc);
	mGroupSet.insert(pGroup);
	return pGroup;
}

void AsyncTaskScheduler::ReleaseGroup(AsyncTaskGroup* apGroup)
{
	CriticalSection cs(&mLock);
	GroupSet::iterator i = mGroupSet.find(apGroup);
	if( i != mGroupSet.end() ) {
		delete *i;
		mGroupSet.erase(i);
	} else throw ArgumentException(LOCATION, "Group not associated with this scheduler");
}

} //end ns


text:
/*=============================================================================
    Copyright (c) 2016 Paul Fultz II
    using.hpp
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/

#ifndef BOOST_HOF_GUARD_USING_HPP
#define BOOST_HOF_GUARD_USING_HPP

#include <boost/hof/config.hpp>

#if BOOST_HOF_HAS_TEMPLATE_ALIAS
#define BOOST_HOF_USING(name, ...) using name = __VA_ARGS__
#define BOOST_HOF_USING_TYPENAME(name, ...) using name = typename __VA_ARGS__
#else
#define BOOST_HOF_USING(name, ...) struct name : std::enable_if<true, __VA_ARGS__>::type {}
#define BOOST_HOF_USING_TYPENAME(name, ...) struct name : __VA_ARGS__ {}
#endif

#endif


text:
/*
 * Copyright 2012 CarCV Development Team
 *
 * 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.
 */

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>

#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>

#include <iostream>
#include <fstream>
#include <cstdlib>

#include "ocr_train.hpp"
#include "ocr_recognizer.hpp"

using namespace cv;
using namespace std;

namespace fs = boost::filesystem;

int main() {

	//1. training

	string samples_str = "samples";
	string responses_str = "responses";
	vector<float> responses = loadArray< vector<float> >(responses_str);
	vector< vector<float> > samples = load2DArray<float>(samples_str);

	cout << "Samples: " << samples.size() << endl;
	cout << "Responses: " << responses.size() << endl;

	//test: convert vector to Mat
	Mat_<float> samples_mat = vector2Mat2D(samples);
	Mat_<float> responses_mat = vector2Mat1D(responses);

	cout << "Samples_mat: " << samples_mat.size() << endl;
	cout << "Responses_mat: " << responses_mat.size() << endl;

	//train
        CvKNearest kn_model(samples_mat, responses_mat);

	//2. testing
	//Loads test image with numbers
	Mat img = imread("test.jpg");
	Mat img_original;
	img.copyTo(img_original);

	//Grayscale
	Mat gray;
	cvtColor(img, gray, CV_BGR2GRAY);

	//Builds a threshold making a binary image
	Mat thresh;
	adaptiveThreshold(gray, thresh, 255, 1, 1, 11, 2);

	//Output
	Mat out(img.size(), CV_32F, Scalar(0, 1));

	//Find contours
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;
	findContours(thresh, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

	double cntArea;
	Mat contourMat;
	for (vector< vector<Point> >::iterator it = contours.begin();
		 it != contours.end(); ++it ) {

		vector<Point> cnt = *it;
		cntArea = contourArea(cnt);

		if (cntArea<50) {
			continue;
		}

		Rect boundbox = boundingRect(cnt);
		int x = boundbox.x;
		int y = boundbox.y;
		int width = boundbox.width;
		int height = boundbox.height;

		if (height<25) { //If it isn't high enough
			continue;
		}

		Point px(x,y);
		Point py(x+width, y+height);
		Scalar color(0, 0, 255); //red

		img.copyTo(contourMat);
		rectangle(contourMat, px, py, color, 2); //draws a rectangle on top of img

		Mat roi;
		roi = thresh(boundbox); //todo could be reverse (x,y) (y,x), am not sure

		//resize it to 10x10
		Mat roismall;
		Size_<float> smallSize(100,1); //todo: make sure no data is getting lost
		resize(roi, roismall, smallSize);

		//convert to float:
		roismall.convertTo(roismall, CV_32F);

		//todo ""  roismall = roismall.reshape((1,100))
		//roismall = np.float32(roismall)

		Mat_<float> results, neighborResponses, dist;

		//cout << "Roismall_mat: " << roismall.size() << endl;

		float retval = kn_model.find_nearest(roismall, 1, results, neighborResponses, dist);
		float number_res = results.at<float>(0,0);

		string str_result = boost::lexical_cast<string>(number_res);

		Point start_point(x,y+height);
		putText(out, str_result, start_point, 0, 1, color);
	}

	namedWindow("img");
	namedWindow("out");
	imshow("img", img);
	imshow("out", out);

	waitKey(0);

	destroyAllWindows();
	return 0;

}

max_stars_repo_name: oskopek/carcv

max_issues_repo_name: oskopek/carcv

max_forks_repo_name: oskopek/carcv


text:
#define BOOST_TEST_MODULE SolutionTest

#include "solution.hpp"

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

BOOST_AUTO_TEST_SUITE(SolutionSuite)

BOOST_AUTO_TEST_CASE(PlainTest1)
{
    vector<int> gas{1,2,3,4,5};
    vector<int> cost{3,4,5,1,2};
    int results = Solution().canCompleteCircuit(gas, cost);

    int expected = 3;

    BOOST_CHECK_EQUAL(results, expected);
}

BOOST_AUTO_TEST_CASE(PlainTest2)
{
    vector<int> gas{3,1,1,3};
    vector<int> cost{2,2,2,2};
    int results = Solution().canCompleteCircuit(gas, cost);

    int expected = 3;

    BOOST_CHECK_EQUAL(results, expected);
}

BOOST_AUTO_TEST_CASE(PlainTest3)
{
    vector<int> gas{3,1,1,1};
    vector<int> cost{2,2,2,2};
    int results = Solution().canCompleteCircuit(gas, cost);

    int expected = -1;

    BOOST_CHECK_EQUAL(results, expected);
}

BOOST_AUTO_TEST_CASE(PlainTest4)
{
    vector<int> gas{2,3,4};
    vector<int> cost{3,4,3};
    int results = Solution().canCompleteCircuit(gas, cost);

    int expected = -1;

    BOOST_CHECK_EQUAL(results, expected);
}

BOOST_AUTO_TEST_CASE(PlainTest5)
{
    vector<int> gas{1,1,1,1};
    vector<int> cost{2,2,2,2};
    int results = Solution().canCompleteCircuit(gas, cost);

    int expected = -1;

    BOOST_CHECK_EQUAL(results, expected);
}

BOOST_AUTO_TEST_CASE(PlainTest6)
{
    vector<int> gas{4};
    vector<int> cost{5};
    int results = Solution().canCompleteCircuit(gas, cost);

    int expected = -1;

    BOOST_CHECK_EQUAL(results, expected);
}

BOOST_AUTO_TEST_CASE(PlainTest7)
{
    vector<int> gas{6};
    vector<int> cost{5};
    int results = Solution().canCompleteCircuit(gas, cost);

    int expected = 0;

    BOOST_CHECK_EQUAL(results, expected);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: johnhany/leetcode

max_issues_repo_name: johnhany/leetcode

max_forks_repo_name: johnhany/leetcode


text:
#include <nano/core_test/testutil.hpp>
#include <nano/node/testing.hpp>
#include <nano/node/transport/udp.hpp>

#include <gtest/gtest.h>

#include <boost/iostreams/stream_buffer.hpp>
#include <boost/thread.hpp>

using namespace std::chrono_literals;

TEST (network, tcp_connection)
{
	boost::asio::io_context io_ctx;
	boost::asio::ip::tcp::acceptor acceptor (io_ctx);
	auto port = nano::get_available_port ();
	boost::asio::ip::tcp::endpoint endpoint (boost::asio::ip::address_v4::any (), port);
	acceptor.open (endpoint.protocol ());
	acceptor.set_option (boost::asio::ip::tcp::acceptor::reuse_address (true));
	acceptor.bind (endpoint);
	acceptor.listen ();
	boost::asio::ip::tcp::socket incoming (io_ctx);
	std::atomic<bool> done1 (false);
	std::string message1;
	acceptor.async_accept (incoming,
	[&done1, &message1](boost::system::error_code const & ec_a) {
		   if (ec_a)
		   {
			   message1 = ec_a.message ();
			   std::cerr << message1;
		   }
		   done1 = true; });
	boost::asio::ip::tcp::socket connector (io_ctx);
	std::atomic<bool> done2 (false);
	std::string message2;
	connector.async_connect (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v4::loopback (), port),
	[&done2, &message2](boost::system::error_code const & ec_a) {
		if (ec_a)
		{
			message2 = ec_a.message ();
			std::cerr << message2;
		}
		done2 = true;
	});
	while (!done1 || !done2)
	{
		io_ctx.poll ();
	}
	ASSERT_EQ (0, message1.size ());
	ASSERT_EQ (0, message2.size ());
}

TEST (network, construction)
{
	auto port = nano::get_available_port ();
	nano::system system;
	system.add_node (nano::node_config (port, system.logging));
	ASSERT_EQ (1, system.nodes.size ());
	ASSERT_EQ (port, system.nodes[0]->network.endpoint ().port ());
}

TEST (network, self_discard)
{
	nano::system system (1);
	nano::message_buffer data;
	data.endpoint = system.nodes[0]->network.endpoint ();
	ASSERT_EQ (0, system.nodes[0]->stats.count (nano::stat::type::error, nano::stat::detail::bad_sender));
	system.nodes[0]->network.udp_channels.receive_action (&data);
	ASSERT_EQ (1, system.nodes[0]->stats.count (nano::stat::type::error, nano::stat::detail::bad_sender));
}

TEST (network, send_node_id_handshake)
{
	nano::system system (1);
	auto node0 (system.nodes[0]);
	ASSERT_EQ (0, node0->network.size ());
	auto node1 (std::make_shared<nano::node> (system.io_ctx, nano::get_available_port (), nano::unique_path (), system.alarm, system.logging, system.work));
	node1->start ();
	system.nodes.push_back (node1);
	auto initial (node0->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in));
	auto initial_node1 (node1->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in));
	auto channel (std::make_shared<nano::transport::channel_udp> (node0->network.udp_channels, node1->network.endpoint (), node1->network_params.protocol.protocol_version));
	node0->network.send_keepalive (channel);
	ASSERT_EQ (0, node0->network.size ());
	ASSERT_EQ (0, node1->network.size ());
	system.deadline_set (10s);
	while (node1->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in) == initial_node1)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	ASSERT_EQ (0, node0->network.size ());
	ASSERT_EQ (1, node1->network.size ());
	system.deadline_set (10s);
	while (node0->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in) < initial + 2)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	ASSERT_EQ (1, node0->network.size ());
	ASSERT_EQ (1, node1->network.size ());
	auto list1 (node0->network.list (1));
	ASSERT_EQ (node1->network.endpoint (), list1[0]->get_endpoint ());
	auto list2 (node1->network.list (1));
	ASSERT_EQ (node0->network.endpoint (), list2[0]->get_endpoint ());
	node1->stop ();
}

TEST (network, send_node_id_handshake_tcp)
{
	nano::system system (1);
	auto node0 (system.nodes[0]);
	ASSERT_EQ (0, node0->network.size ());
	auto node1 (std::make_shared<nano::node> (system.io_ctx, nano::get_available_port (), nano::unique_path (), system.alarm, system.logging, system.work));
	node1->start ();
	system.nodes.push_back (node1);
	auto initial (node0->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in));
	auto initial_node1 (node1->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in));
	auto initial_keepalive (node0->stats.count (nano::stat::type::message, nano::stat::detail::keepalive, nano::stat::dir::in));
	std::weak_ptr<nano::node> node_w (node0);
	node0->network.tcp_channels.start_tcp (node1->network.endpoint (), [node_w](std::shared_ptr<nano::transport::channel> channel_a) {
		if (auto node_l = node_w.lock ())
		{
			node_l->network.send_keepalive (channel_a);
		}
	});
	ASSERT_EQ (0, node0->network.size ());
	ASSERT_EQ (0, node1->network.size ());
	system.deadline_set (10s);
	while (node0->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in) < initial + 2)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	system.deadline_set (5s);
	while (node1->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in) < initial_node1 + 2)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	system.deadline_set (5s);
	while (node0->stats.count (nano::stat::type::message, nano::stat::detail::keepalive, nano::stat::dir::in) < initial_keepalive + 2)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	system.deadline_set (5s);
	while (node1->stats.count (nano::stat::type::message, nano::stat::detail::keepalive, nano::stat::dir::in) < initial_keepalive + 2)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	ASSERT_EQ (1, node0->network.size ());
	ASSERT_EQ (1, node1->network.size ());
	auto list1 (node0->network.list (1));
	ASSERT_EQ (nano::transport::transport_type::tcp, list1[0]->get_type ());
	ASSERT_EQ (node1->network.endpoint (), list1[0]->get_endpoint ());
	auto list2 (node1->network.list (1));
	ASSERT_EQ (nano::transport::transport_type::tcp, list2[0]->get_type ());
	ASSERT_EQ (node0->network.endpoint (), list2[0]->get_endpoint ());
	node1->stop ();
}

TEST (network, last_contacted)
{
	nano::system system (1);
	auto node0 (system.nodes[0]);
	ASSERT_EQ (0, node0->network.size ());
	auto node1 (std::make_shared<nano::node> (system.io_ctx, nano::get_available_port (), nano::unique_path (), system.alarm, system.logging, system.work));
	node1->start ();
	system.nodes.push_back (node1);
	auto channel1 (std::make_shared<nano::transport::channel_udp> (node1->network.udp_channels, nano::endpoint (boost::asio::ip::address_v6::loopback (), system.nodes.front ()->network.endpoint ().port ()), node1->network_params.protocol.protocol_version));
	node1->network.send_keepalive (channel1);
	system.deadline_set (10s);

	// Wait until the handshake is complete
	while (node0->network.size () < 1)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	ASSERT_EQ (node0->network.size (), 1);

	auto channel2 (node0->network.udp_channels.channel (nano::endpoint (boost::asio::ip::address_v6::loopback (), node1->network.endpoint ().port ())));
	ASSERT_NE (nullptr, channel2);
	// Make sure last_contact gets updated on receiving a non-handshake message
	auto timestamp_before_keepalive = channel2->get_last_packet_received ();
	node1->network.send_keepalive (channel1);
	while (node0->stats.count (nano::stat::type::message, nano::stat::detail::keepalive, nano::stat::dir::in) < 2)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	ASSERT_EQ (node0->network.size (), 1);
	auto timestamp_after_keepalive = channel2->get_last_packet_received ();
	ASSERT_GT (timestamp_after_keepalive, timestamp_before_keepalive);

	node1->stop ();
}

TEST (network, multi_keepalive)
{
	nano::system system (1);
	auto node0 (system.nodes[0]);
	ASSERT_EQ (0, node0->network.size ());
	auto node1 (std::make_shared<nano::node> (system.io_ctx, nano::get_available_port (), nano::unique_path (), system.alarm, system.logging, system.work));
	ASSERT_FALSE (node1->init_error ());
	node1->start ();
	system.nodes.push_back (node1);
	ASSERT_EQ (0, node1->network.size ());
	auto channel1 (std::make_shared<nano::transport::channel_udp> (node1->network.udp_channels, node0->network.endpoint (), node1->network_params.protocol.protocol_version));
	node1->network.send_keepalive (channel1);
	ASSERT_EQ (0, node1->network.size ());
	ASSERT_EQ (0, node0->network.size ());
	system.deadline_set (10s);
	while (node0->network.size () != 1)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	auto node2 (std::make_shared<nano::node> (system.io_ctx, nano::get_available_port (), nano::unique_path (), system.alarm, system.logging, system.work));
	ASSERT_FALSE (node2->init_error ());
	node2->start ();
	system.nodes.push_back (node2);
	auto channel2 (std::make_shared<nano::transport::channel_udp> (node2->network.udp_channels, node0->network.endpoint (), node2->network_params.protocol.protocol_version));
	node2->network.send_keepalive (channel2);
	system.deadline_set (10s);
	while (node1->network.size () != 2 || node0->network.size () != 2 || node2->network.size () != 2)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	node1->stop ();
	node2->stop ();
}

TEST (network, send_discarded_publish)
{
	nano::system system (2);
	auto & node1 (*system.nodes[0]);
	auto & node2 (*system.nodes[1]);
	auto block (std::make_shared<nano::send_block> (1, 1, 2, nano::keypair ().prv, 4, *system.work.generate (nano::root (1))));
	nano::genesis genesis;
	{
		auto transaction (node1.store.tx_begin_read ());
		node1.network.flood_block (block);
		ASSERT_EQ (genesis.hash (), node1.ledger.latest (transaction, nano::test_genesis_key.pub));
		ASSERT_EQ (genesis.hash (), node2.latest (nano::test_genesis_key.pub));
	}
	system.deadline_set (10s);
	while (node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in) == 0)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	auto transaction (node1.store.tx_begin_read ());
	ASSERT_EQ (genesis.hash (), node1.ledger.latest (transaction, nano::test_genesis_key.pub));
	ASSERT_EQ (genesis.hash (), node2.latest (nano::test_genesis_key.pub));
}

TEST (network, send_invalid_publish)
{
	nano::system system (2);
	auto & node1 (*system.nodes[0]);
	auto & node2 (*system.nodes[1]);
	nano::genesis genesis;
	auto block (std::make_shared<nano::send_block> (1, 1, 20, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (nano::root (1))));
	{
		auto transaction (node1.store.tx_begin_read ());
		node1.network.flood_block (block);
		ASSERT_EQ (genesis.hash (), node1.ledger.latest (transaction, nano::test_genesis_key.pub));
		ASSERT_EQ (genesis.hash (), node2.latest (nano::test_genesis_key.pub));
	}
	system.deadline_set (10s);
	while (node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in) == 0)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	auto transaction (node1.store.tx_begin_read ());
	ASSERT_EQ (genesis.hash (), node1.ledger.latest (transaction, nano::test_genesis_key.pub));
	ASSERT_EQ (genesis.hash (), node2.latest (nano::test_genesis_key.pub));
}

TEST (network, send_valid_confirm_ack)
{
	std::vector<nano::transport::transport_type> types{ nano::transport::transport_type::tcp, nano::transport::transport_type::udp };
	for (auto & type : types)
	{
		nano::node_flags node_flags;
		if (type == nano::transport::transport_type::tcp)
		{
			node_flags.disable_udp = true;
		}
		else
		{
			node_flags.disable_tcp_realtime = true;
			node_flags.disable_bootstrap_listener = true;
		}
		nano::system system (2, type, node_flags);
		auto & node1 (*system.nodes[0]);
		auto & node2 (*system.nodes[1]);
		nano::keypair key2;
		system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
		system.wallet (1)->insert_adhoc (key2.prv);
		nano::block_hash latest1 (node1.latest (nano::test_genesis_key.pub));
		nano::send_block block2 (latest1, key2.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (latest1));
		nano::block_hash latest2 (node2.latest (nano::test_genesis_key.pub));
		node1.process_active (std::make_shared<nano::send_block> (block2));
		system.deadline_set (10s);
		// Keep polling until latest block changes
		while (node2.latest (nano::test_genesis_key.pub) == latest2)
		{
			ASSERT_NO_ERROR (system.poll ());
		}
		// Make sure the balance has decreased after processing the block.
		ASSERT_EQ (50, node2.balance (nano::test_genesis_key.pub));
	}
}

TEST (network, send_valid_publish)
{
	std::vector<nano::transport::transport_type> types{ nano::transport::transport_type::tcp, nano::transport::transport_type::udp };
	for (auto & type : types)
	{
		nano::node_flags node_flags;
		if (type == nano::transport::transport_type::tcp)
		{
			node_flags.disable_udp = true;
		}
		else
		{
			node_flags.disable_tcp_realtime = true;
			node_flags.disable_bootstrap_listener = true;
		}
		nano::system system (2, type, node_flags);
		auto & node1 (*system.nodes[0]);
		auto & node2 (*system.nodes[1]);
		node1.bootstrap_initiator.stop ();
		node2.bootstrap_initiator.stop ();
		system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
		nano::keypair key2;
		system.wallet (1)->insert_adhoc (key2.prv);
		nano::block_hash latest1 (node1.latest (nano::test_genesis_key.pub));
		nano::send_block block2 (latest1, key2.pub, 50, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (latest1));
		auto hash2 (block2.hash ());
		nano::block_hash latest2 (node2.latest (nano::test_genesis_key.pub));
		node2.process_active (std::make_shared<nano::send_block> (block2));
		system.deadline_set (10s);
		while (node1.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in) == 0)
		{
			ASSERT_NO_ERROR (system.poll ());
		}
		ASSERT_NE (hash2, latest2);
		system.deadline_set (10s);
		while (node2.latest (nano::test_genesis_key.pub) == latest2)
		{
			ASSERT_NO_ERROR (system.poll ());
		}
		ASSERT_EQ (50, node2.balance (nano::test_genesis_key.pub));
	}
}

TEST (network, send_insufficient_work)
{
	nano::system system (2);
	auto & node1 (*system.nodes[0]);
	auto & node2 (*system.nodes[1]);
	auto block (std::make_shared<nano::send_block> (0, 1, 20, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
	nano::publish publish (block);
	nano::transport::channel_udp channel (node1.network.udp_channels, node2.network.endpoint (), node1.network_params.protocol.protocol_version);
	channel.send (publish, [](boost::system::error_code const & ec, size_t size) {});
	ASSERT_EQ (0, node1.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work));
	system.deadline_set (10s);
	while (node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work) == 0)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	ASSERT_EQ (1, node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work));
}

TEST (receivable_processor, confirm_insufficient_pos)
{
	nano::system system (1);
	auto & node1 (*system.nodes[0]);
	nano::genesis genesis;
	auto block1 (std::make_shared<nano::send_block> (genesis.hash (), 0, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
	node1.work_generate_blocking (*block1);
	ASSERT_EQ (nano::process_result::progress, node1.process (*block1).code);
	node1.active.start (block1);
	nano::keypair key1;
	auto vote (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, block1));
	nano::confirm_ack con1 (vote);
	node1.network.process_message (con1, node1.network.udp_channels.create (node1.network.endpoint ()));
}

TEST (receivable_processor, confirm_sufficient_pos)
{
	nano::system system (1);
	auto & node1 (*system.nodes[0]);
	nano::genesis genesis;
	auto block1 (std::make_shared<nano::send_block> (genesis.hash (), 0, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
	node1.work_generate_blocking (*block1);
	ASSERT_EQ (nano::process_result::progress, node1.process (*block1).code);
	node1.active.start (block1);
	auto vote (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 0, block1));
	nano::confirm_ack con1 (vote);
	node1.network.process_message (con1, node1.network.udp_channels.create (node1.network.endpoint ()));
}

TEST (receivable_processor, send_with_receive)
{
	std::vector<nano::transport::transport_type> types{ nano::transport::transport_type::tcp, nano::transport::transport_type::udp };
	for (auto & type : types)
	{
		nano::node_flags node_flags;
		if (type == nano::transport::transport_type::tcp)
		{
			node_flags.disable_udp = true;
		}
		else
		{
			node_flags.disable_tcp_realtime = true;
			node_flags.disable_bootstrap_listener = true;
		}
		nano::system system (2, type, node_flags);
		auto & node1 (*system.nodes[0]);
		auto & node2 (*system.nodes[1]);
		auto amount (std::numeric_limits<nano::uint128_t>::max ());
		nano::keypair key2;
		system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
		nano::block_hash latest1 (node1.latest (nano::test_genesis_key.pub));
		system.wallet (1)->insert_adhoc (key2.prv);
		auto block1 (std::make_shared<nano::send_block> (latest1, key2.pub, amount - node1.config.receive_minimum.number (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (latest1)));
		ASSERT_EQ (amount, node1.balance (nano::test_genesis_key.pub));
		ASSERT_EQ (0, node1.balance (key2.pub));
		ASSERT_EQ (amount, node2.balance (nano::test_genesis_key.pub));
		ASSERT_EQ (0, node2.balance (key2.pub));
		node1.process_active (block1);
		node1.block_processor.flush ();
		node2.process_active (block1);
		node2.block_processor.flush ();
		ASSERT_EQ (amount - node1.config.receive_minimum.number (), node1.balance (nano::test_genesis_key.pub));
		ASSERT_EQ (0, node1.balance (key2.pub));
		ASSERT_EQ (amount - node1.config.receive_minimum.number (), node2.balance (nano::test_genesis_key.pub));
		ASSERT_EQ (0, node2.balance (key2.pub));
		system.deadline_set (10s);
		while (node1.balance (key2.pub) != node1.config.receive_minimum.number () || node2.balance (key2.pub) != node1.config.receive_minimum.number ())
		{
			ASSERT_NO_ERROR (system.poll ());
		}
		ASSERT_EQ (amount - node1.config.receive_minimum.number (), node1.balance (nano::test_genesis_key.pub));
		ASSERT_EQ (node1.config.receive_minimum.number (), node1.balance (key2.pub));
		ASSERT_EQ (amount - node1.config.receive_minimum.number (), node2.balance (nano::test_genesis_key.pub));
		ASSERT_EQ (node1.config.receive_minimum.number (), node2.balance (key2.pub));
	}
}

TEST (network, receive_weight_change)
{
	nano::system system (2);
	system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
	nano::keypair key2;
	system.wallet (1)->insert_adhoc (key2.prv);
	{
		auto transaction (system.nodes[1]->wallets.tx_begin_write ());
		system.wallet (1)->store.representative_set (transaction, key2.pub);
	}
	ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::test_genesis_key.pub, key2.pub, system.nodes[0]->config.receive_minimum.number ()));
	system.deadline_set (10s);
	while (std::any_of (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr<nano::node> const & node_a) { return node_a->weight (key2.pub) != system.nodes[0]->config.receive_minimum.number (); }))
	{
		ASSERT_NO_ERROR (system.poll ());
	}
}

TEST (parse_endpoint, valid)
{
	std::string string ("::1:24000");
	nano::endpoint endpoint;
	ASSERT_FALSE (nano::parse_endpoint (string, endpoint));
	ASSERT_EQ (boost::asio::ip::address_v6::loopback (), endpoint.address ());
	ASSERT_EQ (24000, endpoint.port ());
}

TEST (parse_endpoint, invalid_port)
{
	std::string string ("::1:24a00");
	nano::endpoint endpoint;
	ASSERT_TRUE (nano::parse_endpoint (string, endpoint));
}

TEST (parse_endpoint, invalid_address)
{
	std::string string ("::q:24000");
	nano::endpoint endpoint;
	ASSERT_TRUE (nano::parse_endpoint (string, endpoint));
}

TEST (parse_endpoint, no_address)
{
	std::string string (":24000");
	nano::endpoint endpoint;
	ASSERT_TRUE (nano::parse_endpoint (string, endpoint));
}

TEST (parse_endpoint, no_port)
{
	std::string string ("::1:");
	nano::endpoint endpoint;
	ASSERT_TRUE (nano::parse_endpoint (string, endpoint));
}

TEST (parse_endpoint, no_colon)
{
	std::string string ("::1");
	nano::endpoint endpoint;
	ASSERT_TRUE (nano::parse_endpoint (string, endpoint));
}

TEST (network, ipv6)
{
	boost::asio::ip::address_v6 address (boost::asio::ip::make_address_v6 ("::ffff:127.0.0.1"));
	ASSERT_TRUE (address.is_v4_mapped ());
	nano::endpoint endpoint1 (address, 16384);
	std::vector<uint8_t> bytes1;
	{
		nano::vectorstream stream (bytes1);
		nano::write (stream, address.to_bytes ());
	}
	ASSERT_EQ (16, bytes1.size ());
	for (auto i (bytes1.begin ()), n (bytes1.begin () + 10); i != n; ++i)
	{
		ASSERT_EQ (0, *i);
	}
	ASSERT_EQ (0xff, bytes1[10]);
	ASSERT_EQ (0xff, bytes1[11]);
	std::array<uint8_t, 16> bytes2;
	nano::bufferstream stream (bytes1.data (), bytes1.size ());
	auto error (nano::try_read (stream, bytes2));
	ASSERT_FALSE (error);
	nano::endpoint endpoint2 (boost::asio::ip::address_v6 (bytes2), 16384);
	ASSERT_EQ (endpoint1, endpoint2);
}

TEST (network, ipv6_from_ipv4)
{
	nano::endpoint endpoint1 (boost::asio::ip::address_v4::loopback (), 16000);
	ASSERT_TRUE (endpoint1.address ().is_v4 ());
	nano::endpoint endpoint2 (boost::asio::ip::address_v6::v4_mapped (endpoint1.address ().to_v4 ()), 16000);
	ASSERT_TRUE (endpoint2.address ().is_v6 ());
}

TEST (network, ipv6_bind_send_ipv4)
{
	boost::asio::io_context io_ctx;
	auto port1 = nano::get_available_port ();
	auto port2 = nano::get_available_port ();
	nano::endpoint endpoint1 (boost::asio::ip::address_v6::any (), port1);
	nano::endpoint endpoint2 (boost::asio::ip::address_v4::any (), port2);
	std::array<uint8_t, 16> bytes1;
	auto finish1 (false);
	nano::endpoint endpoint3;
	boost::asio::ip::udp::socket socket1 (io_ctx, endpoint1);
	socket1.async_receive_from (boost::asio::buffer (bytes1.data (), bytes1.size ()), endpoint3, [&finish1](boost::system::error_code const & error, size_t size_a) {
		ASSERT_FALSE (error);
		ASSERT_EQ (16, size_a);
		finish1 = true;
	});
	boost::asio::ip::udp::socket socket2 (io_ctx, endpoint2);
	nano::endpoint endpoint5 (boost::asio::ip::address_v4::loopback (), port1);
	nano::endpoint endpoint6 (boost::asio::ip::address_v6::v4_mapped (boost::asio::ip::address_v4::loopback ()), port2);
	socket2.async_send_to (boost::asio::buffer (std::array<uint8_t, 16>{}, 16), endpoint5, [](boost::system::error_code const & error, size_t size_a) {
		ASSERT_FALSE (error);
		ASSERT_EQ (16, size_a);
	});
	auto iterations (0);
	while (!finish1)
	{
		io_ctx.poll ();
		++iterations;
		ASSERT_LT (iterations, 200);
	}
	ASSERT_EQ (endpoint6, endpoint3);
	std::array<uint8_t, 16> bytes2;
	nano::endpoint endpoint4;
	socket2.async_receive_from (boost::asio::buffer (bytes2.data (), bytes2.size ()), endpoint4, [](boost::system::error_code const & error, size_t size_a) {
		ASSERT_FALSE (!error);
		ASSERT_EQ (16, size_a);
	});
	socket1.async_send_to (boost::asio::buffer (std::array<uint8_t, 16>{}, 16), endpoint6, [](boost::system::error_code const & error, size_t size_a) {
		ASSERT_FALSE (error);
		ASSERT_EQ (16, size_a);
	});
}

TEST (network, endpoint_bad_fd)
{
	nano::system system (1);
	system.nodes[0]->stop ();
	auto endpoint (system.nodes[0]->network.endpoint ());
	ASSERT_TRUE (endpoint.address ().is_loopback ());
	// The endpoint is invalidated asynchronously
	system.deadline_set (10s);
	while (system.nodes[0]->network.endpoint ().port () != 0)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
}

TEST (network, reserved_address)
{
	nano::system system (1);
	// 0 port test
	ASSERT_TRUE (nano::transport::reserved_address (nano::endpoint (boost::asio::ip::make_address_v6 ("2001::"), 0)));
	// Valid address test
	ASSERT_FALSE (nano::transport::reserved_address (nano::endpoint (boost::asio::ip::make_address_v6 ("2001::"), 1)));
	nano::endpoint loopback (boost::asio::ip::make_address_v6 ("::1"), 1);
	ASSERT_FALSE (nano::transport::reserved_address (loopback));
	nano::endpoint private_network_peer (boost::asio::ip::make_address_v6 ("::ffff:10.0.0.0"), 1);
	ASSERT_TRUE (nano::transport::reserved_address (private_network_peer, false));
	ASSERT_FALSE (nano::transport::reserved_address (private_network_peer, true));
}

TEST (node, port_mapping)
{
	nano::system system (1);
	auto node0 (system.nodes[0]);
	node0->port_mapping.refresh_devices ();
	node0->port_mapping.start ();
	auto end (std::chrono::steady_clock::now () + std::chrono::seconds (500));
	(void)end;
	//while (std::chrono::steady_clock::now () < end)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
}

TEST (message_buffer_manager, one_buffer)
{
	nano::stat stats;
	nano::message_buffer_manager buffer (stats, 512, 1);
	auto buffer1 (buffer.allocate ());
	ASSERT_NE (nullptr, buffer1);
	buffer.enqueue (buffer1);
	auto buffer2 (buffer.dequeue ());
	ASSERT_EQ (buffer1, buffer2);
	buffer.release (buffer2);
	auto buffer3 (buffer.allocate ());
	ASSERT_EQ (buffer1, buffer3);
}

TEST (message_buffer_manager, two_buffers)
{
	nano::stat stats;
	nano::message_buffer_manager buffer (stats, 512, 2);
	auto buffer1 (buffer.allocate ());
	ASSERT_NE (nullptr, buffer1);
	auto buffer2 (buffer.allocate ());
	ASSERT_NE (nullptr, buffer2);
	ASSERT_NE (buffer1, buffer2);
	buffer.enqueue (buffer2);
	buffer.enqueue (buffer1);
	auto buffer3 (buffer.dequeue ());
	ASSERT_EQ (buffer2, buffer3);
	auto buffer4 (buffer.dequeue ());
	ASSERT_EQ (buffer1, buffer4);
	buffer.release (buffer3);
	buffer.release (buffer4);
	auto buffer5 (buffer.allocate ());
	ASSERT_EQ (buffer2, buffer5);
	auto buffer6 (buffer.allocate ());
	ASSERT_EQ (buffer1, buffer6);
}

TEST (message_buffer_manager, one_overflow)
{
	nano::stat stats;
	nano::message_buffer_manager buffer (stats, 512, 1);
	auto buffer1 (buffer.allocate ());
	ASSERT_NE (nullptr, buffer1);
	buffer.enqueue (buffer1);
	auto buffer2 (buffer.allocate ());
	ASSERT_EQ (buffer1, buffer2);
}

TEST (message_buffer_manager, two_overflow)
{
	nano::stat stats;
	nano::message_buffer_manager buffer (stats, 512, 2);
	auto buffer1 (buffer.allocate ());
	ASSERT_NE (nullptr, buffer1);
	buffer.enqueue (buffer1);
	auto buffer2 (buffer.allocate ());
	ASSERT_NE (nullptr, buffer2);
	ASSERT_NE (buffer1, buffer2);
	buffer.enqueue (buffer2);
	auto buffer3 (buffer.allocate ());
	ASSERT_EQ (buffer1, buffer3);
	auto buffer4 (buffer.allocate ());
	ASSERT_EQ (buffer2, buffer4);
}

TEST (message_buffer_manager, one_buffer_multithreaded)
{
	nano::stat stats;
	nano::message_buffer_manager buffer (stats, 512, 1);
	boost::thread thread ([&buffer]() {
		auto done (false);
		while (!done)
		{
			auto item (buffer.dequeue ());
			done = item == nullptr;
			if (item != nullptr)
			{
				buffer.release (item);
			}
		}
	});
	auto buffer1 (buffer.allocate ());
	ASSERT_NE (nullptr, buffer1);
	buffer.enqueue (buffer1);
	auto buffer2 (buffer.allocate ());
	ASSERT_EQ (buffer1, buffer2);
	buffer.stop ();
	thread.join ();
}

TEST (message_buffer_manager, many_buffers_multithreaded)
{
	nano::stat stats;
	nano::message_buffer_manager buffer (stats, 512, 16);
	std::vector<boost::thread> threads;
	for (auto i (0); i < 4; ++i)
	{
		threads.push_back (boost::thread ([&buffer]() {
			auto done (false);
			while (!done)
			{
				auto item (buffer.dequeue ());
				done = item == nullptr;
				if (item != nullptr)
				{
					buffer.release (item);
				}
			}
		}));
	}
	std::atomic_int count (0);
	for (auto i (0); i < 4; ++i)
	{
		threads.push_back (boost::thread ([&buffer, &count]() {
			auto done (false);
			for (auto i (0); !done && i < 1000; ++i)
			{
				auto item (buffer.allocate ());
				done = item == nullptr;
				if (item != nullptr)
				{
					buffer.enqueue (item);
					++count;
					if (count > 3000)
					{
						buffer.stop ();
					}
				}
			}
		}));
	}
	buffer.stop ();
	for (auto & i : threads)
	{
		i.join ();
	}
}

TEST (message_buffer_manager, stats)
{
	nano::stat stats;
	nano::message_buffer_manager buffer (stats, 512, 1);
	auto buffer1 (buffer.allocate ());
	buffer.enqueue (buffer1);
	buffer.allocate ();
	ASSERT_EQ (1, stats.count (nano::stat::type::udp, nano::stat::detail::overflow));
}

TEST (tcp_listener, tcp_node_id_handshake)
{
	nano::system system (1);
	auto socket (std::make_shared<nano::socket> (system.nodes[0]));
	auto bootstrap_endpoint (system.nodes[0]->bootstrap.endpoint ());
	auto cookie (system.nodes[0]->network.syn_cookies.assign (nano::transport::map_tcp_to_endpoint (bootstrap_endpoint)));
	nano::node_id_handshake node_id_handshake (cookie, boost::none);
	auto input (node_id_handshake.to_shared_const_buffer ());
	std::atomic<bool> write_done (false);
	socket->async_connect (bootstrap_endpoint, [&input, socket, &write_done](boost::system::error_code const & ec) {
		ASSERT_FALSE (ec);
		socket->async_write (input, [&input, &write_done](boost::system::error_code const & ec, size_t size_a) {
			ASSERT_FALSE (ec);
			ASSERT_EQ (input.size (), size_a);
			write_done = true;
		});
	});

	system.deadline_set (std::chrono::seconds (5));
	while (!write_done)
	{
		ASSERT_NO_ERROR (system.poll ());
	}

	boost::optional<std::pair<nano::account, nano::signature>> response_zero (std::make_pair (nano::account (0), nano::signature (0)));
	nano::node_id_handshake node_id_handshake_response (boost::none, response_zero);
	auto output (node_id_handshake_response.to_bytes ());
	std::atomic<bool> done (false);
	socket->async_read (output, output->size (), [&output, &done](boost::system::error_code const & ec, size_t size_a) {
		ASSERT_FALSE (ec);
		ASSERT_EQ (output->size (), size_a);
		done = true;
	});
	system.deadline_set (std::chrono::seconds (5));
	while (!done)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
}

TEST (tcp_listener, tcp_listener_timeout_empty)
{
	nano::system system (1);
	auto node0 (system.nodes[0]);
	auto socket (std::make_shared<nano::socket> (node0));
	std::atomic<bool> connected (false);
	socket->async_connect (node0->bootstrap.endpoint (), [&connected](boost::system::error_code const & ec) {
		ASSERT_FALSE (ec);
		connected = true;
	});
	system.deadline_set (std::chrono::seconds (5));
	while (!connected)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	bool disconnected (false);
	system.deadline_set (std::chrono::seconds (6));
	while (!disconnected)
	{
		{
			nano::lock_guard<std::mutex> guard (node0->bootstrap.mutex);
			disconnected = node0->bootstrap.connections.empty ();
		}
		ASSERT_NO_ERROR (system.poll ());
	}
}

TEST (tcp_listener, tcp_listener_timeout_node_id_handshake)
{
	nano::system system (1);
	auto node0 (system.nodes[0]);
	auto socket (std::make_shared<nano::socket> (node0));
	auto cookie (node0->network.syn_cookies.assign (nano::transport::map_tcp_to_endpoint (node0->bootstrap.endpoint ())));
	nano::node_id_handshake node_id_handshake (cookie, boost::none);
	auto input (node_id_handshake.to_shared_const_buffer ());
	socket->async_connect (node0->bootstrap.endpoint (), [&input, socket](boost::system::error_code const & ec) {
		ASSERT_FALSE (ec);
		socket->async_write (input, [&input](boost::system::error_code const & ec, size_t size_a) {
			ASSERT_FALSE (ec);
			ASSERT_EQ (input.size (), size_a);
		});
	});
	system.deadline_set (std::chrono::seconds (5));
	while (node0->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake) == 0)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	{
		nano::lock_guard<std::mutex> guard (node0->bootstrap.mutex);
		ASSERT_EQ (node0->bootstrap.connections.size (), 1);
	}
	bool disconnected (false);
	system.deadline_set (std::chrono::seconds (20));
	while (!disconnected)
	{
		{
			nano::lock_guard<std::mutex> guard (node0->bootstrap.mutex);
			disconnected = node0->bootstrap.connections.empty ();
		}
		ASSERT_NO_ERROR (system.poll ());
	}
}

TEST (network, replace_port)
{
	nano::system system (1);
	auto node0 (system.nodes[0]);
	ASSERT_EQ (0, node0->network.size ());
	auto node1 (std::make_shared<nano::node> (system.io_ctx, nano::get_available_port (), nano::unique_path (), system.alarm, system.logging, system.work));
	node1->start ();
	system.nodes.push_back (node1);
	{
		auto channel (node0->network.udp_channels.insert (nano::endpoint (node1->network.endpoint ().address (), 23000), node1->network_params.protocol.protocol_version));
		if (channel)
		{
			channel->set_node_id (node1->node_id.pub);
		}
	}
	auto peers_list (node0->network.list (std::numeric_limits<size_t>::max ()));
	ASSERT_EQ (peers_list[0]->get_node_id (), node1->node_id.pub);
	auto channel (std::make_shared<nano::transport::channel_udp> (node0->network.udp_channels, node1->network.endpoint (), node1->network_params.protocol.protocol_version));
	node0->network.send_keepalive (channel);
	system.deadline_set (5s);
	while (!node0->network.udp_channels.channel (node1->network.endpoint ()))
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	system.deadline_set (5s);
	while (node0->network.udp_channels.size () > 1)
	{
		ASSERT_NO_ERROR (system.poll ());
	}
	ASSERT_EQ (node0->network.udp_channels.size (), 1);
	auto list1 (node0->network.list (1));
	ASSERT_EQ (node1->network.endpoint (), list1[0]->get_endpoint ());
	auto list2 (node1->network.list (1));
	ASSERT_EQ (node0->network.endpoint (), list2[0]->get_endpoint ());
	// Remove correct peer (same node ID)
	node0->network.udp_channels.clean_node_id (nano::endpoint (node1->network.endpoint ().address (), 23000), node1->node_id.pub);
	ASSERT_EQ (node0->network.udp_channels.size (), 0);
	node1->stop ();
}

// The test must be completed in less than 1 second
TEST (bandwidth_limiter, validate)
{
	nano::system system;
	size_t const message_size (1024);
	nano::bandwidth_limiter limiter_0 (0);
	auto message_limit = 3;
	nano::bandwidth_limiter limiter_3 (message_size * message_limit);
	ASSERT_FALSE (limiter_0.should_drop (message_size)); // never drops
	auto start (std::chrono::steady_clock::now ());
	for (unsigned i = 0; i < message_limit; ++i)
	{
		limiter_3.add (message_size);
		ASSERT_FALSE (limiter_3.should_drop (message_size));
	}
	system.deadline_set (300ms);
	// Wait for the trended rate to catch up
	while (limiter_3.get_rate () < limiter_3.get_limit ())
	{
		// Force an update
		limiter_3.add (0);
		ASSERT_NO_ERROR (system.poll (10ms));
	}
	ASSERT_EQ (limiter_3.get_rate (), limiter_3.get_limit ());
	ASSERT_LT (std::chrono::steady_clock::now () - 1s, start);
	// A new message would drop
	ASSERT_TRUE (limiter_3.should_drop (message_size));
	// So adding it will not increase the rate
	limiter_3.add (message_size);
	ASSERT_EQ (limiter_3.get_rate (), limiter_3.get_limit ());
	// Unless the message is forced (e.g. non-droppable packets)
	limiter_3.add (message_size, true);
	// Limiter says it should drop, but the rate will have increased
	// Wait for the trended rate to catch up
	while (limiter_3.get_rate () < limiter_3.get_limit () + message_size)
	{
		// Force an update
		limiter_3.add (0);
		ASSERT_NO_ERROR (system.poll (10ms));
	}
	ASSERT_TRUE (limiter_3.should_drop (message_size));
	ASSERT_EQ (limiter_3.get_rate (), limiter_3.get_limit () + message_size);
	ASSERT_LT (std::chrono::steady_clock::now () - 1s, start);
}

max_stars_repo_name: globotree/nano-node

max_issues_repo_name: globotree/nano-node

max_forks_repo_name: globotree/nano-node


text:
/* vim:set ts=3 sw=3 sts=3 et: */
/**
 * Copyright © 2008-2013 Last.fm Limited
 *
 * This file is part of libmoost.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef MOOST_NAGIOS_NSCA_CLIENT_NSCA_ENCPASS_HPP__
#define MOOST_NAGIOS_NSCA_CLIENT_NSCA_ENCPASS_HPP__

#include <string>
#include <stdexcept>
#include <iostream>

#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/regex.hpp>

#include "nsca_common.hpp"

namespace moost { namespace nagios {

   struct nsca_encpass
   {
      nsca_encpass(std::string const & passwd = std::string())
         : passwd(validate_encryption_password(passwd))
      {
      }

      static std::string validate_encryption_password(
            std::string const & password)
      {
         if(password.size() > nsca_const::MAX_PASSWORD_LENGTH)
         {
            throw std::invalid_argument(
                  "Password is too long for NSCA to handle");
         }

         return password;
      }

      operator std::string const & () const
      {
         return passwd;
      }

      std::string passwd;
   };

}}

#endif

max_stars_repo_name: lastfm/libmoost

max_issues_repo_name: lastfm/libmoost

max_forks_repo_name: lastfm/libmoost