Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 4 additions & 142 deletions gson/src/main/java/com/google/gson/stream/JsonReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.Reader;
import java.util.Arrays;
import java.util.Objects;
import java.util.List;

/**
* Reads a JSON (<a href="http://www.ietf.org/rfc/rfc7159.txt">RFC 7159</a>)
Expand Down Expand Up @@ -229,14 +230,13 @@ public class JsonReader implements Closeable {
/** True to accept non-spec compliant JSON */
private boolean lenient = false;

static final int BUFFER_SIZE = 1024;
/**
* Use a manual buffer to easily read and unread upcoming characters, and
* also so we can create strings without an intermediate StringBuilder.
* We decode literals directly out of this buffer, so it must be at least as
* long as the longest token that can be reported as a number.
*/
private final char[] buffer = new char[BUFFER_SIZE];
private final char[] buffer = new char[1024];
private int pos = 0;
private int limit = 0;

Expand Down Expand Up @@ -288,7 +288,7 @@ public class JsonReader implements Closeable {
* Creates a new instance that reads a JSON-encoded stream from {@code in}.
*/
public JsonReader(Reader in) {
this.in = Objects.requireNonNull(in, "in == null");
this.in = in;
}

/**
Expand Down Expand Up @@ -1567,142 +1567,4 @@ public String getPreviousPath() {
* Returns a <a href="https://goessner.net/articles/JsonPath/">JSONPath</a>
* in <i>dot-notation</i> to the next (or current) location in the JSON document:
* <ul>
* <li>For JSON arrays the path points to the index of the next element (even
* if there are no further elements).</li>
* <li>For JSON objects the path points to the last property, or to the current
* property if its name has already been consumed.</li>
* </ul>
*
* <p>This method can be useful to add additional context to exception messages
* <i>before</i> a value is consumed, for example when the {@linkplain #peek() peeked}
* token is unexpected.
*/
public String getPath() {
return getPath(false);
}

/**
* Unescapes the character identified by the character or characters that
* immediately follow a backslash. The backslash '\' should have already
* been read. This supports both unicode escapes "u000A" and two-character
* escapes "\n".
*
* @throws NumberFormatException if any unicode escape sequences are
* malformed.
*/
@SuppressWarnings("fallthrough")
private char readEscapeCharacter() throws IOException {
if (pos == limit && !fillBuffer(1)) {
throw syntaxError("Unterminated escape sequence");
}

char escaped = buffer[pos++];
switch (escaped) {
case 'u':
if (pos + 4 > limit && !fillBuffer(4)) {
throw syntaxError("Unterminated escape sequence");
}
// Equivalent to Integer.parseInt(stringPool.get(buffer, pos, 4), 16);
int result = 0;
for (int i = pos, end = i + 4; i < end; i++) {
char c = buffer[i];
result <<= 4;
if (c >= '0' && c <= '9') {
result += (c - '0');
} else if (c >= 'a' && c <= 'f') {
result += (c - 'a' + 10);
} else if (c >= 'A' && c <= 'F') {
result += (c - 'A' + 10);
} else {
throw new NumberFormatException("\\u" + new String(buffer, pos, 4));
}
}
pos += 4;
return (char) result;

case 't':
return '\t';

case 'b':
return '\b';

case 'n':
return '\n';

case 'r':
return '\r';

case 'f':
return '\f';

case '\n':
lineNumber++;
lineStart = pos;
// fall-through

case '\'':
case '"':
case '\\':
case '/':
return escaped;
default:
// throw error when none of the above cases are matched
throw syntaxError("Invalid escape sequence");
}
}

/**
* Throws a new IO exception with the given message and a context snippet
* with this reader's content.
*/
private IOException syntaxError(String message) throws IOException {
throw new MalformedJsonException(message + locationString());
}

/**
* Consumes the non-execute prefix if it exists.
*/
private void consumeNonExecutePrefix() throws IOException {
// fast forward through the leading whitespace
nextNonWhitespace(true);
pos--;

if (pos + 5 > limit && !fillBuffer(5)) {
return;
}

int p = pos;
char[] buf = buffer;
if(buf[p] != ')' || buf[p + 1] != ']' || buf[p + 2] != '}' || buf[p + 3] != '\'' || buf[p + 4] != '\n') {
return; // not a security token!
}

// we consumed a security token!
pos += 5;
}

static {
JsonReaderInternalAccess.INSTANCE = new JsonReaderInternalAccess() {
@Override public void promoteNameToValue(JsonReader reader) throws IOException {
if (reader instanceof JsonTreeReader) {
((JsonTreeReader)reader).promoteNameToValue();
return;
}
int p = reader.peeked;
if (p == PEEKED_NONE) {
p = reader.doPeek();
}
if (p == PEEKED_DOUBLE_QUOTED_NAME) {
reader.peeked = PEEKED_DOUBLE_QUOTED;
} else if (p == PEEKED_SINGLE_QUOTED_NAME) {
reader.peeked = PEEKED_SINGLE_QUOTED;
} else if (p == PEEKED_UNQUOTED_NAME) {
reader.peeked = PEEKED_UNQUOTED;
} else {
throw new IllegalStateException(
"Expected a name but was " + reader.peek() + reader.locationString());
}
}
};
}
}
*