Merge pull request #1022 from quajak/master

Removed BitConverterImpl, as we now support unsafe
This commit is contained in:
fanoI 2018-09-16 16:11:34 +02:00 committed by GitHub
commit 5209ea5154
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 268 deletions

View file

@ -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");
}
}
}

View file

@ -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<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().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<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length == 2);
return GetBytes((short)value);
}
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;
}
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;
}
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;
}
public static byte[] GetBytes(ushort value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length == 2);
return GetBytes((short)value);
}
public static byte[] GetBytes(uint value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length == 4);
return GetBytes((int)value);
}
public static byte[] GetBytes(ulong value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length == 8);
return GetBytes((long)value);
}
public unsafe static byte[] GetBytes(float value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length == 4);
return GetBytes(*(int*)&value);
}
public unsafe static byte[] GetBytes(double value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().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");
}
}
}