Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.commons.compress.harmony.pack200.ClassBands Maven / Gradle / Ivy
Go to download
Apache Commons Compress software defines an API for working with
compression and archive formats. These include: bzip2, gzip, pack200,
lzma, xz, Snappy, traditional Unix Compress, DEFLATE, DEFLATE64, LZ4,
Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.compress.harmony.pack200;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.compress.harmony.pack200.AttributeDefinitionBands.AttributeDefinition;
import org.apache.commons.compress.harmony.pack200.IcBands.IcTuple;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
/**
* Class bands (corresponds to the {@code class_bands} set of bands in the pack200 specification)
*/
public class ClassBands extends BandSet {
private static final long[] EMPTY_LONG_ARRAY = new long[0];
private static final class TempParamAnnotation {
int numParams;
int[] annoN;
IntList pairN = new IntList();
List typeRS = new ArrayList<>();
List nameRU = new ArrayList<>();
List tags = new ArrayList<>();
List values = new ArrayList<>();
List caseArrayN = new ArrayList<>();
List nestTypeRS = new ArrayList<>();
List nestNameRU = new ArrayList<>();
List nestPairN = new ArrayList<>();
TempParamAnnotation(final int numParams) {
this.numParams = numParams;
annoN = new int[numParams];
}
void addParameterAnnotation(final int parameter, final String desc, final List nameRU, final List tags,
final List values, final List caseArrayN, final List nestTypeRS, final List nestNameRU,
final List nestPairN) {
annoN[parameter]++;
typeRS.add(desc);
pairN.add(nameRU.size());
this.nameRU.addAll(nameRU);
this.tags.addAll(tags);
this.values.addAll(values);
this.caseArrayN.addAll(caseArrayN);
this.nestTypeRS.addAll(nestTypeRS);
this.nestNameRU.addAll(nestNameRU);
this.nestPairN.addAll(nestPairN);
}
}
protected static int countArgs(final String descriptor) {
final int bra = descriptor.indexOf('(');
final int ket = descriptor.indexOf(')');
if (bra == -1 || ket == -1 || ket < bra) {
throw new IllegalArgumentException("No arguments");
}
boolean inType = false;
boolean consumingNextType = false;
int count = 0;
for (int i = bra + 1; i < ket; i++) {
final char charAt = descriptor.charAt(i);
if (inType && charAt == ';') {
inType = false;
consumingNextType = false;
} else if (!inType && charAt == 'L') {
inType = true;
count++;
} else if (charAt == '[') {
consumingNextType = true;
} else if (inType) {
// NOP
} else if (consumingNextType) {
count++;
consumingNextType = false;
} else if (charAt == 'D' || charAt == 'J') {
count += 2;
} else {
count++;
}
}
return count;
}
private final CpBands cpBands;
private final AttributeDefinitionBands attrBands;
private final CPClass[] class_this;
private final CPClass[] class_super;
private final CPClass[][] class_interface;
private final int[] class_interface_count;
private final int[] major_versions;
private final long[] class_flags;
private int[] class_attr_calls;
private final List classSourceFile = new ArrayList<>();
private final List classEnclosingMethodClass = new ArrayList<>();
private final List classEnclosingMethodDesc = new ArrayList<>();
private final List classSignature = new ArrayList<>();
private final IntList classFileVersionMinor = new IntList();
private final IntList classFileVersionMajor = new IntList();
private final int[] class_field_count;
private final CPNameAndType[][] field_descr;
private final long[][] field_flags;
private int[] field_attr_calls;
private final List> fieldConstantValueKQ = new ArrayList<>();
private final List fieldSignature = new ArrayList<>();
private final int[] class_method_count;
private final CPNameAndType[][] method_descr;
private final long[][] method_flags;
private int[] method_attr_calls;
private final List methodSignature = new ArrayList<>();
private final IntList methodExceptionNumber = new IntList();
private final List methodExceptionClasses = new ArrayList<>();
private int[] codeHeaders;
private final IntList codeMaxStack = new IntList();
private final IntList codeMaxLocals = new IntList();
private final IntList codeHandlerCount = new IntList();
private final List codeHandlerStartP = new ArrayList();
private final List codeHandlerEndPO = new ArrayList();
private final List codeHandlerCatchPO = new ArrayList();
private final List codeHandlerClass = new ArrayList<>();
private final List codeFlags = new ArrayList<>();
private int[] code_attr_calls;
private final IntList codeLineNumberTableN = new IntList();
private final List codeLineNumberTableBciP = new ArrayList();
private final IntList codeLineNumberTableLine = new IntList();
private final IntList codeLocalVariableTableN = new IntList();
private final List codeLocalVariableTableBciP = new ArrayList();
private final List codeLocalVariableTableSpanO = new ArrayList();
private final List codeLocalVariableTableNameRU = new ArrayList<>();
private final List codeLocalVariableTableTypeRS = new ArrayList<>();
private final IntList codeLocalVariableTableSlot = new IntList();
private final IntList codeLocalVariableTypeTableN = new IntList();
private final List codeLocalVariableTypeTableBciP = new ArrayList();
private final List codeLocalVariableTypeTableSpanO = new ArrayList();
private final List codeLocalVariableTypeTableNameRU = new ArrayList<>();
private final List codeLocalVariableTypeTableTypeRS = new ArrayList<>();
private final IntList codeLocalVariableTypeTableSlot = new IntList();
private final MetadataBandGroup class_RVA_bands;
private final MetadataBandGroup class_RIA_bands;
private final MetadataBandGroup field_RVA_bands;
private final MetadataBandGroup field_RIA_bands;
private final MetadataBandGroup method_RVA_bands;
private final MetadataBandGroup method_RIA_bands;
private final MetadataBandGroup method_RVPA_bands;
private final MetadataBandGroup method_RIPA_bands;
private final MetadataBandGroup method_AD_bands;
private final List classAttributeBands = new ArrayList<>();
private final List methodAttributeBands = new ArrayList<>();
private final List fieldAttributeBands = new ArrayList<>();
private final List codeAttributeBands = new ArrayList<>();
private final List tempFieldFlags = new ArrayList<>();
private final List tempFieldDesc = new ArrayList<>();
private final List tempMethodFlags = new ArrayList<>();
private final List tempMethodDesc = new ArrayList<>();
private TempParamAnnotation tempMethodRVPA;
private TempParamAnnotation tempMethodRIPA;
private boolean anySyntheticClasses;
private boolean anySyntheticFields;
private boolean anySyntheticMethods;
private final Segment segment;
private final Map> classReferencesInnerClass = new HashMap<>();
private final boolean stripDebug;
private int index;
private int numMethodArgs;
private int[] class_InnerClasses_N;
private CPClass[] class_InnerClasses_RC;
private int[] class_InnerClasses_F;
private List classInnerClassesOuterRCN;
private List classInnerClassesNameRUN;
public ClassBands(final Segment segment, final int numClasses, final int effort, final boolean stripDebug) throws IOException {
super(effort, segment.getSegmentHeader());
this.stripDebug = stripDebug;
this.segment = segment;
this.cpBands = segment.getCpBands();
this.attrBands = segment.getAttrBands();
class_this = new CPClass[numClasses];
class_super = new CPClass[numClasses];
class_interface_count = new int[numClasses];
class_interface = new CPClass[numClasses][];
class_field_count = new int[numClasses];
class_method_count = new int[numClasses];
field_descr = new CPNameAndType[numClasses][];
field_flags = new long[numClasses][];
method_descr = new CPNameAndType[numClasses][];
method_flags = new long[numClasses][];
for (int i = 0; i < numClasses; i++) {
field_flags[i] = EMPTY_LONG_ARRAY;
method_flags[i] = EMPTY_LONG_ARRAY;
}
// minor_versions = new int[numClasses];
major_versions = new int[numClasses];
class_flags = new long[numClasses];
class_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_CLASS, cpBands, segmentHeader, effort);
class_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_CLASS, cpBands, segmentHeader, effort);
field_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_FIELD, cpBands, segmentHeader, effort);
field_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_FIELD, cpBands, segmentHeader, effort);
method_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader, effort);
method_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader, effort);
method_RVPA_bands = new MetadataBandGroup("RVPA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader, effort);
method_RIPA_bands = new MetadataBandGroup("RIPA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader, effort);
method_AD_bands = new MetadataBandGroup("AD", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader, effort);
createNewAttributeBands();
}
public void addAnnotation(final int context, final String desc, final boolean visible, final List nameRU, final List tags,
final List values, final List caseArrayN, final List nestTypeRS, final List nestNameRU,
final List nestPairN) {
switch (context) {
case MetadataBandGroup.CONTEXT_CLASS:
if (visible) {
class_RVA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
if ((class_flags[index] & 1 << 21) != 0) {
class_RVA_bands.incrementAnnoN();
} else {
class_RVA_bands.newEntryInAnnoN();
class_flags[index] = class_flags[index] | 1 << 21;
}
} else {
class_RIA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
if ((class_flags[index] & 1 << 22) != 0) {
class_RIA_bands.incrementAnnoN();
} else {
class_RIA_bands.newEntryInAnnoN();
class_flags[index] = class_flags[index] | 1 << 22;
}
}
break;
case MetadataBandGroup.CONTEXT_FIELD:
if (visible) {
field_RVA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
final Long flag = tempFieldFlags.remove(tempFieldFlags.size() - 1);
if ((flag.intValue() & 1 << 21) != 0) {
field_RVA_bands.incrementAnnoN();
} else {
field_RVA_bands.newEntryInAnnoN();
}
tempFieldFlags.add(Long.valueOf(flag.intValue() | 1 << 21));
} else {
field_RIA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
final Long flag = tempFieldFlags.remove(tempFieldFlags.size() - 1);
if ((flag.intValue() & 1 << 22) != 0) {
field_RIA_bands.incrementAnnoN();
} else {
field_RIA_bands.newEntryInAnnoN();
}
tempFieldFlags.add(Long.valueOf(flag.intValue() | 1 << 22));
}
break;
case MetadataBandGroup.CONTEXT_METHOD:
if (visible) {
method_RVA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
if ((flag.intValue() & 1 << 21) != 0) {
method_RVA_bands.incrementAnnoN();
} else {
method_RVA_bands.newEntryInAnnoN();
}
tempMethodFlags.add(Long.valueOf(flag.intValue() | 1 << 21));
} else {
method_RIA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
if ((flag.intValue() & 1 << 22) != 0) {
method_RIA_bands.incrementAnnoN();
} else {
method_RIA_bands.newEntryInAnnoN();
}
tempMethodFlags.add(Long.valueOf(flag.intValue() | 1 << 22));
}
break;
}
}
public void addAnnotationDefault(final List nameRU, final List tags, final List values, final List caseArrayN,
final List nestTypeRS, final List nestNameRU, final List nestPairN) {
method_AD_bands.addAnnotation(null, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
tempMethodFlags.add(Long.valueOf(flag.longValue() | 1 << 25));
}
public void addClass(final int major, final int flags, final String className, final String signature, final String superName, final String[] interfaces) {
class_this[index] = cpBands.getCPClass(className);
class_super[index] = cpBands.getCPClass(superName);
class_interface_count[index] = interfaces.length;
class_interface[index] = new CPClass[interfaces.length];
Arrays.setAll(class_interface[index], i -> cpBands.getCPClass(interfaces[i]));
major_versions[index] = major;
class_flags[index] = flags;
if (!anySyntheticClasses && (flags & 1 << 12) != 0 && segment.getCurrentClassReader().hasSyntheticAttributes()) {
cpBands.addCPUtf8("Synthetic");
anySyntheticClasses = true;
}
// if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
// flags &= ~Opcodes.ACC_DEPRECATED;
// flags |= (1 << 20);
// }
if (signature != null) {
class_flags[index] |= 1 << 19;
classSignature.add(cpBands.getCPSignature(signature));
}
}
public void addClassAttribute(final NewAttribute attribute) {
// TODO: backwards calls
final String attributeName = attribute.type;
for (final NewAttributeBands bands : classAttributeBands) {
if (bands.getAttributeName().equals(attributeName)) {
bands.addAttribute(attribute);
final int flagIndex = bands.getFlagIndex();
class_flags[index] |= 1 << flagIndex;
return;
}
}
throw new IllegalArgumentException("No suitable definition for " + attributeName);
}
public void addCode() {
codeHandlerCount.add(0);
if (!stripDebug) {
codeFlags.add(Long.valueOf(1 << 2));
codeLocalVariableTableN.add(0);
}
}
public void addCodeAttribute(final NewAttribute attribute) {
final String attributeName = attribute.type;
for (final NewAttributeBands bands : codeAttributeBands) {
if (bands.getAttributeName().equals(attributeName)) {
bands.addAttribute(attribute);
final int flagIndex = bands.getFlagIndex();
final Long flags = codeFlags.remove(codeFlags.size() - 1);
codeFlags.add(Long.valueOf(flags.longValue() | 1 << flagIndex));
return;
}
}
throw new IllegalArgumentException("No suitable definition for " + attributeName);
}
public void addEnclosingMethod(final String owner, final String name, final String desc) {
class_flags[index] |= 1 << 18;
classEnclosingMethodClass.add(cpBands.getCPClass(owner));
classEnclosingMethodDesc.add(name == null ? null : cpBands.getCPNameAndType(name, desc));
}
public void addField(int flags, final String name, final String desc, final String signature, final Object value) {
flags &= 0xFFFF;
tempFieldDesc.add(cpBands.getCPNameAndType(name, desc));
if (signature != null) {
fieldSignature.add(cpBands.getCPSignature(signature));
flags |= 1 << 19;
}
if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
flags &= ~Opcodes.ACC_DEPRECATED;
flags |= 1 << 20;
}
if (value != null) {
fieldConstantValueKQ.add(cpBands.getConstant(value));
flags |= 1 << 17;
}
if (!anySyntheticFields && (flags & 1 << 12) != 0 && segment.getCurrentClassReader().hasSyntheticAttributes()) {
cpBands.addCPUtf8("Synthetic");
anySyntheticFields = true;
}
tempFieldFlags.add(Long.valueOf(flags));
}
public void addFieldAttribute(final NewAttribute attribute) {
final String attributeName = attribute.type;
for (final NewAttributeBands bands : fieldAttributeBands) {
if (bands.getAttributeName().equals(attributeName)) {
bands.addAttribute(attribute);
final int flagIndex = bands.getFlagIndex();
final Long flags = tempFieldFlags.remove(tempFieldFlags.size() - 1);
tempFieldFlags.add(Long.valueOf(flags.longValue() | 1 << flagIndex));
return;
}
}
throw new IllegalArgumentException("No suitable definition for " + attributeName);
}
public void addHandler(final Label start, final Label end, final Label handler, final String type) {
final int handlers = codeHandlerCount.remove(codeHandlerCount.size() - 1);
codeHandlerCount.add(handlers + 1);
codeHandlerStartP.add(start);
codeHandlerEndPO.add(end);
codeHandlerCatchPO.add(handler);
codeHandlerClass.add(type == null ? null : cpBands.getCPClass(type));
}
public void addLineNumber(final int line, final Label start) {
final Long latestCodeFlag = codeFlags.get(codeFlags.size() - 1);
if ((latestCodeFlag.intValue() & 1 << 1) == 0) {
codeFlags.remove(codeFlags.size() - 1);
codeFlags.add(Long.valueOf(latestCodeFlag.intValue() | 1 << 1));
codeLineNumberTableN.add(1);
} else {
codeLineNumberTableN.increment(codeLineNumberTableN.size() - 1);
}
codeLineNumberTableLine.add(line);
codeLineNumberTableBciP.add(start);
}
public void addLocalVariable(final String name, final String desc, final String signature, final Label start, final Label end, final int indx) {
if (signature != null) { // LocalVariableTypeTable attribute
final Long latestCodeFlag = codeFlags.get(codeFlags.size() - 1);
if ((latestCodeFlag.intValue() & 1 << 3) == 0) {
codeFlags.remove(codeFlags.size() - 1);
codeFlags.add(Long.valueOf(latestCodeFlag.intValue() | 1 << 3));
codeLocalVariableTypeTableN.add(1);
} else {
codeLocalVariableTypeTableN.increment(codeLocalVariableTypeTableN.size() - 1);
}
codeLocalVariableTypeTableBciP.add(start);
codeLocalVariableTypeTableSpanO.add(end);
codeLocalVariableTypeTableNameRU.add(cpBands.getCPUtf8(name));
codeLocalVariableTypeTableTypeRS.add(cpBands.getCPSignature(signature));
codeLocalVariableTypeTableSlot.add(indx);
}
// LocalVariableTable attribute
codeLocalVariableTableN.increment(codeLocalVariableTableN.size() - 1);
codeLocalVariableTableBciP.add(start);
codeLocalVariableTableSpanO.add(end);
codeLocalVariableTableNameRU.add(cpBands.getCPUtf8(name));
codeLocalVariableTableTypeRS.add(cpBands.getCPSignature(desc));
codeLocalVariableTableSlot.add(indx);
}
public void addMaxStack(final int maxStack, int maxLocals) {
final Long latestFlag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
final Long newFlag = Long.valueOf(latestFlag.intValue() | 1 << 17);
tempMethodFlags.add(newFlag);
codeMaxStack.add(maxStack);
if ((newFlag.longValue() & 1 << 3) == 0) { // not static
maxLocals--; // minus 'this' local
}
maxLocals -= numMethodArgs;
codeMaxLocals.add(maxLocals);
}
public void addMethod(int flags, final String name, final String desc, final String signature, final String[] exceptions) {
final CPNameAndType nt = cpBands.getCPNameAndType(name, desc);
tempMethodDesc.add(nt);
if (signature != null) {
methodSignature.add(cpBands.getCPSignature(signature));
flags |= 1 << 19;
}
if (exceptions != null) {
methodExceptionNumber.add(exceptions.length);
for (final String exception : exceptions) {
methodExceptionClasses.add(cpBands.getCPClass(exception));
}
flags |= 1 << 18;
}
if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
flags &= ~Opcodes.ACC_DEPRECATED;
flags |= 1 << 20;
}
tempMethodFlags.add(Long.valueOf(flags));
numMethodArgs = countArgs(desc);
if (!anySyntheticMethods && (flags & 1 << 12) != 0 && segment.getCurrentClassReader().hasSyntheticAttributes()) {
cpBands.addCPUtf8("Synthetic");
anySyntheticMethods = true;
}
}
public void addMethodAttribute(final NewAttribute attribute) {
final String attributeName = attribute.type;
for (final NewAttributeBands bands : methodAttributeBands) {
if (bands.getAttributeName().equals(attributeName)) {
bands.addAttribute(attribute);
final int flagIndex = bands.getFlagIndex();
final Long flags = tempMethodFlags.remove(tempMethodFlags.size() - 1);
tempMethodFlags.add(Long.valueOf(flags.longValue() | 1 << flagIndex));
return;
}
}
throw new IllegalArgumentException("No suitable definition for " + attributeName);
}
public void addParameterAnnotation(final int parameter, final String desc, final boolean visible, final List nameRU, final List tags,
final List values, final List caseArrayN, final List nestTypeRS, final List nestNameRU,
final List nestPairN) {
if (visible) {
if (tempMethodRVPA == null) {
tempMethodRVPA = new TempParamAnnotation(numMethodArgs);
tempMethodRVPA.addParameterAnnotation(parameter, desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
}
final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
tempMethodFlags.add(Long.valueOf(flag.longValue() | 1 << 23));
} else {
if (tempMethodRIPA == null) {
tempMethodRIPA = new TempParamAnnotation(numMethodArgs);
tempMethodRIPA.addParameterAnnotation(parameter, desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
}
final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
tempMethodFlags.add(Long.valueOf(flag.longValue() | 1 << 24));
}
}
public void addSourceFile(final String source) {
String implicitSourceFileName = class_this[index].toString();
if (implicitSourceFileName.indexOf('$') != -1) {
implicitSourceFileName = implicitSourceFileName.substring(0, implicitSourceFileName.indexOf('$'));
}
implicitSourceFileName = implicitSourceFileName.substring(implicitSourceFileName.lastIndexOf('/') + 1) + ".java";
if (source.equals(implicitSourceFileName)) {
classSourceFile.add(null);
} else {
classSourceFile.add(cpBands.getCPUtf8(source));
}
class_flags[index] |= 1 << 17;
}
private void createNewAttributeBands() throws IOException {
for (final AttributeDefinition def : attrBands.getClassAttributeLayouts()) {
classAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
}
for (final AttributeDefinition def : attrBands.getMethodAttributeLayouts()) {
methodAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
}
for (final AttributeDefinition def : attrBands.getFieldAttributeLayouts()) {
fieldAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
}
for (final AttributeDefinition def : attrBands.getCodeAttributeLayouts()) {
codeAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
}
}
public void currentClassReferencesInnerClass(final CPClass inner) {
if (!(index >= class_this.length)) {
final CPClass currentClass = class_this[index];
if (currentClass != null && !currentClass.equals(inner) && !isInnerClassOf(currentClass.toString(), inner)) {
classReferencesInnerClass.computeIfAbsent(currentClass, c -> new HashSet<>()).add(inner);
}
}
}
public void doBciRenumbering(final IntList bciRenumbering, final Map labelsToOffsets) {
renumberBci(codeLineNumberTableBciP, bciRenumbering, labelsToOffsets);
renumberBci(codeLocalVariableTableBciP, bciRenumbering, labelsToOffsets);
renumberOffsetBci(codeLocalVariableTableBciP, codeLocalVariableTableSpanO, bciRenumbering, labelsToOffsets);
renumberBci(codeLocalVariableTypeTableBciP, bciRenumbering, labelsToOffsets);
renumberOffsetBci(codeLocalVariableTypeTableBciP, codeLocalVariableTypeTableSpanO, bciRenumbering, labelsToOffsets);
renumberBci(codeHandlerStartP, bciRenumbering, labelsToOffsets);
renumberOffsetBci(codeHandlerStartP, codeHandlerEndPO, bciRenumbering, labelsToOffsets);
renumberDoubleOffsetBci(codeHandlerStartP, codeHandlerEndPO, codeHandlerCatchPO, bciRenumbering, labelsToOffsets);
for (final NewAttributeBands newAttributeBandSet : classAttributeBands) {
newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
}
for (final NewAttributeBands newAttributeBandSet : methodAttributeBands) {
newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
}
for (final NewAttributeBands newAttributeBandSet : fieldAttributeBands) {
newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
}
for (final NewAttributeBands newAttributeBandSet : codeAttributeBands) {
newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
}
}
public void endOfClass() { // All the data for the current class has been
// read
final int numFields = tempFieldDesc.size();
class_field_count[index] = numFields;
field_descr[index] = new CPNameAndType[numFields];
field_flags[index] = new long[numFields];
for (int i = 0; i < numFields; i++) {
field_descr[index][i] = tempFieldDesc.get(i);
field_flags[index][i] = tempFieldFlags.get(i).longValue();
}
final int numMethods = tempMethodDesc.size();
class_method_count[index] = numMethods;
method_descr[index] = new CPNameAndType[numMethods];
method_flags[index] = new long[numMethods];
for (int i = 0; i < numMethods; i++) {
method_descr[index][i] = tempMethodDesc.get(i);
method_flags[index][i] = tempMethodFlags.get(i).longValue();
}
tempFieldDesc.clear();
tempFieldFlags.clear();
tempMethodDesc.clear();
tempMethodFlags.clear();
index++;
}
public void endOfMethod() {
if (tempMethodRVPA != null) {
method_RVPA_bands.addParameterAnnotation(tempMethodRVPA.numParams, tempMethodRVPA.annoN, tempMethodRVPA.pairN, tempMethodRVPA.typeRS,
tempMethodRVPA.nameRU, tempMethodRVPA.tags, tempMethodRVPA.values, tempMethodRVPA.caseArrayN, tempMethodRVPA.nestTypeRS,
tempMethodRVPA.nestNameRU, tempMethodRVPA.nestPairN);
tempMethodRVPA = null;
}
if (tempMethodRIPA != null) {
method_RIPA_bands.addParameterAnnotation(tempMethodRIPA.numParams, tempMethodRIPA.annoN, tempMethodRIPA.pairN, tempMethodRIPA.typeRS,
tempMethodRIPA.nameRU, tempMethodRIPA.tags, tempMethodRIPA.values, tempMethodRIPA.caseArrayN, tempMethodRIPA.nestTypeRS,
tempMethodRIPA.nestNameRU, tempMethodRIPA.nestPairN);
tempMethodRIPA = null;
}
if (codeFlags.size() > 0) {
final long latestCodeFlag = codeFlags.get(codeFlags.size() - 1).longValue();
final int latestLocalVariableTableN = codeLocalVariableTableN.get(codeLocalVariableTableN.size() - 1);
if (latestCodeFlag == 1 << 2 && latestLocalVariableTableN == 0) {
codeLocalVariableTableN.remove(codeLocalVariableTableN.size() - 1);
codeFlags.remove(codeFlags.size() - 1);
codeFlags.add(Long.valueOf(0));
}
}
}
/**
* All input classes for the segment have now been read in, so this method is called so that this class can calculate/complete anything it could not do
* while classes were being read.
*/
public void finaliseBands() {
final int defaultMajorVersion = segmentHeader.getDefaultMajorVersion();
for (int i = 0; i < class_flags.length; i++) {
final int major = major_versions[i];
if (major != defaultMajorVersion) {
class_flags[i] |= 1 << 24;
classFileVersionMajor.add(major);
classFileVersionMinor.add(0);
}
}
// Calculate code headers
codeHeaders = new int[codeHandlerCount.size()];
int removed = 0;
for (int i = 0; i < codeHeaders.length; i++) {
final int numHandlers = codeHandlerCount.get(i - removed);
final int maxLocals = codeMaxLocals.get(i - removed);
final int maxStack = codeMaxStack.get(i - removed);
switch (numHandlers) {
case 0: {
final int header = maxLocals * 12 + maxStack + 1;
if (header < 145 && maxStack < 12) {
codeHeaders[i] = header;
}
break;
}
case 1: {
final int header = maxLocals * 8 + maxStack + 145;
if (header < 209 && maxStack < 8) {
codeHeaders[i] = header;
}
break;
}
case 2: {
final int header = maxLocals * 7 + maxStack + 209;
if (header < 256 && maxStack < 7) {
codeHeaders[i] = header;
}
break;
}
default:
break;
}
if (codeHeaders[i] != 0) { // Remove the redundant values from
// codeHandlerCount, codeMaxLocals and
// codeMaxStack
codeHandlerCount.remove(i - removed);
codeMaxLocals.remove(i - removed);
codeMaxStack.remove(i - removed);
removed++;
} else if (!segment.getSegmentHeader().have_all_code_flags()) {
codeFlags.add(Long.valueOf(0));
}
}
// Compute any required IcLocals
final IntList innerClassesN = new IntList();
final List icLocal = new ArrayList<>();
for (int i = 0; i < class_this.length; i++) {
final CPClass cpClass = class_this[i];
final Set referencedInnerClasses = classReferencesInnerClass.get(cpClass);
if (referencedInnerClasses != null) {
int innerN = 0;
final List innerClasses = segment.getIcBands().getInnerClassesForOuter(cpClass.toString());
if (innerClasses != null) {
for (final IcTuple element : innerClasses) {
referencedInnerClasses.remove(element.C);
}
}
for (final CPClass inner : referencedInnerClasses) {
final IcTuple icTuple = segment.getIcBands().getIcTuple(inner);
if (icTuple != null && !icTuple.isAnonymous()) {
// should transmit an icLocal entry
icLocal.add(icTuple);
innerN++;
}
}
if (innerN != 0) {
innerClassesN.add(innerN);
class_flags[i] |= 1 << 23;
}
}
}
class_InnerClasses_N = innerClassesN.toArray();
class_InnerClasses_RC = new CPClass[icLocal.size()];
class_InnerClasses_F = new int[icLocal.size()];
classInnerClassesOuterRCN = new ArrayList<>();
classInnerClassesNameRUN = new ArrayList<>();
for (int i = 0; i < class_InnerClasses_RC.length; i++) {
final IcTuple icTuple = icLocal.get(i);
class_InnerClasses_RC[i] = icTuple.C;
if (icTuple.C2 == null && icTuple.N == null) {
class_InnerClasses_F[i] = 0;
} else {
if (icTuple.F == 0) {
class_InnerClasses_F[i] = 0x00010000;
} else {
class_InnerClasses_F[i] = icTuple.F;
}
classInnerClassesOuterRCN.add(icTuple.C2);
classInnerClassesNameRUN.add(icTuple.N);
}
}
// Calculate any backwards calls from metadata bands
final IntList classAttrCalls = new IntList();
final IntList fieldAttrCalls = new IntList();
final IntList methodAttrCalls = new IntList();
final IntList codeAttrCalls = new IntList();
if (class_RVA_bands.hasContent()) {
classAttrCalls.add(class_RVA_bands.numBackwardsCalls());
}
if (class_RIA_bands.hasContent()) {
classAttrCalls.add(class_RIA_bands.numBackwardsCalls());
}
if (field_RVA_bands.hasContent()) {
fieldAttrCalls.add(field_RVA_bands.numBackwardsCalls());
}
if (field_RIA_bands.hasContent()) {
fieldAttrCalls.add(field_RIA_bands.numBackwardsCalls());
}
if (method_RVA_bands.hasContent()) {
methodAttrCalls.add(method_RVA_bands.numBackwardsCalls());
}
if (method_RIA_bands.hasContent()) {
methodAttrCalls.add(method_RIA_bands.numBackwardsCalls());
}
if (method_RVPA_bands.hasContent()) {
methodAttrCalls.add(method_RVPA_bands.numBackwardsCalls());
}
if (method_RIPA_bands.hasContent()) {
methodAttrCalls.add(method_RIPA_bands.numBackwardsCalls());
}
if (method_AD_bands.hasContent()) {
methodAttrCalls.add(method_AD_bands.numBackwardsCalls());
}
// Sort non-predefined attribute bands
final Comparator comparator = (arg0, arg1) -> arg0.getFlagIndex() - arg1.getFlagIndex();
classAttributeBands.sort(comparator);
methodAttributeBands.sort(comparator);
fieldAttributeBands.sort(comparator);
codeAttributeBands.sort(comparator);
for (final NewAttributeBands bands : classAttributeBands) {
if (bands.isUsedAtLeastOnce()) {
for (final int backwardsCallCount : bands.numBackwardsCalls()) {
classAttrCalls.add(backwardsCallCount);
}
}
}
for (final NewAttributeBands bands : methodAttributeBands) {
if (bands.isUsedAtLeastOnce()) {
for (final int backwardsCallCount : bands.numBackwardsCalls()) {
methodAttrCalls.add(backwardsCallCount);
}
}
}
for (final NewAttributeBands bands : fieldAttributeBands) {
if (bands.isUsedAtLeastOnce()) {
for (final int backwardsCallCount : bands.numBackwardsCalls()) {
fieldAttrCalls.add(backwardsCallCount);
}
}
}
for (final NewAttributeBands bands : codeAttributeBands) {
if (bands.isUsedAtLeastOnce()) {
for (final int backwardsCallCount : bands.numBackwardsCalls()) {
codeAttrCalls.add(backwardsCallCount);
}
}
}
class_attr_calls = classAttrCalls.toArray();
field_attr_calls = fieldAttrCalls.toArray();
method_attr_calls = methodAttrCalls.toArray();
code_attr_calls = codeAttrCalls.toArray();
}
private int[] getInts(final CPClass[] cpClasses) {
final int[] ints = new int[cpClasses.length];
for (int i = 0; i < ints.length; i++) {
if (cpClasses[i] != null) {
ints[i] = cpClasses[i].getIndex();
}
}
return ints;
}
public boolean isAnySyntheticClasses() {
return anySyntheticClasses;
}
public boolean isAnySyntheticFields() {
return anySyntheticFields;
}
public boolean isAnySyntheticMethods() {
return anySyntheticMethods;
}
private boolean isInnerClass(final String possibleInner) {
return possibleInner.indexOf('$') != -1;
}
private boolean isInnerClassOf(final String possibleInner, final CPClass possibleOuter) {
if (isInnerClass(possibleInner)) {
final String superClassName = possibleInner.substring(0, possibleInner.lastIndexOf('$'));
if (superClassName.equals(possibleOuter.toString())) {
return true;
}
return isInnerClassOf(superClassName, possibleOuter);
}
return false;
}
public int numClassesProcessed() {
return index;
}
@Override
public void pack(final OutputStream out) throws IOException, Pack200Exception {
PackingUtils.log("Writing class bands...");
byte[] encodedBand = encodeBandInt("class_this", getInts(class_this), Codec.DELTA5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_this[" + class_this.length + "]");
encodedBand = encodeBandInt("class_super", getInts(class_super), Codec.DELTA5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_super[" + class_super.length + "]");
encodedBand = encodeBandInt("class_interface_count", class_interface_count, Codec.DELTA5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_interface_count[" + class_interface_count.length + "]");
final int totalInterfaces = sum(class_interface_count);
final int[] classInterface = new int[totalInterfaces];
int k = 0;
for (final CPClass[] element : class_interface) {
if (element != null) {
for (final CPClass cpClass : element) {
classInterface[k] = cpClass.getIndex();
k++;
}
}
}
encodedBand = encodeBandInt("class_interface", classInterface, Codec.DELTA5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_interface[" + classInterface.length + "]");
encodedBand = encodeBandInt("class_field_count", class_field_count, Codec.DELTA5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_field_count[" + class_field_count.length + "]");
encodedBand = encodeBandInt("class_method_count", class_method_count, Codec.DELTA5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_method_count[" + class_method_count.length + "]");
final int totalFields = sum(class_field_count);
final int[] fieldDescr = new int[totalFields];
k = 0;
for (int i = 0; i < index; i++) {
for (int j = 0; j < field_descr[i].length; j++) {
final CPNameAndType descr = field_descr[i][j];
fieldDescr[k] = descr.getIndex();
k++;
}
}
encodedBand = encodeBandInt("field_descr", fieldDescr, Codec.DELTA5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from field_descr[" + fieldDescr.length + "]");
writeFieldAttributeBands(out);
final int totalMethods = sum(class_method_count);
final int[] methodDescr = new int[totalMethods];
k = 0;
for (int i = 0; i < index; i++) {
for (int j = 0; j < method_descr[i].length; j++) {
final CPNameAndType descr = method_descr[i][j];
methodDescr[k] = descr.getIndex();
k++;
}
}
encodedBand = encodeBandInt("method_descr", methodDescr, Codec.MDELTA5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from method_descr[" + methodDescr.length + "]");
writeMethodAttributeBands(out);
writeClassAttributeBands(out);
writeCodeBands(out);
}
/**
* Remove all entries for the current class
*/
public void removeCurrentClass() {
// Note - this doesn't remove any entries added to the constant pool but
// that shouldn't be a problem
if ((class_flags[index] & 1 << 17) != 0) {
classSourceFile.remove(classSourceFile.size() - 1);
}
if ((class_flags[index] & 1 << 18) != 0) {
classEnclosingMethodClass.remove(classEnclosingMethodClass.size() - 1);
classEnclosingMethodDesc.remove(classEnclosingMethodDesc.size() - 1);
}
if ((class_flags[index] & 1 << 19) != 0) {
classSignature.remove(classSignature.size() - 1);
}
if ((class_flags[index] & 1 << 21) != 0) {
class_RVA_bands.removeLatest();
}
if ((class_flags[index] & 1 << 22) != 0) {
class_RIA_bands.removeLatest();
}
for (final Long flagsL : tempFieldFlags) {
final long flags = flagsL.longValue();
if ((flags & 1 << 19) != 0) {
fieldSignature.remove(fieldSignature.size() - 1);
}
if ((flags & 1 << 17) != 0) {
fieldConstantValueKQ.remove(fieldConstantValueKQ.size() - 1);
}
if ((flags & 1 << 21) != 0) {
field_RVA_bands.removeLatest();
}
if ((flags & 1 << 22) != 0) {
field_RIA_bands.removeLatest();
}
}
for (final Long flagsL : tempMethodFlags) {
final long flags = flagsL.longValue();
if ((flags & 1 << 19) != 0) {
methodSignature.remove(methodSignature.size() - 1);
}
if ((flags & 1 << 18) != 0) {
final int exceptions = methodExceptionNumber.remove(methodExceptionNumber.size() - 1);
for (int i = 0; i < exceptions; i++) {
methodExceptionClasses.remove(methodExceptionClasses.size() - 1);
}
}
if ((flags & 1 << 17) != 0) { // has code attribute
codeMaxLocals.remove(codeMaxLocals.size() - 1);
codeMaxStack.remove(codeMaxStack.size() - 1);
final int handlers = codeHandlerCount.remove(codeHandlerCount.size() - 1);
for (int i = 0; i < handlers; i++) {
final int index = codeHandlerStartP.size() - 1;
codeHandlerStartP.remove(index);
codeHandlerEndPO.remove(index);
codeHandlerCatchPO.remove(index);
codeHandlerClass.remove(index);
}
if (!stripDebug) {
final long cdeFlags = codeFlags.remove(codeFlags.size() - 1).longValue();
final int numLocalVariables = codeLocalVariableTableN.remove(codeLocalVariableTableN.size() - 1);
for (int i = 0; i < numLocalVariables; i++) {
final int location = codeLocalVariableTableBciP.size() - 1;
codeLocalVariableTableBciP.remove(location);
codeLocalVariableTableSpanO.remove(location);
codeLocalVariableTableNameRU.remove(location);
codeLocalVariableTableTypeRS.remove(location);
codeLocalVariableTableSlot.remove(location);
}
if ((cdeFlags & 1 << 3) != 0) {
final int numLocalVariablesInTypeTable = codeLocalVariableTypeTableN.remove(codeLocalVariableTypeTableN.size() - 1);
for (int i = 0; i < numLocalVariablesInTypeTable; i++) {
final int location = codeLocalVariableTypeTableBciP.size() - 1;
codeLocalVariableTypeTableBciP.remove(location);
codeLocalVariableTypeTableSpanO.remove(location);
codeLocalVariableTypeTableNameRU.remove(location);
codeLocalVariableTypeTableTypeRS.remove(location);
codeLocalVariableTypeTableSlot.remove(location);
}
}
if ((cdeFlags & 1 << 1) != 0) {
final int numLineNumbers = codeLineNumberTableN.remove(codeLineNumberTableN.size() - 1);
for (int i = 0; i < numLineNumbers; i++) {
final int location = codeLineNumberTableBciP.size() - 1;
codeLineNumberTableBciP.remove(location);
codeLineNumberTableLine.remove(location);
}
}
}
}
if ((flags & 1 << 21) != 0) {
method_RVA_bands.removeLatest();
}
if ((flags & 1 << 22) != 0) {
method_RIA_bands.removeLatest();
}
if ((flags & 1 << 23) != 0) {
method_RVPA_bands.removeLatest();
}
if ((flags & 1 << 24) != 0) {
method_RIPA_bands.removeLatest();
}
if ((flags & 1 << 25) != 0) {
method_AD_bands.removeLatest();
}
}
class_this[index] = null;
class_super[index] = null;
class_interface_count[index] = 0;
class_interface[index] = null;
major_versions[index] = 0;
class_flags[index] = 0;
tempFieldDesc.clear();
tempFieldFlags.clear();
tempMethodDesc.clear();
tempMethodFlags.clear();
if (index > 0) {
index--;
}
}
private void renumberBci(final List list, final IntList bciRenumbering, final Map labelsToOffsets) {
for (int i = list.size() - 1; i >= 0; i--) {
final Object label = list.get(i);
if (label instanceof Integer) {
break;
}
if (label instanceof Label) {
list.remove(i);
final Integer bytecodeIndex = labelsToOffsets.get(label);
list.add(i, Integer.valueOf(bciRenumbering.get(bytecodeIndex.intValue())));
}
}
}
private void renumberDoubleOffsetBci(final List relative, final List firstOffset, final List list, final IntList bciRenumbering,
final Map labelsToOffsets) {
// TODO: There's probably a nicer way of doing this...
for (int i = list.size() - 1; i >= 0; i--) {
final Object label = list.get(i);
if (label instanceof Integer) {
break;
}
if (label instanceof Label) {
list.remove(i);
final Integer bytecodeIndex = labelsToOffsets.get(label);
final Integer renumberedOffset = Integer
.valueOf(bciRenumbering.get(bytecodeIndex.intValue()) - relative.get(i).intValue() - firstOffset.get(i).intValue());
list.add(i, renumberedOffset);
}
}
}
private void renumberOffsetBci(final List relative, final List list, final IntList bciRenumbering,
final Map labelsToOffsets) {
for (int i = list.size() - 1; i >= 0; i--) {
final Object label = list.get(i);
if (label instanceof Integer) {
break;
}
if (label instanceof Label) {
list.remove(i);
final Integer bytecodeIndex = labelsToOffsets.get(label);
final Integer renumberedOffset = Integer.valueOf(bciRenumbering.get(bytecodeIndex.intValue()) - relative.get(i).intValue());
list.add(i, renumberedOffset);
}
}
}
private int sum(final int[] ints) {
int sum = 0;
for (final int j : ints) {
sum += j;
}
return sum;
}
private void writeClassAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
byte[] encodedBand = encodeFlags("class_flags", class_flags, Codec.UNSIGNED5, Codec.UNSIGNED5, segmentHeader.have_class_flags_hi());
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_flags[" + class_flags.length + "]");
// These bands are not needed, but could be used to reduce the size of
// the archive if there are enough different non-standard attributes
// defined that segmentHeader.have_class_flags_hi() is true. The same
// applies to method_attr_count, field_attr_count, code_attr_count etc.
// *class_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
// *class_attr_indexes :UNSIGNED5 [SUM(*class_attr_count)]
encodedBand = encodeBandInt("class_attr_calls", class_attr_calls, Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_attr_calls[" + class_attr_calls.length + "]");
encodedBand = encodeBandInt("classSourceFile", cpEntryOrNullListToArray(classSourceFile), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from classSourceFile[" + classSourceFile.size() + "]");
encodedBand = encodeBandInt("class_enclosing_method_RC", cpEntryListToArray(classEnclosingMethodClass), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_enclosing_method_RC[" + classEnclosingMethodClass.size() + "]");
encodedBand = encodeBandInt("class_EnclosingMethod_RDN", cpEntryOrNullListToArray(classEnclosingMethodDesc), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_EnclosingMethod_RDN[" + classEnclosingMethodDesc.size() + "]");
encodedBand = encodeBandInt("class_Signature_RS", cpEntryListToArray(classSignature), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_Signature_RS[" + classSignature.size() + "]");
class_RVA_bands.pack(out);
class_RIA_bands.pack(out);
encodedBand = encodeBandInt("class_InnerClasses_N", class_InnerClasses_N, Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_N[" + class_InnerClasses_N.length + "]");
encodedBand = encodeBandInt("class_InnerClasses_RC", getInts(class_InnerClasses_RC), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_RC[" + class_InnerClasses_RC.length + "]");
encodedBand = encodeBandInt("class_InnerClasses_F", class_InnerClasses_F, Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_F[" + class_InnerClasses_F.length + "]");
encodedBand = encodeBandInt("class_InnerClasses_outer_RCN", cpEntryOrNullListToArray(classInnerClassesOuterRCN), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_outer_RCN[" + classInnerClassesOuterRCN.size() + "]");
encodedBand = encodeBandInt("class_InnerClasses_name_RUN", cpEntryOrNullListToArray(classInnerClassesNameRUN), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_name_RUN[" + classInnerClassesNameRUN.size() + "]");
encodedBand = encodeBandInt("classFileVersionMinor", classFileVersionMinor.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from classFileVersionMinor[" + classFileVersionMinor.size() + "]");
encodedBand = encodeBandInt("classFileVersionMajor", classFileVersionMajor.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from classFileVersionMajor[" + classFileVersionMajor.size() + "]");
for (final NewAttributeBands classAttributeBand : classAttributeBands) {
classAttributeBand.pack(out);
}
}
private void writeCodeAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
byte[] encodedBand = encodeFlags("codeFlags", longListToArray(codeFlags), Codec.UNSIGNED5, Codec.UNSIGNED5, segmentHeader.have_code_flags_hi());
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeFlags[" + codeFlags.size() + "]");
// *code_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
// *code_attr_indexes :UNSIGNED5 [SUM(*code_attr_count)]
encodedBand = encodeBandInt("code_attr_calls", code_attr_calls, Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_attr_calls[" + code_attr_calls.length + "]");
encodedBand = encodeBandInt("code_LineNumberTable_N", codeLineNumberTableN.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LineNumberTable_N[" + codeLineNumberTableN.size() + "]");
encodedBand = encodeBandInt("code_LineNumberTable_bci_P", integerListToArray(codeLineNumberTableBciP), Codec.BCI5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LineNumberTable_bci_P[" + codeLineNumberTableBciP.size() + "]");
encodedBand = encodeBandInt("code_LineNumberTable_line", codeLineNumberTableLine.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LineNumberTable_line[" + codeLineNumberTableLine.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTable_N", codeLocalVariableTableN.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_N[" + codeLocalVariableTableN.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTable_bci_P", integerListToArray(codeLocalVariableTableBciP), Codec.BCI5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_bci_P[" + codeLocalVariableTableBciP.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTable_span_O", integerListToArray(codeLocalVariableTableSpanO), Codec.BRANCH5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_span_O[" + codeLocalVariableTableSpanO.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTable_name_RU", cpEntryListToArray(codeLocalVariableTableNameRU), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_name_RU[" + codeLocalVariableTableNameRU.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTable_type_RS", cpEntryListToArray(codeLocalVariableTableTypeRS), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_type_RS[" + codeLocalVariableTableTypeRS.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTable_slot", codeLocalVariableTableSlot.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_slot[" + codeLocalVariableTableSlot.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTypeTable_N", codeLocalVariableTypeTableN.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_N[" + codeLocalVariableTypeTableN.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTypeTable_bci_P", integerListToArray(codeLocalVariableTypeTableBciP), Codec.BCI5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_bci_P[" + codeLocalVariableTypeTableBciP.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTypeTable_span_O", integerListToArray(codeLocalVariableTypeTableSpanO), Codec.BRANCH5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_span_O[" + codeLocalVariableTypeTableSpanO.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTypeTable_name_RU", cpEntryListToArray(codeLocalVariableTypeTableNameRU), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_name_RU[" + codeLocalVariableTypeTableNameRU.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTypeTable_type_RS", cpEntryListToArray(codeLocalVariableTypeTableTypeRS), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_type_RS[" + codeLocalVariableTypeTableTypeRS.size() + "]");
encodedBand = encodeBandInt("code_LocalVariableTypeTable_slot", codeLocalVariableTypeTableSlot.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_slot[" + codeLocalVariableTypeTableSlot.size() + "]");
for (final NewAttributeBands bands : codeAttributeBands) {
bands.pack(out);
}
}
private void writeCodeBands(final OutputStream out) throws IOException, Pack200Exception {
byte[] encodedBand = encodeBandInt("codeHeaders", codeHeaders, Codec.BYTE1);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeHeaders[" + codeHeaders.length + "]");
encodedBand = encodeBandInt("codeMaxStack", codeMaxStack.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeMaxStack[" + codeMaxStack.size() + "]");
encodedBand = encodeBandInt("codeMaxLocals", codeMaxLocals.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeMaxLocals[" + codeMaxLocals.size() + "]");
encodedBand = encodeBandInt("codeHandlerCount", codeHandlerCount.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeHandlerCount[" + codeHandlerCount.size() + "]");
encodedBand = encodeBandInt("codeHandlerStartP", integerListToArray(codeHandlerStartP), Codec.BCI5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeHandlerStartP[" + codeHandlerStartP.size() + "]");
encodedBand = encodeBandInt("codeHandlerEndPO", integerListToArray(codeHandlerEndPO), Codec.BRANCH5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeHandlerEndPO[" + codeHandlerEndPO.size() + "]");
encodedBand = encodeBandInt("codeHandlerCatchPO", integerListToArray(codeHandlerCatchPO), Codec.BRANCH5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeHandlerCatchPO[" + codeHandlerCatchPO.size() + "]");
encodedBand = encodeBandInt("codeHandlerClass", cpEntryOrNullListToArray(codeHandlerClass), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeHandlerClass[" + codeHandlerClass.size() + "]");
writeCodeAttributeBands(out);
}
private void writeFieldAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
byte[] encodedBand = encodeFlags("field_flags", field_flags, Codec.UNSIGNED5, Codec.UNSIGNED5, segmentHeader.have_field_flags_hi());
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from field_flags[" + field_flags.length + "]");
// *field_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
// *field_attr_indexes :UNSIGNED5 [SUM(*field_attr_count)]
encodedBand = encodeBandInt("field_attr_calls", field_attr_calls, Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from field_attr_calls[" + field_attr_calls.length + "]");
encodedBand = encodeBandInt("fieldConstantValueKQ", cpEntryListToArray(fieldConstantValueKQ), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from fieldConstantValueKQ[" + fieldConstantValueKQ.size() + "]");
encodedBand = encodeBandInt("fieldSignature", cpEntryListToArray(fieldSignature), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from fieldSignature[" + fieldSignature.size() + "]");
field_RVA_bands.pack(out);
field_RIA_bands.pack(out);
for (final NewAttributeBands bands : fieldAttributeBands) {
bands.pack(out);
}
}
private void writeMethodAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
byte[] encodedBand = encodeFlags("method_flags", method_flags, Codec.UNSIGNED5, Codec.UNSIGNED5, segmentHeader.have_method_flags_hi());
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from method_flags[" + method_flags.length + "]");
// *method_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
// *method_attr_indexes :UNSIGNED5 [SUM(*method_attr_count)]
encodedBand = encodeBandInt("method_attr_calls", method_attr_calls, Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from method_attr_calls[" + method_attr_calls.length + "]");
encodedBand = encodeBandInt("methodExceptionNumber", methodExceptionNumber.toArray(), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from methodExceptionNumber[" + methodExceptionNumber.size() + "]");
encodedBand = encodeBandInt("methodExceptionClasses", cpEntryListToArray(methodExceptionClasses), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from methodExceptionClasses[" + methodExceptionClasses.size() + "]");
encodedBand = encodeBandInt("methodSignature", cpEntryListToArray(methodSignature), Codec.UNSIGNED5);
out.write(encodedBand);
PackingUtils.log("Wrote " + encodedBand.length + " bytes from methodSignature[" + methodSignature.size() + "]");
method_RVA_bands.pack(out);
method_RIA_bands.pack(out);
method_RVPA_bands.pack(out);
method_RIPA_bands.pack(out);
method_AD_bands.pack(out);
for (final NewAttributeBands bands : methodAttributeBands) {
bands.pack(out);
}
}
}