| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System.IO; |
| | | 5 | | using System.Runtime.InteropServices; |
| | | 6 | | using System.Threading; |
| | | 7 | | using System.Threading.Tasks; |
| | | 8 | | |
| | | 9 | | namespace System.Net.Http |
| | | 10 | | { |
| | | 11 | | internal abstract class HttpBaseStream : Stream |
| | | 12 | | { |
| | 0 | 13 | | public sealed override bool CanSeek => false; |
| | | 14 | | |
| | | 15 | | public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, obj |
| | 0 | 16 | | TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, default), callback, state); |
| | | 17 | | |
| | | 18 | | public sealed override int EndRead(IAsyncResult asyncResult) => |
| | 0 | 19 | | TaskToAsyncResult.End<int>(asyncResult); |
| | | 20 | | |
| | | 21 | | public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, ob |
| | 0 | 22 | | TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, default), callback, state); |
| | | 23 | | |
| | | 24 | | public sealed override void EndWrite(IAsyncResult asyncResult) => |
| | 0 | 25 | | TaskToAsyncResult.End(asyncResult); |
| | | 26 | | |
| | 0 | 27 | | public sealed override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); |
| | | 28 | | |
| | 0 | 29 | | public sealed override void SetLength(long value) => throw new NotSupportedException(); |
| | | 30 | | |
| | 0 | 31 | | public sealed override long Length => throw new NotSupportedException(); |
| | | 32 | | |
| | | 33 | | public sealed override long Position |
| | | 34 | | { |
| | 0 | 35 | | get { throw new NotSupportedException(); } |
| | 0 | 36 | | set { throw new NotSupportedException(); } |
| | | 37 | | } |
| | | 38 | | |
| | | 39 | | public sealed override int ReadByte() |
| | 0 | 40 | | { |
| | 0 | 41 | | byte b = 0; |
| | 0 | 42 | | return Read(new Span<byte>(ref b)) == 1 ? b : -1; |
| | 0 | 43 | | } |
| | | 44 | | |
| | | 45 | | public sealed override int Read(byte[] buffer, int offset, int count) |
| | 0 | 46 | | { |
| | 0 | 47 | | ValidateBufferArguments(buffer, offset, count); |
| | 0 | 48 | | return Read(buffer.AsSpan(offset, count)); |
| | 0 | 49 | | } |
| | | 50 | | |
| | | 51 | | public sealed override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationT |
| | 0 | 52 | | { |
| | 0 | 53 | | ValidateBufferArguments(buffer, offset, count); |
| | 0 | 54 | | return ReadAsync(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask(); |
| | 0 | 55 | | } |
| | | 56 | | |
| | | 57 | | public override void Write(byte[] buffer, int offset, int count) |
| | 0 | 58 | | { |
| | | 59 | | // This does sync-over-async, but it also should only end up being used in strange |
| | | 60 | | // situations. Either a derived stream overrides this anyway, so the implementation won't be used, |
| | | 61 | | // or it's being called as part of HttpContent.SerializeToStreamAsync, which means custom |
| | | 62 | | // content is explicitly choosing to make a synchronous call as part of an asynchronous method. |
| | 0 | 63 | | WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); |
| | 0 | 64 | | } |
| | | 65 | | |
| | | 66 | | public sealed override void WriteByte(byte value) => |
| | 0 | 67 | | Write(new ReadOnlySpan<byte>(in value)); |
| | | 68 | | |
| | | 69 | | public sealed override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken |
| | 0 | 70 | | { |
| | 0 | 71 | | ValidateBufferArguments(buffer, offset, count); |
| | 0 | 72 | | return WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken).AsTask(); |
| | 0 | 73 | | } |
| | | 74 | | |
| | 0 | 75 | | public override void Flush() => FlushAsync(default).GetAwaiter().GetResult(); |
| | | 76 | | |
| | 0 | 77 | | public override Task FlushAsync(CancellationToken cancellationToken) => NopAsync(cancellationToken); |
| | | 78 | | |
| | | 79 | | protected static Task NopAsync(CancellationToken cancellationToken) => |
| | 0 | 80 | | cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : |
| | 0 | 81 | | Task.CompletedTask; |
| | | 82 | | |
| | | 83 | | // |
| | | 84 | | // Methods which must be implemented by derived classes |
| | | 85 | | // |
| | | 86 | | |
| | | 87 | | public abstract override int Read(Span<byte> buffer); |
| | | 88 | | public abstract override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken); |
| | | 89 | | public abstract override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken); |
| | | 90 | | } |
| | | 91 | | } |