Search in sources :

Example 1 with JsonTokenizer

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);
    }
}
Also used : JsonException(net.morimekta.util.json.JsonException) IOException(java.io.IOException) PEnumDescriptor(net.morimekta.providence.descriptor.PEnumDescriptor) ByteArrayInputStream(java.io.ByteArrayInputStream) JsonToken(net.morimekta.util.json.JsonToken) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) JsonTokenizer(net.morimekta.util.json.JsonTokenizer)

Aggregations

ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 PEnumDescriptor (net.morimekta.providence.descriptor.PEnumDescriptor)1 PMessageDescriptor (net.morimekta.providence.descriptor.PMessageDescriptor)1 JsonException (net.morimekta.util.json.JsonException)1 JsonToken (net.morimekta.util.json.JsonToken)1 JsonTokenizer (net.morimekta.util.json.JsonTokenizer)1