ConvertToString() public static method

Convert a byte array to string
public static ConvertToString ( byte data ) : string
data byte /// Byte array to convert ///
return string
Example #1
0
 public static string ConvertToString(byte[] data)
 {
     if (data == null)
     {
         return(string.Empty);
     }
     return(ZipConstants.ConvertToString(data, data.Length));
 }
Example #2
0
 public static string ConvertToStringExt(int flags, byte[] data)
 {
     if (data == null)
     {
         return(string.Empty);
     }
     if ((flags & 2048) != 0)
     {
         return(Encoding.UTF8.GetString(data, 0, data.Length));
     }
     return(ZipConstants.ConvertToString(data, data.Length));
 }
Example #3
0
 public static string ConvertToStringExt(int flags, byte[] data, int count)
 {
     if (data == null)
     {
         return(string.Empty);
     }
     if ((flags & 2048) != 0)
     {
         return(UnitySerializer.TextEncoding.GetString(data, 0, count));
     }
     return(ZipConstants.ConvertToString(data, count));
 }
Example #4
0
        /// <summary>
        /// Search for and read the central directory of a zip file filling the entries
        /// array.  This is called exactly once by the constructors.
        /// </summary>
        /// <exception cref="System.IO.IOException">
        /// An i/o error occurs.
        /// </exception>
        /// <exception cref="ICSharpCode.SharpZipLib.Zip.ZipException">
        /// The central directory is malformed or cannot be found
        /// </exception>
        void ReadEntries()
        {
            // Search for the End Of Central Directory.  When a zip comment is
            // present the directory may start earlier.
            //
            // TODO: The search is limited to 64K which is the maximum size of a trailing comment field to aid speed.
            // This should be compatible with both SFX and ZIP files but has only been tested for Zip files
            // Need to confirm this is valid in all cases.
            // Could also speed this up by reading memory in larger blocks.

            if (baseStream.CanSeek == false)
            {
                throw new ZipException("ZipFile stream must be seekable");
            }

            long locatedCentralDirOffset = LocateBlockWithSignature(ZipConstants.ENDSIG, baseStream.Length, ZipConstants.ENDHDR, 0xffff);

            if (locatedCentralDirOffset < 0)
            {
                throw new ZipException("Cannot find central directory");
            }

            int thisDiskNumber            = ReadLeShort();
            int startCentralDirDisk       = ReadLeShort();
            int entriesForThisDisk        = ReadLeShort();
            int entriesForWholeCentralDir = ReadLeShort();
            int centralDirSize            = ReadLeInt();
            int offsetOfCentralDir        = ReadLeInt();
            int commentSize = ReadLeShort();

            byte[] zipComment = new byte[commentSize];
            baseStream.Read(zipComment, 0, zipComment.Length);
            comment = ZipConstants.ConvertToString(zipComment);

/* Its seems possible that this is too strict, more digging required.
 *                      if (thisDiskNumber != 0 || startCentralDirDisk != 0 || entriesForThisDisk != entriesForWholeCentralDir) {
 *                              throw new ZipException("Spanned archives are not currently handled");
 *                      }
 */

            entries = new ZipEntry[entriesForWholeCentralDir];

            // SFX support, find the offset of the first entry vis the start of the stream
            // This applies to Zip files that are appended to the end of the SFX stub.
            // Zip files created by some archivers have the offsets altered to reflect the true offsets
            // and so dont require any adjustment here...
            if (offsetOfCentralDir < locatedCentralDirOffset - (4 + centralDirSize))
            {
                offsetOfFirstEntry = locatedCentralDirOffset - (4 + centralDirSize + offsetOfCentralDir);
                if (offsetOfFirstEntry <= 0)
                {
                    throw new ZipException("Invalid SFX file");
                }
            }

            baseStream.Seek(offsetOfFirstEntry + offsetOfCentralDir, SeekOrigin.Begin);

            for (int i = 0; i < entriesForThisDisk; i++)
            {
                if (ReadLeInt() != ZipConstants.CENSIG)
                {
                    throw new ZipException("Wrong Central Directory signature");
                }

                int versionMadeBy    = ReadLeShort();
                int versionToExtract = ReadLeShort();
                int bitFlags         = ReadLeShort();
                int method           = ReadLeShort();
                int dostime          = ReadLeInt();
                int crc        = ReadLeInt();
                int csize      = ReadLeInt();
                int size       = ReadLeInt();
                int nameLen    = ReadLeShort();
                int extraLen   = ReadLeShort();
                int commentLen = ReadLeShort();

                int diskStartNo        = ReadLeShort();                  // Not currently used
                int internalAttributes = ReadLeShort();                  // Not currently used

                int externalAttributes = ReadLeInt();
                int offset             = ReadLeInt();

                byte[] buffer = new byte[Math.Max(nameLen, commentLen)];

                baseStream.Read(buffer, 0, nameLen);
                string name = ZipConstants.ConvertToString(buffer, nameLen);

                ZipEntry entry = new ZipEntry(name, versionToExtract, versionMadeBy);
                entry.CompressionMethod = (CompressionMethod)method;
                entry.Crc            = crc & 0xffffffffL;
                entry.Size           = size & 0xffffffffL;
                entry.CompressedSize = csize & 0xffffffffL;
                entry.Flags          = bitFlags;
                entry.DosTime        = (uint)dostime;

                if (extraLen > 0)
                {
                    byte[] extra = new byte[extraLen];
                    baseStream.Read(extra, 0, extraLen);
                    entry.ExtraData = extra;
                }

                if (commentLen > 0)
                {
                    baseStream.Read(buffer, 0, commentLen);
                    entry.Comment = ZipConstants.ConvertToString(buffer, commentLen);
                }

                entry.ZipFileIndex           = i;
                entry.Offset                 = offset;
                entry.ExternalFileAttributes = externalAttributes;

                entries[i] = entry;
            }
        }
