summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go
diff options
context:
space:
mode:
authorLibravatar dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2025-01-14 13:10:39 +0000
committerLibravatar GitHub <noreply@github.com>2025-01-14 13:10:39 +0000
commit4d423102c14de9e9328f1852db539d9561a3cad9 (patch)
tree6df5905f53ad7eadbfa9840939989253bfb4b199 /vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go
parent[bugfix] migration to cleanup dropped status edits (#3637) (diff)
downloadgotosocial-4d423102c14de9e9328f1852db539d9561a3cad9.tar.xz
[chore]: Bump github.com/gin-contrib/gzip from 1.0.1 to 1.1.0 (#3639)
Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.0.1 to 1.1.0. - [Release notes](https://github.com/gin-contrib/gzip/releases) - [Changelog](https://github.com/gin-contrib/gzip/blob/master/.goreleaser.yaml) - [Commits](https://github.com/gin-contrib/gzip/compare/v1.0.1...v1.1.0) --- updated-dependencies: - dependency-name: github.com/gin-contrib/gzip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go')
-rw-r--r--vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go430
1 files changed, 430 insertions, 0 deletions
diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go
new file mode 100644
index 000000000..1a2bda8f3
--- /dev/null
+++ b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/map.go
@@ -0,0 +1,430 @@
+package optdec
+
+import (
+ "encoding"
+ "encoding/json"
+ "math"
+ "reflect"
+ "unsafe"
+
+ "github.com/bytedance/sonic/internal/rt"
+)
+
+/** Decoder for most common map types: map[string]interface{}, map[string]string **/
+
+type mapEfaceDecoder struct {
+}
+
+func (d *mapEfaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
+ if node.IsNull() {
+ *(*map[string]interface{})(vp) = nil
+ return nil
+ }
+
+ return node.AsMapEface(ctx, vp)
+}
+
+type mapStringDecoder struct {
+}
+
+func (d *mapStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
+ if node.IsNull() {
+ *(*map[string]string)(vp) = nil
+ return nil
+ }
+
+ return node.AsMapString(ctx, vp)
+}
+
+/** Decoder for map with string key **/
+
+type mapStrKeyDecoder struct {
+ mapType *rt.GoMapType
+ elemDec decFunc
+ assign rt.MapStrAssign
+ typ reflect.Type
+}
+
+func (d *mapStrKeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
+ if node.IsNull() {
+ *(*unsafe.Pointer)(vp) = nil
+ return nil
+ }
+
+ obj, ok := node.AsObj()
+ if !ok {
+ return error_mismatch(node, ctx, d.mapType.Pack())
+ }
+
+ // allocate map
+ m := *(*unsafe.Pointer)(vp)
+ if m == nil {
+ m = rt.Makemap(&d.mapType.GoType, obj.Len())
+ }
+
+ var gerr error
+ next := obj.Children()
+ for i := 0; i < obj.Len(); i++ {
+ keyn := NewNode(next)
+ key, _ := keyn.AsStr(ctx)
+
+ valn := NewNode(PtrOffset(next, 1))
+ valp := d.assign(d.mapType, m, key)
+ err := d.elemDec.FromDom(valp, valn, ctx)
+ if gerr == nil && err != nil {
+ gerr = err
+ }
+ next = valn.Next()
+ }
+
+ *(*unsafe.Pointer)(vp) = m
+ return gerr
+}
+
+/** Decoder for map with int32 or int64 key **/
+
+type mapI32KeyDecoder struct {
+ mapType *rt.GoMapType
+ elemDec decFunc
+ assign rt.Map32Assign
+}
+
+func (d *mapI32KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
+ if node.IsNull() {
+ *(*unsafe.Pointer)(vp) = nil
+ return nil
+ }
+
+ obj, ok := node.AsObj()
+ if !ok {
+ return error_mismatch(node, ctx, d.mapType.Pack())
+ }
+
+ // allocate map
+ m := *(*unsafe.Pointer)(vp)
+ if m == nil {
+ m = rt.Makemap(&d.mapType.GoType, obj.Len())
+ }
+
+ next := obj.Children()
+ var gerr error
+ for i := 0; i < obj.Len(); i++ {
+ keyn := NewNode(next)
+ k, ok := keyn.ParseI64(ctx)
+ if !ok || k > math.MaxInt32 || k < math.MinInt32 {
+ if gerr == nil {
+ gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
+ }
+ valn := NewNode(PtrOffset(next, 1))
+ next = valn.Next()
+ continue
+ }
+
+ key := int32(k)
+ ku32 := *(*uint32)(unsafe.Pointer(&key))
+ valn := NewNode(PtrOffset(next, 1))
+ valp := d.assign(d.mapType, m, ku32)
+ err := d.elemDec.FromDom(valp, valn, ctx)
+ if gerr == nil && err != nil {
+ gerr = err
+ }
+
+ next = valn.Next()
+ }
+
+ *(*unsafe.Pointer)(vp) = m
+ return gerr
+}
+
+type mapI64KeyDecoder struct {
+ mapType *rt.GoMapType
+ elemDec decFunc
+ assign rt.Map64Assign
+}
+
+func (d *mapI64KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
+ if node.IsNull() {
+ *(*unsafe.Pointer)(vp) = nil
+ return nil
+ }
+
+ obj, ok := node.AsObj()
+ if !ok {
+ return error_mismatch(node, ctx, d.mapType.Pack())
+ }
+
+ // allocate map
+ m := *(*unsafe.Pointer)(vp)
+ if m == nil {
+ m = rt.Makemap(&d.mapType.GoType, obj.Len())
+ }
+
+ var gerr error
+ next := obj.Children()
+ for i := 0; i < obj.Len(); i++ {
+ keyn := NewNode(next)
+ key, ok := keyn.ParseI64(ctx)
+
+ if !ok {
+ if gerr == nil {
+ gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
+ }
+ valn := NewNode(PtrOffset(next, 1))
+ next = valn.Next()
+ continue
+ }
+
+ ku64 := *(*uint64)(unsafe.Pointer(&key))
+ valn := NewNode(PtrOffset(next, 1))
+ valp := d.assign(d.mapType, m, ku64)
+ err := d.elemDec.FromDom(valp, valn, ctx)
+ if gerr == nil && err != nil {
+ gerr = err
+ }
+ next = valn.Next()
+ }
+
+ *(*unsafe.Pointer)(vp) = m
+ return gerr
+}
+
+/** Decoder for map with unt32 or uint64 key **/
+
+type mapU32KeyDecoder struct {
+ mapType *rt.GoMapType
+ elemDec decFunc
+ assign rt.Map32Assign
+}
+
+func (d *mapU32KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
+ if node.IsNull() {
+ *(*unsafe.Pointer)(vp) = nil
+ return nil
+ }
+
+ obj, ok := node.AsObj()
+ if !ok {
+ return error_mismatch(node, ctx, d.mapType.Pack())
+ }
+
+ // allocate map
+ m := *(*unsafe.Pointer)(vp)
+ if m == nil {
+ m = rt.Makemap(&d.mapType.GoType, obj.Len())
+ }
+
+ var gerr error
+ next := obj.Children()
+ for i := 0; i < obj.Len(); i++ {
+ keyn := NewNode(next)
+ k, ok := keyn.ParseU64(ctx)
+ if !ok || k > math.MaxUint32 {
+ if gerr == nil {
+ gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
+ }
+ valn := NewNode(PtrOffset(next, 1))
+ next = valn.Next()
+ continue
+ }
+
+ key := uint32(k)
+ valn := NewNode(PtrOffset(next, 1))
+ valp := d.assign(d.mapType, m, key)
+ err := d.elemDec.FromDom(valp, valn, ctx)
+ if gerr == nil && err != nil {
+ gerr = err
+ }
+ next = valn.Next()
+ }
+
+ *(*unsafe.Pointer)(vp) = m
+ return gerr
+}
+
+type mapU64KeyDecoder struct {
+ mapType *rt.GoMapType
+ elemDec decFunc
+ assign rt.Map64Assign
+}
+
+func (d *mapU64KeyDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
+ if node.IsNull() {
+ *(*unsafe.Pointer)(vp) = nil
+ return nil
+ }
+
+ obj, ok := node.AsObj()
+ if !ok {
+ return error_mismatch(node, ctx, d.mapType.Pack())
+ }
+ // allocate map
+ m := *(*unsafe.Pointer)(vp)
+ if m == nil {
+ m = rt.Makemap(&d.mapType.GoType, obj.Len())
+ }
+
+ var gerr error
+ next := obj.Children()
+ for i := 0; i < obj.Len(); i++ {
+ keyn := NewNode(next)
+ key, ok := keyn.ParseU64(ctx)
+ if !ok {
+ if gerr == nil {
+ gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
+ }
+ valn := NewNode(PtrOffset(next, 1))
+ next = valn.Next()
+ continue
+ }
+
+ valn := NewNode(PtrOffset(next, 1))
+ valp := d.assign(d.mapType, m, key)
+ err := d.elemDec.FromDom(valp, valn, ctx)
+ if gerr == nil && err != nil {
+ gerr = err
+ }
+ next = valn.Next()
+ }
+
+ *(*unsafe.Pointer)(vp) = m
+ return gerr
+}
+
+/** Decoder for generic cases */
+
+type decKey func(dec *mapDecoder, raw string, ctx *context) (interface{}, error)
+
+func decodeKeyU8(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
+ key, err := Unquote(raw)
+ if err != nil {
+ return nil, err
+ }
+ ret, err := ParseU64(key)
+ if err != nil {
+ return nil, err
+ }
+ if ret > math.MaxUint8 {
+ return nil, error_value(key, dec.mapType.Key.Pack())
+ }
+ return uint8(ret), nil
+}
+
+func decodeKeyU16(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
+ key, err := Unquote(raw)
+ if err != nil {
+ return nil, err
+ }
+ ret, err := ParseU64(key)
+ if err != nil {
+ return nil, err
+ }
+ if ret > math.MaxUint16 {
+ return nil, error_value(key, dec.mapType.Key.Pack())
+ }
+ return uint16(ret), nil
+}
+
+func decodeKeyI8(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
+ key, err := Unquote(raw)
+ if err != nil {
+ return nil, err
+ }
+ ret, err := ParseI64(key)
+ if err != nil {
+ return nil, err
+ }
+ if ret > math.MaxInt8 || ret < math.MinInt8 {
+ return nil, error_value(key, dec.mapType.Key.Pack())
+ }
+ return int8(ret), nil
+}
+
+func decodeKeyI16(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
+ key, err := Unquote(raw)
+ if err != nil {
+ return nil, err
+ }
+ ret, err := ParseI64(key)
+ if err != nil {
+ return nil, err
+ }
+ if ret > math.MaxInt16 || ret < math.MinInt16 {
+ return nil, error_value(key, dec.mapType.Key.Pack())
+ }
+ return int16(ret), nil
+}
+
+func decodeKeyJSONUnmarshaler(dec *mapDecoder, raw string, _ *context) (interface{}, error) {
+ ret := reflect.New(dec.mapType.Key.Pack()).Interface()
+ err := ret.(json.Unmarshaler).UnmarshalJSON([]byte(raw))
+ if err != nil {
+ return nil, err
+ }
+ return ret, nil
+}
+
+func decodeKeyTextUnmarshaler(dec *mapDecoder, raw string, ctx *context) (interface{}, error) {
+ key, err := Unquote(raw)
+ if err != nil {
+ return nil, err
+ }
+ ret := reflect.New(dec.mapType.Key.Pack()).Interface()
+ err = ret.(encoding.TextUnmarshaler).UnmarshalText([]byte(key))
+ if err != nil {
+ return nil, err
+ }
+ return ret, nil
+}
+
+type mapDecoder struct {
+ mapType *rt.GoMapType
+ keyDec decKey
+ elemDec decFunc
+}
+
+func (d *mapDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
+ if node.IsNull() {
+ *(*unsafe.Pointer)(vp) = nil
+ return nil
+ }
+
+ obj, ok := node.AsObj()
+ if !ok {
+ return error_mismatch(node, ctx, d.mapType.Pack())
+ }
+
+ // allocate map
+ m := *(*unsafe.Pointer)(vp)
+ if m == nil {
+ m = rt.Makemap(&d.mapType.GoType, obj.Len())
+ }
+
+ next := obj.Children()
+ var gerr error
+ for i := 0; i < obj.Len(); i++ {
+ keyn := NewNode(next)
+ raw := keyn.AsRaw(ctx)
+ key, err := d.keyDec(d, raw, ctx)
+ if err != nil {
+ if gerr == nil {
+ gerr = error_mismatch(keyn, ctx, d.mapType.Pack())
+ }
+ valn := NewNode(PtrOffset(next, 1))
+ next = valn.Next()
+ continue
+ }
+
+ valn := NewNode(PtrOffset(next, 1))
+ keyp := rt.UnpackEface(key).Value
+ valp := rt.Mapassign(d.mapType, m, keyp)
+ err = d.elemDec.FromDom(valp, valn, ctx)
+ if gerr == nil && err != nil {
+ gerr = err
+ }
+
+ next = valn.Next()
+ }
+
+ *(*unsafe.Pointer)(vp) = m
+ return gerr
+}