mirror of https://github.com/goccy/go-json.git
Fix double pointer
This commit is contained in:
parent
5a8383f0d2
commit
ee52d7f0ae
|
@ -8,12 +8,8 @@ import (
|
|||
|
||||
func (d *Decoder) compileHead(typ *rtype) (decoder, error) {
|
||||
switch {
|
||||
case typ.Implements(unmarshalJSONType):
|
||||
return newUnmarshalJSONDecoder(typ, "", ""), nil
|
||||
case rtype_ptrTo(typ).Implements(unmarshalJSONType):
|
||||
return newUnmarshalJSONDecoder(rtype_ptrTo(typ), "", ""), nil
|
||||
case typ.Implements(unmarshalTextType):
|
||||
return newUnmarshalTextDecoder(typ, "", ""), nil
|
||||
case rtype_ptrTo(typ).Implements(unmarshalTextType):
|
||||
return newUnmarshalTextDecoder(rtype_ptrTo(typ), "", ""), nil
|
||||
}
|
||||
|
@ -22,12 +18,8 @@ func (d *Decoder) compileHead(typ *rtype) (decoder, error) {
|
|||
|
||||
func (d *Decoder) compile(typ *rtype, structName, fieldName string) (decoder, error) {
|
||||
switch {
|
||||
case typ.Implements(unmarshalJSONType):
|
||||
return newUnmarshalJSONDecoder(typ, structName, fieldName), nil
|
||||
case rtype_ptrTo(typ).Implements(unmarshalJSONType):
|
||||
return newUnmarshalJSONDecoder(rtype_ptrTo(typ), structName, fieldName), nil
|
||||
case typ.Implements(unmarshalTextType):
|
||||
return newUnmarshalTextDecoder(typ, structName, fieldName), nil
|
||||
case rtype_ptrTo(typ).Implements(unmarshalTextType):
|
||||
return newUnmarshalTextDecoder(rtype_ptrTo(typ), structName, fieldName), nil
|
||||
}
|
||||
|
|
|
@ -38,26 +38,14 @@ func (d *unmarshalJSONDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
|
|||
src := s.buf[start:s.cursor]
|
||||
dst := make([]byte, len(src))
|
||||
copy(dst, src)
|
||||
if d.isDoublePointer {
|
||||
newptr := unsafe_New(d.typ.Elem())
|
||||
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
|
||||
typ: d.typ,
|
||||
ptr: newptr,
|
||||
}))
|
||||
if err := v.(Unmarshaler).UnmarshalJSON(dst); err != nil {
|
||||
d.annotateError(s.cursor, err)
|
||||
return err
|
||||
}
|
||||
*(*unsafe.Pointer)(p) = newptr
|
||||
} else {
|
||||
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
|
||||
typ: d.typ,
|
||||
ptr: p,
|
||||
}))
|
||||
if err := v.(Unmarshaler).UnmarshalJSON(dst); err != nil {
|
||||
d.annotateError(s.cursor, err)
|
||||
return err
|
||||
}
|
||||
|
||||
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
|
||||
typ: d.typ,
|
||||
ptr: p,
|
||||
}))
|
||||
if err := v.(Unmarshaler).UnmarshalJSON(dst); err != nil {
|
||||
d.annotateError(s.cursor, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -45,16 +45,14 @@ func (d *unmarshalTextDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
|
|||
if b, ok := unquoteBytes(dst); ok {
|
||||
dst = b
|
||||
}
|
||||
newptr := unsafe_New(d.typ.Elem())
|
||||
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
|
||||
typ: d.typ,
|
||||
ptr: newptr,
|
||||
ptr: p,
|
||||
}))
|
||||
if err := v.(encoding.TextUnmarshaler).UnmarshalText(dst); err != nil {
|
||||
d.annotateError(s.cursor, err)
|
||||
return err
|
||||
}
|
||||
*(*unsafe.Pointer)(p) = newptr
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1298,7 +1298,7 @@ func TestNilMarshal(t *testing.T) {
|
|||
{v: struct{ M string }{"gopher"}, want: `{"M":"gopher"}`},
|
||||
{v: struct{ M json.Marshaler }{}, want: `{"M":null}`},
|
||||
{v: struct{ M json.Marshaler }{(*nilJSONMarshaler)(nil)}, want: `{"M":"0zenil0"}`},
|
||||
{v: struct{ M interface{} }{(*nilJSONMarshaler)(nil)}, want: `{"M":"0zenil0"}`}, // doesn't compatible with encoding/json
|
||||
{v: struct{ M interface{} }{(*nilJSONMarshaler)(nil)}, want: `{"M":null}`},
|
||||
{v: struct{ M encoding.TextMarshaler }{}, want: `{"M":null}`},
|
||||
{v: struct{ M encoding.TextMarshaler }{(*nilTextMarshaler)(nil)}, want: `{"M":"0zenil0"}`},
|
||||
{v: struct{ M interface{} }{(*nilTextMarshaler)(nil)}, want: `{"M":null}`},
|
||||
|
|
42
encode_vm.go
42
encode_vm.go
|
@ -226,35 +226,23 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
|||
}
|
||||
vv := rv.Interface()
|
||||
header := (*interfaceHeader)(unsafe.Pointer(&vv))
|
||||
typ := header.typ
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
var c *opcode
|
||||
if typ.Kind() == reflect.Map {
|
||||
code, err := e.compileMap(&encodeCompileContext{
|
||||
typ: typ,
|
||||
root: code.root,
|
||||
withIndent: e.enabledIndent,
|
||||
indent: code.indent,
|
||||
}, false)
|
||||
if err != nil {
|
||||
return err
|
||||
if header.typ.Kind() == reflect.Ptr {
|
||||
if rv.Elem().IsNil() {
|
||||
e.encodeNull()
|
||||
e.encodeByte(',')
|
||||
code = code.next
|
||||
break
|
||||
}
|
||||
c = code
|
||||
} else {
|
||||
code, err := e.compile(&encodeCompileContext{
|
||||
typ: typ,
|
||||
root: code.root,
|
||||
withIndent: e.enabledIndent,
|
||||
indent: code.indent,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c = code
|
||||
}
|
||||
|
||||
c, err := e.compileHead(&encodeCompileContext{
|
||||
typ: header.typ,
|
||||
root: code.root,
|
||||
withIndent: e.enabledIndent,
|
||||
indent: code.indent,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
beforeLastCode := c.beforeLastCode()
|
||||
lastCode := beforeLastCode.next
|
||||
lastCode.idx = beforeLastCode.idx + uintptrSize
|
||||
|
|
Loading…
Reference in New Issue