PageRenderTime 84ms CodeModel.GetById 24ms app.highlight 47ms RepoModel.GetById 0ms app.codeStats 0ms

/Utilities/WCell.Util/Data/BinaryPersistors.cs

https://github.com/enjoii/WCell
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}