Skip to content

Instantly share code, notes, and snippets.

@leonardosnt
Last active November 21, 2016 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leonardosnt/19b699c83df538e4f19679d24f6d4a8a to your computer and use it in GitHub Desktop.
Save leonardosnt/19b699c83df538e4f19679d24f6d4a8a to your computer and use it in GitHub Desktop.
/*
* Copyright (C) 2016 Leonardosc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
using System;
using System.IO;
using System.Text;
namespace Testes {
/*
Author: Leonardosc
Date: 07/23/2016
*/
public class ByteBuffer : IDisposable, ICloneable {
public static ByteBuffer Wrap(byte[] buff) {
return new ByteBuffer(new MemoryStream(buff));
}
public static ByteBuffer Allocate(int size) {
return new ByteBuffer(new MemoryStream(size));
}
private readonly MemoryStream _stream;
private byte[] _tmpBuffer;
public long Length => _stream.Length;
public long AvailableToRead => Length - _stream.Position;
public long Position {
get { return _stream.Position; }
set { _stream.Position = value; }
}
private ByteBuffer(MemoryStream stream) {
_stream = stream;
}
public void Write(byte[] bytes, int offset, int len) {
_stream.Write(bytes, offset, len);
}
public void Write(byte[] bytes) {
_stream.Write(bytes, 0, bytes.Length);
}
public void Write(byte val) {
_stream.WriteByte(val);
}
public void Write(string val, Encoding encoding) {
var bytes = encoding.GetBytes(val);
Write(bytes.Length);
Write(bytes);
}
public void Write(string val) {
Write(val, Encoding.UTF8);
}
public void Write(ushort val) {
Write(unchecked((short) val));
}
public void Write(short val) {
_stream.Write(BitConverter.GetBytes(val), 0, sizeof(short));
}
public void Write(uint val) {
_stream.Write(BitConverter.GetBytes(val), 0, sizeof(uint));
}
public void Write(int val) {
_stream.Write(BitConverter.GetBytes(val), 0, sizeof(int));
}
public void Write(ulong val) {
_stream.Write(BitConverter.GetBytes(val), 0, sizeof(ulong));
}
public void Write(long val) {
_stream.Write(BitConverter.GetBytes(val), 0, sizeof(long));
}
public void Write(float val) {
_stream.Write(BitConverter.GetBytes(val), 0, sizeof(float));
}
public void Write(double val) {
_stream.Write(BitConverter.GetBytes(val), 0, sizeof(double));
}
public void Write(bool val) {
Write((byte) (val ? 1 : 0));
}
// No BitConverter.GetBytes for decimal.. :c
public void Write(decimal val) {
var bits = decimal.GetBits(val);
// Low
Write((byte) (bits[0]));
Write((byte) (bits[0] >> 8));
Write((byte) (bits[0] >> 16));
Write((byte) (bits[0] >> 24));
// Middle
Write((byte) (bits[1]));
Write((byte) (bits[1] >> 8));
Write((byte) (bits[1] >> 16));
Write((byte) (bits[1] >> 24));
// High
Write((byte) (bits[2]));
Write((byte) (bits[2] >> 8));
Write((byte) (bits[2] >> 16));
Write((byte) (bits[2] >> 24));
// Flags
Write((byte) (bits[3]));
Write((byte) (bits[3] >> 8));
Write((byte) (bits[3] >> 16));
Write((byte) (bits[3] >> 24));
}
public byte[] ReadBytes(int count) {
if ((_stream.Position + count) > _stream.Length) {
throw new EndOfStreamException();
}
var buff = new byte[count];
_stream.Read(buff, 0, count);
return buff;
}
public byte ReadByte() {
var b = _stream.ReadByte();
if (b == -1) {
throw new EndOfStreamException();
}
return (byte) b;
}
public string ReadString() {
return ReadString(Encoding.UTF8);
}
public string ReadString(Encoding encoding) {
var strSize = ReadInt32();
ReadToBuffer(strSize);
return encoding.GetString(_tmpBuffer, 0, strSize);
}
public ushort ReadUInt16() {
ReadToBuffer(sizeof(ushort));
return BitConverter.ToUInt16(_tmpBuffer, 0);
}
public short ReadInt16() {
ReadToBuffer(sizeof(short));
return BitConverter.ToInt16(_tmpBuffer, 0);
}
public uint ReadUInt32() {
ReadToBuffer(sizeof(uint));
return BitConverter.ToUInt32(_tmpBuffer, 0);
}
public int ReadInt32() {
ReadToBuffer(sizeof(int));
return BitConverter.ToInt32(_tmpBuffer, 0);
}
public ulong ReadUInt64() {
ReadToBuffer(sizeof(ulong));
return BitConverter.ToUInt64(_tmpBuffer, 0);
}
public long ReadInt64() {
ReadToBuffer(sizeof(long));
return BitConverter.ToInt64(_tmpBuffer, 0);
}
public float ReadSingle() {
ReadToBuffer(sizeof(float));
return BitConverter.ToSingle(_tmpBuffer, 0);
}
public double ReadDouble() {
ReadToBuffer(sizeof(double));
return BitConverter.ToDouble(_tmpBuffer, 0);
}
public bool ReadBool() {
return ReadByte() == 1;
}
public decimal ReadDecimal() {
var low = ReadByte() | ReadByte() << 8 | ReadByte() << 16 | ReadByte() << 24;
var mid = ReadByte() | ReadByte() << 8 | ReadByte() << 16 | ReadByte() << 24;
var hig = ReadByte() | ReadByte() << 8 | ReadByte() << 16 | ReadByte() << 24;
var flags = ReadByte() | ReadByte() << 8 | ReadByte() << 16 | ReadByte() << 24;
var scale = (byte) (flags >> 16);
var neg = (flags & int.MinValue) != 0;
return new decimal(low, mid, hig, neg, scale);
}
public byte[] Peek(int count) {
ReadToBuffer(count);
_stream.Position -= count; //Recover position.
var ret = new byte[count];
Buffer.BlockCopy(_tmpBuffer, 0, ret, 0, count);
return ret;
}
public void Dispose() {
_tmpBuffer = null;
_stream.Dispose();
}
public object Clone() {
return Wrap(this.ToArray());
}
public byte[] ToArray() {
return _stream.ToArray();
}
/// <summary>
/// Read n bytes from stream to temp buffer.
/// </summary>
/// <param name="count"></param>
private void ReadToBuffer(int count) {
if ((_stream.Position + count) > _stream.Length) {
throw new EndOfStreamException();
}
if (_tmpBuffer == null || _tmpBuffer.Length < count) {
_tmpBuffer = new byte[count];
}
_stream.Read(_tmpBuffer, 0, count);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment