Skip to content

Commit bfd25b0

Browse files
committed
use direct encoder class access if possible
1 parent 77489e4 commit bfd25b0

5 files changed

Lines changed: 117 additions & 22 deletions

File tree

src/main/java/com/jsoniter/output/CodegenImplArray.java

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

3-
import java.lang.reflect.ParameterizedType;
43
import java.lang.reflect.Type;
54
import java.util.*;
65

@@ -18,12 +17,14 @@ public static String genArray(Class clazz) {
1817
append(lines, "if (arr.length == 0) { stream.writeEmptyArray(); return; }");
1918
append(lines, "stream.startArray();");
2019
append(lines, "for (int i = 0; i < arr.length; i++) {");
21-
append(lines, "stream.writeVal(({{comp}})arr[i]);");
20+
append(lines, "{{op}}");
2221
append(lines, "stream.writeMore();");
2322
append(lines, "}");
2423
append(lines, "stream.endArray();");
2524
append(lines, "}");
26-
return lines.toString().replace("{{comp}}", compType.getCanonicalName());
25+
return lines.toString()
26+
.replace("{{comp}}", compType.getCanonicalName())
27+
.replace("{{op}}", CodegenImplNative.genWriteOp("arr[i]", compType));
2728
}
2829

2930
private static void append(StringBuilder lines, String str) {
@@ -57,27 +58,17 @@ private static String genCollection(Class clazz, Type compType) {
5758
append(lines, "java.util.Iterator iter = ((java.util.Collection)obj).iterator();");
5859
append(lines, "if (!iter.hasNext()) { stream.writeEmptyArray(); return; }");
5960
append(lines, "stream.startArray();");
60-
append(lines, "stream.writeVal(({{comp}})iter.next());");
61+
append(lines, "{{op}}");
6162
append(lines, "stream.writeMore();");
6263
append(lines, "while (iter.hasNext()) {");
63-
append(lines, "stream.writeVal(({{comp}})iter.next());");
64+
append(lines, "{{op}}");
6465
append(lines, "stream.writeMore();");
6566
append(lines, "}");
6667
append(lines, "stream.endArray();");
6768
append(lines, "}");
68-
return lines.toString().replace("{{comp}}", getTypeName(compType));
69+
return lines.toString()
70+
.replace("{{comp}}", CodegenImplNative.getTypeName(compType))
71+
.replace("{{op}}", CodegenImplNative.genWriteOp("iter.next()", compType));
6972
}
7073

71-
private static String getTypeName(Type fieldType) {
72-
if (fieldType instanceof Class) {
73-
Class clazz = (Class) fieldType;
74-
return clazz.getCanonicalName();
75-
} else if (fieldType instanceof ParameterizedType) {
76-
ParameterizedType pType = (ParameterizedType) fieldType;
77-
Class clazz = (Class) pType.getRawType();
78-
return clazz.getCanonicalName();
79-
} else {
80-
throw new RuntimeException("unsupported type: " + fieldType);
81-
}
82-
}
8374
}

src/main/java/com/jsoniter/output/CodegenImplMap.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,19 @@ public static String genMap(Class clazz, Type[] typeArgs) {
3333
append(lines, "java.util.Map.Entry entry = iter.next();");
3434
append(lines, "stream.startObject();");
3535
append(lines, "stream.writeField((String)entry.getKey());");
36-
append(lines, "stream.writeVal(entry.getValue());");
36+
append(lines, "{{op}}");
3737
append(lines, "stream.writeMore();");
3838
append(lines, "while(iter.hasNext()) {");
3939
append(lines, "entry = iter.next();");
4040
append(lines, "stream.writeField((String)entry.getKey());");
41-
append(lines, "stream.writeVal(entry.getValue());");
41+
append(lines, "{{op}}");
4242
append(lines, "stream.writeMore();");
4343
append(lines, "}");
4444
append(lines, "stream.endObject();");
4545
append(lines, "}");
46-
return lines.toString().replace("{{clazz}}", clazz.getName());
46+
return lines.toString()
47+
.replace("{{clazz}}", clazz.getName())
48+
.replace("{{op}}", CodegenImplNative.genWriteOp("entry.getValue()", valueType));
4749
}
4850

