1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-27 08:30:57 +02:00

#56 nil map or array should be null not [] or {}

This commit is contained in:
Tao Wen 2017-06-13 09:14:19 +08:00
parent 6e5817b773
commit 788918b85d
6 changed files with 64 additions and 6 deletions

View File

@ -34,6 +34,10 @@ type Encoder interface {
func writeToStream(val interface{}, stream *Stream, encoder Encoder) { func writeToStream(val interface{}, stream *Stream, encoder Encoder) {
e := (*emptyInterface)(unsafe.Pointer(&val)) e := (*emptyInterface)(unsafe.Pointer(&val))
if e.word == nil {
stream.WriteNil()
return
}
if reflect.TypeOf(val).Kind() == reflect.Ptr { if reflect.TypeOf(val).Kind() == reflect.Ptr {
encoder.encode(unsafe.Pointer(&e.word), stream) encoder.encode(unsafe.Pointer(&e.word), stream)
} else { } else {
@ -512,11 +516,15 @@ func decoderOfOptional(typ reflect.Type) (Decoder, error) {
func encoderOfOptional(typ reflect.Type) (Encoder, error) { func encoderOfOptional(typ reflect.Type) (Encoder, error) {
elemType := typ.Elem() elemType := typ.Elem()
decoder, err := encoderOfType(elemType) elemEncoder, err := encoderOfType(elemType)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &optionalEncoder{decoder}, nil encoder := &optionalEncoder{elemEncoder}
if elemType.Kind() == reflect.Map {
encoder = &optionalEncoder{encoder}
}
return encoder, nil
} }
func decoderOfMap(typ reflect.Type) (Decoder, error) { func decoderOfMap(typ reflect.Type) (Decoder, error) {
@ -539,5 +547,6 @@ func encoderOfMap(typ reflect.Type) (Encoder, error) {
return nil, err return nil, err
} }
mapInterface := reflect.New(typ).Elem().Interface() mapInterface := reflect.New(typ).Elem().Interface()
return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil encoderForMap := &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}
return encoderForMap, nil
} }

View File

@ -34,6 +34,10 @@ type sliceEncoder struct {
func (encoder *sliceEncoder) encode(ptr unsafe.Pointer, stream *Stream) { func (encoder *sliceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
slice := (*sliceHeader)(ptr) slice := (*sliceHeader)(ptr)
if slice.Data == nil {
stream.WriteNil()
return
}
if slice.Len == 0 { if slice.Len == 0 {
stream.WriteEmptyArray() stream.WriteEmptyArray()
return return

View File

@ -228,7 +228,7 @@ func Test_write_array(t *testing.T) {
func Test_write_val_array(t *testing.T) { func Test_write_val_array(t *testing.T) {
should := require.New(t) should := require.New(t)
val := []int{1, 2, 3} val := []int{1, 2, 3}
str, err := MarshalToString(val) str, err := MarshalToString(&val)
should.Nil(err) should.Nil(err)
should.Equal("[1,2,3]", str) should.Equal("[1,2,3]", str)
} }

View File

@ -103,8 +103,6 @@ func Test_decode_TextMarshaler_key_map(t *testing.T) {
should.Equal(`{"1":"2"}`, str) should.Equal(`{"1":"2"}`, str)
} }
func Test_map_key_with_escaped_char(t *testing.T) { func Test_map_key_with_escaped_char(t *testing.T) {
type Ttest struct { type Ttest struct {
Map map[string]string Map map[string]string

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"github.com/json-iterator/go/require" "github.com/json-iterator/go/require"
"testing" "testing"
"encoding/json"
) )
func Test_read_null(t *testing.T) { func Test_read_null(t *testing.T) {
@ -87,3 +88,39 @@ func Test_decode_null_skip(t *testing.T) {
t.FailNow() t.FailNow()
} }
} }
func Test_encode_nil_map(t *testing.T) {
should := require.New(t)
type Ttest map[string]string
var obj1 Ttest
output, err := json.Marshal(obj1)
should.Nil(err)
should.Equal("null", string(output))
output, err = json.Marshal(&obj1)
should.Nil(err)
should.Equal("null", string(output))
output, err = Marshal(obj1)
should.Nil(err)
should.Equal("null", string(output))
output, err = Marshal(&obj1)
should.Nil(err)
should.Equal("null", string(output))
}
func Test_encode_nil_array(t *testing.T) {
should := require.New(t)
type Ttest []string
var obj1 Ttest
output, err := json.Marshal(obj1)
should.Nil(err)
should.Equal("null", string(output))
output, err = json.Marshal(&obj1)
should.Nil(err)
should.Equal("null", string(output))
output, err = Marshal(obj1)
should.Nil(err)
should.Equal("null", string(output))
output, err = Marshal(&obj1)
should.Nil(err)
should.Equal("null", string(output))
}

View File

@ -112,6 +112,16 @@ func Test_decode_slash(t *testing.T) {
should.NotNil(UnmarshalFromString("\\", &obj)) should.NotNil(UnmarshalFromString("\\", &obj))
} }
//func Test_html_escape(t *testing.T) {
// should := require.New(t)
// output, err := json.Marshal(`>`)
// should.Nil(err)
// should.Equal(`"\u003e"`, string(output))
// output, err = Marshal(`>`)
// should.Nil(err)
// should.Equal(`"\u003e"`, string(output))
//}
func Benchmark_jsoniter_unicode(b *testing.B) { func Benchmark_jsoniter_unicode(b *testing.B) {
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
iter := ParseString(`"\ud83d\udc4a"`) iter := ParseString(`"\ud83d\udc4a"`)