diff --git a/src/main/java/org/json/JSONArray.java b/src/main/java/org/json/JSONArray.java index 38b0b31..cda5694 100644 --- a/src/main/java/org/json/JSONArray.java +++ b/src/main/java/org/json/JSONArray.java @@ -5,7 +5,6 @@ Public Domain. */ import java.io.IOException; -import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Array; import java.math.BigDecimal; @@ -1695,7 +1694,7 @@ public class JSONArray implements Iterable { */ @SuppressWarnings("resource") public String toString(int indentFactor) throws JSONException { - StringWriter sw = new StringWriter(); + Writer sw = new StringBuilderWriter(); return this.write(sw, indentFactor, 0).toString(); } diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index 4c08b0b..36a7c7f 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -6,7 +6,6 @@ Public Domain. import java.io.Closeable; import java.io.IOException; -import java.io.StringWriter; import java.io.Writer; import java.lang.annotation.Annotation; import java.lang.reflect.Field; @@ -2227,7 +2226,7 @@ public class JSONObject { */ @SuppressWarnings("resource") public static String quote(String string) { - StringWriter sw = new StringWriter(); + Writer sw = new StringBuilderWriter(); try { return quote(string, sw).toString(); } catch (IOException ignored) { @@ -2558,7 +2557,7 @@ public class JSONObject { */ @SuppressWarnings("resource") public String toString(int indentFactor) throws JSONException { - StringWriter w = new StringWriter(); + Writer w = new StringBuilderWriter(); return this.write(w, indentFactor, 0).toString(); } diff --git a/src/main/java/org/json/StringBuilderWriter.java b/src/main/java/org/json/StringBuilderWriter.java new file mode 100644 index 0000000..25d2dbe --- /dev/null +++ b/src/main/java/org/json/StringBuilderWriter.java @@ -0,0 +1,82 @@ +package org.json; + +import java.io.IOException; +import java.io.Writer; + +/** + * Performance optimised alternative for {@link java.io.StringWriter} + * using internally a {@link StringBuilder} instead of a {@link StringBuffer}. + */ +class StringBuilderWriter extends Writer { + private final StringBuilder builder; + + StringBuilderWriter() { + builder = new StringBuilder(); + lock = builder; + } + + StringBuilderWriter(int initialSize) { + if (initialSize < 0) { + throw new IllegalArgumentException("Negative buffer size"); + } + builder = new StringBuilder(initialSize); + lock = builder; + } + + @Override + public void write(int c) { + builder.append((char) c); + } + + @Override + public void write(char cbuf[], int offset, int length) { + if ((offset < 0) || (offset > cbuf.length) || (length < 0) || + ((offset + length) > cbuf.length) || ((offset + length) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (length == 0) { + return; + } + builder.append(cbuf, offset, length); + } + + @Override + public void write(String str) { + builder.append(str); + } + + @Override + public void write(String str, int offset, int length) { + builder.append(str, offset, offset + length); + } + + @Override + public StringBuilderWriter append(CharSequence csq) { + write(String.valueOf(csq)); + return this; + } + + @Override + public StringBuilderWriter append(CharSequence csq, int start, int end) { + if (csq == null) csq = "null"; + return append(csq.subSequence(start, end)); + } + + @Override + public StringBuilderWriter append(char c) { + write(c); + return this; + } + + @Override + public String toString() { + return builder.toString(); + } + + @Override + public void flush() { + } + + @Override + public void close() throws IOException { + } +}