Skip to content

Commit d2d7255

Browse files
committed
support read object
1 parent 8c72678 commit d2d7255

File tree

3 files changed

+61
-28
lines changed

3 files changed

+61
-28
lines changed

src/main/java/com/github/jsoniter/Codegen.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Codegen {
2727
put(Integer.class.getName(), "Integer.valueOf(iter.readInt())");
2828
put(Long.class.getName(), "Long.valueOf(iter.readLong())");
2929
put(String.class.getName(), "iter.readString()");
30+
put(Object.class.getName(), "iter.read()");
3031
}};
3132
final static Set<Class> WITH_CAPACITY_COLLECTION_CLASSES = new HashSet<Class>() {{
3233
add(ArrayList.class);
@@ -74,31 +75,40 @@ private synchronized static Decoder gen(String cacheKey, Type type, Type[] typeA
7475
}
7576

7677
private static String genSource(String cacheKey, Class clazz, Type[] typeArgs) {
77-
if (Object.class == clazz) {
78-
throw new IllegalArgumentException("can not bind to Object.class, parser need schema");
79-
}
8078
if (NATIVE_READS.containsKey(clazz.getName())) {
8179
return genNative(clazz);
8280
}
8381
if (clazz.isArray()) {
8482
return genArray(clazz);
8583
}
8684
if (Map.class.isAssignableFrom(clazz)) {
87-
if (typeArgs.length != 2) {
85+
Type keyType = String.class;
86+
Type valueType = Object.class;
87+
if (typeArgs.length == 0) {
88+
// default to Map<String, Object>
89+
} else if (typeArgs.length == 2) {
90+
keyType = typeArgs[0];
91+
valueType = typeArgs[1];
92+
} else {
8893
throw new IllegalArgumentException(
8994
"can not bind to generic collection without argument types, " +
9095
"try syntax like TypeLiteral<Map<String, String>>{}");
9196
}
92-
if (typeArgs[0] != String.class) {
97+
if (keyType != String.class) {
9398
throw new IllegalArgumentException("map key must be String");
9499
}
95100
if (clazz == Map.class) {
96101
clazz = HashMap.class;
97102
}
98-
return genMap(clazz, typeArgs[1]);
103+
return genMap(clazz, valueType);
99104
}
100105
if (Collection.class.isAssignableFrom(clazz)) {
101-
if (typeArgs.length != 1) {
106+
Type compType = Object.class;
107+
if (typeArgs.length == 0) {
108+
// default to List<Object>
109+
} else if (typeArgs.length == 1) {
110+
compType = typeArgs[0];
111+
} else {
102112
throw new IllegalArgumentException(
103113
"can not bind to generic collection without argument types, " +
104114
"try syntax like TypeLiteral<List<Integer>>{}");
@@ -109,9 +119,9 @@ private static String genSource(String cacheKey, Class clazz, Type[] typeArgs) {
109119
clazz = HashSet.class;
110120
}
111121
if (WITH_CAPACITY_COLLECTION_CLASSES.contains(clazz)) {
112-
return genCollectionWithCapacity(clazz, typeArgs[0]);
122+
return genCollectionWithCapacity(clazz, compType);
113123
} else {
114-
return genCollection(clazz, typeArgs[0]);
124+
return genCollection(clazz, compType);
115125
}
116126
}
117127
return genObject(clazz, cacheKey);

src/main/java/com/github/jsoniter/Jsoniter.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
import java.io.IOException;
77
import java.io.InputStream;
88
import java.lang.reflect.Type;
9+
import java.util.ArrayList;
910
import java.util.Date;
11+
import java.util.HashMap;
12+
import java.util.Map;
1013

1114
public class Jsoniter implements Closeable {
1215

@@ -663,6 +666,34 @@ public final double readDouble() throws IOException {
663666
return Double.valueOf(readNumber());
664667
}
665668

669+
public final Object read() throws IOException {
670+
ValueType valueType = whatIsNext();
671+
switch (valueType) {
672+
case STRING:
673+
return readString();
674+
case NUMBER:
675+
return readDouble();
676+
case NULL:
677+
return null;
678+
case BOOLEAN:
679+
return readBoolean();
680+
case ARRAY:
681+
ArrayList list = new ArrayList();
682+
while (readArray()) {
683+
list.add(read());
684+
}
685+
return list;
686+
case OBJECT:
687+
Map map = new HashMap();
688+
for (String field = readObject(); field != null; field = readObject()) {
689+
map.put(field, readObject());
690+
}
691+
return map;
692+
default:
693+
throw reportError("read", "unexpected value type: " + valueType);
694+
}
695+
}
696+
666697
public final <T> T read(Class<T> clazz) throws IOException {
667698
return (T) Codegen.getDecoder(TypeLiteral.generateCacheKey(clazz), clazz).decode(clazz, this);
668699
}
@@ -897,11 +928,11 @@ public static void registerTypeDecoder(TypeLiteral typeLiteral, Decoder decoder)
897928
}
898929

899930
public static void registerFieldDecoder(Class clazz, String field, Decoder decoder) {
900-
Codegen.addNewDecoder(field+"@"+TypeLiteral.generateCacheKey(clazz), decoder);
931+
Codegen.addNewDecoder(field + "@" + TypeLiteral.generateCacheKey(clazz), decoder);
901932
}
902933

903934
public static void registerFieldDecoder(TypeLiteral typeLiteral, String field, Decoder decoder) {
904-
Codegen.addNewDecoder(field+"@"+typeLiteral.cacheKey, decoder);
935+
Codegen.addNewDecoder(field + "@" + typeLiteral.cacheKey, decoder);
905936
}
906937

907938
public static void clearDecoders() {

test/main/java/com/github/jsoniter/TestReflection.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.jsoniter;
22

33
import junit.framework.TestCase;
4+
import org.junit.Assert;
45

56
import java.io.IOException;
67
import java.util.*;
@@ -15,24 +16,9 @@ public void test_string() throws IOException {
1516
assertEquals("hello", val);
1617
}
1718

18-
public void test_object() throws IOException {
19-
Jsoniter iter = Jsoniter.parse("'hello'".replace('\'', '"'));
20-
try {
21-
iter.read(Object.class);
22-
} catch (IllegalArgumentException e) {
23-
return;
24-
}
25-
fail();
26-
}
27-
2819
public void test_no_arg_list() throws IOException {
29-
Jsoniter iter = Jsoniter.parse("'hello'".replace('\'', '"'));
30-
try {
31-
iter.read(List.class);
32-
} catch (IllegalArgumentException e) {
33-
return;
34-
}
35-
fail();
20+
Jsoniter iter = Jsoniter.parse("['hello']".replace('\'', '"'));
21+
Assert.assertArrayEquals(new String[]{"hello"}, iter.read(List.class).toArray(new String[0]));
3622
}
3723

3824
public void test_boolean_array() throws IOException {
@@ -105,4 +91,10 @@ public void test_fields_skipped() throws IOException {
10591
ComplexObject val = iter.read(ComplexObject.class);
10692
assertEquals(100, val.field1);
10793
}
94+
95+
public void test_read_object() throws IOException {
96+
Jsoniter iter = Jsoniter.parse("'hello'".replace('\'', '"'));
97+
String val = (String) iter.read(Object.class);
98+
assertEquals("hello", val);
99+
}
108100
}

0 commit comments

Comments
 (0)