NetworkOrderBitsConverter.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. using System;
  2. namespace NetMQ
  3. {
  4. /// <summary>
  5. /// This static class serves to convert between byte-arrays, and various integer sizes
  6. /// - all of which assume the byte-data is in Big-endian, or "Network Byte Order".
  7. /// </summary>
  8. public static class NetworkOrderBitsConverter
  9. {
  10. /// <summary>
  11. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  12. /// - return a 16-bit integer derived from the 2 bytes starting at that offset.
  13. /// </summary>
  14. /// <param name="buffer">the byte-array to get the short from</param>
  15. /// <returns></returns>
  16. public static short ToInt16(byte[] buffer)
  17. {
  18. var i = buffer[0] << 8 |
  19. buffer[1];
  20. return (short)i;
  21. }
  22. /// <summary>
  23. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  24. /// - return a 16-bit integer derived from the 2 bytes starting at that offset.
  25. /// </summary>
  26. /// <param name="buffer">the byte-array to get the short from</param>
  27. /// <param name="offset">Offset to read from</param>
  28. /// <returns></returns>
  29. public static ushort ToUInt16(byte[] buffer, int offset)
  30. {
  31. var i = buffer[offset] << 8 |
  32. buffer[offset + 1];
  33. return (ushort)i;
  34. }
  35. /// <summary>
  36. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  37. /// - return a 16-bit integer derived from the 2 bytes starting at that offset.
  38. /// </summary>
  39. /// <param name="buffer">the byte-array to get the short from</param>
  40. /// <param name="offset"></param>
  41. /// <returns></returns>
  42. public static ushort ToUInt16(Span<byte> buffer, int offset)
  43. {
  44. var i = buffer[offset] << 8 |
  45. buffer[offset + 1];
  46. return (ushort)i;
  47. }
  48. /// <summary>
  49. /// Given a 16-bit integer, return it as a byte-array in Big-endian order.
  50. /// </summary>
  51. /// <param name="value">the short to convert</param>
  52. /// <returns>a 2-byte array containing that short's bits</returns>
  53. public static byte[] GetBytes(short value)
  54. {
  55. var buffer = new byte[2];
  56. PutInt16(value, buffer);
  57. return buffer;
  58. }
  59. /// <summary>
  60. /// Given a 16-bit integer, and a byte-array buffer and offset,
  61. /// - write the 2 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  62. /// </summary>
  63. /// <param name="value">the short to convert into bytes</param>
  64. /// <param name="buffer">the byte-array to write the short's bytes into</param>
  65. public static void PutInt16(short value, byte[] buffer)
  66. {
  67. buffer[0] = (byte)(value >> 8);
  68. buffer[1] = (byte) value;
  69. }
  70. /// <summary>
  71. /// Given a 16-bit integer, and a byte-array buffer and offset,
  72. /// - write the 2 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  73. /// </summary>
  74. /// <param name="value">the short to convert into bytes</param>
  75. /// <param name="buffer">the byte-array to write the short's bytes into</param>
  76. /// <param name="offset">Offset</param>
  77. public static void PutUInt16(ushort value, byte[] buffer, int offset = 0)
  78. {
  79. buffer[offset] = (byte)(value >> 8);
  80. buffer[offset + 1] = (byte) value;
  81. }
  82. /// <summary>
  83. /// Given a 16-bit integer, and a byte-array buffer and offset,
  84. /// - write the 2 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  85. /// </summary>
  86. /// <param name="value">the short to convert into bytes</param>
  87. /// <param name="buffer">the byte-array to write the short's bytes into</param>
  88. /// <param name="offset">Offset</param>
  89. public static void PutUInt16(ushort value, Span<byte> buffer, int offset = 0)
  90. {
  91. buffer[offset] = (byte)(value >> 8);
  92. buffer[offset + 1] = (byte) value;
  93. }
  94. /// <summary>
  95. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  96. /// - return a 32-bit integer derived from the 4 bytes starting at that offset.
  97. /// </summary>
  98. /// <param name="buffer">the byte-array to get the integer from</param>
  99. /// <param name="offset">offset</param>
  100. /// <returns></returns>
  101. public static int ToInt32(byte[] buffer, int offset = 0)
  102. {
  103. return
  104. buffer[offset] << 24 |
  105. buffer[offset + 1] << 16 |
  106. buffer[offset + 2] << 8 |
  107. buffer[offset + 3];
  108. }
  109. /// <summary>
  110. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  111. /// - return a 32-bit integer derived from the 4 bytes starting at that offset.
  112. /// </summary>
  113. /// <param name="buffer">the byte-array to get the integer from</param>
  114. /// <returns></returns>
  115. public static int ToInt32(Span<byte> buffer)
  116. {
  117. return
  118. buffer[0] << 24 |
  119. buffer[1] << 16 |
  120. buffer[2] << 8 |
  121. buffer[3];
  122. }
  123. /// <summary>
  124. /// Given a 32-bit integer, return it as a byte-array in Big-endian order.
  125. /// </summary>
  126. /// <param name="value">the int to convert</param>
  127. /// <returns>a 4-byte array containing that integer's bits</returns>
  128. public static byte[] GetBytes(int value)
  129. {
  130. var buffer = new byte[4];
  131. PutInt32(value, buffer);
  132. return buffer;
  133. }
  134. /// <summary>
  135. /// Given a 32-bit integer, and a byte-array buffer and offset,
  136. /// - write the 4 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  137. /// </summary>
  138. /// <param name="value">the integer to convert into bytes</param>
  139. /// <param name="buffer">the byte-array to write the integer's bytes into</param>
  140. /// <param name="offset">Offset to write to</param>
  141. public static void PutInt32(int value, byte[] buffer, int offset = 0)
  142. {
  143. buffer[offset] = (byte)(value >> 24);
  144. buffer[offset + 1] = (byte)(value >> 16);
  145. buffer[offset + 2] = (byte)(value >> 8);
  146. buffer[offset + 3] = (byte) value;
  147. }
  148. /// <summary>
  149. /// Given a 32-bit integer, and a byte-array buffer and offset,
  150. /// - write the 4 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  151. /// </summary>
  152. /// <param name="value">the integer to convert into bytes</param>
  153. /// <param name="buffer">the byte-array to write the integer's bytes into</param>
  154. public static void PutInt32(int value, Span<byte> buffer)
  155. {
  156. buffer[0] = (byte)(value >> 24);
  157. buffer[1] = (byte)(value >> 16);
  158. buffer[2] = (byte)(value >> 8);
  159. buffer[3] = (byte) value;
  160. }
  161. /// <summary>
  162. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  163. /// - return a 64-bit integer derived from the 8 bytes starting at that offset.
  164. /// </summary>
  165. /// <param name="buffer">the byte-array to get the Int64 from</param>
  166. /// <returns></returns>
  167. public static long ToInt64(byte[] buffer)
  168. {
  169. return
  170. (long)buffer[0] << 56 |
  171. (long)buffer[1] << 48 |
  172. (long)buffer[2] << 40 |
  173. (long)buffer[3] << 32 |
  174. (long)buffer[4] << 24 |
  175. (long)buffer[5] << 16 |
  176. (long)buffer[6] << 8 |
  177. (long)buffer[7];
  178. }
  179. /// <summary>
  180. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  181. /// - return a 64-bit integer derived from the 8 bytes starting at that offset.
  182. /// </summary>
  183. /// <param name="buffer">the byte-array to get the Int64 from</param>
  184. /// <returns></returns>
  185. public static long ToInt64(Span<byte> buffer)
  186. {
  187. return
  188. (long)buffer[0] << 56 |
  189. (long)buffer[1] << 48 |
  190. (long)buffer[2] << 40 |
  191. (long)buffer[3] << 32 |
  192. (long)buffer[4] << 24 |
  193. (long)buffer[5] << 16 |
  194. (long)buffer[6] << 8 |
  195. (long)buffer[7];
  196. }
  197. /// <summary>
  198. /// Given a 64-bit integer, return it as a byte-array in Big-endian order.
  199. /// </summary>
  200. /// <param name="value">The <c>long</c> value to convert from.</param>
  201. /// <returns>The network order presentation of <paramref name="value"/> as an 8-byte array.</returns>
  202. public static byte[] GetBytes(long value)
  203. {
  204. var buffer = new byte[8];
  205. PutInt64(value, buffer);
  206. return buffer;
  207. }
  208. /// <summary>
  209. /// Given a 64-bit integer, and a byte-array buffer and offset,
  210. /// - write the 8 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  211. /// </summary>
  212. /// <param name="value">the long value to convert into bytes</param>
  213. /// <param name="buffer">the byte-array to write the long value's bytes into</param>
  214. public static void PutInt64(long value, byte[] buffer)
  215. {
  216. buffer[0] = (byte)(value >> 56);
  217. buffer[1] = (byte)(value >> 48);
  218. buffer[2] = (byte)(value >> 40);
  219. buffer[3] = (byte)(value >> 32);
  220. buffer[4] = (byte)(value >> 24);
  221. buffer[5] = (byte)(value >> 16);
  222. buffer[6] = (byte)(value >> 8);
  223. buffer[7] = (byte) value;
  224. }
  225. /// <summary>
  226. /// Given a 64-bit integer, and a byte-array buffer and offset,
  227. /// - write the 8 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  228. /// </summary>
  229. /// <param name="value">the long value to convert into bytes</param>
  230. /// <param name="buffer">the byte-array to write the long value's bytes into</param>
  231. public static void PutInt64(long value, Span<byte> buffer)
  232. {
  233. buffer[0] = (byte)(value >> 56);
  234. buffer[1] = (byte)(value >> 48);
  235. buffer[2] = (byte)(value >> 40);
  236. buffer[3] = (byte)(value >> 32);
  237. buffer[4] = (byte)(value >> 24);
  238. buffer[5] = (byte)(value >> 16);
  239. buffer[6] = (byte)(value >> 8);
  240. buffer[7] = (byte) value;
  241. }
  242. /// <summary>
  243. /// Given a 64-bit integer, and a byte-array buffer and offset,
  244. /// - write the 8 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  245. /// </summary>
  246. /// <param name="value">the long value to convert into bytes</param>
  247. /// <param name="buffer">the byte-array to write the long value's bytes into</param>
  248. public static void PutUInt64(ulong value, Span<byte> buffer)
  249. {
  250. buffer[0] = (byte)(value >> 56);
  251. buffer[1] = (byte)(value >> 48);
  252. buffer[2] = (byte)(value >> 40);
  253. buffer[3] = (byte)(value >> 32);
  254. buffer[4] = (byte)(value >> 24);
  255. buffer[5] = (byte)(value >> 16);
  256. buffer[6] = (byte)(value >> 8);
  257. buffer[7] = (byte) value;
  258. }
  259. /// <summary>
  260. /// Given a 64-bit integer, and a byte-array buffer and offset,
  261. /// - write the 8 bytes of that integer into the buffer starting at that offset, in Big-endian order.
  262. /// </summary>
  263. /// <param name="value">the long value to convert into bytes</param>
  264. /// <param name="buffer">the byte-array to write the long value's bytes into</param>
  265. /// <param name="offset">Offset to write to</param>
  266. public static void PutUInt64(ulong value, byte[] buffer, int offset)
  267. {
  268. buffer[offset] = (byte)(value >> 56);
  269. buffer[offset + 1] = (byte)(value >> 48);
  270. buffer[offset + 2] = (byte)(value >> 40);
  271. buffer[offset + 3] = (byte)(value >> 32);
  272. buffer[offset + 4] = (byte)(value >> 24);
  273. buffer[offset + 5] = (byte)(value >> 16);
  274. buffer[offset + 6] = (byte)(value >> 8);
  275. buffer[offset + 7] = (byte) value;
  276. }
  277. /// <summary>
  278. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  279. /// - return a 64-bit integer derived from the 8 bytes starting at that offset.
  280. /// </summary>
  281. /// <param name="buffer">the byte-array to get the Int64 from</param>
  282. /// <param name="offset">Offset to read from</param>
  283. /// <returns></returns>
  284. public static ulong ToUInt64(byte[] buffer, int offset)
  285. {
  286. return
  287. (ulong)buffer[offset] << 56 |
  288. (ulong)buffer[offset + 1] << 48 |
  289. (ulong)buffer[offset + 2] << 40 |
  290. (ulong)buffer[offset + 3] << 32 |
  291. (ulong)buffer[offset + 4] << 24 |
  292. (ulong)buffer[offset + 5] << 16 |
  293. (ulong)buffer[offset + 6] << 8 |
  294. (ulong)buffer[offset + 7];
  295. }
  296. /// <summary>
  297. /// Given a byte-array assumed to be in Big-endian order, and an offset into it
  298. /// - return a 64-bit integer derived from the 8 bytes starting at that offset.
  299. /// </summary>
  300. /// <param name="buffer">the byte-array to get the Int64 from</param>
  301. /// <param name="offset">Offset to read from</param>
  302. /// <returns></returns>
  303. public static ulong ToUInt64(Span<byte> buffer, int offset)
  304. {
  305. return
  306. (ulong)buffer[offset] << 56 |
  307. (ulong)buffer[offset + 1] << 48 |
  308. (ulong)buffer[offset + 2] << 40 |
  309. (ulong)buffer[offset + 3] << 32 |
  310. (ulong)buffer[offset + 4] << 24 |
  311. (ulong)buffer[offset + 5] << 16 |
  312. (ulong)buffer[offset + 6] << 8 |
  313. (ulong)buffer[offset + 7];
  314. }
  315. }
  316. }