All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.driver.core.SimpleJSONParser Maven / Gradle / Ivy

Go to download

A driver for Apache Cassandra 1.2+ that works exclusively with the Cassandra Query Language version 3 (CQL3) and Cassandra's binary protocol.

There is a newer version: 4.0.0
Show newest version
/*
 *      Copyright (C) 2012-2015 DataStax Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package com.datastax.driver.core;

import java.util.*;

/**
 * A very simple json parser.
 * The only reason we need to read json in the driver is because for
 * historical reason Cassandra encodes a few properties using json in
 * the schema and we need to decode them.
 * 

* We however don't need a full-blown JSON library because: * 1) we know we only need to decode string lists and string maps * 2) we can basically assume the input is valid, we don't particularly * have to bother about decoding exactly JSON as long as we at least * decode what we need. * 3) we don't really care much about performance, none of this is done * in performance sensitive parts. *

* So instead of pulling a new dependency, we roll out our own very dumb * parser. We should obviously not expose this publicly. */ class SimpleJSONParser { private final String input; private int idx; private SimpleJSONParser(String input) { this.input = input; } public static List parseStringList(String input) { if (input == null || input.isEmpty()) return Collections.emptyList(); List output = new ArrayList(); SimpleJSONParser parser = new SimpleJSONParser(input); if (parser.nextCharSkipSpaces() != '[') throw new IllegalArgumentException("Not a JSON list: " + input); char c = parser.nextCharSkipSpaces(); if (c == ']') return output; while (true) { assert c == '"'; output.add(parser.nextString()); c = parser.nextCharSkipSpaces(); if (c == ']') return output; assert c == ','; c = parser.nextCharSkipSpaces(); } } public static Map parseStringMap(String input) { if (input == null || input.isEmpty()) return Collections.emptyMap(); Map output = new HashMap(); SimpleJSONParser parser = new SimpleJSONParser(input); if (parser.nextCharSkipSpaces() != '{') throw new IllegalArgumentException("Not a JSON map: " + input); char c = parser.nextCharSkipSpaces(); if (c == '}') return output; while (true) { assert c == '"'; String key = parser.nextString(); c = parser.nextCharSkipSpaces(); assert c == ':'; c = parser.nextCharSkipSpaces(); assert c == '"'; String value = parser.nextString(); output.put(key, value); c = parser.nextCharSkipSpaces(); if (c == '}') return output; assert c == ','; c = parser.nextCharSkipSpaces(); } } /** * Read the next char, the one at position idx, and advance ix. */ private char nextChar() { if (idx >= input.length()) throw new IllegalArgumentException("Invalid json input: " + input); return input.charAt(idx++); } /** * Same as nextChar, except that it skips space characters (' ', '\t' and '\n'). */ private char nextCharSkipSpaces() { char c = nextChar(); while (c == ' ' || c == '\t' || c == '\n') c = nextChar(); return c; } /** * Reads a String, assuming idx is on the first character of the string (i.e. the * one after the opening double-quote character). * After the string has been read, idx will be on the first character after * the closing double-quote. */ private String nextString() { assert input.charAt(idx - 1) == '"' : "Char is '" + input.charAt(idx - 1) + '\''; StringBuilder sb = new StringBuilder(); while (true) { char c = nextChar(); switch (c) { case '\n': case '\r': throw new IllegalArgumentException("Unterminated string"); case '\\': c = nextChar(); switch (c) { case 'b': sb.append('\b'); break; case 't': sb.append('\t'); break; case 'n': sb.append('\n'); break; case 'f': sb.append('\f'); break; case 'r': sb.append('\r'); break; case 'u': sb.append((char) Integer.parseInt(input.substring(idx, idx + 4), 16)); idx += 4; break; case '"': case '\'': case '\\': case '/': sb.append(c); break; default: throw new IllegalArgumentException("Illegal escape"); } break; default: if (c == '"') return sb.toString(); sb.append(c); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy