Пример #1
0
        ValueTask IAsyncBinaryWriter.WriteBigIntegerAsync(BigInteger value, bool littleEndian, LengthFormat?lengthFormat, CancellationToken token)
        {
            ValueTask result;

            if (token.IsCancellationRequested)
            {
#if NETSTANDARD2_1
                result = new (Task.FromCanceled(token));
#else
                result = ValueTask.FromCanceled(token);
#endif
            }
            else
            {
                result = new();
                try
                {
                    writer.WriteBigInteger(in value, littleEndian, lengthFormat);
                }
                catch (Exception e)
                {
#if NETSTANDARD2_1
                    result = new (Task.FromException(e));
#else
                    result = ValueTask.FromException(e);
#endif
                }
            }

            return(result);
        }
Пример #2
0
        internal ValueTask ConnectAsync(EndPoint remoteEP, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            // Use _singleBufferReceiveEventArgs so the AwaitableSocketAsyncEventArgs can be re-used later for receives.
            AwaitableSocketAsyncEventArgs saea =
                Interlocked.Exchange(ref _singleBufferReceiveEventArgs, null) ??
                new AwaitableSocketAsyncEventArgs(this, isReceiveForCaching: true);

            saea.RemoteEndPoint = remoteEP;

            ValueTask connectTask = saea.ConnectAsync(this);

            if (connectTask.IsCompleted || !cancellationToken.CanBeCanceled)
            {
                // Avoid async invocation overhead
                return(connectTask);
            }
            else
            {
                return(WaitForConnectWithCancellation(saea, connectTask, cancellationToken));
            }
Пример #3
0
        /// <summary>Asynchronously waits to enter the mutex.</summary>
        /// <param name="cancellationToken">The CancellationToken token to observe.</param>
        /// <returns>A task that will complete when the mutex has been entered or the enter canceled.</returns>
        public ValueTask EnterAsync(CancellationToken cancellationToken)
        {
            // If cancellation was requested, bail immediately.
            // If the mutex is not currently held nor contended, enter immediately.
            // Otherwise, fall back to a more expensive likely-asynchronous wait.
            return
                (cancellationToken.IsCancellationRequested ? ValueTask.FromCanceled(cancellationToken) :
                 Interlocked.Decrement(ref _gate) >= 0 ? default :
                 Contended(cancellationToken));

            // Everything that follows is the equivalent of:
            //     return _sem.WaitAsync(cancellationToken);
            // if _sem were to be constructed as `new SemaphoreSlim(0)`.

            ValueTask Contended(CancellationToken cancellationToken)
            {
                // Get a reusable waiter object.  We do this before the lock to minimize work (and especially allocation)
                // done while holding the lock.  It's possible we'll end up dequeuing a waiter and then under the lock
                // discovering the mutex is now available, at which point we will have wasted an object.  That's currently
                // showing to be the better alternative (including not trying to put it back in that case).
                if (!_unusedWaiters.TryDequeue(out Waiter? w))
                {
                    w = new Waiter(this);
                }

                lock (SyncObj)
                {
                    // Now that we're holding the lock, check to see whether the async lock is acquirable.
                    if (!_lockedSemaphoreFull)
                    {
                        // If we are able to acquire the lock, we're done.
                        _lockedSemaphoreFull = true;
                        return(default);
Пример #4
0
        public sealed override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken token)
        {
            ValueTask <int> result;

            if (token.IsCancellationRequested)
            {
#if NETSTANDARD2_1
                result = new (Task.FromCanceled <int>(token));
#else
                result = ValueTask.FromCanceled <int>(token);
#endif
            }
            else
            {
                try
                {
                    result = new(Read(buffer.Span));
                }
                catch (Exception e)
                {
#if NETSTANDARD2_1
                    result = new (Task.FromException <int>(e));
#else
                    result = ValueTask.FromException <int>(e);
#endif
                }
            }

            return(result);
        }
Пример #5
0
        protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            try
            {
                if (method != ConnectionCloseMethod.GracefulShutdown)
                {
                    // Dispose must be called first in order to cause a connection reset,
                    // as NetworkStream.Dispose() will call Shutdown(Both).
                    _stream.Socket.Dispose();
                }

                _stream.Dispose();
            }
            catch (SocketException socketException)
            {
                return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(NetworkErrorHelper.MapSocketException(socketException))));
            }
            catch (Exception ex)
            {
                return(ValueTask.FromException(ex));
            }

            return(default);
Пример #6
0
        ValueTask ISupplier <ReadOnlyMemory <byte>, CancellationToken, ValueTask> .Invoke(ReadOnlyMemory <byte> input, CancellationToken token)
        {
            ValueTask result;

            if (token.IsCancellationRequested)
            {
#if NETSTANDARD2_1
                result = new (Task.FromCanceled(token));
#else
                result = ValueTask.FromCanceled(token);
#endif
            }
            else
            {
                result = new();
                try
                {
                    writer.Write(input.Span);
                }
                catch (Exception e)
                {
#if NETSTANDARD2_1
                    result = new (Task.FromException(e));
#else
                    result = ValueTask.FromException(e);
#endif
                }
            }

            return(result);
        }
Пример #7
0
        /// <summary>
        /// Asynchronously updates the underlying data source or repository with the
        /// current state of the buffer, then clears the buffer.
        /// </summary>
        /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
        /// <returns>A task that represents the asynchronous flush operation.</returns>
        public ValueTask FlushFinalBlockAsync(CancellationToken cancellationToken = default)
        {
            if (cancellationToken.IsCancellationRequested)
                return ValueTask.FromCanceled(cancellationToken);

            return FlushFinalBlockAsync(useAsync: true, cancellationToken);
        }
Пример #8
0
        ValueTask IAsyncBinaryWriter.WriteAsync <T>(T value, CancellationToken token)
        {
            ValueTask result;

            if (token.IsCancellationRequested)
            {
#if NETSTANDARD2_1
                result = new (Task.FromCanceled(token));
#else
                result = ValueTask.FromCanceled(token);
#endif
            }
            else
            {
                result = new();
                try
                {
                    writer.Write(in value);
                }
                catch (Exception e)
                {
#if NETSTANDARD2_1
                    result = new (Task.FromException(e));
#else
                    result = ValueTask.FromException(e);
#endif
                }
            }

            return(result);
        }
Пример #9
0
        ValueTask IAsyncBinaryWriter.WriteAsync(ReadOnlyMemory <char> chars, EncodingContext context, LengthFormat?lengthFormat, CancellationToken token)
        {
            ValueTask result;

            if (token.IsCancellationRequested)
            {
#if NETSTANDARD2_1
                result = new (Task.FromCanceled(token));
#else
                result = ValueTask.FromCanceled(token);
#endif
            }
            else
            {
                result = new();
                try
                {
                    writer.WriteString(chars.Span, in context, lengthFormat: lengthFormat);
                }
                catch (Exception e)
                {
#if NETSTANDARD2_1
                    result = new (Task.FromException(e));
#else
                    result = ValueTask.FromException(e);
#endif
                }
            }

            return(result);
        }
Пример #10
0
 public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
 {
     EnsureNotClosed();
     return(cancellationToken.IsCancellationRequested ?
            ValueTask.FromCanceled <int>(cancellationToken) :
            new ValueTask <int>(ReadBuffer(buffer.Span)));
 }
Пример #11
0
        public ValueTask <AsyncLockObject> LockAsync(CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled <AsyncLockObject>(cancellationToken));
            }

            lock (_signalAwaiters)
            {
                if (_signaled)
                {
                    _signaled = false;
                    return(new ValueTask <AsyncLockObject>(new AsyncLockObject(this)));
                }
                else
                {
                    var waiter = new WaiterCompletionSource(this, _allowInliningAwaiters, cancellationToken);
                    if (cancellationToken.IsCancellationRequested)
                    {
                        waiter.TrySetCanceled(cancellationToken);
                    }
                    else
                    {
                        _signalAwaiters.Enqueue(waiter);
                    }

                    return(new ValueTask <AsyncLockObject>(waiter.Task));
                }
            }
        }
