程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 我做的一個C++用的Serialization庫(含部分源碼)

我做的一個C++用的Serialization庫(含部分源碼)

編輯:關於C++

眾所周知,boost裡面有一個Serialization。不過我這個跟boost的有本質上的差別。boost的Serialization是通過重載操作符將一個對象與一個流進行讀寫,而我則通過記錄類的成員變量來自動產生相應的讀寫動作。

不過我的Serialization庫有兩個缺點,就是效率不是特別高,因為我產生的是可以與XML進行互相轉換的通用對象。雖然這並不是必需的,只是我的個人愛好罷了。第二個缺點是Serialization會產生侵入式的代碼。使用方法如下:

首先改造需要被Serialize的類,使之成為一個Serializable Object:

1 class TestTree : public VL_SerializableObject
2 {
3 public:
4   VInt          IntegerMember;
5   VUnicodeString      StringMember;
6   VL_AutoPtr<TestTree>  LeftTree;
7   VL_AutoPtr<TestTree>  RightTree;
8
9   TestTree()
10   {
11     VL_REGISTER_SERIALIZABLE_FIELD(TestTree,IntegerMember);
12     VL_REGISTER_SERIALIZABLE_FIELD(TestTree,StringMember);
13     VL_REGISTER_SERIALIZABLE_FIELD(TestTree,LeftTree);
14     VL_REGISTER_SERIALIZABLE_FIELD(TestTree,RightTree);
15   }
16 };

其次構造一個VL_Serializer並對這個類進行注冊:

1 VL_Serializer Serializer;
2 VL_REGISTER_SERIALIZABLE_CLASS(&Serializer,TestTree);
  完成了!現在可以嘗試將一個對象通過Serializer轉換成XML:
1 VL_AutoPtr<TestTree> Root=new TestTree;
2 Root->IntegerMember=10;
3 Root->StringMember=L"Root";
4
5 VL_AutoPtr<TestTree> Left=new TestTree;
6 Left->IntegerMember=20;
7 Left->StringMember=L"Left";
8
9 VL_AutoPtr<TestTree> Right=new TestTree;
10 Right->IntegerMember=30;
11 Right->StringMember=L"Right";
12
13 Root->LeftTree=Left;
14 Root->RightTree=Right;
15
16 VL_CommonObject SerializedObject=Serializer.Serialize(Root.Object());
17 VL_XMLDocument Document;
18 Document.GetRootElement()->SetName(L"SerializedObject");
19 SerializedObject.SaveToXML(Document.GetRootElement());
20 VL_FileStream Stream(FileName,VL_FileStream::vfomWrite);
21 Document.Save(&Stream,true);

保存的那一段比較多,不過由於是死的,所以可以寫一個函數來完成這些事情。讓我們看看保存到文件裡面的XML吧:

1 <?xml version="1.0" encoding="gb2312" standalone="no" ?>
2 <SerializedObject>
3   <vcoClass TypeName="TestTree">
4     <vcoField FieldName="IntegerMember">
5       <vcoInt Value="0A000000" />
6     </vcoField>
7     <vcoField FieldName="LeftTree">
8       <vcoClass TypeName="TestTree">
9         <vcoField FieldName="IntegerMember">
10           <vcoInt Value="14000000" />
11         </vcoField>
12         <vcoField FieldName="LeftTree">
13           <vcoNull />
14         </vcoField>
15         <vcoField FieldName="RightTree">
16           <vcoNull />
17         </vcoField>
18         <vcoField FieldName="StringMember">
19           <vcoString Value="Left" />
20         </vcoField>
21       </vcoClass>
22     </vcoField>
23     <vcoField FieldName="RightTree">
24       <vcoClass TypeName="TestTree">
25         <vcoField FieldName="IntegerMember">
26           <vcoInt Value="1E000000" />
27         </vcoField>
28         <vcoField FieldName="LeftTree">
29           <vcoNull />
30         </vcoField>
31         <vcoField FieldName="RightTree">
32           <vcoNull />
33         </vcoField>
34         <vcoField FieldName="StringMember">
35           <vcoString Value="Right" />
36         </vcoField>
37       </vcoClass>
38     </vcoField>
39     <vcoField FieldName="StringMember">
40       <vcoString Value="Root" />
41     </vcoField>
42   </vcoClass>
43 </SerializedObject>

造這種東西出來是有特殊的目的的,並不打算將這個Serialization做成一個非常通用的Serialization。

關鍵部分的代碼如下:

頭文件:

1 /*******************************************************************************
2 Vczh Library++ 2.0
3 數據結構::序列化
4 開發者:陳梓瀚
5
6 接口:
7 類:
8 VL_SerializableObject :可序列化對象基類
9 VL_Serializer :序列化/反序列化處理器
10 函數:
11 VL_REGISTER_SERIALIZABLE_CLASS :注冊可序列化類型
12 VL_REGISTER_SERIALIZABLE_FIELD :注冊可序列化成員變量
13 *******************************************************************************/
14
15 #ifndef VL_SERIALIZATION
16 #define VL_SERIALIZATION
17
18 #include "Data\VL_Data_List.h"
19 #include "Data\VL_Data_Map.h"
20 #include "VL_CommonData.h"
21
22 namespace vl
23 {
24 namespace serialization
25 {
26 using namespace collection;
27 using namespace commondata;
28
29 class VL_Serializer;
30
31 class VL_SerializableObject : public VL_Base
32 {
33 protected:
34 class FieldSerializerBase : public VL_Base
35 {
36 public:
37 typedef VL_List<VL_AutoPtr<FieldSerializerBase> , false , FieldSerializerBase*> List;
38 protected:
39 VUnicodeString FFieldName;
40
41 public:
42 FieldSerializerBase(VUnicodeString FieldName);
43
44 virtual void Serialize(VL_Serializer* Serializer , VL_CommonObject& ClassObject)=0;
45 };
46
47 #define DECLARE_PRIMITIVE_SERIALIZER(FIELD) \
48 template<typename _Type> \
49 class FieldSerializer<_Type , FIELD> : public FieldSerializerBase \
50 { \
51 protected: \
52 _Type* FObject; \
53 FIELD _Type::* FFieldPointer; \
54 public: \
55 FieldSerializer(_Type* Object , FIELD _Type::* FieldPointer , VUnicodeString FieldName) \
56 :FieldSerializerBase(FieldName) \
57 { \
58 FObject=Object; \
59 FFieldPointer=FieldPointer; \
60 } \
61 \
62 void Serialize(VL_Serializer* Serializer , VL_CommonObject& ClassObject) \
63 { \
64 ClassObject.SetFieldValue(FFieldName,VL_CommonObject::CreatePrimitive(FObject->*FFieldPointer)); \
65 } \
66 }
67
68 template<typename _Type , typename _Field>
69 class FieldSerializer : public FieldSerializerBase
70 {
71 protected:
72 _Type* FObject;
73 _Field _Type::* FFieldPointer;
74 public:
75 FieldSerializer(_Type* Object , _Field _Type::* FieldPointer , VUnicodeString FieldName)
76 :FieldSerializerBase(FieldName)
77 {
78 FObject=Object;
79 FFieldPointer=FieldPointer;
80 }
81
82 void Serialize(VL_Serializer* Serializer , VL_CommonObject& ClassObject)
83 {
84 ClassObject.SetFieldValue(FFieldName,Serializer->Serialize(&(FObject->*FFieldPointer)));
85 }
86 };
87
88 DECLARE_PRIMITIVE_SERIALIZER(VBool);
89 DECLARE_PRIMITIVE_SERIALIZER(VByte);
90 DECLARE_PRIMITIVE_SERIALIZER(VInt);
91 DECLARE_PRIMITIVE_SERIALIZER(VFloat);
92 DECLARE_PRIMITIVE_SERIALIZER(VDouble);
93 DECLARE_PRIMITIVE_SERIALIZER(VSize);
94 DECLARE_PRIMITIVE_SERIALIZER(VChar);
95 DECLARE_PRIMITIVE_SERIALIZER(VWChar);
96 DECLARE_PRIMITIVE_SERIALIZER(VUnicodeString);
97
98 #undef DECLARE_PRIMITIVE_SERIALIZER
99
100 template<typename _Type , typename _Field>
101 class FieldSerializer<_Type , _Field*> : public FieldSerializerBase
102 {
103 protected:
104 _Type* FObject;
105 _Field* _Type::* FFieldPointer;
106 public:
107 FieldSerializer(_Type* Object , _Field* _Type::* FieldPointer , VUnicodeString FieldName)
108 :FieldSerializerBase(FieldName)
109 {
110 FObject=Object;
111 FFieldPointer=FieldPointer;
112 }
113
114 void Serialize(VL_Serializer* Serializer , VL_CommonObject& ClassObject)
115 {
116 ClassObject.SetFieldValue(FFieldName,Serializer->Serialize(FObject->*FFieldPointer));
117 }
118 };
119
120 template<typename _Type , typename _Field>
121 class FieldSerializer<_Type , VL_AutoPtr<_Field>> : public FieldSerializerBase
122 {
123 protected:
124 _Type* FObject;
125 VL_AutoPtr<_Field> _Type::* FFieldPointer;
126 public:
127 FieldSerializer(_Type* Object , VL_AutoPtr<_Field> _Type::* FieldPointer , VUnicodeString FieldName)
128 :FieldSerializerBase(FieldName)
129 {
130 FObject=Object;
131 FFieldPointer=FieldPointer;
132 }
133
134 void Serialize(VL_Serializer* Serializer , VL_CommonObject& ClassObject)
135 {
136 ClassObject.SetFieldValue(FFieldName,Serializer->Serialize((FObject->*FFieldPointer).Object()));
137 }
138 };
139
140 template<typename _Type , typename _Field>
141 void AddFieldSerializer(_Type* Object , _Field _Type::* FieldPointer , VUnicodeString FieldName)
142 {
143 FFieldSerializers.Add(new FieldSerializer<_Type,_Field>(Object,FieldPointer,FieldName));
144 }
145 private:
146 FieldSerializerBase::List FFieldSerializers;
147 public:
148 VL_SerializableObject();
149 ~VL_SerializableObject();
150
151 virtual void Serialize(VL_Serializer* Serializer , VL_CommonObject& ClassObject);
152 virtual VBool Deserialize(VL_Serializer* Serializer , const VL_CommonObject& ClassObject);
153 };
154
155 class VL_Serializer : public VL_Base
156 {
157 public:
158 class ClassSerializerBase : public VL_Base
159 {
160 public:
161 typedef VL_List<VL_AutoPtr<ClassSerializerBase> , false , ClassSerializerBase*> List;
162 virtual VBool Accept(VL_SerializableObject* Object)=0;
163 virtual VUnicodeString GetClassTypeName()=0;
164 };
165
166 template<typename _Type>
167 class ClassSerializer : public ClassSerializerBase
168 {
169 protected:
170 VUnicodeString FClassTypeName;
171
172 public:
173 ClassSerializer(VUnicodeString ClassTypeName)
174 {
175 FClassTypeName=ClassTypeName;
176 }
177
178 VBool Accept(VL_SerializableObject* Object)
179 {
180 return dynamic_cast<_Type*>(Object)!=0;
181 }
182
183 VUnicodeString GetClassTypeName()
184 {
185 return FClassTypeName;
186 }
187 };
188 protected:
189 ClassSerializerBase::List FClassSerializers;
190 public:
191 VL_Serializer();
192 ~VL_Serializer();
193
194 void RegisterClass(ClassSerializerBase* aClassSerializer);
195 ClassSerializerBase* SelectClass(VL_SerializableObject* Object);
196 VL_CommonObject Serialize(VL_SerializableObject* Object);
197 };
198
199 template<typename _Type>
200 void GenericDeserializerMethod(VL_Serializer* Serializer , const VL_CommonObject& Object , VL_SerializableObject*& Result)
201 {
202 Result=new _Type();
203 Result->Deserialize(Serializer,Object);
204 }
205
206 #define VL_REGISTER_SERIALIZABLE_CLASS(SERIALIZER,CLASS) \
207 do{ \
208 (SERIALIZER)->RegisterClass(new VL_Serializer::ClassSerializer<CLASS>(L#CLASS)); \
209 }while(0)
210
211 #define VL_REGISTER_SERIALIZABLE_FIELD(CLASS,FIELD) \
212 do{ \
213 AddFieldSerializer(this,&CLASS::FIELD,L#FIELD); \
214 }while(0)
215 }
216 }
217
218 #endif

實現文件:

1 #include "VL_Serialization.h"
2
3 namespace vl
4 {
5   namespace serialization
6   {
7
8 /*********************************************************************************************************
9 VL_SerializableObject
10 *********************************************************************************************************/
11
12     VL_SerializableObject::FieldSerializerBase::FieldSerializerBase(VUnicodeString FieldName)
13     {
14       FFieldName=FieldName;
15     }
16
17     VL_SerializableObject::VL_SerializableObject()
18     {
19     }
20
21     VL_SerializableObject::~VL_SerializableObject()
22     {
23     }
24
25     void VL_SerializableObject::Serialize(VL_Serializer* Serializer , VL_CommonObject& ClassObject)
26     {
27       for(VInt i=0;i<FFieldSerializers.GetCount();i++)
28       {
29         FFieldSerializers[i]->Serialize(Serializer,ClassObject);
30       }
31     }
32
33     VBool VL_SerializableObject::Deserialize(VL_Serializer* Serializer , const VL_CommonObject& ClassObject)
34     {
35       return false;
36     }
37
38 /*********************************************************************************************************
39 VL_Serializer
40 *********************************************************************************************************/
41
42     VL_Serializer::VL_Serializer()
43     {
44     }
45
46     VL_Serializer::~VL_Serializer()
47     {
48     }
49
50     void VL_Serializer::RegisterClass(ClassSerializerBase* aClassSerializer)
51     {
52       FClassSerializers.Add(aClassSerializer);
53     }
54
55     VL_Serializer::ClassSerializerBase* VL_Serializer::SelectClass(VL_SerializableObject* Object)
56     {
57       for(VInt i=0;i<FClassSerializers.GetCount();i++)
58       {
59         ClassSerializerBase* Class=FClassSerializers[i].Object();
60         if(Class->Accept(Object))
61         {
62           return Class;
63         }
64       }
65       return 0;
66     }
67
68     VL_CommonObject VL_Serializer::Serialize(VL_SerializableObject* Object)
69     {
70       if(Object)
71       {
72         ClassSerializerBase* Class=SelectClass(Object);
73         if(Class)
74         {
75           VL_CommonObject ClassObject=VL_CommonObject::CreateClass(Class->GetClassTypeName());
76           Object->Serialize(this,ClassObject);
77           return ClassObject;
78         }
79         else
80         {
81           return VL_CommonObject::CreateError();
82         }
83       }
84       else
85       {
86         return VL_CommonObject::CreateNull();
87       }
88     }
89
90   }
91 }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved