Mercurial > projects > orange
annotate orange/serialization/Serializer.d @ 25:b51e953f79eb experimental
Second step in refactoring the API.
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Wed, 06 Oct 2010 16:18:02 +0200 |
parents | 9a575087b961 |
children | 78e5fef4bbf2 |
rev | line source |
---|---|
0 | 1 /** |
2 * Copyright: Copyright (c) 2010 Jacob Carlborg. | |
3 * Authors: Jacob Carlborg | |
4 * Version: Initial created: Jan 26, 2010 | |
5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) | |
6 */ | |
7 module orange.serialization.Serializer; | |
8 | |
9 version (Tango) | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
8
diff
changeset
|
10 import tango.util.Convert : to, ConversionException; |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
8
diff
changeset
|
11 |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
8
diff
changeset
|
12 else |
0 | 13 { |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
8
diff
changeset
|
14 import std.conv; |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
8
diff
changeset
|
15 alias ConvError ConversionException; |
0 | 16 } |
17 | |
18 import orange.serialization._; | |
19 import orange.serialization.archives._; | |
20 import orange.util._; | |
21 | |
22 private | |
23 { | |
24 alias orange.util.CTFE.contains ctfeContains; | |
20
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
25 |
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
26 enum Mode |
0 | 27 { |
28 serializing, | |
29 deserializing | |
30 } | |
31 | |
32 alias Mode.serializing serializing; | |
33 alias Mode.deserializing deserializing; | |
34 } | |
35 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
36 class Serializer |
0 | 37 { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
38 alias void delegate (ArchiveException exception, IArchive.IDataType data) ErrorCallback; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
39 alias IArchive.IDataType DataType; |
18
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
40 |
0 | 41 private |
42 { | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
43 ErrorCallback errorCallback_; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
44 IArchive archive; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
45 |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
46 size_t keyCounter; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
47 size_t idCounter; |
0 | 48 |
49 RegisterBase[string] serializers; | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
50 RegisterBase[string] deserializers; |
0 | 51 |
52 bool hasBegunSerializing; | |
53 bool hasBegunDeserializing; | |
18
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
54 |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
55 void delegate (ArchiveException exception, DataType data) throwOnErrorCallback; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
56 void delegate (ArchiveException exception, DataType data) doNothingOnErrorCallback; |
0 | 57 } |
58 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
59 this (IArchive archive) |
0 | 60 { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
61 this.archive = archive; |
18
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
62 |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
63 throwOnErrorCallback = (ArchiveException exception, IArchive.IDataType data) { throw exception; }; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
64 doNothingOnErrorCallback = (ArchiveException exception, IArchive.IDataType data) { /* do nothing */ }; |
18
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
65 |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
66 setThrowOnErrorCallback(); |
0 | 67 } |
68 | |
18
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
69 ErrorCallback errorCallback () |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
70 { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
71 return errorCallback_; |
18
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
72 } |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
73 |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
74 ErrorCallback errorCallback (ErrorCallback errorCallback) |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
75 { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
76 return errorCallback_ = errorCallback; |
18
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
77 } |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
78 |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
79 void setThrowOnErrorCallback () |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
80 { |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
81 errorCallback = throwOnErrorCallback; |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
82 } |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
83 |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
84 void setDoNothingOnErrorCallback () |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
85 { |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
86 errorCallback = doNothingOnErrorCallback; |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
87 } |
3d42ea434d46
Added an error callback. Fixes #3 and #4.
Jacob Carlborg <doob@me.com>
parents:
17
diff
changeset
|
88 |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
89 DataType serialize (T) (T value, string key = null) |
0 | 90 { |
91 if (!hasBegunSerializing) | |
92 hasBegunSerializing = true; | |
93 | |
20
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
94 serializeInternal(value, key); |
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
95 archive.postProcess; |
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
96 |
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
97 return archive.data; |
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
98 } |
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
99 |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
100 private void serializeInternal (T) (T value, string key = null) |
20
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
101 { |
0 | 102 if (!key) |
103 key = nextKey; | |
104 | |
105 archive.beginArchiving(); | |
106 | |
107 static if (isTypeDef!(T)) | |
108 serializeTypeDef(value, key); | |
109 | |
110 static if (isObject!(T)) | |
111 serializeObject(value, key); | |
112 | |
113 else static if (isStruct!(T)) | |
114 serializeStruct(value, key); | |
115 | |
116 else static if (isString!(T)) | |
117 serializeString(value, key); | |
118 | |
119 else static if (isArray!(T)) | |
120 serializeArray(value, key); | |
121 | |
122 else static if (isAssociativeArray!(T)) | |
123 serializeAssociativeArray(value, key); | |
124 | |
125 else static if (isPrimitive!(T)) | |
126 serializePrimitive(value, key); | |
127 | |
128 else static if (isPointer!(T)) | |
129 { | |
130 static if (isFunctionPointer!(T)) | |
2 | 131 goto error; |
0 | 132 |
133 else | |
134 serializePointer(value, key); | |
2 | 135 } |
0 | 136 |
137 else static if (isEnum!(T)) | |
138 serializeEnum(value, key); | |
139 | |
140 else | |
2 | 141 { |
142 error: | |
143 throw new SerializationException(format!(`The type "`, T, `" cannot be serialized.`), __FILE__, __LINE__); | |
144 } | |
0 | 145 } |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
146 |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
147 private void serializeObject (T) (T value, string key) |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
148 { |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
149 auto runtimeType = value.classinfo.name; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
150 |
0 | 151 triggerEvents(serializing, value, { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
152 archive.archiveObject(runtimeType, T.stringof, key, nextId, { |
0 | 153 if (runtimeType in serializers) |
154 { | |
155 auto wrapper = getSerializerWrapper!(T)(runtimeType); | |
156 wrapper(value, this, key); | |
157 } | |
158 | |
17
c4e7e64ffb67
Changed toData/fromData to take an instance of the serializer instead of the archive.
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
159 else static if (isSerializable!(T, Serializer)) |
0 | 160 value.toData(this, key); |
161 | |
162 else | |
163 { | |
164 if (isBaseClass(value)) | |
165 throw new SerializationException(`The object of the static type "` ~ T.stringof ~ `" have a different runtime type (` ~ runtimeType ~ `) and therefore needs to register a serializer for its type "` ~ runtimeType ~ `".`, __FILE__, __LINE__); | |
166 | |
2 | 167 objectStructSerializeHelper(value); |
0 | 168 } |
169 }); | |
170 }); | |
171 } | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
172 |
0 | 173 private void serializeStruct (T) (T value, DataType key) |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
174 { |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
175 auto type = T.stringof; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
176 |
0 | 177 triggerEvents(serializing, value, { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
178 archive.archive(type, key, nextId, { |
0 | 179 if (type in serializers) |
180 { | |
181 auto wrapper = getSerializerWrapper!(T)(type); | |
182 wrapper(value, this, key); | |
183 } | |
184 | |
185 else | |
186 { | |
17
c4e7e64ffb67
Changed toData/fromData to take an instance of the serializer instead of the archive.
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
187 static if (isSerializable!(T, Serializer)) |
0 | 188 value.toData(this, key); |
189 | |
190 else | |
2 | 191 objectStructSerializeHelper(value); |
0 | 192 } |
193 }); | |
194 }); | |
195 } | |
196 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
197 private void serializeString (T) (T value, string key) |
0 | 198 { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
199 archive.archive(value, key, nextId); |
0 | 200 } |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
201 |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
202 private void serializeArray (T) (T value, string key) |
20
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
203 { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
204 auto array = Array(value.ptr, value.length, BaseTypeOfArray!(T).sizeof); |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
205 |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
206 archive.archiveArray(array, arrayToString!(T), key, nextId, { |
0 | 207 foreach (i, e ; value) |
20
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
208 serializeInternal(e, toDataType(i)); |
0 | 209 }); |
210 } | |
211 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
212 private void serializePrimitive (T) (T value, string key) |
0 | 213 { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
214 archive.archive(value, key, nextId); |
0 | 215 } |
216 | |
3 | 217 private void objectStructSerializeHelper (T) (ref T value) |
218 { | |
219 static assert(isStruct!(T) || isObject!(T), format!(`The given value of the type "`, T, `" is not a valid type, the only valid types for this method are objects and structs.`)); | |
8 | 220 const nonSerializedFields = collectAnnotations!(nonSerializedField, T); |
3 | 221 |
222 foreach (i, dummy ; typeof(T.tupleof)) | |
223 { | |
224 const field = nameOfFieldAt!(T, i); | |
225 | |
226 static if (!internalFields.ctfeContains(field) && !nonSerializedFields.ctfeContains(field)) | |
227 { | |
228 alias typeof(T.tupleof[i]) Type; | |
229 Type v = value.tupleof[i]; | |
20
9a575087b961
Added support for slices. Strings and arrays are now treated as references.
Jacob Carlborg <doob@me.com>
parents:
18
diff
changeset
|
230 serializeInternal(v, toDataType(field)); |
3 | 231 } |
232 } | |
2 | 233 |
4
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
234 static if (isObject!(T) && !is(T == Object)) |
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
235 serializeBaseTypes(value); |
3 | 236 } |
237 | |
238 private void objectStructDeserializeHelper (T) (ref T value) | |
239 { | |
240 static assert(isStruct!(T) || isObject!(T), format!(`The given value of the type "`, T, `" is not a valid type, the only valid types for this method are objects and structs.`)); | |
8 | 241 const nonSerializedFields = collectAnnotations!(nonSerializedField, T); |
3 | 242 |
243 foreach (i, dummy ; typeof(T.tupleof)) | |
244 { | |
245 const field = nameOfFieldAt!(T, i); | |
246 | |
247 static if (!internalFields.ctfeContains(field) && !nonSerializedFields.ctfeContains(field)) | |
248 { | |
249 alias TypeOfField!(T, field) Type; | |
250 auto fieldValue = deserializeInternal!(Type)(toDataType(field)); | |
251 value.tupleof[i] = fieldValue; | |
252 } | |
253 } | |
4
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
254 |
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
255 static if (isObject!(T) && !is(T == Object)) |
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
256 deserializeBaseTypes(value); |
0 | 257 } |
258 | |
2 | 259 private void serializeBaseTypes (T : Object) (T value) |
0 | 260 { |
261 alias BaseTypeTupleOf!(T)[0] Base; | |
262 | |
263 static if (!is(Base == Object)) | |
264 { | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
265 archive.archiveBaseClass(Base.stringof, nextKey, nextId); |
4
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
266 Base base = value; |
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
267 objectStructSerializeHelper(base); |
0 | 268 } |
269 } | |
270 | |
2 | 271 private void deserializeBaseTypes (T : Object) (T value) |
0 | 272 { |
273 alias BaseTypeTupleOf!(T)[0] Base; | |
274 | |
275 static if (!is(Base == Object)) | |
276 { | |
277 archive.unarchiveBaseClass!(Base)(nextKey); | |
4
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
278 Base base = value; |
470ab5270d0c
Simplified the implementation of RegisterWrapper. Fixed: the base class of an object was not serialized
Jacob Carlborg <doob@me.com>
parents:
3
diff
changeset
|
279 objectStructDeserializeHelper(base); |
0 | 280 } |
281 } | |
282 | |
15
9f6064f9505a
Changed from archive to serializer in the register wrappers.
Jacob Carlborg <doob@me.com>
parents:
14
diff
changeset
|
283 private SerializeRegisterWrapper!(T, Serializer) getSerializerWrapper (T) (string type) |
0 | 284 { |
15
9f6064f9505a
Changed from archive to serializer in the register wrappers.
Jacob Carlborg <doob@me.com>
parents:
14
diff
changeset
|
285 auto wrapper = cast(SerializeRegisterWrapper!(T, Serializer)) serializers[type]; |
0 | 286 |
287 if (wrapper) | |
288 return wrapper; | |
289 | |
290 assert(false, "throw exception here"); | |
291 } | |
292 | |
15
9f6064f9505a
Changed from archive to serializer in the register wrappers.
Jacob Carlborg <doob@me.com>
parents:
14
diff
changeset
|
293 private DeserializeRegisterWrapper!(T, Serializer) getDeserializerWrapper (T) (string type) |
0 | 294 { |
15
9f6064f9505a
Changed from archive to serializer in the register wrappers.
Jacob Carlborg <doob@me.com>
parents:
14
diff
changeset
|
295 auto wrapper = cast(DeserializeRegisterWrapper!(T, Serializer)) deserializers[type]; |
0 | 296 |
297 if (wrapper) | |
298 return wrapper; | |
299 | |
300 assert(false, "throw exception here"); | |
301 } | |
302 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
303 private SerializeRegisterWrapper!(T, Serializer) toSerializeRegisterWrapper (T) (void delegate (T, Serializer, string) dg) |
0 | 304 { |
16
091ff1b263db
Missed some in the previous commit.
Jacob Carlborg <doob@me.com>
parents:
15
diff
changeset
|
305 return new SerializeRegisterWrapper!(T, Serializer)(dg); |
0 | 306 } |
307 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
308 private SerializeRegisterWrapper!(T, Serializer) toSerializeRegisterWrapper (T) (void function (T, Serializer, string) func) |
0 | 309 { |
16
091ff1b263db
Missed some in the previous commit.
Jacob Carlborg <doob@me.com>
parents:
15
diff
changeset
|
310 return new SerializeRegisterWrapper!(T, Serializer)(func); |
0 | 311 } |
312 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
313 private DeserializeRegisterWrapper!(T, Serializer) toDeserializeRegisterWrapper (T) (void delegate (ref T, Serializer, string) dg) |
0 | 314 { |
16
091ff1b263db
Missed some in the previous commit.
Jacob Carlborg <doob@me.com>
parents:
15
diff
changeset
|
315 return new DeserializeRegisterWrapper!(T, Serializer)(dg); |
0 | 316 } |
317 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
318 private DeserializeRegisterWrapper!(T, Serializer) toDeserializeRegisterWrapper (T) (void function (ref T, Serializer, string) func) |
0 | 319 { |
16
091ff1b263db
Missed some in the previous commit.
Jacob Carlborg <doob@me.com>
parents:
15
diff
changeset
|
320 return new DeserializeRegisterWrapper!(T, Serializer)(func); |
0 | 321 } |
322 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
323 private template arrayToString (T) |
0 | 324 { |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
325 const arrayToString = BaseTypeOfArray!(T).stringof; |
0 | 326 } |
327 | |
328 private bool isBaseClass (T) (T value) | |
329 { | |
330 auto name = value.classinfo.name; | |
331 auto index = name.lastIndexOf('.'); | |
332 | |
333 return T.stringof != name[index + 1 .. $]; | |
334 } | |
335 | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
336 private size_t nextId () |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
337 { |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
338 return idCounter++; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
339 } |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
340 |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
341 private string nextKey () |
0 | 342 { |
343 return toDataType(keyCounter++); | |
344 } | |
345 | |
346 private void resetCounters () | |
347 { | |
348 keyCounter = 0; | |
25
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
349 idCounter = 0; |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
350 } |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
351 |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
352 private string toDataType (T) (T value) |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
353 { |
b51e953f79eb
Second step in refactoring the API.
Jacob Carlborg <doob@me.com>
parents:
20
diff
changeset
|
354 return to!(string)(value); |
0 | 355 } |
356 | |
357 private void triggerEvent (string name, T) (T value) | |
358 { | |
3 | 359 static assert (isObject!(T) || isStruct!(T), format!(`The given value of the type "`, T, `" is not a valid type, the only valid types for this method are objects and structs.`)); |
0 | 360 |
361 foreach (i, dummy ; typeof(T.tupleof)) | |
362 { | |
363 const field = nameOfFieldAt!(T, i); | |
364 | |
365 static if (field == name) | |
366 { | |
367 alias TypeOfField!(T, field) Type; | |
368 auto event = getValueOfField!(T, Type, field)(value); | |
369 event(value); | |
370 } | |
371 } | |
372 } | |
373 | |
374 private void triggerEvents (T) (Mode mode, T value, void delegate () dg) | |
375 { | |
376 if (mode == serializing) | |
377 triggerEvent!(onSerializingField)(value); | |
378 | |
379 else | |
380 triggerEvent!(onDeserializingField)(value); | |
381 | |
382 dg(); | |
383 | |
384 if (mode == serializing) | |
385 triggerEvent!(onSerializedField)(value); | |
386 | |
387 else | |
388 triggerEvent!(onDeserializedField)(value); | |
389 } | |
390 | |
8 | 391 private static string[] collectAnnotations (string name, T) () |
0 | 392 { |
3 | 393 static assert (isObject!(T) || isStruct!(T), format!(`The given value of the type "`, T, `" is not a valid type, the only valid types for this method are objects and structs.`)); |
0 | 394 |
395 string[] annotations; | |
396 | |
8 | 397 foreach (i, type ; typeof(T.tupleof)) |
0 | 398 { |
399 const field = nameOfFieldAt!(T, i); | |
400 | |
401 static if (field == name) | |
8 | 402 annotations ~= type.field; |
0 | 403 } |
404 | |
405 return annotations; | |
406 } | |
407 } |