// ZipInputStream.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:30>
//
// ------------------------------------------------------------------
//
// This module defines the ZipInputStream class, which is a stream metaphor for
// reading zip files.  This class does not depend on Ionic.Zip.ZipFile, but rather
// stands alongside it as an alternative "container" for ZipEntry, when reading zips.
//
// It adds one interesting method to the normal "stream" interface: GetNextEntry.
//
// ------------------------------------------------------------------
//

using System;
using System.Threading;
using System.Collections.Generic;
using System.IO;
using Ionic.Zip;
using OfficeOpenXml.Packaging.Ionic.Zip;
using OfficeOpenXml.Packaging.Ionic.Crc;

namespace  Ionic.Zip
{
    /// <summary>
    ///   Provides a stream metaphor for reading zip files.
    /// </summary>
    ///
    /// <remarks>
    /// <para>
    ///   This class provides an alternative programming model for reading zip files to
    ///   the one enabled by the <see cref="ZipFile"/> class.  Use this when reading zip
    ///   files, as an alternative to the <see cref="ZipFile"/> class, when you would
    ///   like to use a Stream class to read the file.
    /// </para>
    ///
    /// <para>
    ///   Some application designs require a readable stream for input. This stream can
    ///   be used to read a zip file, and extract entries.
    /// </para>
    ///
    /// <para>
    ///   Both the <c>ZipInputStream</c> class and the <c>ZipFile</c> class can be used
    ///   to read and extract zip files.  Both of them support many of the common zip
    ///   features, including Unicode, different compression levels, and ZIP64.  The
    ///   programming models differ. For example, when extracting entries via calls to
    ///   the <c>GetNextEntry()</c> and <c>Read()</c> methods on the
    ///   <c>ZipInputStream</c> class, the caller is responsible for creating the file,
    ///   writing the bytes into the file, setting the attributes on the file, and
    ///   setting the created, last modified, and last accessed timestamps on the
    ///   file. All of these things are done automatically by a call to <see
    ///   cref="ZipEntry.Extract()">ZipEntry.Extract()</see>.  For this reason, the
    ///   <c>ZipInputStream</c> is generally recommended for when your application wants
    ///   to extract the data, without storing that data into a file.
    /// </para>
    ///
    /// <para>
    ///   Aside from the obvious differences in programming model, there are some
    ///   differences in capability between the <c>ZipFile</c> class and the
    ///   <c>ZipInputStream</c> class.
    /// </para>
    ///
    /// <list type="bullet">
    ///   <item>
    ///     <c>ZipFile</c> can be used to create or update zip files, or read and
    ///     extract zip files. <c>ZipInputStream</c> can be used only to read and
    ///     extract zip files. If you want to use a stream to create zip files, check
    ///     out the <see cref="ZipOutputStream"/>.
    ///   </item>
    ///
    ///   <item>
    ///     <c>ZipInputStream</c> cannot read segmented or spanned
    ///     zip files.
    ///   </item>
    ///
    ///   <item>
    ///     <c>ZipInputStream</c> will not read Zip file comments.
    ///   </item>
    ///
    ///   <item>
    ///     When reading larger files, <c>ZipInputStream</c> will always underperform
    ///     <c>ZipFile</c>. This is because the <c>ZipInputStream</c> does a full scan on the
    ///     zip file, while the <c>ZipFile</c> class reads the central directory of the
    ///     zip file.
    ///   </item>
    ///
    /// </list>
    ///
    /// </remarks>
    internal class ZipInputStream : Stream
    {
        /// <summary>
        ///   Create a <c>ZipInputStream</c>, wrapping it around an existing stream.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        ///   While the <see cref="ZipFile"/> class is generally easier
        ///   to use, this class provides an alternative to those
        ///   applications that want to read from a zipfile directly,
        ///   using a <see cref="System.IO.Stream"/>.
        /// </para>
        ///
        /// <para>
        ///   Both the <c>ZipInputStream</c> class and the <c>ZipFile</c> class can be used
        ///   to read and extract zip files.  Both of them support many of the common zip
        ///   features, including Unicode, different compression levels, and ZIP64.  The
        ///   programming models differ. For example, when extracting entries via calls to
        ///   the <c>GetNextEntry()</c> and <c>Read()</c> methods on the
        ///   <c>ZipInputStream</c> class, the caller is responsible for creating the file,
        ///   writing the bytes into the file, setting the attributes on the file, and
        ///   setting the created, last modified, and last accessed timestamps on the
        ///   file. All of these things are done automatically by a call to <see
        ///   cref="ZipEntry.Extract()">ZipEntry.Extract()</see>.  For this reason, the
        ///   <c>ZipInputStream</c> is generally recommended for when your application wants
        ///   to extract the data, without storing that data into a file.
        /// </para>
        ///
        /// <para>
        ///   Aside from the obvious differences in programming model, there are some
        ///   differences in capability between the <c>ZipFile</c> class and the
        ///   <c>ZipInputStream</c> class.
        /// </para>
        ///
        /// <list type="bullet">
        ///   <item>
        ///   <c>ZipFile</c> can be used to create or update zip files, or read and extract
        ///   zip files. <c>ZipInputStream</c> can be used only to read and extract zip
        ///     files. If you want to use a stream to create zip files, check out the <see
        ///     cref="ZipOutputStream"/>.
        ///   </item>
        ///
        ///   <item>
        ///     <c>ZipInputStream</c> cannot read segmented or spanned
        ///     zip files.
        ///   </item>
        ///
        ///   <item>
        ///     <c>ZipInputStream</c> will not read Zip file comments.
        ///   </item>
        ///
        ///   <item>
        ///     When reading larger files, <c>ZipInputStream</c> will always underperform
        ///     <c>ZipFile</c>. This is because the <c>ZipInputStream</c> does a full scan on the
        ///     zip file, while the <c>ZipFile</c> class reads the central directory of the
        ///     zip file.
        ///   </item>
        ///
        /// </list>
        ///
        /// </remarks>
        ///
        /// <param name="stream">
        ///   The stream to read. It must be readable. This stream will be closed at
        ///   the time the <c>ZipInputStream</c> is closed.
        /// </param>
        ///
        /// <example>
        ///
        ///   This example shows how to read a zip file, and extract entries, using the
        ///   <c>ZipInputStream</c> class.
        ///
        /// <code lang="C#">
        /// private void Unzip()
        /// {
        ///     byte[] buffer= new byte[2048];
        ///     int n;
        ///     using (var raw = File.Open(inputFileName, FileMode.Open, FileAccess.Read))
        ///     {
        ///         using (var input= new ZipInputStream(raw))
        ///         {
        ///             ZipEntry e;
        ///             while (( e = input.GetNextEntry()) != null)
        ///             {
        ///                 if (e.IsDirectory) continue;
        ///                 string outputPath = Path.Combine(extractDir, e.FileName);
        ///                 using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
        ///                 {
        ///                     while ((n= input.Read(buffer, 0, buffer.Length)) > 0)
        ///                     {
        ///                         output.Write(buffer,0,n);
        ///                     }
        ///                 }
        ///             }
        ///         }
        ///     }
        /// }
        /// </code>
        ///
        /// <code lang="VB">
        /// Private Sub UnZip()
        ///     Dim inputFileName As String = "MyArchive.zip"
        ///     Dim extractDir As String = "extract"
        ///     Dim buffer As Byte() = New Byte(2048) {}
        ///     Using raw As FileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read)
        ///         Using input As ZipInputStream = New ZipInputStream(raw)
        ///             Dim e As ZipEntry
        ///             Do While (Not e = input.GetNextEntry Is Nothing)
        ///                 If Not e.IsDirectory Then
        ///                     Using output As FileStream = File.Open(Path.Combine(extractDir, e.FileName), _
        ///                                                            FileMode.Create, FileAccess.ReadWrite)
        ///                         Dim n As Integer
        ///                         Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
        ///                             output.Write(buffer, 0, n)
        ///                         Loop
        ///                     End Using
        ///                 End If
        ///             Loop
        ///         End Using
        ///     End Using
        /// End Sub
        /// </code>
        /// </example>
        public ZipInputStream(Stream stream)  : this (stream, false) { }



