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

View File

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

View File

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

View File

@ -31,46 +31,32 @@
package org.jf.dexlib2.dexbacked.util;
import com.google.common.collect.AbstractIterator;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.dexbacked.DexReader;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
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;
private T cachedItem = null;
protected VariableSizeLookaheadIterator(@Nonnull DexBackedDexFile dexFile, int 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);
@Override
public boolean hasNext() {
return cachedItem != null;
protected T computeNext() {
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(); }
}