mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-11 18:20:26 +09:00
Backport docs for System.IO.Compression.Brotli (#46716)
* Backport docs for System.IO.Compression.Brotli * Addressed PR suggestions and fixed additional bugs. * Address feedback. Enable GenerateDocumentationFile. * BrotliStream.ReadByte docs. * BrotliStream.Flush docs. * BrotliStream.WriteByte docs. * Replace appname includes to plain text. Co-authored-by: carlossanlop <carlossanlop@users.noreply.github.com>
This commit is contained in:
parent
f31473d2ff
commit
f6917292b1
6 changed files with 216 additions and 1 deletions
|
@ -1,8 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
<!-- DesignTimeBuild requires all the TargetFramework Derived Properties to not be present in the first property group. -->
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>Provides methods and properties used to compress and decompress streams by using the Brotli data format specification.</summary>
|
||||
public sealed partial class BrotliStream : Stream
|
||||
{
|
||||
private const int DefaultInternalBufferSize = (1 << 16) - 16; //65520;
|
||||
|
@ -16,7 +17,14 @@ namespace System.IO.Compression
|
|||
private readonly bool _leaveOpen;
|
||||
private readonly CompressionMode _mode;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="System.IO.Compression.BrotliStream" /> class by using the specified stream and compression mode.</summary>
|
||||
/// <param name="stream">The stream to compress.</param>
|
||||
/// <param name="mode">One of the enumeration values that indicates whether to compress or decompress the stream.</param>
|
||||
public BrotliStream(Stream stream, CompressionMode mode) : this(stream, mode, leaveOpen: false) { }
|
||||
/// <summary>Initializes a new instance of the <see cref="System.IO.Compression.BrotliStream" /> class by using the specified stream and compression mode, and optionally leaves the stream open.</summary>
|
||||
/// <param name="stream">The stream to compress.</param>
|
||||
/// <param name="mode">One of the enumeration values that indicates whether to compress or decompress the stream.</param>
|
||||
/// <param name="leaveOpen"><see langword="true" /> to leave the stream open after the <see cref="System.IO.Compression.BrotliStream" /> object is disposed; otherwise, <see langword="false" />.</param>
|
||||
public BrotliStream(Stream stream, CompressionMode mode, bool leaveOpen)
|
||||
{
|
||||
if (stream == null)
|
||||
|
@ -48,6 +56,8 @@ namespace System.IO.Compression
|
|||
throw new ObjectDisposedException(GetType().Name, SR.ObjectDisposed_StreamClosed);
|
||||
}
|
||||
|
||||
/// <summary>Releases the unmanaged resources used by the <see cref="System.IO.Compression.BrotliStream" /> and optionally releases the managed resources.</summary>
|
||||
/// <param name="disposing"><see langword="true" /> to release both managed and unmanaged resources; <see langword="false" /> to release only unmanaged resources.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
|
@ -72,6 +82,11 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Asynchronously releases the unmanaged resources used by the <see cref="System.IO.Compression.BrotliStream" />.</summary>
|
||||
/// <returns>A task that represents the asynchronous dispose operation.</returns>
|
||||
/// <remarks>The `DisposeAsync` method lets you perform a resource-intensive dispose operation without blocking the main thread. This performance consideration is particularly important in a Windows 8.x Store app or desktop app 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#.
|
||||
/// This method disposes the Brotli stream by writing any changes to the backing store and closing the stream to release resources.
|
||||
/// Calling `DisposeAsync` allows the resources used by the <see cref="System.IO.Compression.BrotliStream" /> to be reallocated for other purposes. For more information, see [Cleaning Up Unmanaged Resources](/dotnet/standard/garbage-collection/unmanaged).</remarks>
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
try
|
||||
|
@ -112,17 +127,39 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets a reference to the underlying stream.</summary>
|
||||
/// <value>A stream object that represents the underlying stream.</value>
|
||||
/// <exception cref="System.ObjectDisposedException">The underlying stream is closed.</exception>
|
||||
public Stream BaseStream => _stream;
|
||||
/// <summary>Gets a value indicating whether the stream supports reading while decompressing a file.</summary>
|
||||
/// <value><see langword="true" /> if the <see cref="System.IO.Compression.CompressionMode" /> value is <see langword="Decompress," /> and the underlying stream supports reading and is not closed; otherwise, <see langword="false" />.</value>
|
||||
public override bool CanRead => _mode == CompressionMode.Decompress && _stream != null && _stream.CanRead;
|
||||
/// <summary>Gets a value indicating whether the stream supports writing.</summary>
|
||||
/// <value><see langword="true" /> if the <see cref="System.IO.Compression.CompressionMode" /> value is <see langword="Compress" />, and the underlying stream supports writing and is not closed; otherwise, <see langword="false" />.</value>
|
||||
public override bool CanWrite => _mode == CompressionMode.Compress && _stream != null && _stream.CanWrite;
|
||||
/// <summary>Gets a value indicating whether the stream supports seeking.</summary>
|
||||
/// <value><see langword="false" /> in all cases.</value>
|
||||
public override bool CanSeek => false;
|
||||
/// <summary>This property is not supported and always throws a <see cref="System.NotSupportedException" />.</summary>
|
||||
/// <param name="offset">The location in the stream.</param>
|
||||
/// <param name="origin">One of the <see cref="System.IO.SeekOrigin" /> values.</param>
|
||||
/// <returns>A long value.</returns>
|
||||
/// <exception cref="System.NotSupportedException">This property is not supported on this stream.</exception>
|
||||
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
|
||||
/// <summary>This property is not supported and always throws a <see cref="System.NotSupportedException" />.</summary>
|
||||
/// <value>A long value.</value>
|
||||
/// <exception cref="System.NotSupportedException">This property is not supported on this stream.</exception>
|
||||
public override long Length => throw new NotSupportedException();
|
||||
/// <summary>This property is not supported and always throws a <see cref="System.NotSupportedException" />.</summary>
|
||||
/// <value>A long value.</value>
|
||||
/// <exception cref="System.NotSupportedException">This property is not supported on this stream.</exception>
|
||||
public override long Position
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
/// <summary>This property is not supported and always throws a <see cref="System.NotSupportedException" />.</summary>
|
||||
/// <param name="value">The length of the stream.</param>
|
||||
public override void SetLength(long value) => throw new NotSupportedException();
|
||||
|
||||
private int _activeAsyncOperation; // 1 == true, 0 == false
|
||||
|
|
|
@ -8,6 +8,7 @@ using Microsoft.Win32.SafeHandles;
|
|||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>Provides non-allocating, performant Brotli decompression methods. The methods decompress in a single pass without using a <see cref="System.IO.Compression.BrotliStream" /> instance.</summary>
|
||||
public struct BrotliDecoder : IDisposable
|
||||
{
|
||||
private SafeBrotliDecoderHandle? _state;
|
||||
|
@ -27,6 +28,7 @@ namespace System.IO.Compression
|
|||
InitializeDecoder();
|
||||
}
|
||||
|
||||
/// <summary>Releases all resources used by the current Brotli decoder instance.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_disposed = true;
|
||||
|
@ -39,6 +41,17 @@ namespace System.IO.Compression
|
|||
throw new ObjectDisposedException(nameof(BrotliDecoder), SR.BrotliDecoder_Disposed);
|
||||
}
|
||||
|
||||
/// <summary>Decompresses data that was compressed using the Brotli algorithm.</summary>
|
||||
/// <param name="source">A buffer containing the compressed data.</param>
|
||||
/// <param name="destination">When this method returns, a byte span containing the decompressed data.</param>
|
||||
/// <param name="bytesConsumed">The total number of bytes that were read from <paramref name="source" />.</param>
|
||||
/// <param name="bytesWritten">The total number of bytes that were written in the <paramref name="destination" />.</param>
|
||||
/// <returns>One of the enumeration values that indicates the status of the decompression operation.</returns>
|
||||
/// <remarks>The return value can be as follows:
|
||||
/// - <see cref="System.Buffers.OperationStatus.Done" />: <paramref name="source" /> was successfully and completely decompressed into <paramref name="destination" />.
|
||||
/// - <see cref="System.Buffers.OperationStatus.DestinationTooSmall" />: There is not enough space in <paramref name="destination" /> to decompress <paramref name="source" />.
|
||||
/// - <see cref="System.Buffers.OperationStatus.NeedMoreData" />: The decompression action is partially done at least one more byte is required to complete the decompression task. This method should be called again with more input to decompress.
|
||||
/// - <see cref="System.Buffers.OperationStatus.InvalidData" />: The data in <paramref name="source" /> is invalid and could not be decompressed.</remarks>
|
||||
public OperationStatus Decompress(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesConsumed, out int bytesWritten)
|
||||
{
|
||||
EnsureInitialized();
|
||||
|
@ -92,6 +105,12 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Attempts to decompress data that was compressed with the Brotli algorithm.</summary>
|
||||
/// <param name="source">A buffer containing the compressed data.</param>
|
||||
/// <param name="destination">When this method returns, a byte span containing the decompressed data.</param>
|
||||
/// <param name="bytesWritten">The total number of bytes that were written in the <paramref name="destination" />.</param>
|
||||
/// <returns><see langword="true" /> on success; <see langword="false" /> otherwise.</returns>
|
||||
/// <remarks>If this method returns <see langword="false" />, <paramref name="destination" /> may be empty or contain partially decompressed data, with <paramref name="bytesWritten" /> being zero or greater than zero but less than the expected total.</remarks>
|
||||
public static unsafe bool TryDecompress(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten)
|
||||
{
|
||||
fixed (byte* inBytes = &MemoryMarshal.GetReference(source))
|
||||
|
|
|
@ -8,18 +8,37 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>Provides methods and properties used to compress and decompress streams by using the Brotli data format specification.</summary>
|
||||
public sealed partial class BrotliStream : Stream
|
||||
{
|
||||
private BrotliDecoder _decoder;
|
||||
private int _bufferOffset;
|
||||
private int _bufferCount;
|
||||
|
||||
/// <summary>Reads a number of decompressed bytes into the specified byte array.</summary>
|
||||
/// <param name="buffer">The array used to store decompressed bytes.</param>
|
||||
/// <param name="offset">The byte offset in <paramref name="buffer" /> at which the read bytes will be placed.</param>
|
||||
/// <param name="count">The maximum number of decompressed bytes to read.</param>
|
||||
/// <returns>The number of bytes that were decompressed into the byte array. If the end of the stream has been reached, zero or the number of bytes read is returned.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"><paramref name="buffer" /> is <see langword="null" />.</exception>
|
||||
/// <exception cref="System.InvalidOperationException">The <see cref="System.IO.Compression.CompressionMode" /> value was <see langword="Compress" /> when the object was created, or there is already an active asynchronous operation on this stream.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException"><paramref name="offset" /> or <paramref name="count" /> is less than zero.</exception>
|
||||
/// <exception cref="System.ArgumentException">The <paramref name="buffer" /> length minus the index starting point is less than <paramref name="count" />.</exception>
|
||||
/// <exception cref="System.IO.InvalidDataException">The data is in an invalid format.</exception>
|
||||
/// <exception cref="System.ObjectDisposedException">The underlying stream is null or closed.</exception>
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
ValidateBufferArguments(buffer, offset, count);
|
||||
return Read(new Span<byte>(buffer, offset, count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a byte from the stream and advances the position within the stream by one byte, or returns -1 if at the end of the stream.
|
||||
/// </summary>
|
||||
/// <returns>The unsigned byte cast to an <see cref="int"/>, or -1 if at the end of the stream.</returns>
|
||||
/// <exception cref="InvalidOperationException">Cannot perform read operations on a <see cref="BrotliStream" /> constructed with <see cref="CompressionMode.Compress" />.
|
||||
/// -or-
|
||||
/// <see cref="BaseStream" /> returned more bytes than requested in read.</exception>
|
||||
public override int ReadByte()
|
||||
{
|
||||
byte b = default;
|
||||
|
@ -27,6 +46,12 @@ namespace System.IO.Compression
|
|||
return numRead != 0 ? b : -1;
|
||||
}
|
||||
|
||||
/// <summary>Reads a sequence of bytes from the current Brotli stream to a byte span and advances the position within the Brotli stream by the number of bytes read.</summary>
|
||||
/// <param name="buffer">A region of memory. When this method returns, the contents of this region are replaced by the bytes read from the current source.</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 stream has been reached.</returns>
|
||||
/// <remarks>Use the <see cref="System.IO.Compression.BrotliStream.CanRead" /> property to determine whether the current instance supports reading. Use the <see langword="System.IO.Compression.BrotliStream.ReadAsync" /> method to read asynchronously from the current stream.
|
||||
/// This method read a maximum of `buffer.Length` bytes from the current stream and store them in <paramref name="buffer" />. The current position within the Brotli stream is advanced by the number of bytes read; however, if an exception occurs, the current position within the Brotli stream remains unchanged. This method will block until at least one byte of data can be read, in the event that no data is available. `Read` returns 0 only when there is no more data in the stream and no more is expected (such as a closed socket or end of file). The method is free to return fewer bytes than requested even if the end of the stream has not been reached.
|
||||
/// Use <see cref="System.IO.BinaryReader" /> for reading primitive data types.</remarks>
|
||||
public override int Read(Span<byte> buffer)
|
||||
{
|
||||
if (_mode != CompressionMode.Decompress)
|
||||
|
@ -87,18 +112,52 @@ namespace System.IO.Compression
|
|||
return totalWritten;
|
||||
}
|
||||
|
||||
/// <summary>Begins an asynchronous read operation. (Consider using the <see cref="System.IO.Stream.ReadAsync(byte[],int,int)" /> method instead.)</summary>
|
||||
/// <param name="buffer">The buffer from which data will be read.</param>
|
||||
/// <param name="offset">The byte offset in <paramref name="buffer" /> at which to begin reading data from the stream.</param>
|
||||
/// <param name="count">To maximum number of bytes to read.</param>
|
||||
/// <param name="asyncCallback">An optional asynchronous callback, to be called when the read operation is complete.</param>
|
||||
/// <param name="asyncState">A user-provided object that distinguishes this particular asynchronous read request from other requests.</param>
|
||||
/// <returns>An object that represents the asynchronous read operation, which could still be pending.</returns>
|
||||
/// <exception cref="System.IO.IOException">The method tried to read asynchronously past the end of the stream, or a disk error occurred.</exception>
|
||||
/// <exception cref="System.ArgumentException">One or more of the arguments is invalid.</exception>
|
||||
/// <exception cref="System.ObjectDisposedException">Methods were called after the stream was closed.</exception>
|
||||
/// <exception cref="System.NotSupportedException">The current <see cref="System.IO.Compression.BrotliStream" /> implementation does not support the read operation.</exception>
|
||||
/// <exception cref="System.InvalidOperationException">This call cannot be completed.</exception>
|
||||
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
|
||||
TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
|
||||
|
||||
/// <summary>Waits for the pending asynchronous read to complete. (Consider using the <see cref="System.IO.Stream.ReadAsync(byte[],int,int)" /> method instead.)</summary>
|
||||
/// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
|
||||
/// <returns>The number of bytes read from the stream, between 0 (zero) and the number of bytes you requested. <see cref="System.IO.Compression.BrotliStream" /> returns 0 only at the end of the stream; otherwise, it blocks until at least one byte is available.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"><paramref name="asyncResult" /> is <see langword="null" />.</exception>
|
||||
/// <exception cref="System.ArgumentException"><paramref name="asyncResult" /> did not originate from a <see cref="System.IO.Compression.BrotliStream.BeginRead(byte[],int,int,System.AsyncCallback,object)" /> method on the current stream.</exception>
|
||||
/// <exception cref="System.InvalidOperationException">The end operation cannot be performed because the stream is closed.</exception>
|
||||
public override int EndRead(IAsyncResult asyncResult) =>
|
||||
TaskToApm.End<int>(asyncResult);
|
||||
|
||||
/// <summary>Asynchronously reads a sequence of bytes from the current Brotli stream, writes them to a byte array starting at a specified index, advances the position within the Brotli stream by the number of bytes read, and monitors cancellation requests.</summary>
|
||||
/// <param name="buffer">The buffer to write the data into.</param>
|
||||
/// <param name="offset">The byte offset in <paramref name="buffer" /> at which to begin writing data from the Brotli stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to read.</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 <paramref name="buffer" />. The result value can be less than the number of bytes requested if the number of bytes currently available is less than the requested number, or it can be 0 (zero) if the end of the Brotli stream has been reached.</returns>
|
||||
/// <remarks>The `ReadAsync` method enables you to perform resource-intensive I/O operations without blocking the main thread. This performance consideration is particularly important in a Windows 8.x Store app or desktop app 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#.
|
||||
/// Use the <see cref="System.IO.Compression.BrotliStream.CanRead" /> property to determine whether the current instance supports reading.
|
||||
/// 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.</remarks>
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
ValidateBufferArguments(buffer, offset, count);
|
||||
return ReadAsync(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <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>The `ReadAsync` method enables you to perform resource-intensive I/O operations without blocking the main thread. This performance consideration is particularly important in a Windows 8.x Store app or desktop app 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#.
|
||||
/// Use the <see cref="System.IO.Compression.BrotliStream.CanRead" /> property to determine whether the current instance supports reading.
|
||||
/// 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.</remarks>
|
||||
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (_mode != CompressionMode.Decompress)
|
||||
|
|
|
@ -8,11 +8,19 @@ using Microsoft.Win32.SafeHandles;
|
|||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>Provides methods and static methods to encode and decode data in a streamless, non-allocating, and performant manner using the Brotli data format specification.</summary>
|
||||
public partial struct BrotliEncoder : IDisposable
|
||||
{
|
||||
internal SafeBrotliEncoderHandle? _state;
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="System.IO.Compression.BrotliEncoder" /> structure using the specified quality and window.</summary>
|
||||
/// <param name="quality">A number representing quality of the Brotli compression. 0 is the minimum (no compression), 11 is the maximum.</param>
|
||||
/// <param name="window">A number representing the encoder window bits. The minimum value is 10, and the maximum value is 24.</param>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException"><paramref name="quality" /> is not between the minimum value of 0 and the maximum value of 11.
|
||||
/// -or-
|
||||
/// <paramref name="window" /> is not between the minimum value of 10 and the maximum value of 24.</exception>
|
||||
/// <exception cref="System.IO.IOException">Failed to create the <see cref="System.IO.Compression.BrotliEncoder" /> instance.</exception>
|
||||
public BrotliEncoder(int quality, int window)
|
||||
{
|
||||
_disposed = false;
|
||||
|
@ -45,6 +53,7 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Frees and disposes unmanaged resources.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_disposed = true;
|
||||
|
@ -93,6 +102,11 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the maximum expected compressed length for the provided input size.</summary>
|
||||
/// <param name="inputSize">The input size to get the maximum expected compressed length from. Must be greater or equal than 0 and less or equal than <see cref="int.MaxValue" /> - 515.</param>
|
||||
/// <returns>A number representing the maximum compressed length for the provided input size.</returns>
|
||||
/// <remarks>Returns 1 if <paramref name="inputSize" /> is 0.</remarks>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException"><paramref name="inputSize" /> is less than 0, the minimum allowed input size, or greater than <see cref="int.MaxValue" /> - 515, the maximum allowed input size.</exception>
|
||||
public static int GetMaxCompressedLength(int inputSize)
|
||||
{
|
||||
if (inputSize < 0 || inputSize > BrotliUtils.MaxInputSize)
|
||||
|
@ -111,10 +125,21 @@ namespace System.IO.Compression
|
|||
|
||||
internal OperationStatus Flush(Memory<byte> destination, out int bytesWritten) => Flush(destination.Span, out bytesWritten);
|
||||
|
||||
/// <summary>Compresses an empty read-only span of bytes into its destination, which ensures that output is produced for all the processed input. An actual flush is performed when the source is depleted and there is enough space in the destination for the remaining data.</summary>
|
||||
/// <param name="destination">When this method returns, a span of bytes where the compressed data will be stored.</param>
|
||||
/// <param name="bytesWritten">When this method returns, the total number of bytes that were written to <paramref name="destination" />.</param>
|
||||
/// <returns>One of the enumeration values that describes the status with which the operation finished.</returns>
|
||||
public OperationStatus Flush(Span<byte> destination, out int bytesWritten) => Compress(ReadOnlySpan<byte>.Empty, destination, out int bytesConsumed, out bytesWritten, BrotliEncoderOperation.Flush);
|
||||
|
||||
internal OperationStatus Compress(ReadOnlyMemory<byte> source, Memory<byte> destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock) => Compress(source.Span, destination.Span, out bytesConsumed, out bytesWritten, isFinalBlock);
|
||||
|
||||
/// <summary>Compresses a read-only byte span into a destination span.</summary>
|
||||
/// <param name="source">A read-only span of bytes containing the source data to compress.</param>
|
||||
/// <param name="destination">When this method returns, a byte span where the compressed is stored.</param>
|
||||
/// <param name="bytesConsumed">When this method returns, the total number of bytes that were read from <paramref name="source" />.</param>
|
||||
/// <param name="bytesWritten">When this method returns, the total number of bytes that were written to <paramref name="destination" />.</param>
|
||||
/// <param name="isFinalBlock"><see langword="true" /> to finalize the internal stream, which prevents adding more input data when this method returns; <see langword="false" /> to allow the encoder to postpone the production of output until it has processed enough input.</param>
|
||||
/// <returns>One of the enumeration values that describes the status with which the span-based operation finished.</returns>
|
||||
public OperationStatus Compress(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock) => Compress(source, destination, out bytesConsumed, out bytesWritten, isFinalBlock ? BrotliEncoderOperation.Finish : BrotliEncoderOperation.Process);
|
||||
|
||||
internal OperationStatus Compress(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesConsumed, out int bytesWritten, BrotliEncoderOperation operation)
|
||||
|
@ -162,8 +187,20 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Tries to compress a source byte span into a destination span.</summary>
|
||||
/// <param name="source">A read-only span of bytes containing the source data to compress.</param>
|
||||
/// <param name="destination">When this method returns, a span of bytes where the compressed data is stored.</param>
|
||||
/// <param name="bytesWritten">When this method returns, the total number of bytes that were written to <paramref name="destination" />.</param>
|
||||
/// <returns><see langword="true" /> if the compression operation was successful; <see langword="false" /> otherwise.</returns>
|
||||
public static bool TryCompress(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten) => TryCompress(source, destination, out bytesWritten, BrotliUtils.Quality_Default, BrotliUtils.WindowBits_Default);
|
||||
|
||||
/// <summary>Tries to compress a source byte span into a destination byte span, using the provided compression quality leven and encoder window bits.</summary>
|
||||
/// <param name="source">A read-only span of bytes containing the source data to compress.</param>
|
||||
/// <param name="destination">When this method returns, a span of bytes where the compressed data is stored.</param>
|
||||
/// <param name="bytesWritten">When this method returns, the total number of bytes that were written to <paramref name="destination" />.</param>
|
||||
/// <param name="quality">A number representing quality of the Brotli compression. 0 is the minimum (no compression), 11 is the maximum.</param>
|
||||
/// <param name="window">A number representing the encoder window bits. The minimum value is 10, and the maximum value is 24.</param>
|
||||
/// <returns><see langword="true" /> if the compression operation was successful; <see langword="false" /> otherwise.</returns>
|
||||
public static bool TryCompress(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten, int quality, int window)
|
||||
{
|
||||
if (quality < 0 || quality > BrotliUtils.Quality_Max)
|
||||
|
|
|
@ -8,27 +8,51 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>Provides methods and properties used to compress and decompress streams by using the Brotli data format specification.</summary>
|
||||
public sealed partial class BrotliStream : Stream
|
||||
{
|
||||
private BrotliEncoder _encoder;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="System.IO.Compression.BrotliStream" /> class by using the specified stream and compression level.</summary>
|
||||
/// <param name="stream">The stream to compress.</param>
|
||||
/// <param name="compressionLevel">One of the enumeration values that indicates whether to emphasize speed or compression efficiency when compressing the stream.</param>
|
||||
public BrotliStream(Stream stream, CompressionLevel compressionLevel) : this(stream, compressionLevel, leaveOpen: false) { }
|
||||
/// <summary>Initializes a new instance of the <see cref="System.IO.Compression.BrotliStream" /> class by using the specified stream and compression level, and optionally leaves the stream open.</summary>
|
||||
/// <param name="stream">The stream to compress.</param>
|
||||
/// <param name="compressionLevel">One of the enumeration values that indicates whether to emphasize speed or compression efficiency when compressing the stream.</param>
|
||||
/// <param name="leaveOpen"><see langword="true" /> to leave the stream open after disposing the <see cref="System.IO.Compression.BrotliStream" /> object; otherwise, <see langword="false" />.</param>
|
||||
public BrotliStream(Stream stream, CompressionLevel compressionLevel, bool leaveOpen) : this(stream, CompressionMode.Compress, leaveOpen)
|
||||
{
|
||||
_encoder.SetQuality(BrotliUtils.GetQualityFromCompressionLevel(compressionLevel));
|
||||
}
|
||||
|
||||
/// <summary>Writes compressed bytes to the underlying stream from the specified byte array.</summary>
|
||||
/// <param name="buffer">The buffer containing the data to compress.</param>
|
||||
/// <param name="offset">The byte offset in <paramref name="buffer" /> from which the bytes will be read.</param>
|
||||
/// <param name="count">The maximum number of bytes to write.</param>
|
||||
/// <exception cref="System.ObjectDisposedException">The write operation cannot be performed because the stream is closed.</exception>
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
ValidateBufferArguments(buffer, offset, count);
|
||||
WriteCore(new ReadOnlySpan<byte>(buffer, offset, count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a byte to the current position in the stream and advances the position within the stream by one byte.
|
||||
/// </summary>
|
||||
/// <param name="value">The byte to write to the stream.</param>
|
||||
/// <exception cref="InvalidOperationException">Cannot perform write operations on a <see cref="BrotliStream" /> constructed with <see cref="CompressionMode.Decompress" />.
|
||||
/// -or-
|
||||
/// The encoder ran into invalid data.</exception>
|
||||
public override void WriteByte(byte value)
|
||||
{
|
||||
WriteCore(MemoryMarshal.CreateReadOnlySpan(ref value, 1));
|
||||
}
|
||||
|
||||
/// <summary>Writes a sequence of bytes to the current Brotli stream from a read-only byte span and advances the current position within this Brotli stream by the number of bytes written.</summary>
|
||||
/// <param name="buffer">A region of memory. This method copies the contents of this region to the current Brotli stream.</param>
|
||||
/// <remarks>Use the <see cref="System.IO.Compression.BrotliStream.CanWrite" /> property to determine whether the current instance supports writing. Use the <see langword="System.IO.Compression.BrotliStream.WriteAsync" /> method to write asynchronously to the current stream.
|
||||
/// If the write operation is successful, the position within the Brotli stream advances by the number of bytes written. If an exception occurs, the position within the Brotli stream remains unchanged.</remarks>
|
||||
public override void Write(ReadOnlySpan<byte> buffer)
|
||||
{
|
||||
WriteCore(buffer);
|
||||
|
@ -56,18 +80,49 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Begins an asynchronous write operation. (Consider using the <see cref="System.IO.Stream.WriteAsync(byte[],int,int)" /> method instead.)</summary>
|
||||
/// <param name="buffer">The buffer from which data will be written.</param>
|
||||
/// <param name="offset">The byte offset in <paramref name="buffer" /> at which to begin writing data from the stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to write.</param>
|
||||
/// <param name="asyncCallback">An optional asynchronous callback, to be called when the write operation is complete.</param>
|
||||
/// <param name="asyncState">A user-provided object that distinguishes this particular asynchronous write request from other requests.</param>
|
||||
/// <returns>An object that represents the asynchronous write operation, which could still be pending.</returns>
|
||||
/// <exception cref="System.IO.IOException">The method tried to write asynchronously past the end of the stream, or a disk error occurred.</exception>
|
||||
/// <exception cref="System.ArgumentException">One or more of the arguments is invalid.</exception>
|
||||
/// <exception cref="System.ObjectDisposedException">Methods were called after the stream was closed.</exception>
|
||||
/// <exception cref="System.NotSupportedException">The current <see cref="System.IO.Compression.BrotliStream" /> implementation does not support the write operation.</exception>
|
||||
/// <exception cref="System.InvalidOperationException">The write operation cannot be performed because the stream is closed.</exception>
|
||||
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) =>
|
||||
TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
|
||||
|
||||
/// <summary>Handles the end of an asynchronous write operation. (Consider using the <see cref="System.IO.Stream.WriteAsync(byte[],int,int)" /> method instead.)</summary>
|
||||
/// <param name="asyncResult">The object that represents the asynchronous call.</param>
|
||||
/// <exception cref="System.InvalidOperationException">The underlying stream is closed or <see langword="null" />.</exception>
|
||||
public override void EndWrite(IAsyncResult asyncResult) =>
|
||||
TaskToApm.End(asyncResult);
|
||||
|
||||
/// <summary>Asynchronously writes compressed bytes to the underlying Brotli stream from the specified byte array.</summary>
|
||||
/// <param name="buffer">The buffer that contains the data to compress.</param>
|
||||
/// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> from which to begin copying bytes to the Brotli stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to write.</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>The `WriteAsync` method enables you to perform resource-intensive I/O operations without blocking the main thread. This performance consideration is particularly important in a Windows 8.x Store app or desktop app 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#.
|
||||
/// Use the <see cref="System.IO.Compression.BrotliStream.CanWrite" /> property to determine whether the current instance supports writing.
|
||||
/// 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.</remarks>
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
ValidateBufferArguments(buffer, offset, count);
|
||||
return WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <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>The `WriteAsync` method enables you to perform resource-intensive I/O operations without blocking the main thread. This performance consideration is particularly important in a Windows 8.x Store app or desktop app 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#.
|
||||
/// Use the <see cref="System.IO.Compression.BrotliStream.CanWrite" /> property to determine whether the current instance supports writing.
|
||||
/// 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.</remarks>
|
||||
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (_mode != CompressionMode.Compress)
|
||||
|
@ -106,6 +161,9 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>If the stream is not disposed, and the compression mode is set to compress, writes all the remaining encoder's data into this stream.</summary>
|
||||
/// <exception cref="InvalidDataException">The encoder ran into invalid data.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The stream is disposed.</exception>
|
||||
public override void Flush()
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
|
@ -132,6 +190,10 @@ namespace System.IO.Compression
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Asynchronously clears all buffers for this Brotli stream, causes any buffered data to be written to the underlying device, and monitors cancellation requests.</summary>
|
||||
/// <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 flush operation.</returns>
|
||||
/// <remarks>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.</remarks>
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
EnsureNoActiveAsyncOperation();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue