Kaynağa Gözat

#164 support interface{} with ptr

Tao Wen 8 yıl önce
ebeveyn
işleme
0828e559d0
2 değiştirilmiş dosya ile 23 ekleme ve 1 silme
  1. 7 1
      feature_reflect_native.go
  2. 16 0
      jsoniter_interface_test.go

+ 7 - 1
feature_reflect_native.go

@@ -5,6 +5,7 @@ import (
 	"encoding/base64"
 	"encoding/json"
 	"unsafe"
+	"reflect"
 )
 
 type stringCodec struct {
@@ -349,7 +350,12 @@ type emptyInterfaceCodec struct {
 }
 
 func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
-	*((*interface{})(ptr)) = iter.Read()
+	existing := *((*interface{})(ptr))
+	if existing != nil && reflect.TypeOf(existing).Kind() == reflect.Ptr {
+		iter.ReadVal(existing)
+	} else {
+		*((*interface{})(ptr)) = iter.Read()
+	}
 }
 
 func (codec *emptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) {

+ 16 - 0
jsoniter_interface_test.go

@@ -5,6 +5,7 @@ import (
 	"github.com/stretchr/testify/require"
 	"testing"
 	"unsafe"
+	"fmt"
 )
 
 func Test_write_array_of_interface(t *testing.T) {
@@ -297,3 +298,18 @@ func Test_array_with_nothing(t *testing.T) {
 	should.Nil(err)
 	should.Equal(`[null,null]`, output)
 }
+
+func Test_unmarshal_ptr_to_interface(t *testing.T) {
+	type TestData struct {
+		Name string `json:"name"`
+	}
+	should := require.New(t)
+	var obj interface{} = &TestData{}
+	err := json.Unmarshal([]byte(`{"name":"value"}`), &obj)
+	should.Nil(err)
+	should.Equal("&{value}", fmt.Sprintf("%v", obj))
+	obj = interface{}(&TestData{})
+	err = Unmarshal([]byte(`{"name":"value"}`), &obj)
+	should.Nil(err)
+	should.Equal("&{value}", fmt.Sprintf("%v", obj))
+}