diff --git a/moshi/src/main/java/com/squareup/moshi/JsonReader.java b/moshi/src/main/java/com/squareup/moshi/JsonReader.java index eabc01a..e04acf9 100644 --- a/moshi/src/main/java/com/squareup/moshi/JsonReader.java +++ b/moshi/src/main/java/com/squareup/moshi/JsonReader.java @@ -180,10 +180,10 @@ public abstract class JsonReader implements Closeable { // The nesting stack. Using a manual array rather than an ArrayList saves 20%. This stack will // grow itself up to 256 levels of nesting including the top-level document. Deeper nesting is // prone to trigger StackOverflowErrors. - int stackSize = 0; - int[] scopes = new int[32]; - String[] pathNames = new String[32]; - int[] pathIndices = new int[32]; + int stackSize; + int[] scopes; + String[] pathNames; + int[] pathIndices; /** True to accept non-spec compliant JSON. */ boolean lenient; @@ -196,8 +196,21 @@ public abstract class JsonReader implements Closeable { return new JsonUtf8Reader(source); } + // Package-private to control subclasses. JsonReader() { - // Package-private to control subclasses. + scopes = new int[32]; + pathNames = new String[32]; + pathIndices = new int[32]; + } + + // Package-private to control subclasses. + JsonReader(JsonReader copyFrom) { + this.stackSize = copyFrom.stackSize; + this.scopes = copyFrom.scopes.clone(); + this.pathNames = copyFrom.pathNames.clone(); + this.pathIndices = copyFrom.pathIndices.clone(); + this.lenient = copyFrom.lenient; + this.failOnUnknown = copyFrom.failOnUnknown; } final void pushScope(int newTop) { @@ -461,6 +474,32 @@ public abstract class JsonReader implements Closeable { } } + /** + * Returns a new {@code JsonReader} that can read data from this {@code JsonReader} without + * consuming it. The returned reader becomes invalid once this one is next read or closed. + * + * For example, we can use `peek()` to lookahead and read the same data multiple times. + * + *
 {@code
+   *
+   *   Buffer buffer = new Buffer();
+   *   buffer.writeUtf8("[123, 456, 789]")
+   *
+   *   JsonReader jsonReader = JsonReader.of(buffer);
+   *   jsonReader.beginArray();
+   *   jsonReader.nextInt(); // Returns 123, reader contains 456, 789 and ].
+   *
+   *   JsonReader peek = reader.peekReader();
+   *   peek.nextInt() // Returns 456.
+   *   peek.nextInt() // Returns 789.
+   *   peek.endArray()
+   *
+   *   jsonReader.nextInt() // Returns 456, reader contains 789 and ].
+   * }
+ */ + // TODO(jwilson): make this public once it's supported in JsonUtf8Reader. + abstract JsonReader peekJson(); + /** * Returns a JsonPath to * the current location in the JSON value. diff --git a/moshi/src/main/java/com/squareup/moshi/JsonUtf8Reader.java b/moshi/src/main/java/com/squareup/moshi/JsonUtf8Reader.java index 14e12a5..16c478a 100644 --- a/moshi/src/main/java/com/squareup/moshi/JsonUtf8Reader.java +++ b/moshi/src/main/java/com/squareup/moshi/JsonUtf8Reader.java @@ -1059,6 +1059,10 @@ final class JsonUtf8Reader extends JsonReader { return false; } + @Override JsonReader peekJson() { + throw new UnsupportedOperationException("TODO"); + } + @Override public String toString() { return "JsonReader(" + source + ")"; } diff --git a/moshi/src/main/java/com/squareup/moshi/JsonValueReader.java b/moshi/src/main/java/com/squareup/moshi/JsonValueReader.java index fb3991b..4246d3d 100644 --- a/moshi/src/main/java/com/squareup/moshi/JsonValueReader.java +++ b/moshi/src/main/java/com/squareup/moshi/JsonValueReader.java @@ -20,10 +20,11 @@ import java.math.BigDecimal; import java.util.Arrays; import java.util.Iterator; import java.util.List; -import java.util.ListIterator; import java.util.Map; import javax.annotation.Nullable; +import static com.squareup.moshi.JsonScope.CLOSED; + /** * This class reads a JSON document by traversing a Java object comprising maps, lists, and JSON * primitives. It does depth-first traversal keeping a stack starting with the root object. During @@ -32,11 +33,11 @@ import javax.annotation.Nullable; *