From feb3aec259c9b4a4dc196edcd5a9ab34655d0d97 Mon Sep 17 00:00:00 2001 From: "moandji.ezana" Date: Mon, 29 Jun 2015 18:49:34 +0200 Subject: [PATCH] TomlWriter#write methods delegate to TomlWriter#write(Object, Writer) to take advantage of streaming when possible. --- .../moandjiezana/toml/BooleanConverter.java | 2 +- .../com/moandjiezana/toml/DateConverter.java | 4 +- .../com/moandjiezana/toml/MapValueWriter.java | 8 +- .../moandjiezana/toml/NumberConverter.java | 2 +- .../toml/PrimitiveArrayValueWriter.java | 14 ++-- .../moandjiezana/toml/StringConverter.java | 16 ++-- .../com/moandjiezana/toml/TomlWriter.java | 51 ++++++++----- .../com/moandjiezana/toml/ValueWriters.java | 8 +- .../com/moandjiezana/toml/WriterContext.java | 76 ++++++++++++++----- 9 files changed, 119 insertions(+), 62 deletions(-) diff --git a/src/main/java/com/moandjiezana/toml/BooleanConverter.java b/src/main/java/com/moandjiezana/toml/BooleanConverter.java index 64225de..2fe9877 100644 --- a/src/main/java/com/moandjiezana/toml/BooleanConverter.java +++ b/src/main/java/com/moandjiezana/toml/BooleanConverter.java @@ -31,7 +31,7 @@ class BooleanConverter implements ValueConverter, ValueWriter { @Override public void write(Object value, WriterContext context) { - context.output.append(value.toString()); + context.write(value.toString()); } @Override diff --git a/src/main/java/com/moandjiezana/toml/DateConverter.java b/src/main/java/com/moandjiezana/toml/DateConverter.java index b44f7b7..0c8f375 100644 --- a/src/main/java/com/moandjiezana/toml/DateConverter.java +++ b/src/main/java/com/moandjiezana/toml/DateConverter.java @@ -99,12 +99,12 @@ class DateConverter implements ValueConverter, ValueWriter { } dateFormat.setTimeZone(context.getTomlWriter().getTimeZone()); - context.output.append(dateFormat.format(value)); + context.write(dateFormat.format(value)); if (customDateFormat == null) { Calendar calendar = context.getTomlWriter().getCalendar(); int tzOffset = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000); - context.output.append(String.format("%+03d:%02d", tzOffset / 60, tzOffset % 60)); + context.write(String.format("%+03d:%02d", tzOffset / 60, tzOffset % 60)); } } diff --git a/src/main/java/com/moandjiezana/toml/MapValueWriter.java b/src/main/java/com/moandjiezana/toml/MapValueWriter.java index 8a08eaf..0be9b07 100644 --- a/src/main/java/com/moandjiezana/toml/MapValueWriter.java +++ b/src/main/java/com/moandjiezana/toml/MapValueWriter.java @@ -37,14 +37,14 @@ class MapValueWriter implements ValueWriter { ValueWriter valueWriter = WRITERS.findWriterFor(fromValue); if (valueWriter.isPrimitiveType()) { context.indent(); - context.output.append(quoteKey(key)).append(" = "); + context.write(quoteKey(key)).write(" = "); valueWriter.write(fromValue, context); - context.output.append('\n'); + context.write('\n'); } else if (valueWriter == PRIMITIVE_ARRAY_VALUE_WRITER) { context.setArrayKey(key.toString()); - context.output.append(quoteKey(key)).append(" = "); + context.write(quoteKey(key)).write(" = "); valueWriter.write(fromValue, context); - context.output.append('\n'); + context.write('\n'); } } diff --git a/src/main/java/com/moandjiezana/toml/NumberConverter.java b/src/main/java/com/moandjiezana/toml/NumberConverter.java index 156f6e1..22fceaa 100644 --- a/src/main/java/com/moandjiezana/toml/NumberConverter.java +++ b/src/main/java/com/moandjiezana/toml/NumberConverter.java @@ -90,7 +90,7 @@ class NumberConverter implements ValueConverter, ValueWriter { @Override public void write(Object value, WriterContext context) { - context.output.append(value.toString()); + context.write(value.toString()); } @Override diff --git a/src/main/java/com/moandjiezana/toml/PrimitiveArrayValueWriter.java b/src/main/java/com/moandjiezana/toml/PrimitiveArrayValueWriter.java index 81ad1f4..b9d8018 100644 --- a/src/main/java/com/moandjiezana/toml/PrimitiveArrayValueWriter.java +++ b/src/main/java/com/moandjiezana/toml/PrimitiveArrayValueWriter.java @@ -1,9 +1,9 @@ package com.moandjiezana.toml; -import java.util.Collection; - import static com.moandjiezana.toml.ValueWriters.WRITERS; +import java.util.Collection; + class PrimitiveArrayValueWriter extends ArrayValueWriter { static final ValueWriter PRIMITIVE_ARRAY_VALUE_WRITER = new PrimitiveArrayValueWriter(); @@ -16,9 +16,9 @@ class PrimitiveArrayValueWriter extends ArrayValueWriter { public void write(Object value, WriterContext context) { Collection values = normalize(value); - context.output.append('['); + context.write('['); if (!context.getTomlWriter().wantTerseArrays()) { - context.output.append(' '); + context.write(' '); } boolean first = true; @@ -37,16 +37,16 @@ class PrimitiveArrayValueWriter extends ArrayValueWriter { " but found " + writer ); } - context.output.append(", "); + context.write(", "); } WRITERS.write(elem, context); } if (!context.getTomlWriter().wantTerseArrays()) { - context.output.append(' '); + context.write(' '); } - context.output.append(']'); + context.write(']'); } private PrimitiveArrayValueWriter() {} diff --git a/src/main/java/com/moandjiezana/toml/StringConverter.java b/src/main/java/com/moandjiezana/toml/StringConverter.java index 28b1cb4..1124e38 100644 --- a/src/main/java/com/moandjiezana/toml/StringConverter.java +++ b/src/main/java/com/moandjiezana/toml/StringConverter.java @@ -96,9 +96,9 @@ class StringConverter implements ValueConverter, ValueWriter { @Override public void write(Object value, WriterContext context) { - context.output.append('"'); - escapeUnicode(value.toString(), context.output); - context.output.append('"'); + context.write('"'); + escapeUnicode(value.toString(), context); + context.write('"'); } @Override @@ -106,17 +106,17 @@ class StringConverter implements ValueConverter, ValueWriter { return true; } - private void escapeUnicode(String in, StringBuilder out) { + private void escapeUnicode(String in, WriterContext context) { for (int i = 0; i < in.length(); i++) { int codePoint = in.codePointAt(i); if (codePoint < specialCharacterEscapes.length && specialCharacterEscapes[codePoint] != null) { - out.append(specialCharacterEscapes[codePoint]); + context.write(specialCharacterEscapes[codePoint]); } else if (codePoint > 0x1f && codePoint < 0x7f) { - out.append(Character.toChars(codePoint)); + context.write(Character.toChars(codePoint)); } else if (codePoint <= 0xFFFF) { - out.append(String.format("\\u%04X", codePoint)); + context.write(String.format("\\u%04X", codePoint)); } else { - out.append(String.format("\\U%08X", codePoint)); + context.write(String.format("\\U%08X", codePoint)); // Skip the low surrogate, which will be the next in the code point sequence. i++; } diff --git a/src/main/java/com/moandjiezana/toml/TomlWriter.java b/src/main/java/com/moandjiezana/toml/TomlWriter.java index bddccff..b648f0c 100644 --- a/src/main/java/com/moandjiezana/toml/TomlWriter.java +++ b/src/main/java/com/moandjiezana/toml/TomlWriter.java @@ -1,14 +1,20 @@ package com.moandjiezana.toml; -import java.io.*; +import static com.moandjiezana.toml.ValueWriters.WRITERS; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.Writer; import java.text.DateFormat; import java.util.GregorianCalendar; import java.util.List; import java.util.Map; import java.util.TimeZone; -import static com.moandjiezana.toml.ValueWriters.WRITERS; - /** *

