diff --git a/moshi/src/main/java/com/squareup/moshi/BufferedSourceJsonReader.java b/moshi/src/main/java/com/squareup/moshi/BufferedSourceJsonReader.java index 8f7d5a9..327c06b 100644 --- a/moshi/src/main/java/com/squareup/moshi/BufferedSourceJsonReader.java +++ b/moshi/src/main/java/com/squareup/moshi/BufferedSourceJsonReader.java @@ -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); diff --git a/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java b/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java index 3af3031..7947e9f 100644 --- a/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java +++ b/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java @@ -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 extends JsonAdapter { // Create the binding between field and JSON. field.setAccessible(true); - FieldBinding 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 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 extends JsonAdapter { }; private final ClassFactory classFactory; - private final Map> jsonFields; + private final Map> fieldsMap; + private final FieldBinding[] fieldsArray; - ClassJsonAdapter(ClassFactory classFactory, Map> jsonFields) { + ClassJsonAdapter(ClassFactory classFactory, Map> 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 extends JsonAdapter { 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 extends JsonAdapter { @Override public void toJson(JsonWriter writer, T value) throws IOException { try { writer.beginObject(); - for (Map.Entry> 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 extends JsonAdapter { } static class FieldBinding { - private final Field field; - private final JsonAdapter adapter; + final String name; + final Field field; + final JsonAdapter adapter; - public FieldBinding(Field field, JsonAdapter adapter) { + public FieldBinding(String name, Field field, JsonAdapter adapter) { + this.name = name; this.field = field; this.adapter = adapter; }