740 lines · 29.7 KB · C#
RawDownload
// DeflateStream.cs// ------------------------------------------------------------------//// Copyright (c) 2009-2010 Dino Chiesa.// 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: <2011-July-31 14:48:11>//// ------------------------------------------------------------------//// This module defines the DeflateStream class, which can be used as a replacement for// the System.IO.Compression.DeflateStream class in the .NET BCL.//// ------------------------------------------------------------------  using System; namespace Ionic.Zlib{    /// <summary>    /// A class for compressing and decompressing streams using the Deflate algorithm.    /// </summary>    ///    /// <remarks>    ///    /// <para>    ///   The DeflateStream is a <see    ///   href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a <see    ///   cref="System.IO.Stream"/>.  It adds DEFLATE compression or decompression to any    ///   stream.    /// </para>    ///    /// <para>    ///   Using this stream, applications can compress or decompress data via stream    ///   <c>Read</c> and <c>Write</c> operations.  Either compresssion or decompression    ///   can occur through either reading or writing. The compression format used is    ///   DEFLATE, which is documented in <see    ///   href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC 1951</see>, "DEFLATE    ///   Compressed Data Format Specification version 1.3.".    /// </para>    ///    /// <para>    ///   This class is similar to <see cref="ZlibStream"/>, except that    ///   <c>ZlibStream</c> adds the <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC    ///   1950 - ZLIB</see> framing bytes to a compressed stream when compressing, or    ///   expects the RFC1950 framing bytes when decompressing. The <c>DeflateStream</c>    ///   does not.    /// </para>    ///    /// </remarks>    ///    /// <seealso cref="ZlibStream" />    /// <seealso cref="GZipStream" />    internal class DeflateStream : System.IO.Stream    {        internal ZlibBaseStream _baseStream;        internal System.IO.Stream _innerStream;        bool _disposed;         /// <summary>        ///   Create a DeflateStream using the specified CompressionMode.        /// </summary>        ///        /// <remarks>        ///   When mode is <c>CompressionMode.Compress</c>, the DeflateStream will use        ///   the default compression level. The "captive" stream will be closed when        ///   the DeflateStream is closed.        /// </remarks>        ///        /// <example>        /// This example uses a DeflateStream to compress data from a file, and writes        /// the compressed data to another file.        /// <code>        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))        /// {        ///     using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))        ///     {        ///         using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress))        ///         {        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];        ///             int n;        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)        ///             {        ///                 compressor.Write(buffer, 0, n);        ///             }        ///         }        ///     }        /// }        /// </code>        ///        /// <code lang="VB">        /// Using input As Stream = File.OpenRead(fileToCompress)        ///     Using raw As FileStream = File.Create(fileToCompress &amp; ".deflated")        ///         Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress)        ///             Dim buffer As Byte() = New Byte(4096) {}        ///             Dim n As Integer = -1        ///             Do While (n &lt;&gt; 0)        ///                 If (n &gt; 0) Then        ///                     compressor.Write(buffer, 0, n)        ///                 End If        ///                 n = input.Read(buffer, 0, buffer.Length)        ///             Loop        ///         End Using        ///     End Using        /// End Using        /// </code>        /// </example>        /// <param name="stream">The stream which will be read or written.</param>        /// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param>        public DeflateStream(System.IO.Stream stream, CompressionMode mode)            : this(stream, mode, CompressionLevel.Default, false)        {        }         /// <summary>        /// Create a DeflateStream using the specified CompressionMode and the specified CompressionLevel.        /// </summary>        ///        /// <remarks>        ///        /// <para>        ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is        ///   ignored.  The "captive" stream will be closed when the DeflateStream is        ///   closed.        /// </para>        ///        /// </remarks>        ///        /// <example>        ///        ///   This example uses a DeflateStream to compress data from a file, and writes        ///   the compressed data to another file.        ///        /// <code>        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))        /// {        ///     using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))        ///     {        ///         using (Stream compressor = new DeflateStream(raw,        ///                                                      CompressionMode.Compress,        ///                                                      CompressionLevel.BestCompression))        ///         {        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];        ///             int n= -1;        ///             while (n != 0)        ///             {        ///                 if (n &gt; 0)        ///                     compressor.Write(buffer, 0, n);        ///                 n= input.Read(buffer, 0, buffer.Length);        ///             }        ///         }        ///     }        /// }        /// </code>        ///        /// <code lang="VB">        /// Using input As Stream = File.OpenRead(fileToCompress)        ///     Using raw As FileStream = File.Create(fileToCompress &amp; ".deflated")        ///         Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)        ///             Dim buffer As Byte() = New Byte(4096) {}        ///             Dim n As Integer = -1        ///             Do While (n &lt;&gt; 0)        ///                 If (n &gt; 0) Then        ///                     compressor.Write(buffer, 0, n)        ///                 End If        ///                 n = input.Read(buffer, 0, buffer.Length)        ///             Loop        ///         End Using        ///     End Using        /// End Using        /// </code>        /// </example>        /// <param name="stream">The stream to be read or written while deflating or inflating.</param>        /// <param name="mode">Indicates whether the <c>DeflateStream</c> will compress or decompress.</param>        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>        public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level)            : this(stream, mode, level, false)        {        }         /// <summary>        ///   Create a <c>DeflateStream</c> using the specified        ///   <c>CompressionMode</c>, and explicitly specify whether the        ///   stream should be left open after Deflation or Inflation.        /// </summary>        ///        /// <remarks>        ///        /// <para>        ///   This constructor allows the application to request that the captive stream        ///   remain open after the deflation or inflation occurs.  By default, after        ///   <c>Close()</c> is called on the stream, the captive stream is also        ///   closed. In some cases this is not desired, for example if the stream is a        ///   memory stream that will be re-read after compression.  Specify true for        ///   the <paramref name="leaveOpen"/> parameter to leave the stream open.        /// </para>        ///        /// <para>        ///   The <c>DeflateStream</c> will use the default compression level.        /// </para>        ///        /// <para>        ///   See the other overloads of this constructor for example code.        /// </para>        /// </remarks>        ///        /// <param name="stream">        ///   The stream which will be read or written. This is called the        ///   "captive" stream in other places in this documentation.        /// </param>        ///        /// <param name="mode">        ///   Indicates whether the <c>DeflateStream</c> will compress or decompress.        /// </param>        ///        /// <param name="leaveOpen">true if the application would like the stream to        /// remain open after inflation/deflation.</param>        public DeflateStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen)            : this(stream, mode, CompressionLevel.Default, leaveOpen)        {        }         /// <summary>        ///   Create a <c>DeflateStream</c> using the specified <c>CompressionMode</c>        ///   and the specified <c>CompressionLevel</c>, and explicitly specify whether        ///   the stream should be left open after Deflation or Inflation.        /// </summary>        ///        /// <remarks>        ///        /// <para>        ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is ignored.        /// </para>        ///        /// <para>        ///   This constructor allows the application to request that the captive stream        ///   remain open after the deflation or inflation occurs.  By default, after        ///   <c>Close()</c> is called on the stream, the captive stream is also        ///   closed. In some cases this is not desired, for example if the stream is a        ///   <see cref="System.IO.MemoryStream"/> that will be re-read after        ///   compression.  Specify true for the <paramref name="leaveOpen"/> parameter        ///   to leave the stream open.        /// </para>        ///        /// </remarks>        ///        /// <example>        ///        ///   This example shows how to use a <c>DeflateStream</c> to compress data from        ///   a file, and store the compressed data into another file.        ///        /// <code>        /// using (var output = System.IO.File.Create(fileToCompress + ".deflated"))        /// {        ///     using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))        ///     {        ///         using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true))        ///         {        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];        ///             int n= -1;        ///             while (n != 0)        ///             {        ///                 if (n &gt; 0)        ///                     compressor.Write(buffer, 0, n);        ///                 n= input.Read(buffer, 0, buffer.Length);        ///             }        ///         }        ///     }        ///     // can write additional data to the output stream here        /// }        /// </code>        ///        /// <code lang="VB">        /// Using output As FileStream = File.Create(fileToCompress &amp; ".deflated")        ///     Using input As Stream = File.OpenRead(fileToCompress)        ///         Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True)        ///             Dim buffer As Byte() = New Byte(4096) {}        ///             Dim n As Integer = -1        ///             Do While (n &lt;&gt; 0)        ///                 If (n &gt; 0) Then        ///                     compressor.Write(buffer, 0, n)        ///                 End If        ///                 n = input.Read(buffer, 0, buffer.Length)        ///             Loop        ///         End Using        ///     End Using        ///     ' can write additional data to the output stream here.        /// End Using        /// </code>        /// </example>        /// <param name="stream">The stream which will be read or written.</param>        /// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param>        /// <param name="leaveOpen">true if the application would like the stream to remain open after inflation/deflation.</param>        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>        public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)        {            _innerStream = stream;            _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen);        }         #region Zlib properties         /// <summary>        /// This property sets the flush behavior on the stream.        /// </summary>        /// <remarks> See the ZLIB documentation for the meaning of the flush behavior.        /// </remarks>        public virtual FlushType FlushMode        {            get { return (this._baseStream._flushMode); }            set            {                if (_disposed) throw new ObjectDisposedException("DeflateStream");                this._baseStream._flushMode = value;            }        }         /// <summary>        ///   The size of the working buffer for the compression codec.        /// </summary>        ///        /// <remarks>        /// <para>        ///   The working buffer is used for all stream operations.  The default size is        ///   1024 bytes.  The minimum size is 128 bytes. You may get better performance        ///   with a larger buffer.  Then again, you might not.  You would have to test        ///   it.        /// </para>        ///        /// <para>        ///   Set this before the first call to <c>Read()</c> or <c>Write()</c> on the        ///   stream. If you try to set it afterwards, it will throw.        /// </para>        /// </remarks>        public int BufferSize        {            get            {                return this._baseStream._bufferSize;            }            set            {                if (_disposed) throw new ObjectDisposedException("DeflateStream");                if (this._baseStream._workingBuffer != null)                    throw new ZlibException("The working buffer is already set.");                if (value < ZlibConstants.WorkingBufferSizeMin)                    throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin));                this._baseStream._bufferSize = value;            }        }         /// <summary>        ///   The ZLIB strategy to be used during compression.        /// </summary>        ///        /// <remarks>        ///   By tweaking this parameter, you may be able to optimize the compression for        ///   data with particular characteristics.        /// </remarks>        public CompressionStrategy Strategy        {            get            {                return this._baseStream.Strategy;            }            set            {            if (_disposed) throw new ObjectDisposedException("DeflateStream");                this._baseStream.Strategy = value;            }        }         /// <summary> Returns the total number of bytes input so far.</summary>        public virtual long TotalIn        {            get            {                return this._baseStream._z.TotalBytesIn;            }        }         /// <summary> Returns the total number of bytes output so far.</summary>        public virtual long TotalOut        {            get            {                return this._baseStream._z.TotalBytesOut;            }        }         #endregion         #region System.IO.Stream methods        /// <summary>        ///   Dispose the stream.        /// </summary>        /// <remarks>        ///   <para>        ///     This may or may not result in a <c>Close()</c> call on the captive        ///     stream.  See the constructors that have a <c>leaveOpen</c> parameter        ///     for more information.        ///   </para>        ///   <para>        ///     Application code won't call this code directly.  This method may be        ///     invoked in two distinct scenarios.  If disposing == true, the method        ///     has been called directly or indirectly by a user's code, for example        ///     via the public Dispose() method. In this case, both managed and        ///     unmanaged resources can be referenced and disposed.  If disposing ==        ///     false, the method has been called by the runtime from inside the        ///     object finalizer and this method should not reference other objects;        ///     in that case only unmanaged resources must be referenced or        ///     disposed.        ///   </para>        /// </remarks>        /// <param name="disposing">        ///   true if the Dispose method was invoked by user code.        /// </param>        protected override void Dispose(bool disposing)        {            try            {                if (!_disposed)                {                    if (disposing && (this._baseStream != null))                        this._baseStream.Dispose();                    _disposed = true;                }            }            finally            {                base.Dispose(disposing);            }        }           /// <summary>        /// Indicates whether the stream can be read.        /// </summary>        /// <remarks>        /// The return value depends on whether the captive stream supports reading.        /// </remarks>        public override bool CanRead        {            get            {                if (_disposed) throw new ObjectDisposedException("DeflateStream");                return _baseStream._stream.CanRead;            }        }         /// <summary>        /// Indicates whether the stream supports Seek operations.        /// </summary>        /// <remarks>        /// Always returns false.        /// </remarks>        public override bool CanSeek        {            get { return false; }        }          /// <summary>        /// Indicates whether the stream can be written.        /// </summary>        /// <remarks>        /// The return value depends on whether the captive stream supports writing.        /// </remarks>        public override bool CanWrite        {            get            {                if (_disposed) throw new ObjectDisposedException("DeflateStream");                return _baseStream._stream.CanWrite;            }        }         /// <summary>        /// Flush the stream.        /// </summary>        public override void Flush()        {            if (_disposed) throw new ObjectDisposedException("DeflateStream");            _baseStream.Flush();        }         /// <summary>

Lines 1–500 of 740.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t