1 |
/*************************************************************************** |
/*************************************************************************** |
2 |
* * |
* * |
3 |
* Copyright (C) 2017 Christian Schoenebeck * |
* Copyright (C) 2017-2020 Christian Schoenebeck * |
4 |
* <cuse@users.sourceforge.net> * |
* <cuse@users.sourceforge.net> * |
5 |
* * |
* * |
6 |
* This library is part of libgig. * |
* This library is part of libgig. * |
7 |
* * |
* * |
21 |
* MA 02111-1307 USA * |
* MA 02111-1307 USA * |
22 |
***************************************************************************/ |
***************************************************************************/ |
23 |
|
|
24 |
|
// enable implementation specific declarations in Serialization.h required to |
25 |
|
// build this C++ unit, which should be ignored in the public API though |
26 |
|
#define LIBGIG_SERIALIZATION_INTERNAL 1 |
27 |
|
|
28 |
#include "Serialization.h" |
#include "Serialization.h" |
29 |
|
|
30 |
#include <iostream> |
#include <iostream> |
31 |
#include <assert.h> |
#include <assert.h> |
32 |
#include <string.h> // for memcpy() |
#include <string.h> // for memcpy() |
33 |
#include <stdlib.h> // for atof() |
#include <stdlib.h> // for atof() |
34 |
#include <cxxabi.h> |
#ifdef _MSC_VER |
35 |
|
# include <windows.h> |
36 |
|
# include <dbghelp.h> |
37 |
|
#else |
38 |
|
# include <cxxabi.h> |
39 |
|
#endif |
40 |
#include "helper.h" |
#include "helper.h" |
41 |
|
|
42 |
#define LIBGIG_EPOCH_TIME ((time_t)0) |
#define LIBGIG_EPOCH_TIME ((time_t)0) |
258 |
* characteristic is compared as well. So a @c double type and @c double* |
* characteristic is compared as well. So a @c double type and @c double* |
259 |
* type are also considered to be not equal data types and hence this method |
* type are also considered to be not equal data types and hence this method |
260 |
* would return @c false. |
* would return @c false. |
261 |
|
* |
262 |
|
* As an exception here, classes and structs with the same class/struct name |
263 |
|
* but different sizes are also considered to be "equal". This relaxed |
264 |
|
* requirement is necessary to retain backward compatiblity to older |
265 |
|
* versions of the same native C++ classes/structs. |
266 |
*/ |
*/ |
267 |
bool DataType::operator==(const DataType& other) const { |
bool DataType::operator==(const DataType& other) const { |
268 |
return m_baseTypeName == other.m_baseTypeName && |
return m_baseTypeName == other.m_baseTypeName && |
269 |
m_customTypeName == other.m_customTypeName && |
m_customTypeName == other.m_customTypeName && |
270 |
m_size == other.m_size && |
(m_size == other.m_size || (isClass() && other.isClass())) && |
271 |
m_isPointer == other.m_isPointer; |
m_isPointer == other.m_isPointer; |
272 |
} |
} |
273 |
|
|
294 |
bool DataType::operator<(const DataType& other) const { |
bool DataType::operator<(const DataType& other) const { |
295 |
return m_baseTypeName < other.m_baseTypeName || |
return m_baseTypeName < other.m_baseTypeName || |
296 |
(m_baseTypeName == other.m_baseTypeName && |
(m_baseTypeName == other.m_baseTypeName && |
297 |
m_customTypeName < other.m_customTypeName || |
(m_customTypeName < other.m_customTypeName || |
298 |
(m_customTypeName == other.m_customTypeName && |
(m_customTypeName == other.m_customTypeName && |
299 |
m_size < other.m_size || |
(m_size < other.m_size || |
300 |
(m_size == other.m_size && |
(m_size == other.m_size && |
301 |
m_isPointer < other.m_isPointer))); |
m_isPointer < other.m_isPointer))))); |
302 |
} |
} |
303 |
|
|
304 |
/** @brief Greater than comparison. |
/** @brief Greater than comparison. |
403 |
* In the latter example @c customTypeName(true) would return for both |
* In the latter example @c customTypeName(true) would return for both |
404 |
* @c foo and @c pFoo the string @c "Foo" as return value of this method. |
* @c foo and @c pFoo the string @c "Foo" as return value of this method. |
405 |
* |
* |
406 |
|
* @b Windows: please note that the current implementation of this method |
407 |
|
* on Windows is @b not thread safe! |
408 |
|
* |
409 |
* @see isPointer(), baseTypeName() |
* @see isPointer(), baseTypeName() |
410 |
*/ |
*/ |
411 |
String DataType::customTypeName(bool demangle) const { |
String DataType::customTypeName(bool demangle) const { |
412 |
if (!demangle) return m_customTypeName; |
if (!demangle) return m_customTypeName; |
413 |
|
#ifdef _MSC_VER |
414 |
|
const size_t MAXLENGTH = 1024; |
415 |
|
char result[MAXLENGTH]; |
416 |
|
|
417 |
|
//FIXME: calling UnDecorateSymbolName() is not thread safe! |
418 |
|
//Skip the first char |
419 |
|
size_t size = UnDecorateSymbolName(m_customTypeName.c_str() +1, result, MAXLENGTH, UNDNAME_32_BIT_DECODE | UNDNAME_NO_ARGUMENTS); |
420 |
|
if (size) |
421 |
|
{ |
422 |
|
return result; |
423 |
|
} |
424 |
|
return m_customTypeName; |
425 |
|
#else |
426 |
int status; |
int status; |
427 |
const char* result = |
char* result = |
428 |
abi::__cxa_demangle(m_customTypeName.c_str(), 0, 0, &status); |
abi::__cxa_demangle(m_customTypeName.c_str(), 0, 0, &status); |
429 |
return (status == 0) ? result : m_customTypeName; |
String sResult = result; |
430 |
|
free(result); |
431 |
|
return (status == 0) ? sResult : m_customTypeName; |
432 |
|
#endif |
433 |
} |
} |
434 |
|
|
435 |
// *************** Member *************** |
// *************** Member *************** |
600 |
bool Member::operator<(const Member& other) const { |
bool Member::operator<(const Member& other) const { |
601 |
return m_uid < other.m_uid || |
return m_uid < other.m_uid || |
602 |
(m_uid == other.m_uid && |
(m_uid == other.m_uid && |
603 |
m_offset < other.m_offset || |
(m_offset < other.m_offset || |
604 |
(m_offset == other.m_offset && |
(m_offset == other.m_offset && |
605 |
m_name < other.m_name || |
(m_name < other.m_name || |
606 |
(m_name == other.m_name && |
(m_name == other.m_name && |
607 |
m_type < other.m_type))); |
m_type < other.m_type))))); |
608 |
} |
} |
609 |
|
|
610 |
/** @brief Greater than comparison. |
/** @brief Greater than comparison. |
1090 |
m_root = NO_UID; |
m_root = NO_UID; |
1091 |
m_isModified = false; |
m_isModified = false; |
1092 |
m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME; |
m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME; |
1093 |
decode(m_rawData); |
decode(data); |
1094 |
} |
} |
1095 |
|
|
1096 |
/** @brief Create and fill the archive with the given serialized raw C-buffer data. |
/** @brief Create and fill the archive with the given serialized raw C-buffer data. |
1441 |
return (time_t) i; |
return (time_t) i; |
1442 |
} |
} |
1443 |
|
|
1444 |
DataType _popDataTypeBlob(const char*& p, const char* end) { |
static DataType _popDataTypeBlob(const char*& p, const char* end) { |
1445 |
_Blob blob = _decodeBlob(p, end); |
_Blob blob = _decodeBlob(p, end); |
1446 |
p = blob.p; |
p = blob.p; |
1447 |
end = blob.end; |
end = blob.end; |
2122 |
setBoolValue(object, false); |
setBoolValue(object, false); |
2123 |
else |
else |
2124 |
setBoolValue(object, atof(value.c_str())); |
setBoolValue(object, atof(value.c_str())); |
2125 |
} else if (type.isEnum()) |
} else if (type.isEnum()) |
2126 |
setEnumValue(object, atoll(value.c_str())); |
setEnumValue(object, atoll(value.c_str())); |
2127 |
else |
else |
2128 |
throw Exception("Not a primitive data type"); |
throw Exception("Not a primitive data type"); |
2318 |
// *************** Exception *************** |
// *************** Exception *************** |
2319 |
// * |
// * |
2320 |
|
|
2321 |
|
Exception::Exception() { |
2322 |
|
} |
2323 |
|
|
2324 |
|
Exception::Exception(String format, ...) { |
2325 |
|
va_list arg; |
2326 |
|
va_start(arg, format); |
2327 |
|
Message = assemble(format, arg); |
2328 |
|
va_end(arg); |
2329 |
|
} |
2330 |
|
|
2331 |
|
Exception::Exception(String format, va_list arg) { |
2332 |
|
Message = assemble(format, arg); |
2333 |
|
} |
2334 |
|
|
2335 |
/** @brief Print exception message to stdout. |
/** @brief Print exception message to stdout. |
2336 |
* |
* |
2337 |
* Prints the message of this Exception to the currently defined standard |
* Prints the message of this Exception to the currently defined standard |
2341 |
std::cout << "Serialization::Exception: " << Message << std::endl; |
std::cout << "Serialization::Exception: " << Message << std::endl; |
2342 |
} |
} |
2343 |
|
|
2344 |
|
String Exception::assemble(String format, va_list arg) { |
2345 |
|
char* buf = NULL; |
2346 |
|
vasprintf(&buf, format.c_str(), arg); |
2347 |
|
String s = buf; |
2348 |
|
free(buf); |
2349 |
|
return s; |
2350 |
|
} |
2351 |
|
|
2352 |
} // namespace Serialization |
} // namespace Serialization |