Fix decoding for UnmarshalJSON / UnmarshalText

This commit is contained in:
Masaaki Goshima 2020-11-24 20:15:11 +09:00
parent 5c82b00ee7
commit 47b7f4a5a2
4 changed files with 50 additions and 13 deletions

View File

@ -9,13 +9,13 @@ import (
func (d *Decoder) compileHead(typ *rtype) (decoder, error) {
switch {
case typ.Implements(unmarshalJSONType):
return newUnmarshalJSONDecoder(typ), nil
return newUnmarshalJSONDecoder(typ, "", ""), nil
case rtype_ptrTo(typ).Implements(unmarshalJSONType):
return newUnmarshalJSONDecoder(rtype_ptrTo(typ)), nil
return newUnmarshalJSONDecoder(rtype_ptrTo(typ), "", ""), nil
case typ.Implements(unmarshalTextType):
return newUnmarshalTextDecoder(typ), nil
return newUnmarshalTextDecoder(typ, "", ""), nil
case rtype_ptrTo(typ).Implements(unmarshalTextType):
return newUnmarshalTextDecoder(rtype_ptrTo(typ)), nil
return newUnmarshalTextDecoder(rtype_ptrTo(typ), "", ""), nil
}
return d.compile(typ.Elem(), "", "")
}
@ -23,13 +23,13 @@ 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), nil
return newUnmarshalJSONDecoder(typ, structName, fieldName), nil
case rtype_ptrTo(typ).Implements(unmarshalJSONType):
return newUnmarshalJSONDecoder(rtype_ptrTo(typ)), nil
return newUnmarshalJSONDecoder(rtype_ptrTo(typ), structName, fieldName), nil
case typ.Implements(unmarshalTextType):
return newUnmarshalTextDecoder(typ), nil
return newUnmarshalTextDecoder(typ, structName, fieldName), nil
case rtype_ptrTo(typ).Implements(unmarshalTextType):
return newUnmarshalTextDecoder(rtype_ptrTo(typ)), nil
return newUnmarshalTextDecoder(rtype_ptrTo(typ), structName, fieldName), nil
}
switch typ.Kind() {

View File

@ -35,6 +35,9 @@ func (d *structDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
return errNotAtBeginningOfValue(s.totalOffset())
}
s.cursor++
if s.char() == '}' {
return nil
}
for {
s.reset()
key, err := d.keyDecoder.decodeStreamByte(s)

View File

@ -7,10 +7,24 @@ import (
type unmarshalJSONDecoder struct {
typ *rtype
isDoublePointer bool
structName string
fieldName string
}
func newUnmarshalJSONDecoder(typ *rtype) *unmarshalJSONDecoder {
return &unmarshalJSONDecoder{typ: typ}
func newUnmarshalJSONDecoder(typ *rtype, structName, fieldName string) *unmarshalJSONDecoder {
return &unmarshalJSONDecoder{
typ: typ,
structName: structName,
fieldName: fieldName,
}
}
func (d *unmarshalJSONDecoder) annotateError(err error) {
ut, ok := err.(*UnmarshalTypeError)
if ok {
ut.Struct = d.structName
ut.Field = d.fieldName
}
}
func (d *unmarshalJSONDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
@ -27,6 +41,7 @@ func (d *unmarshalJSONDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
ptr: newptr,
}))
if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil {
d.annotateError(err)
return err
}
*(*unsafe.Pointer)(p) = newptr
@ -36,6 +51,7 @@ func (d *unmarshalJSONDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
ptr: p,
}))
if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil {
d.annotateError(err)
return err
}
}
@ -57,6 +73,7 @@ func (d *unmarshalJSONDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer
ptr: newptr,
}))
if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil {
d.annotateError(err)
return 0, err
}
*(*unsafe.Pointer)(p) = newptr
@ -66,6 +83,7 @@ func (d *unmarshalJSONDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer
ptr: p,
}))
if err := v.(Unmarshaler).UnmarshalJSON(src); err != nil {
d.annotateError(err)
return 0, err
}
}

View File

@ -9,11 +9,25 @@ import (
)
type unmarshalTextDecoder struct {
typ *rtype
typ *rtype
structName string
fieldName string
}
func newUnmarshalTextDecoder(typ *rtype) *unmarshalTextDecoder {
return &unmarshalTextDecoder{typ: typ}
func newUnmarshalTextDecoder(typ *rtype, structName, fieldName string) *unmarshalTextDecoder {
return &unmarshalTextDecoder{
typ: typ,
structName: structName,
fieldName: fieldName,
}
}
func (d *unmarshalTextDecoder) annotateError(err error) {
ut, ok := err.(*UnmarshalTypeError)
if ok {
ut.Struct = d.structName
ut.Field = d.fieldName
}
}
func (d *unmarshalTextDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
@ -32,6 +46,7 @@ func (d *unmarshalTextDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
ptr: newptr,
}))
if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil {
d.annotateError(err)
return err
}
*(*unsafe.Pointer)(p) = newptr
@ -54,6 +69,7 @@ func (d *unmarshalTextDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer
ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
}))
if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil {
d.annotateError(err)
return 0, err
}
return end, nil