![JAR search and dependency download from the Maven repository](/logo.png)
one.nio.serial.JsonReader Maven / Gradle / Ivy
/*
* Copyright 2018 Odnoklassniki Ltd, Mail.Ru Group
*
* 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 one.nio.serial;
import one.nio.util.Base64;
import one.nio.util.ByteArrayBuilder;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Beware: this is NOT a complete and fully compliant JSON parser!
* Its main purpose is to decode typical simple queries without third-party dependencies.
*/
public class JsonReader {
protected byte[] array;
protected int offset;
protected int next;
public JsonReader(byte[] array) {
this(array, 0);
}
public JsonReader(byte[] array, int offset) {
this.array = array;
this.offset = offset;
skipWhitespace();
}
protected int read() {
int b = next;
next = offset < array.length ? array[offset++] & 0xff : -1;
return b;
}
public final int next() {
return next;
}
public final int skipWhitespace() {
while (next <= ' ' && next != -1) {
read();
}
return next;
}
public final IOException exception(String message) {
return new IOException(message + " at " + offset);
}
public final void expect(int b, String message) throws IOException {
if (read() != b) {
throw exception(message);
}
}
public final boolean readBoolean() throws IOException {
int b = read();
if (b == 't' && read() == 'r' && read() == 'u' && read() == 'e') {
return true;
} else if (b == 'f' && read() == 'a' && read() == 'l' && read() == 's' && read() == 'e') {
return false;
}
throw exception("Expected boolean");
}
public final byte readByte() throws IOException {
return Byte.parseByte(readNumber());
}
public final short readShort() throws IOException {
return Short.parseShort(readNumber());
}
public final char readChar() throws IOException {
return readString().charAt(0);
}
public final int readInt() throws IOException {
return Integer.parseInt(readNumber());
}
public final long readLong() throws IOException {
return Long.parseLong(readNumber());
}
public float readFloat() throws IOException {
return Float.parseFloat(readNumber());
}
public final double readDouble() throws IOException {
return Double.parseDouble(readNumber());
}
public final String readNumber() throws IOException {
StringBuilder sb = new StringBuilder();
// Sign
if (next == '-') {
sb.append((char) read());
}
// Integer
int nochars = sb.length();
while (next >= '0' && next <= '9') {
sb.append((char) read());
}
// Fraction
if (next == '.') {
sb.append((char) read());
if (!(next >= '0' && next <= '9')) throw exception("Expected number");
do {
sb.append((char) read());
} while (next >= '0' && next <= '9');
}
if (sb.length() <= nochars) {
throw exception("Expected number");
}
// Exponent
if (next == 'e' || next == 'E') {
sb.append((char) read());
if (next == '-' || next == '+') {
sb.append((char) read());
}
if (!(next >= '0' && next <= '9')) throw exception("Expected number");
do {
sb.append((char) read());
} while (next >= '0' && next <= '9');
}
return sb.toString();
}
public final int readHexChar() throws IOException {
int b = read();
if (b >= '0' && b <= '9') {
return b - '0';
} else if (b >= 'A' && b <= 'F') {
return b - 'A';
} else if (b >= 'a' && b <= 'f') {
return b - 'a';
}
throw exception("Invalid escape character");
}
public final char readEscapeChar() throws IOException {
int b = read();
switch (b) {
case 'b':
return '\b';
case 'f':
return '\f';
case 'n':
return '\n';
case 'r':
return '\r';
case 't':
return '\t';
case 'u':
return (char) (readHexChar() << 12 | readHexChar() << 8 | readHexChar() << 4 | readHexChar());
default:
return (char) b;
}
}
public Object readNull() throws IOException {
if (read() != 'n' || read() != 'u' || read() != 'l' || read() != 'l') {
throw exception("Expected null");
}
return null;
}
public String readString() throws IOException {
StringBuilder sb = new StringBuilder();
expect('\"', "Expected string");
while (next >= 0 && next != '\"') {
int b = read();
if ((b & 0x80) == 0) {
sb.append(b == '\\' ? readEscapeChar() : (char) b);
} else if ((b & 0xe0) == 0xc0) {
sb.append((char) ((b & 0x1f) << 6 | (read() & 0x3f)));
} else if ((b & 0xf0) == 0xe0) {
sb.append((char) ((b & 0x0f) << 12 | (read() & 0x3f) << 6 | (read() & 0x3f)));
} else {
int v = (b & 0x07) << 18 | (read() & 0x3f) << 12 | (read() & 0x3f) << 6 | (read() & 0x3f);
sb.append((char) (0xd800 | (v - 0x10000) >>> 10)).append((char) (0xdc00 | (v & 0x3ff)));
}
}
expect('\"', "Unexpected end of string");
return sb.toString();
}
public byte[] readBinary() throws IOException {
ByteArrayBuilder builder = new ByteArrayBuilder();
expect('\"', "Expected BASE64 data");
while (next >= 0 && next != '\"') {
builder.append((byte) read());
}
expect('\"', "Unexpected end of BASE64 data");
return Base64.decode(builder.buffer(), builder.length());
}
public ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy