summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/BitConverter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/BitConverter.cs')
-rw-r--r--src/mscorlib/src/System/BitConverter.cs451
1 files changed, 451 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/BitConverter.cs b/src/mscorlib/src/System/BitConverter.cs
new file mode 100644
index 0000000000..e4bb9ddc88
--- /dev/null
+++ b/src/mscorlib/src/System/BitConverter.cs
@@ -0,0 +1,451 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================
+**
+**
+**
+** Purpose: Allows developers to view the base data types as
+** an arbitrary array of bits.
+**
+**
+===========================================================*/
+namespace System {
+
+ using System;
+ using System.Runtime.CompilerServices;
+ using System.Diagnostics.Contracts;
+ using System.Security;
+
+ // The BitConverter class contains methods for
+ // converting an array of bytes to one of the base data
+ // types, as well as for converting a base data type to an
+ // array of bytes.
+ //
+ // Only statics, does not need to be marked with the serializable attribute
+ public static class BitConverter {
+
+ // This field indicates the "endianess" of the architecture.
+ // The value is set to true if the architecture is
+ // little endian; false if it is big endian.
+#if BIGENDIAN
+ public static readonly bool IsLittleEndian /* = false */;
+#else
+ public static readonly bool IsLittleEndian = true;
+#endif
+
+ // Converts a byte into an array of bytes with length one.
+ public static byte[] GetBytes(bool value) {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 1);
+
+ byte[] r = new byte[1];
+ r[0] = (value ? (byte)Boolean.True : (byte)Boolean.False );
+ return r;
+ }
+
+ // Converts a char into an array of bytes with length two.
+ public static byte[] GetBytes(char value)
+ {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 2);
+
+ return GetBytes((short)value);
+ }
+
+ // Converts a short into an array of bytes with length
+ // two.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public unsafe static byte[] GetBytes(short value)
+ {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 2);
+
+ byte[] bytes = new byte[2];
+ fixed(byte* b = bytes)
+ *((short*)b) = value;
+ return bytes;
+ }
+
+ // Converts an int into an array of bytes with length
+ // four.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public unsafe static byte[] GetBytes(int value)
+ {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 4);
+
+ byte[] bytes = new byte[4];
+ fixed(byte* b = bytes)
+ *((int*)b) = value;
+ return bytes;
+ }
+
+ // Converts a long into an array of bytes with length
+ // eight.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public unsafe static byte[] GetBytes(long value)
+ {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 8);
+
+ byte[] bytes = new byte[8];
+ fixed(byte* b = bytes)
+ *((long*)b) = value;
+ return bytes;
+ }
+
+ // Converts an ushort into an array of bytes with
+ // length two.
+ [CLSCompliant(false)]
+ public static byte[] GetBytes(ushort value) {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 2);
+
+ return GetBytes((short)value);
+ }
+
+ // Converts an uint into an array of bytes with
+ // length four.
+ [CLSCompliant(false)]
+ public static byte[] GetBytes(uint value) {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 4);
+
+ return GetBytes((int)value);
+ }
+
+ // Converts an unsigned long into an array of bytes with
+ // length eight.
+ [CLSCompliant(false)]
+ public static byte[] GetBytes(ulong value) {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 8);
+
+ return GetBytes((long)value);
+ }
+
+ // Converts a float into an array of bytes with length
+ // four.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public unsafe static byte[] GetBytes(float value)
+ {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 4);
+
+ return GetBytes(*(int*)&value);
+ }
+
+ // Converts a double into an array of bytes with length
+ // eight.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public unsafe static byte[] GetBytes(double value)
+ {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+ Contract.Ensures(Contract.Result<byte[]>().Length == 8);
+
+ return GetBytes(*(long*)&value);
+ }
+
+ // Converts an array of bytes into a char.
+ public static char ToChar(byte[] value, int startIndex)
+ {
+ if (value == null) {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ }
+
+ if ((uint)startIndex >= value.Length) {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ }
+
+ if (startIndex > value.Length - 2) {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ }
+ Contract.EndContractBlock();
+
+ return (char)ToInt16(value, startIndex);
+ }
+
+ // Converts an array of bytes into a short.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public static unsafe short ToInt16(byte[] value, int startIndex) {
+ if( value == null) {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ }
+
+ if ((uint) startIndex >= value.Length) {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ }
+
+ if (startIndex > value.Length -2) {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ }
+ Contract.EndContractBlock();
+
+ fixed( byte * pbyte = &value[startIndex]) {
+ if( startIndex % 2 == 0) { // data is aligned
+ return *((short *) pbyte);
+ }
+ else {
+ if( IsLittleEndian) {
+ return (short)((*pbyte) | (*(pbyte + 1) << 8)) ;
+ }
+ else {
+ return (short)((*pbyte << 8) | (*(pbyte + 1)));
+ }
+ }
+ }
+
+ }
+
+ // Converts an array of bytes into an int.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public static unsafe int ToInt32 (byte[] value, int startIndex) {
+ if( value == null) {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ }
+
+ if ((uint) startIndex >= value.Length) {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ }
+
+ if (startIndex > value.Length -4) {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ }
+ Contract.EndContractBlock();
+
+ fixed( byte * pbyte = &value[startIndex]) {
+ if( startIndex % 4 == 0) { // data is aligned
+ return *((int *) pbyte);
+ }
+ else {
+ if( IsLittleEndian) {
+ return (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24);
+ }
+ else {
+ return (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3));
+ }
+ }
+ }
+ }
+
+ // Converts an array of bytes into a long.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public static unsafe long ToInt64 (byte[] value, int startIndex) {
+ if (value == null) {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ }
+
+ if ((uint) startIndex >= value.Length) {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ }
+
+ if (startIndex > value.Length -8) {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ }
+ Contract.EndContractBlock();
+
+ fixed( byte * pbyte = &value[startIndex]) {
+ if( startIndex % 8 == 0) { // data is aligned
+ return *((long *) pbyte);
+ }
+ else {
+ if( IsLittleEndian) {
+ int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24);
+ int i2 = (*(pbyte+4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24);
+ return (uint)i1 | ((long)i2 << 32);
+ }
+ else {
+ int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3));
+ int i2 = (*(pbyte+4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7));
+ return (uint)i2 | ((long)i1 << 32);
+ }
+ }
+ }
+ }
+
+
+ // Converts an array of bytes into an ushort.
+ //
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(byte[] value, int startIndex)
+ {
+ if (value == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ if ((uint)startIndex >= value.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ if (startIndex > value.Length - 2)
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ Contract.EndContractBlock();
+
+ return (ushort)ToInt16(value, startIndex);
+ }
+
+ // Converts an array of bytes into an uint.
+ //
+ [CLSCompliant(false)]
+ public static uint ToUInt32(byte[] value, int startIndex)
+ {
+ if (value == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ if ((uint)startIndex >= value.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ if (startIndex > value.Length - 4)
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ Contract.EndContractBlock();
+
+ return (uint)ToInt32(value, startIndex);
+ }
+
+ // Converts an array of bytes into an unsigned long.
+ //
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(byte[] value, int startIndex)
+ {
+ if (value == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ if ((uint)startIndex >= value.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ if (startIndex > value.Length - 8)
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ Contract.EndContractBlock();
+
+ return (ulong)ToInt64(value, startIndex);
+ }
+
+ // Converts an array of bytes into a float.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ unsafe public static float ToSingle (byte[] value, int startIndex)
+ {
+ if (value == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ if ((uint)startIndex >= value.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ if (startIndex > value.Length - 4)
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ Contract.EndContractBlock();
+
+ int val = ToInt32(value, startIndex);
+ return *(float*)&val;
+ }
+
+ // Converts an array of bytes into a double.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ unsafe public static double ToDouble (byte[] value, int startIndex)
+ {
+ if (value == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ if ((uint)startIndex >= value.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ if (startIndex > value.Length - 8)
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
+ Contract.EndContractBlock();
+
+ long val = ToInt64(value, startIndex);
+ return *(double*)&val;
+ }
+
+ private static char GetHexValue(int i) {
+ Contract.Assert( i >=0 && i <16, "i is out of range.");
+ if (i<10) {
+ return (char)(i + '0');
+ }
+
+ return (char)(i - 10 + 'A');
+ }
+
+ // Converts an array of bytes into a String.
+ public static String ToString (byte[] value, int startIndex, int length) {
+ if (value == null) {
+ throw new ArgumentNullException("value");
+ }
+
+ if (startIndex < 0 || startIndex >= value.Length && startIndex > 0) { // Don't throw for a 0 length array.
+ throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ }
+
+ if (length < 0) {
+ throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ }
+
+ if (startIndex > value.Length - length) {
+ throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ }
+ Contract.EndContractBlock();
+
+ if (length == 0) {
+ return string.Empty;
+ }
+
+ if (length > (Int32.MaxValue / 3)) {
+ // (Int32.MaxValue / 3) == 715,827,882 Bytes == 699 MB
+ throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_LengthTooLarge", (Int32.MaxValue / 3)));
+ }
+
+ int chArrayLength = length * 3;
+
+ char[] chArray = new char[chArrayLength];
+ int i = 0;
+ int index = startIndex;
+ for (i = 0; i < chArrayLength; i += 3) {
+ byte b = value[index++];
+ chArray[i]= GetHexValue(b/16);
+ chArray[i+1] = GetHexValue(b%16);
+ chArray[i+2] = '-';
+ }
+
+ // We don't need the last '-' character
+ return new String(chArray, 0, chArray.Length - 1);
+ }
+
+ // Converts an array of bytes into a String.
+ public static String ToString(byte [] value) {
+ if (value == null)
+ throw new ArgumentNullException("value");
+ Contract.Ensures(Contract.Result<String>() != null);
+ Contract.EndContractBlock();
+ return ToString(value, 0, value.Length);
+ }
+
+ // Converts an array of bytes into a String.
+ public static String ToString (byte [] value, int startIndex) {
+ if (value == null)
+ throw new ArgumentNullException("value");
+ Contract.Ensures(Contract.Result<String>() != null);
+ Contract.EndContractBlock();
+ return ToString(value, startIndex, value.Length - startIndex);
+ }
+
+ /*==================================ToBoolean===================================
+ **Action: Convert an array of bytes to a boolean value. We treat this array
+ ** as if the first 4 bytes were an Int4 an operate on this value.
+ **Returns: True if the Int4 value of the first 4 bytes is non-zero.
+ **Arguments: value -- The byte array
+ ** startIndex -- The position within the array.
+ **Exceptions: See ToInt4.
+ ==============================================================================*/
+ // Converts an array of bytes into a boolean.
+ public static bool ToBoolean(byte[] value, int startIndex) {
+ if (value==null)
+ throw new ArgumentNullException("value");
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (startIndex > value.Length - 1)
+ throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ Contract.EndContractBlock();
+
+ return (value[startIndex]==0)?false:true;
+ }
+
+ [SecuritySafeCritical]
+ public static unsafe long DoubleToInt64Bits(double value) {
+ return *((long *)&value);
+ }
+
+ [SecuritySafeCritical]
+ public static unsafe double Int64BitsToDouble(long value) {
+ return *((double*)&value);
+ }
+ }
+}