123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- // ZlibStream.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: <2010-January-29 16:35:23>
- //
- // ------------------------------------------------------------------
- //
- // This module defines the ZlibStream class, which is similar in idea to
- // the System.IO.Compression.DeflateStream and
- // System.IO.Compression.GZipStream classes in the .NET BCL.
- //
- // ------------------------------------------------------------------
- using System;
- using System.IO;
- using System.Text;
- namespace SharpCompress.Compressors.Deflate
- {
- public class ZlibStream : Stream
- {
- private readonly ZlibBaseStream _baseStream;
- private bool _disposed;
- public ZlibStream(Stream stream, CompressionMode mode)
- : this(stream, mode, CompressionLevel.Default, Encoding.UTF8)
- {
- }
- public ZlibStream(Stream stream, CompressionMode mode, CompressionLevel level)
- : this(stream, mode, level, Encoding.UTF8)
- {
- }
- public ZlibStream(Stream stream, CompressionMode mode, CompressionLevel level, Encoding encoding)
- {
- _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.ZLIB, encoding);
- }
- #region Zlib properties
- /// <summary>
- /// This property sets the flush behavior on the stream.
- /// Sorry, though, not sure exactly how to describe all the various settings.
- /// </summary>
- public virtual FlushType FlushMode
- {
- get => (_baseStream._flushMode);
- set
- {
- if (_disposed)
- {
- throw new ObjectDisposedException("ZlibStream");
- }
- _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 => _baseStream._bufferSize;
- set
- {
- if (_disposed)
- {
- throw new ObjectDisposedException("ZlibStream");
- }
- if (_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));
- }
- _baseStream._bufferSize = value;
- }
- }
- /// <summary> Returns the total number of bytes input so far.</summary>
- public virtual long TotalIn => _baseStream._z.TotalBytesIn;
- /// <summary> Returns the total number of bytes output so far.</summary>
- public virtual long TotalOut => _baseStream._z.TotalBytesOut;
- #endregion
- #region System.IO.Stream methods
- /// <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("ZlibStream");
- }
- return _baseStream._stream.CanRead;
- }
- }
- /// <summary>
- /// Indicates whether the stream supports Seek operations.
- /// </summary>
- /// <remarks>
- /// Always returns false.
- /// </remarks>
- public override bool CanSeek => 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("ZlibStream");
- }
- return _baseStream._stream.CanWrite;
- }
- }
- /// <summary>
- /// Reading this property always throws a <see cref="NotImplementedException"/>.
- /// </summary>
- public override long Length => throw new NotSupportedException();
- /// <summary>
- /// The position of the stream pointer.
- /// </summary>
- ///
- /// <remarks>
- /// Setting this property always throws a <see
- /// cref="NotImplementedException"/>. Reading will return the total bytes
- /// written out, if used in writing, or the total bytes read in, if used in
- /// reading. The count may refer to compressed bytes or uncompressed bytes,
- /// depending on how you've used the stream.
- /// </remarks>
- public override long Position
- {
- get
- {
- if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
- {
- return _baseStream._z.TotalBytesOut;
- }
- if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
- {
- return _baseStream._z.TotalBytesIn;
- }
- return 0;
- }
- set => throw new NotSupportedException();
- }
- /// <summary>
- /// Dispose the stream.
- /// </summary>
- /// <remarks>
- /// This may or may not result in a <c>Close()</c> call on the captive stream.
- /// </remarks>
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (!_disposed)
- {
- if (disposing)
- {
- _baseStream?.Dispose();
- }
- _disposed = true;
- }
- }
- finally
- {
- base.Dispose(disposing);
- }
- }
- /// <summary>
- /// Flush the stream.
- /// </summary>
- public override void Flush()
- {
- if (_disposed)
- {
- throw new ObjectDisposedException("ZlibStream");
- }
- _baseStream.Flush();
- }
- /// <summary>
- /// Read data from the stream.
- /// </summary>
- ///
- /// <remarks>
- ///
- /// <para>
- /// If you wish to use the <c>ZlibStream</c> to compress data while reading,
- /// you can create a <c>ZlibStream</c> with <c>CompressionMode.Compress</c>,
- /// providing an uncompressed data stream. Then call <c>Read()</c> on that
- /// <c>ZlibStream</c>, and the data read will be compressed. If you wish to
- /// use the <c>ZlibStream</c> to decompress data while reading, you can create
- /// a <c>ZlibStream</c> with <c>CompressionMode.Decompress</c>, providing a
- /// readable compressed data stream. Then call <c>Read()</c> on that
- /// <c>ZlibStream</c>, and the data will be decompressed as it is read.
- /// </para>
- ///
- /// <para>
- /// A <c>ZlibStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but
- /// not both.
- /// </para>
- ///
- /// </remarks>
- /// <param name="buffer">The buffer into which the read data should be placed.</param>
- /// <param name="offset">the offset within that data array to put the first byte read.</param>
- /// <param name="count">the number of bytes to read.</param>
- public override int Read(byte[] buffer, int offset, int count)
- {
- if (_disposed)
- {
- throw new ObjectDisposedException("ZlibStream");
- }
- return _baseStream.Read(buffer, offset, count);
- }
- public override int ReadByte()
- {
- if (_disposed)
- {
- throw new ObjectDisposedException("ZlibStream");
- }
- return _baseStream.ReadByte();
- }
- /// <summary>
- /// Calling this method always throws a <see cref="NotImplementedException"/>.
- /// </summary>
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
- /// <summary>
- /// Calling this method always throws a <see cref="NotImplementedException"/>.
- /// </summary>
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
- /// <summary>
- /// Write data to the stream.
- /// </summary>
- ///
- /// <remarks>
- ///
- /// <para>
- /// If you wish to use the <c>ZlibStream</c> to compress data while writing,
- /// you can create a <c>ZlibStream</c> with <c>CompressionMode.Compress</c>,
- /// and a writable output stream. Then call <c>Write()</c> on that
- /// <c>ZlibStream</c>, providing uncompressed data as input. The data sent to
- /// the output stream will be the compressed form of the data written. If you
- /// wish to use the <c>ZlibStream</c> to decompress data while writing, you
- /// can create a <c>ZlibStream</c> with <c>CompressionMode.Decompress</c>, and a
- /// writable output stream. Then call <c>Write()</c> on that stream,
- /// providing previously compressed data. The data sent to the output stream
- /// will be the decompressed form of the data written.
- /// </para>
- ///
- /// <para>
- /// A <c>ZlibStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not both.
- /// </para>
- /// </remarks>
- /// <param name="buffer">The buffer holding data to write to the stream.</param>
- /// <param name="offset">the offset within that data array to find the first byte to write.</param>
- /// <param name="count">the number of bytes to write.</param>
- public override void Write(byte[] buffer, int offset, int count)
- {
- if (_disposed)
- {
- throw new ObjectDisposedException("ZlibStream");
- }
- _baseStream.Write(buffer, offset, count);
- }
- public override void WriteByte(byte value)
- {
- if (_disposed)
- {
- throw new ObjectDisposedException("ZlibStream");
- }
- _baseStream.WriteByte(value);
- }
- #endregion System.IO.Stream methods
- }
- }
|