summaryrefslogtreecommitdiff
path: root/vendor/github.com/goccy/go-json/internal/decoder/map.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/decoder/map.go')
-rw-r--r--vendor/github.com/goccy/go-json/internal/decoder/map.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/map.go b/vendor/github.com/goccy/go-json/internal/decoder/map.go
index cb55ef006..7a6eea34f 100644
--- a/vendor/github.com/goccy/go-json/internal/decoder/map.go
+++ b/vendor/github.com/goccy/go-json/internal/decoder/map.go
@@ -185,3 +185,96 @@ func (d *mapDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P
cursor++
}
}
+
+func (d *mapDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ buf := ctx.Buf
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+
+ cursor = skipWhiteSpace(buf, cursor)
+ buflen := int64(len(buf))
+ if buflen < 2 {
+ return nil, 0, errors.ErrExpected("{} for map", cursor)
+ }
+ switch buf[cursor] {
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return [][]byte{nullbytes}, cursor, nil
+ case '{':
+ default:
+ return nil, 0, errors.ErrExpected("{ character for map value", cursor)
+ }
+ cursor++
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == '}' {
+ cursor++
+ return nil, cursor, nil
+ }
+ keyDecoder, ok := d.keyDecoder.(*stringDecoder)
+ if !ok {
+ return nil, 0, &errors.UnmarshalTypeError{
+ Value: "string",
+ Type: reflect.TypeOf(""),
+ Offset: cursor,
+ Struct: d.structName,
+ Field: d.fieldName,
+ }
+ }
+ ret := [][]byte{}
+ for {
+ key, keyCursor, err := keyDecoder.decodeByte(buf, cursor)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = skipWhiteSpace(buf, keyCursor)
+ if buf[cursor] != ':' {
+ return nil, 0, errors.ErrExpected("colon after object key", cursor)
+ }
+ cursor++
+ child, found, err := ctx.Option.Path.Field(string(key))
+ if err != nil {
+ return nil, 0, err
+ }
+ if found {
+ if child != nil {
+ oldPath := ctx.Option.Path.node
+ ctx.Option.Path.node = child
+ paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ ctx.Option.Path.node = oldPath
+ ret = append(ret, paths...)
+ cursor = c
+ } else {
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ ret = append(ret, buf[start:end])
+ cursor = end
+ }
+ } else {
+ c, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = c
+ }
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == '}' {
+ cursor++
+ return ret, cursor, nil
+ }
+ if buf[cursor] != ',' {
+ return nil, 0, errors.ErrExpected("comma after object value", cursor)
+ }
+ cursor++
+ }
+}