24 #ifndef LIBGIG_SERIALIZATION_H 25 #define LIBGIG_SERIALIZATION_H 40 #ifndef __has_extension 41 # define __has_extension(x) 0 44 #ifndef HAS_BUILTIN_TYPE_TRAITS 45 # if __cplusplus >= 201103L 46 # define HAS_BUILTIN_TYPE_TRAITS 1 47 # elif ( __has_extension(is_class) && __has_extension(is_enum) ) 48 # define HAS_BUILTIN_TYPE_TRAITS 1 49 # elif ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3 ) ) 50 # define HAS_BUILTIN_TYPE_TRAITS 1 51 # elif _MSC_VER >= 1400 52 # define HAS_BUILTIN_TYPE_TRAITS 1 53 # elif __INTEL_COMPILER >= 1100 54 # define HAS_BUILTIN_TYPE_TRAITS 1 56 # define HAS_BUILTIN_TYPE_TRAITS 0 60 #if !HAS_BUILTIN_TYPE_TRAITS 61 # include <tr1/type_traits> 62 # define LIBGIG_IS_CLASS(type) std::tr1::__is_union_or_class<type>::value //NOTE: without compiler support we cannot distinguish union from class 64 # define LIBGIG_IS_CLASS(type) __is_class(type) 120 typedef std::string String;
172 #if !HAS_BUILTIN_TYPE_TRAITS 173 return std::tr1::is_enum<T>::value;
191 #if !HAS_BUILTIN_TYPE_TRAITS 194 return __is_union(T);
209 #if !HAS_BUILTIN_TYPE_TRAITS 210 return std::tr1::__is_union_or_class<T>::value;
212 return __is_class(T);
249 bool operator==(
const UID& other)
const {
return id == other.
id &&
size == other.
size; }
250 bool operator!=(
const UID& other)
const {
return id != other.id ||
size != other.size; }
251 bool operator<(
const UID& other)
const {
return id < other.id || (
id == other.id &&
size < other.size); }
252 bool operator>(
const UID& other)
const {
return id > other.id || (
id == other.id &&
size > other.size); }
263 return Resolver<T>::resolve(obj);
270 static UID resolve(
const T& obj) {
271 const UID uid = { (
ID) &obj,
sizeof(obj) };
278 struct Resolver<T*> {
279 static UID resolve(
const T*
const & obj) {
280 const UID uid = { (
ID) obj,
sizeof(*obj) };
326 #if LIBGIG_SERIALIZATION_INTERNAL 328 static String _encodePrimitiveValue(
const Object& obj);
329 static DataType _popDataTypeBlob(
const char*& p,
const char* end);
330 static Member _popMemberBlob(
const char*& p,
const char* end);
331 static Object _popObjectBlob(
const char*& p,
const char* end);
332 static void _popPrimitiveValue(
const char*& p,
const char* end,
Object& obj);
333 static String _primitiveObjectValueToString(
const Object& obj);
336 static T _primitiveObjectValueToNumber(
const Object& obj);
337 #endif // LIBGIG_SERIALIZATION_INTERNAL 358 size_t size()
const {
return m_size; }
390 return Resolver<T>::resolve(data);
396 template<
typename T,
bool T_isPo
inter>
397 struct ResolverBase {
398 static DataType resolve(
const T& data) {
399 const std::type_info& type =
typeid(data);
400 const int sz =
sizeof(data);
405 if (type ==
typeid(int8_t))
return DataType(T_isPointer, sz,
"int8");
406 if (type ==
typeid(uint8_t))
return DataType(T_isPointer, sz,
"uint8");
407 if (type ==
typeid(int16_t))
return DataType(T_isPointer, sz,
"int16");
408 if (type ==
typeid(uint16_t))
return DataType(T_isPointer, sz,
"uint16");
409 if (type ==
typeid(int32_t))
return DataType(T_isPointer, sz,
"int32");
410 if (type ==
typeid(uint32_t))
return DataType(T_isPointer, sz,
"uint32");
411 if (type ==
typeid(int64_t))
return DataType(T_isPointer, sz,
"int64");
412 if (type ==
typeid(uint64_t))
return DataType(T_isPointer, sz,
"uint64");
413 if (type ==
typeid(
bool))
return DataType(T_isPointer, sz,
"bool");
414 if (type ==
typeid(
float))
return DataType(T_isPointer, sz,
"real32");
415 if (type ==
typeid(
double))
return DataType(T_isPointer, sz,
"real64");
417 if (
IsEnum(data))
return DataType(T_isPointer, sz,
"enum", rawCppTypeNameOf(data));
418 if (
IsUnion(data))
return DataType(T_isPointer, sz,
"union", rawCppTypeNameOf(data));
419 if (
IsClass(data))
return DataType(T_isPointer, sz,
"class", rawCppTypeNameOf(data));
427 struct Resolver : ResolverBase<T,false> {
428 static DataType resolve(
const T& data) {
429 return ResolverBase<T,false>::resolve(data);
435 struct Resolver<T*> : ResolverBase<T,true> {
436 static DataType resolve(
const T*& data) {
437 return ResolverBase<T,true>::resolve(*data);
442 static String rawCppTypeNameOf(
const T& data) {
443 #if defined _MSC_VER // Microsoft compiler ... 444 # warning type_info::raw_name() demangling has not been tested yet with Microsoft compiler! Feedback appreciated! 445 String name =
typeid(data).raw_name();
446 #else // i.e. especially GCC and clang ... 447 String name =
typeid(data).name();
455 String m_baseTypeName;
456 String m_customTypeName;
460 #if LIBGIG_SERIALIZATION_INTERNAL 461 friend DataType _popDataTypeBlob(
const char*& p,
const char* end);
463 friend class Archive;
512 #if LIBGIG_SERIALIZATION_INTERNAL 513 friend Member _popMemberBlob(
const char*& p,
const char* end);
546 UID uid(
int index = 0)
const;
553 std::vector<Member>&
members();
554 const std::vector<Member>&
members()
const;
568 void remove(
const Member& member);
578 std::vector<Member> m_members;
580 #if LIBGIG_SERIALIZATION_INTERNAL 581 friend String _encodePrimitiveValue(
const Object& obj);
582 friend Object _popObjectBlob(
const char*& p,
const char* end);
583 friend void _popPrimitiveValue(
const char*& p,
const char* end,
Object& obj);
584 friend String _primitiveObjectValueToString(
const Object& obj);
587 friend T _primitiveObjectValueToNumber(
const Object& obj);
588 #endif // LIBGIG_SERIALIZATION_INTERNAL 714 Archive(
const uint8_t* data,
size_t size);
744 m_operation = OPERATION_SERIALIZE;
745 m_allObjects.clear();
750 m_operation = OPERATION_NONE;
780 m_operation = OPERATION_DESERIALIZE;
784 m_operation = OPERATION_NONE;
877 template<
typename T_
classType,
typename T_memberType>
878 void serializeMember(
const T_classType& nativeObject,
const T_memberType& nativeMember,
const char* memberName) {
879 const size_t offset =
880 ((
const uint8_t*)(
const void*)&nativeMember) -
881 ((
const uint8_t*)(
const void*)&nativeObject);
882 const UIDChain uids = UIDChainResolver<T_memberType>(nativeMember);
884 const Member member(memberName, uids[0], offset, type);
886 Object& parent = m_allObjects[parentUID];
888 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
890 parent =
Object(uids, type);
892 parent.
members().push_back(member);
893 const Object obj(uids, type);
894 const bool bExistsAlready = m_allObjects.count(uids[0]);
895 const bool isValidObject = obj;
896 const bool bExistingObjectIsInvalid = !m_allObjects[uids[0]];
897 if (!bExistsAlready || (bExistingObjectIsInvalid && isValidObject)) {
898 m_allObjects[uids[0]] = obj;
901 SerializationRecursion<T_memberType>::serializeObject(
this, nativeMember);
974 template<
typename T_
classType>
977 Object& obj = m_allObjects[uid];
979 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
1015 template<
typename T_
classType>
1018 Object& obj = m_allObjects[uid];
1020 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
1022 obj =
Object(uids, type);
1028 virtual void decode(
const uint8_t* data,
size_t size);
1032 void remove(
const Object& obj);
1046 String
name()
const;
1057 template<
typename T>
1058 class UIDChainResolver {
1060 UIDChainResolver(
const T& data) {
1064 operator UIDChain()
const {
return m_uid; }
1065 UIDChain operator()()
const {
return m_uid; }
1071 template<
typename T>
1072 class UIDChainResolver<T*> {
1074 UIDChainResolver(
const T*& data) {
1075 const UID uids[2] = {
1076 { &data,
sizeof(data) },
1077 { data,
sizeof(*data) }
1079 m_uid.push_back(uids[0]);
1080 m_uid.push_back(uids[1]);
1083 operator UIDChain()
const {
return m_uid; }
1084 UIDChain operator()()
const {
return m_uid; }
1090 template<
typename T,
bool T_isRecursive>
1091 struct SerializationRecursionImpl {
1092 static void serializeObject(
Archive* archive,
const T& obj) {
1098 template<
typename T,
bool T_isRecursive>
1099 struct SerializationRecursionImpl<T*,T_isRecursive> {
1100 static void serializeObject(
Archive* archive,
const T*& obj) {
1102 const_cast<T*&
>(obj)->
serialize(archive);
1107 template<
typename T>
1108 struct SerializationRecursionImpl<T,false> {
1109 static void serializeObject(
Archive* archive,
const T& obj) {}
1113 template<
typename T>
1114 struct SerializationRecursionImpl<T*,
false> {
1115 static void serializeObject(
Archive* archive,
const T*& obj) {}
1119 template<
typename T>
1120 struct SerializationRecursion : SerializationRecursionImpl<T, LIBGIG_IS_CLASS(T)> {
1123 class ObjectPool :
public std::map<UID,Object> {
1126 Object& operator[](
const UID& k) {
1127 static Object invalid;
1132 return std::map<UID,Object>::operator[](k);
1136 friend String _encode(
const ObjectPool& objects);
1139 String _encodeRootBlob();
1140 void _popRootBlob(
const char*& p,
const char* end);
1141 void _popObjectsBlob(
const char*& p,
const char* end);
1148 void syncObject(
const Object& dst,
const Object& src);
1149 void syncPrimitive(
const Object& dst,
const Object& src);
1150 void syncPointer(
const Object& dst,
const Object& src);
1151 void syncMember(
const Member& dstMember,
const Member& srcMember);
1152 static Member dstMemberMatching(
const Object& dstObj,
const Object& srcObj,
const Member& srcMember);
1160 OPERATION_SERIALIZE,
1161 OPERATION_DESERIALIZE
1164 virtual void encode();
1166 ObjectPool m_allObjects;
1167 operation_t m_operation;
1173 time_t m_timeCreated;
1174 time_t m_timeModified;
1192 static String assemble(String format, va_list arg);
1197 #endif // LIBGIG_SERIALIZATION_H String customTypeName(bool demangle=false) const
The user defined C/C++ data type name of this data type.
bool isClass() const
Whether this is reflecting a C/C++ struct or class type.
String baseTypeName() const
The base type name of this data type.
Abstract reflection of some native serialized C/C++ data.
std::vector< Member > membersOfType(const DataType &type) const
Get all members of this Object with given data type.
static UID from(const T &obj)
Create an unique indentifier for a native C++ object/member/variable.
bool isPointer() const
Whether this is reflecting a C/C++ pointer type.
void setName(String name)
Assign a name to this archive.
Destination container for serialization, and source container for deserialization.
std::vector< UID > UIDChain
Chain of UIDs.
bool operator==(const Member &other) const
Comparison for equalness.
void clear()
Clear content of this archive.
static DataType dataTypeOf(const T &data)
Construct a DataType object for the given native C++ data.
Object & objectByUID(const UID &uid)
Access object by its unique identifier.
bool IsUnion(const T &data)
Check whether data is a C++ union type.
bool isVersionCompatibleTo(const Object &other) const
Check version compatibility between Object instances.
void * ID
Abstract identifier for serialized C++ objects.
String name() const
Optional name of this archive.
void serialize(const T *obj)
Initiate serialization.
virtual String rawDataFormat() const
Name of the encoding format used by this Archive class.
int64_t valueAsInt(const Object &object)
Get integer value of object.
bool valueAsBool(const Object &object)
Get boolean value of object.
void setAutoValue(Object &object, String value)
Automatically cast and assign appropriate value to object.
Abstract reflection of a native C++ data type.
const UIDChain & uidChain() const
Unique identifier chain of this Object.
void setMinVersion(const T_classType &nativeObject, Version v)
Set a minimum version number for your C++ class.
const RawData & rawData()
Raw data stream of this archive content.
time_t timeStampCreated() const
Date and time when this archive was initially created.
void deserialize(T *obj)
Initiate deserialization.
bool isSigned() const
Whether this is a signed integer C/C++ data type.
void setIntValue(Object &object, int64_t value)
Set new integer value for given integer object.
uint32_t Version
Version number data type.
bool operator<(const DataType &other) const
Smaller than comparison.
bool isValid() const
Check if this is a valid DataType object.
void setRealValue(Object &object, double value)
Set new floating point value for given floating point object.
void serializeMember(const T_classType &nativeObject, const T_memberType &nativeMember, const char *memberName)
Serialize a native C/C++ member variable.
time_base_t
To which time zone a certain timing information relates to.
bool operator==(const Object &other) const
Comparison for equalness.
bool isValid() const
Check whether this is a valid unique identifier.
void setVersion(const T_classType &nativeObject, Version v)
Set current version number for your C++ class.
Unique identifier referring to one specific native C++ object, member, fundamental variable...
bool isValid() const
Check if this is a valid Object instance.
std::vector< Member > & members()
All members of the original native C/C++ struct or class instance.
void operator<<(const T &obj)
Initiate serialization of your C++ objects.
const DataType & type() const
C/C++ data type this Object is reflecting.
bool isBool() const
Whether this is a boolean C/C++ data type.
virtual void decode(const RawData &data)
Fill this archive with the given serialized raw data.
Object & rootObject()
Root C++ object of this archive.
ID id
Abstract non-unique ID of the object or member in question.
String comment() const
Optional comments for this archive.
bool operator<(const Object &other) const
Smaller than comparison.
std::vector< uint8_t > RawData
Raw data stream of serialized C++ objects.
The time stamp relates to the machine's local time zone. Request a time stamp in local time if you wa...
The time stamp relates to "Greenwhich Mean Time" zone, also known as "Coordinated Universal Time"...
Will be thrown whenever an error occurs during an serialization or deserialization process...
void operator>>(T &obj)
Initiate deserialization of your C++ objects.
Version minVersion() const
Minimum version of original user defined C/C++ struct or class.
String valueAsString(const Object &object)
Get value of object as string.
Version version() const
Version of original user defined C/C++ struct or class.
int sequenceIndexOf(const Member &member) const
Serialization/deserialization sequence number of the requested member.
tm dateTimeCreated(time_base_t base=LOCAL_TIME) const
Date and time when this archive was initially created.
const DataType & type() const
C/C++ Data type of this member.
bool operator>(const DataType &other) const
Greater than comparison.
bool operator!=(const Object &other) const
Comparison for inequalness.
bool isEnum() const
Whether this is a C/C++ enum data type.
Archive()
Create an "empty" archive.
bool isInteger() const
Whether this is an integer C/C++ data type.
bool operator==(const DataType &other) const
Comparison for equalness.
bool IsEnum(const T &data)
Check whether data is a C/C++ enum type.
bool isPrimitive() const
Whether this is reflecting a fundamental C/C++ data type.
Object()
Default constructor (for an "invalid" Object).
bool isReal() const
Whether this is a floating point based C/C++ data type.
UID uid() const
Unique identifier of this member instance.
void setBoolValue(Object &object, bool value)
Set new boolean value for given boolean object.
Member memberNamed(String name) const
Get the member of this Object with given name.
void PrintMessage()
Print exception message to stdout.
String asLongDescr() const
Human readable long description for this data type.
void setEnumValue(Object &object, uint64_t value)
Set new value for given enum object.
UID uid(int index=0) const
Unique identifier of this Object.
double valueAsReal(const Object &object)
Get floating point value of object.
bool IsClass(const T &data)
Check whether data is a C/C++ struct or C++ class type.
size_t size() const
Returns native memory size of the respective C++ object or variable.
tm dateTimeModified(time_base_t base=LOCAL_TIME) const
Date and time when this archive was modified for the last time.
bool isModified() const
Whether this archive was modified.
bool operator!=(const DataType &other) const
Comparison for inequalness.
bool isValid() const
Check if this is a valid Member object.
bool operator>(const Object &other) const
Greater than comparison.
void removeMember(Object &parent, const Member &member)
Remove a member variable from the given object.
const UID NO_UID
Reflects an invalid UID and behaves similar to NULL as invalid value for pointer types.
void setComment(String comment)
Assign a comment to this archive.
Serialization / deserialization framework.
bool operator<(const Member &other) const
Smaller than comparison.
DataType()
Default constructor.
bool operator!=(const Member &other) const
Comparison for inequalness.
Member memberByUID(const UID &uid) const
Get the member of this Object with given unique identifier.
size_t size
Memory size of the object or member in question.
Abstract reflection of a native C++ class/struct's member variable.
time_t timeStampModified() const
Date and time when this archive was modified for the last time.
const RawData & rawData() const
Raw data of the original native C/C++ data.
bool operator>(const Member &other) const
Greater than comparison.
Member()
Default constructor.
size_t offset() const
Offset of member in its containing parent data structure.
String name() const
Name of the member.