ByteBuffer.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. using System;
  2. using System.IO;
  3. namespace Houdar.Core.Communication.Transport
  4. {
  5. public static class ExtensionHelper
  6. {
  7. public static byte[] Reverse(this byte[] buf, int index, int length)
  8. {
  9. Array.Reverse(buf, index, length);
  10. return buf;
  11. }
  12. public static int CompareTo(this byte[] source, Int64 start, Int64 count, byte[] buffer, Int64 offset = 0, Int64 length = -1)
  13. {
  14. if (source == buffer) return 0;
  15. if (start < 0) start = 0;
  16. if (count <= 0 || count > source.Length - start) count = source.Length - start;
  17. if (length <= 0 || length > buffer.Length - offset) length = buffer.Length - offset;
  18. // 逐字节比较
  19. for (int i = 0; i < count && i < length; i++)
  20. {
  21. int rs = source[start + i].CompareTo(buffer[offset + i]);
  22. if (rs != 0) return i > 0 ? i : 1;
  23. }
  24. // 比较完成。如果长度不相等,则较长者较大
  25. if (count != length) return count > length ? 1 : -1;
  26. return 0;
  27. }
  28. }
  29. public class ByteBuffer
  30. {
  31. private readonly byte[] _bufferCache;
  32. /// <summary>
  33. /// 缓冲区
  34. /// </summary>
  35. public byte[] Buffer { get; private set; }
  36. /// <summary>
  37. /// 当前读取位置
  38. /// </summary>
  39. public int ReadIndex { get; private set; }
  40. /// <summary>
  41. /// 当前写入位置
  42. /// </summary>
  43. public int WriteIndex { get; private set; }
  44. /// <summary>
  45. /// 设置读取位置标记
  46. /// </summary>
  47. public int MarkReadIndex { get; private set; }
  48. /// <summary>
  49. /// 设置写入位置标记
  50. /// </summary>
  51. public int MarkWirteIndex { get; private set; }
  52. /// <summary>
  53. /// 当前缓冲大小
  54. /// </summary>
  55. public int Capacity { get; private set; }
  56. /// <summary>
  57. /// 缓冲扩充单位
  58. /// </summary>
  59. public int CapacityUnit { get; set; }
  60. /// <summary>
  61. /// 构造函数
  62. /// </summary>
  63. /// <param name="capacity"></param>
  64. private ByteBuffer(int capacity = 1024)
  65. {
  66. _bufferCache = new byte[0x10];
  67. Buffer = new byte[capacity];
  68. Capacity = capacity;
  69. CapacityUnit = Capacity;
  70. }
  71. /// <summary>
  72. /// 构建一个<see cref="ByteBuffer"/>对象
  73. /// </summary>
  74. /// <param name="capacity"></param>
  75. /// <returns></returns>
  76. public static ByteBuffer Allocate(int capacity = 1024*4)
  77. {
  78. return new ByteBuffer(capacity);
  79. }
  80. /// <summary>
  81. /// 计算扩容需量
  82. /// </summary>
  83. /// <param name="length"></param>
  84. /// <returns></returns>
  85. private int FixLength(int length)
  86. {
  87. int n = 2;
  88. int b = 2;
  89. while (b < length)
  90. {
  91. b = 2 << n;
  92. n++;
  93. }
  94. return (b / CapacityUnit + 1) * CapacityUnit;
  95. }
  96. /// <summary>
  97. /// 长度不够扩充<see cref="Buffer"/>容量
  98. /// </summary>
  99. /// <param name="currLen"></param>
  100. /// <param name="futureLen"></param>
  101. /// <returns></returns>
  102. private int FixSizeAndReset(int currLen, int futureLen)
  103. {
  104. if (futureLen > currLen)
  105. {
  106. int size = FixLength(currLen) + Capacity;
  107. byte[] newbuf = new byte[size];
  108. Array.Copy(Buffer, 0, newbuf, 0, currLen);
  109. Buffer = newbuf;
  110. Capacity = newbuf.Length;
  111. }
  112. return futureLen;
  113. }
  114. #region 压入对象
  115. public void Push(byte[] bytes, int startIndex, int length)
  116. {
  117. lock (this)
  118. {
  119. int offset = length - startIndex;
  120. if (offset <= 0) return;
  121. int total = offset + WriteIndex;
  122. int len = Buffer.Length;
  123. FixSizeAndReset(len, total);
  124. for (int i = WriteIndex, j = startIndex; i < total; i++, j++)
  125. {
  126. Buffer[i] = bytes[j];
  127. }
  128. WriteIndex = total;
  129. }
  130. }
  131. /// <summary>
  132. /// 写入字节数组
  133. /// </summary>
  134. /// <param name="bytes"></param>
  135. /// <param name="length"></param>
  136. /// <param name="reversed"></param>
  137. public void Push(byte[] bytes, int length, bool reversed = false)
  138. {
  139. if (reversed) bytes = bytes.Reverse(0,length);
  140. Push(bytes, 0, length);
  141. }
  142. /// <summary>
  143. /// 写入字节数组
  144. /// </summary>
  145. /// <param name="bytes"></param>
  146. /// <param name="reversed"></param>
  147. public void Push(byte[] bytes, bool reversed = false)
  148. {
  149. Push(bytes, bytes.Length, reversed);
  150. }
  151. /// <summary>
  152. /// 写入另一个<see cref="ByteBuffer"/>对象
  153. /// </summary>
  154. /// <param name="buffer"></param>
  155. /// <param name="reversed"></param>
  156. public void Push(ByteBuffer buffer, bool reversed = false)
  157. {
  158. if (buffer == null) return;
  159. if (buffer.ReadableBytes() <= 0) return;
  160. Push(buffer.ToArray(), reversed);
  161. }
  162. /// <summary>
  163. /// 写入一个<see cref="short"/>对象
  164. /// </summary>
  165. /// <param name="value"></param>
  166. /// <param name="reversed"></param>
  167. public void Push(short value, bool reversed = false)
  168. {
  169. Push((ushort)value, reversed);
  170. }
  171. /// <summary>
  172. /// 写入一个<see cref="ushort"/>对象
  173. /// </summary>
  174. /// <param name="value"></param>
  175. /// <param name="reversed"></param>
  176. public void Push(ushort value, bool reversed = false)
  177. {
  178. _bufferCache[0] = (byte)(value >> 8);
  179. _bufferCache[1] = (byte)value;
  180. Push(_bufferCache, 2, reversed);
  181. }
  182. public void Push(char value, bool reversed = false)
  183. {
  184. Push((short)value, reversed);
  185. }
  186. /// <summary>
  187. /// 写入一个<see cref="int"/>对象
  188. /// </summary>
  189. /// <param name="value"></param>
  190. /// <param name="reversed"></param>
  191. public void Push(int value, bool reversed = false)
  192. {
  193. Push((uint)value);
  194. }
  195. /// <summary>
  196. /// 写入一个<see cref="uint"/>对象
  197. /// </summary>
  198. /// <param name="value"></param>
  199. /// <param name="reversed"></param>
  200. public void Push(uint value, bool reversed = false)
  201. {
  202. _bufferCache[0] = (byte)(value >> 0x18);
  203. _bufferCache[1] = (byte)(value >> 0x10);
  204. _bufferCache[2] = (byte)(value >> 8);
  205. _bufferCache[3] = (byte)value;
  206. Push(_bufferCache, 4, reversed);
  207. }
  208. /// <summary>
  209. /// 写入一个<see cref="long"/>对象
  210. /// </summary>
  211. /// <param name="value"></param>
  212. /// <param name="reversed"></param>
  213. public void Push(long value, bool reversed = false)
  214. {
  215. Push((ulong)value);
  216. }
  217. /// <summary>
  218. /// 写入一个<see cref="ulong"/>对象
  219. /// </summary>
  220. /// <param name="value"></param>
  221. /// <param name="reversed"></param>
  222. public void Push(ulong value, bool reversed = false)
  223. {
  224. _bufferCache[0] = (byte)(value >> 0x38);
  225. _bufferCache[1] = (byte)(value >> 0x30);
  226. _bufferCache[2] = (byte)(value >> 0x28);
  227. _bufferCache[3] = (byte)(value >> 0x20);
  228. _bufferCache[4] = (byte)(value >> 0x18);
  229. _bufferCache[5] = (byte)(value >> 0x10);
  230. _bufferCache[6] = (byte)(value >> 8);
  231. _bufferCache[7] = (byte)value;
  232. Push(_bufferCache, 8, reversed);
  233. }
  234. /// <summary>
  235. /// 写入一个<see cref="float"/>对象
  236. /// </summary>
  237. /// <param name="value"></param>
  238. /// <param name="reversed"></param>
  239. public void Push(float value, bool reversed = false)
  240. {
  241. var buf = BitConverter.GetBytes(value);
  242. Push(buf, reversed);
  243. }
  244. /// <summary>
  245. /// 写入一个<see cref="byte"/>对象
  246. /// </summary>
  247. /// <param name="value"></param>
  248. public void Push(byte value)
  249. {
  250. lock (this)
  251. {
  252. int afterLen = WriteIndex + 1;
  253. int len = Buffer.Length;
  254. FixSizeAndReset(len, afterLen);
  255. Buffer[WriteIndex] = value;
  256. WriteIndex = afterLen;
  257. }
  258. }
  259. /// <summary>
  260. /// 写入一个<see cref="double"/>对象
  261. /// </summary>
  262. /// <param name="value"></param>
  263. /// <param name="reversed"></param>
  264. public void Push(double value, bool reversed = false)
  265. {
  266. var buf = BitConverter.GetBytes(value);
  267. Push(buf, reversed);
  268. }
  269. #endregion
  270. #region pop出一个对象
  271. /// <summary>
  272. /// 读取一个<see cref="byte"/>
  273. /// </summary>
  274. /// <returns></returns>
  275. public byte PopByte()
  276. {
  277. byte b = Buffer[ReadIndex];
  278. ReadIndex++;
  279. return b;
  280. }
  281. /// <summary>
  282. /// 读取指定的<see cref="byte"/>[]
  283. /// </summary>
  284. /// <param name="len"></param>
  285. /// <param name="reversed"></param>
  286. /// <returns></returns>
  287. private byte[] Pop(int len, bool reversed = false)
  288. {
  289. byte[] bytes = new byte[len];
  290. Array.Copy(Buffer, ReadIndex, bytes, 0, len);
  291. if (reversed)
  292. Array.Reverse(bytes);
  293. ReadIndex += len;
  294. return bytes;
  295. }
  296. /// <summary>
  297. /// 读取指定的<see cref="ushort"/>
  298. /// </summary>
  299. /// <returns></returns>
  300. public ushort PopUshort(bool reversed = false)
  301. {
  302. var buf = Pop(2, reversed);
  303. return (ushort)(buf[0] << 8 | buf[1]);
  304. }
  305. /// <summary>
  306. /// 读取指定的<see cref="ushort"/>
  307. /// </summary>
  308. /// <returns></returns>
  309. public char PopChar(bool reversed = false)
  310. {
  311. var buf = Pop(2, reversed);
  312. return (char)(buf[0] << 8 | buf[1]);
  313. }
  314. /// <summary>
  315. /// 读取指定的<see cref="short"/>
  316. /// </summary>
  317. /// <param name="reversed"></param>
  318. /// <returns></returns>
  319. public short PopShort(bool reversed = false)
  320. {
  321. var buf = Pop(2, reversed);
  322. return (short)(buf[0] << 8 | buf[1]);
  323. }
  324. /// <summary>
  325. /// 读取指定的<see cref="uint"/>
  326. /// </summary>
  327. /// <param name="reversed"></param>
  328. /// <returns></returns>
  329. public uint PopUint(bool reversed = false)
  330. {
  331. var buf = Pop(4, reversed);
  332. return (uint)(buf[0] << 0x18 | buf[1] << 0x10 | buf[2] << 0x8 | buf[3]);
  333. }
  334. /// <summary>
  335. /// 读取指定的<see cref="int"/>
  336. /// </summary>
  337. /// <param name="reversed"></param>
  338. /// <returns></returns>
  339. public int PopInt(bool reversed = false)
  340. {
  341. var buf = Pop(4, reversed);
  342. return buf[0] << 0x18 |
  343. buf[1] << 0x10 |
  344. buf[2] << 0x8 |
  345. buf[3];
  346. }
  347. /// <summary>
  348. /// 读取指定的<see cref="ulong"/>
  349. /// </summary>
  350. /// <param name="reversed"></param>
  351. /// <returns></returns>
  352. public ulong PopUlong(bool reversed = false)
  353. {
  354. var buf = Pop(8, reversed);
  355. return (ulong)(buf[0] << 0x38 |
  356. buf[1] << 0x30 |
  357. buf[2] << 0x28 |
  358. buf[3] << 0x20 |
  359. buf[4] << 0x18 |
  360. buf[5] << 0x10 |
  361. buf[6] << 0x08 |
  362. buf[7]);
  363. }
  364. /// <summary>
  365. /// 读取指定的<see cref="long"/>
  366. /// </summary>
  367. /// <param name="reversed"></param>
  368. /// <returns></returns>
  369. public long PopLong(bool reversed = false)
  370. {
  371. var buf = Pop(8, reversed);
  372. return buf[0] << 0x38 |
  373. buf[1] << 0x30 |
  374. buf[2] << 0x28 |
  375. buf[3] << 0x20 |
  376. buf[4] << 0x18 |
  377. buf[5] << 0x10 |
  378. buf[6] << 0x08 |
  379. buf[7];
  380. }
  381. /// <summary>
  382. /// 读取指定的<see cref="float"/>
  383. /// </summary>
  384. /// <param name="reversed"></param>
  385. /// <returns></returns>
  386. public float PopFloat(bool reversed = false)
  387. {
  388. return BitConverter.ToSingle(Pop(4, reversed), 0);
  389. }
  390. /// <summary>
  391. /// 读取指定的<see cref="double"/>
  392. /// </summary>
  393. /// <param name="reversed"></param>
  394. /// <returns></returns>
  395. public double PopDouble(bool reversed = false)
  396. {
  397. return BitConverter.ToDouble(Pop(8, reversed), 0);
  398. }
  399. /// <summary>
  400. /// 读取指定长度的<see cref="byte"/>[]
  401. /// </summary>
  402. /// <param name="desBytes"></param>
  403. /// <param name="desStart"></param>
  404. /// <param name="len"></param>
  405. public void PopBytes(byte[] desBytes, int desStart, int len)
  406. {
  407. int size = desStart + len;
  408. for (int i = desStart; i < size; i++)
  409. {
  410. desBytes[i] = PopByte();
  411. }
  412. }
  413. public byte[] PopBytes(int len)
  414. {
  415. var buf = new byte[len];
  416. for (int i = 0; i < len; i++)
  417. {
  418. buf[i] = PopByte();
  419. }
  420. return buf;
  421. }
  422. #endregion
  423. /// <summary>
  424. /// 清除已读缓冲 后续队列前移
  425. /// </summary>
  426. public void DiscardReadBytes()
  427. {
  428. if (ReadIndex <= 0) return;
  429. int len = Buffer.Length - ReadIndex;
  430. byte[] newbuf = new byte[Buffer.Length];
  431. Array.Copy(Buffer, ReadIndex, newbuf, 0, len);
  432. Buffer = newbuf;
  433. WriteIndex -= ReadIndex;
  434. MarkReadIndex -= ReadIndex;
  435. if (MarkReadIndex < 0)
  436. {
  437. MarkReadIndex = ReadIndex;
  438. }
  439. MarkWirteIndex -= ReadIndex;
  440. if (MarkWirteIndex < 0 || MarkWirteIndex < ReadIndex || MarkWirteIndex < MarkReadIndex)
  441. {
  442. MarkWirteIndex = WriteIndex;
  443. }
  444. ReadIndex = 0;
  445. }
  446. /// <summary>
  447. /// 清空缓存
  448. /// </summary>
  449. public void Clear()
  450. {
  451. Buffer = new byte[Buffer.Length];
  452. ReadIndex = 0;
  453. WriteIndex = 0;
  454. MarkReadIndex = 0;
  455. MarkWirteIndex = 0;
  456. }
  457. /// <summary>
  458. /// 设置缓存读取位置
  459. /// </summary>
  460. /// <param name="index"></param>
  461. public void SetReaderIndex(int index)
  462. {
  463. if (index < 0) return;
  464. ReadIndex = index;
  465. }
  466. /// <summary>
  467. /// 标记当前读取的索引位置
  468. /// </summary>
  469. public void MarkReaderIndex()
  470. {
  471. MarkReadIndex = ReadIndex;
  472. }
  473. /// <summary>
  474. /// 标记当前写入的索引位置
  475. /// </summary>
  476. public void MarkWriterIndex()
  477. {
  478. MarkWirteIndex = WriteIndex;
  479. }
  480. /// <summary>
  481. /// 将读取的索引位置重置为标记的读取索引位置
  482. /// </summary>
  483. public void ResetReaderIndex()
  484. {
  485. ReadIndex = MarkReadIndex;
  486. }
  487. /// <summary>
  488. /// 将写入的索引位置重置为标记的写入索引位置
  489. /// </summary>
  490. public void ResetWriterIndex()
  491. {
  492. WriteIndex = MarkWirteIndex;
  493. }
  494. /// <summary>
  495. /// 剩余可读数量
  496. /// </summary>
  497. /// <returns></returns>
  498. public int ReadableBytes()
  499. {
  500. return WriteIndex - ReadIndex;
  501. }
  502. /// <summary>
  503. /// 剩余可读缓存转数组
  504. /// </summary>
  505. /// <returns></returns>
  506. public byte[] ToArray()
  507. {
  508. byte[] bytes = new byte[WriteIndex];
  509. Array.Copy(Buffer, 0, bytes, 0, bytes.Length);
  510. return bytes;
  511. }
  512. public int IndexOf(byte[] buf, int offset = 0, int length = -1)
  513. {
  514. if (length <= 0) length = buf.Length - offset;
  515. // 位置
  516. int p = -1;
  517. for (int i = 0; i < length;)
  518. {
  519. if (ReadableBytes() < 1) return -1;
  520. int c = PopByte();
  521. if (c == -1) return -1;
  522. p++;
  523. if (c == buf[offset + i])
  524. {
  525. i++;
  526. // 全部匹配,退出
  527. if (i >= length) return p - length + 1;
  528. }
  529. else
  530. {
  531. int n = i;
  532. i = 0;
  533. for (int j = 1; j < n; j++)
  534. {
  535. // 在字节数组前(j,n)里面找自己(0,n-j)
  536. if (buf.CompareTo(j, n, buf, 0, n - j) == 0)
  537. {
  538. // 前面(0,n-j)相等,窗口退回到这里
  539. i = n - j;
  540. break;
  541. }
  542. }
  543. }
  544. }
  545. return -1;
  546. }
  547. public bool EnsureStartWith(byte[] buf, int offset = 0, int length = -1)
  548. {
  549. if (buf.Length < offset) throw new ArgumentOutOfRangeException("offset");
  550. if (offset < 0) offset = 0;
  551. if (length < 0 || buf.Length < (offset + length)) length = buf.Length - offset;
  552. int index = IndexOf(buf, offset, length);
  553. if (index == -1)
  554. {
  555. //重建缓冲清除数据
  556. //DiscardReadBytes();
  557. //不能重建缓冲 有可能尾部有数据部分匹配而导致数据丢失
  558. //重置ReaderIndex即可
  559. SetReaderIndex(0);
  560. return false;
  561. }
  562. if (index == 0) return true;
  563. SetReaderIndex(index);
  564. DiscardReadBytes();
  565. return true;
  566. }
  567. }
  568. }