Merge pull request #704 from square/jwilson.1007.peekutf8

Implement peekJson() for JsonUtf8Reader
This commit is contained in:
Jesse Wilson
2018-10-08 12:27:02 -04:00
committed by GitHub
5 changed files with 90 additions and 8 deletions

View File

@@ -497,8 +497,7 @@ public abstract class JsonReader implements Closeable {
* jsonReader.nextInt() // Returns 456, reader contains 789 and ].
* }</pre>
*/
// TODO(jwilson): make this public once it's supported in JsonUtf8Reader.
abstract JsonReader peekJson();
public abstract JsonReader peekJson();
/**
* Returns a <a href="http://goessner.net/articles/JsonPath/">JsonPath</a> to

View File

@@ -98,6 +98,27 @@ final class JsonUtf8Reader extends JsonReader {
pushScope(JsonScope.EMPTY_DOCUMENT);
}
/** Copy-constructor makes a deep copy for peeking. */
JsonUtf8Reader(JsonUtf8Reader copyFrom) {
super(copyFrom);
BufferedSource sourcePeek = copyFrom.source.peek();
this.source = sourcePeek;
this.buffer = sourcePeek.getBuffer();
this.peeked = copyFrom.peeked;
this.peekedLong = copyFrom.peekedLong;
this.peekedNumberLength = copyFrom.peekedNumberLength;
this.peekedString = copyFrom.peekedString;
// Make sure our buffer has as many bytes as the source's buffer. This is necessary because
// JsonUtf8Reader assumes any data it has peeked (like the peekedNumberLength) are buffered.
try {
sourcePeek.require(copyFrom.buffer.size());
} catch (IOException e) {
throw new AssertionError();
}
}
@Override public void beginArray() throws IOException {
int p = peeked;
if (p == PEEKED_NONE) {
@@ -1051,8 +1072,8 @@ final class JsonUtf8Reader extends JsonReader {
return found;
}
@Override JsonReader peekJson() {
throw new UnsupportedOperationException("TODO");
@Override public JsonReader peekJson() {
return new JsonUtf8Reader(this);
}
@Override public String toString() {

View File

@@ -318,7 +318,7 @@ final class JsonValueReader extends JsonReader {
}
}
@Override JsonReader peekJson() {
@Override public JsonReader peekJson() {
return new JsonValueReader(this);
}

View File

@@ -33,6 +33,7 @@ import static com.squareup.moshi.JsonReader.Token.STRING;
import static com.squareup.moshi.TestUtil.repeat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
@@ -988,7 +989,6 @@ public final class JsonReaderTest {
@Test public void basicPeekJson() throws IOException {
JsonReader reader = newReader("{\"a\":12,\"b\":[34,56],\"c\":78}");
assumeTrue(reader instanceof JsonValueReader); // Not implemented for JsonUtf8Reader yet!
reader.beginObject();
assertThat(reader.nextName()).isEqualTo("a");
assertThat(reader.nextInt()).isEqualTo(12);
@@ -1021,7 +1021,6 @@ public final class JsonReaderTest {
*/
@Test public void peekJsonReader() throws IOException {
JsonReader reader = newReader("[12,34,{\"a\":56,\"b\":78},90]");
assumeTrue(reader instanceof JsonValueReader); // Not implemented for JsonUtf8Reader yet!
for (int i = 0; i < 12; i++) {
readPeek12Steps(reader.peekJson(), i, 12);
readPeek12Steps(reader, i, i + 1);
@@ -1084,4 +1083,67 @@ public final class JsonReaderTest {
assertThat(reader.getPath()).isEqualTo("$");
}
}
/** Confirm that we can peek in every state of the UTF-8 reader. */
@Test public void peekAfterPeek() throws IOException {
JsonReader reader = newReader(
"[{\"a\":\"aaa\",'b':'bbb',c:c,\"d\":\"d\"},true,false,null,1,2.0]");
reader.setLenient(true);
readValue(reader, true);
reader.peekJson();
}
@Test public void peekAfterPromoteNameToValue() throws IOException {
JsonReader reader = newReader("{\"a\":\"b\"}");
reader.beginObject();
reader.promoteNameToValue();
assertEquals("a", reader.peekJson().nextString());
assertEquals("a", reader.nextString());
assertEquals("b", reader.peekJson().nextString());
assertEquals("b", reader.nextString());
reader.endObject();
}
/** Peek a value, then read it, recursively. */
private void readValue(JsonReader reader, boolean peekJsonFirst) throws IOException {
JsonReader.Token token = reader.peek();
if (peekJsonFirst) {
readValue(reader.peekJson(), false);
}
switch (token) {
case BEGIN_ARRAY:
reader.beginArray();
while (reader.hasNext()) {
readValue(reader, peekJsonFirst);
}
reader.peekJson().endArray();
reader.endArray();
break;
case BEGIN_OBJECT:
reader.beginObject();
while (reader.hasNext()) {
assertNotNull(reader.peekJson().nextName());
assertNotNull(reader.nextName());
readValue(reader, peekJsonFirst);
}
reader.peekJson().endObject();
reader.endObject();
break;
case STRING:
reader.nextString();
break;
case NUMBER:
reader.nextDouble();
break;
case BOOLEAN:
reader.nextBoolean();
break;
case NULL:
reader.nextNull();
break;
default:
throw new AssertionError();
}
}
}

View File

@@ -35,7 +35,7 @@
<maven-assembly.version>3.1.0</maven-assembly.version>
<!-- Dependencies -->
<okio.version>1.15.0</okio.version>
<okio.version>1.16.0</okio.version>
<!-- Test Dependencies -->
<compile-testing.version>0.15</compile-testing.version>