Add an experimental rewrite of JsonReader.

The motivating difference is that JsonReaderV2 tries to read each character at most once. This means that when it reads literals, it also attempts to decode them to a keyword (true/false/null) or a number.

This change also _doesn't_ read strings until demanded to do so. This should permit streaming access to strings down the road.

This code is not yet complete, nor is has it been properly optimized. And the implementation is also quite a mess! It is a work in progress.
This commit is contained in:
Jesse Wilson 2012-08-25 04:31:56 +00:00
parent 9c4b23b39a
commit c5c65ba626
2 changed files with 1442 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -73,6 +73,30 @@ public final class JsonReaderTest extends TestCase {
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
public void testSkipInteger() throws IOException {
JsonReader reader = new JsonReader(new StringReader(
"{\"a\":123456789,\"b\":-123456789}"));
reader.beginObject();
assertEquals("a", reader.nextName());
reader.skipValue();
assertEquals("b", reader.nextName());
reader.skipValue();
reader.endObject();
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
public void testSkipDouble() throws IOException {
JsonReader reader = new JsonReader(new StringReader(
"{\"a\":-123.456e-789,\"b\":123456789.0}"));
reader.beginObject();
assertEquals("a", reader.nextName());
reader.skipValue();
assertEquals("b", reader.nextName());
reader.skipValue();
reader.endObject();
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
public void testHelloWorld() throws IOException {
String json = "{\n" +
" \"hello\": true,\n" +
@ -366,6 +390,62 @@ public final class JsonReaderTest extends TestCase {
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
public void testPeekingUnquotedStringsPrefixedWithBooleans() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[truey]"));
reader.setLenient(true);
reader.beginArray();
assertEquals(JsonToken.STRING, reader.peek());
try {
reader.nextBoolean();
fail();
} catch (IllegalStateException expected) {
}
assertEquals("truey", reader.nextString());
reader.endArray();
}
public void testPeekingUnquotedStringsPrefixedWithIntegers() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[12.34e5x]"));
reader.setLenient(true);
reader.beginArray();
assertEquals(JsonToken.STRING, reader.peek());
try {
reader.nextInt();
fail();
} catch (IllegalStateException expected) {
}
assertEquals("12.34e5x", reader.nextString());
}
public void testPeekLongMinValue() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[-9223372036854775808]"));
reader.setLenient(true);
reader.beginArray();
assertEquals(JsonToken.NUMBER, reader.peek());
assertEquals(-9223372036854775808L, reader.nextLong());
}
public void testPeekLargerThanLongMinValue() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[-92233720368547758080]"));
reader.setLenient(true);
reader.beginArray();
assertEquals(JsonToken.NUMBER, reader.peek());
try {
reader.nextLong();
fail();
} catch (NumberFormatException expected) {
}
assertEquals(-92233720368547758080d, reader.nextDouble());
}
public void testQuotedNumberWithEscape() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[\"12\u00334\"]"));
reader.setLenient(true);
reader.beginArray();
assertEquals(JsonToken.STRING, reader.peek());
assertEquals(1234, reader.nextInt());
}
public void testMixedCaseLiterals() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[True,TruE,False,FALSE,NULL,nulL]"));
reader.beginArray();