package launcher.serialize.config;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Map;
import launcher.LauncherAPI;
import launcher.serialize.config.entry.BlockConfigEntry;
import launcher.serialize.config.entry.BooleanConfigEntry;
import launcher.serialize.config.entry.ConfigEntry;
import launcher.serialize.config.entry.IntegerConfigEntry;
import launcher.serialize.config.entry.ListConfigEntry;
import launcher.serialize.config.entry.StringConfigEntry;
public final class TextConfigWriter {
private final Writer writer;
private final boolean comments;
private TextConfigWriter(Writer writer, boolean comments) {
this.writer = writer;
this.comments = comments;
}
private void writeBlock(BlockConfigEntry block, boolean brackets) throws IOException {
// Write start bracket
if (brackets) {
writer.write('{');
}
// Write block entries
Map<String, ConfigEntry<?>> map = block.getValue();
for (Map.Entry<String, ConfigEntry<?>> mapEntry : map.entrySet()) {
String name = mapEntry.getKey();
ConfigEntry<?> entry = mapEntry.getValue();
// Write entry name
writeComment(entry.getComment(0));
writer.write(name);
writeComment(entry.getComment(1));
writer.write(':');
// Write entry value
writeComment(entry.getComment(2));
writeEntry(entry);
writeComment(entry.getComment(3));
writer.write(';');
}
writeComment(block.getComment(-1));
// Write end bracket
if (brackets) {
writer.write('}');
}
}
private void writeBoolean(BooleanConfigEntry entry) throws IOException {
writer.write(entry.getValue().toString());
}
private void writeComment(String comment) throws IOException {
if (comments && comment != null) {
writer.write(comment);
}
}
private void writeEntry(ConfigEntry<?> entry) throws IOException {
ConfigEntry.Type type = entry.getType();
switch (type) {
case BLOCK:
writeBlock((BlockConfigEntry) entry, true);
break;
case STRING:
writeString((StringConfigEntry) entry);
break;
case INTEGER:
writeInteger((IntegerConfigEntry) entry);
break;
case BOOLEAN:
writeBoolean((BooleanConfigEntry) entry);
break;
case LIST:
writeList((ListConfigEntry) entry);
break;
default:
throw new AssertionError("Unsupported config entry type: " + type.name());
}
}
private void writeInteger(IntegerConfigEntry entry) throws IOException {
writer.write(Integer.toString(entry.getValue()));
}
private void writeList(ListConfigEntry entry) throws IOException {
writer.write('[');
// Write list elements
List<ConfigEntry<?>> value = entry.getValue();
for (int i = 0; i < value.size(); i++) {
if (i > 0) {
writer.write(',');
}
// Write element
ConfigEntry<?> element = value.get(i);
writeComment(element.getComment(0));
writeEntry(element);
writeComment(element.getComment(1));
}
writeComment(entry.getComment(-1));
// Write end bracket
writer.write(']');
}
private void writeString(StringConfigEntry entry) throws IOException {
writer.write('"');
// Quote string
String s = entry.getValue();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
switch (ch) {
case '\t':
writer.write("\\t");
break;
case '\b':
writer.write("\\b");
break;
case '\n':
writer.write("\\n");
break;
case '\r':
writer.write("\\r");
break;
case '\f':
writer.write("\\f");
break;
case '"':
case '\\':
writer.write('\\');
writer.write(ch);
break;
default:
writer.write(ch);
break;
}
}
// Write end quote
writer.write('"');
}
@LauncherAPI
public static void write(BlockConfigEntry block, Writer writer, boolean comments) throws IOException {
new TextConfigWriter(writer, comments).writeBlock(block, false);
}
}