Refactor VariableSizeLookaheadIterator

Previously, when referencing instance fields from readNextItem,
the fields wouldn't have been initialized yet on the first call to
readNextItem
This commit is contained in:
Ben Gruver 2014-12-28 12:15:17 -08:00 committed by Connor Tumbleson
parent 3d3db44773
commit 853da5a172
4 changed files with 14 additions and 28 deletions

View File

@ -173,7 +173,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
while (true) { while (true) {
if (++count > staticFieldCount) { if (++count > staticFieldCount) {
instanceFieldsOffset = reader.getOffset(); instanceFieldsOffset = reader.getOffset();
return null; return endOfData();
} }
DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this, DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this,
@ -232,7 +232,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
while (true) { while (true) {
if (++count > instanceFieldCount) { if (++count > instanceFieldCount) {
directMethodsOffset = reader.getOffset(); directMethodsOffset = reader.getOffset();
return null; return endOfData();
} }
DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this, DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this,
@ -301,7 +301,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
while (true) { while (true) {
if (++count > directMethodCount) { if (++count > directMethodCount) {
virtualMethodsOffset = reader.getOffset(); virtualMethodsOffset = reader.getOffset();
return null; return endOfData();
} }
DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this, DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this,
@ -357,7 +357,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
protected DexBackedMethod readNextItem(@Nonnull DexReader reader) { protected DexBackedMethod readNextItem(@Nonnull DexReader reader) {
while (true) { while (true) {
if (++count > virtualMethodCount) { if (++count > virtualMethodCount) {
return null; return endOfData();
} }
DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this, DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this,

View File

@ -76,7 +76,7 @@ public class DexBackedMethodImplementation implements MethodImplementation {
@Override @Override
protected Instruction readNextItem(@Nonnull DexReader reader) { protected Instruction readNextItem(@Nonnull DexReader reader) {
if (reader.getOffset() >= endOffset) { if (reader.getOffset() >= endOffset) {
return null; return endOfData();
} }
Instruction instruction = DexBackedInstruction.readFrom(reader); Instruction instruction = DexBackedInstruction.readFrom(reader);

View File

@ -160,7 +160,7 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
int next = reader.readUbyte(); int next = reader.readUbyte();
switch (next) { switch (next) {
case DebugItemType.END_SEQUENCE: { case DebugItemType.END_SEQUENCE: {
return null; return endOfData();
} }
case DebugItemType.ADVANCE_PC: { case DebugItemType.ADVANCE_PC: {
int addressDiff = reader.readSmallUleb128(); int addressDiff = reader.readSmallUleb128();

View File

@ -31,46 +31,32 @@
package org.jf.dexlib2.dexbacked.util; package org.jf.dexlib2.dexbacked.util;
import com.google.common.collect.AbstractIterator;
import org.jf.dexlib2.dexbacked.DexBackedDexFile; import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.dexbacked.DexReader; import org.jf.dexlib2.dexbacked.DexReader;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException;
public abstract class VariableSizeLookaheadIterator<T> implements Iterator<T> { public abstract class VariableSizeLookaheadIterator<T> extends AbstractIterator<T> implements Iterator<T> {
@Nonnull private final DexReader reader; @Nonnull private final DexReader reader;
private T cachedItem = null;
protected VariableSizeLookaheadIterator(@Nonnull DexBackedDexFile dexFile, int offset) { protected VariableSizeLookaheadIterator(@Nonnull DexBackedDexFile dexFile, int offset) {
this.reader = dexFile.readerAt(offset); this.reader = dexFile.readerAt(offset);
cachedItem = readNextItem(reader);
} }
/** /**
* Reads the next item from reader. If the end of the list has been reached, it should return null. * Reads the next item from reader. If the end of the list has been reached, it should call endOfData.
* *
* @return The item that was read, or null if the end of the list has been reached. * endOfData has a return value of T, so you can simply {@code return endOfData()}
*
* @return The item that was read. If endOfData was called, the return value is ignored.
*/ */
@Nullable protected abstract T readNextItem(@Nonnull DexReader reader); @Nullable protected abstract T readNextItem(@Nonnull DexReader reader);
@Override @Override
public boolean hasNext() { protected T computeNext() {
return cachedItem != null; return readNextItem(reader);
} }
@Override
@Nonnull
public T next() {
if (cachedItem == null) {
throw new NoSuchElementException();
}
T ret = cachedItem;
cachedItem = readNextItem(reader);
return ret;
}
@Override public void remove() { throw new UnsupportedOperationException(); }
} }