PackableDictionary.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using System;
  2. using System.Collections.Generic;
  3. namespace InABox.Core
  4. {
  5. public abstract class PackableDictionary<T> : Dictionary<string, T>, IPackable
  6. {
  7. public void Pack(FastBinaryWriter writer)
  8. {
  9. writer.Write(Count);
  10. foreach (var key in Keys)
  11. {
  12. writer.Write(key);
  13. PackItem(writer, this[key]);
  14. }
  15. }
  16. public void Unpack(FastBinaryReader reader)
  17. {
  18. Clear();
  19. var iCount = reader.ReadInt32();
  20. for (var i = 0; i < iCount; i++)
  21. {
  22. var key = reader.ReadString();
  23. this[key] = UnpackItem(reader);
  24. }
  25. }
  26. public override bool Equals(object obj)
  27. {
  28. var other = obj as PackableDictionary<T>;
  29. if (other == null)
  30. return false;
  31. if (Count != other.Count) // Require equal count.
  32. return false;
  33. foreach (var pair in this)
  34. if (other.TryGetValue(pair.Key, out var value))
  35. {
  36. if (value == null)
  37. {
  38. if (pair.Value != null)
  39. return false;
  40. }
  41. else if (!value.Equals(pair.Value))
  42. {
  43. return false;
  44. }
  45. }
  46. else
  47. {
  48. return false;
  49. }
  50. return true;
  51. }
  52. public abstract void PackItem(FastBinaryWriter writer, T value);
  53. public abstract T UnpackItem(FastBinaryReader reader);
  54. }
  55. public class PackableStringDictionary : PackableDictionary<string>
  56. {
  57. public override void PackItem(FastBinaryWriter writer, string value)
  58. {
  59. writer.Write(value);
  60. }
  61. public override string UnpackItem(FastBinaryReader reader)
  62. {
  63. return reader.ReadString();
  64. }
  65. }
  66. public class PackableBooleanDictionary : PackableDictionary<bool>
  67. {
  68. public override void PackItem(FastBinaryWriter writer, bool value)
  69. {
  70. writer.Write(value);
  71. }
  72. public override bool UnpackItem(FastBinaryReader reader)
  73. {
  74. return reader.ReadBoolean();
  75. }
  76. }
  77. public class PackableObjectDictionary : PackableDictionary<object>
  78. {
  79. private static readonly Dictionary<Type, short> Types = new Dictionary<Type, short>
  80. {
  81. { typeof(object), 0x0000 },
  82. { typeof(string), 0x0001 },
  83. { typeof(string[]), 0x002 },
  84. { typeof(sbyte), 0x1000 },
  85. { typeof(byte), 0x0011 },
  86. { typeof(ushort), 0x0012 },
  87. { typeof(uint), 0x0013 },
  88. { typeof(ulong), 0x0014 },
  89. { typeof(short), 0x0015 },
  90. { typeof(int), 0x0016 },
  91. { typeof(long), 0x0017 },
  92. { typeof(float), 0x0100 },
  93. { typeof(double), 0x0101 },
  94. { typeof(decimal), 0x0102 },
  95. { typeof(TimeSpan), 0x1000 },
  96. { typeof(DateTime), 0x1001 },
  97. { typeof(Guid), 0x1002 }
  98. };
  99. private static readonly Dictionary<short, Type> Indexes = new Dictionary<short, Type>();
  100. static PackableObjectDictionary()
  101. {
  102. foreach (var key in Types.Keys)
  103. Indexes[Types[key]] = key;
  104. }
  105. private static short GetIndex(Type type)
  106. {
  107. if (Types.ContainsKey(type))
  108. return Types[type];
  109. return 0x0000;
  110. }
  111. public static Type GetType(short index)
  112. {
  113. if (Indexes.ContainsKey(index))
  114. return Indexes[index];
  115. return typeof(object);
  116. }
  117. public override void PackItem(FastBinaryWriter writer, object value)
  118. {
  119. if (value == null)
  120. {
  121. writer.Write(default(short));
  122. writer.Write("");
  123. }
  124. else
  125. {
  126. var type = GetIndex(value.GetType());
  127. writer.Write(type);
  128. writer.Write(CoreUtils.TypedValueToString(value));
  129. }
  130. }
  131. public override object UnpackItem(FastBinaryReader reader)
  132. {
  133. var index = reader.ReadInt16();
  134. var type = GetType(index);
  135. var value = reader.ReadString();
  136. if (type == typeof(object) && string.IsNullOrEmpty(value))
  137. return null;
  138. return CoreUtils.StringToTypedValue(value, type);
  139. }
  140. }
  141. }