Пример #12
0
        public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken = default)
        {
            if (GetType() != typeof(FileStream))
            {
                // If this isn't a concrete FileStream, a derived type may have overridden WriteAsync(byte[],...),
                // which was introduced first, so delegate to the base which will delegate to that.
                return(base.WriteAsync(buffer, cancellationToken));
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            if (IsClosed)
            {
                throw Error.GetFileNotOpen();
            }

            if (!_useAsyncIO)
            {
                // If we weren't opened for asynchronous I/O, we still call to the base implementation so that
                // Write is invoked asynchronously.  But if we have a byte[], we can do so using the base Stream's
                // internal helper that bypasses delegating to BeginWrite, since we already know this is FileStream
                // rather than something derived from it and what our BeginWrite implementation is going to do.
                return(MemoryMarshal.TryGetArray(buffer, out ArraySegment <byte> segment) ?
                       new ValueTask((Task)BeginWriteInternal(segment.Array !, segment.Offset, segment.Count, null, null, serializeAsynchronously: true, apm: false)) :
                       base.WriteAsync(buffer, cancellationToken));
            }

            return(WriteAsyncInternal(buffer, cancellationToken));
        }
Пример #13
0
        public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (!_isAsync)
            {
                return(base.ReadAsync(buffer, cancellationToken));
            }

            if (!CanRead)
            {
                throw Error.GetReadNotSupported();
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled <int>(cancellationToken));
            }

            CheckReadOperations();

            if (buffer.Length == 0)
            {
                UpdateMessageCompletion(false);
                return(new ValueTask <int>(0));
            }

            return(ReadAsyncCore(buffer, cancellationToken));
        }
