Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 18 additions & 22 deletions LibCpp2IL/BinaryReaderHelpers.cs
Original file line number Diff line number Diff line change
@@ -1,63 +1,59 @@
using System;
using System.Buffers.Binary;
using System.IO;
using System.Runtime.CompilerServices;

namespace LibCpp2IL;

public static class BinaryReaderHelpers
{
public static byte[] Reverse(this byte[] b)
{
Array.Reverse(b);
return b;
}

public static ushort ReadUInt16WithReversedBits(this BinaryReader binRdr)
{
return BitConverter.ToUInt16(binRdr.ReadBytesRequired(sizeof(ushort)).Reverse(), 0);
return BinaryPrimitives.ReverseEndianness(binRdr.ReadUInt16());
}

public static short ReadInt16WithReversedBits(this BinaryReader binRdr)
{
return BitConverter.ToInt16(binRdr.ReadBytesRequired(sizeof(short)).Reverse(), 0);
return BinaryPrimitives.ReverseEndianness(binRdr.ReadInt16());
}

public static uint ReadUInt32WithReversedBits(this BinaryReader binRdr)
{
return BitConverter.ToUInt32(binRdr.ReadBytesRequired(sizeof(uint)).Reverse(), 0);
return BinaryPrimitives.ReverseEndianness(binRdr.ReadUInt32());
}

public static int ReadInt32WithReversedBits(this BinaryReader binRdr)
{
return BitConverter.ToInt32(binRdr.ReadBytesRequired(sizeof(int)).Reverse(), 0);
return BinaryPrimitives.ReverseEndianness(binRdr.ReadInt32());
}

public static ulong ReadUInt64WithReversedBits(this BinaryReader binRdr)
{
return BitConverter.ToUInt64(binRdr.ReadBytesRequired(sizeof(ulong)).Reverse(), 0);
return BinaryPrimitives.ReverseEndianness(binRdr.ReadUInt64());
}

public static long ReadInt64WithReversedBits(this BinaryReader binRdr)
{
return BitConverter.ToInt64(binRdr.ReadBytesRequired(sizeof(long)).Reverse(), 0);
return BinaryPrimitives.ReverseEndianness(binRdr.ReadInt64());
}

public static float ReadSingleWithReversedBits(this BinaryReader binRdr)
{
return BitConverter.ToSingle(binRdr.ReadBytesRequired(sizeof(float)).Reverse(), 0);
return BitCast<uint, float>(binRdr.ReadUInt32WithReversedBits());
}

public static double ReadDoubleWithReversedBits(this BinaryReader binRdr)
{
return BitConverter.ToDouble(binRdr.ReadBytesRequired(sizeof(double)).Reverse(), 0);
return BitCast<ulong, double>(binRdr.ReadUInt64WithReversedBits());
}

private static byte[] ReadBytesRequired(this BinaryReader binRdr, int byteCount)
private static TTo BitCast<TFrom, TTo>(TFrom source)
where TFrom : unmanaged
where TTo : unmanaged
{
var result = binRdr.ReadBytes(byteCount);

if (result.Length != byteCount)
throw new EndOfStreamException($"{byteCount} bytes required from stream, but only {result.Length} returned.");

return result;
#if NET8_0_OR_GREATER
return Unsafe.BitCast<TFrom, TTo>(source);
#else
return Unsafe.ReadUnaligned<TTo>(ref Unsafe.As<TFrom, byte>(ref source));
#endif
}
}
4 changes: 2 additions & 2 deletions LibCpp2IL/ClassReadingBinaryReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,8 @@ protected void WriteWord(int position, long word)
rawBytes = BitConverter.GetBytes(word);
}

if (ShouldReverseArrays)
rawBytes = rawBytes.Reverse();
if (BitConverter.IsLittleEndian != IsLittleEndian)
Array.Reverse(rawBytes);

if (position > _memoryStream.Length)
throw new Exception($"WriteWord: Position {position} beyond length {_memoryStream.Length}");
Expand Down
21 changes: 9 additions & 12 deletions LibCpp2IL/EndianAwareBinaryReader.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
using System;
using System.IO;
using System.Text;

namespace LibCpp2IL;

public class EndianAwareBinaryReader : BinaryReader
{
protected bool ShouldReverseArrays = !BitConverter.IsLittleEndian; //Default to LE mode, so on LE systems, don't invert.

public bool IsBigEndian { get; private set; } = false;
public bool IsLittleEndian => !IsBigEndian;

private int _numBytesReadSinceLastCall = 0;

Expand All @@ -26,7 +24,6 @@ public EndianAwareBinaryReader(Stream input, Encoding encoding, bool leaveOpen)

public void SetBigEndian()
{
ShouldReverseArrays = BitConverter.IsLittleEndian; //Set to BE mode, so on LE systems we invert.
IsBigEndian = true;
}

Expand Down Expand Up @@ -69,7 +66,7 @@ public sealed override short ReadInt16()
{
_numBytesReadSinceLastCall += 2;

if (!ShouldReverseArrays)
if (IsLittleEndian)
return base.ReadInt16();

return this.ReadInt16WithReversedBits();
Expand All @@ -79,7 +76,7 @@ public sealed override int ReadInt32()
{
_numBytesReadSinceLastCall += 4;

if (!ShouldReverseArrays)
if (IsLittleEndian)
return base.ReadInt32();

return this.ReadInt32WithReversedBits();
Expand All @@ -89,7 +86,7 @@ public sealed override long ReadInt64()
{
_numBytesReadSinceLastCall += 8;

if (!ShouldReverseArrays)
if (IsLittleEndian)
return base.ReadInt64();

return this.ReadInt64WithReversedBits();
Expand All @@ -99,7 +96,7 @@ public sealed override ushort ReadUInt16()
{
_numBytesReadSinceLastCall += 2;

if (!ShouldReverseArrays)
if (IsLittleEndian)
return base.ReadUInt16();

return this.ReadUInt16WithReversedBits();
Expand All @@ -109,7 +106,7 @@ public sealed override uint ReadUInt32()
{
_numBytesReadSinceLastCall += 4;

if (!ShouldReverseArrays)
if (IsLittleEndian)
return base.ReadUInt32();

return this.ReadUInt32WithReversedBits();
Expand All @@ -119,7 +116,7 @@ public sealed override ulong ReadUInt64()
{
_numBytesReadSinceLastCall += 8;

if (!ShouldReverseArrays)
if (IsLittleEndian)
return base.ReadUInt64();

return this.ReadUInt64WithReversedBits();
Expand All @@ -129,7 +126,7 @@ public sealed override float ReadSingle()
{
_numBytesReadSinceLastCall += 4;

if (!ShouldReverseArrays)
if (IsLittleEndian)
return base.ReadSingle();

return this.ReadSingleWithReversedBits();
Expand All @@ -139,7 +136,7 @@ public sealed override double ReadDouble()
{
_numBytesReadSinceLastCall += 8;

if (!ShouldReverseArrays)
if (IsLittleEndian)
return base.ReadDouble();

return this.ReadDoubleWithReversedBits();
Expand Down
Loading