From ba5479cf11484f92ac7b18887759ee9e60359ff6 Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Mon, 11 Aug 2014 09:23:37 -0700 Subject: [PATCH] Convert JsonWriter to use Okio Sink. --- .../java/com/squareup/moshi/JsonAdapter.java | 8 +- .../java/com/squareup/moshi/JsonWriter.java | 68 ++++--- .../com/squareup/moshi/JsonWriterTest.java | 186 +++++++++--------- 3 files changed, 133 insertions(+), 129 deletions(-) diff --git a/moshi/src/main/java/com/squareup/moshi/JsonAdapter.java b/moshi/src/main/java/com/squareup/moshi/JsonAdapter.java index 8197a62..3bb89aa 100644 --- a/moshi/src/main/java/com/squareup/moshi/JsonAdapter.java +++ b/moshi/src/main/java/com/squareup/moshi/JsonAdapter.java @@ -16,9 +16,9 @@ package com.squareup.moshi; import java.io.IOException; -import java.io.StringWriter; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Type; +import okio.Buffer; /** * Converts Java values to JSON, and JSON values to Java. @@ -33,9 +33,9 @@ public abstract class JsonAdapter { public abstract void toJson(JsonWriter writer, T value) throws IOException; public final String toJson(T value) throws IOException { - StringWriter stringWriter = new StringWriter(); - toJson(new JsonWriter(stringWriter), value); - return stringWriter.toString(); + Buffer buffer = new Buffer(); + toJson(new JsonWriter(buffer), value); + return buffer.readUtf8(); } /** diff --git a/moshi/src/main/java/com/squareup/moshi/JsonWriter.java b/moshi/src/main/java/com/squareup/moshi/JsonWriter.java index 3c26ea5..4759624 100644 --- a/moshi/src/main/java/com/squareup/moshi/JsonWriter.java +++ b/moshi/src/main/java/com/squareup/moshi/JsonWriter.java @@ -18,7 +18,9 @@ package com.squareup.moshi; import java.io.Closeable; import java.io.Flushable; import java.io.IOException; -import java.io.Writer; +import okio.BufferedSink; +import okio.Okio; +import okio.Sink; import static com.squareup.moshi.JsonScope.DANGLING_NAME; import static com.squareup.moshi.JsonScope.EMPTY_ARRAY; @@ -74,8 +76,8 @@ import static com.squareup.moshi.JsonScope.NONEMPTY_OBJECT; * } * ]} * This code encodes the above structure:
   {@code
- *   public void writeJsonStream(OutputStream out, List messages) throws IOException {
- *     JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
+ *   public void writeJsonStream(Sink sink, List messages) throws IOException {
+ *     JsonWriter writer = new JsonWriter(sink);
  *     writer.setIndentSpaces(4);
  *     writeMessagesArray(writer, messages);
  *     writer.close();
@@ -153,7 +155,7 @@ public class JsonWriter implements Closeable, Flushable {
   }
 
   /** The output data, containing at most one top-level array or object. */
-  private final Writer out;
+  private final BufferedSink sink;
 
   private int[] stack = new int[32];
   private int stackSize = 0;
