24 #ifndef LIBGIG_SERIALIZATION_H
25 #define LIBGIG_SERIALIZATION_H
48 #ifndef __has_extension
49 # define __has_extension(x) 0
52 #ifndef HAS_BUILTIN_TYPE_TRAITS
53 # if __cplusplus >= 201103L
54 # define HAS_BUILTIN_TYPE_TRAITS 1
55 # elif ( __has_extension(is_class) && __has_extension(is_enum) )
56 # define HAS_BUILTIN_TYPE_TRAITS 1
57 # elif ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3 ) )
58 # define HAS_BUILTIN_TYPE_TRAITS 1
59 # elif _MSC_VER >= 1400
60 # define HAS_BUILTIN_TYPE_TRAITS 1
61 # elif __INTEL_COMPILER >= 1100
62 # define HAS_BUILTIN_TYPE_TRAITS 1
64 # define HAS_BUILTIN_TYPE_TRAITS 0
68 #if !HAS_BUILTIN_TYPE_TRAITS
69 # include <tr1/type_traits>
70 # define LIBGIG_IS_CLASS(type) std::tr1::__is_union_or_class<type>::value
72 # define LIBGIG_IS_CLASS(type) __is_class(type)
230 template<
class T_key,
class T_value>
231 using Map = std::map<T_key,T_value>;
283 #if !HAS_BUILTIN_TYPE_TRAITS
284 return std::tr1::is_enum<T>::value;
302 #if !HAS_BUILTIN_TYPE_TRAITS
305 return __is_union(T);
320 #if !HAS_BUILTIN_TYPE_TRAITS
321 return std::tr1::__is_union_or_class<T>::value;
323 return __is_class(T);
348 template<
typename T>
inline
349 String toString(
const T& value) {
351 std::stringstream ss;
352 ss.imbue(std::locale::classic());
359 String toString(
const double& value) {
361 std::stringstream ss;
362 ss.imbue(std::locale::classic());
364 ss.precision(std::numeric_limits<double>::max_digits10);
369 template<
typename T>
inline
370 String toString(T* ptr) {
371 std::stringstream ss;
372 ss.imbue(std::locale::classic());
373 ss <<
"0x" << std::hex << size_t(ptr);
378 String toString(
const String& value) {
382 #if LIBGIG_SERIALIZATION_INTERNAL
385 static T _primitiveObjectValueToNumber(
const Object& obj);
407 size_t size()
const {
return m_size; }
451 const DataType type = Resolver<T>::resolve(data);
473 const DataType type = Resolver<T>::resolve(unused);
491 const auto itNativeType = m_nativeTypes.find(type.
internalID());
492 return (itNativeType != m_nativeTypes.end()) ?
493 itNativeType->second.size :
sizeof(data);
567 DataType::registerNativeDataType<T>();
578 template<typename T, typename std::enable_if<std::is_default_constructible<T>::value,
bool>::type =
true>
581 template<typename T, typename std::enable_if<!std::is_default_constructible<T>::value,
bool>::type =
true>
585 template<
typename T,
bool T_isPo
inter>
586 struct ResolverBase {
587 static DataType resolve(
const T& data);
592 struct Resolver : ResolverBase<T,false> {
593 static DataType resolve(
const T& data) {
594 return ResolverBase<T,false>::resolve(data);
600 struct Resolver<T*> : ResolverBase<T,true> {
601 static DataType resolve(
const T*
const & data) {
602 return ResolverBase<T,true>::resolve(*data);
608 struct Resolver<
Array<T>> {
609 static DataType resolve(
const Array<T>& data) {
610 const int sz =
sizeof(data);
612 return DataType(
false, sz,
"Array", rawCppTypeNameOf(unused));
618 struct Resolver<
Array<T>*> {
619 static DataType resolve(
const Array<T>*& data) {
620 const int sz =
sizeof(*data);
622 return DataType(
true, sz,
"Array", rawCppTypeNameOf(unused));
628 struct Resolver<
Set<T>> {
629 static DataType resolve(
const Set<T>& data) {
630 const int sz =
sizeof(data);
632 return DataType(
false, sz,
"Set", rawCppTypeNameOf(unused));
638 struct Resolver<
Set<T>*> {
639 static DataType resolve(
const Set<T>*& data) {
640 const int sz =
sizeof(*data);
642 return DataType(
true, sz,
"Set", rawCppTypeNameOf(unused));
647 template<
typename T_key,
typename T_value>
648 struct Resolver<
Map<T_key,T_value>> {
649 static DataType resolve(
const Map<T_key,T_value>& data) {
650 const int sz =
sizeof(data);
651 T_key unused1 = T_key();
652 T_value unused2 = T_value();
653 return DataType(
false, sz,
"Map", rawCppTypeNameOf(unused1),
654 rawCppTypeNameOf(unused2));
659 template<
typename T_key,
typename T_value>
660 struct Resolver<
Map<T_key,T_value>*> {
661 static DataType resolve(
const Map<T_key,T_value>*& data) {
662 const int sz =
sizeof(*data);
663 T_key unused1 = T_key();
664 T_value unused2 = T_value();
665 return DataType(
true, sz,
"Map", rawCppTypeNameOf(unused1),
666 rawCppTypeNameOf(unused2));
672 static String rawCppTypeName() {
673 const std::type_info& type =
typeid(T);
675 String name = type.raw_name();
677 String name = type.name();
686 static String rawCppTypeNameOf(
const T*
const & data) {
687 return rawCppTypeName<T*>();
692 static String rawCppTypeNameOf(
const T& data) {
693 const std::type_info& type =
typeid(data);
695 String name = type.raw_name();
697 String name = type.name();
707 std::function<Object(Archive*)> allocFn;
712 String m_baseTypeName;
713 String m_customTypeName;
714 String m_customTypeName2;
716 static std::map<String,NativeType> m_nativeTypes;
718 friend class Archive;
719 friend class SrxFormat;
720 friend class SrxJSONDecoder;
746 bool operator==(
const UID& other)
const {
return id == other.
id &&
size == other.
size; }
747 bool operator!=(
const UID& other)
const {
return id != other.id ||
size != other.size; }
748 bool operator<(
const UID& other)
const {
return id < other.id || (
id == other.id &&
size < other.size); }
749 bool operator>(
const UID& other)
const {
return id > other.id || (
id == other.id &&
size > other.size); }
760 return Resolver<T>::resolve(obj);
767 static UID resolve(
const T& obj);
772 struct Resolver<T*> {
773 static UID resolve(
const T*
const & obj);
865 friend class SrxFormat;
866 friend class SrxJSONDecoder;
898 UID uid(
int index = 0)
const;
906 std::vector<Member>&
members();
907 const std::vector<Member>&
members()
const;
922 void remove(
const Member& member);
933 std::vector<Member> m_members;
934 std::function<void(
Object& dstObj,
const Object& srcObj,
void* syncer)> m_sync;
936 #if LIBGIG_SERIALIZATION_INTERNAL
938 friend T _primitiveObjectValueToNumber(
const Object& obj);
942 friend class SrxFormat;
943 friend class SrxJSONDecoder;
1151 template<
typename T>
1154 m_allObjects.clear();
1156 preregisterNativeObject(*obj);
1187 template<
typename T>
1191 a.preregisterNativeObject(*obj);
1212 template<
typename T>
1235 template<
typename T>
1299 template<
typename T_
classType,
typename T_memberType>
1300 void serializeMember(
const T_classType& nativeObject,
const T_memberType& nativeMember,
const char* memberName) {
1301 Object& parent = preregisterNativeObject(nativeObject);
1302 const ssize_t offset =
1303 ((
const uint8_t*)(
const void*)&nativeMember) -
1304 ((
const uint8_t*)(
const void*)&nativeObject);
1305 const UIDChain uids = UIDChainResolver<T_memberType>(nativeMember);
1307 const Member member(memberName, uids[0], offset, type, parent);
1308 std::vector<Member>& members = parent.
members();
1309 for (
const Member& m : members)
1310 assert(m.name() != memberName);
1311 parent.
members().push_back(member);
1312 const Object obj(uids, type, parent);
1313 const bool bExistsAlready = m_allObjects.count(uids[0]);
1314 const bool isValidObject = obj;
1315 const Object& existingObj = m_allObjects[uids[0]];
1316 const bool bExistingObjectIsInvalid = !existingObj;
1317 if (isValidObject && (
1318 !bExistsAlready || bExistingObjectIsInvalid || (
1323 m_allObjects[uids[0]] = obj;
1326 SerializationRecursion<T_memberType>::serializeObject(
this, nativeMember);
1360 template<
typename T_
classType,
typename T_memberType>
1361 void serializeHeapMember(
const T_classType& nativeObject,
const T_memberType& heapMember,
const char* memberName) {
1362 Object& parent = preregisterNativeObject(nativeObject);
1363 const ssize_t offset = -1;
1364 const UIDChain uids = UIDChainResolver<T_memberType>(heapMember);
1366 const Member member(memberName, uids[0], offset, type, parent);
1367 parent.
members().push_back(member);
1368 const Object obj(uids, type, parent);
1369 const bool bExistsAlready = m_allObjects.count(uids[0]);
1370 const bool isValidObject = obj;
1371 const Object& existingObj = m_allObjects[uids[0]];
1372 const bool bExistingObjectIsInvalid = !existingObj;
1373 if (isValidObject && (
1374 !bExistsAlready || bExistingObjectIsInvalid || (
1379 m_allObjects[uids[0]] = obj;
1382 SerializationRecursion<T_memberType>::serializeObject(
this, heapMember);
1406 template<
typename T_
objectType>
1408 const UIDChain uids = UIDChainResolver<T_objectType>(heapObject);
1411 const bool bExistsAlready = m_allObjects.count(uids[0]);
1412 const bool isValidObject = obj;
1413 const Object& existingObj = m_allObjects[uids[0]];
1414 const bool bExistingObjectIsInvalid = !existingObj;
1415 if (isValidObject && (
1416 !bExistsAlready || bExistingObjectIsInvalid || (
1421 m_allObjects[uids[0]] = obj;
1424 SerializationRecursion<T_objectType>::serializeObject(
this, heapObject);
1507 template<
typename T_
classType>
1510 Object& obj = m_allObjects[uid];
1512 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
1548 template<
typename T_
classType>
1551 Object& obj = m_allObjects[uid];
1553 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
1562 virtual void decode(
const uint8_t* data,
size_t size);
1563 virtual void decode(
const uint8_t* data,
size_t size,
format_t format);
1598 static String primitiveObjectValueToString(
const Object& obj);
1600 template<
typename T_
classType>
1601 Object& preregisterNativeObject(
const T_classType& nativeObject) {
1603 Object& obj = m_allObjects[uid];
1605 const UIDChain uids = UIDChainResolver<T_classType>(nativeObject);
1613 template<
typename T>
1614 class UIDChainResolver {
1616 UIDChainResolver(
const T& data) {
1620 operator UIDChain()
const {
return m_uid; }
1621 UIDChain operator()()
const {
return m_uid; }
1627 template<
typename T>
1628 class UIDChainResolver<T*> {
1630 UIDChainResolver(
const T*
const & data) {
1631 m_uid.push_back({ (
ID) &data,
sizeof(data) });
1635 m_uid.push_back({ (
ID) data,
sizeof(*data) });
1638 operator UIDChain()
const {
return m_uid; }
1639 UIDChain operator()()
const {
return m_uid; }
1645 template<
typename T,
bool T_isRecursive>
1646 struct SerializationRecursionImpl {
1647 static void serializeObject(
Archive* archive,
const T& obj) {
1653 template<
typename T,
bool T_isRecursive>
1654 struct SerializationRecursionImpl<T*,T_isRecursive> {
1655 static void serializeObject(
Archive* archive,
const T*& obj) {
1657 const_cast<T*&
>(obj)->
serialize(archive);
1662 template<
typename T>
1663 struct SerializationRecursionImpl<T,false> {
1664 static void serializeObject(
Archive* ,
const T& ) {}
1668 template<
typename T>
1669 struct SerializationRecursionImpl<T*,
false> {
1670 static void serializeObject(
Archive* archive,
const T*
const & obj) {
1672 archive->serializeAnonymousObject(*obj);
1677 template<
bool T_isRecursive>
1678 struct SerializationRecursionImpl<String,T_isRecursive> {
1679 static void serializeObject(
Archive* archive,
const String& obj) {}
1683 template<
bool T_isRecursive>
1684 struct SerializationRecursionImpl<String*,T_isRecursive> {
1685 static void serializeObject(
Archive* archive,
const String*& obj) {
1687 archive->serializeAnonymousObject(*obj);
1692 template<
typename T,
bool T_isRecursive>
1693 struct SerializationRecursionImpl<
Array<T>,T_isRecursive> {
1694 static void serializeObject(
Archive* archive,
const Array<T>& obj) {
1695 const UIDChain uids = UIDChainResolver<Array<T>>(obj);
1696 const Object&
object = archive->objectByUID(uids[0]);
1698 for (
size_t i = 0; i < obj.size(); ++i) {
1699 archive->serializeHeapMember(
1700 obj, obj[i], (
"[" + toString(i) +
"]").c_str()
1704 const_cast<Object&
>(object).m_sync =
1705 [&obj,archive](Object& dstObj,
const Object& srcObj,
1708 const size_t n = srcObj.members().size();
1709 const_cast<Array<T>&
>(obj).resize(n);
1710 for (
size_t i = 0; i < n; ++i) {
1711 archive->serializeHeapMember(
1712 obj, obj[i], (
"[" + toString(i) +
"]").c_str()
1717 dstObj = archive->objectByUID(dstObj.uid());
1718 for (
size_t i = 0; i < n; ++i) {
1719 String
name =
"[" + toString(i) +
"]";
1720 Member srcMember = srcObj.memberNamed(
name);
1721 Member dstMember = dstObj.memberNamed(
name);
1722 ((Syncer*)syncer)->syncMember(dstMember, srcMember);
1730 template<
typename T,
bool T_isRecursive>
1731 struct SerializationRecursionImpl<
Array<T>*,T_isRecursive> {
1732 static void serializeObject(
Archive* archive,
const Array<T>*& obj) {
1734 SerializationRecursionImpl<Array<T>,T_isRecursive>::serializeObject(
1741 template<
typename T,
bool T_isRecursive>
1742 struct SerializationRecursionImpl<
Set<T>,T_isRecursive> {
1743 static void serializeObject(
Archive* archive,
const Set<T>& obj) {
1744 const UIDChain uids = UIDChainResolver<Set<T>>(obj);
1745 const Object&
object = archive->objectByUID(uids[0]);
1747 for (
const T& key : obj) {
1748 archive->serializeHeapMember(
1749 obj, key, (
"[" + toString(key) +
"]").c_str()
1753 const_cast<Object&
>(object).m_sync =
1754 [&obj,archive](Object& dstObj,
const Object& srcObj,
1757 const size_t n = srcObj.members().size();
1758 const_cast<Set<T>&
>(obj).
clear();
1759 for (
size_t i = 0; i < n; ++i) {
1760 const Member& member = srcObj.members()[i];
1761 String
name = member.name();
1763 if (
name.length() < 2 ||
name[0] !=
'[' ||
1764 *
name.rbegin() !=
']')
continue;
1767 const UIDChain uids = UIDChainResolver<T>(key);
1769 Object tmpObj(uids, type, Object());
1771 tmpObj.setNativeValueFromString(
name);
1775 ((Syncer*)syncer)->translateKey(key);
1777 const_cast<Set<T>&
>(obj).insert(key);
1780 for (
const T& key : obj) {
1781 archive->serializeHeapMember(
1782 obj, key, (
"[" + toString(key) +
"]").c_str()
1787 dstObj = archive->objectByUID(dstObj.uid());
1794 template<
typename T,
bool T_isRecursive>
1795 struct SerializationRecursionImpl<
Set<T>*,T_isRecursive> {
1796 static void serializeObject(
Archive* archive,
const Set<T>*& obj) {
1798 SerializationRecursionImpl<Set<T>,T_isRecursive>::serializeObject(
1805 template<
typename T_key,
typename T_value,
bool T_isRecursive>
1806 struct SerializationRecursionImpl<
Map<T_key,T_value>,T_isRecursive> {
1807 static void serializeObject(
Archive* archive,
const Map<T_key,T_value>& obj) {
1808 const UIDChain uids = UIDChainResolver<Map<T_key,T_value>>(obj);
1809 const Object&
object = archive->objectByUID(uids[0]);
1811 for (
const auto& it : obj) {
1813 SerializationRecursion<T_key>::serializeObject(archive, it.first);
1815 archive->serializeHeapMember(
1816 obj, it.second, (
"[" + toString(it.first) +
"]").c_str()
1820 const_cast<Object&
>(object).m_sync =
1821 [&obj,archive](Object& dstObj,
const Object& srcObj,
1824 const size_t n = srcObj.members().size();
1825 const_cast<Map<T_key,T_value>&
>(obj).
clear();
1827 std::map<String,String> memberNameTranslation;
1828 for (
size_t i = 0; i < n; ++i) {
1829 const Member& member = srcObj.members()[i];
1830 String
name = member.name();
1832 if (
name.length() < 2 ||
name[0] !=
'[' ||
1833 *
name.rbegin() !=
']')
continue;
1835 T_key srcKey = T_key();
1836 const UIDChain uids = UIDChainResolver<T_key>(srcKey);
1838 Object tmpObj(uids, type, Object());
1840 tmpObj.setNativeValueFromString(
name);
1841 T_key dstKey = srcKey;
1845 ((Syncer*)syncer)->translateKey(dstKey);
1846 memberNameTranslation[member.name()] =
"[" + toString(dstKey) +
"]";
1848 const_cast<Map<T_key,T_value>&
>(obj)[dstKey] = T_value();
1851 for (
const auto& it : obj) {
1853 SerializationRecursion<T_key>::serializeObject(archive, it.first);
1855 archive->serializeHeapMember(
1856 obj, it.second, (
"[" + toString(it.first) +
"]").c_str()
1861 dstObj = archive->objectByUID(dstObj.uid());
1863 for (
size_t i = 0; i < n; ++i) {
1864 Member srcMember = srcObj.members()[i];
1865 Member dstMember = dstObj.memberNamed(
1866 memberNameTranslation[srcMember.name()]
1868 ((Syncer*)syncer)->syncMember(dstMember, srcMember);
1876 template<
typename T_key,
typename T_value,
bool T_isRecursive>
1877 struct SerializationRecursionImpl<
Map<T_key,T_value>*,T_isRecursive> {
1878 static void serializeObject(
Archive* archive,
const Map<T_key,T_value>*& obj) {
1880 SerializationRecursionImpl<Map<T_key,T_value>,T_isRecursive>::serializeObject(
1887 template<
typename T>
1888 struct SerializationRecursion : SerializationRecursionImpl<T, LIBGIG_IS_CLASS(T)> {
1891 class ObjectPool :
public std::map<UID,Object> {
1894 Object& operator[](
const UID& k) {
1896 return invalidObject();
1897 return std::map<UID,Object>::operator[](k);
1900 static Object& invalidObject() {
1901 static Object invalid;
1951 void syncPrimitive(
const Object& dst,
const Object& src);
1956 void syncPointer(
const Object& dst,
const Object& src);
1957 void syncMember(
const Member& dstMember,
const Member& srcMember);
1964 template<
typename T>
1965 void translateKey(T*& key) {
1972 UID uid = { (
ID) key,
sizeof(*key) };
1975 assert(pointedSrcObject);
1976 std::map<UID,UID>::iterator uidRelation = m_counterparts.find(uid);
1977 if (pointedSrcObject.
parentUID() || uidRelation != m_counterparts.end()) {
1978 assert(uidRelation != m_counterparts.end());
1979 key = (T*) uidRelation->second.id;
1981 assert(pointedSrcObject.
type());
1983 assert(pointedDstObject);
1984 m_dst.m_allObjects[pointedDstObject.
uid()] = pointedDstObject;
1985 key = (T*) pointedDstObject.
uid().
id;
1987 syncObject(pointedDstObject, pointedSrcObject);
1992 template<
typename T>
1993 void translateKey(T& key) {}
1999 std::map<UID,UID> m_counterparts;
2002 virtual void encode();
2003 virtual void encode(
format_t format);
2005 ObjectPool m_allObjects;
2013 time_t m_timeCreated;
2014 time_t m_timeModified;
2017 friend class SrxFormat;
2018 friend class SrxJSONEncoder;
2019 friend class SrxJSONDecoder;
2023 template<
typename T>
2024 UID UID::Resolver<T>::resolve(
const T& obj) {
2026 const UID uid = { (
ID) &obj, size };
2031 template<
typename T>
2032 UID UID::Resolver<T*>::resolve(
const T*
const & obj) {
2034 const UID uid = { (
ID) obj, size };
2039 template<
typename T>
2042 std::is_default_constructible<T>::value,
2043 "missing default constructor for type: registration of data "
2044 "types is only needed for creating instances of that type at "
2045 "runtime by this framework's reflection API; which in turn "
2046 "requires the type to provide a default constructor."
2048 const DataType staticType = DataType::dataType<T>(
false);
2050 const auto itType = m_nativeTypes.find(staticType.
internalID());
2051 if (itType != m_nativeTypes.end()) {
2052 assert(itType->second.size >=
sizeof(T));
2060 T* instance =
new T;
2061 Archive::SerializationRecursion<T>::serializeObject(archive, *instance);
2062 const UIDChain uids = Archive::UIDChainResolver<T>(*instance);
2064 if (obj)
return obj;
2073 template<typename T, typename std::enable_if<std::is_default_constructible<T>::value,
bool>::type>
2075 if (!rttiType)
return;
2076 if (m_nativeTypes.find(rttiType.
internalID()) != m_nativeTypes.end())
2095 const DataType staticType = DataType::dataType<T>(
false);
2096 if (staticType != rttiType) {
2097 fprintf(stderr,
"Serialization Failure: run-time data type '%s' does not match compile-time data type '%s'!\n",
2100 assert(
false &&
"You may need to explicitly register this run-time "
2101 "data type by either calling "
2102 "DataType::registerNativeType<T>() or using class "
2103 "NativeDataTypeRegistry");
2109 [](Archive* archive) -> Object {
2110 T* instance =
new T;
2111 Archive::SerializationRecursion<T>::serializeObject(archive, *instance);
2112 const UIDChain uids = Archive::UIDChainResolver<T>(*instance);
2113 Object& obj = archive->objectByUID(uids[0]);
2114 if (obj)
return obj;
2116 return Object(uids, type, Object());
2123 template<typename T, typename std::enable_if<!std::is_default_constructible<T>::value,
bool>::type>
2126 if (m_nativeTypes.find(type.internalID()) != m_nativeTypes.end())
2128 m_nativeTypes[type.internalID()] = {
2130 [](Archive*) -> Object {
2131 assert(
false &&
"instance not possible: native data type does not have default constructor");
2138 template<
typename T,
bool T_isPo
inter>
2139 DataType DataType::ResolverBase<T,T_isPointer>::resolve(
const T& data) {
2143 const std::type_info& type = (T_isPointer) ?
typeid(T) :
typeid(data);
2144 const int sz =
sizeof(data);
2149 if (type ==
typeid(
char))
2153 return DataType(T_isPointer, sz,
"char");
2154 if (type ==
typeid(int8_t))
return DataType(T_isPointer, sz,
"int8");
2155 if (type ==
typeid(uint8_t))
return DataType(T_isPointer, sz,
"uint8");
2156 if (type ==
typeid(int16_t))
return DataType(T_isPointer, sz,
"int16");
2157 if (type ==
typeid(uint16_t))
return DataType(T_isPointer, sz,
"uint16");
2158 if (type ==
typeid(int32_t))
return DataType(T_isPointer, sz,
"int32");
2159 if (type ==
typeid(uint32_t))
return DataType(T_isPointer, sz,
"uint32");
2160 if (type ==
typeid(int64_t))
return DataType(T_isPointer, sz,
"int64");
2161 if (type ==
typeid(uint64_t))
return DataType(T_isPointer, sz,
"uint64");
2164 if (type ==
typeid(
long) || type ==
typeid(int)) {
2165 if (sz == 1)
return DataType(T_isPointer, sz,
"int8");
2166 if (sz == 2)
return DataType(T_isPointer, sz,
"int16");
2167 if (sz == 4)
return DataType(T_isPointer, sz,
"int32");
2168 if (sz == 8)
return DataType(T_isPointer, sz,
"int64");
2169 else assert(
false );
2171 if (type ==
typeid(
unsigned long) || type ==
typeid(
unsigned int)) {
2172 if (sz == 1)
return DataType(T_isPointer, sz,
"uint8");
2173 if (sz == 2)
return DataType(T_isPointer, sz,
"uint16");
2174 if (sz == 4)
return DataType(T_isPointer, sz,
"uint32");
2175 if (sz == 8)
return DataType(T_isPointer, sz,
"uint64");
2176 else assert(
false );
2178 if (type ==
typeid(
bool))
return DataType(T_isPointer, sz,
"bool");
2179 if (type ==
typeid(
float))
return DataType(T_isPointer, sz,
"real32");
2180 if (type ==
typeid(
double))
return DataType(T_isPointer, sz,
"real64");
2181 if (type ==
typeid(String))
return DataType(T_isPointer, sz,
"String");
2190 const String rawCppName =
2191 (T_isPointer) ? rawCppTypeName<T>()
2192 : rawCppTypeNameOf(data);
2194 if (
IsEnum(data))
return DataType(T_isPointer, sz,
"enum", rawCppName);
2195 if (
IsUnion(data))
return DataType(T_isPointer, sz,
"union", rawCppName);
2196 if (
IsClass(data))
return DataType(T_isPointer, sz,
"class", rawCppName);
Synchronizes 2 archives with each other.
Destination container for serialization, and source container for deserialization.
void setStringValue(Object &object, String value)
Set new textual string for given String object.
void setRealValue(Object &object, double value)
Set new floating point value for given floating point object.
void setCharValue(Object &object, char value)
Set new char value for given character object.
char valueAsChar(const Object &object)
Get char value of 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.
Archive(format_t format=FORMAT_AUTO)
Create an "empty" archive.
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.
operation_t
Current activity of Archive object.
@ OPERATION_DESERIALIZE
Archive is currently deserializing.
@ OPERATION_NONE
Archive is currently neither serializing, nor deserializing.
@ OPERATION_SERIALIZE
Archive is currently serializing.
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.
void serializeAnonymousObject(const T_objectType &heapObject)
Serialize anonymous C/C++ 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.
Object & objectByBaseUID(const UID &uid)
Find true object for a base pointer.
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 serializeHeapMember(const T_classType &nativeObject, const T_memberType &heapMember, const char *memberName)
Serialize a C/C++ member variable allocated on the heap.
Object & parentObjectOf(const Object &obj)
Access parent of supplied object.
void operator<<(const T &obj)
Initiate serialization of your C++ objects.
void setComment(String comment)
Assign a comment to this archive.
format_t
Encoding format of serialized data stream.
@ FORMAT_AUTO
Automatically handle the encoding format:
@ FORMAT_SRX_JSON
Use and expect "Srx-JSON" encoding format (user-friendly to read and modify).
@ FORMAT_SRX
Use and expect "Srx" encoding format (simple, reliable, fast).
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.
Registrator for native data types.
Abstract reflection of a native C++ data type.
bool isPrimitive() const
Whether this is reflecting a fundamental C/C++ data type.
bool isSet() const
Whether this is a C++ Set<> object type.
static DataType dataTypeOf(const T &data, bool registerType=true)
Construct a DataType object for the given native C++ data.
bool isNumber() const
Whether this is a numeric 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 (as "invalid" DataType).
static void registerNativeDataType()
Manual registration of native C++ data types.
String asLongDescr() const
Human readable long description for this data type.
bool isBool() const
Whether this is a boolean C/C++ data type.
static size_t sizeOf(const T &data)
True size of passed native data in bytes.
bool isMap() const
Whether this is a C++ Map<> object type.
bool isValid() const
Check if this is a valid DataType object.
bool isArray() const
Whether this is a C++ Array<> object type.
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 isChar() const
Whether this is a character C/C++ data type.
String customTypeName2(bool demangle=false) const
The 2nd 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.
bool isInteger() const
Whether this is an integer C/C++ data type.
bool operator==(const DataType &other) const
Comparison for equalness.
String internalID() const
Unique key for native data type, for internal purposes only.
static DataType dataType(bool registerType=true)
Construct a DataType object for the given native C++ type.
bool isString() const
Whether this is a C++ String data type.
String customTypeName(bool demangle=false) const
The 1st 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.
Object newInstance(Archive *archive) const
Allocate and initialize a native instance of data type.
Will be thrown whenever an error occurs during an serialization or deserialization process.
void PrintMessage() const
Print exception message to stdout.
Abstract reflection of a native C++ class/struct's member variable.
UID parentUID() const
Unique identifier of parent object.
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.
ssize_t offset() const
Offset of member in its containing parent data structure.
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.
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.
void setNativeValueFromString(const String &s)
Cast from string to object's data type and assign value natively.
bool operator!=(const Object &other) const
Comparison for inequalness.
bool operator>(const Object &other) const
Greater than comparison.
UID parentUID() const
Unique identifier of parent object.
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.
C++ Serialization / Deserialization Framework.
bool IsUnion(const T &)
Check whether data is a C++ union type.
void * ID
Abstract identifier for serialized C++ objects.
bool IsClass(const T &)
Check whether data is a C/C++ struct or C++ class type.
const UID NO_UID
Reflects an invalid UID and behaves similar to NULL as invalid value for pointer types.
std::set< T > Set
Set<> template.
std::string String
Textual string.
std::map< T_key, T_value > Map
Map<> template.
bool IsEnum(const T &)
Check whether data is a C/C++ enum type.
uint32_t Version
Version number data type.
std::vector< UID > UIDChain
Chain of UIDs.
std::vector< T > Array
Array<> template.
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...