/[svn]/libgig/trunk/src/Serialization.cpp
ViewVC logotype

Diff of /libgig/trunk/src/Serialization.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3773 by schoenebeck, Tue May 19 14:28:20 2020 UTC revision 3776 by schoenebeck, Sat May 23 19:26:07 2020 UTC
# Line 101  namespace Serialization { Line 101  namespace Serialization {
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", "Set", "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", "Array" or "Set", in which case this
107       *                     defined type name (e.g. "Foo" for @c class @c Foo ),       *                     identifies the 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;
# Line 141  namespace Serialization { Line 142  namespace Serialization {
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
# Line 183  namespace Serialization { Line 188  namespace Serialization {
188       * @see isPointer()       * @see isPointer()
189       */       */
190      bool DataType::isPrimitive() const {      bool DataType::isPrimitive() const {
191          return !isClass();          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.
# Line 265  namespace Serialization { Line 270  namespace Serialization {
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 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
# Line 411  namespace Serialization { Line 448  namespace Serialization {
448    
449      /** @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.
450       *       *
451       * 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,
452       * 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
453       * 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
454       * defined data types. For all fundamental, primitive data types (like i.e.       * for such user defined data types. For all fundamental, primitive data
455       * @c int) this method returns an empty string instead.       * types (like i.e. @c int) this method returns an empty string instead.
456       *       *
457       * This method takes an optional boolean argument @b demangle, which allows       * This method takes an optional boolean argument @b demangle, which allows
458       * 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
# Line 489  namespace Serialization { Line 526  namespace Serialization {
526          m_offset = 0;          m_offset = 0;
527      }      }
528    
529      Member::Member(String name, UID uid, size_t offset, DataType type) {      Member::Member(String name, UID uid, ssize_t offset, DataType type) {
530          m_name = name;          m_name = name;
531          m_uid  = uid;          m_uid  = uid;
532          m_offset = offset;          m_offset = offset;
# Line 571  namespace Serialization { Line 608  namespace Serialization {
608       * @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
609       * 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
610       * for member @c c.       * for member @c c.
611         *
612         * @note Offset is intended for native members only, that is member
613         * variables which are memory located directly within the associated parent
614         * data structure. For members allocated on the heap @c offset() always
615         * returns @c -1 instead since there is no constant, static offset
616         * relationship between data on the heap and the parent structure owning
617         * their life-time control.
618       */       */
619      size_t Member::offset() const {      ssize_t Member::offset() const {
620          return m_offset;          return m_offset;
621      }      }
622    
# Line 733  namespace Serialization { Line 777  namespace Serialization {
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.
# Line 1269  namespace Serialization { Line 1379  namespace Serialization {
1379              } else {              } else {
1380                  assert(false /* unknown primitive type */);                  assert(false /* unknown primitive type */);
1381              }              }
   
1382          }          }
1383          return s;          return s;
1384      }      }
# Line 1376  namespace Serialization { Line 1485  namespace Serialization {
1485      /*      /*
1486       * Srx format history:       * Srx format history:
1487       * - 1.0: Initial version.       * - 1.0: Initial version.
1488       * - 1.1: Adds "String" data type.       * - 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
# Line 1567  namespace Serialization { Line 1676  namespace Serialization {
1676          if (p >= end) return m;          if (p >= end) return m;
1677    
1678          m.m_uid    = _popUIDBlob(p, end);          m.m_uid    = _popUIDBlob(p, end);
1679          m.m_offset = _popIntBlob<size_t>(p, end);          m.m_offset = _popIntBlob<ssize_t>(p, end);
1680          m.m_name   = _popStringBlob(p, end);          m.m_name   = _popStringBlob(p, end);
1681          m.m_type   = _popDataTypeBlob(p, end);          m.m_type   = _popDataTypeBlob(p, end);
1682          assert(m.type());          assert(m.type());
# Line 2322  namespace Serialization { Line 2431  namespace Serialization {
2431          return _primitiveObjectValueToNumber<bool>(*pObject);          return _primitiveObjectValueToNumber<bool>(*pObject);
2432      }      }
2433    
2434        Archive::operation_t Archive::operation() const {
2435            return m_operation;
2436        }
2437    
2438      // *************** Archive::Syncer ***************      // *************** Archive::Syncer ***************
2439      // *      // *
2440    
# Line 2350  namespace Serialization { Line 2463  namespace Serialization {
2463          *pDst = (String) (const char*) &srcObj.rawData()[0];          *pDst = (String) (const char*) &srcObj.rawData()[0];
2464      }      }
2465    
2466        void Archive::Syncer::syncArray(const Object& dstObj, const Object& srcObj) {
2467            assert(dstObj.type().isArray());
2468            assert(dstObj.type() == srcObj.type());
2469            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());
# Line 2383  namespace Serialization { Line 2508  namespace Serialization {
2508              return; // end of recursion              return; // end of recursion
2509          }          }
2510    
2511            if (dstObj.type().isArray()) {
2512                syncArray(dstObj, srcObj);
2513                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;

Legend:
Removed from v.3773  
changed lines
  Added in v.3776

  ViewVC Help
Powered by ViewVC