Ejemplo n.º 1
0
        private async ValueTask ExecuteCommands(CancellationToken ct)
        {
            FlushResult flushResult = default;

            while (!flushResult.IsCompleted)
            {
                var readResult = await _reader.ReadAsync(ct).ConfigureAwait(false);

                var opStatus = ReadCommand(
                    readResult.Buffer,
                    out var copyCommand,
                    out var literalCommand,
                    out var endCommand);
                if (opStatus == OperationStatus.Done)
                {
                    if (copyCommand is CopyCommand copy)
                    {
                        _reader.AdvanceTo(readResult.Buffer.GetPosition(copy.Size));
                        flushResult = await _copier.WriteCopy(copy.Range, ct).ConfigureAwait(false);
                    }
                    else if (literalCommand is LiteralCommand literal)
                    {
                        _reader.AdvanceTo(readResult.Buffer.GetPosition(literal.Size));
                        flushResult = await _writer.CopyFrom(
                            _reader,
                            (long)literal.LiteralLength,
                            ct).ConfigureAwait(false);
                    }
                    else if (endCommand is EndCommand end)
                    {
                        _reader.AdvanceTo(readResult.Buffer.GetPosition(end.Size));
                        return;
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                }
                else if (opStatus == OperationStatus.NeedMoreData)
                {
                    if (readResult.IsCompleted)
                    {
                        throw new FormatException("unexpected EOF");
                    }
                    _reader.AdvanceTo(
                        consumed: readResult.Buffer.Start,
                        examined: readResult.Buffer.End);
                }
                else if (opStatus == OperationStatus.InvalidData)
                {
                    throw new FormatException($"unknown command: {readResult.Buffer.FirstByte()}");
                }
                else
                {
                    Debug.Assert(false, "unreachable");
                }
            }
        }
Ejemplo n.º 2
0
 public async ValueTask <FlushResult> WriteCopy(LongRange range, CancellationToken ct)
 {
     SeekTo(range.Start);
     return(await _writer.CopyFrom(_stream, range.Length, ct).ConfigureAwait(false));
 }