From dc34fc0d62b91bd23cdbf081b6cb4f4a87d16e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sun, 1 Jul 2018 23:39:35 +0200 Subject: [PATCH 1/2] Fix Gzip.Compress and Gzip.Uncompress Fixes #151 Gzip.Compress does not take a "block size" but rather a buffer size --- src/ICSharpCode.SharpZipLib/GZip/GZip.cs | 60 +++++++++++++++--------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs index 1354a6d30..948d74384 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs @@ -15,19 +15,27 @@ public static class GZip /// The readable stream containing data to decompress. /// The output stream to receive the decompressed data. /// Both streams are closed on completion if true. + /// Input or output stream is null public static void Decompress(Stream inStream, Stream outStream, bool isStreamOwner) { - if (inStream == null || outStream == null) { - throw new Exception("Null Stream"); - } + if (inStream == null) + throw new ArgumentNullException(nameof(inStream), "Input stream is null"); + + if (outStream == null) + throw new ArgumentNullException(nameof(outStream), "Output stream is null"); - try { - using (GZipInputStream bzipInput = new GZipInputStream(inStream)) { - bzipInput.IsStreamOwner = isStreamOwner; - Core.StreamUtils.Copy(bzipInput, outStream, new byte[4096]); + try + { + using (GZipInputStream gzipInput = new GZipInputStream(inStream)) + { + gzipInput.IsStreamOwner = isStreamOwner; + Core.StreamUtils.Copy(gzipInput, outStream, new byte[4096]); } - } finally { - if (isStreamOwner) { + } + finally + { + if (isStreamOwner) + { // inStream is closed by the GZipInputStream if stream owner outStream.Dispose(); } @@ -41,21 +49,31 @@ public static void Decompress(Stream inStream, Stream outStream, bool isStreamOw /// The readable stream to compress. /// The output stream to receive the compressed data. /// Both streams are closed on completion if true. - /// Block size acts as compression level (1 to 9) with 1 giving - /// the lowest compression and 9 the highest. - public static void Compress(Stream inStream, Stream outStream, bool isStreamOwner, int level) + /// Deflate buffer size, minimum 512 + /// Input or output stream is null + /// Buffer Size is smaller than 512 + public static void Compress(Stream inStream, Stream outStream, bool isStreamOwner, int bufferSize = 512) { - if (inStream == null || outStream == null) { - throw new Exception("Null Stream"); - } + if (inStream == null) + throw new ArgumentNullException(nameof(inStream), "Input stream is null"); - try { - using (GZipOutputStream bzipOutput = new GZipOutputStream(outStream, level)) { - bzipOutput.IsStreamOwner = isStreamOwner; - Core.StreamUtils.Copy(inStream, bzipOutput, new byte[4096]); + if(outStream == null) + throw new ArgumentNullException(nameof(outStream), "Output stream is null"); + + if (bufferSize < 512) + throw new ArgumentOutOfRangeException(nameof(bufferSize), "Deflate buffer size must be >= 512"); + + try + { + using (GZipOutputStream gzipOutput = new GZipOutputStream(outStream, bufferSize)) + { + gzipOutput.IsStreamOwner = isStreamOwner; + Core.StreamUtils.Copy(inStream, gzipOutput, new byte[bufferSize]); } - } finally { - if (isStreamOwner) { + } + finally { + if (isStreamOwner) + { // outStream is closed by the GZipOutputStream if stream owner inStream.Dispose(); } From c7f2929f41782e5af47b6fad3d9ce438ecd83752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Mon, 2 Jul 2018 00:14:59 +0200 Subject: [PATCH 2/2] Add support for passing compression level to GZip.Compress Lower the minimum compression level on GzipOutputStream to the same minimum as Deflater.SetLevel --- src/ICSharpCode.SharpZipLib/GZip/GZip.cs | 13 +++++++++++-- .../GZip/GzipOutputStream.cs | 8 ++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs index 948d74384..f3970bba7 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs @@ -3,6 +3,8 @@ namespace ICSharpCode.SharpZipLib.GZip { + using static Zip.Compression.Deflater; + /// /// An example class to demonstrate compression and decompression of GZip streams. /// @@ -50,9 +52,11 @@ public static void Decompress(Stream inStream, Stream outStream, bool isStreamOw /// The output stream to receive the compressed data. /// Both streams are closed on completion if true. /// Deflate buffer size, minimum 512 + /// Deflate compression level, 0-9 /// Input or output stream is null /// Buffer Size is smaller than 512 - public static void Compress(Stream inStream, Stream outStream, bool isStreamOwner, int bufferSize = 512) + /// Compression level outside 0-9 + public static void Compress(Stream inStream, Stream outStream, bool isStreamOwner, int bufferSize = 512, int level = 6) { if (inStream == null) throw new ArgumentNullException(nameof(inStream), "Input stream is null"); @@ -63,15 +67,20 @@ public static void Compress(Stream inStream, Stream outStream, bool isStreamOwne if (bufferSize < 512) throw new ArgumentOutOfRangeException(nameof(bufferSize), "Deflate buffer size must be >= 512"); + if (level BEST_COMPRESSION) + throw new ArgumentOutOfRangeException(nameof(level), "Compression level must be 0-9"); + try { using (GZipOutputStream gzipOutput = new GZipOutputStream(outStream, bufferSize)) { + gzipOutput.SetLevel(level); gzipOutput.IsStreamOwner = isStreamOwner; Core.StreamUtils.Copy(inStream, gzipOutput, new byte[bufferSize]); } } - finally { + finally + { if (isStreamOwner) { // outStream is closed by the GZipOutputStream if stream owner diff --git a/src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs b/src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs index e2d35ceb3..083ae08ad 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs @@ -80,7 +80,7 @@ public GZipOutputStream(Stream baseOutputStream) #region Public API /// - /// Sets the active compression level (1-9). The new level will be activated + /// Sets the active compression level (0-9). The new level will be activated /// immediately. /// /// The compression level to set. @@ -90,9 +90,9 @@ public GZipOutputStream(Stream baseOutputStream) /// public void SetLevel(int level) { - if (level < Deflater.BEST_SPEED) { - throw new ArgumentOutOfRangeException(nameof(level)); - } + if (level < Deflater.NO_COMPRESSION || level > Deflater.BEST_COMPRESSION) + throw new ArgumentOutOfRangeException(nameof(level), "Compression level must be 0-9"); + deflater_.SetLevel(level); }