text:
/* For more information please refer to files in the COPYRIGHT directory ***/

/*#define FUSE_DEBUG 1*/

/*
 * Locking order:
 *
 * PathCacheLock (we allow getAndUseConnByPath as an exception, todo add a separate cache for this purpose
 * PathCache
 * DescLock
 * iFuseDesc
 * FileCache
 * iFuseConn.inuseLock
 * iFuseConn struct
 * lock for concurrent queue in iFuseLib.Conn.c
 *
 *
 * Invariants:
 *
 */

#ifndef IFUSELIB_LOCK_H
#define IFUSELIB_LOCK_H
#include "irodsFs.hpp"
#include "iFuseLib.hpp"

#undef USE_BOOST

typedef struct ConcurrentList {
    List *list;
#ifdef USE_BOOST
    boost::mutex* mutex;
#else
    pthread_mutex_t lock;
#endif
} concurrentList_t;

#ifdef USE_BOOST

#include <boost/thread/thread_time.hpp>
extern boost::mutex* PathCacheLock;
extern boost::thread*            ConnManagerThr;
extern boost::mutex*             ConnManagerLock;
extern boost::condition_variable ConnManagerCond;
#else
#include <pthread.h>
extern pthread_mutex_t PathCacheLock;
extern pthread_t ConnManagerThr;
extern pthread_mutex_t ConnManagerLock;
extern pthread_cond_t ConnManagerCond;
#endif

#ifdef USE_BOOST
#define LOCK(Lock) ((Lock)->lock())
#define UNLOCK(Lock) ((Lock)->unlock())
#define INIT_STRUCT_LOCK(s) INIT_LOCK((s).mutex) // JMC :: necessary since no ctor/dtor on struct
#define INIT_LOCK(Lock) ((Lock) = new boost::mutex) // JMC :: necessary since no ctor/dtor on struct
#define FREE_LOCK(Lock) \
	    delete (Lock); \
	    (Lock) = 0;

#define LOCK_STRUCT(s) LOCK(((s).mutex))
#define UNLOCK_STRUCT(s) UNLOCK(((s).mutex))
#define FREE_STRUCT_LOCK(s) \
	FREE_LOCK((s).mutex);

void releaseFuseConnLock( iFuseConn_t *tmpIFuseConn );

void initConnReqWaitMutex( connReqWait_t *myConnReqWait );
void deleteConnReqWaitMutex( connReqWait_t *myConnReqWait );
void timeoutWait( boost::mutex **ConnManagerLock, boost::condition_variable *ConnManagerCond, int sleepTime );
void notifyTimeoutWait( boost::mutex **ConnManagerLock, boost::condition_variable *ConnManagerCond );
#else
#ifdef FUSE_DEBUG
#define UNLOCK(Lock) \
		if(FUSE_DEBUG)rodsLog(LOG_ERROR, "[ LOCK ]%s:%d %p", __FILE__, __LINE__, &(Lock)); \
	(pthread_mutex_unlock (&(Lock)))

#define LOCK(Lock) \
		if(FUSE_DEBUG)rodsLog(LOG_ERROR, "[UNLOCK] %s:%d %p", __FILE__, __LINE__, &(Lock)); \
	(pthread_mutex_lock (&(Lock)))

#else
#define UNLOCK(Lock) (pthread_mutex_unlock (&(Lock)))
#define LOCK(Lock) (pthread_mutex_lock (&(Lock)))
#endif
#define INIT_STRUCT_LOCK(s) INIT_LOCK((s).lock)
#define INIT_LOCK(s) (pthread_mutex_init (&(s), NULL))
#define LOCK_STRUCT(s) LOCK((s).lock)
#define UNLOCK_STRUCT(s) UNLOCK((s).lock)
#define FREE_STRUCT_LOCK(s) FREE_LOCK((s).lock)
#define FREE_LOCK(s) pthread_mutex_destroy (&(s))

void releaseFuseConnLock( iFuseConn_t *tmpIFuseConn );

void initConnReqWaitMutex( connReqWait_t *myConnReqWait );
void deleteConnReqWaitMutex( connReqWait_t *myConnReqWait );
void timeoutWait( pthread_mutex_t *ConnManagerLock, pthread_cond_t *ConnManagerCond, int sleepTime );
void notifyTimeoutWait( pthread_mutex_t *mutex, pthread_cond_t *cond );
#endif

#define FREE(s, t) _free##t(s);

