Methods Summary |
---|
public void | add(OffsettedItem item)Adds an item to this instance. This will in turn tell the given item
that it has been added to this instance. It is invalid to add the
same item to more than one instance, nor to add the same items
multiple times to a single instance.
throwIfPrepared();
try {
if (item.getAlignment() > getAlignment()) {
throw new IllegalArgumentException(
"incompatible item alignment");
}
} catch (NullPointerException ex) {
// Elucidate the exception.
throw new NullPointerException("item == null");
}
items.add(item);
|
public T | get(T item)Gets an item which was previously interned.
throwIfNotPrepared();
OffsettedItem result = interns.get(item);
if (result != null) {
return (T) result;
}
throw new NoSuchElementException(item.toString());
|
public int | getAbsoluteItemOffset(Item item){@inheritDoc}
OffsettedItem oi = (OffsettedItem) item;
return oi.getAbsoluteOffset();
|
public T | intern(T item)Interns an item in this instance, returning the interned instance
(which may not be the one passed in). This will add the item if no
equal item has been added.
throwIfPrepared();
OffsettedItem result = interns.get(item);
if (result != null) {
return (T) result;
}
add(item);
interns.put(item, item);
return item;
|
public java.util.Collection | items(){@inheritDoc}
return items;
|
public void | placeItems()Places all the items in this instance at particular offsets. This
will call {@link OffsettedItem#place} on each item. If an item
does not know its write size before the call to {@code place},
it is that call which is responsible for setting the write size.
This method may only be called once per instance; subsequent calls
will throw an exception.
throwIfNotPrepared();
switch (sort) {
case INSTANCE: {
Collections.sort(items);
break;
}
case TYPE: {
Collections.sort(items, TYPE_SORTER);
break;
}
}
int sz = items.size();
int outAt = 0;
for (int i = 0; i < sz; i++) {
OffsettedItem one = items.get(i);
try {
int placedAt = one.place(this, outAt);
if (placedAt < outAt) {
throw new RuntimeException("bogus place() result for " +
one);
}
outAt = placedAt + one.writeSize();
} catch (RuntimeException ex) {
throw ExceptionWithContext.withContext(ex,
"...while placing " + one);
}
}
writeSize = outAt;
|
protected void | prepare0(){@inheritDoc}
DexFile file = getFile();
/*
* It's okay for new items to be added as a result of an
* addContents() call; we just have to deal with the possibility.
*/
int i = 0;
for (;;) {
int sz = items.size();
if (i >= sz) {
break;
}
for (/*i*/; i < sz; i++) {
OffsettedItem one = items.get(i);
one.addContents(file);
}
}
|
public int | size()Gets the size of this instance, in items.
return items.size();
|
public void | writeHeaderPart(com.android.dexgen.util.AnnotatedOutput out)Writes the portion of the file header that refers to this instance.
throwIfNotPrepared();
if (writeSize == -1) {
throw new RuntimeException("write size not yet set");
}
int sz = writeSize;
int offset = (sz == 0) ? 0 : getFileOffset();
String name = getName();
if (name == null) {
name = "<unnamed>";
}
int spaceCount = 15 - name.length();
char[] spaceArr = new char[spaceCount];
Arrays.fill(spaceArr, ' ");
String spaces = new String(spaceArr);
if (out.annotates()) {
out.annotate(4, name + "_size:" + spaces + Hex.u4(sz));
out.annotate(4, name + "_off: " + spaces + Hex.u4(offset));
}
out.writeInt(sz);
out.writeInt(offset);
|
public void | writeIndexAnnotation(com.android.dexgen.util.AnnotatedOutput out, ItemType itemType, java.lang.String intro)Writes an index of contents of the items in this instance of the
given type. If there are none, this writes nothing. If there are any,
then the index is preceded by the given intro string.
throwIfNotPrepared();
TreeMap<String, OffsettedItem> index =
new TreeMap<String, OffsettedItem>();
for (OffsettedItem item : items) {
if (item.itemType() == itemType) {
String label = item.toHuman();
index.put(label, item);
}
}
if (index.size() == 0) {
return;
}
out.annotate(0, intro);
for (Map.Entry<String, OffsettedItem> entry : index.entrySet()) {
String label = entry.getKey();
OffsettedItem item = entry.getValue();
out.annotate(0, item.offsetString() + ' " + label + '\n");
}
|
public int | writeSize(){@inheritDoc}
throwIfNotPrepared();
return writeSize;
|
protected void | writeTo0(com.android.dexgen.util.AnnotatedOutput out){@inheritDoc}
boolean annotates = out.annotates();
boolean first = true;
DexFile file = getFile();
int at = 0;
for (OffsettedItem one : items) {
if (annotates) {
if (first) {
first = false;
} else {
out.annotate(0, "\n");
}
}
int alignMask = one.getAlignment() - 1;
int writeAt = (at + alignMask) & ~alignMask;
if (at != writeAt) {
out.writeZeroes(writeAt - at);
at = writeAt;
}
one.writeTo(file, out);
at += one.writeSize();
}
if (at != writeSize) {
throw new RuntimeException("output size mismatch");
}
|