18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (C) 2007 The Guava Authors
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * you may not use this file except in compliance with the License.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * You may obtain a copy of the License at
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12e1e03df288d5a44bfbffbd86588395c7cbbc27dfDavid 'Digit' Turner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * See the License for the specific language governing permissions and
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * limitations under the License.
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpackage com.google.common.collect;
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectimport static com.google.common.base.Preconditions.checkState;
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectimport com.google.common.annotations.GwtCompatible;
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectimport java.util.NoSuchElementException;
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This class provides a skeletal implementation of the {@code Iterator}
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * interface, to make this interface easier to implement for certain types of
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * data sources.
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * <p>{@code Iterator} requires its implementations to support querying the
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * end-of-data status without changing the iterator's state, using the {@link
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * #hasNext} method. But many data sources, such as {@link
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * java.io.Reader#read()}, do not expose this information; the only way to
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * discover whether there is any data left is by trying to retrieve it. These
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * types of data sources are ordinarily difficult to write iterators for. But
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * using this class, one must implement only the {@link #computeNext} method,
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and invoke the {@link #endOfData} method when appropriate.
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * <p>Another example is an iterator that skips over null elements in a backing
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * iterator. This could be implemented as: <pre>   {@code
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   public static Iterator<String> skipNulls(final Iterator<String> in) {
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *     return new AbstractIterator<String>() {
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *       protected String computeNext() {
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *         while (in.hasNext()) {
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *           String s = in.next();
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *           if (s != null) {
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *             return s;
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *           }
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *         }
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *         return endOfData();
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *       }
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *     };
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   }}</pre>
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This class supports iterators that include null elements.
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * @author Kevin Bourrillion
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * @since 2.0 (imported from Google Collections Library)
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// When making changes to this class, please also update the copy at
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// com.google.common.base.AbstractIterator
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project@GwtCompatible
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpublic abstract class AbstractIterator<T> extends UnmodifiableIterator<T> {
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  private State state = State.NOT_READY;
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  /** Constructor for use by subclasses. */
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  protected AbstractIterator() {}
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  private enum State {
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /** We have computed the next element and haven't returned it yet. */
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    READY,
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /** We haven't yet computed or have already returned the element. */
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NOT_READY,
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /** We have reached the end of the data and are finished. */
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DONE,
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /** We've suffered an exception and are kaput. */
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FAILED,
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  private T next;
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  /**
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * Returns the next element. <b>Note:</b> the implementation must call {@link
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * #endOfData()} when there are no elements left in the iteration. Failure to
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * do so could result in an infinite loop.
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * <p>The initial invocation of {@link #hasNext()} or {@link #next()} calls
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * this method, as does the first invocation of {@code hasNext} or {@code
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * next} following each successful call to {@code next}. Once the
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * implementation either invokes {@code endOfData} or throws an exception,
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * {@code computeNext} is guaranteed to never be called again.
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * <p>If this method throws an exception, it will propagate outward to the
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * {@code hasNext} or {@code next} invocation that invoked this method. Any
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * further attempts to use the iterator will result in an {@link
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * IllegalStateException}.
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * <p>The implementation of this method may not invoke the {@code hasNext},
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * {@code next}, or {@link #peek()} methods on this instance; if it does, an
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * {@code IllegalStateException} will result.
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * @return the next element if there was one. If {@code endOfData} was called
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *     during execution, the return value will be ignored.
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * @throws RuntimeException if any unrecoverable error happens. This exception
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *     will propagate outward to the {@code hasNext()}, {@code next()}, or
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *     {@code peek()} invocation that invoked this method. Any further
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *     attempts to use the iterator will result in an
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *     {@link IllegalStateException}.
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   */
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  protected abstract T computeNext();
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  /**
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * Implementations of {@link #computeNext} <b>must</b> invoke this method when
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * there are no elements left in the iteration.
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * @return {@code null}; a convenience so your {@code computeNext}
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *     implementation can use the simple statement {@code return endOfData();}
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   */
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  protected final T endOfData() {
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = State.DONE;
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return null;
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  @Override
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  public final boolean hasNext() {
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    checkState(state != State.FAILED);
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (state) {
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case DONE:
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return false;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case READY:
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return true;
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      default:
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return tryToComputeNext();
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  private boolean tryToComputeNext() {
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = State.FAILED; // temporary pessimism
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next = computeNext();
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state != State.DONE) {
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      state = State.READY;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return true;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return false;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  @Override
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  public final T next() {
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!hasNext()) {
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      throw new NoSuchElementException();
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = State.NOT_READY;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return next;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  /**
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * Returns the next element in the iteration without advancing the iteration,
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * according to the contract of {@link PeekingIterator#peek()}.
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   *
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * <p>Implementations of {@code AbstractIterator} that wish to expose this
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   * functionality should implement {@code PeekingIterator}.
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   */
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  public final T peek() {
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!hasNext()) {
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      throw new NoSuchElementException();
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return next;
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project