using System.IO; using System.Text; using Vision.Core.Dump; namespace Vision.Core.Streams { public class ReaderStream : VisionObject { private readonly MemoryStream _stream; private readonly BinaryReader _reader; public ReaderStream(ref MemoryStream stream) { _stream = stream; _reader = new BinaryReader(_stream); } public ReaderStream(byte[] buffer) { _stream = new MemoryStream(buffer, 0, buffer.Length, true, true); _reader = new BinaryReader(_stream); } public void SetOffset(long offset) => _stream.Position = offset; public long GetOffset() => _stream.Position; public long GetSize() => _stream.Length; /// /// The number of unread bytes in the message. /// public int RemainingBytes { get { var length = _stream?.Length; var position = _stream?.Position; return (int)((length.HasValue & position.HasValue ? length.GetValueOrDefault() - position.GetValueOrDefault() : new long?()) ?? 0L); } } #region Read /// /// Reads a boolean value from the current stream. /// public bool ReadBoolean() => _reader.ReadBoolean(); /// /// Reads a byte value from the current stream. /// public byte ReadByte() => _reader.ReadByte(); /// /// Reads an array of bytes from the current stream. /// /// The number of bytes to read. public byte[] ReadBytes(int count) => _reader.ReadBytes(count); /// /// Reads a character value from the current stream. /// public char ReadChar() => _reader.ReadChar(); /// /// Reads a decimal value from the current stream. /// public decimal ReadDecimal() => _reader.ReadDecimal(); /// /// Reads a double value from the current stream. /// public double ReadDouble() => _reader.ReadDouble(); /// /// Reads a 16-bit integer value from the current stream. /// public short ReadInt16() => _reader.ReadInt16(); /// /// Reads a 32-bit integer value from the current stream. /// public int ReadInt32() => _reader.ReadInt32(); /// /// Reads a 64-bit integer value from the current stream. /// /// public long ReadInt64() => _reader.ReadInt64(); /// /// Reads a float value from the current stream. /// /// public float ReadFloat() => _reader.ReadSingle(); /// /// Reads a string value from the current stream. /// public string ReadString() => ReadString(ReadByte()); /// /// Reads a string value from the current stream. /// /// The length of the stream. public string ReadString(int length) { var ret = string.Empty; var buffer = new byte[length]; var count = 0; _stream.Read(buffer, 0, buffer.Length); if (buffer[length - 1] != 0) { count = length; } else { while (buffer[count] != 0 && count < length) { count++; } } if (count > 0) { ret = Encoding.ASCII.GetString(buffer, 0, count); } return ret; } /// /// Reads an unsigned 16-bit integer value from the current stream. /// public ushort ReadUInt16() => _reader.ReadUInt16(); /// /// Reads an unsigned 32-bit integer value from the current stream. /// public uint ReadUInt32() => _reader.ReadUInt32(); /// /// Reads an unsigned 64-bit integer value from the current stream. /// public ulong ReadUInt64() => _reader.ReadUInt64(); #endregion public string Dump() { // hold position for reset after var origPos = _stream.Position; _stream.Position = 0; var buf = (byte[])_stream.GetBuffer().Clone(); var dmp = HexDump.Dump(buf); _stream.Position = origPos; return dmp; } /// /// Destroys the instance. /// protected override void Destroy() { _reader?.Close(); _stream.Close(); } } }