TomlWriter#write methods delegate to TomlWriter#write(Object, Writer) to

take advantage of streaming when possible.
This commit is contained in:
moandji.ezana 2015-06-29 18:49:34 +02:00
parent 123aa21aed
commit feb3aec259
9 changed files with 119 additions and 62 deletions

View file

@ -31,7 +31,7 @@ class BooleanConverter implements ValueConverter, ValueWriter {
@Override @Override
public void write(Object value, WriterContext context) { public void write(Object value, WriterContext context) {
context.output.append(value.toString()); context.write(value.toString());
} }
@Override @Override

View file

@ -99,12 +99,12 @@ class DateConverter implements ValueConverter, ValueWriter {
} }
dateFormat.setTimeZone(context.getTomlWriter().getTimeZone()); dateFormat.setTimeZone(context.getTomlWriter().getTimeZone());
context.output.append(dateFormat.format(value)); context.write(dateFormat.format(value));
if (customDateFormat == null) { if (customDateFormat == null) {
Calendar calendar = context.getTomlWriter().getCalendar(); Calendar calendar = context.getTomlWriter().getCalendar();
int tzOffset = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000); 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));
} }
} }

View file

@ -37,14 +37,14 @@ class MapValueWriter implements ValueWriter {
ValueWriter valueWriter = WRITERS.findWriterFor(fromValue); ValueWriter valueWriter = WRITERS.findWriterFor(fromValue);
if (valueWriter.isPrimitiveType()) { if (valueWriter.isPrimitiveType()) {
context.indent(); context.indent();
context.output.append(quoteKey(key)).append(" = "); context.write(quoteKey(key)).write(" = ");
valueWriter.write(fromValue, context); valueWriter.write(fromValue, context);
context.output.append('\n'); context.write('\n');
} else if (valueWriter == PRIMITIVE_ARRAY_VALUE_WRITER) { } else if (valueWriter == PRIMITIVE_ARRAY_VALUE_WRITER) {
context.setArrayKey(key.toString()); context.setArrayKey(key.toString());
context.output.append(quoteKey(key)).append(" = "); context.write(quoteKey(key)).write(" = ");
valueWriter.write(fromValue, context); valueWriter.write(fromValue, context);
context.output.append('\n'); context.write('\n');
} }
} }

View file

@ -90,7 +90,7 @@ class NumberConverter implements ValueConverter, ValueWriter {
@Override @Override
public void write(Object value, WriterContext context) { public void write(Object value, WriterContext context) {
context.output.append(value.toString()); context.write(value.toString());
} }
@Override @Override

View file

@ -1,9 +1,9 @@
package com.moandjiezana.toml; package com.moandjiezana.toml;
import java.util.Collection;
import static com.moandjiezana.toml.ValueWriters.WRITERS; import static com.moandjiezana.toml.ValueWriters.WRITERS;
import java.util.Collection;
class PrimitiveArrayValueWriter extends ArrayValueWriter { class PrimitiveArrayValueWriter extends ArrayValueWriter {
static final ValueWriter PRIMITIVE_ARRAY_VALUE_WRITER = new PrimitiveArrayValueWriter(); static final ValueWriter PRIMITIVE_ARRAY_VALUE_WRITER = new PrimitiveArrayValueWriter();
@ -16,9 +16,9 @@ class PrimitiveArrayValueWriter extends ArrayValueWriter {
public void write(Object value, WriterContext context) { public void write(Object value, WriterContext context) {
Collection values = normalize(value); Collection values = normalize(value);
context.output.append('['); context.write('[');
if (!context.getTomlWriter().wantTerseArrays()) { if (!context.getTomlWriter().wantTerseArrays()) {
context.output.append(' '); context.write(' ');
} }
boolean first = true; boolean first = true;
@ -37,16 +37,16 @@ class PrimitiveArrayValueWriter extends ArrayValueWriter {
" but found " + writer " but found " + writer
); );
} }
context.output.append(", "); context.write(", ");
} }
WRITERS.write(elem, context); WRITERS.write(elem, context);
} }
if (!context.getTomlWriter().wantTerseArrays()) { if (!context.getTomlWriter().wantTerseArrays()) {
context.output.append(' '); context.write(' ');
} }
context.output.append(']'); context.write(']');
} }
private PrimitiveArrayValueWriter() {} private PrimitiveArrayValueWriter() {}

View file

