text:
//******************************************************************************
// RCF - Remote Call Framework
//
// Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
// http://www.deltavsoft.com
//
// RCF is distributed under dual licenses - closed source or GPL.
// Consult your particular license for conditions of use.
//
// If you have not purchased a commercial license, you are using RCF
// under GPL terms.
//
// Version: 2.0
// Contact: support <at> deltavsoft.com
//
//******************************************************************************

#ifndef INCLUDE_RCF_MARSHAL_HPP
#define INCLUDE_RCF_MARSHAL_HPP

#include <RCF/AmiThreadPool.hpp>
#include <RCF/ClientStub.hpp>
#include <RCF/CurrentSerializationProtocol.hpp>
#include <RCF/ObjectPool.hpp>
#include <RCF/PublishingService.hpp>
#include <RCF/RcfServer.hpp>
#include <RCF/RcfSession.hpp>
#include <RCF/SerializationProtocol.hpp>
#include <RCF/ThreadLocalData.hpp>
#include <RCF/Tools.hpp>
#include <RCF/TypeTraits.hpp>
#include <RCF/Version.hpp>

#include <boost/mpl/and.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/or.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

#if RCF_FEATURE_SF==1
#include <SF/memory.hpp>
#endif

#if RCF_FEATURE_BOOST_SERIALIZATION==1
#include <RCF/BsAutoPtr.hpp>
#include <boost/serialization/binary_object.hpp>
#endif

#include <SF/Tools.hpp>

namespace RCF {

    // The following macro hacks are necessitated by Boost.Serialization, which
    // , apparently on principle, refuses to serialize pointers to (1) fundamental
    // types, and (2) std::string, while happily serializing pointers to everything
    // else...

#define RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION(type)                \
    inline void serializeImpl(                                          \
        SerializationProtocolOut &out,                                  \
        const type *pt,                                                 \
        long int)                                                       \
    {                                                                   \
        serializeImpl(out, *pt, 0);                                     \
    }                                                                   \
                                                                        \
    inline void serializeImpl(                                          \
        SerializationProtocolOut &out,                                  \
        type *const pt,                                                 \
        long int)                                                       \
    {                                                                   \
        serializeImpl(out, *pt, 0);                                     \
    }                                                                   \
                                                                        \
    inline void deserializeImpl(                                        \
        SerializationProtocolIn &in,                                    \
        type *&pt,                                                      \
        long int)                                                       \
    {                                                                   \
        RCF_ASSERT(pt==NULL);                                           \
        pt = new type();                                                \
        deserializeImpl(in, *pt, 0);                                    \
    }

    SF_FOR_EACH_FUNDAMENTAL_TYPE( RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION )

#define RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION_T3(type)             \
    template<typename T1, typename T2, typename T3>                     \
    inline void serializeImpl(                                          \
        SerializationProtocolOut &out,                                  \
        const type<T1,T2,T3> *pt,                                       \
        int)                                                            \
    {                                                                   \
        serializeImpl(out, *pt, 0);                                     \
    }                                                                   \
                                                                        \
    template<typename T1, typename T2, typename T3>                     \
    inline void serializeImpl(                                          \
        SerializationProtocolOut &out,                                  \
        type<T1,T2,T3> *const pt,                                       \
        int)                                                            \
    {                                                                   \
        serializeImpl(out, *pt, 0);                                     \
    }                                                                   \
                                                                        \
    template<typename T1, typename T2, typename T3>                     \
    inline void deserializeImpl(                                        \
        SerializationProtocolIn &in,                                    \
        type<T1,T2,T3> *&pt,                                            \
        int)                                                            \
    {                                                                   \
        RCF_ASSERT(pt==NULL);                                           \
        pt = new type<T1,T2,T3>();                                      \
        deserializeImpl(in, *pt, 0);                                    \
    }

#if RCF_FEATURE_BOOST_SERIALIZATION==1

    RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION_T3(std::basic_string)

#endif

#undef RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION

#undef RCF_DEFINE_PRIMITIVE_POINTER_SERIALIZATION_T3

    // Boost.Serialization handles smart pointers very clumsily, so we do those ourselves

#define RefCountSmartPtr boost::shared_ptr

    template<typename T>
    inline void serializeImpl(
        SerializationProtocolOut &out,
        const RefCountSmartPtr<T> *spt,
        int)
    {
        serialize(out, *spt);
    }

    template<typename T>
    inline void serializeImpl(
        SerializationProtocolOut &out,
        RefCountSmartPtr<T> *const spt,
        int)
    {
        serialize(out, *spt);
    }

    template<typename T>
    inline void deserializeImpl(
        SerializationProtocolIn &in,
        RefCountSmartPtr<T> *&spt,
        int)
    {
        spt = new RefCountSmartPtr<T>();
        deserialize(in, *spt);
    }

    template<typename T>
    inline void serializeImpl(
        SerializationProtocolOut &out,
        const RefCountSmartPtr<T> &spt,
        int)
    {
        serialize(out, spt.get());
    }

    template<typename T>
    inline void deserializeImpl(
        SerializationProtocolIn &in,
        RefCountSmartPtr<T> &spt,
        int)
    {
        T *pt = NULL;
        deserialize(in, pt);
        spt = RefCountSmartPtr<T>(pt);
    }

#undef RefCountSmartPtr

#if RCF_FEATURE_BOOST_SERIALIZATION==1
} // namespace RCF

namespace boost { namespace serialization {

    template<class Archive>
    void save(Archive & ar, const RCF::ByteBuffer &byteBuffer, unsigned int)
    {
        // We have to copy the buffer - can't do efficient zero-copy transmission
        // of ByteBuffer, with B.Ser.

        boost::uint32_t len = byteBuffer.getLength();
        ar & len;
        ar & make_binary_object(byteBuffer.getPtr(), len);

    }

    template<class Archive>
    void load(Archive &ar, RCF::ByteBuffer &byteBuffer, unsigned int)
    {
        // We have to copy the buffer - can't do efficient zero-copy transmission
        // of ByteBuffer, with B.Ser.

        boost::uint32_t len = 0;
        ar & len;

        RCF::ReallocBufferPtr bufferPtr = RCF::getObjectPool().getReallocBufferPtr();
        bufferPtr->resize(len);
        byteBuffer = RCF::ByteBuffer(bufferPtr);

        ar & make_binary_object(byteBuffer.getPtr(), byteBuffer.getLength());
    }

}} // namespace boost namespace serialization

    BOOST_SERIALIZATION_SPLIT_FREE(RCF::ByteBuffer);

namespace RCF {
#endif // RCF_FEATURE_BOOST_SERIALIZATION==1

    // serializeOverride() and deserializeOverride() are used to implement
    // a backwards compatibility workaround, for ByteBuffer interoperability
    // with RCF runtime version <= 3.

    template<typename U>
    bool serializeOverride(SerializationProtocolOut &, U &)
    {
        return false;
    }

    template<typename U>
    bool serializeOverride(SerializationProtocolOut &, U *)
    {
        return false;
    }

    template<typename U>
    bool deserializeOverride(SerializationProtocolIn &, U &)
    {
        return false;
    }

    RCF_EXPORT bool serializeOverride(SerializationProtocolOut &out, ByteBuffer & u);

    RCF_EXPORT bool serializeOverride(SerializationProtocolOut &out, ByteBuffer * pu);

    RCF_EXPORT bool deserializeOverride(SerializationProtocolIn &in, ByteBuffer & u);

    // For vc6, manual zero-initialization of integral types.

    template<typename T> void vc6DefaultInit(T *) {}

    // -------------------------------------------------------------------------
    // Parameter store.

    template<typename T>
    class ParmStore
    {
    public:
        ParmStore() : mptPtr(), mpT(NULL)
        {
        }

        ParmStore(std::vector<char> & vec) : mptPtr(), mpT(NULL)
        {
            allocate(vec);
        }

        void allocate(std::vector<char> & vec)
        {
            RCF_ASSERT(mpT == NULL);

            getObjectPool().getObj(mptPtr, false);

            if (mptPtr)
            {
                mpT = mptPtr.get();
            }
            else
            {
                // If we didn't get it from the pool, use placement new to construct
                // it in the given vector.

                vec.resize(sizeof(T));
                mpT = (T *) & vec[0];

#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4345 )  // warning C4345: behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
#endif

                new (mpT) T();

                vc6DefaultInit(mpT);

#ifdef _MSC_VER
#pragma warning( pop )
#endif
            }

        }

        void assign(T * pt)
        {
            RCF_ASSERT(mpT == NULL);

            mptPtr.reset(pt);
            mpT = mptPtr.get();
        }

        ~ParmStore()
        {
            if (!mptPtr)
            {
                if (mpT)
                {
                    mpT->~T();
                }
            }
        }

        T & operator*()
        {
            return *mpT;
        }

        T * get()
        {
            return mpT;
        }

        boost::shared_ptr<T> mptPtr;
        T * mpT;
    };

    // Helper class to ensure delete is called for pointers that we allocate as part of reference marshaling.
    template<typename T>
    class Deleter
    {
    public:
        Deleter(T *& pt) : mpt(pt), mDismissed(false)
        {
        }
        ~Deleter()
        {
            if ( !mDismissed && mpt )
            {
                delete mpt;
                mpt = NULL;
            }
        }
        void dismiss()
        {
            mDismissed = true;
        }
    private:
        T*&     mpt;
        bool    mDismissed;
    };

    // -------------------------------------------------------------------------
    // Server marshaling.

