Skip to content

Commit

Permalink
Fix decimals + add floating point type tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Kermalis committed Sep 8, 2020
1 parent 2800bf5 commit dddb7d2
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Source/EndianBinaryIO.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageId>EndianBinaryIO</PackageId>
<Product>EndianBinaryIO</Product>
<AssemblyName>EndianBinaryIO</AssemblyName>
<Version>1.0.1.0</Version>
<Version>1.0.2.0</Version>
<RepositoryUrl>https://github.com/Kermalis/EndianBinaryIO</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<NoWarn />
Expand Down
54 changes: 36 additions & 18 deletions Source/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,30 @@ public static unsafe double BytesToDouble(byte[] value, int startIndex)
return *(double*)&val;
}
// TODO: https://github.com/Kermalis/EndianBinaryIO/issues/3
public static decimal BytesToDecimal(byte[] value, int startIndex)
public static unsafe decimal BytesToDecimal(byte[] value, int startIndex)
{
int i1 = BytesToInt32(value, startIndex);
int i2 = BytesToInt32(value, startIndex + 4);
int i3 = BytesToInt32(value, startIndex + 8);
int i4 = BytesToInt32(value, startIndex + 12);
return new decimal(new int[] { i1, i2, i3, i4 });
int i1, i2, i3, i4;
int[] bits;
fixed (byte* b = &value[startIndex])
{
if (SystemEndianness == Endianness.LittleEndian)
{
i1 = (*b) | (*(b + 1) << 8) | (*(b + 2) << 16) | (*(b + 3) << 24);
i2 = (*(b + 4)) | (*(b + 5) << 8) | (*(b + 6) << 16) | (*(b + 7) << 24);
i3 = (*(b + 8)) | (*(b + 9) << 8) | (*(b + 10) << 16) | (*(b + 11) << 24);
i4 = (*(b + 12)) | (*(b + 13) << 8) | (*(b + 14) << 16) | (*(b + 15) << 24);
bits = new int[] { i3, i4, i2, i1 };
}
else
{
i1 = (*b << 24) | (*(b + 1) << 16) | (*(b + 2) << 8) | (*(b + 3));
i2 = (*(b + 4) << 24) | (*(b + 5) << 16) | (*(b + 6) << 8) | (*(b + 7));
i3 = (*(b + 8) << 24) | (*(b + 9) << 16) | (*(b + 10) << 8) | (*(b + 11));
i4 = (*(b + 12) << 24) | (*(b + 13) << 16) | (*(b + 14) << 8) | (*(b + 15));
bits = new int[] { i2, i1, i3, i4 }; // Not tested, as I do not have a big endian system
}
}
return new decimal(bits);
}

