in modules/pack200/src/main/java/org/apache/harmony/unpack200/ClassBands.java [803:963]
private void parseCodeAttrBands(InputStream in, int codeFlagsCount)
throws IOException, Pack200Exception {
long[] codeFlags = parseFlags("code_flags", in, codeFlagsCount,
Codec.UNSIGNED5, segment.getSegmentHeader().getOptions()
.hasCodeFlagsHi());
int codeAttrCount = SegmentUtils.countBit16(codeFlags);
int[] codeAttrCounts = decodeBandInt("code_attr_count", in,
Codec.UNSIGNED5, codeAttrCount);
int[][] codeAttrIndexes = decodeBandInt("code_attr_indexes", in,
Codec.UNSIGNED5, codeAttrCounts);
int callCount = 0;
for (int i = 0; i < codeAttrIndexes.length; i++) {
for (int j = 0; j < codeAttrIndexes[i].length; j++) {
int index = codeAttrIndexes[i][j];
AttributeLayout layout = attrMap.getAttributeLayout(index,
AttributeLayout.CONTEXT_CODE);
callCount += layout.numBackwardsCallables();
}
}
int[] codeAttrCalls = decodeBandInt("code_attr_calls", in,
Codec.UNSIGNED5, callCount);
AttributeLayout lineNumberTableLayout = attrMap.getAttributeLayout(
AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE,
AttributeLayout.CONTEXT_CODE);
int lineNumberTableCount = SegmentUtils.countMatches(codeFlags,
lineNumberTableLayout);
int[] lineNumberTableN = decodeBandInt("code_LineNumberTable_N", in,
Codec.UNSIGNED5, lineNumberTableCount);
int[][] lineNumberTableBciP = decodeBandInt(
"code_LineNumberTable_bci_P", in, Codec.BCI5, lineNumberTableN);
int[][] lineNumberTableLine = decodeBandInt(
"code_LineNumberTable_line", in, Codec.UNSIGNED5,
lineNumberTableN);
AttributeLayout localVariableTableLayout = attrMap.getAttributeLayout(
AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE,
AttributeLayout.CONTEXT_CODE);
AttributeLayout localVariableTypeTableLayout = attrMap
.getAttributeLayout(
AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE,
AttributeLayout.CONTEXT_CODE);
int lengthLocalVariableNBand = SegmentUtils.countMatches(codeFlags,
localVariableTableLayout);
int[] localVariableTableN = decodeBandInt("code_LocalVariableTable_N",
in, Codec.UNSIGNED5, lengthLocalVariableNBand);
int[][] localVariableTableBciP = decodeBandInt(
"code_LocalVariableTable_bci_P", in, Codec.BCI5,
localVariableTableN);
int[][] localVariableTableSpanO = decodeBandInt(
"code_LocalVariableTable_span_O", in, Codec.BRANCH5,
localVariableTableN);
CPUTF8[][] localVariableTableNameRU = parseCPUTF8References(
"code_LocalVariableTable_name_RU", in, Codec.UNSIGNED5,
localVariableTableN);
CPUTF8[][] localVariableTableTypeRS = parseCPSignatureReferences(
"code_LocalVariableTable_type_RS", in, Codec.UNSIGNED5,
localVariableTableN);
int[][] localVariableTableSlot = decodeBandInt(
"code_LocalVariableTable_slot", in, Codec.UNSIGNED5,
localVariableTableN);
int lengthLocalVariableTypeTableNBand = SegmentUtils.countMatches(
codeFlags, localVariableTypeTableLayout);
int[] localVariableTypeTableN = decodeBandInt(
"code_LocalVariableTypeTable_N", in, Codec.UNSIGNED5,
lengthLocalVariableTypeTableNBand);
int[][] localVariableTypeTableBciP = decodeBandInt(
"code_LocalVariableTypeTable_bci_P", in, Codec.BCI5,
localVariableTypeTableN);
int[][] localVariableTypeTableSpanO = decodeBandInt(
"code_LocalVariableTypeTable_span_O", in, Codec.BRANCH5,
localVariableTypeTableN);
CPUTF8[][] localVariableTypeTableNameRU = parseCPUTF8References(
"code_LocalVariableTypeTable_name_RU", in, Codec.UNSIGNED5,
localVariableTypeTableN);
CPUTF8[][] localVariableTypeTableTypeRS = parseCPSignatureReferences(
"code_LocalVariableTypeTable_type_RS", in, Codec.UNSIGNED5,
localVariableTypeTableN);
int[][] localVariableTypeTableSlot = decodeBandInt(
"code_LocalVariableTypeTable_slot", in, Codec.UNSIGNED5,
localVariableTypeTableN);
// Parse non-predefined attribute bands
int backwardsCallIndex = 0;
int limit = options.hasCodeFlagsHi() ? 62 : 31;
AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
int[] counts = new int[limit + 1];
List[] otherAttributes = new List[limit + 1];
for (int i = 0; i < limit; i++) {
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) {
NewAttributeBands bands = attrMap
.getAttributeBands(otherLayouts[i]);
otherAttributes[i] = bands.parseAttributes(in, counts[i]);
int numBackwardsCallables = otherLayouts[i]
.numBackwardsCallables();
if (numBackwardsCallables > 0) {
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])) {
LineNumberTableAttribute lnta = new LineNumberTableAttribute(
lineNumberTableN[lineNumberIndex],
lineNumberTableBciP[lineNumberIndex],
lineNumberTableLine[lineNumberIndex]);
lineNumberIndex++;
codeAttributes[i].add(lnta);
}
if (localVariableTableLayout.matches(codeFlags[i])) {
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])) {
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);
}
}
}
}