        /// <summary>
        ///   Create a <c>ZipInputStream</c>, given the name of an existing zip file.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        ///   This constructor opens a <c>FileStream</c> for the given zipfile, and
        ///   wraps a <c>ZipInputStream</c> around that.  See the documentation for the
        ///   <see cref="ZipInputStream(Stream)"/> constructor for full details.
        /// </para>
        ///
        /// <para>
        ///   While the <see cref="ZipFile"/> class is generally easier
        ///   to use, this class provides an alternative to those
        ///   applications that want to read from a zipfile directly,
        ///   using a <see cref="System.IO.Stream"/>.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <param name="fileName">
        ///   The name of the filesystem file to read.
        /// </param>
        ///
        /// <example>
        ///
        ///   This example shows how to read a zip file, and extract entries, using the
        ///   <c>ZipInputStream</c> class.
        ///
        /// <code lang="C#">
        /// private void Unzip()
        /// {
        ///     byte[] buffer= new byte[2048];
        ///     int n;
        ///     using (var input= new ZipInputStream(inputFileName))
        ///     {
        ///         ZipEntry e;
        ///         while (( e = input.GetNextEntry()) != null)
        ///         {
        ///             if (e.IsDirectory) continue;
        ///             string outputPath = Path.Combine(extractDir, e.FileName);
        ///             using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
        ///             {
        ///                 while ((n= input.Read(buffer, 0, buffer.Length)) > 0)
        ///                 {
        ///                     output.Write(buffer,0,n);
        ///                 }
        ///             }
        ///         }
        ///     }
        /// }
        /// </code>
        ///
        /// <code lang="VB">
        /// Private Sub UnZip()
        ///     Dim inputFileName As String = "MyArchive.zip"
        ///     Dim extractDir As String = "extract"
        ///     Dim buffer As Byte() = New Byte(2048) {}
        ///     Using input As ZipInputStream = New ZipInputStream(inputFileName)
        ///         Dim e As ZipEntry
        ///         Do While (Not e = input.GetNextEntry Is Nothing)
        ///             If Not e.IsDirectory Then
        ///                 Using output As FileStream = File.Open(Path.Combine(extractDir, e.FileName), _
        ///                                                        FileMode.Create, FileAccess.ReadWrite)
        ///                     Dim n As Integer
        ///                     Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
        ///                         output.Write(buffer, 0, n)
        ///                     Loop
        ///                 End Using
        ///             End If
        ///         Loop
        ///     End Using
        /// End Sub
        /// </code>
        /// </example>
        public ZipInputStream(String fileName)
        {
            Stream stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read );
            _Init(stream, false, fileName);
        }


