SimpleJavaEngine/src/main/java/speiger/src/coreengine/utils/io/PrettyGsonWriter.java

177 lines
3.7 KiB
Java

package speiger.src.coreengine.utils.io;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.google.gson.stream.JsonWriter;
import speiger.src.collections.bytes.collections.ByteStack;
import speiger.src.collections.bytes.lists.ByteArrayList;
public class PrettyGsonWriter extends JsonWriter
{
String indent;
ByteStack blocked = ByteArrayList.wrap((byte)0);
int[] usedArrays = new int[32];
int arrayPointer = 0;
String[] singleNames = new String[32];
int namePointer = 0;
String nextArray = null;
Set<String> singleLineObjects = new HashSet<>();
public PrettyGsonWriter(Writer out)
{
this(new Overrider(out));
}
public PrettyGsonWriter(Writer out, String indent)
{
this(new Overrider(out));
setTabs(indent);
}
private PrettyGsonWriter(Overrider rider)
{
super(rider);
rider.owner = this;
}
public PrettyGsonWriter addSinlgeLines(String... names)
{
singleLineObjects.addAll(Arrays.asList(names));
return this;
}
public void setTabs(String key)
{
setIndent(key);
if(key.length() == 0) indent = null;
else indent = key;
}
private void push(boolean value, boolean object)
{
if(indent == null) return;
if(value)
{
if(++arrayPointer >= usedArrays.length) usedArrays = Arrays.copyOf(usedArrays, usedArrays.length * 2);
if(!object && ++namePointer >= singleNames.length) singleNames = Arrays.copyOf(singleNames, singleNames.length * 2);
}
else if((blocked.top() & 1) != 0) usedArrays[arrayPointer]++;
blocked.push((byte)((value ? 1 : 0) | (value && !object ? 2 : 0)));
}
private void pop()
{
if(indent == null) return;
byte value = blocked.pop();
if((value & 1) != 0) usedArrays[arrayPointer--] = 0;
if((value & 2) != 0) singleNames[namePointer--] = null;
}
@Override
public JsonWriter name(String name) throws IOException
{
if(singleLineObjects.contains(name)) nextArray = name;
return super.name(name);
}
@Override
public JsonWriter beginArray() throws IOException
{
super.beginArray();
push(true, false);
singleNames[namePointer] = nextArray;
nextArray = null;
return this;
}
@Override
public JsonWriter beginObject() throws IOException
{
boolean shouldRework = shouldBlockObject();
push(false, true);
super.beginObject();
if(shouldRework) push(shouldRework, true);
return this;
}
@Override
public JsonWriter endArray() throws IOException
{
boolean ignore = usedArrays[arrayPointer] > 0;
if(ignore) pop();
super.endArray();
if(!ignore) pop();
return this;
}
@Override
public JsonWriter endObject() throws IOException
{
super.endObject();
if(shouldBlockObject()) pop();
pop();
return this;
}
public boolean shouldBlockObject()
{
return singleNames[namePointer] != null;
}
public boolean isBlocked()
{
return (blocked.top() & 1) != 0;
}
public static class Overrider extends BufferedWriter
{
PrettyGsonWriter owner;
public Overrider(Writer out)
{
super(out);
}
@Override
public void write(int c) throws IOException
{
if(owner.indent != null && owner.isBlocked())
{
if(c == '\n') return;
else if(c == ',' && owner.shouldBlockObject())
{
super.write(", ");
return;
}
}
super.write(c);
}
@Override
public Writer append(char c) throws IOException
{
if(owner.indent != null && c == ',' && owner.isBlocked() && (owner.usedArrays[owner.arrayPointer] <= 0))
{
super.write(", ");
return this;
}
return super.append(c);
}
@Override
public void write(String str) throws IOException
{
if(owner.indent != null && owner.isBlocked() && str.equals(owner.indent)) return;
super.write(str);
}
}
}