package com.aelfengard.i3;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class LPCUtils {
public static LPCMixed lpcToJava(String lpc) {
return parseObject(lpc.toCharArray(), new int[1]);
}
public static String javaToLPC(Object o) {
if (o instanceof LPCMixed) {
o = ((LPCMixed) o).asObject();
}
if (o instanceof List) {
List list = (List) o;
StringBuffer sb = new StringBuffer();
sb.append("({");
for (Object item : list) {
sb.append(javaToLPC(item));
sb.append(',');
}
sb.append("})");
return sb.toString();
}
else if (o instanceof String) {
char[] s = ((String) o).toCharArray();
StringBuffer sb = new StringBuffer();
sb.append("\"");
for (char c : s) {
switch (c) {
case '\\': sb.append("\\\\"); break;
case '"': sb.append("\\\""); break;
default: sb.append(c); break;
}
}
sb.append("\"");
return sb.toString();
}
else if (o instanceof Integer) {
return o.toString();
}
else if (o instanceof Map) {
Map map = (Map) o;
StringBuffer sb = new StringBuffer();
sb.append("([");
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
sb.append(javaToLPC(entry.getKey()));
sb.append(':');
sb.append(javaToLPC(entry.getValue()));
sb.append(',');
}
sb.append("])");
return sb.toString();
}
else if (o == null) {
return "0";
}
else throw new IllegalArgumentException(o.getClass().getName());
}
private static LPCMixed parseObject(char[] packet, int[] idx) {
switch (packet[idx[0]]) {
case '\"': return new LPCMixed(parseString(packet, idx));
case '(': {
switch (packet[++idx[0]]) {
case '{': return new LPCMixed(parseList(packet, idx));
case '[': return new LPCMixed(parseMap(packet, idx));
default: throw new RuntimeException("Invalid struct type: " + packet[idx[0]]);
}
}
default: return new LPCMixed(parseInt(packet, idx));
}
}
private static List<LPCMixed> parseList(char[] packet, int[] idx) {
idx[0]++;
ArrayList<LPCMixed> list = new ArrayList<LPCMixed>();
while (packet[idx[0]] != '}') {
list.add(parseObject(packet, idx));
idx[0]++; }
idx[0] += 2; return list;
}
private static Map<LPCMixed,LPCMixed> parseMap(char[] packet, int[] idx) {
idx[0]++;
Map<LPCMixed,LPCMixed> map = new LinkedHashMap<LPCMixed,LPCMixed>();
while (packet[idx[0]] != ']') {
LPCMixed key = parseObject(packet, idx);
idx[0]++; LPCMixed value = parseObject(packet, idx);
idx[0]++; map.put(key, value);
}
idx[0] += 2; return map;
}
private static int parseInt(char[] packet, int[] idx) {
int negative = 1;
int i = 0;
while (true) {
if (packet[idx[0]] >= '0' && packet[idx[0]] <= '9') {
i *= 10;
i += packet[idx[0]] - '0';
}
else if (packet[idx[0]] == '-') {
negative = -1;
}
else return negative * i;
idx[0]++;
}
}
private static String parseString(char[] packet, int[] idx) {
StringBuffer sb = new StringBuffer();
while (true) {
idx[0]++;
if (packet[idx[0]] == '"') {
idx[0]++;
return sb.toString();
}
if (packet[idx[0]] == '\\') {
idx[0]++;
}
sb.append(packet[idx[0]]);
}
}
public static List<LPCMixed> makeList(Object... parts) {
List<LPCMixed> list = new ArrayList<LPCMixed>(parts.length);
for (Object part : parts) {
list.add(part instanceof LPCMixed ? (LPCMixed) part : new LPCMixed(part));
}
return list;
}
}