<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#ifndef _Stroika_Foundation_DataExchangeFormat_ObjectVariantMapper_inl_
#define _Stroika_Foundation_DataExchangeFormat_ObjectVariantMapper_inl_  1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "../Execution/Exceptions.h"

#include    "BadFormatException.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   DataExchangeFormat {

            /*
             ********************************************************************************
             ******************* ObjectVariantMapper::StructureFieldInfo ********************
             ********************************************************************************
             */
            inline  ObjectVariantMapper::StructureFieldInfo::StructureFieldInfo (size_t fieldOffset, type_index typeInfo, const String& serializedFieldName)
                : fOffset (fieldOffset)
                , fTypeInfo (typeInfo)
                , fSerializedFieldName (serializedFieldName)
            {
            }

            /*
             ********************************************************************************
             ******************************** ObjectVariantMapper ***************************
             ********************************************************************************
             */
            inline  Set<ObjectVariantMapper::TypeMappingDetails>    ObjectVariantMapper::GetTypeMappingRegistry () const
            {
                return fSerializers_;
            }
            inline  void    ObjectVariantMapper::SetTypeMappingRegistry (const Set<TypeMappingDetails>& s)
            {
                fSerializers_ = s;
            }
            template    <typename CLASS>
            inline  void    ObjectVariantMapper::RegisterClass (const Sequence<StructureFieldInfo>& fieldDescriptions)
            {
                RegisterTypeMapper (TypeMappingDetails (typeid (CLASS), sizeof (CLASS), fieldDescriptions));
            }
            template    <typename CLASS>
            inline  void    ObjectVariantMapper::ToObject (const Memory::VariantValue& v, CLASS* into) const
            {
                ToObject  (typeid (CLASS), v, reinterpret_cast<Byte*> (into));
            }
            template    <typename CLASS>
            inline  CLASS    ObjectVariantMapper::ToObject (const Memory::VariantValue& v) const
            {
                CLASS tmp;
                ToObject (v, &tmp);
                return tmp;
            }
            template    <typename CLASS>
            inline  VariantValue    ObjectVariantMapper::FromObject (const CLASS& from) const
            {
                return FromObject  (typeid (CLASS), reinterpret_cast<const Byte*> (&from));
            }
            template <typename T, size_t SZ>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Array ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    Sequence<VariantValue> s;
                    const T*  actualMember    =   reinterpret_cast<const T*> (fromObjOfTypeT);
                    for (auto i = actualMember; i < actualMember + SZ; ++i) {
                        s.Append (mapper->FromObject<T> (*i));
                    }
                    return VariantValue (s);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    Sequence<VariantValue> s  =   d.As<Sequence<T>> ();
                    T*  actualMember    =   reinterpret_cast<T*> (intoObjOfTypeT);
                    if (s.size () > SZ) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                    size_t idx = 0;
                    for (auto i : s) {
                        actualMember[idx++] = mapper->ToObject<T> (i);
                    }
                    while (idx < SZ) {
                        actualMember[idx++] = T ();
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (Sequence<T>), toVariantMapper, fromVariantMapper);
            }
            template    <typename T>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Sequence ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    Sequence<VariantValue> s;
                    const Sequence<T>*  actualMember    =   reinterpret_cast<const Sequence<T>*> (fromObjOfTypeT);
                    for (auto i : *actualMember) {
                        s.Append (mapper->FromObject<T> (i));
                    }
                    return VariantValue (s);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    Sequence<VariantValue> s  =   d.As<Sequence<T>> ();
                    Sequence<T>*    actualInto  =   reinterpret_cast<Sequence<T>*> (intoObjOfTypeT);
                    actualInto->clear ();
                    for (auto i : s) {
                        actualInto->Append (mapper->ToObject<T> (i));
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (Sequence<T>), toVariantMapper, fromVariantMapper);
            }
            template    <typename KEY_TYPE, typename VALUE_TYPE>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Mapping ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    Sequence<VariantValue> s;
                    const Mapping<KEY_TYPE, VALUE_TYPE>*  actualMember    =   reinterpret_cast<const Mapping<KEY_TYPE, VALUE_TYPE>*> (fromObjOfTypeT);
                    for (auto i : *actualMember) {
                        Sequence<VariantValue>  encodedPair;
                        encodedPair.Append (mapper->FromObject<KEY_TYPE> (i.fKey));
                        encodedPair.Append (mapper->FromObject<VALUE_TYPE> (i.fValue));
                        s.Append (VariantValue (encodedPair));
                    }
                    return VariantValue (s);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    Sequence<VariantValue>          s  =   d.As<Sequence<VariantValue>> ();
                    Mapping<KEY_TYPE, VALUE_TYPE>*  actualInto  =   reinterpret_cast<Mapping<KEY_TYPE, VALUE_TYPE>*> (intoObjOfTypeT);
                    actualInto->clear ();
                    for (VariantValue encodedPair : s) {
                        Sequence<VariantValue>  p   =   p.As<Sequence<VariantValue>> ();
                        if (p.size () != 2) {
                            Execution::DoThrow<BadFormatException> (BadFormatException ());
                        }
                        actualInto->Add (mapper->ToObject<KEY_TYPE> (p[0]), mapper->ToObject<VALUE_TYPE> (p[1]));
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (Mapping<KEY_TYPE, VALUE_TYPE>), toVariantMapper, fromVariantMapper);
            }
            template    <typename KEY_TYPE, typename VALUE_TYPE>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_MappingWithStringishKey ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    const Mapping<KEY_TYPE, VALUE_TYPE>*  actualMember    =   reinterpret_cast<const Mapping<KEY_TYPE, VALUE_TYPE>*> (fromObjOfTypeT);
                    Mapping<String, VariantValue> m;
                    for (Common::KeyValuePair<KEY_TYPE, VALUE_TYPE> i : *actualMember) {
                        m.Add (mapper->FromObject<KEY_TYPE> (i.fKey).template As<String> (), mapper->FromObject<VALUE_TYPE> (i.fValue));
                    }
                    return VariantValue (m);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    Mapping<String, VariantValue>    m  =   d.As<Mapping<String, VariantValue>> ();
                    Mapping<KEY_TYPE, VALUE_TYPE>*  actualInto  =   reinterpret_cast<Mapping<KEY_TYPE, VALUE_TYPE>*> (intoObjOfTypeT);
                    actualInto->clear ();
                    for (Common::KeyValuePair<String, VariantValue> p : m) {
                        actualInto->Add (mapper->ToObject<KEY_TYPE> (p.fKey), mapper->ToObject<VALUE_TYPE> (p.fValue));
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (Mapping<KEY_TYPE, VALUE_TYPE>), toVariantMapper, fromVariantMapper);
            }
            template <typename RANGE_TYPE>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Range ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    typedef typename RANGE_TYPE::ElementType    ElementType;
                    Mapping<String, VariantValue> m;
                    const RANGE_TYPE*  actualMember    =   reinterpret_cast<const RANGE_TYPE*> (fromObjOfTypeT);
                    m.Add (L"Begin", mapper->FromObject<ElementType> (actualMember->begin ()));
                    m.Add (L"End", mapper->FromObject<ElementType> (actualMember->end ()));
                    return VariantValue (m);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    typedef typename RANGE_TYPE::ElementType    ElementType;
                    Mapping<String, VariantValue>          m  =   d.As<Mapping<String, VariantValue>> ();
                    RANGE_TYPE*  actualInto  =   reinterpret_cast<RANGE_TYPE*> (intoObjOfTypeT);
                    if (m.size () != 2) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                    if (not m.ContainsKey (L"Begin") or not m.ContainsKey (L"End")) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                    ElementType from    =   mapper->ToObject<ElementType> (*m.Lookup (L"Begin"));
                    ElementType to      =   mapper->ToObject<ElementType> (*m.Lookup (L"End"));
                    if (not (RANGE_TYPE::TraitsType::kMin <= from and from < RANGE_TYPE::TraitsType::kMax)) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                    if (not (RANGE_TYPE::TraitsType::kMin <= to and to < RANGE_TYPE::TraitsType::kMax)) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                    * actualInto = RANGE_TYPE (from, to);
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (RANGE_TYPE), toVariantMapper, fromVariantMapper);
            }
            template <typename ENUM_TYPE>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Enumeration ()
            {
                /*
                 *  Note: we cannot get the enumeration print names - in general. That would be nicer to read, but we dont have
                 *  the data, and this is simple and efficient.
                 */
                Require (std::is_enum<ENUM_TYPE>::value);
#if     qCompilerAndStdLib_Supports_TypeTraits_underlying_type
                typedef typename std::underlying_type<ENUM_TYPE>::type SerializeAsType;
#else
                typedef long long SerializeAsType;
#endif
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    const ENUM_TYPE*  actualMember    =   reinterpret_cast<const ENUM_TYPE*> (fromObjOfTypeT);
#if     qCompilerAndStdLib_Supports_TypeTraits_underlying_type
                    Assert (sizeof (SerializeAsType) == sizeof (ENUM_TYPE));
#endif
                    Assert (static_cast<ENUM_TYPE> (static_cast<SerializeAsType> (*actualMember)) == *actualMember);    // no round-trip loss
                    return VariantValue (static_cast<SerializeAsType> (*actualMember));
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    ENUM_TYPE*  actualInto  =   reinterpret_cast<ENUM_TYPE*> (intoObjOfTypeT);
                    * actualInto = static_cast<ENUM_TYPE> (d.As<SerializeAsType> ());
#if     qCompilerAndStdLib_Supports_TypeTraits_underlying_type
                    Assert (sizeof (SerializeAsType) == sizeof (ENUM_TYPE));
#endif
                    Assert (static_cast<SerializeAsType> (*actualInto) == d.As<SerializeAsType> ());  // no round-trip loss
                    if (not (ENUM_TYPE::eSTART <= *actualInto and * actualInto <= ENUM_TYPE::eEND)) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (ENUM_TYPE), toVariantMapper, fromVariantMapper);
            }