        /// <summary>
        ///   Create a <c>ZipInputStream</c>, explicitly specifying whether to
        ///   keep the underlying stream open.
        /// </summary>
        ///
        /// <remarks>
        ///   See the documentation for the <see
        ///   cref="ZipInputStream(Stream)">ZipInputStream(Stream)</see>
        ///   constructor for a discussion of the class, and an example of how to use the class.
        /// </remarks>
        ///
        /// <param name="stream">
        ///   The stream to read from. It must be readable.
        /// </param>
        ///
        /// <param name="leaveOpen">
        ///   true if the application would like the stream
        ///   to remain open after the <c>ZipInputStream</c> has been closed.
        /// </param>
        public ZipInputStream(Stream stream, bool leaveOpen)
        {
            _Init(stream, leaveOpen, null);
        }

        private void _Init(Stream stream, bool leaveOpen, string name)
        {
            _inputStream = stream;
            if (!_inputStream.CanRead)
                throw new ZipException("The stream must be readable.");
            _container= new ZipContainer(this);
            _provisionalAlternateEncoding = System.Text.Encoding.GetEncoding("IBM437");
            _leaveUnderlyingStreamOpen = leaveOpen;
            _findRequired= true;
            _name = name ?? "(stream)";
        }


        /// <summary>Provides a string representation of the instance.</summary>
        /// <remarks>
        ///   <para>
        ///     This can be useful for debugging purposes.
        ///   </para>
        /// </remarks>
        /// <returns>a string representation of the instance.</returns>
        public override String ToString()
        {
            return String.Format ("ZipInputStream::{0}(leaveOpen({1})))", _name, _leaveUnderlyingStreamOpen);
        }


