/[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 3146 by schoenebeck, Wed May 3 19:54:08 2017 UTC revision 3150 by schoenebeck, Fri May 5 18:42:06 2017 UTC
# Line 190  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 268  namespace Serialization { Line 268  namespace Serialization {
268      Archive::Archive() {      Archive::Archive() {
269          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
270          m_root = NO_UID;          m_root = NO_UID;
271            m_isModified = false;
272      }      }
273    
274      Archive::Archive(const RawData& data) {      Archive::Archive(const RawData& data) {
275          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
276          m_root = NO_UID;          m_root = NO_UID;
277            m_isModified = false;
278          decode(m_rawData);          decode(m_rawData);
279      }      }
280    
281      Archive::Archive(const uint8_t* data, size_t size) {      Archive::Archive(const uint8_t* data, size_t size) {
282          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
283          m_root = NO_UID;          m_root = NO_UID;
284            m_isModified = false;
285          decode(data, size);          decode(data, size);
286      }      }
287    
# Line 332  namespace Serialization { Line 335  namespace Serialization {
335          return _encodeBlob(s);          return _encodeBlob(s);
336      }      }
337    
338      static String _encodePrimitiveValue(const Object& obj) {      static String _primitiveObjectValueToString(const Object& obj) {
339          String s;          String s;
340          const DataType& type = obj.type();          const DataType& type = obj.type();
341          const ID& id = obj.uid().id;          const ID& id = obj.uid().id;
342            void* ptr = obj.m_data.empty() ? (void*)id : (void*)&obj.m_data[0];
343            if (!obj.m_data.empty())
344                assert(type.size() == obj.m_data.size());
345          if (type.isPrimitive() && !type.isPointer()) {          if (type.isPrimitive() && !type.isPointer()) {
346              if (type.isInteger() || type.isEnum()) {              if (type.isInteger() || type.isEnum()) {
347                  if (type.isSigned()) {                  if (type.isSigned()) {
348                      if (type.size() == 1)                      if (type.size() == 1)
349                          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
350                      else if (type.size() == 2)                      else if (type.size() == 2)
351                          s = ToString(*(int16_t*)id);                          s = ToString(*(int16_t*)ptr);
352                      else if (type.size() == 4)                      else if (type.size() == 4)
353                          s = ToString(*(int32_t*)id);                          s = ToString(*(int32_t*)ptr);
354                      else if (type.size() == 8)                      else if (type.size() == 8)
355                          s = ToString(*(int64_t*)id);                          s = ToString(*(int64_t*)ptr);
356                      else                      else
357                          assert(false /* unknown signed int type size */);                          assert(false /* unknown signed int type size */);
358                  } else {                  } else {
359                      if (type.size() == 1)                      if (type.size() == 1)
360                          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
361                      else if (type.size() == 2)                      else if (type.size() == 2)
362                          s = ToString(*(uint16_t*)id);                          s = ToString(*(uint16_t*)ptr);
363                      else if (type.size() == 4)                      else if (type.size() == 4)
364                          s = ToString(*(uint32_t*)id);                          s = ToString(*(uint32_t*)ptr);
365                      else if (type.size() == 8)                      else if (type.size() == 8)
366                          s = ToString(*(uint64_t*)id);                          s = ToString(*(uint64_t*)ptr);
367                      else                      else
368                          assert(false /* unknown unsigned int type size */);                          assert(false /* unknown unsigned int type size */);
369                  }                  }
370              } else if (type.isReal()) {              } else if (type.isReal()) {
371                  if (type.size() == sizeof(float))                  if (type.size() == sizeof(float))
372                      s = ToString(*(float*)id);                      s = ToString(*(float*)ptr);
373                  else if (type.size() == sizeof(double))                  else if (type.size() == sizeof(double))
374                      s = ToString(*(double*)id);                      s = ToString(*(double*)ptr);
375                  else                  else
376                      assert(false /* unknown floating point type */);                      assert(false /* unknown floating point type */);
377              } else if (type.isBool()) {              } else if (type.isBool()) {
378                  s = ToString(*(bool*)id);                  s = ToString(*(bool*)ptr);
379              } else {              } else {
380                  assert(false /* unknown primitive type */);                  assert(false /* unknown primitive type */);
381              }              }
382    
383          }          }
384          return _encodeBlob(s);          return s;
385        }
386    
387        static String _encodePrimitiveValue(const Object& obj) {
388            return _encodeBlob( _primitiveObjectValueToString(obj) );
389      }      }
390    
391      static String _encode(const Object& obj) {      static String _encode(const Object& obj) {
# Line 417  namespace Serialization { Line 427  namespace Serialization {
427          s += _encodeRootBlob();          s += _encodeRootBlob();
428          m_rawData.resize(s.length() + 1);          m_rawData.resize(s.length() + 1);
429          memcpy(&m_rawData[0], &s[0], s.length() + 1);          memcpy(&m_rawData[0], &s[0], s.length() + 1);
430            m_isModified = false;
431      }      }
432    
433      struct _Blob {      struct _Blob {
# Line 697  namespace Serialization { Line 708  namespace Serialization {
708      void Archive::decode(const RawData& data) {      void Archive::decode(const RawData& data) {
709          m_rawData = data;          m_rawData = data;
710          m_allObjects.clear();          m_allObjects.clear();
711            m_isModified = false;
712          const char* p   = (const char*) &data[0];          const char* p   = (const char*) &data[0];
713          const char* end = p + data.size();          const char* end = p + data.size();
714          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 712  namespace Serialization { Line 724  namespace Serialization {
724          decode(rawData);          decode(rawData);
725      }      }
726    
727        const RawData& Archive::rawData() {
728            if (m_isModified) encode();
729            return m_rawData;
730        }
731    
732      String Archive::rawDataFormat() const {      String Archive::rawDataFormat() const {
733          return MAGIC_START;          return MAGIC_START;
734      }      }
735    
736        bool Archive::isModified() const {
737            return m_isModified;
738        }
739    
740      void Archive::clear() {      void Archive::clear() {
741          m_allObjects.clear();          m_allObjects.clear();
742          m_operation = OPERATION_NONE;          m_operation = OPERATION_NONE;
743          m_root = NO_UID;          m_root = NO_UID;
744          m_rawData.clear();          m_rawData.clear();
745            m_isModified = false;
746      }      }
747    
748      void Archive::remove(const Object& obj) {      void Archive::remove(const Object& obj) {
749          if (!obj.uid()) return;          if (!obj.uid()) return;
750          m_allObjects.erase(obj.uid());          m_allObjects.erase(obj.uid());
751            m_isModified = true;
752      }      }
753    
754      Object& Archive::objectByUID(const UID& uid) {      Object& Archive::objectByUID(const UID& uid) {
755          return m_allObjects[uid];          return m_allObjects[uid];
756      }      }
757    
758        void Archive::setEnumValue(Object& object, uint64_t value) {
759            if (!object) return;
760            if (!object.type().isEnum())
761                throw Exception("Not an enum data type");
762            Object* pObject = &object;
763            if (object.type().isPointer()) {
764                Object& obj = objectByUID(object.uid(1));
765                if (!obj) return;
766                pObject = &obj;
767            }
768            const int nativeEnumSize = sizeof(enum operation_t);
769            DataType& type = const_cast<DataType&>( pObject->type() );
770            // original serializer ("sender") might have had a different word size
771            // than this machine, adjust type object in this case
772            if (type.size() != nativeEnumSize) {
773                type.m_size = nativeEnumSize;
774            }
775            pObject->m_data.resize(type.size());
776            void* ptr = &pObject->m_data[0];
777            if (type.size() == 1)
778                *(uint8_t*)ptr = (uint8_t)value;
779            else if (type.size() == 2)
780                *(uint16_t*)ptr = (uint16_t)value;
781            else if (type.size() == 4)
782                *(uint32_t*)ptr = (uint32_t)value;
783            else if (type.size() == 8)
784                *(uint64_t*)ptr = (uint64_t)value;
785            else
786                assert(false /* unknown enum type size */);
787            m_isModified = true;
788        }
789    
790        void Archive::setIntValue(Object& object, int64_t value) {
791            if (!object) return;
792            if (!object.type().isInteger())
793                throw Exception("Not an integer data type");
794            Object* pObject = &object;
795            if (object.type().isPointer()) {
796                Object& obj = objectByUID(object.uid(1));
797                if (!obj) return;
798                pObject = &obj;
799            }
800            const DataType& type = pObject->type();
801            pObject->m_data.resize(type.size());
802            void* ptr = &pObject->m_data[0];
803            if (type.isSigned()) {
804                if (type.size() == 1)
805                    *(int8_t*)ptr = (int8_t)value;
806                else if (type.size() == 2)
807                    *(int16_t*)ptr = (int16_t)value;
808                else if (type.size() == 4)
809                    *(int32_t*)ptr = (int32_t)value;
810                else if (type.size() == 8)
811                    *(int64_t*)ptr = (int64_t)value;
812                else
813                    assert(false /* unknown signed int type size */);
814            } else {
815                if (type.size() == 1)
816                    *(uint8_t*)ptr = (uint8_t)value;
817                else if (type.size() == 2)
818                    *(uint16_t*)ptr = (uint16_t)value;
819                else if (type.size() == 4)
820                    *(uint32_t*)ptr = (uint32_t)value;
821                else if (type.size() == 8)
822                    *(uint64_t*)ptr = (uint64_t)value;
823                else
824                    assert(false /* unknown unsigned int type size */);
825            }
826            m_isModified = true;
827        }
828    
829        void Archive::setRealValue(Object& object, double value) {
830            if (!object) return;
831            if (!object.type().isReal())
832                throw Exception("Not a real data type");
833            Object* pObject = &object;
834            if (object.type().isPointer()) {
835                Object& obj = objectByUID(object.uid(1));
836                if (!obj) return;
837                pObject = &obj;
838            }
839            const DataType& type = pObject->type();
840            pObject->m_data.resize(type.size());
841            void* ptr = &pObject->m_data[0];
842            if (type.size() == sizeof(float))
843                *(float*)ptr = (float)value;
844            else if (type.size() == sizeof(double))
845                *(double*)ptr = (double)value;
846            else
847                assert(false /* unknown real type size */);
848            m_isModified = true;
849        }
850    
851        void Archive::setBoolValue(Object& object, bool value) {
852            if (!object) return;
853            if (!object.type().isBool())
854                throw Exception("Not a bool data type");
855            Object* pObject = &object;
856            if (object.type().isPointer()) {
857                Object& obj = objectByUID(object.uid(1));
858                if (!obj) return;
859                pObject = &obj;
860            }
861            const DataType& type = pObject->type();
862            pObject->m_data.resize(type.size());
863            bool* ptr = (bool*)&pObject->m_data[0];
864            *ptr = value;
865            m_isModified = true;
866        }
867    
868        void Archive::setAutoValue(Object& object, String value) {
869            if (!object) return;
870            const DataType& type = object.type();
871            if (type.isInteger())
872                setIntValue(object, atoll(value.c_str()));
873            else if (type.isReal())
874                setRealValue(object, atof(value.c_str()));
875            else if (type.isBool())
876                setBoolValue(object, atof(value.c_str()));
877            else if (type.isEnum())
878                setEnumValue(object, atoll(value.c_str()));
879            else
880                throw Exception("Not a primitive data type");
881        }
882    
883        String Archive::valueAsString(const Object& object) {
884            if (!object)
885                throw Exception("Invalid object");
886            if (object.type().isClass())
887                throw Exception("Object is class type");
888            const Object* pObject = &object;
889            if (object.type().isPointer()) {
890                const Object& obj = objectByUID(object.uid(1));
891                if (!obj) return "";
892                pObject = &obj;
893            }
894            return _primitiveObjectValueToString(*pObject);
895        }
896    
897      // *************** Archive::Syncer ***************      // *************** Archive::Syncer ***************
898      // *      // *
899    

Legend:
Removed from v.3146  
changed lines
  Added in v.3150

  ViewVC Help
Powered by ViewVC