101 |
* type in a coarse way, which must be either one of: |
* type in a coarse way, which must be either one of: |
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", "enum", "union" or "class" |
* "String", "Array", "enum", "union" or "class" |
105 |
* @param customType - this is only used for base types "enum", "union" or |
* @param customType - this is only used for base types "enum", "union", |
106 |
* "class", in which case this identifies the user |
* "class" or "Array", in which case this identifies the |
107 |
* defined type name (e.g. "Foo" for @c class @c Foo ), |
* user defined type name (e.g. "Foo" for |
108 |
* for all other types this is empty |
* @c class @c Foo or e.g. "Bar" for @c Array<Bar> |
109 |
|
* respectively), for all other types this is empty |
110 |
*/ |
*/ |
111 |
DataType::DataType(bool isPointer, int size, String baseType, String customType) { |
DataType::DataType(bool isPointer, int size, String baseType, String customType) { |
112 |
m_size = size; |
m_size = size; |
142 |
* |
* |
143 |
* 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 |
144 |
* (this DataType instance is reflecting) is a C/C++ @c struct or @c class |
* (this DataType instance is reflecting) is a C/C++ @c struct or @c class |
145 |
* type, with one exception: @c String objects are handled by this framework |
* type. |
146 |
* as if they were a primitive type. |
* |
147 |
|
* @note: Data types which enjoy out of the box serialization support by |
148 |
|
* this framework, like @c String and @c Array<> are @b NOT handled as class |
149 |
|
* data types by this framwork. So @c isClass() returns @c false for e.g. |
150 |
|
* @c String and any @c Array<> based data type. |
151 |
* |
* |
152 |
* Note that in the following example: |
* Note that in the following example: |
153 |
* @code |
* @code |
188 |
* @see isPointer() |
* @see isPointer() |
189 |
*/ |
*/ |
190 |
bool DataType::isPrimitive() const { |
bool DataType::isPrimitive() const { |
191 |
return !isClass(); |
return !isClass() && !isArray(); |
192 |
} |
} |
193 |
|
|
194 |
/** @brief Whether this is a C++ @c String data type. |
/** @brief Whether this is a C++ @c String data type. |
270 |
return m_baseTypeName == "enum"; |
return m_baseTypeName == "enum"; |
271 |
} |
} |
272 |
|
|
273 |
|
/** @brief Whether this is a C++ @c Array<> object type. |
274 |
|
* |
275 |
|
* Returns @c true if the respective native C/C++ object, member or variable |
276 |
|
* (this DataType instance is reflecting) is a C++ @c Array<> container |
277 |
|
* object type. |
278 |
|
* |
279 |
|
* @note: This framework handles @c Array<> types neither as primitive |
280 |
|
* types, nor as class types. So @c isPrimitive() and @c isClass() both |
281 |
|
* return @c false for arrays. |
282 |
|
* |
283 |
|
* @see isPointer() |
284 |
|
*/ |
285 |
|
bool DataType::isArray() const { |
286 |
|
return m_baseTypeName == "Array"; |
287 |
|
} |
288 |
|
|
289 |
/** @brief Whether this is a signed integer C/C++ data type. |
/** @brief Whether this is a signed integer C/C++ data type. |
290 |
* |
* |
291 |
* 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 |
432 |
|
|
433 |
/** @brief The user defined C/C++ data type name of this data type. |
/** @brief The user defined C/C++ data type name of this data type. |
434 |
* |
* |
435 |
* Call this method on user defined C/C++ data types like @c enum, @c struct |
* Call this method on user defined C/C++ data types like @c enum, |
436 |
* and @c class types to retrieve the user defined type name portion of |
* @c struct, @c class or @c Array<> types to retrieve the user defined type |
437 |
* those data types. Note that this method is only intended for such user |
* name portion of those data types. Note that this method is only intended |
438 |
* defined data types. For all fundamental, primitive data types (like i.e. |
* for such user defined data types. For all fundamental, primitive data |
439 |
* @c int) this method returns an empty string instead. |
* types (like i.e. @c int) this method returns an empty string instead. |
440 |
* |
* |
441 |
* This method takes an optional boolean argument @b demangle, which allows |
* This method takes an optional boolean argument @b demangle, which allows |
442 |
* you define whether you are interested in the raw C++ type name or rather |
* you define whether you are interested in the raw C++ type name or rather |
510 |
m_offset = 0; |
m_offset = 0; |
511 |
} |
} |
512 |
|
|
513 |
Member::Member(String name, UID uid, size_t offset, DataType type) { |
Member::Member(String name, UID uid, ssize_t offset, DataType type) { |
514 |
m_name = name; |
m_name = name; |
515 |
m_uid = uid; |
m_uid = uid; |
516 |
m_offset = offset; |
m_offset = offset; |
592 |
* @c b and @c c instead. For most 64 bit architectures this example would |
* @c b and @c c instead. For most 64 bit architectures this example would |
593 |
* now still return @c 0 for member @c a, but @c 8 for member @c b and @c 16 |
* now still return @c 0 for member @c a, but @c 8 for member @c b and @c 16 |
594 |
* for member @c c. |
* for member @c c. |
595 |
|
* |
596 |
|
* @note Offset is intended for native members only, that is member |
597 |
|
* variables which are memory located directly within the associated parent |
598 |
|
* data structure. For members allocated on the heap @c offset() always |
599 |
|
* returns @c -1 instead since there is no constant, static offset |
600 |
|
* relationship between data on the heap and the parent structure owning |
601 |
|
* their life-time control. |
602 |
*/ |
*/ |
603 |
size_t Member::offset() const { |
ssize_t Member::offset() const { |
604 |
return m_offset; |
return m_offset; |
605 |
} |
} |
606 |
|
|
1297 |
} else { |
} else { |
1298 |
assert(false /* unknown primitive type */); |
assert(false /* unknown primitive type */); |
1299 |
} |
} |
|
|
|
1300 |
} |
} |
1301 |
return s; |
return s; |
1302 |
} |
} |
1403 |
/* |
/* |
1404 |
* Srx format history: |
* Srx format history: |
1405 |
* - 1.0: Initial version. |
* - 1.0: Initial version. |
1406 |
* - 1.1: Adds "String" data type. |
* - 1.1: Adds "String" and "Array" data types. |
1407 |
*/ |
*/ |
1408 |
#define MAGIC_START "Srx1v" |
#define MAGIC_START "Srx1v" |
1409 |
#define ENCODING_FORMAT_MINOR_VERSION 1 |
#define ENCODING_FORMAT_MINOR_VERSION 1 |
1594 |
if (p >= end) return m; |
if (p >= end) return m; |
1595 |
|
|
1596 |
m.m_uid = _popUIDBlob(p, end); |
m.m_uid = _popUIDBlob(p, end); |
1597 |
m.m_offset = _popIntBlob<size_t>(p, end); |
m.m_offset = _popIntBlob<ssize_t>(p, end); |
1598 |
m.m_name = _popStringBlob(p, end); |
m.m_name = _popStringBlob(p, end); |
1599 |
m.m_type = _popDataTypeBlob(p, end); |
m.m_type = _popDataTypeBlob(p, end); |
1600 |
assert(m.type()); |
assert(m.type()); |
2381 |
*pDst = (String) (const char*) &srcObj.rawData()[0]; |
*pDst = (String) (const char*) &srcObj.rawData()[0]; |
2382 |
} |
} |
2383 |
|
|
2384 |
|
void Archive::Syncer::syncArray(const Object& dstObj, const Object& srcObj) { |
2385 |
|
assert(dstObj.type().isArray()); |
2386 |
|
assert(dstObj.type() == srcObj.type()); |
2387 |
|
dstObj.m_sync(const_cast<Object&>(dstObj), srcObj, this); |
2388 |
|
} |
2389 |
|
|
2390 |
void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) { |
void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) { |
2391 |
assert(dstObj.type().isPointer()); |
assert(dstObj.type().isPointer()); |
2392 |
assert(dstObj.type() == srcObj.type()); |
assert(dstObj.type() == srcObj.type()); |
2420 |
return; // end of recursion |
return; // end of recursion |
2421 |
} |
} |
2422 |
|
|
2423 |
|
if (dstObj.type().isArray()) { |
2424 |
|
syncArray(dstObj, srcObj); |
2425 |
|
return; |
2426 |
|
} |
2427 |
|
|
2428 |
if (dstObj.type().isPointer()) { |
if (dstObj.type().isPointer()) { |
2429 |
syncPointer(dstObj, srcObj); |
syncPointer(dstObj, srcObj); |
2430 |
return; |
return; |