// ZlibCodec.cs// ------------------------------------------------------------------//// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. // All rights reserved.//// This code module is part of DotNetZip, a zipfile class library.//// ------------------------------------------------------------------//// This code is licensed under the Microsoft Public License. // See the file License.txt for the license details.// More info on: http://dotnetzip.codeplex.com//// ------------------------------------------------------------------//// last saved (in emacs): // Time-stamp: <2009-November-03 15:40:51>//// ------------------------------------------------------------------//// This module defines a Codec for ZLIB compression and// decompression. This code extends code that was based the jzlib// implementation of zlib, but this code is completely novel. The codec// class is new, and encapsulates some behaviors that are new, and some// that were present in other classes in the jzlib code base. In// keeping with the license for jzlib, the copyright to the jzlib code// is included below.//// ------------------------------------------------------------------// // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.// // Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met:// // 1. Redistributions of source code must retain the above copyright notice,// this list of conditions and the following disclaimer.// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the distribution.// // 3. The names of the authors may not be used to endorse or promote products// derived from this software without specific prior written permission.// // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// // -----------------------------------------------------------------------//// This program is based on zlib-1.1.3; credit to authors// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)// and contributors of zlib.//// ----------------------------------------------------------------------- using System;using Interop=System.Runtime.InteropServices; namespace Ionic.Zlib{ /// <summary> /// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951). /// </summary> /// /// <remarks> /// This class compresses and decompresses data according to the Deflate algorithm /// and optionally, the ZLIB format, as documented in <see /// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950 - ZLIB</see> and <see /// href="http://www.ietf.org/rfc/rfc1951.txt">RFC 1951 - DEFLATE</see>. /// </remarks>#if !PCL [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000D")] [Interop.ComVisible(true)]#if !NETCF [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]#endif#endif internal sealed class ZlibCodec { /// <summary> /// The buffer from which data is taken. /// </summary> public byte[] InputBuffer; /// <summary> /// An index into the InputBuffer array, indicating where to start reading. /// </summary> public int NextIn; /// <summary> /// The number of bytes available in the InputBuffer, starting at NextIn. /// </summary> /// <remarks> /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. /// The class will update this number as calls to Inflate/Deflate are made. /// </remarks> public int AvailableBytesIn; /// <summary> /// Total number of bytes read so far, through all calls to Inflate()/Deflate(). /// </summary> public long TotalBytesIn; /// <summary> /// Buffer to store output data. /// </summary> public byte[] OutputBuffer; /// <summary> /// An index into the OutputBuffer array, indicating where to start writing. /// </summary> public int NextOut; /// <summary> /// The number of bytes available in the OutputBuffer, starting at NextOut. /// </summary> /// <remarks> /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. /// The class will update this number as calls to Inflate/Deflate are made. /// </remarks> public int AvailableBytesOut; /// <summary> /// Total number of bytes written to the output so far, through all calls to Inflate()/Deflate(). /// </summary> public long TotalBytesOut; /// <summary> /// used for diagnostics, when something goes wrong! /// </summary> public System.String Message; internal DeflateManager dstate; internal InflateManager istate; internal uint _Adler32; /// <summary> /// The compression level to use in this codec. Useful only in compression mode. /// </summary> public CompressionLevel CompressLevel = CompressionLevel.Default; /// <summary> /// The number of Window Bits to use. /// </summary> /// <remarks> /// This gauges the size of the sliding window, and hence the /// compression effectiveness as well as memory consumption. It's best to just leave this /// setting alone if you don't know what it is. The maximum value is 15 bits, which implies /// a 32k window. /// </remarks> public int WindowBits = ZlibConstants.WindowBitsDefault; /// <summary> /// The compression strategy to use. /// </summary> /// <remarks> /// This is only effective in compression. The theory offered by ZLIB is that different /// strategies could potentially produce significant differences in compression behavior /// for different data sets. Unfortunately I don't have any good recommendations for how /// to set it differently. When I tested changing the strategy I got minimally different /// compression performance. It's best to leave this property alone if you don't have a /// good feel for it. Or, you may want to produce a test harness that runs through the /// different strategy options and evaluates them on different file types. If you do that, /// let me know your results. /// </remarks> public CompressionStrategy Strategy = CompressionStrategy.Default; /// <summary> /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this. /// </summary> public int Adler32 { get { return (int)_Adler32; } } /// <summary> /// Create a ZlibCodec. /// </summary> /// <remarks> /// If you use this default constructor, you will later have to explicitly call /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress /// or decompress. /// </remarks> public ZlibCodec() { } /// <summary> /// Create a ZlibCodec that either compresses or decompresses. /// </summary> /// <param name="mode"> /// Indicates whether the codec should compress (deflate) or decompress (inflate). /// </param> public ZlibCodec(CompressionMode mode) { if (mode == CompressionMode.Compress) { int rc = InitializeDeflate(); if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for deflate."); } else if (mode == CompressionMode.Decompress) { int rc = InitializeInflate(); if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for inflate."); } else throw new ZlibException("Invalid ZlibStreamFlavor."); } /// <summary> /// Initialize the inflation state. /// </summary> /// <remarks> /// It is not necessary to call this before using the ZlibCodec to inflate data; /// It is implicitly called when you call the constructor. /// </remarks> /// <returns>Z_OK if everything goes well.</returns> public int InitializeInflate() { return InitializeInflate(this.WindowBits); } /// <summary> /// Initialize the inflation state with an explicit flag to /// govern the handling of RFC1950 header bytes. /// </summary> /// /// <remarks> /// By default, the ZLIB header defined in <see /// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950</see> is expected. If /// you want to read a zlib stream you should specify true for /// expectRfc1950Header. If you have a deflate stream, you will want to specify /// false. It is only necessary to invoke this initializer explicitly if you /// want to specify false. /// </remarks> /// /// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte /// pair when reading the stream of data to be inflated.</param> /// /// <returns>Z_OK if everything goes well.</returns> public int InitializeInflate(bool expectRfc1950Header) { return InitializeInflate(this.WindowBits, expectRfc1950Header); } /// <summary> /// Initialize the ZlibCodec for inflation, with the specified number of window bits. /// </summary> /// <param name="windowBits">The number of window bits to use. If you need to ask what that is, /// then you shouldn't be calling this initializer.</param> /// <returns>Z_OK if all goes well.</returns> public int InitializeInflate(int windowBits) { this.WindowBits = windowBits; return InitializeInflate(windowBits, true); } /// <summary> /// Initialize the inflation state with an explicit flag to govern the handling of /// RFC1950 header bytes. /// </summary> /// /// <remarks> /// If you want to read a zlib stream you should specify true for /// expectRfc1950Header. In this case, the library will expect to find a ZLIB /// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC /// 1950</see>, in the compressed stream. If you will be reading a DEFLATE or /// GZIP stream, which does not have such a header, you will want to specify /// false. /// </remarks> /// /// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte pair when reading /// the stream of data to be inflated.</param> /// <param name="windowBits">The number of window bits to use. If you need to ask what that is, /// then you shouldn't be calling this initializer.</param> /// <returns>Z_OK if everything goes well.</returns> public int InitializeInflate(int windowBits, bool expectRfc1950Header) { this.WindowBits = windowBits; if (dstate != null) throw new ZlibException("You may not call InitializeInflate() after calling InitializeDeflate()."); istate = new InflateManager(expectRfc1950Header); return istate.Initialize(this, windowBits); } /// <summary> /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer. /// </summary> /// <remarks> /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and /// AvailableBytesOut before calling this method. /// </remarks> /// <example> /// <code> /// private void InflateBuffer() /// { /// int bufferSize = 1024; /// byte[] buffer = new byte[bufferSize]; /// ZlibCodec decompressor = new ZlibCodec(); /// /// Console.WriteLine("\n============================================"); /// Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length); /// MemoryStream ms = new MemoryStream(DecompressedBytes); /// /// int rc = decompressor.InitializeInflate(); /// /// decompressor.InputBuffer = CompressedBytes; /// decompressor.NextIn = 0; /// decompressor.AvailableBytesIn = CompressedBytes.Length; /// /// decompressor.OutputBuffer = buffer; /// /// // pass 1: inflate /// do /// { /// decompressor.NextOut = 0; /// decompressor.AvailableBytesOut = buffer.Length; /// rc = decompressor.Inflate(FlushType.None); /// /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) /// throw new Exception("inflating: " + decompressor.Message); /// /// ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut); /// } /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); /// /// // pass 2: finish and flush /// do /// { /// decompressor.NextOut = 0; /// decompressor.AvailableBytesOut = buffer.Length; /// rc = decompressor.Inflate(FlushType.Finish); /// /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) /// throw new Exception("inflating: " + decompressor.Message); /// /// if (buffer.Length - decompressor.AvailableBytesOut > 0) /// ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut); /// } /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); /// /// decompressor.EndInflate(); /// } /// /// </code> /// </example> /// <param name="flush">The flush to use when inflating.</param> /// <returns>Z_OK if everything goes well.</returns> public int Inflate(FlushType flush) { if (istate == null) throw new ZlibException("No Inflate State!"); return istate.Inflate(flush); } /// <summary> /// Ends an inflation session. /// </summary> /// <remarks> /// Call this after successively calling Inflate(). This will cause all buffers to be flushed. /// After calling this you cannot call Inflate() without a intervening call to one of the /// InitializeInflate() overloads. /// </remarks> /// <returns>Z_OK if everything goes well.</returns> public int EndInflate() { if (istate == null) throw new ZlibException("No Inflate State!"); int ret = istate.End(); istate = null; return ret; } /// <summary> /// I don't know what this does! /// </summary> /// <returns>Z_OK if everything goes well.</returns> public int SyncInflate() { if (istate == null) throw new ZlibException("No Inflate State!"); return istate.Sync(); } /// <summary> /// Initialize the ZlibCodec for deflation operation. /// </summary> /// <remarks> /// The codec will use the MAX window bits and the default level of compression. /// </remarks> /// <example> /// <code> /// int bufferSize = 40000; /// byte[] CompressedBytes = new byte[bufferSize]; /// byte[] DecompressedBytes = new byte[bufferSize]; /// /// ZlibCodec compressor = new ZlibCodec(); /// /// compressor.InitializeDeflate(CompressionLevel.Default); /// /// compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress); /// compressor.NextIn = 0; /// compressor.AvailableBytesIn = compressor.InputBuffer.Length; /// /// compressor.OutputBuffer = CompressedBytes; /// compressor.NextOut = 0; /// compressor.AvailableBytesOut = CompressedBytes.Length; /// /// while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize) /// { /// compressor.Deflate(FlushType.None); /// } /// /// while (true) /// { /// int rc= compressor.Deflate(FlushType.Finish); /// if (rc == ZlibConstants.Z_STREAM_END) break; /// } /// /// compressor.EndDeflate(); /// /// </code> /// </example> /// <returns>Z_OK if all goes well. You generally don't need to check the return code.</returns> public int InitializeDeflate() { return _InternalInitializeDeflate(true); } /// <summary> /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel. /// </summary> /// <remarks> /// The codec will use the maximum window bits (15) and the specified /// CompressionLevel. It will emit a ZLIB stream as it compresses. /// </remarks> /// <param name="level">The compression level for the codec.</param> /// <returns>Z_OK if all goes well.</returns> public int InitializeDeflate(CompressionLevel level) { this.CompressLevel = level; return _InternalInitializeDeflate(true); } /// <summary> /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, /// and the explicit flag governing whether to emit an RFC1950 header byte pair. /// </summary> /// <remarks> /// The codec will use the maximum window bits (15) and the specified CompressionLevel. /// If you want to generate a zlib stream, you should specify true for /// wantRfc1950Header. In this case, the library will emit a ZLIB /// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC /// 1950</see>, in the compressed stream. /// </remarks> /// <param name="level">The compression level for the codec.</param> /// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param> /// <returns>Z_OK if all goes well.</returns> public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header) { this.CompressLevel = level; return _InternalInitializeDeflate(wantRfc1950Header); } /// <summary> /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, /// and the specified number of window bits. /// </summary> /// <remarks> /// The codec will use the specified number of window bits and the specified CompressionLevel. /// </remarks> /// <param name="level">The compression level for the codec.</param> /// <param name="bits">the number of window bits to use. If you don't know what this means, don't use this method.</param> /// <returns>Z_OK if all goes well.</returns> public int InitializeDeflate(CompressionLevel level, int bits) { this.CompressLevel = level; this.WindowBits = bits; return _InternalInitializeDeflate(true); } /// <summary> /// Initialize the ZlibCodec for deflation operation, using the specified /// CompressionLevel, the specified number of window bits, and the explicit flag /// governing whether to emit an RFC1950 header byte pair. /// </summary> /// /// <param name="level">The compression level for the codec.</param> /// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param> /// <param name="bits">the number of window bits to use. If you don't know what this means, don't use this method.</param>Lines 1–500 of 719. Load more
// ZlibCodec.cs // ------------------------------------------------------------------ // // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. // All rights reserved. // // This code module is part of DotNetZip, a zipfile class library. // // ------------------------------------------------------------------ // // This code is licensed under the Microsoft Public License. // See the file License.txt for the license details. // More info on: http://dotnetzip.codeplex.com // // ------------------------------------------------------------------ // // last saved (in emacs): // Time-stamp: <2009-November-03 15:40:51> // // ------------------------------------------------------------------ // // This module defines a Codec for ZLIB compression and // decompression. This code extends code that was based the jzlib // implementation of zlib, but this code is completely novel. The codec // class is new, and encapsulates some behaviors that are new, and some // that were present in other classes in the jzlib code base. In // keeping with the license for jzlib, the copyright to the jzlib code // is included below. // // ------------------------------------------------------------------ // // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the distribution. // // 3. The names of the authors may not be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, // INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // ----------------------------------------------------------------------- // // This program is based on zlib-1.1.3; credit to authors // Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) // and contributors of zlib. // // ----------------------------------------------------------------------- using System; using Interop=System.Runtime.InteropServices; namespace Ionic.Zlib { /// <summary> /// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951). /// </summary> /// /// <remarks> /// This class compresses and decompresses data according to the Deflate algorithm /// and optionally, the ZLIB format, as documented in <see /// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950 - ZLIB</see> and <see /// href="http://www.ietf.org/rfc/rfc1951.txt">RFC 1951 - DEFLATE</see>. /// </remarks> #if !PCL [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000D")] [Interop.ComVisible(true)] #if !NETCF [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] #endif #endif internal sealed class ZlibCodec { /// <summary> /// The buffer from which data is taken. /// </summary> public byte[] InputBuffer; /// <summary> /// An index into the InputBuffer array, indicating where to start reading. /// </summary> public int NextIn; /// <summary> /// The number of bytes available in the InputBuffer, starting at NextIn. /// </summary> /// <remarks> /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. /// The class will update this number as calls to Inflate/Deflate are made. /// </remarks> public int AvailableBytesIn; /// <summary> /// Total number of bytes read so far, through all calls to Inflate()/Deflate(). /// </summary> public long TotalBytesIn; /// <summary> /// Buffer to store output data. /// </summary> public byte[] OutputBuffer; /// <summary> /// An index into the OutputBuffer array, indicating where to start writing. /// </summary> public int NextOut; /// <summary> /// The number of bytes available in the OutputBuffer, starting at NextOut. /// </summary> /// <remarks> /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. /// The class will update this number as calls to Inflate/Deflate are made. /// </remarks> public int AvailableBytesOut; /// <summary> /// Total number of bytes written to the output so far, through all calls to Inflate()/Deflate(). /// </summary> public long TotalBytesOut; /// <summary> /// used for diagnostics, when something goes wrong! /// </summary> public System.String Message; internal DeflateManager dstate; internal InflateManager istate; internal uint _Adler32; /// <summary> /// The compression level to use in this codec. Useful only in compression mode. /// </summary> public CompressionLevel CompressLevel = CompressionLevel.Default; /// <summary> /// The number of Window Bits to use. /// </summary> /// <remarks> /// This gauges the size of the sliding window, and hence the /// compression effectiveness as well as memory consumption. It's best to just leave this /// setting alone if you don't know what it is. The maximum value is 15 bits, which implies /// a 32k window. /// </remarks> public int WindowBits = ZlibConstants.WindowBitsDefault; /// <summary> /// The compression strategy to use. /// </summary> /// <remarks> /// This is only effective in compression. The theory offered by ZLIB is that different /// strategies could potentially produce significant differences in compression behavior /// for different data sets. Unfortunately I don't have any good recommendations for how /// to set it differently. When I tested changing the strategy I got minimally different /// compression performance. It's best to leave this property alone if you don't have a /// good feel for it. Or, you may want to produce a test harness that runs through the /// different strategy options and evaluates them on different file types. If you do that, /// let me know your results. /// </remarks> public CompressionStrategy Strategy = CompressionStrategy.Default; /// <summary> /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this. /// </summary> public int Adler32 { get { return (int)_Adler32; } } /// <summary> /// Create a ZlibCodec. /// </summary> /// <remarks> /// If you use this default constructor, you will later have to explicitly call /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress /// or decompress. /// </remarks> public ZlibCodec() { } /// <summary> /// Create a ZlibCodec that either compresses or decompresses. /// </summary> /// <param name="mode"> /// Indicates whether the codec should compress (deflate) or decompress (inflate). /// </param> public ZlibCodec(CompressionMode mode) { if (mode == CompressionMode.Compress) { int rc = InitializeDeflate(); if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for deflate."); } else if (mode == CompressionMode.Decompress) { int rc = InitializeInflate(); if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for inflate."); } else throw new ZlibException("Invalid ZlibStreamFlavor."); } /// <summary> /// Initialize the inflation state. /// </summary> /// <remarks> /// It is not necessary to call this before using the ZlibCodec to inflate data; /// It is implicitly called when you call the constructor. /// </remarks> /// <returns>Z_OK if everything goes well.</returns> public int InitializeInflate() { return InitializeInflate(this.WindowBits); } /// <summary> /// Initialize the inflation state with an explicit flag to /// govern the handling of RFC1950 header bytes. /// </summary> /// /// <remarks> /// By default, the ZLIB header defined in <see /// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950</see> is expected. If /// you want to read a zlib stream you should specify true for /// expectRfc1950Header. If you have a deflate stream, you will want to specify /// false. It is only necessary to invoke this initializer explicitly if you /// want to specify false. /// </remarks> /// /// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte /// pair when reading the stream of data to be inflated.</param> /// /// <returns>Z_OK if everything goes well.</returns> public int InitializeInflate(bool expectRfc1950Header) { return InitializeInflate(this.WindowBits, expectRfc1950Header); } /// <summary> /// Initialize the ZlibCodec for inflation, with the specified number of window bits. /// </summary> /// <param name="windowBits">The number of window bits to use. If you need to ask what that is, /// then you shouldn't be calling this initializer.</param> /// <returns>Z_OK if all goes well.</returns> public int InitializeInflate(int windowBits) { this.WindowBits = windowBits; return InitializeInflate(windowBits, true); } /// <summary> /// Initialize the inflation state with an explicit flag to govern the handling of /// RFC1950 header bytes. /// </summary> /// /// <remarks> /// If you want to read a zlib stream you should specify true for /// expectRfc1950Header. In this case, the library will expect to find a ZLIB /// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC /// 1950</see>, in the compressed stream. If you will be reading a DEFLATE or /// GZIP stream, which does not have such a header, you will want to specify /// false. /// </remarks> /// /// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte pair when reading /// the stream of data to be inflated.</param> /// <param name="windowBits">The number of window bits to use. If you need to ask what that is, /// then you shouldn't be calling this initializer.</param> /// <returns>Z_OK if everything goes well.</returns> public int InitializeInflate(int windowBits, bool expectRfc1950Header) { this.WindowBits = windowBits; if (dstate != null) throw new ZlibException("You may not call InitializeInflate() after calling InitializeDeflate()."); istate = new InflateManager(expectRfc1950Header); return istate.Initialize(this, windowBits); } /// <summary> /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer. /// </summary> /// <remarks> /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and /// AvailableBytesOut before calling this method. /// </remarks> /// <example> /// <code> /// private void InflateBuffer() /// { /// int bufferSize = 1024; /// byte[] buffer = new byte[bufferSize]; /// ZlibCodec decompressor = new ZlibCodec(); /// /// Console.WriteLine("\n============================================"); /// Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length); /// MemoryStream ms = new MemoryStream(DecompressedBytes); /// /// int rc = decompressor.InitializeInflate(); /// /// decompressor.InputBuffer = CompressedBytes; /// decompressor.NextIn = 0; /// decompressor.AvailableBytesIn = CompressedBytes.Length; /// /// decompressor.OutputBuffer = buffer; /// /// // pass 1: inflate /// do /// { /// decompressor.NextOut = 0; /// decompressor.AvailableBytesOut = buffer.Length; /// rc = decompressor.Inflate(FlushType.None); /// /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) /// throw new Exception("inflating: " + decompressor.Message); /// /// ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut); /// } /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); /// /// // pass 2: finish and flush /// do /// { /// decompressor.NextOut = 0; /// decompressor.AvailableBytesOut = buffer.Length; /// rc = decompressor.Inflate(FlushType.Finish); /// /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) /// throw new Exception("inflating: " + decompressor.Message); /// /// if (buffer.Length - decompressor.AvailableBytesOut > 0) /// ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut); /// } /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); /// /// decompressor.EndInflate(); /// } /// /// </code> /// </example> /// <param name="flush">The flush to use when inflating.</param> /// <returns>Z_OK if everything goes well.</returns> public int Inflate(FlushType flush) { if (istate == null) throw new ZlibException("No Inflate State!"); return istate.Inflate(flush); } /// <summary> /// Ends an inflation session. /// </summary> /// <remarks> /// Call this after successively calling Inflate(). This will cause all buffers to be flushed. /// After calling this you cannot call Inflate() without a intervening call to one of the /// InitializeInflate() overloads. /// </remarks> /// <returns>Z_OK if everything goes well.</returns> public int EndInflate() { if (istate == null) throw new ZlibException("No Inflate State!"); int ret = istate.End(); istate = null; return ret; } /// <summary> /// I don't know what this does! /// </summary> /// <returns>Z_OK if everything goes well.</returns> public int SyncInflate() { if (istate == null) throw new ZlibException("No Inflate State!"); return istate.Sync(); } /// <summary> /// Initialize the ZlibCodec for deflation operation. /// </summary> /// <remarks> /// The codec will use the MAX window bits and the default level of compression. /// </remarks> /// <example> /// <code> /// int bufferSize = 40000; /// byte[] CompressedBytes = new byte[bufferSize]; /// byte[] DecompressedBytes = new byte[bufferSize]; /// /// ZlibCodec compressor = new ZlibCodec(); /// /// compressor.InitializeDeflate(CompressionLevel.Default); /// /// compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress); /// compressor.NextIn = 0; /// compressor.AvailableBytesIn = compressor.InputBuffer.Length; /// /// compressor.OutputBuffer = CompressedBytes; /// compressor.NextOut = 0; /// compressor.AvailableBytesOut = CompressedBytes.Length; /// /// while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize) /// { /// compressor.Deflate(FlushType.None); /// } /// /// while (true) /// { /// int rc= compressor.Deflate(FlushType.Finish); /// if (rc == ZlibConstants.Z_STREAM_END) break; /// } /// /// compressor.EndDeflate(); /// /// </code> /// </example> /// <returns>Z_OK if all goes well. You generally don't need to check the return code.</returns> public int InitializeDeflate() { return _InternalInitializeDeflate(true); } /// <summary> /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel. /// </summary> /// <remarks> /// The codec will use the maximum window bits (15) and the specified /// CompressionLevel. It will emit a ZLIB stream as it compresses. /// </remarks> /// <param name="level">The compression level for the codec.</param> /// <returns>Z_OK if all goes well.</returns> public int InitializeDeflate(CompressionLevel level) { this.CompressLevel = level; return _InternalInitializeDeflate(true); } /// <summary> /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, /// and the explicit flag governing whether to emit an RFC1950 header byte pair. /// </summary> /// <remarks> /// The codec will use the maximum window bits (15) and the specified CompressionLevel. /// If you want to generate a zlib stream, you should specify true for /// wantRfc1950Header. In this case, the library will emit a ZLIB /// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC /// 1950</see>, in the compressed stream. /// </remarks> /// <param name="level">The compression level for the codec.</param> /// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param> /// <returns>Z_OK if all goes well.</returns> public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header) { this.CompressLevel = level; return _InternalInitializeDeflate(wantRfc1950Header); } /// <summary> /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, /// and the specified number of window bits. /// </summary> /// <remarks> /// The codec will use the specified number of window bits and the specified CompressionLevel. /// </remarks> /// <param name="level">The compression level for the codec.</param> /// <param name="bits">the number of window bits to use. If you don't know what this means, don't use this method.</param> /// <returns>Z_OK if all goes well.</returns> public int InitializeDeflate(CompressionLevel level, int bits) { this.CompressLevel = level; this.WindowBits = bits; return _InternalInitializeDeflate(true); } /// <summary> /// Initialize the ZlibCodec for deflation operation, using the specified /// CompressionLevel, the specified number of window bits, and the explicit flag /// governing whether to emit an RFC1950 header byte pair. /// </summary> /// /// <param name="level">The compression level for the codec.</param> /// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param> /// <param name="bits">the number of window bits to use. If you don't know what this means, don't use this method.</param>