Last active
August 3, 2017 05:16
-
-
Save GlaireDaggers/a74d9342cd2ead8a82655bb50a5a2a72 to your computer and use it in GitHub Desktop.
A simple interface to allow for quick in-line and non-allocating reading and writing with byte arrays.
This file contains 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
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.IO; | |
namespace JetFistGames.Utils.IO | |
{ | |
/// <summary> | |
/// Helper class for a quick non-allocating way to read or write from/to temporary byte arrays as streams | |
/// Use like this: | |
/// using( var reader = ByteArrayReaderWriter.Get( byteArray ) ) | |
/// { ... } | |
/// The reader is automatically released back to the pool after the using code block. | |
/// Note that reader and writer positions are completely independant of each other. | |
/// </summary> | |
public class ByteArrayReaderWriter : IDisposable | |
{ | |
protected static Queue<ByteArrayReaderWriter> readerPool = new Queue<ByteArrayReaderWriter>(); | |
/// <summary> | |
/// Get a reader/writer for the given byte array | |
/// </summary> | |
public static ByteArrayReaderWriter Get(byte[] byteArray) | |
{ | |
ByteArrayReaderWriter reader = null; | |
if (readerPool.Count > 0) | |
{ | |
reader = readerPool.Dequeue(); | |
} | |
else | |
{ | |
reader = new ByteArrayReaderWriter(); | |
} | |
reader.SetStream(byteArray); | |
return reader; | |
} | |
/// <summary> | |
/// Release a reader/writer to the pool | |
/// </summary> | |
public static void Release(ByteArrayReaderWriter reader) | |
{ | |
readerPool.Enqueue(reader); | |
} | |
public long ReadPosition | |
{ | |
get { return readStream.Position; } | |
} | |
public long WritePosition | |
{ | |
get { return writeStream.Position; } | |
} | |
protected ByteStream readStream; | |
protected BinaryReader reader; | |
protected ByteStream writeStream; | |
protected BinaryWriter writer; | |
public ByteArrayReaderWriter() | |
{ | |
this.readStream = new ByteStream(); | |
this.reader = new BinaryReader(readStream); | |
this.writeStream = new ByteStream(); | |
this.writer = new BinaryWriter(writeStream); | |
} | |
public void SetStream(byte[] byteArray) | |
{ | |
this.readStream.SetStreamSource(byteArray); | |
this.writeStream.SetStreamSource(byteArray); | |
} | |
public void Write(byte val) { writer.Write(val); } | |
public void Write(byte[] val) { writer.Write(val); } | |
public void Write(char val) { writer.Write(val); } | |
public void Write(char[] val) { writer.Write(val); } | |
public void Write(string val) { writer.Write(val); } | |
public void Write(short val) { writer.Write(val); } | |
public void Write(int val) { writer.Write(val); } | |
public void Write(long val) { writer.Write(val); } | |
public void Write(ushort val) { writer.Write(val); } | |
public void Write(uint val) { writer.Write(val); } | |
public void Write(ulong val) { writer.Write(val); } | |
public void WriteASCII(char[] chars) | |
{ | |
for (int i = 0; i < chars.Length; i++) | |
{ | |
byte asciiCode = (byte)(chars[i] & 0xFF); | |
Write(asciiCode); | |
} | |
} | |
public void WriteASCII(string str) | |
{ | |
for (int i = 0; i < str.Length; i++) | |
{ | |
byte asciiCode = (byte)(str[i] & 0xFF); | |
Write(asciiCode); | |
} | |
} | |
public void WriteBuffer(byte[] buffer, int length) | |
{ | |
for (int i = 0; i < length; i++) | |
Write(buffer[i]); | |
} | |
public byte ReadByte() { return reader.ReadByte(); } | |
public byte[] ReadBytes(int length) { return reader.ReadBytes(length); } | |
public char ReadChar() { return reader.ReadChar(); } | |
public char[] ReadChars(int length) { return reader.ReadChars(length); } | |
public string ReadString() { return reader.ReadString(); } | |
public short ReadInt16() { return reader.ReadInt16(); } | |
public int ReadInt32() { return reader.ReadInt32(); } | |
public long ReadInt64() { return reader.ReadInt64(); } | |
public ushort ReadUInt16() { return reader.ReadUInt16(); } | |
public uint ReadUInt32() { return reader.ReadUInt32(); } | |
public ulong ReadUInt64() { return reader.ReadUInt64(); } | |
public void ReadASCIICharsIntoBuffer(char[] buffer, int length) | |
{ | |
for (int i = 0; i < length; i++) | |
buffer[i] = (char)ReadByte(); | |
} | |
public void ReadBytesIntoBuffer(byte[] buffer, int length) | |
{ | |
for (int i = 0; i < length; i++) | |
buffer[i] = ReadByte(); | |
} | |
public void Dispose() | |
{ | |
Release(this); | |
} | |
} | |
} |
This file contains 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
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.IO; | |
namespace JetFistGames.Utils.IO | |
{ | |
/// <summary> | |
/// A simple stream implementation for reading/writing from/to byte arrays which can be reused | |
/// </summary> | |
public class ByteStream : Stream | |
{ | |
protected byte[] srcByteArray; | |
public override long Position | |
{ | |
get; set; | |
} | |
public override long Length | |
{ | |
get | |
{ | |
return srcByteArray.Length; | |
} | |
} | |
public override bool CanRead | |
{ | |
get { return true; } | |
} | |
public override bool CanWrite | |
{ | |
get { return true; } | |
} | |
public override bool CanSeek | |
{ | |
get { return true; } | |
} | |
/// <summary> | |
/// Set a new byte array for this stream to read from | |
/// </summary> | |
public void SetStreamSource(byte[] sourceBuffer) | |
{ | |
this.srcByteArray = sourceBuffer; | |
this.Position = 0; | |
} | |
public override int Read(byte[] buffer, int offset, int count) | |
{ | |
int readBytes = 0; | |
long pos = this.Position; | |
long len = this.Length; | |
for (int i = 0; i < count && pos < len; i++) | |
{ | |
buffer[i + offset] = srcByteArray[pos++]; | |
readBytes++; | |
} | |
this.Position = pos; | |
return readBytes; | |
} | |
public override void Write(byte[] buffer, int offset, int count) | |
{ | |
long pos = this.Position; | |
for (int i = 0; i < count; i++) | |
srcByteArray[pos++] = buffer[i + offset]; | |
this.Position = pos; | |
} | |
public override void Flush() | |
{ | |
} | |
public override long Seek(long offset, SeekOrigin origin) | |
{ | |
if (origin == SeekOrigin.Begin) | |
this.Position = offset; | |
else if (origin == SeekOrigin.Current) | |
this.Position += offset; | |
else | |
this.Position = this.Length - offset - 1; | |
return this.Position; | |
} | |
public override void SetLength(long value) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment