summaryrefslogtreecommitdiff
path: root/vendor/github.com/goccy/go-json/internal/decoder/array.go
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2021-09-10 14:42:14 +0200
committerLibravatar GitHub <noreply@github.com>2021-09-10 14:42:14 +0200
commitf2e5bedea6fb93fbbf68ed8f7153c353cc57a9f0 (patch)
tree475ae9e7470d0df670ab2a59dce351cd1d07498a /vendor/github.com/goccy/go-json/internal/decoder/array.go
parentfixes + db changes (#204) (diff)
downloadgotosocial-f2e5bedea6fb93fbbf68ed8f7153c353cc57a9f0.tar.xz
migrate go version to 1.17 (#203)
* migrate go version to 1.17 * update contributing
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/decoder/array.go')
-rw-r--r--vendor/github.com/goccy/go-json/internal/decoder/array.go169
1 files changed, 169 insertions, 0 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/array.go b/vendor/github.com/goccy/go-json/internal/decoder/array.go
new file mode 100644
index 000000000..21f1fd585
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/array.go
@@ -0,0 +1,169 @@
+package decoder
+
+import (
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type arrayDecoder struct {
+ elemType *runtime.Type
+ size uintptr
+ valueDecoder Decoder
+ alen int
+ structName string
+ fieldName string
+ zeroValue unsafe.Pointer
+}
+
+func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder {
+ zeroValue := *(*unsafe.Pointer)(unsafe_New(elemType))
+ return &arrayDecoder{
+ valueDecoder: dec,
+ elemType: elemType,
+ size: elemType.Size(),
+ alen: alen,
+ structName: structName,
+ fieldName: fieldName,
+ zeroValue: zeroValue,
+ }
+}
+
+func (d *arrayDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+
+ for {
+ switch s.char() {
+ case ' ', '\n', '\t', '\r':
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ return nil
+ case '[':
+ idx := 0
+ s.cursor++
+ if s.skipWhiteSpace() == ']' {
+ for idx < d.alen {
+ *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
+ idx++
+ }
+ s.cursor++
+ return nil
+ }
+ for {
+ if idx < d.alen {
+ if err := d.valueDecoder.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)); err != nil {
+ return err
+ }
+ } else {
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ }
+ idx++
+ switch s.skipWhiteSpace() {
+ case ']':
+ for idx < d.alen {
+ *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
+ idx++
+ }
+ s.cursor++
+ return nil
+ case ',':
+ s.cursor++
+ continue
+ case nul:
+ if s.read() {
+ s.cursor++
+ continue
+ }
+ goto ERROR
+ default:
+ goto ERROR
+ }
+ }
+ case nul:
+ if s.read() {
+ continue
+ }
+ goto ERROR
+ default:
+ goto ERROR
+ }
+ s.cursor++
+ }
+ERROR:
+ return errors.ErrUnexpectedEndOfJSON("array", s.totalOffset())
+}
+
+func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+
+ for {
+ switch buf[cursor] {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ return cursor, nil
+ case '[':
+ idx := 0
+ cursor++
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == ']' {
+ for idx < d.alen {
+ *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
+ idx++
+ }
+ cursor++
+ return cursor, nil
+ }
+ for {
+ if idx < d.alen {
+ c, err := d.valueDecoder.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size))
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ } else {
+ c, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ }
+ idx++
+ cursor = skipWhiteSpace(buf, cursor)
+ switch buf[cursor] {
+ case ']':
+ for idx < d.alen {
+ *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
+ idx++
+ }
+ cursor++
+ return cursor, nil
+ case ',':
+ cursor++
+ continue
+ default:
+ return 0, errors.ErrInvalidCharacter(buf[cursor], "array", cursor)
+ }
+ }
+ default:
+ return 0, errors.ErrUnexpectedEndOfJSON("array", cursor)
+ }
+ }
+}