#ifdef FUSE_DEBUG
#undef FREE
#define FREE(s, t) \
	rodsLog(LOG_ERROR, "[FREE "#t" %s:%d %p", __FILE__, __LINE__, s); \
	_free##t(s);
#endif

extern rodsEnv MyRodsEnv;
extern iFuseDesc_t IFuseDesc[MAX_IFUSE_DESC];
extern concurrentList_t *IFuseDescFreeList;

#define UNREF(s, t) \
	if(s != NULL) { \
		LOCK_STRUCT(*(s)); \
		(s)->status--; \
		if((s)->status == 0) { \
			UNLOCK_STRUCT(*(s)); \
			FREE_STRUCT_LOCK(*(s)); \
			FREE(s, t); \
		} else { \
			UNLOCK_STRUCT(*(s)); \
		} \
		(s) = NULL; \
	}

#define REF(v, s) \
	if(s != NULL) { \
		LOCK_STRUCT(*(s)); \
		(s)->status++; \
		UNLOCK_STRUCT(*(s)); \
		(v) = (s);\
	} else { \
		v = NULL; \
	}

#define REF_NO_LOCK(v, s) \
	if(s != NULL) { \
		(s)->status++; \
		(v) = (s);\
	} else { \
		v = NULL; \
	}

fileCache_t *newFileCache( int iFd, char *objPath, char *localPath, char *cacheFilePath, time_t cachedTime, int mode, rodsLong_t fileCache, cacheState_t state );
pathCache_t *newPathCache( char *inPath, fileCache_t *fileCache, struct stat *stbuf, time_t cachedTime );
iFuseConn_t *newIFuseConn( int *status );
iFuseDesc_t *newIFuseDesc( char *objPath, char *localPath, fileCache_t *fileCache, int *status );

int _freeFileCache( fileCache_t *fileCache );
int _freeIFuseConn( iFuseConn_t *conn );
/* precond: lock tmpPathCache */
int _freePathCache( pathCache_t *tmpPathCache );
int _freeIFuseDesc( iFuseDesc_t *desc );
int _freeIFuseConn( iFuseConn_t *tmpIFuseConn );

concurrentList_t *newConcurrentList();
void addToConcurrentList( concurrentList_t *l, void *v );
void removeFromConcurrentList2( concurrentList_t *l, void *v );
void removeFromConcurrentList( concurrentList_t *l, ListNode *v );
void* removeFirstElementOfConcurrentList( concurrentList_t *l );
void* removeLastElementOfConcurrentList( concurrentList_t *l );
int _listSize( concurrentList_t *l );
int listSize( concurrentList_t *l );

iFuseConn_t *getAndUseConnByPath( char *localPath, rodsEnv *myRodsEnv, int *status );
int lookupPathNotExist( char *inPath );
int lookupPathExist( char *inPath, pathCache_t **paca );
int matchAndLockPathCache( char *inPath, pathCache_t **outPathCache );
int _matchAndLockPathCache( char *inPath, pathCache_t **outPathCache );
int updatePathCacheStatFromFileCache( pathCache_t *tmpPathCache );
int _updatePathCacheStatFromFileCache( pathCache_t *tmpPathCache );
int clearPathFromCache( char *inPath );
int pathNotExist( char *inPath );
int pathExist( char *inPath, fileCache_t *fileCache, struct stat *stbuf, pathCache_t **outPathCache );
fileCache_t *addFileCache( int iFd, char *objPath, char *localPath, char *cachePath, int mode, rodsLong_t fileCache, cacheState_t state );
int _addFileCacheForPath( pathCache_t *pathCache, fileCache_t *fileCache );
int _pathNotExist( char *path );
int _pathReplace( char *inPath, fileCache_t *fileCache, struct stat *stbuf, pathCache_t **outPathCache );
int _getAndUseConnForPathCache( iFuseConn_t **iFuseConn, pathCache_t *paca );
int _getAndUseIFuseConn( iFuseConn_t **iFuseConn, rodsEnv *myRodsEnv );
int getAndUseIFuseConn( iFuseConn_t **iFuseConn, rodsEnv *myRodsEnv );

int iFuseFileCacheLseek( fileCache_t *fileCache, off_t offset );
int _iFuseFileCacheLseek( fileCache_t *fileCache, off_t offset );
int iFuseFileCacheFlush( fileCache_t *fileCache );
int _iFuseFileCacheFlush( fileCache_t *fileCache );
int ifuseFileCacheSwapOut( fileCache_t *fileCache );
/* close any open files inside the file cache */
int ifuseFileCacheClose( fileCache_t *fileCache );
int getFileCachePath( const char *inPath, char *cacehPath );
int setAndMkFileCacheDir();
int ifuseFileCacheWrite( fileCache_t *fileCache, char *buf, size_t size, off_t offset );
int ifuseFileCacheRead( fileCache_t *fileCache, char *buf, size_t size, off_t offset );

void _ifuseDisconnect( iFuseConn_t *tmpIFuseConn );

int _ifuseRead( iFuseDesc_t *desc, char *buf, size_t size, off_t offset );
int
_ifuseWrite( iFuseDesc_t *desc, char *buf, size_t size, off_t offset );
int
_ifuseLseek( iFuseDesc_t *desc, off_t offset );

/* dummy function for reusing hashtable.c from RE */
char *cpStringExt( char *str, Region *r );
#endif

max_stars_repo_name: PlantandFoodResearch/irods

max_issues_repo_name: PlantandFoodResearch/irods

max_forks_repo_name: PlantandFoodResearch/irods


text:
#ifndef BOOST_PARSER_DETAIL_PRINTING_IMPL_HPP
#define BOOST_PARSER_DETAIL_PRINTING_IMPL_HPP

#include <boost/parser/detail/printing.hpp>

#if BOOST_PARSER_USE_BOOST
#include <boost/type_index.hpp>
#else
#include <typeinfo>
#endif

namespace boost { namespace parser { namespace detail {

    template<typename T>
    auto type_name()
    {
#if BOOST_PARSER_USE_BOOST
        return typeindex::type_id<T>().pretty_name();
#else
        return typeid(T).name();
#endif
    }

    template<typename Parser>
    struct n_aray_parser : std::false_type
    {};

    template<
        typename Parser,
        typename DelimiterParser,
        typename MinType,
        typename MaxType>
    struct n_aray_parser<
        repeat_parser<Parser, DelimiterParser, MinType, MaxType>>
        : std::true_type
    {};

    template<typename Parser, typename MinType, typename MaxType>
    struct n_aray_parser<repeat_parser<Parser, detail::nope, MinType, MaxType>>
        : std::false_type
    {};

    template<typename Parser, typename DelimiterParser>
    struct n_aray_parser<delimited_seq_parser<Parser, DelimiterParser>>
        : std::true_type
    {};

    template<typename ParserTuple>
    struct n_aray_parser<or_parser<ParserTuple>> : std::true_type
    {};

    template<typename ParserTuple, typename BacktrackingTuple>
    struct n_aray_parser<seq_parser<ParserTuple, BacktrackingTuple>>
        : std::true_type
    {};

    // true iff Parser is an n-ary parser (contains N>2 subparsers).
    template<typename Parser>
    constexpr bool n_aray_parser_v = n_aray_parser<Parser>::value;

    template<typename Context, typename Expected>
    void print_expected(
        Context const & context,
        std::ostream & os,
        Expected expected,
        bool no_parens = false)
    {
        if (is_nope_v<Expected>)
            return;
        if (!no_parens)
            os << "(";
        detail::print(os, detail::resolve(context, expected));
        if (!no_parens)
            os << ")";
    }

    template<
        typename Context,
        typename Parser,
        typename DelimiterParser,
        typename MinType,
        typename MaxType>
    void print_parser(
        Context const & context,
        repeat_parser<Parser, DelimiterParser, MinType, MaxType> const & parser,
        std::ostream & os,
        int components)
    {
        if constexpr (is_nope_v<DelimiterParser>) {
            auto const min_ = detail::resolve(context, parser.min_);
            auto const max_ = detail::resolve(context, parser.max_);
            constexpr bool n_ary_child = n_aray_parser_v<Parser>;
            if (min_ == 0 && max_ == Inf) {
                os << "*";
                if (n_ary_child)
                    os << "(";
                detail::print_parser(
                    context, parser.parser_, os, components + 1);
                if (n_ary_child)
                    os << ")";
            } else if (min_ == 1 && max_ == Inf) {
                os << "+";
                if (n_ary_child)
                    os << "(";
                detail::print_parser(
                    context, parser.parser_, os, components + 1);
                if (n_ary_child)
                    os << ")";
            } else {
                os << "repeat(";
                detail::print(os, min_);
                if (min_ == max_) {
                    os << ")[";
                } else {
                    os << ", ";
                    if (max_ == unbounded)
                        os << "Inf";
                    else
                        detail::print(os, max_);
                    os << ")[";
                }
                detail::print_parser(
                    context, parser.parser_, os, components + 1);
                os << "]";
            }
        } else {
            detail::print_parser(context, parser.parser_, os, components + 1);
            os << " % ";
            detail::print_parser(
                context, parser.delimiter_parser_, os, components + 2);
        }
    }

    template<typename Context, typename Parser>
    void print_parser(
        Context const & context,
        opt_parser<Parser> const & parser,
        std::ostream & os,
        int components)
    {
        os << "-";
        constexpr bool n_ary_child = n_aray_parser_v<Parser>;
        if (n_ary_child)
            os << "(";
        detail::print_parser(context, parser.parser_, os, components + 1);
        if (n_ary_child)
            os << ")";
    }

    template<typename Context, typename ParserTuple>
    void print_parser(
        Context const & context,
        or_parser<ParserTuple> const & parser,
        std::ostream & os,
        int components)
    {
        int i = 0;
        bool printed_ellipsis = false;
        hl::for_each(parser.parsers_, [&](auto const & parser) {
            if (components == parser_component_limit) {
                if (!printed_ellipsis)
                    os << " | ...";
                printed_ellipsis = true;
                return;
            }
            if (i)
                os << " | ";
            detail::print_parser(context, parser, os, components);
            ++components;
            ++i;
        });
    }

    template<typename Context, typename ParserTuple, typename BacktrackingTuple>
    void print_parser(
        Context const & context,
        seq_parser<ParserTuple, BacktrackingTuple> const & parser,
        std::ostream & os,
        int components)
    {
        int i = 0;
        bool printed_ellipsis = false;
        hl::for_each(
            hl::zip(parser.parsers_, BacktrackingTuple{}),
            [&](auto const & parser_and_backtrack) {
                using namespace literals;
                auto const & parser = parser::get(parser_and_backtrack, 0_c);
                auto const backtrack = parser::get(parser_and_backtrack, 1_c);

                if (components == parser_component_limit) {
                    if (!printed_ellipsis)
                        os << (backtrack ? " >> ..." : " > ...");
                    printed_ellipsis = true;
                    return;
                }
                if (i)
                    os << (backtrack ? " >> " : " > ");
                detail::print_parser(context, parser, os, components);
                ++components;
                ++i;
            });
    }

    template<typename Context, typename Parser, typename Action>
    void print_parser(
        Context const & context,
        action_parser<Parser, Action> const & parser,
        std::ostream & os,
        int components)
    {
        detail::print_parser(context, parser.parser_, os, components);
        os << "[<<action>>]";
    }

    template<typename Context, typename Parser>
    void print_directive(
        Context const & context,
        std::string_view name,
        Parser const & parser,
        std::ostream & os,
        int components)
    {
        os << name << "[";
        if (++components == parser_component_limit)
            os << "...";
        else
            detail::print_parser(context, parser, os, components + 1);
        os << "]";
    }

    template<typename Context, typename Parser>
    void print_parser(
        Context const & context,
        omit_parser<Parser> const & parser,
        std::ostream & os,
        int components)
    {
        detail::print_directive(
            context, "omit", parser.parser_, os, components);
    }

    template<typename Context, typename Parser>
    void print_parser(
        Context const & context,
        raw_parser<Parser> const & parser,
        std::ostream & os,
        int components)
    {
        detail::print_directive(context, "raw", parser.parser_, os, components);
    }

    template<typename Context, typename Parser>
    void print_parser(
        Context const & context,
        lexeme_parser<Parser> const & parser,
        std::ostream & os,
        int components)
    {
        detail::print_directive(
            context, "lexeme", parser.parser_, os, components);
    }

    template<typename Context, typename Parser, typename SkipParser>
    void print_parser(
        Context const & context,
        skip_parser<Parser, SkipParser> const & parser,
        std::ostream & os,
        int components)
    {
        if constexpr (is_nope_v<SkipParser>) {
            detail::print_directive(
                context, "skip", parser.parser_, os, components);
        } else {
            os << "skip(";
            detail::print_parser(
                context, parser.skip_parser_.parser_, os, components);
            os << ")";
            detail::print_directive(
                context, "", parser.parser_, os, components + 1);
        }
    }

    template<typename Context, typename Parser, bool FailOnMatch>
    void print_parser(
        Context const & context,
        expect_parser<Parser, FailOnMatch> const & parser,
        std::ostream & os,
        int components)
    {
        if (FailOnMatch)
            os << "!";
        else
            os << "&";
        constexpr bool n_ary_child = n_aray_parser_v<Parser>;
        if (n_ary_child)
            os << "(";
        detail::print_parser(context, parser.parser_, os, components + 1);
        if (n_ary_child)
            os << ")";
    }

    template<
        typename Context,
        bool UseCallbacks,
        typename Parser,
        typename Attribute,
        typename LocalState,
        typename ParamsTuple>
    void print_parser(
        Context const & context,
        rule_parser<
            UseCallbacks,
            Parser,
            Attribute,
            LocalState,
            ParamsTuple> const & parser,
        std::ostream & os,
        int components)
    {
        os << parser.name_;
        if constexpr (!is_nope_v<ParamsTuple>) {
            os << ".with(";
            int i = 0;
            hl::for_each(parser.params_, [&](auto const & param) {
                if (i++)
                    os << ", ";
                detail::print_expected(context, os, param, true);
            });
            os << ")";
        }
    }

    template<typename Context, typename T>
    void print_parser(
        Context const & context,
        symbol_parser<T> const & parser,
        std::ostream & os,
        int components)
    {
        os << "symbols<" << detail::type_name<T>() << ">";
    }

    template<typename Context, typename Predicate>
    void print_parser(
        Context const & context,
        eps_parser<Predicate> const & parser,
        std::ostream & os,
        int components)
    {
        os << "eps(<<pred>>)";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        eps_parser<nope> const & parser,
        std::ostream & os,
        int components)
    {
        os << "eps";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        eoi_parser const & parser,
        std::ostream & os,
        int components)
    {
        os << "eoi";
    }

    template<typename Context, typename Atribute>
    void print_parser(
        Context const & context,
        attr_parser<Atribute> const & parser,
        std::ostream & os,
        int components)
    {
        os << "attr";
        detail::print_expected(context, os, parser.attr_);
    }

    template<
        typename Context,
        typename ResolvedExpected,
        bool Integral = std::is_integral<ResolvedExpected>{},
        int SizeofExpected = sizeof(ResolvedExpected)>
    struct print_expected_char_impl
    {
        static void call(
            Context const & context,
            std::ostream & os,
            ResolvedExpected expected)
        {
            detail::print(os, expected);
        }
    };

    template<typename Context, typename Expected>
    struct print_expected_char_impl<Context, Expected, true, 4>
    {
        static void
        call(Context const & context, std::ostream & os, Expected expected)
        {
            std::array<uint32_t, 1> cps = {{(uint32_t)expected}};
            auto const r = text::as_utf8(cps);
            os << "'";
            for (auto c : r) {
                detail::print_char(os, c);
            }
            os << "'";
        }
    };

    template<typename Context, typename Expected>
    void print_expected_char(
        Context const & context, std::ostream & os, Expected expected)
    {
        auto resolved_expected = detail::resolve(context, expected);
        detail::print_expected_char_impl<Context, decltype(resolved_expected)>::
            call(context, os, resolved_expected);
    }

    template<typename Context, typename T>
    struct char_print_parser_impl
    {
        static void call(Context const & context, std::ostream & os, T expected)
        {
            detail::print_expected_char(context, os, expected);
        }
    };

    template<typename Context, typename T, typename U>
    struct char_print_parser_impl<Context, char_pair<T, U>>
    {
        static void call(
            Context const & context,
            std::ostream & os,
            char_pair<T, U> expected)
        {
            detail::print_expected_char(context, os, expected.lo_);
            os << ", ";
            detail::print_expected_char(context, os, expected.hi_);
        }
    };

    template<typename Context, typename Iter, typename Sentinel>
    struct char_print_parser_impl<Context, char_range<Iter, Sentinel>>
    {
        static void call(
            Context const & context,
            std::ostream & os,
            char_range<Iter, Sentinel> expected)
        {
            os << "\"";
            auto const r = text::as_utf8(expected.chars_);
            for (auto c : r) {
                detail::print_char(os, c);
            }
            os << "\"";
        }
    };

    template<typename Context, typename Expected, typename AttributeType>
    void print_parser(
        Context const & context,
        char_parser<Expected, AttributeType> const & parser,
        std::ostream & os,
        int components)
    {
        if (std::is_same_v<
                Expected,
                ascii_char_class<ascii_char_class_t::alnum>>) {
            os << "ascii::alnum";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::alpha>>) {
            os << "ascii::alpha";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::blank>>) {
            os << "ascii::blank";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::cntrl>>) {
            os << "ascii::cntrl";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::digit>>) {
            os << "ascii::digit";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::graph>>) {
            os << "ascii::graph";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::print>>) {
            os << "ascii::print";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::punct>>) {
            os << "ascii::punct";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::space>>) {
            os << "ascii::space";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::xdigit>>) {
            os << "ascii::xdigit";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::lower>>) {
            os << "ascii::lower";
        } else if (std::is_same_v<
                       Expected,
                       ascii_char_class<ascii_char_class_t::upper>>) {
            os << "ascii::upper";
        } else {
            if (std::is_same_v<AttributeType, uint32_t>)
                os << "cp";
            else if (std::is_same_v<AttributeType, char>)
                os << "cu";
            else
                os << "char_";
            if constexpr (!is_nope_v<Expected>) {
                os << "(";
                char_print_parser_impl<Context, Expected>::call(
                    context, os, parser.expected_);
                os << ")";
            }
        }
    }

    template<typename Context, typename Expected, typename AttributeType>
    void print_parser(
        Context const & context,
        omit_parser<char_parser<Expected, AttributeType>> const & parser,
        std::ostream & os,
        int components)
    {
        if constexpr (is_nope_v<Expected>) {
            os << "omit[char_]";
        } else {
            char_print_parser_impl<Context, Expected>::call(
                context, os, parser.parser_.expected_);
        }
    }

    template<typename Context, typename StrIter, typename StrSentinel>
    void print_parser(
        Context const & context,
        string_parser<StrIter, StrSentinel> const & parser,
        std::ostream & os,
        int components)
    {
        os << "string(\"";
        for (auto c :
             text::as_utf8(parser.expected_first_, parser.expected_last_)) {
            detail::print_char(os, c);
        }
        os << "\")";
    }

    template<typename Context, typename StrIter, typename StrSentinel>
    void print_parser(
        Context const & context,
        omit_parser<string_parser<StrIter, StrSentinel>> const & parser,
        std::ostream & os,
        int components)
    {
        os << "\"";
        for (auto c : text::as_utf8(
                 parser.parser_.expected_first_,
                 parser.parser_.expected_last_)) {
            detail::print_char(os, c);
        }
        os << "\"";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        ws_parser<true> const & parser,
        std::ostream & os,
        int components)
    {
        os << "eol";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        ws_parser<false> const & parser,
        std::ostream & os,
        int components)
    {
        os << "ws";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        bool_parser const & parser,
        std::ostream & os,
        int components)
    {
        os << "bool_";
    }

    template<
        typename Context,
        typename T,
        int Radix,
        int MinDigits,
        int MaxDigits,
        typename Expected>
    void print_parser(
        Context const & context,
        uint_parser<T, Radix, MinDigits, MaxDigits, Expected> const & parser,
        std::ostream & os,
        int components)
    {
        if (MinDigits == 1 && MaxDigits == -1) {
            if (std::is_same_v<T, unsigned short>) {
                os << "ushort_";
                detail::print_expected(context, os, parser.expected_);
                return;
            } else if (std::is_same_v<T, unsigned int>) {
                if (Radix == 2)
                    os << "bin";
                else if (Radix == 8)
                    os << "oct";
                else if (Radix == 16)
                    os << "hex";
                else if (Radix == 10)
                    os << "uint_";
                detail::print_expected(context, os, parser.expected_);
                return;
            } else if (Radix == 10 && std::is_same_v<T, unsigned long>) {
                os << "ulong_";
                detail::print_expected(context, os, parser.expected_);
                return;
            } else if (Radix == 10 && std::is_same_v<T, unsigned long long>) {
                os << "ulong_long";
                detail::print_expected(context, os, parser.expected_);
                return;
            }
        }
        os << "uint<" << detail::type_name<T>() << ", " << Radix << ", "
           << MinDigits << ", " << MaxDigits << ">";
        detail::print_expected(context, os, parser.expected_);
    }

    template<
        typename Context,
        typename T,
        int Radix,
        int MinDigits,
        int MaxDigits,
        typename Expected>
    void print_parser(
        Context const & context,
        int_parser<T, Radix, MinDigits, MaxDigits, Expected> const & parser,
        std::ostream & os,
        int components)
    {
        if (Radix == 10 && MinDigits == 1 && MaxDigits == -1) {
            if (std::is_same_v<T, short>) {
                os << "short_";
                detail::print_expected(context, os, parser.expected_);
                return;
            } else if (std::is_same_v<T, int>) {
                os << "int_";
                detail::print_expected(context, os, parser.expected_);
                return;
            } else if (std::is_same_v<T, long>) {
                os << "long_";
                detail::print_expected(context, os, parser.expected_);
                return;
            } else if (std::is_same_v<T, long long>) {
                os << "long_long";
                detail::print_expected(context, os, parser.expected_);
                return;
            }
        }
        os << "int<" << detail::type_name<T>() << ", " << Radix << ", "
           << MinDigits << ", " << MaxDigits << ">";
        detail::print_expected(context, os, parser.expected_);
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        int_parser<short> const & parser,
        std::ostream & os,
        int components)
    {
        os << "short_";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        int_parser<long> const & parser,
        std::ostream & os,
        int components)
    {
        os << "long_";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        int_parser<long long> const & parser,
        std::ostream & os,
        int components)
    {
        os << "long_long";
    }

    template<typename Context, typename T>
    void print_parser(
        Context const & context,
        float_parser<T> const & parser,
        std::ostream & os,
        int components)
    {
        os << "float<" << detail::type_name<T>() << ">";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        float_parser<float> const & parser,
        std::ostream & os,
        int components)
    {
        os << "float_";
    }

    template<typename Context>
    void print_parser(
        Context const & context,
        float_parser<double> const & parser,
        std::ostream & os,
        int components)
    {
        os << "double_";
    }

    template<typename Context, typename ParserTuple, typename BacktrackingTuple>
    void print_switch_matchers(
        Context const & context,
        seq_parser<ParserTuple, BacktrackingTuple> const & parser,
        std::ostream & os,
        int components)
    {
        using namespace literals;

        os << "("
           << detail::resolve(
                  context, parser::get(parser.parsers_, 0_c).pred_.value_)
           << ", ";
        detail::print_parser(
            context, parser::get(parser.parsers_, 1_c), os, components);
        os << ")";
    }

    template<typename Context, typename ParserTuple>
    void print_switch_matchers(
        Context const & context,
        or_parser<ParserTuple> const & parser,
        std::ostream & os,
        int components)
    {
        using namespace literals;

        bool printed_ellipsis = false;
        hl::for_each(parser.parsers_, [&](auto const & parser) {
            if (components == parser_component_limit) {
                if (!printed_ellipsis)
                    os << "...";
                printed_ellipsis = true;
                return;
            }
            detail::print_switch_matchers(context, parser, os, components);
            ++components;
        });
    }

    template<typename Context, typename SwitchValue, typename OrParser>
    void print_parser(
        Context const & context,
        switch_parser<SwitchValue, OrParser> const & parser,
        std::ostream & os,
        int components)
    {
        os << "switch_(";
        detail::print(os, detail::resolve(context, parser.switch_value_));
        os << ")";
        detail::print_switch_matchers(
            context, parser.or_parser_, os, components);
    }

}}}

#endif

ext: hpp

max_stars_repo_name: tzlaine/parser

max_issues_repo_name: tzlaine/parser

max_forks_repo_name: tzlaine/parser


text:
#include <string>
#include <sstream>
#include <iostream>
#include <unistd.h>
#include "ros/ros.h"
#include <ros/transport_hints.h>
#include <stdio.h>

#include <SystemConfig.h>
#include <Configuration.h>
#include <exception>

#include <boost/asio.hpp>
#include <boost/thread.hpp>

#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "flooding_test/TestMessage.h"

using namespace supplementary;

using boost::asio::ip::udp;

std::string ownRosName;
udp::socket* insocket;
udp::endpoint otherEndPoint;
udp::endpoint destEndPoint;
boost::asio::ip::address multiCastAddress;
boost::asio::io_service io_service;
void handleUdpPacket(const boost::system::error_code& error,   std::size_t bytes_transferred);
void listenForPacket();

void onRosTestMessage2326394828(const ros::MessageEvent<flooding_test::TestMessage>& event) {
	if(0 == event.getPublisherName().compare(ownRosName)) return;
uint8_t* buffer = NULL;
	const flooding_test::TestMessage::ConstPtr& message = event.getMessage();
	try{
		uint32_t serial_size = ros::serialization::serializationLength(*message);
		buffer = new uint8_t[serial_size+sizeof(uint32_t)];
		ros::serialization::OStream stream(buffer+sizeof(uint32_t), serial_size);
		*((uint32_t*)buffer) = 2326394828u;
		ros::serialization::serialize(stream, *message);
		// write message to UDP
		insocket->send_to(boost::asio::buffer((void*)buffer,serial_size+sizeof(uint32_t)),destEndPoint);
	} catch(std::exception& e) {
		ROS_ERROR_STREAM_THROTTLE(2,"Exception while sending UDP message:"<<e.what()<< " Discarding message!");
	}
	if(buffer!=NULL) delete[] buffer;
}

ros::Publisher pub2326394828;

boost::array<char,64000> inBuffer;
void listenForPacket() {
	insocket->async_receive_from(boost::asio::buffer(inBuffer), otherEndPoint,
        boost::bind(&handleUdpPacket, boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
void handleUdpPacket(const boost::system::error_code& error,   std::size_t bytes_transferred) {
	//std::cout << "From "<<otherEndPoint.address() << std::endl;
	if (!error) { // && otherEndPoint.address() != localIP) {
		__uint32_t id = *((__uint32_t*)(inBuffer.data()));
		//std::cout << "Got packet"<<std::endl;
		try {
			ros::serialization::IStream stream(((uint8_t*)inBuffer.data())+sizeof(__uint32_t),bytes_transferred-sizeof(__uint32_t));
			switch(id) {
case 2326394828ul: {
flooding_test::TestMessage m2326394828;
ros::serialization::Serializer<flooding_test::TestMessage>::read(stream, m2326394828);
pub2326394828.publish<flooding_test::TestMessage>(m2326394828);
break; }

				default:
					std::cerr << "Cannot find Matching topic:" << id << std::endl;
			}
		}
		catch(std::exception& e) {
			ROS_ERROR_STREAM_THROTTLE(2,"Exception while receiving DDS message:"<<e.what()<< " Discarding message!");
		}

	}
	listenForPacket();
	return;
}
void run() {
	io_service.run();
}

int main (int argc, char *argv[])
{

	SystemConfig* sc = SystemConfig::getInstance();

	//Configuration *proxyconf = (*sc)["UdpProxy"];
Configuration *proxyconf = (*sc)["multicast_test_bridge"];
	//std::string port = proxyconf->get<std::string>("UdpProxy","Port",NULL);

	std::string baddress = proxyconf->get<std::string>("UdpProxy","MulticastAddress",NULL);

	unsigned short port = (unsigned short)proxyconf->get<int>("UdpProxy","Port",NULL);

	//udp::resolver resolver(io_service);
    //udp::resolver::query query(udp::v4(), baddress, port);

	//bcastEndPoint = *resolver.resolve(query);

	//myEndPoint = udp::endpoint(udp::v4(),bcastEndPoint.port());

	multiCastAddress = boost::asio::ip::address::from_string(baddress);
	destEndPoint = udp::endpoint(multiCastAddress,port);

	std::cout<<"Opening to "<<multiCastAddress <<std::endl;

	insocket = new udp::socket(io_service,udp::endpoint(multiCastAddress,port));

	insocket->set_option(boost::asio::ip::multicast::enable_loopback(false));
	insocket->set_option(boost::asio::ip::multicast::join_group(multiCastAddress));
	listenForPacket();

ros::init(argc, argv, "multicast_test_bridge"); //   ros::init(argc, argv, "udpProxy");

    ros::NodeHandle n;
    ownRosName = ros::this_node::getName();//n.getNamespace();//n.resolveName("ddsProxy",true);

    std::cout << ownRosName << std::endl;

ros::Subscriber sub0 = n.subscribe("/flooding_test/TestMessage",5, onRosTestMessage2326394828,ros::TransportHints().unreliable().tcpNoDelay().reliable());

pub2326394828 = n.advertise<flooding_test::TestMessage>("/flooding_test/TestMessage",5,false);

	boost::thread iothread(run);

    //ros::spin();
	ros::AsyncSpinner *spinner;

	spinner = new ros::AsyncSpinner(4);
	spinner->start();

	std::cout << "Ros2Udp Proxy running..." <<std::endl;
    while(n.ok()) {
	    usleep(300000);
    }
    io_service.stop();
    iothread.join();
    return 0;
}

ext: cpp

max_stars_repo_name: carpe-noctem-cassel/cace

max_issues_repo_name: carpe-noctem-cassel/cace

max_forks_repo_name: carpe-noctem-cassel/cace


text:
#include "LowerIntrinsicsPass.hpp"

#include <cassert>
#include <boost/foreach.hpp>
#include <llvm/Module.h>
#include <llvm/Function.h>
#include <llvm/Instructions.h>
#include <llvm/Support/Casting.h>
#include <llvm/Target/TargetData.h>
#include <llvm/CodeGen/IntrinsicLowering.h>
#include "../Util/Logging.hpp"
using llvm::dyn_cast;

namespace ltf
{
    char LowerIntrinsicsPass::ID = 0;

    void LowerIntrinsicsPass::getAnalysisUsage(llvm::AnalysisUsage& usage) const
    {
        // We don't modify blocks or terminator instructions.
        usage.setPreservesCFG();
        usage.addRequired<llvm::TargetData>();
    }

    bool LowerIntrinsicsPass::runOnModule(llvm::Module& module)
    {
        bool hasChanged = false;

        // Collect instructions to lower first.
        std::vector<llvm::CallInst*> intrinsicCalls;

        BOOST_FOREACH (llvm::Function& function, module.getFunctionList())
        {
            if (function.isDeclaration()) continue;

            BOOST_FOREACH (llvm::BasicBlock& block, function.getBasicBlockList())
            {
                BOOST_FOREACH (llvm::Instruction& instruction, block.getInstList())
                {
                    llvm::CallInst* callInstruction =
                        dyn_cast<llvm::CallInst>(&instruction);

                    // Find lowerable intrinsic calls.
                    if (canBeLowered(callInstruction))
                    {
                        intrinsicCalls.push_back(callInstruction);
                    }
                }
            }
        }

        // Create an intrinsic lowering object.
        llvm::TargetData& targetData = getAnalysis<llvm::TargetData>();
        llvm::IntrinsicLowering intrinsicLowering(targetData);

        // Lower intrinsic calls.
        BOOST_FOREACH (llvm::CallInst* instruction, intrinsicCalls)
        {
            llvm::Intrinsic::ID intrinsicId = static_cast<llvm::Intrinsic::ID>(
                instruction->getCalledFunction()->getIntrinsicID()
            );

            log::debug << "Lowering " << llvm::Intrinsic::getName(
                intrinsicId) << " intrinsic" << log::end;

            // Actually lower the call.
            intrinsicLowering.LowerIntrinsicCall(instruction);

            hasChanged = true;
        }

        return hasChanged;
    }

    bool LowerIntrinsicsPass::canBeLowered(llvm::CallInst* instruction)
    {
        if (instruction == 0) return false;
        const llvm::Function* calledFunction = instruction->getCalledFunction();

        // Only process calls to intrinsics.
        if ((calledFunction == 0) || !calledFunction->isIntrinsic()) return false;

        // These are basically all calls that the IntrinsicLowering object can
        // lower and that are not directly supported.
        switch (calledFunction->getIntrinsicID())
        {
        // Lower intrinsics to function calls.
        case llvm::Intrinsic::memcpy:  return true;
        case llvm::Intrinsic::memset:  return true;
        case llvm::Intrinsic::memmove: return true;
        case llvm::Intrinsic::sqrt:    return true;
        case llvm::Intrinsic::sin:     return true;
        case llvm::Intrinsic::cos:     return true;
        case llvm::Intrinsic::pow:     return true;
        case llvm::Intrinsic::log:     return true;
        case llvm::Intrinsic::log2:    return true;
        case llvm::Intrinsic::log10:   return true;
        case llvm::Intrinsic::exp:     return true;
        case llvm::Intrinsic::exp2:    return true;

        // [TODO] Check, which could be done directly in firm.
        case llvm::Intrinsic::ctpop:   return true;
        case llvm::Intrinsic::bswap:   return true;
        case llvm::Intrinsic::ctlz:    return true;
        case llvm::Intrinsic::cttz:    return true;

        // According to IntrinsicLowering.cpp, these should only
        // appear in totally unoptimized code. Make sure to get rid
        // off them in any case.
        case llvm::Intrinsic::setjmp:     return true;
        case llvm::Intrinsic::longjmp:    return true;
        case llvm::Intrinsic::siglongjmp: return true;
        }

        return false;
    }
}

max_stars_repo_name: libfirm/LlvmToFirm

max_issues_repo_name: libfirm/LlvmToFirm

max_forks_repo_name: libfirm/LlvmToFirm


text:
#include <chratos/lib/blocks.hpp>

#include <boost/endian/conversion.hpp>

/** Compare blocks, first by type, then content. This is an optimization over dynamic_cast, which is very slow on some platforms. */
namespace
{
template <typename T>
bool blocks_equal (T const & first, chratos::block const & second)
{
	static_assert (std::is_base_of<chratos::block, T>::value, "Input parameter is not a block type");
	return (first.type () == second.type ()) && (static_cast<T const &> (second)) == first;
}
}

std::string chratos::to_string_hex (uint64_t value_a)
{
	std::stringstream stream;
	stream << std::hex << std::noshowbase << std::setw (16) << std::setfill ('0');
	stream << value_a;
	return stream.str ();
}

bool chratos::from_string_hex (std::string const & value_a, uint64_t & target_a)
{
	auto error (value_a.empty ());
	if (!error)
	{
		error = value_a.size () > 16;
		if (!error)
		{
			std::stringstream stream (value_a);
			stream << std::hex << std::noshowbase;
			try
			{
				uint64_t number_l;
				stream >> number_l;
				target_a = number_l;
				if (!stream.eof ())
				{
					error = true;
				}
			}
			catch (std::runtime_error &)
			{
				error = true;
			}
		}
	}
	return error;
}

std::string chratos::block::to_json ()
{
	std::string result;
	serialize_json (result);
	return result;
}

chratos::block_hash chratos::block::hash () const
{
	chratos::uint256_union result;
	blake2b_state hash_l;
	auto status (blake2b_init (&hash_l, sizeof (result.bytes)));
	assert (status == 0);
	hash (hash_l);
	status = blake2b_final (&hash_l, result.bytes.data (), sizeof (result.bytes));
	assert (status == 0);
	return result;
}
chratos::state_hashables::state_hashables (chratos::account const & account_a, chratos::block_hash const & previous_a, chratos::account const & representative_a, chratos::amount const & balance_a, chratos::uint256_union const & link_a, chratos::block_hash const & dividend_a) :
account (account_a),
previous (previous_a),
representative (representative_a),
balance (balance_a),
link (link_a),
dividend (dividend_a)
{
}

chratos::state_hashables::state_hashables (bool & error_a, chratos::stream & stream_a)
{
	error_a = chratos::read (stream_a, account);
	if (!error_a)
	{
		error_a = chratos::read (stream_a, previous);
		if (!error_a)
		{
			error_a = chratos::read (stream_a, representative);
			if (!error_a)
			{
				error_a = chratos::read (stream_a, balance);
				if (!error_a)
				{
					error_a = chratos::read (stream_a, link);
					if (!error_a)
					{
						error_a = chratos::read (stream_a, dividend.bytes);
					}
				}
			}
		}
	}
}

chratos::state_hashables::state_hashables (bool & error_a, boost::property_tree::ptree const & tree_a)
{
	try
	{
		auto account_l (tree_a.get<std::string> ("account"));
		auto previous_l (tree_a.get<std::string> ("previous"));
		auto representative_l (tree_a.get<std::string> ("representative"));
		auto balance_l (tree_a.get<std::string> ("balance"));
		auto link_l (tree_a.get<std::string> ("link"));
		auto dividend_l (tree_a.get<std::string> ("dividend"));
		error_a = account.decode_account (account_l);
		if (!error_a)
		{
			error_a = previous.decode_hex (previous_l);
			if (!error_a)
			{
				error_a = representative.decode_account (representative_l);
				if (!error_a)
				{
					error_a = balance.decode_dec (balance_l);
					if (!error_a)
					{
						error_a = link.decode_account (link_l) && link.decode_hex (link_l);
						if (!error_a)
						{
							error_a = dividend.decode_hex (dividend_l);
						}
					}
				}
			}
		}
	}
	catch (std::runtime_error const &)
	{
		error_a = true;
	}
}

void chratos::state_hashables::hash (blake2b_state & hash_a) const
{
	blake2b_update (&hash_a, account.bytes.data (), sizeof (account.bytes));
	blake2b_update (&hash_a, previous.bytes.data (), sizeof (previous.bytes));
	blake2b_update (&hash_a, representative.bytes.data (), sizeof (representative.bytes));
	blake2b_update (&hash_a, balance.bytes.data (), sizeof (balance.bytes));
	blake2b_update (&hash_a, link.bytes.data (), sizeof (link.bytes));
	blake2b_update (&hash_a, dividend.bytes.data (), sizeof (dividend.bytes));
}

chratos::state_block::state_block (chratos::account const & account_a, chratos::block_hash const & previous_a, chratos::account const & representative_a, chratos::amount const & balance_a, chratos::uint256_union const & link_a, chratos::block_hash const & dividend_a, chratos::raw_key const & prv_a, chratos::public_key const & pub_a, uint64_t work_a) :
hashables (account_a, previous_a, representative_a, balance_a, link_a, dividend_a),
signature (chratos::sign_message (prv_a, pub_a, hash ())),
work (work_a)
{
}

chratos::state_block::state_block (bool & error_a, chratos::stream & stream_a) :
hashables (error_a, stream_a)
{
	if (!error_a)
	{
		error_a = chratos::read (stream_a, signature);
		if (!error_a)
		{
			error_a = chratos::read (stream_a, work);
			boost::endian::big_to_native_inplace (work);
		}
	}
}

chratos::state_block::state_block (bool & error_a, boost::property_tree::ptree const & tree_a) :
hashables (error_a, tree_a)
{
	if (!error_a)
	{
		try
		{
			auto type_l (tree_a.get<std::string> ("type"));
			auto signature_l (tree_a.get<std::string> ("signature"));
			auto work_l (tree_a.get<std::string> ("work"));
			error_a = type_l != "state";
			if (!error_a)
			{
				error_a = chratos::from_string_hex (work_l, work);
				if (!error_a)
				{
					error_a = signature.decode_hex (signature_l);
				}
			}
		}
		catch (std::runtime_error const &)
		{
			error_a = true;
		}
	}
}

void chratos::state_block::hash (blake2b_state & hash_a) const
{
	chratos::uint256_union preamble (static_cast<uint64_t> (chratos::block_type::state));
	blake2b_update (&hash_a, preamble.bytes.data (), preamble.bytes.size ());
	hashables.hash (hash_a);
}

uint64_t chratos::state_block::block_work () const
{
	return work;
}

void chratos::state_block::block_work_set (uint64_t work_a)
{
	work = work_a;
}

chratos::block_hash chratos::state_block::previous () const
{
	return hashables.previous;
}

void chratos::state_block::serialize (chratos::stream & stream_a) const
{
	write (stream_a, hashables.account);
	write (stream_a, hashables.previous);
	write (stream_a, hashables.representative);
	write (stream_a, hashables.balance);
	write (stream_a, hashables.link);
	write (stream_a, hashables.dividend);
	write (stream_a, signature);
	write (stream_a, boost::endian::native_to_big (work));
}

void chratos::state_block::serialize_json (std::string & string_a) const
{
	boost::property_tree::ptree tree;
	tree.put ("type", "state");
	tree.put ("account", hashables.account.to_account ());
	tree.put ("previous", hashables.previous.to_string ());
	tree.put ("representative", representative ().to_account ());
	tree.put ("balance", hashables.balance.to_string_dec ());
	tree.put ("link", hashables.link.to_string ());
	tree.put ("link_as_account", hashables.link.to_account ());
	tree.put ("dividend", hashables.dividend.to_string ());
	std::string signature_l;
	signature.encode_hex (signature_l);
	tree.put ("signature", signature_l);
	tree.put ("work", chratos::to_string_hex (work));
	std::stringstream ostream;
	boost::property_tree::write_json (ostream, tree);
	string_a = ostream.str ();
}

bool chratos::state_block::deserialize (chratos::stream & stream_a)
{
	auto error (read (stream_a, hashables.account));
	if (!error)
	{
		error = read (stream_a, hashables.previous);
		if (!error)
		{
			error = read (stream_a, hashables.representative);
			if (!error)
			{
				error = read (stream_a, hashables.balance);
				if (!error)
				{
					error = read (stream_a, hashables.link);
					if (!error)
					{
						error = read (stream_a, hashables.dividend);
						if (!error)
						{
							error = read (stream_a, signature);
							if (!error)
							{
								error = read (stream_a, work);
								boost::endian::big_to_native_inplace (work);
							}
						}
					}
				}
			}
		}
	}
	return error;
}

bool chratos::state_block::deserialize_json (boost::property_tree::ptree const & tree_a)
{
	auto error (false);
	try
	{
		assert (tree_a.get<std::string> ("type") == "state");
		auto account_l (tree_a.get<std::string> ("account"));
		auto previous_l (tree_a.get<std::string> ("previous"));
		auto representative_l (tree_a.get<std::string> ("representative"));
		auto balance_l (tree_a.get<std::string> ("balance"));
		auto link_l (tree_a.get<std::string> ("link"));
		auto dividend_l (tree_a.get<std::string> ("dividend"));
		auto work_l (tree_a.get<std::string> ("work"));
		auto signature_l (tree_a.get<std::string> ("signature"));
		error = hashables.account.decode_account (account_l);
		if (!error)
		{
			error = hashables.previous.decode_hex (previous_l);
			if (!error)
			{
				error = hashables.representative.decode_account (representative_l);
				if (!error)
				{
					error = hashables.balance.decode_dec (balance_l);
					if (!error)
					{
						error = hashables.link.decode_account (link_l) && hashables.link.decode_hex (link_l);
						if (!error)
						{
							error = chratos::from_string_hex (work_l, work);
							if (!error)
							{
								error = signature.decode_hex (signature_l);
								if (!error)
								{
									error = hashables.dividend.decode_hex (dividend_l);
								}
							}
						}
					}
				}
			}
		}
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}
	return error;
}

void chratos::state_block::visit (chratos::block_visitor & visitor_a) const
{
	visitor_a.state_block (*this);
}

chratos::block_type chratos::state_block::type () const
{
	return chratos::block_type::state;
}

bool chratos::state_block::operator== (chratos::block const & other_a) const
{
	return blocks_equal (*this, other_a);
}

bool chratos::state_block::operator== (chratos::state_block const & other_a) const
{
	return hashables.account == other_a.hashables.account && hashables.previous == other_a.hashables.previous && hashables.representative == other_a.hashables.representative && hashables.balance == other_a.hashables.balance && hashables.link == other_a.hashables.link && hashables.dividend == other_a.hashables.dividend && signature == other_a.signature && work == other_a.work;
}

bool chratos::state_block::valid_predecessor (chratos::block const & block_a) const
{
	return true;
}

chratos::block_hash chratos::state_block::source () const
{
	return 0;
}

chratos::block_hash chratos::state_block::root () const
{
	return !hashables.previous.is_zero () ? hashables.previous : hashables.account;
}

chratos::block_hash chratos::state_block::dividend () const
{
	return hashables.dividend;
}

chratos::block_hash chratos::state_block::link () const
{
	return hashables.link;
}

chratos::account chratos::state_block::representative () const
{
	return hashables.representative;
}

chratos::account chratos::state_block::account () const
{
  return hashables.account;
}

chratos::signature chratos::state_block::block_signature () const
{
	return signature;
}

void chratos::state_block::signature_set (chratos::uint512_union const & signature_a)
{
	signature = signature_a;
}

std::unique_ptr<chratos::block> chratos::deserialize_block_json (boost::property_tree::ptree const & tree_a)
{
	std::unique_ptr<chratos::block> result;
	try
	{
		auto type (tree_a.get<std::string> ("type"));
		if (type == "state")
		{
			bool error (false);
			std::unique_ptr<chratos::state_block> obj (new chratos::state_block (error, tree_a));
			if (!error)
			{
				result = std::move (obj);
			}
		}
		else if (type == "dividend")
		{
			bool error (false);
			std::unique_ptr<chratos::dividend_block> obj (new chratos::dividend_block (error, tree_a));
			if (!error)
			{
				result = std::move (obj);
			}
		}
		else if (type == "claim")
		{
			bool error (false);
			std::unique_ptr<chratos::claim_block> obj (new chratos::claim_block (error, tree_a));
			if (!error)
			{
				result = std::move (obj);
			}
		}
	}
	catch (std::runtime_error const &)
	{
	}
	return result;
}

std::unique_ptr<chratos::block> chratos::deserialize_block (chratos::stream & stream_a)
{
	chratos::block_type type;
	auto error (read (stream_a, type));
	std::unique_ptr<chratos::block> result;
	if (!error)
	{
		result = chratos::deserialize_block (stream_a, type);
	}
	return result;
}

std::unique_ptr<chratos::block> chratos::deserialize_block (chratos::stream & stream_a, chratos::block_type type_a)
{
	std::unique_ptr<chratos::block> result;
	switch (type_a)
	{
		case chratos::block_type::state:
		{
			bool error (false);
			std::unique_ptr<chratos::state_block> obj (new chratos::state_block (error, stream_a));
			if (!error)
			{
				result = std::move (obj);
			}
			break;
		}
		case chratos::block_type::dividend:
		{
			bool error (false);
			std::unique_ptr<chratos::dividend_block> obj (new chratos::dividend_block (error, stream_a));
			if (!error)
			{
				result = std::move (obj);
			}
			break;
		}
		case chratos::block_type::claim:
		{
			bool error (false);
			std::unique_ptr<chratos::claim_block> obj (new chratos::claim_block (error, stream_a));
			if (!error)
			{
				result = std::move (obj);
			}
			break;
		}
		default:
			assert (false);
			break;
	}
	return result;
}
void chratos::dividend_block::visit (chratos::block_visitor & visitor_a) const
{
	visitor_a.dividend_block (*this);
}

void chratos::dividend_block::hash (blake2b_state & hash_a) const
{
	chratos::uint256_union preamble (static_cast<uint64_t> (chratos::block_type::dividend));
	blake2b_update (&hash_a, preamble.bytes.data (), preamble.bytes.size ());
	hashables.hash (hash_a);
}

uint64_t chratos::dividend_block::block_work () const
{
	return work;
}

void chratos::dividend_block::block_work_set (uint64_t work_a)
{
	work = work_a;
}

chratos::dividend_hashables::dividend_hashables (chratos::account const & account_a, chratos::block_hash const & previous_a, chratos::account const & representative_a, chratos::amount const & balance_a, const chratos::block_hash & dividend_a) :
account (account_a),
previous (previous_a),
representative (representative_a),
balance (balance_a),
dividend (dividend_a)
{
}

chratos::dividend_hashables::dividend_hashables (bool & error_a, chratos::stream & stream_a)
{
	error_a = chratos::read (stream_a, account);
	if (!error_a)
	{
		error_a = chratos::read (stream_a, previous);
		if (!error_a)
		{
			error_a = chratos::read (stream_a, representative);
			if (!error_a)
			{
				error_a = chratos::read (stream_a, balance);
				if (!error_a)
				{
					error_a = chratos::read (stream_a, dividend);
				}
			}
		}
	}
}

chratos::dividend_hashables::dividend_hashables (bool & error_a, boost::property_tree::ptree const & tree_a)
{
	try
	{
		auto account_l (tree_a.get<std::string> ("account"));
		auto previous_l (tree_a.get<std::string> ("previous"));
		auto representative_l (tree_a.get<std::string> ("representative"));
		auto balance_l (tree_a.get<std::string> ("balance"));
		auto dividend_l (tree_a.get<std::string> ("dividend"));
		error_a = account.decode_account (account_l);
		if (!error_a)
		{
			error_a = previous.decode_hex (previous_l);
			if (!error_a)
			{
				error_a = representative.decode_account (representative_l);
				if (!error_a)
				{
					error_a = balance.decode_dec (balance_l);
					if (!error_a)
					{
						error_a = dividend.decode_hex (dividend_l);
					}
				}
			}
		}
	}
	catch (std::runtime_error const &)
	{
		error_a = true;
	}
}

void chratos::dividend_hashables::hash (blake2b_state & hash_a) const
{
	blake2b_update (&hash_a, account.bytes.data (), sizeof (account.bytes));
	blake2b_update (&hash_a, previous.bytes.data (), sizeof (previous.bytes));
	blake2b_update (&hash_a, representative.bytes.data (), sizeof (representative.bytes));
	blake2b_update (&hash_a, balance.bytes.data (), sizeof (balance.bytes));
	blake2b_update (&hash_a, dividend.bytes.data (), sizeof (dividend.bytes));
}

void chratos::dividend_block::serialize (chratos::stream & stream_a) const
{
	write (stream_a, hashables.account);
	write (stream_a, hashables.previous);
	write (stream_a, hashables.representative);
	write (stream_a, hashables.balance);
	write (stream_a, hashables.dividend);
	write (stream_a, signature);
	write (stream_a, boost::endian::native_to_big (work));
}

void chratos::dividend_block::serialize_json (std::string & string_a) const
{
	boost::property_tree::ptree tree;
	tree.put ("type", "dividend");
	tree.put ("account", hashables.account.to_account ());
	tree.put ("previous", hashables.previous.to_string ());
	tree.put ("representative", representative ().to_account ());
	tree.put ("balance", hashables.balance.to_string_dec ());
	tree.put ("dividend", hashables.dividend.to_string ());
	std::string signature_l;
	signature.encode_hex (signature_l);
	tree.put ("signature", signature_l);
	tree.put ("work", chratos::to_string_hex (work));
	std::stringstream ostream;
	boost::property_tree::write_json (ostream, tree);
	string_a = ostream.str ();
}

bool chratos::dividend_block::deserialize (chratos::stream & stream_a)
{
	auto error (read (stream_a, hashables.account));
	if (!error)
	{
		error = read (stream_a, hashables.previous);
		if (!error)
		{
			error = read (stream_a, hashables.representative);
			if (!error)
			{
				error = read (stream_a, hashables.balance);
				if (!error)
				{
					error = read (stream_a, hashables.dividend);
					if (!error)
					{
						error = read (stream_a, signature);
						if (!error)
						{
							error = read (stream_a, work);
							boost::endian::big_to_native_inplace (work);
						}
					}
				}
			}
		}
	}
	return error;
}

bool chratos::dividend_block::deserialize_json (boost::property_tree::ptree const & tree_a)
{
	auto error (false);
	try
	{
		assert (tree_a.get<std::string> ("type") == "dividend");
		auto account_l (tree_a.get<std::string> ("account"));
		auto previous_l (tree_a.get<std::string> ("previous"));
		auto representative_l (tree_a.get<std::string> ("representative"));
		auto balance_l (tree_a.get<std::string> ("balance"));
		auto dividend_l (tree_a.get<std::string> ("dividend"));
		auto work_l (tree_a.get<std::string> ("work"));
		auto signature_l (tree_a.get<std::string> ("signature"));
		error = hashables.account.decode_account (account_l);
		if (!error)
		{
			error = hashables.previous.decode_hex (previous_l);
			if (!error)
			{
				error = hashables.representative.decode_account (representative_l);
				if (!error)
				{
					error = hashables.balance.decode_dec (balance_l);
					if (!error)
					{
						error = chratos::from_string_hex (work_l, work);
						if (!error)
						{
							error = signature.decode_hex (signature_l);
							if (!error)
							{
								error = hashables.dividend.decode_hex (dividend_l);
							}
						}
					}
				}
			}
		}
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}
	return error;
}

chratos::dividend_block::dividend_block (chratos::account const & account_a, chratos::block_hash const & previous_a, chratos::account const & representative_a, chratos::amount const & balance_a, chratos::block_hash const & dividend_a, chratos::raw_key const & prv_a, chratos::public_key const & pub_a, uint64_t work_a) :
hashables (account_a, previous_a, representative_a, balance_a, dividend_a),
signature (chratos::sign_message (prv_a, pub_a, hash ())),
work (work_a)
{
}

chratos::dividend_block::dividend_block (bool & error_a, chratos::stream & stream_a) :
hashables (error_a, stream_a)
{
	if (!error_a)
	{
		error_a = chratos::read (stream_a, signature.bytes);
		if (!error_a)
		{
			error_a = chratos::read (stream_a, work);
			boost::endian::big_to_native_inplace (work);
		}
	}
}

chratos::dividend_block::dividend_block (bool & error_a, boost::property_tree::ptree const & tree_a) :
hashables (error_a, tree_a)
{
	if (!error_a)
	{
		try
		{
			auto signature_l (tree_a.get<std::string> ("signature"));
			auto work_l (tree_a.get<std::string> ("work"));
			error_a = signature.decode_hex (signature_l);
			if (!error_a)
			{
				error_a = chratos::from_string_hex (work_l, work);
			}
		}
		catch (std::runtime_error const &)
		{
			error_a = true;
		}
	}
}

bool chratos::dividend_block::operator== (chratos::block const & other_a) const
{
	return blocks_equal (*this, other_a);
}

bool chratos::dividend_block::valid_predecessor (chratos::block const & block_a) const
{
	return true;
}

chratos::block_type chratos::dividend_block::type () const
{
	return chratos::block_type::dividend;
}

bool chratos::dividend_block::operator== (chratos::dividend_block const & other_a) const
{
	auto result (hashables.account == other_a.hashables.account && hashables.previous == other_a.hashables.previous && hashables.balance == other_a.hashables.balance && hashables.dividend == other_a.hashables.dividend && work == other_a.work && signature == other_a.signature);
	return result;
}

chratos::block_hash chratos::dividend_block::previous () const
{
	return hashables.previous;
}

chratos::block_hash chratos::dividend_block::source () const
{
	return hashables.account;
}

chratos::block_hash chratos::dividend_block::root () const
{
	return hashables.previous;
}

chratos::block_hash chratos::dividend_block::dividend () const
{
	return hashables.dividend;
}

chratos::block_hash chratos::dividend_block::link () const
{
	return 0;
}

chratos::account chratos::dividend_block::representative () const
{
	return hashables.representative;
}

chratos::account chratos::dividend_block::account () const
{
  return hashables.account;
}

chratos::signature chratos::dividend_block::block_signature () const
{
	return signature;
}

void chratos::dividend_block::signature_set (chratos::uint512_union const & signature_a)
{
	signature = signature_a;
}

void chratos::claim_block::visit (chratos::block_visitor & visitor_a) const
{
	visitor_a.claim_block (*this);
}

void chratos::claim_block::hash (blake2b_state & hash_a) const
{
	chratos::uint256_union preamble (static_cast<uint64_t> (chratos::block_type::claim));
	blake2b_update (&hash_a, preamble.bytes.data (), preamble.bytes.size ());
	hashables.hash (hash_a);
}

uint64_t chratos::claim_block::block_work () const
{
	return work;
}

void chratos::claim_block::block_work_set (uint64_t work_a)
{
	work = work_a;
}

chratos::claim_hashables::claim_hashables (chratos::account const & account_a, chratos::block_hash const & previous_a, chratos::account const & representative_a, chratos::amount const & balance_a, const chratos::block_hash & dividend_a) :
account (account_a),
previous (previous_a),
representative (representative_a),
balance (balance_a),
dividend (dividend_a)
{
}

chratos::claim_hashables::claim_hashables (bool & error_a, chratos::stream & stream_a)
{
	error_a = chratos::read (stream_a, account);
	if (!error_a)
	{
		error_a = chratos::read (stream_a, previous);
		if (!error_a)
		{
			error_a = chratos::read (stream_a, representative);
			if (!error_a)
			{
				error_a = chratos::read (stream_a, balance);
				if (!error_a)
				{
					error_a = chratos::read (stream_a, dividend);
				}
			}
		}
	}
}

chratos::claim_hashables::claim_hashables (bool & error_a, boost::property_tree::ptree const & tree_a)
{
	try
	{
		auto account_l (tree_a.get<std::string> ("account"));
		auto previous_l (tree_a.get<std::string> ("previous"));
		auto representative_l (tree_a.get<std::string> ("representative"));
		auto balance_l (tree_a.get<std::string> ("balance"));
		auto dividend_l (tree_a.get<std::string> ("dividend"));
		error_a = account.decode_account (account_l);
		if (!error_a)
		{
			error_a = previous.decode_hex (previous_l);
			if (!error_a)
			{
				error_a = representative.decode_account (representative_l);
				if (!error_a)
				{
					error_a = balance.decode_dec (balance_l);
					if (!error_a)
					{
						error_a = dividend.decode_hex (dividend_l);
					}
				}
			}
		}
	}
	catch (std::runtime_error const &)
	{
		error_a = true;
	}
}

void chratos::claim_hashables::hash (blake2b_state & hash_a) const
{
	auto status (blake2b_update (&hash_a, account.bytes.data (), sizeof (account.bytes)));
	assert (status == 0);
	status = blake2b_update (&hash_a, previous.bytes.data (), sizeof (previous.bytes));
	assert (status == 0);
	status = blake2b_update (&hash_a, representative.bytes.data (), sizeof (representative.bytes));
	assert (status == 0);
	status = blake2b_update (&hash_a, balance.bytes.data (), sizeof (balance.bytes));
	assert (status == 0);
	status = blake2b_update (&hash_a, dividend.bytes.data (), sizeof (dividend.bytes));
	assert (status == 0);
}

void chratos::claim_block::serialize (chratos::stream & stream_a) const
{
	write (stream_a, hashables.account);
	write (stream_a, hashables.previous);
	write (stream_a, hashables.representative);
	write (stream_a, hashables.balance);
	write (stream_a, hashables.dividend);
	write (stream_a, signature);
	write (stream_a, boost::endian::native_to_big (work));
}

void chratos::claim_block::serialize_json (std::string & string_a) const
{
	boost::property_tree::ptree tree;
	tree.put ("type", "claim");
	tree.put ("account", hashables.account.to_account ());
	tree.put ("previous", hashables.previous.to_string ());
	tree.put ("representative", representative ().to_account ());
	tree.put ("balance", hashables.balance.to_string_dec ());
	tree.put ("dividend", hashables.dividend.to_string ());
	std::string signature_l;
	signature.encode_hex (signature_l);
	tree.put ("signature", signature_l);
	tree.put ("work", chratos::to_string_hex (work));
	std::stringstream ostream;
	boost::property_tree::write_json (ostream, tree);
	string_a = ostream.str ();
}

bool chratos::claim_block::deserialize (chratos::stream & stream_a)
{
	auto error (read (stream_a, hashables.account));
	if (!error)
	{
		error = read (stream_a, hashables.previous);
		if (!error)
		{
			error = read (stream_a, hashables.representative);
			if (!error)
			{
				error = read (stream_a, hashables.balance);
				if (!error)
				{
					error = read (stream_a, hashables.dividend);
					if (!error)
					{
						error = read (stream_a, signature);
						if (!error)
						{
							error = read (stream_a, work);
							boost::endian::big_to_native_inplace (work);
						}
					}
				}
			}
		}
	}
	return error;
}

bool chratos::claim_block::deserialize_json (boost::property_tree::ptree const & tree_a)
{
	auto error (false);
	try
	{
		assert (tree_a.get<std::string> ("type") == "dividend");
		auto account_l (tree_a.get<std::string> ("account"));
		auto previous_l (tree_a.get<std::string> ("previous"));
		auto representative_l (tree_a.get<std::string> ("representative"));
		auto balance_l (tree_a.get<std::string> ("balance"));
		auto dividend_l (tree_a.get<std::string> ("dividend"));
		auto work_l (tree_a.get<std::string> ("work"));
		auto signature_l (tree_a.get<std::string> ("signature"));
		error = hashables.account.decode_account (account_l);
		if (!error)
		{
			error = hashables.previous.decode_hex (previous_l);
			if (!error)
			{
				error = hashables.representative.decode_account (representative_l);
				if (!error)
				{
					error = hashables.balance.decode_dec (balance_l);
					if (!error)
					{
						error = chratos::from_string_hex (work_l, work);
						if (!error)
						{
							error = signature.decode_hex (signature_l);
							if (!error)
							{
								error = hashables.dividend.decode_hex (dividend_l);
							}
						}
					}
				}
			}
		}
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}
	return error;
}

chratos::claim_block::claim_block (chratos::account const & account_a, chratos::block_hash const & previous_a, chratos::account const & representative_a, chratos::amount const & balance_a, chratos::block_hash const & dividend_a, chratos::raw_key const & prv_a, chratos::public_key const & pub_a, uint64_t work_a) :
hashables (account_a, previous_a, representative_a, balance_a, dividend_a),
signature (chratos::sign_message (prv_a, pub_a, hash ())),
work (work_a)
{
}

chratos::claim_block::claim_block (bool & error_a, chratos::stream & stream_a) :
hashables (error_a, stream_a)
{
	if (!error_a)
	{
		error_a = chratos::read (stream_a, signature.bytes);
		if (!error_a)
		{
			error_a = chratos::read (stream_a, work);
			boost::endian::big_to_native_inplace (work);
		}
	}
}

chratos::claim_block::claim_block (bool & error_a, boost::property_tree::ptree const & tree_a) :
hashables (error_a, tree_a)
{
	if (!error_a)
	{
		try
		{
			auto signature_l (tree_a.get<std::string> ("signature"));
			auto work_l (tree_a.get<std::string> ("work"));
			error_a = signature.decode_hex (signature_l);
			if (!error_a)
			{
				error_a = chratos::from_string_hex (work_l, work);
			}
		}
		catch (std::runtime_error const &)
		{
			error_a = true;
		}
	}
}

bool chratos::claim_block::operator== (chratos::block const & other_a) const
{
	return blocks_equal (*this, other_a);
}

bool chratos::claim_block::valid_predecessor (chratos::block const & block_a) const
{
	return true;
}

chratos::block_type chratos::claim_block::type () const
{
	return chratos::block_type::claim;
}

bool chratos::claim_block::operator== (chratos::claim_block const & other_a) const
{
	auto result (hashables.account == other_a.hashables.account && hashables.previous == other_a.hashables.previous && hashables.balance == other_a.hashables.balance && hashables.dividend == other_a.hashables.dividend && work == other_a.work && signature == other_a.signature);
	return result;
}

chratos::block_hash chratos::claim_block::previous () const
{
	return hashables.previous;
}

chratos::block_hash chratos::claim_block::source () const
{
	return hashables.account;
}

chratos::block_hash chratos::claim_block::root () const
{
	return hashables.previous;
}

chratos::block_hash chratos::claim_block::dividend () const
{
	return hashables.dividend;
}

chratos::block_hash chratos::claim_block::link () const
{
	return 0;
}

chratos::account chratos::claim_block::representative () const
{
	return hashables.representative;
}

chratos::account chratos::claim_block::account () const
{
  return hashables.account;
}

chratos::signature chratos::claim_block::block_signature () const
{
	return signature;
}

void chratos::claim_block::signature_set (chratos::uint512_union const & signature_a)
{
	signature = signature_a;
}

max_stars_repo_name: chratos-system/chratos

max_issues_repo_name: chratos-system/chratos

max_forks_repo_name: chratos-system/chratos


text:
#include <boost/test/unit_test.hpp>
#include <iostream>

#include "amount.h"
#include "arith_uint256.h"
#include "key.h"
#include "utiltime.h"
#include "primitives/block.h"

#include "mn-pos/kernel.h"
#include "mn-pos/stakeminer.h"
#include "mn-pos/stakevalidation.h"

BOOST_AUTO_TEST_SUITE(staking_tests)

BOOST_AUTO_TEST_CASE(stakeminer)
{
    //Make a kernel with some fake data
    std::pair<uint256, unsigned int> outpoint = std::make_pair(uint256S("99999"), 0);
    uint256 nModifier = uint256S("123456");
    unsigned int nTimeBlockFrom = 100000;
    unsigned int nTimeStake = nTimeBlockFrom + (60*60*48);
    uint64_t nAmount = 10000;
    Kernel kernel(outpoint, nAmount, nModifier, nTimeBlockFrom, nTimeStake);

    //A moderately easy difficulty target to hit
    arith_uint256 aTarget;
    aTarget = ~aTarget;
    aTarget >>= 14;
    uint256 nTarget = ArithToUint256(aTarget);

    //Start searching from the current time and do not stop until a valid hash is found
    uint64_t nSearchStart = GetTime();
    bool found = false;
    while (!found)
    {
        uint64_t nSearchEnd = nSearchStart + 180;
        found = SearchTimeSpan(kernel, nSearchStart, nSearchStart + 180, nTarget);
        nSearchStart = nSearchEnd + 1;
    }

    BOOST_CHECK_MESSAGE(kernel.IsValidProof(nTarget), "did not find a valid kernel");
}

BOOST_AUTO_TEST_CASE(proof_validity)
{
    uint64_t nAmount = 10000 * COIN; //10,000 coins is the amount for a masternode

    arith_uint256 target;
    target = ~target;
    target >>= 8; //0x00F

    uint256 hashReq = uint256S("00ffffffffffffffffffffffffffffffffffffffffffffffffffff8463423000");
    arith_uint256 hash = UintToArith256(hashReq) - 1;
    target /= nAmount; //Need to compare the hash divided by the amount because it gets multiplied inside the check

    BOOST_CHECK_MESSAGE(Kernel::CheckProof(target, hash, nAmount), "failed to pass hash proof that is valid");
    BOOST_CHECK_MESSAGE(!Kernel::CheckProof(target, hash + 1, nAmount), "hash that is equal to target was considered valid proof hash");
    BOOST_CHECK_MESSAGE(!Kernel::CheckProof(target, hash + 2, nAmount), "hash that is greater than target was considered valid proof hash");
}

BOOST_AUTO_TEST_CASE(transaction_type)
{
    CTxIn txIn;
    txIn.scriptSig << OP_PROOFOFSTAKE << 10000 << OP_0;
    CMutableTransaction tx;
    tx.vin.emplace_back(txIn);
    tx.vout.emplace_back(CTxOut());

    CTransaction txCoinStake(tx);
    BOOST_CHECK_MESSAGE(txCoinStake.IsCoinStake(), "coinstake transaction not marked as coinstake");
    BOOST_CHECK_MESSAGE(!txCoinStake.IsCoinBase(), "coinstake transaction is marked as coinbase");

    tx.vin.clear();
    txCoinStake = tx;
    BOOST_CHECK_MESSAGE(!txCoinStake.IsCoinStake(), "tx with no inputs is marked as coinstake");

    tx.vin.emplace_back(CTxIn());
    txCoinStake = tx;
    BOOST_CHECK_MESSAGE(!txCoinStake.IsCoinStake(), "tx with null input but no PoS mark is marked as coinstake");

    tx.vin.clear();
    tx.vin.emplace_back(txIn);
    tx.vout.emplace_back(CTxOut());
    txCoinStake = tx;
    BOOST_CHECK_MESSAGE(!txCoinStake.IsCoinStake(), "tx with two outputs is marked as coinstake");

    tx.vout.clear();
    txCoinStake = tx;
    BOOST_CHECK_MESSAGE(!txCoinStake.IsCoinStake(), "tx with no outputs is marked as coinstake");
}

BOOST_AUTO_TEST_CASE(block_type)
{
    CBlock block;
    CMutableTransaction tx;
    CTxIn txIn;
    txIn.scriptSig << OP_PROOFOFSTAKE << 29180 << OP_0;
    tx.vin.emplace_back(txIn);
    tx.vout.emplace_back(CTxOut());
    block.vtx.emplace_back(CTransaction());
    block.vtx.emplace_back(tx);
    BOOST_CHECK_MESSAGE(block.IsProofOfStake(), "Proof of Stake block failed IsProofOfStake() test");

    CBlock blockPoW;
    BOOST_CHECK_MESSAGE(blockPoW.IsProofOfWork(), "Proof of Work block failed IsProofOfWork() test");
}

BOOST_AUTO_TEST_CASE(block_signature)
{
    //Dummy PoS Block
    CBlock block;
    CMutableTransaction tx;
    uint256 txid = uint256S("1");
    tx.vin.emplace_back(CTxIn(COutPoint(uint256(), -1), CScript()));
    tx.vin.emplace_back(CTxIn(COutPoint(txid, 0), CScript()));
    block.vtx.emplace_back(CTransaction());
    block.vtx.emplace_back(tx);

    CKey keyMasternode;
    keyMasternode.MakeNewKey(true);
    std::vector<unsigned char> vchSig;
    BOOST_CHECK_MESSAGE(keyMasternode.Sign(block.GetHash(), vchSig), "failed to sign block with key");

    //Correct signature
    block.vchBlockSig = vchSig;
    BOOST_CHECK_MESSAGE(CheckBlockSignature(block, keyMasternode.GetPubKey()), "block signature validation failed");

    //Sign with different key
    CKey keyOther;
    keyOther.MakeNewKey(true);
    BOOST_CHECK_MESSAGE(!CheckBlockSignature(block, keyOther.GetPubKey()), "considered block signature valid when it "
                                                                           "should not have");
    //Sign wrong hash
    vchSig.clear();
    BOOST_CHECK_MESSAGE(keyMasternode.Sign(uint256S("123456789"), vchSig), "failed to sign block with key");
    block.vchBlockSig = vchSig;
    BOOST_CHECK_MESSAGE(!CheckBlockSignature(block, keyMasternode.GetPubKey()), "Validated signature that was not valid");
}

BOOST_AUTO_TEST_SUITE_END()


text:
#pragma once

#include <boost/hana/for_each.hpp>
#include <boost/hana/size.hpp>
#include <boost/hana/tuple.hpp>

namespace codys {

namespace detail {

template <class T, class Tuple>
struct TagIndex;

template <class T, typename... Ts>
struct TagIndex<T, boost::hana::tuple<Ts...>> {
    static constexpr int index = []() {
        constexpr std::array<bool, sizeof...(Ts)> a{
            {std::is_same<T, typename Ts::Operand>::value...}};

        const auto it = std::find(a.begin(), a.end(), true);
        if (it == a.end()) {
            return static_cast<decltype(std::distance(a.begin(), it))>(
                sizeof...(Ts));
        }

        return std::distance(a.begin(), it);
    }();
};

template <typename SystemType, typename StateSpaceType>
constexpr bool all_states_have_derivatives() {
    constexpr auto states = typename SystemType::UnderlyingType{};
    constexpr auto stateSize = decltype(boost::hana::size(states))::value;
    constexpr auto stateIndices = std::make_index_sequence<stateSize>{};

    bool ret = true;
    boost::hana::for_each(stateIndices, [&ret](auto idx) {
        constexpr auto ind = TagIndex<
            typename std::remove_cvref_t<decltype(boost::hana::at(states,
                                                                  idx))>,
            std::remove_cvref_t<decltype(StateSpaceType::make_dot())>>::index;

        ret &= (ind >= 0) && (ind < stateSize);
    });

    return ret;
}

template <class T, class Tuple>
struct Contains;

template <class T, typename... Ts>
struct Contains<T, boost::hana::tuple<Ts...>> {
    static constexpr bool value = []() {
        constexpr std::array<bool, sizeof...(Ts)> a{
            {std::is_same<T, Ts>::value...}};

        return std::find(a.begin(), a.end(), true) != a.end();
    }();
};

template<class Unit>
using derivative_in_time_t = decltype(std::declval<Unit>() / (units::isq::si::time<units::isq::si::second>{}));

} // namespace detail

template <typename T>
concept PhysicalType = requires {
    typename T::Unit;
};

template <typename T>
concept PhysicalValue = requires (T t) {
    t.number();
};

template <typename SystemType>
concept TypeIndexedList = requires(SystemType sys, typename SystemType::UnderlyingType states) {
    typename SystemType::UnderlyingType;

   {sys.template idx_of<std::remove_cvref_t<decltype(boost::hana::at(states,boost::hana::int_c<0>))>>()} -> std::same_as<std::size_t>;
};

template <typename T, typename SystemType>
concept SystemStateFor = PhysicalType<T> && detail::Contains<T, typename SystemType::UnderlyingType>::value;

template<typename Expression, typename Operand>
concept TimeDerivativeOf = std::is_same_v<detail::derivative_in_time_t<typename Operand::Unit>, typename Expression::Unit>;

template <typename T, typename SystemType>
concept DerivativeSystemOf = TypeIndexedList<SystemType> && detail::all_states_have_derivatives<SystemType, T>();

} // namespace codys

max_stars_repo_name: hansepp/codys

max_issues_repo_name: hansepp/codys

max_forks_repo_name: hansepp/codys


text:
/**
 * This file is part of S-PTAM.
 *
 * Copyright (C) 2013-2017 Taihú Pire
 * Copyright (C) 2014-2017 Thomas Fischer
 * Copyright (C) 2016-2017 Gastón Castro
 * Copyright (C) 2017 Matias Nitsche
 * For more information see <https://github.com/lrse/sptam>
 *
 * S-PTAM is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * S-PTAM is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with S-PTAM. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:  Taihú Pire
 *           Thomas Fischer
 *           Gastón Castro
 *           Matías Nitsche
 *
 * Laboratory of Robotics and Embedded Systems
 * Department of Computer Science
 * Faculty of Exact and Natural Sciences
 * University of Buenos Aires
 */

#include "SmoothEstimatePropagator.hpp"

#include <Eigen/Eigen>

// OpenCV
//#include <opencv2/core/core.hpp>
//#include <opencv2/core/eigen.hpp>

using namespace std;
//using namespace cv;
namespace g2o {
SmoothEstimatePropagator::SmoothEstimatePropagator(g2o::SparseOptimizer* g,
                         const double& maxDistance,
                         const double& maxEdgeCost)
  : g2o::EstimatePropagator(g), _smoothAction(&_adjacencyMap,maxDistance), _treeCost(g),
    _maxDistance(maxDistance), _maxEdgeCost(maxEdgeCost) {}

void SmoothEstimatePropagator::propagate(g2o::OptimizableGraph::Vertex* v)
{ g2o::EstimatePropagator::propagate(v, _treeCost, _smoothAction, _maxDistance, _maxEdgeCost); }

SmoothEstimatePropagator::SmoothPropagateAction::
  SmoothPropagateAction(g2o::EstimatePropagator::AdjacencyMap* adj, const double& max_distance)
  : adjacency(adj), maxDistance(max_distance){}

void SmoothEstimatePropagator::SmoothPropagateAction::
  operator()(g2o::OptimizableGraph::Edge* e_, const g2o::OptimizableGraph::VertexSet& from_, g2o::OptimizableGraph::Vertex* to_) const
{
  if (to_->fixed())
    return;

  // Static cast to SE3, this must be ensure beforehand using the propagator.
  g2o::VertexSE3* from = static_cast<g2o::VertexSE3*>(e_->vertex(0));
  g2o::VertexSE3* to = static_cast<g2o::VertexSE3*>(e_->vertex(1));
  g2o::EdgeSE3* e = static_cast<g2o::EdgeSE3*>(e_);

  if (from_.count(from) > 0){
    auto entry = adjacency->find(to);
    double distance = entry == adjacency->end() ? 0 : entry->second.distance(); // this shouldnt happen! "to" must be on the adjacency map
    to->setEstimate(exponencialInterpolation(to->estimate(), from->estimate() * e->measurement(), distance));
  }else{
    auto entry = adjacency->find(from);
    double distance = entry == adjacency->end() ? 0 : entry->second.distance(); // this shouldnt happen! "to" must be on the adjacency map
    from->setEstimate(exponencialInterpolation(from->estimate(), to->estimate() * e->measurement().inverse(), distance));
  }
}

Eigen::Isometry3d SmoothEstimatePropagator::SmoothPropagateAction::
  exponencialInterpolation(const Eigen::Isometry3d& from, const Eigen::Isometry3d& to, double step) const
{
  Eigen::Isometry3d res;

  double maxdist = maxDistance-2;

  // step goes from 1 to maxDistance, we need x from 0 to 1 in a linear way.
  double x = 1 - ((maxdist - (step-1))/maxdist);
  // alpha in [0, inf) describes the explonential ramp "steepness"
  double alpha = 50;
  // exponential ramp from 0 to 1
  double exp_ramp = 1 - (x/(1+alpha*(1-x)));

  // using quaternion representation and slerp for interpolate between from and to isometry transformations
  res.linear() = (Eigen::Quaterniond(from.rotation()).slerp(exp_ramp, Eigen::Quaterniond(to.rotation()))).toRotationMatrix();
  res.translation() = (1 - exp_ramp) * from.translation() + exp_ramp * to.translation();

  return res;
}
}


text:
//          Copyright Oliver Kowalke 2009.
// 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_COROUTINES_PROTECTED_STACK_ALLOCATOR_H
#define BOOST_COROUTINES_PROTECTED_STACK_ALLOCATOR_H

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

#include <cmath>
#include <cstddef>
#include <new>

#include <boost/config.hpp>

#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/stack_traits.hpp>

#ifdef BOOST_HAS_ABI_HEADERS
#  include BOOST_ABI_PREFIX
#endif

namespace boost {
namespace coroutines {

struct stack_context;

template< typename traitsT >
struct basic_protected_stack_allocator
{
    typedef traitsT traits_type;

    void allocate( stack_context & ctx, std::size_t size)
    {
        BOOST_ASSERT( traits_type::minimum_size() <= size);
        BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= size) );

        // page at bottom will be used as guard-page
        const std::size_t pages(
            static_cast< std::size_t >(
                std::floor(
                    static_cast< float >( size) / traits_type::page_size() ) ) );
        BOOST_ASSERT_MSG( 2 <= pages, "at least two pages must fit into stack (one page is guard-page)");
        const std::size_t size_ = pages * traits_type::page_size();
        BOOST_ASSERT( 0 < size && 0 < size_);

        void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE);
        if ( ! limit) throw std::bad_alloc();

        DWORD old_options;
#if defined(BOOST_DISABLE_ASSERTS)
        ::VirtualProtect(
            limit, traits_type::page_size(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
#else
        const BOOL result = ::VirtualProtect(
            limit, traits_type::page_size(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
        BOOST_ASSERT( FALSE != result);
#endif

        ctx.size = size_;
        ctx.sp = static_cast< char * >( limit) + ctx.size;
    }

    void deallocate( stack_context & ctx)
    {
        BOOST_ASSERT( ctx.sp);
        BOOST_ASSERT( traits_type::minimum_size() <= ctx.size);
        BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= ctx.size) );

        void * limit = static_cast< char * >( ctx.sp) - ctx.size;
        ::VirtualFree( limit, 0, MEM_RELEASE);
    }
};

typedef basic_protected_stack_allocator< stack_traits > protected_stack_allocator;

}}

#ifdef BOOST_HAS_ABI_HEADERS
#  include BOOST_ABI_SUFFIX
#endif

#endif // BOOST_COROUTINES_PROTECTED_STACK_ALLOCATOR_H

max_stars_repo_name: multi-os-engine/cinder-natj-binding

max_issues_repo_name: wujf/mongo

max_forks_repo_name: wujf/mongo