2 using System.Collections.Generic;
8 public class InteropException : Exception
10 public InteropException()
14 public InteropException(string message)
19 public InteropException(string message, Exception inner)
20 : base(message, inner)
27 public static byte[] ReverseIfLE(byte[] source)
29 if (BitConverter.IsLittleEndian)
31 Array.Reverse(source);
37 public static byte[] LEBytes(uint[] values)
39 if (BitConverter.IsLittleEndian)
41 byte[] result = new byte[values.Length * sizeof(uint)];
42 Buffer.BlockCopy(values, 0, result, 0, result.Length);
48 List<byte> result = new List<byte>();
50 foreach (uint i in values)
52 result.AddRange(LEBytes(i));
55 return result.ToArray();
59 public static uint[] ToUInt32Array(byte[] bytes)
61 if (BitConverter.IsLittleEndian)
63 uint[] result = new uint[bytes.Length / sizeof(uint)];
64 Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length);
70 List<uint> result = new List<uint>();
72 for (int i = 0; i < bytes.Length; i += 4)
74 result.Add(LEBytesToUInt32(bytes.Skip(i).Take(4).ToArray()));
77 return result.ToArray();
81 public static byte[] LEBytes(ushort n)
83 byte[] resultBytes = BitConverter.GetBytes(n);
85 if (!BitConverter.IsLittleEndian)
87 // Reverse array if we are on big-endian machine
88 Array.Reverse(resultBytes);
94 public static byte[] LEBytes(uint n)
96 byte[] resultBytes = BitConverter.GetBytes(n);
98 if (!BitConverter.IsLittleEndian)
100 // Reverse array if we are on big-endian machine
101 Array.Reverse(resultBytes);
107 public static byte[] LEBytes(ulong n)
109 byte[] resultBytes = BitConverter.GetBytes(n);
111 if (!BitConverter.IsLittleEndian)
113 // Reverse array if we are on big-endian machine
114 Array.Reverse(resultBytes);
120 public static byte[] BEBytes(ushort n)
122 byte[] resultBytes = BitConverter.GetBytes(n);
124 if (BitConverter.IsLittleEndian)
126 // Reverse array if we are on little-endian machine
127 Array.Reverse(resultBytes);
133 public static byte[] BEBytes(uint n)
135 byte[] resultBytes = BitConverter.GetBytes(n);
137 if (BitConverter.IsLittleEndian)
139 // Reverse array if we are on little-endian machine
140 Array.Reverse(resultBytes);
146 public static byte[] BEBytes(ulong n)
148 byte[] resultBytes = BitConverter.GetBytes(n);
150 if (BitConverter.IsLittleEndian)
152 // Reverse array if we are on little-endian machine
153 Array.Reverse(resultBytes);
159 public static ushort LEBytesToUInt16(byte[] bytes)
161 if (bytes.Length != sizeof(ushort))
163 throw new InteropException("Array size doesn't match the ushort data type.");
166 if (!BitConverter.IsLittleEndian)
168 // Reverse array if we are on big-endian machine
169 Array.Reverse(bytes);
172 return BitConverter.ToUInt16(bytes, 0);
175 public static uint LEBytesToUInt32(byte[] bytes)
177 if (bytes.Length != sizeof(uint))
179 throw new InteropException("Array size doesn't match the uint data type.");
182 if (!BitConverter.IsLittleEndian)
184 // Reverse array if we are on big-endian machine
185 Array.Reverse(bytes);
188 return BitConverter.ToUInt32(bytes, 0);
191 public static ulong LEBytesToUInt64(byte[] bytes)
193 if (bytes.Length != sizeof(ulong))
195 throw new InteropException("Array size doesn't match the ulong data type.");
198 if (!BitConverter.IsLittleEndian)
200 // Reverse array if we are on big-endian machine
201 Array.Reverse(bytes);
204 return BitConverter.ToUInt64(bytes, 0);
207 public static ushort BEBytesToUInt16(byte[] bytes)
209 if (bytes.Length != sizeof(ushort))
211 throw new InteropException("Array size doesn't match the ushort data type.");
214 if (BitConverter.IsLittleEndian)
216 // Reverse array if we are on little-endian machine
217 Array.Reverse(bytes);
220 return BitConverter.ToUInt16(bytes, 0);
223 public static uint BEBytesToUInt32(byte[] bytes)
225 if (bytes.Length != sizeof(uint))
227 throw new InteropException("Array size doesn't match the uint data type.");
230 if (BitConverter.IsLittleEndian)
232 // Reverse array if we are on little-endian machine
233 Array.Reverse(bytes);
236 return BitConverter.ToUInt32(bytes, 0);
239 public static ulong BEBytesToUInt64(byte[] bytes)
241 if (bytes.Length != sizeof(ulong))
243 throw new InteropException("Array size doesn't match the ulong data type.");
246 if (BitConverter.IsLittleEndian)
248 // Reverse array if we are on little-endian machine
249 Array.Reverse(bytes);
252 return BitConverter.ToUInt64(bytes, 0);
255 public static IEnumerable<byte> ParseHex(string hex)
257 return Enumerable.Range(0, hex.Length)
258 .Where(x => x % 2 == 0)
259 .Select(x => Convert.ToByte(hex.Substring(x, 2), 16));
262 public static string ToHex(IEnumerable<byte> bytes)
264 StringBuilder sb = new StringBuilder();
265 foreach (byte b in bytes)
267 sb.AppendFormat("{0:x2}", b);
269 return sb.ToString();
272 public static void UInt16ToBE(ushort n, byte[] bs)
274 bs[0] = (byte)(n >> 8);
278 public static ushort BEToUInt16(byte[] bs)
280 ushort n = (ushort)(bs[0] << 8);
285 public static ushort BEToUInt16(byte[] bs, int off)
287 ushort n = (ushort)(bs[off] << 8);
288 n |= (ushort)bs[++off];
292 public static void UInt16ToLE(ushort n, byte[] bs)
295 bs[1] = (byte)(n >> 8);
298 public static void UInt16ToLE(ushort n, byte[] bs, int off)
301 bs[++off] = (byte)(n >> 8);
304 public static ushort LEToUInt16(byte[] bs)
306 ushort n = (ushort)bs[0];
307 n |= (ushort)(bs[1] << 8);
311 public static ushort LEToUInt16(byte[] bs, int off)
313 ushort n = (ushort)bs[off];
314 n |= (ushort)(bs[++off] << 8);
318 public static void UInt32ToBE(uint n, byte[] bs)
320 bs[0] = (byte)(n >> 24);
321 bs[1] = (byte)(n >> 16);
322 bs[2] = (byte)(n >> 8);
326 public static void UInt32ToBE(uint n, byte[] bs, int off)
328 bs[off] = (byte)(n >> 24);
329 bs[++off] = (byte)(n >> 16);
330 bs[++off] = (byte)(n >> 8);
331 bs[++off] = (byte)(n);
334 public static uint BEToUInt32(byte[] bs)
336 uint n = (uint)bs[0] << 24;
337 n |= (uint)bs[1] << 16;
338 n |= (uint)bs[2] << 8;
343 public static uint BEToUInt32(byte[] bs, int off)
345 uint n = (uint)bs[off] << 24;
346 n |= (uint)bs[++off] << 16;
347 n |= (uint)bs[++off] << 8;
348 n |= (uint)bs[++off];
352 public static ulong BEToUInt64(byte[] bs)
354 uint hi = BEToUInt32(bs);
355 uint lo = BEToUInt32(bs, 4);
356 return ((ulong)hi << 32) | (ulong)lo;
359 public static ulong BEToUInt64(byte[] bs, int off)
361 uint hi = BEToUInt32(bs, off);
362 uint lo = BEToUInt32(bs, off + 4);
363 return ((ulong)hi << 32) | (ulong)lo;
366 public static void UInt64ToBE(ulong n, byte[] bs)
368 UInt32ToBE((uint)(n >> 32), bs);
369 UInt32ToBE((uint)(n), bs, 4);
372 public static void UInt64ToBE(ulong n, byte[] bs, int off)
374 UInt32ToBE((uint)(n >> 32), bs, off);
375 UInt32ToBE((uint)(n), bs, off + 4);
378 public static void UInt32ToLE(uint n, byte[] bs)
381 bs[1] = (byte)(n >> 8);
382 bs[2] = (byte)(n >> 16);
383 bs[3] = (byte)(n >> 24);
386 public static void UInt32ToLE(uint n, byte[] bs, int off)
389 bs[++off] = (byte)(n >> 8);
390 bs[++off] = (byte)(n >> 16);
391 bs[++off] = (byte)(n >> 24);
394 public static uint LEToUInt32(byte[] bs)
396 uint n = (uint)bs[0];
397 n |= (uint)bs[1] << 8;
398 n |= (uint)bs[2] << 16;
399 n |= (uint)bs[3] << 24;
403 public static uint LEToUInt32(byte[] bs, int off)
405 uint n = (uint)bs[off];
406 n |= (uint)bs[++off] << 8;
407 n |= (uint)bs[++off] << 16;
408 n |= (uint)bs[++off] << 24;
412 public static ulong LEToUInt64(byte[] bs)
414 uint lo = LEToUInt32(bs);
415 uint hi = LEToUInt32(bs, 4);
416 return ((ulong)hi << 32) | (ulong)lo;
419 public static ulong LEToUInt64(byte[] bs, int off)
421 uint lo = LEToUInt32(bs, off);
422 uint hi = LEToUInt32(bs, off + 4);
423 return ((ulong)hi << 32) | (ulong)lo;
426 public static void UInt64ToLE(ulong n, byte[] bs)
428 UInt32ToLE((uint)(n), bs);
429 UInt32ToLE((uint)(n >> 32), bs, 4);
432 public static void UInt64ToLE(ulong n, byte[] bs, int off)
434 UInt32ToLE((uint)(n), bs, off);
435 UInt32ToLE((uint)(n >> 32), bs, off + 4);