    template<typename T>
    class Sm_Value
    {
    public:

        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));

        Sm_Value(std::vector<char> & vec) : mPs(vec)
        {
        }

        T &get()
        {
            return *mPs;
        }

        void set(bool assign, const T &t)
        {
            if (assign)
            {
                *mPs = t;
            }
        }

        void set(const T &t)
        {
            *mPs = t;
        }

        void read(SerializationProtocolIn &in)
        {
            if (in.getRemainingArchiveLength() != 0)
            {
                if (!deserializeOverride(in, *mPs))
                {
                    deserialize(in, *mPs);
                }
            }
        }

        void write(SerializationProtocolOut &)
        {
            RCF_ASSERT(0);
        }

    private:
        ParmStore<T> mPs;
    };

    template<>
    class Sm_Value<Void>
    {
    public:

        Sm_Value(std::vector<char> &)
        {
        }

        ~Sm_Value()
        {
        }

        Void &get()
        {
            RCF_ASSERT(0);
            static Void v;
            return v;
        }

        void set(bool , const Void &)
        {
            RCF_ASSERT(0);
        }

        void set(const Void &)
        {
            RCF_ASSERT(0);
        }

        void read(SerializationProtocolIn &)
        {
            RCF_ASSERT(0);
        }

        void write(SerializationProtocolOut &)
        {
            RCF_ASSERT(0);
        }
    };

    template<typename T>
    class Sm_Ret
    {
    public:

        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));

        Sm_Ret(std::vector<char> & vec) : mPs(vec)
        {
        }

        T &get()
        {
            return *mPs;
        }

        void set(bool assign, const T &t)
        {
            if (assign)
            {
                *mPs = t;
            }
        }

        void set(const T &t)
        {
            *mPs = t;
        }

        void read(SerializationProtocolIn &)
        {
            RCF_ASSERT(0);
        }

        void write(SerializationProtocolOut &out)
        {
            if (!serializeOverride(out, *mPs))
            {
                serialize(out, *mPs);
            }
        }

    private:
        ParmStore<T> mPs;
    };

    template<typename CRefT>
    class Sm_CRef
    {
    public:

        typedef typename RemoveReference<CRefT>::type CT;
        typedef typename RemoveCv<CT>::type T;
        BOOST_MPL_ASSERT(( IsReference<CRefT> ));

        BOOST_MPL_ASSERT(( IsConst<CT> ));

        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));

        Sm_CRef(std::vector<char> & vec) : mPs(), mVec(vec)
        {}

        T &get()
        {
            return *mPs;
        }

        void set(bool assign, const T &t)
        {
            if (assign)
            {
                *mPs = t;
            }
        }

        void set(const T &t)
        {
            *mPs = t;
        }

        void read(SerializationProtocolIn &in)
        {
            if (in.getRemainingArchiveLength() != 0)
            {
                int ver = in.getRuntimeVersion();
                if (ver < 8)
                {
                    // Deserialize as pointer, which means we may get
                    // polymorphic serialization happening.

                    T *pt = NULL;
                    Deleter<T> deleter(pt);
                    deserialize(in, pt);
                    deleter.dismiss();
                    mPs.assign(pt);
                }
                else if (ver == 8)
                {
                    // Deserialize as value.
                    mPs.allocate(mVec);
                    deserialize(in, *mPs);
                }
                else if (ver >= 9)
                {
                    // If BSer, deserialize through pointer.
                    // If SF and caching disabled, deserialize through pointer.
                    // If SF and caching enabled, use object cache and deserialize through value.

                    int sp = in.getSerializationProtocol();
                    if (    (sp == Sp_SfBinary || sp == Sp_SfText)
                        &&  getObjectPool().isCachingEnabled( (T *) NULL ))
                    {
                        mPs.allocate(mVec);
                        deserialize(in, *mPs);
                    }
                    else
                    {
                        T *pt = NULL;
                        Deleter<T> deleter(pt);
                        deserialize(in, pt);
                        if (!pt)
                        {
                            RCF::Exception e(RCF::_RcfError_DeserializationNullPointer());
                            RCF_THROW(e);
                        }
                        deleter.dismiss();
                        mPs.assign(pt);
                    }
                }
            }
            else
            {
                mPs.allocate(mVec);
            }
        }

        void write(SerializationProtocolOut &)
        {
            RCF_ASSERT(0);
        }

    private:
        ParmStore<T> mPs;
        std::vector<char> & mVec;
    };

    template<typename RefT>
    class Sm_Ref
    {
    public:

        typedef typename RemoveReference<RefT>::type T;
        typedef typename RemoveCv<T>::type U;
        BOOST_MPL_ASSERT(( IsReference<RefT> ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));

        Sm_Ref(std::vector<char> & vec) : mVec(vec)
        {}

        T &get()
        {
            return *mPs;
        }

        void set(bool assign, const T &t)
        {
            if (assign)
            {
                *mPs = t;
            }
        }

        void set(const T &t)
        {
            *mPs = t;
        }

        void read(SerializationProtocolIn &in)
        {
            if (in.getRemainingArchiveLength() != 0)
            {
                int ver = in.getRuntimeVersion();
                if (ver < 8)
                {
                    // Deserialize as pointer, which means we may get
                    // polymorphic serialization happening.

                    T * pt = NULL;
                    Deleter<T> deleter(pt);
                    deserialize(in, pt);
                    deleter.dismiss();
                    mPs.assign(pt);
                }
                else if (ver == 8)
                {
                    // Deserialize as value.

                    mPs.allocate(mVec);
                    deserialize(in, *mPs);
                }
                else if (ver >= 9)
                {
                    // If BSer, deserialize through pointer.
                    // If SF and caching disabled, deserialize through pointer.
                    // If SF and caching enabled, use object cache and deserialize through value.

                    int sp = in.getSerializationProtocol();
                    if (    (sp == Sp_SfBinary || sp == Sp_SfText)
                        &&  getObjectPool().isCachingEnabled( (T *) NULL ))
                    {
                        mPs.allocate(mVec);
                        deserialize(in, *mPs);
                    }
                    else
                    {
                        T *pt = NULL;
                        Deleter<T> deleter(pt);
                        deserialize(in, pt);
                        if (!pt)
                        {
                            RCF::Exception e(RCF::_RcfError_DeserializationNullPointer());
                            RCF_THROW(e);
                        }
                        deleter.dismiss();
                        mPs.assign(pt);
                    }
                }
            }
            else
            {
                mPs.allocate(mVec);
            }
        }

        void write(SerializationProtocolOut &out)
        {
            RCF_ASSERT(mPs.get());

            if (!serializeOverride(out, *mPs))
            {
                // B.Ser. issues - because the client side proxy for a T& has to
                // deserialize itself as a value, here we have to serialize as a
                // value.

                serialize(out, *mPs);
            }
        }

    private:
        ParmStore<T> mPs;
        std::vector<char> & mVec;
    };

    template<typename OutRefT>
    class Sm_OutRef
    {
    public:

        typedef typename RemoveOut<OutRefT>::type RefT;
        typedef typename RemoveReference<RefT>::type T;
        typedef typename RemoveCv<T>::type U;
        BOOST_MPL_ASSERT(( IsReference<RefT> ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));

        Sm_OutRef(std::vector<char> & vec) : mPs(vec)
        {
        }

        T &get()
        {
            return *mPs;
        }

        void set(bool assign, const T &t)
        {
            if (assign)
            {
                *mPs = t;
            }
        }

        void set(const T &t)
        {
            *mPs = t;
        }

        void read(SerializationProtocolIn &)
        {
            RCF_ASSERT(0);
        }

        void write(SerializationProtocolOut &out)
        {
            if (!serializeOverride(out, *mPs))
            {
                // B.Ser. issues - because the client side proxy for a T& has to
                // deserialize itself as a value, here we have to serialize as a
                // value.

                serialize(out, *mPs);
            }
        }

    private:
        ParmStore<T> mPs;
    };

    template<typename PtrT>
    class Sm_Ptr
    {
    public:

        typedef typename RemovePointer<PtrT>::type T;
        typedef typename RemoveCv<T>::type U;
        BOOST_MPL_ASSERT(( IsPointer<PtrT> ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));

        Sm_Ptr(std::vector<char> &)
        {}

        T *get()
        {
            return mPs.get();
        }

        void set(bool assign, const T &t)
        {
            if (assign)
            {
                *mPs = t;
            }
        }

        void set(const T &t)
        {
            *mPs = t;
        }

        void read(SerializationProtocolIn &in)
        {
            if (in.getRemainingArchiveLength() != 0)
            {
                T *pt = NULL;
                Deleter<T> deleter(pt);
                deserialize(in, pt);
                deleter.dismiss();
                mPs.assign(pt);
            }
        }

        void write(SerializationProtocolOut &)
        {
            RCF_ASSERT(0);
        }

    private:
        ParmStore<T> mPs;
    };

    // -------------------------------------------------------------------------
    // Client marshaling.

    template<typename T>
    class Cm_Ret
    {
    public:

        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));

        Cm_Ret()
        {
            RCF::ClientStub * pClientStub = getTlsClientStubPtr();
            std::vector<char> & vec = pClientStub->getRetValVec();
            mPs.allocate(vec);
        }

        T &get()
        {
            return *mPs;
        }

        void set(bool assign, const T &t)
        {
            if (assign)
            {
                *mPs = t;
            }
        }

        void set(const T &t)
        {
            *mPs = t;
        }

        void read(SerializationProtocolIn &in)
        {
            if (in.getRemainingArchiveLength() != 0)
            {
                if (!deserializeOverride(in, *mPs))
                {
                    deserialize(in, *mPs);
                }
            }
        }

        void write(SerializationProtocolOut &)
        {
            RCF_ASSERT(0);
        }

    private:
        ParmStore<T> mPs;
    };

    template<typename T>
    class Cm_Value
    {
    public:

        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsReference<T> > ));

        // We use const_cast here, in case T's copy constructor is non-const.
        // E.g. if T is a std::auto_ptr.
        Cm_Value(const T &t) : mT( const_cast<T &>(t) )
        {
        }

        const T &get()
        {
            return mT;
        }

        void read(SerializationProtocolIn &in)
        {
            RCF_UNUSED_VARIABLE(in);
        }

        void write(SerializationProtocolOut &out)
        {
            if (!serializeOverride(out, mT))
            {
                serialize(out, mT);
            }
        }

    private:
        T mT;
    };

    template<typename PtrT>
    class Cm_Ptr
    {
    public:

        typedef typename RemovePointer<PtrT>::type T;

        BOOST_MPL_ASSERT(( IsPointer<PtrT> ));

        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));

        // We use const_cast here, in case T's copy constructor is non-const.
        // E.g. if T is a std::auto_ptr.
        //Proxy_Ptr(const T &t) : mT( const_cast<T &>(t) )
        Cm_Ptr(T * pt) : mpT(pt)
        {
        }

        T *& get()
        {
            return mpT;
        }

        void read(SerializationProtocolIn &in)
        {
            RCF_UNUSED_VARIABLE(in);
        }

        void write(SerializationProtocolOut &out)
        {
            serialize(out, mpT);
        }

    private:
        T * mpT;
    };

    template<typename CRefT>
    class Cm_CRef
    {
    public:

        typedef typename RemoveReference<CRefT>::type CT;
        typedef typename RemoveCv<CT>::type T;
        BOOST_MPL_ASSERT(( IsReference<CRefT> ));

        BOOST_MPL_ASSERT(( IsConst<CT> ));

        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));

        Cm_CRef(const T &t) : mT(t)
        {}

        const T &get()
        {
            return mT;
        }

        void read(SerializationProtocolIn &in)
        {
            RCF_UNUSED_VARIABLE(in);
        }

        void write(SerializationProtocolOut &out)
        {
            int ver = out.getRuntimeVersion();
            if (ver < 8)
            {
                serialize(out, &mT);
            }
            else if (ver == 8)
            {
                serialize(out, mT);
            }
            else if (ver >= 9)
            {
                serialize(out, &mT);
            }
        }

    private:
        const T &mT;
    };

    template<typename RefT>
    class Cm_Ref
    {
    public:

        typedef typename RemoveReference<RefT>::type T;
        BOOST_MPL_ASSERT(( IsReference<RefT> ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsConst<RefT> > ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));

        Cm_Ref(T &t) : mT(t)
        {}

        T &get()
        {
            return mT;
        }

        void read(SerializationProtocolIn &in)
        {
            if (in.getRemainingArchiveLength() != 0)
            {
                if (!deserializeOverride(in, mT))
                {
                    deserialize(in, mT);
                }
            }
        }

        void write(SerializationProtocolOut &out)
        {
            int ver = out.getRuntimeVersion();
            if (ver < 8)
            {
                serialize(out, &mT);
            }
            else if (ver == 8)
            {
                serialize(out, mT);
            }
            else if (ver >= 9)
            {
                serialize(out, &mT);
            }
        }

    private:
        T & mT;
    };

    template<typename OutRefT>
    class Cm_OutRef
    {
    public:

        typedef typename RemoveOut<OutRefT>::type RefT;
        typedef typename RemoveReference<RefT>::type T;
        BOOST_MPL_ASSERT(( IsReference<RefT> ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsConst<RefT> > ));
        BOOST_MPL_ASSERT(( boost::mpl::not_< IsPointer<T> > ));

        Cm_OutRef(T &t) : mT(t)
        {}

        T &get()
        {
            return mT;
        }

        void read(SerializationProtocolIn &in)
        {
            if (in.getRemainingArchiveLength() != 0)
            {
                if (!deserializeOverride(in, mT))
                {
                    deserialize(in, mT);
                }
            }
        }

        void write(SerializationProtocolOut &)
        {
            RCF_ASSERT(0);
        }

    private:
        T &mT;
    };

    template<typename T>
    struct IsConstReference
    {
        typedef typename
            boost::mpl::and_<
                IsReference<T>,
                IsConst< typename RemoveReference<T>::type >
            >::type type;

        enum { value = type::value };
    };

    template<typename T>
    struct ServerMarshalRet
    {
        typedef typename
        boost::mpl::if_<
            boost::is_same<void, T>,
            Sm_Ret<Void>,
            Sm_Ret<T> >::type type;
    };

    template<typename T>
    struct ServerMarshal
    {
        typedef typename
        boost::mpl::if_<
            IsPointer<T>,
            Sm_Ptr<T>,
            typename boost::mpl::if_<
                IsConstReference<T>,
                Sm_CRef<T>,
                typename boost::mpl::if_<
                    IsReference<T>,
                    Sm_Ref<T>,
                    typename boost::mpl::if_<
                        IsOut<T>,
                        Sm_OutRef<T>,
                        Sm_Value<T>
                    >::type

                >::type
            >::type
        >::type type;
    };

    template<typename T>
    struct ClientMarshal
    {
        typedef typename
        boost::mpl::if_<
            IsPointer<T>,
            Cm_Ptr<T>,
            typename boost::mpl::if_<
                IsConstReference<T>,
                Cm_CRef<T>,
                typename boost::mpl::if_<
                    IsReference<T>,
                    Cm_Ref<T>,
                    typename boost::mpl::if_<
                        IsOut<T>,
                        Cm_OutRef<T>,
                        Cm_Value<T>
                    >::type
                >::type
            >::type
        >::type type;
    };

    // ReferenceTo:
    // For generic T, return const T &.
    // For T &, return T &.
    // For const T &, return const T &

    template<typename T>
    struct ReferenceTo
    {
        typedef typename
        boost::mpl::if_<
            IsReference<T>,
            T,
            typename boost::mpl::if_<
                RCF::IsConst<T>,
                typename boost::add_reference<T>::type,
                typename boost::add_reference<
                    typename boost::add_const<T>::type
                >::type
            >::type
        >::type type;
    };

    class I_Parameters
    {
    public:
        virtual ~I_Parameters() {}
        virtual void read(SerializationProtocolIn &in) = 0;
        virtual void write(SerializationProtocolOut &out) = 0;
        virtual bool enrolFutures(RCF::ClientStub *pClientStub) = 0;
    };

    template<typename T>
    struct IsInParameter
    {
        typedef typename boost::mpl::not_< boost::is_same<T,Void> >::type   NotVoid;
        typedef typename boost::mpl::not_< IsOut<T> >::type                 NotExplicitOutParameter;

        typedef typename boost::mpl::and_<
            NotVoid,
            NotExplicitOutParameter
        >::type type;

        enum { value = type::value };
    };

    template<typename T>
    struct IsOutParameter
    {
        typedef typename
        boost::mpl::and_<
            IsReference<T>,
            boost::mpl::not_<
                boost::is_const<
                    typename RemoveReference<T>::type
                >
            >
        >::type NonConstRef_;

        typedef typename IsOut<T>::type ExplicitOutParameter;

        // Following construction doesn't compile with VC6 for some reason.

        //typedef typename boost::mpl::or_<
        //  NonConstRef,
        //  ExplicitOutParameter
        //>::type type;

        enum { value = NonConstRef_::value || ExplicitOutParameter::value };
    };

    template<typename T>
    struct IsReturnValue
    {
        typedef typename boost::mpl::not_< boost::is_same<T, Void> >::type type;
        enum { value = type::value };
    };

    class Candidates
    {
    public:
        I_Future * find(const void * pv)
        {
            I_Future * pFuture = NULL;
            for (std::size_t i=0; i<mCandidateList.size(); ++i)
            {
                if (mCandidateList[i].first == pv)
                {
                    RCF_ASSERT(!pFuture);
                    pFuture = mCandidateList[i].second;
                }
            }
            return pFuture;
        }

        void erase(const void * pv)
        {
            for (std::size_t i=0; i<mCandidateList.size(); ++i)
            {
                if (mCandidateList[i].first == pv)
                {
                    mCandidateList.erase( mCandidateList.begin() + i );
                    return;
                }
            }
            RCF_ASSERT(0);
        }

        void add(const void * pv, I_Future * pFuture)
        {
            for (std::size_t i=0; i<mCandidateList.size(); ++i)
            {
                if (mCandidateList[i].first == pv)
                {
                    mCandidateList[i].second = pFuture;
                    return;
                }
            }
            mCandidateList.push_back( std::make_pair(pv, pFuture) );
        }

    private:

        typedef std::vector< std::pair<const void *, I_Future *> > CandidateList;
        CandidateList mCandidateList;
    };

    //typedef std::vector< std::pair<const void *, I_Future *> > Candidates;

    RCF_EXPORT Mutex & gCandidatesMutex();
    RCF_EXPORT Candidates & gCandidates();

    template<
        typename R,
        typename A1,
        typename A2,
        typename A3,
        typename A4,
        typename A5,
        typename A6,
        typename A7,
        typename A8,
        typename A9,
        typename A10,
        typename A11,
        typename A12,
        typename A13,
        typename A14,
        typename A15>
    class ClientParameters : public I_Parameters
    {
    public:

        typedef typename RemoveOut<A1 >::type A1_;
        typedef typename RemoveOut<A2 >::type A2_;
        typedef typename RemoveOut<A3 >::type A3_;
        typedef typename RemoveOut<A4 >::type A4_;
        typedef typename RemoveOut<A5 >::type A5_;
        typedef typename RemoveOut<A6 >::type A6_;
        typedef typename RemoveOut<A7 >::type A7_;
        typedef typename RemoveOut<A8 >::type A8_;
        typedef typename RemoveOut<A9 >::type A9_;
        typedef typename RemoveOut<A10>::type A10_;
        typedef typename RemoveOut<A11>::type A11_;
        typedef typename RemoveOut<A12>::type A12_;
        typedef typename RemoveOut<A13>::type A13_;
        typedef typename RemoveOut<A14>::type A14_;
        typedef typename RemoveOut<A15>::type A15_;

        typedef typename ReferenceTo<A1_ >::type A1Ref;
        typedef typename ReferenceTo<A2_ >::type A2Ref;
        typedef typename ReferenceTo<A3_ >::type A3Ref;
        typedef typename ReferenceTo<A4_ >::type A4Ref;
        typedef typename ReferenceTo<A5_ >::type A5Ref;
        typedef typename ReferenceTo<A6_ >::type A6Ref;
        typedef typename ReferenceTo<A7_ >::type A7Ref;
        typedef typename ReferenceTo<A8_ >::type A8Ref;
        typedef typename ReferenceTo<A9_ >::type A9Ref;
        typedef typename ReferenceTo<A10_>::type A10Ref;
        typedef typename ReferenceTo<A11_>::type A11Ref;
        typedef typename ReferenceTo<A12_>::type A12Ref;
        typedef typename ReferenceTo<A13_>::type A13Ref;
        typedef typename ReferenceTo<A14_>::type A14Ref;
        typedef typename ReferenceTo<A15_>::type A15Ref;

        ClientParameters(
            A1Ref a1, A2Ref a2, A3Ref a3, A4Ref a4, A5Ref a5, A6Ref a6,
            A7Ref a7, A8Ref a8, A9Ref a9, A10Ref a10, A11Ref a11, A12Ref a12,
            A13Ref a13, A14Ref a14, A15Ref a15) :
                a1(a1), a2(a2), a3(a3), a4(a4), a5(a5), a6(a6), a7(a7), a8(a8),
                a9(a9), a10(a10), a11(a11), a12(a12), a13(a13), a14(a14), a15(a15)
        {
        }

        void read(SerializationProtocolIn &in)
        {
            if (IsReturnValue<R>::value)        r.read(in);
            if (IsOutParameter<A1 >::value)     a1.read(in);
            if (IsOutParameter<A2 >::value)     a2.read(in);
            if (IsOutParameter<A3 >::value)     a3.read(in);
            if (IsOutParameter<A4 >::value)     a4.read(in);
            if (IsOutParameter<A5 >::value)     a5.read(in);
            if (IsOutParameter<A6 >::value)     a6.read(in);
            if (IsOutParameter<A7 >::value)     a7.read(in);
            if (IsOutParameter<A8 >::value)     a8.read(in);
            if (IsOutParameter<A9 >::value)     a9.read(in);
            if (IsOutParameter<A10>::value)     a10.read(in);
            if (IsOutParameter<A11>::value)     a11.read(in);
            if (IsOutParameter<A12>::value)     a12.read(in);
            if (IsOutParameter<A13>::value)     a13.read(in);
            if (IsOutParameter<A14>::value)     a14.read(in);
            if (IsOutParameter<A15>::value)     a15.read(in);
        }

        void write(SerializationProtocolOut &out)
        {
            if (IsInParameter<A1 >::value)      a1.write(out);
            if (IsInParameter<A2 >::value)      a2.write(out);
            if (IsInParameter<A3 >::value)      a3.write(out);
            if (IsInParameter<A4 >::value)      a4.write(out);
            if (IsInParameter<A5 >::value)      a5.write(out);
            if (IsInParameter<A6 >::value)      a6.write(out);
            if (IsInParameter<A7 >::value)      a7.write(out);
            if (IsInParameter<A8 >::value)      a8.write(out);
            if (IsInParameter<A9 >::value)      a9.write(out);
            if (IsInParameter<A10>::value)      a10.write(out);
            if (IsInParameter<A11>::value)      a11.write(out);
            if (IsInParameter<A12>::value)      a12.write(out);
            if (IsInParameter<A13>::value)      a13.write(out);
            if (IsInParameter<A14>::value)      a14.write(out);
            if (IsInParameter<A15>::value)      a15.write(out);
        }

        bool enrolFutures(RCF::ClientStub *pClientStub)
        {
            bool enrolled = false;

            const void * pva[] = {
                &a1.get(),
                &a2.get(),
                &a3.get(),
                &a4.get(),
                &a5.get(),
                &a6.get(),
                &a7.get(),
                &a8.get(),
                &a9.get(),
                &a10.get(),
                &a11.get(),
                &a12.get(),
                &a13.get(),
                &a14.get(),
                &a15.get()
            };

            for (std::size_t i=0; i<sizeof(pva)/sizeof(pva[0]); ++i)
            {
                const void *pv = pva[i];
                I_Future * pFuture = NULL;

                {
                    Lock lock(gCandidatesMutex());
                    pFuture = gCandidates().find(pv);
                    if (pFuture)
                    {
                        gCandidates().erase(pv);
                    }
                }

                if (pFuture)
                {
                    pClientStub->enrol( pFuture );
                    enrolled = true;
                }
            }

            return enrolled;
        }

        Cm_Ret<R>                               r;
        typename ClientMarshal<A1>::type        a1;
        typename ClientMarshal<A2>::type        a2;
        typename ClientMarshal<A3>::type        a3;
        typename ClientMarshal<A4>::type        a4;
        typename ClientMarshal<A5>::type        a5;
        typename ClientMarshal<A6>::type        a6;
        typename ClientMarshal<A7>::type        a7;
        typename ClientMarshal<A8>::type        a8;
        typename ClientMarshal<A9>::type        a9;
        typename ClientMarshal<A10>::type       a10;
        typename ClientMarshal<A11>::type       a11;
        typename ClientMarshal<A12>::type       a12;
        typename ClientMarshal<A13>::type       a13;
        typename ClientMarshal<A14>::type       a14;
        typename ClientMarshal<A15>::type       a15;
    };

    template<
        typename R,
        typename A1,
        typename A2,
        typename A3,
        typename A4,
        typename A5,
        typename A6,
        typename A7,
        typename A8,
        typename A9,
        typename A10,
        typename A11,
        typename A12,
        typename A13,
        typename A14,
        typename A15>
    class AllocateClientParameters
    {
    public:

        typedef typename RemoveOut<A1 >::type A1_;
        typedef typename RemoveOut<A2 >::type A2_;
        typedef typename RemoveOut<A3 >::type A3_;
        typedef typename RemoveOut<A4 >::type A4_;
        typedef typename RemoveOut<A5 >::type A5_;
        typedef typename RemoveOut<A6 >::type A6_;
        typedef typename RemoveOut<A7 >::type A7_;
        typedef typename RemoveOut<A8 >::type A8_;
        typedef typename RemoveOut<A9 >::type A9_;
        typedef typename RemoveOut<A10>::type A10_;
        typedef typename RemoveOut<A11>::type A11_;
        typedef typename RemoveOut<A12>::type A12_;
        typedef typename RemoveOut<A13>::type A13_;
        typedef typename RemoveOut<A14>::type A14_;
        typedef typename RemoveOut<A15>::type A15_;

        typedef typename ReferenceTo<A1_ >::type A1Ref;
        typedef typename ReferenceTo<A2_ >::type A2Ref;
        typedef typename ReferenceTo<A3_ >::type A3Ref;
        typedef typename ReferenceTo<A4_ >::type A4Ref;
        typedef typename ReferenceTo<A5_ >::type A5Ref;
        typedef typename ReferenceTo<A6_ >::type A6Ref;
        typedef typename ReferenceTo<A7_ >::type A7Ref;
        typedef typename ReferenceTo<A8_ >::type A8Ref;
        typedef typename ReferenceTo<A9_ >::type A9Ref;
        typedef typename ReferenceTo<A10_>::type A10Ref;
        typedef typename ReferenceTo<A11_>::type A11Ref;
        typedef typename ReferenceTo<A12_>::type A12Ref;
        typedef typename ReferenceTo<A13_>::type A13Ref;
        typedef typename ReferenceTo<A14_>::type A14Ref;
        typedef typename ReferenceTo<A15_>::type A15Ref;

        typedef ClientParameters<
            R,
            A1, A2, A3, A4, A5, A6, A7, A8,
            A9, A10, A11, A12, A13, A14, A15> ParametersT;

        // TODO: unnecessary copy of a* here, if A* is not a reference
        ParametersT &operator()(
            ClientStub &clientStub,
            A1Ref  a1,
            A2Ref  a2,
            A3Ref  a3,
            A4Ref  a4,
            A5Ref  a5,
            A6Ref  a6,
            A7Ref  a7,
            A8Ref  a8,
            A9Ref  a9,
            A10Ref a10,
            A11Ref a11,
            A12Ref a12,
            A13Ref a13,
            A14Ref a14,
            A15Ref a15) const
        {
            CurrentClientStubSentry sentry(clientStub);

            clientStub.clearParameters();

            clientStub.mParametersVec.resize(sizeof(ParametersT));

            clientStub.mpParameters = new ( &clientStub.mParametersVec[0] )
                ParametersT(
                    a1,a2,a3,a4,a5,a6,a7,a8,
                    a9,a10,a11,a12,a13,a14,a15);

            if (!clientStub.mpParameters)
            {
                Exception e(_RcfError_ClientStubParms());
                RCF_THROW(e);
            }

            return static_cast<ParametersT &>(*clientStub.mpParameters);
        }
    };

    template<
        typename R,
        typename A1  = Void,
        typename A2  = Void,
        typename A3  = Void,
        typename A4  = Void,
        typename A5  = Void,
        typename A6  = Void,
        typename A7  = Void,
        typename A8  = Void,
        typename A9  = Void,
        typename A10 = Void,
        typename A11 = Void,
        typename A12 = Void,
        typename A13 = Void,
        typename A14 = Void,
        typename A15 = Void>
    class ServerParameters : public I_Parameters
    {
    public:

        ServerParameters(RcfSession &session) :
            r(session.mParmsVec[0]),
            a1(session.mParmsVec[1]),
            a2(session.mParmsVec[2]),
            a3(session.mParmsVec[3]),
            a4(session.mParmsVec[4]),
            a5(session.mParmsVec[5]),
            a6(session.mParmsVec[6]),
            a7(session.mParmsVec[7]),
            a8(session.mParmsVec[8]),
            a9(session.mParmsVec[9]),
            a10(session.mParmsVec[10]),
            a11(session.mParmsVec[11]),
            a12(session.mParmsVec[12]),
            a13(session.mParmsVec[13]),
            a14(session.mParmsVec[14]),
            a15(session.mParmsVec[15])
        {
            read(session.mIn);
        }

        void read(SerializationProtocolIn &in)
        {
            if (IsInParameter<A1 >::value)      a1.read(in);
            if (IsInParameter<A2 >::value)      a2.read(in);
            if (IsInParameter<A3 >::value)      a3.read(in);
            if (IsInParameter<A4 >::value)      a4.read(in);
            if (IsInParameter<A5 >::value)      a5.read(in);
            if (IsInParameter<A6 >::value)      a6.read(in);
            if (IsInParameter<A7 >::value)      a7.read(in);
            if (IsInParameter<A8 >::value)      a8.read(in);
            if (IsInParameter<A9 >::value)      a9.read(in);
            if (IsInParameter<A10>::value)      a10.read(in);
            if (IsInParameter<A11>::value)      a11.read(in);
            if (IsInParameter<A12>::value)      a12.read(in);
            if (IsInParameter<A13>::value)      a13.read(in);
            if (IsInParameter<A14>::value)      a14.read(in);
            if (IsInParameter<A15>::value)      a15.read(in);
        }

        void write(SerializationProtocolOut &out)
        {
            if (IsReturnValue<R>::value)        r.write(out);
            if (IsOutParameter<A1>::value)      a1.write(out);
            if (IsOutParameter<A2>::value)      a2.write(out);
            if (IsOutParameter<A3>::value)      a3.write(out);
            if (IsOutParameter<A4>::value)      a4.write(out);
            if (IsOutParameter<A5>::value)      a5.write(out);
            if (IsOutParameter<A6>::value)      a6.write(out);
            if (IsOutParameter<A7>::value)      a7.write(out);
            if (IsOutParameter<A8>::value)      a8.write(out);
            if (IsOutParameter<A9>::value)      a9.write(out);
            if (IsOutParameter<A10>::value)     a10.write(out);
            if (IsOutParameter<A11>::value)     a11.write(out);
            if (IsOutParameter<A12>::value)     a12.write(out);
            if (IsOutParameter<A13>::value)     a13.write(out);
            if (IsOutParameter<A14>::value)     a14.write(out);
            if (IsOutParameter<A15>::value)     a15.write(out);
        }

        // TODO: we shouldn't need this here
        bool enrolFutures(RCF::ClientStub *)
        {
            RCF_ASSERT(0);
            return false;
        }

        typename ServerMarshalRet<R>::type      r;
        typename ServerMarshal<A1>::type        a1;
        typename ServerMarshal<A2>::type        a2;
        typename ServerMarshal<A3>::type        a3;
        typename ServerMarshal<A4>::type        a4;
        typename ServerMarshal<A5>::type        a5;
        typename ServerMarshal<A6>::type        a6;
        typename ServerMarshal<A7>::type        a7;
        typename ServerMarshal<A8>::type        a8;
        typename ServerMarshal<A9>::type        a9;
        typename ServerMarshal<A10>::type       a10;
        typename ServerMarshal<A11>::type       a11;
        typename ServerMarshal<A12>::type       a12;
        typename ServerMarshal<A13>::type       a13;
        typename ServerMarshal<A14>::type       a14;
        typename ServerMarshal<A15>::type       a15;
    };

    typedef boost::shared_ptr<I_Parameters> ParametersPtr;

    template<
        typename R,
        typename A1  = Void,
        typename A2  = Void,
        typename A3  = Void,
        typename A4  = Void,
        typename A5  = Void,
        typename A6  = Void,
        typename A7  = Void,
        typename A8  = Void,
        typename A9  = Void,
        typename A10 = Void,
        typename A11 = Void,
        typename A12 = Void,
        typename A13 = Void,
        typename A14 = Void,
        typename A15 = Void>
    class AllocateServerParameters
    {
    public:
        typedef ServerParameters<
            R,
            A1, A2, A3, A4, A5, A6, A7, A8,
            A9, A10, A11, A12, A13, A14, A15> ParametersT;

        ParametersT &operator()(RcfSession &session) const
        {
            session.clearParameters();

            session.mParametersVec.resize(sizeof(ParametersT));

            session.mpParameters = new
                ( &session.mParametersVec[0] )
                ParametersT(session);

            if (!session.mpParameters)
            {
                Exception e(_RcfError_ServerStubParms());
                RCF_THROW(e);
            }

            return static_cast<ParametersT &>(*session.mpParameters);
        }
    };

    // Bidirectional connections - converting between RcfClient and RcfSession.

    RCF_EXPORT void convertRcfSessionToRcfClient(
        OnCallbackConnectionCreated func,
        RemoteCallSemantics rcs = RCF::Twoway);

    RCF_EXPORT RcfSessionPtr convertRcfClientToRcfSession(
        ClientStub & clientStub,
        ServerTransport & serverTransport,
        bool keepClientConnection = false);

    RCF_EXPORT RcfSessionPtr convertRcfClientToRcfSession(
        ClientStub & clientStub,
        RcfServer & server,
        bool keepClientConnection = false);

    template<typename RcfClientT>
    inline RcfSessionPtr convertRcfClientToRcfSession(
        RcfClientT & client,
        RcfServer & server,
        bool keepClientConnection = false)
    {
        return convertRcfClientToRcfSession(
            client.getClientStub(),
            server,
            keepClientConnection);
    }

    template<typename RcfClientT>
    inline RcfSessionPtr convertRcfClientToRcfSession(
        RcfClientT & client,
        ServerTransport & serverTransport,
        bool keepClientConnection = false)
    {
        return convertRcfClientToRcfSession(
            client.getClientStub(),
            serverTransport,
            keepClientConnection);
    }

    RCF_EXPORT void createCallbackConnectionImpl(
        ClientStub & client,
        ServerTransport & callbackServer);

    RCF_EXPORT void createCallbackConnectionImpl_Legacy(
        ClientStub & client,
        ServerTransport & callbackServer);

    RCF_EXPORT void createCallbackConnectionImpl(
        ClientStub & client,
        RcfServer & callbackServer);

    template<typename RcfClientT>
    void createCallbackConnection(
        RcfClientT & client,
        RcfServer & callbackServer)
    {
        createCallbackConnectionImpl(
            client.getClientStub(),
            callbackServer);
    }

    template<typename RcfClientT>
    void createCallbackConnectionImpl(
        RcfClientT & client,
        ServerTransport & callbackServer)
    {
        createCallbackConnection(
            client.getClientStub(),
            callbackServer);
    }

} // namespace RCF

