private void readFilesInfo()

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


    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, isEmptyStream.cardinality());
                    break;
                }
                case NID.kAnti: {
                    isAnti = readBits(header, isEmptyStream.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);
    }