--- libgig/trunk/src/Serialization.cpp 2020/05/19 15:23:11 3775 +++ libgig/trunk/src/Serialization.cpp 2020/05/23 19:26:07 3776 @@ -101,10 +101,10 @@ * type in a coarse way, which must be either one of: * "int8", "uint8", "int16", "uint16", "int32", "uint32", * "int64", "uint64", "bool", "real32", "real64", - * "String", "Array", "enum", "union" or "class" + * "String", "Array", "Set", "enum", "union" or "class" * @param customType - this is only used for base types "enum", "union", - * "class" or "Array", in which case this identifies the - * user defined type name (e.g. "Foo" for + * "class", "Array" or "Set", in which case this + * identifies the user defined type name (e.g. "Foo" for * @c class @c Foo or e.g. "Bar" for @c Array * respectively), for all other types this is empty */ @@ -188,7 +188,7 @@ * @see isPointer() */ bool DataType::isPrimitive() const { - return !isClass() && !isArray(); + return !isClass() && !isArray() && !isSet(); } /** @brief Whether this is a C++ @c String data type. @@ -286,6 +286,22 @@ return m_baseTypeName == "Array"; } + /** @brief Whether this is a C++ @c Set<> object type. + * + * Returns @c true if the respective native C/C++ object, member or variable + * (this DataType instance is reflecting) is a C++ @c Set<> unique container + * object type. + * + * @note: This framework handles @c Set<> types neither as primitive + * types, nor as class types. So @c isPrimitive() and @c isClass() both + * return @c false for sets. + * + * @see isPointer() + */ + bool DataType::isSet() const { + return m_baseTypeName == "Set"; + } + /** @brief Whether this is a signed integer C/C++ data type. * * Returns @c true if the respective native C/C++ object, member or variable @@ -761,6 +777,72 @@ return (index < m_uid.size()) ? m_uid[index] : NO_UID; } + static void _setNativeValueFromString(void* ptr, const DataType& type, const char* s) { + if (type.isPrimitive() && !type.isPointer()) { + if (type.isInteger() || type.isEnum()) { + if (type.isSigned()) { + if (type.size() == 1) + *(int8_t*)ptr = (int8_t) atoll(s); + else if (type.size() == 2) + *(int16_t*)ptr = (int16_t) atoll(s); + else if (type.size() == 4) + *(int32_t*)ptr = (int32_t) atoll(s); + else if (type.size() == 8) + *(int64_t*)ptr = (int64_t) atoll(s); + else + assert(false /* unknown signed int type size */); + } else { + if (type.size() == 1) + *(uint8_t*)ptr = (uint8_t) atoll(s); + else if (type.size() == 2) + *(uint16_t*)ptr = (uint16_t) atoll(s); + else if (type.size() == 4) + *(uint32_t*)ptr = (uint32_t) atoll(s); + else if (type.size() == 8) + *(uint64_t*)ptr = (uint64_t) atoll(s); + else + assert(false /* unknown unsigned int type size */); + } + } else if (type.isReal()) { + if (type.size() == sizeof(float)) + *(float*)ptr = (float) atof(s); + else if (type.size() == sizeof(double)) + *(double*)ptr = (double) atof(s); + else + assert(false /* unknown floating point type */); + } else if (type.isBool()) { + String lower = toLowerCase(s); + const bool b = lower != "0" && lower != "false" && lower != "no"; + *(bool*)ptr = b; + } else if (type.isString()) { + *(String*)ptr = s; + } else { + assert(false /* no built-in cast from string support for this data type */); + } + } + } + + /** @brief Cast from string to object's data type and assign value natively. + * + * The passed String @a s is decoded from its string representation to this + * object's corresponding native data type, then that casted value is + * assigned to the native memory location this Object is referring to. + * + * Note: This method may only be called for data types which enjoy built-in + * support for casting from string to their native data type, which are + * basically primitive data types (e.g. @c int, @c bool, @c double, etc.) or + * @c String objects. For all other data types calling this method will + * cause an assertion fault at runtime. + * + * @param s - textual string representation of the value to be assigned to + * this object + */ + void Object::setNativeValueFromString(const String& s) { + const ID& id = uid().id; + void* ptr = (void*)id; + _setNativeValueFromString(ptr, m_type, s.c_str()); + } + /** @brief Unique identifier chain of this Object. * * Returns the entire unique identifier chain of this Object. @@ -1403,7 +1485,7 @@ /* * Srx format history: * - 1.0: Initial version. - * - 1.1: Adds "String" and "Array" data types. + * - 1.1: Adds "String", "Array" and "Set" data types. */ #define MAGIC_START "Srx1v" #define ENCODING_FORMAT_MINOR_VERSION 1 @@ -2387,6 +2469,12 @@ dstObj.m_sync(const_cast(dstObj), srcObj, this); } + void Archive::Syncer::syncSet(const Object& dstObj, const Object& srcObj) { + assert(dstObj.type().isSet()); + assert(dstObj.type() == srcObj.type()); + dstObj.m_sync(const_cast(dstObj), srcObj, this); + } + void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) { assert(dstObj.type().isPointer()); assert(dstObj.type() == srcObj.type()); @@ -2425,6 +2513,11 @@ return; } + if (dstObj.type().isSet()) { + syncSet(dstObj, srcObj); + return; + } + if (dstObj.type().isPointer()) { syncPointer(dstObj, srcObj); return;