        /// <summary>
        ///   The text encoding to use when reading entries into the zip archive, for
        ///   those entries whose filenames or comments cannot be encoded with the
        ///   default (IBM437) encoding.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   In <see href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">its
        ///   zip specification</see>, PKWare describes two options for encoding
        ///   filenames and comments: using IBM437 or UTF-8.  But, some archiving tools
        ///   or libraries do not follow the specification, and instead encode
        ///   characters using the system default code page.  For example, WinRAR when
        ///   run on a machine in Shanghai may encode filenames with the Big-5 Chinese
        ///   (950) code page.  This behavior is contrary to the Zip specification, but
        ///   it occurs anyway.
        /// </para>
        ///
        /// <para>
        ///   When using DotNetZip to read zip archives that use something other than
        ///   UTF-8 or IBM437, set this property to specify the code page to use when
        ///   reading encoded filenames and comments for each <c>ZipEntry</c> in the zip
        ///   file.
        /// </para>
        ///
        /// <para>
        ///   This property is "provisional". When the entry in the zip archive is not
        ///   explicitly marked as using UTF-8, then IBM437 is used to decode filenames
        ///   and comments. If a loss of data would result from using IBM436 -
        ///   specifically when encoding and decoding is not reflexive - the codepage
        ///   specified here is used. It is possible, therefore, to have a given entry
        ///   with a <c>Comment</c> encoded in IBM437 and a <c>FileName</c> encoded with
        ///   the specified "provisional" codepage.
        /// </para>
        ///
        /// <para>
        ///   When a zip file uses an arbitrary, non-UTF8 code page for encoding, there
        ///   is no standard way for the reader application - whether DotNetZip, WinZip,
        ///   WinRar, or something else - to know which codepage has been used for the
        ///   entries. Readers of zip files are not able to inspect the zip file and
        ///   determine the codepage that was used for the entries contained within it.
        ///   It is left to the application or user to determine the necessary codepage
        ///   when reading zip files encoded this way.  If you use an incorrect codepage
        ///   when reading a zipfile, you will get entries with filenames that are
        ///   incorrect, and the incorrect filenames may even contain characters that
        ///   are not legal for use within filenames in Windows. Extracting entries with
        ///   illegal characters in the filenames will lead to exceptions. It's too bad,
        ///   but this is just the way things are with code pages in zip files. Caveat
        ///   Emptor.
        /// </para>
        ///
        /// </remarks>
        public System.Text.Encoding ProvisionalAlternateEncoding
        {
            get
            {
                return _provisionalAlternateEncoding;
            }
            set
            {
                _provisionalAlternateEncoding = value;
            }
        }


        /// <summary>
        ///   Size of the work buffer to use for the ZLIB codec during decompression.
        /// </summary>
        ///
        /// <remarks>
        ///   Setting this affects the performance and memory efficiency of compression
        ///   and decompression.  For larger files, setting this to a larger size may
        ///   improve performance, but the exact numbers vary depending on available
        ///   memory, and a bunch of other variables. I don't have good firm
        ///   recommendations on how to set it.  You'll have to test it yourself. Or
        ///   just leave it alone and accept the default.
        /// </remarks>
        public int CodecBufferSize
        {
            get;
            set;
        }


        /// <summary>
        ///   Sets the password to be used on the <c>ZipInputStream</c> instance.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        ///   When reading a zip archive, this password is used to read and decrypt the
        ///   entries that are encrypted within the zip file. When entries within a zip
        ///   file use different passwords, set the appropriate password for the entry
        ///   before the first call to <c>Read()</c> for each entry.
        /// </para>
        ///
        /// <para>
        ///   When reading an entry that is not encrypted, the value of this property is
        ///   ignored.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <example>
        ///
        ///   This example uses the ZipInputStream to read and extract entries from a
        ///   zip file, using a potentially different password for each entry.
        ///
        /// <code lang="C#">
        /// byte[] buffer= new byte[2048];
        /// int n;
        /// using (var raw = File.Open(_inputFileName, FileMode.Open, FileAccess.Read ))
        /// {
        ///     using (var input= new ZipInputStream(raw))
        ///     {
        ///         ZipEntry e;
        ///         while (( e = input.GetNextEntry()) != null)
        ///         {
        ///             input.Password = PasswordForEntry(e.FileName);
        ///             if (e.IsDirectory) continue;
        ///             string outputPath = Path.Combine(_extractDir, e.FileName);
        ///             using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
        ///             {
        ///                 while ((n= input.Read(buffer,0,buffer.Length)) > 0)
        ///                 {
        ///                     output.Write(buffer,0,n);
        ///                 }
        ///             }
        ///         }
        ///     }
        /// }
        ///
        /// </code>
        /// </example>
        public String Password
        {
            set
            {
                if (_closed)
                {
                    _exceptionPending = true;
                    throw new System.InvalidOperationException("The stream has been closed.");
                }
                _Password = value;
            }
        }


