diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs
index 33a99b7fe..8ab81aa7f 100644
--- a/src/IO/DataReader.cs
+++ b/src/IO/DataReader.cs
@@ -180,19 +180,49 @@ public readonly DataReader Slice(int start) {
/// Reads a
///
///
- 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;
+ }
///
/// Reads a
///
///
- 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;
+ }
///
/// Reads a
///
///
- 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;
+ }
///
/// Reads a
@@ -214,7 +244,17 @@ public byte ReadByte() {
/// Reads a
///
///
- 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;
+ }
///
/// Reads a
@@ -236,7 +276,17 @@ public ushort ReadUInt16() {
/// Reads a
///
///
- 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;
+ }
///
/// Reads a
@@ -291,7 +341,17 @@ internal uint Unsafe_ReadUInt32() {
/// Reads a
///
///
- 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;
+ }
///
/// Reads a
@@ -362,13 +422,15 @@ public Guid ReadGuid() {
///
///
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;
}
///
diff --git a/src/IO/DataStream.cs b/src/IO/DataStream.cs
index 654374a3b..6bdb959a2 100644
--- a/src/IO/DataStream.cs
+++ b/src/IO/DataStream.cs
@@ -34,6 +34,20 @@ public abstract class DataStream {
///
public abstract byte ReadByte(uint offset);
+ ///
+ /// Reads a
+ ///
+ /// Offset of data
+ ///
+ public virtual sbyte ReadSByte(uint offset) => (sbyte)ReadByte(offset);
+
+ ///
+ /// Reads a 1-byte-long
+ ///
+ /// Offset of data
+ ///
+ public virtual bool ReadBoolean(uint offset) => ReadByte(offset) != 0;
+
///
/// Reads a
///
@@ -41,6 +55,20 @@ public abstract class DataStream {
///
public abstract ushort ReadUInt16(uint offset);
+ ///
+ /// Reads a
+ ///
+ /// Offset of data
+ ///
+ public virtual short ReadInt16(uint offset) => (short)ReadUInt16(offset);
+
+ ///
+ /// Reads a 2-byte-long
+ ///
+ /// Offset of data
+ ///
+ public virtual char ReadChar(uint offset) => (char)ReadUInt16(offset);
+
///
/// Reads a
///
@@ -48,6 +76,13 @@ public abstract class DataStream {
///
public abstract uint ReadUInt32(uint offset);
+ ///
+ /// Reads a
+ ///
+ /// Offset of data
+ ///
+ public virtual int ReadInt32(uint offset) => (int)ReadUInt32(offset);
+
///
/// Reads a
///
@@ -55,6 +90,13 @@ public abstract class DataStream {
///
public abstract ulong ReadUInt64(uint offset);
+ ///
+ /// Reads a
+ ///
+ /// Offset of data
+ ///
+ public virtual long ReadInt64(uint offset) => (long)ReadUInt64(offset);
+
///
/// Reads a
///
@@ -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));
+ ///
+ /// Reads a
+ ///
+ /// Offset of data
+ ///
+ 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);
+ }
+
///
/// Reads a UTF-16 encoded
///