Merge pull request #147 from square/jwilson_0406_small_optimizations
Small optimizations to JSON parsing.
This commit is contained in:
commit
40e323c805
2 changed files with 25 additions and 29 deletions
|
@ -304,7 +304,7 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
break;
|
||||
case '=':
|
||||
checkLenient();
|
||||
if (fillBuffer(1) && buffer.getByte(0) == '>') {
|
||||
if (source.request(1) && buffer.getByte(0) == '>') {
|
||||
buffer.readByte(); // Consume '>'.
|
||||
}
|
||||
break;
|
||||
|
@ -400,7 +400,7 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
// Confirm that chars [1..length) match the keyword.
|
||||
int length = keyword.length();
|
||||
for (int i = 1; i < length; i++) {
|
||||
if (!fillBuffer(i + 1)) {
|
||||
if (!source.request(i + 1)) {
|
||||
return PEEKED_NONE;
|
||||
}
|
||||
c = buffer.getByte(i);
|
||||
|
@ -409,7 +409,7 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
}
|
||||
}
|
||||
|
||||
if (fillBuffer(length + 1) && isLiteral(buffer.getByte(length))) {
|
||||
if (source.request(length + 1) && isLiteral(buffer.getByte(length))) {
|
||||
return PEEKED_NONE; // Don't match trues, falsey or nullsoft!
|
||||
}
|
||||
|
||||
|
@ -428,7 +428,7 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
|
||||
charactersOfNumber:
|
||||
for (; true; i++) {
|
||||
if (!fillBuffer(i + 1)) {
|
||||
if (!source.request(i + 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -880,15 +880,6 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
stack[stackSize++] = newTop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true once {@code limit - pos >= minimum}. If the data is
|
||||
* exhausted before that many characters are available, this returns
|
||||
* false.
|
||||
*/
|
||||
private boolean fillBuffer(int minimum) throws IOException {
|
||||
return source.request(minimum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next character in the stream that is neither whitespace nor a
|
||||
* part of a comment. When this returns, the returned character is always at
|
||||
|
@ -905,7 +896,7 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
* 'p' and 'l' after any (potentially indirect) call to the same method.
|
||||
*/
|
||||
int p = 0;
|
||||
while (fillBuffer(p + 1)) {
|
||||
while (source.request(p + 1)) {
|
||||
int c = buffer.getByte(p++);
|
||||
if (c == '\n' || c == ' ' || c == '\r' || c == '\t') {
|
||||
continue;
|
||||
|
@ -913,7 +904,7 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
|
||||
buffer.skip(p - 1);
|
||||
if (c == '/') {
|
||||
if (!fillBuffer(2)) {
|
||||
if (!source.request(2)) {
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -981,7 +972,7 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
*/
|
||||
private boolean skipTo(String toFind) throws IOException {
|
||||
outer:
|
||||
for (; fillBuffer(toFind.length());) {
|
||||
for (; source.request(toFind.length());) {
|
||||
for (int c = 0; c < toFind.length(); c++) {
|
||||
if (buffer.getByte(c) != toFind.charAt(c)) {
|
||||
buffer.readByte();
|
||||
|
@ -1009,14 +1000,14 @@ final class BufferedSourceJsonReader extends JsonReader {
|
|||
* @throws IOException if any unicode escape sequences are malformed.
|
||||
*/
|
||||
private char readEscapeCharacter() throws IOException {
|
||||
if (!fillBuffer(1)) {
|
||||
if (!source.request(1)) {
|
||||
throw syntaxError("Unterminated escape sequence");
|
||||
}
|
||||
|
||||
byte escaped = buffer.readByte();
|
||||
switch (escaped) {
|
||||
case 'u':
|
||||
if (!fillBuffer(4)) {
|
||||
if (!source.request(4)) {
|
||||
throw new EOFException("Unterminated escape sequence at path " + getPath());
|
||||
}
|
||||
// Equivalent to Integer.parseInt(stringPool.get(buffer, pos, 4), 16);
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.lang.reflect.Field;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
@ -81,11 +82,11 @@ final class ClassJsonAdapter<T> extends JsonAdapter<T> {
|
|||
|
||||
// Create the binding between field and JSON.
|
||||
field.setAccessible(true);
|
||||
FieldBinding<Object> fieldBinding = new FieldBinding<>(field, adapter);
|
||||
|
||||
// Store it using the field's name. If there was already a field with this name, fail!
|
||||
Json jsonAnnotation = field.getAnnotation(Json.class);
|
||||
String name = jsonAnnotation != null ? jsonAnnotation.name() : field.getName();
|
||||
FieldBinding<Object> fieldBinding = new FieldBinding<>(name, field, adapter);
|
||||
FieldBinding<?> replaced = fieldBindings.put(name, fieldBinding);
|
||||
if (replaced != null) {
|
||||
throw new IllegalArgumentException("Conflicting fields:\n"
|
||||
|
@ -113,11 +114,13 @@ final class ClassJsonAdapter<T> extends JsonAdapter<T> {
|
|||
};
|
||||
|
||||
private final ClassFactory<T> classFactory;
|
||||
private final Map<String, FieldBinding<?>> jsonFields;
|
||||
private final Map<String, FieldBinding<?>> fieldsMap;
|
||||
private final FieldBinding<?>[] fieldsArray;
|
||||
|
||||
ClassJsonAdapter(ClassFactory<T> classFactory, Map<String, FieldBinding<?>> jsonFields) {
|
||||
ClassJsonAdapter(ClassFactory<T> classFactory, Map<String, FieldBinding<?>> fieldsMap) {
|
||||
this.classFactory = classFactory;
|
||||
this.jsonFields = jsonFields;
|
||||
this.fieldsMap = new LinkedHashMap<>(fieldsMap);
|
||||
this.fieldsArray = fieldsMap.values().toArray(new FieldBinding[fieldsMap.size()]);
|
||||
}
|
||||
|
||||
@Override public T fromJson(JsonReader reader) throws IOException {
|
||||
|
@ -139,7 +142,7 @@ final class ClassJsonAdapter<T> extends JsonAdapter<T> {
|
|||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String name = reader.nextName();
|
||||
FieldBinding<?> fieldBinding = jsonFields.get(name);
|
||||
FieldBinding<?> fieldBinding = fieldsMap.get(name);
|
||||
if (fieldBinding != null) {
|
||||
fieldBinding.read(reader, result);
|
||||
} else {
|
||||
|
@ -156,9 +159,9 @@ final class ClassJsonAdapter<T> extends JsonAdapter<T> {
|
|||
@Override public void toJson(JsonWriter writer, T value) throws IOException {
|
||||
try {
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, FieldBinding<?>> entry : jsonFields.entrySet()) {
|
||||
writer.name(entry.getKey());
|
||||
entry.getValue().write(writer, value);
|
||||
for (FieldBinding<?> fieldBinding : fieldsArray) {
|
||||
writer.name(fieldBinding.name);
|
||||
fieldBinding.write(writer, value);
|
||||
}
|
||||
writer.endObject();
|
||||
} catch (IllegalAccessException e) {
|
||||
|
@ -171,10 +174,12 @@ final class ClassJsonAdapter<T> extends JsonAdapter<T> {
|
|||
}
|
||||
|
||||
static class FieldBinding<T> {
|
||||
private final Field field;
|
||||
private final JsonAdapter<T> adapter;
|
||||
final String name;
|
||||
final Field field;
|
||||
final JsonAdapter<T> adapter;
|
||||
|
||||
public FieldBinding(Field field, JsonAdapter<T> adapter) {
|
||||
public FieldBinding(String name, Field field, JsonAdapter<T> adapter) {
|
||||
this.name = name;
|
||||
this.field = field;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue