mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 16:09:21 +08:00
Merge pull request #704 from square/jwilson.1007.peekutf8
Implement peekJson() for JsonUtf8Reader
This commit is contained in:
@@ -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
|
||||
|
@@ -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() {
|
||||
|
@@ -318,7 +318,7 @@ final class JsonValueReader extends JsonReader {
|
||||
}
|
||||
}
|
||||
|
||||
@Override JsonReader peekJson() {
|
||||
@Override public JsonReader peekJson() {
|
||||
return new JsonValueReader(this);
|
||||
}
|
||||
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user