// // System.BitConverter // // Author: // Matt Kimball (matt@kimball.net) // using System; namespace System { public sealed class BitConverter { private BitConverter () {} static bool AmILittleEndian() { byte[] one = GetBytes((int)1); return (one[0] == 1); } public static readonly bool IsLittleEndian = AmILittleEndian (); public static long DoubleToInt64Bits(double value) { return ToInt64(GetBytes(value), 0); } public static double Int64BitsToDouble(long value) { return ToDouble(GetBytes(value), 0); } unsafe static byte[] GetBytes(byte *ptr, int count) { byte[] ret = new byte[count]; for (int i = 0; i < count; i++) { ret[i] = ptr[i]; } return ret; } unsafe public static byte[] GetBytes(bool value) { return GetBytes((byte *)&value, 1); } unsafe public static byte[] GetBytes(char value) { return GetBytes((byte *)&value, 2); } unsafe public static byte[] GetBytes(short value) { return GetBytes((byte *)&value, 2); } unsafe public static byte[] GetBytes(int value) { return GetBytes((byte *)&value, 4); } unsafe public static byte[] GetBytes(long value) { return GetBytes((byte *)&value, 8); } [CLSCompliant(false)] unsafe public static byte[] GetBytes(ushort value) { return GetBytes((byte *)&value, 2); } [CLSCompliant(false)] unsafe public static byte[] GetBytes(uint value) { return GetBytes((byte *)&value, 4); } [CLSCompliant(false)] unsafe public static byte[] GetBytes(ulong value) { return GetBytes((byte *)&value, 8); } unsafe public static byte[] GetBytes(float value) { return GetBytes((byte *)&value, 4); } unsafe public static byte[] GetBytes(double value) { return GetBytes((byte *)&value, 8); } unsafe static void PutBytes(byte *dst, byte[] src, int start_index, int count) { if (src == null) { throw new ArgumentNullException(); } if (src.Length < start_index + count) { // LAMESPEC: // the docs say it should be ArgumentOutOfRangeException, but // the mscorlib throws an ArgumentException. throw new ArgumentException(); } for (int i = 0; i < count; i++) { dst[i] = src[i + start_index]; } } unsafe public static bool ToBoolean(byte[] value, int start_index) { bool ret; PutBytes((byte *)&ret, value, start_index, 1); return ret; } unsafe public static char ToChar(byte[] value, int start_index) { char ret; PutBytes((byte *)&ret, value, start_index, 2); return ret; } unsafe public static short ToInt16(byte[] value, int start_index) { short ret; PutBytes((byte *)&ret, value, start_index, 2); return ret; } unsafe public static int ToInt32(byte[] value, int start_index) { int ret; PutBytes((byte *)&ret, value, start_index, 4); return ret; } unsafe public static long ToInt64(byte[] value, int start_index) { long ret; PutBytes((byte *)&ret, value, start_index, 8); return ret; } [CLSCompliant(false)] unsafe public static ushort ToUInt16(byte[] value, int start_index) { ushort ret; PutBytes((byte *)&ret, value, start_index, 2); return ret; } [CLSCompliant(false)] unsafe public static uint ToUInt32(byte[] value, int start_index) { uint ret; PutBytes((byte *)&ret, value, start_index, 4); return ret; } [CLSCompliant(false)] unsafe public static ulong ToUInt64(byte[] value, int start_index) { ulong ret; PutBytes((byte *)&ret, value, start_index, 8); return ret; } unsafe public static float ToSingle(byte[] value, int start_index) { float ret; PutBytes((byte *)&ret, value, start_index, 4); return ret; } unsafe public static double ToDouble(byte[] value, int start_index) { double ret; PutBytes((byte *)&ret, value, start_index, 8); return ret; } public static string ToString(byte[] value) { if (value == null) { throw new ArgumentNullException(); } return ToString(value, 0, value.Length); } public static string ToString(byte[] value, int start_index) { if (value == null) throw new ArgumentNullException("value"); if (start_index < 0 || start_index > value.Length - 1) throw new ArgumentOutOfRangeException("start_index"); return ToString(value, start_index, value.Length - start_index); } public static string ToString(byte[] value, int start_index, int length) { if (value == null) { throw new ArgumentNullException(); } // The 4th and last clause (start_index >= value.Length) // was added as a small fix to a very obscure bug. // It makes a small difference when start_index is // outside the range and length==0. if (start_index < 0 || length < 0 || start_index + length > value.Length || start_index >= value.Length) { throw new ArgumentOutOfRangeException(); } string ret = ""; int end = start_index + length; for (int i = start_index; i < end; i++) { if (i > start_index) ret = ret + '-'; char high = (char)((value[i] >> 4) & 0x0f); char low = (char)(value[i] & 0x0f); if (high < 10) high += '0'; else { high -= (char) 10; high += 'A'; } if (low < 10) low += '0'; else { low -= (char) 10; low += 'A'; } ret = ret + high + low; } return ret; } } }