        private void SetupStream()
        {
            // Seek to the correct posn in the file, and open a
            // stream that can be read.
            _crcStream= _currentEntry.InternalOpenReader(_Password);
            _LeftToRead = _crcStream.Length;
            _needSetup = false;
        }



        internal Stream ReadStream
        {
            get
            {
                return _inputStream;
            }
        }


        /// <summary>
        ///   Read the data from the stream into the buffer.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   The data for the zipentry will be decrypted and uncompressed, as
        ///   necessary, before being copied into the buffer.
        /// </para>
        ///
        /// <para>
        ///   You must set the <see cref="Password"/> property before calling
        ///   <c>Read()</c> the first time for an encrypted entry.  To determine if an
        ///   entry is encrypted and requires a password, check the <see
        ///   cref="ZipEntry.Encryption">ZipEntry.Encryption</see> property.
        /// </para>
        /// </remarks>
        ///
        /// <param name="buffer">The buffer to hold the data read from the stream.</param>
        /// <param name="offset">the offset within the buffer to copy the first byte read.</param>
        /// <param name="count">the number of bytes to read.</param>
        /// <returns>the number of bytes read, after decryption and decompression.</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (_closed)
            {
                _exceptionPending = true;
                throw new System.InvalidOperationException("The stream has been closed.");
            }

            if (_needSetup)
                SetupStream();

            if (_LeftToRead == 0) return 0;

            int len = (_LeftToRead > count) ? count : (int)_LeftToRead;
            int n = _crcStream.Read(buffer, offset, len);

            _LeftToRead -= n;

            if (_LeftToRead == 0)
            {
                int CrcResult = _crcStream.Crc;
                _currentEntry.VerifyCrcAfterExtract(CrcResult);
                _inputStream.Seek(_endOfEntry, SeekOrigin.Begin);
                // workitem 10178
                SharedUtilities.Workaround_Ladybug318918(_inputStream);
            }

