Introduced toJson() method

This commit is contained in:
Christian Basler 2017-01-23 12:49:27 +01:00
parent 30da667fdb
commit d1215c6e12
12 changed files with 162 additions and 11 deletions

View File

@ -25,6 +25,7 @@ public class MPArray<T extends MPType> implements MPType<List<T>>, List<T> {
this.array = array; this.array = array;
} }
@SafeVarargs
public MPArray(T... objects) { public MPArray(T... objects) {
this.array = Arrays.asList(objects); this.array = Arrays.asList(objects);
} }
@ -179,17 +180,29 @@ public class MPArray<T extends MPType> implements MPType<List<T>>, List<T> {
@Override @Override
public String toString() { public String toString() {
return toJson();
}
@Override
public String toJson() {
return toJson("");
}
String toJson(String indent) {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
result.append('['); result.append("[\n");
Iterator<T> iterator = array.iterator(); Iterator<T> iterator = array.iterator();
String indent2 = indent + " ";
while (iterator.hasNext()) { while (iterator.hasNext()) {
T item = iterator.next(); T item = iterator.next();
result.append(item.toString()); result.append(indent2);
result.append(Utils.toJson(item, indent2));
if (iterator.hasNext()) { if (iterator.hasNext()) {
result.append(", "); result.append(',');
} }
result.append('\n');
} }
result.append(']'); result.append("]");
return result.toString(); return result.toString();
} }

View File

@ -52,7 +52,12 @@ public class MPBinary implements MPType<byte[]> {
@Override @Override
public String toString() { public String toString() {
return null; // TODO base64 return toJson();
}
@Override
public String toJson() {
return Utils.base64(value);
} }
public static class Unpacker implements MPType.Unpacker<MPBinary> { public static class Unpacker implements MPType.Unpacker<MPBinary> {

View File

@ -48,6 +48,11 @@ public class MPBoolean implements MPType<Boolean> {
return String.valueOf(value); return String.valueOf(value);
} }
@Override
public String toJson() {
return String.valueOf(value);
}
public static class Unpacker implements MPType.Unpacker<MPBoolean> { public static class Unpacker implements MPType.Unpacker<MPBoolean> {
public boolean is(int firstByte) { public boolean is(int firstByte) {

View File

@ -46,6 +46,11 @@ public class MPDouble implements MPType<Double> {
return String.valueOf(value); return String.valueOf(value);
} }
@Override
public String toJson() {
return String.valueOf(value);
}
public static class Unpacker implements MPType.Unpacker<MPDouble> { public static class Unpacker implements MPType.Unpacker<MPDouble> {
public boolean is(int firstByte) { public boolean is(int firstByte) {
return firstByte == 0xCB; return firstByte == 0xCB;

View File

@ -46,6 +46,11 @@ public class MPFloat implements MPType<Float> {
return String.valueOf(value); return String.valueOf(value);
} }
@Override
public String toJson() {
return String.valueOf(value);
}
public static class Unpacker implements MPType.Unpacker<MPFloat> { public static class Unpacker implements MPType.Unpacker<MPFloat> {
public boolean is(int firstByte) { public boolean is(int firstByte) {
return firstByte == 0xCA; return firstByte == 0xCA;

View File

@ -78,6 +78,11 @@ public class MPInteger implements MPType<Long> {
return String.valueOf(value); return String.valueOf(value);
} }
@Override
public String toJson() {
return String.valueOf(value);
}
public static class Unpacker implements MPType.Unpacker<MPInteger> { public static class Unpacker implements MPType.Unpacker<MPInteger> {
public boolean is(int firstByte) { public boolean is(int firstByte) {
switch (firstByte) { switch (firstByte) {

View File

@ -123,22 +123,34 @@ public class MPMap<K extends MPType, V extends MPType> implements MPType<Map<K,
@Override @Override
public String toString() { public String toString() {
return toJson();
}
String toJson(String indent) {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
result.append('{'); result.append("{\n");
Iterator<Map.Entry<K, V>> iterator = map.entrySet().iterator(); Iterator<Map.Entry<K, V>> iterator = map.entrySet().iterator();
String indent2 = indent + " ";
while (iterator.hasNext()) { while (iterator.hasNext()) {
Map.Entry<K, V> item = iterator.next(); Map.Entry<K, V> item = iterator.next();
result.append(item.getKey().toString()); result.append(indent2);
result.append(Utils.toJson(item.getKey(), indent2));
result.append(": "); result.append(": ");
result.append(item.getValue().toString()); result.append(Utils.toJson(item.getValue(), indent2));
if (iterator.hasNext()) { if (iterator.hasNext()) {
result.append(", "); result.append(',');
} }
result.append('\n');
} }
result.append('}'); result.append(indent).append("}");
return result.toString(); return result.toString();
} }
@Override
public String toJson() {
return toJson("");
}
public static class Unpacker implements MPType.Unpacker<MPMap> { public static class Unpacker implements MPType.Unpacker<MPMap> {
private final Reader reader; private final Reader reader;

View File

@ -33,6 +33,11 @@ public class MPNil implements MPType<Void> {
return "null"; return "null";
} }
@Override
public String toJson() {
return "null";
}
public static class Unpacker implements MPType.Unpacker<MPNil> { public static class Unpacker implements MPType.Unpacker<MPNil> {
public boolean is(int firstByte) { public boolean is(int firstByte) {

View File

@ -99,6 +99,50 @@ public class MPString implements MPType<String>, CharSequence {
return value; return value;
} }
@Override
public String toJson() {
StringBuilder result = new StringBuilder(value.length() + 4);
result.append('"');
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
switch (c) {
case '\\':
case '"':
case '/':
result.append('\\').append(c);
break;
case '\b':
result.append("\\b");
break;
case '\t':
result.append("\\t");
break;
case '\n':
result.append("\\n");
break;
case '\f':
result.append("\\f");
break;
case '\r':
result.append("\\r");
break;
default:
if (c < ' ') {
result.append("\\u");
String hex = Integer.toHexString(c);
for (int j = 0; j - hex.length() < 4; j++) {
result.append('0');
}
result.append(hex);
} else {
result.append(c);
}
}
}
result.append('"');
return result.toString();
}
public static class Unpacker implements MPType.Unpacker<MPString> { public static class Unpacker implements MPType.Unpacker<MPString> {
public boolean is(int firstByte) { public boolean is(int firstByte) {
return firstByte == STR8_PREFIX || firstByte == STR16_PREFIX || firstByte == STR32_PREFIX return firstByte == STR8_PREFIX || firstByte == STR16_PREFIX || firstByte == STR32_PREFIX

View File

@ -17,4 +17,6 @@ public interface MPType<T> {
T getValue(); T getValue();
void pack(OutputStream out) throws IOException; void pack(OutputStream out) throws IOException;
String toJson();
} }

View File

@ -5,6 +5,8 @@ import java.io.InputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
class Utils { class Utils {
private static final char[] BASE64_CODES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
/** /**
* Returns a {@link ByteBuffer} containing the next <code>count</code> bytes from the {@link InputStream}. * Returns a {@link ByteBuffer} containing the next <code>count</code> bytes from the {@link InputStream}.
*/ */
@ -20,4 +22,49 @@ class Utils {
} }
return ByteBuffer.wrap(result); return ByteBuffer.wrap(result);
} }
/**
* Helper method to decide which types support extra indention (for pretty printing JSON)
*/
static String toJson(MPType<?> type, String indent) {
if (type instanceof MPMap) {
return ((MPMap) type).toJson(indent);
}
if (type instanceof MPArray) {
return ((MPArray) type).toJson(indent);
}
return type.toJson();
}
/**
* Slightly improved code from https://en.wikipedia.org/wiki/Base64
*/
static String base64(byte[] data) {
StringBuilder result = new StringBuilder((data.length * 4) / 3 + 3);
int b;
for (int i = 0; i < data.length; i += 3) {
b = (data[i] & 0xFC) >> 2;
result.append(BASE64_CODES[b]);
b = (data[i] & 0x03) << 4;
if (i + 1 < data.length) {
b |= (data[i + 1] & 0xF0) >> 4;
result.append(BASE64_CODES[b]);
b = (data[i + 1] & 0x0F) << 2;
if (i + 2 < data.length) {
b |= (data[i + 2] & 0xC0) >> 6;
result.append(BASE64_CODES[b]);
b = data[i + 2] & 0x3F;
result.append(BASE64_CODES[b]);
} else {
result.append(BASE64_CODES[b]);
result.append('=');
}
} else {
result.append(BASE64_CODES[b]);
result.append("==");
}
}
return result.toString();
}
} }

View File

@ -1 +1,4 @@
{"compact": true, "schema": 0} {
"compact": true,
"schema": 0
}