com.alibaba.fastjson.parser.JSONLexerBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fastjson Show documentation
Show all versions of fastjson Show documentation
Fastjson is a JSON processor (JSON parser + JSON generator) written in Java, majinju定制版
The newest version!
/*
* Copyright 1999-2019 Alibaba 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 com.alibaba.fastjson.parser;
import java.io.Closeable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.util.IOUtils;
import static com.alibaba.fastjson.parser.JSONToken.*;
import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode;
import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_prime;
/**
* @author wenshao[[email protected]]
*/
public abstract class JSONLexerBase implements JSONLexer, Closeable {
protected void lexError(String key, Object... args) {
token = ERROR;
}
protected int token;
protected int pos;
protected int features;
protected char ch;
protected int bp;
protected int eofPos;
/**
* A character buffer for literals.
*/
protected char[] sbuf;
protected int sp;
/**
* number start position
*/
protected int np;
protected boolean hasSpecial;
protected Calendar calendar = null;
protected TimeZone timeZone = JSON.defaultTimeZone;
protected Locale locale = JSON.defaultLocale;
public int matchStat = UNKNOWN;
private final static ThreadLocal SBUF_LOCAL = new ThreadLocal();
protected String stringDefaultValue = null;
protected int nanos = 0;
public JSONLexerBase(int features){
this.features = features;
if ((features & Feature.InitStringFieldAsEmpty.mask) != 0) {
stringDefaultValue = "";
}
sbuf = SBUF_LOCAL.get();
if (sbuf == null) {
sbuf = new char[512];
}
}
public final int matchStat() {
return matchStat;
}
/**
* internal method, don't invoke
* @param token
*/
public void setToken(int token) {
this.token = token;
}
public final void nextToken() {
sp = 0;
for (;;) {
pos = bp;
if (ch == '/') {
skipComment();
continue;
}
if (ch == '"') {
scanString();
return;
}
if (ch == ',') {
next();
token = COMMA;
return;
}
if (ch >= '0' && ch <= '9') {
scanNumber();
return;
}
if (ch == '-') {
scanNumber();
return;
}
switch (ch) {
case '\'':
if (!isEnabled(Feature.AllowSingleQuotes)) {
throw new JSONException("Feature.AllowSingleQuotes is false");
}
scanStringSingleQuote();
return;
case ' ':
case '\t':
case '\b':
case '\f':
case '\n':
case '\r':
next();
break;
case 't': // true
scanTrue();
return;
case 'f': // false
scanFalse();
return;
case 'n': // new,null
scanNullOrNew();
return;
case 'T':
case 'N': // NULL
case 'S':
case 'u': // undefined
scanIdent();
return;
case '(':
next();
token = LPAREN;
return;
case ')':
next();
token = RPAREN;
return;
case '[':
next();
token = LBRACKET;
return;
case ']':
next();
token = RBRACKET;
return;
case '{':
next();
token = LBRACE;
return;
case '}':
next();
token = RBRACE;
return;
case ':':
next();
token = COLON;
return;
case ';':
next();
token = SEMI;
return;
case '.':
next();
token = DOT;
return;
case '+':
next();
scanNumber();
return;
case 'x':
scanHex();
return;
default:
if (isEOF()) { // JLS
if (token == EOF) {
throw new JSONException("EOF error");
}
token = EOF;
eofPos = pos = bp;
} else {
if (ch <= 31 || ch == 127) {
next();
break;
}
lexError("illegal.char", String.valueOf((int) ch));
next();
}
return;
}
}
}
public final void nextToken(int expect) {
sp = 0;
for (;;) {
switch (expect) {
case JSONToken.LBRACE:
if (ch == '{') {
token = JSONToken.LBRACE;
next();
return;
}
if (ch == '[') {
token = JSONToken.LBRACKET;
next();
return;
}
break;
case JSONToken.COMMA:
if (ch == ',') {
token = JSONToken.COMMA;
next();
return;
}
if (ch == '}') {
token = JSONToken.RBRACE;
next();
return;
}
if (ch == ']') {
token = JSONToken.RBRACKET;
next();
return;
}
if (ch == EOI) {
token = JSONToken.EOF;
return;
}
if (ch == 'n') {
scanNullOrNew(false);
return;
}
break;
case JSONToken.LITERAL_INT:
if (ch >= '0' && ch <= '9') {
pos = bp;
scanNumber();
return;
}
if (ch == '"') {
pos = bp;
scanString();
return;
}
if (ch == '[') {
token = JSONToken.LBRACKET;
next();
return;
}
if (ch == '{') {
token = JSONToken.LBRACE;
next();
return;
}
break;
case JSONToken.LITERAL_STRING:
if (ch == '"') {
pos = bp;
scanString();
return;
}
if (ch >= '0' && ch <= '9') {
pos = bp;
scanNumber();
return;
}
if (ch == '[') {
token = JSONToken.LBRACKET;
next();
return;
}
if (ch == '{') {
token = JSONToken.LBRACE;
next();
return;
}
break;
case JSONToken.LBRACKET:
if (ch == '[') {
token = JSONToken.LBRACKET;
next();
return;
}
if (ch == '{') {
token = JSONToken.LBRACE;
next();
return;
}
break;
case JSONToken.RBRACKET:
if (ch == ']') {
token = JSONToken.RBRACKET;
next();
return;
}
case JSONToken.EOF:
if (ch == EOI) {
token = JSONToken.EOF;
return;
}
break;
case JSONToken.IDENTIFIER:
nextIdent();
return;
default:
break;
}
if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') {
next();
continue;
}
nextToken();
break;
}
}
public final void nextIdent() {
while (isWhitespace(ch)) {
next();
}
if (ch == '_' || ch == '$' || Character.isLetter(ch)) {
scanIdent();
} else {
nextToken();
}
}
public final void nextTokenWithColon() {
nextTokenWithChar(':');
}
public final void nextTokenWithChar(char expect) {
sp = 0;
for (;;) {
if (ch == expect) {
next();
nextToken();
return;
}
if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') {
next();
continue;
}
throw new JSONException("not match " + expect + " - " + ch + ", info : " + this.info());
}
}
public final int token() {
return token;
}
public final String tokenName() {
return JSONToken.name(token);
}
public final int pos() {
return pos;
}
public final String stringDefaultValue() {
return stringDefaultValue;
}
public final Number integerValue() throws NumberFormatException {
long result = 0;
boolean negative = false;
if (np == -1) {
np = 0;
}
int i = np, max = np + sp;
long limit;
long multmin;
int digit;
char type = ' ';
switch (charAt(max - 1)) {
case 'L':
max--;
type = 'L';
break;
case 'S':
max--;
type = 'S';
break;
case 'B':
max--;
type = 'B';
break;
default:
break;
}
if (charAt(np) == '-') {
negative = true;
limit = Long.MIN_VALUE;
i++;
} else {
limit = -Long.MAX_VALUE;
}
multmin = MULTMIN_RADIX_TEN;
if (i < max) {
digit = charAt(i++) - '0';
result = -digit;
}
while (i < max) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = charAt(i++) - '0';
if (result < multmin) {
return new BigInteger(numberString(), 10);
}
result *= 10;
if (result < limit + digit) {
return new BigInteger(numberString(), 10);
}
result -= digit;
}
if (negative) {
if (i > np + 1) {
if (result >= Integer.MIN_VALUE && type != 'L') {
if (type == 'S') {
return (short) result;
}
if (type == 'B') {
return (byte) result;
}
return (int) result;
}
return result;
} else { /* Only got "-" */
throw new JSONException("illegal number format : " + numberString());
}
} else {
result = -result;
if (result <= Integer.MAX_VALUE && type != 'L') {
if (type == 'S') {
return (short) result;
}
if (type == 'B') {
return (byte) result;
}
return (int) result;
}
return result;
}
}
public final void nextTokenWithColon(int expect) {
nextTokenWithChar(':');
}
public float floatValue() {
String strVal = numberString();
float floatValue = Float.parseFloat(strVal);
if (floatValue == 0 || floatValue == Float.POSITIVE_INFINITY) {
char c0 = strVal.charAt(0);
if (c0 > '0' && c0 <= '9') {
throw new JSONException("float overflow : " + strVal);
}
}
return floatValue;
}
public double doubleValue() {
return Double.parseDouble(numberString());
}
public void config(Feature feature, boolean state) {
features = Feature.config(features, feature, state);
if ((features & Feature.InitStringFieldAsEmpty.mask) != 0) {
stringDefaultValue = "";
}
}
public final boolean isEnabled(Feature feature) {
return isEnabled(feature.mask);
}
public final boolean isEnabled(int feature) {
return (this.features & feature) != 0;
}
public final boolean isEnabled(int features, int feature) {
return (this.features & feature) != 0 || (features & feature) != 0;
}
public abstract String numberString();
public abstract boolean isEOF();
public final char getCurrent() {
return ch;
}
public abstract char charAt(int index);
// public final char next() {
// ch = doNext();
//// if (ch == '/' && (this.features & Feature.AllowComment.mask) != 0) {
//// skipComment();
//// }
// return ch;
// }
public abstract char next();
protected void skipComment() {
next();
if (ch == '/') {
for (;;) {
next();
if (ch == '\n') {
next();
return;
} else if (ch == EOI) {
return;
}
}
} else if (ch == '*') {
next();
for (; ch != EOI;) {
if (ch == '*') {
next();
if (ch == '/') {
next();
return;
} else {
continue;
}
}
next();
}
} else {
throw new JSONException("invalid comment");
}
}
public final String scanSymbol(final SymbolTable symbolTable) {
skipWhitespace();
if (ch == '"') {
return scanSymbol(symbolTable, '"');
}
if (ch == '\'') {
if (!isEnabled(Feature.AllowSingleQuotes)) {
throw new JSONException("syntax error");
}
return scanSymbol(symbolTable, '\'');
}
if (ch == '}') {
next();
token = JSONToken.RBRACE;
return null;
}
if (ch == ',') {
next();
token = JSONToken.COMMA;
return null;
}
if (ch == EOI) {
token = JSONToken.EOF;
return null;
}
if (!isEnabled(Feature.AllowUnQuotedFieldNames)) {
throw new JSONException("syntax error");
}
return scanSymbolUnQuoted(symbolTable);
}
// public abstract String scanSymbol(final SymbolTable symbolTable, final char quote);
protected abstract void arrayCopy(int srcPos, char[] dest, int destPos, int length);
public final String scanSymbol(final SymbolTable symbolTable, final char quote) {
int hash = 0;
np = bp;
sp = 0;
boolean hasSpecial = false;
char chLocal;
for (;;) {
chLocal = next();
if (chLocal == quote) {
break;
}
if (chLocal == EOI) {
throw new JSONException("unclosed.str");
}
if (chLocal == '\\') {
if (!hasSpecial) {
hasSpecial = true;
if (sp >= sbuf.length) {
int newCapcity = sbuf.length * 2;
if (sp > newCapcity) {
newCapcity = sp;
}
char[] newsbuf = new char[newCapcity];
System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
sbuf = newsbuf;
}
// text.getChars(np + 1, np + 1 + sp, sbuf, 0);
// System.arraycopy(this.buf, np + 1, sbuf, 0, sp);
arrayCopy(np + 1, sbuf, 0, sp);
}
chLocal = next();
switch (chLocal) {
case '0':
hash = 31 * hash + (int) chLocal;
putChar('\0');
break;
case '1':
hash = 31 * hash + (int) chLocal;
putChar('\1');
break;
case '2':
hash = 31 * hash + (int) chLocal;
putChar('\2');
break;
case '3':
hash = 31 * hash + (int) chLocal;
putChar('\3');
break;
case '4':
hash = 31 * hash + (int) chLocal;
putChar('\4');
break;
case '5':
hash = 31 * hash + (int) chLocal;
putChar('\5');
break;
case '6':
hash = 31 * hash + (int) chLocal;
putChar('\6');
break;
case '7':
hash = 31 * hash + (int) chLocal;
putChar('\7');
break;
case 'b': // 8
hash = 31 * hash + (int) '\b';
putChar('\b');
break;
case 't': // 9
hash = 31 * hash + (int) '\t';
putChar('\t');
break;
case 'n': // 10
hash = 31 * hash + (int) '\n';
putChar('\n');
break;
case 'v': // 11
hash = 31 * hash + (int) '\u000B';
putChar('\u000B');
break;
case 'f': // 12
case 'F':
hash = 31 * hash + (int) '\f';
putChar('\f');
break;
case 'r': // 13
hash = 31 * hash + (int) '\r';
putChar('\r');
break;
case '"': // 34
hash = 31 * hash + (int) '"';
putChar('"');
break;
case '\'': // 39
hash = 31 * hash + (int) '\'';
putChar('\'');
break;
case '/': // 47
hash = 31 * hash + (int) '/';
putChar('/');
break;
case '\\': // 92
hash = 31 * hash + (int) '\\';
putChar('\\');
break;
case 'x':
char x1 = ch = next();
char x2 = ch = next();
int x_val = digits[x1] * 16 + digits[x2];
char x_char = (char) x_val;
hash = 31 * hash + (int) x_char;
putChar(x_char);
break;
case 'u':
char c1 = chLocal = next();
char c2 = chLocal = next();
char c3 = chLocal = next();
char c4 = chLocal = next();
int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16);
hash = 31 * hash + val;
putChar((char) val);
break;
default:
this.ch = chLocal;
throw new JSONException("unclosed.str.lit");
}
continue;
}
hash = 31 * hash + chLocal;
if (!hasSpecial) {
sp++;
continue;
}
if (sp == sbuf.length) {
putChar(chLocal);
} else {
sbuf[sp++] = chLocal;
}
}
token = LITERAL_STRING;
String value;
if (!hasSpecial) {
// return this.text.substring(np + 1, np + 1 + sp).intern();
int offset;
if (np == -1) {
offset = 0;
} else {
offset = np + 1;
}
value = addSymbol(offset, sp, hash, symbolTable);
} else {
value = symbolTable.addSymbol(sbuf, 0, sp, hash);
}
sp = 0;
this.next();
return value;
}
public final void resetStringPosition() {
this.sp = 0;
}
public String info() {
return "";
}
public final String scanSymbolUnQuoted(final SymbolTable symbolTable) {
if (token == JSONToken.ERROR && pos == 0 && bp == 1) {
bp = 0; // adjust
}
final boolean[] firstIdentifierFlags = IOUtils.firstIdentifierFlags;
final char first = ch;
final boolean firstFlag = ch >= firstIdentifierFlags.length || firstIdentifierFlags[first];
if (!firstFlag) {
throw new JSONException("illegal identifier : " + ch //
+ info());
}
final boolean[] identifierFlags = IOUtils.identifierFlags;
int hash = first;
np = bp;
sp = 1;
char chLocal;
for (;;) {
chLocal = next();
if (chLocal < identifierFlags.length) {
if (!identifierFlags[chLocal]) {
break;
}
}
hash = 31 * hash + chLocal;
sp++;
continue;
}
this.ch = charAt(bp);
token = JSONToken.IDENTIFIER;
final int NULL_HASH = 3392903;
if (sp == 4 && hash == NULL_HASH && charAt(np) == 'n' && charAt(np + 1) == 'u' && charAt(np + 2) == 'l'
&& charAt(np + 3) == 'l') {
return null;
}
// return text.substring(np, np + sp).intern();
if (symbolTable == null) {
return subString(np, sp);
}
return this.addSymbol(np, sp, hash, symbolTable);
// return symbolTable.addSymbol(buf, np, sp, hash);
}
protected abstract void copyTo(int offset, int count, char[] dest);
public final void scanString() {
np = bp;
hasSpecial = false;
char ch;
for (;;) {
ch = next();
if (ch == '\"') {
break;
}
if (ch == EOI) {
if (!isEOF()) {
putChar((char) EOI);
continue;
}
throw new JSONException("unclosed string : " + ch);
}
if (ch == '\\') {
if (!hasSpecial) {
hasSpecial = true;
if (sp >= sbuf.length) {
int newCapcity = sbuf.length * 2;
if (sp > newCapcity) {
newCapcity = sp;
}
char[] newsbuf = new char[newCapcity];
System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
sbuf = newsbuf;
}
copyTo(np + 1, sp, sbuf);
// text.getChars(np + 1, np + 1 + sp, sbuf, 0);
// System.arraycopy(buf, np + 1, sbuf, 0, sp);
}
ch = next();
switch (ch) {
case '0':
putChar('\0');
break;
case '1':
putChar('\1');
break;
case '2':
putChar('\2');
break;
case '3':
putChar('\3');
break;
case '4':
putChar('\4');
break;
case '5':
putChar('\5');
break;
case '6':
putChar('\6');
break;
case '7':
putChar('\7');
break;
case 'b': // 8
putChar('\b');
break;
case 't': // 9
putChar('\t');
break;
case 'n': // 10
putChar('\n');
break;
case 'v': // 11
putChar('\u000B');
break;
case 'f': // 12
case 'F':
putChar('\f');
break;
case 'r': // 13
putChar('\r');
break;
case '"': // 34
putChar('"');
break;
case '\'': // 39
putChar('\'');
break;
case '/': // 47
putChar('/');
break;
case '\\': // 92
putChar('\\');
break;
case 'x':
char x1 = next();
char x2 = next();
boolean hex1 = (x1 >= '0' && x1 <= '9')
|| (x1 >= 'a' && x1 <= 'f')
|| (x1 >= 'A' && x1 <= 'F');
boolean hex2 = (x2 >= '0' && x2 <= '9')
|| (x2 >= 'a' && x2 <= 'f')
|| (x2 >= 'A' && x2 <= 'F');
if (!hex1 || !hex2) {
throw new JSONException("invalid escape character \\x" + x1 + x2);
}
char x_char = (char) (digits[x1] * 16 + digits[x2]);
putChar(x_char);
break;
case 'u':
char u1 = next();
char u2 = next();
char u3 = next();
char u4 = next();
int val = Integer.parseInt(new String(new char[] { u1, u2, u3, u4 }), 16);
putChar((char) val);
break;
default:
this.ch = ch;
throw new JSONException("unclosed string : " + ch);
}
continue;
}
if (!hasSpecial) {
sp++;
continue;
}
if (sp == sbuf.length) {
putChar(ch);
} else {
sbuf[sp++] = ch;
}
}
token = JSONToken.LITERAL_STRING;
this.ch = next();
}
public Calendar getCalendar() {
return this.calendar;
}
public TimeZone getTimeZone() {
return timeZone;
}
public void setTimeZone(TimeZone timeZone) {
this.timeZone = timeZone;
}
public Locale getLocale() {
return locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
public final int intValue() {
if (np == -1) {
np = 0;
}
int result = 0;
boolean negative = false;
int i = np, max = np + sp;
int limit;
int digit;
if (charAt(np) == '-') {
negative = true;
limit = Integer.MIN_VALUE;
i++;
} else {
limit = -Integer.MAX_VALUE;
}
long multmin = INT_MULTMIN_RADIX_TEN;
if (i < max) {
digit = charAt(i++) - '0';
result = -digit;
}
while (i < max) {
// Accumulating negatively avoids surprises near MAX_VALUE
char chLocal = charAt(i++);
if (chLocal == 'L' || chLocal == 'S' || chLocal == 'B') {
break;
}
digit = chLocal - '0';
if (result < multmin) {
throw new NumberFormatException(numberString());
}
result *= 10;
if (result < limit + digit) {
throw new NumberFormatException(numberString());
}
result -= digit;
}
if (negative) {
if (i > np + 1) {
return result;
} else { /* Only got "-" */
throw new NumberFormatException(numberString());
}
} else {
return -result;
}
}
public abstract byte[] bytesValue();
public void close() {
if (sbuf.length <= 1024 * 8) {
SBUF_LOCAL.set(sbuf);
}
this.sbuf = null;
}
public final boolean isRef() {
if (sp != 4) {
return false;
}
return charAt(np + 1) == '$' //
&& charAt(np + 2) == 'r' //
&& charAt(np + 3) == 'e' //
&& charAt(np + 4) == 'f';
}
public String scanTypeName(SymbolTable symbolTable) {
return null;
}
protected final static char[] typeFieldName = ("\"" + JSON.DEFAULT_TYPE_KEY + "\":\"").toCharArray();
public final int scanType(String type) {
matchStat = UNKNOWN;
if (!charArrayCompare(typeFieldName)) {
return NOT_MATCH_NAME;
}
int bpLocal = this.bp + typeFieldName.length;
final int typeLength = type.length();
for (int i = 0; i < typeLength; ++i) {
if (type.charAt(i) != charAt(bpLocal + i)) {
return NOT_MATCH;
}
}
bpLocal += typeLength;
if (charAt(bpLocal) != '"') {
return NOT_MATCH;
}
this.ch = charAt(++bpLocal);
if (ch == ',') {
this.ch = charAt(++bpLocal);
this.bp = bpLocal;
token = JSONToken.COMMA;
return VALUE;
} else if (ch == '}') {
ch = charAt(++bpLocal);
if (ch == ',') {
token = JSONToken.COMMA;
this.ch = charAt(++bpLocal);
} else if (ch == ']') {
token = JSONToken.RBRACKET;
this.ch = charAt(++bpLocal);
} else if (ch == '}') {
token = JSONToken.RBRACE;
this.ch = charAt(++bpLocal);
} else if (ch == EOI) {
token = JSONToken.EOF;
} else {
return NOT_MATCH;
}
matchStat = END;
}
this.bp = bpLocal;
return matchStat;
}
public final boolean matchField(char[] fieldName) {
for (;;) {
if (!charArrayCompare(fieldName)) {
if (isWhitespace(ch)) {
next();
continue;
}
return false;
} else {
break;
}
}
bp = bp + fieldName.length;
ch = charAt(bp);
if (ch == '{') {
next();
token = JSONToken.LBRACE;
} else if (ch == '[') {
next();
token = JSONToken.LBRACKET;
} else if (ch == 'S' && charAt(bp + 1) == 'e' && charAt(bp + 2) == 't' && charAt(bp + 3) == '[') {
bp += 3;
ch = charAt(bp);
token = JSONToken.SET;
} else {
nextToken();
}
return true;
}
public int matchField(long fieldNameHash) {
throw new UnsupportedOperationException();
}
public boolean seekArrayToItem(int index) {
throw new UnsupportedOperationException();
}
public int seekObjectToField(long fieldNameHash, boolean deepScan) {
throw new UnsupportedOperationException();
}
public int seekObjectToField(long[] fieldNameHash) {
throw new UnsupportedOperationException();
}
public int seekObjectToFieldDeepScan(long fieldNameHash) {
throw new UnsupportedOperationException();
}
public void skipObject() {
throw new UnsupportedOperationException();
}
public void skipObject(boolean valid) {
throw new UnsupportedOperationException();
}
public void skipArray() {
throw new UnsupportedOperationException();
}
public abstract int indexOf(char ch, int startIndex);
public abstract String addSymbol(int offset, int len, int hash, final SymbolTable symbolTable);
public String scanFieldString(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return stringDefaultValue();
}
// int index = bp + fieldName.length;
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
if (chLocal != '"') {
matchStat = NOT_MATCH;
return stringDefaultValue();
}
final String strVal;
{
int startIndex = bp + fieldName.length + 1;
int endIndex = indexOf('"', startIndex);
if (endIndex == -1) {
throw new JSONException("unclosed str");
}
int startIndex2 = bp + fieldName.length + 1; // must re compute
String stringVal = subString(startIndex2, endIndex - startIndex2);
if (stringVal.indexOf('\\') != -1) {
for (;;) {
int slashCount = 0;
for (int i = endIndex - 1; i >= 0; --i) {
if (charAt(i) == '\\') {
slashCount++;
} else {
break;
}
}
if (slashCount % 2 == 0) {
break;
}
endIndex = indexOf('"', endIndex + 1);
}
int chars_len = endIndex - (bp + fieldName.length + 1);
char[] chars = sub_chars( bp + fieldName.length + 1, chars_len);
stringVal = readString(chars, chars_len);
}
offset += (endIndex - (bp + fieldName.length + 1) + 1);
chLocal = charAt(bp + (offset++));
strVal = stringVal;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return strVal;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return stringDefaultValue();
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return stringDefaultValue();
}
return strVal;
}
public String scanString(char expectNextChar) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
if (chLocal == 'n') {
if (charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') {
offset += 3;
chLocal = charAt(bp + (offset++));
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == expectNextChar) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return null;
} else {
matchStat = NOT_MATCH;
return null;
}
}
final String strVal;
for (;;) {
if (chLocal == '"') {
int startIndex = bp + offset;
int endIndex = indexOf('"', startIndex);
if (endIndex == -1) {
throw new JSONException("unclosed str");
}
String stringVal = subString(bp + offset, endIndex - startIndex);
if (stringVal.indexOf('\\') != -1) {
for (; ; ) {
int slashCount = 0;
for (int i = endIndex - 1; i >= 0; --i) {
if (charAt(i) == '\\') {
slashCount++;
} else {
break;
}
}
if (slashCount % 2 == 0) {
break;
}
endIndex = indexOf('"', endIndex + 1);
}
int chars_len = endIndex - startIndex;
char[] chars = sub_chars(bp + 1, chars_len);
stringVal = readString(chars, chars_len);
}
offset += (endIndex - startIndex + 1);
chLocal = charAt(bp + (offset++));
strVal = stringVal;
break;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + (offset++));
continue;
} else {
matchStat = NOT_MATCH;
return stringDefaultValue();
}
}
for (;;) {
if (chLocal == expectNextChar) {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return strVal;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + (offset++));
continue;
} else {
if (chLocal == ']') {
bp += offset;
this.ch = charAt(bp);
matchStat = NOT_MATCH;
}
return strVal;
}
}
}
public long scanFieldSymbol(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return 0;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
if (chLocal != '"') {
matchStat = NOT_MATCH;
return 0;
}
long hash = fnv1a_64_magic_hashcode;
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal == '\"') {
chLocal = charAt(bp + (offset++));
break;
}
hash ^= chLocal;
hash *= fnv1a_64_magic_prime;
if (chLocal == '\\') {
matchStat = NOT_MATCH;
return 0;
}
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return hash;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return 0;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return 0;
}
return hash;
}
public long scanEnumSymbol(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return 0;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
if (chLocal != '"') {
matchStat = NOT_MATCH;
return 0;
}
long hash = fnv1a_64_magic_hashcode;
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal == '\"') {
chLocal = charAt(bp + (offset++));
break;
}
hash ^= ((chLocal >= 'A' && chLocal <= 'Z') ? (chLocal + 32) : chLocal);
hash *= fnv1a_64_magic_prime;
if (chLocal == '\\') {
matchStat = NOT_MATCH;
return 0;
}
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return hash;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return 0;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return 0;
}
return hash;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public Enum> scanEnum(Class> enumClass, final SymbolTable symbolTable, char serperator) {
String name = scanSymbolWithSeperator(symbolTable, serperator);
if (name == null) {
return null;
}
return Enum.valueOf((Class extends Enum>) enumClass, name);
}
public String scanSymbolWithSeperator(final SymbolTable symbolTable, char serperator) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
if (chLocal == 'n') {
if (charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') {
offset += 3;
chLocal = charAt(bp + (offset++));
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == serperator) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return null;
} else {
matchStat = NOT_MATCH;
return null;
}
}
if (chLocal != '"') {
matchStat = NOT_MATCH;
return null;
}
String strVal;
// int start = index;
int hash = 0;
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal == '\"') {
// bp = index;
// this.ch = chLocal = charAt(bp);
int start = bp + 0 + 1;
int len = bp + offset - start - 1;
strVal = addSymbol(start, len, hash, symbolTable);
chLocal = charAt(bp + (offset++));
break;
}
hash = 31 * hash + chLocal;
if (chLocal == '\\') {
matchStat = NOT_MATCH;
return null;
}
}
for (;;) {
if (chLocal == serperator) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return strVal;
} else {
if (isWhitespace(chLocal)) {
chLocal = charAt(bp + (offset++));
continue;
}
matchStat = NOT_MATCH;
return strVal;
}
}
}
public Collection newCollectionByType(Class> type){
if (type.isAssignableFrom(HashSet.class)) {
return new HashSet();
} else if (type.isAssignableFrom(ArrayList.class)) {
return new ArrayList();
} else if (type.isAssignableFrom(LinkedList.class)) {
return new LinkedList();
} else {
try {
return (Collection) type.newInstance();
} catch (Exception e) {
throw new JSONException(e.getMessage(), e);
}
}
}
@SuppressWarnings("unchecked")
public Collection scanFieldStringArray(char[] fieldName, Class> type) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return null;
}
Collection list = newCollectionByType(type);
// if (type.isAssignableFrom(HashSet.class)) {
// list = new HashSet();
// } else if (type.isAssignableFrom(ArrayList.class)) {
// list = new ArrayList();
// } else {
// try {
// list = (Collection) type.newInstance();
// } catch (Exception e) {
// throw new JSONException(e.getMessage(), e);
// }
// }
// int index = bp + fieldName.length;
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
if (chLocal != '[') {
matchStat = NOT_MATCH;
return null;
}
chLocal = charAt(bp + (offset++));
for (;;) {
// int start = index;
if (chLocal == '"') {
int startIndex = bp + offset;
int endIndex = indexOf('"', startIndex);
if (endIndex == -1) {
throw new JSONException("unclosed str");
}
int startIndex2 = bp + offset; // must re compute
String stringVal = subString(startIndex2, endIndex - startIndex2);
if (stringVal.indexOf('\\') != -1) {
for (;;) {
int slashCount = 0;
for (int i = endIndex - 1; i >= 0; --i) {
if (charAt(i) == '\\') {
slashCount++;
} else {
break;
}
}
if (slashCount % 2 == 0) {
break;
}
endIndex = indexOf('"', endIndex + 1);
}
int chars_len = endIndex - (bp + offset);
char[] chars = sub_chars(bp + offset, chars_len);
stringVal = readString(chars, chars_len);
}
offset += (endIndex - (bp + offset) + 1);
chLocal = charAt(bp + (offset++));
list.add(stringVal);
} else if (chLocal == 'n' //
&& charAt(bp + offset) == 'u' //
&& charAt(bp + offset + 1) == 'l' //
&& charAt(bp + offset + 2) == 'l') {
offset += 3;
chLocal = charAt(bp + (offset++));
list.add(null);
} else if (chLocal == ']' && list.size() == 0) {
chLocal = charAt(bp + (offset++));
break;
} else {
throw new JSONException("illega str");
}
if (chLocal == ',') {
chLocal = charAt(bp + (offset++));
continue;
}
if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
break;
}
matchStat = NOT_MATCH;
return null;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return list;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
bp += (offset - 1);
token = JSONToken.EOF;
this.ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return list;
}
public void scanStringArray(Collection list, char seperator) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
if (chLocal == 'n'
&& charAt(bp + offset) == 'u'
&& charAt(bp + offset + 1) == 'l'
&& charAt(bp + offset + 2) == 'l'
&& charAt(bp + offset + 3) == seperator
) {
bp += 5;
ch = charAt(bp);
matchStat = VALUE_NULL;
return;
}
if (chLocal != '[') {
matchStat = NOT_MATCH;
return;
}
chLocal = charAt(bp + (offset++));
for (;;) {
if (chLocal == 'n' //
&& charAt(bp + offset) == 'u' //
&& charAt(bp + offset + 1) == 'l' //
&& charAt(bp + offset + 2) == 'l') {
offset += 3;
chLocal = charAt(bp + (offset++));
list.add(null);
} else if (chLocal == ']' && list.size() == 0) {
chLocal = charAt(bp + (offset++));
break;
} else if (chLocal != '"') {
matchStat = NOT_MATCH;
return;
} else {
int startIndex = bp + offset;
int endIndex = indexOf('"', startIndex);
if (endIndex == -1) {
throw new JSONException("unclosed str");
}
String stringVal = subString(bp + offset, endIndex - startIndex);
if (stringVal.indexOf('\\') != -1) {
for (;;) {
int slashCount = 0;
for (int i = endIndex - 1; i >= 0; --i) {
if (charAt(i) == '\\') {
slashCount++;
} else {
break;
}
}
if (slashCount % 2 == 0) {
break;
}
endIndex = indexOf('"', endIndex + 1);
}
int chars_len = endIndex - startIndex;
char[] chars = sub_chars(bp + offset, chars_len);
stringVal = readString(chars, chars_len);
}
offset += (endIndex - (bp + offset) + 1);
chLocal = charAt(bp + (offset++));
list.add(stringVal);
}
if (chLocal == ',') {
chLocal = charAt(bp + (offset++));
continue;
}
if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
break;
}
matchStat = NOT_MATCH;
return;
}
if (chLocal == seperator) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return;
} else {
matchStat = NOT_MATCH;
return;
}
}
public int scanFieldInt(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return 0;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
final boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
int value;
if (chLocal >= '0' && chLocal <= '9') {
value = chLocal - '0';
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
value = value * 10 + (chLocal - '0');
} else if (chLocal == '.') {
matchStat = NOT_MATCH;
return 0;
} else {
break;
}
}
if (value < 0 //
|| offset > 11 + 3 + fieldName.length) {
if (value != Integer.MIN_VALUE //
|| offset != 17 //
|| !negative) {
matchStat = NOT_MATCH;
return 0;
}
}
} else {
matchStat = NOT_MATCH;
return 0;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return negative ? -value : value;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return 0;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return 0;
}
return negative ? -value : value;
}
public final int[] scanFieldIntArray(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return null;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
if (chLocal != '[') {
matchStat = NOT_MATCH_NAME;
return null;
}
chLocal = charAt(bp + (offset++));
int[] array = new int[16];
int arrayIndex = 0;
if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
} else {
for (;;) {
boolean nagative = false;
if (chLocal == '-') {
chLocal = charAt(bp + (offset++));
nagative = true;
}
if (chLocal >= '0' && chLocal <= '9') {
int value = chLocal - '0';
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
value = value * 10 + (chLocal - '0');
} else {
break;
}
}
if (arrayIndex >= array.length) {
int[] tmp = new int[array.length * 3 / 2];
System.arraycopy(array, 0, tmp, 0, arrayIndex);
array = tmp;
}
array[arrayIndex++] = nagative ? -value : value;
if (chLocal == ',') {
chLocal = charAt(bp + (offset++));
} else if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
break;
}
} else {
matchStat = NOT_MATCH;
return null;
}
}
}
if (arrayIndex != array.length) {
int[] tmp = new int[arrayIndex];
System.arraycopy(array, 0, tmp, 0, arrayIndex);
array = tmp;
}
if (chLocal == ',') {
bp += (offset - 1);
this.next();
matchStat = VALUE;
token = JSONToken.COMMA;
return array;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += (offset - 1);
this.next();
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += (offset - 1);
this.next();
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += (offset - 1);
this.next();
} else if (chLocal == EOI) {
bp += (offset - 1);
token = JSONToken.EOF;
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return array;
}
public boolean scanBoolean(char expectNext) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
boolean value = false;
if (chLocal == 't') {
if (charAt(bp + offset) == 'r' //
&& charAt(bp + offset + 1) == 'u' //
&& charAt(bp + offset + 2) == 'e') {
offset += 3;
chLocal = charAt(bp + (offset++));
value = true;
} else {
matchStat = NOT_MATCH;
return false;
}
} else if (chLocal == 'f') {
if (charAt(bp + offset) == 'a' //
&& charAt(bp + offset + 1) == 'l' //
&& charAt(bp + offset + 2) == 's' //
&& charAt(bp + offset + 3) == 'e') {
offset += 4;
chLocal = charAt(bp + (offset++));
value = false;
} else {
matchStat = NOT_MATCH;
return false;
}
} else if (chLocal == '1') {
chLocal = charAt(bp + (offset++));
value = true;
} else if (chLocal == '0') {
chLocal = charAt(bp + (offset++));
value = false;
}
for (;;) {
if (chLocal == expectNext) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return value;
} else {
if (isWhitespace(chLocal)) {
chLocal = charAt(bp + (offset++));
continue;
}
matchStat = NOT_MATCH;
return value;
}
}
}
public int scanInt(char expectNext) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
final boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
int value;
if (chLocal >= '0' && chLocal <= '9') {
value = chLocal - '0';
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
value = value * 10 + (chLocal - '0');
} else if (chLocal == '.') {
matchStat = NOT_MATCH;
return 0;
} else {
break;
}
}
if (value < 0) {
matchStat = NOT_MATCH;
return 0;
}
} else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = 0;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == ']') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACKET;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return 0;
} else {
matchStat = NOT_MATCH;
return 0;
}
for (;;) {
if (chLocal == expectNext) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return negative ? -value : value;
} else {
if (isWhitespace(chLocal)) {
chLocal = charAt(bp + (offset++));
continue;
}
matchStat = NOT_MATCH;
return negative ? -value : value;
}
}
}
public boolean scanFieldBoolean(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return false;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
boolean value;
if (chLocal == 't') {
if (charAt(bp + (offset++)) != 'r') {
matchStat = NOT_MATCH;
return false;
}
if (charAt(bp + (offset++)) != 'u') {
matchStat = NOT_MATCH;
return false;
}
if (charAt(bp + (offset++)) != 'e') {
matchStat = NOT_MATCH;
return false;
}
value = true;
} else if (chLocal == 'f') {
if (charAt(bp + (offset++)) != 'a') {
matchStat = NOT_MATCH;
return false;
}
if (charAt(bp + (offset++)) != 'l') {
matchStat = NOT_MATCH;
return false;
}
if (charAt(bp + (offset++)) != 's') {
matchStat = NOT_MATCH;
return false;
}
if (charAt(bp + (offset++)) != 'e') {
matchStat = NOT_MATCH;
return false;
}
value = false;
} else {
matchStat = NOT_MATCH;
return false;
}
chLocal = charAt(bp + offset++);
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return false;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return false;
}
return value;
}
public long scanFieldLong(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return 0;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
boolean negative = false;
if (chLocal == '-') {
chLocal = charAt(bp + (offset++));
negative = true;
}
long value;
if (chLocal >= '0' && chLocal <= '9') {
value = chLocal - '0';
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
value = value * 10 + (chLocal - '0');
} else if (chLocal == '.') {
matchStat = NOT_MATCH;
return 0;
} else {
break;
}
}
boolean valid = offset - fieldName.length < 21
&& (value >= 0 || (value == -9223372036854775808L && negative));
if (!valid) {
matchStat = NOT_MATCH;
return 0;
}
} else {
matchStat = NOT_MATCH;
return 0;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return negative ? -value : value;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return 0;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return 0;
}
return negative ? -value : value;
}
public long scanLong(char expectNextChar) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
final boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
long value;
if (chLocal >= '0' && chLocal <= '9') {
value = chLocal - '0';
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
value = value * 10 + (chLocal - '0');
} else if (chLocal == '.') {
matchStat = NOT_MATCH;
return 0;
} else {
break;
}
}
boolean valid = value >= 0 || (value == -9223372036854775808L && negative);
if (!valid) {
String val = subString(bp, offset - 1);
throw new NumberFormatException(val);
}
} else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = 0;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == ']') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACKET;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return 0;
} else {
matchStat = NOT_MATCH;
return 0;
}
if (quote) {
if (chLocal != '"') {
matchStat = NOT_MATCH;
return 0;
} else {
chLocal = charAt(bp + (offset++));
}
}
for (;;) {
if (chLocal == expectNextChar) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return negative ? -value : value;
} else {
if (isWhitespace(chLocal)) {
chLocal = charAt(bp + (offset++));
continue;
}
matchStat = NOT_MATCH;
return value;
}
}
}
public final float scanFieldFloat(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return 0;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
float value;
if (chLocal >= '0' && chLocal <= '9') {
long intVal = chLocal - '0';
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
continue;
} else {
break;
}
}
long power = 1;
boolean small = (chLocal == '.');
if (small) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power = 10;
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power *= 10;
continue;
} else {
break;
}
}
} else {
matchStat = NOT_MATCH;
return 0;
}
}
boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (;;) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}
int start, count;
if (quote) {
if (chLocal != '"') {
matchStat = NOT_MATCH;
return 0;
} else {
chLocal = charAt(bp + (offset++));
}
start = bp + fieldName.length + 1;
count = bp + offset - start - 2;
} else {
start = bp + fieldName.length;
count = bp + offset - start - 1;
}
if ((!exp) && count < 17) {
value = (float) (((double) intVal) / power);
if (negative) {
value = -value;
}
} else {
String text = this.subString(start, count);
value = Float.parseFloat(text);
}
} else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = 0;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == '}') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACE;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return 0;
} else {
matchStat = NOT_MATCH;
return 0;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
bp += (offset - 1);
token = JSONToken.EOF;
ch = EOI;
} else {
matchStat = NOT_MATCH;
return 0;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return 0;
}
return value;
}
public final float scanFloat(char seperator) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
float value;
if (chLocal >= '0' && chLocal <= '9') {
long intVal = chLocal - '0';
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
continue;
} else {
break;
}
}
long power = 1;
boolean small = (chLocal == '.');
if (small) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power = 10;
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power *= 10;
continue;
} else {
break;
}
}
} else {
matchStat = NOT_MATCH;
return 0;
}
}
boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (; ; ) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}
// int start, count;
// if (quote) {
// if (chLocal != '"') {
// matchStat = NOT_MATCH;
// return 0;
// } else {
// chLocal = charAt(bp + (offset++));
// }
// start = bp + 1;
// count = bp + offset - start - 2;
// } else {
// start = bp;
// count = bp + offset - start - 1;
// }
// String text = this.subString(start, count);
// value = Float.parseFloat(text);
int start, count;
if (quote) {
if (chLocal != '"') {
matchStat = NOT_MATCH;
return 0;
} else {
chLocal = charAt(bp + (offset++));
}
start = bp + 1;
count = bp + offset - start - 2;
} else {
start = bp;
count = bp + offset - start - 1;
}
if ((!exp) && count < 17) {
value = (float) (((double) intVal) / power);
if (negative) {
value = -value;
}
} else {
String text = this.subString(start, count);
value = Float.parseFloat(text);
}
} else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = 0;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == ']') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACKET;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return 0;
} else {
matchStat = NOT_MATCH;
return 0;
}
if (chLocal == seperator) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
} else {
matchStat = NOT_MATCH;
return value;
}
}
public double scanDouble(char seperator) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
double value;
if (chLocal >= '0' && chLocal <= '9') {
long intVal = chLocal - '0';
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
continue;
} else {
break;
}
}
long power = 1;
boolean small = (chLocal == '.');
if (small) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power = 10;
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power *= 10;
continue;
} else {
break;
}
}
} else {
matchStat = NOT_MATCH;
return 0;
}
}
boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (; ; ) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}
int start, count;
if (quote) {
if (chLocal != '"') {
matchStat = NOT_MATCH;
return 0;
} else {
chLocal = charAt(bp + (offset++));
}
start = bp + 1;
count = bp + offset - start - 2;
} else {
start = bp;
count = bp + offset - start - 1;
}
if (!exp && count < 17) {
value = ((double) intVal) / power;
if (negative) {
value = -value;
}
} else {
String text = this.subString(start, count);
value = Double.parseDouble(text);
}
} else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = 0;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == ']') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACKET;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return 0;
} else {
matchStat = NOT_MATCH;
return 0;
}
if (chLocal == seperator) {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
} else {
matchStat = NOT_MATCH;
return value;
}
}
public BigDecimal scanDecimal(char seperator) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
BigDecimal value;
if (chLocal >= '0' && chLocal <= '9') {
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
continue;
} else {
break;
}
}
boolean small = (chLocal == '.');
if (small) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
continue;
} else {
break;
}
}
} else {
matchStat = NOT_MATCH;
return null;
}
}
boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (;;) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}
int start, count;
if (quote) {
if (chLocal != '"') {
matchStat = NOT_MATCH;
return null;
} else {
chLocal = charAt(bp + (offset++));
}
start = bp + 1;
count = bp + offset - start - 2;
} else {
start = bp;
count = bp + offset - start - 1;
}
if (count > 65535) {
throw new JSONException("decimal overflow");
}
char[] chars = this.sub_chars(start, count);
value = new BigDecimal(chars, 0, chars.length, MathContext.UNLIMITED);
} else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = null;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == '}') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACE;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return null;
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
}
if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return value;
}
public final float[] scanFieldFloatArray(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return null;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
if (chLocal != '[') {
matchStat = NOT_MATCH_NAME;
return null;
}
chLocal = charAt(bp + (offset++));
float[] array = new float[16];
int arrayIndex = 0;
for (;;) {
int start = bp + offset - 1;
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
if (chLocal >= '0' && chLocal <= '9') {
int intVal = chLocal - '0';
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
continue;
} else {
break;
}
}
int power = 1;
boolean small = (chLocal == '.');
if (small) {
chLocal = charAt(bp + (offset++));
power = 10;
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power *= 10;
continue;
} else {
break;
}
}
} else {
matchStat = NOT_MATCH;
return null;
}
}
boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (;;) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}
int count = bp + offset - start - 1;
float value;
if (!exp && count < 10) {
value = ((float) intVal) / power;
if (negative) {
value = -value;
}
} else {
String text = this.subString(start, count);
value = Float.parseFloat(text);
}
if (arrayIndex >= array.length) {
float[] tmp = new float[array.length * 3 / 2];
System.arraycopy(array, 0, tmp, 0, arrayIndex);
array = tmp;
}
array[arrayIndex++] = value;
if (chLocal == ',') {
chLocal = charAt(bp + (offset++));
} else if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
break;
}
} else {
matchStat = NOT_MATCH;
return null;
}
}
if (arrayIndex != array.length) {
float[] tmp = new float[arrayIndex];
System.arraycopy(array, 0, tmp, 0, arrayIndex);
array = tmp;
}
if (chLocal == ',') {
bp += (offset - 1);
this.next();
matchStat = VALUE;
token = JSONToken.COMMA;
return array;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += (offset - 1);
this.next();
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += (offset - 1);
this.next();
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += (offset - 1);
this.next();
} else if (chLocal == EOI) {
bp += (offset - 1);
token = JSONToken.EOF;
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return array;
}
public final float[][] scanFieldFloatArray2(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return null;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
if (chLocal != '[') {
matchStat = NOT_MATCH_NAME;
return null;
}
chLocal = charAt(bp + (offset++));
float[][] arrayarray = new float[16][];
int arrayarrayIndex = 0;
for (;;) {
if (chLocal == '[') {
chLocal = charAt(bp + (offset++));
float[] array = new float[16];
int arrayIndex = 0;
for (; ; ) {
int start = bp + offset - 1;
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
if (chLocal >= '0' && chLocal <= '9') {
int intVal = chLocal - '0';
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
continue;
} else {
break;
}
}
int power = 1;
if (chLocal == '.') {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power = 10;
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power *= 10;
continue;
} else {
break;
}
}
} else {
matchStat = NOT_MATCH;
return null;
}
}
boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (;;) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}
int count = bp + offset - start - 1;
float value;
if (!exp && count < 10) {
value = ((float) intVal) / power;
if (negative) {
value = -value;
}
} else {
String text = this.subString(start, count);
value = Float.parseFloat(text);
}
if (arrayIndex >= array.length) {
float[] tmp = new float[array.length * 3 / 2];
System.arraycopy(array, 0, tmp, 0, arrayIndex);
array = tmp;
}
array[arrayIndex++] = value;
if (chLocal == ',') {
chLocal = charAt(bp + (offset++));
} else if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
break;
}
} else {
matchStat = NOT_MATCH;
return null;
}
}
// compact
if (arrayIndex != array.length) {
float[] tmp = new float[arrayIndex];
System.arraycopy(array, 0, tmp, 0, arrayIndex);
array = tmp;
}
if (arrayarrayIndex >= arrayarray.length) {
float[][] tmp = new float[arrayarray.length * 3 / 2][];
System.arraycopy(array, 0, tmp, 0, arrayIndex);
arrayarray = tmp;
}
arrayarray[arrayarrayIndex++] = array;
if (chLocal == ',') {
chLocal = charAt(bp + (offset++));
} else if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
break;
}
} else {
break;
}
}
// compact
if (arrayarrayIndex != arrayarray.length) {
float[][] tmp = new float[arrayarrayIndex][];
System.arraycopy(arrayarray, 0, tmp, 0, arrayarrayIndex);
arrayarray = tmp;
}
if (chLocal == ',') {
bp += (offset - 1);
this.next();
matchStat = VALUE;
token = JSONToken.COMMA;
return arrayarray;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += (offset - 1);
this.next();
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += (offset - 1);
this.next();
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += (offset - 1);
this.next();
} else if (chLocal == EOI) {
bp += (offset - 1);
token = JSONToken.EOF;
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return arrayarray;
}
public final double scanFieldDouble(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return 0;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
double value;
if (chLocal >= '0' && chLocal <= '9') {
long intVal = chLocal - '0';
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
continue;
} else {
break;
}
}
long power = 1;
boolean small = (chLocal == '.');
if (small) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power = 10;
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power *= 10;
continue;
} else {
break;
}
}
} else {
matchStat = NOT_MATCH;
return 0;
}
}
boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (;;) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}
int start, count;
if (quote) {
if (chLocal != '"') {
matchStat = NOT_MATCH;
return 0;
} else {
chLocal = charAt(bp + (offset++));
}
start = bp + fieldName.length + 1;
count = bp + offset - start - 2;
} else {
start = bp + fieldName.length;
count = bp + offset - start - 1;
}
if (!exp && count < 17) {
value = ((double) intVal) / power;
if (negative) {
value = -value;
}
} else {
String text = this.subString(start, count);
value = Double.parseDouble(text);
}
} else if (chLocal == 'n' &&
charAt(bp + offset) == 'u' &&
charAt(bp + offset + 1) == 'l' &&
charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = 0;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == '}') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACE;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return 0;
} else {
matchStat = NOT_MATCH;
return 0;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return 0;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return 0;
}
return value;
}
public BigDecimal scanFieldDecimal(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return null;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
BigDecimal value;
if (chLocal >= '0' && chLocal <= '9') {
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
continue;
} else {
break;
}
}
boolean small = (chLocal == '.');
if (small) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
continue;
} else {
break;
}
}
} else {
matchStat = NOT_MATCH;
return null;
}
}
boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (;;) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}
int start, count;
if (quote) {
if (chLocal != '"') {
matchStat = NOT_MATCH;
return null;
} else {
chLocal = charAt(bp + (offset++));
}
start = bp + fieldName.length + 1;
count = bp + offset - start - 2;
} else {
start = bp + fieldName.length;
count = bp + offset - start - 1;
}
if (count > 65535) {
throw new JSONException("scan decimal overflow");
}
char[] chars = this.sub_chars(start, count);
value = new BigDecimal(chars, 0, chars.length, MathContext.UNLIMITED);
} else if (chLocal == 'n' &&
charAt(bp + offset) == 'u' &&
charAt(bp + offset + 1) == 'l' &&
charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = null;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == '}') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACE;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return null;
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return value;
}
public BigInteger scanFieldBigInteger(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return null;
}
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
final boolean quote = chLocal == '"';
if (quote) {
chLocal = charAt(bp + (offset++));
}
boolean negative = chLocal == '-';
if (negative) {
chLocal = charAt(bp + (offset++));
}
BigInteger value;
if (chLocal >= '0' && chLocal <= '9') {
long intVal = chLocal - '0';
boolean overflow = false;
long temp;
for (;;) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
temp = intVal * 10 + (chLocal - '0');
if (temp < intVal) {
overflow = true;
break;
}
intVal = temp;
continue;
} else {
break;
}
}
int start, count;
if (quote) {
if (chLocal != '"') {
matchStat = NOT_MATCH;
return null;
} else {
chLocal = charAt(bp + (offset++));
}
start = bp + fieldName.length + 1;
count = bp + offset - start - 2;
} else {
start = bp + fieldName.length;
count = bp + offset - start - 1;
}
if (!overflow && (count < 20 || (negative && count < 21))) {
value = BigInteger.valueOf(negative ? -intVal : intVal);
} else {
// char[] chars = this.sub_chars(negative ? start + 1 : start, count);
// value = new BigInteger(chars, )
if (count > 65535) {
throw new JSONException("scanInteger overflow");
}
String strVal = this.subString(start, count);
value = new BigInteger(strVal, 10);
}
} else if (chLocal == 'n' &&
charAt(bp + offset) == 'u' &&
charAt(bp + offset + 1) == 'l' &&
charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
value = null;
offset += 3;
chLocal = charAt(bp + offset++);
if (quote && chLocal == '"') {
chLocal = charAt(bp + offset++);
}
for (;;) {
if (chLocal == ',') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.COMMA;
return value;
} else if (chLocal == '}') {
bp += offset;
this.ch = charAt(bp);
matchStat = VALUE_NULL;
token = JSONToken.RBRACE;
return value;
} else if (isWhitespace(chLocal)) {
chLocal = charAt(bp + offset++);
continue;
}
break;
}
matchStat = NOT_MATCH;
return null;
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return value;
}
public java.util.Date scanFieldDate(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return null;
}
// int index = bp + fieldName.length;
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
final java.util.Date dateVal;
if (chLocal == '"'){
int startIndex = bp + fieldName.length + 1;
int endIndex = indexOf('"', startIndex);
if (endIndex == -1) {
throw new JSONException("unclosed str");
}
int startIndex2 = bp + fieldName.length + 1; // must re compute
String stringVal = subString(startIndex2, endIndex - startIndex2);
if (stringVal.indexOf('\\') != -1) {
for (;;) {
int slashCount = 0;
for (int i = endIndex - 1; i >= 0; --i) {
if (charAt(i) == '\\') {
slashCount++;
} else {
break;
}
}
if (slashCount % 2 == 0) {
break;
}
endIndex = indexOf('"', endIndex + 1);
}
int chars_len = endIndex - (bp + fieldName.length + 1);
char[] chars = sub_chars( bp + fieldName.length + 1, chars_len);
stringVal = readString(chars, chars_len);
}
offset += (endIndex - (bp + fieldName.length + 1) + 1);
chLocal = charAt(bp + (offset++));
JSONScanner dateLexer = new JSONScanner(stringVal);
try {
if (dateLexer.scanISO8601DateIfMatch(false)) {
Calendar calendar = dateLexer.getCalendar();
dateVal = calendar.getTime();
} else {
matchStat = NOT_MATCH;
return null;
}
} finally {
dateLexer.close();
}
} else if (chLocal == '-' || (chLocal >= '0' && chLocal <= '9')) {
long millis = 0;
boolean negative = false;
if (chLocal == '-') {
chLocal = charAt(bp + (offset++));
negative = true;
}
if (chLocal >= '0' && chLocal <= '9') {
millis = chLocal - '0';
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
millis = millis * 10 + (chLocal - '0');
} else {
break;
}
}
}
if (millis < 0) {
matchStat = NOT_MATCH;
return null;
}
if (negative) {
millis = -millis;
}
dateVal = new java.util.Date(millis);
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return dateVal;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return dateVal;
}
public java.util.Date scanDate(char seperator) {
matchStat = UNKNOWN;
int offset = 0;
char chLocal = charAt(bp + (offset++));
final java.util.Date dateVal;
if (chLocal == '"'){
int startIndex = bp + 1;
int endIndex = indexOf('"', startIndex);
if (endIndex == -1) {
throw new JSONException("unclosed str");
}
int startIndex2 = bp + 1; // must re compute
String stringVal = subString(startIndex2, endIndex - startIndex2);
if (stringVal.indexOf('\\') != -1) {
for (;;) {
int slashCount = 0;
for (int i = endIndex - 1; i >= 0; --i) {
if (charAt(i) == '\\') {
slashCount++;
} else {
break;
}
}
if (slashCount % 2 == 0) {
break;
}
endIndex = indexOf('"', endIndex + 1);
}
int chars_len = endIndex - (bp + 1);
char[] chars = sub_chars( bp + 1, chars_len);
stringVal = readString(chars, chars_len);
}
offset += (endIndex - (bp + 1) + 1);
chLocal = charAt(bp + (offset++));
JSONScanner dateLexer = new JSONScanner(stringVal);
try {
if (dateLexer.scanISO8601DateIfMatch(false)) {
Calendar calendar = dateLexer.getCalendar();
dateVal = calendar.getTime();
} else {
matchStat = NOT_MATCH;
return null;
}
} finally {
dateLexer.close();
}
} else if (chLocal == '-' || (chLocal >= '0' && chLocal <= '9')) {
long millis = 0;
boolean negative = false;
if (chLocal == '-') {
chLocal = charAt(bp + (offset++));
negative = true;
}
if (chLocal >= '0' && chLocal <= '9') {
millis = chLocal - '0';
for (; ; ) {
chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') {
millis = millis * 10 + (chLocal - '0');
} else {
break;
}
}
}
if (millis < 0) {
matchStat = NOT_MATCH;
return null;
}
if (negative) {
millis = -millis;
}
dateVal = new java.util.Date(millis);
} else if (chLocal == 'n' &&
charAt(bp + offset) == 'u' &&
charAt(bp + offset + 1) == 'l' &&
charAt(bp + offset + 2) == 'l') {
matchStat = VALUE_NULL;
dateVal = null;
offset += 3;
chLocal = charAt(bp + offset++);
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
token = JSONToken.COMMA;
return dateVal;
}
if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return dateVal;
}
public java.util.UUID scanFieldUUID(char[] fieldName) {
matchStat = UNKNOWN;
if (!charArrayCompare(fieldName)) {
matchStat = NOT_MATCH_NAME;
return null;
}
// int index = bp + fieldName.length;
int offset = fieldName.length;
char chLocal = charAt(bp + (offset++));
final java.util.UUID uuid;
if (chLocal == '"') {
int startIndex = bp + fieldName.length + 1;
int endIndex = indexOf('"', startIndex);
if (endIndex == -1) {
throw new JSONException("unclosed str");
}
int startIndex2 = bp + fieldName.length + 1; // must re compute
int len = endIndex - startIndex2;
if (len == 36) {
long mostSigBits = 0, leastSigBits = 0;
for (int i = 0; i < 8; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
mostSigBits <<= 4;
mostSigBits |= num;
}
for (int i = 9; i < 13; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
mostSigBits <<= 4;
mostSigBits |= num;
}
for (int i = 14; i < 18; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
mostSigBits <<= 4;
mostSigBits |= num;
}
for (int i = 19; i < 23; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
leastSigBits <<= 4;
leastSigBits |= num;
}
for (int i = 24; i < 36; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
leastSigBits <<= 4;
leastSigBits |= num;
}
uuid = new UUID(mostSigBits, leastSigBits);
offset += (endIndex - (bp + fieldName.length + 1) + 1);
chLocal = charAt(bp + (offset++));
} else if (len == 32) {
long mostSigBits = 0, leastSigBits = 0;
for (int i = 0; i < 16; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
mostSigBits <<= 4;
mostSigBits |= num;
}
for (int i = 16; i < 32; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
leastSigBits <<= 4;
leastSigBits |= num;
}
uuid = new UUID(mostSigBits, leastSigBits);
offset += (endIndex - (bp + fieldName.length + 1) + 1);
chLocal = charAt(bp + (offset++));
} else {
matchStat = NOT_MATCH;
return null;
}
} else if (chLocal == 'n'
&& charAt(bp + (offset++)) == 'u'
&& charAt(bp + (offset++)) == 'l'
&& charAt(bp + (offset++)) == 'l') {
uuid = null;
chLocal = charAt(bp + (offset++));
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return uuid;
}
if (chLocal == '}') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return uuid;
}
public java.util.UUID scanUUID(char seperator) {
matchStat = UNKNOWN;
// int index = bp + fieldName.length;
int offset = 0;
char chLocal = charAt(bp + (offset++));
final java.util.UUID uuid;
if (chLocal == '"') {
int startIndex = bp + 1;
int endIndex = indexOf('"', startIndex);
if (endIndex == -1) {
throw new JSONException("unclosed str");
}
int startIndex2 = bp + 1; // must re compute
int len = endIndex - startIndex2;
if (len == 36) {
long mostSigBits = 0, leastSigBits = 0;
for (int i = 0; i < 8; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
mostSigBits <<= 4;
mostSigBits |= num;
}
for (int i = 9; i < 13; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
mostSigBits <<= 4;
mostSigBits |= num;
}
for (int i = 14; i < 18; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
mostSigBits <<= 4;
mostSigBits |= num;
}
for (int i = 19; i < 23; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
leastSigBits <<= 4;
leastSigBits |= num;
}
for (int i = 24; i < 36; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
leastSigBits <<= 4;
leastSigBits |= num;
}
uuid = new UUID(mostSigBits, leastSigBits);
offset += (endIndex - (bp + 1) + 1);
chLocal = charAt(bp + (offset++));
} else if (len == 32) {
long mostSigBits = 0, leastSigBits = 0;
for (int i = 0; i < 16; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
mostSigBits <<= 4;
mostSigBits |= num;
}
for (int i = 16; i < 32; ++i) {
char ch = charAt(startIndex2 + i);
int num;
if (ch >= '0' && ch <= '9') {
num = ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
num = 10 + (ch - 'a');
} else if (ch >= 'A' && ch <= 'F') {
num = 10 + (ch - 'A');
} else {
matchStat = NOT_MATCH_NAME;
return null;
}
leastSigBits <<= 4;
leastSigBits |= num;
}
uuid = new UUID(mostSigBits, leastSigBits);
offset += (endIndex - (bp + 1) + 1);
chLocal = charAt(bp + (offset++));
} else {
matchStat = NOT_MATCH;
return null;
}
} else if (chLocal == 'n'
&& charAt(bp + (offset++)) == 'u'
&& charAt(bp + (offset++)) == 'l'
&& charAt(bp + (offset++)) == 'l') {
uuid = null;
chLocal = charAt(bp + (offset++));
} else {
matchStat = NOT_MATCH;
return null;
}
if (chLocal == ',') {
bp += offset;
this.ch = this.charAt(bp);
matchStat = VALUE;
return uuid;
}
if (chLocal == ']') {
chLocal = charAt(bp + (offset++));
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += offset;
this.ch = this.charAt(bp);
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
ch = EOI;
} else {
matchStat = NOT_MATCH;
return null;
}
matchStat = END;
} else {
matchStat = NOT_MATCH;
return null;
}
return uuid;
}
public final void scanTrue() {
if (ch != 't') {
throw new JSONException("error parse true");
}
next();
if (ch != 'r') {
throw new JSONException("error parse true");
}
next();
if (ch != 'u') {
throw new JSONException("error parse true");
}
next();
if (ch != 'e') {
throw new JSONException("error parse true");
}
next();
if (ch == ' ' ||
ch == ',' ||
ch == '}' ||
ch == ']' ||
ch == '\n' ||
ch == '\r' ||
ch == '\t' ||
ch == EOI ||
ch == '\f' ||
ch == '\b' ||
ch == ':' ||
ch == '/') {
token = JSONToken.TRUE;
} else {
throw new JSONException("scan true error");
}
}
public final void scanNullOrNew() {
scanNullOrNew(true);
}
public final void scanNullOrNew(boolean acceptColon) {
if (ch != 'n') {
throw new JSONException("error parse null or new");
}
next();
if (ch == 'u') {
next();
if (ch != 'l') {
throw new JSONException("error parse null");
}
next();
if (ch != 'l') {
throw new JSONException("error parse null");
}
next();
if (ch == ' '
|| ch == ','
|| ch == '}'
|| ch == ']'
|| ch == '\n'
|| ch == '\r'
|| ch == '\t'
|| ch == EOI
|| (ch == ':' && acceptColon)
|| ch == '\f'
|| ch == '\b') {
token = JSONToken.NULL;
} else {
throw new JSONException("scan null error");
}
return;
}
if (ch != 'e') {
throw new JSONException("error parse new");
}
next();
if (ch != 'w') {
throw new JSONException("error parse new");
}
next();
if (ch == ' ' ||
ch == ',' ||
ch == '}' ||
ch == ']' ||
ch == '\n' ||
ch == '\r' ||
ch == '\t' ||
ch == EOI ||
ch == '\f' ||
ch == '\b') {
token = JSONToken.NEW;
} else {
throw new JSONException("scan new error");
}
}
public final void scanFalse() {
if (ch != 'f') {
throw new JSONException("error parse false");
}
next();
if (ch != 'a') {
throw new JSONException("error parse false");
}
next();
if (ch != 'l') {
throw new JSONException("error parse false");
}
next();
if (ch != 's') {
throw new JSONException("error parse false");
}
next();
if (ch != 'e') {
throw new JSONException("error parse false");
}
next();
if (ch == ' ' ||
ch == ',' ||
ch == '}' ||
ch == ']' ||
ch == '\n' ||
ch == '\r' ||
ch == '\t' ||
ch == EOI ||
ch == '\f' ||
ch == '\b' ||
ch == ':' ||
ch == '/') {
token = JSONToken.FALSE;
} else {
throw new JSONException("scan false error");
}
}
public final void scanIdent() {
np = bp - 1;
hasSpecial = false;
for (;;) {
sp++;
next();
if (Character.isLetterOrDigit(ch)) {
continue;
}
String ident = stringVal();
if ("null".equalsIgnoreCase(ident)) {
token = JSONToken.NULL;
} else if ("new".equals(ident)) {
token = JSONToken.NEW;
} else if ("true".equals(ident)) {
token = JSONToken.TRUE;
} else if ("false".equals(ident)) {
token = JSONToken.FALSE;
} else if ("undefined".equals(ident)) {
token = JSONToken.UNDEFINED;
} else if ("Set".equals(ident)) {
token = JSONToken.SET;
} else if ("TreeSet".equals(ident)) {
token = JSONToken.TREE_SET;
} else {
token = JSONToken.IDENTIFIER;
}
return;
}
}
public abstract String stringVal();
public abstract String subString(int offset, int count);
protected abstract char[] sub_chars(int offset, int count);
public static String readString(char[] chars, int chars_len) {
char[] sbuf = new char[chars_len];
int len = 0;
for (int i = 0; i < chars_len; ++i) {
char ch = chars[i];
if (ch != '\\') {
sbuf[len++] = ch;
continue;
}
ch = chars[++i];
switch (ch) {
case '0':
sbuf[len++] = '\0';
break;
case '1':
sbuf[len++] = '\1';
break;
case '2':
sbuf[len++] = '\2';
break;
case '3':
sbuf[len++] = '\3';
break;
case '4':
sbuf[len++] = '\4';
break;
case '5':
sbuf[len++] = '\5';
break;
case '6':
sbuf[len++] = '\6';
break;
case '7':
sbuf[len++] = '\7';
break;
case 'b': // 8
sbuf[len++] = '\b';
break;
case 't': // 9
sbuf[len++] = '\t';
break;
case 'n': // 10
sbuf[len++] = '\n';
break;
case 'v': // 11
sbuf[len++] = '\u000B';
break;
case 'f': // 12
case 'F':
sbuf[len++] = '\f';
break;
case 'r': // 13
sbuf[len++] = '\r';
break;
case '"': // 34
sbuf[len++] = '"';
break;
case '\'': // 39
sbuf[len++] = '\'';
break;
case '/': // 47
sbuf[len++] = '/';
break;
case '\\': // 92
sbuf[len++] = '\\';
break;
case 'x':
sbuf[len++] = (char) (digits[chars[++i]] * 16 + digits[chars[++i]]);
break;
case 'u':
sbuf[len++] = (char) Integer.parseInt(new String(new char[] { chars[++i], //
chars[++i], //
chars[++i], //
chars[++i] }),
16);
break;
default:
throw new JSONException("unclosed.str.lit");
}
}
return new String(sbuf, 0, len);
}
protected abstract boolean charArrayCompare(char[] chars);
public boolean isBlankInput() {
for (int i = 0;; ++i) {
char chLocal = charAt(i);
if (chLocal == EOI) {
token = JSONToken.EOF;
break;
}
if (!isWhitespace(chLocal)) {
return false;
}
}
return true;
}
public final void skipWhitespace() {
for (;;) {
if (ch <= '/') {
if (ch == ' ' ||
ch == '\r' ||
ch == '\n' ||
ch == '\t' ||
ch == '\f' ||
ch == '\b') {
next();
continue;
} else if (ch == '/') {
skipComment();
continue;
} else {
break;
}
} else {
break;
}
}
}
private void scanStringSingleQuote() {
np = bp;
hasSpecial = false;
char chLocal;
for (;;) {
chLocal = next();
if (chLocal == '\'') {
break;
}
if (chLocal == EOI) {
if (!isEOF()) {
putChar((char) EOI);
continue;
}
throw new JSONException("unclosed single-quote string");
}
if (chLocal == '\\') {
if (!hasSpecial) {
hasSpecial = true;
if (sp > sbuf.length) {
char[] newsbuf = new char[sp * 2];
System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
sbuf = newsbuf;
}
// text.getChars(offset, offset + count, dest, 0);
this.copyTo(np + 1, sp, sbuf);
// System.arraycopy(buf, np + 1, sbuf, 0, sp);
}
chLocal = next();
switch (chLocal) {
case '0':
putChar('\0');
break;
case '1':
putChar('\1');
break;
case '2':
putChar('\2');
break;
case '3':
putChar('\3');
break;
case '4':
putChar('\4');
break;
case '5':
putChar('\5');
break;
case '6':
putChar('\6');
break;
case '7':
putChar('\7');
break;
case 'b': // 8
putChar('\b');
break;
case 't': // 9
putChar('\t');
break;
case 'n': // 10
putChar('\n');
break;
case 'v': // 11
putChar('\u000B');
break;
case 'f': // 12
case 'F':
putChar('\f');
break;
case 'r': // 13
putChar('\r');
break;
case '"': // 34
putChar('"');
break;
case '\'': // 39
putChar('\'');
break;
case '/': // 47
putChar('/');
break;
case '\\': // 92
putChar('\\');
break;
case 'x':
char x1 = next();
char x2 = next();
boolean hex1 = (x1 >= '0' && x1 <= '9')
|| (x1 >= 'a' && x1 <= 'f')
|| (x1 >= 'A' && x1 <= 'F');
boolean hex2 = (x2 >= '0' && x2 <= '9')
|| (x2 >= 'a' && x2 <= 'f')
|| (x2 >= 'A' && x2 <= 'F');
if (!hex1 || !hex2) {
throw new JSONException("invalid escape character \\x" + x1 + x2);
}
putChar((char) (digits[x1] * 16 + digits[x2]));
break;
case 'u':
putChar((char) Integer.parseInt(new String(new char[] { next(), next(), next(), next() }), 16));
break;
default:
this.ch = chLocal;
throw new JSONException("unclosed single-quote string");
}
continue;
}
if (!hasSpecial) {
sp++;
continue;
}
if (sp == sbuf.length) {
putChar(chLocal);
} else {
sbuf[sp++] = chLocal;
}
}
token = LITERAL_STRING;
this.next();
}
/**
* Append a character to sbuf.
*/
protected final void putChar(char ch) {
if (sp >= sbuf.length) {
int len = sbuf.length * 2;
if (len < sp) {
len = sp + 1;
}
char[] newsbuf = new char[len];
System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
sbuf = newsbuf;
}
sbuf[sp++] = ch;
}
public final void scanHex() {
if (ch != 'x') {
throw new JSONException("illegal state. " + ch);
}
next();
if (ch != '\'') {
throw new JSONException("illegal state. " + ch);
}
np = bp;
next();
if (ch == '\'') {
next();
token = JSONToken.HEX;
return;
}
for (int i = 0;;++i) {
char ch = next();
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) {
sp++;
continue;
} else if (ch == '\'') {
sp++;
next();
break;
} else {
throw new JSONException("illegal state. " + ch);
}
}
token = JSONToken.HEX;
}
public final void scanNumber() {
np = bp;
if (ch == '-') {
sp++;
next();
}
for (;;) {
if (ch >= '0' && ch <= '9') {
sp++;
} else {
break;
}
next();
}
boolean isDouble = false;
if (ch == '.') {
sp++;
next();
isDouble = true;
for (;;) {
if (ch >= '0' && ch <= '9') {
sp++;
} else {
break;
}
next();
}
}
if (sp > 65535) {
throw new JSONException("scanNumber overflow");
}
if (ch == 'L') {
sp++;
next();
} else if (ch == 'S') {
sp++;
next();
} else if (ch == 'B') {
sp++;
next();
} else if (ch == 'F') {
sp++;
next();
isDouble = true;
} else if (ch == 'D') {
sp++;
next();
isDouble = true;
} else if (ch == 'e' || ch == 'E') {
sp++;
next();
if (ch == '+' || ch == '-') {
sp++;
next();
}
for (;;) {
if (ch >= '0' && ch <= '9') {
sp++;
} else {
break;
}
next();
}
if (ch == 'D' || ch == 'F') {
sp++;
next();
}
isDouble = true;
}
if (isDouble) {
token = JSONToken.LITERAL_FLOAT;
} else {
token = JSONToken.LITERAL_INT;
}
}
public final long longValue() throws NumberFormatException {
long result = 0;
boolean negative = false;
long limit;
int digit;
if (np == -1) {
np = 0;
}
int i = np, max = np + sp;
if (charAt(np) == '-') {
negative = true;
limit = Long.MIN_VALUE;
i++;
} else {
limit = -Long.MAX_VALUE;
}
long multmin = MULTMIN_RADIX_TEN;
if (i < max) {
digit = charAt(i++) - '0';
result = -digit;
}
while (i < max) {
// Accumulating negatively avoids surprises near MAX_VALUE
char chLocal = charAt(i++);
if (chLocal == 'L' || chLocal == 'S' || chLocal == 'B') {
break;
}
digit = chLocal - '0';
if (result < multmin) {
throw new NumberFormatException(numberString());
}
result *= 10;
if (result < limit + digit) {
throw new NumberFormatException(numberString());
}
result -= digit;
}
if (negative) {
if (i > np + 1) {
return result;
} else { /* Only got "-" */
throw new NumberFormatException(numberString());
}
} else {
return -result;
}
}
public final Number decimalValue(boolean decimal) {
char chLocal = charAt(np + sp - 1);
try {
if (chLocal == 'F') {
return Float.parseFloat(numberString());
}
if (chLocal == 'D') {
return Double.parseDouble(numberString());
}
if (decimal) {
return decimalValue();
} else {
return doubleValue();
}
} catch (NumberFormatException ex) {
throw new JSONException(ex.getMessage() + ", " + info());
}
}
public abstract BigDecimal decimalValue();
public static boolean isWhitespace(char ch) {
// 专门调整了判断顺序
return ch <= ' ' &&
(ch == ' ' ||
ch == '\n' ||
ch == '\r' ||
ch == '\t' ||
ch == '\f' ||
ch == '\b');
}
protected static final long MULTMIN_RADIX_TEN = Long.MIN_VALUE / 10;
protected static final int INT_MULTMIN_RADIX_TEN = Integer.MIN_VALUE / 10;
protected final static int[] digits = new int[(int) 'f' + 1];
static {
for (int i = '0'; i <= '9'; ++i) {
digits[i] = i - '0';
}
for (int i = 'a'; i <= 'f'; ++i) {
digits[i] = (i - 'a') + 10;
}
for (int i = 'A'; i <= 'F'; ++i) {
digits[i] = (i - 'A') + 10;
}
}
/**
* hsf support
* @param fieldName
* @param argTypesCount
* @param typeSymbolTable
* @return
*/
public String[] scanFieldStringArray(char[] fieldName, int argTypesCount, SymbolTable typeSymbolTable) {
throw new UnsupportedOperationException();
}
public boolean matchField2(char[] fieldName) {
throw new UnsupportedOperationException();
}
public int getFeatures() {
return this.features;
}
public void setFeatures(int features) {
this.features = features;
}
}