summaryrefslogtreecommitdiff
path: root/vendor/github.com/goccy/go-json/internal/decoder/func.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/decoder/func.go')
-rw-r--r--vendor/github.com/goccy/go-json/internal/decoder/func.go141
1 files changed, 141 insertions, 0 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/func.go b/vendor/github.com/goccy/go-json/internal/decoder/func.go
new file mode 100644
index 000000000..ee3563711
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/func.go
@@ -0,0 +1,141 @@
+package decoder
+
+import (
+ "bytes"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type funcDecoder struct {
+ typ *runtime.Type
+ structName string
+ fieldName string
+}
+
+func newFuncDecoder(typ *runtime.Type, structName, fieldName string) *funcDecoder {
+ fnDecoder := &funcDecoder{typ, structName, fieldName}
+ return fnDecoder
+}
+
+func (d *funcDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ s.skipWhiteSpace()
+ start := s.cursor
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ src := s.buf[start:s.cursor]
+ if len(src) > 0 {
+ switch src[0] {
+ case '"':
+ return &errors.UnmarshalTypeError{
+ Value: "string",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case '[':
+ return &errors.UnmarshalTypeError{
+ Value: "array",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case '{':
+ return &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return &errors.UnmarshalTypeError{
+ Value: "number",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ *(*unsafe.Pointer)(p) = nil
+ return nil
+ case 't':
+ if err := trueBytes(s); err == nil {
+ return &errors.UnmarshalTypeError{
+ Value: "boolean",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ }
+ case 'f':
+ if err := falseBytes(s); err == nil {
+ return &errors.UnmarshalTypeError{
+ Value: "boolean",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ }
+ }
+ }
+ return errors.ErrInvalidBeginningOfValue(s.buf[s.cursor], s.totalOffset())
+}
+
+func (d *funcDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ src := buf[start:end]
+ if len(src) > 0 {
+ switch src[0] {
+ case '"':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "string",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case '[':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "array",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case '{':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "number",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case 'n':
+ if bytes.Equal(src, nullbytes) {
+ *(*unsafe.Pointer)(p) = nil
+ return end, nil
+ }
+ case 't':
+ if err := validateTrue(buf, start); err == nil {
+ return 0, &errors.UnmarshalTypeError{
+ Value: "boolean",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ }
+ case 'f':
+ if err := validateFalse(buf, start); err == nil {
+ return 0, &errors.UnmarshalTypeError{
+ Value: "boolean",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ }
+ }
+ }
+ return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
+}