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