mirror of
https://github.com/json-iterator/go.git
synced 2025-04-04 21:34:16 +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 {
|
type sliceDecoder struct {
|
||||||
sliceType reflect.Type
|
sliceType reflect.Type
|
||||||
elemType reflect.Type
|
elemType reflect.Type
|
||||||
@ -582,6 +603,8 @@ func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
|
|||||||
return decoderOfStruct(type_)
|
return decoderOfStruct(type_)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
return prefix("[slice]").addTo(decoderOfSlice(type_))
|
return prefix("[slice]").addTo(decoderOfSlice(type_))
|
||||||
|
case reflect.Map:
|
||||||
|
return prefix("[map]").addTo(decoderOfMap(type_))
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
return prefix("[optional]").addTo(decoderOfOptional(type_.Elem()))
|
return prefix("[optional]").addTo(decoderOfOptional(type_.Elem()))
|
||||||
default:
|
default:
|
||||||
@ -703,3 +726,12 @@ func decoderOfSlice(type_ reflect.Type) (Decoder, error) {
|
|||||||
}
|
}
|
||||||
return &sliceDecoder{type_, type_.Elem(), decoder}, nil
|
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