Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove EOFException special casing of JsonStreamParser.next() #2281

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 9 additions & 13 deletions gson/src/main/java/com/google/gson/JsonStreamParser.java
Expand Up @@ -15,18 +15,16 @@
*/
package com.google.gson;

import java.io.EOFException;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.MalformedJsonException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Iterator;
import java.util.NoSuchElementException;

import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.MalformedJsonException;

/**
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
* asynchronously. The JSON data is parsed in lenient mode, see also
Expand Down Expand Up @@ -61,7 +59,7 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
public JsonStreamParser(String json) {
this(new StringReader(json));
}

/**
* @param reader The data stream containing JSON elements concatenated to each other.
* @since 1.4
Expand All @@ -71,13 +69,13 @@ public JsonStreamParser(Reader reader) {
parser.setLenient(true);
lock = new Object();
}

/**
* Returns the next available {@link JsonElement} on the reader. Throws a
* {@link NoSuchElementException} if no element is available.
*
* @return the next available {@code JsonElement} on the reader.
* @throws JsonSyntaxException if the incoming stream is malformed JSON.
* @throws JsonParseException if the incoming stream is malformed JSON.
* @throws NoSuchElementException if no {@code JsonElement} is available.
* @since 1.4
*/
Expand All @@ -86,22 +84,20 @@ public JsonElement next() throws JsonParseException {
if (!hasNext()) {
throw new NoSuchElementException();
}

try {
return Streams.parse(parser);
} catch (StackOverflowError e) {
throw new JsonParseException("Failed parsing JSON source to Json", e);
} catch (OutOfMemoryError e) {
throw new JsonParseException("Failed parsing JSON source to Json", e);
} catch (JsonParseException e) {
throw e.getCause() instanceof EOFException ? new NoSuchElementException() : e;
}
}

/**
* Returns true if a {@link JsonElement} is available on the input for consumption
* @return true if a {@link JsonElement} is available on the input, false otherwise
* @throws JsonSyntaxException if the incoming stream is malformed JSON.
* @throws JsonParseException if the incoming stream is malformed JSON.
* @since 1.4
*/
@Override
Expand Down
74 changes: 65 additions & 9 deletions gson/src/test/java/com/google/gson/JsonStreamParserTest.java
Expand Up @@ -15,31 +15,38 @@
*/
package com.google.gson;

import junit.framework.TestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.EOFException;
import java.util.NoSuchElementException;
import org.junit.Before;
import org.junit.Test;

/**
* Unit tests for {@link JsonStreamParser}
*
*
* @author Inderjeet Singh
*/
public class JsonStreamParserTest extends TestCase {
public class JsonStreamParserTest {
private JsonStreamParser parser;

@Override
protected void setUp() throws Exception {
super.setUp();

@Before
public void setUp() throws Exception {
parser = new JsonStreamParser("'one' 'two'");
}

@Test
public void testParseTwoStrings() {
String actualOne = parser.next().getAsString();
assertEquals("one", actualOne);
String actualTwo = parser.next().getAsString();
assertEquals("two", actualTwo);
}

@Test
public void testIterator() {
assertTrue(parser.hasNext());
assertEquals("one", parser.next().getAsString());
Expand All @@ -48,20 +55,22 @@ public void testIterator() {
assertFalse(parser.hasNext());
}

@Test
public void testNoSideEffectForHasNext() throws Exception {
assertTrue(parser.hasNext());
assertTrue(parser.hasNext());
assertTrue(parser.hasNext());
assertEquals("one", parser.next().getAsString());

assertTrue(parser.hasNext());
assertTrue(parser.hasNext());
assertEquals("two", parser.next().getAsString());

assertFalse(parser.hasNext());
assertFalse(parser.hasNext());
}

@Test
public void testCallingNextBeyondAvailableInput() {
parser.next();
parser.next();
Expand All @@ -71,4 +80,51 @@ public void testCallingNextBeyondAvailableInput() {
} catch (NoSuchElementException expected) {
}
}

@Test
public void testEmptyInput() {
JsonStreamParser parser = new JsonStreamParser("");
try {
parser.next();
fail();
} catch (JsonIOException e) {
assertTrue(e.getCause() instanceof EOFException);
}

parser = new JsonStreamParser("");
try {
parser.hasNext();
fail();
} catch (JsonIOException e) {
assertTrue(e.getCause() instanceof EOFException);
}
}

@Test
public void testIncompleteInput() {
JsonStreamParser parser = new JsonStreamParser("[");
assertTrue(parser.hasNext());
try {
parser.next();
fail();
} catch (JsonSyntaxException e) {
}
}

@Test
public void testMalformedInput() {
JsonStreamParser parser = new JsonStreamParser(":");
try {
parser.hasNext();
fail();
} catch (JsonSyntaxException e) {
}

parser = new JsonStreamParser(":");
try {
parser.next();
fail();
} catch (JsonSyntaxException e) {
}
}
}