#endif // ! INCLUDE_RCF_MARSHAL_HPP

ext: hpp

max_stars_repo_name: ASMlover/study

max_issues_repo_name: ASMlover/study

max_forks_repo_name: ASMlover/study


text:
/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include "ifmap_manager.h"
#include "ifmap_channel.h"
#include "ifmap_state_machine.h"
#include "ifmap/ifmap_server.h"

#include <sandesh/sandesh_types.h>
#include <sandesh/sandesh.h>
#include "ifmap/ifmap_server_show_types.h"

#include <boost/function.hpp>
#include <boost/asio/io_service.hpp>

IFMapManager::IFMapManager(IFMapServer *ifmap_server, const std::string& url,
                           const std::string& user, const std::string& passwd,
                           const std::string& certstore, PollReadCb readcb,
                           boost::asio::io_service *io_service)
    : pollreadcb_(readcb), io_service_(io_service),
      channel_(new IFMapChannel(this, url, user, passwd, certstore)),
      state_machine_(new IFMapStateMachine(this)), ifmap_server_(ifmap_server) {

}

IFMapManager::~IFMapManager() {
}

void IFMapManager::Start() {
    channel_->set_sm(state_machine_.get());

    state_machine_->set_channel(channel_.get());
    state_machine_->Start();
}