@@ -179,15 +181,17 @@ public class JsonWriter implements Closeable, Flushable {
   private boolean serializeNulls;
 
   /**
-   * Creates a new instance that writes a JSON-encoded stream to {@code out}.
-   * For best performance, ensure {@link Writer} is buffered; wrapping in
-   * {@link java.io.BufferedWriter BufferedWriter} if necessary.
+   * Creates a new instance that writes a JSON-encoded stream to {@code sink}.
    */
-  public JsonWriter(Writer out) {
-    if (out == null) {
-      throw new NullPointerException("out == null");
+  public JsonWriter(Sink sink) {
+    if (sink == null) {
+      throw new NullPointerException("sink == null");
+    }
+    if (sink instanceof BufferedSink) {
+      this.sink = (BufferedSink) sink;
+    } else {
+      this.sink = Okio.buffer(sink);
     }
-    this.out = out;
   }
 
   /**
@@ -294,7 +298,7 @@ public class JsonWriter implements Closeable, Flushable {
   private JsonWriter open(int empty, String openBracket) throws IOException {
     beforeValue(true);
     push(empty);
-    out.write(openBracket);
+    sink.writeUtf8(openBracket);
     return this;
   }
 
@@ -316,7 +320,7 @@ public class JsonWriter implements Closeable, Flushable {
     if (context == nonempty) {
       newline();
     }
-    out.write(closeBracket);
+    sink.writeUtf8(closeBracket);
     return this;
   }
 
@@ -405,7 +409,7 @@ public class JsonWriter implements Closeable, Flushable {
       }
     }
     beforeValue(false);
-    out.write("null");
+    sink.writeUtf8("null");
     return this;
   }
 
@@ -417,7 +421,7 @@ public class JsonWriter implements Closeable, Flushable {
   public JsonWriter value(boolean value) throws IOException {
     writeDeferredName();
     beforeValue(false);
-    out.write(value ? "true" : "false");
+    sink.writeUtf8(value ? "true" : "false");
     return this;
   }
 
@@ -434,7 +438,7 @@ public class JsonWriter implements Closeable, Flushable {
     }
     writeDeferredName();
     beforeValue(false);
-    out.append(Double.toString(value));
+    sink.writeUtf8(Double.toString(value));
     return this;
   }
 
@@ -446,7 +450,7 @@ public class JsonWriter implements Closeable, Flushable {
   public JsonWriter value(long value) throws IOException {
     writeDeferredName();
     beforeValue(false);
-    out.write(Long.toString(value));
+    sink.writeUtf8(Long.toString(value));
     return this;
   }
 
@@ -469,28 +473,28 @@ public class JsonWriter implements Closeable, Flushable {
       throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
     }
     beforeValue(false);
-    out.append(string);
+    sink.writeUtf8(string);
     return this;
   }
 
   /**
-   * Ensures all buffered data is written to the underlying {@link Writer}
+   * Ensures all buffered data is written to the underlying {@link Sink}
    * and flushes that writer.
    */
   public void flush() throws IOException {
     if (stackSize == 0) {
       throw new IllegalStateException("JsonWriter is closed.");
     }
-    out.flush();
+    sink.flush();
   }
 
   /**
-   * Flushes and closes this writer and the underlying {@link Writer}.
+   * Flushes and closes this writer and the underlying {@link Sink}.
    *
    * @throws IOException if the JSON document is incomplete.
    */
   public void close() throws IOException {
-    out.close();
+    sink.close();
 
     int size = stackSize;
     if (size > 1 || size == 1 && stack[size - 1] != NONEMPTY_DOCUMENT) {
@@ -501,7 +505,7 @@ public class JsonWriter implements Closeable, Flushable {
 
   private void string(String value) throws IOException {
     String[] replacements = REPLACEMENT_CHARS;
-    out.write("\"");
+    sink.writeByte('"');
     int last = 0;
     int length = value.length();
     for (int i = 0; i < length; i++) {
@@ -520,15 +524,15 @@ public class JsonWriter implements Closeable, Flushable {
         continue;
       }
       if (last < i) {
-        out.write(value, last, i - last);
+        sink.writeUtf8(value.substring(last, i));
       }
-      out.write(replacement);
+      sink.writeUtf8(replacement);
       last = i + 1;
     }
     if (last < length) {
-      out.write(value, last, length - last);
+      sink.writeUtf8(value.substring(last, length));
     }
-    out.write("\"");
+    sink.writeByte('"');
   }
 
   private void newline() throws IOException {
@@ -536,9 +540,9 @@ public class JsonWriter implements Closeable, Flushable {
       return;
     }
 
-    out.write("\n");
+    sink.writeByte('\n');
     for (int i = 1, size = stackSize; i < size; i++) {
-      out.write(indent);
+      sink.writeUtf8(indent);
     }
   }
 
@@ -549,7 +553,7 @@ public class JsonWriter implements Closeable, Flushable {
   private void beforeName() throws IOException {
     int context = peek();
     if (context == NONEMPTY_OBJECT) { // first in object
-      out.write(',');
+      sink.writeByte(',');
     } else if (context != EMPTY_OBJECT) { // not in an object!
       throw new IllegalStateException("Nesting problem.");
     }
@@ -588,12 +592,12 @@ public class JsonWriter implements Closeable, Flushable {
         break;
 
       case NONEMPTY_ARRAY: // another in array
-        out.append(',');
+        sink.writeByte(',');
         newline();
         break;
 
       case DANGLING_NAME: // value for name
-        out.append(separator);
+        sink.writeUtf8(separator);
         replaceTop(NONEMPTY_OBJECT);
         break;
 
diff --git a/moshi/src/test/java/com/squareup/moshi/JsonWriterTest.java b/moshi/src/test/java/com/squareup/moshi/JsonWriterTest.java
index 0d327ab..4978a23 100644
--- a/moshi/src/test/java/com/squareup/moshi/JsonWriterTest.java
+++ b/moshi/src/test/java/com/squareup/moshi/JsonWriterTest.java
@@ -16,9 +16,9 @@
 package com.squareup.moshi;
 
 import java.io.IOException;
-import java.io.StringWriter;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import okio.Buffer;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -26,31 +26,31 @@ import static org.junit.Assert.fail;
 
 public final class JsonWriterTest {
   @Test public void nullsValuesNotSerializedByDefault() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     jsonWriter.name("a");
     jsonWriter.nullValue();
     jsonWriter.endObject();
     jsonWriter.close();
-    assertEquals("{}", stringWriter.toString());
+    assertEquals("{}", buffer.readUtf8());
   }
 
   @Test public void nullsValuesSerializedWhenConfigured() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.setSerializeNulls(true);
     jsonWriter.beginObject();
     jsonWriter.name("a");
     jsonWriter.nullValue();
     jsonWriter.endObject();
     jsonWriter.close();
-    assertEquals("{\"a\":null}", stringWriter.toString());
+    assertEquals("{\"a\":null}", buffer.readUtf8());
   }
 
   @Test public void wrongTopLevelType() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     try {
       jsonWriter.value("a");
       fail();
@@ -59,8 +59,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void twoNames() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     jsonWriter.name("a");
     try {
@@ -71,8 +71,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void nameWithoutValue() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     jsonWriter.name("a");
     try {
@@ -83,8 +83,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void valueWithoutName() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     try {
       jsonWriter.value(true);
@@ -94,8 +94,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void multipleTopLevelValues() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray().endArray();
     try {
       jsonWriter.beginArray();
@@ -105,8 +105,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void badNestingObject() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.beginObject();
     try {
@@ -117,8 +117,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void badNestingArray() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.beginArray();
     try {
@@ -129,8 +129,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void nullName() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     try {
       jsonWriter.name(null);
@@ -140,19 +140,19 @@ public final class JsonWriterTest {
   }
 
   @Test public void nullStringValue() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.setSerializeNulls(true);
     jsonWriter.beginObject();
     jsonWriter.name("a");
     jsonWriter.value((String) null);
     jsonWriter.endObject();
-    assertEquals("{\"a\":null}", stringWriter.toString());
+    assertEquals("{\"a\":null}", buffer.readUtf8());
   }
 
   @Test public void nonFiniteDoubles() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     try {
       jsonWriter.value(Double.NaN);
@@ -172,8 +172,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void nonFiniteBoxedDoubles() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     try {
       jsonWriter.value(new Double(Double.NaN));
@@ -193,8 +193,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void doubles() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.value(-0.0);
     jsonWriter.value(1.0);
@@ -215,12 +215,12 @@ public final class JsonWriterTest {
         + "-0.5,"
         + "2.2250738585072014E-308,"
         + "3.141592653589793,"
-        + "2.718281828459045]", stringWriter.toString());
+        + "2.718281828459045]", buffer.readUtf8());
   }
 
   @Test public void longs() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.value(0);
     jsonWriter.value(1);
@@ -233,12 +233,12 @@ public final class JsonWriterTest {
         + "1,"
         + "-1,"
         + "-9223372036854775808,"
-        + "9223372036854775807]", stringWriter.toString());
+        + "9223372036854775807]", buffer.readUtf8());
   }
 
   @Test public void numbers() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.value(new BigInteger("0"));
     jsonWriter.value(new BigInteger("9223372036854775808"));
@@ -249,31 +249,31 @@ public final class JsonWriterTest {
     assertEquals("[0,"
         + "9223372036854775808,"
         + "-9223372036854775809,"
-        + "3.141592653589793238462643383]", stringWriter.toString());
+        + "3.141592653589793238462643383]", buffer.readUtf8());
   }
 
   @Test public void booleans() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.value(true);
     jsonWriter.value(false);
     jsonWriter.endArray();
-    assertEquals("[true,false]", stringWriter.toString());
+    assertEquals("[true,false]", buffer.readUtf8());
   }
 
   @Test public void nulls() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.nullValue();
     jsonWriter.endArray();
-    assertEquals("[null]", stringWriter.toString());
+    assertEquals("[null]", buffer.readUtf8());
   }
 
   @Test public void strings() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.value("a");
     jsonWriter.value("a\"");
@@ -311,37 +311,37 @@ public final class JsonWriterTest {
         + "\"[\","
         + "\"]\","
         + "\"\\u0000\","
-        + "\"\\u0019\"]", stringWriter.toString());
+        + "\"\\u0019\"]", buffer.readUtf8());
   }
 
   @Test public void unicodeLineBreaksEscaped() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.value("\u2028 \u2029");
     jsonWriter.endArray();
-    assertEquals("[\"\\u2028 \\u2029\"]", stringWriter.toString());
+    assertEquals("[\"\\u2028 \\u2029\"]", buffer.readUtf8());
   }
 
   @Test public void emptyArray() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.endArray();
-    assertEquals("[]", stringWriter.toString());
+    assertEquals("[]", buffer.readUtf8());
   }
 
   @Test public void emptyObject() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     jsonWriter.endObject();
-    assertEquals("{}", stringWriter.toString());
+    assertEquals("{}", buffer.readUtf8());
   }
 
   @Test public void objectsInArrays() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginArray();
     jsonWriter.beginObject();
     jsonWriter.name("a").value(5);
@@ -353,12 +353,12 @@ public final class JsonWriterTest {
     jsonWriter.endObject();
     jsonWriter.endArray();
     assertEquals("[{\"a\":5,\"b\":false},"
-        + "{\"c\":6,\"d\":true}]", stringWriter.toString());
+        + "{\"c\":6,\"d\":true}]", buffer.readUtf8());
   }
 
   @Test public void arraysInObjects() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     jsonWriter.name("a");
     jsonWriter.beginArray();
@@ -372,24 +372,24 @@ public final class JsonWriterTest {
     jsonWriter.endArray();
     jsonWriter.endObject();
     assertEquals("{\"a\":[5,false],"
-        + "\"b\":[6,true]}", stringWriter.toString());
+        + "\"b\":[6,true]}", buffer.readUtf8());
   }
 
   @Test public void deepNestingArrays() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     for (int i = 0; i < 20; i++) {
       jsonWriter.beginArray();
     }
     for (int i = 0; i < 20; i++) {
       jsonWriter.endArray();
     }
-    assertEquals("[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]", stringWriter.toString());
+    assertEquals("[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]", buffer.readUtf8());
   }
 
   @Test public void deepNestingObjects() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     for (int i = 0; i < 20; i++) {
       jsonWriter.name("a");
@@ -401,23 +401,23 @@ public final class JsonWriterTest {
     jsonWriter.endObject();
     assertEquals("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":"
         + "{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{"
-        + "}}}}}}}}}}}}}}}}}}}}}", stringWriter.toString());
+        + "}}}}}}}}}}}}}}}}}}}}}", buffer.readUtf8());
   }
 
   @Test public void repeatedName() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.beginObject();
     jsonWriter.name("a").value(true);
     jsonWriter.name("a").value(false);
     jsonWriter.endObject();
     // JsonWriter doesn't attempt to detect duplicate names
-    assertEquals("{\"a\":true,\"a\":false}", stringWriter.toString());
+    assertEquals("{\"a\":true,\"a\":false}", buffer.readUtf8());
   }
 
   @Test public void prettyPrintObject() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.setSerializeNulls(true);
     jsonWriter.setIndent("   ");
 
@@ -450,12 +450,12 @@ public final class JsonWriterTest {
         + "      \"i\": 9.0\n"
         + "   }\n"
         + "}";
-    assertEquals(expected, stringWriter.toString());
+    assertEquals(expected, buffer.readUtf8());
   }
 
   @Test public void prettyPrintArray() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter jsonWriter = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter jsonWriter = new JsonWriter(buffer);
     jsonWriter.setIndent("   ");
 
     jsonWriter.beginArray();
@@ -487,24 +487,24 @@ public final class JsonWriterTest {
         + "      9.0\n"
         + "   ]\n"
         + "]";
-    assertEquals(expected, stringWriter.toString());
+    assertEquals(expected, buffer.readUtf8());
   }
 
   @Test public void lenientWriterPermitsMultipleTopLevelValues() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter writer = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter writer = new JsonWriter(buffer);
     writer.setLenient(true);
     writer.beginArray();
     writer.endArray();
     writer.beginArray();
     writer.endArray();
     writer.close();
-    assertEquals("[][]", stringWriter.toString());
+    assertEquals("[][]", buffer.readUtf8());
   }
 
   @Test public void strictWriterDoesNotPermitMultipleTopLevelValues() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter writer = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter writer = new JsonWriter(buffer);
     writer.beginArray();
     writer.endArray();
     try {
@@ -515,8 +515,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void closedWriterThrowsOnStructure() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter writer = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter writer = new JsonWriter(buffer);
     writer.beginArray();
     writer.endArray();
     writer.close();
@@ -543,8 +543,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void closedWriterThrowsOnName() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter writer = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter writer = new JsonWriter(buffer);
     writer.beginArray();
     writer.endArray();
     writer.close();
@@ -556,8 +556,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void closedWriterThrowsOnValue() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter writer = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter writer = new JsonWriter(buffer);
     writer.beginArray();
     writer.endArray();
     writer.close();
@@ -569,8 +569,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void closedWriterThrowsOnFlush() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter writer = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter writer = new JsonWriter(buffer);
     writer.beginArray();
     writer.endArray();
     writer.close();
@@ -582,8 +582,8 @@ public final class JsonWriterTest {
   }
 
   @Test public void writerCloseIsIdempotent() throws IOException {
-    StringWriter stringWriter = new StringWriter();
-    JsonWriter writer = new JsonWriter(stringWriter);
+    Buffer buffer = new Buffer();
+    JsonWriter writer = new JsonWriter(buffer);
     writer.beginArray();
     writer.endArray();
     writer.close();