Converts Objects to TOML

* @@ -45,29 +51,27 @@ public class TomlWriter { * @return a string containing the TOML representation of the given Object */ public String write(Object from) { - return WRITERS.write(from, this); - } - - /** - * Write an Object in TOML to a {@link Writer}. - * - * @param from the object to be written - * @param target the Writer to which TOML will be written - * @throws IOException if target.write() fails - */ - public void write(Object from, Writer target) throws IOException { - target.write(write(from)); + try { + StringWriter output = new StringWriter(); + write(from, output); + + return output.toString(); + } catch (IOException e) { + throw new RuntimeException(e); + } } /** * Write an Object in TOML to a {@link OutputStream}. * * @param from the object to be written - * @param target the OutputStream to which the TOML will be written + * @param target the OutputStream to which the TOML will be written. The stream is not closed after being written to. * @throws IOException if target.write() fails */ public void write(Object from, OutputStream target) throws IOException { - target.write(write(from).getBytes()); + OutputStreamWriter writer = new OutputStreamWriter(target); + write(from, writer); + writer.flush(); } /** @@ -79,10 +83,21 @@ public class TomlWriter { */ public void write(Object from, File target) throws IOException { FileWriter writer = new FileWriter(target); - writer.write(write(from)); + write(from, writer); writer.close(); } + /** + * Write an Object in TOML to a {@link Writer}. + * + * @param from the object to be written + * @param target the Writer to which TOML will be written. The Writer is not closed. + * @throws IOException if target.write() fails + */ + public void write(Object from, Writer target) throws IOException { + WRITERS.write(from, this, target); + } + public WriterIndentationPolicy getIndentationPolicy() { return indentationPolicy; } diff --git a/src/main/java/com/moandjiezana/toml/ValueWriters.java b/src/main/java/com/moandjiezana/toml/ValueWriters.java index aba1b99..1c7a27f 100644 --- a/src/main/java/com/moandjiezana/toml/ValueWriters.java +++ b/src/main/java/com/moandjiezana/toml/ValueWriters.java @@ -9,6 +9,8 @@ import static com.moandjiezana.toml.PrimitiveArrayValueWriter.PRIMITIVE_ARRAY_VA import static com.moandjiezana.toml.StringConverter.STRING_PARSER; import static com.moandjiezana.toml.TableArrayValueWriter.TABLE_ARRAY_VALUE_WRITER; +import java.io.Writer; + class ValueWriters { static final ValueWriters WRITERS = new ValueWriters(); @@ -23,11 +25,9 @@ class ValueWriters { return OBJECT_VALUE_WRITER; } - String write(Object value, TomlWriter tomlWriter) { - WriterContext context = new WriterContext(tomlWriter); + void write(Object value, TomlWriter tomlWriter, Writer output) { + WriterContext context = new WriterContext(tomlWriter, output); write(value, context); - - return context.output.toString(); } void write(Object value, WriterContext context) { diff --git a/src/main/java/com/moandjiezana/toml/WriterContext.java b/src/main/java/com/moandjiezana/toml/WriterContext.java index 61095f9..239ffb9 100644 --- a/src/main/java/com/moandjiezana/toml/WriterContext.java +++ b/src/main/java/com/moandjiezana/toml/WriterContext.java @@ -1,5 +1,7 @@ package com.moandjiezana.toml; +import java.io.IOException; +import java.io.Writer; import java.util.Arrays; class WriterContext { @@ -8,19 +10,13 @@ class WriterContext { private String currentFieldIndent = ""; private String arrayKey = null; private boolean isArrayOfTable = false; + private boolean empty = true; private final TomlWriter tomlWriter; - StringBuilder output = new StringBuilder(); + private final Writer output; - WriterContext(String key, String tableIndent, StringBuilder output, TomlWriter tomlWriter) { - this.key = key; - this.currentTableIndent = tableIndent; - this.currentFieldIndent = tableIndent + fillStringWithSpaces(tomlWriter.getIndentationPolicy().getKeyValueIndent()); + WriterContext(TomlWriter tomlWriter, Writer output) { + this.tomlWriter = tomlWriter; this.output = output; - this.tomlWriter = tomlWriter; - } - - WriterContext(TomlWriter tomlWriter) { - this.tomlWriter = tomlWriter; } WriterContext pushTable(String newKey) { @@ -31,37 +27,75 @@ class WriterContext { String fullKey = key + (key.isEmpty() ? newKey : "." + newKey); - return new WriterContext(fullKey, newIndent, output, tomlWriter); + WriterContext subContext = new WriterContext(fullKey, newIndent, output, tomlWriter); + if (!empty) { + subContext.empty = false; + } + + return subContext; } WriterContext pushTableFromArray() { WriterContext subContext = new WriterContext(key, currentTableIndent, output, tomlWriter); + if (!empty) { + subContext.empty = false; + } subContext.setIsArrayOfTable(true); return subContext; } + + WriterContext write(String s) { + try { + output.write(s); + if (s != null && !s.isEmpty()) { + empty = false; + } + + return this; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + void write(char[] chars) { + for (char c : chars) { + write(c); + } + } + + WriterContext write(char c) { + try { + output.write(c); + empty = false; + + return this; + } catch (IOException e) { + throw new RuntimeException(e); + } + } void writeKey() { if (key.isEmpty()) { return; } - if (output.length() > 0) { - output.append('\n'); + if (!empty) { + write('\n'); } - output.append(currentTableIndent); + write(currentTableIndent); if (isArrayOfTable) { - output.append("[[").append(key).append("]]\n"); + write("[[").write(key).write("]]\n"); } else { - output.append('[').append(key).append("]\n"); + write('[').write(key).write("]\n"); } } void indent() { if (!key.isEmpty()) { - output.append(currentFieldIndent); + write(currentFieldIndent); } } @@ -81,6 +115,14 @@ class WriterContext { return new String(chars); } + private WriterContext(String key, String tableIndent, Writer output, TomlWriter tomlWriter) { + this.key = key; + this.currentTableIndent = tableIndent; + this.currentFieldIndent = tableIndent + fillStringWithSpaces(tomlWriter.getIndentationPolicy().getKeyValueIndent()); + this.output = output; + this.tomlWriter = tomlWriter; + } + public TomlWriter getTomlWriter() { return tomlWriter; }