Fields Summary |
---|
private final com.android.dexgen.rop.cst.CstType | thisClass{@code non-null;} what class this data is for, just for listing generation |
private final ArrayList | staticFields{@code non-null;} list of static fields |
private final HashMap | staticValues{@code non-null;} list of initial values for static fields |
private final ArrayList | instanceFields{@code non-null;} list of instance fields |
private final ArrayList | directMethods{@code non-null;} list of direct methods |
private final ArrayList | virtualMethods{@code non-null;} list of virtual methods |
private com.android.dexgen.rop.cst.CstArray | staticValuesConstant{@code null-ok;} static initializer list; set in {@link #addContents} |
private byte[] | encodedForm{@code null-ok;} encoded form, ready for writing to a file; set during
{@link #place0} |
Methods Summary |
---|
public void | addContents(DexFile file){@inheritDoc}
if (!staticFields.isEmpty()) {
getStaticValuesConstant(); // Force the fields to be sorted.
for (EncodedField field : staticFields) {
field.addContents(file);
}
}
if (!instanceFields.isEmpty()) {
Collections.sort(instanceFields);
for (EncodedField field : instanceFields) {
field.addContents(file);
}
}
if (!directMethods.isEmpty()) {
Collections.sort(directMethods);
for (EncodedMethod method : directMethods) {
method.addContents(file);
}
}
if (!virtualMethods.isEmpty()) {
Collections.sort(virtualMethods);
for (EncodedMethod method : virtualMethods) {
method.addContents(file);
}
}
|
public void | addDirectMethod(EncodedMethod method)Adds a direct ({@code static} and/or {@code private}) method.
if (method == null) {
throw new NullPointerException("method == null");
}
directMethods.add(method);
|
public void | addInstanceField(EncodedField field)Adds an instance field.
if (field == null) {
throw new NullPointerException("field == null");
}
instanceFields.add(field);
|
public void | addStaticField(EncodedField field, com.android.dexgen.rop.cst.Constant value)Adds a static field.
if (field == null) {
throw new NullPointerException("field == null");
}
if (staticValuesConstant != null) {
throw new UnsupportedOperationException(
"static fields already sorted");
}
staticFields.add(field);
staticValues.put(field, value);
|
public void | addVirtualMethod(EncodedMethod method)Adds a virtual method.
if (method == null) {
throw new NullPointerException("method == null");
}
virtualMethods.add(method);
|
public void | debugPrint(java.io.Writer out, boolean verbose)Prints out the contents of this instance, in a debugging-friendly
way.
PrintWriter pw = Writers.printWriterFor(out);
int sz = staticFields.size();
for (int i = 0; i < sz; i++) {
pw.println(" sfields[" + i + "]: " + staticFields.get(i));
}
sz = instanceFields.size();
for (int i = 0; i < sz; i++) {
pw.println(" ifields[" + i + "]: " + instanceFields.get(i));
}
sz = directMethods.size();
for (int i = 0; i < sz; i++) {
pw.println(" dmeths[" + i + "]:");
directMethods.get(i).debugPrint(pw, verbose);
}
sz = virtualMethods.size();
for (int i = 0; i < sz; i++) {
pw.println(" vmeths[" + i + "]:");
virtualMethods.get(i).debugPrint(pw, verbose);
}
|
private static void | encodeList(DexFile file, com.android.dexgen.util.AnnotatedOutput out, java.lang.String label, java.util.ArrayList list)Helper for {@link #encodeOutput}, which writes out the given
list. It also annotates the items (if any and if annotations
are enabled).
int size = list.size();
int lastIndex = 0;
if (size == 0) {
return;
}
if (out.annotates()) {
out.annotate(0, " " + label + ":");
}
for (int i = 0; i < size; i++) {
lastIndex = list.get(i).encode(file, out, lastIndex, i);
}
|
private void | encodeOutput(DexFile file, com.android.dexgen.util.AnnotatedOutput out)Writes out the encoded form of this instance.
boolean annotates = out.annotates();
if (annotates) {
out.annotate(0, offsetString() + " class data for " +
thisClass.toHuman());
}
encodeSize(file, out, "static_fields", staticFields.size());
encodeSize(file, out, "instance_fields", instanceFields.size());
encodeSize(file, out, "direct_methods", directMethods.size());
encodeSize(file, out, "virtual_methods", virtualMethods.size());
encodeList(file, out, "static_fields", staticFields);
encodeList(file, out, "instance_fields", instanceFields);
encodeList(file, out, "direct_methods", directMethods);
encodeList(file, out, "virtual_methods", virtualMethods);
if (annotates) {
out.endAnnotation();
}
|
private static void | encodeSize(DexFile file, com.android.dexgen.util.AnnotatedOutput out, java.lang.String label, int size)Helper for {@link #encodeOutput}, which writes out the given
size value, annotating it as well (if annotations are enabled).
if (out.annotates()) {
out.annotate(String.format(" %-21s %08x", label + "_size:",
size));
}
out.writeUnsignedLeb128(size);
|
public java.util.ArrayList | getMethods()Gets all the methods in this class. The returned list is not linked
in any way to the underlying lists contained in this instance, but
the objects contained in the list are shared.
int sz = directMethods.size() + virtualMethods.size();
ArrayList<EncodedMethod> result = new ArrayList<EncodedMethod>(sz);
result.addAll(directMethods);
result.addAll(virtualMethods);
return result;
|
public com.android.dexgen.rop.cst.CstArray | getStaticValuesConstant()Gets a {@link CstArray} corresponding to {@link #staticValues} if
it contains any non-zero non-{@code null} values.
if ((staticValuesConstant == null) && (staticFields.size() != 0)) {
staticValuesConstant = makeStaticValuesConstant();
}
return staticValuesConstant;
|
public boolean | isEmpty()Returns whether this instance is empty.
return staticFields.isEmpty() && instanceFields.isEmpty()
&& directMethods.isEmpty() && virtualMethods.isEmpty();
|
public ItemType | itemType(){@inheritDoc}
return ItemType.TYPE_CLASS_DATA_ITEM;
|
private com.android.dexgen.rop.cst.CstArray | makeStaticValuesConstant()Gets a {@link CstArray} corresponding to {@link #staticValues} if
it contains any non-zero non-{@code null} values.
// First sort the statics into their final order.
Collections.sort(staticFields);
/*
* Get the size of staticValues minus any trailing zeros/nulls (both
* nulls per se as well as instances of CstKnownNull).
*/
int size = staticFields.size();
while (size > 0) {
EncodedField field = staticFields.get(size - 1);
Constant cst = staticValues.get(field);
if (cst instanceof CstLiteralBits) {
// Note: CstKnownNull extends CstLiteralBits.
if (((CstLiteralBits) cst).getLongBits() != 0) {
break;
}
} else if (cst != null) {
break;
}
size--;
}
if (size == 0) {
return null;
}
// There is something worth encoding, so build up a result.
CstArray.List list = new CstArray.List(size);
for (int i = 0; i < size; i++) {
EncodedField field = staticFields.get(i);
Constant cst = staticValues.get(field);
if (cst == null) {
cst = Zeroes.zeroFor(field.getRef().getType());
}
list.set(i, cst);
}
list.setImmutable();
return new CstArray(list);
|
protected void | place0(Section addedTo, int offset){@inheritDoc}
// Encode the data and note the size.
ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
encodeOutput(addedTo.getFile(), out);
encodedForm = out.toByteArray();
setWriteSize(encodedForm.length);
|
public java.lang.String | toHuman(){@inheritDoc}
return toString();
|
public void | writeTo0(DexFile file, com.android.dexgen.util.AnnotatedOutput out){@inheritDoc}
boolean annotates = out.annotates();
if (annotates) {
/*
* The output is to be annotated, so redo the work previously
* done by place0(), except this time annotations will actually
* get emitted.
*/
encodeOutput(file, out);
} else {
out.write(encodedForm);
}
|