I\'m trying to improve my understanding of the STFS file format by using a program to read all the different bits of information. Using a website with a reference of which o
A mostly-complete (for my purposes) drop-in replacement for BinaryReader
that handles endianness correctly, unlike most of these answers. By default it works exactly like BinaryReader
, but can be constructed to read in the required endianness. Additionally the Read
methods are overloaded to allow you to specify the endianness to read a particular value in - useful in the (unlikely) scenario that you're dealing with a stream of mixed LE/BE data.
public class EndiannessAwareBinaryReader : BinaryReader
{
public enum Endianness
{
Little,
Big,
}
private readonly Endianness _endianness = Endianness.Little;
public EndiannessAwareBinaryReader(Stream input) : base(input)
{
}
public EndiannessAwareBinaryReader(Stream input, Encoding encoding) : base(input, encoding)
{
}
public EndiannessAwareBinaryReader(Stream input, Encoding encoding, bool leaveOpen) : base(input, encoding, leaveOpen)
{
}
public EndiannessAwareBinaryReader(Stream input, Endianness endianness) : base(input)
{
_endianness = endianness;
}
public EndiannessAwareBinaryReader(Stream input, Encoding encoding, Endianness endianness) : base(input, encoding)
{
_endianness = endianness;
}
public EndiannessAwareBinaryReader(Stream input, Encoding encoding, bool leaveOpen, Endianness endianness) : base(input, encoding, leaveOpen)
{
_endianness = endianness;
}
public override short ReadInt16() => ReadInt16(_endianness);
public override int ReadInt32() => ReadInt32(_endianness);
public override long ReadInt64() => ReadInt64(_endianness);
public override ushort ReadUInt16() => ReadUInt16(_endianness);
public override uint ReadUInt32() => ReadUInt32(_endianness);
public override ulong ReadUInt64() => ReadUInt64(_endianness);
public short ReadInt16(Endianness endianness) => BitConverter.ToInt16(ReadForEndianness(sizeof(short), endianness));
public int ReadInt32(Endianness endianness) => BitConverter.ToInt32(ReadForEndianness(sizeof(int), endianness));
public long ReadInt64(Endianness endianness) => BitConverter.ToInt64(ReadForEndianness(sizeof(long), endianness));
public ushort ReadUInt16(Endianness endianness) => BitConverter.ToUInt16(ReadForEndianness(sizeof(ushort), endianness));
public uint ReadUInt32(Endianness endianness) => BitConverter.ToUInt32(ReadForEndianness(sizeof(uint), endianness));
public ulong ReadUInt64(Endianness endianness) => BitConverter.ToUInt64(ReadForEndianness(sizeof(ulong), endianness));
private byte[] ReadForEndianness(int bytesToRead, Endianness endianness)
{
var bytesRead = ReadBytes(bytesToRead);
if ((endianness == Endianness.Little && !BitConverter.IsLittleEndian)
|| (endianness == Endianness.Big && BitConverter.IsLittleEndian))
{
Array.Reverse(bytesRead);
}
return bytesRead;
}
}