@ -96,9 +96,9 @@ class StringConverter implements ValueConverter, ValueWriter {
@Override @Override
public void write(Object value, WriterContext context) { public void write(Object value, WriterContext context) {
context.output.append('"'); context.write('"');
escapeUnicode(value.toString(), context.output); escapeUnicode(value.toString(), context);
context.output.append('"'); context.write('"');
} }
@Override @Override
@ -106,17 +106,17 @@ class StringConverter implements ValueConverter, ValueWriter {
return true; return true;
} }
private void escapeUnicode(String in, StringBuilder out) { private void escapeUnicode(String in, WriterContext context) {
for (int i = 0; i < in.length(); i++) { for (int i = 0; i < in.length(); i++) {
int codePoint = in.codePointAt(i); int codePoint = in.codePointAt(i);
if (codePoint < specialCharacterEscapes.length && specialCharacterEscapes[codePoint] != null) { if (codePoint < specialCharacterEscapes.length && specialCharacterEscapes[codePoint] != null) {
out.append(specialCharacterEscapes[codePoint]); context.write(specialCharacterEscapes[codePoint]);
} else if (codePoint > 0x1f && codePoint < 0x7f) { } else if (codePoint > 0x1f && codePoint < 0x7f) {
out.append(Character.toChars(codePoint)); context.write(Character.toChars(codePoint));
} else if (codePoint <= 0xFFFF) { } else if (codePoint <= 0xFFFF) {
out.append(String.format("\\u%04X", codePoint)); context.write(String.format("\\u%04X", codePoint));
} else { } 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. // Skip the low surrogate, which will be the next in the code point sequence.
i++; i++;
} }

View file

@ -1,14 +1,20 @@
package com.moandjiezana.toml; 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.text.DateFormat;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import static com.moandjiezana.toml.ValueWriters.WRITERS;
/** /**
* <p>Converts Objects to TOML</p> * <p>Converts Objects to TOML</p>
* *
@ -45,29 +51,27 @@ public class TomlWriter {
* @return a string containing the TOML representation of the given Object * @return a string containing the TOML representation of the given Object
*/ */
public String write(Object from) { public String write(Object from) {
return WRITERS.write(from, this); try {
} StringWriter output = new StringWriter();
write(from, output);
/** return output.toString();
* Write an Object in TOML to a {@link Writer}. } catch (IOException e) {
* throw new RuntimeException(e);
* @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));
} }
/** /**
* Write an Object in TOML to a {@link OutputStream}. * Write an Object in TOML to a {@link OutputStream}.
* *
* @param from the object to be written * @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 * @throws IOException if target.write() fails
*/ */
public void write(Object from, OutputStream target) throws IOException { 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 { public void write(Object from, File target) throws IOException {
FileWriter writer = new FileWriter(target); FileWriter writer = new FileWriter(target);
writer.write(write(from)); write(from, writer);
writer.close(); 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() { public WriterIndentationPolicy getIndentationPolicy() {
return indentationPolicy; return indentationPolicy;
} }

View file

@ -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.StringConverter.STRING_PARSER;
import static com.moandjiezana.toml.TableArrayValueWriter.TABLE_ARRAY_VALUE_WRITER; import static com.moandjiezana.toml.TableArrayValueWriter.TABLE_ARRAY_VALUE_WRITER;
import java.io.Writer;
class ValueWriters { class ValueWriters {
static final ValueWriters WRITERS = new ValueWriters(); static final ValueWriters WRITERS = new ValueWriters();
@ -23,11 +25,9 @@ class ValueWriters {
return OBJECT_VALUE_WRITER; return OBJECT_VALUE_WRITER;
} }
String write(Object value, TomlWriter tomlWriter) { void write(Object value, TomlWriter tomlWriter, Writer output) {
WriterContext context = new WriterContext(tomlWriter); WriterContext context = new WriterContext(tomlWriter, output);
write(value, context); write(value, context);
return context.output.toString();
} }
void write(Object value, WriterContext context) { void write(Object value, WriterContext context) {

View file

@ -1,5 +1,7 @@
package com.moandjiezana.toml; package com.moandjiezana.toml;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays; import java.util.Arrays;
class WriterContext { class WriterContext {
@ -8,19 +10,13 @@ class WriterContext {
private String currentFieldIndent = ""; private String currentFieldIndent = "";
private String arrayKey = null; private String arrayKey = null;
private boolean isArrayOfTable = false; private boolean isArrayOfTable = false;
private boolean empty = true;
private final TomlWriter tomlWriter; private final TomlWriter tomlWriter;
StringBuilder output = new StringBuilder(); private final Writer output;
WriterContext(String key, String tableIndent, StringBuilder output, TomlWriter tomlWriter) { WriterContext(TomlWriter tomlWriter, Writer output) {
this.key = key; this.tomlWriter = tomlWriter;
this.currentTableIndent = tableIndent;
this.currentFieldIndent = tableIndent + fillStringWithSpaces(tomlWriter.getIndentationPolicy().getKeyValueIndent());
this.output = output; this.output = output;
this.tomlWriter = tomlWriter;
}
WriterContext(TomlWriter tomlWriter) {
this.tomlWriter = tomlWriter;
} }
WriterContext pushTable(String newKey) { WriterContext pushTable(String newKey) {
@ -31,37 +27,75 @@ class WriterContext {
String fullKey = key + (key.isEmpty() ? newKey : "." + newKey); 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 pushTableFromArray() {
WriterContext subContext = new WriterContext(key, currentTableIndent, output, tomlWriter); WriterContext subContext = new WriterContext(key, currentTableIndent, output, tomlWriter);
if (!empty) {
subContext.empty = false;
}
subContext.setIsArrayOfTable(true); subContext.setIsArrayOfTable(true);
return subContext; 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() { void writeKey() {
if (key.isEmpty()) { if (key.isEmpty()) {
return; return;
} }
if (output.length() > 0) { if (!empty) {
output.append('\n'); write('\n');
} }
output.append(currentTableIndent); write(currentTableIndent);
if (isArrayOfTable) { if (isArrayOfTable) {
output.append("[[").append(key).append("]]\n"); write("[[").write(key).write("]]\n");
} else { } else {
output.append('[').append(key).append("]\n"); write('[').write(key).write("]\n");
} }
} }
void indent() { void indent() {
if (!key.isEmpty()) { if (!key.isEmpty()) {
output.append(currentFieldIndent); write(currentFieldIndent);
} }
} }
@ -81,6 +115,14 @@ class WriterContext {
return new String(chars); 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() { public TomlWriter getTomlWriter() {
return tomlWriter; return tomlWriter;
} }