using System; using System.Text; namespace InABox.Core { public class FastBinaryReader { private readonly byte[] _data; private int index = -1; public FastBinaryReader(byte[] data) { _data = data; index = 0; } public bool ReadBoolean() { var result = _data[index] != 0; index++; return result; } public byte ReadByte() { var result = _data[index]; index++; return result; } public short ReadInt16() { var result = BitConverter.ToInt16(_data, index); index += 2; return result; } public int ReadInt32() { var result = BitConverter.ToInt32(_data, index); index += 4; return result; } public long ReadInt64() { var result = BitConverter.ToInt64(_data, index); index += 8; return result; } public double ReadFloat() { var result = BitConverter.ToSingle(_data, index); index += 4; return result; } public double ReadDouble() { var result = BitConverter.ToDouble(_data, index); index += 8; return result; } protected internal int Read7BitEncodedInt() { // Read out an Int32 7 bits at a time. The high bit // of the byte when on means to continue reading more bytes. var count = 0; var shift = 0; byte b; do { // Check for a corrupted stream. Read a max of 5 bytes. // In a future version, add a DataFormatException. if (shift == 5 * 7) // 5 bytes max per Int32, shift += 7 throw new FormatException("Format_Bad7BitInt32"); // ReadByte handles end of stream cases for us. b = ReadByte(); count |= (b & 0x7F) << shift; shift += 7; } while ((b & 0x80) != 0); return count; } public string ReadString() { var length = Read7BitEncodedInt(); var result = Encoding.UTF8.GetString(_data, index, length); index += length; return result; } public DateTime ReadDateTime() { var result = ReadInt64(); return DateTime.FromBinary(result); } public TimeSpan ReadTimeSpan() { var result = ReadInt64(); return new TimeSpan(result); } public Guid ReadGuid() { var buf = new byte[16]; Buffer.BlockCopy(_data, index, buf, 0, 16); var result = new Guid(buf); index += 16; return result; } public byte[] ReadBytes(int length) { var result = new byte[length]; Buffer.BlockCopy(_data, index, result, 0, length); index += length; return result; } } }