// 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.ASCII;
            _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;
    }



}
