Example #1
0
        /// <summary>
        /// Parses the next <see cref="BString"/> from the reader.
        /// </summary>
        /// <param name="reader">The reader to parse from.</param>
        /// <param name="cancellationToken"></param>
        /// <returns>The parsed <see cref="BString"/>.</returns>
        /// <exception cref="InvalidBencodeException{BString}">Invalid bencode.</exception>
        /// <exception cref="UnsupportedBencodeException{BString}">The bencode is unsupported by this library.</exception>
        public override async ValueTask <BString> ParseAsync(PipeBencodeReader reader, CancellationToken cancellationToken = default)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var startPosition = reader.Position;

            using (var memoryOwner = MemoryPool <char> .Shared.Rent(BString.LengthMaxDigits))
            {
                var lengthString      = memoryOwner.Memory;
                var lengthStringCount = 0;
                for (var c = await reader.ReadCharAsync(cancellationToken).ConfigureAwait(false);
                     c != default && c.IsDigit();
                     c = await reader.ReadCharAsync(cancellationToken).ConfigureAwait(false))
                {
                    EnsureLengthStringBelowMaxLength(lengthStringCount, startPosition);

                    lengthString.Span[lengthStringCount++] = c;
                }

                EnsurePreviousCharIsColon(reader.PreviousChar, reader.Position);

                var stringLength = ParseStringLength(lengthString.Span, lengthStringCount, startPosition);
                var bytes        = new byte[stringLength];
                var bytesRead    = await reader.ReadAsync(bytes, cancellationToken).ConfigureAwait(false);

                EnsureExpectedBytesRead(bytesRead, stringLength, startPosition);

                return(new BString(bytes, Encoding));
            }
        }
        public async Task CanReadLessThanRequested()
        {
            var bytes = Encoding.UTF8.GetBytes("abc").AsMemory();

            var(reader, writer) = new Pipe();
            var bencodeReader = new PipeBencodeReader(reader);

            await writer.WriteAsync(bytes.Slice(0, 1));

            var buffer   = new byte[bytes.Length];
            var readTask = bencodeReader.ReadAsync(buffer);

            await writer.WriteAsync(bytes.Slice(1, 1));

            writer.Complete();

            var bytesRead = await readTask;

            bytesRead.Should().Be(2);
            buffer[0].Should().Be((byte)'a');
            buffer[1].Should().Be((byte)'b');
            buffer[2].Should().Be(default);
Example #3
0
 internal static Task SkipBytesAsync(this PipeBencodeReader reader, int length)
 {
     return(reader.ReadAsync(new byte[length]).AsTask());
 }