use of net.morimekta.util.json.JsonTokenizer in project providence by morimekta.
the class JsonSerializer method parseMapKey.
private Object parseMapKey(String key, PDescriptor keyType) throws SerializerException {
try {
switch(keyType.getType()) {
case BOOL:
if (key.equalsIgnoreCase("true")) {
return Boolean.TRUE;
} else if (key.equalsIgnoreCase("false")) {
return Boolean.FALSE;
}
throw new SerializerException("Invalid boolean value: \"" + Strings.escape(key) + "\"");
case BYTE:
return Byte.parseByte(key);
case I16:
return Short.parseShort(key);
case I32:
return Integer.parseInt(key);
case I64:
return Long.parseLong(key);
case DOUBLE:
try {
JsonTokenizer tokenizer = new JsonTokenizer(new ByteArrayInputStream(key.getBytes(StandardCharsets.US_ASCII)));
JsonToken token = tokenizer.next();
if (!token.isNumber()) {
throw new SerializerException("Unable to parse double from key \"" + key + "\"");
} else if (tokenizer.hasNext()) {
throw new SerializerException("Garbage after double: \"" + key + "\"");
}
return token.doubleValue();
} catch (SerializerException e) {
throw e;
} catch (JsonException | IOException e) {
throw new SerializerException(e, "Unable to parse double from key \"" + key + "\"");
}
case STRING:
return key;
case BINARY:
try {
return Binary.fromBase64(key);
} catch (IllegalArgumentException e) {
throw new SerializerException(e, "Unable to parse Base64 data");
}
case ENUM:
PEnumBuilder<?> eb = ((PEnumDescriptor<?>) keyType).builder();
if (Strings.isInteger(key)) {
eb.setById(Integer.parseInt(key));
} else {
eb.setByName(key);
}
if (readStrict && !eb.valid()) {
throw new SerializerException("\"%s\" is not a known enum value for %s", Strings.escape(key), keyType.getQualifiedName());
}
return eb.build();
case MESSAGE:
PMessageDescriptor<?, ?> st = (PMessageDescriptor<?, ?>) keyType;
if (!st.isSimple()) {
throw new SerializerException("Only simple structs can be used as map key. %s is not.", st.getQualifiedName());
}
ByteArrayInputStream input = new ByteArrayInputStream(key.getBytes(StandardCharsets.UTF_8));
try {
JsonTokenizer tokenizer = new JsonTokenizer(input);
if (JsonToken.kMapStart == tokenizer.expectSymbol("message start", JsonToken.kMapStart, JsonToken.kListStart)) {
return parseMessage(tokenizer, st);
} else {
return parseCompactMessage(tokenizer, st);
}
} catch (JsonException | IOException e) {
throw new SerializerException(e, "Error parsing message key: " + e.getMessage());
}
default:
throw new SerializerException("Illegal key type: %s", keyType.getType());
}
} catch (NumberFormatException nfe) {
throw new SerializerException(nfe, "Unable to parse numeric value %s", key);
}
}
Aggregations