            return n;
        }



        /// <summary>
        ///   Read the next entry from the zip file.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   Call this method just before calling <see cref="Read(byte[], int, int)"/>,
        ///   to position the pointer in the zip file to the next entry that can be
        ///   read.  Subsequent calls to <c>Read()</c>, will decrypt and decompress the
        ///   data in the zip file, until <c>Read()</c> returns 0.
        /// </para>
        ///
        /// <para>
        ///   Each time you call <c>GetNextEntry()</c>, the pointer in the wrapped
        ///   stream is moved to the next entry in the zip file.  If you call <see
        ///   cref="Seek(long, SeekOrigin)"/>, and thus re-position the pointer within
        ///   the file, you will need to call <c>GetNextEntry()</c> again, to insure
        ///   that the file pointer is positioned at the beginning of a zip entry.
        /// </para>
        ///
        /// <para>
        ///   This method returns the <c>ZipEntry</c>. Using a stream approach, you will
        ///   read the raw bytes for an entry in a zip file via calls to <c>Read()</c>.
        ///   Alternatively, you can extract an entry into a file, or a stream, by
        ///   calling <see cref="ZipEntry.Extract()"/>, or one of its siblings.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <returns>
        ///   The <c>ZipEntry</c> read. Returns null (or Nothing in VB) if there are no more
        ///   entries in the zip file.
        /// </returns>
        ///
        public ZipEntry GetNextEntry()
        {
            if (_findRequired)
            {
                // find the next signature
                long d = SharedUtilities.FindSignature(_inputStream, ZipConstants.ZipEntrySignature);
                if (d == -1) return null;
                // back up 4 bytes: ReadEntry assumes the file pointer is positioned before the entry signature
                _inputStream.Seek(-4, SeekOrigin.Current);
                // workitem 10178
                SharedUtilities.Workaround_Ladybug318918(_inputStream);
            }
            // workitem 10923
            else if (_firstEntry)
            {
                // we've already read one entry.
                // Seek to the end of it.
                _inputStream.Seek(_endOfEntry, SeekOrigin.Begin);
                SharedUtilities.Workaround_Ladybug318918(_inputStream);
            }

            _currentEntry = ZipEntry.ReadEntry(_container, !_firstEntry);
            // ReadEntry leaves the file position after all the entry
            // data and the optional bit-3 data descriptpr.  This is
            // where the next entry would normally start.
            _endOfEntry = _inputStream.Position;
            _firstEntry = true;
            _needSetup = true;
            _findRequired= false;
            return _currentEntry;
        }


        /// <summary>
        ///   Dispose the stream.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This method disposes the ZipInputStream.  It may also close the
        ///   underlying stream, depending on which constructor was used.
        /// </para>
        ///
        /// <para>
        ///   Typically the application will call <c>Dispose()</c> implicitly, via
        ///   a <c>using</c> statement in C#, or a <c>Using</c> statement in VB.
        /// </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)
        {
            if (_closed) return;

            if (disposing) // not called from finalizer
            {
                // When ZipInputStream is used within a using clause, and an
                // exception is thrown, Close() is invoked.  But we don't want to
                // try to write anything in that case.  Eventually the exception
                // will be propagated to the application.
                if (_exceptionPending) return;

                if (!_leaveUnderlyingStreamOpen)
                {
#if NETCF
                    _inputStream.Close();
#else
                    _inputStream.Dispose();
#endif
                }
            }
            _closed= true;
        }


        /// <summary>
        /// Always returns true.
        /// </summary>
        public override bool CanRead  { get { return true; }}

        /// <summary>
        /// Returns the value of <c>CanSeek</c> for the underlying (wrapped) stream.
        /// </summary>
        public override bool CanSeek  { get { return _inputStream.CanSeek; } }

        /// <summary>
        /// Always returns false.
        /// </summary>
        public override bool CanWrite { get { return false; } }

        /// <summary>
        /// Returns the length of the underlying stream.
        /// </summary>
        public override long Length   { get { return _inputStream.Length; }}

        /// <summary>
        /// Gets or sets the position of the underlying stream.
        /// </summary>
        /// <remarks>
        /// Setting the position is equivalent to calling <c>Seek(value, SeekOrigin.Begin)</c>.
        /// </remarks>
        public override long Position
        {
            get { return _inputStream.Position;}
            set { Seek(value, SeekOrigin.Begin); }
        }

        /// <summary>
        /// This is a no-op.
        /// </summary>
        public override void Flush()
        {
            throw new NotSupportedException("Flush");
        }


        /// <summary>
        /// This method always throws a NotSupportedException.
        /// </summary>
        /// <param name="buffer">ignored</param>
        /// <param name="offset">ignored</param>
        /// <param name="count">ignored</param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            throw new NotSupportedException("Write");
        }


        /// <summary>
        ///   This method seeks in the underlying stream.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   Call this method if you want to seek around within the zip file for random access.
        /// </para>
        ///
        /// <para>
        ///   Applications can intermix calls to <c>Seek()</c> with calls to <see
        ///   cref="GetNextEntry()"/>.  After a call to <c>Seek()</c>,
        ///   <c>GetNextEntry()</c> will get the next <c>ZipEntry</c> that falls after
        ///   the current position in the input stream. You're on your own for finding
        ///   out just where to seek in the stream, to get to the various entries.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <param name="offset">the offset point to seek to</param>
        /// <param name="origin">the reference point from which to seek</param>
        /// <returns>The new position</returns>
        public override long Seek(long offset, SeekOrigin origin)
        {
            _findRequired= true;
            var x = _inputStream.Seek(offset, origin);
            // workitem 10178
            SharedUtilities.Workaround_Ladybug318918(_inputStream);
            return x;
        }

        /// <summary>
        /// This method always throws a NotSupportedException.
        /// </summary>
        /// <param name="value">ignored</param>
        public override void SetLength(long value)
        {
            throw new NotSupportedException();
        }


        private Stream _inputStream;
        private System.Text.Encoding _provisionalAlternateEncoding;
        private ZipEntry _currentEntry;
        private bool _firstEntry;
        private bool _needSetup;
        private ZipContainer _container;
        private CrcCalculatorStream _crcStream;
        private Int64 _LeftToRead;
        internal String _Password;
        private Int64 _endOfEntry;
        private string _name;

        private bool _leaveUnderlyingStreamOpen;
        private bool _closed;
        private bool _findRequired;
        private bool _exceptionPending;
    }



}