using System; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; namespace UTILS { // Converts base data types to an array of bytes, and an array of bytes to base data types. // This class must be compiled with the "unsafe" code option specified in "Build" menu public static class BitDiddle { // Indicates the byte order ("endianness") in which data is stored in this computer architecture. public static readonly bool IsLittleEndian = Utility.ExtractValueFromArray(new byte[] { 0xaa, 0xbb }, 0, 2) == 0xbbaa; #region Boolean // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, bool value) { Utility.InsertValueIntoArray(data, startIndex, 1, value ? 1u : 0u); } // Returns the specified Boolean value as an array of bytes. public static byte[] GetBytes(bool value) { var array = new byte[1]; InsertValueIntoArray(array, 0, value); return array; } // Returns a Boolean value converted from one byte at a specified position in a byte array. public static bool ToBoolean(byte[] value, int startIndex) { return Utility.ExtractValueFromArray(value, startIndex, 1) != 0u; } #endregion #region Char // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, char value) { Utility.InsertValueIntoArray(data, startIndex, 2, value); } // Returns the specified Unicode character value as an array of bytes. public static byte[] GetBytes(char value) { var array = new byte[2]; InsertValueIntoArray(array, 0, value); return array; } // Returns a Unicode character converted from two bytes at a specified position in a byte array. public static char ToChar(byte[] value, int startIndex) { return (char)Utility.ExtractValueFromArray(value, startIndex, 2); } #endregion #region Int16 // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, short value) { Utility.InsertValueIntoArray(data, startIndex, 2, (uint)value); } // Returns the specified 16-bit signed integer value as an array of bytes. public static byte[] GetBytes(short value) { var array = new byte[2]; InsertValueIntoArray(array, 0, value); return array; } // Returns a 16-bit signed integer converted from two bytes at a specified position in a byte array. public static short ToInt16(byte[] value, int startIndex) { return (short)Utility.ExtractValueFromArray(value, startIndex, 2); } #endregion #region UInt16 // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, ushort value) { Utility.InsertValueIntoArray(data, startIndex, 2, (uint)value); } // Returns the specified 16-bit unsigned integer value as an array of bytes. public static byte[] GetBytes(ushort value) { var array = new byte[2]; InsertValueIntoArray(array, 0, value); return array; } // Returns a 16-bit unsigned integer converted from two bytes at a specified position in a byte array. public static ushort ToUInt16(byte[] value, int startIndex) { return (ushort)Utility.ExtractValueFromArray(value, startIndex, 2); } #endregion #region Int32 // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, int value) { Utility.InsertValueIntoArray(data, startIndex, 4, (uint)value); } // Returns the specified 32-bit signed integer value as an array of bytes. public static byte[] GetBytes(int value) { var array = new byte[4]; InsertValueIntoArray(array, 0, value); return array; } // Returns a 32-bit signed integer converted from four bytes at a specified position in a byte array. public static int ToInt32(byte[] value, int startIndex) { return (int)Utility.ExtractValueFromArray(value, startIndex, 4); } #endregion #region UInt32 /// Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, uint value) { Utility.InsertValueIntoArray(data, startIndex, 4, value); } // Returns the specified 32-bit unsigned integer value as an array of bytes. public static byte[] GetBytes(uint value) { var array = new byte[4]; InsertValueIntoArray(array, 0, value); return array; } // Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array. public static uint ToUInt32(byte[] value, int startIndex) { return Utility.ExtractValueFromArray(value, startIndex, 4); } #endregion #region Int64 // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, long value) { var high = (uint)(value >> 32); var low = (uint)value; if (IsLittleEndian) { Utility.InsertValueIntoArray(data, startIndex, 4, low); Utility.InsertValueIntoArray(data, startIndex + 4, 4, high); } else { Utility.InsertValueIntoArray(data, startIndex, 4, high); Utility.InsertValueIntoArray(data, startIndex + 4, 4, low); } } // Returns the specified 64-bit signed integer value as an array of bytes. public static byte[] GetBytes(long value) { var array = new byte[8]; InsertValueIntoArray(array, 0, value); return array; } // Returns a 64-bit signed integer converted from eight bytes at a specified position in a byte array. public static long ToInt64(byte[] value, int startIndex) { var value0 = (ulong)Utility.ExtractValueFromArray(value, startIndex, 4); var value1 = (ulong)Utility.ExtractValueFromArray(value, startIndex + 4, 4); if (IsLittleEndian) { return (long)(value1 << 32 | value0); } else { return (long)(value0 << 32 | value1); } } #endregion #region UInt64 // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, ulong value) { var high = (uint)(value >> 32); var low = (uint)value; if (IsLittleEndian) { Utility.InsertValueIntoArray(data, startIndex, 4, low); Utility.InsertValueIntoArray(data, startIndex + 4, 4, high); } else { Utility.InsertValueIntoArray(data, startIndex, 4, high); Utility.InsertValueIntoArray(data, startIndex + 4, 4, low); } } // Returns the specified 64-bit unsigned integer value as an array of bytes. public static byte[] GetBytes(ulong value) { var array = new byte[8]; InsertValueIntoArray(array, 0, value); return array; } // Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array. public static ulong ToUInt64(byte[] value, int startIndex) { var value0 = (ulong)Utility.ExtractValueFromArray(value, startIndex, 4); var value1 = (ulong)Utility.ExtractValueFromArray(value, startIndex + 4, 4); if (IsLittleEndian) { return value1 << 32 | value0; } else { return value0 << 32 | value1; } } #endregion #region Single // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, float value) { unsafe { var buffer = *((uint*)&value); Utility.InsertValueIntoArray(data, startIndex, 4, buffer); } } // Returns the specified single-precision floating point value as an array of bytes. public static byte[] GetBytes(float value) { var array = new byte[4]; InsertValueIntoArray(array, 0, value); return array; } // Returns a single-precision floating point number converted from four bytes at a specified position in a byte array. public static float ToSingle(byte[] value, int startIndex) { var result = Utility.ExtractValueFromArray(value, startIndex, 4); unsafe { return *((float*)&result); } } #endregion #region Double // Inserts a value at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, double value) { unsafe { var buffer = *((ulong*)&value); InsertValueIntoArray(data, startIndex, buffer); } } // Returns the specified double-precision floating point value as an array of bytes. public static byte[] GetBytes(double value) { var array = new byte[8]; InsertValueIntoArray(array, 0, value); return array; } // Returns a double-precision floating point number converted from eight bytes at a specified position in a byte array. public static double ToDouble(byte[] value, int startIndex) { var result = ToUInt64(value, startIndex); unsafe { return *((double*)&result); } } #endregion #region DateTime // Inserts a DateTime at a specified position in a byte array. public static void InsertValueIntoArray(byte[] data, int startIndex, DateTime value) { unsafe { var buffer = *((ulong*)&value); InsertValueIntoArray(data, startIndex, buffer); } } // Returns the specified DateTime value as an array of bytes. public static byte[] GetBytes(DateTime value) { var array = new byte[8]; InsertValueIntoArray(array, 0, value); return array; } // Returns a DateTime converted from eight bytes at a specified position in a byte array. public static DateTime ToDateTime(byte[] value, int startIndex) { var result = ToUInt64(value, startIndex); unsafe { return *((DateTime*) &result); } } #endregion // Converts the specified double-precision floating point number to a 64-bit signed integer. public static long DoubleToInt64Bits(double value) { unsafe { return *((long*)&value); } } // Converts the specified 64-bit signed integer to a double-precision floating point number. public static double Int64BitsToDouble(long value) { unsafe { return *((double*)&value); } } } }