void IFMapManager::SetChannel(IFMapChannel *channel) {
    channel_.reset(channel);
}

uint64_t IFMapManager::GetChannelSequenceNumber() {
    return channel_->get_sequence_number();
}

void IFMapManager::GetPeerServerInfo(IFMapPeerServerInfo &server_info) {
    server_info.set_url(channel()->get_url());
    server_info.set_connection_status(channel()->get_connection_status());
}

ext: cc

max_stars_repo_name: sysbot/contrail-controller

max_issues_repo_name: sysbot/contrail-controller

max_forks_repo_name: sysbot/contrail-controller


text:
// Copyright (c) 2019-2021 Xenios SEZC
// https://www.veriblock.org
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_SRC_VBK_TEST_UTIL_E2E_FIXTURE_HPP
#define BITCOIN_SRC_VBK_TEST_UTIL_E2E_FIXTURE_HPP

#include <boost/test/unit_test.hpp>

#include <chain.h>
#include <chainparams.h>
#include <consensus/validation.h>
#include <test/util/setup_common.h>
#include <validation.h>
#include <vbk/bootstraps.h>
#include <vbk/log.hpp>
#include <vbk/util.hpp>
#include <veriblock/pop.hpp>

#include <consensus/merkle.h>

using altintegration::ATV;
using altintegration::BtcBlock;
using altintegration::MockMiner;
using altintegration::PublicationData;
using altintegration::VbkBlock;
using altintegration::VTB;

