/[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 3770 by schoenebeck, Sun May 17 14:05:08 2020 UTC revision 3771 by schoenebeck, Sun May 17 17:14:31 2020 UTC
# Line 71  namespace Serialization { Line 71  namespace Serialization {
71      // *************** DataType ***************      // *************** DataType ***************
72      // *      // *
73    
74      /** @brief Default constructor.      /** @brief Default constructor (as "invalid" DataType).
75       *       *
76       * Initializes a DataType object as being an "invalid" DataType object.       * Initializes a DataType object as being an "invalid" DataType object.
77       * Thus calling isValid(), after creating a DataType object with this       * Thus calling isValid(), after creating a DataType object with this
# Line 85  namespace Serialization { Line 85  namespace Serialization {
85          m_isPointer = false;          m_isPointer = false;
86      }      }
87    
88        /** @brief Constructs a valid DataType object.
89         *
90         * Initializes this object as "valid" DataType object, with specific and
91         * useful data type information.
92         *
93         * This is a protected constructor which should not be called directly by
94         * applications, as its argument list is somewhat implementation specific
95         * and might change at any time. Applications should call the static
96         * function DataType::dataTypeOf() instead.
97         *
98         * @param isPointer - whether pointer type (i.e. a simple memory address)
99         * @param size - native size of data type in bytes (i.e. according to
100         *               @c sizeof() C/C++ keyword)
101         * @param baseType - this framework's internal name for specifying the base
102         *                   type in a coarse way, which must be either one of:
103         *                   "int8", "uint8", "int16", "uint16", "int32", "uint32",
104         *                   "int64", "uint64", "bool", "real32", "real64",
105         *                   "String", "enum", "union" or "class"
106         * @param customType - this is only used for base types "enum", "union" or
107         *                     "class", in which case this identifies the user
108         *                     defined type name (e.g. "Foo" for @c class @c Foo ),
109         *                     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;
113          m_isPointer = isPointer;          m_isPointer = isPointer;
# Line 119  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.       * type, with one exception: @c String objects are handled by this framework
146         * as if they were a primitive type.
147       *       *
148       * Note that in the following example:       * Note that in the following example:
149       * @code       * @code
# Line 145  namespace Serialization { Line 169  namespace Serialization {
169       * (this DataType instance is reflecting) is a primitive, fundamental C/C++       * (this DataType instance is reflecting) is a primitive, fundamental C/C++
170       * data type. Those are fundamental data types which are already predefined       * data type. Those are fundamental data types which are already predefined
171       * by the C/C++ language, for example: @c char, @c int, @c float, @c double,       * by the C/C++ language, for example: @c char, @c int, @c float, @c double,
172       * @c bool, but also @b any pointer types like @c int*, @c double**, but       * @c bool, but also @c String objects and @b any pointer types like
173       * including pointers to user defined types like:       * @c int*, @c double**, but including pointers to user defined types like:
174       * @code       * @code
175       * struct Foo {       * struct Foo {
176       *     int  a;       *     int  a;
# Line 163  namespace Serialization { Line 187  namespace Serialization {
187          return !isClass();          return !isClass();
188      }      }
189    
190        /** @brief Whether this is a C++ @c String data type.
191         *
192         * Returns @c true if the respective native C/C++ object, member or variable
193         * (this DataType instance is reflecting) is a C++ @c String object (a.k.a.
194         * @c std::string from the C++ STL).
195         *
196         * Note that this framework handles @c String objects as if they were a
197         * fundamental, primitive C/C++ data type, so @c isPrimitive() returns
198         * @c true for strings.
199         */
200        bool DataType::isString() const {
201            return m_baseTypeName == "String";
202        }
203    
204      /** @brief Whether this is an integer C/C++ data type.      /** @brief Whether this is an integer C/C++ data type.
205       *       *
206       * 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 746  namespace Serialization { Line 784  namespace Serialization {
784       * In case this Object is reflecting a native C/C++ @c struct or @c class       * In case this Object is reflecting a native C/C++ @c struct or @c class
785       * type, then this method returns the version of that native C/C++ @c struct       * type, then this method returns the version of that native C/C++ @c struct
786       * or @c class layout or implementation. For primitive, fundamental C/C++       * or @c class layout or implementation. For primitive, fundamental C/C++
787       * data types the return value of this method has no meaning.       * data types (including @c String objects) the return value of this method
788         * has no meaning.
789       *       *
790       * @see Archive::setVersion() for more details about this overall topic.       * @see Archive::setVersion() for more details about this overall topic.
791       */       */
# Line 759  namespace Serialization { Line 798  namespace Serialization {
798       * In case this Object is reflecting a native C/C++ @c struct or @c class       * In case this Object is reflecting a native C/C++ @c struct or @c class
799       * type, then this method returns the "minimum" version of that native C/C++       * type, then this method returns the "minimum" version of that native C/C++
800       * @c struct or @c class layout or implementation which it may be compatible       * @c struct or @c class layout or implementation which it may be compatible
801       * with. For primitive, fundamental C/C++ data types the return value of       * with. For primitive, fundamental C/C++ data types (including @c String
802       * this method has no meaning.       * objects) the return value of this method has no meaning.
803       *       *
804       * @see Archive::setVersion() and Archive::setMinVersion() for more details       * @see Archive::setVersion() and Archive::setMinVersion() for more details
805       *      about this overall topic.       *      about this overall topic.
# Line 1226  namespace Serialization { Line 1265  namespace Serialization {
1265                      assert(false /* unknown floating point type */);                      assert(false /* unknown floating point type */);
1266              } else if (type.isBool()) {              } else if (type.isBool()) {
1267                  s = ToString(*(bool*)ptr);                  s = ToString(*(bool*)ptr);
1268                } else if (type.isString()) {
1269                    s = obj.m_data.empty() ? *(String*)ptr : String((const char*)ptr);
1270              } else {              } else {
1271                  assert(false /* unknown primitive type */);                  assert(false /* unknown primitive type */);
1272              }              }
# Line 1235  namespace Serialization { Line 1276  namespace Serialization {
1276      }      }
1277    
1278      template<typename T>      template<typename T>
1279        inline T _stringToNumber(const String& s) {
1280            assert(false /* String cast to unknown primitive number type */);
1281        }
1282    
1283        template<>
1284        inline int64_t _stringToNumber(const String& s) {
1285            return atoll(s.c_str());
1286        }
1287    
1288        template<>
1289        inline double _stringToNumber(const String& s) {
1290            return atof(s.c_str());
1291        }
1292    
1293        template<>
1294        inline bool _stringToNumber(const String& s) {
1295            return (bool) atoll(s.c_str());
1296        }
1297    
1298        template<typename T>
1299      static T _primitiveObjectValueToNumber(const Object& obj) {      static T _primitiveObjectValueToNumber(const Object& obj) {
1300          T value = 0;          T value = 0;
1301          const DataType& type = obj.type();          const DataType& type = obj.type();
# Line 1276  namespace Serialization { Line 1337  namespace Serialization {
1337                      assert(false /* unknown floating point type */);                      assert(false /* unknown floating point type */);
1338              } else if (type.isBool()) {              } else if (type.isBool()) {
1339                  value = (T)*(bool*)ptr;                  value = (T)*(bool*)ptr;
1340                } else if (type.isString()) {
1341                    value = _stringToNumber<T>(
1342                        obj.m_data.empty() ? *(String*)ptr : String((const char*)ptr)
1343                    );
1344              } else {              } else {
1345                  assert(false /* unknown primitive type */);                  assert(false /* unknown primitive type */);
1346              }              }
# Line 1309  namespace Serialization { Line 1374  namespace Serialization {
1374          return _encodeBlob(s);          return _encodeBlob(s);
1375      }      }
1376    
1377        /*
1378         * Srx format history:
1379         * - 1.0: Initial version.
1380         * - 1.1: Adds "String" data type.
1381         */
1382      #define MAGIC_START "Srx1v"      #define MAGIC_START "Srx1v"
1383      #define ENCODING_FORMAT_MINOR_VERSION 0      #define ENCODING_FORMAT_MINOR_VERSION 1
1384    
1385      String Archive::_encodeRootBlob() {      String Archive::_encodeRootBlob() {
1386          String s;          String s;
# Line 1436  namespace Serialization { Line 1506  namespace Serialization {
1506          return s;          return s;
1507      }      }
1508    
1509        static void _popStringBlob(const char*& p, const char* end, RawData& rawData) {
1510            String s = _popStringBlob(p, end);
1511            rawData.resize(s.length() + 1);
1512            strcpy((char*)&rawData[0], &s[0]);
1513        }
1514    
1515      static time_t _popTimeBlob(const char*& p, const char* end) {      static time_t _popTimeBlob(const char*& p, const char* end) {
1516          const uint64_t i = _popIntBlob<uint64_t>(p, end);          const uint64_t i = _popIntBlob<uint64_t>(p, end);
1517          return (time_t) i;          return (time_t) i;
# Line 1554  namespace Serialization { Line 1630  namespace Serialization {
1630                      assert(false /* unknown floating point type */);                      assert(false /* unknown floating point type */);
1631              } else if (type.isBool()) {              } else if (type.isBool()) {
1632                  _popIntBlob<uint8_t>(p, end, obj.m_data);                  _popIntBlob<uint8_t>(p, end, obj.m_data);
1633                } else if (type.isString()) {
1634                    _popStringBlob(p, end, obj.m_data);
1635              } else {              } else {
1636                  assert(false /* unknown primitive type */);                  assert(false /* unknown primitive type */);
1637              }              }
# Line 2094  namespace Serialization { Line 2172  namespace Serialization {
2172          m_isModified = true;          m_isModified = true;
2173      }      }
2174    
2175        /** @brief Set new textual string for given String object.
2176         *
2177         * Sets the new textual string @a value to the given String @a object.
2178         *
2179         * @param object - the String object to be changed
2180         * @param value - the new textual string to be assigned to the @a object
2181         * @throws Exception if @a object is not a String type.
2182         */
2183        void Archive::setStringValue(Object& object, String value) {
2184            if (!object) return;
2185            if (!object.type().isString())
2186                throw Exception("Not a String data type");
2187            Object* pObject = &object;
2188            if (object.type().isPointer()) {
2189                Object& obj = objectByUID(object.uid(1));
2190                if (!obj) return;
2191                pObject = &obj;
2192            }
2193            pObject->m_data.resize(value.length() + 1);
2194            char* ptr = (char*) &pObject->m_data[0];
2195            strcpy(ptr, &value[0]);
2196            m_isModified = true;
2197        }
2198    
2199      /** @brief Automatically cast and assign appropriate value to object.      /** @brief Automatically cast and assign appropriate value to object.
2200       *       *
2201       * This method automatically converts the given @a value from textual string       * This method automatically converts the given @a value from textual string
# Line 2122  namespace Serialization { Line 2224  namespace Serialization {
2224                  setBoolValue(object, false);                  setBoolValue(object, false);
2225              else              else
2226                  setBoolValue(object, atof(value.c_str()));                  setBoolValue(object, atof(value.c_str()));
2227          } else if (type.isEnum())          } else if (type.isString())
2228                setStringValue(object, value);
2229            else if (type.isEnum())
2230              setEnumValue(object, atoll(value.c_str()));              setEnumValue(object, atoll(value.c_str()));
2231          else          else
2232              throw Exception("Not a primitive data type");              throw Exception("Not a primitive data type");
# Line 2240  namespace Serialization { Line 2344  namespace Serialization {
2344          memcpy(pDst, &srcObj.rawData()[0], dstObj.type().size());          memcpy(pDst, &srcObj.rawData()[0], dstObj.type().size());
2345      }      }
2346    
2347        void Archive::Syncer::syncString(const Object& dstObj, const Object& srcObj) {
2348            assert(dstObj.type().isString());
2349            assert(dstObj.type() == srcObj.type());
2350            String* pDst = (String*)(void*)dstObj.uid().id;
2351            *pDst = (String) (const char*) &srcObj.rawData()[0];
2352        }
2353    
2354      void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) {      void Archive::Syncer::syncPointer(const Object& dstObj, const Object& srcObj) {
2355          assert(dstObj.type().isPointer());          assert(dstObj.type().isPointer());
2356          assert(dstObj.type() == srcObj.type());          assert(dstObj.type() == srcObj.type());
# Line 2266  namespace Serialization { Line 2377  namespace Serialization {
2377          m_dst.m_allObjects.erase(dstObj.uid());          m_dst.m_allObjects.erase(dstObj.uid());
2378    
2379          if (dstObj.type().isPrimitive() && !dstObj.type().isPointer()) {          if (dstObj.type().isPrimitive() && !dstObj.type().isPointer()) {
2380              syncPrimitive(dstObj, srcObj);              if (dstObj.type().isString())
2381                    syncString(dstObj, srcObj);
2382                else
2383                    syncPrimitive(dstObj, srcObj);
2384              return; // end of recursion              return; // end of recursion
2385          }          }
2386    

Legend:
Removed from v.3770  
changed lines
  Added in v.3771

  ViewVC Help
Powered by ViewVC