Skip to content

Commit bc9681c

Browse files
committed
decode integer key
1 parent 2581901 commit bc9681c

File tree

9 files changed

+90
-76
lines changed

9 files changed

+90
-76
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ private static Type chooseImpl(Type type) {
171171
if (keyType == Object.class) {
172172
keyType = String.class;
173173
}
174-
DefaultMapKeyDecoder.registerOrGetExisting(keyType);
174+
MapKeyDecoders.registerOrGetExisting(keyType);
175175
return GenericsHelper.createParameterizedType(new Type[]{keyType, valueType}, null, clazz);
176176
}
177177
if (implClazz != null) {

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,8 @@ public static final Slice readSlice(JsonIterator iter) throws IOException {
142142
}
143143

144144
public static final Object readMapKey(String cacheKey, JsonIterator iter) throws IOException {
145-
Slice encodedMapKey = readObjectFieldAsSlice(iter);
146-
MapKeyDecoder mapKeyDecoder = JsoniterSpi.getMapKeyDecoder(cacheKey);
147-
return mapKeyDecoder.decode(encodedMapKey);
145+
Decoder mapKeyDecoder = JsoniterSpi.getMapKeyDecoder(cacheKey);
146+
return mapKeyDecoder.decode(iter);
148147
}
149148

150149
final static boolean skipWhitespacesWithoutLoadMore(JsonIterator iter) throws IOException {

src/main/java/com/jsoniter/DefaultMapKeyDecoder.java

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.jsoniter;
2+
3+
import com.jsoniter.spi.*;
4+
5+
import java.io.IOException;
6+
import java.lang.reflect.Type;
7+
8+
class MapKeyDecoders {
9+
10+
public static Decoder registerOrGetExisting(Type mapKeyType) {
11+
String cacheKey = JsoniterSpi.getMapKeyDecoderCacheKey(mapKeyType);
12+
Decoder mapKeyDecoder = JsoniterSpi.getMapKeyDecoder(cacheKey);
13+
if (null != mapKeyDecoder) {
14+
return mapKeyDecoder;
15+
}
16+
mapKeyDecoder = createMapKeyDecoder(mapKeyType);
17+
JsoniterSpi.addNewMapDecoder(cacheKey, mapKeyDecoder);
18+
return mapKeyDecoder;
19+
}
20+
21+
private static Decoder createMapKeyDecoder(Type mapKeyType) {
22+
if (String.class == mapKeyType) {
23+
return new StringKeyDecoder();
24+
}
25+
Decoder decoder = CodegenImplNative.NATIVE_DECODERS.get(mapKeyType);
26+
if (decoder != null) {
27+
return new NumberKeyDecoder(decoder);
28+
}
29+
throw new JsonException("can not encode map key type: " + mapKeyType);
30+
}
31+
32+
private static class StringKeyDecoder implements Decoder {
33+
34+
@Override
35+
public Object decode(JsonIterator iter) throws IOException {
36+
return iter.readString();
37+
}
38+
}
39+
40+
private static class NumberKeyDecoder implements Decoder {
41+
42+
private final Decoder decoder;
43+
44+
private NumberKeyDecoder(Decoder decoder) {
45+
this.decoder = decoder;
46+
}
47+
48+
@Override
49+
public Object decode(JsonIterator iter) throws IOException {
50+
if (IterImpl.nextToken(iter) != '"') {
51+
throw iter.reportError("decode number map key", "expect \"");
52+
}
53+
Object key = decoder.decode(iter);
54+
if (IterImpl.nextToken(iter) != '"') {
55+
throw iter.reportError("decode number map key", "expect \"");
56+
}
57+
return key;
58+
}
59+
}
60+
}

src/main/java/com/jsoniter/ReflectionMapDecoder.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class ReflectionMapDecoder implements Decoder {
1111

1212
private final Constructor ctor;
1313
private final Decoder valueTypeDecoder;
14-
private final MapKeyDecoder mapKeyDecoder;
14+
private final Decoder mapKeyDecoder;
1515

1616
public ReflectionMapDecoder(Class clazz, Type[] typeArgs) {
1717
try {
@@ -20,11 +20,7 @@ public ReflectionMapDecoder(Class clazz, Type[] typeArgs) {
2020
throw new JsonException(e);
2121
}
2222
Type keyType = typeArgs[0];
23-
if (keyType == String.class) {
24-
mapKeyDecoder = null;
25-
} else {
26-
mapKeyDecoder = DefaultMapKeyDecoder.registerOrGetExisting(keyType);
27-
}
23+
mapKeyDecoder = MapKeyDecoders.registerOrGetExisting(keyType);
2824
TypeLiteral valueTypeLiteral = TypeLiteral.create(typeArgs[1]);
2925
valueTypeDecoder = Codegen.getDecoder(valueTypeLiteral.getDecoderCacheKey(), typeArgs[1]);
3026
}
@@ -59,11 +55,10 @@ private Object decode_(JsonIterator iter) throws Exception {
5955
}
6056

6157
private Object readMapKey(JsonIterator iter) throws IOException {
62-
if (mapKeyDecoder == null) {
63-
return CodegenAccess.readObjectFieldAsString(iter);
64-
} else {
65-
Slice mapKey = CodegenAccess.readObjectFieldAsSlice(iter);
66-
return mapKeyDecoder.decode(mapKey);
58+
Object key = mapKeyDecoder.decode(iter);
59+
if (':' != IterImpl.nextToken(iter)) {
60+
throw iter.reportError("readMapKey", "expect :");
6761
}
62+
return key;
6863
}
6964
}

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,9 @@ private static Encoder createDefaultEncoder(Type mapKeyType) {
2525
if (mapKeyType == Object.class) {
2626
return new DynamicKeyEncoder();
2727
}
28-
if (mapKeyType instanceof Class) {
29-
if (Number.class.isAssignableFrom((Class<?>) mapKeyType)) {
30-
return new NumberKeyEncoder();
31-
}
28+
Encoder.ReflectionEncoder encoder = CodegenImplNative.NATIVE_ENCODERS.get(mapKeyType);
29+
if (encoder != null) {
30+
return new NumberKeyEncoder(encoder);
3231
}
3332
throw new JsonException("can not encode map key type: " + mapKeyType);
3433
}
@@ -43,10 +42,16 @@ public void encode(Object obj, JsonStream stream) throws IOException {
4342

4443
private static class NumberKeyEncoder implements Encoder {
4544

45+
private final Encoder encoder;
46+
47+
private NumberKeyEncoder(Encoder encoder) {
48+
this.encoder = encoder;
49+
}
50+
4651
@Override
4752
public void encode(Object obj, JsonStream stream) throws IOException {
4853
stream.write('"');
49-
stream.writeVal(obj);
54+
encoder.encode(obj, stream);
5055
stream.write('"');
5156
}
5257
}

src/main/java/com/jsoniter/spi/JsoniterSpi.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class JsoniterSpi {
1212
private static Config defaultConfig;
1313
private static List<Extension> extensions = new ArrayList<Extension>();
1414
private static Map<Class, Class> typeImpls = new HashMap<Class, Class>();
15-
private static Map<Type, MapKeyDecoder> globalMapKeyDecoders = new HashMap<Type, MapKeyDecoder>();
15+
private static Map<Type, Decoder> globalMapKeyDecoders = new HashMap<Type, Decoder>();
1616
private static Map<Type, Encoder> globalMapKeyEncoders = new HashMap<Type, Encoder>();
1717
private static Map<Type, Decoder> globalTypeDecoders = new HashMap<Type, Decoder>();
1818
private static Map<Type, Encoder> globalTypeEncoders = new HashMap<Type, Encoder>();
@@ -28,7 +28,7 @@ protected Config initialValue() {
2828
};
2929
private static volatile Map<Object, String> configNames = new HashMap<Object, String>();
3030
private static volatile Map<String, Encoder> mapKeyEncoders = new HashMap<String, Encoder>();
31-
private static volatile Map<String, MapKeyDecoder> mapKeyDecoders = new HashMap<String, MapKeyDecoder>();
31+
private static volatile Map<String, Decoder> mapKeyDecoders = new HashMap<String, Decoder>();
3232
private static volatile Map<String, Encoder> encoders = new HashMap<String, Encoder>();
3333
private static volatile Map<String, Decoder> decoders = new HashMap<String, Decoder>();
3434
private static volatile Map<Class, Extension> objectFactories = new HashMap<Class, Extension>();
@@ -98,7 +98,7 @@ public static List<Extension> getExtensions() {
9898
return combined;
9999
}
100100

101-
public static void registerMapKeyDecoder(Type mapKeyType, MapKeyDecoder mapKeyDecoder) {
101+
public static void registerMapKeyDecoder(Type mapKeyType, Decoder mapKeyDecoder) {
102102
globalMapKeyDecoders.put(mapKeyType, mapKeyDecoder);
103103
copyGlobalMapKeyDecoder(getCurrentConfig().configName(), mapKeyType, mapKeyDecoder);
104104
}
@@ -159,7 +159,7 @@ public static void registerPropertyEncoder(TypeLiteral typeLiteral, String prope
159159
// === copy from global to current ===
160160

161161
private static void copyGlobalSettings(String configName) {
162-
for (Map.Entry<Type, MapKeyDecoder> entry : globalMapKeyDecoders.entrySet()) {
162+
for (Map.Entry<Type, Decoder> entry : globalMapKeyDecoders.entrySet()) {
163163
copyGlobalMapKeyDecoder(configName, entry.getKey(), entry.getValue());
164164
}
165165
for (Map.Entry<Type, Encoder> entry : globalMapKeyEncoders.entrySet()) {
@@ -196,7 +196,7 @@ private static void copyGlobalTypeDecoder(String configName, Type type, Decoder
196196
addNewDecoder(TypeLiteral.create(type).getDecoderCacheKey(configName), typeDecoder);
197197
}
198198

199-
private static void copyGlobalMapKeyDecoder(String configName, Type mapKeyType, MapKeyDecoder mapKeyDecoder) {
199+
private static void copyGlobalMapKeyDecoder(String configName, Type mapKeyType, Decoder mapKeyDecoder) {
200200
addNewMapDecoder(TypeLiteral.create(mapKeyType).getDecoderCacheKey(configName), mapKeyDecoder);
201201
}
202202

@@ -216,13 +216,13 @@ public static String getMapKeyDecoderCacheKey(Type mapKeyType) {
216216

217217
// === current ===
218218

219-
public synchronized static void addNewMapDecoder(String cacheKey, MapKeyDecoder mapKeyDecoder) {
220-
HashMap<String, MapKeyDecoder> newCache = new HashMap<String, MapKeyDecoder>(mapKeyDecoders);
219+
public synchronized static void addNewMapDecoder(String cacheKey, Decoder mapKeyDecoder) {
220+
HashMap<String, Decoder> newCache = new HashMap<String, Decoder>(mapKeyDecoders);
221221
newCache.put(cacheKey, mapKeyDecoder);
222222
mapKeyDecoders = newCache;
223223
}
224224

225-
public static MapKeyDecoder getMapKeyDecoder(String cacheKey) {
225+
public static Decoder getMapKeyDecoder(String cacheKey) {
226226
return mapKeyDecoders.get(cacheKey);
227227
}
228228

src/main/java/com/jsoniter/spi/MapKeyDecoder.java

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/test/java/com/jsoniter/TestMap.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,11 @@ public static class TestObject1 {
4444
}
4545

4646
public void test_MapKeyCodec() {
47-
JsoniterSpi.registerMapKeyDecoder(TestObject1.class, new MapKeyDecoder() {
47+
JsoniterSpi.registerMapKeyDecoder(TestObject1.class, new Decoder() {
4848
@Override
49-
public Object decode(Slice encodedMapKey) {
50-
Integer field = Integer.valueOf(encodedMapKey.toString());
49+
public Object decode(JsonIterator iter) throws IOException {
5150
TestObject1 obj = new TestObject1();
52-
obj.Field = field;
51+
obj.Field = Integer.valueOf(iter.readString());
5352
return obj;
5453
}
5554
});

0 commit comments

Comments
 (0)