/*
* Decompiled with CFR 0_101, deobfucsted by Skylinerw
*
* Could not load the following classes:
* com.google.common.annotations.VisibleForTesting
* com.google.common.collect.Lists
*/
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import NBTByteArray;
import NBTByte;
import NBTCompound;
import NBTDouble;
import NBTFloat;
import NBTIntArray;
import NBTFloat;
import NBTList;
import NBTLong;
import NBTPrimitive;
import NBTShort;
import NBTString;
import NBTBase;
import NBTParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class stringToNBT {
private static final Pattern regexDouble1 = Pattern.compile("[-+]?(?:[0-9]+[.]|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?", 2);
private static final Pattern regexDouble2 = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
private static final Pattern regexFloat = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?f", 2);
private static final Pattern regexByte = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)b", 2);
private static final Pattern regexLong = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)l", 2);
private static final Pattern regexShort = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)s", 2);
private static final Pattern regexInt = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)");
private final String inputString;
private int cursor;
public static NBTCompound getNewInstance(String string) throws NBTParseException {
return new stringToNBT(string).parse();
}
@VisibleForTesting
NBTCompound parse() throws NBTParseException {
NBTCompound nbtcompound = this.createCompoundNBT();
this.movePastWhitespace();
if (this.withinBounds()) {
++this.cursor;
throw this.newParseException("Trailing data found");
}
return nbtcompound;
}
@VisibleForTesting
stringToNBT(String raw) {
this.inputString = raw;
}
protected String getKey() throws NBTParseException {
this.movePastWhitespace();
if (!this.withinBounds()) { // If at end of string, throw.
throw this.newParseException("Expected key");
}
return this.getCurrentChar() == '\"' ? this.getQuotedString() : this.getUnquotedString();
}
private NBTParseException newParseException(String message) {
return new NBTParseException(message, this.inputString, this.cursor);
}
protected NBTBase getSimpleValue() throws NBTParseException {
this.movePastWhitespace();
if (this.getCurrentChar() == '\"') {
return new NBTString(this.getQuotedString());
}
String string = this.getUnquotedString();
if (string.isEmpty()) {
throw this.newParseException("Expected value");
}
return this.createSimpleNBT(string);
}
private NBTBase createSimpleNBT(String value) {
try {
if (regexFloat.matcher((CharSequence)value).matches()) {
return new NBTFloat(Float.parseFloat(value.substring(0, value.length() - 1)));
}
if (regexByte.matcher((CharSequence)value).matches()) {
return new NBTByte(Byte.parseByte(value.substring(0, value.length() - 1)));
}
if (regexLong.matcher((CharSequence)value).matches()) {
return new NBTLong(Long.parseLong(value.substring(0, value.length() - 1)));
}
if (regexShort.matcher((CharSequence)value).matches()) {
return new NBTShort(Short.parseShort(value.substring(0, value.length() - 1)));
}
if (regexInt.matcher((CharSequence)value).matches()) {
return new NBTInteger(Integer.parseInt(value));
}
if (regexDouble2.matcher((CharSequence)value).matches()) {
return new NBTDouble(Double.parseDouble(value.substring(0, value.length() - 1)));
}
if (regexDouble1.matcher((CharSequence)value).matches()) {
return new NBTDouble(Double.parseDouble(value));
}
if ("true".equalsIgnoreCase(value)) {
return new NBTByte(1);
}
if ("false".equalsIgnoreCase(value)) {
return new NBTByte(0);
}
}
catch (NumberFormatException exception) {
// empty catch block
}
return new NBTString(value);
}
private String getQuotedString() throws NBTParseException {
int cursorPos = ++this.cursor;
StringBuilder stringBuilder = null;
boolean escaping = false;
while (this.withinBounds()) {
char currentChar = this.getToNextChar();
if (escaping) {
if (currentChar != '\\' && currentChar != '\"') {
throw this.newParseException("Invalid escape of '" + currentChar + "'");
}
escaping = false;
} else {
if (currentChar == '\\') {
escaping = true;
if (stringBuilder != null) continue;
stringBuilder = new StringBuilder(this.inputString.substring(cursorPos, this.cursor - 1));
continue;
}
if (currentChar == '\"') {
return stringBuilder == null ? this.inputString.substring(cursorPos, this.cursor - 1) : stringBuilder.toString();
}
}
if (stringBuilder == null) continue;
stringBuilder.append(currentChar);
}
throw this.newParseException("Missing termination quote");
}
private String getUnquotedString() {
int n = this.cursor;
while (this.withinBounds() && this.isValidChar(this.getCurrentChar())) {
++this.cursor;
}
return this.inputString.substring(n, this.cursor);
}
protected NBTBase getValue() throws NBTParseException {
this.movePastWhitespace();
if (!this.withinBounds()) {
throw this.newParseException("Expected value");
}
char currentChar = this.getCurrentChar();
if (currentChar == '{') {
return this.createCompoundNBT();
}
if (currentChar == '[') {
return this.getArrayOrList();
}
return this.getSimpleValue();
}
protected NBTBase getArrayOrList() throws NBTParseException {
char c;
if (this.cursorPlusNWithinBounds(1) && ((c = this.getCharAtCursorPlusN(1)) == 'B' || c == 'I') && this.cursorPlusNWithinBounds(2) && this.getCharAtCursorPlusN(2) == ';') {
return this.getArrayValue();
}
return this.createListNBT();
}
protected NBTCompound createCompoundNBT() throws NBTParseException {
this.moveToNextChar('{');
NBTCompound nbtcompound = new NBTCompound();
this.movePastWhitespace();
while (this.withinBounds() && this.getCurrentChar() != '}') {
String key = this.getKey();
if (key.isEmpty()) {
throw this.newParseException("Expected non-empty key");
}
this.moveToNextChar(':');
nbtcompound.setTag(key, this.getValue());
if (!this.hasNextComma()) break;
if (this.withinBounds()) continue;
throw this.newParseException("Expected key");
}
this.moveToNextChar('}');
return nbtcompound;
}
private NBTBase createListNBT() throws NBTParseException {
this.moveToNextChar('[');
this.movePastWhitespace();
if (!this.withinBounds()) {
throw this.newParseException("Expected value");
}
NBTList nbtlist = new NBTList();
byte rootType = -1;
while (this.getCurrentChar() != ']') {
NBTBase nbtbase = this.getValue();
byte inputType = nbtbase.getId();
if (rootType < 0) {
rootType = inputType;
} else if (inputType != rootType) {
throw this.newParseException("Unable to insert " + nbtbase.getTypeName(inputType) + " into ListTag of type " + nbtbase.getTypeName(rootType));
}
nbtlist.appendTag(nbtbase);
if (!this.hasNextComma()) break;
if (this.withinBounds()) continue;
throw this.newParseException("Expected value");
}
this.moveToNextChar(']');
return nbtlist;
}
private NBTBase getArrayValue() throws NBTParseException {
this.moveToNextChar('[');
char identifier = this.getToNextChar();
this.getToNextChar();
this.movePastWhitespace();
if (!this.withinBounds()) {
throw this.newParseException("Expected value");
}
if (identifier == 'B') {
return new NBTByteArray(this.createArrayNBT(7, 1));
}
return new NBTIntArray(this.createArrayNBT(11, 3));
}
private List createArrayNBT(byte arrayType, byte primitiveType) throws NBTParseException {
ArrayList arrayList = Lists.newArrayList();
while (this.getCurrentChar() != ']') {
NBTBase nbtbase = this.getValue();
byte inputValue = nbtbase.getId();
if (inputValue != primitiveType) {
throw this.newParseException("Unable to insert " + nbtbase.getTypeName(inputValue) + " into " + nbtbase.getTypeName(arrayType));
}
if (primitiveType == 1) {
arrayList.add(Byte.valueOf(((NBTPrimitive)nbtbase).getByte()));
} else {
arrayList.add(((NBTPrimitive)nbtbase).getInt());
}
if (!this.hasNextComma()) break;
if (this.withinBounds()) continue;
throw this.newParseException("Expected value");
}
this.moveToNextChar(']');
return arrayList;
}
private void movePastWhitespace() {
while (this.withinBounds() && Character.isWhitespace(this.getCurrentChar())) {
++this.cursor;
}
}
private boolean hasNextComma() {
this.movePastWhitespace();
if (this.withinBounds() && this.getCurrentChar() == ',') {
++this.cursor;
this.movePastWhitespace();
return true;
}
return false;
}
private void moveToNextChar(char requiredNextChar) throws NBTParseException {
this.movePastWhitespace();
boolean withinBounds = this.withinBounds();
if (withinBounds && this.getCurrentChar() == requiredNextChar) {
++this.cursor;
return;
}
throw new NBTParseException("Expected '" + requiredNextChar + "' but got '" + (withinBounds ? Character.valueOf(this.getCurrentChar()) : "") + "'", this.inputString, this.cursor + 1);
}
protected boolean isValidChar(char c) {
return c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '_' || c == '-' || c == '.' || c == '+';
}
private boolean cursorPlusNWithinBounds(int n) {
return this.cursor + n < this.inputString.length();
}
boolean withinBounds() {
return this.cursorPlusNWithinBounds(0);
}
private char getCharAtCursorPlusN(int n) {
return this.inputString.charAt(this.cursor + n);
}
private char getCurrentChar() {
return this.getCharAtCursorPlusN(0);
}
private char getToNextChar() {
return this.inputString.charAt(this.cursor++);
}
}