#if 0
            template    <typename T>
            inline  ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer<Sequence<T>> ()
            {
                return mkSerializerInfoFor_Sequence_<T> ();
            }
#endif

        }
    }
}
#endif  /*_Stroika_Foundation_DataExchangeFormat_ObjectVariantMapper_inl_*/
<commit_msg>Fixed DataExchangeFormat/ObjectVariantMapper code to use CheckedConverter_Range<RANGE_TYPE> () instead of its own manual checking<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#ifndef _Stroika_Foundation_DataExchangeFormat_ObjectVariantMapper_inl_
#define _Stroika_Foundation_DataExchangeFormat_ObjectVariantMapper_inl_  1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "../Execution/Exceptions.h"

#include    "BadFormatException.h"
#include    "CheckedConverter.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   DataExchangeFormat {

            /*
             ********************************************************************************
             ******************* ObjectVariantMapper::StructureFieldInfo ********************
             ********************************************************************************
             */
            inline  ObjectVariantMapper::StructureFieldInfo::StructureFieldInfo (size_t fieldOffset, type_index typeInfo, const String& serializedFieldName)
                : fOffset (fieldOffset)
                , fTypeInfo (typeInfo)
                , fSerializedFieldName (serializedFieldName)
            {
            }

            /*
             ********************************************************************************
             ******************************** ObjectVariantMapper ***************************
             ********************************************************************************
             */
            inline  Set<ObjectVariantMapper::TypeMappingDetails>    ObjectVariantMapper::GetTypeMappingRegistry () const
            {
                return fSerializers_;
            }
            inline  void    ObjectVariantMapper::SetTypeMappingRegistry (const Set<TypeMappingDetails>& s)
            {
                fSerializers_ = s;
            }
            template    <typename CLASS>
            inline  void    ObjectVariantMapper::RegisterClass (const Sequence<StructureFieldInfo>& fieldDescriptions)
            {
                RegisterTypeMapper (TypeMappingDetails (typeid (CLASS), sizeof (CLASS), fieldDescriptions));
            }
            template    <typename CLASS>
            inline  void    ObjectVariantMapper::ToObject (const Memory::VariantValue& v, CLASS* into) const
            {
                ToObject  (typeid (CLASS), v, reinterpret_cast<Byte*> (into));
            }
            template    <typename CLASS>
            inline  CLASS    ObjectVariantMapper::ToObject (const Memory::VariantValue& v) const
            {
                CLASS tmp;
                ToObject (v, &tmp);
                return tmp;
            }
            template    <typename CLASS>
            inline  VariantValue    ObjectVariantMapper::FromObject (const CLASS& from) const
            {
                return FromObject  (typeid (CLASS), reinterpret_cast<const Byte*> (&from));
            }
            template <typename T, size_t SZ>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Array ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    Sequence<VariantValue> s;
                    const T*  actualMember    =   reinterpret_cast<const T*> (fromObjOfTypeT);
                    for (auto i = actualMember; i < actualMember + SZ; ++i) {
                        s.Append (mapper->FromObject<T> (*i));
                    }
                    return VariantValue (s);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    Sequence<VariantValue> s  =   d.As<Sequence<T>> ();
                    T*  actualMember    =   reinterpret_cast<T*> (intoObjOfTypeT);
                    if (s.size () > SZ) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                    size_t idx = 0;
                    for (auto i : s) {
                        actualMember[idx++] = mapper->ToObject<T> (i);
                    }
                    while (idx < SZ) {
                        actualMember[idx++] = T ();
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (Sequence<T>), toVariantMapper, fromVariantMapper);
            }
            template    <typename T>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Sequence ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    Sequence<VariantValue> s;
                    const Sequence<T>*  actualMember    =   reinterpret_cast<const Sequence<T>*> (fromObjOfTypeT);
                    for (auto i : *actualMember) {
                        s.Append (mapper->FromObject<T> (i));
                    }
                    return VariantValue (s);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    Sequence<VariantValue> s  =   d.As<Sequence<T>> ();
                    Sequence<T>*    actualInto  =   reinterpret_cast<Sequence<T>*> (intoObjOfTypeT);
                    actualInto->clear ();
                    for (auto i : s) {
                        actualInto->Append (mapper->ToObject<T> (i));
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (Sequence<T>), toVariantMapper, fromVariantMapper);
            }
            template    <typename KEY_TYPE, typename VALUE_TYPE>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Mapping ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    Sequence<VariantValue> s;
                    const Mapping<KEY_TYPE, VALUE_TYPE>*  actualMember    =   reinterpret_cast<const Mapping<KEY_TYPE, VALUE_TYPE>*> (fromObjOfTypeT);
                    for (auto i : *actualMember) {
                        Sequence<VariantValue>  encodedPair;
                        encodedPair.Append (mapper->FromObject<KEY_TYPE> (i.fKey));
                        encodedPair.Append (mapper->FromObject<VALUE_TYPE> (i.fValue));
                        s.Append (VariantValue (encodedPair));
                    }
                    return VariantValue (s);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    Sequence<VariantValue>          s  =   d.As<Sequence<VariantValue>> ();
                    Mapping<KEY_TYPE, VALUE_TYPE>*  actualInto  =   reinterpret_cast<Mapping<KEY_TYPE, VALUE_TYPE>*> (intoObjOfTypeT);
                    actualInto->clear ();
                    for (VariantValue encodedPair : s) {
                        Sequence<VariantValue>  p   =   p.As<Sequence<VariantValue>> ();
                        if (p.size () != 2) {
                            Execution::DoThrow<BadFormatException> (BadFormatException ());
                        }
                        actualInto->Add (mapper->ToObject<KEY_TYPE> (p[0]), mapper->ToObject<VALUE_TYPE> (p[1]));
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (Mapping<KEY_TYPE, VALUE_TYPE>), toVariantMapper, fromVariantMapper);
            }
            template    <typename KEY_TYPE, typename VALUE_TYPE>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_MappingWithStringishKey ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    const Mapping<KEY_TYPE, VALUE_TYPE>*  actualMember    =   reinterpret_cast<const Mapping<KEY_TYPE, VALUE_TYPE>*> (fromObjOfTypeT);
                    Mapping<String, VariantValue> m;
                    for (Common::KeyValuePair<KEY_TYPE, VALUE_TYPE> i : *actualMember) {
                        m.Add (mapper->FromObject<KEY_TYPE> (i.fKey).template As<String> (), mapper->FromObject<VALUE_TYPE> (i.fValue));
                    }
                    return VariantValue (m);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    Mapping<String, VariantValue>    m  =   d.As<Mapping<String, VariantValue>> ();
                    Mapping<KEY_TYPE, VALUE_TYPE>*  actualInto  =   reinterpret_cast<Mapping<KEY_TYPE, VALUE_TYPE>*> (intoObjOfTypeT);
                    actualInto->clear ();
                    for (Common::KeyValuePair<String, VariantValue> p : m) {
                        actualInto->Add (mapper->ToObject<KEY_TYPE> (p.fKey), mapper->ToObject<VALUE_TYPE> (p.fValue));
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (Mapping<KEY_TYPE, VALUE_TYPE>), toVariantMapper, fromVariantMapper);
            }
            template <typename RANGE_TYPE>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Range ()
            {
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    typedef typename RANGE_TYPE::ElementType    ElementType;
                    Mapping<String, VariantValue> m;
                    const RANGE_TYPE*  actualMember    =   reinterpret_cast<const RANGE_TYPE*> (fromObjOfTypeT);
                    m.Add (L"Begin", mapper->FromObject<ElementType> (actualMember->begin ()));
                    m.Add (L"End", mapper->FromObject<ElementType> (actualMember->end ()));
                    return VariantValue (m);
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    typedef typename RANGE_TYPE::ElementType    ElementType;
                    Mapping<String, VariantValue>          m  =   d.As<Mapping<String, VariantValue>> ();
                    RANGE_TYPE*  actualInto  =   reinterpret_cast<RANGE_TYPE*> (intoObjOfTypeT);
                    if (m.size () != 2) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                    if (not m.ContainsKey (L"Begin") or not m.ContainsKey (L"End")) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                    ElementType from    =   mapper->ToObject<ElementType> (*m.Lookup (L"Begin"));
                    ElementType to      =   mapper->ToObject<ElementType> (*m.Lookup (L"End"));
                    * actualInto = CheckedConverter_Range<RANGE_TYPE> (from, to);
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (RANGE_TYPE), toVariantMapper, fromVariantMapper);
            }
            template <typename ENUM_TYPE>
            ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_Enumeration ()
            {
                /*
                 *  Note: we cannot get the enumeration print names - in general. That would be nicer to read, but we dont have
                 *  the data, and this is simple and efficient.
                 */
                Require (std::is_enum<ENUM_TYPE>::value);
#if     qCompilerAndStdLib_Supports_TypeTraits_underlying_type
                typedef typename std::underlying_type<ENUM_TYPE>::type SerializeAsType;
#else
                typedef long long SerializeAsType;
#endif
                auto toVariantMapper = [] (const ObjectVariantMapper * mapper, const Byte * fromObjOfTypeT) -> VariantValue {
                    const ENUM_TYPE*  actualMember    =   reinterpret_cast<const ENUM_TYPE*> (fromObjOfTypeT);
#if     qCompilerAndStdLib_Supports_TypeTraits_underlying_type
                    Assert (sizeof (SerializeAsType) == sizeof (ENUM_TYPE));
#endif
                    Assert (static_cast<ENUM_TYPE> (static_cast<SerializeAsType> (*actualMember)) == *actualMember);    // no round-trip loss
                    return VariantValue (static_cast<SerializeAsType> (*actualMember));
                };
                auto fromVariantMapper = [] (const ObjectVariantMapper * mapper, const VariantValue & d, Byte * intoObjOfTypeT) -> void {
                    ENUM_TYPE*  actualInto  =   reinterpret_cast<ENUM_TYPE*> (intoObjOfTypeT);
                    * actualInto = static_cast<ENUM_TYPE> (d.As<SerializeAsType> ());
#if     qCompilerAndStdLib_Supports_TypeTraits_underlying_type
                    Assert (sizeof (SerializeAsType) == sizeof (ENUM_TYPE));
#endif
                    Assert (static_cast<SerializeAsType> (*actualInto) == d.As<SerializeAsType> ());  // no round-trip loss
                    if (not (ENUM_TYPE::eSTART <= *actualInto and * actualInto <= ENUM_TYPE::eEND)) {
                        Execution::DoThrow<BadFormatException> (BadFormatException ());
                    }
                };
                return ObjectVariantMapper::TypeMappingDetails (typeid (ENUM_TYPE), toVariantMapper, fromVariantMapper);
            }

