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);
}
}
}
}