struct TestLogger : public altintegration::Logger {
    ~TestLogger() override = default;

    void log(altintegration::LogLevel lvl, const std::string& msg) override
    {
        fmt::printf("[pop] [%s]\t%s\n", altintegration::LevelToString(lvl), msg);
    }
};

struct E2eFixture : public TestChain100Setup {
    CScript cbKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
    altintegration::AltChainParamsRegTest alt_params{};
    altintegration::VbkChainParamsRegTest vbk_params{};
    altintegration::BtcChainParamsRegTest btc_params{};
    MockMiner popminer{
        alt_params, vbk_params, btc_params};
    altintegration::ValidationState state;
    altintegration::PopContext* pop;
    std::vector<uint8_t> defaultPayoutInfo = {1, 2, 3, 4, 5};

    E2eFixture()
    {
        altintegration::SetLogger<TestLogger>();
        altintegration::GetLogger().level = altintegration::LogLevel::warn;

        // create N blocks necessary to start POP fork resolution
        CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
        while (!VeriBlock::isPopActive()) {
            CBlock b = CreateAndProcessBlock({}, scriptPubKey);
            m_coinbase_txns.push_back(b.vtx[0]);
        }

        pop = &VeriBlock::GetPop();
    }

    void InvalidateTestBlock(CBlockIndex* pblock)
    {
        BlockValidationState state;
        InvalidateBlock(state, Params(), pblock);
        ActivateBestChain(state, Params());
        mempool.clear();
    }

    void ReconsiderTestBlock(CBlockIndex* pblock)
    {
        BlockValidationState state;

        {
            LOCK(cs_main);
            ResetBlockFailureFlags(pblock);
        }
        ActivateBestChain(state, Params(), std::shared_ptr<const CBlock>());
    }

    BtcBlock::hash_t getLastKnownBTCblock()
    {
        auto blocks = VeriBlock::getLastKnownBTCBlocks(1);
        BOOST_CHECK(blocks.size() == 1);
        return blocks[0];
    }

    VbkBlock::hash_t getLastKnownVBKblock()
    {
        auto blocks = VeriBlock::getLastKnownVBKBlocks(1);
        BOOST_CHECK(blocks.size() == 1);
        return blocks[0];
    }

    ATV endorseAltBlock(uint256 hash, const std::vector<uint8_t>& payoutInfo)
    {
        CBlockIndex* endorsed = nullptr;
        {
            LOCK(cs_main);
            endorsed = LookupBlockIndex(hash);
            BOOST_CHECK(endorsed != nullptr);
        }

        auto publicationdata = createPublicationData(endorsed, payoutInfo);
        auto vbktx = popminer.createVbkTxEndorsingAltBlock(publicationdata);
        auto* vbkblock = popminer.mineVbkBlocks(1, {vbktx});
        auto atv = popminer.createATV(vbkblock->getHeader(), vbktx);
        BOOST_CHECK(state.IsValid());
        return atv;
    }

    ATV endorseAltBlock(uint256 hash)
    {
        return endorseAltBlock(hash, defaultPayoutInfo);
    }

    CBlock endorseAltBlockAndMine(const std::vector<uint256>& hashes, size_t generateVtbs = 0)
    {
        return endorseAltBlockAndMine(hashes, ChainActive().Tip()->GetBlockHash(), generateVtbs);
    }

    CBlock endorseAltBlockAndMine(const std::vector<uint256>& hashes, uint256 prevBlock, size_t generateVtbs = 0)
    {
        return endorseAltBlockAndMine(hashes, prevBlock, defaultPayoutInfo, generateVtbs);
    }

    CBlock endorseAltBlockAndMine(const std::vector<uint256>& hashes, uint256 prevBlock, const std::vector<uint8_t>& payoutInfo, size_t generateVtbs = 0, bool expectAccepted = false)
    {
        std::vector<VTB> vtbs;
        vtbs.reserve(generateVtbs);
        std::generate_n(std::back_inserter(vtbs), generateVtbs, [&]() {
            return endorseVbkTip();
        });

        std::vector<ATV> atvs;
        atvs.reserve(hashes.size());
        std::transform(hashes.begin(), hashes.end(), std::back_inserter(atvs), [&](const uint256& hash) -> ATV {
            return endorseAltBlock(hash, payoutInfo);
        });

        auto& pop_mempool = VeriBlock::GetPop().getMemPool();
        altintegration::ValidationState state;
        for (const auto& atv : atvs) {
            pop_mempool.submit(atv, true, state);
            // do not check the submit result - expect statefully invalid data for testing purposes
        }

        for (const auto& vtb : vtbs) {
            pop_mempool.submit(vtb, true, state);
            // do not check the submit result - expect statefully invalid data for testing purposes
        }

        bool isValid = false;
        const auto& block = CreateAndProcessBlock({}, prevBlock, cbKey, &isValid);
        BOOST_CHECK(isValid);
        return block;
    }

    CBlock endorseAltBlockAndMine(uint256 hash, uint256 prevBlock, const std::vector<uint8_t>& payoutInfo, size_t generateVtbs = 0)
    {
        return endorseAltBlockAndMine(std::vector<uint256>{hash}, prevBlock, payoutInfo, generateVtbs);
    }

    CBlock endorseAltBlockAndMine(uint256 hash, size_t generateVtbs = 0)
    {
        return endorseAltBlockAndMine(hash, ChainActive().Tip()->GetBlockHash(), generateVtbs);
    }

    CBlock endorseAltBlockAndMine(uint256 hash, uint256 prevBlock, size_t generateVtbs = 0)
    {
        return endorseAltBlockAndMine(hash, prevBlock, defaultPayoutInfo, generateVtbs);
    }

    VTB endorseVbkTip()
    {
        auto best = popminer.vbk().getBestChain();
        auto tip = best.tip();
        BOOST_CHECK(tip != nullptr);
        return endorseVbkBlock(tip->getHeight());
    }

    VTB endorseVbkBlock(int height)
    {
        auto vbkbest = popminer.vbk().getBestChain();
        auto endorsed = vbkbest[height];
        if (!endorsed) {
            throw std::logic_error("can not find VBK block at height " + std::to_string(height));
        }

        return popminer.endorseVbkBlock(endorsed->getHeader(), getLastKnownBTCblock());
    }

    PublicationData createPublicationData(CBlockIndex* endorsed, const std::vector<uint8_t>& payoutInfo)
    {
        assert(endorsed);

        auto hash = endorsed->GetBlockHash();
        CBlock block;
        bool read = ReadBlockFromDisk(block, endorsed, Params().GetConsensus());
        assert(read && "expected to read endorsed block from disk");

        CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
        stream << endorsed->GetBlockHeader();
        std::vector<uint8_t> header{stream.begin(), stream.end()};

        auto txRoot = BlockMerkleRoot(block, nullptr).asVector();
        auto* libendorsed = VeriBlock::GetAltBlockIndex(hash);
        assert(libendorsed && "expected to have endorsed header in library");
        return altintegration::GeneratePublicationData(
            header,
            *libendorsed,
            txRoot,
            block.popData,
            payoutInfo,
            VeriBlock::GetPop().getConfig().getAltParams());
    }

    PublicationData createPublicationData(CBlockIndex* endorsed)
    {
        return createPublicationData(endorsed, defaultPayoutInfo);
    }

    CBlockIndex* MineToKeystone()
    {
        while (true) {
            CBlockIndex* tip = ChainActive().Tip();
            if (tip == nullptr) return tip;
            if (VeriBlock::isKeystone(*tip)) return tip;
            CreateAndProcessBlock({}, cbKey);
        }
    }
};

#endif // BITCOIN_SRC_VBK_TEST_UTIL_E2E_FIXTURE_HPP

max_stars_repo_name: VeriBlock/b

max_issues_repo_name: VeriBlock/b

max_forks_repo_name: VeriBlock/b


text:
//  (C) Copyright Gennadiy Rozental 2005-2014.
//  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)

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

// Boost.Test
#define BOOST_TEST_MODULE Unit_test_example_04
#include <boost/test/unit_test.hpp>
namespace bt=boost::unit_test;

//____________________________________________________________________________//

struct suite_fixture {
    suite_fixture()     { BOOST_TEST_MESSAGE( "Running some test suite setup" ); }
    ~suite_fixture()    { BOOST_TEST_MESSAGE( "Running some test suite teardown" ); }
};
struct suite_fixture2 {
    suite_fixture2()    { BOOST_TEST_MESSAGE( "Running some more test suite setup" ); }
    ~suite_fixture2()   { BOOST_TEST_MESSAGE( "Running some more test suite teardown" ); }
};

// automatically registered test cases could be organized in test suites
BOOST_AUTO_TEST_SUITE( my_suite1,
* bt::fixture<suite_fixture>()
* bt::fixture<suite_fixture2>() )

BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(my_test1,1)

void some_setup()
{
    BOOST_TEST_MESSAGE( "Running some extra setup" );
}

auto& d =
* bt::label( "L1" )
* bt::label( "L2" )
* bt::description( "test case 1 description" )
* bt::fixture( &some_setup );
BOOST_AUTO_TEST_CASE( my_test1 )
{
    BOOST_TEST( 2 == 1 );
}

//____________________________________________________________________________//

// this test case belongs to suite1 test suite
BOOST_AUTO_TEST_CASE( my_test2, * bt::description( "test case 2 description" ) )
{
    int i = 0;

    BOOST_TEST( i == 2 );

    BOOST_TEST( i == 0 );
}

BOOST_AUTO_TEST_SUITE_END()

//____________________________________________________________________________//

// this test case belongs to master test suite
BOOST_AUTO_TEST_CASE( my_test3 )
{
    int i = 0;

    BOOST_TEST( i == 0 );
}

//____________________________________________________________________________//

BOOST_TEST_DECORATOR(
* bt::label( "L3" )
* bt::description( "suite description" )
)
BOOST_AUTO_TEST_SUITE( my_suite2 )

// this test case belongs to suite2 test suite
BOOST_AUTO_TEST_CASE( my_test4, * bt::depends_on( "my_suite2/internal_suite/my_test5" ) )
{
    int i = 0;

    BOOST_CHECK_EQUAL( i, 1 );
}

BOOST_AUTO_TEST_SUITE( internal_suite )

// this test case belongs to my_suite2:internal_suite test suite

BOOST_TEST_DECORATOR(
* bt::timeout( 100 )
)
BOOST_AUTO_TEST_CASE( my_test5, * bt::expected_failures( 1 ) )
{
    int i = 0;

    BOOST_CHECK_EQUAL( i, 1 );
}

BOOST_AUTO_TEST_CASE( my_test6, *bt::disabled() )
{
}

BOOST_AUTO_TEST_CASE( this_should_also_be_disabled,
* bt::depends_on( "my_suite2/internal_suite/disabled_suite/my_test7" ) )
{
}

BOOST_AUTO_TEST_SUITE( disabled_suite, * bt::disabled() )

BOOST_AUTO_TEST_CASE( my_test7 ) {}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()

//____________________________________________________________________________//

// EOF

ext: cpp


text:
#include "sql_statement.h"

#include <iomanip>
#include <iostream>

#include <boost/algorithm/string.hpp>

#include "commons.h"
#include "exceptions.h"

using namespace boost::algorithm;
using namespace std;

