You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

328 lines
9.9 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. using Apewer.Internals;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Text;
  6. namespace Apewer
  7. {
  8. /// <summary></summary>
  9. public class BytesSet
  10. {
  11. private Dictionary<string, byte[]> _dict = new Dictionary<string, byte[]>();
  12. private volatile Func<byte[], byte[]> _inbound = null;
  13. private volatile Func<byte[], byte[]> _outbound = null;
  14. /// <summary></summary>
  15. public byte[] this[string key]
  16. {
  17. get { return GetValue(key); }
  18. set { SetValue(key, value); }
  19. }
  20. /// <summary>设置或获取值入站的函数,设置时字典必须为空。设置为 Null 将忽略入站函数。</summary>
  21. public Func<byte[], byte[]> Inbound
  22. {
  23. get { lock (_dict) return _inbound; }
  24. set { lock (_dict) _inbound = value; }
  25. }
  26. /// <summary>设置或获取值出站的函数。设置为 Null 将忽略出站函数。</summary>
  27. public Func<byte[], byte[]> Outbound
  28. {
  29. get { lock (_dict) return _outbound; }
  30. set { lock (_dict) _outbound = value; }
  31. }
  32. /// <summary></summary>
  33. public int Count
  34. {
  35. get
  36. {
  37. var count = 0;
  38. lock (_dict) { count = _dict.Count; }
  39. return count;
  40. }
  41. }
  42. /// <summary></summary>
  43. public List<string> Keys
  44. {
  45. get
  46. {
  47. var list = new List<string>();
  48. lock (_dict)
  49. {
  50. list.AddRange(_dict.Keys);
  51. }
  52. return list;
  53. }
  54. }
  55. /// <summary></summary>
  56. public BytesSet() { }
  57. /// <summary></summary>
  58. public BytesSet(Func<byte[], byte[]> inbound, Func<byte[], byte[]> outbound)
  59. {
  60. _inbound = inbound;
  61. _outbound = outbound;
  62. }
  63. /// <summary></summary>
  64. public void Clear()
  65. {
  66. lock (_dict)
  67. {
  68. foreach (var key in _dict.Keys)
  69. {
  70. _dict[key] = null;
  71. }
  72. _dict.Clear();
  73. }
  74. }
  75. /// <summary></summary>
  76. public bool Import(byte[] data)
  77. {
  78. var memory = new MemoryStream();
  79. lock (data)
  80. {
  81. if (data != null) memory.Write(data, 0, data.Length);
  82. BytesUtility.ResetPosition(memory);
  83. }
  84. if (memory.Length < 4) return false;
  85. var count = 0;
  86. var first = true;
  87. while (true)
  88. {
  89. if (!CanRead(memory, 4)) break;
  90. if (first)
  91. {
  92. var buffer = new byte[4];
  93. memory.Read(buffer, 0, 4);
  94. count = GetInt32(buffer);
  95. first = false;
  96. }
  97. else
  98. {
  99. // Read Key Length
  100. var keylength = 0;
  101. {
  102. if (!CanRead(memory, 4)) break;
  103. var buffer = new byte[4];
  104. memory.Read(buffer, 0, 4);
  105. keylength = GetInt32(buffer);
  106. }
  107. // Read Key Data
  108. var key = Constant.EmptyString;
  109. if (keylength > 1)
  110. {
  111. if (!CanRead(memory, keylength)) break;
  112. var buffer = new byte[keylength];
  113. memory.Read(buffer, 0, keylength);
  114. key = BytesUtility.ToText(buffer);
  115. }
  116. // Read Value Length
  117. var valuelength = 0;
  118. {
  119. if (!CanRead(memory, 4)) break;
  120. var buffer = new byte[4];
  121. memory.Read(buffer, 0, 4);
  122. valuelength = GetInt32(buffer);
  123. }
  124. // Read Key Data
  125. var value = Constant.EmptyBytes;
  126. if (valuelength > 1)
  127. {
  128. if (!CanRead(memory, valuelength)) break;
  129. var buffer = new byte[valuelength];
  130. memory.Read(buffer, 0, valuelength);
  131. value = BytesUtility.Clone(buffer);
  132. }
  133. if (_dict.ContainsKey(key)) continue;
  134. _dict.Add(key, value);
  135. if (_dict.Count >= count) break;
  136. }
  137. }
  138. return count == _dict.Count;
  139. }
  140. /// <summary></summary>
  141. public byte[] Export()
  142. {
  143. var memory = new MemoryStream();
  144. lock (_dict)
  145. {
  146. var count = _dict.Count;
  147. var countbytes = GetBytes(count);
  148. memory.Write(countbytes, 0, countbytes.Length);
  149. foreach (var pair in _dict)
  150. {
  151. var keydata = BytesUtility.FromText(pair.Key);
  152. var keycount = GetBytes(keydata.Length);
  153. memory.Write(keycount, 0, keycount.Length);
  154. if (keydata.Length > 0) memory.Write(keydata, 0, keydata.Length);
  155. var valuedata = pair.Value ?? Constant.EmptyBytes;
  156. var valuecount = GetBytes(valuedata.Length);
  157. memory.Write(valuecount, 0, valuecount.Length);
  158. if (valuedata.Length > 0) memory.Write(valuedata, 0, valuedata.Length);
  159. }
  160. }
  161. var data = memory.ToArray();
  162. memory.Dispose();
  163. return data;
  164. }
  165. /// <summary></summary>
  166. public bool Contains(string key)
  167. {
  168. if (key == null) return false;
  169. var contains = false;
  170. lock (_dict)
  171. {
  172. contains = _dict.ContainsKey(key);
  173. }
  174. return contains;
  175. }
  176. /// <summary></summary>
  177. public byte[] GetValue(string key)
  178. {
  179. var k = key;
  180. var v = Constant.EmptyBytes;
  181. if (k == null) return v;
  182. lock (_dict)
  183. {
  184. if (_dict.ContainsKey(k)) v = _dict[k];
  185. }
  186. if (_outbound != null)
  187. {
  188. v = _outbound(v);
  189. if (v == null) v = Constant.EmptyBytes;
  190. }
  191. return v;
  192. }
  193. /// <summary></summary>
  194. public bool SetValue(string key, byte[] value)
  195. {
  196. var k = key;
  197. var v = Constant.EmptyBytes;
  198. if (k == null) return false;
  199. lock (value)
  200. {
  201. if (value != null) v = BytesUtility.Clone(value);
  202. }
  203. if (_inbound != null)
  204. {
  205. v = _inbound(v);
  206. if (v == null) v = Constant.EmptyBytes;
  207. }
  208. lock (_dict)
  209. {
  210. if (_dict.ContainsKey(k)) _dict.Remove(k);
  211. _dict.Add(k, v);
  212. }
  213. return true;
  214. }
  215. private static bool CanRead(Stream stream, int length)
  216. {
  217. if (length < 0) return false;
  218. if (stream == null) return false;
  219. if (stream.CanRead == false) return false;
  220. if (stream.Position + length > stream.Length) return false;
  221. return true;
  222. }
  223. /// <summary>Int32 -> Byte[]</summary>
  224. private static byte[] GetBytes(int value)
  225. {
  226. const int t3 = 256 * 256 * 256;
  227. const int t2 = 256 * 256;
  228. const int t1 = 256;
  229. byte[] bs = { 0, 0, 0, 0 };
  230. if (value >= 0)
  231. {
  232. int vint = value;
  233. bs[0] = (byte)(vint / t3);
  234. vint = vint % t3;
  235. bs[1] = (byte)(vint / t2);
  236. vint = vint % t2;
  237. bs[2] = (byte)(vint / t1);
  238. vint = vint % t1;
  239. bs[3] = (byte)(vint);
  240. }
  241. else
  242. {
  243. int minusInt = Math.Abs(value + 1);
  244. var minusBytes = GetBytes(minusInt);
  245. bs[0] = (byte)(255 - minusBytes[0]);
  246. bs[1] = (byte)(255 - minusBytes[1]);
  247. bs[2] = (byte)(255 - minusBytes[2]);
  248. bs[3] = (byte)(255 - minusBytes[3]);
  249. }
  250. return bs;
  251. }
  252. /// <summary>Byte[] -> Int32</summary>
  253. private static Int32 GetInt32(byte[] value)
  254. {
  255. if (value.Length == 4)
  256. {
  257. const int t3 = 256 * 256 * 256;
  258. const int t2 = 256 * 256;
  259. const int t1 = 256;
  260. if (value[0] <= 127)
  261. {
  262. int[] vis = { 0, 0, 0, 0 };
  263. vis[0] = value[0] * t3;
  264. vis[1] = value[1] * t2;
  265. vis[2] = value[2] * t1;
  266. vis[3] = value[3];
  267. int vr = vis[0] + vis[1] + vis[2] + vis[3];
  268. return vr;
  269. }
  270. else
  271. {
  272. if ((value[0] == 128) && (value[1] == 0) && (value[2] == 0) && (value[3] == 0))
  273. {
  274. return int.MinValue;
  275. }
  276. else
  277. {
  278. var bytes = new byte[4];
  279. bytes[0] = (byte)(255 - value[0]);
  280. bytes[1] = (byte)(255 - value[1]);
  281. bytes[2] = (byte)(255 - value[2]);
  282. bytes[3] = (byte)(255 - value[3]);
  283. int vminusint = 0 - 1 - GetInt32(bytes);
  284. return vminusint;
  285. }
  286. }
  287. }
  288. return 0;
  289. }
  290. }
  291. }