private void parseCodeAttrBands()

in src/main/java/org/apache/commons/compress/harmony/unpack200/ClassBands.java [576:680]


    private void parseCodeAttrBands(final InputStream in, final int codeFlagsCount) throws IOException, Pack200Exception {
        final long[] codeFlags = parseFlags("code_flags", in, codeFlagsCount, Codec.UNSIGNED5, segment.getSegmentHeader().getOptions().hasCodeFlagsHi());
        final int codeAttrCount = SegmentUtils.countBit16(codeFlags);
        final int[] codeAttrCounts = decodeBandInt("code_attr_count", in, Codec.UNSIGNED5, codeAttrCount);
        final int[][] codeAttrIndexes = decodeBandInt("code_attr_indexes", in, Codec.UNSIGNED5, codeAttrCounts);
        int callCount = 0;
        for (final int[] element : codeAttrIndexes) {
            for (final int index : element) {
                final AttributeLayout layout = attrMap.getAttributeLayout(index, AttributeLayout.CONTEXT_CODE);
                callCount += layout.numBackwardsCallables();
            }
        }
        final int[] codeAttrCalls = decodeBandInt("code_attr_calls", in, Codec.UNSIGNED5, callCount);

        final AttributeLayout lineNumberTableLayout = attrMap.getAttributeLayout(AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE, AttributeLayout.CONTEXT_CODE);
        final int lineNumberTableCount = SegmentUtils.countMatches(codeFlags, lineNumberTableLayout);
        final int[] lineNumberTableN = decodeBandInt("code_LineNumberTable_N", in, Codec.UNSIGNED5, lineNumberTableCount);
        final int[][] lineNumberTableBciP = decodeBandInt("code_LineNumberTable_bci_P", in, Codec.BCI5, lineNumberTableN);
        final int[][] lineNumberTableLine = decodeBandInt("code_LineNumberTable_line", in, Codec.UNSIGNED5, lineNumberTableN);

        final AttributeLayout localVariableTableLayout = attrMap.getAttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE,
                AttributeLayout.CONTEXT_CODE);
        final AttributeLayout localVariableTypeTableLayout = attrMap.getAttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE,
                AttributeLayout.CONTEXT_CODE);

        final int lengthLocalVariableNBand = SegmentUtils.countMatches(codeFlags, localVariableTableLayout);
        final int[] localVariableTableN = decodeBandInt("code_LocalVariableTable_N", in, Codec.UNSIGNED5, lengthLocalVariableNBand);
        final int[][] localVariableTableBciP = decodeBandInt("code_LocalVariableTable_bci_P", in, Codec.BCI5, localVariableTableN);
        final int[][] localVariableTableSpanO = decodeBandInt("code_LocalVariableTable_span_O", in, Codec.BRANCH5, localVariableTableN);
        final CPUTF8[][] localVariableTableNameRU = parseCPUTF8References("code_LocalVariableTable_name_RU", in, Codec.UNSIGNED5, localVariableTableN);
        final CPUTF8[][] localVariableTableTypeRS = parseCPSignatureReferences("code_LocalVariableTable_type_RS", in, Codec.UNSIGNED5, localVariableTableN);
        final int[][] localVariableTableSlot = decodeBandInt("code_LocalVariableTable_slot", in, Codec.UNSIGNED5, localVariableTableN);

        final int lengthLocalVariableTypeTableNBand = SegmentUtils.countMatches(codeFlags, localVariableTypeTableLayout);
        final int[] localVariableTypeTableN = decodeBandInt("code_LocalVariableTypeTable_N", in, Codec.UNSIGNED5, lengthLocalVariableTypeTableNBand);
        final int[][] localVariableTypeTableBciP = decodeBandInt("code_LocalVariableTypeTable_bci_P", in, Codec.BCI5, localVariableTypeTableN);
        final int[][] localVariableTypeTableSpanO = decodeBandInt("code_LocalVariableTypeTable_span_O", in, Codec.BRANCH5, localVariableTypeTableN);
        final CPUTF8[][] localVariableTypeTableNameRU = parseCPUTF8References("code_LocalVariableTypeTable_name_RU", in, Codec.UNSIGNED5,
                localVariableTypeTableN);
        final CPUTF8[][] localVariableTypeTableTypeRS = parseCPSignatureReferences("code_LocalVariableTypeTable_type_RS", in, Codec.UNSIGNED5,
                localVariableTypeTableN);
        final int[][] localVariableTypeTableSlot = decodeBandInt("code_LocalVariableTypeTable_slot", in, Codec.UNSIGNED5, localVariableTypeTableN);

        // Parse non-predefined attribute bands
        int backwardsCallIndex = 0;
        final int limit = options.hasCodeFlagsHi() ? 62 : 31;
        final AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
        final int[] counts = new int[limit + 1];
        final List<Attribute>[] otherAttributes = new List[limit + 1];
        for (int i = 0; i < limit; i++) {
            final AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_CODE);
            if (layout != null && !layout.isDefaultLayout()) {
                otherLayouts[i] = layout;
                counts[i] = SegmentUtils.countMatches(codeFlags, layout);
            }
        }
        for (int i = 0; i < counts.length; i++) {
            if (counts[i] > 0) {
                final NewAttributeBands bands = attrMap.getAttributeBands(otherLayouts[i]);
                otherAttributes[i] = bands.parseAttributes(in, counts[i]);
                final int numBackwardsCallables = otherLayouts[i].numBackwardsCallables();
                if (numBackwardsCallables > 0) {
                    final int[] backwardsCalls = new int[numBackwardsCallables];
                    System.arraycopy(codeAttrCalls, backwardsCallIndex, backwardsCalls, 0, numBackwardsCallables);
                    bands.setBackwardsCalls(backwardsCalls);
                    backwardsCallIndex += numBackwardsCallables;
                }
            }
        }

        int lineNumberIndex = 0;
        int lvtIndex = 0;
        int lvttIndex = 0;
        for (int i = 0; i < codeFlagsCount; i++) {
            if (lineNumberTableLayout.matches(codeFlags[i])) {
                final LineNumberTableAttribute lnta = new LineNumberTableAttribute(lineNumberTableN[lineNumberIndex], lineNumberTableBciP[lineNumberIndex],
                        lineNumberTableLine[lineNumberIndex]);
                lineNumberIndex++;
                codeAttributes[i].add(lnta);
            }
            if (localVariableTableLayout.matches(codeFlags[i])) {
                final LocalVariableTableAttribute lvta = new LocalVariableTableAttribute(localVariableTableN[lvtIndex], localVariableTableBciP[lvtIndex],
                        localVariableTableSpanO[lvtIndex], localVariableTableNameRU[lvtIndex], localVariableTableTypeRS[lvtIndex],
                        localVariableTableSlot[lvtIndex]);
                lvtIndex++;
                codeAttributes[i].add(lvta);
            }
            if (localVariableTypeTableLayout.matches(codeFlags[i])) {
                final LocalVariableTypeTableAttribute lvtta = new LocalVariableTypeTableAttribute(localVariableTypeTableN[lvttIndex],
                        localVariableTypeTableBciP[lvttIndex], localVariableTypeTableSpanO[lvttIndex], localVariableTypeTableNameRU[lvttIndex],
                        localVariableTypeTableTypeRS[lvttIndex], localVariableTypeTableSlot[lvttIndex]);
                lvttIndex++;
                codeAttributes[i].add(lvtta);
            }
            // Non-predefined attributes
            for (int j = 0; j < otherLayouts.length; j++) {
                if (otherLayouts[j] != null && otherLayouts[j].matches(codeFlags[i])) {
                    // Add the next attribute
                    codeAttributes[i].add(otherAttributes[j].get(0));
                    otherAttributes[j].remove(0);
                }
            }
        }

    }