예제 #1
0
        /// <summary>
        /// Reads the compressed bytes from the <paramref name="source"/> stream and
        /// writes them decompressed to the <paramref name="destination"/> stream.
        /// <para/>
        /// This operation is optimized by using parallel algorithms.
        /// </summary>
        /// <param name="source">The stream from which the compressed content will be read.</param>
        /// <param name="destination">The stream to which the decompressed content will be written.</param>
        /// <param name="progress">The progress that is used for progress reporting.</param>
        /// <param name="cancellationToken">The cancellation token with which to request cancellation of the operation.</param>
        /// <returns>The awaitable <see cref="Task"/> to synchronize the operation.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="source"/>, <paramref name="destination"/> or <paramref name="progress"/> is null.</exception>
        /// <exception cref="System.NotSupportedException"><paramref name="source"/> does not support reading or <paramref name="destination"/> does not support writing.</exception>
        /// <remarks>
        /// The compressed content must be created by the method <see cref="CompressParallelToAsync(System.IO.Stream, System.IO.Stream, System.IO.Compression.CompressionLevel, int, System.IProgress{double})"/>.
        /// <para/>
        /// Copying begins at the current position in the <paramref name="source"/> stream,
        /// and does not reset the position of the <paramref name="destination"/> stream after the copy operation is complete.
        /// </remarks>
        public static async Task DecompressParallelToAsync(this Stream source, Stream destination, IProgress <double> progress, CancellationToken cancellationToken)
        {
            #region Contracts

            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (!source.CanRead)
            {
                throw new NotSupportedException("source does not support reading");
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            if (!destination.CanWrite)
            {
                throw new NotSupportedException("destination does not support writing");
            }

            if (progress == null)
            {
                throw new ArgumentNullException(nameof(progress));
            }

            Contract.EndContractBlock();

            #endregion

            var decompressGraph = new DecompressGraph(source);

            try
            {
                while (await decompressGraph.OutputAvailableAsync(cancellationToken).ConfigureAwait(false))
                {
                    var buffer = await decompressGraph.ReceiveAsync(cancellationToken).ConfigureAwait(false);

                    buffer.WriteTo(destination, progress);
                }
            }
            finally
            {
                decompressGraph.Complete();

                await decompressGraph.Completion.ConfigureAwait(false);
            }

            progress.Report(1.0);
        }
예제 #2
0
        private async Task <bool> ReceiveBufferAsync(CancellationToken cancellationToken)
        {
            if (await _DecompressGraph.OutputAvailableAsync(cancellationToken).ConfigureAwait(false))
            {
                _Buffer = await _DecompressGraph.ReceiveAsync(cancellationToken).ConfigureAwait(false);

                _BufferPosition = 0;

                return(true);
            }

            _Buffer = Buffer.Empty;

            _BufferPosition = 0;

            return(false);
        }