4951
private static void append(StringBuilder lines, String str) {

src/main/java/com/jsoniter/output/CodegenImplNative.java

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

3+
import com.jsoniter.TypeLiteral;
4+
35
import java.io.IOException;
6+
import java.lang.reflect.ParameterizedType;
47
import java.lang.reflect.Type;
58
import java.util.IdentityHashMap;
69
import java.util.Map;
@@ -14,4 +17,28 @@ public void encode(Object obj, JsonStream stream) throws IOException {
1417
}
1518
});
1619
}};
20+
21+
public static String genWriteOp(String code, Type valueType) {
22+
if (NATIVE_ENCODERS.containsKey(valueType)) {
23+
return String.format("stream.writeVal((%s)%s);", getTypeName(valueType), code);
24+
}
25+
26+
String cacheKey = TypeLiteral.generateEncoderCacheKey(valueType);
27+
Codegen.getEncoder(cacheKey, valueType);
28+
// Encoder encoder = Codegen.cache.get(cacheKey);
29+
return String.format("%s.encode_(%s, stream);", cacheKey, code);
30+
}
31+
32+
public static String getTypeName(Type fieldType) {
33+
if (fieldType instanceof Class) {
34+
Class clazz = (Class) fieldType;
35+
return clazz.getCanonicalName();
36+
} else if (fieldType instanceof ParameterizedType) {
37+
ParameterizedType pType = (ParameterizedType) fieldType;
38+
Class clazz = (Class) pType.getRawType();
39+
return clazz.getCanonicalName();
40+
} else {
41+
throw new RuntimeException("unsupported type: " + fieldType);
42+
}
43+
}
1744
}

src/main/java/com/jsoniter/output/CodegenImplObject.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public static String genObject(Class clazz) {
2121
for (Binding field : allBindings) {
2222
for (String fromName : field.fromNames) {
2323
append(lines, String.format("stream.writeField(\"%s\");", field.name));
24-
append(lines, String.format("stream.writeVal(obj.%s);", fromName));
24+
append(lines, CodegenImplNative.genWriteOp("obj." + fromName, field.valueType));
2525
append(lines, "stream.writeMore();");
2626
}
2727
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.jsoniter.output;
2+
3+
import com.jsoniter.TypeLiteral;
4+
import junit.framework.TestCase;
5+
6+
import java.io.ByteArrayOutputStream;
7+
import java.io.IOException;
8+
import java.util.ArrayList;
9+
import java.util.HashMap;
10+
import java.util.List;
11+
import java.util.Map;
12+
13+
public class TestNested extends TestCase {
14+
15+
private ByteArrayOutputStream baos;
16+
private JsonStream stream;
17+
18+
public void setUp() {
19+
baos = new ByteArrayOutputStream();
20+
stream = new JsonStream(baos, 4096);
21+
}
22+
23+
public static class TestObject1 {
24+
public String field1;
25+
public String field2;
26+
}
27+
28+
public void test_array_of_objects() throws IOException {
29+
TestObject1 obj1 = new TestObject1();
30+
obj1.field1 = "1";
31+
obj1.field2 = "2";
32+
stream.writeVal(new TestObject1[]{obj1});
33+
stream.close();
34+
assertEquals("[{'field1':'1','field2':'2'}]".replace('\'', '"'), baos.toString());
35+
}
36+
37+
public void test_collection_of_objects() throws IOException {
38+
final TestObject1 obj1 = new TestObject1();
39+
obj1.field1 = "1";
40+
obj1.field2 = "2";
41+
stream.writeVal(new TypeLiteral<List<TestObject1>>() {
42+
}, new ArrayList() {{
43+
add(obj1);
44+
}});
45+
stream.close();
46+
assertEquals("[{'field1':'1','field2':'2'}]".replace('\'', '"'), baos.toString());
47+
}
48+
49+
public static class TestObject2 {
50+
public TestObject1[] objs;
51+
}
52+
53+
public void test_object_of_array() throws IOException {
54+
TestObject2 obj = new TestObject2();
55+
obj.objs = new TestObject1[1];
56+
obj.objs[0] = new TestObject1();
57+
obj.objs[0].field1 = "1";
58+
obj.objs[0].field2 = "2";
59+
stream.writeVal(obj);
60+
stream.close();
61+
assertEquals("{'objs':[{'field1':'1','field2':'2'}]}".replace('\'', '"'), baos.toString());
62+
}
63+
64+
public void test_map_of_objects() throws IOException {
65+
final TestObject1 obj1 = new TestObject1();
66+
obj1.field1 = "1";
67+
obj1.field2 = "2";
68+
stream.writeVal(new TypeLiteral<Map<String, TestObject1>>() {
69+
}, new HashMap() {{
70+
put("hello", obj1);
71+
}});
72+
stream.close();
73+
assertEquals("{'hello':{'field1':'1','field2':'2'}}".replace('\'', '"'), baos.toString());
74+
}
75+
}

0 commit comments

Comments
 (0)