#if 0
            template    <typename T>
            inline  ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer<Sequence<T>> ()
            {
                return mkSerializerInfoFor_Sequence_<T> ();
            }
#endif

        }
    }
}
#endif  /*_Stroika_Foundation_DataExchangeFormat_ObjectVariantMapper_inl_*/
<|endoftext|>


<commit_before>#include"all_defines.hpp"

#include"symbols.hpp"
#include"mutexes.hpp"

#include<boost/noncopyable.hpp>

#include<string>
#include<map>

void Symbol::copy_value_to(ValueHolderRef& p) {
	{AppLock l(m);
		/*Unfortunately the entire cloning has to be
		done while we have the lock.  This is because
		a Symbol::set_value() might invalidate the
		pointer from under us if we didn't do the
		entire cloning locked.
		Other alternatives exist: we can use a locked
		reference counting scheme, or use some sort
		of deferred deallocation.
		*/
		value->clone(p);
	}
}
void Symbol::copy_value_to_and_add_notify(ValueHolderRef& p, Process* R) {
	{AppLock l(m);
		value->clone(p);
		/*check for dead processes in notification list*/
		size_t j = 0;
		for(size_t i = 0; i < notification_list.size(); ++i) {
			if(!notification_list[i]->is_dead()) {
				if(i != j) {
					notification_list[j] = notification_list[i];
				}
				++j;
			}
		}
		notification_list.resize(j + 1);
		notification_list[j] = R;
	}
}

void Symbol::set_value(Object::ref o) {
	ValueHolderRef tmp;
	ValueHolder::copy_object(tmp, o);
	{AppLock l(m);
		value.swap(tmp);
		size_t j = 0;
		for(size_t i = 0; i < notification_list.size(); ++i) {
			if(!notification_list[i]->is_dead()) {
				if(i != j) {
					notification_list[j] = notification_list[i];
				}
				++j;
				notification_list[j]->notify_global_change(this);
			}
		}
		notification_list.resize(j);
	}
}

typedef std::map<std::string, Symbol*> maptype;

Symbol* SymbolsTable::lookup(std::string x) {
	{AppLock l(m);
		Symbol*& s = tb[x];
		if(s) return s;
		s = new Symbol(x);
		return s;
	}
}

void SymbolsTable::traverse_symbols(SymbolsTableTraverser* stt) const {
	for(maptype::const_iterator it = tb.begin(); it != tb.end(); ++it) {
		stt->traverse(it->second);
	}
}

class SymbolDeletor : public SymbolsTableTraverser {
public:
	virtual void traverse(Symbol* s) {
		delete s;
	}
};

SymbolsTable::~SymbolsTable() {
	/*go through the table and delete each symbol*/
	SymbolDeletor sd;
	traverse_symbols(&sd);
}

<commit_msg>src/symbols.cpp: Added missing include for processes.hpp<commit_after>#include"all_defines.hpp"

#include"symbols.hpp"
#include"processes.hpp"
#include"mutexes.hpp"

#include<boost/noncopyable.hpp>

#include<string>
#include<map>

void Symbol::copy_value_to(ValueHolderRef& p) {
	{AppLock l(m);
		/*Unfortunately the entire cloning has to be
		done while we have the lock.  This is because
		a Symbol::set_value() might invalidate the
		pointer from under us if we didn't do the
		entire cloning locked.
		Other alternatives exist: we can use a locked
		reference counting scheme, or use some sort
		of deferred deallocation.
		*/
		value->clone(p);
	}
}
void Symbol::copy_value_to_and_add_notify(ValueHolderRef& p, Process* R) {
	{AppLock l(m);
		value->clone(p);
		/*check for dead processes in notification list*/
		size_t j = 0;
		for(size_t i = 0; i < notification_list.size(); ++i) {
			if(!notification_list[i]->is_dead()) {
				if(i != j) {
					notification_list[j] = notification_list[i];
				}
				++j;
			}
		}
		notification_list.resize(j + 1);
		notification_list[j] = R;
	}
}

void Symbol::set_value(Object::ref o) {
	ValueHolderRef tmp;
	ValueHolder::copy_object(tmp, o);
	{AppLock l(m);
		value.swap(tmp);
		size_t j = 0;
		for(size_t i = 0; i < notification_list.size(); ++i) {
			if(!notification_list[i]->is_dead()) {
				if(i != j) {
					notification_list[j] = notification_list[i];
				}
				++j;
				notification_list[j]->notify_global_change(this);
			}
		}
		notification_list.resize(j);
	}
}

typedef std::map<std::string, Symbol*> maptype;

Symbol* SymbolsTable::lookup(std::string x) {
	{AppLock l(m);
		Symbol*& s = tb[x];
		if(s) return s;
		s = new Symbol(x);
		return s;
	}
}

void SymbolsTable::traverse_symbols(SymbolsTableTraverser* stt) const {
	for(maptype::const_iterator it = tb.begin(); it != tb.end(); ++it) {
		stt->traverse(it->second);
	}
}

class SymbolDeletor : public SymbolsTableTraverser {
public:
	virtual void traverse(Symbol* s) {
		delete s;
	}
};

SymbolsTable::~SymbolsTable() {
	/*go through the table and delete each symbol*/
	SymbolDeletor sd;
	traverse_symbols(&sd);
}

<|endoftext|>


<commit_before>#include "cc_music_locate.hh"
#include "cc_music_io.hh"
#include "cc_music_edit.hh"
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

Vec4i locateSymbolsX(Mat, Vec4i);

vector<Vec4i> locateSheetLines(Mat image){
  vector<Vec4i> lines;
  Mat temp;

  Mat kernel = (Mat_<float>(3,3) <<  0, -1, 0, 0, 3, 0, 0, -1, 0);
  filter2D(image, temp, image.depth(), kernel);
  image = temp;

  polarize(image, 128);

  int threshold = image.cols / 10;
  int minLen = image.cols / 2;
  int maxGap = 10;
  HoughLinesP(image, lines, 1, CV_PI/180, threshold, minLen, maxGap);

  auto cmp = [](const Vec4i& l, const Vec4i& r){
    return l[1]<r[1];
  };
  sort(lines.begin(), lines.end(), cmp);

  return lines;
}

vector<Vec4i> locateFrames(vector<Vec4i> lines){
  vector<Vec4i> mid, res;
  size_t i,j;
  int min_x, max_x, min_y, max_y;

  for(i = 0; i<lines.size(); i++){
    if (i==0){
      mid.push_back(lines[i]);
    } else {
      if (lines[i][1]!=lines[i-1][1]+1)
        mid.push_back(lines[i]);
    }
  }

  if (mid.size()%5!=0){
    cout << "Number does not match." << endl;
    cout << "Found: " << mid.size() << endl;
    return vector<Vec4i>();
  }

  for (i=0; i<mid.size(); i++)
    if (i%5 == 0){
        min_x = mid[i][0];
        min_y = mid[i][1];
        max_x = mid[i][2];
        max_y = mid[i][3];
    } else {
      if (min_x > mid[i][0]) min_x = mid[i][0];
      if (min_y > mid[i][1]) min_y = mid[i][1];
      if (max_x < mid[i][2]) max_x = mid[i][2];
      if (max_y < mid[i][3]) max_y = mid[i][3];
      if (i%5 == 4){
        int space = (max_y - min_y)/2;
        res.push_back(Vec4i(min_x, min_y - space, max_x + 1, max_y + space));
      }
    }

  return res;
}

