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);
247 operator bool()
const {
return isValid(); }
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; }
368 operator bool()
const {
return isValid(); }
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 String name =
typeid(data).raw_name();
445 #else // i.e. especially GCC and clang ...
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;
494 operator bool()
const {
return isValid(); }
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;
559 operator bool()
const {
return isValid(); }
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);
587 #endif // LIBGIG_SERIALIZATION_INTERNAL
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);
1196 #endif // LIBGIG_SERIALIZATION_H
bool operator<(const DataType &other) const
Smaller than comparison.
void setIntValue(Object &object, int64_t value)
Set new integer value for given integer object.
Member memberByUID(const UID &uid) const
Get the member of this Object with given unique identifier.
const RawData & rawData() const
Raw data of the original native C/C++ data.
uint32_t Version
Version number data type.
Object & objectByUID(const UID &uid)
Access object by its unique identifier.
const UIDChain & uidChain() const
Unique identifier chain of this Object.
bool operator==(const Member &other) const
Comparison for equalness.
bool isPointer() const
Whether this is reflecting a C/C++ pointer type.
Abstract reflection of a native C++ class/struct's member variable.
bool operator>(const DataType &other) const
Greater than comparison.
bool isEnum() const
Whether this is a C/C++ enum data type.
bool valueAsBool(const Object &object)
Get boolean value of object.
Archive()
Create an "empty" archive.
std::vector< UID > UIDChain
Chain of UIDs.
void clear()
Clear content of this archive.
String name() const
Optional name of this archive.
int64_t valueAsInt(const Object &object)
Get integer value of object.
bool IsUnion(const T &data)
Check whether data is a C++ union type.
bool isBool() const
Whether this is a boolean C/C++ data type.
void setBoolValue(Object &object, bool value)
Set new boolean value for given boolean object.
void serialize(const T *obj)
Initiate serialization.
String comment() const
Optional comments for this archive.
virtual String rawDataFormat() const
Name of the encoding format used by this Archive class.
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.
tm dateTimeCreated(time_base_t base=LOCAL_TIME) const
Date and time when this archive was initially created.
bool isValid() const
Check if this is a valid Object instance.
bool isVersionCompatibleTo(const Object &other) const
Check version compatibility between Object instances.
bool isModified() const
Whether this archive was modified.
std::vector< uint8_t > RawData
Raw data stream of serialized C++ objects.
@ LOCAL_TIME
The time stamp relates to the machine's local time zone. Request a time stamp in local time if you wa...
bool operator==(const Object &other) const
Comparison for equalness.
Will be thrown whenever an error occurs during an serialization or deserialization process.
void * ID
Abstract identifier for serialized C++ objects.
bool isInteger() const
Whether this is an integer C/C++ data type.
void operator<<(const T &obj)
Initiate serialization of your C++ objects.
String asLongDescr() const
Human readable long description for this data type.
void setName(String name)
Assign a name to this archive.
bool isSigned() const
Whether this is a signed integer C/C++ data type.
DataType()
Default constructor.
std::vector< Member > & members()
All members of the original native C/C++ struct or class instance.
Abstract reflection of some native serialized C/C++ data.
const RawData & rawData()
Raw data stream of this archive content.
Unique identifier referring to one specific native C++ object, member, fundamental variable,...
void setAutoValue(Object &object, String value)
Automatically cast and assign appropriate value to object.
Version version() const
Version of original user defined C/C++ struct or class.
bool operator<(const Object &other) const
Smaller than comparison.
const DataType & type() const
C/C++ data type this Object is reflecting.
time_base_t
To which time zone a certain timing information relates to.
void setVersion(const T_classType &nativeObject, Version v)
Set current version number for your C++ class.
size_t size
Memory size of the object or member in question.
bool operator!=(const DataType &other) const
Comparison for inequalness.
int sequenceIndexOf(const Member &member) const
Serialization/deserialization sequence number of the requested member.
void PrintMessage()
Print exception message to stdout.
Destination container for serialization, and source container for deserialization.
const DataType & type() const
C/C++ Data type of this member.
Object()
Default constructor (for an "invalid" Object).
bool isPrimitive() const
Whether this is reflecting a fundamental C/C++ data type.
bool IsEnum(const T &data)
Check whether data is a C/C++ enum type.
time_t timeStampModified() const
Date and time when this archive was modified for the last time.
Version minVersion() const
Minimum version of original user defined C/C++ struct or class.
bool operator!=(const Object &other) const
Comparison for inequalness.
bool operator==(const DataType &other) const
Comparison for equalness.
time_t timeStampCreated() const
Date and time when this archive was initially created.
Object & rootObject()
Root C++ object of this archive.
String valueAsString(const Object &object)
Get value of object as string.
double valueAsReal(const Object &object)
Get floating point value of object.
bool isClass() const
Whether this is reflecting a C/C++ struct or class type.
Member memberNamed(String name) const
Get the member of this Object with given name.
virtual void decode(const RawData &data)
Fill this archive with the given serialized raw data.
UID uid() const
Unique identifier of this member instance.
void setMinVersion(const T_classType &nativeObject, Version v)
Set a minimum version number for your C++ class.
@ UTC_TIME
The time stamp relates to "Greenwhich Mean Time" zone, also known as "Coordinated Universal Time"....
UID uid(int index=0) const
Unique identifier of this Object.
bool isReal() const
Whether this is a floating point based C/C++ data type.
bool isValid() const
Check if this is a valid DataType object.
Abstract reflection of a native C++ data type.
void removeMember(Object &parent, const Member &member)
Remove a member variable from the given object.
Serialization / deserialization framework.
bool IsClass(const T &data)
Check whether data is a C/C++ struct or C++ class type.
void setComment(String comment)
Assign a comment to this archive.
void setEnumValue(Object &object, uint64_t value)
Set new value for given enum object.
void remove(const Object &obj)
Remove an object from this archive.
bool isValid() const
Check if this is a valid Member object.
const UID NO_UID
Reflects an invalid UID and behaves similar to NULL as invalid value for pointer types.
tm dateTimeModified(time_base_t base=LOCAL_TIME) const
Date and time when this archive was modified for the last time.
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.
bool operator>(const Object &other) const
Greater than comparison.
void deserialize(T *obj)
Initiate deserialization.
ID id
Abstract non-unique ID of the object or member in question.
bool operator<(const Member &other) const
Smaller than comparison.
bool operator!=(const Member &other) const
Comparison for inequalness.
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.
String baseTypeName() const
The base type name of this data type.
void operator>>(T &obj)
Initiate deserialization of your C++ objects.
Member()
Default constructor.
String name() const
Name of the member.
size_t offset() const
Offset of member in its containing parent data structure.
bool operator>(const Member &other) const
Greater than comparison.
std::vector< Member > membersOfType(const DataType &type) const
Get all members of this Object with given data type.