Created
March 17, 2020 13:58
-
-
Save nathan130200/981bcf6b8ab56abf74f1672ba203dfea to your computer and use it in GitHub Desktop.
C# Binary Stream with endianess.
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
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