erlang自定义二进制协议
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.

148 line
4.7 KiB

  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. namespace bintalk
  5. {
  6. /** This class can read basic types by using a bintalk.IReader object. */
  7. public static partial class ProtocolReader
  8. {
  9. public static bool readMid(bintalk.IReader r, ref ushort v)
  10. {
  11. return read(r, ref v, 0);
  12. }
  13. // int64
  14. public static bool read(bintalk.IReader r, ref long v, uint maxValue)
  15. {
  16. byte[] data; int startId;
  17. if (!r.read(8, out data, out startId)) return false;
  18. v = BitConverter.ToInt64(data, startId);
  19. return true;
  20. }
  21. // uint64
  22. public static bool read(bintalk.IReader r, ref ulong v, uint maxValue)
  23. {
  24. byte[] data; int startId;
  25. if (!r.read(8, out data, out startId)) return false;
  26. v = BitConverter.ToUInt64(data, startId);
  27. return true;
  28. }
  29. // double
  30. public static bool read(bintalk.IReader r, ref double v, uint maxValue)
  31. {
  32. byte[] data; int startId;
  33. if (!r.read(8, out data, out startId)) return false;
  34. v = BitConverter.ToDouble(data, startId);
  35. return true;
  36. }
  37. // float
  38. public static bool read(bintalk.IReader r, ref float v, uint maxValue)
  39. {
  40. byte[] data; int startId;
  41. if (!r.read(4, out data, out startId)) return false;
  42. v = BitConverter.ToSingle(data, startId);
  43. return true;
  44. }
  45. // int32
  46. public static bool read(bintalk.IReader r, ref int v, uint maxValue)
  47. {
  48. byte[] data; int startId;
  49. if (!r.read(4, out data, out startId)) return false;
  50. v = BitConverter.ToInt32(data, startId);
  51. return true;
  52. }
  53. // uint32
  54. public static bool read(bintalk.IReader r, ref uint v, uint maxValue)
  55. {
  56. byte[] data; int startId;
  57. if (!r.read(4, out data, out startId)) return false;
  58. v = BitConverter.ToUInt32(data, startId);
  59. return true;
  60. }
  61. // int16
  62. public static bool read(bintalk.IReader r, ref short v, uint maxValue)
  63. {
  64. byte[] data; int startId;
  65. if (!r.read(2, out data, out startId)) return false;
  66. v = BitConverter.ToInt16(data, startId);
  67. return true;
  68. }
  69. // uint16
  70. public static bool read(bintalk.IReader r, ref ushort v, uint maxValue)
  71. {
  72. byte[] data; int startId;
  73. if (!r.read(2, out data, out startId)) return false;
  74. v = BitConverter.ToUInt16(data, startId);
  75. return true;
  76. }
  77. // int8
  78. public static bool read(bintalk.IReader r, ref sbyte v, uint maxValue)
  79. {
  80. byte[] data; int startId;
  81. if (!r.read(1, out data, out startId))
  82. return false;
  83. v = (sbyte)data[startId];
  84. return true;
  85. }
  86. // uint8
  87. public static bool read(bintalk.IReader r, ref byte v, uint maxValue)
  88. {
  89. byte[] data; int startId;
  90. if (!r.read(1, out data, out startId))
  91. return false;
  92. v = data[startId];
  93. return true;
  94. }
  95. // bool
  96. public static bool read(bintalk.IReader r, ref bool v, uint maxValue)
  97. {
  98. byte[] data; int startId;
  99. if (!r.read(1, out data, out startId))
  100. return false;
  101. v = (data[startId] == 0)?false:true;
  102. return true;
  103. }
  104. // string.
  105. public static bool read(bintalk.IReader r, ref string v, uint maxValue)
  106. {
  107. uint s;
  108. if (!readDynSize(r, out s) || s > maxValue)
  109. return false;
  110. byte[] data; int startId;
  111. if(!r.read(s, out data, out startId))
  112. return false;
  113. v = Encoding.UTF8.GetString(data, startId, (int)s);
  114. return true;
  115. }
  116. // binary.
  117. public static bool read(bintalk.IReader r, ref byte[] v, uint maxValue)
  118. {
  119. uint s;
  120. if (!readDynSize(r, out s) || s > maxValue)
  121. return false;
  122. v = new byte[s];
  123. byte[] data; int startId;
  124. if(!r.read(s, out data, out startId))
  125. return false;
  126. Array.Copy(data, startId, v, 0, s);
  127. return true;
  128. }
  129. // dynamic size.
  130. public static bool readDynSize(bintalk.IReader r, out uint s)
  131. {
  132. s = 0;
  133. byte b = 0;
  134. if (!read(r, ref b, 0))
  135. return false;
  136. uint n = (uint)((b & 0XC0) >> 6);
  137. s = (uint)(b & 0X3F);
  138. for (int i = 0; i < n; i++)
  139. {
  140. if (!read(r, ref b, 0))
  141. return false;
  142. s = (s << 8) | b;
  143. }
  144. return true;
  145. }
  146. }
  147. }