ICSharpCode.SharpZipLib.Zip.ZipFile.ReadEntries C# (CSharp) Метод

ReadEntries() приватный Метод

Search for and read the central directory of a zip file filling the entries array.
/// An i/o error occurs. /// /// The central directory is malformed or cannot be found ///
private ReadEntries ( ) : void
Результат void
        private void ReadEntries() {
            // Search for the End Of Central Directory.  When a zip comment is
            // present the directory will start earlier
            // 
            // 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
            // If a SFX file has the Zip data attached as a resource and there are other resources occuring later then
            // this could be invalid.
            // Could also speed this up by reading memory in larger blocks.			

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

            long locatedEndOfCentralDir=LocateBlockWithSignature(ZipConstants.EndOfCentralDirectorySignature,
                                                                   baseStream_.Length,
                                                                   ZipConstants.EndOfCentralRecordBaseSize, 0xffff);

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

            // Read end of central directory record
            ushort thisDiskNumber=ReadLEUshort();
            ushort startCentralDirDisk=ReadLEUshort();
            ulong entriesForThisDisk=ReadLEUshort();
            ulong entriesForWholeCentralDir=ReadLEUshort();
            ulong centralDirSize=ReadLEUint();
            long offsetOfCentralDir=ReadLEUint();
            uint commentSize=ReadLEUshort();

            if (commentSize>0) {
                var comment=new byte[commentSize];

                StreamUtils.ReadFully(baseStream_, comment);
                comment_=ZipConstants.ConvertToString(comment);
            } else {
                comment_=string.Empty;
            }

            bool isZip64=false;

            // Check if zip64 header information is required.
            if ((thisDiskNumber==0xffff)||
                (startCentralDirDisk==0xffff)||
                (entriesForThisDisk==0xffff)||
                (entriesForWholeCentralDir==0xffff)||
                (centralDirSize==0xffffffff)||
                (offsetOfCentralDir==0xffffffff)) {
                isZip64=true;

                long offset=LocateBlockWithSignature(ZipConstants.Zip64CentralDirLocatorSignature,
                                                       locatedEndOfCentralDir, 0, 0x1000);
                if (offset<0) {
                    throw new ZipException("Cannot find Zip64 locator");
                }

                // number of the disk with the start of the zip64 end of central directory 4 bytes 
                // relative offset of the zip64 end of central directory record 8 bytes 
                // total number of disks 4 bytes 
                ReadLEUint(); // startDisk64 is not currently used
                ulong offset64=ReadLEUlong();
                uint totalDisks=ReadLEUint();

                baseStream_.Position=(long)offset64;
                long sig64=ReadLEUint();

                if (sig64!=ZipConstants.Zip64CentralFileHeaderSignature) {
                    throw new ZipException(string.Format("Invalid Zip64 Central directory signature at {0:X}", offset64));
                }

                // NOTE: Record size = SizeOfFixedFields + SizeOfVariableData - 12.
                ulong recordSize=ReadLEUlong();
                int versionMadeBy=ReadLEUshort();
                int versionToExtract=ReadLEUshort();
                uint thisDisk=ReadLEUint();
                uint centralDirDisk=ReadLEUint();
                entriesForThisDisk=ReadLEUlong();
                entriesForWholeCentralDir=ReadLEUlong();
                centralDirSize=ReadLEUlong();
                offsetOfCentralDir=(long)ReadLEUlong();

                // NOTE: zip64 extensible data sector (variable size) is ignored.
            }

            entries_=new ZipEntry[entriesForThisDisk];

            // SFX/embedded 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 an SFX stub.
            // Or are appended as a resource to an executable.
            // Zip files created by some archivers have the offsets altered to reflect the true offsets
            // and so dont require any adjustment here...
            // TODO: Difficulty with Zip64 and SFX offset handling needs resolution - maths?
            if (!isZip64&&(offsetOfCentralDir<locatedEndOfCentralDir-(4+(long)centralDirSize))) {
                offsetOfFirstEntry=locatedEndOfCentralDir-(4+(long)centralDirSize+offsetOfCentralDir);
                if (offsetOfFirstEntry<=0) {
                    throw new ZipException("Invalid embedded zip archive");
                }
            }

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

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

                int versionMadeBy=ReadLEUshort();
                int versionToExtract=ReadLEUshort();
                int bitFlags=ReadLEUshort();
                int method=ReadLEUshort();
                uint dostime=ReadLEUint();
                uint crc=ReadLEUint();
                long csize=ReadLEUint();
                long size=ReadLEUint();
                int nameLen=ReadLEUshort();
                int extraLen=ReadLEUshort();
                int commentLen=ReadLEUshort();

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

                uint externalAttributes=ReadLEUint();
                long offset=ReadLEUint();

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

                StreamUtils.ReadFully(baseStream_, buffer, 0, nameLen);
                string name=ZipConstants.ConvertToStringExt(bitFlags, buffer, nameLen);

                var entry=new ZipEntry(name, versionToExtract, versionMadeBy, (CompressionMethod)method);
                entry.Crc=crc&0xffffffffL;
                entry.Size=size&0xffffffffL;
                entry.CompressedSize=csize&0xffffffffL;
                entry.Flags=bitFlags;
                entry.DosTime=dostime;
                entry.ZipFileIndex=(long)i;
                entry.Offset=offset;
                entry.ExternalFileAttributes=(int)externalAttributes;

                if ((bitFlags&8)==0) {
                    entry.CryptoCheckValue=(byte)(crc>>24);
                } else {
                    entry.CryptoCheckValue=(byte)((dostime>>8)&0xff);
                }

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

                entry.ProcessExtraData(false);

                if (commentLen>0) {
                    StreamUtils.ReadFully(baseStream_, buffer, 0, commentLen);
                    entry.Comment=ZipConstants.ConvertToStringExt(bitFlags, buffer, commentLen);
                }

                entries_[i]=entry;
            }
        }