Skip to content

Reformat ZLibNative comments #112585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,47 @@ namespace System.IO.Compression;
internal static partial class ZLibNative
{
/// <summary>
/// <p>ZLib can accept any integer value between 0 and 9 (inclusive) as a valid compression level parameter:
/// ZLib can accept any integer value between 0 and 9 (inclusive) as a valid compression level parameter:
/// 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time).
/// <code>CompressionLevel.DefaultCompression</code> = -1 requests a default compromise between speed and compression
/// (currently equivalent to level 6).</p>
///
/// <p><strong>How to choose a compression level:</strong></p>
///
/// <p>The names <code>NoCompression</code>, <code>BestSpeed</code>, <code>DefaultCompression</code>, <code>BestCompression</code> are taken over from
/// the corresponding ZLib definitions, which map to our public NoCompression, Fastest, Optimal, and SmallestSize respectively.</p>
/// <p><em>Optimal Compression:</em></p>
/// <p><code>ZLibNative.CompressionLevel compressionLevel = ZLibNative.CompressionLevel.DefaultCompression;</code> <br />
/// <code>int windowBits = 15; // or -15 if no headers required</code> <br />
/// <code>int memLevel = 8;</code> <br />
/// <code>ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy;</code> </p>
/// <see cref="CompressionLevel.DefaultCompression" /> = -1 requests a default compromise between speed and compression
/// (currently equivalent to level 6).
/// </summary>
/// <remarks>
/// <para><strong>How to choose a compression level:</strong><br />
/// The names <see cref="NoCompression" />, <see cref="BestSpeed" />, <see cref="DefaultCompression" />, <see cref="BestCompression" /> are taken over from
/// the corresponding ZLib definitions, which map to our public NoCompression, Fastest, Optimal, and SmallestSize respectively.</para>
/// <em>Optimal Compression:</em>
/// <code>
/// ZLibNative.CompressionLevel compressionLevel = ZLibNative.CompressionLevel.DefaultCompression;
/// int windowBits = 15; // or -15 if no headers required
/// int memLevel = 8;
/// ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy;
/// </code>
///
///<p><em>Fastest compression:</em></p>
///<p><code>ZLibNative.CompressionLevel compressionLevel = ZLibNative.CompressionLevel.BestSpeed;</code> <br />
/// <code>int windowBits = 15; // or -15 if no headers required</code> <br />
/// <code>int memLevel = 8; </code> <br />
/// <code>ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy;</code> </p>
/// <em>Fastest compression:</em>
/// <code>
/// ZLibNative.CompressionLevel compressionLevel = ZLibNative.CompressionLevel.BestSpeed;
/// int windowBits = 15; // or -15 if no headers required
/// int memLevel = 8;
/// ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy;
/// </code>
///
/// <p><em>No compression (even faster, useful for data that cannot be compressed such some image formats):</em></p>
/// <p><code>ZLibNative.CompressionLevel compressionLevel = ZLibNative.CompressionLevel.NoCompression;</code> <br />
/// <code>int windowBits = 15; // or -15 if no headers required</code> <br />
/// <code>int memLevel = 7;</code> <br />
/// <code>ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy;</code> </p>
/// <em>No compression (even faster, useful for data that cannot be compressed such some image formats):</em>
/// <code>
/// ZLibNative.CompressionLevel compressionLevel = ZLibNative.CompressionLevel.NoCompression;
/// int windowBits = 15; // or -15 if no headers required
/// int memLevel = 7;
/// ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy;
/// </code>
///
/// <p><em>Smallest Size Compression:</em></p>
/// <p><code>ZLibNative.CompressionLevel compressionLevel = ZLibNative.CompressionLevel.BestCompression;</code> <br />
/// <code>int windowBits = 15; // or -15 if no headers required</code> <br />
/// <code>int memLevel = 8;</code> <br />
/// <code>ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy;</code> </p>
/// </summary>
/// <em>Smallest Size Compression:</em>
/// <code>
/// ZLibNative.CompressionLevel compressionLevel = ZLibNative.CompressionLevel.BestCompression;
/// int windowBits = 15; // or -15 if no headers required
/// int memLevel = 8;
/// ZLibNative.CompressionStrategy strategy = ZLibNative.CompressionStrategy.DefaultStrategy;
/// </code>
/// </remarks>
public enum CompressionLevel : int
{
NoCompression = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ internal static partial class ZLibNative
{
/// <summary>
/// ZLib stream descriptor data structure
/// Do not construct instances of <code>ZStream</code> explicitly.
/// Always use <code>ZLibNative.DeflateInit2_</code> or <code>ZLibNative.InflateInit2_</code> instead.
/// Those methods will wrap this structure into a <code>SafeHandle</code> and thus make sure that it is always disposed correctly.
/// Do not construct instances of <see cref="ZStream" /> explicitly.
/// Always use <see cref="ZLibNative.CreateZLibStreamForDeflate" /> or <see cref="ZLibNative.CreateZLibStreamForInflate" /> instead.
/// Those methods will wrap this structure into a <see cref="ZLibStreamHandle" /> and thus make sure that it is always disposed correctly.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal struct ZStream
Expand Down
100 changes: 52 additions & 48 deletions src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ namespace System.IO.Compression
/// This class provides declaration for constants and PInvokes as well as some basic tools for exposing the
/// native System.IO.Compression.Native.dll (effectively, ZLib) library to managed code.
///
/// See also: How to choose a compression level (in comments to <code>CompressionLevel</code>.
/// <para>See also: How to choose a compression level (in comments to <see cref="CompressionLevel" />.)</para>
/// </summary>
/// <seealso href="https://www.zlib.net/manual.html">ZLib manual</seealso>
internal static partial class ZLibNative
{
// This is the NULL pointer for using with ZLib pointers;
Expand All @@ -38,21 +39,22 @@ public enum ErrorCode : int
}

/// <summary>
/// <p><strong>From the ZLib manual:</strong></p>
/// <p><code>CompressionStrategy</code> is used to tune the compression algorithm.<br />
/// Use the value <code>DefaultStrategy</code> for normal data, <code>Filtered</code> for data produced by a filter (or predictor),
/// <code>HuffmanOnly</code> to force Huffman encoding only (no string match), or <code>Rle</code> to limit match distances to one
/// <para><strong>From the ZLib manual:</strong><br />
/// <see cref="CompressionStrategy" /> is used to tune the compression algorithm.<br />
/// Use the value <see cref="DefaultStrategy" /> for normal data, <see cref="Filtered" /> for data produced by a filter (or predictor),
/// <see cref="HuffmanOnly" /> to force Huffman encoding only (no string match), or <see cref="RunLengthEncoding" /> to limit match distances to one
/// (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the
/// compression algorithm is tuned to compress them better. The effect of <code>Filtered</code> is to force more Huffman coding and]
/// less string matching; it is somewhat intermediate between <code>DefaultStrategy</code> and <code>HuffmanOnly</code>.
/// <code>Rle</code> is designed to be almost as fast as <code>HuffmanOnly</code>, but give better compression for PNG image data.
/// compression algorithm is tuned to compress them better. The effect of <see cref="Filtered" /> is to force more Huffman coding and
/// less string matching; it is somewhat intermediate between <see cref="DefaultStrategy" /> and <see cref="HuffmanOnly" />.
/// <see cref="RunLengthEncoding" /> is designed to be almost as fast as <see cref="HuffmanOnly" />, but give better compression for PNG image data.
/// The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set
/// appropriately. <code>Fixed</code> prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.</p>
/// appropriately. <see cref="Fixed" /> prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.</para>
///
/// <p><strong>For .NET Framework use:</strong></p>
/// <p>We have investigated compression scenarios for a bunch of different frequently occurring compression data and found that in all
/// cases we investigated so far, <code>DefaultStrategy</code> provided best results</p>
/// <p>See also: How to choose a compression level (in comments to <code>CompressionLevel</code>.</p>
/// <para><strong>For .NET Framework use:</strong><br />
/// We have investigated compression scenarios for a bunch of different frequently occurring compression data and found that in all
/// cases we investigated so far, <see cref="DefaultStrategy" /> provided best results</para>
///
/// <para>See also: How to choose a compression level (in comments to <see cref="CompressionLevel" />.)</para>
/// </summary>
public enum CompressionStrategy : int
{
Expand All @@ -64,51 +66,53 @@ public enum CompressionStrategy : int
}

/// <summary>
/// In version 1.2.3, ZLib provides on the <code>Deflated</code>-<code>CompressionMethod</code>.
/// In version 2.2.1, zlib-ng provides only the <see cref="Deflated" /> <see cref="CompressionMethod" />.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I assume zlib-ng 2.2.1 is the minimum version where this restriction was added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'm describing a lack of support for anything besides Deflated, so the restriction's been present from the outset. The only reason I've picked v2.2.1 is that it's the one we've used at time of writing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay. That's alright too.

/// </summary>
public enum CompressionMethod : int
{
Deflated = 8
}

/// <summary>
/// <p><strong>From the ZLib manual:</strong></p>
/// <p>ZLib's <code>windowBits</code> parameter is the base two logarithm of the window size (the size of the history buffer).
/// <para><strong>From the ZLib manual:</strong><br />
/// ZLib's <c>windowBits</c> parameter is the base two logarithm of the window size (the size of the history buffer).
/// It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression
/// at the expense of memory usage. The default value is 15 if deflateInit is used instead.<br /></p>
/// <strong>Note</strong>:
/// <code>windowBits</code> can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size.
/// <code>Deflate</code> will then generate raw deflate data with no ZLib header or trailer, and will not compute an adler32 check value.<br />
/// <p>See also: How to choose a compression level (in comments to <code>CompressionLevel</code>.</p>
/// at the expense of memory usage. The default value is 15 if <c>deflateInit</c> is used instead.</para>
///
/// <para><strong>Note</strong>: <c>windowBits</c> can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size.
/// <c>Deflate</c> will then generate raw deflate data with no ZLib header or trailer, and will not compute an adler32 check value.</para>
///
/// <para>See also: How to choose a compression level (in comments to <see cref="CompressionLevel" />.)</para>
/// </summary>
public const int Deflate_DefaultWindowBits = -15; // Legal values are 8..15 and -8..-15. 15 is the window size,
// negative val causes deflate to produce raw deflate data (no zlib header).

/// <summary>
/// <p><strong>From the ZLib manual:</strong></p>
/// <p>ZLib's <code>windowBits</code> parameter is the base two logarithm of the window size (the size of the history buffer).
/// <para><strong>From the ZLib manual:</strong><br />
/// ZLib's <c>windowBits</c> parameter is the base two logarithm of the window size (the size of the history buffer).
/// It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression
/// at the expense of memory usage. The default value is 15 if deflateInit is used instead.<br /></p>
/// at the expense of memory usage. The default value is 15 if <c>deflateInit</c> is used instead.</para>
/// </summary>
public const int ZLib_DefaultWindowBits = 15;

/// <summary>
/// <p>Zlib's <code>windowBits</code> parameter is the base two logarithm of the window size (the size of the history buffer).
/// For GZip header encoding, <code>windowBits</code> should be equal to a value between 8..15 (to specify Window Size) added to
/// 16. The range of values for GZip encoding is therefore 24..31.
/// <strong>Note</strong>:
/// <para>ZLib's <c>windowBits</c> parameter is the base two logarithm of the window size (the size of the history buffer).
/// For GZip header encoding, <c>windowBits</c> should be equal to a value between 8..15 (to specify Window Size) added to
/// 16. The range of values for GZip encoding is therefore 24..31.</para>
/// <para><strong>Note</strong>:<br />
/// The GZip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and
/// the operating system will be set based on the OS that the ZLib library was compiled to. <code>ZStream.adler</code>
/// is a crc32 instead of an adler32.</p>
/// the operating system will be set based on the OS that the ZLib library was compiled to. <c>ZStream.adler</c>
/// is a crc32 instead of an adler32.</para>
/// </summary>
public const int GZip_DefaultWindowBits = 31;

/// <summary>
/// <p><strong>From the ZLib manual:</strong></p>
/// <p>The <code>memLevel</code> parameter specifies how much memory should be allocated for the internal compression state.
/// <code>memLevel</code> = 1 uses minimum memory but is slow and reduces compression ratio; <code>memLevel</code> = 9 uses maximum
/// memory for optimal speed. The default value is 8.</p>
/// <p>See also: How to choose a compression level (in comments to <code>CompressionLevel</code>.</p>
/// <para><strong>From the ZLib manual:</strong><br />
/// The <c>memLevel</c> parameter specifies how much memory should be allocated for the internal compression state.
/// <c>memLevel</c> = 1 uses minimum memory but is slow and reduces compression ratio; <c>memLevel</c> = 9 uses maximum
/// memory for optimal speed. The default value is 8.</para>
///
/// <para>See also: How to choose a compression level (in comments to <see cref="CompressionLevel" />.)</para>
/// </summary>
public const int Deflate_DefaultMemLevel = 8; // Memory usage by deflate. Legal range: [1..9]. 8 is ZLib default.
// More is faster and better compression with more memory usage.
Expand All @@ -118,16 +122,16 @@ public enum CompressionMethod : int
public const byte GZip_Header_ID2 = 139;

/**
* Do not remove the nested typing of types inside of <code>System.IO.Compression.ZLibNative</code>.
* Do not remove the nested typing of types inside of <see cref="ZLibNative" />.
* This was done on purpose to:
*
* - Achieve the right encapsulation in a situation where <code>ZLibNative</code> may be compiled division-wide
* into different assemblies that wish to consume <code>System.IO.Compression.Native</code>. Since <code>internal</code>
* scope is effectively like <code>public</code> scope when compiling <code>ZLibNative</code> into a higher
* level assembly, we need a combination of inner types and <code>private</code>-scope members to achieve
* - Achieve the right encapsulation in a situation where <see cref="ZLibNative" /> may be compiled division-wide
* into different assemblies that wish to consume <c>System.IO.Compression.Native</c>. Since <c>internal</c>
* scope is effectively like <c>public</c> scope when compiling <see cref="ZLibNative" /> into a higher
* level assembly, we need a combination of inner types and <c>private</c>-scope members to achieve
* the right encapsulation.
*
* - Achieve late dynamic loading of <code>System.IO.Compression.Native.dll</code> at the right time.
* - Achieve late dynamic loading of <c>System.IO.Compression.Native.dll</c> at the right time.
* The native assembly will not be loaded unless it is actually used since the loading is performed by a static
* constructor of an inner type that is not directly referenced by user code.
*
Expand All @@ -137,15 +141,15 @@ public enum CompressionMethod : int
*/

/// <summary>
/// The <code>ZLibStreamHandle</code> could be a <code>CriticalFinalizerObject</code> rather than a
/// <code>SafeHandleMinusOneIsInvalid</code>. This would save an <code>IntPtr</code> field since
/// <code>ZLibStreamHandle</code> does not actually use its <code>handle</code> field.
/// Instead it uses a <code>private ZStream zStream</code> field which is the actual handle data
/// The <see cref="ZLibStreamHandle" /> could be a <see cref="System.Runtime.ConstrainedExecution.CriticalFinalizerObject" /> rather than a
/// <see cref="SafeHandle" />. This would save an <see cref="IntPtr" /> field since
/// <see cref="ZLibStreamHandle" /> does not actually use its <see cref="SafeHandle.handle" /> field.
/// Instead it uses a private <see cref="_zStream" /> field which is the actual handle data
/// structure requiring critical finalization.
/// However, we would like to take advantage if the better debugability offered by the fact that a
/// <em>releaseHandleFailed MDA</em> is raised if the <code>ReleaseHandle</code> method returns
/// <code>false</code>, which can for instance happen if the underlying ZLib <code>XxxxEnd</code>
/// routines return an failure error code.
/// <em>releaseHandleFailed MDA</em> is raised if the <see cref="ReleaseHandle" /> method returns
/// <c>false</c>, which can for instance happen if the underlying ZLib <see cref="Interop.ZLib.InflateEnd"/>
/// or <see cref="Interop.ZLib.DeflateEnd"/> routines return an failure error code.
/// </summary>
public sealed class ZLibStreamHandle : SafeHandle
{
Expand Down
Loading