Example #5
0
        /// <summary>
        /// Open the next entry from the zip archive, and return its description.
        /// If the previous entry wasn't closed, this method will close it.
        /// </summary>
        public ZipEntry GetNextEntry()
        {
            if (crc == null)
            {
                throw new InvalidOperationException("Closed.");
            }
            if (entry != null)
            {
                CloseEntry();
            }

            if (this.cryptbuffer != null)
            {
                if (avail == 0 && inf.RemainingInput != 0)
                {
                    avail = inf.RemainingInput - 16;
                    inf.Reset();
                }
                baseInputStream.Position -= this.len;
                baseInputStream.Read(this.buf, 0, this.len);
            }

            int header = ReadLeInt();

            // -jr- added end sig for empty zip files, Zip64 end sig and digital sig for files that have them...
            if (header == ZipConstants.CENSIG ||
                header == ZipConstants.ENDSIG ||
                header == ZipConstants.CENDIGITALSIG ||
                header == ZipConstants.CENSIG64)
            {
                // Central Header reached or end of empty zip file
                Close();
                return(null);
            }
            // -jr- 07-Dec-2003 ignore spanning temporary signatures if found
            // SPANNINGSIG is same as descriptor signature and is untested as yet.
            if (header == ZipConstants.SPANTEMPSIG || header == ZipConstants.SPANNINGSIG)
            {
                header = ReadLeInt();
            }

            if (header != ZipConstants.LOCSIG)
            {
                throw new ZipException("Wrong Local header signature: 0x" + String.Format("{0:X}", header));
            }

            short version = (short)ReadLeShort();

            flags  = ReadLeShort();
            method = ReadLeShort();
            uint dostime = (uint)ReadLeInt();
            int  crc2    = ReadLeInt();

            csize = ReadLeInt();
            size  = ReadLeInt();
            int  nameLen   = ReadLeShort();
            int  extraLen  = ReadLeShort();
            bool isCrypted = (flags & 1) == 1;

            if (method == ZipOutputStream.STORED && (!isCrypted && csize != size || (isCrypted && csize - 12 != size)))
            {
                throw new ZipException("Stored, but compressed != uncompressed");
            }

            byte[] buffer = new byte[nameLen];
            ReadFully(buffer);

            string name = ZipConstants.ConvertToString(buffer);

            entry           = new ZipEntry(name);
            entry.IsCrypted = isCrypted;
            entry.Version   = (ushort)version;
            if (method != 0 && method != 8)
            {
                throw new ZipException("unknown compression method " + method);
            }
            entry.CompressionMethod = (CompressionMethod)method;

            if ((flags & 8) == 0)
            {
                entry.Crc            = crc2 & 0xFFFFFFFFL;
                entry.Size           = size & 0xFFFFFFFFL;
                entry.CompressedSize = csize & 0xFFFFFFFFL;
            }

            entry.DosTime = dostime;

            if (extraLen > 0)
            {
                byte[] extra = new byte[extraLen];
                ReadFully(extra);
                entry.ExtraData = extra;
            }

            // test for encryption
            if (isCrypted)
            {
                if (password == null)
                {
                    throw new ZipException("No password set.");
                }
                InitializePassword(password);
                cryptbuffer = new byte[12];
                ReadFully(cryptbuffer);
                DecryptBlock(cryptbuffer, 0, cryptbuffer.Length);
                if ((flags & 8) == 0)                  // -jr- 10-Feb-2004 Dont yet know correct size here....
                {
                    csize -= 12;
                }
            }
            else
            {
                cryptbuffer = null;
            }

            if (method == ZipOutputStream.DEFLATED && avail > 0)
            {
                System.Array.Copy(buf, len - (int)avail, buf, 0, (int)avail);
                len   = (int)avail;
                avail = 0;
                if (isCrypted)
                {
                    DecryptBlock(buf, 0, Math.Min((int)csize, len));
                }
                inf.SetInput(buf, 0, len);
            }

            return(entry);
        }
