diff --git a/gson/src/main/java/com/google/gson/stream/JsonReader.java b/gson/src/main/java/com/google/gson/stream/JsonReader.java
index ea738f82..838355cb 100644
--- a/gson/src/main/java/com/google/gson/stream/JsonReader.java
+++ b/gson/src/main/java/com/google/gson/stream/JsonReader.java
@@ -24,7 +24,7 @@ import java.io.IOException;
import java.io.Reader;
/**
- * Reads a JSON (RFC 4627)
+ * Reads a JSON (RFC 7159)
* encoded value as a stream of tokens. This stream includes both literal
* values (strings, numbers, booleans, and nulls) as well as the begin and
* end delimiters of objects and arrays. The tokens are traversed in
@@ -571,9 +571,6 @@ public class JsonReader implements Closeable {
checkLenient();
return peeked = PEEKED_SINGLE_QUOTED;
case '"':
- if (stackSize == 1) {
- checkLenient();
- }
return peeked = PEEKED_DOUBLE_QUOTED;
case '[':
return peeked = PEEKED_BEGIN_ARRAY;
@@ -583,10 +580,6 @@ public class JsonReader implements Closeable {
pos--; // Don't consume the first character in a literal value.
}
- if (stackSize == 1) {
- checkLenient(); // Top-level value isn't an array or an object.
- }
-
int result = peekKeyword();
if (result != PEEKED_NONE) {
return result;
diff --git a/gson/src/main/java/com/google/gson/stream/JsonWriter.java b/gson/src/main/java/com/google/gson/stream/JsonWriter.java
index 8d3bdb34..9bf2d22a 100644
--- a/gson/src/main/java/com/google/gson/stream/JsonWriter.java
+++ b/gson/src/main/java/com/google/gson/stream/JsonWriter.java
@@ -30,7 +30,7 @@ import static com.google.gson.stream.JsonScope.NONEMPTY_DOCUMENT;
import static com.google.gson.stream.JsonScope.NONEMPTY_OBJECT;
/**
- * Writes a JSON (RFC 4627)
+ * Writes a JSON (RFC 7159)
* encoded value to a stream, one token at a time. The stream includes both
* literal values (strings, numbers, booleans and nulls) as well as the begin
* and end delimiters of objects and arrays.
@@ -130,7 +130,7 @@ import static com.google.gson.stream.JsonScope.NONEMPTY_OBJECT;
public class JsonWriter implements Closeable, Flushable {
/*
- * From RFC 4627, "All Unicode characters may be placed within the
+ * From RFC 7159, "All Unicode characters may be placed within the
* quotation marks except for the characters that must be escaped:
* quotation mark, reverse solidus, and the control characters
* (U+0000 through U+001F)."
@@ -222,7 +222,7 @@ public class JsonWriter implements Closeable, Flushable {
/**
* Configure this writer to relax its syntax rules. By default, this writer
* only emits well-formed JSON as specified by RFC 4627. Setting the writer
+ * href="http://www.ietf.org/rfc/rfc7159.txt">RFC 7159. Setting the writer
* to lenient permits the following:
*
* - Top-level values of any type. With strict writing, the top-level
@@ -322,7 +322,7 @@ public class JsonWriter implements Closeable, Flushable {
* bracket.
*/
private JsonWriter open(int empty, String openBracket) throws IOException {
- beforeValue(true);
+ beforeValue();
push(empty);
out.write(openBracket);
return this;
@@ -415,7 +415,7 @@ public class JsonWriter implements Closeable, Flushable {
return nullValue();
}
writeDeferredName();
- beforeValue(false);
+ beforeValue();
string(value);
return this;
}
@@ -432,7 +432,7 @@ public class JsonWriter implements Closeable, Flushable {
return nullValue();
}
writeDeferredName();
- beforeValue(false);
+ beforeValue();
out.append(value);
return this;
}
@@ -451,7 +451,7 @@ public class JsonWriter implements Closeable, Flushable {
return this; // skip the name and the value
}
}
- beforeValue(false);
+ beforeValue();
out.write("null");
return this;
}
@@ -463,7 +463,7 @@ public class JsonWriter implements Closeable, Flushable {
*/
public JsonWriter value(boolean value) throws IOException {
writeDeferredName();
- beforeValue(false);
+ beforeValue();
out.write(value ? "true" : "false");
return this;
}
@@ -480,7 +480,7 @@ public class JsonWriter implements Closeable, Flushable {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
}
writeDeferredName();
- beforeValue(false);
+ beforeValue();
out.append(Double.toString(value));
return this;
}
@@ -492,7 +492,7 @@ public class JsonWriter implements Closeable, Flushable {
*/
public JsonWriter value(long value) throws IOException {
writeDeferredName();
- beforeValue(false);
+ beforeValue();
out.write(Long.toString(value));
return this;
}
@@ -515,7 +515,7 @@ public class JsonWriter implements Closeable, Flushable {
&& (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN"))) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
}
- beforeValue(false);
+ beforeValue();
out.append(string);
return this;
}
@@ -608,12 +608,9 @@ public class JsonWriter implements Closeable, Flushable {
* Inserts any necessary separators and whitespace before a literal value,
* inline array, or inline object. Also adjusts the stack to expect either a
* closing bracket or another element.
- *
- * @param root true if the value is a new array or object, the two values
- * permitted as top-level elements.
*/
@SuppressWarnings("fallthrough")
- private void beforeValue(boolean root) throws IOException {
+ private void beforeValue() throws IOException {
switch (peek()) {
case NONEMPTY_DOCUMENT:
if (!lenient) {
@@ -622,10 +619,6 @@ public class JsonWriter implements Closeable, Flushable {
}
// fall-through
case EMPTY_DOCUMENT: // first in document
- if (!lenient && !root) {
- throw new IllegalStateException(
- "JSON must start with an array or an object.");
- }
replaceTop(NONEMPTY_DOCUMENT);
break;
diff --git a/gson/src/test/java/com/google/gson/stream/JsonReaderTest.java b/gson/src/test/java/com/google/gson/stream/JsonReaderTest.java
index 72c9aa4c..a192940f 100644
--- a/gson/src/test/java/com/google/gson/stream/JsonReaderTest.java
+++ b/gson/src/test/java/com/google/gson/stream/JsonReaderTest.java
@@ -195,14 +195,6 @@ public final class JsonReaderTest extends TestCase {
}
}
- public void testNoTopLevelObject() {
- try {
- new JsonReader(reader("true")).nextBoolean();
- fail();
- } catch (IOException expected) {
- }
- }
-
public void testCharacterUnescaping() throws IOException {
String json = "[\"a\","
+ "\"a\\\"\","
@@ -1227,46 +1219,39 @@ public final class JsonReaderTest extends TestCase {
}
}
- public void testStrictTopLevelString() {
- JsonReader reader = new JsonReader(reader("\"a\""));
- try {
- reader.nextString();
- fail();
- } catch (IOException expected) {
- }
+ public void testTopLevelValueTypes() throws IOException {
+ JsonReader reader1 = new JsonReader(reader("true"));
+ assertTrue(reader1.nextBoolean());
+ assertEquals(JsonToken.END_DOCUMENT, reader1.peek());
+
+ JsonReader reader2 = new JsonReader(reader("false"));
+ assertFalse(reader2.nextBoolean());
+ assertEquals(JsonToken.END_DOCUMENT, reader2.peek());
+
+ JsonReader reader3 = new JsonReader(reader("null"));
+ assertEquals(JsonToken.NULL, reader3.peek());
+ reader3.nextNull();
+ assertEquals(JsonToken.END_DOCUMENT, reader3.peek());
+
+ JsonReader reader4 = new JsonReader(reader("123"));
+ assertEquals(123, reader4.nextInt());
+ assertEquals(JsonToken.END_DOCUMENT, reader4.peek());
+
+ JsonReader reader5 = new JsonReader(reader("123.4"));
+ assertEquals(123.4, reader5.nextDouble());
+ assertEquals(JsonToken.END_DOCUMENT, reader5.peek());
+
+ JsonReader reader6 = new JsonReader(reader("\"a\""));
+ assertEquals("a", reader6.nextString());
+ assertEquals(JsonToken.END_DOCUMENT, reader6.peek());
}
- public void testLenientTopLevelString() throws IOException {
- JsonReader reader = new JsonReader(reader("\"a\""));
- reader.setLenient(true);
- assertEquals("a", reader.nextString());
+ public void testTopLevelValueTypeWithSkipValue() throws IOException {
+ JsonReader reader = new JsonReader(reader("true"));
+ reader.skipValue();
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
- public void testStrictTopLevelValueType() {
- JsonReader reader = new JsonReader(reader("true"));
- try {
- reader.nextBoolean();
- fail();
- } catch (IOException expected) {
- }
- }
-
- public void testLenientTopLevelValueType() throws IOException {
- JsonReader reader = new JsonReader(reader("true"));
- reader.setLenient(true);
- assertEquals(true, reader.nextBoolean());
- }
-
- public void testStrictTopLevelValueTypeWithSkipValue() {
- JsonReader reader = new JsonReader(reader("true"));
- try {
- reader.skipValue();
- fail();
- } catch (IOException expected) {
- }
- }
-
public void testStrictNonExecutePrefix() {
JsonReader reader = new JsonReader(reader(")]}'\n []"));
try {
@@ -1524,7 +1509,7 @@ public final class JsonReaderTest extends TestCase {
} catch (MalformedJsonException expected) {
}
}
-
+
public void testVeryLongQuotedString() throws IOException {
char[] stringChars = new char[1024 * 16];
Arrays.fill(stringChars, 'x');
diff --git a/gson/src/test/java/com/google/gson/stream/JsonWriterTest.java b/gson/src/test/java/com/google/gson/stream/JsonWriterTest.java
index 4cfd55a7..91763d18 100644
--- a/gson/src/test/java/com/google/gson/stream/JsonWriterTest.java
+++ b/gson/src/test/java/com/google/gson/stream/JsonWriterTest.java
@@ -25,11 +25,44 @@ import junit.framework.TestCase;
@SuppressWarnings("resource")
public final class JsonWriterTest extends TestCase {
- public void testWrongTopLevelType() throws IOException {
+ public void testTopLevelValueTypes() throws IOException {
+ StringWriter string1 = new StringWriter();
+ JsonWriter writer1 = new JsonWriter(string1);
+ writer1.value(true);
+ writer1.close();
+ assertEquals("true", string1.toString());
+
+ StringWriter string2 = new StringWriter();
+ JsonWriter writer2 = new JsonWriter(string2);
+ writer2.nullValue();
+ writer2.close();
+ assertEquals("null", string2.toString());
+
+ StringWriter string3 = new StringWriter();
+ JsonWriter writer3 = new JsonWriter(string3);
+ writer3.value(123);
+ writer3.close();
+ assertEquals("123", string3.toString());
+
+ StringWriter string4 = new StringWriter();
+ JsonWriter writer4 = new JsonWriter(string4);
+ writer4.value(123.4);
+ writer4.close();
+ assertEquals("123.4", string4.toString());
+
+ StringWriter string5 = new StringWriter();
+ JsonWriter writert = new JsonWriter(string5);
+ writert.value("a");
+ writert.close();
+ assertEquals("\"a\"", string5.toString());
+ }
+
+ public void testInvalidTopLevelTypes() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
+ jsonWriter.name("hello");
try {
- jsonWriter.value("a");
+ jsonWriter.value("world");
fail();
} catch (IllegalStateException expected) {
}