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
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);
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) {
444 String name =
typeid(data).raw_name();
446 String name =
typeid(data).name();
454 String m_baseTypeName;
455 String m_customTypeName;
459 #if LIBGIG_SERIALIZATION_INTERNAL
460 friend DataType _popDataTypeBlob(
const char*& p,
const char* end);
462 friend class Archive;
511 #if LIBGIG_SERIALIZATION_INTERNAL
512 friend Member _popMemberBlob(
const char*& p,
const char* end);
545 UID uid(
int index = 0)
const;
552 std::vector<Member>&
members();
553 const std::vector<Member>&
members()
const;
567 void remove(
const Member& member);
577 std::vector<Member> m_members;
579 #if LIBGIG_SERIALIZATION_INTERNAL
580 friend String _encodePrimitiveValue(
const Object& obj);
581 friend Object _popObjectBlob(
const char*& p,
const char* end);
582 friend void _popPrimitiveValue(
const char*& p,
const char* end,
Object& obj);
583 friend String _primitiveObjectValueToString(
const Object& obj);
586 friend T _primitiveObjectValueToNumber(
const Object& obj);
713 Archive(
const uint8_t* data,
size_t size);
743 m_operation = OPERATION_SERIALIZE;
744 m_allObjects.clear();
749 m_operation = OPERATION_NONE;
779 m_operation = OPERATION_DESERIALIZE;
783 m_operation = OPERATION_NONE;
876 template<
typename T_
classType,
typename T_memberType>
877 void serializeMember(
const T_classType& nativeObject,
const T_memberType& nativeMember,
const char* memberName) {
878 const size_t offset =
879 ((
const uint8_t*)(
const void*)&nativeMember) -
880 ((
const uint8_t*)(
const void*)&nativeObject);
881 const UIDChain uids = UIDChainResolver<T_memberType>(nativeMember);
883 const Member member(memberName, uids[0], offset, type);
885 Object& parent = m_allObjects[parentUID];
887 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
889 parent =
Object(uids, type);
891 parent.
members().push_back(member);
892 const Object obj(uids, type);
893 const bool bExistsAlready = m_allObjects.count(uids[0]);
894 const bool isValidObject = obj;
895 const bool bExistingObjectIsInvalid = !m_allObjects[uids[0]];
896 if (!bExistsAlready || (bExistingObjectIsInvalid && isValidObject)) {
897 m_allObjects[uids[0]] = obj;
900 SerializationRecursion<T_memberType>::serializeObject(
this, nativeMember);
973 template<
typename T_
classType>
976 Object& obj = m_allObjects[uid];
978 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
1014 template<
typename T_
classType>
1017 Object& obj = m_allObjects[uid];
1019 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
1021 obj =
Object(uids, type);
1027 virtual void decode(
const uint8_t* data,
size_t size);
1045 String
name()
const;
1056 template<
typename T>
1057 class UIDChainResolver {
1059 UIDChainResolver(
const T& data) {
1063 operator UIDChain()
const {
return m_uid; }
1064 UIDChain operator()()
const {
return m_uid; }
1070 template<
typename T>
1071 class UIDChainResolver<T*> {
1073 UIDChainResolver(
const T*& data) {
1074 const UID uids[2] = {
1075 { &data,
sizeof(data) },
1076 { data,
sizeof(*data) }
1078 m_uid.push_back(uids[0]);
1079 m_uid.push_back(uids[1]);
1082 operator UIDChain()
const {
return m_uid; }
1083 UIDChain operator()()
const {
return m_uid; }
1089 template<
typename T,
bool T_isRecursive>
1090 struct SerializationRecursionImpl {
1091 static void serializeObject(
Archive* archive,
const T& obj) {
1097 template<
typename T,
bool T_isRecursive>
1098 struct SerializationRecursionImpl<T*,T_isRecursive> {
1099 static void serializeObject(
Archive* archive,
const T*& obj) {
1101 const_cast<T*&
>(obj)->
serialize(archive);
1106 template<
typename T>
1107 struct SerializationRecursionImpl<T,false> {
1108 static void serializeObject(
Archive* archive,
const T& obj) {}
1112 template<
typename T>
1113 struct SerializationRecursionImpl<T*,
false> {
1114 static void serializeObject(
Archive* archive,
const T*& obj) {}
1118 template<
typename T>
1119 struct SerializationRecursion : SerializationRecursionImpl<T, LIBGIG_IS_CLASS(T)> {
1122 class ObjectPool :
public std::map<UID,Object> {
1125 Object& operator[](
const UID& k) {
1126 static Object invalid;
1131 return std::map<UID,Object>::operator[](k);
1135 friend String _encode(
const ObjectPool& objects);
1138 String _encodeRootBlob();
1139 void _popRootBlob(
const char*& p,
const char* end);
1140 void _popObjectsBlob(
const char*& p,
const char* end);
1147 void syncObject(
const Object& dst,
const Object& src);
1148 void syncPrimitive(
const Object& dst,
const Object& src);
1149 void syncPointer(
const Object& dst,
const Object& src);
1150 void syncMember(
const Member& dstMember,
const Member& srcMember);
1151 static Member dstMemberMatching(
const Object& dstObj,
const Object& srcObj,
const Member& srcMember);
1159 OPERATION_SERIALIZE,
1160 OPERATION_DESERIALIZE
1163 virtual void encode();
1165 ObjectPool m_allObjects;
1166 operation_t m_operation;
1172 time_t m_timeCreated;
1173 time_t m_timeModified;
1191 static String assemble(String format, va_list arg);
Destination container for serialization, and source container for deserialization.
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.
void setMinVersion(const T_classType &nativeObject, Version v)
Set a minimum version number for your C++ class.
void setName(String name)
Assign a name to this archive.
void serialize(const T *obj)
Initiate serialization.
time_t timeStampCreated() const
Date and time when this archive was initially created.
void setBoolValue(Object &object, bool value)
Set new boolean value for given boolean object.
void clear()
Clear content of this archive.
double valueAsReal(const Object &object)
Get floating point value of object.
time_t timeStampModified() const
Date and time when this archive was modified for the last time.
virtual String rawDataFormat() const
Name of the encoding format used by this Archive class.
void setIntValue(Object &object, int64_t value)
Set new integer value for given integer object.
const RawData & rawData()
Raw data stream of this archive content.
bool isModified() const
Whether this archive was modified.
void deserialize(T *obj)
Initiate deserialization.
virtual void decode(const RawData &data)
Fill this archive with the given serialized raw data.
tm dateTimeCreated(time_base_t base=LOCAL_TIME) const
Date and time when this archive was initially created.
Object & rootObject()
Root C++ object of this archive.
Object & objectByUID(const UID &uid)
Access object by its unique identifier.
String valueAsString(const Object &object)
Get value of object as string.
int64_t valueAsInt(const Object &object)
Get integer value of object.
void setVersion(const T_classType &nativeObject, Version v)
Set current version number for your C++ class.
void removeMember(Object &parent, const Member &member)
Remove a member variable from the given object.
void remove(const Object &obj)
Remove an object from this archive.
bool valueAsBool(const Object &object)
Get boolean value of object.
void setEnumValue(Object &object, uint64_t value)
Set new value for given enum object.
void operator<<(const T &obj)
Initiate serialization of your C++ objects.
void setComment(String comment)
Assign a comment to this archive.
Archive()
Create an "empty" archive.
String name() const
Optional name of this archive.
void setAutoValue(Object &object, String value)
Automatically cast and assign appropriate value to object.
String comment() const
Optional comments for this archive.
void operator>>(T &obj)
Initiate deserialization of your C++ objects.
tm dateTimeModified(time_base_t base=LOCAL_TIME) const
Date and time when this archive was modified for the last time.
Abstract reflection of a native C++ data type.
bool isPrimitive() const
Whether this is reflecting a fundamental C/C++ data type.
bool isPointer() const
Whether this is reflecting a C/C++ pointer type.
bool isSigned() const
Whether this is a signed integer C/C++ data type.
String baseTypeName() const
The base type name of this data type.
bool operator!=(const DataType &other) const
Comparison for inequalness.
bool isReal() const
Whether this is a floating point based C/C++ data type.
DataType()
Default constructor.
String asLongDescr() const
Human readable long description for this data type.
bool isBool() const
Whether this is a boolean C/C++ data type.
bool isValid() const
Check if this is a valid DataType object.
bool operator>(const DataType &other) const
Greater than comparison.
bool isEnum() const
Whether this is a C/C++ enum data type.
bool operator<(const DataType &other) const
Smaller than comparison.
bool isClass() const
Whether this is reflecting a C/C++ struct or class type.
bool isInteger() const
Whether this is an integer C/C++ data type.
bool operator==(const DataType &other) const
Comparison for equalness.
static DataType dataTypeOf(const T &data)
Construct a DataType object for the given native C++ data.
String customTypeName(bool demangle=false) const
The user defined C/C++ data type name of this data type.
size_t size() const
Returns native memory size of the respective C++ object or variable.
Will be thrown whenever an error occurs during an serialization or deserialization process.
void PrintMessage()
Print exception message to stdout.
Abstract reflection of a native C++ class/struct's member variable.
Member()
Default constructor.
bool operator!=(const Member &other) const
Comparison for inequalness.
bool operator<(const Member &other) const
Smaller than comparison.
bool operator>(const Member &other) const
Greater than comparison.
String name() const
Name of the member.
bool operator==(const Member &other) const
Comparison for equalness.
const DataType & type() const
C/C++ Data type of this member.
size_t offset() const
Offset of member in its containing parent data structure.
bool isValid() const
Check if this is a valid Member object.
UID uid() const
Unique identifier of this member instance.
Abstract reflection of some native serialized C/C++ data.
bool isValid() const
Check if this is a valid Object instance.
Member memberNamed(String name) const
Get the member of this Object with given name.
Version version() const
Version of original user defined C/C++ struct or class.
UID uid(int index=0) const
Unique identifier of this Object.
const UIDChain & uidChain() const
Unique identifier chain of this Object.
const RawData & rawData() const
Raw data of the original native C/C++ data.
bool operator<(const Object &other) const
Smaller than comparison.
Object()
Default constructor (for an "invalid" Object).
Member memberByUID(const UID &uid) const
Get the member of this Object with given unique identifier.
std::vector< Member > membersOfType(const DataType &type) const
Get all members of this Object with given data type.
int sequenceIndexOf(const Member &member) const
Serialization/deserialization sequence number of the requested member.
bool operator!=(const Object &other) const
Comparison for inequalness.
bool operator>(const Object &other) const
Greater than comparison.
std::vector< Member > & members()
All members of the original native C/C++ struct or class instance.
const DataType & type() const
C/C++ data type this Object is reflecting.
bool isVersionCompatibleTo(const Object &other) const
Check version compatibility between Object instances.
Version minVersion() const
Minimum version of original user defined C/C++ struct or class.
bool operator==(const Object &other) const
Comparison for equalness.
Unique identifier referring to one specific native C++ object, member, fundamental variable,...
static UID from(const T &obj)
Create an unique indentifier for a native C++ object/member/variable.
bool isValid() const
Check whether this is a valid unique identifier.
size_t size
Memory size of the object or member in question.
ID id
Abstract non-unique ID of the object or member in question.
Serialization / deserialization framework.
bool IsUnion(const T &data)
Check whether data is a C++ union type.
void * ID
Abstract identifier for serialized C++ objects.
const UID NO_UID
Reflects an invalid UID and behaves similar to NULL as invalid value for pointer types.
bool IsEnum(const T &data)
Check whether data is a C/C++ enum type.
bool IsClass(const T &data)
Check whether data is a C/C++ struct or C++ class type.
uint32_t Version
Version number data type.
std::vector< UID > UIDChain
Chain of UIDs.
std::vector< uint8_t > RawData
Raw data stream of serialized C++ objects.
time_base_t
To which time zone a certain timing information relates to.
@ UTC_TIME
The time stamp relates to "Greenwhich Mean Time" zone, also known as "Coordinated Universal Time"....
@ LOCAL_TIME
The time stamp relates to the machine's local time zone. Request a time stamp in local time if you wa...