/[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 3153 by schoenebeck, Sat May 6 13:43:43 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()
 #include <xlocale.h> // for locale passed to atof_l()  
30    
31  #include "helper.h"  #include "helper.h"
32    
# Line 191  namespace Serialization { Line 190  namespace Serialization {
190          m_uid  = uidChain;          m_uid  = uidChain;
191          m_version = 0;          m_version = 0;
192          m_minVersion = 0;          m_minVersion = 0;
193          m_data.resize(type.size());          //m_data.resize(type.size());
194      }      }
195    
196      bool Object::isValid() const {      bool Object::isValid() const {
# Line 237  namespace Serialization { Line 236  namespace Serialization {
236          return Member();          return Member();
237      }      }
238    
239        Member Object::memberByUID(const UID& uid) const {
240            if (!uid) return Member();
241            for (int i = 0; i < m_members.size(); ++i)
242                if (m_members[i].uid() == uid)
243                    return m_members[i];
244            return Member();
245        }
246    
247      void Object::remove(const Member& member) {      void Object::remove(const Member& member) {
248          for (int i = 0; i < m_members.size(); ++i) {          for (int i = 0; i < m_members.size(); ++i) {
249              if (m_members[i] == member) {              if (m_members[i] == member) {
# Line 269  namespace Serialization { Line 276  namespace Serialization {
276      Archive::Archive() {      Archive::Archive() {
277          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
278          m_root = NO_UID;          m_root = NO_UID;
279            m_isModified = false;
280      }      }
281    
282      Archive::Archive(const RawData& data) {      Archive::Archive(const RawData& data) {
283          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
284          m_root = NO_UID;          m_root = NO_UID;
285            m_isModified = false;
286          decode(m_rawData);          decode(m_rawData);
287      }      }
288    
289      Archive::Archive(const uint8_t* data, size_t size) {      Archive::Archive(const uint8_t* data, size_t size) {
290          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
291          m_root = NO_UID;          m_root = NO_UID;
292            m_isModified = false;
293          decode(data, size);          decode(data, size);
294      }      }
295    
# Line 333  namespace Serialization { Line 343  namespace Serialization {
343          return _encodeBlob(s);          return _encodeBlob(s);
344      }      }
345    
346      static String _encodePrimitiveValue(const Object& obj) {      static String _primitiveObjectValueToString(const Object& obj) {
347          String s;          String s;
348          const DataType& type = obj.type();          const DataType& type = obj.type();
349          const ID& id = obj.uid().id;          const ID& id = obj.uid().id;
350            void* ptr = obj.m_data.empty() ? (void*)id : (void*)&obj.m_data[0];
351            if (!obj.m_data.empty())
352                assert(type.size() == obj.m_data.size());
353          if (type.isPrimitive() && !type.isPointer()) {          if (type.isPrimitive() && !type.isPointer()) {
354              if (type.isInteger() || type.isEnum()) {              if (type.isInteger() || type.isEnum()) {
355                  if (type.isSigned()) {                  if (type.isSigned()) {
356                      if (type.size() == 1)                      if (type.size() == 1)
357                          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
358                      else if (type.size() == 2)                      else if (type.size() == 2)
359                          s = ToString(*(int16_t*)id);                          s = ToString(*(int16_t*)ptr);
360                      else if (type.size() == 4)                      else if (type.size() == 4)
361                          s = ToString(*(int32_t*)id);                          s = ToString(*(int32_t*)ptr);
362                      else if (type.size() == 8)                      else if (type.size() == 8)
363                          s = ToString(*(int64_t*)id);                          s = ToString(*(int64_t*)ptr);
364                      else                      else
365                          assert(false /* unknown signed int type size */);                          assert(false /* unknown signed int type size */);
366                  } else {                  } else {
367                      if (type.size() == 1)                      if (type.size() == 1)
368                          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
369                      else if (type.size() == 2)                      else if (type.size() == 2)
370                          s = ToString(*(uint16_t*)id);                          s = ToString(*(uint16_t*)ptr);
371                      else if (type.size() == 4)                      else if (type.size() == 4)
372                          s = ToString(*(uint32_t*)id);                          s = ToString(*(uint32_t*)ptr);
373                      else if (type.size() == 8)                      else if (type.size() == 8)
374                          s = ToString(*(uint64_t*)id);                          s = ToString(*(uint64_t*)ptr);
375                      else                      else
376                          assert(false /* unknown unsigned int type size */);                          assert(false /* unknown unsigned int type size */);
377                  }                  }
378              } else if (type.isReal()) {              } else if (type.isReal()) {
379                  if (type.size() == sizeof(float))                  if (type.size() == sizeof(float))
380                      s = ToString(*(float*)id);                      s = ToString(*(float*)ptr);
381                  else if (type.size() == sizeof(double))                  else if (type.size() == sizeof(double))
382                      s = ToString(*(double*)id);                      s = ToString(*(double*)ptr);
383                  else                  else
384                      assert(false /* unknown floating point type */);                      assert(false /* unknown floating point type */);
385              } else if (type.isBool()) {              } else if (type.isBool()) {
386                  s = ToString(*(bool*)id);                  s = ToString(*(bool*)ptr);
387              } else {              } else {
388                  assert(false /* unknown primitive type */);                  assert(false /* unknown primitive type */);
389              }              }
390    
391          }          }
392          return _encodeBlob(s);          return s;
393        }
394    
395        static String _encodePrimitiveValue(const Object& obj) {
396            return _encodeBlob( _primitiveObjectValueToString(obj) );
397      }      }
398    
399      static String _encode(const Object& obj) {      static String _encode(const Object& obj) {
# Line 418  namespace Serialization { Line 435  namespace Serialization {
435          s += _encodeRootBlob();          s += _encodeRootBlob();
436          m_rawData.resize(s.length() + 1);          m_rawData.resize(s.length() + 1);
437          memcpy(&m_rawData[0], &s[0], s.length() + 1);          memcpy(&m_rawData[0], &s[0], s.length() + 1);
438            m_isModified = false;
439      }      }
440    
441      struct _Blob {      struct _Blob {
# Line 487  namespace Serialization { Line 505  namespace Serialization {
505          String s(p, size_t(end - p));          String s(p, size_t(end - p));
506    
507          T_real r;          T_real r;
508          if (sizeof(T_real) == sizeof(float))          if (sizeof(T_real) <= sizeof(double))
509              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);  
510          else          else
511              assert(false /* unknown real type */);              assert(false /* unknown real type */);
512    
# Line 560  namespace Serialization { Line 576  namespace Serialization {
576          return chain;          return chain;
577      }      }
578    
579      Member _popMemberBlob(const char*& p, const char* end) {      static Member _popMemberBlob(const char*& p, const char* end) {
580          _Blob blob = _decodeBlob(p, end, false);          _Blob blob = _decodeBlob(p, end, false);
581          p   = blob.p;          p   = blob.p;
582          end = blob.end;          end = blob.end;
# Line 574  namespace Serialization { Line 590  namespace Serialization {
590          m.m_type   = _popDataTypeBlob(p, end);          m.m_type   = _popDataTypeBlob(p, end);
591          assert(m.type());          assert(m.type());
592          assert(!m.name().empty());          assert(!m.name().empty());
593          assert(m.uid() != NULL);          assert(m.uid().isValid());
594          return m;          return m;
595      }      }
596    
# Line 594  namespace Serialization { Line 610  namespace Serialization {
610          return members;          return members;
611      }      }
612    
613      void _popPrimitiveValue(const char*& p, const char* end, Object& obj) {      static void _popPrimitiveValue(const char*& p, const char* end, Object& obj) {
614          const DataType& type = obj.type();          const DataType& type = obj.type();
615          if (type.isPrimitive() && !type.isPointer()) {          if (type.isPrimitive() && !type.isPointer()) {
616              obj.m_data.resize(type.size());              obj.m_data.resize(type.size());
# Line 643  namespace Serialization { Line 659  namespace Serialization {
659          }          }
660      }      }
661    
662      Object _popObjectBlob(const char*& p, const char* end) {      static Object _popObjectBlob(const char*& p, const char* end) {
663          _Blob blob = _decodeBlob(p, end, false);          _Blob blob = _decodeBlob(p, end, false);
664          p   = blob.p;          p   = blob.p;
665          end = blob.end;          end = blob.end;
# Line 700  namespace Serialization { Line 716  namespace Serialization {
716      void Archive::decode(const RawData& data) {      void Archive::decode(const RawData& data) {
717          m_rawData = data;          m_rawData = data;
718          m_allObjects.clear();          m_allObjects.clear();
719            m_isModified = false;
720          const char* p   = (const char*) &data[0];          const char* p   = (const char*) &data[0];
721          const char* end = p + data.size();          const char* end = p + data.size();
722          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 732  namespace Serialization {
732          decode(rawData);          decode(rawData);
733      }      }
734    
735        const RawData& Archive::rawData() {
736            if (m_isModified) encode();
737            return m_rawData;
738        }
739    
740      String Archive::rawDataFormat() const {      String Archive::rawDataFormat() const {
741          return MAGIC_START;          return MAGIC_START;
742      }      }
743    
744        bool Archive::isModified() const {
745            return m_isModified;
746        }
747    
748      void Archive::clear() {      void Archive::clear() {
749          m_allObjects.clear();          m_allObjects.clear();
750          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
751          m_root = NO_UID;          m_root = NO_UID;
752          m_rawData.clear();          m_rawData.clear();
753            m_isModified = false;
754        }
755    
756        void Archive::removeMember(Object& parent, const Member& member) {
757            parent.remove(member);
758            m_isModified = true;
759      }      }
760    
761      void Archive::remove(const Object& obj) {      void Archive::remove(const Object& obj) {
762            //FIXME: Should traverse from root object and remove all members associated with this object
763          if (!obj.uid()) return;          if (!obj.uid()) return;
764          m_allObjects.erase(obj.uid());          m_allObjects.erase(obj.uid());
765            m_isModified = true;
766      }      }
767    
768      Object& Archive::objectByUID(const UID& uid) {      Object& Archive::objectByUID(const UID& uid) {
769          return m_allObjects[uid];          return m_allObjects[uid];
770      }      }
771    
772        void Archive::setEnumValue(Object& object, uint64_t value) {
773            if (!object) return;
774            if (!object.type().isEnum())
775                throw Exception("Not an enum data type");
776            Object* pObject = &object;
777            if (object.type().isPointer()) {
778                Object& obj = objectByUID(object.uid(1));
779                if (!obj) return;
780                pObject = &obj;
781            }
782            const int nativeEnumSize = sizeof(enum operation_t);
783            DataType& type = const_cast<DataType&>( pObject->type() );
784            // original serializer ("sender") might have had a different word size
785            // than this machine, adjust type object in this case
786            if (type.size() != nativeEnumSize) {
787                type.m_size = nativeEnumSize;
788            }
789            pObject->m_data.resize(type.size());
790            void* ptr = &pObject->m_data[0];
791            if (type.size() == 1)
792                *(uint8_t*)ptr = (uint8_t)value;
793            else if (type.size() == 2)
794                *(uint16_t*)ptr = (uint16_t)value;
795            else if (type.size() == 4)
796                *(uint32_t*)ptr = (uint32_t)value;
797            else if (type.size() == 8)
798                *(uint64_t*)ptr = (uint64_t)value;
799            else
800                assert(false /* unknown enum type size */);
801            m_isModified = true;
802        }
803    
804        void Archive::setIntValue(Object& object, int64_t value) {
805            if (!object) return;
806            if (!object.type().isInteger())
807                throw Exception("Not an integer data type");
808            Object* pObject = &object;
809            if (object.type().isPointer()) {
810                Object& obj = objectByUID(object.uid(1));
811                if (!obj) return;
812                pObject = &obj;
813            }
814            const DataType& type = pObject->type();
815            pObject->m_data.resize(type.size());
816            void* ptr = &pObject->m_data[0];
817            if (type.isSigned()) {
818                if (type.size() == 1)
819                    *(int8_t*)ptr = (int8_t)value;
820                else if (type.size() == 2)
821                    *(int16_t*)ptr = (int16_t)value;
822                else if (type.size() == 4)
823                    *(int32_t*)ptr = (int32_t)value;
824                else if (type.size() == 8)
825                    *(int64_t*)ptr = (int64_t)value;
826                else
827                    assert(false /* unknown signed int type size */);
828            } else {
829                if (type.size() == 1)
830                    *(uint8_t*)ptr = (uint8_t)value;
831                else if (type.size() == 2)
832                    *(uint16_t*)ptr = (uint16_t)value;
833                else if (type.size() == 4)
834                    *(uint32_t*)ptr = (uint32_t)value;
835                else if (type.size() == 8)
836                    *(uint64_t*)ptr = (uint64_t)value;
837                else
838                    assert(false /* unknown unsigned int type size */);
839            }
840            m_isModified = true;
841        }
842    
843        void Archive::setRealValue(Object& object, double value) {
844            if (!object) return;
845            if (!object.type().isReal())
846                throw Exception("Not a real data type");
847            Object* pObject = &object;
848            if (object.type().isPointer()) {
849                Object& obj = objectByUID(object.uid(1));
850                if (!obj) return;
851                pObject = &obj;
852            }
853            const DataType& type = pObject->type();
854            pObject->m_data.resize(type.size());
855            void* ptr = &pObject->m_data[0];
856            if (type.size() == sizeof(float))
857                *(float*)ptr = (float)value;
858            else if (type.size() == sizeof(double))
859                *(double*)ptr = (double)value;
860            else
861                assert(false /* unknown real type size */);
862            m_isModified = true;
863        }
864    
865        void Archive::setBoolValue(Object& object, bool value) {
866            if (!object) return;
867            if (!object.type().isBool())
868                throw Exception("Not a bool data type");
869            Object* pObject = &object;
870            if (object.type().isPointer()) {
871                Object& obj = objectByUID(object.uid(1));
872                if (!obj) return;
873                pObject = &obj;
874            }
875            const DataType& type = pObject->type();
876            pObject->m_data.resize(type.size());
877            bool* ptr = (bool*)&pObject->m_data[0];
878            *ptr = value;
879            m_isModified = true;
880        }
881    
882        void Archive::setAutoValue(Object& object, String value) {
883            if (!object) return;
884            const DataType& type = object.type();
885            if (type.isInteger())
886                setIntValue(object, atoll(value.c_str()));
887            else if (type.isReal())
888                setRealValue(object, atof(value.c_str()));
889            else if (type.isBool())
890                setBoolValue(object, atof(value.c_str()));
891            else if (type.isEnum())
892                setEnumValue(object, atoll(value.c_str()));
893            else
894                throw Exception("Not a primitive data type");
895        }
896    
897        String Archive::valueAsString(const Object& object) {
898            if (!object)
899                throw Exception("Invalid object");
900            if (object.type().isClass())
901                throw Exception("Object is class type");
902            const Object* pObject = &object;
903            if (object.type().isPointer()) {
904                const Object& obj = objectByUID(object.uid(1));
905                if (!obj) return "";
906                pObject = &obj;
907            }
908            return _primitiveObjectValueToString(*pObject);
909        }
910    
911      // *************** Archive::Syncer ***************      // *************** Archive::Syncer ***************
912      // *      // *
913    

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

  ViewVC Help
Powered by ViewVC