std::ostream& operator<<(std::ostream& out, const TKey& object) {
	switch (object.key_type_) {
	case 0: {
		int a;
		memcpy(&a, object.key_, object.length_);
		out << setw(9) << left << a;
	} break;
	case 1: {
		float a;
		memcpy(&a, object.key_, object.length_);
		out << setw(9) << left << a;
	} break;
	case 2: {
		out << setw(9) << left << object.key_;
	} break;
	}

	return out;
}

void SQLSelect::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 90;
	unsigned int pos = 1;

	if (sql_vector.size() <= pos) {
		throw SyntaxErrorException();
	}

	if (sql_vector[pos] != "*") {
		throw SyntaxErrorException();
	}
	pos++;

	if (sql_vector[pos] != "from") {
		throw SyntaxErrorException();
	}
	pos++;

	std::cout << "TABLE NAME: " << sql_vector[pos] << std::endl;
	tb_name_ = sql_vector[pos];
	pos++;

	if (sql_vector.size() == pos) {
		return;
	}

	if (sql_vector[pos] != "where") {
		throw SyntaxErrorException();
	}
	pos++;

	while (true) {
		SQLWhere where;

		where.key = sql_vector[pos];
		pos++;

		if (sql_vector[pos] == "=") {
			where.sign_type = SIGN_EQ;
		}
		else if (sql_vector[pos] == "<") {
			where.sign_type = SIGN_LT;
		}
		else if (sql_vector[pos] == ">") {
			where.sign_type = SIGN_GT;
		}
		else if (sql_vector[pos] == "<=") {
			where.sign_type = SIGN_LE;
		}
		else if (sql_vector[pos] == ">=") {
			where.sign_type = SIGN_GE;
		}
		else if (sql_vector[pos] == "<>") {
			where.sign_type = SIGN_NE;
		}
		pos++;

		where.value = sql_vector[pos];
		pos++;

		if (where.value.at(0) == '\'' || where.value.at(0) == '\"') {
			where.value.assign(where.value, 1, where.value.length() - 2);
		}

		wheres_.push_back(where);
		cout << where.key << " " << where.sign_type << " " << where.value << endl;

		if (sql_vector.size() == pos) {
			break;
		}

		if (sql_vector[pos] != "and") {
			throw SyntaxErrorException();
		}
		pos++;
	}
}

void SQLExec::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 80;
	if (sql_vector.size() <= 1) {
		throw SyntaxErrorException();
	}
	else {
		std::cout << "FILE NAME: " << sql_vector[1] << std::endl;
		file_name_ = sql_vector[1];
	}
}

void SQLCreateDatabase::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 30;
	if (sql_vector.size() <= 2) {
		throw SyntaxErrorException();
	}
	else {
		std::cout << "DB NAME: " << sql_vector[2] << std::endl;
		db_name_ = sql_vector[2];
	}
}

void SQLDropDatabase::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 50;
	if (sql_vector.size() <= 2) {
		throw SyntaxErrorException();
	}
	else {
		std::cout << "DB NAME: " << sql_vector[2] << std::endl;
		db_name_ = sql_vector[2];
	}
}

void SQLDropTable::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 51;
	if (sql_vector.size() <= 2) {
		throw SyntaxErrorException();
	}
	else {
		std::cout << "TB NAME: " << sql_vector[2] << std::endl;
		tb_name_ = sql_vector[2];
	}
}

void SQLDropIndex::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 52;
	if (sql_vector.size() <= 2) {
		throw SyntaxErrorException();
	}
	else {
		std::cout << "IDX NAME: " << sql_vector[2] << std::endl;
		idx_name_ = sql_vector[2];
	}
}

void SQLUse::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 60;
	if (sql_vector.size() <= 1) {
		throw SyntaxErrorException();
	}
	else {
		std::cout << "DB NAME: " << sql_vector[1] << std::endl;
		db_name_ = sql_vector[1];
	}
}

void SQLCreateTable::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 31;
	unsigned int pos = 2;
	bool is_attr = true;

	if (sql_vector.size() <= pos) {
		throw SyntaxErrorException();
	}

	std::cout << "TABLE NAME: " << sql_vector[pos] << std::endl;
	tb_name_ = sql_vector[pos];
	pos++;

	if (sql_vector[pos] != "(") {
		throw SyntaxErrorException();
	}
	pos++;

	bool has_pk = false;

	while (is_attr) {
		is_attr = false;

		if (sql_vector[pos] == "primary") {
			pos++;
			if (sql_vector[pos] != "key") {
				throw SyntaxErrorException();
			}
			pos++;

			if (has_pk) {
				throw SyntaxErrorException();
			}

			if (sql_vector[pos] != "(") {
				throw SyntaxErrorException();
			}
			pos++;
			for (unsigned int i = 0; i < attrs_.size(); ++i) {
				if (attrs_[i].attr_name() == sql_vector[pos]) {
					attrs_[i].set_attr_type(1);
					std::cout << "PRIMARY KEY: " << sql_vector[pos] << std::endl;
				}
			}
			pos++;
			if (sql_vector[pos] != ")") {
				throw SyntaxErrorException();
			}
			has_pk = true;
		}
		else {
			std::cout << "COLUMN: " << sql_vector[pos] << std::endl;
			Attribute attr;
			attr.set_attr_name(sql_vector[pos]);
			pos++;

			pos = ParseDataType(sql_vector, attr, pos);

			attrs_.push_back(attr);

			if (sql_vector[pos] != ")") {
				is_attr = true;
			}
		}
	}
}

void SQLCreateIndex::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 32;
	unsigned int pos = 2;
	if (sql_vector.size() <= pos) {
		throw SyntaxErrorException();
	}

	std::cout << "INDEX NAME: " << sql_vector[pos] << std::endl;
	index_name_ = sql_vector[pos];
	pos++;

	if (to_lower_copy(sql_vector[pos]) != "on") {
		throw SyntaxErrorException();
	}
	pos++;

	std::cout << "TABLE NAME: " << sql_vector[pos] << std::endl;
	tb_name_ = sql_vector[pos];
	pos++;

	if (to_lower_copy(sql_vector[pos]) != "(") {
		throw SyntaxErrorException();
	}
	pos++;

	std::cout << "COLUMN NAME: " << sql_vector[pos] << std::endl;
	col_name_ = sql_vector[pos];
	pos++;

	if (to_lower_copy(sql_vector[pos]) != ")") {
		throw SyntaxErrorException();
	}
	pos++;
}

void SQLInsert::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 70;
	unsigned int pos = 1;
	bool is_attr = true;

	if (to_lower_copy(sql_vector[pos]) != "into") {
		throw SyntaxErrorException();
	}
	pos++;
	cout << "TABLE NAME: " << sql_vector[pos] << endl;
	tb_name_ = sql_vector[pos];
	pos++;
	if (to_lower_copy(sql_vector[pos]) != "values") {
		throw SyntaxErrorException();
	}
	pos++;
	if (to_lower_copy(sql_vector[pos]) != "(") {
		throw SyntaxErrorException();
	}
	pos++;
	while (is_attr) {
		is_attr = false;
		SQLValue sql_value;
		std::string value = sql_vector[pos];
		if (value.at(0) == '\'' || value.at(0) == '\"') {
			value.assign(value, 1, value.length() - 2);
			sql_value.data_type = 2;
		}
		else {
			if (value.find(".") != string::npos) {
				sql_value.data_type = 1;
			}
			else {
				sql_value.data_type = 0;
			}
		}
		sql_value.value = value;
		cout << sql_value.data_type << " : " << value << endl;
		pos++;
		values_.push_back(sql_value);
		if (sql_vector[pos] != ")") {
			is_attr = true;
		}
		pos++;
	}
}

int SQL::ParseDataType(std::vector<std::string> sql_vector, Attribute& attr,
	unsigned int pos) {
	boost::algorithm::to_lower(sql_vector[pos]);

	if (sql_vector[pos] == "int") {
		std::cout << "TYPE: "
			<< "int" << std::endl;
		attr.set_data_type(T_INT);
		attr.set_length(4);
		pos++;
		if (sql_vector[pos] == ",") {
			pos++;
		}
	}
	else if (sql_vector[pos] == "float") {
		std::cout << "TYPE: "
			<< "float" << std::endl;
		attr.set_data_type(T_FLOAT);
		attr.set_length(4);
		pos++;
		if (sql_vector[pos] == ",") {
			pos++;
		}
	}
	else if (sql_vector[pos] == "char") {
		attr.set_data_type(T_CHAR);
		pos++;
		if (sql_vector[pos] == "(") {
			pos++;
		}
		attr.set_length(atoi(sql_vector[pos].c_str()));
		pos++;
		if (sql_vector[pos] == ")") {
			pos++;
		}
		if (sql_vector[pos] == ",") {
			pos++;
		}
	}
	else {
		throw SyntaxErrorException();
	}

	return pos;
}

void SQLDelete::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 100;
	unsigned int pos = 1;

	if (sql_vector.size() <= pos) {
		throw SyntaxErrorException();
	}

	if (sql_vector[pos] != "from") {
		throw SyntaxErrorException();
	}
	pos++;

	std::cout << "TABLE NAME: " << sql_vector[pos] << std::endl;
	tb_name_ = sql_vector[pos];
	pos++;

	if (sql_vector.size() == pos) {
		return;
	}

	if (sql_vector[pos] != "where") {
		throw SyntaxErrorException();
	}
	pos++;

	while (true) {
		SQLWhere where;

		where.key = sql_vector[pos];
		pos++;

		if (sql_vector[pos] == "=") {
			where.sign_type = SIGN_EQ;
		}
		else if (sql_vector[pos] == "<") {
			where.sign_type = SIGN_LT;
		}
		else if (sql_vector[pos] == ">") {
			where.sign_type = SIGN_GT;
		}
		else if (sql_vector[pos] == "<=") {
			where.sign_type = SIGN_LE;
		}
		else if (sql_vector[pos] == ">=") {
			where.sign_type = SIGN_GE;
		}
		else if (sql_vector[pos] == "<>") {
			where.sign_type = SIGN_NE;
		}
		pos++;

		where.value = sql_vector[pos];
		pos++;

		if (where.value.at(0) == '\'' || where.value.at(0) == '\"') {
			where.value.assign(where.value, 1, where.value.length() - 2);
		}

		wheres_.push_back(where);
		cout << where.key << " " << where.sign_type << " " << where.value << endl;

		if (sql_vector.size() == pos) {
			break;
		}

		if (sql_vector[pos] != "and") {
			throw SyntaxErrorException();
		}
		pos++;
	}
}

void SQLUpdate::Parse(std::vector<std::string> sql_vector) {
	sql_type_ = 110;
	unsigned int pos = 1;

	if (sql_vector.size() <= pos) {
		throw SyntaxErrorException();
	}

	std::cout << "TABLE NAME: " << sql_vector[pos] << std::endl;
	tb_name_ = sql_vector[pos];
	pos++;

	if (sql_vector.size() == pos) {
		return;
	}

	if (sql_vector[pos] != "set") {
		throw SyntaxErrorException();
	}
	pos++;

	while (true) {
		SQLKeyValue keyvalue;

		keyvalue.key = sql_vector[pos];
		pos++;

		if (sql_vector[pos] != "=") {
			throw SyntaxErrorException();
		}
		pos++;

		keyvalue.value = sql_vector[pos];
		pos++;
		if (keyvalue.value.at(0) == '\'' || keyvalue.value.at(0) == '\"') {
			keyvalue.value.assign(keyvalue.value, 1, keyvalue.value.length() - 2);
		}

		keyvalues_.push_back(keyvalue);
		cout << keyvalue.key << " " << keyvalue.value << endl;

		if (sql_vector[pos] == ",") {
			pos++;
		}
		else if (sql_vector[pos] == "where") {
			break;
		}
		else {
			throw SyntaxErrorException();
		}
	}

	if (sql_vector[pos] != "where") {
		throw SyntaxErrorException();
	}
	pos++;

	while (true) {
		SQLWhere where;

		where.key = sql_vector[pos];
		pos++;

		if (sql_vector[pos] == "=") {
			where.sign_type = SIGN_EQ;
		}
		else if (sql_vector[pos] == "<") {
			where.sign_type = SIGN_LT;
		}
		else if (sql_vector[pos] == ">") {
			where.sign_type = SIGN_GT;
		}
		else if (sql_vector[pos] == "<=") {
			where.sign_type = SIGN_LE;
		}
		else if (sql_vector[pos] == ">=") {
			where.sign_type = SIGN_GE;
		}
		else if (sql_vector[pos] == "<>") {
			where.sign_type = SIGN_NE;
		}
		pos++;

		where.value = sql_vector[pos];
		pos++;

		if (where.value.at(0) == '\'' || where.value.at(0) == '\"') {
			where.value.assign(where.value, 1, where.value.length() - 2);
		}

		wheres_.push_back(where);
		cout << where.key << " " << where.sign_type << " " << where.value << endl;

		if (sql_vector.size() == pos) {
			break;
		}

		if (sql_vector[pos] != "and") {
			throw SyntaxErrorException();
		}
		pos++;
	}
}