Пример #14
0
        /// <summary>
        /// Reads bytes from stream and puts them into the buffer
        /// </summary>
        /// <param name="buffer">Buffer to read the bytes to.</param>
        /// <param name="cancellationToken">Token that can be used to cancel this operation.</param>
        public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled <int>(cancellationToken));
            }

            try
            {
                // ReadAsync(Memory<byte>,...) needs to delegate to an existing virtual to do the work, in case an existing derived type
                // has changed or augmented the logic associated with reads.  If the Memory wraps an array, we could delegate to
                // ReadAsync(byte[], ...), but that would defeat part of the purpose, as ReadAsync(byte[], ...) often needs to allocate
                // a Task<int> for the return value, so we want to delegate to one of the synchronous methods.  We could always
                // delegate to the Read(Span<byte>) method, and that's the most efficient solution when dealing with a concrete
                // UnmanagedMemoryStream, but if we're dealing with a type derived from UnmanagedMemoryStream, Read(Span<byte>) will end up delegating
                // to Read(byte[], ...), which requires it to get a byte[] from ArrayPool and copy the data.  So, we special-case the
                // very common case of the Memory<byte> wrapping an array: if it does, we delegate to Read(byte[], ...) with it,
                // as that will be efficient in both cases, and we fall back to Read(Span<byte>) if the Memory<byte> wrapped something
                // else; if this is a concrete UnmanagedMemoryStream, that'll be efficient, and only in the case where the Memory<byte> wrapped
                // something other than an array and this is an UnmanagedMemoryStream-derived type that doesn't override Read(Span<byte>) will
                // it then fall back to doing the ArrayPool/copy behavior.
                return(new ValueTask <int>(
                           MemoryMarshal.TryGetArray(buffer, out ArraySegment <byte> destinationArray) ?
                           Read(destinationArray.Array !, destinationArray.Offset, destinationArray.Count) :
                           Read(buffer.Span)));
            }
            catch (Exception ex)
            {
                return(ValueTask.FromException <int>(ex));
            }
        }
            public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    // Cancellation requested.
                    return(ValueTask.FromCanceled <int>(cancellationToken));
                }

                if (_connection == null || buffer.Length == 0)
                {
                    // Response body fully consumed or the caller didn't ask for any data.
                    return(new ValueTask <int>(0));
                }

                // Try to consume from data we already have in the buffer.
                int bytesRead = ReadChunksFromConnectionBuffer(buffer.Span, cancellationRegistration: default);

                if (bytesRead > 0)
                {
                    return(new ValueTask <int>(bytesRead));
                }

                // We may have just consumed the remainder of the response (with no actual data
                // available), so check again.
                if (_connection == null)
                {
                    Debug.Assert(_state == ParsingState.Done);
                    return(new ValueTask <int>(0));
                }

                // Nothing available to consume.  Fall back to I/O.
                return(ReadAsyncCore(buffer, cancellationToken));
            }
