Skip to content

Instantly share code, notes, and snippets.

@aensidhe
Created January 12, 2019 07:13
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 aensidhe/439d801227a6b25bad062493da97901b to your computer and use it in GitHub Desktop.
Save aensidhe/439d801227a6b25bad062493da97901b to your computer and use it in GitHub Desktop.
Is there a way to generalize it?
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using ProGaudi.Buffers;
namespace ProGaudi.MsgPack.Converters.Array
{
public sealed class SequenceParser<TElement> : IMsgPackSequenceParser<IMemoryOwner<TElement>>, IMsgPackSequenceParser<TElement[]>
{
private readonly IMsgPackSequenceParser<TElement> _elementSequenceParser;
public SequenceParser(MsgPackContext context)
{
_elementSequenceParser = context.GetRequiredSequenceParser<TElement>();
}
IMemoryOwner<TElement> IMsgPackSequenceParser<IMemoryOwner<TElement>>.Parse(ReadOnlySequence<byte> source, out int readSize)
{
if (MsgPackSpec.TryReadNil(source, out readSize)) return null;
var length = MsgPackSpec.ReadArrayHeader(source, out readSize);
var result = FixedLengthMemoryPool<TElement>.Shared.Rent(length);
Read(source, result.Memory.Span, ref readSize);
return result;
}
TElement[] IMsgPackSequenceParser<TElement[]>.Parse(ReadOnlySequence<byte> source, out int readSize)
{
if (MsgPackSpec.TryReadNil(source, out readSize)) return null;
var length = MsgPackSpec.ReadArrayHeader(source, out readSize);
var array = new TElement[length];
Read(source, array, ref readSize);
return array;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Read(ReadOnlySequence<byte> source, Span<TElement> array, ref int readSize)
{
for (var i = 0; i < array.Length; i++)
{
array[i] = _elementSequenceParser.Parse(source.Slice(readSize), out var temp);
readSize += temp;
}
}
}
}
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using ProGaudi.Buffers;
namespace ProGaudi.MsgPack.Converters.Array
{
public sealed class SpanParser<TElement> : IMsgPackParser<IMemoryOwner<TElement>>, IMsgPackParser<TElement[]>
{
private readonly IMsgPackParser<TElement> _elementParser;
public SpanParser(MsgPackContext context)
{
_elementParser = context.GetRequiredParser<TElement>();
}
IMemoryOwner<TElement> IMsgPackParser<IMemoryOwner<TElement>>.Parse(ReadOnlySpan<byte> source, out int readSize)
{
if (MsgPackSpec.TryReadNil(source, out readSize)) return null;
var length = MsgPackSpec.ReadArrayHeader(source, out readSize);
var result = FixedLengthMemoryPool<TElement>.Shared.Rent(length);
Read(source, result.Memory.Span, ref readSize);
return result;
}
TElement[] IMsgPackParser<TElement[]>.Parse(ReadOnlySpan<byte> source, out int readSize)
{
if (MsgPackSpec.TryReadNil(source, out readSize)) return null;
var length = MsgPackSpec.ReadArrayHeader(source, out readSize);
var array = new TElement[length];
Read(source, array, ref readSize);
return array;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Read(ReadOnlySpan<byte> source, Span<TElement> array, ref int readSize)
{
for (var i = 0; i < array.Length; i++)
{
array[i] = _elementParser.Parse(source.Slice(readSize), out var temp);
readSize += temp;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment