From 8eed14cfa2e6f47f96f5a0b87e77a8226cd2f0fd Mon Sep 17 00:00:00 2001 From: Quajak Date: Mon, 6 Aug 2018 17:25:41 +0200 Subject: [PATCH 1/2] Removed BitConverterImpl, as we now support unsafe --- .../System/BitConverterImpl.cs | 260 ------------------ 1 file changed, 260 deletions(-) delete mode 100644 source/Cosmos.Core_Plugs/System/BitConverterImpl.cs diff --git a/source/Cosmos.Core_Plugs/System/BitConverterImpl.cs b/source/Cosmos.Core_Plugs/System/BitConverterImpl.cs deleted file mode 100644 index 360ccdc66..000000000 --- a/source/Cosmos.Core_Plugs/System/BitConverterImpl.cs +++ /dev/null @@ -1,260 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.Contracts; -using System.Text; - -using IL2CPU.API.Attribs; - -namespace Cosmos.Core_Plugs.System -{ - [Plug(typeof(BitConverter))] - public class BitConverterImpl - { - public static byte[] GetBytes(bool value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 1); - - byte[] r = new byte[1]; - r[0] = (value ? (byte)1 : (byte)0); - return r; - } - - public static byte[] GetBytes(char value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 2); - - return GetBytes((short)value); - } - - public unsafe static byte[] GetBytes(short value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 2); - - byte[] bytes = new byte[2]; - fixed (byte* b = bytes) - *((short*)b) = value; - return bytes; - } - - public unsafe static byte[] GetBytes(int value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 4); - - byte[] bytes = new byte[4]; - fixed (byte* b = bytes) - *((int*)b) = value; - return bytes; - } - - public unsafe static byte[] GetBytes(long value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 8); - - byte[] bytes = new byte[8]; - fixed (byte* b = bytes) - *((long*)b) = value; - return bytes; - } - - public static byte[] GetBytes(ushort value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 2); - - return GetBytes((short)value); - } - - public static byte[] GetBytes(uint value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 4); - - return GetBytes((int)value); - } - - public static byte[] GetBytes(ulong value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 8); - - return GetBytes((long)value); - } - - public unsafe static byte[] GetBytes(float value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 4); - - return GetBytes(*(int*)&value); - } - - public unsafe static byte[] GetBytes(double value) - { - Contract.Ensures(Contract.Result() != null); - Contract.Ensures(Contract.Result().Length == 8); - - return GetBytes(*(long*)&value); - } - - public static unsafe short ToInt16(byte[] value, int startIndex) - { - if (value == null) - ThrowValueArgumentNull(); - if ((uint)startIndex >= value.Length) - ThrowStartIndexArgumentOutOfRange(); - if (startIndex > value.Length - 2) - ThrowValueArgumentTooSmall(); - Contract.EndContractBlock(); - - fixed (byte* pbyte = &value[startIndex]) - { - if (startIndex % 2 == 0) - { - // data is aligned - return *((short*)pbyte); - } - else if (BitConverter.IsLittleEndian) - { - return (short)((*pbyte) | (*(pbyte + 1) << 8)); - } - else - { - return (short)((*pbyte << 8) | (*(pbyte + 1))); - } - } - } - - public static unsafe int ToInt32(byte[] value, int startIndex) - { - if (value == null) - ThrowValueArgumentNull(); - if ((uint)startIndex >= value.Length) - ThrowStartIndexArgumentOutOfRange(); - if (startIndex > value.Length - 4) - ThrowValueArgumentTooSmall(); - Contract.EndContractBlock(); - - fixed (byte* pbyte = &value[startIndex]) - { - if (startIndex % 4 == 0) - { - // data is aligned - return *((int*)pbyte); - } - else if (BitConverter.IsLittleEndian) - { - return (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); - } - else - { - return (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); - } - } - } - - public static unsafe long ToInt64(byte[] value, int startIndex) - { - if (value == null) - ThrowValueArgumentNull(); - if ((uint)startIndex >= value.Length) - ThrowStartIndexArgumentOutOfRange(); - if (startIndex > value.Length - 8) - ThrowValueArgumentTooSmall(); - Contract.EndContractBlock(); - - fixed (byte* pbyte = &value[startIndex]) - { - if (startIndex % 8 == 0) - { - // data is aligned - return *((long*)pbyte); - } - else if (BitConverter.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); - } - } - } - - public static unsafe double ToDouble(byte[] value, int startIndex) - { - if (value == null) - throw new ArgumentNullException("value"); - if ((uint)startIndex > value.Length) - throw new ArgumentOutOfRangeException("startIndex"); - if (startIndex > value.Length - 8) - throw new ArgumentException("Array with offset is too short"); - Contract.EndContractBlock(); - - long val = ToInt64(value, startIndex); - return *(double*)&val; - } - - public static ushort ToUInt16(byte[] value, int startIndex) - { - if (value == null) - throw new ArgumentNullException("value"); - if ((uint)startIndex > value.Length) - throw new ArgumentOutOfRangeException("startIndex"); - if (startIndex > value.Length - 2) - throw new ArgumentException("Array with offset is too short"); - Contract.EndContractBlock(); - - return (ushort)ToInt16(value, startIndex); - } - - public static uint ToUInt32(byte[] value, int startIndex) - { - if (value == null) - throw new ArgumentNullException("value"); - if ((uint)startIndex > value.Length) - throw new ArgumentOutOfRangeException("startIndex"); - if (startIndex > value.Length - 4) - throw new ArgumentException("Array with offset is too short"); - Contract.EndContractBlock(); - - return (uint)ToInt32(value, startIndex); - } - - public static ulong ToUInt64(byte[] value, int startIndex) - { - if (value == null) - throw new ArgumentNullException("value"); - if ((uint)startIndex > value.Length) - throw new ArgumentOutOfRangeException("startIndex"); - if (startIndex > value.Length - 8) - throw new ArgumentException("Array with offset is too short"); - Contract.EndContractBlock(); - - return (ulong)ToInt64(value, startIndex); - } - - private static void ThrowValueArgumentNull() - { - throw new ArgumentNullException("value"); - } - - private static void ThrowStartIndexArgumentOutOfRange() - { - throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_Index"); - } - - private static void ThrowValueArgumentTooSmall() - { - throw new ArgumentException("Arg_ArrayPlusOffTooSmall", "value"); - } - } -} From c59bf1e4e30fdd2f58e65c1ddc8ab2422260e5c4 Mon Sep 17 00:00:00 2001 From: Quajak Date: Wed, 8 Aug 2018 09:04:22 +0200 Subject: [PATCH 2/2] Added tests for all BitConverter Methods --- .../System/BitConverterTest.cs | 84 +++++++++++++++++-- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/System/BitConverterTest.cs b/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/System/BitConverterTest.cs index 633859502..30c6c3215 100644 --- a/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/System/BitConverterTest.cs +++ b/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/System/BitConverterTest.cs @@ -11,6 +11,13 @@ namespace Cosmos.Compiler.Tests.Bcl.System string result; string expectedResult; + short aShort = 1; + byte[] shortBytes = BitConverter.GetBytes(aShort); + result = BitConverter.ToString(shortBytes); + expectedResult = "01-00"; + + Assert.IsTrue((result == expectedResult), "BitConverter.ToString(shortBytes) doesn't work: result " + result + " != " + expectedResult); + int anInt = 1; byte[] intBytes = BitConverter.GetBytes(anInt); @@ -29,6 +36,22 @@ namespace Cosmos.Compiler.Tests.Bcl.System Assert.IsTrue((result == expectedResult), "BitConverter.ToString(longBytes) doesn't work: result " + result + " != " + expectedResult); + ushort anUShort = 1; + byte[] ushortBytes = BitConverter.GetBytes(anUShort); + result = BitConverter.ToString(ushortBytes); + expectedResult = "01-00"; + + Assert.IsTrue((result == expectedResult), "BitConverter.ToString(ushortBytes) doesn't work: result " + result + " != " + expectedResult); + + uint anUInt = 1; + + byte[] uintBytes = BitConverter.GetBytes(anUInt); + + result = BitConverter.ToString(uintBytes, 0); + expectedResult = "01-00-00-00"; + + Assert.IsTrue((result == expectedResult), "BitConverter.ToString(uintBytes) doesn't work: result " + result + " != " + expectedResult); + ulong anULong = 1; byte[] ulongBytes = BitConverter.GetBytes(anULong); @@ -48,6 +71,55 @@ namespace Cosmos.Compiler.Tests.Bcl.System Assert.IsTrue((result == expectedResult), "BitConverter.ToString(floatBytes) doesn't work: result " + result + " != " + expectedResult); + double aDouble = 1.0; + result = BitConverter.ToString(BitConverter.GetBytes(aDouble)); + expectedResult = "00-00-00-00-00-00-F0-3F"; + Assert.IsTrue((result == expectedResult), "BitConverter.ToString(doubleBytes) doesn't work: result " + result + " != " + expectedResult); + + bool aBool = true; + result = BitConverter.ToString(BitConverter.GetBytes(aBool)); + expectedResult = "01"; + Assert.IsTrue((result == expectedResult), "BitConverter.ToString(bool) doesn't work: result " + result + " != " + expectedResult); + + char aChar = 'X'; + result = BitConverter.ToString(BitConverter.GetBytes(aChar)); + expectedResult = "58-00"; + Assert.IsTrue((result == expectedResult), "BitConverter.ToString(char) doesn't work: result " + result + " != " + expectedResult); + + //Tests for GetBytes and ToXXX + aShort = 240; + Assert.IsTrue(BitConverter.ToInt16(BitConverter.GetBytes(aShort), 0) == aShort, "BitConverter works with Int16"); + + aShort = -240; + Assert.IsTrue(BitConverter.ToInt16(BitConverter.GetBytes(aShort), 0) == aShort, "BitConverter works with negativ Int16"); + + anInt = 1234; + Assert.IsTrue(BitConverter.ToInt32(BitConverter.GetBytes(anInt), 0) == anInt, "BitConverter works with Int32"); + + anInt = -1234; + Assert.IsTrue(BitConverter.ToInt32(BitConverter.GetBytes(anInt), 0) == anInt, "BitConverter works with negative Int32"); + + aLong = 123456789000; + Assert.IsTrue(BitConverter.ToInt64(BitConverter.GetBytes(aLong), 0) == aLong, "BitConvert works with Int64"); + + aLong = -123456789000; + Assert.IsTrue(BitConverter.ToInt64(BitConverter.GetBytes(aLong), 0) == aLong, "BitConvert works with negative Int64"); + + anUShort = 240; + Assert.IsTrue(BitConverter.ToUInt16(BitConverter.GetBytes(anUShort), 0) == anUShort, "BitConverter works with UInt16"); + + anUInt = 1233346; + Assert.IsTrue(BitConverter.ToUInt32(BitConverter.GetBytes(anUInt), 0) == anUInt, "BitConverter works with UInt32"); + + anULong = 123456789000; + Assert.IsTrue(BitConverter.ToUInt64(BitConverter.GetBytes(anULong), 0) == anULong, "BitConverter works with UInt64"); + + aBool = false; + Assert.IsTrue(BitConverter.ToBoolean(BitConverter.GetBytes(aBool), 0) == aBool, "BitConverter works with Bool"); + + aChar = 'C'; + Assert.IsTrue(BitConverter.ToChar(BitConverter.GetBytes(aChar), 0) == aChar, "BitConverter works with Char"); + double Result; byte[] doubleBytes = BitConverter.GetBytes(0d); Result = BitConverter.ToDouble(doubleBytes, 0); @@ -77,14 +149,10 @@ namespace Cosmos.Compiler.Tests.Bcl.System Result = BitConverter.ToDouble(doubleBytes, 0); Assert.IsTrue(Result == -1.2345, "BitConverter.ToDouble works with -1.2345"); - double aDouble = 1.0; - - doubleBytes = BitConverter.GetBytes(aDouble); - - result = BitConverter.ToString(doubleBytes, 0); - expectedResult = "00-00-00-00-00-00-F0-3F"; - - Assert.IsTrue((result == expectedResult), "BitConverter.ToString(doubleBytes) doesn't work: result " + result + " != " + expectedResult); + //Conversion between doubles and long + Assert.IsTrue(BitConverter.Int64BitsToDouble(1) == 4.94065645841247E-324, "BitConverter long bits to double works"); + Assert.IsTrue(BitConverter.DoubleToInt64Bits(4.94065645841247E-324) == 1, "BitConverter double to long bits works"); + } } }