Пример #16
0
        protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            try
            {
                if (method != ConnectionCloseMethod.GracefulShutdown)
                {
                    // Dispose must be called first in order to cause a connection reset,
                    // as NetworkStream.Dispose() will call Shutdown(Both).
                    _socket.Dispose();
                }

                // Since CreatePipe() calls CreateStream(), so _stream should be present even in the pipe case:
                _stream?.Dispose();
            }
            catch (SocketException socketException)
            {
                return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(socketException)));
            }
            catch (Exception ex)
            {
                return(ValueTask.FromException(ex));
            }

            return(default);
Пример #17
0
        ValueTask IAsyncBinaryWriter.WriteAsync <TArg>(Action <TArg, IBufferWriter <byte> > writer, TArg arg, CancellationToken token)
        {
            ValueTask result;

            if (token.IsCancellationRequested)
            {
#if NETSTANDARD2_1
                result = new (Task.FromCanceled(token));
#else
                result = ValueTask.FromCanceled(token);
#endif
            }
            else
            {
                result = new();
                try
                {
                    writer(arg, this.writer);
                }
                catch (Exception e)
                {
#if NETSTANDARD2_1
                    result = new (Task.FromException(e));
#else
                    result = ValueTask.FromException(e);
#endif
                }
            }

            return(result);
        }
Пример #18
0
        ValueTask IAsyncBinaryWriter.WriteBigIntegerAsync(BigInteger value, LengthFormat lengthFormat, EncodingContext context, string?format, IFormatProvider?provider, CancellationToken token)
        {
            ValueTask result;

            if (token.IsCancellationRequested)
            {
#if NETSTANDARD2_1
                result = new (Task.FromCanceled(token));
#else
                result = ValueTask.FromCanceled(token);
#endif
            }
            else
            {
                result = new();
                try
                {
                    writer.WriteBigInteger(value, lengthFormat, in context, format, provider);
                }
                catch (Exception e)
                {
#if NETSTANDARD2_1
                    result = new (Task.FromException(e));
#else
                    result = ValueTask.FromException(e);
#endif
                }
            }

            return(result);
        }
 public override ValueTask <ConnectionListener> BindAsync(EndPoint endPoint, IConnectionProperties options = null, CancellationToken cancellationToken = default)
 {
     if (cancellationToken.IsCancellationRequested)
     {
         return(ValueTask.FromCanceled <ConnectionListener>(cancellationToken));
     }
     return(new ValueTask <ConnectionListener>(new VirtualConnectionListener(endPoint)));
 }
Пример #20
0
 public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default)
 {
     if (cancellationToken.IsCancellationRequested)
     {
         return(ValueTask.FromCanceled <int>(cancellationToken));
     }
     ThrowIfDisposed();
     ThrowIfBeyondEndOfStream();
     return(ReadAsyncCore(buffer, cancellationToken));
 }
Пример #21
0
 /// <summary>
 ///  命令を非同期的に実行します。
 /// </summary>
 /// <param name="context">実行文脈情報です。</param>
 /// <param name="cancellationToken">処理の取り消し通知を行うトークンを指定します。</param>
 /// <returns>この処理の非同期操作です。</returns>
 /// <exception cref="System.ArgumentNullException"/>
 /// <exception cref="System.ObjectDisposedException"/>
 public ValueTask InvokeAsync(ExecutionContext context, CancellationToken cancellationToken = default)
 {
     this.EnsureNotDisposed();
     context.EnsureNotNull(nameof(context));
     if (cancellationToken.IsCancellationRequested)
     {
         return(ValueTask.FromCanceled(cancellationToken));
     }
     return(this.InvokeAsyncCore(context, cancellationToken));
 }
