|
|
@@ -25,43 +25,47 @@ func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
if realVal.IsNil() {
|
|
|
realVal.Set(reflect.MakeMap(realVal.Type()))
|
|
|
}
|
|
|
- iter.ReadObjectCB(func(iter *Iterator, keyStr string) bool{
|
|
|
+ iter.ReadObjectCB(func(iter *Iterator, keyStr string) bool {
|
|
|
elem := reflect.New(decoder.elemType)
|
|
|
decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter)
|
|
|
// to put into map, we have to use reflection
|
|
|
- realVal.SetMapIndex(decodeMapKey(iter, keyStr, decoder.keyType), elem.Elem())
|
|
|
- return true
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-func decodeMapKey(iter *Iterator, keyStr string, keyType reflect.Type) reflect.Value {
|
|
|
- switch {
|
|
|
- case keyType.Kind() == reflect.String:
|
|
|
- return reflect.ValueOf(keyStr)
|
|
|
- //case reflect.PtrTo(kt).Implements(textUnmarshalerType):
|
|
|
- // kv = reflect.New(v.Type().Key())
|
|
|
- // d.literalStore(item, kv, true)
|
|
|
- // kv = kv.Elem()
|
|
|
- default:
|
|
|
- switch keyType.Kind() {
|
|
|
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
- n, err := strconv.ParseInt(keyStr, 10, 64)
|
|
|
- if err != nil || reflect.Zero(keyType).OverflowInt(n) {
|
|
|
- iter.reportError("read map key as int64", "read int64 failed")
|
|
|
- return reflect.ValueOf("")
|
|
|
+ keyType := decoder.keyType
|
|
|
+ switch {
|
|
|
+ case keyType.Kind() == reflect.String:
|
|
|
+ realVal.SetMapIndex(reflect.ValueOf(keyStr), elem.Elem())
|
|
|
+ return true
|
|
|
+ case keyType.Implements(textUnmarshalerType):
|
|
|
+ textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler)
|
|
|
+ err := textUnmarshaler.UnmarshalText([]byte(keyStr))
|
|
|
+ if err != nil {
|
|
|
+ iter.reportError("read map key as TextUnmarshaler", err.Error())
|
|
|
+ return false
|
|
|
}
|
|
|
- return reflect.ValueOf(n).Convert(keyType)
|
|
|
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
|
- n, err := strconv.ParseUint(keyStr, 10, 64)
|
|
|
- if err != nil || reflect.Zero(keyType).OverflowUint(n) {
|
|
|
- iter.reportError("read map key as uint64", "read uint64 failed")
|
|
|
- return reflect.ValueOf("")
|
|
|
+ realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem())
|
|
|
+ return true
|
|
|
+ default:
|
|
|
+ switch keyType.Kind() {
|
|
|
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
+ n, err := strconv.ParseInt(keyStr, 10, 64)
|
|
|
+ if err != nil || reflect.Zero(keyType).OverflowInt(n) {
|
|
|
+ iter.reportError("read map key as int64", "read int64 failed")
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
|
|
|
+ return true
|
|
|
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
|
+ n, err := strconv.ParseUint(keyStr, 10, 64)
|
|
|
+ if err != nil || reflect.Zero(keyType).OverflowUint(n) {
|
|
|
+ iter.reportError("read map key as uint64", "read uint64 failed")
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
|
|
|
+ return true
|
|
|
}
|
|
|
- return reflect.ValueOf(n).Convert(keyType)
|
|
|
}
|
|
|
- }
|
|
|
- iter.reportError("read map key", "json: Unexpected key type")
|
|
|
- return reflect.ValueOf("")
|
|
|
+ iter.reportError("read map key", "unexpected map key type "+keyType.String())
|
|
|
+ return true
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
type mapEncoder struct {
|
|
|
@@ -131,4 +135,4 @@ func (encoder *mapEncoder) isEmpty(ptr unsafe.Pointer) bool {
|
|
|
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
|
|
|
realVal := reflect.ValueOf(*realInterface)
|
|
|
return realVal.Len() == 0
|
|
|
-}
|
|
|
+}
|