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