34 |
#include <string> |
#include <string> |
35 |
#include <vector> |
#include <vector> |
36 |
#include <map> |
#include <map> |
37 |
|
#include <time.h> |
38 |
|
|
39 |
|
#ifndef __has_extension |
40 |
|
# define __has_extension(x) 0 |
41 |
|
#endif |
42 |
|
|
43 |
|
#ifndef HAS_BUILTIN_TYPE_TRAITS |
44 |
|
# if __cplusplus >= 201103L |
45 |
|
# define HAS_BUILTIN_TYPE_TRAITS 1 |
46 |
|
# elif ( __has_extension(is_class) && __has_extension(is_enum) ) |
47 |
|
# define HAS_BUILTIN_TYPE_TRAITS 1 |
48 |
|
# elif ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3 ) ) |
49 |
|
# define HAS_BUILTIN_TYPE_TRAITS 1 |
50 |
|
# elif _MSC_VER >= 1400 /* MS Visual C++ 8.0 (Visual Studio 2005) */ |
51 |
|
# define HAS_BUILTIN_TYPE_TRAITS 1 |
52 |
|
# elif __INTEL_COMPILER >= 1100 |
53 |
|
# define HAS_BUILTIN_TYPE_TRAITS 1 |
54 |
|
# else |
55 |
|
# define HAS_BUILTIN_TYPE_TRAITS 0 |
56 |
|
# endif |
57 |
|
#endif |
58 |
|
|
59 |
|
#if !HAS_BUILTIN_TYPE_TRAITS |
60 |
|
# include <tr1/type_traits> |
61 |
|
# define LIBGIG_IS_CLASS(type) std::tr1::__is_union_or_class<type>::value //NOTE: without compiler support we cannot distinguish union from class |
62 |
|
#else |
63 |
|
# define LIBGIG_IS_CLASS(type) __is_class(type) |
64 |
|
#endif |
65 |
|
|
66 |
/** @brief Serialization / deserialization framework. |
/** @brief Serialization / deserialization framework. |
67 |
* |
* |
130 |
OPERATION_DESERIALIZE |
OPERATION_DESERIALIZE |
131 |
}; |
}; |
132 |
|
|
133 |
|
enum time_base_t { |
134 |
|
LOCAL_TIME, |
135 |
|
UTC_TIME |
136 |
|
}; |
137 |
|
|
138 |
template<typename T> |
template<typename T> |
139 |
bool IsEnum(const T& data) { |
bool IsEnum(const T& data) { |
140 |
|
#if !HAS_BUILTIN_TYPE_TRAITS |
141 |
|
return std::tr1::is_enum<T>::value; |
142 |
|
#else |
143 |
return __is_enum(T); |
return __is_enum(T); |
144 |
|
#endif |
145 |
} |
} |
146 |
|
|
147 |
template<typename T> |
template<typename T> |
148 |
bool IsUnion(const T& data) { |
bool IsUnion(const T& data) { |
149 |
|
#if !HAS_BUILTIN_TYPE_TRAITS |
150 |
|
return false; // without compiler support we cannot distinguish union from class |
151 |
|
#else |
152 |
return __is_union(T); |
return __is_union(T); |
153 |
|
#endif |
154 |
} |
} |
155 |
|
|
156 |
template<typename T> |
template<typename T> |
157 |
bool IsClass(const T& data) { |
bool IsClass(const T& data) { |
158 |
|
#if !HAS_BUILTIN_TYPE_TRAITS |
159 |
|
return std::tr1::__is_union_or_class<T>::value; // without compiler support we cannot distinguish union from class |
160 |
|
#else |
161 |
return __is_class(T); |
return __is_class(T); |
162 |
|
#endif |
163 |
} |
} |
164 |
|
|
165 |
/*template<typename T> |
/*template<typename T> |
201 |
template<typename T> |
template<typename T> |
202 |
struct Resolver { |
struct Resolver { |
203 |
static UID resolve(const T& obj) { |
static UID resolve(const T& obj) { |
204 |
return (UID) { (ID) &obj, sizeof(obj) }; |
const UID uid = { (ID) &obj, sizeof(obj) }; |
205 |
|
return uid; |
206 |
} |
} |
207 |
}; |
}; |
208 |
|
|
210 |
template<typename T> |
template<typename T> |
211 |
struct Resolver<T*> { |
struct Resolver<T*> { |
212 |
static UID resolve(const T* const & obj) { |
static UID resolve(const T* const & obj) { |
213 |
return (UID) { (ID) obj, sizeof(*obj) }; |
const UID uid = { (ID) obj, sizeof(*obj) }; |
214 |
|
return uid; |
215 |
} |
} |
216 |
}; |
}; |
217 |
}; |
}; |
225 |
typedef std::vector<UID> UIDChain; |
typedef std::vector<UID> UIDChain; |
226 |
|
|
227 |
// prototyping of private internal friend functions |
// prototyping of private internal friend functions |
228 |
|
static String _encodePrimitiveValue(const Object& obj); |
229 |
static DataType _popDataTypeBlob(const char*& p, const char* end); |
static DataType _popDataTypeBlob(const char*& p, const char* end); |
230 |
static Member _popMemberBlob(const char*& p, const char* end); |
static Member _popMemberBlob(const char*& p, const char* end); |
231 |
static Object _popObjectBlob(const char*& p, const char* end); |
static Object _popObjectBlob(const char*& p, const char* end); |
232 |
static void _popPrimitiveValue(const char*& p, const char* end, Object& obj); |
static void _popPrimitiveValue(const char*& p, const char* end, Object& obj); |
233 |
|
static String _primitiveObjectValueToString(const Object& obj); |
234 |
|
// | |
235 |
|
template<typename T> |
236 |
|
static T _primitiveObjectValueToNumber(const Object& obj); |
237 |
|
|
238 |
/** @brief Abstract reflection of a native C++ data type. |
/** @brief Abstract reflection of a native C++ data type. |
239 |
* |
* |
263 |
bool operator>(const DataType& other) const; |
bool operator>(const DataType& other) const; |
264 |
String asLongDescr() const; |
String asLongDescr() const; |
265 |
String baseTypeName() const { return m_baseTypeName; } |
String baseTypeName() const { return m_baseTypeName; } |
266 |
String customTypeName() const { return m_customTypeName; } |
String customTypeName(bool demangle = false) const; |
267 |
|
|
268 |
template<typename T> |
template<typename T> |
269 |
static DataType dataTypeOf(const T& data) { |
static DataType dataTypeOf(const T& data) { |
338 |
bool m_isPointer; |
bool m_isPointer; |
339 |
|
|
340 |
friend DataType _popDataTypeBlob(const char*& p, const char* end); |
friend DataType _popDataTypeBlob(const char*& p, const char* end); |
341 |
|
friend class Archive; |
342 |
}; |
}; |
343 |
|
|
344 |
/** @brief Abstract reflection of a native C++ class/struct's member variable. |
/** @brief Abstract reflection of a native C++ class/struct's member variable. |
412 |
std::vector<Member>& members() { return m_members; } |
std::vector<Member>& members() { return m_members; } |
413 |
const std::vector<Member>& members() const { return m_members; } |
const std::vector<Member>& members() const { return m_members; } |
414 |
Member memberNamed(String name) const; |
Member memberNamed(String name) const; |
415 |
void remove(const Member& member); |
Member memberByUID(const UID& uid) const; |
416 |
std::vector<Member> membersOfType(const DataType& type) const; |
std::vector<Member> membersOfType(const DataType& type) const; |
417 |
int sequenceIndexOf(const Member& member) const; |
int sequenceIndexOf(const Member& member) const; |
418 |
bool isValid() const; |
bool isValid() const; |
423 |
bool operator<(const Object& other) const; |
bool operator<(const Object& other) const; |
424 |
bool operator>(const Object& other) const; |
bool operator>(const Object& other) const; |
425 |
|
|
426 |
|
protected: |
427 |
|
void remove(const Member& member); |
428 |
|
|
429 |
private: |
private: |
430 |
DataType m_type; |
DataType m_type; |
431 |
UIDChain m_uid; |
UIDChain m_uid; |
434 |
RawData m_data; |
RawData m_data; |
435 |
std::vector<Member> m_members; |
std::vector<Member> m_members; |
436 |
|
|
437 |
|
friend String _encodePrimitiveValue(const Object& obj); |
438 |
friend Object _popObjectBlob(const char*& p, const char* end); |
friend Object _popObjectBlob(const char*& p, const char* end); |
439 |
friend void _popPrimitiveValue(const char*& p, const char* end, Object& obj); |
friend void _popPrimitiveValue(const char*& p, const char* end, Object& obj); |
440 |
|
friend String _primitiveObjectValueToString(const Object& obj); |
441 |
|
|
442 |
|
template<typename T> |
443 |
|
friend T _primitiveObjectValueToNumber(const Object& obj); |
444 |
|
|
445 |
|
friend class Archive; |
446 |
}; |
}; |
447 |
|
|
448 |
/** @brief Destination container for serialization, and source container for deserialization. |
/** @brief Destination container for serialization, and source container for deserialization. |
596 |
deserialize(&obj); |
deserialize(&obj); |
597 |
} |
} |
598 |
|
|
599 |
const RawData& rawData() const { return m_rawData; } |
const RawData& rawData(); |
600 |
virtual String rawDataFormat() const; |
virtual String rawDataFormat() const; |
601 |
|
|
602 |
template<typename T_classType, typename T_memberType> |
template<typename T_classType, typename T_memberType> |
630 |
virtual void decode(const RawData& data); |
virtual void decode(const RawData& data); |
631 |
virtual void decode(const uint8_t* data, size_t size); |
virtual void decode(const uint8_t* data, size_t size); |
632 |
void clear(); |
void clear(); |
633 |
|
bool isModified() const; |
634 |
|
void removeMember(Object& parent, const Member& member); |
635 |
void remove(const Object& obj); |
void remove(const Object& obj); |
636 |
Object& rootObject(); |
Object& rootObject(); |
637 |
Object& objectByUID(const UID& uid); |
Object& objectByUID(const UID& uid); |
638 |
|
void setAutoValue(Object& object, String value); |
639 |
|
void setIntValue(Object& object, int64_t value); |
640 |
|
void setRealValue(Object& object, double value); |
641 |
|
void setBoolValue(Object& object, bool value); |
642 |
|
void setEnumValue(Object& object, uint64_t value); |
643 |
|
String valueAsString(const Object& object); |
644 |
|
int64_t valueAsInt(const Object& object); |
645 |
|
double valueAsReal(const Object& object); |
646 |
|
bool valueAsBool(const Object& object); |
647 |
|
String name() const; |
648 |
|
void setName(String name); |
649 |
|
String comment() const; |
650 |
|
void setComment(String comment); |
651 |
|
time_t timeStampCreated() const; |
652 |
|
time_t timeStampModified() const; |
653 |
|
tm dateTimeCreated(time_base_t base = LOCAL_TIME) const; |
654 |
|
tm dateTimeModified(time_base_t base = LOCAL_TIME) const; |
655 |
|
|
656 |
protected: |
protected: |
657 |
// UID resolver for non-pointer types |
// UID resolver for non-pointer types |
673 |
class UIDChainResolver<T*> { |
class UIDChainResolver<T*> { |
674 |
public: |
public: |
675 |
UIDChainResolver(const T*& data) { |
UIDChainResolver(const T*& data) { |
676 |
m_uid.push_back((UID) { &data, sizeof(data) }); |
const UID uids[2] = { |
677 |
m_uid.push_back((UID) { data, sizeof(*data) }); |
{ &data, sizeof(data) }, |
678 |
|
{ data, sizeof(*data) } |
679 |
|
}; |
680 |
|
m_uid.push_back(uids[0]); |
681 |
|
m_uid.push_back(uids[1]); |
682 |
} |
} |
683 |
|
|
684 |
operator UIDChain() const { return m_uid; } |
operator UIDChain() const { return m_uid; } |
718 |
|
|
719 |
// Automatically handles recursion for class/struct types, while ignoring all primitive types. |
// Automatically handles recursion for class/struct types, while ignoring all primitive types. |
720 |
template<typename T> |
template<typename T> |
721 |
struct SerializationRecursion : SerializationRecursionImpl<T, __is_class(T)> { |
struct SerializationRecursion : SerializationRecursionImpl<T, LIBGIG_IS_CLASS(T)> { |
722 |
}; |
}; |
723 |
|
|
724 |
class ObjectPool : public std::map<UID,Object> { |
class ObjectPool : public std::map<UID,Object> { |
762 |
operation_t m_operation; |
operation_t m_operation; |
763 |
UID m_root; |
UID m_root; |
764 |
RawData m_rawData; |
RawData m_rawData; |
765 |
|
bool m_isModified; |
766 |
|
String m_name; |
767 |
|
String m_comment; |
768 |
|
time_t m_timeCreated; |
769 |
|
time_t m_timeModified; |
770 |
}; |
}; |
771 |
|
|
772 |
/** |
/** |