mirror of
https://github.com/json-iterator/go.git
synced 2025-03-23 21:09:11 +02:00
support map
This commit is contained in:
parent
aa42ac95c0
commit
e427475e9c
17
jsoniter_map_test.go
Normal file
17
jsoniter_map_test.go
Normal file
@ -0,0 +1,17 @@
|
||||
package jsoniter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"reflect"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func Test_read_map(t *testing.T) {
|
||||
iter := ParseString(`{"hello": "world"}`)
|
||||
m := map[string]string{"1": "2"}
|
||||
iter.Read(&m)
|
||||
if !reflect.DeepEqual(map[string]string{"1": "2", "hello": "world"}, m) {
|
||||
fmt.Println(iter.Error)
|
||||
t.Fatal(m)
|
||||
}
|
||||
}
|
@ -295,6 +295,27 @@ func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
}
|
||||
}
|
||||
|
||||
type mapDecoder struct {
|
||||
mapType reflect.Type
|
||||
elemType reflect.Type
|
||||
elemDecoder Decoder
|
||||
mapInterface emptyInterface
|
||||
}
|
||||
|
||||
func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
// dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
|
||||
mapInterface := decoder.mapInterface
|
||||
mapInterface.word = ptr
|
||||
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
|
||||
realVal := reflect.ValueOf(*realInterface).Elem()
|
||||
|
||||
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
|
||||
elem := reflect.New(decoder.elemType)
|
||||
decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter)
|
||||
realVal.SetMapIndex(reflect.ValueOf(field), elem.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
type sliceDecoder struct {
|
||||
sliceType reflect.Type
|
||||
elemType reflect.Type
|
||||
@ -582,6 +603,8 @@ func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
|
||||
return decoderOfStruct(type_)
|
||||
case reflect.Slice:
|
||||
return prefix("[slice]").addTo(decoderOfSlice(type_))
|
||||
case reflect.Map:
|
||||
return prefix("[map]").addTo(decoderOfMap(type_))
|
||||
case reflect.Ptr:
|
||||
return prefix("[optional]").addTo(decoderOfOptional(type_.Elem()))
|
||||
default:
|
||||
@ -703,3 +726,12 @@ func decoderOfSlice(type_ reflect.Type) (Decoder, error) {
|
||||
}
|
||||
return &sliceDecoder{type_, type_.Elem(), decoder}, nil
|
||||
}
|
||||
|
||||
func decoderOfMap(type_ reflect.Type) (Decoder, error) {
|
||||
decoder, err := decoderOfPtr(type_.Elem())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapInterface := reflect.New(type_).Interface()
|
||||
return &mapDecoder{type_, type_.Elem(), decoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user