using System.Text; namespace SoulstormReplayReader.Core.Extensions; public class ExBinaryReader : BinaryReader { public long Position => BaseStream.Position; public long Length => BaseStream.Length; public long BytesLeft => Length - Position; public bool HasBytes => Position < Length; public ExBinaryReader(Stream stream) : base(stream) { } public ExBinaryReader(byte[] byteArray) : base(new MemoryStream(byteArray)) { } public ExBinaryReader SkipInt32(int count = 1) => Skip(count * 4); public ExBinaryReader Skip(int bytesCount) { BaseStream.Seek(bytesCount, SeekOrigin.Current); return this; } public ExBinaryReader Seek(int offset, SeekOrigin seekOrigin = SeekOrigin.Begin) { BaseStream.Seek(offset, seekOrigin); return this; } public ExBinaryReader Seek(uint offset, SeekOrigin seekOrigin = SeekOrigin.Begin) { BaseStream.Seek(offset, seekOrigin); return this; } public ExBinaryReader Seek(long offset, SeekOrigin seekOrigin = SeekOrigin.Begin) { BaseStream.Seek(offset, seekOrigin); return this; } public string ReadNextUnicodeString() => ReadUnicodeString(ReadInt32()); public string ReadUnicodeString(int length) { var doubleLength = length * 2; var bytes = doubleLength switch { > 0 and < 0xFF => ReadBytes(stackalloc byte[doubleLength]), _ => ReadBytes(doubleLength) }; return Encoding.UTF8.GetString(bytes); } public string ReadNextAsciiString() => ReadAsciiString(ReadInt32()); public string ReadAsciiString(int length) { var bytes = length switch { > 0 and < 0xFF => ReadBytes(stackalloc byte[length]), _ => ReadBytes(length) }; return Encoding.ASCII.GetString(bytes); } public string ReadCString(int length = 150) { var bytes = length switch { > 0 and < 0xFF => ReadBytes(stackalloc byte[length]), _ => ReadBytes(length) }; bytes = bytes[..bytes.IndexOf(byte.MinValue)]; return Encoding.ASCII.GetString(bytes); } public Span ReadBytes(Span buffer) { BaseStream.ReadExactly(buffer); return buffer; } }