vector<Vec4i> locateSymbols(Mat image, Vec4i frame){
  vector<Vec4i> res, resx;
  vector<int> weight;
  int i,j;
  int x1 = frame[0];
  int y1 = frame[1];
  int x2 = frame[2];
  int y2 = frame[3];

  weight.resize(x2 - x1 + 1, 0);
  for (i=y1; i<=y2; i++){
    uchar* row = image.ptr<uchar>(i);
    for (j=x1; j<=x2; j++){
      if (row[j] == 255) weight[j-x1]++;
    }
  }

  bool streak = false;
  int xa = 0;
  for (j=x1; j<=x2; j++){
    int a = weight[j-x1];
    if (a != 0 && !streak){
      xa = j;
      streak = true;
    }
    if (a == 0 && streak){
      streak = false;
      resx.push_back(Vec4i(xa, y1, j, y2));
    }
  }
  for (Vec4i v : resx){
    vector<Vec4i> r = locateSymbolsX(image, v);
    res.insert(res.end(), r.begin(), r.end());
  }
  return res;
}

Vec4i locateSymbolsX(Mat image, Vec4i frame){
  vector<Vec4i> res;
  vector<int> weight;
  int i,j;
  int x1 = frame[0];
  int y1 = frame[1];
  int x2 = frame[2];
  int y2 = frame[3];

  weight.resize(y2 - y1 + 1, 0);
  for (i=y1; i<=y2; i++){
    uchar* row = image.ptr<uchar>(i);
    for (j=x1; j<=x2; j++){
      if (row[j] == 255) weight[i-y1]++;
    }
  }

  bool streak = false;
  int ya = 0;
  for (j=y1; j<=y2; j++){
    int a = weight[j-y1];
    if (a != 0 && !streak){
      ya = j;
      streak = true;
    }
    if (a == 0 && streak){
      res.push_back(Vec4i(x1, ya, x2, j));
    }
  }
  return res;
}
<commit_msg>Modify symbol locate<commit_after>#include "cc_music_locate.hh"
#include "cc_music_io.hh"
#include "cc_music_edit.hh"
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

vector<Vec4i> locateSymbolsX(Mat, Vec4i);

vector<Vec4i> locateSheetLines(Mat image){
  vector<Vec4i> lines;
  Mat temp;

  Mat kernel = (Mat_<float>(3,3) <<  0, -1, 0, 0, 3, 0, 0, -1, 0);
  filter2D(image, temp, image.depth(), kernel);
  image = temp;

  polarize(image, 128);

  int threshold = image.cols / 10;
  int minLen = image.cols / 2;
  int maxGap = 10;
  HoughLinesP(image, lines, 1, CV_PI/180, threshold, minLen, maxGap);

  auto cmp = [](const Vec4i& l, const Vec4i& r){
    return l[1]<r[1];
  };
  sort(lines.begin(), lines.end(), cmp);

  return lines;
}

vector<Vec4i> locateFrames(vector<Vec4i> lines){
  vector<Vec4i> mid, res;
  size_t i,j;
  int min_x, max_x, min_y, max_y;

  for(i = 0; i<lines.size(); i++){
    if (i==0){
      mid.push_back(lines[i]);
    } else {
      if (lines[i][1]!=lines[i-1][1]+1)
        mid.push_back(lines[i]);
    }
  }

  if (mid.size()%5!=0){
    cout << "Number does not match." << endl;
    cout << "Found: " << mid.size() << endl;
    return vector<Vec4i>();
  }

  for (i=0; i<mid.size(); i++)
    if (i%5 == 0){
        min_x = mid[i][0];
        min_y = mid[i][1];
        max_x = mid[i][2];
        max_y = mid[i][3];
    } else {
      if (min_x > mid[i][0]) min_x = mid[i][0];
      if (min_y > mid[i][1]) min_y = mid[i][1];
      if (max_x < mid[i][2]) max_x = mid[i][2];
      if (max_y < mid[i][3]) max_y = mid[i][3];
      if (i%5 == 4){
        int space = (max_y - min_y)/2;
        res.push_back(Vec4i(min_x, min_y - space, max_x + 1, max_y + space));
      }
    }

  return res;
}

vector<Vec4i> locateSymbols(Mat image, Vec4i frame){
  vector<Vec4i> res, resx;
  vector<int> weight;
  int i,j;
  int x1 = frame[0];
  int y1 = frame[1];
  int x2 = frame[2];
  int y2 = frame[3];

  weight.resize(x2 - x1 + 1, 0);
  for (i=y1; i<=y2; i++){
    uchar* row = image.ptr<uchar>(i);
    for (j=x1; j<=x2; j++){
      if (row[j] == 255) weight[j-x1]++;
    }
  }

  bool streak = false;
  int xa = 0;
  for (j=x1; j<=x2; j++){
    int a = weight[j-x1];
    if (a != 0 && !streak){
      xa = j;
      streak = true;
    }
    if (a == 0 && streak){
      streak = false;
      resx.push_back(Vec4i(xa, y1, j, y2));
    }
  }
  for (Vec4i v : resx){
    vector<Vec4i> r = locateSymbolsX(image, v);
    res.insert(res.end(), r.begin(), r.end());
  }
  return res;
}

vector<Vec4i> locateSymbolsX(Mat image, Vec4i frame){
  vector<Vec4i> res;
  vector<int> weight;
  int i,j;
  int x1 = frame[0];
  int y1 = frame[1];
  int x2 = frame[2];
  int y2 = frame[3];

  weight.resize(y2 - y1 + 1, 0);
  for (i=y1; i<=y2; i++){
    uchar* row = image.ptr<uchar>(i);
    for (j=x1; j<=x2; j++){
      if (row[j] == 255) weight[i-y1]++;
    }
  }

  bool streak = false;
  int ya = 0;
  for (j=y1; j<=y2; j++){
    int a = weight[j-y1];
    if (a != 0 && !streak){
      ya = j;
      streak = true;
    }
    if (a == 0 && streak){
      streak = false;
      res.push_back(Vec4i(x1, ya, x2, j));
    }
  }
  return res;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include <iostream>
#include <sstream>
#include <vector>
#include <string>

#include <mapnik/version.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_renderer_agg.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-local-typedef"
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#pragma GCC diagnostic pop

#include "agg_rasterizer_scanline_aa.h"
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_renderer_base.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"

#include <libxml/parser.h> // for xmlInitParser(), xmlCleanupParser()

struct main_marker_visitor
{
    main_marker_visitor(std::string & svg_name,
                        int & return_value,
                        bool verbose,
                        bool auto_open)
        : svg_name_(svg_name),
          return_value_(return_value),
          verbose_(verbose),
          auto_open_(auto_open) {}

    void operator() (mapnik::marker_null const&)
    {
        std::clog << "svg2png error: '" << svg_name_ << "' is not a valid vector!\n";
        return_value_ = -1;
    }

    void operator() (mapnik::marker_rgba8 const&)
    {
        std::clog << "svg2png error: '" << svg_name_ << "' is not a valid vector!\n";
        return_value_ = -1;
    }

    void operator() (mapnik::marker_svg const& marker)
    {
        using pixfmt = agg::pixfmt_rgba32_pre;
        using renderer_base = agg::renderer_base<pixfmt>;
        using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>;
        agg::rasterizer_scanline_aa<> ras_ptr;
        agg::scanline_u8 sl;

        double opacity = 1;
        int w = marker.width();
        int h = marker.height();
        if (verbose_)
        {
            std::clog << "found width of '" << w << "' and height of '" << h << "'\n";
        }
        // 10 pixel buffer to avoid edge clipping of 100% svg's
        mapnik::image_rgba8 im(w+0,h+0);
        agg::rendering_buffer buf(im.bytes(), im.width(), im.height(), im.row_size());
        pixfmt pixf(buf);
        renderer_base renb(pixf);

        mapnik::box2d<double> const& bbox = marker.get_data()->bounding_box();
        mapnik::coord<double,2> c = bbox.center();
        // center the svg marker on '0,0'
        agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
        // render the marker at the center of the marker box
        mtx.translate(0.5 * im.width(), 0.5 * im.height());

        mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker.get_data()->source());
        mapnik::svg::svg_path_adapter svg_path(stl_storage);
        mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter,
            agg::pod_bvector<mapnik::svg::path_attributes>,
            renderer_solid,
            agg::pixfmt_rgba32_pre > svg_renderer_this(svg_path,
                                                       marker.get_data()->attributes());

        svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox);

        boost::algorithm::ireplace_last(svg_name_,".svg",".png");
        demultiply_alpha(im);
        mapnik::save_to_file<mapnik::image_rgba8>(im,svg_name_,"png");
        if (auto_open_)
        {
            std::ostringstream s;
#ifdef DARWIN
            s << "open " << svg_name_;
#else
            s << "xdg-open " << svg_name_;
#endif
            int ret = system(s.str().c_str());
            if (ret != 0)
                return_value_ = ret;
        }
        std::clog << "rendered to: " << svg_name_ << "\n";

    }

  private:
    std::string & svg_name_;
    int & return_value_;
    bool verbose_;
    bool auto_open_;
};

