kz.greetgo.strconverter.simple.core.Reader Maven / Gradle / Ivy
package kz.greetgo.strconverter.simple.core;
import kz.greetgo.strconverter.simple.acceptors.NameValueList;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static kz.greetgo.strconverter.simple.core.ConvertRegistry.isJavaVariableChar;
/**
* Reads object from serialised string.
*
* Single threaded - you cannot use this class from different threads
*/
public class Reader {
private final ConvertRegistry convertRegistry;
private final char[] source;
@SuppressWarnings("SpellCheckingInspection")
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
private int index = 0;
public Reader(ConvertRegistry convertRegistry, String sourceStr) {
this.convertRegistry = convertRegistry;
this.source = sourceStr.toCharArray();
}
@SuppressWarnings("unchecked")
public T read() {
try {
return (T) read0();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object read0() throws Exception {
char commandChar = source[index++];
switch (commandChar) {
case 'N':
return null;
case 'I':
return Integer.valueOf(readNumStr());
case 'L':
return Long.valueOf(readNumStr());
case 'C':
return source[index++];
case 'O':
return Short.valueOf(readNumStr());
case 'B':
return Byte.valueOf(readNumStr());
case 'F':
return Float.valueOf(readNumStr());
case 'U':
return Double.valueOf(readNumStr());
case 'D':
return sdf.parse(readDateStr());
case 'S':
return readAndUnquoteStr();
case 'J':
return true;
case 'K':
return false;
case 'X':
return new BigDecimal(readNumStr());
case 'A':
return readArray(Integer.parseInt(readNumStr()));
case 'P':
return readListAsArrayList();
case 'G':
return readSetAsHashSet();
case 'M':
return readMapAsHashMap();
case 'Q':
return readObjectByAlias();
case 'b':
return readByteArray();
case 'c':
return readAndUnquoteStr().toCharArray();
}
throw new RuntimeException("Illegal command char " + commandChar);
}
private Object readByteArray() {
String base64str = readAndUnquoteStr();
return Base64.getDecoder().decode(base64str);
}
private Object readMapAsHashMap() throws Exception {
char openBrace = source[index++];
if (openBrace != '[') {
throw new RuntimeException("YTWhS7HDW7U: Here must be char [");
}
HashMap