Пример #22
0
        public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken = default)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            Write(buffer.Span);
            return(ValueTask.CompletedTask);
        }
Пример #23
0
        public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled <int>(cancellationToken));
            }

            EnsureCanRead();

            Debug.Assert(!_strategy.IsClosed, "FileStream ensures that strategy is not closed");
            Debug.Assert((_readPos == 0 && _readLen == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLen),
                         "We're either reading or writing, but not both.");

            if (!_strategy.CanSeek)
            {
                return(ReadFromNonSeekableAsync(buffer, cancellationToken));
            }

            SemaphoreSlim semaphore         = EnsureAsyncActiveSemaphoreInitialized();
            Task          semaphoreLockTask = semaphore.WaitAsync(cancellationToken);

            if (semaphoreLockTask.IsCompletedSuccessfully && // lock has been acquired
                _writePos == 0)    // there is nothing to flush
            {
                bool releaseTheLock = true;
                try
                {
                    if (_readLen == _readPos && buffer.Length >= _bufferSize)
                    {
                        // hot path #1: the read buffer is empty and buffering would not be beneficial
                        // To find out why we are bypassing cache here, please see WriteAsync comments.
                        return(_strategy.ReadAsync(buffer, cancellationToken));
                    }
                    else if (_readLen - _readPos >= buffer.Length)
                    {
                        // hot path #2: there is enough data in the buffer
                        _buffer.AsSpan(_readPos, buffer.Length).CopyTo(buffer.Span);
                        _readPos += buffer.Length;
                        return(new ValueTask <int>(buffer.Length));
                    }

                    releaseTheLock = false;
                }
                finally
                {
                    if (releaseTheLock)
                    {
                        semaphore.Release();
                    }
                    // the code is going to call ReadAsyncSlowPath which is going to release the lock
                }
            }

            return(ReadAsyncSlowPath(semaphoreLockTask, buffer, cancellationToken));
        }
Пример #24
0
        /// <summary>
        /// Reads a sequence of bytes from given file at given offset.
        /// </summary>
        /// <param name="handle">The file handle.</param>
        /// <param name="buffer">A region of memory. When this method returns, the contents of this region are replaced by the bytes read from the file.</param>
        /// <param name="fileOffset">The file position to read from.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
        /// <returns>The total number of bytes read into the buffer. This can be less than the number of bytes allocated in the buffer if that many bytes are not currently available, or zero (0) if the end of the file has been reached.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="handle" /> is <see langword="null" />.</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="handle" /> is invalid.</exception>
        /// <exception cref="T:System.ObjectDisposedException">The file is closed.</exception>
        /// <exception cref="T:System.NotSupportedException">The file does not support seeking (pipe or socket).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="handle" /> was not opened for async IO.</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="fileOffset" /> is negative.</exception>
        /// <exception cref="T:System.UnauthorizedAccessException"><paramref name="handle" /> was not opened for reading.</exception>
        /// <exception cref="T:System.IO.IOException">An I/O error occurred.</exception>
        /// <remarks>Position of the file is not advanced.</remarks>
        public static ValueTask <int> ReadAsync(SafeFileHandle handle, Memory <byte> buffer, long fileOffset, CancellationToken cancellationToken = default)
        {
            ValidateInput(handle, fileOffset, mustBeAsync: OperatingSystem.IsWindows());

            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled <int>(cancellationToken));
            }

            return(ReadAtOffsetAsync(handle, buffer, fileOffset, cancellationToken));
        }
Пример #25
0
        /// <summary>
        /// Writes a sequence of bytes from given buffer to given file at given offset.
        /// </summary>
        /// <param name="handle">The file handle.</param>
        /// <param name="buffer">A region of memory. This method copies the contents of this region to the file.</param>
        /// <param name="fileOffset">The file position to write to.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
        /// <returns>A task representing the asynchronous completion of the write operation.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="handle" /> is <see langword="null" />.</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="handle" /> is invalid.</exception>
        /// <exception cref="T:System.ObjectDisposedException">The file is closed.</exception>
        /// <exception cref="T:System.NotSupportedException">The file does not support seeking (pipe or socket).</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="fileOffset" /> is negative.</exception>
        /// <exception cref="T:System.UnauthorizedAccessException"><paramref name="handle" /> was not opened for writing.</exception>
        /// <exception cref="T:System.IO.IOException">An I/O error occurred.</exception>
        /// <remarks>Position of the file is not advanced.</remarks>
        public static ValueTask WriteAsync(SafeFileHandle handle, ReadOnlyMemory <byte> buffer, long fileOffset, CancellationToken cancellationToken = default)
        {
            ValidateInput(handle, fileOffset);

            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            return(WriteAtOffsetAsync(handle, buffer, fileOffset, cancellationToken));
        }