int main (int argc,char** argv)
{
    namespace po = boost::program_options;

    bool verbose = false;
    bool auto_open = false;
    int return_value = 0;
    std::vector<std::string> svg_files;
    mapnik::logger::instance().set_severity(mapnik::logger::error);

    try
    {
        po::options_description desc("svg2png utility");
        desc.add_options()
            ("help,h", "produce usage message")
            ("version,V","print version string")
            ("verbose,v","verbose output")
            ("open","automatically open the file after rendering (os x only)")
            ("svg",po::value<std::vector<std::string> >(),"svg file to read")
            ;

        po::positional_options_description p;
        p.add("svg",-1);
        po::variables_map vm;
        po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
        po::notify(vm);

        if (vm.count("version"))
        {
            std::clog <<"version " << MAPNIK_VERSION_STRING << std::endl;
            return 1;
        }

        if (vm.count("help"))
        {
            std::clog << desc << std::endl;
            return 1;
        }

        if (vm.count("verbose"))
        {
            verbose = true;
        }

        if (vm.count("open"))
        {
            auto_open = true;
        }

        if (vm.count("svg"))
        {
            svg_files=vm["svg"].as< std::vector<std::string> >();
        }
        else
        {
            std::clog << "please provide an svg file!" << std::endl;
            return -1;
        }

        std::vector<std::string>::const_iterator itr = svg_files.begin();
        if (itr == svg_files.end())
        {
            std::clog << "no svg files to render" << std::endl;
            return 0;
        }

        xmlInitParser();

        while (itr != svg_files.end())
        {
            std::string svg_name (*itr++);
            if (verbose)
            {
                std::clog << "found: " << svg_name << "\n";
            }

            std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
            main_marker_visitor visitor(svg_name, return_value, verbose, auto_open);
            mapnik::util::apply_visitor(visitor, *marker);
        }
    }
    catch (...)
    {
        std::clog << "Exception of unknown type!" << std::endl;
        xmlCleanupParser();
        return -1;
    }

    // only call this once, on exit
    // to make sure valgrind output is clean
    // http://xmlsoft.org/xmlmem.html
    xmlCleanupParser();
    return return_value;
}
<commit_msg>make visitor return `status` + don't mutating `svg_name_`<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include <iostream>
#include <sstream>
#include <vector>
#include <string>

#include <mapnik/version.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_renderer_agg.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-local-typedef"
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#pragma GCC diagnostic pop

#include "agg_rasterizer_scanline_aa.h"
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_renderer_base.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"

#include <libxml/parser.h> // for xmlInitParser(), xmlCleanupParser()

struct main_marker_visitor
{
    main_marker_visitor(std::string const& svg_name,
                        bool verbose,
                        bool auto_open)
        : svg_name_(svg_name),
          verbose_(verbose),
          auto_open_(auto_open) {}

    int operator() (mapnik::marker_null const&)
    {
        std::clog << "svg2png error: '" << svg_name_ << "' is not a valid vector!\n";
        return -1;
    }

    int operator() (mapnik::marker_rgba8 const&)
    {
        std::clog << "svg2png error: '" << svg_name_ << "' is not a valid vector!\n";
        return  -1;
    }

    int operator() (mapnik::marker_svg const& marker)
    {
        using pixfmt = agg::pixfmt_rgba32_pre;
        using renderer_base = agg::renderer_base<pixfmt>;
        using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>;
        agg::rasterizer_scanline_aa<> ras_ptr;
        agg::scanline_u8 sl;

        double opacity = 1;
        int w = marker.width();
        int h = marker.height();
        if (verbose_)
        {
            std::clog << "found width of '" << w << "' and height of '" << h << "'\n";
        }
        // 10 pixel buffer to avoid edge clipping of 100% svg's
        mapnik::image_rgba8 im(w+0,h+0);
        agg::rendering_buffer buf(im.bytes(), im.width(), im.height(), im.row_size());
        pixfmt pixf(buf);
        renderer_base renb(pixf);

        mapnik::box2d<double> const& bbox = marker.get_data()->bounding_box();
        mapnik::coord<double,2> c = bbox.center();
        // center the svg marker on '0,0'
        agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
        // render the marker at the center of the marker box
        mtx.translate(0.5 * im.width(), 0.5 * im.height());

        mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker.get_data()->source());
        mapnik::svg::svg_path_adapter svg_path(stl_storage);
        mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter,
            agg::pod_bvector<mapnik::svg::path_attributes>,
            renderer_solid,
            agg::pixfmt_rgba32_pre > svg_renderer_this(svg_path,
                                                       marker.get_data()->attributes());

        svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox);

        std::string png_name(svg_name_);
        boost::algorithm::ireplace_last(png_name,".svg",".png");
        demultiply_alpha(im);
        mapnik::save_to_file<mapnik::image_rgba8>(im,png_name,"png");
        int status = 0;
        if (auto_open_)
        {
            std::ostringstream s;
#ifdef DARWIN
            s << "open " << png_name;
#else
            s << "xdg-open " << png_name;
#endif
            int ret = system(s.str().c_str());
            if (ret != 0)
                status = ret;
        }
        std::clog << "rendered to: " << svg_name_ << "\n";
        return status;
    }

  private:
    std::string const& svg_name_;
    bool verbose_;
    bool auto_open_;
};

int main (int argc,char** argv)
{
    namespace po = boost::program_options;

    bool verbose = false;
    bool auto_open = false;
    int status = 0;
    std::vector<std::string> svg_files;
    mapnik::logger::instance().set_severity(mapnik::logger::error);

    try
    {
        po::options_description desc("svg2png utility");
        desc.add_options()
            ("help,h", "produce usage message")
            ("version,V","print version string")
            ("verbose,v","verbose output")
            ("open","automatically open the file after rendering (os x only)")
            ("svg",po::value<std::vector<std::string> >(),"svg file to read")
            ;

        po::positional_options_description p;
        p.add("svg",-1);
        po::variables_map vm;
        po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
        po::notify(vm);

        if (vm.count("version"))
        {
            std::clog <<"version " << MAPNIK_VERSION_STRING << std::endl;
            return 1;
        }

        if (vm.count("help"))
        {
            std::clog << desc << std::endl;
            return 1;
        }

        if (vm.count("verbose"))
        {
            verbose = true;
        }

        if (vm.count("open"))
        {
            auto_open = true;
        }

        if (vm.count("svg"))
        {
            svg_files=vm["svg"].as< std::vector<std::string> >();
        }
        else
        {
            std::clog << "please provide an svg file!" << std::endl;
            return -1;
        }

        std::vector<std::string>::const_iterator itr = svg_files.begin();
        if (itr == svg_files.end())
        {
            std::clog << "no svg files to render" << std::endl;
            return 0;
        }

        xmlInitParser();

        while (itr != svg_files.end())
        {
            std::string svg_name (*itr++);
            if (verbose)
            {
                std::clog << "found: " << svg_name << "\n";
            }

            std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
            main_marker_visitor visitor(svg_name, verbose, auto_open);
            status = mapnik::util::apply_visitor(visitor, *marker);
        }
    }
    catch (...)
    {
        std::clog << "Exception of unknown type!" << std::endl;
        xmlCleanupParser();
        return -1;
    }

    // only call this once, on exit
    // to make sure valgrind output is clean
    // http://xmlsoft.org/xmlmem.html
    xmlCleanupParser();
    return status;
}
<|endoftext|>


<commit_before>#pragma once

#include <memory>
#include <iostream>
#include <array>
#include <mutex>
#include <cassert>

namespace petsc
{
class TimeStepper;
namespace TimeStepper_private
{
    // template< typename context >
    std::function<PetscErrorCode(TS, PetscReal, Vec, Mat*, Mat*, MatStructure*)>
    jacobian;

    PetscErrorCode jacobian_function_( TS ts,
                                       PetscReal t,
                                       Vec u,
                                       Mat* A,
                                       Mat* B,
                                       MatStructure* ms,
                                       void* cntx );

    // template< typename context >
    std::function<PetscErrorCode( TS, PetscReal, Vec, Vec )> rhs;

    PetscErrorCode
    rhs_function_( TS ts, PetscReal t, Vec v, Vec f, void* cntx );
}
class TimeStepper
{
  public:

    typedef PetscErrorCode( jacobian_function_type )(
        TS, PetscReal, Vec, Mat*, Mat*, MatStructure* );

    typedef PetscErrorCode( rhs_function_type )( TS, PetscReal, Vec, Vec );
    // This won't immediately run, because that is impractical (a lot of
    // optional setup)
    TimeStepper( const MPI_Comm& comm,
                 TSProblemType pt,
                 TSType type,
                 PetscReal t0,
                 PetscReal dt,
                 Vector& solution,
                 PetscReal tf,
                 PetscInt max_step,
                 std::function<jacobian_function_type> jac,
                 std::function<rhs_function_type> rhs,
                 Matrix& rhs_mat_initial )
    {
        TSCreate( comm, &ts_ );
        TSSetProblemType( ts_, pt );
        TSSetType( ts_, type );
        TSSetInitialTimeStep( ts_, t0, dt );
        TSSetSolution( ts_, solution.v_ );
        if ( max_step > 0 )
            TSSetDuration( ts_, static_cast<int>( ( tf - t0 ) / dt ), tf );
        else
            TSSetDuration( ts_, max_step, tf );
        TSSetFromOptions( ts_ );

        TSSetRHSJacobian( ts_,
                          rhs_mat_initial.m_,
                          rhs_mat_initial.m_,
                          TimeStepper_private::jacobian_function_,
                          NULL );

        TimeStepper_private::jacobian = jac;
        if ( pt == TS_LINEAR )
            TSSetRHSFunction( ts_, NULL, TSComputeRHSFunctionLinear, NULL );
        else {
            TSSetRHSFunction(
                ts_, NULL, TimeStepper_private::rhs_function_, NULL );
            TimeStepper_private::rhs = rhs;
        }

        TSSolve( ts_, PETSC_NULL );
    }

