mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 07:59:21 +08:00
Add JsonReader.readJsonValue
This commit is contained in:
@@ -17,6 +17,9 @@ package com.squareup.moshi;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
@@ -390,6 +393,57 @@ public abstract class JsonReader implements Closeable {
|
||||
*/
|
||||
public abstract void skipValue() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the value of the next token, consuming it. The result may be a string, number, boolean,
|
||||
* null, map, or list, according to the JSON structure.
|
||||
*
|
||||
* @throws JsonDataException if the next token is not a literal value, if a JSON object has a
|
||||
* duplicate key.
|
||||
*/
|
||||
public final Object readJsonValue() throws IOException {
|
||||
switch (peek()) {
|
||||
case BEGIN_ARRAY:
|
||||
List<Object> list = new ArrayList<>();
|
||||
beginArray();
|
||||
while (hasNext()) {
|
||||
list.add(readJsonValue());
|
||||
}
|
||||
endArray();
|
||||
return list;
|
||||
|
||||
case BEGIN_OBJECT:
|
||||
Map<String, Object> map = new LinkedHashTreeMap<>();
|
||||
beginObject();
|
||||
while (hasNext()) {
|
||||
String name = nextName();
|
||||
Object value = readJsonValue();
|
||||
Object replaced = map.put(name, value);
|
||||
if (replaced != null) {
|
||||
throw new JsonDataException("Map key '" + name + "' has multiple values at path "
|
||||
+ getPath() + ": " + replaced + " and " + value);
|
||||
}
|
||||
}
|
||||
endObject();
|
||||
return map;
|
||||
|
||||
case STRING:
|
||||
return nextString();
|
||||
|
||||
case NUMBER:
|
||||
return nextDouble();
|
||||
|
||||
case BOOLEAN:
|
||||
return nextBoolean();
|
||||
|
||||
case NULL:
|
||||
return nextNull();
|
||||
|
||||
default:
|
||||
throw new IllegalStateException(
|
||||
"Expected a value but was " + peek() + " at path " + getPath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <a href="http://goessner.net/articles/JsonPath/">JsonPath</a> to
|
||||
* the current location in the JSON value.
|
||||
|
@@ -18,11 +18,8 @@ package com.squareup.moshi;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -272,47 +269,7 @@ final class StandardJsonAdapters {
|
||||
}
|
||||
|
||||
@Override public Object fromJson(JsonReader reader) throws IOException {
|
||||
switch (reader.peek()) {
|
||||
case BEGIN_ARRAY:
|
||||
List<Object> list = new ArrayList<>();
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
list.add(fromJson(reader));
|
||||
}
|
||||
reader.endArray();
|
||||
return list;
|
||||
|
||||
case BEGIN_OBJECT:
|
||||
Map<String, Object> map = new LinkedHashTreeMap<>();
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String name = reader.nextName();
|
||||
Object value = fromJson(reader);
|
||||
Object replaced = map.put(name, value);
|
||||
if (replaced != null) {
|
||||
throw new JsonDataException("Map key '" + name + "' has multiple values at path "
|
||||
+ reader.getPath() + ": " + replaced + " and " + value);
|
||||
}
|
||||
}
|
||||
reader.endObject();
|
||||
return map;
|
||||
|
||||
case STRING:
|
||||
return reader.nextString();
|
||||
|
||||
case NUMBER:
|
||||
return reader.nextDouble();
|
||||
|
||||
case BOOLEAN:
|
||||
return reader.nextBoolean();
|
||||
|
||||
case NULL:
|
||||
return reader.nextNull();
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("Expected a value but was " + reader.peek()
|
||||
+ " at path " + reader.getPath());
|
||||
}
|
||||
return reader.readJsonValue();
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
|
@@ -17,6 +17,8 @@ package com.squareup.moshi;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -912,4 +914,35 @@ public final class JsonReaderTest {
|
||||
assertThat(reader.nextString()).isEqualTo("a");
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void readJsonValueInt() throws IOException {
|
||||
JsonReader reader = newReader("1");
|
||||
Object value = reader.readJsonValue();
|
||||
assertThat(value).isEqualTo(1.0);
|
||||
}
|
||||
|
||||
@Test public void readJsonValueMap() throws IOException {
|
||||
JsonReader reader = newReader("{\"hello\": \"world\"}");
|
||||
Object value = reader.readJsonValue();
|
||||
assertThat(value).isEqualTo(Collections.singletonMap("hello", "world"));
|
||||
}
|
||||
|
||||
@Test public void readJsonValueList() throws IOException {
|
||||
JsonReader reader = newReader("[\"a\", \"b\"]");
|
||||
Object value = reader.readJsonValue();
|
||||
assertThat(value).isEqualTo(Arrays.asList("a", "b"));
|
||||
}
|
||||
|
||||
@Test public void readJsonValueListMultipleTypes() throws IOException {
|
||||
JsonReader reader = newReader("[\"a\", 5, false]");
|
||||
Object value = reader.readJsonValue();
|
||||
assertThat(value).isEqualTo(Arrays.asList("a", 5.0, false));
|
||||
}
|
||||
|
||||
@Test public void readJsonValueNestedListInMap() throws IOException {
|
||||
JsonReader reader = newReader("{\"pizzas\": [\"cheese\", \"pepperoni\"]}");
|
||||
Object value = reader.readJsonValue();
|
||||
assertThat(value).isEqualTo(
|
||||
Collections.singletonMap("pizzas", Arrays.asList("cheese", "pepperoni")));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user