/[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 3138 by schoenebeck, Wed May 3 14:41:58 2017 UTC revision 3182 by schoenebeck, Sun May 14 20:40:02 2017 UTC
# Line 26  Line 26 
26  #include <iostream>  #include <iostream>
27  #include <assert.h>  #include <assert.h>
28  #include <string.h> // for memcpy()  #include <string.h> // for memcpy()
29  #include <stdlib.h> // for atof() and atof_l()  #include <stdlib.h> // for atof()
30  #include <xlocale.h> // for locale passed to atof_l()  #include <cxxabi.h>
31    
32  #include "helper.h"  #include "helper.h"
33    
34    #define LIBGIG_EPOCH_TIME ((time_t)0)
35    
36  namespace Serialization {  namespace Serialization {
37    
38      // *************** DataType ***************      // *************** DataType ***************
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 125  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 191  namespace Serialization { Line 201  namespace Serialization {
201          m_uid  = uidChain;          m_uid  = uidChain;
202          m_version = 0;          m_version = 0;
203          m_minVersion = 0;          m_minVersion = 0;
204          m_data.resize(type.size());          //m_data.resize(type.size());
205      }      }
206    
207      bool Object::isValid() const {      bool Object::isValid() const {
# Line 230  namespace Serialization { Line 240  namespace Serialization {
240              return other.minVersion() <= this->version();              return other.minVersion() <= this->version();
241      }      }
242    
243        void Object::setVersion(Version v) {
244            m_version = v;
245        }
246    
247        void Object::setMinVersion(Version v) {
248            m_minVersion = v;
249        }
250    
251      Member Object::memberNamed(String name) const {      Member Object::memberNamed(String name) const {
252          for (int i = 0; i < m_members.size(); ++i)          for (int i = 0; i < m_members.size(); ++i)
253              if (m_members[i].name() == name)              if (m_members[i].name() == name)
# Line 237  namespace Serialization { Line 255  namespace Serialization {
255          return Member();          return Member();
256      }      }
257    
258        Member Object::memberByUID(const UID& uid) const {
259            if (!uid) return Member();
260            for (int i = 0; i < m_members.size(); ++i)
261                if (m_members[i].uid() == uid)
262                    return m_members[i];
263            return Member();
264        }
265    
266      void Object::remove(const Member& member) {      void Object::remove(const Member& member) {
267          for (int i = 0; i < m_members.size(); ++i) {          for (int i = 0; i < m_members.size(); ++i) {
268              if (m_members[i] == member) {              if (m_members[i] == member) {
# Line 269  namespace Serialization { Line 295  namespace Serialization {
295      Archive::Archive() {      Archive::Archive() {
296          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
297          m_root = NO_UID;          m_root = NO_UID;
298            m_isModified = false;
299            m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
300      }      }
301    
302      Archive::Archive(const RawData& data) {      Archive::Archive(const RawData& data) {
303          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
304          m_root = NO_UID;          m_root = NO_UID;
305            m_isModified = false;
306            m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
307          decode(m_rawData);          decode(m_rawData);
308      }      }
309    
310      Archive::Archive(const uint8_t* data, size_t size) {      Archive::Archive(const uint8_t* data, size_t size) {
311          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
312          m_root = NO_UID;          m_root = NO_UID;
313            m_isModified = false;
314            m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
315          decode(data, size);          decode(data, size);
316      }      }
317    
# Line 301  namespace Serialization { Line 333  namespace Serialization {
333          return _encodeBlob(s);          return _encodeBlob(s);
334      }      }
335    
336        static String _encode(const time_t& time) {
337            return _encodeBlob(ToString(time));
338        }
339    
340      static String _encode(const DataType& type) {      static String _encode(const DataType& type) {
341          String s;          String s;
342          s += _encodeBlob(type.baseTypeName());          s += _encodeBlob(type.baseTypeName());
# Line 333  namespace Serialization { Line 369  namespace Serialization {
369          return _encodeBlob(s);          return _encodeBlob(s);
370      }      }
371    
372      static String _encodePrimitiveValue(const Object& obj) {      static String _primitiveObjectValueToString(const Object& obj) {
373          String s;          String s;
374          const DataType& type = obj.type();          const DataType& type = obj.type();
375          const ID& id = obj.uid().id;          const ID& id = obj.uid().id;
376            void* ptr = obj.m_data.empty() ? (void*)id : (void*)&obj.m_data[0];
377            if (!obj.m_data.empty())
378                assert(type.size() == obj.m_data.size());
379          if (type.isPrimitive() && !type.isPointer()) {          if (type.isPrimitive() && !type.isPointer()) {
380              if (type.isInteger() || type.isEnum()) {              if (type.isInteger() || type.isEnum()) {
381                  if (type.isSigned()) {                  if (type.isSigned()) {
382                      if (type.size() == 1)                      if (type.size() == 1)
383                          s = ToString((int16_t)*(int8_t*)id); // int16_t: prevent ToString() to render an ASCII character                          s = ToString((int16_t)*(int8_t*)ptr); // int16_t: prevent ToString() to render an ASCII character
384                      else if (type.size() == 2)                      else if (type.size() == 2)
385                          s = ToString(*(int16_t*)id);                          s = ToString(*(int16_t*)ptr);
386                      else if (type.size() == 4)                      else if (type.size() == 4)
387                          s = ToString(*(int32_t*)id);                          s = ToString(*(int32_t*)ptr);
388                      else if (type.size() == 8)                      else if (type.size() == 8)
389                          s = ToString(*(int64_t*)id);                          s = ToString(*(int64_t*)ptr);
390                      else                      else
391                          assert(false /* unknown signed int type size */);                          assert(false /* unknown signed int type size */);
392                  } else {                  } else {
393                      if (type.size() == 1)                      if (type.size() == 1)
394                          s = ToString((uint16_t)*(uint8_t*)id); // uint16_t: prevent ToString() to render an ASCII character                          s = ToString((uint16_t)*(uint8_t*)ptr); // uint16_t: prevent ToString() to render an ASCII character
395                      else if (type.size() == 2)                      else if (type.size() == 2)
396                          s = ToString(*(uint16_t*)id);                          s = ToString(*(uint16_t*)ptr);
397                      else if (type.size() == 4)                      else if (type.size() == 4)
398                          s = ToString(*(uint32_t*)id);                          s = ToString(*(uint32_t*)ptr);
399                      else if (type.size() == 8)                      else if (type.size() == 8)
400                          s = ToString(*(uint64_t*)id);                          s = ToString(*(uint64_t*)ptr);
401                      else                      else
402                          assert(false /* unknown unsigned int type size */);                          assert(false /* unknown unsigned int type size */);
403                  }                  }
404              } else if (type.isReal()) {              } else if (type.isReal()) {
405                  if (type.size() == sizeof(float))                  if (type.size() == sizeof(float))
406                      s = ToString(*(float*)id);                      s = ToString(*(float*)ptr);
407                  else if (type.size() == sizeof(double))                  else if (type.size() == sizeof(double))
408                      s = ToString(*(double*)id);                      s = ToString(*(double*)ptr);
409                  else                  else
410                      assert(false /* unknown floating point type */);                      assert(false /* unknown floating point type */);
411              } else if (type.isBool()) {              } else if (type.isBool()) {
412                  s = ToString(*(bool*)id);                  s = ToString(*(bool*)ptr);
413              } else {              } else {
414                  assert(false /* unknown primitive type */);                  assert(false /* unknown primitive type */);
415              }              }
416    
417          }          }
418          return _encodeBlob(s);          return s;
419        }
420    
421        template<typename T>
422        static T _primitiveObjectValueToNumber(const Object& obj) {
423            T value = 0;
424            const DataType& type = obj.type();
425            const ID& id = obj.uid().id;
426            void* ptr = obj.m_data.empty() ? (void*)id : (void*)&obj.m_data[0];
427            if (!obj.m_data.empty())
428                assert(type.size() == obj.m_data.size());
429            if (type.isPrimitive() && !type.isPointer()) {
430                if (type.isInteger() || type.isEnum()) {
431                    if (type.isSigned()) {
432                        if (type.size() == 1)
433                            value = (T)*(int8_t*)ptr;
434                        else if (type.size() == 2)
435                            value = (T)*(int16_t*)ptr;
436                        else if (type.size() == 4)
437                            value = (T)*(int32_t*)ptr;
438                        else if (type.size() == 8)
439                            value = (T)*(int64_t*)ptr;
440                        else
441                            assert(false /* unknown signed int type size */);
442                    } else {
443                        if (type.size() == 1)
444                            value = (T)*(uint8_t*)ptr;
445                        else if (type.size() == 2)
446                            value = (T)*(uint16_t*)ptr;
447                        else if (type.size() == 4)
448                            value = (T)*(uint32_t*)ptr;
449                        else if (type.size() == 8)
450                            value = (T)*(uint64_t*)ptr;
451                        else
452                            assert(false /* unknown unsigned int type size */);
453                    }
454                } else if (type.isReal()) {
455                    if (type.size() == sizeof(float))
456                        value = (T)*(float*)ptr;
457                    else if (type.size() == sizeof(double))
458                        value = (T)*(double*)ptr;
459                    else
460                        assert(false /* unknown floating point type */);
461                } else if (type.isBool()) {
462                    value = (T)*(bool*)ptr;
463                } else {
464                    assert(false /* unknown primitive type */);
465                }
466            }
467            return value;
468        }
469    
470        static String _encodePrimitiveValue(const Object& obj) {
471            return _encodeBlob( _primitiveObjectValueToString(obj) );
472      }      }
473    
474      static String _encode(const Object& obj) {      static String _encode(const Object& obj) {
# Line 409  namespace Serialization { Line 501  namespace Serialization {
501          s += _encodeBlob(ToString(ENCODING_FORMAT_MINOR_VERSION));          s += _encodeBlob(ToString(ENCODING_FORMAT_MINOR_VERSION));
502          s += _encode(m_root);          s += _encode(m_root);
503          s += _encode(m_allObjects);          s += _encode(m_allObjects);
504            s += _encodeBlob(m_name);
505            s += _encodeBlob(m_comment);
506            s += _encode(m_timeCreated);
507            s += _encode(m_timeModified);
508          return _encodeBlob(s);          return _encodeBlob(s);
509      }      }
510    
511      void Archive::encode() {      void Archive::encode() {
512          m_rawData.clear();          m_rawData.clear();
513          String s = MAGIC_START;          String s = MAGIC_START;
514            m_timeModified = time(NULL);
515            if (m_timeCreated == LIBGIG_EPOCH_TIME)
516                m_timeCreated = m_timeModified;
517          s += _encodeRootBlob();          s += _encodeRootBlob();
518          m_rawData.resize(s.length() + 1);          m_rawData.resize(s.length() + 1);
519          memcpy(&m_rawData[0], &s[0], s.length() + 1);          memcpy(&m_rawData[0], &s[0], s.length() + 1);
520            m_isModified = false;
521      }      }
522    
523      struct _Blob {      struct _Blob {
# Line 426  namespace Serialization { Line 526  namespace Serialization {
526      };      };
527    
528      static _Blob _decodeBlob(const char* p, const char* end, bool bThrow = true) {      static _Blob _decodeBlob(const char* p, const char* end, bool bThrow = true) {
529          if (!bThrow && p >= end)          if (!bThrow && p >= end) {
530              return (_Blob) { p, end };              const _Blob blob =  { p, end };
531                return blob;
532            }
533          size_t sz = 0;          size_t sz = 0;
534          for (; true; ++p) {          for (; true; ++p) {
535              if (p >= end)              if (p >= end)
# Line 442  namespace Serialization { Line 544  namespace Serialization {
544          ++p;          ++p;
545          if (p + sz > end)          if (p + sz > end)
546              throw Exception("Decode Error: Premature end of blob");              throw Exception("Decode Error: Premature end of blob");
547          return (_Blob) { p, p + sz };          const _Blob blob = { p, p + sz };
548            return blob;
549      }      }
550    
551      template<typename T_int>      template<typename T_int>
# Line 487  namespace Serialization { Line 590  namespace Serialization {
590          String s(p, size_t(end - p));          String s(p, size_t(end - p));
591    
592          T_real r;          T_real r;
593          if (sizeof(T_real) == sizeof(float))          if (sizeof(T_real) <= sizeof(double))
594              r = atof(s.c_str());              r = atof(s.c_str());
         else if (sizeof(T_real) == sizeof(double))  
             r = atof_l(s.c_str(), _c_locale);  
595          else          else
596              assert(false /* unknown real type */);              assert(false /* unknown real type */);
597    
# Line 519  namespace Serialization { Line 620  namespace Serialization {
620          return s;          return s;
621      }      }
622    
623        static time_t _popTimeBlob(const char*& p, const char* end) {
624            const uint64_t i = _popIntBlob<uint64_t>(p, end);
625            return (time_t) i;
626        }
627    
628      DataType _popDataTypeBlob(const char*& p, const char* end) {      DataType _popDataTypeBlob(const char*& p, const char* end) {
629          _Blob blob = _decodeBlob(p, end);          _Blob blob = _decodeBlob(p, end);
630          p   = blob.p;          p   = blob.p;
# Line 543  namespace Serialization { Line 649  namespace Serialization {
649          const ID id = (ID) _popIntBlob<size_t>(p, end);          const ID id = (ID) _popIntBlob<size_t>(p, end);
650          const size_t size = _popIntBlob<size_t>(p, end);          const size_t size = _popIntBlob<size_t>(p, end);
651    
652          return (UID) { id, size };          const UID uid = { id, size };
653            return uid;
654      }      }
655    
656      static UIDChain _popUIDChainBlob(const char*& p, const char* end) {      static UIDChain _popUIDChainBlob(const char*& p, const char* end) {
# Line 560  namespace Serialization { Line 667  namespace Serialization {
667          return chain;          return chain;
668      }      }
669    
670      Member _popMemberBlob(const char*& p, const char* end) {      static Member _popMemberBlob(const char*& p, const char* end) {
671          _Blob blob = _decodeBlob(p, end, false);          _Blob blob = _decodeBlob(p, end, false);
672          p   = blob.p;          p   = blob.p;
673          end = blob.end;          end = blob.end;
# Line 574  namespace Serialization { Line 681  namespace Serialization {
681          m.m_type   = _popDataTypeBlob(p, end);          m.m_type   = _popDataTypeBlob(p, end);
682          assert(m.type());          assert(m.type());
683          assert(!m.name().empty());          assert(!m.name().empty());
684          assert(m.uid() != NULL);          assert(m.uid().isValid());
685          return m;          return m;
686      }      }
687    
# Line 594  namespace Serialization { Line 701  namespace Serialization {
701          return members;          return members;
702      }      }
703    
704      void _popPrimitiveValue(const char*& p, const char* end, Object& obj) {      static void _popPrimitiveValue(const char*& p, const char* end, Object& obj) {
705          const DataType& type = obj.type();          const DataType& type = obj.type();
706          if (type.isPrimitive() && !type.isPointer()) {          if (type.isPrimitive() && !type.isPointer()) {
707              obj.m_data.resize(type.size());              obj.m_data.resize(type.size());
# Line 643  namespace Serialization { Line 750  namespace Serialization {
750          }          }
751      }      }
752    
753      Object _popObjectBlob(const char*& p, const char* end) {      static Object _popObjectBlob(const char*& p, const char* end) {
754          _Blob blob = _decodeBlob(p, end, false);          _Blob blob = _decodeBlob(p, end, false);
755          p   = blob.p;          p   = blob.p;
756          end = blob.end;          end = blob.end;
# Line 695  namespace Serialization { Line 802  namespace Serialization {
802          _popObjectsBlob(p, end);          _popObjectsBlob(p, end);
803          if (!m_allObjects[m_root])          if (!m_allObjects[m_root])
804              throw Exception("Decode Error: Missing declared root object");              throw Exception("Decode Error: Missing declared root object");
805    
806            m_name = _popStringBlob(p, end);
807            m_comment = _popStringBlob(p, end);
808            m_timeCreated = _popTimeBlob(p, end);
809            m_timeModified = _popTimeBlob(p, end);
810      }      }
811    
812      void Archive::decode(const RawData& data) {      void Archive::decode(const RawData& data) {
813          m_rawData = data;          m_rawData = data;
814          m_allObjects.clear();          m_allObjects.clear();
815            m_isModified = false;
816            m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
817          const char* p   = (const char*) &data[0];          const char* p   = (const char*) &data[0];
818          const char* end = p + data.size();          const char* end = p + data.size();
819          if (memcmp(p, MAGIC_START, std::min(strlen(MAGIC_START), data.size())))          if (memcmp(p, MAGIC_START, std::min(strlen(MAGIC_START), data.size())))
# Line 715  namespace Serialization { Line 829  namespace Serialization {
829          decode(rawData);          decode(rawData);
830      }      }
831    
832        const RawData& Archive::rawData() {
833            if (m_isModified) encode();
834            return m_rawData;
835        }
836    
837      String Archive::rawDataFormat() const {      String Archive::rawDataFormat() const {
838          return MAGIC_START;          return MAGIC_START;
839      }      }
840    
841        bool Archive::isModified() const {
842            return m_isModified;
843        }
844    
845      void Archive::clear() {      void Archive::clear() {
846          m_allObjects.clear();          m_allObjects.clear();
847          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
848          m_root = NO_UID;          m_root = NO_UID;
849          m_rawData.clear();          m_rawData.clear();
850            m_isModified = false;
851            m_timeCreated = m_timeModified = LIBGIG_EPOCH_TIME;
852        }
853    
854        String Archive::name() const {
855            return m_name;
856        }
857    
858        void Archive::setName(String name) {
859            if (m_name == name) return;
860            m_name = name;
861            m_isModified = true;
862        }
863    
864        String Archive::comment() const {
865            return m_comment;
866        }
867    
868        void Archive::setComment(String comment) {
869            if (m_comment == comment) return;
870            m_comment = comment;
871            m_isModified = true;
872        }
873    
874        static tm _convertTimeStamp(const time_t& time, time_base_t base) {
875            tm* pTm;
876            switch (base) {
877                case LOCAL_TIME:
878                    pTm = localtime(&time);
879                    break;
880                case UTC_TIME:
881                    pTm = gmtime(&time);
882                    break;
883                default:
884                    throw Exception("Time stamp with unknown time base (" + ToString((int64_t)base) + ") requested");
885            }
886            if (!pTm)
887                throw Exception("Failed assembling time stamp structure");
888            return *pTm;
889        }
890    
891        time_t Archive::timeStampCreated() const {
892            return m_timeCreated;
893        }
894    
895        time_t Archive::timeStampModified() const {
896            return m_timeModified;
897        }
898    
899        tm Archive::dateTimeCreated(time_base_t base) const {
900            return _convertTimeStamp(m_timeCreated, base);
901        }
902    
903        tm Archive::dateTimeModified(time_base_t base) const {
904            return _convertTimeStamp(m_timeModified, base);
905        }
906    
907        void Archive::removeMember(Object& parent, const Member& member) {
908            parent.remove(member);
909            m_isModified = true;
910      }      }
911    
912      void Archive::remove(const Object& obj) {      void Archive::remove(const Object& obj) {
913            //FIXME: Should traverse from root object and remove all members associated with this object
914          if (!obj.uid()) return;          if (!obj.uid()) return;
915          m_allObjects.erase(obj.uid());          m_allObjects.erase(obj.uid());
916            m_isModified = true;
917      }      }
918    
919      Object& Archive::objectByUID(const UID& uid) {      Object& Archive::objectByUID(const UID& uid) {
920          return m_allObjects[uid];          return m_allObjects[uid];
921      }      }
922    
923        void Archive::setVersion(Object& object, Version v) {
924            if (!object) return;
925            object.setVersion(v);
926            m_isModified = true;
927        }
928    
929        void Archive::setMinVersion(Object& object, Version v) {
930            if (!object) return;
931            object.setMinVersion(v);
932            m_isModified = true;
933        }
934    
935        void Archive::setEnumValue(Object& object, uint64_t value) {
936            if (!object) return;
937            if (!object.type().isEnum())
938                throw Exception("Not an enum data type");
939            Object* pObject = &object;
940            if (object.type().isPointer()) {
941                Object& obj = objectByUID(object.uid(1));
942                if (!obj) return;
943                pObject = &obj;
944            }
945            const int nativeEnumSize = sizeof(enum operation_t);
946            DataType& type = const_cast<DataType&>( pObject->type() );
947            // original serializer ("sender") might have had a different word size
948            // than this machine, adjust type object in this case
949            if (type.size() != nativeEnumSize) {
950                type.m_size = nativeEnumSize;
951            }
952            pObject->m_data.resize(type.size());
953            void* ptr = &pObject->m_data[0];
954            if (type.size() == 1)
955                *(uint8_t*)ptr = (uint8_t)value;
956            else if (type.size() == 2)
957                *(uint16_t*)ptr = (uint16_t)value;
958            else if (type.size() == 4)
959                *(uint32_t*)ptr = (uint32_t)value;
960            else if (type.size() == 8)
961                *(uint64_t*)ptr = (uint64_t)value;
962            else
963                assert(false /* unknown enum type size */);
964            m_isModified = true;
965        }
966    
967        void Archive::setIntValue(Object& object, int64_t value) {
968            if (!object) return;
969            if (!object.type().isInteger())
970                throw Exception("Not an integer data type");
971            Object* pObject = &object;
972            if (object.type().isPointer()) {
973                Object& obj = objectByUID(object.uid(1));
974                if (!obj) return;
975                pObject = &obj;
976            }
977            const DataType& type = pObject->type();
978            pObject->m_data.resize(type.size());
979            void* ptr = &pObject->m_data[0];
980            if (type.isSigned()) {
981                if (type.size() == 1)
982                    *(int8_t*)ptr = (int8_t)value;
983                else if (type.size() == 2)
984                    *(int16_t*)ptr = (int16_t)value;
985                else if (type.size() == 4)
986                    *(int32_t*)ptr = (int32_t)value;
987                else if (type.size() == 8)
988                    *(int64_t*)ptr = (int64_t)value;
989                else
990                    assert(false /* unknown signed int type size */);
991            } else {
992                if (type.size() == 1)
993                    *(uint8_t*)ptr = (uint8_t)value;
994                else if (type.size() == 2)
995                    *(uint16_t*)ptr = (uint16_t)value;
996                else if (type.size() == 4)
997                    *(uint32_t*)ptr = (uint32_t)value;
998                else if (type.size() == 8)
999                    *(uint64_t*)ptr = (uint64_t)value;
1000                else
1001                    assert(false /* unknown unsigned int type size */);
1002            }
1003            m_isModified = true;
1004        }
1005    
1006        void Archive::setRealValue(Object& object, double value) {
1007            if (!object) return;
1008            if (!object.type().isReal())
1009                throw Exception("Not a real data type");
1010            Object* pObject = &object;
1011            if (object.type().isPointer()) {
1012                Object& obj = objectByUID(object.uid(1));
1013                if (!obj) return;
1014                pObject = &obj;
1015            }
1016            const DataType& type = pObject->type();
1017            pObject->m_data.resize(type.size());
1018            void* ptr = &pObject->m_data[0];
1019            if (type.size() == sizeof(float))
1020                *(float*)ptr = (float)value;
1021            else if (type.size() == sizeof(double))
1022                *(double*)ptr = (double)value;
1023            else
1024                assert(false /* unknown real type size */);
1025            m_isModified = true;
1026        }
1027    
1028        void Archive::setBoolValue(Object& object, bool value) {
1029            if (!object) return;
1030            if (!object.type().isBool())
1031                throw Exception("Not a bool data type");
1032            Object* pObject = &object;
1033            if (object.type().isPointer()) {
1034                Object& obj = objectByUID(object.uid(1));
1035                if (!obj) return;
1036                pObject = &obj;
1037            }
1038            const DataType& type = pObject->type();
1039            pObject->m_data.resize(type.size());
1040            bool* ptr = (bool*)&pObject->m_data[0];
1041            *ptr = value;
1042            m_isModified = true;
1043        }
1044    
1045        void Archive::setAutoValue(Object& object, String value) {
1046            if (!object) return;
1047            const DataType& type = object.type();
1048            if (type.isInteger())
1049                setIntValue(object, atoll(value.c_str()));
1050            else if (type.isReal())
1051                setRealValue(object, atof(value.c_str()));
1052            else if (type.isBool())
1053                setBoolValue(object, atof(value.c_str()));
1054            else if (type.isEnum())
1055                setEnumValue(object, atoll(value.c_str()));
1056            else
1057                throw Exception("Not a primitive data type");
1058        }
1059    
1060        String Archive::valueAsString(const Object& object) {
1061            if (!object)
1062                throw Exception("Invalid object");
1063            if (object.type().isClass())
1064                throw Exception("Object is class type");
1065            const Object* pObject = &object;
1066            if (object.type().isPointer()) {
1067                const Object& obj = objectByUID(object.uid(1));
1068                if (!obj) return "";
1069                pObject = &obj;
1070            }
1071            return _primitiveObjectValueToString(*pObject);
1072        }
1073    
1074        int64_t Archive::valueAsInt(const Object& object) {
1075            if (!object)
1076                throw Exception("Invalid object");
1077            if (!object.type().isInteger() && !object.type().isEnum())
1078                throw Exception("Object is neither an integer nor an enum");
1079            const Object* pObject = &object;
1080            if (object.type().isPointer()) {
1081                const Object& obj = objectByUID(object.uid(1));
1082                if (!obj) return 0;
1083                pObject = &obj;
1084            }
1085            return _primitiveObjectValueToNumber<int64_t>(*pObject);
1086        }
1087    
1088        double Archive::valueAsReal(const Object& object) {
1089            if (!object)
1090                throw Exception("Invalid object");
1091            if (!object.type().isReal())
1092                throw Exception("Object is not an real type");
1093            const Object* pObject = &object;
1094            if (object.type().isPointer()) {
1095                const Object& obj = objectByUID(object.uid(1));
1096                if (!obj) return 0;
1097                pObject = &obj;
1098            }
1099            return _primitiveObjectValueToNumber<double>(*pObject);
1100        }
1101    
1102        bool Archive::valueAsBool(const Object& object) {
1103            if (!object)
1104                throw Exception("Invalid object");
1105            if (!object.type().isBool())
1106                throw Exception("Object is not a bool");
1107            const Object* pObject = &object;
1108            if (object.type().isPointer()) {
1109                const Object& obj = objectByUID(object.uid(1));
1110                if (!obj) return 0;
1111                pObject = &obj;
1112            }
1113            return _primitiveObjectValueToNumber<bool>(*pObject);
1114        }
1115    
1116      // *************** Archive::Syncer ***************      // *************** Archive::Syncer ***************
1117      // *      // *
1118    

Legend:
Removed from v.3138  
changed lines
  Added in v.3182

  ViewVC Help
Powered by ViewVC