    explicit TimeStepper( TS& ts ) : ts_( ts ) {}

    TimeStepper( Vector& solution,
                 PetscReal t0,
                 PetscReal tf,
                 PetscReal dt,
                 std::function<jacobian_function_type> jac,
                 Matrix& rhs_mat_initial,
                 TSProblemType pt = TS_LINEAR,
                 TSType type = TSCN )
        : TimeStepper( solution.comm(),
                       pt,
                       type,
                       t0,
                       dt,
                       solution,
                       tf,
                       -1,
                       jac,
                       nullptr,
                       rhs_mat_initial ) {}

    TimeStepper( const TimeStepper& other ) = delete;

    TimeStepper( TimeStepper&& other ) : ts_( other.ts_ )
    {
        other.ts_ = PETSC_NULL;
    }

    ~TimeStepper()
    {
        TSDestroy( &ts_ );
    }

    // func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);
    // void rhs_function( std::function<PetscErrorCode(
    // TimeStepper, PetscReal, Vector, Vector )> rhs_function_ )
    //{
    // TimeStepper_private::rhs = rhs_function_;
    //}

    //// func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void
    //// *ctx);
    // void rhs_jacobian( std::function<PetscErrorCode(
    // TS, PetscReal, Vec, Mat*, Mat*, MatStructure*)>
    // jac_function_ )
    //{
    // TimeStepper_private::jacobian = jac_function_;
    //}

    TS ts_;
};

PetscErrorCode TimeStepper_private::jacobian_function_(
    TS ts, PetscReal t, Vec u, Mat* A, Mat* B, MatStructure* ms, void* cntx )
{
    return TimeStepper_private::jacobian( ts, t, u, A, B, ms );
}
PetscErrorCode TimeStepper_private::rhs_function_(
    TS ts, PetscReal t, Vec v, Vec f, void* cntx )
{
    return TimeStepper_private::rhs( ts, t, v, f );
}
}
<commit_msg>TimeStepper initial commit.<commit_after>#pragma once

#include <petsc.h>
#ifdef SLEPC
#include <slepc.h>
#endif

#include <petsc_cpp/Vector.hpp>
#include <petsc_cpp/Matrix.hpp>

namespace petsc
{

class TimeStepper
{
    /* Interested in solving problems of the type:

       F(t, u, u') = G(t, u)

       Where the jacobian is F_u + (shift) F_u'.  G_u is the RHS jacobian.

       For the most common case:

       u' = A(t) u:

       G = A(t) u
       G_u = A(t).
       F = u'
       F_u + (shift) F_u' = (shift)
    */
  public:
    using RHSJacobian =
        PetscErrorCode ( * )( TS, PetscReal, Vec, Mat, Mat, void* );
    using RHS = PetscErrorCode ( * )( TS, PetscReal, Vec, Vec, void* );

    using LHSJacobian = PetscErrorCode ( * )(
        TS, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void* );
    using LHS = PetscErrorCode ( * )( TS, PetscReal, Vec, Vec, Vec, void* );

    enum class problem_type { linear = TS_LINEAR, nonlinear = TS_NONLINEAR };

    struct time {
        double t0, tf, dt;
    };

    TimeStepper( problem_type type,
                 TSType solver_type,
                 const MPI_Comm& comm = PETSC_COMM_WORLD )
    {
        TSCreate( comm, &ts );
        TSSetProblemType( ts, static_cast<TSProblemType>( type ) );
        TSSetType( ts, solver_type );
    }

    /* For simple case u' = A(t) u */
    // Jac has approximate type (Vector& u, Matrix& A, Matrix& B, TimeStepper&
    // ts, double time)
    template <typename Jac>
    TimeStepper( Jac G_u,
                 Matrix& A,
                 time t,
                 TSType solver_type,
                 const MPI_Comm& comm = PETSC_COMM_WORLD )
        : TimeStepper( problem_type::linear, solver_type, comm )
    {
        assert( A.comm() == comm );
        TSSetInitialTimeStep( ts, t.t0, t.dt );
        // TSSetSolution( ts, solution.v_ );
        TSSetDuration( ts, static_cast<int>( ( t.tf - t.t0 ) / t.dt ) + 10,
                       t.tf );
        TSSetFromOptions( ts );

        TSSetRHSFunction( ts, NULL, TSComputeRHSFunctionLinear, NULL );
        TSSetRHSJacobian( ts, A.m_, A.m_,
                          TimeStepper::RHSJacobian_function<Jac>, &G_u );
    }

    template <typename Jac>
    static PetscErrorCode
    RHSJacobian_function( TS ts, double t_, Vec u, Mat A, Mat B, void* G_u )
    {
        ( *(Jac*)G_u )( Vector( u, false ), Matrix( A, false ),
                        Matrix( B, false ), TimeStepper( ts, false ), t_ );
        return 0;
    }

    explicit TimeStepper( TS& ts, bool owned = false )
        : ts( ts ), owned( owned )
    {
    }

    /* rule of 4.5 */
    TimeStepper( const TimeStepper& other ) = delete;

    TimeStepper( TimeStepper&& other ) : ts( other.ts )
    {
        other.ts = PETSC_NULL;
    }

    ~TimeStepper()
    {
        if ( !owned ) TSDestroy( &ts );
    }

    void solve( Vector& u_0 ) { TSSolve( ts, u_0.v_ ); }

    void print() const { TSView( ts, PETSC_VIEWER_STDOUT_WORLD ); }

    template <typename Mon>
    void set_monitor( Mon m )
    {
        TSMonitorSet( ts,
                      []( TS ts, int step, double t, Vec u, void* monitor ) {
                          ( *(Mon*)monitor )( TimeStepper( ts, false ), step, t,
                                              Vector( u, false ) );
                      },
                      &m, PETSC_NULL );
    }

    TS ts;
    bool owned{true};
};
}
<|endoftext|>


<commit_before>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

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

******************************************************************************/
#ifndef NOMLIB_SYSTEM_SEARCH_PATH_HPP
#define NOMLIB_SYSTEM_SEARCH_PATH_HPP

#include <memory>
#include <string>
#include <vector>

#include "nomlib/config.hpp"
#include "nomlib/system/File.hpp"

#include "nomlib/ptree.hpp"
#include "nomlib/serializers.hpp"

namespace nom {

/// \brief Determine the directory location to use based on search prefixes
///
/// \todo Add an interface for using this class without a file.
class SearchPath
{
  public:
    typedef SearchPath self_type;

    typedef self_type* raw_ptr;
    typedef std::unique_ptr<self_type> unique_ptr;
    typedef std::shared_ptr<self_type> shared_ptr;

    /// \brief Default constructor; initialize the parser to NULL.
    SearchPath();

    /// \brief Destructor.
    ~SearchPath();

    /// \brief Get the resolved path.
    const std::string& path();

    /// \brief Set a custom parser.
    ///
    /// \remarks The default parser is JSON.
    void set_deserializer( std::unique_ptr<IValueDeserializer> fp );

    /// \brief Parse a file into memory.
    ///
    /// \param filename The absolute file path.
    /// \param node     The top-level object to use in formation of the path.
    ///
    /// \remarks The default parser is JSON, and can be changed using the
    /// ::set_deserializer method.
    bool load_file( const std::string& filename, const std::string& node );

  private:
    /// \brief Parser object to use.
    ///
    /// \see nom::IValueDeserializer
    std::unique_ptr<IValueDeserializer> fp_;

    /// \brief List of path prefixes to scan through with the given path.
    std::vector<std::string> search_prefix_;

    /// \brief The resolved path.
    std::string path_;
};

} // namespace nom

#endif // include guard defined

/// Usage example:
///
/// nom::SearchPath resources;
/// resources.load_file( "resources.json" );
///
/// ```resources.json```
/// (should generally be in the same directory as the executable)
///
/// \code
/// {
///   // Top-level object 'node'
///   "resources":
///   {
///     // List of paths to search
///     "search_prefix":
///     [
///       "./",
///       "../../",
///       "../../../"
///     ],
///     // The 'suffix' that is appended to each search prefix path during the
///     // scan; the first full path that exists will be what is returned on a
///     // call to ::path.
///     "path": "Resources/tests/gui/librocket/nomlibTest/"
///   }
/// }
/// \endcode
<commit_msg>SearchPaths: Use arg default for 2nd param in ::load_file method<commit_after>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

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

******************************************************************************/
#ifndef NOMLIB_SYSTEM_SEARCH_PATH_HPP
#define NOMLIB_SYSTEM_SEARCH_PATH_HPP

#include <memory>
#include <string>
#include <vector>

#include "nomlib/config.hpp"
#include "nomlib/system/File.hpp"

#include "nomlib/ptree.hpp"
#include "nomlib/serializers.hpp"

