/[svn]/libgig/trunk/src/Serialization.h
ViewVC logotype

Diff of /libgig/trunk/src/Serialization.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3138 by schoenebeck, Wed May 3 14:41:58 2017 UTC revision 3178 by schoenebeck, Thu May 11 23:06:40 2017 UTC
# Line 34  Line 34 
34  #include <string>  #include <string>
35  #include <vector>  #include <vector>
36  #include <map>  #include <map>
37    #include <time.h>
38    
39    #ifndef __has_extension
40    # define __has_extension(x) 0
41    #endif
42    
43    #ifndef HAS_BUILTIN_TYPE_TRAITS
44    # if __cplusplus >= 201103L
45    #  define HAS_BUILTIN_TYPE_TRAITS 1
46    # elif ( __has_extension(is_class) && __has_extension(is_enum) )
47    #  define HAS_BUILTIN_TYPE_TRAITS 1
48    # elif ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3 ) )
49    #  define HAS_BUILTIN_TYPE_TRAITS 1
50    # elif _MSC_VER >= 1400 /* MS Visual C++ 8.0 (Visual Studio 2005) */
51    #  define HAS_BUILTIN_TYPE_TRAITS 1
52    # elif __INTEL_COMPILER >= 1100
53    #  define HAS_BUILTIN_TYPE_TRAITS 1
54    # else
55    #  define HAS_BUILTIN_TYPE_TRAITS 0
56    # endif
57    #endif
58    
59    #if !HAS_BUILTIN_TYPE_TRAITS
60    # include <tr1/type_traits>
61    # define LIBGIG_IS_CLASS(type) std::tr1::__is_union_or_class<type>::value //NOTE: without compiler support we cannot distinguish union from class
62    #else
63    # define LIBGIG_IS_CLASS(type) __is_class(type)
64    #endif
65    
66  /** @brief Serialization / deserialization framework.  /** @brief Serialization / deserialization framework.
67   *   *
# Line 80  Line 108 
108   */   */
109  namespace Serialization {  namespace Serialization {
110    
111        // just symbol prototyping
112        class DataType;
113        class Object;
114        class Member;
115      class Archive;      class Archive;
116        class ObjectPool;
117      class Exception;      class Exception;
118    
119      typedef std::string String;      typedef std::string String;
# Line 97  namespace Serialization { Line 130  namespace Serialization {
130          OPERATION_DESERIALIZE          OPERATION_DESERIALIZE
131      };      };
132    
133        enum time_base_t {
134            LOCAL_TIME,
135            UTC_TIME
136        };
137    
138      template<typename T>      template<typename T>
139      bool IsEnum(const T& data) {      bool IsEnum(const T& data) {
140            #if !HAS_BUILTIN_TYPE_TRAITS
141            return std::tr1::is_enum<T>::value;
142            #else
143          return __is_enum(T);          return __is_enum(T);
144            #endif
145      }      }
146    
147      template<typename T>      template<typename T>
148      bool IsUnion(const T& data) {      bool IsUnion(const T& data) {
149            #if !HAS_BUILTIN_TYPE_TRAITS
150            return false; // without compiler support we cannot distinguish union from class
151            #else
152          return __is_union(T);          return __is_union(T);
153            #endif
154      }      }
155    
156      template<typename T>      template<typename T>
157      bool IsClass(const T& data) {      bool IsClass(const T& data) {
158            #if !HAS_BUILTIN_TYPE_TRAITS
159            return std::tr1::__is_union_or_class<T>::value; // without compiler support we cannot distinguish union from class
160            #else
161          return __is_class(T);          return __is_class(T);
162            #endif
163      }      }
164    
165      /*template<typename T>      /*template<typename T>
# Line 151  namespace Serialization { Line 201  namespace Serialization {
201          template<typename T>          template<typename T>
202          struct Resolver {          struct Resolver {
203              static UID resolve(const T& obj) {              static UID resolve(const T& obj) {
204                  return (UID) { (ID) &obj, sizeof(obj) };                  const UID uid = { (ID) &obj, sizeof(obj) };
205                    return uid;
206              }              }
207          };          };
208    
# Line 159  namespace Serialization { Line 210  namespace Serialization {
210          template<typename T>          template<typename T>
211          struct Resolver<T*> {          struct Resolver<T*> {
212              static UID resolve(const T* const & obj) {              static UID resolve(const T* const & obj) {
213                  return (UID) { (ID) obj, sizeof(*obj) };                  const UID uid = { (ID) obj, sizeof(*obj) };
214                    return uid;
215              }              }
216          };          };
217      };      };
# Line 172  namespace Serialization { Line 224  namespace Serialization {
224    
225      typedef std::vector<UID> UIDChain;      typedef std::vector<UID> UIDChain;
226    
227        // prototyping of private internal friend functions
228        static String _encodePrimitiveValue(const Object& obj);
229        static DataType _popDataTypeBlob(const char*& p, const char* end);
230        static Member _popMemberBlob(const char*& p, const char* end);
231        static Object _popObjectBlob(const char*& p, const char* end);
232        static void _popPrimitiveValue(const char*& p, const char* end, Object& obj);
233        static String _primitiveObjectValueToString(const Object& obj);
234        //  |
235        template<typename T>
236        static T _primitiveObjectValueToNumber(const Object& obj);
237    
238      /** @brief Abstract reflection of a native C++ data type.      /** @brief Abstract reflection of a native C++ data type.
239       *       *
240       * Provides detailed information about a C++ data type, whether it is a       * Provides detailed information about a C++ data type, whether it is a
# Line 200  namespace Serialization { Line 263  namespace Serialization {
263          bool operator>(const DataType& other) const;          bool operator>(const DataType& other) const;
264          String asLongDescr() const;          String asLongDescr() const;
265          String baseTypeName() const { return m_baseTypeName; }          String baseTypeName() const { return m_baseTypeName; }
266          String customTypeName() const { return m_customTypeName; }          String customTypeName(bool demangle = false) const;
267    
268          template<typename T>          template<typename T>
269          static DataType dataTypeOf(const T& data) {          static DataType dataTypeOf(const T& data) {
# Line 275  namespace Serialization { Line 338  namespace Serialization {
338          bool m_isPointer;          bool m_isPointer;
339    
340          friend DataType _popDataTypeBlob(const char*& p, const char* end);          friend DataType _popDataTypeBlob(const char*& p, const char* end);
341            friend class Archive;
342      };      };
343    
344      /** @brief Abstract reflection of a native C++ class/struct's member variable.      /** @brief Abstract reflection of a native C++ class/struct's member variable.
# Line 348  namespace Serialization { Line 412  namespace Serialization {
412          std::vector<Member>& members() { return m_members; }          std::vector<Member>& members() { return m_members; }
413          const std::vector<Member>& members() const { return m_members; }          const std::vector<Member>& members() const { return m_members; }
414          Member memberNamed(String name) const;          Member memberNamed(String name) const;
415          void remove(const Member& member);          Member memberByUID(const UID& uid) const;
416          std::vector<Member> membersOfType(const DataType& type) const;          std::vector<Member> membersOfType(const DataType& type) const;
417          int sequenceIndexOf(const Member& member) const;          int sequenceIndexOf(const Member& member) const;
418          bool isValid() const;          bool isValid() const;
# Line 359  namespace Serialization { Line 423  namespace Serialization {
423          bool operator<(const Object& other) const;          bool operator<(const Object& other) const;
424          bool operator>(const Object& other) const;          bool operator>(const Object& other) const;
425    
426        protected:
427            void remove(const Member& member);
428    
429      private:      private:
430          DataType m_type;          DataType m_type;
431          UIDChain m_uid;          UIDChain m_uid;
# Line 367  namespace Serialization { Line 434  namespace Serialization {
434          RawData m_data;          RawData m_data;
435          std::vector<Member> m_members;          std::vector<Member> m_members;
436    
437            friend String _encodePrimitiveValue(const Object& obj);
438          friend Object _popObjectBlob(const char*& p, const char* end);          friend Object _popObjectBlob(const char*& p, const char* end);
439          friend void _popPrimitiveValue(const char*& p, const char* end, Object& obj);          friend void _popPrimitiveValue(const char*& p, const char* end, Object& obj);
440            friend String _primitiveObjectValueToString(const Object& obj);
441    
442            template<typename T>
443            friend T _primitiveObjectValueToNumber(const Object& obj);
444    
445            friend class Archive;
446      };      };
447    
448      /** @brief Destination container for serialization, and source container for deserialization.      /** @brief Destination container for serialization, and source container for deserialization.
# Line 382  namespace Serialization { Line 456  namespace Serialization {
456       * @code       * @code
457       * Archive a;       * Archive a;
458       * a.serialize(&myRootObject);       * a.serialize(&myRootObject);
459       * @encode       * @endcode
460       * Or if you prefer the look of operator based code:       * Or if you prefer the look of operator based code:
461       * @code       * @code
462       * Archive a;       * Archive a;
463       * a << myRootObject;       * a << myRootObject;
464       * @encode       * @endcode
465       * The Archive object will then serialize all members of the passed C++       * The Archive object will then serialize all members of the passed C++
466       * object, and will recursively serialize all other C++ objects which it       * object, and will recursively serialize all other C++ objects which it
467       * contains or points to. So the root object is the starting point for the       * contains or points to. So the root object is the starting point for the
# Line 402  namespace Serialization { Line 476  namespace Serialization {
476       * @code       * @code
477       * Archive a(rawDataStream);       * Archive a(rawDataStream);
478       * a.deserialize(&myRootObject);       * a.deserialize(&myRootObject);
479       * @encode       * @endcode
480       * Or with operator instead:       * Or with operator instead:
481       * @code       * @code
482       * Archive a(rawDataStream);       * Archive a(rawDataStream);
483       * a >> myRootObject;       * a >> myRootObject;
484       * @encode       * @endcode
485       * Now this framework automatically handles serialization and       * Now this framework automatically handles serialization and
486       * deserialization of fundamental data types automatically for you (like       * deserialization of fundamental data types automatically for you (like
487       * i.e. char, int, long int, float, double, etc.). However for your own       * i.e. char, int, long int, float, double, etc.). However for your own
# Line 522  namespace Serialization { Line 596  namespace Serialization {
596              deserialize(&obj);              deserialize(&obj);
597          }          }
598    
599          const RawData& rawData() const { return m_rawData; }          const RawData& rawData();
600          virtual String rawDataFormat() const;          virtual String rawDataFormat() const;
601    
602          template<typename T_classType, typename T_memberType>          template<typename T_classType, typename T_memberType>
# Line 556  namespace Serialization { Line 630  namespace Serialization {
630          virtual void decode(const RawData& data);          virtual void decode(const RawData& data);
631          virtual void decode(const uint8_t* data, size_t size);          virtual void decode(const uint8_t* data, size_t size);
632          void clear();          void clear();
633            bool isModified() const;
634            void removeMember(Object& parent, const Member& member);
635          void remove(const Object& obj);          void remove(const Object& obj);
636          Object& rootObject();          Object& rootObject();
637          Object& objectByUID(const UID& uid);          Object& objectByUID(const UID& uid);
638            void setAutoValue(Object& object, String value);
639            void setIntValue(Object& object, int64_t value);
640            void setRealValue(Object& object, double value);
641            void setBoolValue(Object& object, bool value);
642            void setEnumValue(Object& object, uint64_t value);
643            String valueAsString(const Object& object);
644            int64_t valueAsInt(const Object& object);
645            double valueAsReal(const Object& object);
646            bool valueAsBool(const Object& object);
647            String name() const;
648            void setName(String name);
649            String comment() const;
650            void setComment(String comment);
651            time_t timeStampCreated() const;
652            time_t timeStampModified() const;
653            tm dateTimeCreated(time_base_t base = LOCAL_TIME) const;
654            tm dateTimeModified(time_base_t base = LOCAL_TIME) const;
655    
656      protected:      protected:
657          // UID resolver for non-pointer types          // UID resolver for non-pointer types
# Line 580  namespace Serialization { Line 673  namespace Serialization {
673          class UIDChainResolver<T*> {          class UIDChainResolver<T*> {
674          public:          public:
675              UIDChainResolver(const T*& data) {              UIDChainResolver(const T*& data) {
676                  m_uid.push_back((UID) { &data, sizeof(data) });                  const UID uids[2] = {
677                  m_uid.push_back((UID) { data, sizeof(*data) });                      { &data, sizeof(data) },
678                        { data, sizeof(*data) }
679                    };
680                    m_uid.push_back(uids[0]);
681                    m_uid.push_back(uids[1]);
682              }              }
683    
684              operator UIDChain() const { return m_uid; }              operator UIDChain() const { return m_uid; }
# Line 621  namespace Serialization { Line 718  namespace Serialization {
718    
719          // Automatically handles recursion for class/struct types, while ignoring all primitive types.          // Automatically handles recursion for class/struct types, while ignoring all primitive types.
720          template<typename T>          template<typename T>
721          struct SerializationRecursion : SerializationRecursionImpl<T, __is_class(T)> {          struct SerializationRecursion : SerializationRecursionImpl<T, LIBGIG_IS_CLASS(T)> {
722          };          };
723    
724          class ObjectPool : public std::map<UID,Object> {          class ObjectPool : public std::map<UID,Object> {
# Line 665  namespace Serialization { Line 762  namespace Serialization {
762          operation_t m_operation;          operation_t m_operation;
763          UID m_root;          UID m_root;
764          RawData m_rawData;          RawData m_rawData;
765            bool m_isModified;
766            String m_name;
767            String m_comment;
768            time_t m_timeCreated;
769            time_t m_timeModified;
770      };      };
771    
772      /**      /**

Legend:
Removed from v.3138  
changed lines
  Added in v.3178

  ViewVC Help
Powered by ViewVC