aboutsummaryrefslogtreecommitdiff
path: root/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/util/VariableSizeLookaheadIterator.java
diff options
context:
space:
mode:
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.java68
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);
}