public ZipArchiveEntry getNextZipEntry()

in src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java [662:809]


    public ZipArchiveEntry getNextZipEntry() throws IOException {
        uncompressedCount = 0;

        boolean firstEntry = true;
        if (closed || hitCentralDirectory) {
            return null;
        }
        if (current != null) {
            closeEntry();
            firstEntry = false;
        }

        final long currentHeaderOffset = getBytesRead();
        try {
            if (firstEntry) {
                // split archives have a special signature before the
                // first local file header - look for it and fail with
                // the appropriate error message if this is a split
                // archive.
                if (!readFirstLocalFileHeader()) {
                    hitCentralDirectory = true;
                    skipRemainderOfArchive();
                    return null;
                }
            } else {
                readFully(lfhBuf);
            }
        } catch (final EOFException e) { // NOSONAR
            return null;
        }

        final ZipLong sig = new ZipLong(lfhBuf);
        if (!sig.equals(ZipLong.LFH_SIG)) {
            if (sig.equals(ZipLong.CFH_SIG) || sig.equals(ZipLong.AED_SIG) || isApkSigningBlock(lfhBuf)) {
                hitCentralDirectory = true;
                skipRemainderOfArchive();
                return null;
            }
            throw new ZipException(String.format("Unexpected record signature: 0x%x", sig.getValue()));
        }
        // off: go past the signature
        int off = WORD;
        current = new CurrentEntry();
        // get version
        final int versionMadeBy = ZipShort.getValue(lfhBuf, off);
        off += SHORT;
        current.entry.setPlatform(ZipFile.toPlatform(versionMadeBy));

        final GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(lfhBuf, off);
        final boolean hasUTF8Flag = gpFlag.usesUTF8ForNames();
        final ZipEncoding entryEncoding = hasUTF8Flag ? ZipEncodingHelper.ZIP_ENCODING_UTF_8 : zipEncoding;
        current.hasDataDescriptor = gpFlag.usesDataDescriptor();
        current.entry.setGeneralPurposeBit(gpFlag);

        off += SHORT;

        current.entry.setMethod(ZipShort.getValue(lfhBuf, off));
        off += SHORT;

        final long time = ZipUtil.dosToJavaTime(ZipLong.getValue(lfhBuf, off));
        current.entry.setTime(time);
        off += WORD;

        ZipLong size = null;
        ZipLong cSize = null;
        if (!current.hasDataDescriptor) {
            current.entry.setCrc(ZipLong.getValue(lfhBuf, off));
            off += WORD;

            cSize = new ZipLong(lfhBuf, off);
            off += WORD;

            size = new ZipLong(lfhBuf, off);
            off += WORD;
        } else {
            off += 3 * WORD;
        }

        final int fileNameLen = ZipShort.getValue(lfhBuf, off);

        off += SHORT;

        final int extraLen = ZipShort.getValue(lfhBuf, off);
        off += SHORT; // NOSONAR - assignment as documentation

        final byte[] fileName = readRange(fileNameLen);
        current.entry.setName(entryEncoding.decode(fileName), fileName);
        if (hasUTF8Flag) {
            current.entry.setNameSource(ZipArchiveEntry.NameSource.NAME_WITH_EFS_FLAG);
        }

        final byte[] extraData = readRange(extraLen);
        try {
            current.entry.setExtra(extraData);
        } catch (final RuntimeException ex) {
            throw ZipUtil.newZipException("Invalid extra data in entry " + current.entry.getName(), ex);
        }

        if (!hasUTF8Flag && useUnicodeExtraFields) {
            ZipUtil.setNameAndCommentFromExtraFields(current.entry, fileName, null);
        }

        processZip64Extra(size, cSize);

        current.entry.setLocalHeaderOffset(currentHeaderOffset);
        current.entry.setDataOffset(getBytesRead());
        current.entry.setStreamContiguous(true);

        final ZipMethod m = ZipMethod.getMethodByCode(current.entry.getMethod());
        if (current.entry.getCompressedSize() != ArchiveEntry.SIZE_UNKNOWN) {
            if (ZipUtil.canHandleEntryData(current.entry) && m != ZipMethod.STORED && m != ZipMethod.DEFLATED) {
                final InputStream bis = new BoundCountInputStream(in, current.entry.getCompressedSize());
                switch (m) {
                case UNSHRINKING:
                    current.inputStream = new UnshrinkingInputStream(bis);
                    break;
                case IMPLODING:
                    try {
                        current.inputStream = new ExplodingInputStream(current.entry.getGeneralPurposeBit().getSlidingDictionarySize(),
                                current.entry.getGeneralPurposeBit().getNumberOfShannonFanoTrees(), bis);
                    } catch (final IllegalArgumentException ex) {
                        throw new IOException("bad IMPLODE data", ex);
                    }
                    break;
                case BZIP2:
                    current.inputStream = new BZip2CompressorInputStream(bis);
                    break;
                case ENHANCED_DEFLATED:
                    current.inputStream = new Deflate64CompressorInputStream(bis);
                    break;
                case ZSTD:
                case ZSTD_DEPRECATED:
                    current.inputStream = createZstdInputStream(bis);
                    break;
                default:
                    // we should never get here as all supported methods have been covered
                    // will cause an error when read is invoked, don't throw an exception here so people can
                    // skip unsupported entries
                    break;
                }
            }
        } else if (m == ZipMethod.ENHANCED_DEFLATED) {
            current.inputStream = new Deflate64CompressorInputStream(in);
        }

        entriesRead++;
        return current.entry;
    }