Example #6
0
        /// <summary>
        /// Advances to the next entry in the archive
        /// </summary>
        /// <returns>
        /// The next <see cref="ZipEntry">entry</see> in the archive or null if there are no more entries.
        /// </returns>
        /// <remarks>
        /// If the previous entry is still open <see cref="CloseEntry">CloseEntry</see> is called.
        /// </remarks>
        /// <exception cref="InvalidOperationException">
        /// Input stream is closed
        /// </exception>
        /// <exception cref="ZipException">
        /// Password is not set, password is invalid, compression method is invalid,
        /// version required to extract is not supported
        /// </exception>
        public ZipEntry GetNextEntry()
        {
            if (crc == null)
            {
                throw new InvalidOperationException("Closed.");
            }

            if (entry != null)
            {
                CloseEntry();
            }

            var header = inputBuffer.ReadLeInt();

            if (header == ZipConstants.CENSIG ||
                header == ZipConstants.ENDSIG ||
                header == ZipConstants.CENDIGITALSIG ||
                header == ZipConstants.CENSIG64)
            {
                // No more individual entries exist
                Close();
                return(null);
            }

            // -jr- 07-Dec-2003 Ignore spanning temporary signatures if found
            // SPANNINGSIG is same as descriptor signature and is untested as yet.
            if (header == ZipConstants.SPANTEMPSIG || header == ZipConstants.SPANNINGSIG)
            {
                header = inputBuffer.ReadLeInt();
            }

            if (header != ZipConstants.LOCSIG)
            {
                throw new ZipException("Wrong Local header signature: 0x" + $"{header:X}");
            }

            var versionRequiredToExtract = (short)inputBuffer.ReadLeShort();

            flags  = inputBuffer.ReadLeShort();
            method = inputBuffer.ReadLeShort();
            var dostime = (uint)inputBuffer.ReadLeInt();
            var crc2    = inputBuffer.ReadLeInt();

            csize = inputBuffer.ReadLeInt();
            size  = inputBuffer.ReadLeInt();
            var nameLen  = inputBuffer.ReadLeShort();
            var extraLen = inputBuffer.ReadLeShort();

            var isCrypted = (flags & 1) == 1;

            var buffer = new byte[nameLen];

            inputBuffer.ReadRawBuffer(buffer);

            var name = ZipConstants.ConvertToString(buffer);

            entry       = new ZipEntry(name, versionRequiredToExtract);
            entry.Flags = flags;

            if (method == (int)CompressionMethod.Stored && (!isCrypted && csize != size || (isCrypted && csize - ZipConstants.CRYPTO_HEADER_SIZE != size)))
            {
                throw new ZipException("Stored, but compressed != uncompressed");
            }

            if (method != (int)CompressionMethod.Stored && method != (int)CompressionMethod.Deflated)
            {
                throw new ZipException("Unknown compression method " + method);
            }

            entry.CompressionMethod = (CompressionMethod)method;

            if ((flags & 8) == 0)
            {
                entry.Crc            = crc2 & 0xFFFFFFFFL;
                entry.Size           = size & 0xFFFFFFFFL;
                entry.CompressedSize = csize & 0xFFFFFFFFL;
            }
            else
            {
                // This allows for GNU, WinZip and possibly other archives, the PKZIP spec says these are zero
                // under these circumstances.
                if (crc2 != 0)
                {
                    entry.Crc = crc2 & 0xFFFFFFFFL;
                }

                if (size != 0)
                {
                    entry.Size = size & 0xFFFFFFFFL;
                }
                if (csize != 0)
                {
                    entry.CompressedSize = csize & 0xFFFFFFFFL;
                }
            }

            entry.DosTime = dostime;

            if (extraLen > 0)
            {
                var extra = new byte[extraLen];
                inputBuffer.ReadRawBuffer(extra);
                entry.ExtraData = extra;
            }

            internalReader = InitialRead;
            return(entry);
        }
Example #7
0
        /// <summary>
        /// Search for and read the central directory of a zip file filling the entries
        /// array.  This is called exactly once by the constructors.
        /// </summary>
        /// <exception cref="System.IO.IOException">
        /// An i/o error occurs.
        /// </exception>
        /// <exception cref="ICSharpCode.SharpZipLib.ZipException">
        /// The central directory is malformed or cannot be found
        /// </exception>
        void ReadEntries()
        {
            // Search for the End Of Central Directory.  When a zip comment is
            // present the directory may start earlier.
            //
            // TODO: The search is limited to 64K which is the maximum size of a trailing comment field to aid speed.
            // This should be compatible with both SFX and ZIP files but has only been tested for Zip files
            // Need to confirm this is valid in all cases.
            // Could also speed this up by reading memory in larger blocks?


            if (baseStream.CanSeek == false)
            {
                throw new ZipException("ZipFile stream must be seekable");
            }

            long pos = baseStream.Length - ZipConstants.ENDHDR;

            if (pos <= 0)
            {
                throw new ZipException("File is too small to be a Zip file");
            }

            long giveUpMarker = Math.Max(pos - 0x10000, 0);

            do
            {
                if (pos < giveUpMarker)
                {
                    throw new ZipException("central directory not found, probably not a zip file");
                }
                baseStream.Seek(pos--, SeekOrigin.Begin);
            } while (ReadLeInt() != ZipConstants.ENDSIG);

            int thisDiskNumber            = ReadLeShort();
            int startCentralDirDisk       = ReadLeShort();
            int entriesForThisDisk        = ReadLeShort();
            int entriesForWholeCentralDir = ReadLeShort();
            int centralDirSize            = ReadLeInt();
            int offsetOfCentralDir        = ReadLeInt();
            int commentSize = ReadLeShort();

            byte[] zipComment = new byte[commentSize];
            baseStream.Read(zipComment, 0, zipComment.Length);
            comment = ZipConstants.ConvertToString(zipComment);

/* Its seems possible that this is too strict, more digging required.
 *                      if (thisDiskNumber != 0 || startCentralDirDisk != 0 || entriesForThisDisk != entriesForWholeCentralDir) {
 *                              throw new ZipException("Spanned archives are not currently handled");
 *                      }
 */

            entries = new ZipEntry[entriesForWholeCentralDir];
            baseStream.Seek(offsetOfCentralDir, SeekOrigin.Begin);

            for (int i = 0; i < entriesForWholeCentralDir; i++)
            {
                if (ReadLeInt() != ZipConstants.CENSIG)
                {
                    throw new ZipException("Wrong Central Directory signature");
                }

                int versionMadeBy    = ReadLeShort();
                int versionToExtract = ReadLeShort();
                int bitFlags         = ReadLeShort();
                int method           = ReadLeShort();
                int dostime          = ReadLeInt();
                int crc        = ReadLeInt();
                int csize      = ReadLeInt();
                int size       = ReadLeInt();
                int nameLen    = ReadLeShort();
                int extraLen   = ReadLeShort();
                int commentLen = ReadLeShort();

                int diskStartNo        = ReadLeShort();                  // Not currently used
                int internalAttributes = ReadLeShort();                  // Not currently used

                int externalAttributes = ReadLeInt();
                int offset             = ReadLeInt();

                byte[] buffer = new byte[Math.Max(nameLen, commentLen)];

                baseStream.Read(buffer, 0, nameLen);
                string name = ZipConstants.ConvertToString(buffer, nameLen);

                ZipEntry entry = new ZipEntry(name, versionToExtract, versionMadeBy);
                entry.CompressionMethod = (CompressionMethod)method;
                entry.Crc            = crc & 0xffffffffL;
                entry.Size           = size & 0xffffffffL;
                entry.CompressedSize = csize & 0xffffffffL;
                entry.DosTime        = (uint)dostime;

                if (extraLen > 0)
                {
                    byte[] extra = new byte[extraLen];
                    baseStream.Read(extra, 0, extraLen);
                    entry.ExtraData = extra;
                }

                if (commentLen > 0)
                {
                    baseStream.Read(buffer, 0, commentLen);
                    entry.Comment = ZipConstants.ConvertToString(buffer, commentLen);
                }

                entry.ZipFileIndex           = i;
                entry.Offset                 = offset;
                entry.ExternalFileAttributes = externalAttributes;

                entries[i] = entry;
            }
        }
Example #8
0
        /// <summary>
        /// Read the central directory of a zip file and fill the entries
        /// array.  This is called exactly once by the constructors.
        /// </summary>
        /// <exception name="System.IO.IOException">
        /// if a i/o error occured.
        /// </exception>
        /// <exception name="ICSharpCode.SharpZipLib.ZipException">
        /// if the central directory is malformed
        /// </exception>
        void ReadEntries()
        {
            /* Search for the End Of Central Directory.  When a zip comment is
             * present the directory may start earlier.
             * FIXME: This searches the whole file in a very slow manner if the
             * file isn't a zip file.
             */
            long pos = baseStream.Length - ZipConstants.ENDHDR;

            do
            {
                if (pos < 0)
                {
                    throw new ZipException("central directory not found, probably not a zip file");
                }
                baseStream.Seek(pos--, SeekOrigin.Begin);
            } while (ReadLeInt() != ZipConstants.ENDSIG);

            long oldPos = baseStream.Position;

            baseStream.Position += ZipConstants.ENDTOT - ZipConstants.ENDNRD;

            if (baseStream.Position - oldPos != ZipConstants.ENDTOT - ZipConstants.ENDNRD)
            {
                throw new EndOfStreamException();
            }
            int count = ReadLeShort();

            oldPos = baseStream.Position;
            baseStream.Position += ZipConstants.ENDOFF - ZipConstants.ENDSIZ;

            if (baseStream.Position - oldPos != ZipConstants.ENDOFF - ZipConstants.ENDSIZ)
            {
                throw new EndOfStreamException();
            }

            int centralOffset = ReadLeInt();

            // GET COMMENT SIZE (COMES AFTER CENTRALOFFSET)
            int commentSize = ReadLeShort();

            byte[] zipComment = new byte[commentSize];
            baseStream.Read(zipComment, 0, zipComment.Length);
            comment = ZipConstants.ConvertToString(zipComment);

            entries = new ZipEntry[count];
            baseStream.Seek(centralOffset, SeekOrigin.Begin);
            for (int i = 0; i < count; i++)
            {
                if (ReadLeInt() != ZipConstants.CENSIG)
                {
                    throw new ZipException("Wrong Central Directory signature");
                }

                oldPos = baseStream.Position;
                baseStream.Position += ZipConstants.CENHOW - ZipConstants.CENVEM;

                if (baseStream.Position - oldPos != ZipConstants.CENHOW - ZipConstants.CENVEM)
                {
                    throw new EndOfStreamException();
                }
                int method     = ReadLeShort();
                int dostime    = ReadLeInt();
                int crc        = ReadLeInt();
                int csize      = ReadLeInt();
                int size       = ReadLeInt();
                int nameLen    = ReadLeShort();
                int extraLen   = ReadLeShort();
                int commentLen = ReadLeShort();

                oldPos = baseStream.Position;
                baseStream.Position += ZipConstants.CENOFF - ZipConstants.CENDSK;
                if (baseStream.Position - oldPos != ZipConstants.CENOFF - ZipConstants.CENDSK)
                {
                    throw new EndOfStreamException();
                }
                int offset = ReadLeInt();

                byte[] buffer = new byte[Math.Max(nameLen, commentLen)];

                baseStream.Read(buffer, 0, nameLen);
                string name = ZipConstants.ConvertToString(buffer);

                ZipEntry entry = new ZipEntry(name);
                entry.CompressionMethod = (CompressionMethod)method;
                entry.Crc            = crc & 0xffffffffL;
                entry.Size           = size & 0xffffffffL;
                entry.CompressedSize = csize & 0xffffffffL;
                entry.DosTime        = (uint)dostime;
                if (extraLen > 0)
                {
                    byte[] extra = new byte[extraLen];
                    baseStream.Read(extra, 0, extraLen);
                    entry.ExtraData = extra;
                }
                if (commentLen > 0)
                {
                    baseStream.Read(buffer, 0, commentLen);
                    entry.Comment = ZipConstants.ConvertToString(buffer);
                }
                entry.ZipFileIndex = i;
                entry.Offset       = offset;
                entries[i]         = entry;
            }
        }
        public ZipEntry GetNextEntry()
        {
            if (this.crc == null)
            {
                throw new InvalidOperationException("Closed.");
            }
            if (this.entry != null)
            {
                this.CloseEntry();
            }
            int num = base.inputBuffer.ReadLeInt();

            switch (num)
            {
            case 0x2014b50:
            case 0x6054b50:
            case 0x5054b50:
            case 0x6064b50:
                this.Close();
                return(null);

            case 0x30304b50:
            case 0x8074b50:
                num = base.inputBuffer.ReadLeInt();
                break;
            }
            if (num != 0x4034b50)
            {
                throw new ZipException("Wrong Local header signature: 0x" + string.Format("{0:X}", num));
            }
            short versionRequiredToExtract = (short)base.inputBuffer.ReadLeShort();

            this.flags  = base.inputBuffer.ReadLeShort();
            this.method = base.inputBuffer.ReadLeShort();
            uint num3 = (uint)base.inputBuffer.ReadLeInt();
            int  num4 = base.inputBuffer.ReadLeInt();

            base.csize = base.inputBuffer.ReadLeInt();
            this.size  = base.inputBuffer.ReadLeInt();
            int  num5 = base.inputBuffer.ReadLeShort();
            int  num6 = base.inputBuffer.ReadLeShort();
            bool flag = (this.flags & 1) == 1;

            byte[] buffer = new byte[num5];
            base.inputBuffer.ReadRawBuffer(buffer);
            string name = ZipConstants.ConvertToString(buffer);

            this.entry       = new ZipEntry(name, versionRequiredToExtract);
            this.entry.Flags = this.flags;
            if ((this.method == 0) && ((!flag && (base.csize != this.size)) || (flag && ((base.csize - 12L) != this.size))))
            {
                throw new ZipException("Stored, but compressed != uncompressed");
            }
            if ((this.method != 0) && (this.method != 8))
            {
                throw new ZipException("Unknown compression method " + this.method);
            }
            this.entry.CompressionMethod = (CompressionMethod)this.method;
            if ((this.flags & 8) == 0)
            {
                this.entry.Crc            = num4 & ((long)0xffffffffL);
                this.entry.Size           = this.size & ((long)0xffffffffL);
                this.entry.CompressedSize = base.csize & ((long)0xffffffffL);
            }
            else
            {
                if (num4 != 0)
                {
                    this.entry.Crc = num4 & ((long)0xffffffffL);
                }
                if (this.size != 0L)
                {
                    this.entry.Size = this.size & ((long)0xffffffffL);
                }
                if (base.csize != 0L)
                {
                    this.entry.CompressedSize = base.csize & ((long)0xffffffffL);
                }
            }
            this.entry.DosTime = num3;
            if (num6 > 0)
            {
                byte[] buffer2 = new byte[num6];
                base.inputBuffer.ReadRawBuffer(buffer2);
                this.entry.ExtraData = buffer2;
            }
            this.internalReader = new ReaderDelegate(this.InitialRead);
            return(this.entry);
        }
        /// <summary>
        /// Read the central directory of a zip file and fill the entries
        /// array.  This is called exactly once by the constructors.
        /// </summary>
        /// <exception cref="System.IO.IOException">
        /// An i/o error occurs.
        /// </exception>
        /// <exception cref="ICSharpCode.SharpZipLib.ZipException">
        /// The central directory is malformed or cannot be found
        /// </exception>
        void ReadEntries()
        {
            /* Search for the End Of Central Directory.  When a zip comment is
             * present the directory may start earlier.
             *
             * TODO: The search is limited to 64K which is the maximum size of a trailing comment field to aid speed.
             * This should be compatible with both SFX and ZIP files but has only been tested for Zip files
             * Need to confirm this is valid in all cases.
             */

            long pos          = baseStream.Length - ZipConstants.ENDHDR;
            long giveUpMarker = Math.Max(pos - 0x10000, 0);

            do
            {
                if (pos < giveUpMarker)
                {
                    throw new ZipException("central directory not found, probably not a zip file");
                }
                baseStream.Seek(pos--, SeekOrigin.Begin);
            } while (ReadLeInt() != ZipConstants.ENDSIG);

            long oldPos = baseStream.Position;

            baseStream.Position += ZipConstants.ENDTOT - ZipConstants.ENDNRD;

            if (baseStream.Position - oldPos != ZipConstants.ENDTOT - ZipConstants.ENDNRD)
            {
                throw new EndOfStreamException();
            }
            int count = ReadLeShort();

            oldPos = baseStream.Position;
            baseStream.Position += ZipConstants.ENDOFF - ZipConstants.ENDSIZ;

            if (baseStream.Position - oldPos != ZipConstants.ENDOFF - ZipConstants.ENDSIZ)
            {
                throw new EndOfStreamException();
            }

            int centralOffset = ReadLeInt();

            int commentSize = ReadLeShort();

            byte[] zipComment = new byte[commentSize];
            baseStream.Read(zipComment, 0, zipComment.Length);
            comment = ZipConstants.ConvertToString(zipComment);

            entries = new ZipEntry[count];
            baseStream.Seek(centralOffset, SeekOrigin.Begin);

            for (int i = 0; i < count; i++)
            {
                if (ReadLeInt() != ZipConstants.CENSIG)
                {
                    throw new ZipException("Wrong Central Directory signature");
                }

                int versionMadeBy    = ReadLeShort();
                int versionToExtract = ReadLeShort();
                int bitFlags         = ReadLeShort();
                int method           = ReadLeShort();
                int dostime          = ReadLeInt();
                int crc        = ReadLeInt();
                int csize      = ReadLeInt();
                int size       = ReadLeInt();
                int nameLen    = ReadLeShort();
                int extraLen   = ReadLeShort();
                int commentLen = ReadLeShort();

                int diskStartNo        = ReadLeShort();                  // Not currently used
                int internalAttributes = ReadLeShort();                  // Not currently used
                int externalAttributes = ReadLeInt();
                int offset             = ReadLeInt();

                byte[] buffer = new byte[Math.Max(nameLen, commentLen)];

                baseStream.Read(buffer, 0, nameLen);
                string name = ZipConstants.ConvertToString(buffer, nameLen);

                ZipEntry entry = new ZipEntry(name, versionToExtract, versionMadeBy);
                entry.CompressionMethod = (CompressionMethod)method;
                entry.Crc            = crc & 0xffffffffL;
                entry.Size           = size & 0xffffffffL;
                entry.CompressedSize = csize & 0xffffffffL;
                entry.DosTime        = (uint)dostime;

                if (extraLen > 0)
                {
                    byte[] extra = new byte[extraLen];
                    baseStream.Read(extra, 0, extraLen);
                    entry.ExtraData = extra;
                }

                if (commentLen > 0)
                {
                    baseStream.Read(buffer, 0, commentLen);
                    entry.Comment = ZipConstants.ConvertToString(buffer, commentLen);
                }

                entry.ZipFileIndex           = i;
                entry.Offset                 = offset;
                entry.ExternalFileAttributes = externalAttributes;

                entries[i] = entry;
            }
        }
        private void ReadEntries()
        {
            if (!this.baseStream.CanSeek)
            {
                throw new ZipException("ZipFile stream must be seekable");
            }
            long num = this.LocateBlockWithSignature(0x6054b50, this.baseStream.Length, 0x16, 0xffff);

            if (num < 0L)
            {
                throw new ZipException("Cannot find central directory");
            }
            this.ReadLeShort();
            this.ReadLeShort();
            int num2 = this.ReadLeShort();
            int num3 = this.ReadLeShort();
            int num4 = this.ReadLeInt();
            int num5 = this.ReadLeInt();

            byte[] buffer = new byte[this.ReadLeShort()];
            this.baseStream.Read(buffer, 0, buffer.Length);
            this.comment = ZipConstants.ConvertToString(buffer);
            this.entries = new ZipEntry[num3];
            if (num5 < (num - (4 + num4)))
            {
                this.offsetOfFirstEntry = num - ((4 + num4) + num5);
                if (this.offsetOfFirstEntry <= 0L)
                {
                    throw new ZipException("Invalid SFX file");
                }
            }
            this.baseStream.Seek(this.offsetOfFirstEntry + num5, SeekOrigin.Begin);
            for (int i = 0; i < num2; i++)
            {
                if (this.ReadLeInt() != 0x2014b50)
                {
                    throw new ZipException("Wrong Central Directory signature");
                }
                int madeByInfo = this.ReadLeShort();
                int versionRequiredToExtract = this.ReadLeShort();
                int num10 = this.ReadLeShort();
                int num11 = this.ReadLeShort();
                int num12 = this.ReadLeInt();
                int num13 = this.ReadLeInt();
                int num14 = this.ReadLeInt();
                int num15 = this.ReadLeInt();
                int num16 = this.ReadLeShort();
                int count = this.ReadLeShort();
                int num18 = this.ReadLeShort();
                this.ReadLeShort();
                this.ReadLeShort();
                int    num19   = this.ReadLeInt();
                int    num20   = this.ReadLeInt();
                byte[] buffer2 = new byte[Math.Max(num16, num18)];
                this.baseStream.Read(buffer2, 0, num16);
                ZipEntry entry = new ZipEntry(ZipConstants.ConvertToString(buffer2, num16), versionRequiredToExtract, madeByInfo)
                {
                    CompressionMethod = (CompressionMethod)num11,
                    Crc            = num13 & ((long)0xffffffffL),
                    Size           = num15 & ((long)0xffffffffL),
                    CompressedSize = num14 & ((long)0xffffffffL),
                    Flags          = num10,
                    DosTime        = (long)((ulong)num12)
                };
                if (count > 0)
                {
                    byte[] buffer3 = new byte[count];
                    this.baseStream.Read(buffer3, 0, count);
                    entry.ExtraData = buffer3;
                }
                if (num18 > 0)
                {
                    this.baseStream.Read(buffer2, 0, num18);
                    entry.Comment = ZipConstants.ConvertToString(buffer2, num18);
                }
                entry.ZipFileIndex           = i;
                entry.Offset                 = num20;
                entry.ExternalFileAttributes = num19;
                this.entries[i]              = entry;
            }
        }
        /// <summary>
        /// Advances to the next entry in the archive
        /// </summary>
        /// <returns>
        /// The next <see cref="ZipEntry">entry</see> in the archive or null if there are no more entries.
        /// </returns>
        /// <remarks>
        /// If the previous entry is still open <see cref="CloseEntry">CloseEntry</see> is called.
        /// </remarks>
        /// <exception cref="InvalidOperationException">
        /// Input stream is closed
        /// </exception>
        /// <exception cref="ZipException">
        /// Password is not set, password is invalid, compression method is invalid,
        /// version required to extract is not supported
        /// </exception>
        public ZipEntry GetNextEntry()
        {
            if (crc == null)
            {
                throw new InvalidOperationException("Closed.");
            }

            if (entry != null)
            {
                CloseEntry();
            }

            if (this.cryptbuffer != null)
            {
                if (inf.IsFinished == false && (entry.Flags & 8) != 0)
                {
                    throw new ZipException("NextEntry location not known");
                }

                if (avail == 0 && inf.RemainingInput != 0)
                {
                    avail = inf.RemainingInput - 16;
                    inf.Reset();
                }
                baseInputStream.Position -= this.len;
                baseInputStream.Read(this.buf, 0, this.len);
            }

            if (avail <= 0)
            {
                FillBuf(ZipConstants.LOCHDR);
            }

            int header = ReadLeInt();

            if (header == ZipConstants.CENSIG ||
                header == ZipConstants.ENDSIG ||
                header == ZipConstants.CENDIGITALSIG ||
                header == ZipConstants.CENSIG64)
            {
                // No more individual entries exist
                Close();
                return(null);
            }

            // -jr- 07-Dec-2003 Ignore spanning temporary signatures if found
            // SPANNINGSIG is same as descriptor signature and is untested as yet.
            if (header == ZipConstants.SPANTEMPSIG || header == ZipConstants.SPANNINGSIG)
            {
                header = ReadLeInt();
            }

            if (header != ZipConstants.LOCSIG)
            {
                throw new ZipException("Wrong Local header signature: 0x" + String.Format("{0:X}", header));
            }

            short versionRequiredToExtract = (short)ReadLeShort();

            flags  = ReadLeShort();
            method = ReadLeShort();
            uint dostime = (uint)ReadLeInt();
            int  crc2    = ReadLeInt();

            csize = ReadLeInt();
            size  = ReadLeInt();
            int nameLen  = ReadLeShort();
            int extraLen = ReadLeShort();

            bool isCrypted = (flags & 1) == 1;

            byte[] buffer = new byte[nameLen];
            ReadFully(buffer);

            string name = ZipConstants.ConvertToString(buffer);

            entry       = new ZipEntry(name, versionRequiredToExtract);
            entry.Flags = flags;

            if (method == (int)CompressionMethod.Stored && (!isCrypted && csize != size || (isCrypted && csize - ZipConstants.CRYPTO_HEADER_SIZE != size)))
            {
                throw new ZipException("Stored, but compressed != uncompressed");
            }

            if (method != (int)CompressionMethod.Stored && method != (int)CompressionMethod.Deflated)
            {
                throw new ZipException("unknown compression method " + method);
            }

            entry.CompressionMethod = (CompressionMethod)method;

            if ((flags & 8) == 0)
            {
                entry.Crc            = crc2 & 0xFFFFFFFFL;
                entry.Size           = size & 0xFFFFFFFFL;
                entry.CompressedSize = csize & 0xFFFFFFFFL;
                BufferReadSize       = 0;
            }
            else
            {
                if (isCrypted)
                {
                    BufferReadSize = 1;
                }
                else
                {
                    BufferReadSize = 0;
                }

                // This allows for GNU, WinZip and possibly other archives, the PKZIP spec says these are zero
                // under these circumstances.
                if (crc2 != 0)
                {
                    entry.Crc = crc2 & 0xFFFFFFFFL;
                }

                if (size != 0)
                {
                    entry.Size = size & 0xFFFFFFFFL;
                }
                if (csize != 0)
                {
                    entry.CompressedSize = csize & 0xFFFFFFFFL;
                }
            }


            entry.DosTime = dostime;

            if (extraLen > 0)
            {
                byte[] extra = new byte[extraLen];
                ReadFully(extra);
                entry.ExtraData = extra;
            }

            // TODO How to handle this?
            // This library cannot handle versions greater than 20
            // Throwing an exception precludes getting at later possibly useable entries.
            // Could also skip this entry entirely
            // Letting it slip past here isnt so great as it wont work
            if (versionRequiredToExtract > 20)
            {
                throw new ZipException("Libray cannot extract this entry version required (" + versionRequiredToExtract.ToString() + ")");
            }

            // test for encryption
            if (isCrypted)
            {
                if (password == null)
                {
                    throw new ZipException("No password set.");
                }
                InitializePassword(password);
                cryptbuffer = new byte[ZipConstants.CRYPTO_HEADER_SIZE];
                ReadFully(cryptbuffer);
                DecryptBlock(cryptbuffer, 0, cryptbuffer.Length);

                if ((flags & 8) == 0)
                {
                    if (cryptbuffer[ZipConstants.CRYPTO_HEADER_SIZE - 1] != (byte)(crc2 >> 24))
                    {
                        throw new ZipException("Invalid password");
                    }
                }
                else
                {
                    if (cryptbuffer[ZipConstants.CRYPTO_HEADER_SIZE - 1] != (byte)((dostime >> 8) & 0xff))
                    {
                        throw new ZipException("Invalid password");
                    }
                }

                if (csize >= ZipConstants.CRYPTO_HEADER_SIZE)
                {
                    csize -= ZipConstants.CRYPTO_HEADER_SIZE;
                }
            }
            else
            {
                cryptbuffer = null;
            }

            if (method == (int)CompressionMethod.Deflated && avail > 0)
            {
                System.Array.Copy(buf, len - (int)avail, buf, 0, (int)avail);
                len   = (int)avail;
                avail = 0;
                if (isCrypted)
                {
                    DecryptBlock(buf, 0, Math.Min((int)csize, len));
                }
                inf.SetInput(buf, 0, len);
            }

            return(entry);
        }