namespace nom {

/// \brief Determine the directory location to use based on search prefixes
///
/// \todo Add an interface for using this class without a file.
class SearchPath
{
  public:
    typedef SearchPath self_type;

    typedef self_type* raw_ptr;
    typedef std::unique_ptr<self_type> unique_ptr;
    typedef std::shared_ptr<self_type> shared_ptr;

    /// \brief Default constructor; initialize the parser to NULL.
    SearchPath();

    /// \brief Destructor.
    ~SearchPath();

    /// \brief Get the resolved path.
    const std::string& path();

    /// \brief Set a custom parser.
    ///
    /// \remarks The default parser is JSON.
    void set_deserializer( std::unique_ptr<IValueDeserializer> fp );

    /// \brief Parse a file into memory.
    ///
    /// \param filename The absolute file path.
    /// \param node     The top-level object to use in formation of the path;
    /// defaults to an object member by name of "resources".
    ///
    /// \remarks The default parser is JSON, and can be changed using the
    /// ::set_deserializer method.
    bool load_file( const std::string& filename, const std::string& node = "resources" );

  private:
    /// \brief Parser object to use.
    ///
    /// \see nom::IValueDeserializer
    std::unique_ptr<IValueDeserializer> fp_;

    /// \brief List of path prefixes to scan through with the given path.
    std::vector<std::string> search_prefix_;

    /// \brief The resolved path.
    std::string path_;
};

} // namespace nom

#endif // include guard defined

/// Common usage:
///
/// #include "nomlib/system.hpp"
///
/// int main( int argc, char** argv )
/// {
///   // Set the current working directory path to the path leading to this
///   // executable file; used for unit tests that require file-system I/O.
///   if( nom::init( argc, argv ) == false )
///   {
///     nom::DialogMessageBox( "Critical Error", "Could not initialize nomlib.", nom::MessageBoxType::NOM_DIALOG_ERROR );
///     return NOM_EXIT_FAILURE;
///   }
///   atexit( nom::quit );
///   return NOM_EXIT_SUCCESS;
/// }
///
/// nom::SearchPath resources;
/// resources.load_file( "resources.json" );
///
/// ```resources.json```
/// (should generally be in the same directory as the executable)
///
/// \code
/// {
///   // Top-level object 'node'
///   "resources":
///   {
///     // List of paths to search
///     "search_prefix":
///     [
///       "./",
///       "../../",
///       "../../../"
///     ],
///     // The 'suffix' that is appended to each search prefix path during the
///     // scan; the first full path that exists will be what is returned on a
///     // call to ::path.
///     "path": "Resources/tests/gui/librocket/nomlibTest/"
///   }
/// }
/// \endcode
<|endoftext|>


<commit_before>/* -*- Mode:C++; c-file-style:"gnu" -*- */
/*
 * Copyright 2014 Waseda University, Sato Laboratory
 *   Author: Zhu Li <phillipszhuli1990@gmail.com>
 *           Jairo Eduardo Lopez <jairo@ruri.waseda.jp>
 *
 *  nnn-face.cc is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  nnn-face.cc 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 Affero Public License for more details.
 *
 *  You should have received a copy of the GNU Affero Public License
 *  along with nnn-face.cc.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ns3-dev/ns3/assert.h>
#include <ns3-dev/ns3/boolean.h>
#include <ns3-dev/ns3/double.h>
#include <ns3-dev/ns3/log.h>
#include <ns3-dev/ns3/node.h>
#include <ns3-dev/ns3/packet.h>
#include <ns3-dev/ns3/uinteger.h>

#include <ns3-dev/ns3/simulator.h>
#include <ns3-dev/ns3/random-variable.h>
#include <ns3-dev/ns3/pointer.h>

#include "nnn-face.h"
#include "../helper/nnn-header-helper.h"
#include "wire/nnn-wire.h"

#include <boost/ref.hpp>

NS_LOG_COMPONENT_DEFINE ("nnn.Face");

namespace ns3 {
namespace nnn {

NS_OBJECT_ENSURE_REGISTERED (Face);

TypeId
Face::GetTypeId ()
{
	static TypeId tid = TypeId ("ns3::nnn::Face")
    		.SetParent<Object> ()
    		.SetGroupName ("Nnn")
    		.AddAttribute ("Id", "Face id (unique integer for the Nnn stack on this node)",
    				TypeId::ATTR_GET, // allow only getting it.
    				UintegerValue (0),
    				MakeUintegerAccessor (&Face::m_id),
    				MakeUintegerChecker<uint32_t> ())
    				;
	return tid;
}

/**
 * By default, Nnn face are created in the "down" state
 *  with no MAC addresses.  Before becoming useable, the user must
 * invoke SetUp on them once an Nnn address and mask have been set.
 */
Face::Face (Ptr<Node> node)
: m_node (node)
, m_upstreamNULLpHandler (MakeNullCallback< void, Ptr<Face>, Ptr<NULLp> > ())
, m_upstreamSOHandler (MakeNullCallback< void, Ptr<Face>, Ptr<SO> > ())
, m_upstreamDOHandler (MakeNullCallback< void, Ptr<Face>, Ptr<DO> > ())
, m_ifup (false)
, m_id ((uint32_t)-1)
, m_metric (0)
, m_flags (0)
{
	NS_LOG_FUNCTION (this << node);

	NS_ASSERT_MSG (node != 0, "node cannot be NULL. Check the code");
}

Face::~Face ()
{
	NS_LOG_FUNCTION_NOARGS ();
}

Face::Face (const Face &)
{
}

Face& Face::operator= (const Face &)
{
	return *this;
}

Ptr<Node>
Face::GetNode () const
{
	return m_node;
}

void
Face::RegisterProtocolHandlers (const NULLpHandler &NULLpHandler, const SOHandler &SOHandler,
		const DOHandler &DOHandler, const ENHandler &ENHandler,
		const AENHandler &AENHandler, const RENHandler &RENHandler,
		const INFHandler &INFHandler)
{
	NS_LOG_FUNCTION_NOARGS ();

	m_upstreamNULLpHandler = NULLpHandler;
	m_upstreamSOHandler = SOHandler;
	m_upstreamDOHandler = DOHandler;
	m_upstreamENHandler = ENHandler;
	m_upstreamAENHandler = AENHandler;
	m_upstreamRENHandler = RENHandler;
	m_upstreamINFHandler = INFHandler;
}

void
Face::UnRegisterProtocolHandlers ()
{
	NS_LOG_FUNCTION_NOARGS ();

	m_upstreamNULLpHandler = MakeNullCallback< void, Ptr<Face>, Ptr<NULLp> > ();
	m_upstreamSOHandler = MakeNullCallback< void, Ptr<Face>, Ptr<SO> > ();
	m_upstreamDOHandler = MakeNullCallback< void, Ptr<Face>, Ptr<DO> > ();
}

bool
Face::SendNULLp (Ptr<const NULLp> n_o)
{
	NS_LOG_FUNCTION (this << n_o);

	if (!IsUp ())
	{
		return false;
	}

	return Send (Wire::FromNULLp (n_o));
}

bool
Face::SendSO (Ptr<const SO> so_p)
{
	NS_LOG_FUNCTION (this << boost::cref (*this) << so_p->GetName ());

	if (!IsUp ())
	{
		return false;
	}

	return Send (Wire::FromSO (so_p));
}

bool
Face::SendDO (Ptr<const DO> do_p)
{
	NS_LOG_FUNCTION (this << boost::cref (*this) << do_p->GetName ());

	if (!IsUp ())
	{
		return false;
	}

	return Send (Wire::FromDO (do_p));
}

bool
Face::Send (Ptr<Packet> packet)
{
	return true;
}

bool
Face::Receive (Ptr<const Packet> p)
{
	NS_LOG_FUNCTION (this << p << p->GetSize ());

	if (!IsUp ())
	{
		// no tracing here. If we were off while receiving, we shouldn't even know that something was there
		return false;
	}

	Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
	try
	{
		HeaderHelper::Type type = HeaderHelper::GetNnnHeaderType (packet);
		switch (type)
		{
		case HeaderHelper::NULL_NNN:
			return ReceiveNULLp (Wire::ToNULLp (packet, Wire::WIRE_FORMAT_NNNSIM));
		case HeaderHelper::SO_NNN:
			return ReceiveSO (Wire::ToSO (packet, Wire::WIRE_FORMAT_NNNSIM));
		case HeaderHelper::DO_NNN:
			return ReceiveDO (Wire::ToDO (packet, Wire::WIRE_FORMAT_NNNSIM));
		default:
			NS_FATAL_ERROR ("Not supported NNN header");
			return false;
		}

		// exception will be thrown if packet is not recognized
	}
	catch (UnknownHeaderException)
	{
		NS_FATAL_ERROR ("Unknown NNN header. Should not happen");
		return false;
	}

	return false;
}

bool
Face::ReceiveNULLp (Ptr<NULLp> n_o)
{
	if (!IsUp ())
	{
		// no tracing here. If we were off while receiving, we shouldn't even know that something was there
		return false;
	}

	m_upstreamNULLpHandler (this, n_o);
	return true;
}

bool
Face::ReceiveSO (Ptr<SO> so_p)
{
	if (!IsUp ())
	{
		// no tracing here. If we were off while receiving, we shouldn't even know that something was there
		return false;
	}

	m_upstreamSOHandler (this, so_p);
	return true;
}

