Skip to content

Instantly share code, notes, and snippets.

@nathan130200
Created March 17, 2020 13:58
Show Gist options
  • Save nathan130200/981bcf6b8ab56abf74f1672ba203dfea to your computer and use it in GitHub Desktop.
Save nathan130200/981bcf6b8ab56abf74f1672ba203dfea to your computer and use it in GitHub Desktop.
C# Binary Stream with endianess.
namespace System.IO
{
public enum BinaryEndianess
{
BigEndian,
LittleEndian
}
public class BinaryStream : Stream
{
private Stream stream;
private BinaryEndianess endianess;
public BinaryStream(BinaryEndianess? endianess = default, Stream stream = default) : base()
{
this.endianess = !endianess.HasValue ? (BitConverter.IsLittleEndian ? BinaryEndianess.LittleEndian : BinaryEndianess.BigEndian) : endianess.Value;
this.stream = stream ?? new MemoryStream();
}
public override void Flush() =>
this.stream.Flush();
public override long Seek(long offset, SeekOrigin origin) =>
this.stream.Seek(offset, origin);
public override void SetLength(long value) =>
this.stream.SetLength(value);
public override int Read(byte[] buffer, int offset, int count) =>
this.stream.Read(buffer, offset, count);
public override void Write(byte[] buffer, int offset, int count) =>
this.stream.Write(buffer, offset, count);
public override void Close()
{
base.Close();
this.stream.Close();
}
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token) =>
Task.FromResult(this.Read(buffer, offset, count));
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken token) =>
Task.Run(() => this.Write(buffer, offset, count));
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
this.stream.Dispose();
}
public override bool CanRead => this.stream.CanRead;
public override bool CanSeek => this.stream.CanSeek;
public override bool CanWrite => this.stream.CanWrite;
public override long Length => this.stream.Length;
public override long Position
{
get => this.stream.Position;
set => this.stream.Position = value;
}
protected internal T ReadInternal<T>(int size, Func<byte[], int, T> fn)
{
var buff = new byte[size];
this.Read(buff, 0, buff.Length);
if (this.endianess == BinaryEndianess.LittleEndian)
Array.Reverse(buff);
return fn(buff, 0);
}
protected internal void WriteInternal<T>(T value, Func<T, byte[]> fn)
{
var buff = fn(value);
if (this.endianess == BinaryEndianess.LittleEndian)
Array.Reverse(buff);
this.stream.Write(buff, 0, buff.Length);
}
public short ReadInt16() =>
this.ReadInternal(sizeof(short), BitConverter.ToInt16);
public int ReadInt32() =>
this.ReadInternal(sizeof(int), BitConverter.ToInt32);
public long ReadInt64() =>
this.ReadInternal(sizeof(long), BitConverter.ToInt64);
public ushort ReadUInt16() =>
this.ReadInternal(sizeof(ushort), BitConverter.ToUInt16);
public uint ReadUInt32() =>
this.ReadInternal(sizeof(uint), BitConverter.ToUInt32);
public ulong ReadUInt64() =>
this.ReadInternal(sizeof(ulong), BitConverter.ToUInt64);
public void WriteInt16(short value) =>
this.WriteInternal(value, BitConverter.GetBytes);
public void WriteInt32(int value) =>
this.WriteInternal(value, BitConverter.GetBytes);
public void WriteInt64(long value) =>
this.WriteInternal(value, BitConverter.GetBytes);
public void WriteUInt16(ushort value) =>
this.WriteInternal(value, BitConverter.GetBytes);
public void WriteUInt32(uint value) =>
this.WriteInternal(value, BitConverter.GetBytes);
public void WriteUInt64(ulong value) =>
this.WriteInternal(value, BitConverter.GetBytes);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment