diff --git a/faunaJava/src/main/java/com/fauna/serialization/FaunaParser.java b/faunaJava/src/main/java/com/fauna/serialization/FaunaParser.java index 8f5bfbe8..76727903 100644 --- a/faunaJava/src/main/java/com/fauna/serialization/FaunaParser.java +++ b/faunaJava/src/main/java/com/fauna/serialization/FaunaParser.java @@ -71,7 +71,28 @@ public FaunaTokenType getCurrentTokenType() { END_REF, END_ARRAY )); - + + public void skip() throws IOException { + switch (getCurrentTokenType()) { + case START_OBJECT: + case START_ARRAY: + case START_PAGE: + case START_REF: + case START_DOCUMENT: + skipInternal(); + break; + } + } + + private void skipInternal() throws IOException { + int startCount = tokenStack.size(); + while (read()) { + if (tokenStack.size() < startCount) { + break; + } + } + } + public boolean read() throws IOException { taggedTokenValue = null; diff --git a/faunaJava/src/test/java/com/fauna/serialization/FaunaParserTest.java b/faunaJava/src/test/java/com/fauna/serialization/FaunaParserTest.java index b8c14025..c18f2eac 100644 --- a/faunaJava/src/test/java/com/fauna/serialization/FaunaParserTest.java +++ b/faunaJava/src/test/java/com/fauna/serialization/FaunaParserTest.java @@ -512,6 +512,76 @@ public void throwsOnMalformedJson() { }, "Failed to advance underlying JSON reader."); } + @Test + public void skipValues() throws IOException { + List tests = List.of( + "{\"k1\": {}, \"k2\": {}}", + "[\"k1\",[],{}]", + "{\"@ref\": {}}", + "{\"@doc\": {}}", + "{\"@set\": {}}", + "{\"@object\":{}}" + ); + + for (String test : tests) { + FaunaParser reader = new FaunaParser(new ByteArrayInputStream(test.getBytes())); + reader.read(); + reader.skip(); + assertFalse(reader.read()); + } + } + + @Test + public void skipNestedEscapedObject() throws IOException { + String test = "{\"@object\": {\"inner\": {\"@object\": {\"foo\": \"bar\"}}, \"k2\": {}}}"; + FaunaParser reader = new FaunaParser(new ByteArrayInputStream(test.getBytes())); + reader.read(); // {"@object":{ + assertEquals(FaunaTokenType.START_OBJECT, reader.getCurrentTokenType()); + reader.read(); // inner + assertEquals(FaunaTokenType.FIELD_NAME, reader.getCurrentTokenType()); + reader.read(); // {"@object":{ + assertEquals(FaunaTokenType.START_OBJECT, reader.getCurrentTokenType()); + reader.skip(); // "foo": "bar"}} + assertEquals(FaunaTokenType.END_OBJECT, reader.getCurrentTokenType()); + reader.read(); + assertEquals(FaunaTokenType.FIELD_NAME, reader.getCurrentTokenType()); + assertEquals("k2", reader.getValueAsString()); + } + + @Test + public void skipNestedObject() throws IOException { + String test = "{\"k\":{\"inner\":{}},\"k2\":{}}"; + FaunaParser reader = new FaunaParser(new ByteArrayInputStream(test.getBytes())); + reader.read(); // { + assertEquals(FaunaTokenType.START_OBJECT, reader.getCurrentTokenType()); + reader.read(); // k + assertEquals(FaunaTokenType.FIELD_NAME, reader.getCurrentTokenType()); + reader.read(); // { + assertEquals(FaunaTokenType.START_OBJECT, reader.getCurrentTokenType()); + reader.skip(); // "inner":{}} + assertEquals(FaunaTokenType.END_OBJECT, reader.getCurrentTokenType()); + reader.read(); + assertEquals(FaunaTokenType.FIELD_NAME, reader.getCurrentTokenType()); + assertEquals("k2", reader.getValueAsString()); + } + + @Test + public void skipNestedArrays() throws IOException { + String test = "{\"k\":[\"1\",\"2\"],\"k2\":{}}"; + FaunaParser reader = new FaunaParser(new ByteArrayInputStream(test.getBytes())); + reader.read(); // { + assertEquals(FaunaTokenType.START_OBJECT, reader.getCurrentTokenType()); + reader.read(); // k + assertEquals(FaunaTokenType.FIELD_NAME, reader.getCurrentTokenType()); + reader.read(); // [ + assertEquals(FaunaTokenType.START_ARRAY, reader.getCurrentTokenType()); + reader.skip(); // "1","2"] + assertEquals(FaunaTokenType.END_ARRAY, reader.getCurrentTokenType()); + reader.read(); + assertEquals(FaunaTokenType.FIELD_NAME, reader.getCurrentTokenType()); + assertEquals("k2", reader.getValueAsString()); + } + private static void assertReader(FaunaParser reader, List> tokens) throws IOException { for (Map.Entry entry : tokens) {