using System; using System.Text; namespace Gibbed.IO { public class ByteBufferReader { private readonly byte[] _Buffer; private readonly Endian _Endian; private readonly int _Offset; public ByteBufferReader(byte[] buffer) : this(buffer, 0, Endian.Little) { } public ByteBufferReader(byte[] buffer, int offset) : this(buffer, offset, Endian.Little) { } public ByteBufferReader(byte[] buffer, int offset, Endian endian) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || offset >= buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } this._Buffer = buffer; this._Offset = offset; this._Endian = endian; } public ByteBufferReader this[int index] { get { if (index == 0) { return this; } return new ByteBufferReader(this._Buffer, this._Offset + index, this._Endian); } } public bool ReadValueB8() { return this._Buffer[this._Offset] != 0; } public bool ReadValueB32() { // no need for swap return BitConverter.ToInt32(this._Buffer, this._Offset) != 0; } public sbyte ReadValueS8() { return (sbyte)this._Buffer[this._Offset]; } public byte ReadValueU8() { return this._Buffer[this._Offset]; } public short ReadValueS16() { var value = BitConverter.ToInt16(this._Buffer, this._Offset); if (StreamHelpers.ShouldSwap(this._Endian) == true) { value = value.Swap(); } return value; } public ushort ReadValueU16() { var value = BitConverter.ToUInt16(this._Buffer, this._Offset); if (StreamHelpers.ShouldSwap(this._Endian) == true) { value = value.Swap(); } return value; } public int ReadValueS32() { var value = BitConverter.ToInt32(this._Buffer, this._Offset); if (StreamHelpers.ShouldSwap(this._Endian) == true) { value = value.Swap(); } return value; } public uint ReadValueU32() { var value = BitConverter.ToUInt32(this._Buffer, this._Offset); if (StreamHelpers.ShouldSwap(this._Endian) == true) { value = value.Swap(); } return value; } public long ReadValueS64() { var value = BitConverter.ToInt64(this._Buffer, this._Offset); if (StreamHelpers.ShouldSwap(this._Endian) == true) { value = value.Swap(); } return value; } public ulong ReadValueU64() { var value = BitConverter.ToUInt64(this._Buffer, this._Offset); if (StreamHelpers.ShouldSwap(this._Endian) == true) { value = value.Swap(); } return value; } public float ReadValueF32() { if (StreamHelpers.ShouldSwap(this._Endian) == true) { return BitConverter.ToSingle( BitConverter.GetBytes(BitConverter.ToInt32(this._Buffer, this._Offset).Swap()), 0); } return BitConverter.ToSingle(this._Buffer, this._Offset); } public double ReadValueF64() { if (StreamHelpers.ShouldSwap(this._Endian) == true) { return BitConverter.Int64BitsToDouble(BitConverter.ToInt64(this._Buffer, this._Offset).Swap()); } return BitConverter.ToDouble(this._Buffer, this._Offset); } public string ReadString(int size, bool trailingNull, Encoding encoding) { if (size < 0 || this._Offset + size > this._Buffer.Length) { throw new ArgumentOutOfRangeException("size"); } string value = encoding.GetString(this._Buffer, this._Offset, size); if (trailingNull == true) { var position = value.IndexOf('\0'); if (position >= 0) { value = value.Substring(0, position); } } return value; } } }