Пример #26
0
        /// <summary>
        /// Reads a sequence of bytes from given file at given offset.
        /// </summary>
        /// <param name="handle">The file handle.</param>
        /// <param name="buffers">A list of memory buffers. When this method returns, the contents of these buffers are replaced by the bytes read from the file.</param>
        /// <param name="fileOffset">The file position to read from.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
        /// <returns>The total number of bytes read into the buffers. This can be less than the number of bytes allocated in the buffers if that many bytes are not currently available, or zero (0) if the end of the file has been reached.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="handle" /> or <paramref name="buffers" /> is <see langword="null" />.</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="handle" /> is invalid.</exception>
        /// <exception cref="T:System.ObjectDisposedException">The file is closed.</exception>
        /// <exception cref="T:System.NotSupportedException">The file does not support seeking (pipe or socket).</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="fileOffset" /> is negative.</exception>
        /// <exception cref="T:System.UnauthorizedAccessException"><paramref name="handle" /> was not opened for reading.</exception>
        /// <exception cref="T:System.IO.IOException">An I/O error occurred.</exception>
        /// <remarks>Position of the file is not advanced.</remarks>
        public static ValueTask <long> ReadAsync(SafeFileHandle handle, IReadOnlyList <Memory <byte> > buffers, long fileOffset, CancellationToken cancellationToken = default)
        {
            ValidateInput(handle, fileOffset);
            ValidateBuffers(buffers);

            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled <long>(cancellationToken));
            }

            return(ReadScatterAtOffsetAsync(handle, buffers, fileOffset, cancellationToken));
        }
Пример #27
0
 /// <inheritdoc/>
 public ValueTask <bool> MoveNextAsync()
 {
     if (_ct.IsCancellationRequested)
     {
         return(ValueTask.FromCanceled <bool>(_ct));
     }
     if (_enumerator is null)
     {
         return(ValueTask.FromResult(false));
     }
     return(_enumerator.MoveNextAsync());
 }
Пример #28
0
        /// <summary>
        /// Writes a sequence of bytes from given buffers to given file at given offset.
        /// </summary>
        /// <param name="handle">The file handle.</param>
        /// <param name="buffers">A list of memory buffers. This method copies the contents of these buffers to the file.</param>
        /// <param name="fileOffset">The file position to write to.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
        /// <returns>The total number of bytes written into the file. This can be less than the number of bytes provided in the buffers and it's not an error.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="handle" /> or <paramref name="buffers"/> is <see langword="null" />.</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="handle" /> is invalid.</exception>
        /// <exception cref="T:System.ObjectDisposedException">The file is closed.</exception>
        /// <exception cref="T:System.NotSupportedException">The file does not support seeking (pipe or socket).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="handle" /> was not opened for async IO.</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="fileOffset" /> is negative.</exception>
        /// <exception cref="T:System.UnauthorizedAccessException"><paramref name="handle" /> was not opened for writing.</exception>
        /// <exception cref="T:System.IO.IOException">An I/O error occurred.</exception>
        /// <remarks>Position of the file is not advanced.</remarks>
        public static ValueTask <long> WriteAsync(SafeFileHandle handle, IReadOnlyList <ReadOnlyMemory <byte> > buffers, long fileOffset, CancellationToken cancellationToken = default)
        {
            ValidateInput(handle, fileOffset, mustBeAsync: OperatingSystem.IsWindows());
            ValidateBuffers(buffers);

            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled <long>(cancellationToken));
            }

            return(WriteGatherAtOffsetAsync(handle, buffers, fileOffset, cancellationToken));
        }