bool
Face::ReceiveDO (Ptr<DO> do_p)
{
	if (!IsUp ())
	{
		// no tracing here. If we were off while receiving, we shouldn't even know that something was there
		return false;
	}

	m_upstreamDOHandler (this, do_p);
	return true;
}

void
Face::SetMetric (uint16_t metric)
{
	NS_LOG_FUNCTION (metric);
	m_metric = metric;
}

uint16_t
Face::GetMetric (void) const
{
	return m_metric;
}

void
Face::SetFlags (uint32_t flags)
{
	m_flags = flags;
}

bool
Face::operator== (const Face &face) const
{
	NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
			"NN_Faces of different nodes should not be compared to each other: " << *this << " == " << face);

	return (m_id == face.m_id);
}

bool
Face::operator< (const Face &face) const
{
	NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
			"NN_Faces of different nodes should not be compared to each other: " << *this << " == " << face);

	return (m_id < face.m_id);
}

std::ostream&
Face::Print (std::ostream &os) const
{
	os << "id=" << GetId ();
	return os;
}

std::ostream&
operator<< (std::ostream& os, const Face &face)
{
	face.Print (os);
	return os;
}

} // namespace nnn
} // namespace ns3

<commit_msg>New headers for nnn-face.cc<commit_after>/* -*- Mode:C++; c-file-style:"gnu" -*- */
/*
 * Copyright 2014 Waseda University, Sato Laboratory
 *   Author: Zhu Li <phillipszhuli1990@gmail.com>
 *           Jairo Eduardo Lopez <jairo@ruri.waseda.jp>
 *
 *  nnn-face.cc is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  nnn-face.cc 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 Affero Public License for more details.
 *
 *  You should have received a copy of the GNU Affero Public License
 *  along with nnn-face.cc.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ns3-dev/ns3/assert.h>
#include <ns3-dev/ns3/boolean.h>
#include <ns3-dev/ns3/double.h>
#include <ns3-dev/ns3/log.h>
#include <ns3-dev/ns3/node.h>
#include <ns3-dev/ns3/packet.h>
#include <ns3-dev/ns3/uinteger.h>

#include <ns3-dev/ns3/simulator.h>
#include <ns3-dev/ns3/random-variable.h>
#include <ns3-dev/ns3/pointer.h>

#include "nnn-face.h"
#include "../helper/nnn-header-helper.h"
#include "wire/nnn-nnnsim-wire.h"

#include <boost/ref.hpp>

NS_LOG_COMPONENT_DEFINE ("nnn.Face");

namespace ns3 {
namespace nnn {

NS_OBJECT_ENSURE_REGISTERED (Face);

TypeId
Face::GetTypeId ()
{
	static TypeId tid = TypeId ("ns3::nnn::Face")
    		.SetParent<Object> ()
    		.SetGroupName ("Nnn")
    		.AddAttribute ("Id", "Face id (unique integer for the Nnn stack on this node)",
    				TypeId::ATTR_GET, // allow only getting it.
    				UintegerValue (0),
    				MakeUintegerAccessor (&Face::m_id),
    				MakeUintegerChecker<uint32_t> ())
    				;
	return tid;
}

/**
 * By default, Nnn face are created in the "down" state
 *  with no MAC addresses.  Before becoming useable, the user must
 * invoke SetUp on them once an Nnn address and mask have been set.
 */
Face::Face (Ptr<Node> node)
: m_node (node)
, m_upstreamNULLpHandler (MakeNullCallback< void, Ptr<Face>, Ptr<NULLp> > ())
, m_upstreamSOHandler (MakeNullCallback< void, Ptr<Face>, Ptr<SO> > ())
, m_upstreamDOHandler (MakeNullCallback< void, Ptr<Face>, Ptr<DO> > ())
, m_ifup (false)
, m_id ((uint32_t)-1)
, m_metric (0)
, m_flags (0)
{
	NS_LOG_FUNCTION (this << node);

	NS_ASSERT_MSG (node != 0, "node cannot be NULL. Check the code");
}

Face::~Face ()
{
	NS_LOG_FUNCTION_NOARGS ();
}

Face::Face (const Face &)
{
}

Face& Face::operator= (const Face &)
{
	return *this;
}

Ptr<Node>
Face::GetNode () const
{
	return m_node;
}

void
Face::RegisterProtocolHandlers (const NULLpHandler &NULLpHandler, const SOHandler &SOHandler,
		const DOHandler &DOHandler, const ENHandler &ENHandler,
		const AENHandler &AENHandler, const RENHandler &RENHandler,
		const INFHandler &INFHandler)
{
	NS_LOG_FUNCTION_NOARGS ();

	m_upstreamNULLpHandler = NULLpHandler;
	m_upstreamSOHandler = SOHandler;
	m_upstreamDOHandler = DOHandler;
	m_upstreamENHandler = ENHandler;
	m_upstreamAENHandler = AENHandler;
	m_upstreamRENHandler = RENHandler;
	m_upstreamINFHandler = INFHandler;
}

void
Face::UnRegisterProtocolHandlers ()
{
	NS_LOG_FUNCTION_NOARGS ();

	m_upstreamNULLpHandler = MakeNullCallback< void, Ptr<Face>, Ptr<NULLp> > ();
	m_upstreamSOHandler = MakeNullCallback< void, Ptr<Face>, Ptr<SO> > ();
	m_upstreamDOHandler = MakeNullCallback< void, Ptr<Face>, Ptr<DO> > ();
}

bool
Face::SendNULLp (Ptr<const NULLp> n_o)
{
	NS_LOG_FUNCTION (this << n_o);

	if (!IsUp ())
	{
		return false;
	}

	return Send (Wire::FromNULLp (n_o));
}

bool
Face::SendSO (Ptr<const SO> so_p)
{
	NS_LOG_FUNCTION (this << boost::cref (*this) << so_p->GetName ());

	if (!IsUp ())
	{
		return false;
	}

	return Send (Wire::FromSO (so_p));
}

bool
Face::SendDO (Ptr<const DO> do_p)
{
	NS_LOG_FUNCTION (this << boost::cref (*this) << do_p->GetName ());

	if (!IsUp ())
	{
		return false;
	}

	return Send (Wire::FromDO (do_p));
}

bool
Face::Send (Ptr<Packet> packet)
{
	return true;
}

bool
Face::Receive (Ptr<const Packet> p)
{
	NS_LOG_FUNCTION (this << p << p->GetSize ());

	if (!IsUp ())
	{
		// no tracing here. If we were off while receiving, we shouldn't even know that something was there
		return false;
	}

	Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
	try
	{
		HeaderHelper::Type type = HeaderHelper::GetNnnHeaderType (packet);
		switch (type)
		{
		case HeaderHelper::NULL_NNN:
			return ReceiveNULLp (Wire::ToNULLp (packet, Wire::WIRE_FORMAT_NNNSIM));
		case HeaderHelper::SO_NNN:
			return ReceiveSO (Wire::ToSO (packet, Wire::WIRE_FORMAT_NNNSIM));
		case HeaderHelper::DO_NNN:
			return ReceiveDO (Wire::ToDO (packet, Wire::WIRE_FORMAT_NNNSIM));
		default:
			NS_FATAL_ERROR ("Not supported NNN header");
			return false;
		}

		// exception will be thrown if packet is not recognized
	}
	catch (UnknownHeaderException)
	{
		NS_FATAL_ERROR ("Unknown NNN header. Should not happen");
		return false;
	}

	return false;
}

bool
Face::ReceiveNULLp (Ptr<NULLp> n_o)
{
	if (!IsUp ())
	{
		// no tracing here. If we were off while receiving, we shouldn't even know that something was there
		return false;
	}

	m_upstreamNULLpHandler (this, n_o);
	return true;
}

bool
Face::ReceiveSO (Ptr<SO> so_p)
{
	if (!IsUp ())
	{
		// no tracing here. If we were off while receiving, we shouldn't even know that something was there
		return false;
	}

	m_upstreamSOHandler (this, so_p);
	return true;
}

bool
Face::ReceiveDO (Ptr<DO> do_p)
{
	if (!IsUp ())
	{
		// no tracing here. If we were off while receiving, we shouldn't even know that something was there
		return false;
	}

	m_upstreamDOHandler (this, do_p);
	return true;
}

void
Face::SetMetric (uint16_t metric)
{
	NS_LOG_FUNCTION (metric);
	m_metric = metric;
}

uint16_t
Face::GetMetric (void) const
{
	return m_metric;
}

void
Face::SetFlags (uint32_t flags)
{
	m_flags = flags;
}

bool
Face::operator== (const Face &face) const
{
	NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
			"NN_Faces of different nodes should not be compared to each other: " << *this << " == " << face);

	return (m_id == face.m_id);
}

bool
Face::operator< (const Face &face) const
{
	NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
			"NN_Faces of different nodes should not be compared to each other: " << *this << " == " << face);

	return (m_id < face.m_id);
}

std::ostream&
Face::Print (std::ostream &os) const
{
	os << "id=" << GetId ();
	return os;
}

std::ostream&
operator<< (std::ostream& os, const Face &face)
{
	face.Print (os);
	return os;
}

} // namespace nnn
} // namespace ns3

<|endoftext|>


<commit_before><commit_msg>Fix bad regex<commit_after><|endoftext|>