public static T AttributeValueOrDefault<T>(PropertyInfo propertyInfo, Type attributeType, T defaultValue)
Expand All @@ -162,20 +179,21 @@ public static T AttributeValueOrDefault<T>(PropertyInfo propertyInfo, Type attri

public static void FlipPrimitives(byte[] buffer, Endianness targetEndianness, int byteCount, int primitiveSize)
{
if (SystemEndianness != targetEndianness)
if (SystemEndianness == targetEndianness || primitiveSize <= 1)
{
return;
}
for (int i = 0; i < byteCount; i += primitiveSize)
{
for (int i = 0; i < byteCount; i += primitiveSize)
int a = i;
int b = i + primitiveSize - 1;
while (a < b)
{
int a = i;
int b = i + primitiveSize - 1;
while (a < b)
{
byte by = buffer[a];
buffer[a] = buffer[b];
buffer[b] = by;
a++;
b--;
}
byte by = buffer[a];
buffer[a] = buffer[b];
buffer[b] = by;
a++;
b--;
}
}
}
Expand Down
124 changes: 124 additions & 0 deletions Testing/FloatTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using Kermalis.EndianBinaryIO;
using System.IO;
using System.Linq;
using Xunit;

namespace Kermalis.EndianBinaryIOTests
{
public sealed class FloatTests
{
private const float TestValue_Single = 1234.1234f;
private const double TestValue_Double = 12345678.12345678d;
private const decimal TestValue_Decimal = 12345678909876543210.123456789M;

private static readonly byte[] _bigEndianBytes_Single = new byte[4]
{
0x44, 0x9A, 0x43, 0xF3
};
private static readonly byte[] _littleEndianBytes_Single = new byte[4]
{
0xF3, 0x43, 0x9A, 0x44
};
private static readonly byte[] _bigEndianBytes_Double = new byte[8]
{
0x41, 0x67, 0x8C, 0x29, 0xC3, 0xF3, 0x5B, 0xA2
};
private static readonly byte[] _littleEndianBytes_Double = new byte[8]
{
0xA2, 0x5B, 0xF3, 0xC3, 0x29, 0x8C, 0x67, 0x41
};
private static readonly byte[] _bigEndianBytes_Decimal = new byte[16]
{
0xBE, 0xAD, 0x40, 0x75, 0xA0, 0x84, 0x71, 0x15, 0x27, 0xE4, 0x1B, 0x32, 0x00, 0x09, 0x00, 0x00
};
private static readonly byte[] _littleEndianBytes_Decimal = new byte[16]
{
0x00, 0x00, 0x09, 0x00, 0x32, 0x1B, 0xE4, 0x27, 0x15, 0x71, 0x84, 0xA0, 0x75, 0x40, 0xAD, 0xBE
};

[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReadSingle(bool le)
{
byte[] input = le ? _littleEndianBytes_Single : _bigEndianBytes_Single;
Endianness e = le ? Endianness.LittleEndian : Endianness.BigEndian;
using (var stream = new MemoryStream(input))
using (var reader = new EndianBinaryReader(stream, endianness: e))
{
Assert.Equal(reader.ReadSingle(), TestValue_Single);
}
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void WriteSingle(bool le)
{
byte[] input = le ? _littleEndianBytes_Single : _bigEndianBytes_Single;
Endianness e = le ? Endianness.LittleEndian : Endianness.BigEndian;
byte[] bytes = new byte[4];
using (var stream = new MemoryStream(bytes))
using (var writer = new EndianBinaryWriter(stream, endianness: e))
{
writer.Write(TestValue_Single);
}
Assert.True(bytes.SequenceEqual(input));
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReadDouble(bool le)
{
byte[] input = le ? _littleEndianBytes_Double : _bigEndianBytes_Double;
Endianness e = le ? Endianness.LittleEndian : Endianness.BigEndian;
using (var stream = new MemoryStream(input))
using (var reader = new EndianBinaryReader(stream, endianness: e))
{
Assert.Equal(reader.ReadDouble(), TestValue_Double);
}
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void WriteDouble(bool le)
{
byte[] input = le ? _littleEndianBytes_Double : _bigEndianBytes_Double;
Endianness e = le ? Endianness.LittleEndian : Endianness.BigEndian;
byte[] bytes = new byte[8];
using (var stream = new MemoryStream(bytes))
using (var writer = new EndianBinaryWriter(stream, endianness: e))
{
writer.Write(TestValue_Double);
}
Assert.True(bytes.SequenceEqual(input));
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReadDecimal(bool le)
{
byte[] input = le ? _littleEndianBytes_Decimal : _bigEndianBytes_Decimal;
Endianness e = le ? Endianness.LittleEndian : Endianness.BigEndian;
using (var stream = new MemoryStream(input))
using (var reader = new EndianBinaryReader(stream, endianness: e))
{
Assert.Equal(reader.ReadDecimal(), TestValue_Decimal);
}
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void WriteDecimal(bool le)
{
byte[] input = le ? _littleEndianBytes_Decimal : _bigEndianBytes_Decimal;
Endianness e = le ? Endianness.LittleEndian : Endianness.BigEndian;
byte[] bytes = new byte[16];
using (var stream = new MemoryStream(bytes))
using (var writer = new EndianBinaryWriter(stream, endianness: e))
{
writer.Write(TestValue_Decimal);
}
Assert.True(bytes.SequenceEqual(input));
}
}
}

0 comments on commit dddb7d2

Please sign in to comment.