in src/main/java/org/apache/commons/compress/harmony/unpack200/ClassBands.java [747:853]
private void parseFieldAttrBands(final InputStream in) throws IOException, Pack200Exception {
fieldFlags = parseFlags("field_flags", in, classFieldCount, Codec.UNSIGNED5, options.hasFieldFlagsHi());
final int fieldAttrCount = SegmentUtils.countBit16(fieldFlags);
final int[] fieldAttrCounts = decodeBandInt("field_attr_count", in, Codec.UNSIGNED5, fieldAttrCount);
final int[][] fieldAttrIndexes = decodeBandInt("field_attr_indexes", in, Codec.UNSIGNED5, fieldAttrCounts);
final int callCount = getCallCount(fieldAttrIndexes, fieldFlags, AttributeLayout.CONTEXT_FIELD);
final int[] fieldAttrCalls = decodeBandInt("field_attr_calls", in, Codec.UNSIGNED5, callCount);
// Assign empty field attributes
fieldAttributes = new ArrayList[classCount][];
for (int i = 0; i < classCount; i++) {
fieldAttributes[i] = new ArrayList[fieldFlags[i].length];
for (int j = 0; j < fieldFlags[i].length; j++) {
fieldAttributes[i][j] = new ArrayList<>();
}
}
final AttributeLayout constantValueLayout = attrMap.getAttributeLayout("ConstantValue", AttributeLayout.CONTEXT_FIELD);
final int constantCount = SegmentUtils.countMatches(fieldFlags, constantValueLayout);
final int[] field_constantValue_KQ = decodeBandInt("field_ConstantValue_KQ", in, Codec.UNSIGNED5, constantCount);
int constantValueIndex = 0;
final AttributeLayout signatureLayout = attrMap.getAttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_FIELD);
final int signatureCount = SegmentUtils.countMatches(fieldFlags, signatureLayout);
final int[] fieldSignatureRS = decodeBandInt("field_Signature_RS", in, Codec.UNSIGNED5, signatureCount);
int signatureIndex = 0;
final AttributeLayout deprecatedLayout = attrMap.getAttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED, AttributeLayout.CONTEXT_FIELD);
for (int i = 0; i < classCount; i++) {
for (int j = 0; j < fieldFlags[i].length; j++) {
final long flag = fieldFlags[i][j];
if (deprecatedLayout.matches(flag)) {
fieldAttributes[i][j].add(new DeprecatedAttribute());
}
if (constantValueLayout.matches(flag)) {
// we've got a value to read
final long result = field_constantValue_KQ[constantValueIndex];
final String desc = fieldDescr[i][j];
final int colon = desc.indexOf(':');
String type = desc.substring(colon + 1);
if (type.equals("B") || type.equals("S") || type.equals("C") || type.equals("Z")) {
type = "I";
}
final ClassFileEntry value = constantValueLayout.getValue(result, type, cpBands.getConstantPool());
fieldAttributes[i][j].add(new ConstantValueAttribute(value));
constantValueIndex++;
}
if (signatureLayout.matches(flag)) {
// we've got a signature attribute
final long result = fieldSignatureRS[signatureIndex];
final String desc = fieldDescr[i][j];
final int colon = desc.indexOf(':');
final String type = desc.substring(colon + 1);
final CPUTF8 value = (CPUTF8) signatureLayout.getValue(result, type, cpBands.getConstantPool());
fieldAttributes[i][j].add(new SignatureAttribute(value));
signatureIndex++;
}
}
}
// Parse non-predefined attribute bands
int backwardsCallIndex = parseFieldMetadataBands(in, fieldAttrCalls);
final int limit = options.hasFieldFlagsHi() ? 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_FIELD);
if (layout != null && !layout.isDefaultLayout()) {
otherLayouts[i] = layout;
counts[i] = SegmentUtils.countMatches(fieldFlags, 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(fieldAttrCalls, backwardsCallIndex, backwardsCalls, 0, numBackwardsCallables);
bands.setBackwardsCalls(backwardsCalls);
backwardsCallIndex += numBackwardsCallables;
}
}
}
// Non-predefined attributes
for (int i = 0; i < classCount; i++) {
for (int j = 0; j < fieldFlags[i].length; j++) {
final long flag = fieldFlags[i][j];
int othersAddedAtStart = 0;
for (int k = 0; k < otherLayouts.length; k++) {
if (otherLayouts[k] != null && otherLayouts[k].matches(flag)) {
// Add the next attribute
if (otherLayouts[k].getIndex() < 15) {
fieldAttributes[i][j].add(othersAddedAtStart++, otherAttributes[k].get(0));
} else {
fieldAttributes[i][j].add(otherAttributes[k].get(0));
}
otherAttributes[k].remove(0);
}
}
}
}
}