public async Task <(TId, TData)> DeserializeAsync(PipeReader pipeReader, CancellationToken token) { TData data; TId id; var metaReadResult = await pipeReader.ReadLengthAsync(_reflection.MetaLength, token); if (_reflection.LengthProperty == null) { var sequence = metaReadResult.Slice(_reflection.MetaLength); (id, data) = Deserialize(sequence); pipeReader.Consume(sequence.GetPosition(_reflection.MetaLength)); } else { var lengthAttribute = _reflection.LengthProperty.Attribute; var lengthSequence = metaReadResult.Slice(lengthAttribute.Length, lengthAttribute.Index); var lengthValue = _bitConverter.ConvertFromBytes(lengthSequence, _reflection.LengthProperty.PropertyType, lengthAttribute.Reverse); var totalLength = _reflection.MetaLength + (lengthValue is int length ? length : Convert.ToInt32(lengthValue)); ReadOnlySequence <byte> sequence; if (metaReadResult.Buffer.Length >= totalLength) { sequence = metaReadResult.Slice(totalLength); } else { pipeReader.Examine(metaReadResult.Buffer.Start, metaReadResult.Buffer.GetPosition(_reflection.MetaLength)); var totalReadResult = await pipeReader.ReadLengthAsync(totalLength, token); sequence = totalReadResult.Slice(totalLength); } (id, data) = Deserialize(sequence, lengthValue); pipeReader.Consume(sequence.GetPosition(totalLength)); } return(id, data); }
public async Task <IDeserializeResult <TId, TData> > DeserializeAsync <TId, TData>(PipeReader pipeReader, CancellationToken token = default) where TId : struct where TData : new() { IDeserializeResult <TId, TData> result; var context = BinaryCache.GetOrAddContext(typeof(TData), _helper); var metaReadResult = await pipeReader.ReadLengthAsync(context.ReflectionData.MetaLength, token); if (context.ReflectionData.LengthProperty == null) { var sequence = metaReadResult.Slice(context.ReflectionData.MetaLength); result = Deserialize <TId, TData>(sequence); pipeReader.Consume(sequence.GetPosition(context.ReflectionData.MetaLength)); } else { var lengthAttribute = context.ReflectionData.LengthProperty.Attribute; var lengthSequence = metaReadResult.Slice(lengthAttribute.Length, lengthAttribute.Index); var lengthValue = context.BitConverterHelper.ConvertFromBytes(lengthSequence, context.ReflectionData.LengthProperty.Type, lengthAttribute.Reverse); var totalLength = context.ReflectionData.MetaLength + (lengthValue is int length ? length : Convert.ToInt32(lengthValue)); ReadOnlySequence <byte> sequence; if (metaReadResult.Buffer.Length >= totalLength) { sequence = metaReadResult.Slice(totalLength); } else { pipeReader.Examine(metaReadResult.Buffer.Start, metaReadResult.Buffer.GetPosition(context.ReflectionData.MetaLength)); var totalReadResult = await pipeReader.ReadLengthAsync(totalLength, token); sequence = totalReadResult.Slice(totalLength); } result = Deserialize <TId, TData>(sequence); pipeReader.Consume(sequence.GetPosition(totalLength)); } return(result); }
public static async Task <ReadResult> ReadLengthAsync(this PipeReader reader, long length, CancellationToken cancellationToken = default) { if (length < 1) { throw new ArgumentOutOfRangeException(nameof(length)); } while (true) { cancellationToken.ThrowIfCancellationRequested(); var readResult = await reader.ReadAsync(cancellationToken); if (readResult.IsCanceled) { throw new OperationCanceledException(); } if (readResult.IsCompleted) { throw new EndOfStreamException(); } if (readResult.Buffer.IsEmpty) { continue; } var readResultLength = readResult.Buffer.Length; if (readResultLength >= length) { return(readResult); } reader.Examine(readResult.Buffer.Start, readResult.Buffer.GetPosition(readResultLength)); } }