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.

184 line
6.1 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Buffers.Binary;
  5. namespace JT1078.Hls.MessagePack
  6. {
  7. public ref partial struct TSMessagePackWriter
  8. {
  9. private TSBufferWriter writer;
  10. public TSMessagePackWriter(Span<byte> buffer)
  11. {
  12. this.writer = new TSBufferWriter(buffer);
  13. }
  14. public byte[] FlushAndGetArray()
  15. {
  16. return writer.Written.ToArray();
  17. }
  18. public void WriteByte(byte value)
  19. {
  20. var span = writer.Free;
  21. span[0] = value;
  22. writer.Advance(1);
  23. }
  24. public void WriteUInt16(ushort value)
  25. {
  26. BinaryPrimitives.WriteUInt16BigEndian(writer.Free, value);
  27. writer.Advance(2);
  28. }
  29. public void WriteInt32(int value)
  30. {
  31. BinaryPrimitives.WriteInt32BigEndian(writer.Free, value);
  32. writer.Advance(4);
  33. }
  34. public void WriteUInt64(ulong value)
  35. {
  36. BinaryPrimitives.WriteUInt64BigEndian(writer.Free, value);
  37. writer.Advance(8);
  38. }
  39. public void WriteUInt5(ulong value)
  40. {
  41. writer.Free[0] = (byte)(value >> 32);
  42. writer.Free[1] = (byte)(value >> 24);
  43. writer.Free[2] = (byte)(value >> 16);
  44. writer.Free[3] = (byte)(value >> 8);
  45. writer.Free[4] = (byte)(value);
  46. writer.Advance(5);
  47. }
  48. public void WriteUInt6(ulong value)
  49. {
  50. writer.Free[0] = (byte)(value >> 40);
  51. writer.Free[1] = (byte)(value >> 32);
  52. writer.Free[2] = (byte)(value >> 24);
  53. writer.Free[3] = (byte)(value >> 16);
  54. writer.Free[4] = (byte)(value >> 8);
  55. writer.Free[5] = (byte)(value);
  56. writer.Advance(6);
  57. }
  58. public void WriteInt5(long value)
  59. {
  60. writer.Free[0] = (byte)(value >> 32);
  61. writer.Free[1] = (byte)(value >> 24);
  62. writer.Free[2] = (byte)(value >> 16);
  63. writer.Free[3] = (byte)(value >> 8);
  64. writer.Free[4] = (byte)(value);
  65. writer.Advance(5);
  66. }
  67. public void WriteInt6(long value)
  68. {
  69. writer.Free[0] = (byte)(value >> 40);
  70. writer.Free[1] = (byte)(value >> 32);
  71. writer.Free[2] = (byte)(value >> 24);
  72. writer.Free[3] = (byte)(value >> 16);
  73. writer.Free[4] = (byte)(value >> 8);
  74. writer.Free[5] = (byte)(value);
  75. writer.Advance(6);
  76. }
  77. public void WritePCR(long value)
  78. {
  79. writer.Free[0] = (byte)(value >> 25);
  80. writer.Free[1] = (byte)((value >> 17) & 0xff);
  81. writer.Free[2] = (byte)((value >> 9) & 0xff);
  82. writer.Free[3] = (byte)((value >> 1) & 0xff);
  83. writer.Free[4] = (byte)(((value & 0x1) << 7) | 0x7e);
  84. writer.Free[5] = 0x00;
  85. writer.Advance(6);
  86. }
  87. public void WriteUInt3(uint value)
  88. {
  89. writer.Free[0] = (byte)(value >> 16);
  90. writer.Free[1] = (byte)(value >> 8);
  91. writer.Free[2] = (byte)(value);
  92. writer.Advance(3);
  93. }
  94. public void WriteInt3(int value)
  95. {
  96. writer.Free[0] = (byte)(value >> 16);
  97. writer.Free[1] = (byte)(value >> 8);
  98. writer.Free[2] = (byte)(value);
  99. writer.Advance(3);
  100. }
  101. public void WriteUInt32(uint value)
  102. {
  103. BinaryPrimitives.WriteUInt32BigEndian(writer.Free, value);
  104. writer.Advance(4);
  105. }
  106. public void WriteArray(ReadOnlySpan<byte> src)
  107. {
  108. src.CopyTo(writer.Free);
  109. writer.Advance(src.Length);
  110. }
  111. public void Skip(int count, out int position)
  112. {
  113. position = writer.WrittenCount;
  114. byte[] tmp = new byte[count];
  115. tmp.CopyTo(writer.Free);
  116. writer.Advance(count);
  117. }
  118. public void WriteCRC32()
  119. {
  120. if (writer.WrittenCount < 1)
  121. {
  122. throw new ArgumentOutOfRangeException($"Written<start:{writer.WrittenCount}>{1}");
  123. }
  124. //从第1位开始
  125. var crcSpan = writer.Written.Slice(1);
  126. uint crc = 0xFFFFFFFF;
  127. for (int i = 0; i < crcSpan.Length; i++)
  128. {
  129. crc = (crc << 8) ^ Util.crcTable[(crc >> 24) ^ crcSpan[i]];
  130. }
  131. WriteUInt32(crc);
  132. }
  133. public void WriteCRC32(int start)
  134. {
  135. if (writer.WrittenCount < start)
  136. {
  137. throw new ArgumentOutOfRangeException($"Written<start:{writer.WrittenCount}>{1}");
  138. }
  139. var crcSpan = writer.Written.Slice(start);
  140. uint crc = 0xFFFFFFFF;
  141. byte j = 0;
  142. for (int i = 0; i < crcSpan.Length; i++)
  143. {
  144. j = (byte)(((crc >> 24) ^ crcSpan[i]) & 0xff);
  145. crc = (crc << 8) ^ Util.crcTable[j];
  146. }
  147. WriteUInt32(crc);
  148. }
  149. public void WriteCRC32(int start, int end)
  150. {
  151. if (start > end)
  152. {
  153. throw new ArgumentOutOfRangeException($"start>end:{start}>{end}");
  154. }
  155. var crcSpan = writer.Written.Slice(start, end);
  156. uint crc = 0xFFFFFFFF;
  157. for (int i = 0; i < crcSpan.Length; i++)
  158. {
  159. crc = ((crc << 8) ^ Util.crcTable[(crc >> 8) ^ crcSpan[i]]);
  160. }
  161. WriteUInt32(crc);
  162. }
  163. public void WriteUInt16Return(ushort value, int position)
  164. {
  165. BinaryPrimitives.WriteUInt16BigEndian(writer.Written.Slice(position, 2), value);
  166. }
  167. public void WriteByteReturn(byte value, int position)
  168. {
  169. writer.Written[position] = value;
  170. }
  171. public int GetCurrentPosition()
  172. {
  173. return writer.WrittenCount;
  174. }
  175. public void WriteString(string value)
  176. {
  177. byte[] codeBytes = TSConstants.Encoding.GetBytes(value);
  178. codeBytes.CopyTo(writer.Free);
  179. writer.Advance(codeBytes.Length);
  180. }
  181. }
  182. }