Last active
November 21, 2016 21:39
-
-
Save leonardosnt/19b699c83df538e4f19679d24f6d4a8a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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