using System.Buffers.Binary; using System.Text; namespace Wabbajack.IO.Async; public class AsyncBinaryReader { private readonly Stream _s; private readonly Memory _buffer; private readonly Endian _endian; public AsyncBinaryReader(Stream s, Endian endian = Endian.Little) { _s = s; _buffer = new Memory(new byte[256]); _endian = endian; } public async ValueTask ReadByte() { await _s.ReadAllAsync(_buffer[..1]); return _buffer.Span[0]; } public async ValueTask ReadUInt16() { await _s.ReadAllAsync(_buffer[..2]); return _endian == Endian.Big ? BinaryPrimitives.ReadUInt16BigEndian(_buffer[..2].Span) : BinaryPrimitives.ReadUInt16LittleEndian(_buffer[..2].Span); } public async ValueTask ReadUInt32() { await _s.ReadAllAsync(_buffer[..4]); return _endian == Endian.Big ? BinaryPrimitives.ReadUInt32BigEndian(_buffer[..4].Span) : BinaryPrimitives.ReadUInt32LittleEndian(_buffer[..4].Span); } public async ValueTask ReadUInt64() { await _s.ReadAllAsync(_buffer[..8]); return _endian == Endian.Big ? BinaryPrimitives.ReadUInt64BigEndian(_buffer[..8].Span) : BinaryPrimitives.ReadUInt64LittleEndian(_buffer[..8].Span); } public async ValueTask ReadInt16() { await _s.ReadAllAsync(_buffer[..2]); return _endian == Endian.Big ? BinaryPrimitives.ReadInt16BigEndian(_buffer[..2].Span) : BinaryPrimitives.ReadInt16LittleEndian(_buffer[..2].Span); } public async ValueTask ReadInt32() { await _s.ReadAllAsync(_buffer[..4]); return _endian == Endian.Big ? BinaryPrimitives.ReadInt32BigEndian(_buffer[..4].Span) : BinaryPrimitives.ReadInt32LittleEndian(_buffer[..4].Span); } public async ValueTask ReadInt64() { await _s.ReadAllAsync(_buffer[..8]); return _endian == Endian.Big ? BinaryPrimitives.ReadInt64BigEndian(_buffer[..8].Span) : BinaryPrimitives.ReadInt64LittleEndian(_buffer[..8].Span); } public async ValueTask ReadFloat() { await _s.ReadAllAsync(_buffer[..4]); return _endian == Endian.Big ? BinaryPrimitives.ReadSingleBigEndian(_buffer[..4].Span) : BinaryPrimitives.ReadSingleLittleEndian(_buffer[..4].Span); } public async ValueTask ReadDouble() { await _s.ReadAllAsync(_buffer[..8]); return _endian == Endian.Big ? BinaryPrimitives.ReadDoubleBigEndian(_buffer[..8].Span) : BinaryPrimitives.ReadDoubleLittleEndian(_buffer[..8].Span); } public async ValueTask ReadBytes(int size) { var bytes = new byte[size]; await _s.ReadAllAsync(bytes); return bytes; } public long Position { set => _s.Position = value; get => _s.Position; } public long Length => _s.Length; public Stream BaseStream => _s; public async Task ReadFixedSizeString(ushort length, Encoding encoding) { var buf = new Memory(new byte[length]); await _s.ReadAllAsync(buf); return encoding.GetString(buf.Span); } }