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", "Array", "enum", "union" or "class" |
* "String", "Array", "Set", "enum", "union" or "class" |
105 |
* @param customType - this is only used for base types "enum", "union", |
* @param customType - this is only used for base types "enum", "union", |
106 |
* "class" or "Array", in which case this identifies the |
* "class", "Array" or "Set", in which case this |
107 |
* 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 |
*/ |
*/ |
188 |
* @see isPointer() |
* @see isPointer() |
189 |
*/ |
*/ |
190 |
bool DataType::isPrimitive() const { |
bool DataType::isPrimitive() const { |
191 |
return !isClass() && !isArray(); |
return !isClass() && !isArray() && !isSet(); |
192 |
} |
} |
193 |
|
|
194 |
/** @brief Whether this is a C++ @c String data type. |
/** @brief Whether this is a C++ @c String data type. |
286 |
return m_baseTypeName == "Array"; |
return m_baseTypeName == "Array"; |
287 |
} |
} |
288 |
|
|
289 |
|
/** @brief Whether this is a C++ @c Set<> object type. |
290 |
|
* |
291 |
|
* Returns @c true if the respective native C/C++ object, member or variable |
292 |
|
* (this DataType instance is reflecting) is a C++ @c Set<> unique container |
293 |
|
* object type. |
294 |
|
* |
295 |
|
* @note: This framework handles @c Set<> types neither as primitive |
296 |
|
* types, nor as class types. So @c isPrimitive() and @c isClass() both |
297 |
|
* return @c false for sets. |
298 |
|
* |
299 |
|
* @see isPointer() |
300 |
|
*/ |
301 |
|
bool DataType::isSet() const { |
302 |
|
return m_baseTypeName == "Set"; |
303 |
|
} |
304 |
|
|
305 |
/** @brief Whether this is a signed integer C/C++ data type. |
/** @brief Whether this is a signed integer C/C++ data type. |
306 |
* |
* |
307 |
* 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 |
777 |
return (index < m_uid.size()) ? m_uid[index] : NO_UID; |
return (index < m_uid.size()) ? m_uid[index] : NO_UID; |
778 |
} |
} |
779 |
|
|
780 |
|
static void _setNativeValueFromString(void* ptr, const DataType& type, const char* s) { |
781 |
|
if (type.isPrimitive() && !type.isPointer()) { |
782 |
|
if (type.isInteger() || type.isEnum()) { |
783 |
|
if (type.isSigned()) { |
784 |
|
if (type.size() == 1) |
785 |
|
*(int8_t*)ptr = (int8_t) atoll(s); |
786 |
|
else if (type.size() == 2) |
787 |
|
*(int16_t*)ptr = (int16_t) atoll(s); |
788 |
|
else if (type.size() == 4) |
789 |
|
*(int32_t*)ptr = (int32_t) atoll(s); |
790 |
|
else if (type.size() == 8) |
791 |
|
*(int64_t*)ptr = (int64_t) atoll(s); |
792 |
|
else |
793 |
|
assert(false /* unknown signed int type size */); |
794 |
|
} else { |
795 |
|
if (type.size() == 1) |
796 |
|
*(uint8_t*)ptr = (uint8_t) atoll(s); |
797 |
|
else if (type.size() == 2) |
798 |
|
*(uint16_t*)ptr = (uint16_t) atoll(s); |
799 |
|
else if (type.size() == 4) |
800 |
|
*(uint32_t*)ptr = (uint32_t) atoll(s); |
801 |
|
else if (type.size() == 8) |
802 |
|
*(uint64_t*)ptr = (uint64_t) atoll(s); |
803 |
|
else |
804 |
|
assert(false /* unknown unsigned int type size */); |
805 |
|
} |
806 |
|
} else if (type.isReal()) { |
807 |
|
if (type.size() == sizeof(float)) |
808 |
|
*(float*)ptr = (float) atof(s); |
809 |
|
else if (type.size() == sizeof(double)) |
810 |
|
*(double*)ptr = (double) atof(s); |
811 |
|
else |
812 |
|
assert(false /* unknown floating point type */); |
813 |
|
} else if (type.isBool()) { |
814 |
|
String lower = toLowerCase(s); |
815 |
|
const bool b = lower != "0" && lower != "false" && lower != "no"; |
816 |
|
*(bool*)ptr = b; |
817 |
|
} else if (type.isString()) { |
818 |
|
*(String*)ptr = s; |
819 |
|
} else { |
820 |
|
assert(false /* no built-in cast from string support for this data type */); |
821 |
|
} |
822 |
|
} |
823 |
|
} |
824 |
|
|
825 |
|
/** @brief Cast from string to object's data type and assign value natively. |
826 |
|
* |
827 |
|
* The passed String @a s is decoded from its string representation to this |
828 |
|
* object's corresponding native data type, then that casted value is |
829 |
|
* assigned to the native memory location this Object is referring to. |
830 |
|
* |
831 |
|
* Note: This method may only be called for data types which enjoy built-in |
832 |
|
* support for casting from string to their native data type, which are |
833 |
|
* basically primitive data types (e.g. @c int, @c bool, @c double, etc.) or |
834 |
|
* @c String objects. For all other data types calling this method will |
835 |
|
* cause an assertion fault at runtime. |
836 |
|
* |
837 |
|
* @param s - textual string representation of the value to be assigned to |
838 |
|
* this object |
839 |
|
*/ |
840 |
|
void Object::setNativeValueFromString(const String& s) { |
841 |
|
const ID& id = uid().id; |
842 |
|
void* ptr = (void*)id; |
843 |
|
_setNativeValueFromString(ptr, m_type, s.c_str()); |
844 |
|
} |
845 |
|
|
846 |
/** @brief Unique identifier chain of this Object. |
/** @brief Unique identifier chain of this Object. |
847 |
* |
* |
848 |
* Returns the entire unique identifier chain of this Object. |
* Returns the entire unique identifier chain of this Object. |
1485 |
/* |
/* |
1486 |
* Srx format history: |
* Srx format history: |
1487 |
* - 1.0: Initial version. |
* - 1.0: Initial version. |
1488 |
* - 1.1: Adds "String" and "Array" data types. |
* - 1.1: Adds "String", "Array" and "Set" data types. |
1489 |
*/ |
*/ |
1490 |
#define MAGIC_START "Srx1v" |
#define MAGIC_START "Srx1v" |
1491 |
#define ENCODING_FORMAT_MINOR_VERSION 1 |
#define ENCODING_FORMAT_MINOR_VERSION 1 |
2469 |
dstObj.m_sync(const_cast<Object&>(dstObj), srcObj, this); |
dstObj.m_sync(const_cast<Object&>(dstObj), srcObj, this); |
2470 |
} |
} |
2471 |
|
|
2472 |
|
void Archive::Syncer::syncSet(const Object& dstObj, const Object& srcObj) { |
2473 |
|
assert(dstObj.type().isSet()); |
2474 |
|
assert(dstObj.type() == srcObj.type()); |
2475 |
|
dstObj.m_sync(const_cast<Object&>(dstObj), srcObj, this); |
2476 |
|
} |
2477 |
|
|
2478 |
void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) { |
void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) { |
2479 |
assert(dstObj.type().isPointer()); |
assert(dstObj.type().isPointer()); |
2480 |
assert(dstObj.type() == srcObj.type()); |
assert(dstObj.type() == srcObj.type()); |
2513 |
return; |
return; |
2514 |
} |
} |
2515 |
|
|
2516 |
|
if (dstObj.type().isSet()) { |
2517 |
|
syncSet(dstObj, srcObj); |
2518 |
|
return; |
2519 |
|
} |
2520 |
|
|
2521 |
if (dstObj.type().isPointer()) { |
if (dstObj.type().isPointer()) { |
2522 |
syncPointer(dstObj, srcObj); |
syncPointer(dstObj, srcObj); |
2523 |
return; |
return; |