C# - Binary reader in Big Endian?

后端 未结 6 848
有刺的猬
有刺的猬 2020-12-02 18:38

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

6条回答
  •  醉梦人生
    2020-12-02 19:16

    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;
        }
    }
    

提交回复
热议问题