package com.jsoniter;
import com.jsoniter.any.Any;
import com.jsoniter.spi.*;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JsonIterator implements Closeable {
public Config configCache;
private static boolean isStreamingEnabled = false;
final static ValueType[] valueTypes = new ValueType[256];
InputStream in;
byte[] buf;
// Whenever buf is not large enough new one is created with size of
// buf.length + autoExpandBufferStep. Set to < 1 to disable auto expanding.
int autoExpandBufferStep;
int head;
int tail;
int skipStartedAt = -1; // skip should keep bytes starting at this pos
Map tempObjects = null; // used in reflection object decoder
final Slice reusableSlice = new Slice(null, 0, 0);
char[] reusableChars = new char[32];
Object existingObject = null; // the object should be bind to next
static {
for (int i = 0; i < valueTypes.length; i++) {
valueTypes[i] = ValueType.INVALID;
}
valueTypes['"'] = ValueType.STRING;
valueTypes['-'] = ValueType.NUMBER;
valueTypes['0'] = ValueType.NUMBER;
valueTypes['1'] = ValueType.NUMBER;
valueTypes['2'] = ValueType.NUMBER;
valueTypes['3'] = ValueType.NUMBER;
valueTypes['4'] = ValueType.NUMBER;
valueTypes['5'] = ValueType.NUMBER;
valueTypes['6'] = ValueType.NUMBER;
valueTypes['7'] = ValueType.NUMBER;
valueTypes['8'] = ValueType.NUMBER;
valueTypes['9'] = ValueType.NUMBER;
valueTypes['t'] = ValueType.BOOLEAN;
valueTypes['f'] = ValueType.BOOLEAN;
valueTypes['n'] = ValueType.NULL;
valueTypes['['] = ValueType.ARRAY;
valueTypes['{'] = ValueType.OBJECT;
}
private JsonIterator(InputStream in, byte[] buf, int head, int tail) {
this.in = in;
this.buf = buf;
this.head = head;
this.tail = tail;
}
private JsonIterator(InputStream in, byte[] buf, int autoExpandBufferStep) {
this(in, buf, 0, 0);
this.autoExpandBufferStep = autoExpandBufferStep;
}
public JsonIterator() {
this(null, new byte[0], 0, 0);
}
public static JsonIterator parse(InputStream in, int bufSize) {
return parse(in, bufSize, bufSize);
}
public static JsonIterator parse(InputStream in, int bufSize, int autoExpandBufferStep) {
enableStreamingSupport();
return new JsonIterator(in, new byte[bufSize], autoExpandBufferStep);
}
public static JsonIterator parse(byte[] buf) {
return new JsonIterator(null, buf, 0, buf.length);
}
public static JsonIterator parse(byte[] buf, int head, int tail) {
return new JsonIterator(null, buf, head, tail);
}
public static JsonIterator parse(String str) {
return parse(str.getBytes());
}
public static JsonIterator parse(Slice slice) {
return new JsonIterator(null, slice.data(), slice.head(), slice.tail());
}
public final void reset(byte[] buf) {
this.buf = buf;
this.head = 0;
this.tail = buf.length;
}
public final void reset(byte[] buf, int head, int tail) {
this.buf = buf;
this.head = head;
this.tail = tail;
}
public final void reset(Slice value) {
this.buf = value.data();
this.head = value.head();
this.tail = value.tail();
}
public final void reset(InputStream in) {
JsonIterator.enableStreamingSupport();
this.in = in;
this.head = 0;
this.tail = 0;
}
public final void close() throws IOException {
if (in != null) {
in.close();
}
}
final void unreadByte() {
if (head == 0) {
throw reportError("unreadByte", "unread too many bytes");
}
head--;
}
public final JsonException reportError(String op, String msg) {
int peekStart = head - 10;
if (peekStart < 0) {
peekStart = 0;
}
int peekSize = head - peekStart;
if (head > tail) {
peekSize = tail - peekStart;
}
String peek = new String(buf, peekStart, peekSize);
throw new JsonException(op + ": " + msg + ", head: " + head + ", peek: " + peek + ", buf: " + new String(buf));
}
public final String currentBuffer() {
int peekStart = head - 10;
if (peekStart < 0) {
peekStart = 0;
}
String peek = new String(buf, peekStart, head - peekStart);
return "head: " + head + ", peek: " + peek + ", buf: " + new String(buf);
}
public final boolean readNull() throws IOException {
byte c = IterImpl.nextToken(this);
if (c != 'n') {
unreadByte();
return false;
}
IterImpl.skipFixedBytes(this, 3); // null
return true;
}
public final boolean readBoolean() throws IOException {
byte c = IterImpl.nextToken(this);
if ('t' == c) {
IterImpl.skipFixedBytes(this, 3); // true
return true;
}
if ('f' == c) {
IterImpl.skipFixedBytes(this, 4); // false
return false;
}
throw reportError("readBoolean", "expect t or f, found: " + c);
}
public final short readShort() throws IOException {
int v = readInt();
if (Short.MIN_VALUE