/Utilities/WCell.Util/Data/BinaryPersistors.cs
C# | 521 lines | 433 code | 73 blank | 15 comment | 29 complexity | d75233c74e2e13c1604fa942d2f042c3 MD5 | raw file
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.IO;
6using System.Collections;
7using WCell.Util.DB;
8
9namespace WCell.Util.Data
10{
11 public interface IComplexBinaryPersistor : IBinaryPersistor
12 {
13 }
14
15 public interface ISimpleBinaryPersistor : IBinaryPersistor
16 {
17 int BinaryLength { get; }
18 }
19
20 public interface IBinaryPersistor
21 {
22 void Write(BinaryWriter writer, object obj);
23
24 object Read(BinaryReader reader);
25 }
26
27 public interface IStringPersistor
28 {
29 void WriteText(BinaryWriter writer, string text);
30
31 object ReadText(BinaryReader reader);
32 }
33
34 public class ArrayPersistor : IComplexBinaryPersistor
35 {
36 private readonly ArrayDataField m_DataField;
37 private IBinaryPersistor m_UnderlyingPersistor;
38
39 public ArrayPersistor(ArrayDataField field)
40 {
41 m_DataField = field;
42 m_UnderlyingPersistor = BinaryPersistors.GetPersistorNoArray(m_DataField);
43 }
44
45 public ArrayDataField DataField
46 {
47 get { return m_DataField; }
48 }
49
50 public IBinaryPersistor UnderlyingPersistor
51 {
52 get { return m_UnderlyingPersistor; }
53 }
54
55 //public int BinaryLength
56 //{
57 // get { return m_UnderlyingPersistor.BinaryLength * m_DataField.Length; }
58 //}
59
60 public void Write(BinaryWriter writer, object obj)
61 {
62 var i = 0;
63 if (obj != null)
64 {
65 for (; i < ((Array) obj).Length; i++)
66 {
67 var item = ((Array) obj).GetValue(i);
68 m_UnderlyingPersistor.Write(writer, item);
69 }
70 }
71
72 if (i < m_DataField.Length)
73 {
74 // write default Item as a filler
75 var type = m_DataField.MappedMember.GetActualType();
76
77 object deflt;
78 if (type == typeof(string))
79 {
80 deflt = "";
81 }
82 else
83 {
84 deflt = Activator.CreateInstance(type);
85 }
86
87 for (; i < m_DataField.Length; i++)
88 {
89 m_UnderlyingPersistor.Write(writer, deflt);
90 }
91 }
92 }
93
94 public object Read(BinaryReader reader)
95 {
96 var arr = (Array)m_DataField.ArrayProducer.Produce();
97 for (var i = 0; i < m_DataField.Length; i++)
98 {
99 object obj;
100 if (m_UnderlyingPersistor is NestedPersistor)
101 {
102 obj = arr.GetValue(i);
103 ((NestedPersistor)m_UnderlyingPersistor).Read(reader, ref obj);
104 }
105 else
106 {
107 obj = m_UnderlyingPersistor.Read(reader);
108 }
109 ArrayUtil.SetValue(arr, i, obj);
110 }
111 return arr;
112 }
113 }
114
115 public class NestedPersistor : IComplexBinaryPersistor
116 {
117 private readonly INestedDataField m_DataField;
118 private IBinaryPersistor[] m_UnderlyingPersistors;
119 private IGetterSetter[] m_accessors;
120
121 public NestedPersistor(
122 INestedDataField dataField)
123 {
124 m_DataField = dataField;
125 m_UnderlyingPersistors = new IBinaryPersistor[m_DataField.InnerFields.Count];
126 m_accessors = new IGetterSetter[m_DataField.InnerFields.Count];
127 var i = 0;
128 foreach (var field in m_DataField.InnerFields.Values)
129 {
130 var persistor = BinaryPersistors.GetPersistor(field);
131 m_UnderlyingPersistors[i] = persistor;
132 m_accessors[i] = field.Accessor;
133 i++;
134 }
135 }
136
137 public INestedDataField DataField
138 {
139 get { return m_DataField; }
140 }
141
142 public IBinaryPersistor[] UnderlyingPersistors
143 {
144 get { return m_UnderlyingPersistors; }
145 }
146
147 public void Write(BinaryWriter writer, object obj)
148 {
149 if (obj == null)
150 {
151 obj = m_DataField.Producer.Produce();
152 }
153
154 for (var i = 0; i < m_UnderlyingPersistors.Length; i++)
155 {
156 var persistor = m_UnderlyingPersistors[i];
157 var val = m_accessors[i].Get(obj);
158 persistor.Write(writer, val);
159 }
160 }
161
162 public object Read(BinaryReader reader)
163 {
164 object obj = null;
165
166 Read(reader, ref obj);
167
168 return obj;
169 }
170
171 public void Read(BinaryReader reader, ref object obj)
172 {
173 if (obj == null)
174 {
175 if (m_DataField.Producer != null)
176 {
177 obj = m_DataField.Producer.Produce();
178 }
179 else
180 {
181 obj = Activator.CreateInstance(m_DataField.BelongsTo.GetActualType());
182 }
183
184 }
185 for (var i = 0; i < m_UnderlyingPersistors.Length; i++)
186 {
187 var persistor = m_UnderlyingPersistors[i];
188 var val = persistor.Read(reader);
189 m_accessors[i].Set(obj, val);
190 }
191 }
192 }
193
194 public static class BinaryPersistors
195 {
196 public static readonly Dictionary<Type, ISimpleBinaryPersistor> SimplePersistors =
197 new Dictionary<Type, ISimpleBinaryPersistor>();
198
199 public static Encoding DefaultEncoding = Encoding.UTF8;
200
201 static BinaryPersistors()
202 {
203 SimplePersistors[typeof(int)] = new Int32Persistor();
204 SimplePersistors[typeof(uint)] = new UInt32Persistor();
205 SimplePersistors[typeof(short)] = new Int16Persistor();
206 SimplePersistors[typeof(ushort)] = new UInt16Persistor();
207 SimplePersistors[typeof(byte)] = new BytePersistor();
208 SimplePersistors[typeof(sbyte)] = new SBytePersistor();
209 SimplePersistors[typeof(long)] = new Int64Persistor();
210 SimplePersistors[typeof(ulong)] = new UInt64Persistor();
211 SimplePersistors[typeof(float)] = new FloatPersistor();
212 SimplePersistors[typeof(double)] = new DoublePersistor();
213 SimplePersistors[typeof(string)] = new StringPersistor();
214 SimplePersistors[typeof(bool)] = new BoolPersistor();
215 }
216
217 public static ISimpleBinaryPersistor GetSimplePersistor(Type type)
218 {
219 ISimpleBinaryPersistor persistor;
220 if (type.IsEnum)
221 {
222 type = Enum.GetUnderlyingType(type);
223 }
224 SimplePersistors.TryGetValue(type, out persistor);
225 if (persistor is FloatPersistor)
226 {
227 type.ToString();
228 }
229 return persistor;
230 }
231
232 /// <summary>
233 /// Returns null if its a String field
234 /// </summary>
235 /// <param name="field"></param>
236 /// <returns></returns>
237 public static IBinaryPersistor GetPersistor(IDataField field)
238 {
239 if (field.DataFieldType == DataFieldType.FlatArray ||
240 field.DataFieldType == DataFieldType.NestedArray)
241 {
242 return new ArrayPersistor((ArrayDataField)field);
243 }
244 else
245 {
246 return GetPersistorNoArray(field);
247 }
248 }
249
250 public static IBinaryPersistor GetPersistorNoArray(IDataField field)
251 {
252 var type = field.MappedMember.GetActualType();
253 if (field is INestedDataField)
254 {
255 // nested
256 return new NestedPersistor((INestedDataField)field);
257 }
258 else
259 {
260 // simple
261 var persistor = GetSimplePersistor(type);
262 if (persistor == null)
263 {
264 throw new DataHolderException("Simple Type did not have a binary Persistor: " + type.FullName);
265 }
266 return persistor;
267 }
268 }
269 }
270
271 public abstract class SimpleBinaryPersistor : ISimpleBinaryPersistor
272 {
273 public abstract int BinaryLength
274 {
275 get;
276 }
277
278 public abstract void Write(BinaryWriter writer, object obj);
279
280 public abstract object Read(BinaryReader reader);
281
282 public int InitPersistor(List<IGetterSetter> stringPersistors)
283 {
284 return BinaryLength;
285 }
286 }
287
288 public class BoolPersistor : SimpleBinaryPersistor
289 {
290 public override int BinaryLength
291 {
292 get { return 1; }
293 }
294
295 public override void Write(BinaryWriter writer, object obj)
296 {
297 writer.Write((byte)((bool)obj ? 1 : 0));
298 }
299
300 public override object Read(BinaryReader reader)
301 {
302 return reader.ReadByte() == 1;
303 }
304 }
305
306 public class Int32Persistor : SimpleBinaryPersistor
307 {
308 public override int BinaryLength
309 {
310 get { return 4; }
311 }
312
313 public override void Write(BinaryWriter writer, object obj)
314 {
315 writer.Write((int)obj);
316 }
317
318 public override object Read(BinaryReader reader)
319 {
320 return reader.ReadInt32();
321 }
322 }
323
324 public class StringPersistor : SimpleBinaryPersistor
325 {
326 /// <summary>
327 /// Redundant
328 /// </summary>
329 public override int BinaryLength
330 {
331 get { return -1; }
332 }
333
334 public override void Write(BinaryWriter writer, object obj)
335 {
336 if (string.IsNullOrEmpty(obj as string))
337 {
338 writer.Write((ushort)0);
339 }
340 else
341 {
342 var bytes = BinaryPersistors.DefaultEncoding.GetBytes((string) obj);
343 writer.Write((ushort) bytes.Length);
344 writer.Write(bytes);
345 }
346 }
347
348 public override object Read(BinaryReader reader)
349 {
350 var len = reader.ReadUInt16();
351 if (len == 0)
352 {
353 return "";
354 }
355 var bytes = reader.ReadBytes(len);
356 return BinaryPersistors.DefaultEncoding.GetString(bytes);
357 }
358 }
359
360 public class UInt32Persistor : SimpleBinaryPersistor
361 {
362 public override int BinaryLength
363 {
364 get { return 4; }
365 }
366
367 public override void Write(BinaryWriter writer, object obj)
368 {
369 writer.Write((uint)obj);
370 }
371
372 public override object Read(BinaryReader reader)
373 {
374 return reader.ReadUInt32();
375 }
376 }
377
378 public class Int16Persistor : SimpleBinaryPersistor
379 {
380 public override int BinaryLength
381 {
382 get { return 2; }
383 }
384
385 public override void Write(BinaryWriter writer, object obj)
386 {
387 writer.Write((short)obj);
388 }
389
390 public override object Read(BinaryReader reader)
391 {
392 return reader.ReadInt16();
393 }
394 }
395
396 public class UInt16Persistor : SimpleBinaryPersistor
397 {
398 public override int BinaryLength
399 {
400 get { return 2; }
401 }
402
403 public override void Write(BinaryWriter writer, object obj)
404 {
405 writer.Write((ushort)obj);
406 }
407
408 public override object Read(BinaryReader reader)
409 {
410 return reader.ReadUInt16();
411 }
412 }
413
414 public class BytePersistor : SimpleBinaryPersistor
415 {
416 public override int BinaryLength
417 {
418 get { return 1; }
419 }
420
421 public override void Write(BinaryWriter writer, object obj)
422 {
423 writer.Write((byte)obj);
424 }
425
426 public override object Read(BinaryReader reader)
427 {
428 return reader.ReadByte();
429 }
430 }
431
432 public class SBytePersistor : SimpleBinaryPersistor
433 {
434 public override int BinaryLength
435 {
436 get { return 1; }
437 }
438
439 public override void Write(BinaryWriter writer, object obj)
440 {
441 writer.Write((sbyte)obj);
442 }
443
444 public override object Read(BinaryReader reader)
445 {
446 return reader.ReadSByte();
447 }
448 }
449
450 public class Int64Persistor : SimpleBinaryPersistor
451 {
452 public override int BinaryLength
453 {
454 get { return 8; }
455 }
456
457 public override void Write(BinaryWriter writer, object obj)
458 {
459 writer.Write((long)obj);
460 }
461
462 public override object Read(BinaryReader reader)
463 {
464 return reader.ReadInt64();
465 }
466 }
467
468 public class UInt64Persistor : SimpleBinaryPersistor
469 {
470 public override int BinaryLength
471 {
472 get { return 8; }
473 }
474
475 public override void Write(BinaryWriter writer, object obj)
476 {
477 writer.Write((ulong)obj);
478 }
479
480 public override object Read(BinaryReader reader)
481 {
482 return reader.ReadUInt64();
483 }
484 }
485
486 public class FloatPersistor : SimpleBinaryPersistor
487 {
488 public override int BinaryLength
489 {
490 get { return 4; }
491 }
492
493 public override void Write(BinaryWriter writer, object obj)
494 {
495 writer.Write((float)obj);
496 }
497
498 public override object Read(BinaryReader reader)
499 {
500 return reader.ReadSingle();
501 }
502 }
503
504 public class DoublePersistor : SimpleBinaryPersistor
505 {
506 public override int BinaryLength
507 {
508 get { return 8; }
509 }
510
511 public override void Write(BinaryWriter writer, object obj)
512 {
513 writer.Write((double)obj);
514 }
515
516 public override object Read(BinaryReader reader)
517 {
518 return reader.ReadSingle();
519 }
520 }
521}