private void readFilesInfo()

in src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java [1276:1417]


    private void readFilesInfo(final ByteBuffer header, final Archive archive) throws IOException {
        final int numFilesInt = (int) readUint64(header);
        final Map<Integer, SevenZArchiveEntry> fileMap = new LinkedHashMap<>();
        BitSet isEmptyStream = null;
        BitSet isEmptyFile = null;
        BitSet isAnti = null;
        while (true) {
            final int propertyType = getUnsignedByte(header);
            if (propertyType == 0) {
                break;
            }
            final long size = readUint64(header);
            switch (propertyType) {
            case NID.kEmptyStream: {
                isEmptyStream = readBits(header, numFilesInt);
                break;
            }
            case NID.kEmptyFile: {
                isEmptyFile = readBits(header, ArchiveException.requireNonNull(isEmptyStream, () -> "isEmptyStream for " + archive).cardinality());
                break;
            }
            case NID.kAnti: {
                isAnti = readBits(header, ArchiveException.requireNonNull(isEmptyStream, () -> "isEmptyStream for " + archive).cardinality());
                break;
            }
            case NID.kName: {
                /* final int external = */ getUnsignedByte(header);
                final byte[] names = new byte[(int) (size - 1)];
                final int namesLength = names.length;
                get(header, names);
                int nextFile = 0;
                int nextName = 0;
                for (int i = 0; i < namesLength; i += 2) {
                    if (names[i] == 0 && names[i + 1] == 0) {
                        checkEntryIsInitialized(fileMap, nextFile);
                        fileMap.get(nextFile).setName(new String(names, nextName, i - nextName, UTF_16LE));
                        nextName = i + 2;
                        nextFile++;
                    }
                }
                if (nextName != namesLength || nextFile != numFilesInt) {
                    throw new IOException("Error parsing file names");
                }
                break;
            }
            case NID.kCTime: {
                final BitSet timesDefined = readAllOrBits(header, numFilesInt);
                /* final int external = */ getUnsignedByte(header);
                for (int i = 0; i < numFilesInt; i++) {
                    checkEntryIsInitialized(fileMap, i);
                    final SevenZArchiveEntry entryAtIndex = fileMap.get(i);
                    entryAtIndex.setHasCreationDate(timesDefined.get(i));
                    if (entryAtIndex.getHasCreationDate()) {
                        entryAtIndex.setCreationDate(getLong(header));
                    }
                }
                break;
            }
            case NID.kATime: {
                final BitSet timesDefined = readAllOrBits(header, numFilesInt);
                /* final int external = */ getUnsignedByte(header);
                for (int i = 0; i < numFilesInt; i++) {
                    checkEntryIsInitialized(fileMap, i);
                    final SevenZArchiveEntry entryAtIndex = fileMap.get(i);
                    entryAtIndex.setHasAccessDate(timesDefined.get(i));
                    if (entryAtIndex.getHasAccessDate()) {
                        entryAtIndex.setAccessDate(getLong(header));
                    }
                }
                break;
            }
            case NID.kMTime: {
                final BitSet timesDefined = readAllOrBits(header, numFilesInt);
                /* final int external = */ getUnsignedByte(header);
                for (int i = 0; i < numFilesInt; i++) {
                    checkEntryIsInitialized(fileMap, i);
                    final SevenZArchiveEntry entryAtIndex = fileMap.get(i);
                    entryAtIndex.setHasLastModifiedDate(timesDefined.get(i));
                    if (entryAtIndex.getHasLastModifiedDate()) {
                        entryAtIndex.setLastModifiedDate(getLong(header));
                    }
                }
                break;
            }
            case NID.kWinAttributes: {
                final BitSet attributesDefined = readAllOrBits(header, numFilesInt);
                /* final int external = */ getUnsignedByte(header);
                for (int i = 0; i < numFilesInt; i++) {
                    checkEntryIsInitialized(fileMap, i);
                    final SevenZArchiveEntry entryAtIndex = fileMap.get(i);
                    entryAtIndex.setHasWindowsAttributes(attributesDefined.get(i));
                    if (entryAtIndex.getHasWindowsAttributes()) {
                        entryAtIndex.setWindowsAttributes(getInt(header));
                    }
                }
                break;
            }
            case NID.kDummy: {
                // 7z 9.20 asserts the content is all zeros and ignores the property
                // Compress up to 1.8.1 would throw an exception, now we ignore it (see COMPRESS-287
                skipBytesFully(header, size);
                break;
            }
            default: {
                // Compress up to 1.8.1 would throw an exception, now we ignore it (see COMPRESS-287
                skipBytesFully(header, size);
                break;
            }
            }
        }
        int nonEmptyFileCounter = 0;
        int emptyFileCounter = 0;
        for (int i = 0; i < numFilesInt; i++) {
            final SevenZArchiveEntry entryAtIndex = fileMap.get(i);
            if (entryAtIndex == null) {
                continue;
            }
            entryAtIndex.setHasStream(isEmptyStream == null || !isEmptyStream.get(i));
            if (entryAtIndex.hasStream()) {
                if (archive.subStreamsInfo == null) {
                    throw new IOException("Archive contains file with streams but no subStreamsInfo");
                }
                entryAtIndex.setDirectory(false);
                entryAtIndex.setAntiItem(false);
                entryAtIndex.setHasCrc(archive.subStreamsInfo.hasCrc.get(nonEmptyFileCounter));
                entryAtIndex.setCrcValue(archive.subStreamsInfo.crcs[nonEmptyFileCounter]);
                entryAtIndex.setSize(archive.subStreamsInfo.unpackSizes[nonEmptyFileCounter]);
                if (entryAtIndex.getSize() < 0) {
                    throw new IOException("broken archive, entry with negative size");
                }
                ++nonEmptyFileCounter;
            } else {
                entryAtIndex.setDirectory(isEmptyFile == null || !isEmptyFile.get(emptyFileCounter));
                entryAtIndex.setAntiItem(isAnti != null && isAnti.get(emptyFileCounter));
                entryAtIndex.setHasCrc(false);
                entryAtIndex.setSize(0);
                ++emptyFileCounter;
            }
        }
        archive.files = fileMap.values().stream().filter(Objects::nonNull).toArray(SevenZArchiveEntry[]::new);
        calculateStreamMap(archive);
    }