mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 16:09:21 +08:00
Don't decode into memory in RuntimeJsonAdapterFactory
Instead use our new flatten API to decode directly to the stream.
This commit is contained in:
@@ -26,9 +26,7 @@ import java.lang.annotation.Annotation;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.annotation.CheckReturnValue;
|
import javax.annotation.CheckReturnValue;
|
||||||
|
|
||||||
@@ -182,12 +180,12 @@ final class RuntimeJsonAdapterFactory<T> implements JsonAdapter.Factory {
|
|||||||
+ ". Register this subtype.");
|
+ ". Register this subtype.");
|
||||||
}
|
}
|
||||||
JsonAdapter<Object> adapter = jsonAdapters.get(labelIndex);
|
JsonAdapter<Object> adapter = jsonAdapters.get(labelIndex);
|
||||||
Map<String, Object> jsonValue = (Map<String, Object>) adapter.toJsonValue(value);
|
writer.beginObject();
|
||||||
|
writer.name(labelKey).value(labels.get(labelIndex));
|
||||||
Map<String, Object> valueWithLabel = new LinkedHashMap<>(1 + jsonValue.size());
|
int flattenToken = writer.beginFlatten();
|
||||||
valueWithLabel.put(labelKey, labels.get(labelIndex));
|
adapter.toJson(writer, value);
|
||||||
valueWithLabel.putAll(jsonValue);
|
writer.endFlatten(flattenToken);
|
||||||
objectJsonAdapter.toJson(writer, valueWithLabel);
|
writer.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String toString() {
|
@Override public String toString() {
|
||||||
|
@@ -180,6 +180,24 @@ public final class RuntimeJsonAdapterFactoryTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Longs that do not have an exact double representation are problematic for JSON. It is a bad
|
||||||
|
* idea to use JSON for these values! But Moshi tries to retain long precision where possible.
|
||||||
|
*/
|
||||||
|
@Test public void unportableTypes() throws IOException {
|
||||||
|
Moshi moshi = new Moshi.Builder()
|
||||||
|
.add(RuntimeJsonAdapterFactory.of(Message.class, "type")
|
||||||
|
.withSubtype(MessageWithUnportableTypes.class, "unportable"))
|
||||||
|
.build();
|
||||||
|
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||||
|
|
||||||
|
assertThat(adapter.toJson(new MessageWithUnportableTypes(9007199254740993L)))
|
||||||
|
.isEqualTo("{\"type\":\"unportable\",\"long_value\":9007199254740993}");
|
||||||
|
MessageWithUnportableTypes decoded = (MessageWithUnportableTypes) adapter.fromJson(
|
||||||
|
"{\"type\":\"unportable\",\"long_value\":9007199254740993}");
|
||||||
|
assertThat(decoded.long_value).isEqualTo(9007199254740993L);
|
||||||
|
}
|
||||||
|
|
||||||
interface Message {
|
interface Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,4 +244,12 @@ public final class RuntimeJsonAdapterFactoryTest {
|
|||||||
return "EmptyMessage";
|
return "EmptyMessage";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final class MessageWithUnportableTypes implements Message {
|
||||||
|
final long long_value;
|
||||||
|
|
||||||
|
MessageWithUnportableTypes(long long_value) {
|
||||||
|
this.long_value = long_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user