max_stars_repo_name: JingzeWang/Library-Management-System

max_issues_repo_name: JingzeWang/Library-Management-System

max_forks_repo_name: JingzeWang/Library-Management-System


text:
#pragma once

#include <memory>
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <rai/common/parameters.hpp>
#include <rai/common/errors.hpp>
#include <rai/common/util.hpp>
#include <rai/common/blocks.hpp>

namespace rai
{
class RpcConfig
{
public:
    boost::asio::ip::address_v4 address_;
    uint16_t port_;
    bool enable_control_;
    // only ips in the white list can access
    std::vector<boost::asio::ip::address_v4> whitelist_;
};

class Rpc;
class RpcHandler;
typedef std::function<std::unique_ptr<RpcHandler>(
    rai::Rpc&, const std::string&,
    const boost::asio::ip::address_v4&,
    const std::function<void(const rai::Ptree&)>&)>
    RpcHandlerMaker;

class Rpc
{
public:
    Rpc(boost::asio::io_service&, const rai::RpcConfig&,
        const rai::RpcHandlerMaker&);
    void Start();
    void Stop();
    virtual void Accept();
    bool CheckWhitelist(const boost::asio::ip::address_v4&) const;

    boost::asio::io_service& service_;
    boost::asio::ip::tcp::acceptor acceptor_;
    rai::RpcConfig config_;
    std::atomic_flag stopped_;
    rai::RpcHandlerMaker make_handler_;
};

class RpcConnection : public std::enable_shared_from_this<rai::RpcConnection>
{
public:
    RpcConnection(rai::Rpc&);
    virtual void Parse();
    virtual void Read();
    virtual void Write(const std::string&, unsigned);

    rai::Rpc& rpc_;
    boost::asio::ip::tcp::socket socket_;
    boost::beast::flat_buffer buffer_;
    boost::beast::http::request<boost::beast::http::string_body> request_;
    boost::beast::http::response<boost::beast::http::string_body> response_;
    std::atomic_flag responded_;
};

class RpcHandler
{
public:
    RpcHandler(rai::Rpc&, const std::string&,
               const boost::asio::ip::address_v4&,
               const std::function<void(const rai::Ptree&)>&);
    virtual ~RpcHandler() = default;
    void Check();
    void Process();
    void Response();
    void Stop();

    virtual void ProcessImpl() = 0;
    virtual void ExtraCheck(const std::string&);

    static int constexpr MAX_JSON_DEPTH = 20;
    static uint32_t constexpr MAX_BODY_SIZE = 64 * 1024;

    rai::Rpc& rpc_;
    std::string body_;
    std::string header_api_key_;
    boost::asio::ip::address_v4 ip_;
    std::function<void(const rai::Ptree&)> send_response_;
    rai::ErrorCode error_code_;
    rai::Ptree request_;
    rai::Ptree response_;

protected:
    bool CheckControl_();
    bool CheckLocal_();
    bool GetAccount_(rai::Account&);
    bool GetCount_(uint64_t&);
    bool GetHash_(rai::BlockHash&);
    bool GetHeight_(uint64_t&);
    bool GetPrevious_(rai::BlockHash&);
    bool GetSignature_(rai::Signature&);
    bool GetTimestamp_(uint64_t&);
    bool GetNext_(rai::Account&);
    bool GetAccountTypes_(std::vector<rai::BlockType>&);
};

std::unique_ptr<rai::Rpc> MakeRpc(boost::asio::io_service&,
                                  const rai::RpcConfig&,
                                  const rai::RpcHandlerMaker&);

}  // namespace rai

max_stars_repo_name: gokoo/Raicoin

max_issues_repo_name: Cryptonoz/Raicoin

max_forks_repo_name: Cryptonoz/Raicoin


text:
#include "G4chroma.hh"
#include <G4OpticalPhysics.hh>
#include <G4EmPenelopePhysics.hh>

ChromaPhysicsList::ChromaPhysicsList():  G4VModularPhysicsList()
{
  // default cut value  (1.0mm)
  defaultCutValue = 1.0*mm;

  // General Physics
  RegisterPhysics( new G4EmPenelopePhysics(0) );
  // Optical Physics
  G4OpticalPhysics* opticalPhysics = new G4OpticalPhysics();
  RegisterPhysics( opticalPhysics );
}

ChromaPhysicsList::~ChromaPhysicsList()
{
}

void ChromaPhysicsList::SetCuts(){
  //  " G4VUserPhysicsList::SetCutsWithDefault" method sets
  //   the default cut value for all particle types
  SetCutsWithDefault();
}

PhotonTrackingAction::PhotonTrackingAction()
{
}

PhotonTrackingAction::~PhotonTrackingAction()
{
}

int PhotonTrackingAction::GetNumPhotons() const
{
  return pos.size();
}

void PhotonTrackingAction::AssignNumPhotons(int n)
{
  pos.assign(n,G4ThreeVector());
  dir.assign(n,G4ThreeVector());
  pol.assign(n,G4ThreeVector());
  wavelength.assign(n, 0.0);
  t0.assign(n, 0.0);
}

void PhotonTrackingAction::Clear()
{
  pos.clear();
  dir.clear();
  pol.clear();
  wavelength.clear();
  t0.clear();
}

void PhotonTrackingAction::GetX(double *x) const
{
  for (unsigned i=0; i < pos.size(); i++) x[i] = pos[i].x();
}
void PhotonTrackingAction::GetY(double *y) const
{
  for (unsigned i=0; i < pos.size(); i++) y[i] = pos[i].y();
}
void PhotonTrackingAction::GetZ(double *z) const
{
  for (unsigned i=0; i < pos.size(); i++) z[i] = pos[i].z();
}

void PhotonTrackingAction::SetX(const double *x)
{
  for (unsigned i=0; i < pos.size(); i++) pos[i].setX(x[i]);
}

void PhotonTrackingAction::SetY(const double *y)
{
  for (unsigned i=0; i < pos.size(); i++) pos[i].setY(y[i]);
}

void PhotonTrackingAction::SetZ(const double *z)
{
  for (unsigned i=0; i < pos.size(); i++) pos[i].setZ(z[i]);
}

void PhotonTrackingAction::GetDirX(double *dir_x) const
{
  for (unsigned i=0; i < dir.size(); i++) dir_x[i] = dir[i].x();
}

void PhotonTrackingAction::GetDirY(double *dir_y) const
{
  for (unsigned i=0; i < dir.size(); i++) dir_y[i] = dir[i].y();
}

void PhotonTrackingAction::GetDirZ(double *dir_z) const
{
  for (unsigned i=0; i < dir.size(); i++) dir_z[i] = dir[i].z();
}

void PhotonTrackingAction::SetDirX(const double *dir_x)
{
  for (unsigned i=0; i < dir.size(); i++) dir[i].setX(dir_x[i]);
}

void PhotonTrackingAction::SetDirY(const double *dir_y)
{
  for (unsigned i=0; i < dir.size(); i++) dir[i].setY(dir_y[i]);
}

void PhotonTrackingAction::SetDirZ(const double *dir_z)
{
  for (unsigned i=0; i < dir.size(); i++) dir[i].setZ(dir_z[i]);
}

void PhotonTrackingAction::GetPolX(double *pol_x) const
{
  for (unsigned i=0; i < pol.size(); i++) pol_x[i] = pol[i].x();
}

void PhotonTrackingAction::GetPolY(double *pol_y) const
{
  for (unsigned i=0; i < pol.size(); i++) pol_y[i] = pol[i].y();
}

void PhotonTrackingAction::GetPolZ(double *pol_z) const
{
  for (unsigned i=0; i < pol.size(); i++) pol_z[i] = pol[i].z();
}

void PhotonTrackingAction::GetWavelength(double *wl) const
{
  for (unsigned i=0; i < wavelength.size(); i++) wl[i] = wavelength[i];
}

void PhotonTrackingAction::GetT0(double *t) const
{
  for (unsigned i=0; i < t0.size(); i++) t[i] = t0[i];
}

void PhotonTrackingAction::PreUserTrackingAction(const G4Track *track)
{
  G4ParticleDefinition *particle = track->GetDefinition();
  if (particle->GetParticleName() == "opticalphoton") {
    pos.push_back(track->GetPosition()/mm);
    dir.push_back(track->GetMomentumDirection());
    pol.push_back(track->GetPolarization());
    wavelength.push_back( (h_Planck * c_light / track->GetKineticEnergy()) / nanometer );
    t0.push_back(track->GetGlobalTime() / ns);
    const_cast<G4Track *>(track)->SetTrackStatus(fStopAndKill);
  }
}

//http://docs.scipy.org/doc/numpy-dev/reference/c-api.deprecations.html
//#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

#include <boost/python.hpp>
#include <pyublas/numpy.hpp>

using namespace boost::python;

pyublas::numpy_vector<double> PTA_GetX(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetX(&r[0]);
  return r;
}
// http://documen.tician.de/pyublas/converters.html
void PTA_SetX(PhotonTrackingAction *pta, const pyublas::numpy_vector<double>& r)
{
  pta->SetX(&r[0]);
}

pyublas::numpy_vector<double> PTA_GetY(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetY(&r[0]);
  return r;
}
void PTA_SetY(PhotonTrackingAction *pta, const pyublas::numpy_vector<double>& r)
{
  pta->SetY(&r[0]);
}

pyublas::numpy_vector<double> PTA_GetZ(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetZ(&r[0]);
  return r;
}
void PTA_SetZ(PhotonTrackingAction *pta, const pyublas::numpy_vector<double>& r)
{
  pta->SetZ(&r[0]);
}

pyublas::numpy_vector<double> PTA_GetDirX(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetDirX(&r[0]);
  return r;
}

pyublas::numpy_vector<double> PTA_GetDirY(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetDirY(&r[0]);
  return r;
}

pyublas::numpy_vector<double> PTA_GetDirZ(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetDirZ(&r[0]);
  return r;
}

void PTA_SetDirX(PhotonTrackingAction *pta, const pyublas::numpy_vector<double>& r)
{
  pta->SetDirX(&r[0]);
}
void PTA_SetDirY(PhotonTrackingAction *pta, const pyublas::numpy_vector<double>& r)
{
  pta->SetDirY(&r[0]);
}
void PTA_SetDirZ(PhotonTrackingAction *pta, const pyublas::numpy_vector<double>& r)
{
  pta->SetDirZ(&r[0]);
}

pyublas::numpy_vector<double> PTA_GetPolX(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetPolX(&r[0]);
  return r;
}

pyublas::numpy_vector<double> PTA_GetPolY(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetPolY(&r[0]);
  return r;
}

pyublas::numpy_vector<double> PTA_GetPolZ(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetPolZ(&r[0]);
  return r;
}

pyublas::numpy_vector<double> PTA_GetWave(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetWavelength(&r[0]);
  return r;
}

pyublas::numpy_vector<double> PTA_GetT0(const PhotonTrackingAction *pta)
{
  pyublas::numpy_vector<double> r(pta->GetNumPhotons());
  pta->GetT0(&r[0]);
  return r;
}

void export_Chroma()
{
  class_<ChromaPhysicsList, ChromaPhysicsList*, bases<G4VModularPhysicsList>, boost::noncopyable > ("ChromaPhysicsList", "EM+Optics physics list")
    .def(init<>())
    ;

  class_<PhotonTrackingAction, PhotonTrackingAction*, bases<G4UserTrackingAction>,
	 boost::noncopyable > ("PhotonTrackingAction", "Tracking action that saves photons")
    .def(init<>())
    .def("GetNumPhotons", &PhotonTrackingAction::GetNumPhotons)
    .def("AssignNumPhotons", &PhotonTrackingAction::AssignNumPhotons)
    .def("Clear", &PhotonTrackingAction::Clear)
    .def("GetX", PTA_GetX)
    .def("GetY", PTA_GetY)
    .def("GetZ", PTA_GetZ)
    .def("GetDirX", PTA_GetDirX)
    .def("GetDirY", PTA_GetDirY)
    .def("GetDirZ", PTA_GetDirZ)
    .def("GetPolX", PTA_GetPolX)
    .def("GetPolY", PTA_GetPolY)
    .def("GetPolZ", PTA_GetPolZ)
    .def("GetWavelength", PTA_GetWave)
    .def("GetT0", PTA_GetT0)
    .def("SetX", PTA_SetX)
    .def("SetY", PTA_SetY)
    .def("SetZ", PTA_SetZ)
    .def("SetDirX", PTA_SetDirX)
    .def("SetDirY", PTA_SetDirY)
    .def("SetDirZ", PTA_SetDirZ)
    ;
}

BOOST_PYTHON_MODULE(_g4chroma)
{
  export_Chroma();
}


text:
/* Copyright Institute of Sound and Vibration Research - All rights reserved */

#include <libefl/vector_functions.hpp>
#include <libefl/vector_functions_reference.hpp>

#include <libefl/aligned_array.hpp>

#include <boost/test/unit_test.hpp>
#include <libefl/lagrange_coefficient_calculator.hpp>

#include <algorithm>
#include <cmath>
#include <complex>
#include <iostream>
#include <valarray>

namespace visr
{
namespace efl
{
namespace test
{

BOOST_AUTO_TEST_CASE( instantiateL7 )
{
  constexpr std::size_t order = 7;

  bool const reverseCoefficients = true;

  using InterType = efl::LagrangeCoefficientCalculator<float, order, reverseCoefficients>;

  InterType lagInt;

  float const mu = -0.25;

  std::array<float, order+1> res;
  lagInt.calculateCoefficients( mu, &res[0] );

//  std::cout << "storage size: " << InterType::storageSize() << std::endl;
}

} // namespace test
} // namespace rbbl
} // namespace visr


text:
/*! \brief Automatically configures and runs a Benchmark from a CFG file.

    This program 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.
    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
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <cmath>
#include <array>
#include <string>

#include <boost/variant.hpp>

#include "../fmm/fmdata/fmcell.h"
#include "../ndgridmap/ndgridmap.hpp"

#include "../fmm/fmm.hpp"
#include "../fmm/fim.hpp"
#include "../fmm/gmm.hpp"
#include "../fmm/ufmm.hpp"

#include "../fmm/fmdata/fmfibheap.hpp"
#include "../fmm/fmdata/fmdaryheap.hpp"
#include "../fmm/fmdata/fmpriorityqueue.hpp"

#include "../benchmark/benchmark.hpp"
#include "../benchmark/benchmarkcfg.hpp"

using namespace std;

int main(int argc, const char ** argv)
{
    // Parse input.
    if (argc < 2)
    {
        std::cerr << "Usage:\n\t " << argv[0] << " problem.cfg" << std::endl;
        return 1;
    }

    // Parse the CFG file.
    BenchmarkCFG bcfg;
    if (bcfg.readOptions(argv[1]))
    {
        // If FMCell is used...
        if(bcfg.getValue<std::string>("grid.cell") == "FMCell")
        {
            // ... and for dimensions...
            switch (bcfg.getValue<unsigned int>("grid.ndims"))
            {
                case 2:
                {
                    Benchmark<nDGridMap<FMCell,2> > b;
                    bcfg.configure<nDGridMap<FMCell,2>, FMCell>(b);
                    b.run();
                    break;
                }
                case 3:
                {
                    Benchmark<nDGridMap<FMCell,3> > b;
                    bcfg.configure<nDGridMap<FMCell,3>, FMCell>(b);
                    b.run();
                    break;
                }
                // Include here new dimensions copying, pasting and changing x.
                /*case x:
                {
                    Benchmark<nDGridMap<FMCell,x> > b;
                    bcfg.configure<nDGridMap<FMCell,x>, FMCell>(b);
                    b.run();
                    break;
                }*/
            }
        }
        else // else if (bcfg.getValue<std::string>("grid.cell") == "MyCell")
        {
            // Include here new celltypes and include the corresponding switch dimensions as for FMCell.
            // ... and for dimensions...
            /*switch (bcfg.getValue<unsigned int>("grid.ndims"))
            {
                case 2:
                {
                    Benchmark<nDGridMap<MyCell,2> > b;
                    bcfg.configure<nDGridMap<MyCell,2>, MyCell>(b);
                    b.run();
                    break;
                }
                //...
            }*/
        }
    }
}


text:
/**
 * Copyright (c) 2019 Osaka University
 *
 * This software is released under the MIT License.
 *
 * 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.
 *
 * @author Yoji Yamamoto
 *
 */
#ifndef PRODUCER_HPP_INC
#define PRODUCER_HPP_INC

#include <memory>
#include <random>
#include <thread>
#include <unordered_map>
#include <vector>

#include <boost/asio.hpp>
#include <boost/noncopyable.hpp>
#include <boost/system/error_code.hpp>

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/validator-null.hpp>

#include "objectdetection.hpp"

namespace ndn {
class Interest;
class Data;
class InterestFilter;
class Name;
};  // namespace ndn

class Producer : boost::noncopyable {
 public:
  Producer(int mode, detector_ptr detector);
  ~Producer();
  void run();
  void adddata(std::string result);

 private:
  void onInterest(const ndn::InterestFilter& filter, const ndn::Interest& interest);
  void onInterest_Cloud(const ndn::InterestFilter& filter, const ndn::Interest& interest);
  void onRegisterFailed(const ndn::Name& prefix, const std::string& reason);
  void onData(const ndn::Interest&, const ndn::Data& data);
  void onNack(const ndn::Interest&, ndn::lp::Nack& nack);
  void onTimeout(const ndn::Interest& interest);

  void send_data(const boost::system::error_code& error, uint64_t session_id);
  //この3つはまとめる
  void convertInterestName(const std::string& interest_name, std::vector<std::string> &interest_name_list);
  std::vector<std::string> ExtractTargets(const std::string& interest_name);
  std::vector<std::string> ExtractLocname(const std::string& interest_name);
  std::string decodeURI(const std::string& uri);

  template <class F> void post_task(F f);
  boost::asio::io_service& io_service();

 private:
  ndn::KeyChain m_key_chain;
  ndn::Face     m_ndn_face;

  std::unique_ptr<ndn::Face> m_ndn_face_ptr;

  const uint_fast32_t m_num_thread;
  const uint_fast32_t m_num_queue;
  uint_fast32_t m_current_queue;

  std::vector<boost::asio::io_service> m_io_service_pool;
  std::vector<boost::asio::io_service::work> m_worker_pool;
  std::vector<std::thread> m_thread_pool;

  boost::asio::io_service m_timer_service;
  std::shared_ptr<boost::asio::io_service::work> m_timer_worker;

  static const uint_fast32_t m_timeout_second = 10000;

  std::mt19937_64 m_id_generator;

  const uint8_t m_edge_mode;
  detector_ptr m_detector;

  std::vector<std::string> m_target_name;
  std::vector<std::string> m_location_name;

  uint64_t m_number_of_arrival_interest;
  uint64_t m_issued_interest;

};
#endif


text:
#include <boost/make_shared.hpp>
#include <thrift/server/TSimpleServer.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include "gen-cpp/nvi_types.h"
#include "gen-cpp/NVITest.h"

using namespace ::apache::thrift::server;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using boost::make_shared;

class NVITestHandler : public NVITestIf {
public:
    NVITestHandler() : trade_count(0) { ; }
    int32_t report_trade(const Trade& trade) override {
        return ++trade_count;
    }
private:
    int32_t trade_count;
};

int main() {
    auto handler = make_shared<NVITestHandler>();
    auto proc = make_shared<NVITestProcessor>(handler);
    auto svr_trans = make_shared<TServerSocket>(8585);
    auto trans_fac = make_shared<TBufferedTransportFactory>();
    auto proto_fac = make_shared<TBinaryProtocolFactoryT<TBufferedTransport>>();
    TSimpleServer server(proc, svr_trans, trans_fac, proto_fac);
    server.serve();
    return 0;
}

max_stars_repo_name: csaltos/ThriftBook

max_issues_repo_name: csaltos/ThriftBook

max_forks_repo_name: csaltos/ThriftBook


text:
#include <preprocessor/options.h>
#include <boost/program_options.hpp>

namespace preprocessor
{
	boost::program_options::options_description setup_options()
	{
		boost::program_options::options_description desc("Preprocessing options");

		return desc;
	}
}

max_stars_repo_name: Lewerow/DetailIdentifier

max_issues_repo_name: Lewerow/DetailIdentifier

max_forks_repo_name: Lewerow/DetailIdentifier


text:
#include "stdafx.h"
#include "CppUnitTest.h"

#include <vector>
#include <algorithm>
#include <boost\timer.hpp>
#include <CppUnitTestLogger.h>
#include "UnitTestAux.h"
#include "../BVP/Utils/AuxUtils.h"
#include "../BVP/Utils/SolutionUtils.h"
#include <string>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace GeneralTest
{
TEST_CLASS(simplification_test)
{
public:
	template <bool Deriv>
	void Run_simplification_test()
	{
		const auto solution = auxutils::ReadFromFile<InitCondition<double>>("TestData\\solution_double_precision.txt");
		const auto length_init = solutionutils::length<Deriv>(solution);

		boost::timer t;

		double percentage_of_points_to_keep = 0.01;
		const auto solution_simplified = solutionutils::simplify_polyline<Deriv>(solution, percentage_of_points_to_keep);

		Logger::WriteMessage((std::string("Simplification time : ") + auxutils::ToString(t.elapsed())+"\n").c_str());

		const auto length_simplified = solutionutils::length<Deriv>(solution_simplified);

		auto diff = std::abs(length_init - length_simplified);

		Logger::WriteMessage((std::string("Length before simplification : ") + auxutils::ToString(length_init)+"\n").c_str());
		Logger::WriteMessage((std::string("Length after simplification : ") + auxutils::ToString(length_simplified) + "\n").c_str());
		Logger::WriteMessage((std::string("Length difference : ") + auxutils::ToString(diff)+"\n").c_str());

		Assert::IsTrue(diff < 2e-7, L"Too big difference in th elength before and after simplification");
		Assert::IsTrue(solution_simplified.size()/solution.size() <= percentage_of_points_to_keep, L"Unexpectedly many points have been left");

		//auxutils::SaveToFile(solution_simplified, "E:\\Research\\Derivative_simplified_double_precision.txt");
		//auxutils::SaveFunction<Deriv>("x", "u", "E:\\Research\\derivative_to_plot.txt", solution_simplified);
	}

	TEST_METHOD(Function_simplification_test)
	{
		Run_simplification_test<false>();
	}

	TEST_METHOD(Derivative_simplification_test)
	{
		Run_simplification_test<true>();
	}
};
}

max_stars_repo_name: imathsoft/MathSoftDevelopment

max_issues_repo_name: imathsoft/MathSoftDevelopment

max_forks_repo_name: imathsoft/MathSoftDevelopment