Skip to content

Commit 8326d11

Browse files
committed
#62 support map with non-string key
1 parent 059da6a commit 8326d11

25 files changed

+186
-28
lines changed

demo/src/test/java/com/jsoniter/demo/LazyAny.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import com.jsoniter.any.Any;
44
import com.jsoniter.JsonIterator;
5-
import com.jsoniter.Slice;
5+
import com.jsoniter.spi.Slice;
66
import com.jsoniter.output.JsonStream;
77
import org.junit.Test;
88
import org.openjdk.jmh.Main;
@@ -12,8 +12,6 @@
1212

1313
import java.io.IOException;
1414
import java.io.InputStream;
15-
import java.util.Arrays;
16-
import java.util.HashMap;
1715
import java.util.List;
1816
import java.util.Map;
1917

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@
5555
<version>2.8.5</version>
5656
<optional>true</optional>
5757
</dependency>
58+
<dependency>
59+
<groupId>com.fasterxml.jackson.core</groupId>
60+
<artifactId>jackson-databind</artifactId>
61+
<version>2.8.5</version>
62+
<optional>true</optional>
63+
</dependency>
5864
</dependencies>
5965

6066
<build>

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,12 @@ private static Type chooseImpl(Type type) {
160160
"can not bind to generic collection without argument types, " +
161161
"try syntax like TypeLiteral<Map<String, String>>{}");
162162
}
163-
if (keyType != String.class) {
164-
throw new IllegalArgumentException("map key must be String");
165-
}
166163
if (clazz == Map.class) {
167164
clazz = implClazz == null ? HashMap.class : implClazz;
168165
}
166+
if (keyType == Object.class) {
167+
keyType = String.class;
168+
}
169169
return new ParameterizedTypeImpl(new Type[]{keyType, valueType}, null, clazz);
170170
}
171171
if (implClazz != null) {

src/main/java/com/jsoniter/CodegenAccess.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ public static final Slice readSlice(JsonIterator iter) throws IOException {
141141
return IterImpl.readSlice(iter);
142142
}
143143

144+
public static final Object readMapKey(String cacheKey, JsonIterator iter) throws IOException {
145+
Slice mapKey = readObjectFieldAsSlice(iter);
146+
MapKeyDecoder mapKeyDecoder = JsoniterSpi.getMapKeyDecoder(cacheKey);
147+
return mapKeyDecoder.decode(mapKey);
148+
}
149+
144150
final static boolean skipWhitespacesWithoutLoadMore(JsonIterator iter) throws IOException {
145151
for (int i = iter.head; i < iter.tail; i++) {
146152
byte c = iter.buf[i];

src/main/java/com/jsoniter/CodegenImplEnum.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class CodegenImplEnum {
66
public static String genEnum(Class clazz) {
77
StringBuilder lines = new StringBuilder();
88
append(lines, "if (iter.readNull()) { return null; }");
9-
append(lines, "com.jsoniter.Slice field = com.jsoniter.CodegenAccess.readSlice(iter);");
9+
append(lines, "com.jsoniter.spi.Slice field = com.jsoniter.CodegenAccess.readSlice(iter);");
1010
append(lines, "switch (field.len()) {");
1111
append(lines, renderTriTree(buildTriTree(Arrays.asList(clazz.getEnumConstants()))));
1212
append(lines, "}"); // end of switch

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.jsoniter;
22

3+
import com.jsoniter.spi.TypeLiteral;
4+
35
import java.lang.reflect.Type;
46
import java.util.HashMap;
57
import java.util.Map;
68

79
class CodegenImplMap {
810

911
public static String genMap(Class clazz, Type[] typeArgs) {
12+
Type keyType = typeArgs[0];
13+
MapKeyDecoders.register(keyType);
1014
Type valueType = typeArgs[1];
1115
StringBuilder lines = new StringBuilder();
1216
append(lines, "{{clazz}} map = ({{clazz}})com.jsoniter.CodegenAccess.resetExistingObject(iter);");
@@ -16,11 +20,18 @@ public static String genMap(Class clazz, Type[] typeArgs) {
1620
append(lines, "return map;");
1721
append(lines, "}");
1822
append(lines, "do {");
19-
append(lines, "String field = com.jsoniter.CodegenAccess.readObjectFieldAsString(iter);");
20-
append(lines, "map.put(field, {{op}});");
23+
if (keyType == String.class) {
24+
append(lines, "Object mapKey = com.jsoniter.CodegenAccess.readObjectFieldAsString(iter);");
25+
} else {
26+
append(lines, "Object mapKey = com.jsoniter.CodegenAccess.readMapKey(\"" +
27+
TypeLiteral.create(keyType).getDecoderCacheKey() +"\", iter);");
28+
}
29+
append(lines, "map.put(mapKey, {{op}});");
2130
append(lines, "} while (com.jsoniter.CodegenAccess.nextToken(iter) == ',');");
2231
append(lines, "return map;");
23-
return lines.toString().replace("{{clazz}}", clazz.getName()).replace("{{op}}", CodegenImplNative.genReadOp(valueType));
32+
return lines.toString()
33+
.replace("{{clazz}}", clazz.getName())
34+
.replace("{{op}}", CodegenImplNative.genReadOp(valueType));
2435
}
2536

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

src/main/java/com/jsoniter/CodegenImplObjectStrict.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public static String genObjectUsingStrict(Class clazz, ClassDescriptor desc) {
8282
if (desc.onExtraProperties != null) {
8383
append(lines, "java.util.Map extra = null;");
8484
}
85-
append(lines, "com.jsoniter.Slice field = com.jsoniter.CodegenAccess.readObjectFieldAsSlice(iter);");
85+
append(lines, "com.jsoniter.spi.Slice field = com.jsoniter.CodegenAccess.readObjectFieldAsSlice(iter);");
8686
append(lines, "boolean once = true;");
8787
append(lines, "while (once) {");
8888
append(lines, "once = false;");

src/main/java/com/jsoniter/IterImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.jsoniter.any.Any;
44
import com.jsoniter.spi.JsonException;
5+
import com.jsoniter.spi.Slice;
56

67
import java.io.IOException;
78

src/main/java/com/jsoniter/IterImplForStreaming.java

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

33
import com.jsoniter.any.Any;
4+
import com.jsoniter.spi.Slice;
45

56
import java.io.IOException;
67

src/main/java/com/jsoniter/JsonIterator.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.jsoniter.annotation.JsoniterAnnotationSupport;
44
import com.jsoniter.any.Any;
55
import com.jsoniter.spi.JsonException;
6+
import com.jsoniter.spi.Slice;
67
import com.jsoniter.spi.TypeLiteral;
78

89
import java.io.Closeable;
@@ -51,6 +52,7 @@ public class JsonIterator implements Closeable {
5152
valueTypes['n'] = ValueType.NULL;
5253
valueTypes['['] = ValueType.ARRAY;
5354
valueTypes['{'] = ValueType.OBJECT;
55+
MapKeyDecoders.registerNativeMapKeyDecoders();
5456
}
5557

5658
private JsonIterator(InputStream in, byte[] buf, int head, int tail) {

0 commit comments

Comments
 (0)