mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 07:59: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.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
||||
@@ -182,12 +180,12 @@ final class RuntimeJsonAdapterFactory<T> implements JsonAdapter.Factory {
|
||||
+ ". Register this subtype.");
|
||||
}
|
||||
JsonAdapter<Object> adapter = jsonAdapters.get(labelIndex);
|
||||
Map<String, Object> jsonValue = (Map<String, Object>) adapter.toJsonValue(value);
|
||||
|
||||
Map<String, Object> valueWithLabel = new LinkedHashMap<>(1 + jsonValue.size());
|
||||
valueWithLabel.put(labelKey, labels.get(labelIndex));
|
||||
valueWithLabel.putAll(jsonValue);
|
||||
objectJsonAdapter.toJson(writer, valueWithLabel);
|
||||
writer.beginObject();
|
||||
writer.name(labelKey).value(labels.get(labelIndex));
|
||||
int flattenToken = writer.beginFlatten();
|
||||
adapter.toJson(writer, value);
|
||||
writer.endFlatten(flattenToken);
|
||||
writer.endObject();
|
||||
}
|
||||
|
||||
@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 {
|
||||
}
|
||||
|
||||
@@ -226,4 +244,12 @@ public final class RuntimeJsonAdapterFactoryTest {
|
||||
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