/[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 3159 by schoenebeck, Mon May 8 21:15:16 2017 UTC revision 3173 by schoenebeck, Wed May 10 23:07:28 2017 UTC
# Line 27  Line 27 
27  #include <assert.h>  #include <assert.h>
28  #include <string.h> // for memcpy()  #include <string.h> // for memcpy()
29  #include <stdlib.h> // for atof()  #include <stdlib.h> // for atof()
30    #include <cxxabi.h>
31    
32  #include "helper.h"  #include "helper.h"
33    
# Line 38  namespace Serialization { Line 39  namespace Serialization {
39      // *      // *
40    
41      static UID _createNullUID() {      static UID _createNullUID() {
42          return (UID) { NULL, 0 };          const UID uid = { NULL, 0 };
43            return uid;
44      }      }
45    
46      const UID NO_UID = _createNullUID();      const UID NO_UID = _createNullUID();
# Line 126  namespace Serialization { Line 128  namespace Serialization {
128      }      }
129    
130      String DataType::asLongDescr() const {      String DataType::asLongDescr() const {
         //TODO: Demangling of C++ raw type names  
131          String s = m_baseTypeName;          String s = m_baseTypeName;
132          if (!m_customTypeName.empty())          if (!m_customTypeName.empty())
133              s += " " + m_customTypeName;              s += " " + customTypeName(true);
134          if (isPointer())          if (isPointer())
135              s += " pointer";              s += " pointer";
136          return s;          return s;
137      }      }
138    
139        String DataType::customTypeName(bool demangle) const {
140            if (!demangle) return m_customTypeName;
141            int status;
142            const char* result =
143                abi::__cxa_demangle(m_customTypeName.c_str(), 0, 0, &status);
144            return (status == 0) ? result : m_customTypeName;
145        }
146    
147      // *************** Member ***************      // *************** Member ***************
148      // *      // *
149    
# Line 401  namespace Serialization { Line 410  namespace Serialization {
410          return s;          return s;
411      }      }
412    
413        template<typename T>
414        static T _primitiveObjectValueToNumber(const Object& obj) {
415            T value = 0;
416            const DataType& type = obj.type();
417            const ID& id = obj.uid().id;
418            void* ptr = obj.m_data.empty() ? (void*)id : (void*)&obj.m_data[0];
419            if (!obj.m_data.empty())
420                assert(type.size() == obj.m_data.size());
421            if (type.isPrimitive() && !type.isPointer()) {
422                if (type.isInteger() || type.isEnum()) {
423                    if (type.isSigned()) {
424                        if (type.size() == 1)
425                            value = (T)*(int8_t*)ptr;
426                        else if (type.size() == 2)
427                            value = (T)*(int16_t*)ptr;
428                        else if (type.size() == 4)
429                            value = (T)*(int32_t*)ptr;
430                        else if (type.size() == 8)
431                            value = (T)*(int64_t*)ptr;
432                        else
433                            assert(false /* unknown signed int type size */);
434                    } else {
435                        if (type.size() == 1)
436                            value = (T)*(uint8_t*)ptr;
437                        else if (type.size() == 2)
438                            value = (T)*(uint16_t*)ptr;
439                        else if (type.size() == 4)
440                            value = (T)*(uint32_t*)ptr;
441                        else if (type.size() == 8)
442                            value = (T)*(uint64_t*)ptr;
443                        else
444                            assert(false /* unknown unsigned int type size */);
445                    }
446                } else if (type.isReal()) {
447                    if (type.size() == sizeof(float))
448                        value = (T)*(float*)ptr;
449                    else if (type.size() == sizeof(double))
450                        value = (T)*(double*)ptr;
451                    else
452                        assert(false /* unknown floating point type */);
453                } else if (type.isBool()) {
454                    value = (T)*(bool*)ptr;
455                } else {
456                    assert(false /* unknown primitive type */);
457                }
458            }
459            return value;
460        }
461    
462      static String _encodePrimitiveValue(const Object& obj) {      static String _encodePrimitiveValue(const Object& obj) {
463          return _encodeBlob( _primitiveObjectValueToString(obj) );          return _encodeBlob( _primitiveObjectValueToString(obj) );
464      }      }
# Line 460  namespace Serialization { Line 518  namespace Serialization {
518      };      };
519    
520      static _Blob _decodeBlob(const char* p, const char* end, bool bThrow = true) {      static _Blob _decodeBlob(const char* p, const char* end, bool bThrow = true) {
521          if (!bThrow && p >= end)          if (!bThrow && p >= end) {
522              return (_Blob) { p, end };              const _Blob blob =  { p, end };
523                return blob;
524            }
525          size_t sz = 0;          size_t sz = 0;
526          for (; true; ++p) {          for (; true; ++p) {
527              if (p >= end)              if (p >= end)
# Line 476  namespace Serialization { Line 536  namespace Serialization {
536          ++p;          ++p;
537          if (p + sz > end)          if (p + sz > end)
538              throw Exception("Decode Error: Premature end of blob");              throw Exception("Decode Error: Premature end of blob");
539          return (_Blob) { p, p + sz };          const _Blob blob = { p, p + sz };
540            return blob;
541      }      }
542    
543      template<typename T_int>      template<typename T_int>
# Line 580  namespace Serialization { Line 641  namespace Serialization {
641          const ID id = (ID) _popIntBlob<size_t>(p, end);          const ID id = (ID) _popIntBlob<size_t>(p, end);
642          const size_t size = _popIntBlob<size_t>(p, end);          const size_t size = _popIntBlob<size_t>(p, end);
643    
644          return (UID) { id, size };          const UID uid = { id, size };
645            return uid;
646      }      }
647    
648      static UIDChain _popUIDChainBlob(const char*& p, const char* end) {      static UIDChain _popUIDChainBlob(const char*& p, const char* end) {
# Line 989  namespace Serialization { Line 1051  namespace Serialization {
1051          return _primitiveObjectValueToString(*pObject);          return _primitiveObjectValueToString(*pObject);
1052      }      }
1053    
1054        int64_t Archive::valueAsInt(const Object& object) {
1055            if (!object)
1056                throw Exception("Invalid object");
1057            if (!object.type().isInteger() && !object.type().isEnum())
1058                throw Exception("Object is neither an integer nor an enum");
1059            const Object* pObject = &object;
1060            if (object.type().isPointer()) {
1061                const Object& obj = objectByUID(object.uid(1));
1062                if (!obj) return 0;
1063                pObject = &obj;
1064            }
1065            return _primitiveObjectValueToNumber<int64_t>(*pObject);
1066        }
1067    
1068        double Archive::valueAsReal(const Object& object) {
1069            if (!object)
1070                throw Exception("Invalid object");
1071            if (!object.type().isReal())
1072                throw Exception("Object is not an real type");
1073            const Object* pObject = &object;
1074            if (object.type().isPointer()) {
1075                const Object& obj = objectByUID(object.uid(1));
1076                if (!obj) return 0;
1077                pObject = &obj;
1078            }
1079            return _primitiveObjectValueToNumber<double>(*pObject);
1080        }
1081    
1082        bool Archive::valueAsBool(const Object& object) {
1083            if (!object)
1084                throw Exception("Invalid object");
1085            if (!object.type().isBool())
1086                throw Exception("Object is not a bool");
1087            const Object* pObject = &object;
1088            if (object.type().isPointer()) {
1089                const Object& obj = objectByUID(object.uid(1));
1090                if (!obj) return 0;
1091                pObject = &obj;
1092            }
1093            return _primitiveObjectValueToNumber<bool>(*pObject);
1094        }
1095    
1096      // *************** Archive::Syncer ***************      // *************** Archive::Syncer ***************
1097      // *      // *
1098    

Legend:
Removed from v.3159  
changed lines
  Added in v.3173

  ViewVC Help
Powered by ViewVC