diff options
Diffstat (limited to 'dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/util/VariableSizeLookaheadIterator.java')
-rw-r--r-- | dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/util/VariableSizeLookaheadIterator.java | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/util/VariableSizeLookaheadIterator.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/util/VariableSizeLookaheadIterator.java index 36e4b421..7dfc1f93 100644 --- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/util/VariableSizeLookaheadIterator.java +++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/util/VariableSizeLookaheadIterator.java @@ -30,31 +30,83 @@ package com.android.tools.smali.dexlib2.dexbacked.util; -import com.google.common.collect.AbstractIterator; import com.android.tools.smali.dexlib2.dexbacked.DexBuffer; import com.android.tools.smali.dexlib2.dexbacked.DexReader; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Iterator; +import java.util.NoSuchElementException; -public abstract class VariableSizeLookaheadIterator<T> extends AbstractIterator<T> implements Iterator<T> { - @Nonnull private final DexReader reader; +public abstract class VariableSizeLookaheadIterator<T> implements Iterator<T> { + /** We have computed the next element and haven't returned it yet. */ + private static final int STATE_READY = 1; + + /** We haven't yet computed or have already returned the element. */ + private static final int STATE_NOT_READY = 2; + + /** We have reached the end of the data and are finished. */ + private static final int STATE_DONE = 3; + + /** We've suffered an exception and are kaputt. */ + private static final int STATE_FAILED = 4; + + private int state = STATE_NOT_READY; + private T next; + @Nonnull + private final DexReader<? extends DexBuffer> reader; protected VariableSizeLookaheadIterator(@Nonnull DexBuffer buffer, int offset) { this.reader = buffer.readerAt(offset); } + protected final T endOfData() { + state = STATE_DONE; + return null; + } + + @Override + public final boolean hasNext() { + switch (state) { + case STATE_DONE: + return false; + case STATE_READY: + return true; + default: + } + return tryToComputeNext(); + } + + private boolean tryToComputeNext() { + state = STATE_FAILED; // temporary pessimism + next = computeNext(); + if (state != STATE_DONE) { + state = STATE_READY; + return true; + } + return false; + } + + @Override + public final T next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + state = STATE_NOT_READY; + T result = next; + next = null; + return result; + } + /** - * Reads the next item from reader. If the end of the list has been reached, it should call endOfData. - * - * endOfData has a return value of T, so you can simply {@code return endOfData()} + * Reads the next item from reader. If the end of the list has been reached, it should call + * endOfData. 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<? extends DexBuffer> reader); - @Override protected T computeNext() { return readNextItem(reader); } |