26 #define LIBGIG_SERIALIZATION_INTERNAL 1
28 #include "Serialization.h"
40 #include "SrxFormat.h"
42 #define LIBGIG_EPOCH_TIME ((time_t)0)
49 static UID _createNullUID() {
50 const UID uid = { NULL, 0 };
68 return id != NULL &&
id != (
void*)-1 &&
size;
85 std::map<String,DataType::NativeType> DataType::m_nativeTypes;
133 m_baseTypeName = baseType;
134 m_customTypeName = customType1;
135 m_customTypeName2 = customType2;
187 return m_baseTypeName ==
"class";
225 return m_baseTypeName ==
"String";
243 return m_baseTypeName.substr(0, 3) ==
"int" ||
244 m_baseTypeName.substr(0, 4) ==
"uint";
260 return m_baseTypeName.substr(0, 4) ==
"real";
275 return m_baseTypeName ==
"bool";
290 return m_baseTypeName ==
"enum";
306 return m_baseTypeName ==
"Array";
322 return m_baseTypeName ==
"Set";
338 return m_baseTypeName ==
"Map";
355 return m_baseTypeName.substr(0, 3) ==
"int" ||
378 return m_baseTypeName == other.m_baseTypeName &&
379 m_customTypeName == other.m_customTypeName &&
380 m_customTypeName2 == other.m_customTypeName2 &&
382 m_isPointer == other.m_isPointer;
398 return m_baseTypeName +
"," +
399 m_customTypeName +
"," +
400 m_customTypeName2 +
"," +
402 ToString(m_isPointer);
426 return m_baseTypeName < other.m_baseTypeName ||
427 (m_baseTypeName == other.m_baseTypeName &&
428 (m_customTypeName < other.m_customTypeName ||
429 (m_customTypeName == other.m_customTypeName &&
430 (m_customTypeName2 < other.m_customTypeName2 ||
431 (m_customTypeName2 == other.m_customTypeName2 &&
432 (m_size < other.m_size ||
433 (m_size == other.m_size &&
434 m_isPointer < other.m_isPointer)))))));
467 String s = m_baseTypeName;
468 if (!m_customTypeName.empty())
470 if (!m_customTypeName2.empty())
507 return m_baseTypeName;
510 static String _demangleTypeName(
const char* name) {
512 const size_t MAXLENGTH = 1024;
513 char result[MAXLENGTH];
517 size_t size = UnDecorateSymbolName(name + 1, result, MAXLENGTH, UNDNAME_32_BIT_DECODE | UNDNAME_NO_ARGUMENTS);
526 abi::__cxa_demangle(name, 0, 0, &status);
527 String sResult = result;
529 return (status == 0) ? sResult : name;
570 if (!demangle)
return m_customTypeName;
571 return _demangleTypeName(m_customTypeName.c_str());
582 if (!demangle)
return m_customTypeName2;
583 return _demangleTypeName(m_customTypeName2.c_str());
601 auto itNativeType = m_nativeTypes.find(
id);
602 if (itNativeType == m_nativeTypes.end()) {
604 "(De)serialization Failure: cannot create new instance of "
605 "unknown data type '%s' !\n",
607 assert(
false &&
"You may need to explicitly register this data "
608 "type by either calling "
609 "DataType::registerNativeType<T>() or using class "
610 "NativeDataTypeRegistry");
612 const std::function<
Object(
Archive*)>& allocFn = itNativeType->second.allocFn;
613 return allocFn(archive);
642 m_parentUID = parent.
uid();
762 return m_uid && !m_name.empty() && m_type;
774 return m_uid == other.m_uid &&
775 m_offset == other.m_offset &&
776 m_name == other.m_name &&
777 m_type == other.m_type;
802 return m_uid < other.m_uid ||
803 (m_uid == other.m_uid &&
804 (m_offset < other.m_offset ||
805 (m_offset == other.m_offset &&
806 (m_name < other.m_name ||
807 (m_name == other.m_name &&
808 m_type < other.m_type)))));
867 m_parentUID = parent.
uid();
884 return m_type && !m_uid.empty();
899 return (index < m_uid.size()) ? m_uid[index] :
NO_UID;
918 static void _setNativeValueFromString(
void* ptr,
const DataType& type,
const char* s) {
921 uintptr_t addr = std::stoull(s, NULL, 16);
922 *(
void**)ptr =
reinterpret_cast<void*
>(addr);
926 if (type.
size() == 1)
927 *(int8_t*)ptr = strTo<int8_t>(s);
928 else if (type.
size() == 2)
929 *(int16_t*)ptr = strTo<int16_t>(s);
930 else if (type.
size() == 4)
931 *(int32_t*)ptr = strTo<int32_t>(s);
932 else if (type.
size() == 8)
933 *(int64_t*)ptr = strTo<int64_t>(s);
937 if (type.
size() == 1)
938 *(uint8_t*)ptr = strTo<uint8_t>(s);
939 else if (type.
size() == 2)
940 *(uint16_t*)ptr = strTo<uint16_t>(s);
941 else if (type.
size() == 4)
942 *(uint32_t*)ptr = strTo<uint32_t>(s);
943 else if (type.
size() == 8)
944 *(uint64_t*)ptr = strTo<uint64_t>(s);
948 }
else if (type.
isReal()) {
949 if (type.
size() ==
sizeof(
float))
950 *(
float*)ptr = strTo<float>(s);
951 else if (type.
size() ==
sizeof(double))
952 *(
double*)ptr = strTo<double>(s);
955 }
else if (type.
isBool()) {
956 String lower = toLowerCase(s);
957 const bool b = lower !=
"0" && lower !=
"false" && lower !=
"no";
984 void* ptr = (
void*)
id;
985 _setNativeValueFromString(ptr, m_type, s.c_str());
1059 return m_minVersion;
1121 return m_uid == other.m_uid &&
1122 m_type == other.m_type;
1149 return m_uid < other.m_uid ||
1150 (m_uid == other.m_uid &&
1151 m_type < other.m_type);
1197 void Object::setVersion(
Version v) {
1201 void Object::setMinVersion(
Version v) {
1235 for (
int i = 0; i < m_members.size(); ++i)
1236 if (m_members[i].name() == name)
1237 return m_members[i];
1257 for (
int i = 0; i < m_members.size(); ++i)
1258 if (m_members[i].
uid() ==
uid)
1259 return m_members[i];
1263 void Object::remove(
const Member& member) {
1264 for (
int i = 0; i < m_members.size(); ++i) {
1265 if (m_members[i] == member) {
1266 m_members.erase(m_members.begin() + i);
1288 std::vector<Member> v;
1289 for (
int i = 0; i < m_members.size(); ++i) {
1290 const Member& member = m_members[i];
1292 v.push_back(member);
1329 for (
int i = 0; i < m_members.size(); ++i)
1330 if (m_members[i] == member)
1359 m_isModified =
false;
1360 m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
1381 m_isModified =
false;
1382 m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
1409 m_isModified =
false;
1410 m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
1414 Archive::~Archive() {
1428 return m_allObjects[m_root];
1431 String Archive::primitiveObjectValueToString(
const Object& obj) {
1435 void* ptr = obj.m_data.empty() ? (
void*)
id : (
void*)&obj.m_data[0];
1436 if (!obj.m_data.empty())
1437 assert(type.
size() == obj.m_data.size());
1441 if (type.
size() == 1)
1442 s = ToString((int16_t)*(int8_t*)ptr);
1443 else if (type.
size() == 2)
1444 s = ToString(*(int16_t*)ptr);
1445 else if (type.
size() == 4)
1446 s = ToString(*(int32_t*)ptr);
1447 else if (type.
size() == 8)
1448 s = ToString(*(int64_t*)ptr);
1452 if (type.
size() == 1)
1453 s = ToString((uint16_t)*(uint8_t*)ptr);
1454 else if (type.
size() == 2)
1455 s = ToString(*(uint16_t*)ptr);
1456 else if (type.
size() == 4)
1457 s = ToString(*(uint32_t*)ptr);
1458 else if (type.
size() == 8)
1459 s = ToString(*(uint64_t*)ptr);
1463 }
else if (type.
isReal()) {
1464 if (type.
size() ==
sizeof(
float))
1465 s = ToString(*(
float*)ptr);
1466 else if (type.
size() ==
sizeof(
double))
1467 s = ToString(*(
double*)ptr);
1470 }
else if (type.
isBool()) {
1471 s = ToString(*(
bool*)ptr);
1473 s = obj.m_data.empty() ? *(String*)ptr :
String((
const char*)ptr);
1481 template<
typename T>
1482 inline T _stringToNumber(
const String& s) {
1487 inline int64_t _stringToNumber(
const String& s) {
1488 return strTo<int64_t>(s);
1492 inline double _stringToNumber(
const String& s) {
1493 return strTo<double>(s);
1497 inline bool _stringToNumber(
const String& s) {
1498 return strTo<bool>(s);
1501 template<
typename T>
1502 static T _primitiveObjectValueToNumber(
const Object& obj) {
1504 const DataType& type = obj.type();
1505 const ID&
id = obj.uid().id;
1506 void* ptr = obj.m_data.empty() ? (
void*)
id : (
void*)&obj.m_data[0];
1507 if (!obj.m_data.empty())
1508 assert(type.size() == obj.m_data.size());
1509 if (type.isPrimitive() && !type.isPointer()) {
1510 if (type.isInteger() || type.isEnum()) {
1511 if (type.isSigned()) {
1512 if (type.size() == 1)
1513 value = (T)*(int8_t*)ptr;
1514 else if (type.size() == 2)
1515 value = (T)*(int16_t*)ptr;
1516 else if (type.size() == 4)
1517 value = (T)*(int32_t*)ptr;
1518 else if (type.size() == 8)
1519 value = (T)*(int64_t*)ptr;
1523 if (type.size() == 1)
1524 value = (T)*(uint8_t*)ptr;
1525 else if (type.size() == 2)
1526 value = (T)*(uint16_t*)ptr;
1527 else if (type.size() == 4)
1528 value = (T)*(uint32_t*)ptr;
1529 else if (type.size() == 8)
1530 value = (T)*(uint64_t*)ptr;
1534 }
else if (type.isReal()) {
1535 if (type.size() ==
sizeof(
float))
1536 value = (T)*(
float*)ptr;
1537 else if (type.size() ==
sizeof(double))
1538 value = (T)*(
double*)ptr;
1541 }
else if (type.isBool()) {
1542 value = (T)*(
bool*)ptr;
1543 }
else if (type.isString()) {
1544 value = _stringToNumber<T>(
1545 obj.m_data.empty() ? *(String*)ptr : String((
const char*)ptr)
1554 void Archive::encode() {
1556 m_timeModified = time(NULL);
1557 if (m_timeCreated == LIBGIG_EPOCH_TIME)
1558 m_timeCreated = m_timeModified;
1560 m_rawData = SrxFormat::encode(*
this);
1562 m_isModified =
false;
1582 m_allObjects.clear();
1583 m_isModified =
false;
1584 m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
1586 SrxFormat::decode(*
this, data);
1612 memcpy(&
rawData[0], data, size);
1632 if (m_isModified) encode();
1642 return SrxFormat::name();
1660 return m_isModified;
1669 m_allObjects.clear();
1673 m_isModified =
false;
1674 m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
1698 if (m_name ==
name)
return;
1700 m_isModified =
true;
1724 if (m_comment ==
comment)
return;
1726 m_isModified =
true;
1729 static tm _convertTimeStamp(
const time_t& time,
time_base_t base) {
1733 pTm = localtime(&time);
1736 pTm = gmtime(&time);
1739 throw Exception(
"Time stamp with unknown time base (" + ToString((int64_t)base) +
") requested");
1742 throw Exception(
"Failed assembling time stamp structure");
1752 return m_timeCreated;
1761 return m_timeModified;
1775 return _convertTimeStamp(m_timeCreated, base);
1789 return _convertTimeStamp(m_timeModified, base);
1810 parent.remove(member);
1811 m_isModified =
true;
1831 if (!obj.
uid())
return;
1832 m_allObjects.erase(obj.
uid());
1833 m_isModified =
true;
1849 return m_allObjects[uid];
1867 ObjectPool::iterator it = m_allObjects.find(uid);
1868 if (it != m_allObjects.end())
1873 std::map<size_t,UID> matches;
1874 for (
const auto& it : m_allObjects)
1875 if (it.first.id == uid.
id && it.first.size > uid.
size)
1876 matches[it.first.size] = it.first;
1878 if (matches.empty())
1879 return ObjectPool::invalidObject();
1882 return m_allObjects[matches.begin()->second];
1903 return m_allObjects[member.
parentUID()];
1917 if (!
object)
return;
1918 object.setVersion(v);
1919 m_isModified =
true;
1933 if (!
object)
return;
1934 object.setMinVersion(v);
1935 m_isModified =
true;
1947 if (!
object)
return;
1948 if (!
object.type().isEnum())
1949 throw Exception(
"Not an enum data type");
1950 Object* pObject = &object;
1951 if (
object.type().isPointer()) {
1956 const int nativeEnumSize =
sizeof(
enum operation_t);
1960 if (type.
size() != nativeEnumSize) {
1961 type.m_size = nativeEnumSize;
1963 pObject->m_data.resize(type.
size());
1964 void* ptr = &pObject->m_data[0];
1965 if (type.
size() == 1)
1966 *(uint8_t*)ptr = (uint8_t)value;
1967 else if (type.
size() == 2)
1968 *(uint16_t*)ptr = (uint16_t)value;
1969 else if (type.
size() == 4)
1970 *(uint32_t*)ptr = (uint32_t)value;
1971 else if (type.
size() == 8)
1972 *(uint64_t*)ptr = (uint64_t)value;
1975 m_isModified =
true;
1989 if (!
object)
return;
1990 if (!
object.type().isInteger())
1991 throw Exception(
"Not an integer data type");
1992 Object* pObject = &object;
1993 if (
object.type().isPointer()) {
1999 pObject->m_data.resize(type.
size());
2000 void* ptr = &pObject->m_data[0];
2002 if (type.
size() == 1)
2003 *(int8_t*)ptr = (int8_t)value;
2004 else if (type.
size() == 2)
2005 *(int16_t*)ptr = (int16_t)value;
2006 else if (type.
size() == 4)
2007 *(int32_t*)ptr = (int32_t)value;
2008 else if (type.
size() == 8)
2009 *(int64_t*)ptr = (int64_t)value;
2013 if (type.
size() == 1)
2014 *(uint8_t*)ptr = (uint8_t)value;
2015 else if (type.
size() == 2)
2016 *(uint16_t*)ptr = (uint16_t)value;
2017 else if (type.
size() == 4)
2018 *(uint32_t*)ptr = (uint32_t)value;
2019 else if (type.
size() == 8)
2020 *(uint64_t*)ptr = (uint64_t)value;
2024 m_isModified =
true;
2039 if (!
object)
return;
2040 if (!
object.type().isReal())
2041 throw Exception(
"Not a real data type");
2042 Object* pObject = &object;
2043 if (
object.type().isPointer()) {
2049 pObject->m_data.resize(type.
size());
2050 void* ptr = &pObject->m_data[0];
2051 if (type.
size() ==
sizeof(
float))
2052 *(
float*)ptr = (
float)value;
2053 else if (type.
size() ==
sizeof(double))
2054 *(
double*)ptr = (
double)value;
2057 m_isModified =
true;
2069 if (!
object)
return;
2070 if (!
object.type().isBool())
2071 throw Exception(
"Not a bool data type");
2072 Object* pObject = &object;
2073 if (
object.type().isPointer()) {
2079 pObject->m_data.resize(type.
size());
2080 bool* ptr = (
bool*)&pObject->m_data[0];
2082 m_isModified =
true;
2094 if (!
object)
return;
2095 if (!
object.type().isString())
2096 throw Exception(
"Not a String data type");
2097 Object* pObject = &object;
2098 if (
object.type().isPointer()) {
2103 pObject->m_data.resize(value.length() + 1);
2104 char* ptr = (
char*) &pObject->m_data[0];
2105 strcpy(ptr, &value[0]);
2106 m_isModified =
true;
2123 if (!
object)
return;
2124 const DataType& type =
object.type();
2129 else if (type.
isBool()) {
2130 String val = toLowerCase(value);
2131 if (val ==
"true" || val ==
"yes" || val ==
"1")
2133 else if (val ==
"false" || val ==
"no" || val ==
"0")
2142 throw Exception(
"Not a primitive data type");
2157 if (
object.type().isClass())
2158 throw Exception(
"Object is class type");
2159 const Object* pObject = &object;
2160 if (
object.type().isPointer()) {
2162 if (!obj)
return "";
2165 return primitiveObjectValueToString(*pObject);
2180 if (!
object.type().isInteger() && !
object.type().isEnum())
2181 throw Exception(
"Object is neither an integer nor an enum");
2182 const Object* pObject = &object;
2183 if (
object.type().isPointer()) {
2188 return _primitiveObjectValueToNumber<int64_t>(*pObject);
2203 if (!
object.type().isReal())
2204 throw Exception(
"Object is not an real type");
2205 const Object* pObject = &object;
2206 if (
object.type().isPointer()) {
2211 return _primitiveObjectValueToNumber<double>(*pObject);
2225 if (!
object.type().isBool())
2226 throw Exception(
"Object is not a bool");
2227 const Object* pObject = &object;
2228 if (
object.type().isPointer()) {
2233 return _primitiveObjectValueToNumber<bool>(*pObject);
2243 Archive::Syncer::Syncer(Archive& dst, Archive& src)
2244 : m_dst(dst), m_src(src)
2246 const Object srcRootObj = src.rootObject();
2247 const Object dstRootObj = dst.rootObject();
2249 throw Exception(
"No source root object!");
2251 throw Exception(
"Expected destination root object not found!");
2252 syncObject(dstRootObj, srcRootObj);
2255 void Archive::Syncer::syncPrimitive(
const Object& dstObj,
const Object& srcObj) {
2256 assert(srcObj.rawData().size() == dstObj.type().size());
2257 void* pDst = (
void*)dstObj.uid().id;
2258 memcpy(pDst, &srcObj.rawData()[0], dstObj.type().size());
2261 void Archive::Syncer::syncString(
const Object& dstObj,
const Object& srcObj) {
2262 assert(dstObj.type().isString());
2263 assert(dstObj.type() == srcObj.type());
2264 String* pDst = (String*)(
void*)dstObj.uid().id;
2265 *pDst = (
String) (
const char*) &srcObj.rawData()[0];
2268 void Archive::Syncer::syncArray(
const Object& dstObj,
const Object& srcObj) {
2269 assert(dstObj.type().isArray());
2270 assert(dstObj.type() == srcObj.type());
2271 dstObj.m_sync(
const_cast<Object&
>(dstObj), srcObj,
this);
2274 void Archive::Syncer::syncSet(
const Object& dstObj,
const Object& srcObj) {
2275 assert(dstObj.type().isSet());
2276 assert(dstObj.type() == srcObj.type());
2277 dstObj.m_sync(
const_cast<Object&
>(dstObj), srcObj,
this);
2280 void Archive::Syncer::syncMap(
const Object& dstObj,
const Object& srcObj) {
2281 assert(dstObj.type().isMap());
2282 assert(dstObj.type() == srcObj.type());
2283 dstObj.m_sync(
const_cast<Object&
>(dstObj), srcObj,
this);
2286 void Archive::Syncer::syncPointer(
const Object& dstObj,
const Object& srcObj) {
2287 assert(dstObj.type().isPointer());
2288 assert(dstObj.type() == srcObj.type());
2289 void** ppDst = (
void**)dstObj.uid().id;
2290 if (!srcObj.uid(1)) {
2294 const Object& pointedSrcObject = m_src.m_allObjects[srcObj.uid(1)];
2295 assert(pointedSrcObject);
2296 std::map<UID,UID>::iterator uidRelation = m_counterparts.find(srcObj.uid(1));
2297 if (pointedSrcObject.parentUID() || uidRelation != m_counterparts.end()) {
2298 assert(uidRelation != m_counterparts.end());
2299 const Object& pointedDstObject = m_dst.m_allObjects[uidRelation->second];
2300 assert(pointedDstObject);
2301 *ppDst = (
void*)pointedDstObject.uid().id;
2303 assert(pointedSrcObject.type());
2304 Object pointedDstObject = pointedSrcObject.type().newInstance(&m_dst);
2305 assert(pointedDstObject);
2307 m_dst.m_allObjects[pointedDstObject.uid()] = pointedDstObject;
2308 *ppDst = (
void*)pointedDstObject.uid().id;
2309 syncObject(pointedDstObject, pointedSrcObject);
2313 void Archive::Syncer::syncObject(
const Object& dstObj,
const Object& srcObj) {
2314 assert(dstObj && srcObj);
2324 const bool alreadySynced =
2325 !m_counterparts.insert({srcObj.uid(), dstObj.uid()}).second;
2332 if (!dstObj.isVersionCompatibleTo(srcObj))
2333 throw Exception(
"Version incompatible (destination version " +
2334 ToString(dstObj.version()) +
" [min. version " +
2335 ToString(dstObj.minVersion()) +
"], source version " +
2336 ToString(srcObj.version()) +
" [min. version " +
2337 ToString(srcObj.minVersion()) +
"])");
2338 if (dstObj.type() != srcObj.type())
2339 throw Exception(
"Incompatible data structure type (destination type " +
2340 dstObj.type().asLongDescr() +
" vs. source type " +
2341 srcObj.type().asLongDescr() +
")");
2343 if (dstObj.type().isPrimitive() && !dstObj.type().isPointer()) {
2344 if (dstObj.type().isString())
2345 syncString(dstObj, srcObj);
2347 syncPrimitive(dstObj, srcObj);
2351 if (dstObj.type().isArray()) {
2352 syncArray(dstObj, srcObj);
2356 if (dstObj.type().isSet()) {
2357 syncSet(dstObj, srcObj);
2361 if (dstObj.type().isMap()) {
2362 syncMap(dstObj, srcObj);
2366 if (dstObj.type().isPointer()) {
2367 syncPointer(dstObj, srcObj);
2371 assert(dstObj.type().isClass());
2372 for (
int iMember = 0; iMember < srcObj.members().size(); ++iMember) {
2373 const Member& srcMember = srcObj.members()[iMember];
2374 Member dstMember = dstMemberMatching(dstObj, srcObj, srcMember);
2376 throw Exception(
"Expected member missing in destination object");
2377 syncMember(dstMember, srcMember);
2381 Member Archive::Syncer::dstMemberMatching(
const Object& dstObj,
const Object& srcObj,
const Member& srcMember) {
2382 Member dstMember = dstObj.memberNamed(srcMember.name());
2384 return (dstMember.type() == srcMember.type()) ? dstMember : Member();
2385 std::vector<Member> members = dstObj.membersOfType(srcMember.type());
2386 if (members.size() <= 0)
2388 if (members.size() == 1)
2390 for (
int i = 0; i < members.size(); ++i)
2391 if (members[i].offset() == srcMember.offset())
2393 const int srcSeqNr = srcObj.sequenceIndexOf(srcMember);
2394 assert(srcSeqNr >= 0);
2395 for (
int i = 0; i < members.size(); ++i) {
2396 const int dstSeqNr = dstObj.sequenceIndexOf(members[i]);
2397 if (dstSeqNr == srcSeqNr)
2403 void Archive::Syncer::syncMember(
const Member& dstMember,
const Member& srcMember) {
2404 assert(dstMember && srcMember);
2405 assert(dstMember.type() == srcMember.type());
2406 const Object dstObj = m_dst.m_allObjects[dstMember.uid()];
2407 const Object srcObj = m_src.m_allObjects[srcMember.uid()];
2408 syncObject(dstObj, srcObj);
2414 Exception::Exception() {
2417 Exception::Exception(String format, ...) {
2419 va_start(arg, format);
2420 Message = assemble(format, arg);
2424 Exception::Exception(String format, va_list arg) {
2425 Message = assemble(format, arg);
2434 std::cout <<
"Serialization::Exception: " << Message << std::endl;
2437 String Exception::assemble(
String format, va_list arg) {
2439 vasprintf(&buf, format.c_str(), arg);
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 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.
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.
operation_t
Current activity of Archive object.
@ OPERATION_NONE
Archive is currently neither serializing, nor deserializing.
const RawData & rawData()
Raw data stream of this archive content.
bool isModified() const
Whether this archive was modified.
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.
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.
Object & parentObjectOf(const Object &obj)
Access parent of supplied object.
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.
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 isSet() const
Whether this is a C++ Set<> object 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).
String asLongDescr() const
Human readable long description for this data type.
bool isBool() const
Whether this is a boolean C/C++ data type.
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.
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.
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,...
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.
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.
std::string String
Textual string.
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...