2021-06-03 12:49:01 +03:00
|
|
|
package decoder
|
2020-05-08 14:22:57 +03:00
|
|
|
|
|
|
|
import (
|
2021-06-03 12:49:01 +03:00
|
|
|
"encoding/json"
|
2020-05-08 14:22:57 +03:00
|
|
|
"unsafe"
|
2021-06-03 12:49:01 +03:00
|
|
|
|
|
|
|
"github.com/goccy/go-json/internal/errors"
|
|
|
|
"github.com/goccy/go-json/internal/runtime"
|
2020-05-08 14:22:57 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type unmarshalJSONDecoder struct {
|
2021-06-03 12:49:01 +03:00
|
|
|
typ *runtime.Type
|
2020-12-15 06:29:19 +03:00
|
|
|
structName string
|
|
|
|
fieldName string
|
2020-05-08 14:22:57 +03:00
|
|
|
}
|
|
|
|
|
2021-06-03 12:49:01 +03:00
|
|
|
func newUnmarshalJSONDecoder(typ *runtime.Type, structName, fieldName string) *unmarshalJSONDecoder {
|
2020-11-24 14:15:11 +03:00
|
|
|
return &unmarshalJSONDecoder{
|
|
|
|
typ: typ,
|
|
|
|
structName: structName,
|
|
|
|
fieldName: fieldName,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-27 11:11:53 +03:00
|
|
|
func (d *unmarshalJSONDecoder) annotateError(cursor int64, err error) {
|
|
|
|
switch e := err.(type) {
|
2021-06-03 12:49:01 +03:00
|
|
|
case *errors.UnmarshalTypeError:
|
2020-11-27 11:11:53 +03:00
|
|
|
e.Struct = d.structName
|
|
|
|
e.Field = d.fieldName
|
2021-06-03 12:49:01 +03:00
|
|
|
case *errors.SyntaxError:
|
2020-11-27 11:11:53 +03:00
|
|
|
e.Offset = cursor
|
2020-11-24 14:15:11 +03:00
|
|
|
}
|
2020-05-08 14:22:57 +03:00
|
|
|
}
|
|
|
|
|
2021-06-03 12:49:01 +03:00
|
|
|
func (d *unmarshalJSONDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
|
2020-07-30 16:41:53 +03:00
|
|
|
s.skipWhiteSpace()
|
|
|
|
start := s.cursor
|
2021-02-18 13:05:06 +03:00
|
|
|
if err := s.skipValue(depth); err != nil {
|
2020-07-30 16:41:53 +03:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
src := s.buf[start:s.cursor]
|
2020-12-05 16:27:33 +03:00
|
|
|
dst := make([]byte, len(src))
|
|
|
|
copy(dst, src)
|
2020-12-07 04:44:24 +03:00
|
|
|
|
2021-03-13 08:12:31 +03:00
|
|
|
v := *(*interface{})(unsafe.Pointer(&emptyInterface{
|
2020-12-07 04:44:24 +03:00
|
|
|
typ: d.typ,
|
|
|
|
ptr: p,
|
|
|
|
}))
|
2021-06-03 12:49:01 +03:00
|
|
|
if err := v.(json.Unmarshaler).UnmarshalJSON(dst); err != nil {
|
2020-12-07 04:44:24 +03:00
|
|
|
d.annotateError(s.cursor, err)
|
|
|
|
return err
|
2020-07-30 16:41:53 +03:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-06-03 12:49:01 +03:00
|
|
|
func (d *unmarshalJSONDecoder) Decode(buf []byte, cursor, depth int64, p unsafe.Pointer) (int64, error) {
|
2020-05-08 14:22:57 +03:00
|
|
|
cursor = skipWhiteSpace(buf, cursor)
|
|
|
|
start := cursor
|
2021-02-18 13:05:06 +03:00
|
|
|
end, err := skipValue(buf, cursor, depth)
|
2020-05-08 14:22:57 +03:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
src := buf[start:end]
|
2021-01-22 08:01:01 +03:00
|
|
|
dst := make([]byte, len(src))
|
|
|
|
copy(dst, src)
|
|
|
|
|
2021-03-13 08:12:31 +03:00
|
|
|
v := *(*interface{})(unsafe.Pointer(&emptyInterface{
|
2020-12-15 06:29:19 +03:00
|
|
|
typ: d.typ,
|
|
|
|
ptr: p,
|
|
|
|
}))
|
2021-06-03 12:49:01 +03:00
|
|
|
if err := v.(json.Unmarshaler).UnmarshalJSON(dst); err != nil {
|
2020-12-15 06:29:19 +03:00
|
|
|
d.annotateError(cursor, err)
|
|
|
|
return 0, err
|
2020-05-08 14:22:57 +03:00
|
|
|
}
|
|
|
|
return end, nil
|
|
|
|
}
|