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.

310 lines
9.7 KiB

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