Skip to content

Instantly share code, notes, and snippets.

@thenameless314159
Last active February 23, 2019 20:34
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 thenameless314159/02030b7b3053ecdd6c4a32e7f8aaaf7c to your computer and use it in GitHub Desktop.
Save thenameless314159/02030b7b3053ecdd6c4a32e7f8aaaf7c to your computer and use it in GitHub Desktop.
public class BeInt16BinaryStorage : FixedBinaryStorage<short>
{
public BeInt16BinaryStorage() : base(sizeof(short)) { }
protected override short ReadValue(ReadOnlySpan<byte> src)
=> BinaryPrimitives.ReadInt16BigEndian(src);
protected override void WriteValue(Span<byte> dst, short value)
=> BinaryPrimitives.WriteInt16BigEndian(dst, value);
}
public abstract class FixedReaderStorage<T> : IReaderStorage<T>
{
public int SizeOfT { get; }
protected FixedReaderStorage(int sizeOfT) => SizeOfT = sizeOfT;
protected abstract T ReadValue(ReadOnlySpan<byte> src);
public T ReadValue(IReader reader, out int bytesRead)
{
bytesRead = 0;
if(reader.BytesAvailable < SizeOfT)
throw new InternalBufferOverflowException("Not enough bytes available to read into the buffer");
bytesRead = SizeOfT;
var toRead = reader.Slice(SizeOfT);
return ReadValue(toRead.Span);
}
}
public class MemoryReader : IReader
{
private int _position;
private ReadOnlyMemory<byte> _buffer;
private readonly ImmutableDictionary<Type, object> _storage;
protected IReaderStorage<T> GetStorage<T>() => (IReaderStorage<T>)_storage[typeof(T)];
public int Length { get; }
public int Position
{
get => _position;
private set
{
if (value > Length || value < 0)
throw new ArgumentOutOfRangeException(nameof(value), value, "Position > Length or < 0");
_position = value;
}
}
public int BytesAvailable => Length - Position;
private readonly IArrayPolicy _policy;
//todo: add a length param if its collected from pool
internal MemoryReader(ReadOnlyMemory<byte> memory, ImmutableDictionary<Type, object> storage, IArrayPolicy policy)
{
Length = memory.Length;
_buffer = memory;
_storage = storage;
_policy = policy;
}
public ReadOnlyMemory<byte> Slice(int length) => _buffer.Slice(Position, length);
public ReadOnlyMemory<byte> Slice() => _buffer.Slice(Position);
public void Seek(int toPosition) => Position = toPosition;
public void Skip(int number) => Position += number;
public T ReadValue<T>()
{
var value = GetStorage<T>().ReadValue(this, out var bytesRead);
Position += bytesRead;
return value;
}
//make it alloc-free later
public T[] ReadValues<T>(int n)
{
var values = _policy.GetArray<T>(n).ToArray();
for (var i = 0; i < n; i++)
{
values[i] = ReadValue<T>();
}
return values;
}
/*public T[] ReadValues<TSize, T>() where TSize : IConvertible
{
var n = (long)(object)ReadValue<TSize>(); // find better way to do it
var values = new T[n];
for (var i = 0; i < n; i++)
values[i] = ReadValue<T>();
return values;
}*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment