try {
int firstIntRead = skipWhitespace();
if (firstIntRead == -1) return null;
char firstChar = (char) firstIntRead;
JsonTokenType possibleTokenType = startingWith((char) firstIntRead);
if (possibleTokenType == null) {
throw new JsonException(
"Lexing failed on line: " + reader.getLine() + ", column: " + reader.getColumn() +
", while reading '" + firstChar + "', " +
"no possible valid JSON value or punctuation could be recognized."
);
}
reader.reset();
long startLine = reader.getLine();
long startColumn = reader.getColumn();
JsonToken token = new JsonToken();
token.setStartLine(startLine);
token.setStartColumn(startColumn);
token.setEndLine(startLine);
token.setEndColumn(startColumn + 1);
token.setType(possibleTokenType);
token.setText("" + firstChar);
if (possibleTokenType.ordinal() >= OPEN_CURLY.ordinal() && possibleTokenType.ordinal() <= FALSE.ordinal()) {
return readingConstant(possibleTokenType, token);
} else if (possibleTokenType == STRING) {
StringBuilder currentContent = new StringBuilder("\"");
// consume the first double quote starting the string
reader.read();
boolean isEscaped = false;
for (;;) {
int read = reader.read();
if (read == -1) return null;
isEscaped = (!isEscaped && currentContent.charAt(currentContent.length() - 1) == '\\');
char charRead = (char) read;
currentContent.append(charRead);
if (charRead == '"' && !isEscaped &&
possibleTokenType.matching(currentContent.toString())) {
token.setEndLine(reader.getLine());
token.setEndColumn(reader.getColumn());
token.setText(unescape(currentContent.toString()));
return token;
}
}
} else if (possibleTokenType == NUMBER) {
StringBuilder currentContent = new StringBuilder();
for (;;) {
reader.mark(1);
int read = reader.read();
if (read == -1) return null;
char lastCharRead = (char) read;
if (lastCharRead >= ZERO && lastCharRead <= NINE ||
lastCharRead == DOT || lastCharRead == MINUS || lastCharRead == PLUS ||
lastCharRead == LOWER_E || lastCharRead == UPPER_E) {
currentContent.append(lastCharRead);
} else {
reader.reset();
break;
}
}
String content = currentContent.toString();
if (possibleTokenType.matching(content)) {
token.setEndLine(reader.getLine());
token.setEndColumn(reader.getColumn());
token.setText(currentContent.toString());
return token;