102 |
* "int8", "uint8", "int16", "uint16", "int32", "uint32", |
* "int8", "uint8", "int16", "uint16", "int32", "uint32", |
103 |
* "int64", "uint64", "bool", "real32", "real64", |
* "int64", "uint64", "bool", "real32", "real64", |
104 |
* "String", "Array", "Set", "enum", "union" or "class" |
* "String", "Array", "Set", "enum", "union" or "class" |
105 |
* @param customType - this is only used for base types "enum", "union", |
* @param customType1 - this is only used for base types "enum", "union", |
106 |
* "class", "Array" or "Set", in which case this |
* "class", "Array", "Set" or "Map", in which case this |
107 |
* identifies the user defined type name (e.g. "Foo" for |
* identifies the user defined type name (e.g. "Foo" for |
108 |
* @c class @c Foo or e.g. "Bar" for @c Array<Bar> |
* @c class @c Foo or e.g. "Bar" for @c Array<Bar> |
109 |
* respectively), for all other types this is empty |
* respectively), for all other types this is empty |
110 |
|
* @param customType2 - this is only used for @c Map<> objects in which case |
111 |
|
* it identifies the map's value type (i.e. 2nd |
112 |
|
* template parameter of map) |
113 |
*/ |
*/ |
114 |
DataType::DataType(bool isPointer, int size, String baseType, String customType) { |
DataType::DataType(bool isPointer, int size, String baseType, |
115 |
|
String customType1, String customType2) |
116 |
|
{ |
117 |
m_size = size; |
m_size = size; |
118 |
m_isPointer = isPointer; |
m_isPointer = isPointer; |
119 |
m_baseTypeName = baseType; |
m_baseTypeName = baseType; |
120 |
m_customTypeName = customType; |
m_customTypeName = customType1; |
121 |
|
m_customTypeName2 = customType2; |
122 |
} |
} |
123 |
|
|
124 |
/** @brief Check if this is a valid DataType object. |
/** @brief Check if this is a valid DataType object. |
194 |
* @see isPointer() |
* @see isPointer() |
195 |
*/ |
*/ |
196 |
bool DataType::isPrimitive() const { |
bool DataType::isPrimitive() const { |
197 |
return !isClass() && !isArray() && !isSet(); |
return !isClass() && !isArray() && !isSet() && !isMap(); |
198 |
} |
} |
199 |
|
|
200 |
/** @brief Whether this is a C++ @c String data type. |
/** @brief Whether this is a C++ @c String data type. |
308 |
return m_baseTypeName == "Set"; |
return m_baseTypeName == "Set"; |
309 |
} |
} |
310 |
|
|
311 |
|
/** @brief Whether this is a C++ @c Map<> object type. |
312 |
|
* |
313 |
|
* Returns @c true if the respective native C/C++ object, member or variable |
314 |
|
* (this DataType instance is reflecting) is an associative sorted C++ |
315 |
|
* @c Map<> container object type. |
316 |
|
* |
317 |
|
* @note: This framework handles @c Map<> types neither as primitive |
318 |
|
* types, nor as class types. So @c isPrimitive() and @c isClass() both |
319 |
|
* return @c false for maps. |
320 |
|
* |
321 |
|
* @see isPointer() |
322 |
|
*/ |
323 |
|
bool DataType::isMap() const { |
324 |
|
return m_baseTypeName == "Map"; |
325 |
|
} |
326 |
|
|
327 |
/** @brief Whether this is a signed integer C/C++ data type. |
/** @brief Whether this is a signed integer C/C++ data type. |
328 |
* |
* |
329 |
* Returns @c true if the respective native C/C++ object, member or variable |
* Returns @c true if the respective native C/C++ object, member or variable |
363 |
bool DataType::operator==(const DataType& other) const { |
bool DataType::operator==(const DataType& other) const { |
364 |
return m_baseTypeName == other.m_baseTypeName && |
return m_baseTypeName == other.m_baseTypeName && |
365 |
m_customTypeName == other.m_customTypeName && |
m_customTypeName == other.m_customTypeName && |
366 |
|
m_customTypeName2 == other.m_customTypeName2 && |
367 |
(m_size == other.m_size || (isClass() && other.isClass())) && |
(m_size == other.m_size || (isClass() && other.isClass())) && |
368 |
m_isPointer == other.m_isPointer; |
m_isPointer == other.m_isPointer; |
369 |
} |
} |
393 |
(m_baseTypeName == other.m_baseTypeName && |
(m_baseTypeName == other.m_baseTypeName && |
394 |
(m_customTypeName < other.m_customTypeName || |
(m_customTypeName < other.m_customTypeName || |
395 |
(m_customTypeName == other.m_customTypeName && |
(m_customTypeName == other.m_customTypeName && |
396 |
|
(m_customTypeName2 < other.m_customTypeName2 || |
397 |
|
(m_customTypeName2 == other.m_customTypeName2 && |
398 |
(m_size < other.m_size || |
(m_size < other.m_size || |
399 |
(m_size == other.m_size && |
(m_size == other.m_size && |
400 |
m_isPointer < other.m_isPointer))))); |
m_isPointer < other.m_isPointer))))))); |
401 |
} |
} |
402 |
|
|
403 |
/** @brief Greater than comparison. |
/** @brief Greater than comparison. |
433 |
String s = m_baseTypeName; |
String s = m_baseTypeName; |
434 |
if (!m_customTypeName.empty()) |
if (!m_customTypeName.empty()) |
435 |
s += " " + customTypeName(true); |
s += " " + customTypeName(true); |
436 |
|
if (!m_customTypeName2.empty()) |
437 |
|
s += " " + customTypeName2(true); |
438 |
if (isPointer()) |
if (isPointer()) |
439 |
s += " pointer"; |
s += " pointer"; |
440 |
return s; |
return s; |
467 |
* @endcode |
* @endcode |
468 |
* this method would return for both @c i and @c pi the string @c "uint64" ! |
* this method would return for both @c i and @c pi the string @c "uint64" ! |
469 |
* |
* |
470 |
* @see isPointer(), customTypeName() |
* @see isPointer(), customTypeName(), customTypeName2() |
471 |
*/ |
*/ |
472 |
String DataType::baseTypeName() const { |
String DataType::baseTypeName() const { |
473 |
return m_baseTypeName; |
return m_baseTypeName; |
474 |
} |
} |
475 |
|
|
476 |
/** @brief The user defined C/C++ data type name of this data type. |
static String _demangleTypeName(const char* name) { |
477 |
|
#ifdef _MSC_VER |
478 |
|
const size_t MAXLENGTH = 1024; |
479 |
|
char result[MAXLENGTH]; |
480 |
|
|
481 |
|
//FIXME: calling UnDecorateSymbolName() is not thread safe! |
482 |
|
//Skip the first char |
483 |
|
size_t size = UnDecorateSymbolName(name + 1, result, MAXLENGTH, UNDNAME_32_BIT_DECODE | UNDNAME_NO_ARGUMENTS); |
484 |
|
if (size) |
485 |
|
{ |
486 |
|
return result; |
487 |
|
} |
488 |
|
return name; |
489 |
|
#else |
490 |
|
int status; |
491 |
|
char* result = |
492 |
|
abi::__cxa_demangle(name, 0, 0, &status); |
493 |
|
String sResult = result; |
494 |
|
free(result); |
495 |
|
return (status == 0) ? sResult : name; |
496 |
|
#endif |
497 |
|
} |
498 |
|
|
499 |
|
/** @brief The 1st user defined C/C++ data type name of this data type. |
500 |
* |
* |
501 |
* Call this method on user defined C/C++ data types like @c enum, |
* Call this method on user defined C/C++ data types like @c enum, |
502 |
* @c struct, @c class or @c Array<> types to retrieve the user defined type |
* @c struct, @c class or @c Array<> types to retrieve the user defined type |
530 |
* @b Windows: please note that the current implementation of this method |
* @b Windows: please note that the current implementation of this method |
531 |
* on Windows is @b not thread safe! |
* on Windows is @b not thread safe! |
532 |
* |
* |
533 |
* @see isPointer(), baseTypeName() |
* @see baseTypeName(), customTypeName2(), isPointer() |
534 |
*/ |
*/ |
535 |
String DataType::customTypeName(bool demangle) const { |
String DataType::customTypeName(bool demangle) const { |
536 |
if (!demangle) return m_customTypeName; |
if (!demangle) return m_customTypeName; |
537 |
#ifdef _MSC_VER |
return _demangleTypeName(m_customTypeName.c_str()); |
538 |
const size_t MAXLENGTH = 1024; |
} |
|
char result[MAXLENGTH]; |
|
539 |
|
|
540 |
//FIXME: calling UnDecorateSymbolName() is not thread safe! |
/** @brief The 2nd user defined C/C++ data type name of this data type. |
541 |
//Skip the first char |
* |
542 |
size_t size = UnDecorateSymbolName(m_customTypeName.c_str() +1, result, MAXLENGTH, UNDNAME_32_BIT_DECODE | UNDNAME_NO_ARGUMENTS); |
* This is currently only used for @c Map<> data types in which case this |
543 |
if (size) |
* method returns the map's value type (i.e. map's 2nd template parameter). |
544 |
{ |
* |
545 |
return result; |
* @see baseTypeName(), customTypeName() |
546 |
} |
*/ |
547 |
return m_customTypeName; |
String DataType::customTypeName2(bool demangle) const { |
548 |
#else |
if (!demangle) return m_customTypeName2; |
549 |
int status; |
return _demangleTypeName(m_customTypeName2.c_str()); |
|
char* result = |
|
|
abi::__cxa_demangle(m_customTypeName.c_str(), 0, 0, &status); |
|
|
String sResult = result; |
|
|
free(result); |
|
|
return (status == 0) ? sResult : m_customTypeName; |
|
|
#endif |
|
550 |
} |
} |
551 |
|
|
552 |
// *************** Member *************** |
// *************** Member *************** |
1348 |
String s; |
String s; |
1349 |
s += _encodeBlob(type.baseTypeName()); |
s += _encodeBlob(type.baseTypeName()); |
1350 |
s += _encodeBlob(type.customTypeName()); |
s += _encodeBlob(type.customTypeName()); |
1351 |
|
if (!type.customTypeName2().empty()) |
1352 |
|
s += _encodeBlob(type.customTypeName2()); |
1353 |
s += _encodeBlob(ToString(type.size())); |
s += _encodeBlob(ToString(type.size())); |
1354 |
s += _encodeBlob(ToString(type.isPointer())); |
s += _encodeBlob(ToString(type.isPointer())); |
1355 |
return _encodeBlob(s); |
return _encodeBlob(s); |
1530 |
/* |
/* |
1531 |
* Srx format history: |
* Srx format history: |
1532 |
* - 1.0: Initial version. |
* - 1.0: Initial version. |
1533 |
* - 1.1: Adds "String", "Array" and "Set" data types. |
* - 1.1: Adds "String", "Array", "Set" and "Map" data types and an optional |
1534 |
|
* 2nd custom type name (e.g. "Map" types which always contain two |
1535 |
|
* user defined types). |
1536 |
*/ |
*/ |
1537 |
#define MAGIC_START "Srx1v" |
#define MAGIC_START "Srx1v" |
1538 |
#define ENCODING_FORMAT_MINOR_VERSION 1 |
#define ENCODING_FORMAT_MINOR_VERSION 1 |
1680 |
DataType type; |
DataType type; |
1681 |
type.m_baseTypeName = _popStringBlob(p, end); |
type.m_baseTypeName = _popStringBlob(p, end); |
1682 |
type.m_customTypeName = _popStringBlob(p, end); |
type.m_customTypeName = _popStringBlob(p, end); |
1683 |
|
if (type.isMap()) |
1684 |
|
type.m_customTypeName2 = _popStringBlob(p, end); |
1685 |
type.m_size = _popIntBlob<int>(p, end); |
type.m_size = _popIntBlob<int>(p, end); |
1686 |
type.m_isPointer = _popIntBlob<bool>(p, end); |
type.m_isPointer = _popIntBlob<bool>(p, end); |
1687 |
return type; |
return type; |
2524 |
dstObj.m_sync(const_cast<Object&>(dstObj), srcObj, this); |
dstObj.m_sync(const_cast<Object&>(dstObj), srcObj, this); |
2525 |
} |
} |
2526 |
|
|
2527 |
|
void Archive::Syncer::syncMap(const Object& dstObj, const Object& srcObj) { |
2528 |
|
assert(dstObj.type().isMap()); |
2529 |
|
assert(dstObj.type() == srcObj.type()); |
2530 |
|
dstObj.m_sync(const_cast<Object&>(dstObj), srcObj, this); |
2531 |
|
} |
2532 |
|
|
2533 |
void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) { |
void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) { |
2534 |
assert(dstObj.type().isPointer()); |
assert(dstObj.type().isPointer()); |
2535 |
assert(dstObj.type() == srcObj.type()); |
assert(dstObj.type() == srcObj.type()); |
2573 |
return; |
return; |
2574 |
} |
} |
2575 |
|
|
2576 |
|
if (dstObj.type().isMap()) { |
2577 |
|
syncMap(dstObj, srcObj); |
2578 |
|
return; |
2579 |
|
} |
2580 |
|
|
2581 |
if (dstObj.type().isPointer()) { |
if (dstObj.type().isPointer()) { |
2582 |
syncPointer(dstObj, srcObj); |
syncPointer(dstObj, srcObj); |
2583 |
return; |
return; |