124 |
|
|
125 |
typedef uint32_t Version; |
typedef uint32_t Version; |
126 |
|
|
|
enum operation_t { |
|
|
OPERATION_NONE, |
|
|
OPERATION_SERIALIZE, |
|
|
OPERATION_DESERIALIZE |
|
|
}; |
|
|
|
|
127 |
enum time_base_t { |
enum time_base_t { |
128 |
LOCAL_TIME, |
LOCAL_TIME, |
129 |
UTC_TIME |
UTC_TIME |
388 |
const UIDChain& uidChain() const { return m_uid; } |
const UIDChain& uidChain() const { return m_uid; } |
389 |
const DataType& type() const { return m_type; } |
const DataType& type() const { return m_type; } |
390 |
const RawData& rawData() const { return m_data; } |
const RawData& rawData() const { return m_data; } |
|
|
|
391 |
Version version() const { return m_version; } |
Version version() const { return m_version; } |
|
|
|
|
void setVersion(Version v) { |
|
|
m_version = v; |
|
|
} |
|
|
|
|
392 |
Version minVersion() const { return m_minVersion; } |
Version minVersion() const { return m_minVersion; } |
|
|
|
|
void setMinVersion(Version v) { |
|
|
m_minVersion = v; |
|
|
} |
|
|
|
|
393 |
bool isVersionCompatibleTo(const Object& other) const; |
bool isVersionCompatibleTo(const Object& other) const; |
|
|
|
394 |
std::vector<Member>& members() { return m_members; } |
std::vector<Member>& members() { return m_members; } |
395 |
const std::vector<Member>& members() const { return m_members; } |
const std::vector<Member>& members() const { return m_members; } |
396 |
Member memberNamed(String name) const; |
Member memberNamed(String name) const; |
407 |
|
|
408 |
protected: |
protected: |
409 |
void remove(const Member& member); |
void remove(const Member& member); |
410 |
|
void setVersion(Version v); |
411 |
|
void setMinVersion(Version v); |
412 |
|
|
413 |
private: |
private: |
414 |
DataType m_type; |
DataType m_type; |
541 |
* Note that there is only one method that you need to implement. So the |
* Note that there is only one method that you need to implement. So the |
542 |
* respective serialize() method implementation of your classes/structs are |
* respective serialize() method implementation of your classes/structs are |
543 |
* both called for serialization, as well as for deserialization! |
* both called for serialization, as well as for deserialization! |
544 |
|
* |
545 |
|
* In case you need to enforce backward incompatiblity for one of your C++ |
546 |
|
* classes, you can do so by setting a version and minimum version for your |
547 |
|
* class (see @c setVersion() and @c setMinVersion() for details). |
548 |
*/ |
*/ |
549 |
class Archive { |
class Archive { |
550 |
public: |
public: |
590 |
template<typename T_classType, typename T_memberType> |
template<typename T_classType, typename T_memberType> |
591 |
void serializeMember(const T_classType& nativeObject, const T_memberType& nativeMember, const char* memberName) { |
void serializeMember(const T_classType& nativeObject, const T_memberType& nativeMember, const char* memberName) { |
592 |
const size_t offset = |
const size_t offset = |
593 |
((const uint8_t*)(const void*)&nativeMember) - |
((const uint8_t*)(const void*)&nativeMember) - |
594 |
((const uint8_t*)(const void*)&nativeObject); |
((const uint8_t*)(const void*)&nativeObject); |
595 |
const UIDChain uids = UIDChainResolver<T_memberType>(nativeMember); |
const UIDChain uids = UIDChainResolver<T_memberType>(nativeMember); |
596 |
const DataType type = DataType::dataTypeOf(nativeMember); |
const DataType type = DataType::dataTypeOf(nativeMember); |
597 |
const Member member(memberName, uids[0], offset, type); |
const Member member(memberName, uids[0], offset, type); |
615 |
} |
} |
616 |
} |
} |
617 |
|
|
618 |
|
/** @brief Set version number for your C++ class. |
619 |
|
* |
620 |
|
* By calling this method you can store a version number for your |
621 |
|
* current C++ class (that is a version for its current data structure |
622 |
|
* layout and method implementations) with serialized archive. |
623 |
|
* |
624 |
|
* Along with calling @c setMinVersion() this provides a way for you |
625 |
|
* to constrain backward compatiblity regarding serialization and |
626 |
|
* deserialization of your class which the Archive class will obey to. |
627 |
|
* If required, then typically you might do so in your @c serialize() |
628 |
|
* method implementation like: |
629 |
|
* @code |
630 |
|
* #define SRLZ(member) \ |
631 |
|
* archive->serializeMember(*this, member, #member); |
632 |
|
* |
633 |
|
* void Foo::serialize(Serialization::Archive* archive) { |
634 |
|
* // when serializing: the current version of this class that is |
635 |
|
* // going to be stored with the serialized archive |
636 |
|
* archive->setVersion(*this, 6); |
637 |
|
* // when deserializing: the minimum allowed version of this class |
638 |
|
* // being serialized in the past |
639 |
|
* archive->setMinVersion(*this, 3); |
640 |
|
* // actual data mebers to serialize / deserialize |
641 |
|
* SRLZ(a); |
642 |
|
* SRLZ(b); |
643 |
|
* SRLZ(c); |
644 |
|
* } |
645 |
|
* @endcode |
646 |
|
* In this example above, the C++ clas "Foo" would be serialized along |
647 |
|
* with the version number @c 6 in the resulting archive (and its raw |
648 |
|
* data stream respectively). |
649 |
|
* |
650 |
|
* When deserializing archives with the example C++ class code above, |
651 |
|
* the Archive object would check whether your originally serialized |
652 |
|
* C++ "Foo" object had at least version number @c 3, if not the |
653 |
|
* deserialization process would automatically be stopped with a |
654 |
|
* @c Serialization::Exception, claiming that the classes are version |
655 |
|
* incompatible. |
656 |
|
* |
657 |
|
* Since this Serialization / deserialization framework is designed to |
658 |
|
* be robust on changes to your C++ classes and aims trying to |
659 |
|
* deserialize all your C++ objects correctly even if your C++ classes |
660 |
|
* have seen substantial software changes in the meantime; you might |
661 |
|
* sometimes see it as necessary to constrain backward compatiblity |
662 |
|
* this way. |
663 |
|
* |
664 |
|
* @param nativeObject - your C++ object you want to set a version for |
665 |
|
* @param v - the version number to set for your C++ class (by default, |
666 |
|
* that is if you do not explicitly call this method, then |
667 |
|
* your C++ object will be stored with version number @c 0 ). |
668 |
|
*/ |
669 |
|
template<typename T_classType> |
670 |
|
void setVersion(const T_classType& nativeObject, Version v) { |
671 |
|
const UID uid = UID::from(nativeObject); |
672 |
|
Object& obj = m_allObjects[uid]; |
673 |
|
if (!obj) { |
674 |
|
const UIDChain uids = UIDChainResolver<T_classType>(nativeObject); |
675 |
|
const DataType type = DataType::dataTypeOf(nativeObject); |
676 |
|
obj = Object(uids, type); |
677 |
|
} |
678 |
|
setVersion(obj, v); |
679 |
|
} |
680 |
|
|
681 |
|
/** @brief Set a minimum version number for your C++ class. |
682 |
|
* |
683 |
|
* Call this method to define a minimum version that your current C++ |
684 |
|
* class implementation would be compatible with when it comes to |
685 |
|
* deserialization of an archive containing an object with an older |
686 |
|
* version of your C++ class. |
687 |
|
* |
688 |
|
* @see @c setVersion() for more details about this overall topic. |
689 |
|
*/ |
690 |
|
template<typename T_classType> |
691 |
|
void setMinVersion(const T_classType& nativeObject, Version v) { |
692 |
|
const UID uid = UID::from(nativeObject); |
693 |
|
Object& obj = m_allObjects[uid]; |
694 |
|
if (!obj) { |
695 |
|
const UIDChain uids = UIDChainResolver<T_classType>(nativeObject); |
696 |
|
const DataType type = DataType::dataTypeOf(nativeObject); |
697 |
|
obj = Object(uids, type); |
698 |
|
} |
699 |
|
setMinVersion(obj, v); |
700 |
|
} |
701 |
|
|
702 |
virtual void decode(const RawData& data); |
virtual void decode(const RawData& data); |
703 |
virtual void decode(const uint8_t* data, size_t size); |
virtual void decode(const uint8_t* data, size_t size); |
704 |
void clear(); |
void clear(); |
716 |
int64_t valueAsInt(const Object& object); |
int64_t valueAsInt(const Object& object); |
717 |
double valueAsReal(const Object& object); |
double valueAsReal(const Object& object); |
718 |
bool valueAsBool(const Object& object); |
bool valueAsBool(const Object& object); |
719 |
|
void setVersion(Object& object, Version v); |
720 |
|
void setMinVersion(Object& object, Version v); |
721 |
String name() const; |
String name() const; |
722 |
void setName(String name); |
void setName(String name); |
723 |
String comment() const; |
String comment() const; |
830 |
Archive& m_src; |
Archive& m_src; |
831 |
}; |
}; |
832 |
|
|
833 |
|
enum operation_t { |
834 |
|
OPERATION_NONE, |
835 |
|
OPERATION_SERIALIZE, |
836 |
|
OPERATION_DESERIALIZE |
837 |
|
}; |
838 |
|
|
839 |
virtual void encode(); |
virtual void encode(); |
840 |
|
|
841 |
ObjectPool m_allObjects; |
ObjectPool m_allObjects; |