Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 75 additions & 13 deletions src/IO/DataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,19 +180,49 @@ public readonly DataReader Slice(int start) {
/// Reads a <see cref="bool"/>
/// </summary>
/// <returns></returns>
public bool ReadBoolean() => ReadByte() != 0;
public bool ReadBoolean() {
VerifyState();
const uint SIZE = 1;
var currentOffset = this.currentOffset;
if (currentOffset == endOffset)
ThrowNoMoreBytesLeft();
var value = stream.ReadBoolean(currentOffset);
this.currentOffset = currentOffset + SIZE;
VerifyState();
return value;
}

/// <summary>
/// Reads a <see cref="char"/>
/// </summary>
/// <returns></returns>
public char ReadChar() => (char)ReadUInt16();
public char ReadChar() {
VerifyState();
const uint SIZE = 2;
var currentOffset = this.currentOffset;
if (endOffset - currentOffset < SIZE)
ThrowNoMoreBytesLeft();
var value = stream.ReadChar(currentOffset);
this.currentOffset = currentOffset + SIZE;
VerifyState();
return value;
}

/// <summary>
/// Reads a <see cref="sbyte"/>
/// </summary>
/// <returns></returns>
public sbyte ReadSByte() => (sbyte)ReadByte();
public sbyte ReadSByte() {
VerifyState();
const uint SIZE = 1;
var currentOffset = this.currentOffset;
if (currentOffset == endOffset)
ThrowNoMoreBytesLeft();
var value = stream.ReadSByte(currentOffset);
this.currentOffset = currentOffset + SIZE;
VerifyState();
return value;
}

/// <summary>
/// Reads a <see cref="byte"/>
Expand All @@ -214,7 +244,17 @@ public byte ReadByte() {
/// Reads a <see cref="short"/>
/// </summary>
/// <returns></returns>
public short ReadInt16() => (short)ReadUInt16();
public short ReadInt16() {
VerifyState();
const uint SIZE = 2;
var currentOffset = this.currentOffset;
if (endOffset - currentOffset < SIZE)
ThrowNoMoreBytesLeft();
var value = stream.ReadInt16(currentOffset);
this.currentOffset = currentOffset + SIZE;
VerifyState();
return value;
}

/// <summary>
/// Reads a <see cref="ushort"/>
Expand All @@ -236,7 +276,17 @@ public ushort ReadUInt16() {
/// Reads a <see cref="int"/>
/// </summary>
/// <returns></returns>
public int ReadInt32() => (int)ReadUInt32();
public int ReadInt32() {
VerifyState();
const uint SIZE = 4;
var currentOffset = this.currentOffset;
if (endOffset - currentOffset < SIZE)
ThrowNoMoreBytesLeft();
var value = stream.ReadInt32(currentOffset);
this.currentOffset = currentOffset + SIZE;
VerifyState();
return value;
}

/// <summary>
/// Reads a <see cref="uint"/>
Expand Down Expand Up @@ -291,7 +341,17 @@ internal uint Unsafe_ReadUInt32() {
/// Reads a <see cref="long"/>
/// </summary>
/// <returns></returns>
public long ReadInt64() => (long)ReadUInt64();
public long ReadInt64() {
VerifyState();
const uint SIZE = 8;
var currentOffset = this.currentOffset;
if (endOffset - currentOffset < SIZE)
ThrowNoMoreBytesLeft();
var value = stream.ReadInt64(currentOffset);
this.currentOffset = currentOffset + SIZE;
VerifyState();
return value;
}

/// <summary>
/// Reads a <see cref="ulong"/>
Expand Down Expand Up @@ -362,13 +422,15 @@ public Guid ReadGuid() {
/// </summary>
/// <returns></returns>
public decimal ReadDecimal() {
var bits = new int[4] {
ReadInt32(), // lo
ReadInt32(), // mid
ReadInt32(), // hi
ReadInt32(), // flags
};
return new decimal(bits);
VerifyState();
const uint SIZE = 16;
var currentOffset = this.currentOffset;
if (endOffset - currentOffset < SIZE)
ThrowNoMoreBytesLeft();
var value = stream.ReadDecimal(currentOffset);
this.currentOffset = currentOffset + SIZE;
VerifyState();
return value;
}

/// <summary>
Expand Down
58 changes: 58 additions & 0 deletions src/IO/DataStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,69 @@ public abstract class DataStream {
/// <returns></returns>
public abstract byte ReadByte(uint offset);

/// <summary>
/// Reads a <see cref="sbyte"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public virtual sbyte ReadSByte(uint offset) => (sbyte)ReadByte(offset);

/// <summary>
/// Reads a 1-byte-long <see cref="bool"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public virtual bool ReadBoolean(uint offset) => ReadByte(offset) != 0;

/// <summary>
/// Reads a <see cref="ushort"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public abstract ushort ReadUInt16(uint offset);

/// <summary>
/// Reads a <see cref="short"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public virtual short ReadInt16(uint offset) => (short)ReadUInt16(offset);

/// <summary>
/// Reads a 2-byte-long <see cref="char"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public virtual char ReadChar(uint offset) => (char)ReadUInt16(offset);

/// <summary>
/// Reads a <see cref="uint"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public abstract uint ReadUInt32(uint offset);

/// <summary>
/// Reads a <see cref="int"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public virtual int ReadInt32(uint offset) => (int)ReadUInt32(offset);

/// <summary>
/// Reads a <see cref="ulong"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public abstract ulong ReadUInt64(uint offset);

/// <summary>
/// Reads a <see cref="long"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public virtual long ReadInt64(uint offset) => (long)ReadUInt64(offset);

/// <summary>
/// Reads a <see cref="float"/>
/// </summary>
Expand All @@ -79,6 +121,22 @@ public virtual Guid ReadGuid(uint offset) =>
ReadByte(offset + 8), ReadByte(offset + 9), ReadByte(offset + 10), ReadByte(offset + 11),
ReadByte(offset + 12), ReadByte(offset + 13), ReadByte(offset + 14), ReadByte(offset + 15));

/// <summary>
/// Reads a <see cref="decimal"/>
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns></returns>
public virtual decimal ReadDecimal(uint offset) {
int lo = ReadInt32(offset);
int mid = ReadInt32(offset + 4);
int hi = ReadInt32(offset + 8);
int flags = ReadInt32(offset + 12);

byte scale = (byte)(flags >> 16);
bool isNegative = (flags & 0x80000000) != 0;
return new decimal(lo, mid, hi, isNegative, scale);
}

/// <summary>
/// Reads a UTF-16 encoded <see cref="string"/>
/// </summary>
Expand Down