BinaryExtension.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //------------------------------------------------------------
  2. // Game Framework
  3. // Copyright © 2013-2021 loyalsoft. All rights reserved.
  4. // Homepage: http://www.game7000.com/
  5. // Feedback: http://www.game7000.com/
  6. //------------------------------------------------------------
  7. using GameFramework;
  8. using System;
  9. using System.IO;
  10. /// <summary>
  11. /// 对 BinaryReader 和 BinaryWriter 的扩展方法。
  12. /// </summary>
  13. public static class BinaryExtension
  14. {
  15. private static readonly byte[] s_CachedBytes = new byte[byte.MaxValue + 1];
  16. /// <summary>
  17. /// 从二进制流读取编码后的 32 位有符号整数。
  18. /// </summary>
  19. /// <param name="binaryReader">要读取的二进制流。</param>
  20. /// <returns>读取的 32 位有符号整数。</returns>
  21. public static int Read7BitEncodedInt32(this BinaryReader binaryReader)
  22. {
  23. int value = 0;
  24. int shift = 0;
  25. byte b;
  26. do
  27. {
  28. if (shift >= 35)
  29. {
  30. throw new GameFrameworkException("7 bit encoded int is invalid.");
  31. }
  32. b = binaryReader.ReadByte();
  33. value |= (b & 0x7f) << shift;
  34. shift += 7;
  35. } while ((b & 0x80) != 0);
  36. return value;
  37. }
  38. /// <summary>
  39. /// 向二进制流写入编码后的 32 位有符号整数。
  40. /// </summary>
  41. /// <param name="binaryWriter">要写入的二进制流。</param>
  42. /// <param name="value">要写入的 32 位有符号整数。</param>
  43. public static void Write7BitEncodedInt32(this BinaryWriter binaryWriter, int value)
  44. {
  45. uint num = (uint)value;
  46. while (num >= 0x80)
  47. {
  48. binaryWriter.Write((byte)(num | 0x80));
  49. num >>= 7;
  50. }
  51. binaryWriter.Write((byte)num);
  52. }
  53. /// <summary>
  54. /// 从二进制流读取编码后的 32 位无符号整数。
  55. /// </summary>
  56. /// <param name="binaryReader">要读取的二进制流。</param>
  57. /// <returns>读取的 32 位无符号整数。</returns>
  58. public static uint Read7BitEncodedUInt32(this BinaryReader binaryReader)
  59. {
  60. return (uint)Read7BitEncodedInt32(binaryReader);
  61. }
  62. /// <summary>
  63. /// 向二进制流写入编码后的 32 位无符号整数。
  64. /// </summary>
  65. /// <param name="binaryWriter">要写入的二进制流。</param>
  66. /// <param name="value">要写入的 32 位无符号整数。</param>
  67. public static void Write7BitEncodedUInt32(this BinaryWriter binaryWriter, uint value)
  68. {
  69. Write7BitEncodedInt32(binaryWriter, (int)value);
  70. }
  71. /// <summary>
  72. /// 从二进制流读取编码后的 64 位有符号整数。
  73. /// </summary>
  74. /// <param name="binaryReader">要读取的二进制流。</param>
  75. /// <returns>读取的 64 位有符号整数。</returns>
  76. public static long Read7BitEncodedInt64(this BinaryReader binaryReader)
  77. {
  78. long value = 0L;
  79. int shift = 0;
  80. byte b;
  81. do
  82. {
  83. if (shift >= 70)
  84. {
  85. throw new GameFrameworkException("7 bit encoded int is invalid.");
  86. }
  87. b = binaryReader.ReadByte();
  88. value |= (b & 0x7fL) << shift;
  89. shift += 7;
  90. } while ((b & 0x80) != 0);
  91. return value;
  92. }
  93. /// <summary>
  94. /// 向二进制流写入编码后的 64 位有符号整数。
  95. /// </summary>
  96. /// <param name="binaryWriter">要写入的二进制流。</param>
  97. /// <param name="value">要写入的 64 位有符号整数。</param>
  98. public static void Write7BitEncodedInt64(this BinaryWriter binaryWriter, long value)
  99. {
  100. ulong num = (ulong)value;
  101. while (num >= 0x80)
  102. {
  103. binaryWriter.Write((byte)(num | 0x80));
  104. num >>= 7;
  105. }
  106. binaryWriter.Write((byte)num);
  107. }
  108. /// <summary>
  109. /// 从二进制流读取编码后的 64 位无符号整数。
  110. /// </summary>
  111. /// <param name="binaryReader">要读取的二进制流。</param>
  112. /// <returns>读取的 64 位无符号整数。</returns>
  113. public static ulong Read7BitEncodedUInt64(this BinaryReader binaryReader)
  114. {
  115. return (ulong)Read7BitEncodedInt64(binaryReader);
  116. }
  117. /// <summary>
  118. /// 向二进制流写入编码后的 64 位无符号整数。
  119. /// </summary>
  120. /// <param name="binaryWriter">要写入的二进制流。</param>
  121. /// <param name="value">要写入的 64 位无符号整数。</param>
  122. public static void Write7BitEncodedUInt64(this BinaryWriter binaryWriter, ulong value)
  123. {
  124. Write7BitEncodedInt64(binaryWriter, (long)value);
  125. }
  126. /// <summary>
  127. /// 从二进制流读取加密字符串。
  128. /// </summary>
  129. /// <param name="binaryReader">要读取的二进制流。</param>
  130. /// <param name="encryptBytes">密钥数组。</param>
  131. /// <returns>读取的字符串。</returns>
  132. public static string ReadEncryptedString(this BinaryReader binaryReader, byte[] encryptBytes)
  133. {
  134. byte length = binaryReader.ReadByte();
  135. if (length <= 0)
  136. {
  137. return null;
  138. }
  139. if (length > byte.MaxValue)
  140. {
  141. throw new GameFrameworkException("String is too long.");
  142. }
  143. for (byte i = 0; i < length; i++)
  144. {
  145. s_CachedBytes[i] = binaryReader.ReadByte();
  146. }
  147. Utility.Encryption.GetSelfXorBytes(s_CachedBytes, 0, length, encryptBytes);
  148. string value = Utility.Converter.GetString(s_CachedBytes, 0, length);
  149. Array.Clear(s_CachedBytes, 0, length);
  150. return value;
  151. }
  152. /// <summary>
  153. /// 向二进制流写入加密字符串。
  154. /// </summary>
  155. /// <param name="binaryWriter">要写入的二进制流。</param>
  156. /// <param name="value">要写入的字符串。</param>
  157. /// <param name="encryptBytes">密钥数组。</param>
  158. public static void WriteEncryptedString(this BinaryWriter binaryWriter, string value, byte[] encryptBytes)
  159. {
  160. if (string.IsNullOrEmpty(value))
  161. {
  162. binaryWriter.Write((byte)0);
  163. return;
  164. }
  165. int length = Utility.Converter.GetBytes(value, s_CachedBytes);
  166. if (length > byte.MaxValue)
  167. {
  168. throw new GameFrameworkException(Utility.Text.Format("String '{0}' is too long.", value));
  169. }
  170. Utility.Encryption.GetSelfXorBytes(s_CachedBytes, encryptBytes);
  171. binaryWriter.Write((byte)length);
  172. binaryWriter.Write(s_CachedBytes, 0, length);
  173. }
  174. }