Пример #29
0
        /// <summary>Asynchronously reads a sequence of bytes from the current Brotli stream, writes them to a byte memory range, advances the position within the Brotli stream by the number of bytes read, and monitors cancellation requests.</summary>
        /// <param name="buffer">The region of memory to write the data into.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="System.Threading.CancellationToken.None" />.</param>
        /// <returns>A task that represents the asynchronous read operation, which wraps the total number of bytes read into the buffer. The result value can be less than the number of bytes allocated in the buffer if that many bytes are not currently available, or it can be 0 (zero) if the end of the Brotli stream has been reached.</returns>
        /// <remarks><para>This method enables you to perform resource-intensive I/O operations without blocking the main thread. This performance consideration is particularly important in apps where a time-consuming stream operation can block the UI thread and make your app appear as if it is not working. The async methods are used in conjunction with the <see langword="async" /> and <see langword="await" /> keywords in Visual Basic and C#.</para>
        /// <para>Use the <see cref="System.IO.Compression.BrotliStream.CanRead" /> property to determine whether the current instance supports reading.</para>
        /// <para>If the operation is canceled before it completes, the returned task contains the <see cref="System.Threading.Tasks.TaskStatus.Canceled" /> value for the <see cref="System.Threading.Tasks.Task.Status" /> property.</para></remarks>
        public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (_mode != CompressionMode.Decompress)
            {
                throw new InvalidOperationException(SR.BrotliStream_Compress_UnsupportedOperation);
            }
            EnsureNoActiveAsyncOperation();
            EnsureNotDisposed();

            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled <int>(cancellationToken));
            }

            return(Core(buffer, cancellationToken));

            async ValueTask <int> Core(Memory <byte> buffer, CancellationToken cancellationToken)
            {
                AsyncOperationStarting();
                try
                {
                    int bytesWritten;
                    while (!TryDecompress(buffer.Span, out bytesWritten))
                    {
                        int bytesRead = await _stream.ReadAsync(_buffer.AsMemory(_bufferCount), cancellationToken).ConfigureAwait(false);

                        if (bytesRead <= 0)
                        {
                            if (_nonEmptyInput && !buffer.IsEmpty)
                            {
                                ThrowTruncatedInvalidData();
                            }
                            break;
                        }

                        _nonEmptyInput = true;
                        _bufferCount  += bytesRead;

                        if (_bufferCount > _buffer.Length)
                        {
                            ThrowInvalidStream();
                        }
                    }

                    return(bytesWritten);
                }
                finally
                {
                    AsyncOperationCompleting();
                }
            }
        }
Пример #30
0
        /// <summary>Asynchronously writes compressed bytes to the underlying Brotli stream from the specified byte memory range.</summary>
        /// <param name="buffer">The memory region to write data from.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="System.Threading.CancellationToken.None" />.</param>
        /// <returns>A task that represents the asynchronous write operation.</returns>
        /// <remarks><para>This method enables you to perform resource-intensive I/O operations without blocking the main thread. This performance consideration is particularly important in apps where a time-consuming stream operation can block the UI thread and make your app appear as if it is not working. The async methods are used in conjunction with the <see langword="async" /> and <see langword="await" /> keywords in Visual Basic and C#.</para>
        /// <para>Use the <see cref="System.IO.Compression.BrotliStream.CanWrite" /> property to determine whether the current instance supports writing.</para>
        /// <para>If the operation is canceled before it completes, the returned task contains the <see cref="System.Threading.Tasks.TaskStatus.Canceled" /> value for the <see cref="System.Threading.Tasks.Task.Status" /> property.</para></remarks>
        public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (_mode != CompressionMode.Compress)
            {
                throw new InvalidOperationException(SR.BrotliStream_Decompress_UnsupportedOperation);
            }
            EnsureNoActiveAsyncOperation();
            EnsureNotDisposed();

            return(cancellationToken.IsCancellationRequested ?
                   ValueTask.FromCanceled(cancellationToken) :
                   WriteAsyncMemoryCore(buffer, cancellationToken));
        }