mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-12-26 17:10:32 +00:00
[chore]: Bump github.com/gin-contrib/cors from 1.5.0 to 1.7.0 (#2745)
This commit is contained in:
parent
4c155aa847
commit
e24efcac8b
158 changed files with 11727 additions and 4290 deletions
26
go.mod
26
go.mod
|
@ -27,7 +27,7 @@ require (
|
||||||
github.com/buckket/go-blurhash v1.1.0
|
github.com/buckket/go-blurhash v1.1.0
|
||||||
github.com/coreos/go-oidc/v3 v3.9.0
|
github.com/coreos/go-oidc/v3 v3.9.0
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
github.com/gin-contrib/cors v1.5.0
|
github.com/gin-contrib/cors v1.7.0
|
||||||
github.com/gin-contrib/gzip v0.0.6
|
github.com/gin-contrib/gzip v0.0.6
|
||||||
github.com/gin-contrib/sessions v0.0.5
|
github.com/gin-contrib/sessions v0.0.5
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
|
@ -69,9 +69,9 @@ require (
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.20.0
|
go.opentelemetry.io/otel/sdk/metric v1.20.0
|
||||||
go.opentelemetry.io/otel/trace v1.20.0
|
go.opentelemetry.io/otel/trace v1.20.0
|
||||||
go.uber.org/automaxprocs v1.5.3
|
go.uber.org/automaxprocs v1.5.3
|
||||||
golang.org/x/crypto v0.20.0
|
golang.org/x/crypto v0.21.0
|
||||||
golang.org/x/image v0.15.0
|
golang.org/x/image v0.15.0
|
||||||
golang.org/x/net v0.21.0
|
golang.org/x/net v0.22.0
|
||||||
golang.org/x/oauth2 v0.17.0
|
golang.org/x/oauth2 v0.17.0
|
||||||
golang.org/x/text v0.14.0
|
golang.org/x/text v0.14.0
|
||||||
gopkg.in/mcuadros/go-syslog.v2 v2.3.0
|
gopkg.in/mcuadros/go-syslog.v2 v2.3.0
|
||||||
|
@ -91,11 +91,11 @@ require (
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bytedance/sonic v1.10.1 // indirect
|
github.com/bytedance/sonic v1.11.2 // indirect
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||||
github.com/chenzhuoyu/iasm v0.9.0 // indirect
|
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||||
github.com/cilium/ebpf v0.9.1 // indirect
|
github.com/cilium/ebpf v0.9.1 // indirect
|
||||||
github.com/containerd/cgroups/v3 v3.0.1 // indirect
|
github.com/containerd/cgroups/v3 v3.0.1 // indirect
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||||
|
@ -110,7 +110,7 @@ require (
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-errors/errors v1.4.1 // indirect
|
github.com/go-errors/errors v1.4.1 // indirect
|
||||||
github.com/go-fed/httpsig v1.1.0 // indirect
|
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||||
|
@ -130,7 +130,7 @@ require (
|
||||||
github.com/go-openapi/validate v0.22.1 // indirect
|
github.com/go-openapi/validate v0.22.1 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.15.5 // indirect
|
github.com/go-playground/validator/v10 v10.19.0 // indirect
|
||||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20211206191508-7fd73a941850 // indirect
|
github.com/go-xmlfmt/xmlfmt v0.0.0-20211206191508-7fd73a941850 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
github.com/godbus/dbus/v5 v5.0.4 // indirect
|
github.com/godbus/dbus/v5 v5.0.4 // indirect
|
||||||
|
@ -156,10 +156,10 @@ require (
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
github.com/klauspost/compress v1.17.4 // indirect
|
github.com/klauspost/compress v1.17.4 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/leodido/go-urn v1.2.4 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
@ -198,7 +198,7 @@ require (
|
||||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
||||||
github.com/toqueteos/webbrowser v1.2.0 // indirect
|
github.com/toqueteos/webbrowser v1.2.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
github.com/uptrace/opentelemetry-go-extra/otelsql v0.2.3 // indirect
|
github.com/uptrace/opentelemetry-go-extra/otelsql v0.2.3 // indirect
|
||||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
|
@ -207,17 +207,17 @@ require (
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/arch v0.5.0 // indirect
|
golang.org/x/arch v0.7.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
|
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/mod v0.14.0 // indirect
|
||||||
golang.org/x/sync v0.6.0 // indirect
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
golang.org/x/sys v0.17.0 // indirect
|
golang.org/x/sys v0.18.0 // indirect
|
||||||
golang.org/x/tools v0.17.0 // indirect
|
golang.org/x/tools v0.17.0 // indirect
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
|
||||||
google.golang.org/grpc v1.59.0 // indirect
|
google.golang.org/grpc v1.59.0 // indirect
|
||||||
google.golang.org/protobuf v1.31.0 // indirect
|
google.golang.org/protobuf v1.33.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
lukechampine.com/uint128 v1.2.0 // indirect
|
lukechampine.com/uint128 v1.2.0 // indirect
|
||||||
|
|
56
go.sum
56
go.sum
|
@ -105,8 +105,8 @@ github.com/buckket/go-blurhash v1.1.0 h1:X5M6r0LIvwdvKiUtiNcRL2YlmOfMzYobI3VCKCZ
|
||||||
github.com/buckket/go-blurhash v1.1.0/go.mod h1:aT2iqo5W9vu9GpyoLErKfTHwgODsZp3bQfXjXJUxNb8=
|
github.com/buckket/go-blurhash v1.1.0/go.mod h1:aT2iqo5W9vu9GpyoLErKfTHwgODsZp3bQfXjXJUxNb8=
|
||||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||||
github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc=
|
github.com/bytedance/sonic v1.11.2 h1:ywfwo0a/3j9HR8wsYGWsIWl2mvRsI950HyoxiBERw5A=
|
||||||
github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
github.com/bytedance/sonic v1.11.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
@ -116,8 +116,9 @@ github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||||
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
|
||||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||||
|
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
|
||||||
|
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
|
@ -178,12 +179,12 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8=
|
github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8=
|
||||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||||
github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk=
|
github.com/gin-contrib/cors v1.7.0 h1:wZX2wuZ0o7rV2/1i7gb4Jn+gW7HBqaP91fizJkBUJOA=
|
||||||
github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI=
|
github.com/gin-contrib/cors v1.7.0/go.mod h1:cI+h6iOAyxKRtUtC6iF/Si1KSFvGm/gK+kshxlCi8ro=
|
||||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||||
github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE=
|
github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE=
|
||||||
|
@ -262,8 +263,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||||
github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24=
|
github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
|
||||||
github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0=
|
github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-swagger/go-swagger v0.30.5 h1:SQ2+xSonWjjoEMOV5tcOnZJVlfyUfCBhGQGArS1b9+U=
|
github.com/go-swagger/go-swagger v0.30.5 h1:SQ2+xSonWjjoEMOV5tcOnZJVlfyUfCBhGQGArS1b9+U=
|
||||||
|
@ -451,8 +452,8 @@ github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW
|
||||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
@ -467,8 +468,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
@ -616,7 +617,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
@ -670,8 +670,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA=
|
github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA=
|
||||||
github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI=
|
github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI=
|
||||||
github.com/uptrace/bun v1.1.17 h1:qxBaEIo0hC/8O3O6GrMDKxqyT+mw5/s0Pn/n6xjyGIk=
|
github.com/uptrace/bun v1.1.17 h1:qxBaEIo0hC/8O3O6GrMDKxqyT+mw5/s0Pn/n6xjyGIk=
|
||||||
|
@ -762,8 +762,8 @@ go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y=
|
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
||||||
golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
|
@ -777,8 +777,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -851,8 +851,8 @@ golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -923,13 +923,13 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -1083,8 +1083,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
68
vendor/github.com/bytedance/sonic/README.md
generated
vendored
68
vendor/github.com/bytedance/sonic/README.md
generated
vendored
|
@ -5,18 +5,27 @@ English | [中文](README_ZH_CN.md)
|
||||||
A blazingly fast JSON serializing & deserializing library, accelerated by JIT (just-in-time compiling) and SIMD (single-instruction-multiple-data).
|
A blazingly fast JSON serializing & deserializing library, accelerated by JIT (just-in-time compiling) and SIMD (single-instruction-multiple-data).
|
||||||
|
|
||||||
## Requirement
|
## Requirement
|
||||||
- Go 1.16~1.21
|
|
||||||
|
- Go 1.16~1.22
|
||||||
- Linux / MacOS / Windows(need go1.17 above)
|
- Linux / MacOS / Windows(need go1.17 above)
|
||||||
- Amd64 ARCH
|
- Amd64 ARCH
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Runtime object binding without code generation
|
- Runtime object binding without code generation
|
||||||
- Complete APIs for JSON value manipulation
|
- Complete APIs for JSON value manipulation
|
||||||
- Fast, fast, fast!
|
- Fast, fast, fast!
|
||||||
|
|
||||||
|
## APIs
|
||||||
|
|
||||||
|
see [go.dev](https://pkg.go.dev/github.com/bytedance/sonic)
|
||||||
|
|
||||||
## Benchmarks
|
## Benchmarks
|
||||||
|
|
||||||
For **all sizes** of json and **all scenarios** of usage, **Sonic performs best**.
|
For **all sizes** of json and **all scenarios** of usage, **Sonic performs best**.
|
||||||
|
|
||||||
- [Medium](https://github.com/bytedance/sonic/blob/main/decoder/testdata_test.go#L19) (13KB, 300+ key, 6 layers)
|
- [Medium](https://github.com/bytedance/sonic/blob/main/decoder/testdata_test.go#L19) (13KB, 300+ key, 6 layers)
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
goversion: 1.17.1
|
goversion: 1.17.1
|
||||||
goos: darwin
|
goos: darwin
|
||||||
|
@ -81,6 +90,7 @@ BenchmarkLoadNode_Parallel/LoadAll()-16 5493 ns/op 2370.6
|
||||||
BenchmarkLoadNode/Interface()-16 17722 ns/op 734.85 MB/s 13323 B/op 88 allocs/op
|
BenchmarkLoadNode/Interface()-16 17722 ns/op 734.85 MB/s 13323 B/op 88 allocs/op
|
||||||
BenchmarkLoadNode_Parallel/Interface()-16 10330 ns/op 1260.70 MB/s 15178 B/op 88 allocs/op
|
BenchmarkLoadNode_Parallel/Interface()-16 10330 ns/op 1260.70 MB/s 15178 B/op 88 allocs/op
|
||||||
```
|
```
|
||||||
|
|
||||||
- [Small](https://github.com/bytedance/sonic/blob/main/testdata/small.go) (400B, 11 keys, 3 layers)
|
- [Small](https://github.com/bytedance/sonic/blob/main/testdata/small.go) (400B, 11 keys, 3 layers)
|
||||||
![small benchmarks](./docs/imgs/bench-small.png)
|
![small benchmarks](./docs/imgs/bench-small.png)
|
||||||
- [Large](https://github.com/bytedance/sonic/blob/main/testdata/twitter.json) (635KB, 10000+ key, 6 layers)
|
- [Large](https://github.com/bytedance/sonic/blob/main/testdata/twitter.json) (635KB, 10000+ key, 6 layers)
|
||||||
|
@ -89,6 +99,7 @@ BenchmarkLoadNode_Parallel/Interface()-16 10330 ns/op 1260.7
|
||||||
See [bench.sh](https://github.com/bytedance/sonic/blob/main/scripts/bench.sh) for benchmark codes.
|
See [bench.sh](https://github.com/bytedance/sonic/blob/main/scripts/bench.sh) for benchmark codes.
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
See [INTRODUCTION.md](./docs/INTRODUCTION.md).
|
See [INTRODUCTION.md](./docs/INTRODUCTION.md).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
@ -96,6 +107,7 @@ See [INTRODUCTION.md](./docs/INTRODUCTION.md).
|
||||||
### Marshal/Unmarshal
|
### Marshal/Unmarshal
|
||||||
|
|
||||||
Default behaviors are mostly consistent with `encoding/json`, except HTML escaping form (see [Escape HTML](https://github.com/bytedance/sonic/blob/main/README.md#escape-html)) and `SortKeys` feature (optional support see [Sort Keys](https://github.com/bytedance/sonic/blob/main/README.md#sort-keys)) that is **NOT** in conformity to [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259).
|
Default behaviors are mostly consistent with `encoding/json`, except HTML escaping form (see [Escape HTML](https://github.com/bytedance/sonic/blob/main/README.md#escape-html)) and `SortKeys` feature (optional support see [Sort Keys](https://github.com/bytedance/sonic/blob/main/README.md#sort-keys)) that is **NOT** in conformity to [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259).
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -107,8 +119,11 @@ err := sonic.Unmarshal(output, &data)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Streaming IO
|
### Streaming IO
|
||||||
Sonic supports decoding json from `io.Reader` or encoding objects into `io.`Writer`, aims at handling multiple values as well as reducing memory consumption.
|
|
||||||
|
Sonic supports decoding json from `io.Reader` or encoding objects into `io.Writer`, aims at handling multiple values as well as reducing memory consumption.
|
||||||
|
|
||||||
- encoder
|
- encoder
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var o1 = map[string]interface{}{
|
var o1 = map[string]interface{}{
|
||||||
"a": "b",
|
"a": "b",
|
||||||
|
@ -123,7 +138,9 @@ fmt.Println(w.String())
|
||||||
// {"a":"b"}
|
// {"a":"b"}
|
||||||
// 1
|
// 1
|
||||||
```
|
```
|
||||||
|
|
||||||
- decoder
|
- decoder
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var o = map[string]interface{}{}
|
var o = map[string]interface{}{}
|
||||||
var r = strings.NewReader(`{"a":"b"}{"1":"2"}`)
|
var r = strings.NewReader(`{"a":"b"}{"1":"2"}`)
|
||||||
|
@ -136,6 +153,7 @@ fmt.Printf("%+v", o)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Use Number/Use Int64
|
### Use Number/Use Int64
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic/decoder"
|
import "github.com/bytedance/sonic/decoder"
|
||||||
|
|
||||||
|
@ -164,7 +182,9 @@ fm := root.Interface().(float64) // jn == jm
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sort Keys
|
### Sort Keys
|
||||||
|
|
||||||
On account of the performance loss from sorting (roughly 10%), sonic doesn't enable this feature by default. If your component depends on it to work (like [zstd](https://github.com/facebook/zstd)), Use it like this:
|
On account of the performance loss from sorting (roughly 10%), sonic doesn't enable this feature by default. If your component depends on it to work (like [zstd](https://github.com/facebook/zstd)), Use it like this:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
import "github.com/bytedance/sonic/encoder"
|
import "github.com/bytedance/sonic/encoder"
|
||||||
|
@ -177,19 +197,26 @@ v, err := encoder.Encode(m, encoder.SortMapKeys)
|
||||||
var root := sonic.Get(JSON)
|
var root := sonic.Get(JSON)
|
||||||
err := root.SortKeys()
|
err := root.SortKeys()
|
||||||
```
|
```
|
||||||
|
|
||||||
### Escape HTML
|
### Escape HTML
|
||||||
|
|
||||||
On account of the performance loss (roughly 15%), sonic doesn't enable this feature by default. You can use `encoder.EscapeHTML` option to open this feature (align with `encoding/json.HTMLEscape`).
|
On account of the performance loss (roughly 15%), sonic doesn't enable this feature by default. You can use `encoder.EscapeHTML` option to open this feature (align with `encoding/json.HTMLEscape`).
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
v := map[string]string{"&&":"<>"}
|
v := map[string]string{"&&":"<>"}
|
||||||
ret, err := Encode(v, EscapeHTML) // ret == `{"\u0026\u0026":{"X":"\u003c\u003e"}}`
|
ret, err := Encode(v, EscapeHTML) // ret == `{"\u0026\u0026":{"X":"\u003c\u003e"}}`
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compact Format
|
### Compact Format
|
||||||
|
|
||||||
Sonic encodes primitive objects (struct/map...) as compact-format JSON by default, except marshaling `json.RawMessage` or `json.Marshaler`: sonic ensures validating their output JSON but **DONOT** compacting them for performance concerns. We provide the option `encoder.CompactMarshaler` to add compacting process.
|
Sonic encodes primitive objects (struct/map...) as compact-format JSON by default, except marshaling `json.RawMessage` or `json.Marshaler`: sonic ensures validating their output JSON but **DONOT** compacting them for performance concerns. We provide the option `encoder.CompactMarshaler` to add compacting process.
|
||||||
|
|
||||||
### Print Error
|
### Print Error
|
||||||
|
|
||||||
If there invalid syntax in input JSON, sonic will return `decoder.SyntaxError`, which supports pretty-printing of error position
|
If there invalid syntax in input JSON, sonic will return `decoder.SyntaxError`, which supports pretty-printing of error position
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
import "github.com/bytedance/sonic/decoder"
|
import "github.com/bytedance/sonic/decoder"
|
||||||
|
@ -215,7 +242,9 @@ if err != nil {
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Mismatched Types [Sonic v1.6.0]
|
#### Mismatched Types [Sonic v1.6.0]
|
||||||
|
|
||||||
If there a **mismatch-typed** value for a given key, sonic will report `decoder.MismatchTypeError` (if there are many, report the last one), but still skip wrong the value and keep decoding next JSON.
|
If there a **mismatch-typed** value for a given key, sonic will report `decoder.MismatchTypeError` (if there are many, report the last one), but still skip wrong the value and keep decoding next JSON.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
import "github.com/bytedance/sonic/decoder"
|
import "github.com/bytedance/sonic/decoder"
|
||||||
|
@ -228,10 +257,15 @@ err := UnmarshalString(`{"A":"1","B":1}`, &data)
|
||||||
println(err.Error()) // Mismatch type int with value string "at index 5: mismatched type with value\n\n\t{\"A\":\"1\",\"B\":1}\n\t.....^.........\n"
|
println(err.Error()) // Mismatch type int with value string "at index 5: mismatched type with value\n\n\t{\"A\":\"1\",\"B\":1}\n\t.....^.........\n"
|
||||||
fmt.Printf("%+v", data) // {A:0 B:1}
|
fmt.Printf("%+v", data) // {A:0 B:1}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ast.Node
|
### Ast.Node
|
||||||
|
|
||||||
Sonic/ast.Node is a completely self-contained AST for JSON. It implements serialization and deserialization both and provides robust APIs for obtaining and modification of generic data.
|
Sonic/ast.Node is a completely self-contained AST for JSON. It implements serialization and deserialization both and provides robust APIs for obtaining and modification of generic data.
|
||||||
|
|
||||||
#### Get/Index
|
#### Get/Index
|
||||||
|
|
||||||
Search partial JSON by given paths, which must be non-negative integer or string, or nil
|
Search partial JSON by given paths, which must be non-negative integer or string, or nil
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -245,10 +279,13 @@ raw := root.Raw() // == string(input)
|
||||||
root, err := sonic.Get(input, "key1", 1, "key2")
|
root, err := sonic.Get(input, "key1", 1, "key2")
|
||||||
sub := root.Get("key3").Index(2).Int64() // == 3
|
sub := root.Get("key3").Index(2).Int64() // == 3
|
||||||
```
|
```
|
||||||
|
|
||||||
**Tip**: since `Index()` uses offset to locate data, which is much faster than scanning like `Get()`, we suggest you use it as much as possible. And sonic also provides another API `IndexOrGet()` to underlying use offset as well as ensure the key is matched.
|
**Tip**: since `Index()` uses offset to locate data, which is much faster than scanning like `Get()`, we suggest you use it as much as possible. And sonic also provides another API `IndexOrGet()` to underlying use offset as well as ensure the key is matched.
|
||||||
|
|
||||||
#### Set/Unset
|
#### Set/Unset
|
||||||
|
|
||||||
Modify the json content by Set()/Unset()
|
Modify the json content by Set()/Unset()
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -265,7 +302,9 @@ println(root.Get("key4").Check()) // "value not exist"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Serialize
|
#### Serialize
|
||||||
|
|
||||||
To encode `ast.Node` as json, use `MarshalJson()` or `json.Marshal()` (MUST pass the node's pointer)
|
To encode `ast.Node` as json, use `MarshalJson()` or `json.Marshal()` (MUST pass the node's pointer)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -279,6 +318,7 @@ println(string(buf) == string(exp)) // true
|
||||||
```
|
```
|
||||||
|
|
||||||
#### APIs
|
#### APIs
|
||||||
|
|
||||||
- validation: `Check()`, `Error()`, `Valid()`, `Exist()`
|
- validation: `Check()`, `Error()`, `Valid()`, `Exist()`
|
||||||
- searching: `Index()`, `Get()`, `IndexPair()`, `IndexOrGet()`, `GetByPath()`
|
- searching: `Index()`, `Get()`, `IndexPair()`, `IndexOrGet()`, `GetByPath()`
|
||||||
- go-type casting: `Int64()`, `Float64()`, `String()`, `Number()`, `Bool()`, `Map[UseNumber|UseNode]()`, `Array[UseNumber|UseNode]()`, `Interface[UseNumber|UseNode]()`
|
- go-type casting: `Int64()`, `Float64()`, `String()`, `Number()`, `Bool()`, `Map[UseNumber|UseNode]()`, `Array[UseNumber|UseNode]()`, `Interface[UseNumber|UseNode]()`
|
||||||
|
@ -287,7 +327,9 @@ println(string(buf) == string(exp)) // true
|
||||||
- modification: `Set()`, `SetByIndex()`, `Add()`
|
- modification: `Set()`, `SetByIndex()`, `Add()`
|
||||||
|
|
||||||
### Ast.Visitor
|
### Ast.Visitor
|
||||||
|
|
||||||
Sonic provides an advanced API for fully parsing JSON into non-standard types (neither `struct` not `map[string]interface{}`) without using any intermediate representation (`ast.Node` or `interface{}`). For example, you might have the following types which are like `interface{}` but actually not `interface{}`:
|
Sonic provides an advanced API for fully parsing JSON into non-standard types (neither `struct` not `map[string]interface{}`) without using any intermediate representation (`ast.Node` or `interface{}`). For example, you might have the following types which are like `interface{}` but actually not `interface{}`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type UserNode interface {}
|
type UserNode interface {}
|
||||||
|
|
||||||
|
@ -302,7 +344,9 @@ type (
|
||||||
UserArray struct{ Value []UserNode }
|
UserArray struct{ Value []UserNode }
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Sonic provides the following API to return **the preorder traversal of a JSON AST**. The `ast.Visitor` is a SAX style interface which is used in some C++ JSON library. You should implement `ast.Visitor` by yourself and pass it to `ast.Preorder()` method. In your visitor you can make your custom types to represent JSON values. There may be an O(n) space container (such as stack) in your visitor to record the object / array hierarchy.
|
Sonic provides the following API to return **the preorder traversal of a JSON AST**. The `ast.Visitor` is a SAX style interface which is used in some C++ JSON library. You should implement `ast.Visitor` by yourself and pass it to `ast.Preorder()` method. In your visitor you can make your custom types to represent JSON values. There may be an O(n) space container (such as stack) in your visitor to record the object / array hierarchy.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Preorder(str string, visitor Visitor, opts *VisitorOptions) error
|
func Preorder(str string, visitor Visitor, opts *VisitorOptions) error
|
||||||
|
|
||||||
|
@ -323,12 +367,14 @@ type Visitor interface {
|
||||||
See [ast/visitor.go](https://github.com/bytedance/sonic/blob/main/ast/visitor.go) for detailed usage. We also implement a demo visitor for `UserNode` in [ast/visitor_test.go](https://github.com/bytedance/sonic/blob/main/ast/visitor_test.go).
|
See [ast/visitor.go](https://github.com/bytedance/sonic/blob/main/ast/visitor.go) for detailed usage. We also implement a demo visitor for `UserNode` in [ast/visitor_test.go](https://github.com/bytedance/sonic/blob/main/ast/visitor_test.go).
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
Sonic **DOES NOT** ensure to support all environments, due to the difficulty of developing high-performance codes. For developers who use sonic to build their applications in different environments, we have the following suggestions:
|
Sonic **DOES NOT** ensure to support all environments, due to the difficulty of developing high-performance codes. For developers who use sonic to build their applications in different environments, we have the following suggestions:
|
||||||
|
|
||||||
- Developing on **Mac M1**: Make sure you have Rosetta 2 installed on your machine, and set `GOARCH=amd64` when building your application. Rosetta 2 can automatically translate x86 binaries to arm64 binaries and run x86 applications on Mac M1.
|
- Developing on **Mac M1**: Make sure you have Rosetta 2 installed on your machine, and set `GOARCH=amd64` when building your application. Rosetta 2 can automatically translate x86 binaries to arm64 binaries and run x86 applications on Mac M1.
|
||||||
- Developing on **Linux arm64**: You can install qemu and use the `qemu-x86_64 -cpu max` command to convert x86 binaries to amr64 binaries for applications built with sonic. The qemu can achieve a similar transfer effect to Rosetta 2 on Mac M1.
|
- Developing on **Linux arm64**: You can install qemu and use the `qemu-x86_64 -cpu max` command to convert x86 binaries to amr64 binaries for applications built with sonic. The qemu can achieve a similar transfer effect to Rosetta 2 on Mac M1.
|
||||||
|
|
||||||
For developers who want to use sonic on Linux arm64 without qemu, or those who want to handle JSON strictly consistent with `encoding/json`, we provide some compatible APIs as `sonic.API`
|
For developers who want to use sonic on Linux arm64 without qemu, or those who want to handle JSON strictly consistent with `encoding/json`, we provide some compatible APIs as `sonic.API`
|
||||||
|
|
||||||
- `ConfigDefault`: the sonic's default config (`EscapeHTML=false`,`SortKeys=false`...) to run on sonic-supporting environment. It will fall back to `encoding/json` with the corresponding config, and some options like `SortKeys=false` will be invalid.
|
- `ConfigDefault`: the sonic's default config (`EscapeHTML=false`,`SortKeys=false`...) to run on sonic-supporting environment. It will fall back to `encoding/json` with the corresponding config, and some options like `SortKeys=false` will be invalid.
|
||||||
- `ConfigStd`: the std-compatible config (`EscapeHTML=true`,`SortKeys=true`...) to run on sonic-supporting environment. It will fall back to `encoding/json`.
|
- `ConfigStd`: the std-compatible config (`EscapeHTML=true`,`SortKeys=true`...) to run on sonic-supporting environment. It will fall back to `encoding/json`.
|
||||||
- `ConfigFastest`: the fastest config (`NoQuoteTextMarshaler=true`) to run on sonic-supporting environment. It will fall back to `encoding/json` with the corresponding config, and some options will be invalid.
|
- `ConfigFastest`: the fastest config (`NoQuoteTextMarshaler=true`) to run on sonic-supporting environment. It will fall back to `encoding/json` with the corresponding config, and some options will be invalid.
|
||||||
|
@ -336,7 +382,9 @@ For developers who want to use sonic on Linux arm64 without qemu, or those who w
|
||||||
## Tips
|
## Tips
|
||||||
|
|
||||||
### Pretouch
|
### Pretouch
|
||||||
|
|
||||||
Since Sonic uses [golang-asm](https://github.com/twitchyliquid64/golang-asm) as a JIT assembler, which is NOT very suitable for runtime compiling, first-hit running of a huge schema may cause request-timeout or even process-OOM. For better stability, we advise **using `Pretouch()` for huge-schema or compact-memory applications** before `Marshal()/Unmarshal()`.
|
Since Sonic uses [golang-asm](https://github.com/twitchyliquid64/golang-asm) as a JIT assembler, which is NOT very suitable for runtime compiling, first-hit running of a huge schema may cause request-timeout or even process-OOM. For better stability, we advise **using `Pretouch()` for huge-schema or compact-memory applications** before `Marshal()/Unmarshal()`.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -362,17 +410,23 @@ func init() {
|
||||||
```
|
```
|
||||||
|
|
||||||
### Copy string
|
### Copy string
|
||||||
When decoding **string values without any escaped characters**, sonic references them from the origin JSON buffer instead of mallocing a new buffer to copy. This helps a lot for CPU performance but may leave the whole JSON buffer in memory as long as the decoded objects are being used. In practice, we found the extra memory introduced by referring JSON buffer is usually 20% ~ 80% of decoded objects. Once an application holds these objects for a long time (for example, cache the decoded objects for reusing), its in-use memory on the server may go up. We provide the option `decoder.CopyString()` for users to choose not to reference the JSON buffer, which may cause a decline in CPU performance to some degree.
|
|
||||||
|
When decoding **string values without any escaped characters**, sonic references them from the origin JSON buffer instead of mallocing a new buffer to copy. This helps a lot for CPU performance but may leave the whole JSON buffer in memory as long as the decoded objects are being used. In practice, we found the extra memory introduced by referring JSON buffer is usually 20% ~ 80% of decoded objects. Once an application holds these objects for a long time (for example, cache the decoded objects for reusing), its in-use memory on the server may go up. - `Config.CopyString`/`decoder.CopyString()`: We provide the option for `Decode()` / `Unmarshal()` users to choose not to reference the JSON buffer, which may cause a decline in CPU performance to some degree.
|
||||||
|
|
||||||
|
- `GetFromStringNoCopy()`: For memory safty, `sonic.Get()` / `sonic.GetFromString()` now copies return JSON. If users want to get json more quickly and not care about memory usage, you can use `GetFromStringNoCopy()` to return a JSON direclty referenced from source.
|
||||||
|
|
||||||
### Pass string or []byte?
|
### Pass string or []byte?
|
||||||
|
|
||||||
For alignment to `encoding/json`, we provide API to pass `[]byte` as an argument, but the string-to-bytes copy is conducted at the same time considering safety, which may lose performance when the origin JSON is huge. Therefore, you can use `UnmarshalString()` and `GetFromString()` to pass a string, as long as your origin data is a string or **nocopy-cast** is safe for your []byte. We also provide API `MarshalString()` for convenient **nocopy-cast** of encoded JSON []byte, which is safe since sonic's output bytes is always duplicated and unique.
|
For alignment to `encoding/json`, we provide API to pass `[]byte` as an argument, but the string-to-bytes copy is conducted at the same time considering safety, which may lose performance when the origin JSON is huge. Therefore, you can use `UnmarshalString()` and `GetFromString()` to pass a string, as long as your origin data is a string or **nocopy-cast** is safe for your []byte. We also provide API `MarshalString()` for convenient **nocopy-cast** of encoded JSON []byte, which is safe since sonic's output bytes is always duplicated and unique.
|
||||||
|
|
||||||
### Accelerate `encoding.TextMarshaler`
|
### Accelerate `encoding.TextMarshaler`
|
||||||
|
|
||||||
To ensure data security, sonic.Encoder quotes and escapes string values from `encoding.TextMarshaler` interfaces by default, which may degrade performance much if most of your data is in form of them. We provide `encoder.NoQuoteTextMarshaler` to skip these operations, which means you **MUST** ensure their output string escaped and quoted following [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259).
|
To ensure data security, sonic.Encoder quotes and escapes string values from `encoding.TextMarshaler` interfaces by default, which may degrade performance much if most of your data is in form of them. We provide `encoder.NoQuoteTextMarshaler` to skip these operations, which means you **MUST** ensure their output string escaped and quoted following [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259).
|
||||||
|
|
||||||
|
|
||||||
### Better performance for generic data
|
### Better performance for generic data
|
||||||
|
|
||||||
In **fully-parsed** scenario, `Unmarshal()` performs better than `Get()`+`Node.Interface()`. But if you only have a part of the schema for specific json, you can combine `Get()` and `Unmarshal()` together:
|
In **fully-parsed** scenario, `Unmarshal()` performs better than `Get()`+`Node.Interface()`. But if you only have a part of the schema for specific json, you can combine `Get()` and `Unmarshal()` together:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -380,7 +434,9 @@ node, err := sonic.GetFromString(_TwitterJson, "statuses", 3, "user")
|
||||||
var user User // your partial schema...
|
var user User // your partial schema...
|
||||||
err = sonic.UnmarshalString(node.Raw(), &user)
|
err = sonic.UnmarshalString(node.Raw(), &user)
|
||||||
```
|
```
|
||||||
|
|
||||||
Even if you don't have any schema, use `ast.Node` as the container of generic values instead of `map` or `interface`:
|
Even if you don't have any schema, use `ast.Node` as the container of generic values instead of `map` or `interface`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -391,7 +447,9 @@ err = user.Check()
|
||||||
// err = user.LoadAll() // only call this when you want to use 'user' concurrently...
|
// err = user.LoadAll() // only call this when you want to use 'user' concurrently...
|
||||||
go someFunc(user)
|
go someFunc(user)
|
||||||
```
|
```
|
||||||
|
|
||||||
Why? Because `ast.Node` stores its children using `array`:
|
Why? Because `ast.Node` stores its children using `array`:
|
||||||
|
|
||||||
- `Array`'s performance is **much better** than `Map` when Inserting (Deserialize) and Scanning (Serialize) data;
|
- `Array`'s performance is **much better** than `Map` when Inserting (Deserialize) and Scanning (Serialize) data;
|
||||||
- **Hashing** (`map[x]`) is not as efficient as **Indexing** (`array[x]`), which `ast.Node` can conduct on **both array and object**;
|
- **Hashing** (`map[x]`) is not as efficient as **Indexing** (`array[x]`), which `ast.Node` can conduct on **both array and object**;
|
||||||
- Using `Interface()`/`Map()` means Sonic must parse all the underlying values, while `ast.Node` can parse them **on demand**.
|
- Using `Interface()`/`Map()` means Sonic must parse all the underlying values, while `ast.Node` can parse them **on demand**.
|
||||||
|
@ -399,6 +457,7 @@ Why? Because `ast.Node` stores its children using `array`:
|
||||||
**CAUTION:** `ast.Node` **DOESN'T** ensure concurrent security directly, due to its **lazy-load** design. However, you can call `Node.Load()`/`Node.LoadAll()` to achieve that, which may bring performance reduction while it still works faster than converting to `map` or `interface{}`
|
**CAUTION:** `ast.Node` **DOESN'T** ensure concurrent security directly, due to its **lazy-load** design. However, you can call `Node.Load()`/`Node.LoadAll()` to achieve that, which may bring performance reduction while it still works faster than converting to `map` or `interface{}`
|
||||||
|
|
||||||
### Ast.Node or Ast.Visitor?
|
### Ast.Node or Ast.Visitor?
|
||||||
|
|
||||||
For generic data, `ast.Node` should be enough for your needs in most cases.
|
For generic data, `ast.Node` should be enough for your needs in most cases.
|
||||||
|
|
||||||
However, `ast.Node` is designed for partially processing JSON string. It has some special designs such as lazy-load which might not be suitable for directly parsing the whole JSON string like `Unmarshal()`. Although `ast.Node` is better then `map` or `interface{}`, it's also a kind of intermediate representation after all if your final types are customized and you have to convert the above types to your custom types after parsing.
|
However, `ast.Node` is designed for partially processing JSON string. It has some special designs such as lazy-load which might not be suitable for directly parsing the whole JSON string like `Unmarshal()`. Although `ast.Node` is better then `map` or `interface{}`, it's also a kind of intermediate representation after all if your final types are customized and you have to convert the above types to your custom types after parsing.
|
||||||
|
@ -408,4 +467,5 @@ For better performance, in previous case the `ast.Visitor` will be the better ch
|
||||||
But `ast.Visitor` is not a very handy API. You might need to write a lot of code to implement your visitor and carefully maintain the tree hierarchy during decoding. Please read the comments in [ast/visitor.go](https://github.com/bytedance/sonic/blob/main/ast/visitor.go) carefully if you decide to use this API.
|
But `ast.Visitor` is not a very handy API. You might need to write a lot of code to implement your visitor and carefully maintain the tree hierarchy during decoding. Please read the comments in [ast/visitor.go](https://github.com/bytedance/sonic/blob/main/ast/visitor.go) carefully if you decide to use this API.
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
Sonic is a subproject of [CloudWeGo](https://www.cloudwego.io/). We are committed to building a cloud native ecosystem.
|
Sonic is a subproject of [CloudWeGo](https://www.cloudwego.io/). We are committed to building a cloud native ecosystem.
|
||||||
|
|
45
vendor/github.com/bytedance/sonic/README_ZH_CN.md
generated
vendored
45
vendor/github.com/bytedance/sonic/README_ZH_CN.md
generated
vendored
|
@ -6,10 +6,14 @@
|
||||||
|
|
||||||
## 依赖
|
## 依赖
|
||||||
|
|
||||||
- Go 1.16~1.21
|
- Go 1.16~1.22
|
||||||
- Linux / MacOS / Windows(需要 Go1.17 以上)
|
- Linux / MacOS / Windows(需要 Go1.17 以上)
|
||||||
- Amd64 架构
|
- Amd64 架构
|
||||||
|
|
||||||
|
## 接口
|
||||||
|
|
||||||
|
详见 [go.dev](https://pkg.go.dev/github.com/bytedance/sonic)
|
||||||
|
|
||||||
## 特色
|
## 特色
|
||||||
|
|
||||||
- 运行时对象绑定,无需代码生成
|
- 运行时对象绑定,无需代码生成
|
||||||
|
@ -19,7 +23,9 @@
|
||||||
## 基准测试
|
## 基准测试
|
||||||
|
|
||||||
对于**所有大小**的 json 和**所有使用场景**, **Sonic 表现均为最佳**。
|
对于**所有大小**的 json 和**所有使用场景**, **Sonic 表现均为最佳**。
|
||||||
|
|
||||||
- [中型](https://github.com/bytedance/sonic/blob/main/decoder/testdata_test.go#L19) (13kB, 300+ 键, 6 层)
|
- [中型](https://github.com/bytedance/sonic/blob/main/decoder/testdata_test.go#L19) (13kB, 300+ 键, 6 层)
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
goversion: 1.17.1
|
goversion: 1.17.1
|
||||||
goos: darwin
|
goos: darwin
|
||||||
|
@ -84,6 +90,7 @@ BenchmarkLoadNode_Parallel/LoadAll()-16 5493 ns/op 2370.6
|
||||||
BenchmarkLoadNode/Interface()-16 17722 ns/op 734.85 MB/s 13323 B/op 88 allocs/op
|
BenchmarkLoadNode/Interface()-16 17722 ns/op 734.85 MB/s 13323 B/op 88 allocs/op
|
||||||
BenchmarkLoadNode_Parallel/Interface()-16 10330 ns/op 1260.70 MB/s 15178 B/op 88 allocs/op
|
BenchmarkLoadNode_Parallel/Interface()-16 10330 ns/op 1260.70 MB/s 15178 B/op 88 allocs/op
|
||||||
```
|
```
|
||||||
|
|
||||||
- [小型](https://github.com/bytedance/sonic/blob/main/testdata/small.go) (400B, 11 个键, 3 层)
|
- [小型](https://github.com/bytedance/sonic/blob/main/testdata/small.go) (400B, 11 个键, 3 层)
|
||||||
![small benchmarks](./docs/imgs/bench-small.png)
|
![small benchmarks](./docs/imgs/bench-small.png)
|
||||||
- [大型](https://github.com/bytedance/sonic/blob/main/testdata/twitter.json) (635kB, 10000+ 个键, 6 层)
|
- [大型](https://github.com/bytedance/sonic/blob/main/testdata/twitter.json) (635kB, 10000+ 个键, 6 层)
|
||||||
|
@ -100,6 +107,7 @@ BenchmarkLoadNode_Parallel/Interface()-16 10330 ns/op 1260.7
|
||||||
### 序列化/反序列化
|
### 序列化/反序列化
|
||||||
|
|
||||||
默认的行为基本上与 `encoding/json` 相一致,除了 HTML 转义形式(参见 [Escape HTML](https://github.com/bytedance/sonic/blob/main/README.md#escape-html)) 和 `SortKeys` 功能(参见 [Sort Keys](https://github.com/bytedance/sonic/blob/main/README.md#sort-keys))**没有**遵循 [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259) 。
|
默认的行为基本上与 `encoding/json` 相一致,除了 HTML 转义形式(参见 [Escape HTML](https://github.com/bytedance/sonic/blob/main/README.md#escape-html)) 和 `SortKeys` 功能(参见 [Sort Keys](https://github.com/bytedance/sonic/blob/main/README.md#sort-keys))**没有**遵循 [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259) 。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -113,7 +121,9 @@ err := sonic.Unmarshal(output, &data)
|
||||||
### 流式输入输出
|
### 流式输入输出
|
||||||
|
|
||||||
Sonic 支持解码 `io.Reader` 中输入的 json,或将对象编码为 json 后输出至 `io.Writer`,以处理多个值并减少内存消耗。
|
Sonic 支持解码 `io.Reader` 中输入的 json,或将对象编码为 json 后输出至 `io.Writer`,以处理多个值并减少内存消耗。
|
||||||
|
|
||||||
- 编码器
|
- 编码器
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var o1 = map[string]interface{}{
|
var o1 = map[string]interface{}{
|
||||||
"a": "b",
|
"a": "b",
|
||||||
|
@ -128,7 +138,9 @@ fmt.Println(w.String())
|
||||||
// {"a":"b"}
|
// {"a":"b"}
|
||||||
// 1
|
// 1
|
||||||
```
|
```
|
||||||
|
|
||||||
- 解码器
|
- 解码器
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var o = map[string]interface{}{}
|
var o = map[string]interface{}{}
|
||||||
var r = strings.NewReader(`{"a":"b"}{"1":"2"}`)
|
var r = strings.NewReader(`{"a":"b"}{"1":"2"}`)
|
||||||
|
@ -172,6 +184,7 @@ fm := root.Interface().(float64) // jn == jm
|
||||||
### 对键排序
|
### 对键排序
|
||||||
|
|
||||||
考虑到排序带来的性能损失(约 10% ), sonic 默认不会启用这个功能。如果你的组件依赖这个行为(如 [zstd](https://github.com/facebook/zstd)) ,可以仿照下面的例子:
|
考虑到排序带来的性能损失(约 10% ), sonic 默认不会启用这个功能。如果你的组件依赖这个行为(如 [zstd](https://github.com/facebook/zstd)) ,可以仿照下面的例子:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
import "github.com/bytedance/sonic/encoder"
|
import "github.com/bytedance/sonic/encoder"
|
||||||
|
@ -188,6 +201,7 @@ err := root.SortKeys()
|
||||||
### HTML 转义
|
### HTML 转义
|
||||||
|
|
||||||
考虑到性能损失(约15%), sonic 默认不会启用这个功能。你可以使用 `encoder.EscapeHTML` 选项来开启(与 `encoding/json.HTMLEscape` 行为一致)。
|
考虑到性能损失(约15%), sonic 默认不会启用这个功能。你可以使用 `encoder.EscapeHTML` 选项来开启(与 `encoding/json.HTMLEscape` 行为一致)。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -196,11 +210,13 @@ ret, err := Encode(v, EscapeHTML) // ret == `{"\u0026\u0026":{"X":"\u003c\u003e"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 紧凑格式
|
### 紧凑格式
|
||||||
|
|
||||||
Sonic 默认将基本类型( `struct` , `map` 等)编码为紧凑格式的 JSON ,除非使用 `json.RawMessage` or `json.Marshaler` 进行编码: sonic 确保输出的 JSON 合法,但出于性能考虑,**不会**加工成紧凑格式。我们提供选项 `encoder.CompactMarshaler` 来添加此过程,
|
Sonic 默认将基本类型( `struct` , `map` 等)编码为紧凑格式的 JSON ,除非使用 `json.RawMessage` or `json.Marshaler` 进行编码: sonic 确保输出的 JSON 合法,但出于性能考虑,**不会**加工成紧凑格式。我们提供选项 `encoder.CompactMarshaler` 来添加此过程,
|
||||||
|
|
||||||
### 打印错误
|
### 打印错误
|
||||||
|
|
||||||
如果输入的 JSON 存在无效的语法,sonic 将返回 `decoder.SyntaxError`,该错误支持错误位置的美化输出。
|
如果输入的 JSON 存在无效的语法,sonic 将返回 `decoder.SyntaxError`,该错误支持错误位置的美化输出。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
import "github.com/bytedance/sonic/decoder"
|
import "github.com/bytedance/sonic/decoder"
|
||||||
|
@ -228,6 +244,7 @@ if err != nil {
|
||||||
#### 类型不匹配 [Sonic v1.6.0]
|
#### 类型不匹配 [Sonic v1.6.0]
|
||||||
|
|
||||||
如果给定键中存在**类型不匹配**的值, sonic 会抛出 `decoder.MismatchTypeError` (如果有多个,只会报告最后一个),但仍会跳过错误的值并解码下一个 JSON 。
|
如果给定键中存在**类型不匹配**的值, sonic 会抛出 `decoder.MismatchTypeError` (如果有多个,只会报告最后一个),但仍会跳过错误的值并解码下一个 JSON 。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
import "github.com/bytedance/sonic/decoder"
|
import "github.com/bytedance/sonic/decoder"
|
||||||
|
@ -240,6 +257,7 @@ err := UnmarshalString(`{"A":"1","B":1}`, &data)
|
||||||
println(err.Error()) // Mismatch type int with value string "at index 5: mismatched type with value\n\n\t{\"A\":\"1\",\"B\":1}\n\t.....^.........\n"
|
println(err.Error()) // Mismatch type int with value string "at index 5: mismatched type with value\n\n\t{\"A\":\"1\",\"B\":1}\n\t.....^.........\n"
|
||||||
fmt.Printf("%+v", data) // {A:0 B:1}
|
fmt.Printf("%+v", data) // {A:0 B:1}
|
||||||
```
|
```
|
||||||
|
|
||||||
### `Ast.Node`
|
### `Ast.Node`
|
||||||
|
|
||||||
Sonic/ast.Node 是完全独立的 JSON 抽象语法树库。它实现了序列化和反序列化,并提供了获取和修改通用数据的鲁棒的 API。
|
Sonic/ast.Node 是完全独立的 JSON 抽象语法树库。它实现了序列化和反序列化,并提供了获取和修改通用数据的鲁棒的 API。
|
||||||
|
@ -247,6 +265,7 @@ Sonic/ast.Node 是完全独立的 JSON 抽象语法树库。它实现了序列
|
||||||
#### 查找/索引
|
#### 查找/索引
|
||||||
|
|
||||||
通过给定的路径搜索 JSON 片段,路径必须为非负整数,字符串或 `nil` 。
|
通过给定的路径搜索 JSON 片段,路径必须为非负整数,字符串或 `nil` 。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -260,11 +279,13 @@ raw := root.Raw() // == string(input)
|
||||||
root, err := sonic.Get(input, "key1", 1, "key2")
|
root, err := sonic.Get(input, "key1", 1, "key2")
|
||||||
sub := root.Get("key3").Index(2).Int64() // == 3
|
sub := root.Get("key3").Index(2).Int64() // == 3
|
||||||
```
|
```
|
||||||
|
|
||||||
**注意**:由于 `Index()` 使用偏移量来定位数据,比使用扫描的 `Get()` 要快的多,建议尽可能的使用 `Index` 。 Sonic 也提供了另一个 API, `IndexOrGet()` ,以偏移量为基础并且也确保键的匹配。
|
**注意**:由于 `Index()` 使用偏移量来定位数据,比使用扫描的 `Get()` 要快的多,建议尽可能的使用 `Index` 。 Sonic 也提供了另一个 API, `IndexOrGet()` ,以偏移量为基础并且也确保键的匹配。
|
||||||
|
|
||||||
#### 修改
|
#### 修改
|
||||||
|
|
||||||
使用 ` Set()` / `Unset()` 修改 json 的内容
|
使用 `Set()` / `Unset()` 修改 json 的内容
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -281,7 +302,9 @@ println(root.Get("key4").Check()) // "value not exist"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 序列化
|
#### 序列化
|
||||||
|
|
||||||
要将 `ast.Node` 编码为 json ,使用 `MarshalJson()` 或者 `json.Marshal()` (必须传递指向节点的指针)
|
要将 `ast.Node` 编码为 json ,使用 `MarshalJson()` 或者 `json.Marshal()` (必须传递指向节点的指针)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -295,6 +318,7 @@ println(string(buf) == string(exp)) // true
|
||||||
```
|
```
|
||||||
|
|
||||||
#### APIs
|
#### APIs
|
||||||
|
|
||||||
- 合法性检查: `Check()`, `Error()`, `Valid()`, `Exist()`
|
- 合法性检查: `Check()`, `Error()`, `Valid()`, `Exist()`
|
||||||
- 索引: `Index()`, `Get()`, `IndexPair()`, `IndexOrGet()`, `GetByPath()`
|
- 索引: `Index()`, `Get()`, `IndexPair()`, `IndexOrGet()`, `GetByPath()`
|
||||||
- 转换至 go 内置类型: `Int64()`, `Float64()`, `String()`, `Number()`, `Bool()`, `Map[UseNumber|UseNode]()`, `Array[UseNumber|UseNode]()`, `Interface[UseNumber|UseNode]()`
|
- 转换至 go 内置类型: `Int64()`, `Float64()`, `String()`, `Number()`, `Bool()`, `Map[UseNumber|UseNode]()`, `Array[UseNumber|UseNode]()`, `Interface[UseNumber|UseNode]()`
|
||||||
|
@ -303,7 +327,9 @@ println(string(buf) == string(exp)) // true
|
||||||
- 修改: `Set()`, `SetByIndex()`, `Add()`
|
- 修改: `Set()`, `SetByIndex()`, `Add()`
|
||||||
|
|
||||||
### `Ast.Visitor`
|
### `Ast.Visitor`
|
||||||
|
|
||||||
Sonic 提供了一个高级的 API 用于直接全量解析 JSON 到非标准容器里 (既不是 `struct` 也不是 `map[string]interface{}`) 且不需要借助任何中间表示 (`ast.Node` 或 `interface{}`)。举个例子,你可能定义了下述的类型,它们看起来像 `interface{}`,但实际上并不是:
|
Sonic 提供了一个高级的 API 用于直接全量解析 JSON 到非标准容器里 (既不是 `struct` 也不是 `map[string]interface{}`) 且不需要借助任何中间表示 (`ast.Node` 或 `interface{}`)。举个例子,你可能定义了下述的类型,它们看起来像 `interface{}`,但实际上并不是:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type UserNode interface {}
|
type UserNode interface {}
|
||||||
|
|
||||||
|
@ -318,7 +344,9 @@ type (
|
||||||
UserArray struct{ Value []UserNode }
|
UserArray struct{ Value []UserNode }
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Sonic 提供了下述的 API 来返回 **“对 JSON AST 的前序遍历”**。`ast.Visitor` 是一个 SAX 风格的接口,这在某些 C++ 的 JSON 解析库中被使用到。你需要自己实现一个 `ast.Visitor`,将它传递给 `ast.Preorder()` 方法。在你的实现中你可以使用自定义的类型来表示 JSON 的值。在你的 `ast.Visitor` 中,可能需要有一个 O(n) 空间复杂度的容器(比如说栈)来记录 object / array 的层级。
|
Sonic 提供了下述的 API 来返回 **“对 JSON AST 的前序遍历”**。`ast.Visitor` 是一个 SAX 风格的接口,这在某些 C++ 的 JSON 解析库中被使用到。你需要自己实现一个 `ast.Visitor`,将它传递给 `ast.Preorder()` 方法。在你的实现中你可以使用自定义的类型来表示 JSON 的值。在你的 `ast.Visitor` 中,可能需要有一个 O(n) 空间复杂度的容器(比如说栈)来记录 object / array 的层级。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Preorder(str string, visitor Visitor, opts *VisitorOptions) error
|
func Preorder(str string, visitor Visitor, opts *VisitorOptions) error
|
||||||
|
|
||||||
|
@ -335,15 +363,18 @@ type Visitor interface {
|
||||||
OnArrayEnd() error
|
OnArrayEnd() error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
详细用法参看 [ast/visitor.go](https://github.com/bytedance/sonic/blob/main/ast/visitor.go),我们还为 `UserNode` 实现了一个示例 `ast.Visitor`,你可以在 [ast/visitor_test.go](https://github.com/bytedance/sonic/blob/main/ast/visitor_test.go) 中找到它。
|
详细用法参看 [ast/visitor.go](https://github.com/bytedance/sonic/blob/main/ast/visitor.go),我们还为 `UserNode` 实现了一个示例 `ast.Visitor`,你可以在 [ast/visitor_test.go](https://github.com/bytedance/sonic/blob/main/ast/visitor_test.go) 中找到它。
|
||||||
|
|
||||||
## 兼容性
|
## 兼容性
|
||||||
|
|
||||||
由于开发高性能代码的困难性, Sonic **不**保证对所有环境的支持。对于在不同环境中使用 Sonic 构建应用程序的开发者,我们有以下建议:
|
由于开发高性能代码的困难性, Sonic **不**保证对所有环境的支持。对于在不同环境中使用 Sonic 构建应用程序的开发者,我们有以下建议:
|
||||||
|
|
||||||
- 在 **Mac M1** 上开发:确保在您的计算机上安装了 Rosetta 2,并在构建时设置 `GOARCH=amd64` 。 Rosetta 2 可以自动将 x86 二进制文件转换为 arm64 二进制文件,并在 Mac M1 上运行 x86 应用程序。
|
- 在 **Mac M1** 上开发:确保在您的计算机上安装了 Rosetta 2,并在构建时设置 `GOARCH=amd64` 。 Rosetta 2 可以自动将 x86 二进制文件转换为 arm64 二进制文件,并在 Mac M1 上运行 x86 应用程序。
|
||||||
- 在 **Linux arm64** 上开发:您可以安装 qemu 并使用 `qemu-x86_64 -cpu max` 命令来将 x86 二进制文件转换为 arm64 二进制文件。qemu可以实现与Mac M1上的Rosetta 2类似的转换效果。
|
- 在 **Linux arm64** 上开发:您可以安装 qemu 并使用 `qemu-x86_64 -cpu max` 命令来将 x86 二进制文件转换为 arm64 二进制文件。qemu可以实现与Mac M1上的Rosetta 2类似的转换效果。
|
||||||
|
|
||||||
对于希望在不使用 qemu 下使用 sonic 的开发者,或者希望处理 JSON 时与 `encoding/JSON` 严格保持一致的开发者,我们在 `sonic.API` 中提供了一些兼容性 API
|
对于希望在不使用 qemu 下使用 sonic 的开发者,或者希望处理 JSON 时与 `encoding/JSON` 严格保持一致的开发者,我们在 `sonic.API` 中提供了一些兼容性 API
|
||||||
|
|
||||||
- `ConfigDefault`: 在支持 sonic 的环境下 sonic 的默认配置(`EscapeHTML=false`,`SortKeys=false`等)。行为与具有相应配置的 `encoding/json` 一致,一些选项,如 `SortKeys=false` 将无效。
|
- `ConfigDefault`: 在支持 sonic 的环境下 sonic 的默认配置(`EscapeHTML=false`,`SortKeys=false`等)。行为与具有相应配置的 `encoding/json` 一致,一些选项,如 `SortKeys=false` 将无效。
|
||||||
- `ConfigStd`: 在支持 sonic 的环境下与标准库兼容的配置(`EscapeHTML=true`,`SortKeys=true`等)。行为与 `encoding/json` 一致。
|
- `ConfigStd`: 在支持 sonic 的环境下与标准库兼容的配置(`EscapeHTML=true`,`SortKeys=true`等)。行为与 `encoding/json` 一致。
|
||||||
- `ConfigFastest`: 在支持 sonic 的环境下运行最快的配置(`NoQuoteTextMarshaler=true`)。行为与具有相应配置的 `encoding/json` 一致,某些选项将无效。
|
- `ConfigFastest`: 在支持 sonic 的环境下运行最快的配置(`NoQuoteTextMarshaler=true`)。行为与具有相应配置的 `encoding/json` 一致,某些选项将无效。
|
||||||
|
@ -351,7 +382,9 @@ type Visitor interface {
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
### 预热
|
### 预热
|
||||||
|
|
||||||
由于 Sonic 使用 [golang-asm](https://github.com/twitchyliquid64/golang-asm) 作为 JIT 汇编器,这个库并不适用于运行时编译,第一次运行一个大型模式可能会导致请求超时甚至进程内存溢出。为了更好地稳定性,我们建议在运行大型模式或在内存有限的应用中,在使用 `Marshal()/Unmarshal()` 前运行 `Pretouch()`。
|
由于 Sonic 使用 [golang-asm](https://github.com/twitchyliquid64/golang-asm) 作为 JIT 汇编器,这个库并不适用于运行时编译,第一次运行一个大型模式可能会导致请求超时甚至进程内存溢出。为了更好地稳定性,我们建议在运行大型模式或在内存有限的应用中,在使用 `Marshal()/Unmarshal()` 前运行 `Pretouch()`。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -381,16 +414,17 @@ func init() {
|
||||||
当解码 **没有转义字符的字符串**时, sonic 会从原始的 JSON 缓冲区内引用而不是复制到新的一个缓冲区中。这对 CPU 的性能方面很有帮助,但是可能因此在解码后对象仍在使用的时候将整个 JSON 缓冲区保留在内存中。实践中我们发现,通过引用 JSON 缓冲区引入的额外内存通常是解码后对象的 20% 至 80% ,一旦应用长期保留这些对象(如缓存以备重用),服务器所使用的内存可能会增加。我们提供了选项 `decoder.CopyString()` 供用户选择,不引用 JSON 缓冲区。这可能在一定程度上降低 CPU 性能。
|
当解码 **没有转义字符的字符串**时, sonic 会从原始的 JSON 缓冲区内引用而不是复制到新的一个缓冲区中。这对 CPU 的性能方面很有帮助,但是可能因此在解码后对象仍在使用的时候将整个 JSON 缓冲区保留在内存中。实践中我们发现,通过引用 JSON 缓冲区引入的额外内存通常是解码后对象的 20% 至 80% ,一旦应用长期保留这些对象(如缓存以备重用),服务器所使用的内存可能会增加。我们提供了选项 `decoder.CopyString()` 供用户选择,不引用 JSON 缓冲区。这可能在一定程度上降低 CPU 性能。
|
||||||
|
|
||||||
### 传递字符串还是字节数组?
|
### 传递字符串还是字节数组?
|
||||||
|
|
||||||
为了和 `encoding/json` 保持一致,我们提供了传递 `[]byte` 作为参数的 API ,但考虑到安全性,字符串到字节的复制是同时进行的,这在原始 JSON 非常大时可能会导致性能损失。因此,你可以使用 `UnmarshalString()` 和 `GetFromString()` 来传递字符串,只要你的原始数据是字符串,或**零拷贝类型转换**对于你的字节数组是安全的。我们也提供了 `MarshalString()` 的 API ,以便对编码的 JSON 字节数组进行**零拷贝类型转换**,因为 sonic 输出的字节始终是重复并且唯一的,所以这样是安全的。
|
为了和 `encoding/json` 保持一致,我们提供了传递 `[]byte` 作为参数的 API ,但考虑到安全性,字符串到字节的复制是同时进行的,这在原始 JSON 非常大时可能会导致性能损失。因此,你可以使用 `UnmarshalString()` 和 `GetFromString()` 来传递字符串,只要你的原始数据是字符串,或**零拷贝类型转换**对于你的字节数组是安全的。我们也提供了 `MarshalString()` 的 API ,以便对编码的 JSON 字节数组进行**零拷贝类型转换**,因为 sonic 输出的字节始终是重复并且唯一的,所以这样是安全的。
|
||||||
|
|
||||||
### 加速 `encoding.TextMarshaler`
|
### 加速 `encoding.TextMarshaler`
|
||||||
|
|
||||||
为了保证数据安全性, `sonic.Encoder` 默认会对来自 `encoding.TextMarshaler` 接口的字符串进行引用和转义,如果大部分数据都是这种形式那可能会导致很大的性能损失。我们提供了 `encoder.NoQuoteTextMarshaler` 选项来跳过这些操作,但你**必须**保证他们的输出字符串依照 [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259) 进行了转义和引用。
|
为了保证数据安全性, `sonic.Encoder` 默认会对来自 `encoding.TextMarshaler` 接口的字符串进行引用和转义,如果大部分数据都是这种形式那可能会导致很大的性能损失。我们提供了 `encoder.NoQuoteTextMarshaler` 选项来跳过这些操作,但你**必须**保证他们的输出字符串依照 [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259) 进行了转义和引用。
|
||||||
|
|
||||||
|
|
||||||
### 泛型的性能优化
|
### 泛型的性能优化
|
||||||
|
|
||||||
在 **完全解析**的场景下, `Unmarshal()` 表现得比 `Get()`+`Node.Interface()` 更好。但是如果你只有特定 JSON 的部分模式,你可以将 `Get()` 和 `Unmarshal()` 结合使用:
|
在 **完全解析**的场景下, `Unmarshal()` 表现得比 `Get()`+`Node.Interface()` 更好。但是如果你只有特定 JSON 的部分模式,你可以将 `Get()` 和 `Unmarshal()` 结合使用:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -398,7 +432,9 @@ node, err := sonic.GetFromString(_TwitterJson, "statuses", 3, "user")
|
||||||
var user User // your partial schema...
|
var user User // your partial schema...
|
||||||
err = sonic.UnmarshalString(node.Raw(), &user)
|
err = sonic.UnmarshalString(node.Raw(), &user)
|
||||||
```
|
```
|
||||||
|
|
||||||
甚至如果你没有任何模式,可以用 `ast.Node` 代替 `map` 或 `interface` 作为泛型的容器:
|
甚至如果你没有任何模式,可以用 `ast.Node` 代替 `map` 或 `interface` 作为泛型的容器:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/bytedance/sonic"
|
import "github.com/bytedance/sonic"
|
||||||
|
|
||||||
|
@ -409,7 +445,9 @@ err = user.Check()
|
||||||
// err = user.LoadAll() // only call this when you want to use 'user' concurrently...
|
// err = user.LoadAll() // only call this when you want to use 'user' concurrently...
|
||||||
go someFunc(user)
|
go someFunc(user)
|
||||||
```
|
```
|
||||||
|
|
||||||
为什么?因为 `ast.Node` 使用 `array` 来存储其子节点:
|
为什么?因为 `ast.Node` 使用 `array` 来存储其子节点:
|
||||||
|
|
||||||
- 在插入(反序列化)和扫描(序列化)数据时,`Array` 的性能比 `Map` **好得多**;
|
- 在插入(反序列化)和扫描(序列化)数据时,`Array` 的性能比 `Map` **好得多**;
|
||||||
- **哈希**(`map[x]`)的效率不如**索引**(`array[x]`)高效,而 `ast.Node` 可以在数组和对象上使用索引;
|
- **哈希**(`map[x]`)的效率不如**索引**(`array[x]`)高效,而 `ast.Node` 可以在数组和对象上使用索引;
|
||||||
- 使用 `Interface()` / `Map()` 意味着 sonic 必须解析所有的底层值,而 `ast.Node` 可以**按需解析**它们。
|
- 使用 `Interface()` / `Map()` 意味着 sonic 必须解析所有的底层值,而 `ast.Node` 可以**按需解析**它们。
|
||||||
|
@ -417,6 +455,7 @@ go someFunc(user)
|
||||||
**注意**:由于 `ast.Node` 的惰性加载设计,其**不能**直接保证并发安全性,但你可以调用 `Node.Load()` / `Node.LoadAll()` 来实现并发安全。尽管可能会带来性能损失,但仍比转换成 `map` 或 `interface{}` 更为高效。
|
**注意**:由于 `ast.Node` 的惰性加载设计,其**不能**直接保证并发安全性,但你可以调用 `Node.Load()` / `Node.LoadAll()` 来实现并发安全。尽管可能会带来性能损失,但仍比转换成 `map` 或 `interface{}` 更为高效。
|
||||||
|
|
||||||
### 使用 `ast.Node` 还是 `ast.Visitor`?
|
### 使用 `ast.Node` 还是 `ast.Visitor`?
|
||||||
|
|
||||||
对于泛型数据的解析,`ast.Node` 在大多数场景上应该能够满足你的需求。
|
对于泛型数据的解析,`ast.Node` 在大多数场景上应该能够满足你的需求。
|
||||||
|
|
||||||
然而,`ast.Node` 是一种针对部分解析 JSON 而设计的泛型容器,它包含一些特殊设计,比如惰性加载,如果你希望像 `Unmarshal()` 那样直接解析整个 JSON,这些设计可能并不合适。尽管 `ast.Node` 相较于 `map` 或 `interface{}` 来说是更好的一种泛型容器,但它毕竟也是一种中间表示,如果你的最终类型是自定义的,你还得在解析完成后将上述类型转化成你自定义的类型。
|
然而,`ast.Node` 是一种针对部分解析 JSON 而设计的泛型容器,它包含一些特殊设计,比如惰性加载,如果你希望像 `Unmarshal()` 那样直接解析整个 JSON,这些设计可能并不合适。尽管 `ast.Node` 相较于 `map` 或 `interface{}` 来说是更好的一种泛型容器,但它毕竟也是一种中间表示,如果你的最终类型是自定义的,你还得在解析完成后将上述类型转化成你自定义的类型。
|
||||||
|
|
30
vendor/github.com/bytedance/sonic/api.go
generated
vendored
30
vendor/github.com/bytedance/sonic/api.go
generated
vendored
|
@ -20,6 +20,7 @@ import (
|
||||||
`io`
|
`io`
|
||||||
|
|
||||||
`github.com/bytedance/sonic/ast`
|
`github.com/bytedance/sonic/ast`
|
||||||
|
`github.com/bytedance/sonic/internal/rt`
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config is a combination of sonic/encoder.Options and sonic/decoder.Options
|
// Config is a combination of sonic/encoder.Options and sonic/decoder.Options
|
||||||
|
@ -73,6 +74,9 @@ type Config struct {
|
||||||
// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
|
// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
|
||||||
// after encoding the JSONMarshaler to JSON.
|
// after encoding the JSONMarshaler to JSON.
|
||||||
NoValidateJSONMarshaler bool
|
NoValidateJSONMarshaler bool
|
||||||
|
|
||||||
|
// NoEncoderNewline indicates that the encoder should not add a newline after every message
|
||||||
|
NoEncoderNewline bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -170,27 +174,41 @@ func UnmarshalString(buf string, val interface{}) error {
|
||||||
return ConfigDefault.UnmarshalFromString(buf, val)
|
return ConfigDefault.UnmarshalFromString(buf, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get searches the given path from json,
|
// Get searches and locates the given path from src json,
|
||||||
// and returns its representing ast.Node.
|
// and returns a ast.Node representing the partially json.
|
||||||
//
|
//
|
||||||
// Each path arg must be integer or string:
|
// Each path arg must be integer or string:
|
||||||
// - Integer is target index(>=0), means searching current node as array.
|
// - Integer is target index(>=0), means searching current node as array.
|
||||||
// - String is target key, means searching current node as object.
|
// - String is target key, means searching current node as object.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Note, the api expects the json is well-formed at least,
|
// Notice: It expects the src json is **Well-formed** and **Immutable** when calling,
|
||||||
// otherwise it may return unexpected result.
|
// otherwise it may return unexpected result.
|
||||||
|
// Considering memory safty, the returned JSON is **Copied** from the input
|
||||||
func Get(src []byte, path ...interface{}) (ast.Node, error) {
|
func Get(src []byte, path ...interface{}) (ast.Node, error) {
|
||||||
return GetFromString(string(src), path...)
|
return GetCopyFromString(rt.Mem2Str(src), path...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFromString is same with Get except src is string,
|
// GetFromString is same with Get except src is string.
|
||||||
// which can reduce unnecessary memory copy.
|
//
|
||||||
|
// WARNING: The returned JSON is **Referenced** from the input.
|
||||||
|
// Caching or long-time holding the returned node may cause OOM.
|
||||||
|
// If your src is big, consider use GetFromStringCopy().
|
||||||
func GetFromString(src string, path ...interface{}) (ast.Node, error) {
|
func GetFromString(src string, path ...interface{}) (ast.Node, error) {
|
||||||
return ast.NewSearcher(src).GetByPath(path...)
|
return ast.NewSearcher(src).GetByPath(path...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCopyFromString is same with Get except src is string
|
||||||
|
func GetCopyFromString(src string, path ...interface{}) (ast.Node, error) {
|
||||||
|
return ast.NewSearcher(src).GetByPathCopy(path...)
|
||||||
|
}
|
||||||
|
|
||||||
// Valid reports whether data is a valid JSON encoding.
|
// Valid reports whether data is a valid JSON encoding.
|
||||||
func Valid(data []byte) bool {
|
func Valid(data []byte) bool {
|
||||||
return ConfigDefault.Valid(data)
|
return ConfigDefault.Valid(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Valid reports whether data is a valid JSON encoding.
|
||||||
|
func ValidString(data string) bool {
|
||||||
|
return ConfigDefault.Valid(rt.Str2Mem(data))
|
||||||
|
}
|
||||||
|
|
26
vendor/github.com/bytedance/sonic/ast/api_amd64.go
generated
vendored
26
vendor/github.com/bytedance/sonic/ast/api_amd64.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64,go1.16,!go1.22
|
// +build amd64,go1.16,!go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2022 ByteDance Inc.
|
* Copyright 2022 ByteDance Inc.
|
||||||
|
@ -131,27 +131,3 @@ func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) {
|
||||||
}
|
}
|
||||||
return start, 0
|
return start, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
|
|
||||||
var err types.ParsingError
|
|
||||||
var start int
|
|
||||||
|
|
||||||
self.parser.p = 0
|
|
||||||
start, err = self.parser.getByPath(path...)
|
|
||||||
if err != 0 {
|
|
||||||
// for compatibility with old version
|
|
||||||
if err == types.ERR_NOT_FOUND {
|
|
||||||
return Node{}, ErrNotExist
|
|
||||||
}
|
|
||||||
if err == types.ERR_UNSUPPORT_TYPE {
|
|
||||||
panic("path must be either int(>=0) or string")
|
|
||||||
}
|
|
||||||
return Node{}, self.parser.syntaxError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t := switchRawType(self.parser.s[start])
|
|
||||||
if t == _V_NONE {
|
|
||||||
return Node{}, self.parser.ExportError(err)
|
|
||||||
}
|
|
||||||
return newRawNode(self.parser.s[start:self.parser.p], t), nil
|
|
||||||
}
|
|
||||||
|
|
35
vendor/github.com/bytedance/sonic/ast/api_compat.go
generated
vendored
35
vendor/github.com/bytedance/sonic/ast/api_compat.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build !amd64 !go1.16 go1.22
|
// +build !amd64 !go1.16 go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2022 ByteDance Inc.
|
* Copyright 2022 ByteDance Inc.
|
||||||
|
@ -21,14 +21,13 @@ package ast
|
||||||
import (
|
import (
|
||||||
`encoding/base64`
|
`encoding/base64`
|
||||||
`encoding/json`
|
`encoding/json`
|
||||||
`fmt`
|
|
||||||
|
|
||||||
`github.com/bytedance/sonic/internal/native/types`
|
`github.com/bytedance/sonic/internal/native/types`
|
||||||
`github.com/bytedance/sonic/internal/rt`
|
`github.com/bytedance/sonic/internal/rt`
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
println("WARNING: sonic only supports Go1.16~1.20 && CPU amd64, but your environment is not suitable")
|
println("WARNING: sonic only supports Go1.16~1.22 && CPU amd64, but your environment is not suitable")
|
||||||
}
|
}
|
||||||
|
|
||||||
func quote(buf *[]byte, val string) {
|
func quote(buf *[]byte, val string) {
|
||||||
|
@ -88,37 +87,25 @@ func (self *Node) encodeInterface(buf *[]byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
|
func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) {
|
||||||
self.parser.p = 0
|
|
||||||
|
|
||||||
var err types.ParsingError
|
var err types.ParsingError
|
||||||
for _, p := range path {
|
for _, p := range path {
|
||||||
if idx, ok := p.(int); ok && idx >= 0 {
|
if idx, ok := p.(int); ok && idx >= 0 {
|
||||||
if err = self.parser.searchIndex(idx); err != 0 {
|
if err = self.searchIndex(idx); err != 0 {
|
||||||
return Node{}, self.parser.ExportError(err)
|
return -1, err
|
||||||
}
|
}
|
||||||
} else if key, ok := p.(string); ok {
|
} else if key, ok := p.(string); ok {
|
||||||
if err = self.parser.searchKey(key); err != 0 {
|
if err = self.searchKey(key); err != 0 {
|
||||||
return Node{}, self.parser.ExportError(err)
|
return -1, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic("path must be either int(>=0) or string")
|
panic("path must be either int(>=0) or string")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var start = self.parser.p
|
var start int
|
||||||
if start, err = self.parser.skip(); err != 0 {
|
if start, err = self.skip(); err != 0 {
|
||||||
return Node{}, self.parser.ExportError(err)
|
return -1, err
|
||||||
}
|
}
|
||||||
ns := len(self.parser.s)
|
return start, 0
|
||||||
if self.parser.p > ns || start >= ns || start>=self.parser.p {
|
|
||||||
return Node{}, fmt.Errorf("skip %d char out of json boundary", start)
|
|
||||||
}
|
|
||||||
|
|
||||||
t := switchRawType(self.parser.s[start])
|
|
||||||
if t == _V_NONE {
|
|
||||||
return Node{}, self.parser.ExportError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return newRawNode(self.parser.s[start:self.parser.p], t), nil
|
|
||||||
}
|
}
|
150
vendor/github.com/bytedance/sonic/ast/buffer.go
generated
vendored
150
vendor/github.com/bytedance/sonic/ast/buffer.go
generated
vendored
|
@ -58,29 +58,89 @@ func (self *linkedNodes) At(i int) (*Node) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *linkedNodes) Add(v Node) {
|
func (self *linkedNodes) MoveOne(source int, target int) {
|
||||||
if self.size < _DEFAULT_NODE_CAP {
|
if source == target {
|
||||||
self.head[self.size] = v
|
|
||||||
self.size++
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if source < 0 || source >= self.size || target < 0 || target >= self.size {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// reserve source
|
||||||
|
n := *self.At(source)
|
||||||
|
if source < target {
|
||||||
|
// move every element (source,target] one step back
|
||||||
|
for i:=source; i<target; i++ {
|
||||||
|
*self.At(i) = *self.At(i+1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// move every element [target,source) one step forward
|
||||||
|
for i:=source; i>target; i-- {
|
||||||
|
*self.At(i) = *self.At(i-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// set target
|
||||||
|
*self.At(target) = n
|
||||||
|
}
|
||||||
|
|
||||||
a, b, c := self.size/_DEFAULT_NODE_CAP-1 , self.size%_DEFAULT_NODE_CAP, cap(self.tail)
|
func (self *linkedNodes) Pop() {
|
||||||
if a - c >= 0 {
|
if self == nil || self.size == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.Set(self.size-1, Node{})
|
||||||
|
self.size--
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *linkedPairs) Pop() {
|
||||||
|
if self == nil || self.size == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.Set(self.size-1, Pair{})
|
||||||
|
self.size--
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *linkedNodes) Push(v Node) {
|
||||||
|
self.Set(self.size, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *linkedNodes) Set(i int, v Node) {
|
||||||
|
if i < _DEFAULT_NODE_CAP {
|
||||||
|
self.head[i] = v
|
||||||
|
if self.size <= i {
|
||||||
|
self.size = i+1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
|
||||||
|
if a < 0 {
|
||||||
|
self.head[b] = v
|
||||||
|
} else {
|
||||||
|
self.growTailLength(a+1)
|
||||||
|
var n = &self.tail[a]
|
||||||
|
if *n == nil {
|
||||||
|
*n = new(nodeChunk)
|
||||||
|
}
|
||||||
|
(*n)[b] = v
|
||||||
|
}
|
||||||
|
if self.size <= i {
|
||||||
|
self.size = i+1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *linkedNodes) growTailLength(l int) {
|
||||||
|
if l <= len(self.tail) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c := cap(self.tail)
|
||||||
|
for c < l {
|
||||||
c += 1 + c>>_APPEND_GROW_SHIFT
|
c += 1 + c>>_APPEND_GROW_SHIFT
|
||||||
tmp := make([]*nodeChunk, a + 1, c)
|
|
||||||
copy(tmp, self.tail)
|
|
||||||
self.tail = tmp
|
|
||||||
} else if a >= len(self.tail) {
|
|
||||||
self.tail = self.tail[:a+1]
|
|
||||||
}
|
}
|
||||||
|
if c == cap(self.tail) {
|
||||||
var n = &self.tail[a]
|
self.tail = self.tail[:l]
|
||||||
if *n == nil {
|
return
|
||||||
*n = new(nodeChunk)
|
|
||||||
}
|
}
|
||||||
(*n)[b] = v
|
tmp := make([]*nodeChunk, l, c)
|
||||||
self.size++
|
copy(tmp, self.tail)
|
||||||
|
self.tail = tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *linkedNodes) ToSlice(con []Node) {
|
func (self *linkedNodes) ToSlice(con []Node) {
|
||||||
|
@ -169,29 +229,49 @@ func (self *linkedPairs) At(i int) *Pair {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *linkedPairs) Add(v Pair) {
|
func (self *linkedPairs) Push(v Pair) {
|
||||||
if self.size < _DEFAULT_NODE_CAP {
|
self.Set(self.size, v)
|
||||||
self.head[self.size] = v
|
}
|
||||||
self.size++
|
|
||||||
|
func (self *linkedPairs) Set(i int, v Pair) {
|
||||||
|
if i < _DEFAULT_NODE_CAP {
|
||||||
|
self.head[i] = v
|
||||||
|
if self.size <= i {
|
||||||
|
self.size = i+1
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
|
||||||
|
if a < 0 {
|
||||||
|
self.head[b] = v
|
||||||
|
} else {
|
||||||
|
self.growTailLength(a+1)
|
||||||
|
var n = &self.tail[a]
|
||||||
|
if *n == nil {
|
||||||
|
*n = new(pairChunk)
|
||||||
|
}
|
||||||
|
(*n)[b] = v
|
||||||
|
}
|
||||||
|
if self.size <= i {
|
||||||
|
self.size = i+1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a, b, c := self.size/_DEFAULT_NODE_CAP-1 , self.size%_DEFAULT_NODE_CAP, cap(self.tail)
|
func (self *linkedPairs) growTailLength(l int) {
|
||||||
if a - c >= 0 {
|
if l <= len(self.tail) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c := cap(self.tail)
|
||||||
|
for c < l {
|
||||||
c += 1 + c>>_APPEND_GROW_SHIFT
|
c += 1 + c>>_APPEND_GROW_SHIFT
|
||||||
tmp := make([]*pairChunk, a + 1, c)
|
|
||||||
copy(tmp, self.tail)
|
|
||||||
self.tail = tmp
|
|
||||||
} else if a >= len(self.tail) {
|
|
||||||
self.tail = self.tail[:a+1]
|
|
||||||
}
|
}
|
||||||
|
if c == cap(self.tail) {
|
||||||
var n = &self.tail[a]
|
self.tail = self.tail[:l]
|
||||||
if *n == nil {
|
return
|
||||||
*n = new(pairChunk)
|
|
||||||
}
|
}
|
||||||
(*n)[b] = v
|
tmp := make([]*pairChunk, l, c)
|
||||||
self.size++
|
copy(tmp, self.tail)
|
||||||
|
self.tail = tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
// linear search
|
// linear search
|
||||||
|
@ -271,7 +351,7 @@ func (self *linkedPairs) Swap(i, j int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *linkedPairs) Sort() {
|
func (self *linkedPairs) Sort() {
|
||||||
sort.Sort(self)
|
sort.Stable(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare two strings from the pos d.
|
// Compare two strings from the pos d.
|
||||||
|
|
32
vendor/github.com/bytedance/sonic/ast/encode.go
generated
vendored
32
vendor/github.com/bytedance/sonic/ast/encode.go
generated
vendored
|
@ -193,20 +193,9 @@ func (self *Node) encodeArray(buf *[]byte) error {
|
||||||
|
|
||||||
*buf = append(*buf, '[')
|
*buf = append(*buf, '[')
|
||||||
|
|
||||||
var s = (*linkedNodes)(self.p)
|
|
||||||
var started bool
|
var started bool
|
||||||
if nb > 0 {
|
for i := 0; i < nb; i++ {
|
||||||
n := s.At(0)
|
n := self.nodeAt(i)
|
||||||
if n.Exists() {
|
|
||||||
if err := n.encode(buf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
started = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 1; i < nb; i++ {
|
|
||||||
n := s.At(i)
|
|
||||||
if !n.Exists() {
|
if !n.Exists() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -250,21 +239,10 @@ func (self *Node) encodeObject(buf *[]byte) error {
|
||||||
|
|
||||||
*buf = append(*buf, '{')
|
*buf = append(*buf, '{')
|
||||||
|
|
||||||
var s = (*linkedPairs)(self.p)
|
|
||||||
var started bool
|
var started bool
|
||||||
if nb > 0 {
|
for i := 0; i < nb; i++ {
|
||||||
n := s.At(0)
|
n := self.pairAt(i)
|
||||||
if n.Value.Exists() {
|
if n == nil || !n.Value.Exists() {
|
||||||
if err := n.encode(buf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
started = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 1; i < nb; i++ {
|
|
||||||
n := s.At(i)
|
|
||||||
if !n.Value.Exists() {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if started {
|
if started {
|
||||||
|
|
14
vendor/github.com/bytedance/sonic/ast/iterator.go
generated
vendored
14
vendor/github.com/bytedance/sonic/ast/iterator.go
generated
vendored
|
@ -32,7 +32,11 @@ func (self *Node) Values() (ListIterator, error) {
|
||||||
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
||||||
return ListIterator{}, err
|
return ListIterator{}, err
|
||||||
}
|
}
|
||||||
return ListIterator{Iterator{p: self}}, nil
|
return self.values(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Node) values() ListIterator {
|
||||||
|
return ListIterator{Iterator{p: self}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties returns iterator for object's children traversal
|
// Properties returns iterator for object's children traversal
|
||||||
|
@ -40,7 +44,11 @@ func (self *Node) Properties() (ObjectIterator, error) {
|
||||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||||
return ObjectIterator{}, err
|
return ObjectIterator{}, err
|
||||||
}
|
}
|
||||||
return ObjectIterator{Iterator{p: self}}, nil
|
return self.properties(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Node) properties() ObjectIterator {
|
||||||
|
return ObjectIterator{Iterator{p: self}}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Iterator struct {
|
type Iterator struct {
|
||||||
|
@ -114,7 +122,7 @@ next_start:
|
||||||
} else {
|
} else {
|
||||||
n := self.p.pairAt(self.i)
|
n := self.p.pairAt(self.i)
|
||||||
self.i++
|
self.i++
|
||||||
if !n.Value.Exists() {
|
if n == nil || !n.Value.Exists() {
|
||||||
goto next_start
|
goto next_start
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
253
vendor/github.com/bytedance/sonic/ast/node.go
generated
vendored
253
vendor/github.com/bytedance/sonic/ast/node.go
generated
vendored
|
@ -491,7 +491,6 @@ func (self *Node) StrictFloat64() (float64, error) {
|
||||||
|
|
||||||
// Len returns children count of a array|object|string node
|
// Len returns children count of a array|object|string node
|
||||||
// WARN: For partially loaded node, it also works but only counts the parsed children
|
// WARN: For partially loaded node, it also works but only counts the parsed children
|
||||||
// WARN: For ARRAY|OBJECT nodes which has been conducted `UnsetXX()`, its length WON'T change
|
|
||||||
func (self *Node) Len() (int, error) {
|
func (self *Node) Len() (int, error) {
|
||||||
if err := self.checkRaw(); err != nil {
|
if err := self.checkRaw(); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -538,6 +537,8 @@ func (self *Node) Set(key string, node Node) (bool, error) {
|
||||||
if self.t == _V_NONE || self.t == types.V_NULL {
|
if self.t == _V_NONE || self.t == types.V_NULL {
|
||||||
*self = NewObject([]Pair{{key, node}})
|
*self = NewObject([]Pair{{key, node}})
|
||||||
return false, nil
|
return false, nil
|
||||||
|
} else if self.itype() != types.V_OBJECT {
|
||||||
|
return false, ErrUnsupportType
|
||||||
}
|
}
|
||||||
|
|
||||||
p := self.Get(key)
|
p := self.Get(key)
|
||||||
|
@ -548,7 +549,7 @@ func (self *Node) Set(key string, node Node) (bool, error) {
|
||||||
*self = newObject(new(linkedPairs))
|
*self = newObject(new(linkedPairs))
|
||||||
}
|
}
|
||||||
s := (*linkedPairs)(self.p)
|
s := (*linkedPairs)(self.p)
|
||||||
s.Add(Pair{key, node})
|
s.Push(Pair{key, node})
|
||||||
self.l++
|
self.l++
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
||||||
|
@ -565,20 +566,22 @@ func (self *Node) SetAny(key string, val interface{}) (bool, error) {
|
||||||
return self.Set(key, NewAny(val))
|
return self.Set(key, NewAny(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unset RESET the node of given key under object parent, and reports if the key has existed.
|
// Unset REMOVE (soft) the node of given key under object parent, and reports if the key has existed.
|
||||||
// WARN: After conducting `UnsetXX()`, the node's length WON'T change
|
|
||||||
func (self *Node) Unset(key string) (bool, error) {
|
func (self *Node) Unset(key string) (bool, error) {
|
||||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
// NOTICE: must get acurate length before deduct
|
||||||
|
if err := self.skipAllKey(); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
p, i := self.skipKey(key)
|
p, i := self.skipKey(key)
|
||||||
if !p.Exists() {
|
if !p.Exists() {
|
||||||
return false, nil
|
return false, nil
|
||||||
} else if err := p.Check(); err != nil {
|
} else if err := p.Check(); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
self.removePairAt(i)
|
||||||
self.removePair(i)
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,22 +617,28 @@ func (self *Node) SetAnyByIndex(index int, val interface{}) (bool, error) {
|
||||||
return self.SetByIndex(index, NewAny(val))
|
return self.SetByIndex(index, NewAny(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsetByIndex remove the node of given index
|
// UnsetByIndex REOMVE (softly) the node of given index.
|
||||||
// WARN: After conducting `UnsetXX()`, the node's length WON'T change
|
//
|
||||||
|
// WARN: this will change address of elements, which is a dangerous action.
|
||||||
|
// Use Unset() for object or Pop() for array instead.
|
||||||
func (self *Node) UnsetByIndex(index int) (bool, error) {
|
func (self *Node) UnsetByIndex(index int) (bool, error) {
|
||||||
if err := self.Check(); err != nil {
|
if err := self.checkRaw(); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var p *Node
|
var p *Node
|
||||||
it := self.itype()
|
it := self.itype()
|
||||||
|
|
||||||
if it == types.V_ARRAY {
|
if it == types.V_ARRAY {
|
||||||
p = self.Index(index)
|
if err := self.skipAllIndex(); err != nil {
|
||||||
}else if it == types.V_OBJECT {
|
|
||||||
if err := self.checkRaw(); err != nil {
|
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
pr := self.skipIndexPair(index)
|
p = self.nodeAt(index)
|
||||||
|
} else if it == types.V_OBJECT {
|
||||||
|
if err := self.skipAllKey(); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
pr := self.pairAt(index)
|
||||||
if pr == nil {
|
if pr == nil {
|
||||||
return false, ErrNotExist
|
return false, ErrNotExist
|
||||||
}
|
}
|
||||||
|
@ -642,6 +651,12 @@ func (self *Node) UnsetByIndex(index int) (bool, error) {
|
||||||
return false, ErrNotExist
|
return false, ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// last elem
|
||||||
|
if index == self.len() - 1 {
|
||||||
|
return true, self.Pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// not last elem, self.len() change but linked-chunk not change
|
||||||
if it == types.V_ARRAY {
|
if it == types.V_ARRAY {
|
||||||
self.removeNode(index)
|
self.removeNode(index)
|
||||||
}else if it == types.V_OBJECT {
|
}else if it == types.V_OBJECT {
|
||||||
|
@ -665,16 +680,101 @@ func (self *Node) Add(node Node) error {
|
||||||
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := self.unsafeArray()
|
s, err := self.unsafeArray()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Add(node)
|
// Notice: array won't have unset node in tail
|
||||||
|
s.Push(node)
|
||||||
self.l++
|
self.l++
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pop remove the last child of the V_Array or V_Object node.
|
||||||
|
func (self *Node) Pop() error {
|
||||||
|
if err := self.checkRaw(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if it := self.itype(); it == types.V_ARRAY {
|
||||||
|
s, err := self.unsafeArray()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// remove tail unset nodes
|
||||||
|
for i := s.Len()-1; i >= 0; i-- {
|
||||||
|
if s.At(i).Exists() {
|
||||||
|
s.Pop()
|
||||||
|
self.l--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
s.Pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if it == types.V_OBJECT {
|
||||||
|
s, err := self.unsafeMap()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// remove tail unset nodes
|
||||||
|
for i := s.Len()-1; i >= 0; i-- {
|
||||||
|
if p := s.At(i); p != nil && p.Value.Exists() {
|
||||||
|
s.Pop()
|
||||||
|
self.l--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
s.Pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return ErrUnsupportType
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move moves the child at src index to dst index,
|
||||||
|
// meanwhile slides sliblings from src+1 to dst.
|
||||||
|
//
|
||||||
|
// WARN: this will change address of elements, which is a dangerous action.
|
||||||
|
func (self *Node) Move(dst, src int) error {
|
||||||
|
if err := self.should(types.V_ARRAY, "an array"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := self.unsafeArray()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if any unset node exists
|
||||||
|
if l := s.Len(); self.len() != l {
|
||||||
|
di, si := dst, src
|
||||||
|
// find real pos of src and dst
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
if s.At(i).Exists() {
|
||||||
|
di--
|
||||||
|
si--
|
||||||
|
}
|
||||||
|
if di == -1 {
|
||||||
|
dst = i
|
||||||
|
di--
|
||||||
|
}
|
||||||
|
if si == -1 {
|
||||||
|
src = i
|
||||||
|
si--
|
||||||
|
}
|
||||||
|
if di == -2 && si == -2 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.MoveOne(src, dst)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetAny wraps val with V_ANY node, and Add() the node.
|
// SetAny wraps val with V_ANY node, and Add() the node.
|
||||||
func (self *Node) AddAny(val interface{}) error {
|
func (self *Node) AddAny(val interface{}) error {
|
||||||
|
@ -721,8 +821,6 @@ func (self *Node) Get(key string) *Node {
|
||||||
|
|
||||||
// Index indexies node at given idx,
|
// Index indexies node at given idx,
|
||||||
// node type CAN be either V_OBJECT or V_ARRAY
|
// node type CAN be either V_OBJECT or V_ARRAY
|
||||||
// WARN: After conducting `UnsetXX()`, the node's length WON'T change,
|
|
||||||
// thus its children's indexing WON'T change too
|
|
||||||
func (self *Node) Index(idx int) *Node {
|
func (self *Node) Index(idx int) *Node {
|
||||||
if err := self.checkRaw(); err != nil {
|
if err := self.checkRaw(); err != nil {
|
||||||
return unwrapError(err)
|
return unwrapError(err)
|
||||||
|
@ -746,8 +844,6 @@ func (self *Node) Index(idx int) *Node {
|
||||||
|
|
||||||
// IndexPair indexies pair at given idx,
|
// IndexPair indexies pair at given idx,
|
||||||
// node type MUST be either V_OBJECT
|
// node type MUST be either V_OBJECT
|
||||||
// WARN: After conducting `UnsetXX()`, the node's length WON'T change,
|
|
||||||
// thus its children's indexing WON'T change too
|
|
||||||
func (self *Node) IndexPair(idx int) *Pair {
|
func (self *Node) IndexPair(idx int) *Pair {
|
||||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -755,19 +851,30 @@ func (self *Node) IndexPair(idx int) *Pair {
|
||||||
return self.skipIndexPair(idx)
|
return self.skipIndexPair(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Node) indexOrGet(idx int, key string) (*Node, int) {
|
||||||
|
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
||||||
|
return unwrapError(err), idx
|
||||||
|
}
|
||||||
|
|
||||||
|
pr := self.skipIndexPair(idx)
|
||||||
|
if pr != nil && pr.Key == key {
|
||||||
|
return &pr.Value, idx
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.skipKey(key)
|
||||||
|
}
|
||||||
|
|
||||||
// IndexOrGet firstly use idx to index a value and check if its key matches
|
// IndexOrGet firstly use idx to index a value and check if its key matches
|
||||||
// If not, then use the key to search value
|
// If not, then use the key to search value
|
||||||
func (self *Node) IndexOrGet(idx int, key string) *Node {
|
func (self *Node) IndexOrGet(idx int, key string) *Node {
|
||||||
if err := self.should(types.V_OBJECT, "an object"); err != nil {
|
node, _ := self.indexOrGet(idx, key)
|
||||||
return unwrapError(err)
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
pr := self.skipIndexPair(idx)
|
// IndexOrGetWithIdx attempts to retrieve a node by index and key, returning the node and its correct index.
|
||||||
if pr != nil && pr.Key == key {
|
// If the key does not match at the given index, it searches by key and returns the node with its updated index.
|
||||||
return &pr.Value
|
func (self *Node) IndexOrGetWithIdx(idx int, key string) (*Node, int) {
|
||||||
}
|
return self.indexOrGet(idx, key)
|
||||||
n, _ := self.skipKey(key)
|
|
||||||
return n
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generic Value Converters **/
|
/** Generic Value Converters **/
|
||||||
|
@ -864,7 +971,7 @@ func (self *Node) SortKeys(recurse bool) error {
|
||||||
}
|
}
|
||||||
if self.itype() == types.V_OBJECT {
|
if self.itype() == types.V_OBJECT {
|
||||||
return self.sortKeys(recurse)
|
return self.sortKeys(recurse)
|
||||||
} else {
|
} else if self.itype() == types.V_ARRAY {
|
||||||
var err error
|
var err error
|
||||||
err2 := self.ForEach(func(path Sequence, node *Node) bool {
|
err2 := self.ForEach(func(path Sequence, node *Node) bool {
|
||||||
it := node.itype()
|
it := node.itype()
|
||||||
|
@ -880,10 +987,16 @@ func (self *Node) SortKeys(recurse bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return err2
|
return err2
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Node) sortKeys(recurse bool) (err error) {
|
func (self *Node) sortKeys(recurse bool) (err error) {
|
||||||
|
// check raw node first
|
||||||
|
if err := self.checkRaw(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ps, err := self.unsafeMap()
|
ps, err := self.unsafeMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1172,6 +1285,19 @@ func (self *Node) nodeAt(i int) *Node {
|
||||||
p = &stack.v
|
p = &stack.v
|
||||||
} else {
|
} else {
|
||||||
p = (*linkedNodes)(self.p)
|
p = (*linkedNodes)(self.p)
|
||||||
|
if l := p.Len(); l != self.len() {
|
||||||
|
// some nodes got unset, iterate to skip them
|
||||||
|
for j:=0; j<l; j++ {
|
||||||
|
v := p.At(j)
|
||||||
|
if v.Exists() {
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
if i < 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return p.At(i)
|
return p.At(i)
|
||||||
}
|
}
|
||||||
|
@ -1183,6 +1309,19 @@ func (self *Node) pairAt(i int) *Pair {
|
||||||
p = &stack.v
|
p = &stack.v
|
||||||
} else {
|
} else {
|
||||||
p = (*linkedPairs)(self.p)
|
p = (*linkedPairs)(self.p)
|
||||||
|
if l := p.Len(); l != self.len() {
|
||||||
|
// some nodes got unset, iterate to skip them
|
||||||
|
for j:=0; j<l; j++ {
|
||||||
|
v := p.At(j)
|
||||||
|
if v != nil && v.Value.Exists() {
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
if i < 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return p.At(i)
|
return p.At(i)
|
||||||
}
|
}
|
||||||
|
@ -1334,8 +1473,8 @@ func (self *Node) removeNode(i int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*node = Node{}
|
*node = Node{}
|
||||||
// NOTICE: for consistency with linkedNodes, we DOSEN'T reduce size here
|
// NOTICE: not be consistent with linkedNode.Len()
|
||||||
// self.l--
|
self.l--
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Node) removePair(i int) {
|
func (self *Node) removePair(i int) {
|
||||||
|
@ -1344,8 +1483,18 @@ func (self *Node) removePair(i int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*last = Pair{}
|
*last = Pair{}
|
||||||
// NOTICE: for consistency with linkedNodes, we DOSEN'T reduce size here
|
// NOTICE: should be consistent with linkedPair.Len()
|
||||||
// self.l--
|
self.l--
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Node) removePairAt(i int) {
|
||||||
|
p := (*linkedPairs)(self.p).At(i)
|
||||||
|
if p == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
*p = Pair{}
|
||||||
|
// NOTICE: should be consistent with linkedPair.Len()
|
||||||
|
self.l--
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Node) toGenericArray() ([]interface{}, error) {
|
func (self *Node) toGenericArray() ([]interface{}, error) {
|
||||||
|
@ -1353,17 +1502,16 @@ func (self *Node) toGenericArray() ([]interface{}, error) {
|
||||||
if nb == 0 {
|
if nb == 0 {
|
||||||
return []interface{}{}, nil
|
return []interface{}{}, nil
|
||||||
}
|
}
|
||||||
ret := make([]interface{}, nb)
|
ret := make([]interface{}, 0, nb)
|
||||||
|
|
||||||
/* convert each item */
|
/* convert each item */
|
||||||
var s = (*linkedNodes)(self.p)
|
it := self.values()
|
||||||
for i := 0; i < nb; i++ {
|
for v := it.next(); v != nil; v = it.next() {
|
||||||
p := s.At(i)
|
vv, err := v.Interface()
|
||||||
x, err := p.Interface()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ret[i] = x
|
ret = append(ret, vv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all done */
|
/* all done */
|
||||||
|
@ -1375,17 +1523,16 @@ func (self *Node) toGenericArrayUseNumber() ([]interface{}, error) {
|
||||||
if nb == 0 {
|
if nb == 0 {
|
||||||
return []interface{}{}, nil
|
return []interface{}{}, nil
|
||||||
}
|
}
|
||||||
ret := make([]interface{}, nb)
|
ret := make([]interface{}, 0, nb)
|
||||||
|
|
||||||
/* convert each item */
|
/* convert each item */
|
||||||
var s = (*linkedNodes)(self.p)
|
it := self.values()
|
||||||
for i := 0; i < nb; i++ {
|
for v := it.next(); v != nil; v = it.next() {
|
||||||
p := s.At(i)
|
vv, err := v.InterfaceUseNumber()
|
||||||
x, err := p.InterfaceUseNumber()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ret[i] = x
|
ret = append(ret, vv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all done */
|
/* all done */
|
||||||
|
@ -1413,14 +1560,13 @@ func (self *Node) toGenericObject() (map[string]interface{}, error) {
|
||||||
ret := make(map[string]interface{}, nb)
|
ret := make(map[string]interface{}, nb)
|
||||||
|
|
||||||
/* convert each item */
|
/* convert each item */
|
||||||
var s = (*linkedPairs)(self.p)
|
it := self.properties()
|
||||||
for i := 0; i < nb; i++ {
|
for v := it.next(); v != nil; v = it.next() {
|
||||||
p := s.At(i)
|
vv, err := v.Value.Interface()
|
||||||
x, err := p.Value.Interface()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ret[p.Key] = x
|
ret[v.Key] = vv
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all done */
|
/* all done */
|
||||||
|
@ -1436,14 +1582,13 @@ func (self *Node) toGenericObjectUseNumber() (map[string]interface{}, error) {
|
||||||
ret := make(map[string]interface{}, nb)
|
ret := make(map[string]interface{}, nb)
|
||||||
|
|
||||||
/* convert each item */
|
/* convert each item */
|
||||||
var s = (*linkedPairs)(self.p)
|
it := self.properties()
|
||||||
for i := 0; i < nb; i++ {
|
for v := it.next(); v != nil; v = it.next() {
|
||||||
p := s.At(i)
|
vv, err := v.Value.InterfaceUseNumber()
|
||||||
x, err := p.Value.InterfaceUseNumber()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ret[p.Key] = x
|
ret[v.Key] = vv
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all done */
|
/* all done */
|
||||||
|
|
8
vendor/github.com/bytedance/sonic/ast/parser.go
generated
vendored
8
vendor/github.com/bytedance/sonic/ast/parser.go
generated
vendored
|
@ -157,7 +157,7 @@ func (self *Parser) decodeArray(ret *linkedNodes) (Node, types.ParsingError) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the value to result */
|
/* add the value to result */
|
||||||
ret.Add(val)
|
ret.Push(val)
|
||||||
self.p = self.lspace(self.p)
|
self.p = self.lspace(self.p)
|
||||||
|
|
||||||
/* check for EOF */
|
/* check for EOF */
|
||||||
|
@ -244,7 +244,7 @@ func (self *Parser) decodeObject(ret *linkedPairs) (Node, types.ParsingError) {
|
||||||
|
|
||||||
/* add the value to result */
|
/* add the value to result */
|
||||||
// FIXME: ret's address may change here, thus previous referred node in ret may be invalid !!
|
// FIXME: ret's address may change here, thus previous referred node in ret may be invalid !!
|
||||||
ret.Add(Pair{Key: key, Value: val})
|
ret.Push(Pair{Key: key, Value: val})
|
||||||
self.p = self.lspace(self.p)
|
self.p = self.lspace(self.p)
|
||||||
|
|
||||||
/* check for EOF */
|
/* check for EOF */
|
||||||
|
@ -475,7 +475,7 @@ func (self *Node) skipNextNode() *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the value to result */
|
/* add the value to result */
|
||||||
ret.Add(val)
|
ret.Push(val)
|
||||||
self.l++
|
self.l++
|
||||||
parser.p = parser.lspace(parser.p)
|
parser.p = parser.lspace(parser.p)
|
||||||
|
|
||||||
|
@ -558,7 +558,7 @@ func (self *Node) skipNextPair() (*Pair) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the value to result */
|
/* add the value to result */
|
||||||
ret.Add(Pair{Key: key, Value: val})
|
ret.Push(Pair{Key: key, Value: val})
|
||||||
self.l++
|
self.l++
|
||||||
parser.p = parser.lspace(parser.p)
|
parser.p = parser.lspace(parser.p)
|
||||||
|
|
||||||
|
|
50
vendor/github.com/bytedance/sonic/ast/search.go
generated
vendored
50
vendor/github.com/bytedance/sonic/ast/search.go
generated
vendored
|
@ -16,6 +16,11 @@
|
||||||
|
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
`github.com/bytedance/sonic/internal/rt`
|
||||||
|
`github.com/bytedance/sonic/internal/native/types`
|
||||||
|
)
|
||||||
|
|
||||||
type Searcher struct {
|
type Searcher struct {
|
||||||
parser Parser
|
parser Parser
|
||||||
}
|
}
|
||||||
|
@ -28,3 +33,48 @@ func NewSearcher(str string) *Searcher {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetByPathCopy search in depth from top json and returns a **Copied** json node at the path location
|
||||||
|
func (self *Searcher) GetByPathCopy(path ...interface{}) (Node, error) {
|
||||||
|
return self.getByPath(true, path...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetByPathNoCopy search in depth from top json and returns a **Referenced** json node at the path location
|
||||||
|
//
|
||||||
|
// WARN: this search directly refer partial json from top json, which has faster speed,
|
||||||
|
// may consumes more memory.
|
||||||
|
func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
|
||||||
|
return self.getByPath(false, path...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Searcher) getByPath(copystring bool, path ...interface{}) (Node, error) {
|
||||||
|
var err types.ParsingError
|
||||||
|
var start int
|
||||||
|
|
||||||
|
self.parser.p = 0
|
||||||
|
start, err = self.parser.getByPath(path...)
|
||||||
|
if err != 0 {
|
||||||
|
// for compatibility with old version
|
||||||
|
if err == types.ERR_NOT_FOUND {
|
||||||
|
return Node{}, ErrNotExist
|
||||||
|
}
|
||||||
|
if err == types.ERR_UNSUPPORT_TYPE {
|
||||||
|
panic("path must be either int(>=0) or string")
|
||||||
|
}
|
||||||
|
return Node{}, self.parser.syntaxError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t := switchRawType(self.parser.s[start])
|
||||||
|
if t == _V_NONE {
|
||||||
|
return Node{}, self.parser.ExportError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy string to reducing memory usage
|
||||||
|
var raw string
|
||||||
|
if copystring {
|
||||||
|
raw = rt.Mem2Str([]byte(self.parser.s[start:self.parser.p]))
|
||||||
|
} else {
|
||||||
|
raw = self.parser.s[start:self.parser.p]
|
||||||
|
}
|
||||||
|
return newRawNode(raw, t), nil
|
||||||
|
}
|
||||||
|
|
2
vendor/github.com/bytedance/sonic/compat.go
generated
vendored
2
vendor/github.com/bytedance/sonic/compat.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build !amd64 !go1.16 go1.22
|
// +build !amd64 !go1.16 go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
2
vendor/github.com/bytedance/sonic/decoder/decoder_amd64.go
generated
vendored
2
vendor/github.com/bytedance/sonic/decoder/decoder_amd64.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64,go1.16,!go1.22
|
// +build amd64,go1.16,!go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2023 ByteDance Inc.
|
* Copyright 2023 ByteDance Inc.
|
||||||
|
|
4
vendor/github.com/bytedance/sonic/decoder/decoder_compat.go
generated
vendored
4
vendor/github.com/bytedance/sonic/decoder/decoder_compat.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build !amd64 !go1.16 go1.22
|
// +build !amd64 !go1.16 go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2023 ByteDance Inc.
|
* Copyright 2023 ByteDance Inc.
|
||||||
|
@ -30,7 +30,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
println("WARNING: sonic only supports Go1.16~1.20 && CPU amd64, but your environment is not suitable")
|
println("WARNING: sonic only supports Go1.16~1.22 && CPU amd64, but your environment is not suitable")
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
5
vendor/github.com/bytedance/sonic/encoder/encoder_amd64.go
generated
vendored
5
vendor/github.com/bytedance/sonic/encoder/encoder_amd64.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64,go1.16,!go1.22
|
// +build amd64,go1.16,!go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2023 ByteDance Inc.
|
* Copyright 2023 ByteDance Inc.
|
||||||
|
@ -63,6 +63,9 @@ const (
|
||||||
// after encoding the JSONMarshaler to JSON.
|
// after encoding the JSONMarshaler to JSON.
|
||||||
NoValidateJSONMarshaler Options = encoder.NoValidateJSONMarshaler
|
NoValidateJSONMarshaler Options = encoder.NoValidateJSONMarshaler
|
||||||
|
|
||||||
|
// NoEncoderNewline indicates that the encoder should not add a newline after every message
|
||||||
|
NoEncoderNewline Options = encoder.NoEncoderNewline
|
||||||
|
|
||||||
// CompatibleWithStd is used to be compatible with std encoder.
|
// CompatibleWithStd is used to be compatible with std encoder.
|
||||||
CompatibleWithStd Options = encoder.CompatibleWithStd
|
CompatibleWithStd Options = encoder.CompatibleWithStd
|
||||||
)
|
)
|
||||||
|
|
17
vendor/github.com/bytedance/sonic/encoder/encoder_compat.go
generated
vendored
17
vendor/github.com/bytedance/sonic/encoder/encoder_compat.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build !amd64 !go1.16 go1.22
|
// +build !amd64 !go1.16 go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2023 ByteDance Inc.
|
* Copyright 2023 ByteDance Inc.
|
||||||
|
@ -28,7 +28,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
println("WARNING: sonic only supports Go1.16~1.20 && CPU amd64, but your environment is not suitable")
|
println("WARNING: sonic only supports Go1.16~1.22 && CPU amd64, but your environment is not suitable")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options is a set of encoding options.
|
// Options is a set of encoding options.
|
||||||
|
@ -42,6 +42,7 @@ const (
|
||||||
bitNoNullSliceOrMap
|
bitNoNullSliceOrMap
|
||||||
bitValidateString
|
bitValidateString
|
||||||
bitNoValidateJSONMarshaler
|
bitNoValidateJSONMarshaler
|
||||||
|
bitNoEncoderNewline
|
||||||
|
|
||||||
// used for recursive compile
|
// used for recursive compile
|
||||||
bitPointerValue = 63
|
bitPointerValue = 63
|
||||||
|
@ -78,6 +79,9 @@ const (
|
||||||
// after encoding the JSONMarshaler to JSON.
|
// after encoding the JSONMarshaler to JSON.
|
||||||
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler
|
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler
|
||||||
|
|
||||||
|
// NoEncoderNewline indicates that the encoder should not add a newline after every message
|
||||||
|
NoEncoderNewline Options = 1 << bitNoEncoderNewline
|
||||||
|
|
||||||
// CompatibleWithStd is used to be compatible with std encoder.
|
// CompatibleWithStd is used to be compatible with std encoder.
|
||||||
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
|
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
|
||||||
)
|
)
|
||||||
|
@ -130,6 +134,15 @@ func (self *Encoder) SetNoValidateJSONMarshaler(f bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNoEncoderNewline specifies if option NoEncoderNewline opens
|
||||||
|
func (self *Encoder) SetNoEncoderNewline(f bool) {
|
||||||
|
if f {
|
||||||
|
self.Opts |= NoEncoderNewline
|
||||||
|
} else {
|
||||||
|
self.Opts &= ^NoEncoderNewline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetCompactMarshaler specifies if option CompactMarshaler opens
|
// SetCompactMarshaler specifies if option CompactMarshaler opens
|
||||||
func (self *Encoder) SetCompactMarshaler(f bool) {
|
func (self *Encoder) SetCompactMarshaler(f bool) {
|
||||||
if f {
|
if f {
|
||||||
|
|
2
vendor/github.com/bytedance/sonic/internal/decoder/asm_stubs_amd64_go121.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/decoder/asm_stubs_amd64_go121.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build go1.21,!go1.22
|
// +build go1.21,!go1.23
|
||||||
|
|
||||||
// Copyright 2023 CloudWeGo Authors
|
// Copyright 2023 CloudWeGo Authors
|
||||||
//
|
//
|
||||||
|
|
12
vendor/github.com/bytedance/sonic/internal/decoder/assembler_regabi_amd64.go
generated
vendored
12
vendor/github.com/bytedance/sonic/internal/decoder/assembler_regabi_amd64.go
generated
vendored
|
@ -1,5 +1,4 @@
|
||||||
//go:build go1.17 && !go1.22
|
// +build go1.17,!go1.23
|
||||||
// +build go1.17,!go1.22
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
@ -420,9 +419,9 @@ func (self *_Assembler) call_go(fn obj.Addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Assembler) callc(fn obj.Addr) {
|
func (self *_Assembler) callc(fn obj.Addr) {
|
||||||
self.Emit("XCHGQ", _IP, _BP)
|
self.save(_IP)
|
||||||
self.call(fn)
|
self.call(fn)
|
||||||
self.Emit("XCHGQ", _IP, _BP)
|
self.load(_IP)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Assembler) call_c(fn obj.Addr) {
|
func (self *_Assembler) call_c(fn obj.Addr) {
|
||||||
|
@ -1164,7 +1163,7 @@ var (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_F_FieldMap_GetCaseInsensitive obj.Addr
|
_F_FieldMap_GetCaseInsensitive obj.Addr
|
||||||
_Empty_Slice = make([]byte, 0)
|
_Empty_Slice = []byte{}
|
||||||
_Zero_Base = int64(uintptr(((*rt.GoSlice)(unsafe.Pointer(&_Empty_Slice))).Ptr))
|
_Zero_Base = int64(uintptr(((*rt.GoSlice)(unsafe.Pointer(&_Empty_Slice))).Ptr))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1641,7 +1640,8 @@ func (self *_Assembler) _asm_OP_check_empty(p *_Instr) {
|
||||||
self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(rbracket))) // CMPB (IP)(IC), ']'
|
self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(rbracket))) // CMPB (IP)(IC), ']'
|
||||||
self.Sjmp("JNE" , "_not_empty_array_{n}") // JNE _not_empty_array_{n}
|
self.Sjmp("JNE" , "_not_empty_array_{n}") // JNE _not_empty_array_{n}
|
||||||
self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC
|
self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC
|
||||||
self.StorePtr(_Zero_Base, jit.Ptr(_VP, 0), _AX) // MOVQ $zerobase, (VP)
|
self.Emit("MOVQ", jit.Imm(_Zero_Base), _AX)
|
||||||
|
self.WritePtrAX(9, jit.Ptr(_VP, 0), false)
|
||||||
self.Emit("PXOR", _X0, _X0) // PXOR X0, X0
|
self.Emit("PXOR", _X0, _X0) // PXOR X0, X0
|
||||||
self.Emit("MOVOU", _X0, jit.Ptr(_VP, 8)) // MOVOU X0, 8(VP)
|
self.Emit("MOVOU", _X0, jit.Ptr(_VP, 8)) // MOVOU X0, 8(VP)
|
||||||
self.Xjmp("JMP" , p.vi()) // JMP {p.vi()}
|
self.Xjmp("JMP" , p.vi()) // JMP {p.vi()}
|
||||||
|
|
3
vendor/github.com/bytedance/sonic/internal/decoder/assembler_stkabi_amd64.go
generated
vendored
3
vendor/github.com/bytedance/sonic/internal/decoder/assembler_stkabi_amd64.go
generated
vendored
|
@ -1651,7 +1651,8 @@ func (self *_Assembler) _asm_OP_check_empty(p *_Instr) {
|
||||||
self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(rbracket))) // CMPB (IP)(IC), ']'
|
self.Emit("CMPB", jit.Sib(_IP, _IC, 1, 0), jit.Imm(int64(rbracket))) // CMPB (IP)(IC), ']'
|
||||||
self.Sjmp("JNE" , "_not_empty_array_{n}") // JNE _not_empty_array_{n}
|
self.Sjmp("JNE" , "_not_empty_array_{n}") // JNE _not_empty_array_{n}
|
||||||
self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC
|
self.Emit("MOVQ", _AX, _IC) // MOVQ AX, IC
|
||||||
self.StorePtr(_Zero_Base, jit.Ptr(_VP, 0), _AX) // MOVQ $zerobase, (VP)
|
self.Emit("MOVQ", jit.Imm(_Zero_Base), _AX)
|
||||||
|
self.WritePtrAX(9, jit.Ptr(_VP, 0), false)
|
||||||
self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0
|
self.Emit("PXOR" , _X0, _X0) // PXOR X0, X0
|
||||||
self.Emit("MOVOU", _X0, jit.Ptr(_VP, 8)) // MOVOU X0, 8(VP)
|
self.Emit("MOVOU", _X0, jit.Ptr(_VP, 8)) // MOVOU X0, 8(VP)
|
||||||
self.Xjmp("JMP" , p.vi()) // JMP {p.vi()}
|
self.Xjmp("JMP" , p.vi()) // JMP {p.vi()}
|
||||||
|
|
73
vendor/github.com/bytedance/sonic/internal/decoder/compiler.go
generated
vendored
73
vendor/github.com/bytedance/sonic/internal/decoder/compiler.go
generated
vendored
|
@ -527,6 +527,38 @@ func (self *_Compiler) compile(vt reflect.Type) (ret _Program, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *_Compiler) checkMarshaler(p *_Program, vt reflect.Type) bool {
|
||||||
|
pt := reflect.PtrTo(vt)
|
||||||
|
|
||||||
|
/* check for `json.Unmarshaler` with pointer receiver */
|
||||||
|
if pt.Implements(jsonUnmarshalerType) {
|
||||||
|
p.rtt(_OP_unmarshal_p, pt)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for `json.Unmarshaler` */
|
||||||
|
if vt.Implements(jsonUnmarshalerType) {
|
||||||
|
p.add(_OP_lspace)
|
||||||
|
self.compileUnmarshalJson(p, vt)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for `encoding.TextMarshaler` with pointer receiver */
|
||||||
|
if pt.Implements(encodingTextUnmarshalerType) {
|
||||||
|
p.add(_OP_lspace)
|
||||||
|
self.compileUnmarshalTextPtr(p, pt)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for `encoding.TextUnmarshaler` */
|
||||||
|
if vt.Implements(encodingTextUnmarshalerType) {
|
||||||
|
p.add(_OP_lspace)
|
||||||
|
self.compileUnmarshalText(p, vt)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) {
|
func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) {
|
||||||
/* check for recursive nesting */
|
/* check for recursive nesting */
|
||||||
ok := self.tab[vt]
|
ok := self.tab[vt]
|
||||||
|
@ -535,32 +567,7 @@ func (self *_Compiler) compileOne(p *_Program, sp int, vt reflect.Type) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pt := reflect.PtrTo(vt)
|
if self.checkMarshaler(p, vt) {
|
||||||
|
|
||||||
/* check for `json.Unmarshaler` with pointer receiver */
|
|
||||||
if pt.Implements(jsonUnmarshalerType) {
|
|
||||||
p.rtt(_OP_unmarshal_p, pt)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for `json.Unmarshaler` */
|
|
||||||
if vt.Implements(jsonUnmarshalerType) {
|
|
||||||
p.add(_OP_lspace)
|
|
||||||
self.compileUnmarshalJson(p, vt)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for `encoding.TextMarshaler` with pointer receiver */
|
|
||||||
if pt.Implements(encodingTextUnmarshalerType) {
|
|
||||||
p.add(_OP_lspace)
|
|
||||||
self.compileUnmarshalTextPtr(p, pt)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for `encoding.TextUnmarshaler` */
|
|
||||||
if vt.Implements(encodingTextUnmarshalerType) {
|
|
||||||
p.add(_OP_lspace)
|
|
||||||
self.compileUnmarshalText(p, vt)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,17 +690,9 @@ func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) {
|
||||||
|
|
||||||
/* dereference all the way down */
|
/* dereference all the way down */
|
||||||
for et.Kind() == reflect.Ptr {
|
for et.Kind() == reflect.Ptr {
|
||||||
if et.Implements(jsonUnmarshalerType) {
|
if self.checkMarshaler(p, et) {
|
||||||
p.rtt(_OP_unmarshal_p, et)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if et.Implements(encodingTextUnmarshalerType) {
|
|
||||||
p.add(_OP_lspace)
|
|
||||||
self.compileUnmarshalTextPtr(p, et)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
et = et.Elem()
|
et = et.Elem()
|
||||||
p.rtt(_OP_deref, et)
|
p.rtt(_OP_deref, et)
|
||||||
}
|
}
|
||||||
|
@ -716,8 +715,12 @@ func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) {
|
||||||
|
|
||||||
j := p.pc()
|
j := p.pc()
|
||||||
p.add(_OP_goto)
|
p.add(_OP_goto)
|
||||||
|
|
||||||
|
// set val pointer as nil
|
||||||
p.pin(i)
|
p.pin(i)
|
||||||
p.add(_OP_nil_1)
|
p.add(_OP_nil_1)
|
||||||
|
|
||||||
|
// nothing todo
|
||||||
p.pin(j)
|
p.pin(j)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64.go
generated
vendored
6
vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build go1.17,!go1.22
|
// +build go1.17,!go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
@ -119,9 +119,9 @@ func (self *_ValueDecoder) call_go(fn obj.Addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_ValueDecoder) callc(fn obj.Addr) {
|
func (self *_ValueDecoder) callc(fn obj.Addr) {
|
||||||
self.Emit("XCHGQ", _IP, _BP)
|
self.save(_IP)
|
||||||
self.call(fn)
|
self.call(fn)
|
||||||
self.Emit("XCHGQ", _IP, _BP)
|
self.load(_IP)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_ValueDecoder) call_c(fn obj.Addr) {
|
func (self *_ValueDecoder) call_c(fn obj.Addr) {
|
||||||
|
|
2
vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64_test.s
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/decoder/generic_regabi_amd64_test.s
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build go1.17,!go1.22
|
// +build go1.17,!go1.23
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright 2021 ByteDance Inc.
|
// Copyright 2021 ByteDance Inc.
|
||||||
|
|
201
vendor/github.com/bytedance/sonic/internal/decoder/stream.go
generated
vendored
201
vendor/github.com/bytedance/sonic/internal/decoder/stream.go
generated
vendored
|
@ -23,11 +23,12 @@ import (
|
||||||
|
|
||||||
`github.com/bytedance/sonic/internal/native`
|
`github.com/bytedance/sonic/internal/native`
|
||||||
`github.com/bytedance/sonic/internal/native/types`
|
`github.com/bytedance/sonic/internal/native/types`
|
||||||
|
`github.com/bytedance/sonic/internal/rt`
|
||||||
`github.com/bytedance/sonic/option`
|
`github.com/bytedance/sonic/option`
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
minLeftBufferShift uint = 1
|
minLeftBufferShift uint = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
// StreamDecoder is the decoder context object for streaming input.
|
// StreamDecoder is the decoder context object for streaming input.
|
||||||
|
@ -58,95 +59,71 @@ func NewStreamDecoder(r io.Reader) *StreamDecoder {
|
||||||
// Either io error from underlying io.Reader (except io.EOF)
|
// Either io error from underlying io.Reader (except io.EOF)
|
||||||
// or syntax error from data will be recorded and stop subsequently decoding.
|
// or syntax error from data will be recorded and stop subsequently decoding.
|
||||||
func (self *StreamDecoder) Decode(val interface{}) (err error) {
|
func (self *StreamDecoder) Decode(val interface{}) (err error) {
|
||||||
if self.err != nil {
|
// read more data into buf
|
||||||
return self.err
|
if self.More() {
|
||||||
}
|
// println(string(self.buf))
|
||||||
|
var s = self.scanp
|
||||||
var buf = self.buf[self.scanp:]
|
try_skip:
|
||||||
var p = 0
|
var e = len(self.buf)
|
||||||
var recycle bool
|
// println("s:", s, "e:", e, "scanned:",self.scanned, "scanp:",self.scanp, self.buf)
|
||||||
if cap(buf) == 0 {
|
var src = rt.Mem2Str(self.buf[s:e])
|
||||||
buf = bufPool.Get().([]byte)
|
// if len(src) > 5 {
|
||||||
recycle = true
|
// println(src[:5], src[len(src)-5:])
|
||||||
}
|
// } else {
|
||||||
|
// println(src)
|
||||||
var first = true
|
// }
|
||||||
var repeat = true
|
// try skip
|
||||||
|
var x = 0;
|
||||||
read_more:
|
if y := native.SkipOneFast(&src, &x); y < 0 {
|
||||||
for {
|
if self.readMore() {
|
||||||
l := len(buf)
|
// println("more")
|
||||||
realloc(&buf)
|
goto try_skip
|
||||||
n, err := self.r.Read(buf[l:cap(buf)])
|
|
||||||
buf = buf[:l+n]
|
|
||||||
if err != nil {
|
|
||||||
repeat = false
|
|
||||||
if err == io.EOF {
|
|
||||||
if len(buf) == 0 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
self.err = err
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if n > 0 || first {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first = false
|
|
||||||
|
|
||||||
l := len(buf)
|
|
||||||
if l > 0 {
|
|
||||||
self.Decoder.Reset(string(buf))
|
|
||||||
|
|
||||||
var x int
|
|
||||||
if ret := native.SkipOneFast(&self.s, &x); ret < 0 {
|
|
||||||
if repeat {
|
|
||||||
goto read_more
|
|
||||||
} else {
|
} else {
|
||||||
err = SyntaxError{x, self.s, types.ParsingError(-ret), ""}
|
// println("no more")
|
||||||
self.err = err
|
err = SyntaxError{e, self.s, types.ParsingError(-s), ""}
|
||||||
|
self.setErr(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
s = y + s
|
||||||
|
e = x + s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// println("decode: ", s, e)
|
||||||
|
// must copy string here for safety
|
||||||
|
self.Decoder.Reset(string(self.buf[s:e]))
|
||||||
err = self.Decoder.Decode(val)
|
err = self.Decoder.Decode(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.err = err
|
self.setErr(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p = self.Decoder.Pos()
|
self.scanp = e
|
||||||
self.scanned += int64(p)
|
_, empty := self.scan()
|
||||||
|
if empty {
|
||||||
|
// println("recycle")
|
||||||
|
// no remain valid bytes, thus we just recycle buffer
|
||||||
|
mem := self.buf
|
||||||
|
self.buf = nil
|
||||||
|
bufPool.Put(mem[:0])
|
||||||
|
} else {
|
||||||
|
// println("keep")
|
||||||
|
// remain undecoded bytes, move them onto head
|
||||||
|
n := copy(self.buf, self.buf[self.scanp:])
|
||||||
|
self.buf = self.buf[:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
self.scanned += int64(self.scanp)
|
||||||
self.scanp = 0
|
self.scanp = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if l > p {
|
return self.err
|
||||||
// remain undecoded bytes, so copy them into self.buf
|
|
||||||
self.buf = append(self.buf[:0], buf[p:]...)
|
|
||||||
} else {
|
|
||||||
self.buf = nil
|
|
||||||
recycle = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if recycle {
|
|
||||||
buf = buf[:0]
|
|
||||||
bufPool.Put(buf)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self StreamDecoder) repeatable(err error) bool {
|
|
||||||
if ee, ok := err.(SyntaxError); ok &&
|
|
||||||
(ee.Code == types.ERR_EOF || (ee.Code == types.ERR_INVALID_CHAR && self.i >= len(self.s)-1)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// InputOffset returns the input stream byte offset of the current decoder position.
|
// InputOffset returns the input stream byte offset of the current decoder position.
|
||||||
// The offset gives the location of the end of the most recently returned token and the beginning of the next token.
|
// The offset gives the location of the end of the most recently returned token and the beginning of the next token.
|
||||||
func (self *StreamDecoder) InputOffset() int64 {
|
func (self *StreamDecoder) InputOffset() int64 {
|
||||||
|
// println("input offset",self.scanned, self.scanp)
|
||||||
return self.scanned + int64(self.scanp)
|
return self.scanned + int64(self.scanp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,28 +143,72 @@ func (self *StreamDecoder) More() bool {
|
||||||
return err == nil && c != ']' && c != '}'
|
return err == nil && c != ']' && c != '}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// More reports whether there is another element in the
|
||||||
|
// current array or object being parsed.
|
||||||
|
func (self *StreamDecoder) readMore() bool {
|
||||||
|
if self.err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var n int
|
||||||
|
for {
|
||||||
|
// Grow buffer if not large enough.
|
||||||
|
l := len(self.buf)
|
||||||
|
realloc(&self.buf)
|
||||||
|
|
||||||
|
n, err = self.r.Read(self.buf[l:cap(self.buf)])
|
||||||
|
self.buf = self.buf[: l+n]
|
||||||
|
|
||||||
|
self.scanp = l
|
||||||
|
_, empty := self.scan()
|
||||||
|
if !empty {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// buffer has been scanned, now report any error
|
||||||
|
if err != nil {
|
||||||
|
self.setErr(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *StreamDecoder) setErr(err error) {
|
||||||
|
self.err = err
|
||||||
|
mem := self.buf[:0]
|
||||||
|
self.buf = nil
|
||||||
|
bufPool.Put(mem)
|
||||||
|
}
|
||||||
|
|
||||||
func (self *StreamDecoder) peek() (byte, error) {
|
func (self *StreamDecoder) peek() (byte, error) {
|
||||||
var err error
|
var err error
|
||||||
for {
|
for {
|
||||||
for i := self.scanp; i < len(self.buf); i++ {
|
c, empty := self.scan()
|
||||||
c := self.buf[i]
|
if !empty {
|
||||||
if isSpace(c) {
|
return byte(c), nil
|
||||||
continue
|
|
||||||
}
|
|
||||||
self.scanp = i
|
|
||||||
return c, nil
|
|
||||||
}
|
}
|
||||||
// buffer has been scanned, now report any error
|
// buffer has been scanned, now report any error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
self.setErr(err)
|
||||||
self.err = err
|
|
||||||
}
|
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
err = self.refill()
|
err = self.refill()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *StreamDecoder) scan() (byte, bool) {
|
||||||
|
for i := self.scanp; i < len(self.buf); i++ {
|
||||||
|
c := self.buf[i]
|
||||||
|
if isSpace(c) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
self.scanp = i
|
||||||
|
return c, false
|
||||||
|
}
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
|
||||||
func isSpace(c byte) bool {
|
func isSpace(c byte) bool {
|
||||||
return types.SPACE_MASK & (1 << c) != 0
|
return types.SPACE_MASK & (1 << c) != 0
|
||||||
}
|
}
|
||||||
|
@ -212,17 +233,25 @@ func (self *StreamDecoder) refill() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func realloc(buf *[]byte) {
|
func realloc(buf *[]byte) bool {
|
||||||
l := uint(len(*buf))
|
l := uint(len(*buf))
|
||||||
c := uint(cap(*buf))
|
c := uint(cap(*buf))
|
||||||
|
if c == 0 {
|
||||||
|
// println("use pool!")
|
||||||
|
*buf = bufPool.Get().([]byte)
|
||||||
|
return true
|
||||||
|
}
|
||||||
if c - l <= c >> minLeftBufferShift {
|
if c - l <= c >> minLeftBufferShift {
|
||||||
|
// println("realloc!")
|
||||||
e := l+(l>>minLeftBufferShift)
|
e := l+(l>>minLeftBufferShift)
|
||||||
if e < option.DefaultDecoderBufferSize {
|
if e <= c {
|
||||||
e = option.DefaultDecoderBufferSize
|
e = c*2
|
||||||
}
|
}
|
||||||
tmp := make([]byte, l, e)
|
tmp := make([]byte, l, e)
|
||||||
copy(tmp, *buf)
|
copy(tmp, *buf)
|
||||||
*buf = tmp
|
*buf = tmp
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
vendor/github.com/bytedance/sonic/internal/encoder/asm_stubs_amd64_go121.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/encoder/asm_stubs_amd64_go121.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build go1.21,!go1.22
|
// +build go1.21,!go1.23
|
||||||
|
|
||||||
// Copyright 2023 CloudWeGo Authors
|
// Copyright 2023 CloudWeGo Authors
|
||||||
//
|
//
|
||||||
|
|
7
vendor/github.com/bytedance/sonic/internal/encoder/assembler_regabi_amd64.go
generated
vendored
7
vendor/github.com/bytedance/sonic/internal/encoder/assembler_regabi_amd64.go
generated
vendored
|
@ -1,5 +1,4 @@
|
||||||
//go:build go1.17 && !go1.22
|
// +build go1.17,!go1.23
|
||||||
// +build go1.17,!go1.22
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
@ -171,7 +170,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_REG_ffi = []obj.Addr{ _RP, _RL, _RC}
|
_REG_ffi = []obj.Addr{ _RP, _RL, _RC, _SP_q}
|
||||||
_REG_b64 = []obj.Addr{_SP_p, _SP_q}
|
_REG_b64 = []obj.Addr{_SP_p, _SP_q}
|
||||||
|
|
||||||
_REG_all = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _RP, _RL, _RC}
|
_REG_all = []obj.Addr{_ST, _SP_x, _SP_f, _SP_p, _SP_q, _RP, _RL, _RC}
|
||||||
|
@ -510,11 +509,9 @@ func (self *_Assembler) call_b64(pc obj.Addr) {
|
||||||
|
|
||||||
func (self *_Assembler) call_c(pc obj.Addr) {
|
func (self *_Assembler) call_c(pc obj.Addr) {
|
||||||
self.Emit("XCHGQ", _SP_p, _BX)
|
self.Emit("XCHGQ", _SP_p, _BX)
|
||||||
self.Emit("XCHGQ", _SP_q, _BP)
|
|
||||||
self.call(pc) // CALL $pc
|
self.call(pc) // CALL $pc
|
||||||
self.xload(_REG_ffi...) // LOAD $REG_ffi
|
self.xload(_REG_ffi...) // LOAD $REG_ffi
|
||||||
self.Emit("XCHGQ", _SP_p, _BX)
|
self.Emit("XCHGQ", _SP_p, _BX)
|
||||||
self.Emit("XCHGQ", _SP_q, _BP)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Assembler) call_go(pc obj.Addr) {
|
func (self *_Assembler) call_go(pc obj.Addr) {
|
||||||
|
|
2
vendor/github.com/bytedance/sonic/internal/encoder/compiler.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/encoder/compiler.go
generated
vendored
|
@ -831,7 +831,7 @@ func (self *_Compiler) compileStructFieldZero(p *_Program, vt reflect.Type) {
|
||||||
case reflect.Float32 : p.add(_OP_is_zero_4)
|
case reflect.Float32 : p.add(_OP_is_zero_4)
|
||||||
case reflect.Float64 : p.add(_OP_is_zero_8)
|
case reflect.Float64 : p.add(_OP_is_zero_8)
|
||||||
case reflect.String : p.add(_OP_is_nil_p1)
|
case reflect.String : p.add(_OP_is_nil_p1)
|
||||||
case reflect.Interface : p.add(_OP_is_nil_p1)
|
case reflect.Interface : p.add(_OP_is_nil)
|
||||||
case reflect.Map : p.add(_OP_is_zero_map)
|
case reflect.Map : p.add(_OP_is_zero_map)
|
||||||
case reflect.Ptr : p.add(_OP_is_nil)
|
case reflect.Ptr : p.add(_OP_is_nil)
|
||||||
case reflect.Slice : p.add(_OP_is_nil_p1)
|
case reflect.Slice : p.add(_OP_is_nil_p1)
|
||||||
|
|
2
vendor/github.com/bytedance/sonic/internal/encoder/debug_go117.go
generated
vendored
2
vendor/github.com/bytedance/sonic/internal/encoder/debug_go117.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build go1.17,!go1.22
|
// +build go1.17,!go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
14
vendor/github.com/bytedance/sonic/internal/encoder/encoder.go
generated
vendored
14
vendor/github.com/bytedance/sonic/internal/encoder/encoder.go
generated
vendored
|
@ -41,6 +41,7 @@ const (
|
||||||
bitNoNullSliceOrMap
|
bitNoNullSliceOrMap
|
||||||
bitValidateString
|
bitValidateString
|
||||||
bitNoValidateJSONMarshaler
|
bitNoValidateJSONMarshaler
|
||||||
|
bitNoEncoderNewline
|
||||||
|
|
||||||
// used for recursive compile
|
// used for recursive compile
|
||||||
bitPointerValue = 63
|
bitPointerValue = 63
|
||||||
|
@ -77,6 +78,9 @@ const (
|
||||||
// after encoding the JSONMarshaler to JSON.
|
// after encoding the JSONMarshaler to JSON.
|
||||||
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler
|
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler
|
||||||
|
|
||||||
|
// NoEncoderNewline indicates that the encoder should not add a newline after every message
|
||||||
|
NoEncoderNewline Options = 1 << bitNoEncoderNewline
|
||||||
|
|
||||||
// CompatibleWithStd is used to be compatible with std encoder.
|
// CompatibleWithStd is used to be compatible with std encoder.
|
||||||
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
|
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
|
||||||
)
|
)
|
||||||
|
@ -129,6 +133,16 @@ func (self *Encoder) SetNoValidateJSONMarshaler(f bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNoEncoderNewline specifies if option NoEncoderNewline opens
|
||||||
|
func (self *Encoder) SetNoEncoderNewline(f bool) {
|
||||||
|
if f {
|
||||||
|
self.Opts |= NoEncoderNewline
|
||||||
|
} else {
|
||||||
|
self.Opts &= ^NoEncoderNewline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// SetCompactMarshaler specifies if option CompactMarshaler opens
|
// SetCompactMarshaler specifies if option CompactMarshaler opens
|
||||||
func (self *Encoder) SetCompactMarshaler(f bool) {
|
func (self *Encoder) SetCompactMarshaler(f bool) {
|
||||||
if f {
|
if f {
|
||||||
|
|
6
vendor/github.com/bytedance/sonic/internal/encoder/primitives.go
generated
vendored
6
vendor/github.com/bytedance/sonic/internal/encoder/primitives.go
generated
vendored
|
@ -154,17 +154,17 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_F_assertI2I = jit.Func(assertI2I)
|
_F_assertI2I = jit.Func(rt.AssertI2I2)
|
||||||
)
|
)
|
||||||
|
|
||||||
func asText(v unsafe.Pointer) (string, error) {
|
func asText(v unsafe.Pointer) (string, error) {
|
||||||
text := assertI2I(_T_encoding_TextMarshaler, *(*rt.GoIface)(v))
|
text := rt.AssertI2I2(_T_encoding_TextMarshaler, *(*rt.GoIface)(v))
|
||||||
r, e := (*(*encoding.TextMarshaler)(unsafe.Pointer(&text))).MarshalText()
|
r, e := (*(*encoding.TextMarshaler)(unsafe.Pointer(&text))).MarshalText()
|
||||||
return rt.Mem2Str(r), e
|
return rt.Mem2Str(r), e
|
||||||
}
|
}
|
||||||
|
|
||||||
func asJson(v unsafe.Pointer) (string, error) {
|
func asJson(v unsafe.Pointer) (string, error) {
|
||||||
text := assertI2I(_T_json_Marshaler, *(*rt.GoIface)(v))
|
text := rt.AssertI2I2(_T_json_Marshaler, *(*rt.GoIface)(v))
|
||||||
r, e := (*(*json.Marshaler)(unsafe.Pointer(&text))).MarshalJSON()
|
r, e := (*(*json.Marshaler)(unsafe.Pointer(&text))).MarshalJSON()
|
||||||
return rt.Mem2Str(r), e
|
return rt.Mem2Str(r), e
|
||||||
}
|
}
|
||||||
|
|
13
vendor/github.com/bytedance/sonic/internal/encoder/stream.go
generated
vendored
13
vendor/github.com/bytedance/sonic/internal/encoder/stream.go
generated
vendored
|
@ -36,7 +36,8 @@ func NewStreamEncoder(w io.Writer) *StreamEncoder {
|
||||||
|
|
||||||
// Encode encodes interface{} as JSON to io.Writer
|
// Encode encodes interface{} as JSON to io.Writer
|
||||||
func (enc *StreamEncoder) Encode(val interface{}) (err error) {
|
func (enc *StreamEncoder) Encode(val interface{}) (err error) {
|
||||||
out := newBytes()
|
buf := newBytes()
|
||||||
|
out := buf
|
||||||
|
|
||||||
/* encode into the buffer */
|
/* encode into the buffer */
|
||||||
err = EncodeInto(&out, val, enc.Opts)
|
err = EncodeInto(&out, val, enc.Opts)
|
||||||
|
@ -54,7 +55,9 @@ func (enc *StreamEncoder) Encode(val interface{}) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// according to standard library, terminate each value with a newline...
|
// according to standard library, terminate each value with a newline...
|
||||||
buf.WriteByte('\n')
|
if enc.Opts & NoEncoderNewline == 0 {
|
||||||
|
buf.WriteByte('\n')
|
||||||
|
}
|
||||||
|
|
||||||
/* copy into io.Writer */
|
/* copy into io.Writer */
|
||||||
_, err = io.Copy(enc.w, buf)
|
_, err = io.Copy(enc.w, buf)
|
||||||
|
@ -75,10 +78,12 @@ func (enc *StreamEncoder) Encode(val interface{}) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// according to standard library, terminate each value with a newline...
|
// according to standard library, terminate each value with a newline...
|
||||||
enc.w.Write([]byte{'\n'})
|
if enc.Opts & NoEncoderNewline == 0 {
|
||||||
|
enc.w.Write([]byte{'\n'})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_bytes:
|
free_bytes:
|
||||||
freeBytes(out)
|
freeBytes(buf)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
4
vendor/github.com/bytedance/sonic/internal/encoder/stubs_go116.go
generated
vendored
4
vendor/github.com/bytedance/sonic/internal/encoder/stubs_go116.go
generated
vendored
|
@ -38,10 +38,6 @@ func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
|
||||||
//goland:noinspection GoUnusedParameter
|
//goland:noinspection GoUnusedParameter
|
||||||
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
||||||
|
|
||||||
//go:linkname assertI2I runtime.assertI2I
|
|
||||||
//goland:noinspection GoUnusedParameter
|
|
||||||
func assertI2I(inter *rt.GoType, i rt.GoIface) rt.GoIface
|
|
||||||
|
|
||||||
//go:linkname mapiternext runtime.mapiternext
|
//go:linkname mapiternext runtime.mapiternext
|
||||||
//goland:noinspection GoUnusedParameter
|
//goland:noinspection GoUnusedParameter
|
||||||
func mapiternext(it *rt.GoMapIterator)
|
func mapiternext(it *rt.GoMapIterator)
|
||||||
|
|
4
vendor/github.com/bytedance/sonic/internal/encoder/stubs_go117.go
generated
vendored
4
vendor/github.com/bytedance/sonic/internal/encoder/stubs_go117.go
generated
vendored
|
@ -38,10 +38,6 @@ func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
|
||||||
//goland:noinspection GoUnusedParameter
|
//goland:noinspection GoUnusedParameter
|
||||||
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
||||||
|
|
||||||
//go:linkname assertI2I runtime.assertI2I2
|
|
||||||
//goland:noinspection GoUnusedParameter
|
|
||||||
func assertI2I(inter *rt.GoType, i rt.GoIface) rt.GoIface
|
|
||||||
|
|
||||||
//go:linkname mapiternext runtime.mapiternext
|
//go:linkname mapiternext runtime.mapiternext
|
||||||
//goland:noinspection GoUnusedParameter
|
//goland:noinspection GoUnusedParameter
|
||||||
func mapiternext(it *rt.GoMapIterator)
|
func mapiternext(it *rt.GoMapIterator)
|
||||||
|
|
4
vendor/github.com/bytedance/sonic/internal/encoder/stubs_go120.go
generated
vendored
4
vendor/github.com/bytedance/sonic/internal/encoder/stubs_go120.go
generated
vendored
|
@ -38,10 +38,6 @@ func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
|
||||||
//goland:noinspection GoUnusedParameter
|
//goland:noinspection GoUnusedParameter
|
||||||
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
||||||
|
|
||||||
//go:linkname assertI2I runtime.assertI2I2
|
|
||||||
//goland:noinspection GoUnusedParameter
|
|
||||||
func assertI2I(inter *rt.GoType, i rt.GoIface) rt.GoIface
|
|
||||||
|
|
||||||
//go:linkname mapiternext runtime.mapiternext
|
//go:linkname mapiternext runtime.mapiternext
|
||||||
//goland:noinspection GoUnusedParameter
|
//goland:noinspection GoUnusedParameter
|
||||||
func mapiternext(it *rt.GoMapIterator)
|
func mapiternext(it *rt.GoMapIterator)
|
||||||
|
|
4
vendor/github.com/bytedance/sonic/internal/encoder/stubs_go121.go
generated
vendored
4
vendor/github.com/bytedance/sonic/internal/encoder/stubs_go121.go
generated
vendored
|
@ -38,10 +38,6 @@ func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
|
||||||
//goland:noinspection GoUnusedParameter
|
//goland:noinspection GoUnusedParameter
|
||||||
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
func growslice(et *rt.GoType, old rt.GoSlice, cap int) rt.GoSlice
|
||||||
|
|
||||||
//go:linkname assertI2I runtime.assertI2I2
|
|
||||||
//goland:noinspection GoUnusedParameter
|
|
||||||
func assertI2I(inter *rt.GoType, i rt.GoIface) rt.GoIface
|
|
||||||
|
|
||||||
//go:linkname mapiternext runtime.mapiternext
|
//go:linkname mapiternext runtime.mapiternext
|
||||||
//goland:noinspection GoUnusedParameter
|
//goland:noinspection GoUnusedParameter
|
||||||
func mapiternext(it *rt.GoMapIterator)
|
func mapiternext(it *rt.GoMapIterator)
|
||||||
|
|
12
vendor/github.com/bytedance/sonic/internal/jit/assembler_amd64.go
generated
vendored
12
vendor/github.com/bytedance/sonic/internal/jit/assembler_amd64.go
generated
vendored
|
@ -72,18 +72,6 @@ func (self *BaseAssembler) NOPn(n int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *BaseAssembler) StorePtr(ptr int64, to obj.Addr, tmp obj.Addr) {
|
|
||||||
if (to.Type != obj.TYPE_MEM) || (tmp.Type != obj.TYPE_REG) {
|
|
||||||
panic("must store imm to memory, tmp must be register")
|
|
||||||
}
|
|
||||||
if (ptr >> 32) != 0 {
|
|
||||||
self.Emit("MOVQ", Imm(ptr), tmp)
|
|
||||||
self.Emit("MOVQ", tmp, to)
|
|
||||||
} else {
|
|
||||||
self.Emit("MOVQ", Imm(ptr), to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *BaseAssembler) Byte(v ...byte) {
|
func (self *BaseAssembler) Byte(v ...byte) {
|
||||||
for ; len(v) >= 8; v = v[8:] { self.From("QUAD", Imm(rt.Get64(v))) }
|
for ; len(v) >= 8; v = v[8:] { self.From("QUAD", Imm(rt.Get64(v))) }
|
||||||
for ; len(v) >= 4; v = v[4:] { self.From("LONG", Imm(int64(rt.Get32(v)))) }
|
for ; len(v) >= 4; v = v[4:] { self.From("LONG", Imm(int64(rt.Get32(v)))) }
|
||||||
|
|
7
vendor/github.com/bytedance/sonic/internal/jit/runtime.go
generated
vendored
7
vendor/github.com/bytedance/sonic/internal/jit/runtime.go
generated
vendored
|
@ -24,11 +24,6 @@ import (
|
||||||
`github.com/twitchyliquid64/golang-asm/obj`
|
`github.com/twitchyliquid64/golang-asm/obj`
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
//go:linkname getitab runtime.getitab
|
|
||||||
//goland:noinspection ALL
|
|
||||||
func getitab(inter *rt.GoType, typ *rt.GoType, canfail bool) *rt.GoItab
|
|
||||||
|
|
||||||
func Func(f interface{}) obj.Addr {
|
func Func(f interface{}) obj.Addr {
|
||||||
if p := rt.UnpackEface(f); p.Type.Kind() != reflect.Func {
|
if p := rt.UnpackEface(f); p.Type.Kind() != reflect.Func {
|
||||||
panic("f is not a function")
|
panic("f is not a function")
|
||||||
|
@ -42,7 +37,7 @@ func Type(t reflect.Type) obj.Addr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Itab(i *rt.GoType, t reflect.Type) obj.Addr {
|
func Itab(i *rt.GoType, t reflect.Type) obj.Addr {
|
||||||
return Imm(int64(uintptr(unsafe.Pointer(getitab(i, rt.UnpackType(t), false)))))
|
return Imm(int64(uintptr(unsafe.Pointer(rt.Getitab(rt.IfaceType(i), rt.UnpackType(t), false)))))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Gitab(i *rt.GoItab) obj.Addr {
|
func Gitab(i *rt.GoItab) obj.Addr {
|
||||||
|
|
3
vendor/github.com/bytedance/sonic/internal/rt/asm_amd64.s
generated
vendored
3
vendor/github.com/bytedance/sonic/internal/rt/asm_amd64.s
generated
vendored
|
@ -1,5 +1,4 @@
|
||||||
// +build !noasm !appengine
|
// +build !noasm,amd64 !appengine,amd64
|
||||||
// Code generated by asm2asm, DO NOT EDIT·
|
|
||||||
|
|
||||||
#include "go_asm.h"
|
#include "go_asm.h"
|
||||||
#include "funcdata.h"
|
#include "funcdata.h"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// +build !noasm !appengine
|
// +build !noasm,!amd64 !appengine,!amd64
|
||||||
// Code generated by asm2asm, DO NOT EDIT.
|
|
||||||
|
|
||||||
#include "go_asm.h"
|
#include "go_asm.h"
|
||||||
#include "funcdata.h"
|
#include "funcdata.h"
|
3
vendor/github.com/bytedance/sonic/internal/rt/fastmem.go
generated
vendored
3
vendor/github.com/bytedance/sonic/internal/rt/fastmem.go
generated
vendored
|
@ -66,15 +66,16 @@ func FuncAddr(f interface{}) unsafe.Pointer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nocheckptr
|
||||||
func IndexChar(src string, index int) unsafe.Pointer {
|
func IndexChar(src string, index int) unsafe.Pointer {
|
||||||
return unsafe.Pointer(uintptr((*GoString)(unsafe.Pointer(&src)).Ptr) + uintptr(index))
|
return unsafe.Pointer(uintptr((*GoString)(unsafe.Pointer(&src)).Ptr) + uintptr(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nocheckptr
|
||||||
func IndexByte(ptr []byte, index int) unsafe.Pointer {
|
func IndexByte(ptr []byte, index int) unsafe.Pointer {
|
||||||
return unsafe.Pointer(uintptr((*GoSlice)(unsafe.Pointer(&ptr)).Ptr) + uintptr(index))
|
return unsafe.Pointer(uintptr((*GoSlice)(unsafe.Pointer(&ptr)).Ptr) + uintptr(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:nosplit
|
|
||||||
func GuardSlice(buf *[]byte, n int) {
|
func GuardSlice(buf *[]byte, n int) {
|
||||||
c := cap(*buf)
|
c := cap(*buf)
|
||||||
l := len(*buf)
|
l := len(*buf)
|
||||||
|
|
21
vendor/github.com/bytedance/sonic/internal/rt/fastvalue.go
generated
vendored
21
vendor/github.com/bytedance/sonic/internal/rt/fastvalue.go
generated
vendored
|
@ -211,3 +211,24 @@ func findReflectRtypeItab() *GoItab {
|
||||||
v := reflect.TypeOf(struct{}{})
|
v := reflect.TypeOf(struct{}{})
|
||||||
return (*GoIface)(unsafe.Pointer(&v)).Itab
|
return (*GoIface)(unsafe.Pointer(&v)).Itab
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AssertI2I2(t *GoType, i GoIface) (r GoIface) {
|
||||||
|
inter := IfaceType(t)
|
||||||
|
tab := i.Itab
|
||||||
|
if tab == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (*GoInterfaceType)(tab.it) != inter {
|
||||||
|
tab = Getitab(inter, tab.Vt, true)
|
||||||
|
if tab == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.Itab = tab
|
||||||
|
r.Value = i.Value
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
//go:linkname Getitab runtime.getitab
|
||||||
|
func Getitab(inter *GoInterfaceType, typ *GoType, canfail bool) *GoItab
|
||||||
|
|
6
vendor/github.com/bytedance/sonic/internal/rt/int48.go
generated
vendored
6
vendor/github.com/bytedance/sonic/internal/rt/int48.go
generated
vendored
|
@ -17,12 +17,12 @@
|
||||||
package rt
|
package rt
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MinInt48 = -(1 << 47)
|
MinInt48 int64 = -(1 << 47)
|
||||||
MaxInt48 = +(1 << 47) - 1
|
MaxInt48 int64 = +(1 << 47) - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func PackInt(v int) uint64 {
|
func PackInt(v int) uint64 {
|
||||||
if u := uint64(v); v < MinInt48 || v > MaxInt48 {
|
if u := uint64(v); int64(v) < MinInt48 || int64(v) > MaxInt48 {
|
||||||
panic("int48 out of range")
|
panic("int48 out of range")
|
||||||
} else {
|
} else {
|
||||||
return ((u >> 63) << 47) | (u & 0x00007fffffffffff)
|
return ((u >> 63) << 47) | (u & 0x00007fffffffffff)
|
||||||
|
|
4
vendor/github.com/bytedance/sonic/loader/funcdata_go121.go
generated
vendored
4
vendor/github.com/bytedance/sonic/loader/funcdata_go121.go
generated
vendored
|
@ -1,5 +1,5 @@
|
||||||
//go:build go1.21 && !go1.22
|
//go:build go1.21 && !go1.23
|
||||||
// +build go1.21,!go1.22
|
// +build go1.21,!go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
4
vendor/github.com/bytedance/sonic/loader/funcdata_latest.go
generated
vendored
4
vendor/github.com/bytedance/sonic/loader/funcdata_latest.go
generated
vendored
|
@ -1,5 +1,5 @@
|
||||||
// go:build go1.18 && !go1.22
|
// go:build go1.18 && !go1.23
|
||||||
// +build go1.18,!go1.22
|
// +build go1.18,!go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
3
vendor/github.com/bytedance/sonic/loader/loader_latest.go
generated
vendored
3
vendor/github.com/bytedance/sonic/loader/loader_latest.go
generated
vendored
|
@ -1,5 +1,4 @@
|
||||||
//go:build go1.16 && !go1.22
|
// +build go1.16,!go1.23
|
||||||
// +build go1.16,!go1.22
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
4
vendor/github.com/bytedance/sonic/loader/mmap_unix.go
generated
vendored
4
vendor/github.com/bytedance/sonic/loader/mmap_unix.go
generated
vendored
|
@ -1,5 +1,5 @@
|
||||||
//go:build darwin || linux
|
//go:build !windows
|
||||||
// +build darwin linux
|
// +build !windows
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright 2023 ByteDance Inc.
|
* Copyright 2023 ByteDance Inc.
|
||||||
|
|
34
vendor/github.com/bytedance/sonic/loader/stubs.go
generated
vendored
34
vendor/github.com/bytedance/sonic/loader/stubs.go
generated
vendored
|
@ -17,7 +17,8 @@
|
||||||
package loader
|
package loader
|
||||||
|
|
||||||
import (
|
import (
|
||||||
`sync`
|
"sync/atomic"
|
||||||
|
"unsafe"
|
||||||
_ `unsafe`
|
_ `unsafe`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,16 +26,35 @@ import (
|
||||||
//goland:noinspection GoUnusedGlobalVariable
|
//goland:noinspection GoUnusedGlobalVariable
|
||||||
var lastmoduledatap *moduledata
|
var lastmoduledatap *moduledata
|
||||||
|
|
||||||
var moduledataMux sync.Mutex
|
|
||||||
|
|
||||||
func registerModule(mod *moduledata) {
|
func registerModule(mod *moduledata) {
|
||||||
moduledataMux.Lock()
|
registerModuleLockFree(&lastmoduledatap, mod)
|
||||||
lastmoduledatap.next = mod
|
|
||||||
lastmoduledatap = mod
|
|
||||||
moduledataMux.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname moduledataverify1 runtime.moduledataverify1
|
//go:linkname moduledataverify1 runtime.moduledataverify1
|
||||||
func moduledataverify1(_ *moduledata)
|
func moduledataverify1(_ *moduledata)
|
||||||
|
|
||||||
|
func registerModuleLockFree(tail **moduledata, mod *moduledata) {
|
||||||
|
for {
|
||||||
|
oldTail := loadModule(tail)
|
||||||
|
if casModule(tail, oldTail, mod) {
|
||||||
|
storeModule(&oldTail.next, mod)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadModule(p **moduledata) *moduledata {
|
||||||
|
return (*moduledata)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeModule(p **moduledata, value *moduledata) {
|
||||||
|
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
func casModule(p **moduledata, oldValue *moduledata, newValue *moduledata) bool {
|
||||||
|
return atomic.CompareAndSwapPointer(
|
||||||
|
(*unsafe.Pointer)(unsafe.Pointer(p)),
|
||||||
|
unsafe.Pointer(oldValue),
|
||||||
|
unsafe.Pointer(newValue),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
5
vendor/github.com/bytedance/sonic/sonic.go
generated
vendored
5
vendor/github.com/bytedance/sonic/sonic.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64,go1.16,!go1.22
|
// +build amd64,go1.16,!go1.23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
@ -61,6 +61,9 @@ func (cfg Config) Froze() API {
|
||||||
if cfg.NoValidateJSONMarshaler {
|
if cfg.NoValidateJSONMarshaler {
|
||||||
api.encoderOpts |= encoder.NoValidateJSONMarshaler
|
api.encoderOpts |= encoder.NoValidateJSONMarshaler
|
||||||
}
|
}
|
||||||
|
if cfg.NoEncoderNewline {
|
||||||
|
api.encoderOpts |= encoder.NoEncoderNewline
|
||||||
|
}
|
||||||
|
|
||||||
// configure decoder options:
|
// configure decoder options:
|
||||||
if cfg.UseInt64 {
|
if cfg.UseInt64 {
|
||||||
|
|
729
vendor/github.com/chenzhuoyu/iasm/x86_64/operands.go
generated
vendored
729
vendor/github.com/chenzhuoyu/iasm/x86_64/operands.go
generated
vendored
|
@ -1,13 +1,13 @@
|
||||||
package x86_64
|
package x86_64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
`errors`
|
"errors"
|
||||||
`fmt`
|
"fmt"
|
||||||
`math`
|
"math"
|
||||||
`reflect`
|
"reflect"
|
||||||
`strconv`
|
"strconv"
|
||||||
`strings`
|
"strings"
|
||||||
`sync/atomic`
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RelativeOffset represents an RIP-relative offset.
|
// RelativeOffset represents an RIP-relative offset.
|
||||||
|
@ -15,496 +15,635 @@ type RelativeOffset int32
|
||||||
|
|
||||||
// String implements the fmt.Stringer interface.
|
// String implements the fmt.Stringer interface.
|
||||||
func (self RelativeOffset) String() string {
|
func (self RelativeOffset) String() string {
|
||||||
if self == 0 {
|
if self == 0 {
|
||||||
return "(%rip)"
|
return "(%rip)"
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("%d(%%rip)", self)
|
return fmt.Sprintf("%d(%%rip)", self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoundingControl represents a floating-point rounding option.
|
// RoundingControl represents a floating-point rounding option.
|
||||||
type RoundingControl uint8
|
type RoundingControl uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RN_SAE represents "Round Nearest", which is the default rounding option.
|
// RN_SAE represents "Round Nearest", which is the default rounding option.
|
||||||
RN_SAE RoundingControl = iota
|
RN_SAE RoundingControl = iota
|
||||||
|
|
||||||
// RD_SAE represents "Round Down".
|
// RD_SAE represents "Round Down".
|
||||||
RD_SAE
|
RD_SAE
|
||||||
|
|
||||||
// RU_SAE represents "Round Up".
|
// RU_SAE represents "Round Up".
|
||||||
RU_SAE
|
RU_SAE
|
||||||
|
|
||||||
// RZ_SAE represents "Round towards Zero".
|
// RZ_SAE represents "Round towards Zero".
|
||||||
RZ_SAE
|
RZ_SAE
|
||||||
)
|
)
|
||||||
|
|
||||||
var _RC_NAMES = map[RoundingControl]string {
|
var _RC_NAMES = map[RoundingControl]string{
|
||||||
RN_SAE: "rn-sae",
|
RN_SAE: "rn-sae",
|
||||||
RD_SAE: "rd-sae",
|
RD_SAE: "rd-sae",
|
||||||
RU_SAE: "ru-sae",
|
RU_SAE: "ru-sae",
|
||||||
RZ_SAE: "rz-sae",
|
RZ_SAE: "rz-sae",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self RoundingControl) String() string {
|
func (self RoundingControl) String() string {
|
||||||
if v, ok := _RC_NAMES[self]; ok {
|
if v, ok := _RC_NAMES[self]; ok {
|
||||||
return v
|
return v
|
||||||
} else {
|
} else {
|
||||||
panic("invalid RoundingControl value")
|
panic("invalid RoundingControl value")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExceptionControl represents the "Suppress All Exceptions" flag.
|
// ExceptionControl represents the "Suppress All Exceptions" flag.
|
||||||
type ExceptionControl uint8
|
type ExceptionControl uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// SAE represents the flag "Suppress All Exceptions" for floating point operations.
|
// SAE represents the flag "Suppress All Exceptions" for floating point operations.
|
||||||
SAE ExceptionControl = iota
|
SAE ExceptionControl = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ExceptionControl) String() string {
|
func (ExceptionControl) String() string {
|
||||||
return "sae"
|
return "sae"
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressType indicates which kind of value that an Addressable object contains.
|
// AddressType indicates which kind of value that an Addressable object contains.
|
||||||
type AddressType uint
|
type AddressType uint
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// None indicates the Addressable does not contain any addressable value.
|
// None indicates the Addressable does not contain any addressable value.
|
||||||
None AddressType = iota
|
None AddressType = iota
|
||||||
|
|
||||||
// Memory indicates the Addressable contains a memory address.
|
// Memory indicates the Addressable contains a memory address.
|
||||||
Memory
|
Memory
|
||||||
|
|
||||||
// Offset indicates the Addressable contains an RIP-relative offset.
|
// Offset indicates the Addressable contains an RIP-relative offset.
|
||||||
Offset
|
Offset
|
||||||
|
|
||||||
// Reference indicates the Addressable contains a label reference.
|
// Reference indicates the Addressable contains a label reference.
|
||||||
Reference
|
Reference
|
||||||
)
|
)
|
||||||
|
|
||||||
// Disposable is a type of object that can be Free'd manually.
|
// Disposable is a type of object that can be Free'd manually.
|
||||||
type Disposable interface {
|
type Disposable interface {
|
||||||
Free()
|
Free()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Label represents a location within the program.
|
// Label represents a location within the program.
|
||||||
type Label struct {
|
type Label struct {
|
||||||
refs int64
|
refs int64
|
||||||
Name string
|
Name string
|
||||||
Dest *Instruction
|
Dest *Instruction
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Label) offset(p uintptr, n int) RelativeOffset {
|
func (self *Label) offset(p uintptr, n int) RelativeOffset {
|
||||||
if self.Dest == nil {
|
if self.Dest == nil {
|
||||||
panic("unresolved label: " + self.Name)
|
panic("unresolved label: " + self.Name)
|
||||||
} else {
|
} else {
|
||||||
return RelativeOffset(self.Dest.pc - p - uintptr(n))
|
return RelativeOffset(self.Dest.pc - p - uintptr(n))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free decreases the reference count of a Label, if the
|
// Free decreases the reference count of a Label, if the
|
||||||
// refcount drops to 0, the Label will be recycled.
|
// refcount drops to 0, the Label will be recycled.
|
||||||
func (self *Label) Free() {
|
func (self *Label) Free() {
|
||||||
if atomic.AddInt64(&self.refs, -1) == 0 {
|
if atomic.AddInt64(&self.refs, -1) == 0 {
|
||||||
freeLabel(self)
|
//freeLabel(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the fmt.Stringer interface.
|
// String implements the fmt.Stringer interface.
|
||||||
func (self *Label) String() string {
|
func (self *Label) String() string {
|
||||||
if self.Dest == nil {
|
if self.Dest == nil {
|
||||||
return fmt.Sprintf("%s(%%rip)", self.Name)
|
return fmt.Sprintf("%s(%%rip)", self.Name)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("%s(%%rip)@%#x", self.Name, self.Dest.pc)
|
return fmt.Sprintf("%s(%%rip)@%#x", self.Name, self.Dest.pc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retain increases the reference count of a Label.
|
// Retain increases the reference count of a Label.
|
||||||
func (self *Label) Retain() *Label {
|
func (self *Label) Retain() *Label {
|
||||||
atomic.AddInt64(&self.refs, 1)
|
atomic.AddInt64(&self.refs, 1)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate implements the interface expr.Term.
|
// Evaluate implements the interface expr.Term.
|
||||||
func (self *Label) Evaluate() (int64, error) {
|
func (self *Label) Evaluate() (int64, error) {
|
||||||
if self.Dest != nil {
|
if self.Dest != nil {
|
||||||
return int64(self.Dest.pc), nil
|
return int64(self.Dest.pc), nil
|
||||||
} else {
|
} else {
|
||||||
return 0, errors.New("unresolved label: " + self.Name)
|
return 0, errors.New("unresolved label: " + self.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addressable is a union to represent an addressable operand.
|
// Addressable is a union to represent an addressable operand.
|
||||||
type Addressable struct {
|
type Addressable struct {
|
||||||
Type AddressType
|
Type AddressType
|
||||||
Memory MemoryAddress
|
Memory MemoryAddress
|
||||||
Offset RelativeOffset
|
Offset RelativeOffset
|
||||||
Reference *Label
|
Reference *Label
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the fmt.Stringer interface.
|
// String implements the fmt.Stringer interface.
|
||||||
func (self *Addressable) String() string {
|
func (self *Addressable) String() string {
|
||||||
switch self.Type {
|
switch self.Type {
|
||||||
case None : return "(not addressable)"
|
case None:
|
||||||
case Memory : return self.Memory.String()
|
return "(not addressable)"
|
||||||
case Offset : return self.Offset.String()
|
case Memory:
|
||||||
case Reference : return self.Reference.String()
|
return self.Memory.String()
|
||||||
default : return "(invalid addressable)"
|
case Offset:
|
||||||
}
|
return self.Offset.String()
|
||||||
|
case Reference:
|
||||||
|
return self.Reference.String()
|
||||||
|
default:
|
||||||
|
return "(invalid addressable)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemoryOperand represents a memory operand for an instruction.
|
// MemoryOperand represents a memory operand for an instruction.
|
||||||
type MemoryOperand struct {
|
type MemoryOperand struct {
|
||||||
refs int64
|
refs int64
|
||||||
Size int
|
Size int
|
||||||
Addr Addressable
|
Addr Addressable
|
||||||
Mask RegisterMask
|
Mask RegisterMask
|
||||||
Masked bool
|
Masked bool
|
||||||
Broadcast uint8
|
Broadcast uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_Sizes = 0b10000000100010111 // bit-mask for valid sizes (0, 1, 2, 4, 8, 16)
|
_Sizes = 0b10000000100010111 // bit-mask for valid sizes (0, 1, 2, 4, 8, 16)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (self *MemoryOperand) isVMX(evex bool) bool {
|
func (self *MemoryOperand) isVMX(evex bool) bool {
|
||||||
return self.Addr.Type == Memory && self.Addr.Memory.isVMX(evex)
|
return self.Addr.Type == Memory && self.Addr.Memory.isVMX(evex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) isVMY(evex bool) bool {
|
func (self *MemoryOperand) isVMY(evex bool) bool {
|
||||||
return self.Addr.Type == Memory && self.Addr.Memory.isVMY(evex)
|
return self.Addr.Type == Memory && self.Addr.Memory.isVMY(evex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) isVMZ() bool {
|
func (self *MemoryOperand) isVMZ() bool {
|
||||||
return self.Addr.Type == Memory && self.Addr.Memory.isVMZ()
|
return self.Addr.Type == Memory && self.Addr.Memory.isVMZ()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) isMem() bool {
|
func (self *MemoryOperand) isMem() bool {
|
||||||
if (_Sizes & (1 << self.Broadcast)) == 0 {
|
if (_Sizes & (1 << self.Broadcast)) == 0 {
|
||||||
return false
|
return false
|
||||||
} else if self.Addr.Type == Memory {
|
} else if self.Addr.Type == Memory {
|
||||||
return self.Addr.Memory.isMem()
|
return self.Addr.Memory.isMem()
|
||||||
} else if self.Addr.Type == Offset {
|
} else if self.Addr.Type == Offset {
|
||||||
return true
|
return true
|
||||||
} else if self.Addr.Type == Reference {
|
} else if self.Addr.Type == Reference {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) isSize(n int) bool {
|
func (self *MemoryOperand) isSize(n int) bool {
|
||||||
return self.Size == 0 || self.Size == n
|
return self.Size == 0 || self.Size == n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) isBroadcast(n int, b uint8) bool {
|
func (self *MemoryOperand) isBroadcast(n int, b uint8) bool {
|
||||||
return self.Size == n && self.Broadcast == b
|
return self.Size == n && self.Broadcast == b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) formatMask() string {
|
func (self *MemoryOperand) formatMask() string {
|
||||||
if !self.Masked {
|
if !self.Masked {
|
||||||
return ""
|
return ""
|
||||||
} else {
|
} else {
|
||||||
return self.Mask.String()
|
return self.Mask.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) formatBroadcast() string {
|
func (self *MemoryOperand) formatBroadcast() string {
|
||||||
if self.Broadcast == 0 {
|
if self.Broadcast == 0 {
|
||||||
return ""
|
return ""
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("{1to%d}", self.Broadcast)
|
return fmt.Sprintf("{1to%d}", self.Broadcast)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) ensureAddrValid() {
|
func (self *MemoryOperand) ensureAddrValid() {
|
||||||
switch self.Addr.Type {
|
switch self.Addr.Type {
|
||||||
case None : break
|
case None:
|
||||||
case Memory : self.Addr.Memory.EnsureValid()
|
break
|
||||||
case Offset : break
|
case Memory:
|
||||||
case Reference : break
|
self.Addr.Memory.EnsureValid()
|
||||||
default : panic("invalid address type")
|
case Offset:
|
||||||
}
|
break
|
||||||
|
case Reference:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
panic("invalid address type")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) ensureSizeValid() {
|
func (self *MemoryOperand) ensureSizeValid() {
|
||||||
if (_Sizes & (1 << self.Size)) == 0 {
|
if (_Sizes & (1 << self.Size)) == 0 {
|
||||||
panic("invalid memory operand size")
|
panic("invalid memory operand size")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryOperand) ensureBroadcastValid() {
|
func (self *MemoryOperand) ensureBroadcastValid() {
|
||||||
if (_Sizes & (1 << self.Broadcast)) == 0 {
|
if (_Sizes & (1 << self.Broadcast)) == 0 {
|
||||||
panic("invalid memory operand broadcast")
|
panic("invalid memory operand broadcast")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free decreases the reference count of a MemoryOperand, if the
|
// Free decreases the reference count of a MemoryOperand, if the
|
||||||
// refcount drops to 0, the Label will be recycled.
|
// refcount drops to 0, the Label will be recycled.
|
||||||
func (self *MemoryOperand) Free() {
|
func (self *MemoryOperand) Free() {
|
||||||
if atomic.AddInt64(&self.refs, -1) == 0 {
|
if atomic.AddInt64(&self.refs, -1) == 0 {
|
||||||
freeMemoryOperand(self)
|
//freeMemoryOperand(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the fmt.Stringer interface.
|
// String implements the fmt.Stringer interface.
|
||||||
func (self *MemoryOperand) String() string {
|
func (self *MemoryOperand) String() string {
|
||||||
return self.Addr.String() + self.formatMask() + self.formatBroadcast()
|
return self.Addr.String() + self.formatMask() + self.formatBroadcast()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retain increases the reference count of a MemoryOperand.
|
// Retain increases the reference count of a MemoryOperand.
|
||||||
func (self *MemoryOperand) Retain() *MemoryOperand {
|
func (self *MemoryOperand) Retain() *MemoryOperand {
|
||||||
atomic.AddInt64(&self.refs, 1)
|
atomic.AddInt64(&self.refs, 1)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureValid checks if the memory operand is valid, if not, it panics.
|
// EnsureValid checks if the memory operand is valid, if not, it panics.
|
||||||
func (self *MemoryOperand) EnsureValid() {
|
func (self *MemoryOperand) EnsureValid() {
|
||||||
self.ensureAddrValid()
|
self.ensureAddrValid()
|
||||||
self.ensureSizeValid()
|
self.ensureSizeValid()
|
||||||
self.ensureBroadcastValid()
|
self.ensureBroadcastValid()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemoryAddress represents a memory address.
|
// MemoryAddress represents a memory address.
|
||||||
type MemoryAddress struct {
|
type MemoryAddress struct {
|
||||||
Base Register
|
Base Register
|
||||||
Index Register
|
Index Register
|
||||||
Scale uint8
|
Scale uint8
|
||||||
Displacement int32
|
Displacement int32
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_Scales = 0b100010111 // bit-mask for valid scales (0, 1, 2, 4, 8)
|
_Scales = 0b100010111 // bit-mask for valid scales (0, 1, 2, 4, 8)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (self *MemoryAddress) isVMX(evex bool) bool {
|
func (self *MemoryAddress) isVMX(evex bool) bool {
|
||||||
return self.isMemBase() && (self.Index == nil || isXMM(self.Index) || (evex && isEVEXXMM(self.Index)))
|
return self.isMemBase() && (self.Index == nil || isXMM(self.Index) || (evex && isEVEXXMM(self.Index)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryAddress) isVMY(evex bool) bool {
|
func (self *MemoryAddress) isVMY(evex bool) bool {
|
||||||
return self.isMemBase() && (self.Index == nil || isYMM(self.Index) || (evex && isEVEXYMM(self.Index)))
|
return self.isMemBase() && (self.Index == nil || isYMM(self.Index) || (evex && isEVEXYMM(self.Index)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryAddress) isVMZ() bool {
|
func (self *MemoryAddress) isVMZ() bool {
|
||||||
return self.isMemBase() && (self.Index == nil || isZMM(self.Index))
|
return self.isMemBase() && (self.Index == nil || isZMM(self.Index))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryAddress) isMem() bool {
|
func (self *MemoryAddress) isMem() bool {
|
||||||
return self.isMemBase() && (self.Index == nil || isReg64(self.Index))
|
return self.isMemBase() && (self.Index == nil || isReg64(self.Index))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MemoryAddress) isMemBase() bool {
|
func (self *MemoryAddress) isMemBase() bool {
|
||||||
return (self.Base == nil || isReg64(self.Base)) && // `Base` must be 64-bit if present
|
return (self.Base == nil || isReg64(self.Base)) && // `Base` must be 64-bit if present
|
||||||
(self.Scale == 0) == (self.Index == nil) && // `Scale` and `Index` depends on each other
|
(self.Scale == 0) == (self.Index == nil) && // `Scale` and `Index` depends on each other
|
||||||
(_Scales & (1 << self.Scale)) != 0 // `Scale` can only be 0, 1, 2, 4 or 8
|
(_Scales&(1<<self.Scale)) != 0 // `Scale` can only be 0, 1, 2, 4 or 8
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the fmt.Stringer interface.
|
// String implements the fmt.Stringer interface.
|
||||||
func (self *MemoryAddress) String() string {
|
func (self *MemoryAddress) String() string {
|
||||||
var dp int
|
var dp int
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
|
|
||||||
/* the displacement part */
|
/* the displacement part */
|
||||||
if dp = int(self.Displacement); dp != 0 {
|
if dp = int(self.Displacement); dp != 0 {
|
||||||
sb.WriteString(strconv.Itoa(dp))
|
sb.WriteString(strconv.Itoa(dp))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the base register */
|
/* the base register */
|
||||||
if sb.WriteByte('('); self.Base != nil {
|
if sb.WriteByte('('); self.Base != nil {
|
||||||
sb.WriteByte('%')
|
sb.WriteByte('%')
|
||||||
sb.WriteString(self.Base.String())
|
sb.WriteString(self.Base.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
/* index is optional */
|
/* index is optional */
|
||||||
if self.Index != nil {
|
if self.Index != nil {
|
||||||
sb.WriteString(",%")
|
sb.WriteString(",%")
|
||||||
sb.WriteString(self.Index.String())
|
sb.WriteString(self.Index.String())
|
||||||
|
|
||||||
/* scale is also optional */
|
/* scale is also optional */
|
||||||
if self.Scale >= 2 {
|
if self.Scale >= 2 {
|
||||||
sb.WriteByte(',')
|
sb.WriteByte(',')
|
||||||
sb.WriteString(strconv.Itoa(int(self.Scale)))
|
sb.WriteString(strconv.Itoa(int(self.Scale)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close the bracket */
|
/* close the bracket */
|
||||||
sb.WriteByte(')')
|
sb.WriteByte(')')
|
||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureValid checks if the memory address is valid, if not, it panics.
|
// EnsureValid checks if the memory address is valid, if not, it panics.
|
||||||
func (self *MemoryAddress) EnsureValid() {
|
func (self *MemoryAddress) EnsureValid() {
|
||||||
if !self.isMemBase() || (self.Index != nil && !isIndexable(self.Index)) {
|
if !self.isMemBase() || (self.Index != nil && !isIndexable(self.Index)) {
|
||||||
panic("not a valid memory address")
|
panic("not a valid memory address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref constructs a memory reference to a label.
|
// Ref constructs a memory reference to a label.
|
||||||
func Ref(ref *Label) (v *MemoryOperand) {
|
func Ref(ref *Label) (v *MemoryOperand) {
|
||||||
v = CreateMemoryOperand()
|
v = CreateMemoryOperand()
|
||||||
v.Addr.Type = Reference
|
v.Addr.Type = Reference
|
||||||
v.Addr.Reference = ref
|
v.Addr.Reference = ref
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abs construct a simple memory address that represents absolute addressing.
|
// Abs construct a simple memory address that represents absolute addressing.
|
||||||
func Abs(disp int32) *MemoryOperand {
|
func Abs(disp int32) *MemoryOperand {
|
||||||
return Sib(nil, nil, 0, disp)
|
return Sib(nil, nil, 0, disp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ptr constructs a simple memory operand with base and displacement.
|
// Ptr constructs a simple memory operand with base and displacement.
|
||||||
func Ptr(base Register, disp int32) *MemoryOperand {
|
func Ptr(base Register, disp int32) *MemoryOperand {
|
||||||
return Sib(base, nil, 0, disp)
|
return Sib(base, nil, 0, disp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sib constructs a simple memory operand that represents a complete memory address.
|
// Sib constructs a simple memory operand that represents a complete memory address.
|
||||||
func Sib(base Register, index Register, scale uint8, disp int32) (v *MemoryOperand) {
|
func Sib(base Register, index Register, scale uint8, disp int32) (v *MemoryOperand) {
|
||||||
v = CreateMemoryOperand()
|
v = CreateMemoryOperand()
|
||||||
v.Addr.Type = Memory
|
v.Addr.Type = Memory
|
||||||
v.Addr.Memory.Base = base
|
v.Addr.Memory.Base = base
|
||||||
v.Addr.Memory.Index = index
|
v.Addr.Memory.Index = index
|
||||||
v.Addr.Memory.Scale = scale
|
v.Addr.Memory.Scale = scale
|
||||||
v.Addr.Memory.Displacement = disp
|
v.Addr.Memory.Displacement = disp
|
||||||
v.EnsureValid()
|
v.EnsureValid()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Operand Matching Helpers **/
|
/** Operand Matching Helpers **/
|
||||||
|
|
||||||
const _IntMask =
|
const _IntMask = (1 << reflect.Int) |
|
||||||
(1 << reflect.Int ) |
|
(1 << reflect.Int8) |
|
||||||
(1 << reflect.Int8 ) |
|
(1 << reflect.Int16) |
|
||||||
(1 << reflect.Int16 ) |
|
(1 << reflect.Int32) |
|
||||||
(1 << reflect.Int32 ) |
|
(1 << reflect.Int64) |
|
||||||
(1 << reflect.Int64 ) |
|
(1 << reflect.Uint) |
|
||||||
(1 << reflect.Uint ) |
|
(1 << reflect.Uint8) |
|
||||||
(1 << reflect.Uint8 ) |
|
(1 << reflect.Uint16) |
|
||||||
(1 << reflect.Uint16 ) |
|
(1 << reflect.Uint32) |
|
||||||
(1 << reflect.Uint32 ) |
|
(1 << reflect.Uint64) |
|
||||||
(1 << reflect.Uint64 ) |
|
(1 << reflect.Uintptr)
|
||||||
(1 << reflect.Uintptr)
|
|
||||||
|
|
||||||
func isInt(k reflect.Kind) bool {
|
func isInt(k reflect.Kind) bool {
|
||||||
return (_IntMask & (1 << k)) != 0
|
return (_IntMask & (1 << k)) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func asInt64(v interface{}) (int64, bool) {
|
func asInt64(v interface{}) (int64, bool) {
|
||||||
if isSpecial(v) {
|
if isSpecial(v) {
|
||||||
return 0, false
|
return 0, false
|
||||||
} else if x := efaceOf(v); isInt(x.kind()) {
|
} else if x := efaceOf(v); isInt(x.kind()) {
|
||||||
return x.toInt64(), true
|
return x.toInt64(), true
|
||||||
} else {
|
} else {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func inRange(v interface{}, low int64, high int64) bool {
|
func inRange(v interface{}, low int64, high int64) bool {
|
||||||
x, ok := asInt64(v)
|
x, ok := asInt64(v)
|
||||||
return ok && x >= low && x <= high
|
return ok && x >= low && x <= high
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSpecial(v interface{}) bool {
|
func isSpecial(v interface{}) bool {
|
||||||
switch v.(type) {
|
switch v.(type) {
|
||||||
case Register8 : return true
|
case Register8:
|
||||||
case Register16 : return true
|
return true
|
||||||
case Register32 : return true
|
case Register16:
|
||||||
case Register64 : return true
|
return true
|
||||||
case KRegister : return true
|
case Register32:
|
||||||
case MMRegister : return true
|
return true
|
||||||
case XMMRegister : return true
|
case Register64:
|
||||||
case YMMRegister : return true
|
return true
|
||||||
case ZMMRegister : return true
|
case KRegister:
|
||||||
case RelativeOffset : return true
|
return true
|
||||||
case RoundingControl : return true
|
case MMRegister:
|
||||||
case ExceptionControl : return true
|
return true
|
||||||
default : return false
|
case XMMRegister:
|
||||||
}
|
return true
|
||||||
|
case YMMRegister:
|
||||||
|
return true
|
||||||
|
case ZMMRegister:
|
||||||
|
return true
|
||||||
|
case RelativeOffset:
|
||||||
|
return true
|
||||||
|
case RoundingControl:
|
||||||
|
return true
|
||||||
|
case ExceptionControl:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isIndexable(v interface{}) bool {
|
func isIndexable(v interface{}) bool {
|
||||||
return isZMM(v) || isReg64(v) || isEVEXXMM(v) || isEVEXYMM(v)
|
return isZMM(v) || isReg64(v) || isEVEXXMM(v) || isEVEXYMM(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isImm4 (v interface{}) bool { return inRange(v, 0, 15) }
|
func isImm4(v interface{}) bool { return inRange(v, 0, 15) }
|
||||||
func isImm8 (v interface{}) bool { return inRange(v, math.MinInt8, math.MaxUint8) }
|
func isImm8(v interface{}) bool { return inRange(v, math.MinInt8, math.MaxUint8) }
|
||||||
func isImm16 (v interface{}) bool { return inRange(v, math.MinInt16, math.MaxUint16) }
|
func isImm16(v interface{}) bool { return inRange(v, math.MinInt16, math.MaxUint16) }
|
||||||
func isImm32 (v interface{}) bool { return inRange(v, math.MinInt32, math.MaxUint32) }
|
func isImm32(v interface{}) bool { return inRange(v, math.MinInt32, math.MaxUint32) }
|
||||||
func isImm64 (v interface{}) bool { _, r := asInt64(v) ; return r }
|
func isImm64(v interface{}) bool { _, r := asInt64(v); return r }
|
||||||
func isConst1 (v interface{}) bool { x, r := asInt64(v) ; return r && x == 1 }
|
func isConst1(v interface{}) bool { x, r := asInt64(v); return r && x == 1 }
|
||||||
func isConst3 (v interface{}) bool { x, r := asInt64(v) ; return r && x == 3 }
|
func isConst3(v interface{}) bool { x, r := asInt64(v); return r && x == 3 }
|
||||||
func isRel8 (v interface{}) bool { x, r := v.(RelativeOffset) ; return r && x >= math.MinInt8 && x <= math.MaxInt8 }
|
func isRel8(v interface{}) bool {
|
||||||
func isRel32 (v interface{}) bool { _, r := v.(RelativeOffset) ; return r }
|
x, r := v.(RelativeOffset)
|
||||||
func isLabel (v interface{}) bool { _, r := v.(*Label) ; return r }
|
return r && x >= math.MinInt8 && x <= math.MaxInt8
|
||||||
func isReg8 (v interface{}) bool { _, r := v.(Register8) ; return r }
|
}
|
||||||
func isReg8REX (v interface{}) bool { x, r := v.(Register8) ; return r && (x & 0x80) == 0 && x >= SPL }
|
func isRel32(v interface{}) bool { _, r := v.(RelativeOffset); return r }
|
||||||
func isReg16 (v interface{}) bool { _, r := v.(Register16) ; return r }
|
func isLabel(v interface{}) bool { _, r := v.(*Label); return r }
|
||||||
func isReg32 (v interface{}) bool { _, r := v.(Register32) ; return r }
|
func isReg8(v interface{}) bool { _, r := v.(Register8); return r }
|
||||||
func isReg64 (v interface{}) bool { _, r := v.(Register64) ; return r }
|
func isReg8REX(v interface{}) bool {
|
||||||
func isMM (v interface{}) bool { _, r := v.(MMRegister) ; return r }
|
x, r := v.(Register8)
|
||||||
func isXMM (v interface{}) bool { x, r := v.(XMMRegister) ; return r && x <= XMM15 }
|
return r && (x&0x80) == 0 && x >= SPL
|
||||||
func isEVEXXMM (v interface{}) bool { _, r := v.(XMMRegister) ; return r }
|
}
|
||||||
func isXMMk (v interface{}) bool { x, r := v.(MaskedRegister) ; return isXMM(v) || (r && isXMM(x.Reg) && !x.Mask.Z) }
|
func isReg16(v interface{}) bool { _, r := v.(Register16); return r }
|
||||||
func isXMMkz (v interface{}) bool { x, r := v.(MaskedRegister) ; return isXMM(v) || (r && isXMM(x.Reg)) }
|
func isReg32(v interface{}) bool { _, r := v.(Register32); return r }
|
||||||
func isYMM (v interface{}) bool { x, r := v.(YMMRegister) ; return r && x <= YMM15 }
|
func isReg64(v interface{}) bool { _, r := v.(Register64); return r }
|
||||||
func isEVEXYMM (v interface{}) bool { _, r := v.(YMMRegister) ; return r }
|
func isMM(v interface{}) bool { _, r := v.(MMRegister); return r }
|
||||||
func isYMMk (v interface{}) bool { x, r := v.(MaskedRegister) ; return isYMM(v) || (r && isYMM(x.Reg) && !x.Mask.Z) }
|
func isXMM(v interface{}) bool { x, r := v.(XMMRegister); return r && x <= XMM15 }
|
||||||
func isYMMkz (v interface{}) bool { x, r := v.(MaskedRegister) ; return isYMM(v) || (r && isYMM(x.Reg)) }
|
func isEVEXXMM(v interface{}) bool { _, r := v.(XMMRegister); return r }
|
||||||
func isZMM (v interface{}) bool { _, r := v.(ZMMRegister) ; return r }
|
func isXMMk(v interface{}) bool {
|
||||||
func isZMMk (v interface{}) bool { x, r := v.(MaskedRegister) ; return isZMM(v) || (r && isZMM(x.Reg) && !x.Mask.Z) }
|
x, r := v.(MaskedRegister)
|
||||||
func isZMMkz (v interface{}) bool { x, r := v.(MaskedRegister) ; return isZMM(v) || (r && isZMM(x.Reg)) }
|
return isXMM(v) || (r && isXMM(x.Reg) && !x.Mask.Z)
|
||||||
func isK (v interface{}) bool { _, r := v.(KRegister) ; return r }
|
}
|
||||||
func isKk (v interface{}) bool { x, r := v.(MaskedRegister) ; return isK(v) || (r && isK(x.Reg) && !x.Mask.Z) }
|
func isXMMkz(v interface{}) bool {
|
||||||
func isM (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isMem() && x.Broadcast == 0 && !x.Masked }
|
x, r := v.(MaskedRegister)
|
||||||
func isMk (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isMem() && x.Broadcast == 0 && !(x.Masked && x.Mask.Z) }
|
return isXMM(v) || (r && isXMM(x.Reg))
|
||||||
func isMkz (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isMem() && x.Broadcast == 0 }
|
}
|
||||||
func isM8 (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isM(v) && x.isSize(1) }
|
func isYMM(v interface{}) bool { x, r := v.(YMMRegister); return r && x <= YMM15 }
|
||||||
func isM16 (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isM(v) && x.isSize(2) }
|
func isEVEXYMM(v interface{}) bool { _, r := v.(YMMRegister); return r }
|
||||||
func isM16kz (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isMkz(v) && x.isSize(2) }
|
func isYMMk(v interface{}) bool {
|
||||||
func isM32 (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isM(v) && x.isSize(4) }
|
x, r := v.(MaskedRegister)
|
||||||
func isM32k (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isMk(v) && x.isSize(4) }
|
return isYMM(v) || (r && isYMM(x.Reg) && !x.Mask.Z)
|
||||||
func isM32kz (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isMkz(v) && x.isSize(4) }
|
}
|
||||||
func isM64 (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isM(v) && x.isSize(8) }
|
func isYMMkz(v interface{}) bool {
|
||||||
func isM64k (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isMk(v) && x.isSize(8) }
|
x, r := v.(MaskedRegister)
|
||||||
func isM64kz (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isMkz(v) && x.isSize(8) }
|
return isYMM(v) || (r && isYMM(x.Reg))
|
||||||
func isM128 (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isM(v) && x.isSize(16) }
|
}
|
||||||
func isM128kz (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isMkz(v) && x.isSize(16) }
|
func isZMM(v interface{}) bool { _, r := v.(ZMMRegister); return r }
|
||||||
func isM256 (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isM(v) && x.isSize(32) }
|
func isZMMk(v interface{}) bool {
|
||||||
func isM256kz (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isMkz(v) && x.isSize(32) }
|
x, r := v.(MaskedRegister)
|
||||||
func isM512 (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isM(v) && x.isSize(64) }
|
return isZMM(v) || (r && isZMM(x.Reg) && !x.Mask.Z)
|
||||||
func isM512kz (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && isMkz(v) && x.isSize(64) }
|
}
|
||||||
func isM64M32bcst (v interface{}) bool { x, r := v.(*MemoryOperand) ; return isM64(v) || (r && x.isBroadcast(4, 2)) }
|
func isZMMkz(v interface{}) bool {
|
||||||
func isM128M32bcst (v interface{}) bool { x, r := v.(*MemoryOperand) ; return isM128(v) || (r && x.isBroadcast(4, 4)) }
|
x, r := v.(MaskedRegister)
|
||||||
func isM256M32bcst (v interface{}) bool { x, r := v.(*MemoryOperand) ; return isM256(v) || (r && x.isBroadcast(4, 8)) }
|
return isZMM(v) || (r && isZMM(x.Reg))
|
||||||
func isM512M32bcst (v interface{}) bool { x, r := v.(*MemoryOperand) ; return isM512(v) || (r && x.isBroadcast(4, 16)) }
|
}
|
||||||
func isM128M64bcst (v interface{}) bool { x, r := v.(*MemoryOperand) ; return isM128(v) || (r && x.isBroadcast(8, 2)) }
|
func isK(v interface{}) bool { _, r := v.(KRegister); return r }
|
||||||
func isM256M64bcst (v interface{}) bool { x, r := v.(*MemoryOperand) ; return isM256(v) || (r && x.isBroadcast(8, 4)) }
|
func isKk(v interface{}) bool {
|
||||||
func isM512M64bcst (v interface{}) bool { x, r := v.(*MemoryOperand) ; return isM512(v) || (r && x.isBroadcast(8, 8)) }
|
x, r := v.(MaskedRegister)
|
||||||
func isVMX (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isVMX(false) && !x.Masked }
|
return isK(v) || (r && isK(x.Reg) && !x.Mask.Z)
|
||||||
func isEVEXVMX (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isVMX(true) && !x.Masked }
|
}
|
||||||
func isVMXk (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isVMX(true) }
|
func isM(v interface{}) bool {
|
||||||
func isVMY (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isVMY(false) && !x.Masked }
|
x, r := v.(*MemoryOperand)
|
||||||
func isEVEXVMY (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isVMY(true) && !x.Masked }
|
return r && x.isMem() && x.Broadcast == 0 && !x.Masked
|
||||||
func isVMYk (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isVMY(true) }
|
}
|
||||||
func isVMZ (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isVMZ() && !x.Masked }
|
func isMk(v interface{}) bool {
|
||||||
func isVMZk (v interface{}) bool { x, r := v.(*MemoryOperand) ; return r && x.isVMZ() }
|
x, r := v.(*MemoryOperand)
|
||||||
func isSAE (v interface{}) bool { _, r := v.(ExceptionControl) ; return r }
|
return r && x.isMem() && x.Broadcast == 0 && !(x.Masked && x.Mask.Z)
|
||||||
func isER (v interface{}) bool { _, r := v.(RoundingControl) ; return r }
|
}
|
||||||
|
func isMkz(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && x.isMem() && x.Broadcast == 0
|
||||||
|
}
|
||||||
|
func isM8(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isM(v) && x.isSize(1)
|
||||||
|
}
|
||||||
|
func isM16(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isM(v) && x.isSize(2)
|
||||||
|
}
|
||||||
|
func isM16kz(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isMkz(v) && x.isSize(2)
|
||||||
|
}
|
||||||
|
func isM32(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isM(v) && x.isSize(4)
|
||||||
|
}
|
||||||
|
func isM32k(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isMk(v) && x.isSize(4)
|
||||||
|
}
|
||||||
|
func isM32kz(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isMkz(v) && x.isSize(4)
|
||||||
|
}
|
||||||
|
func isM64(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isM(v) && x.isSize(8)
|
||||||
|
}
|
||||||
|
func isM64k(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isMk(v) && x.isSize(8)
|
||||||
|
}
|
||||||
|
func isM64kz(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isMkz(v) && x.isSize(8)
|
||||||
|
}
|
||||||
|
func isM128(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isM(v) && x.isSize(16)
|
||||||
|
}
|
||||||
|
func isM128kz(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isMkz(v) && x.isSize(16)
|
||||||
|
}
|
||||||
|
func isM256(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isM(v) && x.isSize(32)
|
||||||
|
}
|
||||||
|
func isM256kz(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isMkz(v) && x.isSize(32)
|
||||||
|
}
|
||||||
|
func isM512(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isM(v) && x.isSize(64)
|
||||||
|
}
|
||||||
|
func isM512kz(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && isMkz(v) && x.isSize(64)
|
||||||
|
}
|
||||||
|
func isM64M32bcst(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return isM64(v) || (r && x.isBroadcast(4, 2))
|
||||||
|
}
|
||||||
|
func isM128M32bcst(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return isM128(v) || (r && x.isBroadcast(4, 4))
|
||||||
|
}
|
||||||
|
func isM256M32bcst(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return isM256(v) || (r && x.isBroadcast(4, 8))
|
||||||
|
}
|
||||||
|
func isM512M32bcst(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return isM512(v) || (r && x.isBroadcast(4, 16))
|
||||||
|
}
|
||||||
|
func isM128M64bcst(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return isM128(v) || (r && x.isBroadcast(8, 2))
|
||||||
|
}
|
||||||
|
func isM256M64bcst(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return isM256(v) || (r && x.isBroadcast(8, 4))
|
||||||
|
}
|
||||||
|
func isM512M64bcst(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return isM512(v) || (r && x.isBroadcast(8, 8))
|
||||||
|
}
|
||||||
|
func isVMX(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && x.isVMX(false) && !x.Masked
|
||||||
|
}
|
||||||
|
func isEVEXVMX(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && x.isVMX(true) && !x.Masked
|
||||||
|
}
|
||||||
|
func isVMXk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMX(true) }
|
||||||
|
func isVMY(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && x.isVMY(false) && !x.Masked
|
||||||
|
}
|
||||||
|
func isEVEXVMY(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && x.isVMY(true) && !x.Masked
|
||||||
|
}
|
||||||
|
func isVMYk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMY(true) }
|
||||||
|
func isVMZ(v interface{}) bool {
|
||||||
|
x, r := v.(*MemoryOperand)
|
||||||
|
return r && x.isVMZ() && !x.Masked
|
||||||
|
}
|
||||||
|
func isVMZk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMZ() }
|
||||||
|
func isSAE(v interface{}) bool { _, r := v.(ExceptionControl); return r }
|
||||||
|
func isER(v interface{}) bool { _, r := v.(RoundingControl); return r }
|
||||||
|
|
||||||
func isImmExt(v interface{}, ext int, min int64, max int64) bool {
|
func isImmExt(v interface{}, ext int, min int64, max int64) bool {
|
||||||
if x, ok := asInt64(v); !ok {
|
if x, ok := asInt64(v); !ok {
|
||||||
return false
|
return false
|
||||||
} else if m := int64(1) << (8 * ext); x < m && x >= m + min {
|
} else if m := int64(1) << (8 * ext); x < m && x >= m+min {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return x <= max && x >= min
|
return x <= max && x >= min
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isImm8Ext(v interface{}, ext int) bool {
|
func isImm8Ext(v interface{}, ext int) bool {
|
||||||
return isImmExt(v, ext, math.MinInt8, math.MaxInt8)
|
return isImmExt(v, ext, math.MinInt8, math.MaxInt8)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isImm32Ext(v interface{}, ext int) bool {
|
func isImm32Ext(v interface{}, ext int) bool {
|
||||||
return isImmExt(v, ext, math.MinInt32, math.MaxInt32)
|
return isImmExt(v, ext, math.MinInt32, math.MaxInt32)
|
||||||
}
|
}
|
||||||
|
|
117
vendor/github.com/chenzhuoyu/iasm/x86_64/pools.go
generated
vendored
117
vendor/github.com/chenzhuoyu/iasm/x86_64/pools.go
generated
vendored
|
@ -1,117 +1,38 @@
|
||||||
package x86_64
|
package x86_64
|
||||||
|
|
||||||
import (
|
|
||||||
`sync`
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
labelPool sync.Pool
|
|
||||||
programPool sync.Pool
|
|
||||||
instructionPool sync.Pool
|
|
||||||
memoryOperandPool sync.Pool
|
|
||||||
)
|
|
||||||
|
|
||||||
func freeLabel(v *Label) {
|
|
||||||
labelPool.Put(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func clearLabel(p *Label) *Label {
|
|
||||||
*p = Label{}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateLabel creates a new Label, it may allocate a new one or grab one from a pool.
|
// CreateLabel creates a new Label, it may allocate a new one or grab one from a pool.
|
||||||
func CreateLabel(name string) *Label {
|
func CreateLabel(name string) *Label {
|
||||||
var p *Label
|
p := new(Label)
|
||||||
var v interface{}
|
|
||||||
|
|
||||||
/* attempt to grab from the pool */
|
/* initialize the label */
|
||||||
if v = labelPool.Get(); v == nil {
|
p.refs = 1
|
||||||
p = new(Label)
|
p.Name = name
|
||||||
} else {
|
return p
|
||||||
p = clearLabel(v.(*Label))
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the label */
|
|
||||||
p.refs = 1
|
|
||||||
p.Name = name
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProgram(arch *Arch) *Program {
|
func newProgram(arch *Arch) *Program {
|
||||||
var p *Program
|
p := new(Program)
|
||||||
var v interface{}
|
|
||||||
|
|
||||||
/* attempt to grab from the pool */
|
/* initialize the program */
|
||||||
if v = programPool.Get(); v == nil {
|
p.arch = arch
|
||||||
p = new(Program)
|
return p
|
||||||
} else {
|
|
||||||
p = clearProgram(v.(*Program))
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the program */
|
|
||||||
p.arch = arch
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func freeProgram(p *Program) {
|
|
||||||
programPool.Put(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func clearProgram(p *Program) *Program {
|
|
||||||
*p = Program{}
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInstruction(name string, argc int, argv Operands) *Instruction {
|
func newInstruction(name string, argc int, argv Operands) *Instruction {
|
||||||
var v interface{}
|
p := new(Instruction)
|
||||||
var p *Instruction
|
|
||||||
|
|
||||||
/* attempt to grab from the pool */
|
/* initialize the instruction */
|
||||||
if v = instructionPool.Get(); v == nil {
|
p.name = name
|
||||||
p = new(Instruction)
|
p.argc = argc
|
||||||
} else {
|
p.argv = argv
|
||||||
p = clearInstruction(v.(*Instruction))
|
return p
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the instruction */
|
|
||||||
p.name = name
|
|
||||||
p.argc = argc
|
|
||||||
p.argv = argv
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func freeInstruction(v *Instruction) {
|
|
||||||
instructionPool.Put(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func clearInstruction(p *Instruction) *Instruction {
|
|
||||||
*p = Instruction { prefix: p.prefix[:0] }
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func freeMemoryOperand(m *MemoryOperand) {
|
|
||||||
memoryOperandPool.Put(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func clearMemoryOperand(m *MemoryOperand) *MemoryOperand {
|
|
||||||
*m = MemoryOperand{}
|
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMemoryOperand creates a new MemoryOperand, it may allocate a new one or grab one from a pool.
|
// CreateMemoryOperand creates a new MemoryOperand, it may allocate a new one or grab one from a pool.
|
||||||
func CreateMemoryOperand() *MemoryOperand {
|
func CreateMemoryOperand() *MemoryOperand {
|
||||||
var v interface{}
|
p := new(MemoryOperand)
|
||||||
var p *MemoryOperand
|
|
||||||
|
|
||||||
/* attempt to grab from the pool */
|
/* initialize the memory operand */
|
||||||
if v = memoryOperandPool.Get(); v == nil {
|
p.refs = 1
|
||||||
p = new(MemoryOperand)
|
return p
|
||||||
} else {
|
|
||||||
p = clearMemoryOperand(v.(*MemoryOperand))
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the memory operand */
|
|
||||||
p.refs = 1
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
656
vendor/github.com/chenzhuoyu/iasm/x86_64/program.go
generated
vendored
656
vendor/github.com/chenzhuoyu/iasm/x86_64/program.go
generated
vendored
|
@ -1,127 +1,149 @@
|
||||||
package x86_64
|
package x86_64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
`fmt`
|
"fmt"
|
||||||
`math`
|
"math"
|
||||||
`math/bits`
|
"math/bits"
|
||||||
|
|
||||||
`github.com/chenzhuoyu/iasm/expr`
|
"github.com/chenzhuoyu/iasm/expr"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
_PseudoType int
|
_PseudoType int
|
||||||
_InstructionEncoder func(*Program, ...interface{}) *Instruction
|
_InstructionEncoder func(*Program, ...interface{}) *Instruction
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_PseudoNop _PseudoType = iota + 1
|
_PseudoNop _PseudoType = iota + 1
|
||||||
_PseudoByte
|
_PseudoByte
|
||||||
_PseudoWord
|
_PseudoWord
|
||||||
_PseudoLong
|
_PseudoLong
|
||||||
_PseudoQuad
|
_PseudoQuad
|
||||||
_PseudoData
|
_PseudoData
|
||||||
_PseudoAlign
|
_PseudoAlign
|
||||||
)
|
)
|
||||||
|
|
||||||
func (self _PseudoType) String() string {
|
func (self _PseudoType) String() string {
|
||||||
switch self {
|
switch self {
|
||||||
case _PseudoNop : return ".nop"
|
case _PseudoNop:
|
||||||
case _PseudoByte : return ".byte"
|
return ".nop"
|
||||||
case _PseudoWord : return ".word"
|
case _PseudoByte:
|
||||||
case _PseudoLong : return ".long"
|
return ".byte"
|
||||||
case _PseudoQuad : return ".quad"
|
case _PseudoWord:
|
||||||
case _PseudoData : return ".data"
|
return ".word"
|
||||||
case _PseudoAlign : return ".align"
|
case _PseudoLong:
|
||||||
default : panic("unreachable")
|
return ".long"
|
||||||
}
|
case _PseudoQuad:
|
||||||
|
return ".quad"
|
||||||
|
case _PseudoData:
|
||||||
|
return ".data"
|
||||||
|
case _PseudoAlign:
|
||||||
|
return ".align"
|
||||||
|
default:
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type _Pseudo struct {
|
type _Pseudo struct {
|
||||||
kind _PseudoType
|
kind _PseudoType
|
||||||
data []byte
|
data []byte
|
||||||
uint uint64
|
uint uint64
|
||||||
expr *expr.Expr
|
expr *expr.Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) free() {
|
func (self *_Pseudo) free() {
|
||||||
if self.expr != nil {
|
if self.expr != nil {
|
||||||
self.expr.Free()
|
self.expr.Free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) encode(m *[]byte, pc uintptr) int {
|
func (self *_Pseudo) encode(m *[]byte, pc uintptr) int {
|
||||||
switch self.kind {
|
switch self.kind {
|
||||||
case _PseudoNop : return 0
|
case _PseudoNop:
|
||||||
case _PseudoByte : self.encodeByte(m) ; return 1
|
return 0
|
||||||
case _PseudoWord : self.encodeWord(m) ; return 2
|
case _PseudoByte:
|
||||||
case _PseudoLong : self.encodeLong(m) ; return 4
|
self.encodeByte(m)
|
||||||
case _PseudoQuad : self.encodeQuad(m) ; return 8
|
return 1
|
||||||
case _PseudoData : self.encodeData(m) ; return len(self.data)
|
case _PseudoWord:
|
||||||
case _PseudoAlign : self.encodeAlign(m, pc) ; return self.alignSize(pc)
|
self.encodeWord(m)
|
||||||
default : panic("invalid pseudo instruction")
|
return 2
|
||||||
}
|
case _PseudoLong:
|
||||||
|
self.encodeLong(m)
|
||||||
|
return 4
|
||||||
|
case _PseudoQuad:
|
||||||
|
self.encodeQuad(m)
|
||||||
|
return 8
|
||||||
|
case _PseudoData:
|
||||||
|
self.encodeData(m)
|
||||||
|
return len(self.data)
|
||||||
|
case _PseudoAlign:
|
||||||
|
self.encodeAlign(m, pc)
|
||||||
|
return self.alignSize(pc)
|
||||||
|
default:
|
||||||
|
panic("invalid pseudo instruction")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) evalExpr(low int64, high int64) int64 {
|
func (self *_Pseudo) evalExpr(low int64, high int64) int64 {
|
||||||
if v, err := self.expr.Evaluate(); err != nil {
|
if v, err := self.expr.Evaluate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
} else if v < low || v > high {
|
} else if v < low || v > high {
|
||||||
panic(fmt.Sprintf("expression out of range [%d, %d]: %d", low, high, v))
|
panic(fmt.Sprintf("expression out of range [%d, %d]: %d", low, high, v))
|
||||||
} else {
|
} else {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) alignSize(pc uintptr) int {
|
func (self *_Pseudo) alignSize(pc uintptr) int {
|
||||||
if !ispow2(self.uint) {
|
if !ispow2(self.uint) {
|
||||||
panic(fmt.Sprintf("aligment should be a power of 2, not %d", self.uint))
|
panic(fmt.Sprintf("aligment should be a power of 2, not %d", self.uint))
|
||||||
} else {
|
} else {
|
||||||
return align(int(pc), bits.TrailingZeros64(self.uint)) - int(pc)
|
return align(int(pc), bits.TrailingZeros64(self.uint)) - int(pc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) encodeData(m *[]byte) {
|
func (self *_Pseudo) encodeData(m *[]byte) {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
*m = append(*m, self.data...)
|
*m = append(*m, self.data...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) encodeByte(m *[]byte) {
|
func (self *_Pseudo) encodeByte(m *[]byte) {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
append8(m, byte(self.evalExpr(math.MinInt8, math.MaxUint8)))
|
append8(m, byte(self.evalExpr(math.MinInt8, math.MaxUint8)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) encodeWord(m *[]byte) {
|
func (self *_Pseudo) encodeWord(m *[]byte) {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
append16(m, uint16(self.evalExpr(math.MinInt16, math.MaxUint16)))
|
append16(m, uint16(self.evalExpr(math.MinInt16, math.MaxUint16)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) encodeLong(m *[]byte) {
|
func (self *_Pseudo) encodeLong(m *[]byte) {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
append32(m, uint32(self.evalExpr(math.MinInt32, math.MaxUint32)))
|
append32(m, uint32(self.evalExpr(math.MinInt32, math.MaxUint32)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) encodeQuad(m *[]byte) {
|
func (self *_Pseudo) encodeQuad(m *[]byte) {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
if v, err := self.expr.Evaluate(); err != nil {
|
if v, err := self.expr.Evaluate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
} else {
|
} else {
|
||||||
append64(m, uint64(v))
|
append64(m, uint64(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *_Pseudo) encodeAlign(m *[]byte, pc uintptr) {
|
func (self *_Pseudo) encodeAlign(m *[]byte, pc uintptr) {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
if self.expr == nil {
|
if self.expr == nil {
|
||||||
expandmm(m, self.alignSize(pc), 0)
|
expandmm(m, self.alignSize(pc), 0)
|
||||||
} else {
|
} else {
|
||||||
expandmm(m, self.alignSize(pc), byte(self.evalExpr(math.MinInt8, math.MaxUint8)))
|
expandmm(m, self.alignSize(pc), byte(self.evalExpr(math.MinInt8, math.MaxUint8)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operands represents a sequence of operand required by an instruction.
|
// Operands represents a sequence of operand required by an instruction.
|
||||||
|
@ -131,15 +153,15 @@ type Operands [_N_args]interface{}
|
||||||
type InstructionDomain uint8
|
type InstructionDomain uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DomainGeneric InstructionDomain = iota
|
DomainGeneric InstructionDomain = iota
|
||||||
DomainMMXSSE
|
DomainMMXSSE
|
||||||
DomainAVX
|
DomainAVX
|
||||||
DomainFMA
|
DomainFMA
|
||||||
DomainCrypto
|
DomainCrypto
|
||||||
DomainMask
|
DomainMask
|
||||||
DomainAMDSpecific
|
DomainAMDSpecific
|
||||||
DomainMisc
|
DomainMisc
|
||||||
DomainPseudo
|
DomainPseudo
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -147,139 +169,139 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_B_none _BranchType = iota
|
_B_none _BranchType = iota
|
||||||
_B_conditional
|
_B_conditional
|
||||||
_B_unconditional
|
_B_unconditional
|
||||||
)
|
)
|
||||||
|
|
||||||
// Instruction represents an unencoded instruction.
|
// Instruction represents an unencoded instruction.
|
||||||
type Instruction struct {
|
type Instruction struct {
|
||||||
next *Instruction
|
next *Instruction
|
||||||
pc uintptr
|
pc uintptr
|
||||||
nb int
|
nb int
|
||||||
len int
|
len int
|
||||||
argc int
|
argc int
|
||||||
name string
|
name string
|
||||||
argv Operands
|
argv Operands
|
||||||
forms [_N_forms]_Encoding
|
forms [_N_forms]_Encoding
|
||||||
pseudo _Pseudo
|
pseudo _Pseudo
|
||||||
branch _BranchType
|
branch _BranchType
|
||||||
domain InstructionDomain
|
domain InstructionDomain
|
||||||
prefix []byte
|
prefix []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Instruction) add(flags int, encoder func(m *_Encoding, v []interface{})) {
|
func (self *Instruction) add(flags int, encoder func(m *_Encoding, v []interface{})) {
|
||||||
self.forms[self.len].flags = flags
|
self.forms[self.len].flags = flags
|
||||||
self.forms[self.len].encoder = encoder
|
self.forms[self.len].encoder = encoder
|
||||||
self.len++
|
self.len++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Instruction) free() {
|
func (self *Instruction) free() {
|
||||||
self.clear()
|
self.clear()
|
||||||
self.pseudo.free()
|
self.pseudo.free()
|
||||||
freeInstruction(self)
|
//freeInstruction(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Instruction) clear() {
|
func (self *Instruction) clear() {
|
||||||
for i := 0; i < self.argc; i++ {
|
for i := 0; i < self.argc; i++ {
|
||||||
if v, ok := self.argv[i].(Disposable); ok {
|
if v, ok := self.argv[i].(Disposable); ok {
|
||||||
v.Free()
|
v.Free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Instruction) check(e *_Encoding) bool {
|
func (self *Instruction) check(e *_Encoding) bool {
|
||||||
if (e.flags & _F_rel1) != 0 {
|
if (e.flags & _F_rel1) != 0 {
|
||||||
return isRel8(self.argv[0])
|
return isRel8(self.argv[0])
|
||||||
} else if (e.flags & _F_rel4) != 0 {
|
} else if (e.flags & _F_rel4) != 0 {
|
||||||
return isRel32(self.argv[0]) || isLabel(self.argv[0])
|
return isRel32(self.argv[0]) || isLabel(self.argv[0])
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Instruction) encode(m *[]byte) int {
|
func (self *Instruction) encode(m *[]byte) int {
|
||||||
n := math.MaxInt64
|
n := math.MaxInt64
|
||||||
p := (*_Encoding)(nil)
|
p := (*_Encoding)(nil)
|
||||||
|
|
||||||
/* encode prefixes if any */
|
/* encode prefixes if any */
|
||||||
if self.nb = len(self.prefix); m != nil {
|
if self.nb = len(self.prefix); m != nil {
|
||||||
*m = append(*m, self.prefix...)
|
*m = append(*m, self.prefix...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for pseudo-instructions */
|
/* check for pseudo-instructions */
|
||||||
if self.pseudo.kind != 0 {
|
if self.pseudo.kind != 0 {
|
||||||
self.nb += self.pseudo.encode(m, self.pc)
|
self.nb += self.pseudo.encode(m, self.pc)
|
||||||
return self.nb
|
return self.nb
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the shortest encoding */
|
/* find the shortest encoding */
|
||||||
for i := 0; i < self.len; i++ {
|
for i := 0; i < self.len; i++ {
|
||||||
if e := &self.forms[i]; self.check(e) {
|
if e := &self.forms[i]; self.check(e) {
|
||||||
if v := e.encode(self.argv[:self.argc]); v < n {
|
if v := e.encode(self.argv[:self.argc]); v < n {
|
||||||
n = v
|
n = v
|
||||||
p = e
|
p = e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to buffer if needed */
|
/* add to buffer if needed */
|
||||||
if m != nil {
|
if m != nil {
|
||||||
*m = append(*m, p.bytes[:n]...)
|
*m = append(*m, p.bytes[:n]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update the instruction length */
|
/* update the instruction length */
|
||||||
self.nb += n
|
self.nb += n
|
||||||
return self.nb
|
return self.nb
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Instruction Prefixes **/
|
/** Instruction Prefixes **/
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_P_cs = 0x2e
|
_P_cs = 0x2e
|
||||||
_P_ds = 0x3e
|
_P_ds = 0x3e
|
||||||
_P_es = 0x26
|
_P_es = 0x26
|
||||||
_P_fs = 0x64
|
_P_fs = 0x64
|
||||||
_P_gs = 0x65
|
_P_gs = 0x65
|
||||||
_P_ss = 0x36
|
_P_ss = 0x36
|
||||||
_P_lock = 0xf0
|
_P_lock = 0xf0
|
||||||
)
|
)
|
||||||
|
|
||||||
// CS overrides the memory operation of this instruction to CS.
|
// CS overrides the memory operation of this instruction to CS.
|
||||||
func (self *Instruction) CS() *Instruction {
|
func (self *Instruction) CS() *Instruction {
|
||||||
self.prefix = append(self.prefix, _P_cs)
|
self.prefix = append(self.prefix, _P_cs)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// DS overrides the memory operation of this instruction to DS,
|
// DS overrides the memory operation of this instruction to DS,
|
||||||
// this is the default section for most instructions if not specified.
|
// this is the default section for most instructions if not specified.
|
||||||
func (self *Instruction) DS() *Instruction {
|
func (self *Instruction) DS() *Instruction {
|
||||||
self.prefix = append(self.prefix, _P_ds)
|
self.prefix = append(self.prefix, _P_ds)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// ES overrides the memory operation of this instruction to ES.
|
// ES overrides the memory operation of this instruction to ES.
|
||||||
func (self *Instruction) ES() *Instruction {
|
func (self *Instruction) ES() *Instruction {
|
||||||
self.prefix = append(self.prefix, _P_es)
|
self.prefix = append(self.prefix, _P_es)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// FS overrides the memory operation of this instruction to FS.
|
// FS overrides the memory operation of this instruction to FS.
|
||||||
func (self *Instruction) FS() *Instruction {
|
func (self *Instruction) FS() *Instruction {
|
||||||
self.prefix = append(self.prefix, _P_fs)
|
self.prefix = append(self.prefix, _P_fs)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// GS overrides the memory operation of this instruction to GS.
|
// GS overrides the memory operation of this instruction to GS.
|
||||||
func (self *Instruction) GS() *Instruction {
|
func (self *Instruction) GS() *Instruction {
|
||||||
self.prefix = append(self.prefix, _P_gs)
|
self.prefix = append(self.prefix, _P_gs)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// SS overrides the memory operation of this instruction to SS.
|
// SS overrides the memory operation of this instruction to SS.
|
||||||
func (self *Instruction) SS() *Instruction {
|
func (self *Instruction) SS() *Instruction {
|
||||||
self.prefix = append(self.prefix, _P_ss)
|
self.prefix = append(self.prefix, _P_ss)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOCK causes the processor's LOCK# signal to be asserted during execution of
|
// LOCK causes the processor's LOCK# signal to be asserted during execution of
|
||||||
|
@ -287,128 +309,132 @@ func (self *Instruction) SS() *Instruction {
|
||||||
// In a multiprocessor environment, the LOCK# signal insures that the processor
|
// In a multiprocessor environment, the LOCK# signal insures that the processor
|
||||||
// has exclusive use of any shared memory while the signal is asserted.
|
// has exclusive use of any shared memory while the signal is asserted.
|
||||||
func (self *Instruction) LOCK() *Instruction {
|
func (self *Instruction) LOCK() *Instruction {
|
||||||
self.prefix = append(self.prefix, _P_lock)
|
self.prefix = append(self.prefix, _P_lock)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Basic Instruction Properties **/
|
/** Basic Instruction Properties **/
|
||||||
|
|
||||||
// Name returns the instruction name.
|
// Name returns the instruction name.
|
||||||
func (self *Instruction) Name() string {
|
func (self *Instruction) Name() string {
|
||||||
return self.name
|
return self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Domain returns the domain of this instruction.
|
// Domain returns the domain of this instruction.
|
||||||
func (self *Instruction) Domain() InstructionDomain {
|
func (self *Instruction) Domain() InstructionDomain {
|
||||||
return self.domain
|
return self.domain
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operands returns the operands of this instruction.
|
// Operands returns the operands of this instruction.
|
||||||
func (self *Instruction) Operands() []interface{} {
|
func (self *Instruction) Operands() []interface{} {
|
||||||
return self.argv[:self.argc]
|
return self.argv[:self.argc]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Program represents a sequence of instructions.
|
// Program represents a sequence of instructions.
|
||||||
type Program struct {
|
type Program struct {
|
||||||
arch *Arch
|
arch *Arch
|
||||||
head *Instruction
|
head *Instruction
|
||||||
tail *Instruction
|
tail *Instruction
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_N_near = 2 // near-branch (-128 ~ +127) takes 2 bytes to encode
|
_N_near = 2 // near-branch (-128 ~ +127) takes 2 bytes to encode
|
||||||
_N_far_cond = 6 // conditional far-branch takes 6 bytes to encode
|
_N_far_cond = 6 // conditional far-branch takes 6 bytes to encode
|
||||||
_N_far_uncond = 5 // unconditional far-branch takes 5 bytes to encode
|
_N_far_uncond = 5 // unconditional far-branch takes 5 bytes to encode
|
||||||
)
|
)
|
||||||
|
|
||||||
func (self *Program) clear() {
|
func (self *Program) clear() {
|
||||||
for p, q := self.head, self.head; p != nil; p = q {
|
for p, q := self.head, self.head; p != nil; p = q {
|
||||||
q = p.next
|
q = p.next
|
||||||
p.free()
|
p.free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Program) alloc(name string, argc int, argv Operands) *Instruction {
|
func (self *Program) alloc(name string, argc int, argv Operands) *Instruction {
|
||||||
p := self.tail
|
p := self.tail
|
||||||
q := newInstruction(name, argc, argv)
|
q := newInstruction(name, argc, argv)
|
||||||
|
|
||||||
/* attach to tail if any */
|
/* attach to tail if any */
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.next = q
|
p.next = q
|
||||||
} else {
|
} else {
|
||||||
self.head = q
|
self.head = q
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the new tail */
|
/* set the new tail */
|
||||||
self.tail = q
|
self.tail = q
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Program) pseudo(kind _PseudoType) (p *Instruction) {
|
func (self *Program) pseudo(kind _PseudoType) (p *Instruction) {
|
||||||
p = self.alloc(kind.String(), 0, Operands{})
|
p = self.alloc(kind.String(), 0, Operands{})
|
||||||
p.domain = DomainPseudo
|
p.domain = DomainPseudo
|
||||||
p.pseudo.kind = kind
|
p.pseudo.kind = kind
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Program) require(isa ISA) {
|
func (self *Program) require(isa ISA) {
|
||||||
if !self.arch.HasISA(isa) {
|
if !self.arch.HasISA(isa) {
|
||||||
panic("ISA '" + isa.String() + "' was not enabled")
|
panic("ISA '" + isa.String() + "' was not enabled")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Program) branchSize(p *Instruction) int {
|
func (self *Program) branchSize(p *Instruction) int {
|
||||||
switch p.branch {
|
switch p.branch {
|
||||||
case _B_none : panic("p is not a branch")
|
case _B_none:
|
||||||
case _B_conditional : return _N_far_cond
|
panic("p is not a branch")
|
||||||
case _B_unconditional : return _N_far_uncond
|
case _B_conditional:
|
||||||
default : panic("invalid instruction")
|
return _N_far_cond
|
||||||
}
|
case _B_unconditional:
|
||||||
|
return _N_far_uncond
|
||||||
|
default:
|
||||||
|
panic("invalid instruction")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Pseudo-Instructions **/
|
/** Pseudo-Instructions **/
|
||||||
|
|
||||||
// Byte is a pseudo-instruction to add raw byte to the assembled code.
|
// Byte is a pseudo-instruction to add raw byte to the assembled code.
|
||||||
func (self *Program) Byte(v *expr.Expr) (p *Instruction) {
|
func (self *Program) Byte(v *expr.Expr) (p *Instruction) {
|
||||||
p = self.pseudo(_PseudoByte)
|
p = self.pseudo(_PseudoByte)
|
||||||
p.pseudo.expr = v
|
p.pseudo.expr = v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Word is a pseudo-instruction to add raw uint16 as little-endian to the assembled code.
|
// Word is a pseudo-instruction to add raw uint16 as little-endian to the assembled code.
|
||||||
func (self *Program) Word(v *expr.Expr) (p *Instruction) {
|
func (self *Program) Word(v *expr.Expr) (p *Instruction) {
|
||||||
p = self.pseudo(_PseudoWord)
|
p = self.pseudo(_PseudoWord)
|
||||||
p.pseudo.expr = v
|
p.pseudo.expr = v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Long is a pseudo-instruction to add raw uint32 as little-endian to the assembled code.
|
// Long is a pseudo-instruction to add raw uint32 as little-endian to the assembled code.
|
||||||
func (self *Program) Long(v *expr.Expr) (p *Instruction) {
|
func (self *Program) Long(v *expr.Expr) (p *Instruction) {
|
||||||
p = self.pseudo(_PseudoLong)
|
p = self.pseudo(_PseudoLong)
|
||||||
p.pseudo.expr = v
|
p.pseudo.expr = v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quad is a pseudo-instruction to add raw uint64 as little-endian to the assembled code.
|
// Quad is a pseudo-instruction to add raw uint64 as little-endian to the assembled code.
|
||||||
func (self *Program) Quad(v *expr.Expr) (p *Instruction) {
|
func (self *Program) Quad(v *expr.Expr) (p *Instruction) {
|
||||||
p = self.pseudo(_PseudoQuad)
|
p = self.pseudo(_PseudoQuad)
|
||||||
p.pseudo.expr = v
|
p.pseudo.expr = v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data is a pseudo-instruction to add raw bytes to the assembled code.
|
// Data is a pseudo-instruction to add raw bytes to the assembled code.
|
||||||
func (self *Program) Data(v []byte) (p *Instruction) {
|
func (self *Program) Data(v []byte) (p *Instruction) {
|
||||||
p = self.pseudo(_PseudoData)
|
p = self.pseudo(_PseudoData)
|
||||||
p.pseudo.data = v
|
p.pseudo.data = v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align is a pseudo-instruction to ensure the PC is aligned to a certain value.
|
// Align is a pseudo-instruction to ensure the PC is aligned to a certain value.
|
||||||
func (self *Program) Align(align uint64, padding *expr.Expr) (p *Instruction) {
|
func (self *Program) Align(align uint64, padding *expr.Expr) (p *Instruction) {
|
||||||
p = self.pseudo(_PseudoAlign)
|
p = self.pseudo(_PseudoAlign)
|
||||||
p.pseudo.uint = align
|
p.pseudo.uint = align
|
||||||
p.pseudo.expr = padding
|
p.pseudo.expr = padding
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Program Assembler **/
|
/** Program Assembler **/
|
||||||
|
@ -417,126 +443,126 @@ func (self *Program) Align(align uint64, padding *expr.Expr) (p *Instruction) {
|
||||||
// Any operation performed after Free is undefined behavior.
|
// Any operation performed after Free is undefined behavior.
|
||||||
//
|
//
|
||||||
// NOTE: This also frees all the instructions, labels, memory
|
// NOTE: This also frees all the instructions, labels, memory
|
||||||
// operands and expressions associated with this program.
|
|
||||||
//
|
//
|
||||||
|
// operands and expressions associated with this program.
|
||||||
func (self *Program) Free() {
|
func (self *Program) Free() {
|
||||||
self.clear()
|
self.clear()
|
||||||
freeProgram(self)
|
//freeProgram(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link pins a label at the current position.
|
// Link pins a label at the current position.
|
||||||
func (self *Program) Link(p *Label) {
|
func (self *Program) Link(p *Label) {
|
||||||
if p.Dest != nil {
|
if p.Dest != nil {
|
||||||
panic("lable was alreay linked")
|
panic("lable was alreay linked")
|
||||||
} else {
|
} else {
|
||||||
p.Dest = self.pseudo(_PseudoNop)
|
p.Dest = self.pseudo(_PseudoNop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assemble assembles and links the entire program into machine code.
|
// Assemble assembles and links the entire program into machine code.
|
||||||
func (self *Program) Assemble(pc uintptr) (ret []byte) {
|
func (self *Program) Assemble(pc uintptr) (ret []byte) {
|
||||||
orig := pc
|
orig := pc
|
||||||
next := true
|
next := true
|
||||||
offs := uintptr(0)
|
offs := uintptr(0)
|
||||||
|
|
||||||
/* Pass 0: PC-precompute, assume all labeled branches are far-branches. */
|
/* Pass 0: PC-precompute, assume all labeled branches are far-branches. */
|
||||||
for p := self.head; p != nil; p = p.next {
|
for p := self.head; p != nil; p = p.next {
|
||||||
if p.pc = pc; !isLabel(p.argv[0]) || p.branch == _B_none {
|
if p.pc = pc; !isLabel(p.argv[0]) || p.branch == _B_none {
|
||||||
pc += uintptr(p.encode(nil))
|
pc += uintptr(p.encode(nil))
|
||||||
} else {
|
} else {
|
||||||
pc += uintptr(self.branchSize(p))
|
pc += uintptr(self.branchSize(p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate space for the machine code */
|
/* allocate space for the machine code */
|
||||||
nb := int(pc - orig)
|
nb := int(pc - orig)
|
||||||
ret = make([]byte, 0, nb)
|
ret = make([]byte, 0, nb)
|
||||||
|
|
||||||
/* Pass 1: adjust all the jumps */
|
/* Pass 1: adjust all the jumps */
|
||||||
for next {
|
for next {
|
||||||
next = false
|
next = false
|
||||||
offs = uintptr(0)
|
offs = uintptr(0)
|
||||||
|
|
||||||
/* scan all the branches */
|
/* scan all the branches */
|
||||||
for p := self.head; p != nil; p = p.next {
|
for p := self.head; p != nil; p = p.next {
|
||||||
var ok bool
|
var ok bool
|
||||||
var lb *Label
|
var lb *Label
|
||||||
|
|
||||||
/* re-calculate the alignment here */
|
/* re-calculate the alignment here */
|
||||||
if nb = p.nb; p.pseudo.kind == _PseudoAlign {
|
if nb = p.nb; p.pseudo.kind == _PseudoAlign {
|
||||||
p.pc -= offs
|
p.pc -= offs
|
||||||
offs += uintptr(nb - p.encode(nil))
|
offs += uintptr(nb - p.encode(nil))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust the program counter */
|
/* adjust the program counter */
|
||||||
p.pc -= offs
|
p.pc -= offs
|
||||||
lb, ok = p.argv[0].(*Label)
|
lb, ok = p.argv[0].(*Label)
|
||||||
|
|
||||||
/* only care about labeled far-branches */
|
/* only care about labeled far-branches */
|
||||||
if !ok || p.nb == _N_near || p.branch == _B_none {
|
if !ok || p.nb == _N_near || p.branch == _B_none {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate the jump offset */
|
/* calculate the jump offset */
|
||||||
size := self.branchSize(p)
|
size := self.branchSize(p)
|
||||||
diff := lb.offset(p.pc, size)
|
diff := lb.offset(p.pc, size)
|
||||||
|
|
||||||
/* too far to be a near jump */
|
/* too far to be a near jump */
|
||||||
if diff > 127 || diff < -128 {
|
if diff > 127 || diff < -128 {
|
||||||
p.nb = size
|
p.nb = size
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a far jump becomes a near jump, calculate
|
/* a far jump becomes a near jump, calculate
|
||||||
* the PC adjustment value and assemble again */
|
* the PC adjustment value and assemble again */
|
||||||
next = true
|
next = true
|
||||||
p.nb = _N_near
|
p.nb = _N_near
|
||||||
offs += uintptr(size - _N_near)
|
offs += uintptr(size - _N_near)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass 3: link all the cross-references */
|
/* Pass 3: link all the cross-references */
|
||||||
for p := self.head; p != nil; p = p.next {
|
for p := self.head; p != nil; p = p.next {
|
||||||
for i := 0; i < p.argc; i++ {
|
for i := 0; i < p.argc; i++ {
|
||||||
var ok bool
|
var ok bool
|
||||||
var lb *Label
|
var lb *Label
|
||||||
var op *MemoryOperand
|
var op *MemoryOperand
|
||||||
|
|
||||||
/* resolve labels */
|
/* resolve labels */
|
||||||
if lb, ok = p.argv[i].(*Label); ok {
|
if lb, ok = p.argv[i].(*Label); ok {
|
||||||
p.argv[i] = lb.offset(p.pc, p.nb)
|
p.argv[i] = lb.offset(p.pc, p.nb)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for memory operands */
|
/* check for memory operands */
|
||||||
if op, ok = p.argv[i].(*MemoryOperand); !ok {
|
if op, ok = p.argv[i].(*MemoryOperand); !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for label references */
|
/* check for label references */
|
||||||
if op.Addr.Type != Reference {
|
if op.Addr.Type != Reference {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
/* replace the label with the real offset */
|
/* replace the label with the real offset */
|
||||||
op.Addr.Type = Offset
|
op.Addr.Type = Offset
|
||||||
op.Addr.Offset = op.Addr.Reference.offset(p.pc, p.nb)
|
op.Addr.Offset = op.Addr.Reference.offset(p.pc, p.nb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass 4: actually encode all the instructions */
|
/* Pass 4: actually encode all the instructions */
|
||||||
for p := self.head; p != nil; p = p.next {
|
for p := self.head; p != nil; p = p.next {
|
||||||
p.encode(&ret)
|
p.encode(&ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all done */
|
/* all done */
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssembleAndFree is like Assemble, but it frees the Program after assembling.
|
// AssembleAndFree is like Assemble, but it frees the Program after assembling.
|
||||||
func (self *Program) AssembleAndFree(pc uintptr) (ret []byte) {
|
func (self *Program) AssembleAndFree(pc uintptr) (ret []byte) {
|
||||||
ret = self.Assemble(pc)
|
ret = self.Assemble(pc)
|
||||||
self.Free()
|
self.Free()
|
||||||
return
|
return
|
||||||
}
|
}
|
3
vendor/github.com/gabriel-vasile/mimetype/README.md
generated
vendored
3
vendor/github.com/gabriel-vasile/mimetype/README.md
generated
vendored
|
@ -10,9 +10,6 @@
|
||||||
</h6>
|
</h6>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://travis-ci.org/gabriel-vasile/mimetype">
|
|
||||||
<img alt="Build Status" src="https://travis-ci.org/gabriel-vasile/mimetype.svg?branch=master">
|
|
||||||
</a>
|
|
||||||
<a href="https://pkg.go.dev/github.com/gabriel-vasile/mimetype">
|
<a href="https://pkg.go.dev/github.com/gabriel-vasile/mimetype">
|
||||||
<img alt="Go Reference" src="https://pkg.go.dev/badge/github.com/gabriel-vasile/mimetype.svg">
|
<img alt="Go Reference" src="https://pkg.go.dev/badge/github.com/gabriel-vasile/mimetype.svg">
|
||||||
</a>
|
</a>
|
||||||
|
|
38
vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go
generated
vendored
38
vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go
generated
vendored
|
@ -150,32 +150,34 @@ func Marc(raw []byte, limit uint32) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Glb matches a glTF model format file.
|
// Glb matches a glTF model format file.
|
||||||
// GLB is the binary file format representation of 3D models save in
|
// GLB is the binary file format representation of 3D models saved in
|
||||||
// the GL transmission Format (glTF).
|
// the GL transmission Format (glTF).
|
||||||
// see more: https://docs.fileformat.com/3d/glb/
|
// GLB uses little endian and its header structure is as follows:
|
||||||
// https://www.iana.org/assignments/media-types/model/gltf-binary
|
|
||||||
// GLB file format is based on little endian and its header structure
|
|
||||||
// show below:
|
|
||||||
//
|
//
|
||||||
// <-- 12-byte header -->
|
// <-- 12-byte header -->
|
||||||
// | magic | version | length |
|
// | magic | version | length |
|
||||||
// | (uint32) | (uint32) | (uint32) |
|
// | (uint32) | (uint32) | (uint32) |
|
||||||
// | \x67\x6C\x54\x46 | \x01\x00\x00\x00 | ... |
|
// | \x67\x6C\x54\x46 | \x01\x00\x00\x00 | ... |
|
||||||
// | g l T F | 1 | ... |
|
// | g l T F | 1 | ... |
|
||||||
|
//
|
||||||
|
// Visit [glTF specification] and [IANA glTF entry] for more details.
|
||||||
|
//
|
||||||
|
// [glTF specification]: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html
|
||||||
|
// [IANA glTF entry]: https://www.iana.org/assignments/media-types/model/gltf-binary
|
||||||
var Glb = prefix([]byte("\x67\x6C\x54\x46\x02\x00\x00\x00"),
|
var Glb = prefix([]byte("\x67\x6C\x54\x46\x02\x00\x00\x00"),
|
||||||
[]byte("\x67\x6C\x54\x46\x01\x00\x00\x00"))
|
[]byte("\x67\x6C\x54\x46\x01\x00\x00\x00"))
|
||||||
|
|
||||||
// TzIf matches a Time Zone Information Format (TZif) file.
|
// TzIf matches a Time Zone Information Format (TZif) file.
|
||||||
// See more: https://tools.ietf.org/id/draft-murchison-tzdist-tzif-00.html#rfc.section.3
|
// See more: https://tools.ietf.org/id/draft-murchison-tzdist-tzif-00.html#rfc.section.3
|
||||||
// Its header structure is shown below:
|
// Its header structure is shown below:
|
||||||
// +---------------+---+
|
// +---------------+---+
|
||||||
// | magic (4) | <-+-- version (1)
|
// | magic (4) | <-+-- version (1)
|
||||||
// +---------------+---+---------------------------------------+
|
// +---------------+---+---------------------------------------+
|
||||||
// | [unused - reserved for future use] (15) |
|
// | [unused - reserved for future use] (15) |
|
||||||
// +---------------+---------------+---------------+-----------+
|
// +---------------+---------------+---------------+-----------+
|
||||||
// | isutccnt (4) | isstdcnt (4) | leapcnt (4) |
|
// | isutccnt (4) | isstdcnt (4) | leapcnt (4) |
|
||||||
// +---------------+---------------+---------------+
|
// +---------------+---------------+---------------+
|
||||||
// | timecnt (4) | typecnt (4) | charcnt (4) |
|
// | timecnt (4) | typecnt (4) | charcnt (4) |
|
||||||
func TzIf(raw []byte, limit uint32) bool {
|
func TzIf(raw []byte, limit uint32) bool {
|
||||||
// File is at least 44 bytes (header size).
|
// File is at least 44 bytes (header size).
|
||||||
if len(raw) < 44 {
|
if len(raw) < 44 {
|
||||||
|
|
4
vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go
generated
vendored
4
vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go
generated
vendored
|
@ -177,7 +177,9 @@ func newXMLSig(localName, xmlns string) xmlSig {
|
||||||
// and, optionally, followed by the arguments for the interpreter.
|
// and, optionally, followed by the arguments for the interpreter.
|
||||||
//
|
//
|
||||||
// Ex:
|
// Ex:
|
||||||
// #! /usr/bin/env php
|
//
|
||||||
|
// #! /usr/bin/env php
|
||||||
|
//
|
||||||
// /usr/bin/env is the interpreter, php is the first and only argument.
|
// /usr/bin/env is the interpreter, php is the first and only argument.
|
||||||
func shebang(sigs ...[]byte) Detector {
|
func shebang(sigs ...[]byte) Detector {
|
||||||
return func(raw []byte, limit uint32) bool {
|
return func(raw []byte, limit uint32) bool {
|
||||||
|
|
18
vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go
generated
vendored
18
vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go
generated
vendored
|
@ -3,6 +3,7 @@ package magic
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,12 +20,23 @@ func Tsv(raw []byte, limit uint32) bool {
|
||||||
func sv(in []byte, comma rune, limit uint32) bool {
|
func sv(in []byte, comma rune, limit uint32) bool {
|
||||||
r := csv.NewReader(dropLastLine(in, limit))
|
r := csv.NewReader(dropLastLine(in, limit))
|
||||||
r.Comma = comma
|
r.Comma = comma
|
||||||
r.TrimLeadingSpace = true
|
r.ReuseRecord = true
|
||||||
r.LazyQuotes = true
|
r.LazyQuotes = true
|
||||||
r.Comment = '#'
|
r.Comment = '#'
|
||||||
|
|
||||||
lines, err := r.ReadAll()
|
lines := 0
|
||||||
return err == nil && r.FieldsPerRecord > 1 && len(lines) > 1
|
for {
|
||||||
|
_, err := r.Read()
|
||||||
|
if errors.Is(err, io.EOF) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
lines++
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.FieldsPerRecord > 1 && lines > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// dropLastLine drops the last incomplete line from b.
|
// dropLastLine drops the last incomplete line from b.
|
||||||
|
|
3
vendor/github.com/gabriel-vasile/mimetype/mimetype.go
generated
vendored
3
vendor/github.com/gabriel-vasile/mimetype/mimetype.go
generated
vendored
|
@ -39,7 +39,8 @@ func Detect(in []byte) *MIME {
|
||||||
//
|
//
|
||||||
// DetectReader assumes the reader offset is at the start. If the input is an
|
// DetectReader assumes the reader offset is at the start. If the input is an
|
||||||
// io.ReadSeeker you previously read from, it should be rewinded before detection:
|
// io.ReadSeeker you previously read from, it should be rewinded before detection:
|
||||||
// reader.Seek(0, io.SeekStart)
|
//
|
||||||
|
// reader.Seek(0, io.SeekStart)
|
||||||
func DetectReader(r io.Reader) (*MIME, error) {
|
func DetectReader(r io.Reader) (*MIME, error) {
|
||||||
var in []byte
|
var in []byte
|
||||||
var err error
|
var err error
|
||||||
|
|
2
vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md
generated
vendored
2
vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
## 172 Supported MIME types
|
## 173 Supported MIME types
|
||||||
This file is automatically generated when running tests. Do not edit manually.
|
This file is automatically generated when running tests. Do not edit manually.
|
||||||
|
|
||||||
Extension | MIME type | Aliases
|
Extension | MIME type | Aliases
|
||||||
|
|
44
vendor/github.com/gin-contrib/cors/config.go
generated
vendored
44
vendor/github.com/gin-contrib/cors/config.go
generated
vendored
|
@ -8,14 +8,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type cors struct {
|
type cors struct {
|
||||||
allowAllOrigins bool
|
allowAllOrigins bool
|
||||||
allowCredentials bool
|
allowCredentials bool
|
||||||
allowOriginFunc func(string) bool
|
allowOriginFunc func(string) bool
|
||||||
allowOrigins []string
|
allowOriginWithContextFunc func(*gin.Context, string) bool
|
||||||
normalHeaders http.Header
|
allowOrigins []string
|
||||||
preflightHeaders http.Header
|
normalHeaders http.Header
|
||||||
wildcardOrigins [][]string
|
preflightHeaders http.Header
|
||||||
optionsResponseStatusCode int
|
wildcardOrigins [][]string
|
||||||
|
optionsResponseStatusCode int
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -54,14 +55,15 @@ func newCors(config Config) *cors {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &cors{
|
return &cors{
|
||||||
allowOriginFunc: config.AllowOriginFunc,
|
allowOriginFunc: config.AllowOriginFunc,
|
||||||
allowAllOrigins: config.AllowAllOrigins,
|
allowOriginWithContextFunc: config.AllowOriginWithContextFunc,
|
||||||
allowCredentials: config.AllowCredentials,
|
allowAllOrigins: config.AllowAllOrigins,
|
||||||
allowOrigins: normalize(config.AllowOrigins),
|
allowCredentials: config.AllowCredentials,
|
||||||
normalHeaders: generateNormalHeaders(config),
|
allowOrigins: normalize(config.AllowOrigins),
|
||||||
preflightHeaders: generatePreflightHeaders(config),
|
normalHeaders: generateNormalHeaders(config),
|
||||||
wildcardOrigins: config.parseWildcardRules(),
|
preflightHeaders: generatePreflightHeaders(config),
|
||||||
optionsResponseStatusCode: config.OptionsResponseStatusCode,
|
wildcardOrigins: config.parseWildcardRules(),
|
||||||
|
optionsResponseStatusCode: config.OptionsResponseStatusCode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +81,7 @@ func (cors *cors) applyCors(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cors.validateOrigin(origin) {
|
if !cors.isOriginValid(c, origin) {
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
c.AbortWithStatus(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -112,6 +114,14 @@ func (cors *cors) validateWildcardOrigin(origin string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cors *cors) isOriginValid(c *gin.Context, origin string) bool {
|
||||||
|
valid := cors.validateOrigin(origin)
|
||||||
|
if !valid && cors.allowOriginWithContextFunc != nil {
|
||||||
|
valid = cors.allowOriginWithContextFunc(c, origin)
|
||||||
|
}
|
||||||
|
return valid
|
||||||
|
}
|
||||||
|
|
||||||
func (cors *cors) validateOrigin(origin string) bool {
|
func (cors *cors) validateOrigin(origin string) bool {
|
||||||
if cors.allowAllOrigins {
|
if cors.allowAllOrigins {
|
||||||
return true
|
return true
|
||||||
|
|
32
vendor/github.com/gin-contrib/cors/cors.go
generated
vendored
32
vendor/github.com/gin-contrib/cors/cors.go
generated
vendored
|
@ -2,6 +2,7 @@ package cors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -22,6 +23,12 @@ type Config struct {
|
||||||
// set, the content of AllowOrigins is ignored.
|
// set, the content of AllowOrigins is ignored.
|
||||||
AllowOriginFunc func(origin string) bool
|
AllowOriginFunc func(origin string) bool
|
||||||
|
|
||||||
|
// Same as AllowOriginFunc except also receives the full request context.
|
||||||
|
// This function should use the context as a read only source and not
|
||||||
|
// have any side effects on the request, such as aborting or injecting
|
||||||
|
// values on the request.
|
||||||
|
AllowOriginWithContextFunc func(c *gin.Context, origin string) bool
|
||||||
|
|
||||||
// AllowMethods is a list of methods the client is allowed to use with
|
// AllowMethods is a list of methods the client is allowed to use with
|
||||||
// cross-domain requests. Default value is simple methods (GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS)
|
// cross-domain requests. Default value is simple methods (GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS)
|
||||||
AllowMethods []string
|
AllowMethods []string
|
||||||
|
@ -51,6 +58,9 @@ type Config struct {
|
||||||
// Allows usage of popular browser extensions schemas
|
// Allows usage of popular browser extensions schemas
|
||||||
AllowBrowserExtensions bool
|
AllowBrowserExtensions bool
|
||||||
|
|
||||||
|
// Allows to add custom schema like tauri://
|
||||||
|
CustomSchemas []string
|
||||||
|
|
||||||
// Allows usage of WebSocket protocol
|
// Allows usage of WebSocket protocol
|
||||||
AllowWebSockets bool
|
AllowWebSockets bool
|
||||||
|
|
||||||
|
@ -87,6 +97,9 @@ func (c Config) getAllowedSchemas() []string {
|
||||||
if c.AllowFiles {
|
if c.AllowFiles {
|
||||||
allowedSchemas = append(allowedSchemas, FileSchemas...)
|
allowedSchemas = append(allowedSchemas, FileSchemas...)
|
||||||
}
|
}
|
||||||
|
if c.CustomSchemas != nil {
|
||||||
|
allowedSchemas = append(allowedSchemas, c.CustomSchemas...)
|
||||||
|
}
|
||||||
return allowedSchemas
|
return allowedSchemas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +115,21 @@ func (c Config) validateAllowedSchemas(origin string) bool {
|
||||||
|
|
||||||
// Validate is check configuration of user defined.
|
// Validate is check configuration of user defined.
|
||||||
func (c Config) Validate() error {
|
func (c Config) Validate() error {
|
||||||
if c.AllowAllOrigins && (c.AllowOriginFunc != nil || len(c.AllowOrigins) > 0) {
|
hasOriginFn := c.AllowOriginFunc != nil
|
||||||
return errors.New("conflict settings: all origins are allowed. AllowOriginFunc or AllowOrigins is not needed")
|
hasOriginFn = hasOriginFn || c.AllowOriginWithContextFunc != nil
|
||||||
|
|
||||||
|
if c.AllowAllOrigins && (hasOriginFn || len(c.AllowOrigins) > 0) {
|
||||||
|
originFields := strings.Join([]string{
|
||||||
|
"AllowOriginFunc",
|
||||||
|
"AllowOriginFuncWithContext",
|
||||||
|
"AllowOrigins",
|
||||||
|
}, " or ")
|
||||||
|
return fmt.Errorf(
|
||||||
|
"conflict settings: all origins enabled. %s is not needed",
|
||||||
|
originFields,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if !c.AllowAllOrigins && c.AllowOriginFunc == nil && len(c.AllowOrigins) == 0 {
|
if !c.AllowAllOrigins && !hasOriginFn && len(c.AllowOrigins) == 0 {
|
||||||
return errors.New("conflict settings: all origins disabled")
|
return errors.New("conflict settings: all origins disabled")
|
||||||
}
|
}
|
||||||
for _, origin := range c.AllowOrigins {
|
for _, origin := range c.AllowOrigins {
|
||||||
|
@ -138,7 +162,7 @@ func (c Config) parseWildcardRules() [][]string {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if i == (len(o) - 1) {
|
if i == (len(o) - 1) {
|
||||||
wRules = append(wRules, []string{o[:i-1], "*"})
|
wRules = append(wRules, []string{o[:i], "*"})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
vendor/github.com/go-playground/validator/v10/Makefile
generated
vendored
2
vendor/github.com/go-playground/validator/v10/Makefile
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
GOCMD=GO111MODULE=on go
|
GOCMD=go
|
||||||
|
|
||||||
linters-install:
|
linters-install:
|
||||||
@golangci-lint --version >/dev/null 2>&1 || { \
|
@golangci-lint --version >/dev/null 2>&1 || { \
|
||||||
|
|
3
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
3
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
Package validator
|
Package validator
|
||||||
=================
|
=================
|
||||||
<img align="right" src="logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
<img align="right" src="logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
![Project status](https://img.shields.io/badge/version-10.15.4-green.svg)
|
![Project status](https://img.shields.io/badge/version-10.19.0-green.svg)
|
||||||
[![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator)
|
[![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator)
|
||||||
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
|
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
|
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
|
||||||
|
@ -178,6 +178,7 @@ validate := validator.New(validator.WithRequiredStructEnabled())
|
||||||
| isbn | International Standard Book Number |
|
| isbn | International Standard Book Number |
|
||||||
| isbn10 | International Standard Book Number 10 |
|
| isbn10 | International Standard Book Number 10 |
|
||||||
| isbn13 | International Standard Book Number 13 |
|
| isbn13 | International Standard Book Number 13 |
|
||||||
|
| issn | International Standard Serial Number |
|
||||||
| iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) |
|
| iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) |
|
||||||
| iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) |
|
| iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) |
|
||||||
| iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) |
|
| iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) |
|
||||||
|
|
61
vendor/github.com/go-playground/validator/v10/baked_in.go
generated
vendored
61
vendor/github.com/go-playground/validator/v10/baked_in.go
generated
vendored
|
@ -51,6 +51,7 @@ var (
|
||||||
endKeysTag: {},
|
endKeysTag: {},
|
||||||
structOnlyTag: {},
|
structOnlyTag: {},
|
||||||
omitempty: {},
|
omitempty: {},
|
||||||
|
omitnil: {},
|
||||||
skipValidationTag: {},
|
skipValidationTag: {},
|
||||||
utf8HexComma: {},
|
utf8HexComma: {},
|
||||||
utf8Pipe: {},
|
utf8Pipe: {},
|
||||||
|
@ -149,6 +150,7 @@ var (
|
||||||
"isbn": isISBN,
|
"isbn": isISBN,
|
||||||
"isbn10": isISBN10,
|
"isbn10": isISBN10,
|
||||||
"isbn13": isISBN13,
|
"isbn13": isISBN13,
|
||||||
|
"issn": isISSN,
|
||||||
"eth_addr": isEthereumAddress,
|
"eth_addr": isEthereumAddress,
|
||||||
"eth_addr_checksum": isEthereumAddressChecksum,
|
"eth_addr_checksum": isEthereumAddressChecksum,
|
||||||
"btc_addr": isBitcoinAddress,
|
"btc_addr": isBitcoinAddress,
|
||||||
|
@ -508,47 +510,47 @@ func isASCII(fl FieldLevel) bool {
|
||||||
|
|
||||||
// isUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
|
// isUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
|
||||||
func isUUID5(fl FieldLevel) bool {
|
func isUUID5(fl FieldLevel) bool {
|
||||||
return uUID5Regex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uUID5Regex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
|
// isUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
|
||||||
func isUUID4(fl FieldLevel) bool {
|
func isUUID4(fl FieldLevel) bool {
|
||||||
return uUID4Regex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uUID4Regex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
|
// isUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
|
||||||
func isUUID3(fl FieldLevel) bool {
|
func isUUID3(fl FieldLevel) bool {
|
||||||
return uUID3Regex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uUID3Regex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUUID is the validation function for validating if the field's value is a valid UUID of any version.
|
// isUUID is the validation function for validating if the field's value is a valid UUID of any version.
|
||||||
func isUUID(fl FieldLevel) bool {
|
func isUUID(fl FieldLevel) bool {
|
||||||
return uUIDRegex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uUIDRegex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
|
// isUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
|
||||||
func isUUID5RFC4122(fl FieldLevel) bool {
|
func isUUID5RFC4122(fl FieldLevel) bool {
|
||||||
return uUID5RFC4122Regex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uUID5RFC4122Regex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
|
// isUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
|
||||||
func isUUID4RFC4122(fl FieldLevel) bool {
|
func isUUID4RFC4122(fl FieldLevel) bool {
|
||||||
return uUID4RFC4122Regex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uUID4RFC4122Regex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
|
// isUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
|
||||||
func isUUID3RFC4122(fl FieldLevel) bool {
|
func isUUID3RFC4122(fl FieldLevel) bool {
|
||||||
return uUID3RFC4122Regex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uUID3RFC4122Regex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
|
// isUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
|
||||||
func isUUIDRFC4122(fl FieldLevel) bool {
|
func isUUIDRFC4122(fl FieldLevel) bool {
|
||||||
return uUIDRFC4122Regex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uUIDRFC4122Regex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isULID is the validation function for validating if the field's value is a valid ULID.
|
// isULID is the validation function for validating if the field's value is a valid ULID.
|
||||||
func isULID(fl FieldLevel) bool {
|
func isULID(fl FieldLevel) bool {
|
||||||
return uLIDRegex.MatchString(fl.Field().String())
|
return fieldMatchesRegexByStringerValOrString(uLIDRegex, fl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isMD4 is the validation function for validating if the field's value is a valid MD4.
|
// isMD4 is the validation function for validating if the field's value is a valid MD4.
|
||||||
|
@ -650,6 +652,32 @@ func isISBN10(fl FieldLevel) bool {
|
||||||
return checksum%11 == 0
|
return checksum%11 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isISSN is the validation function for validating if the field's value is a valid ISSN.
|
||||||
|
func isISSN(fl FieldLevel) bool {
|
||||||
|
s := fl.Field().String()
|
||||||
|
|
||||||
|
if !iSSNRegex.MatchString(s) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
s = strings.ReplaceAll(s, "-", "")
|
||||||
|
|
||||||
|
pos := 8
|
||||||
|
checksum := 0
|
||||||
|
|
||||||
|
for i := 0; i < 7; i++ {
|
||||||
|
checksum += pos * int(s[i]-'0')
|
||||||
|
pos--
|
||||||
|
}
|
||||||
|
|
||||||
|
if s[7] == 'X' {
|
||||||
|
checksum += 10
|
||||||
|
} else {
|
||||||
|
checksum += int(s[7] - '0')
|
||||||
|
}
|
||||||
|
|
||||||
|
return checksum%11 == 0
|
||||||
|
}
|
||||||
|
|
||||||
// isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address.
|
// isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address.
|
||||||
func isEthereumAddress(fl FieldLevel) bool {
|
func isEthereumAddress(fl FieldLevel) bool {
|
||||||
address := fl.Field().String()
|
address := fl.Field().String()
|
||||||
|
@ -1413,6 +1441,15 @@ func isURI(fl FieldLevel) bool {
|
||||||
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isFileURL is the helper function for validating if the `path` valid file URL as per RFC8089
|
||||||
|
func isFileURL(path string) bool {
|
||||||
|
if !strings.HasPrefix(path, "file:/") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, err := url.ParseRequestURI(path)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
// isURL is the validation function for validating if the current field's value is a valid URL.
|
// isURL is the validation function for validating if the current field's value is a valid URL.
|
||||||
func isURL(fl FieldLevel) bool {
|
func isURL(fl FieldLevel) bool {
|
||||||
field := fl.Field()
|
field := fl.Field()
|
||||||
|
@ -1420,12 +1457,16 @@ func isURL(fl FieldLevel) bool {
|
||||||
switch field.Kind() {
|
switch field.Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
|
|
||||||
s := field.String()
|
s := strings.ToLower(field.String())
|
||||||
|
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isFileURL(s) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
url, err := url.Parse(s)
|
url, err := url.Parse(s)
|
||||||
if err != nil || url.Scheme == "" {
|
if err != nil || url.Scheme == "" {
|
||||||
return false
|
return false
|
||||||
|
|
7
vendor/github.com/go-playground/validator/v10/cache.go
generated
vendored
7
vendor/github.com/go-playground/validator/v10/cache.go
generated
vendored
|
@ -20,6 +20,7 @@ const (
|
||||||
typeOr
|
typeOr
|
||||||
typeKeys
|
typeKeys
|
||||||
typeEndKeys
|
typeEndKeys
|
||||||
|
typeOmitNil
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -125,7 +126,7 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr
|
||||||
|
|
||||||
fld = typ.Field(i)
|
fld = typ.Field(i)
|
||||||
|
|
||||||
if !fld.Anonymous && len(fld.PkgPath) > 0 {
|
if !v.privateFieldValidation && !fld.Anonymous && len(fld.PkgPath) > 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +253,10 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s
|
||||||
current.typeof = typeOmitEmpty
|
current.typeof = typeOmitEmpty
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
case omitnil:
|
||||||
|
current.typeof = typeOmitNil
|
||||||
|
continue
|
||||||
|
|
||||||
case structOnlyTag:
|
case structOnlyTag:
|
||||||
current.typeof = typeStructOnly
|
current.typeof = typeStructOnly
|
||||||
continue
|
continue
|
||||||
|
|
7
vendor/github.com/go-playground/validator/v10/doc.go
generated
vendored
7
vendor/github.com/go-playground/validator/v10/doc.go
generated
vendored
|
@ -194,6 +194,13 @@ such as min or max won't run, but if a value is set validation will run.
|
||||||
|
|
||||||
Usage: omitempty
|
Usage: omitempty
|
||||||
|
|
||||||
|
# Omit Nil
|
||||||
|
|
||||||
|
Allows to skip the validation if the value is nil (same as omitempty, but
|
||||||
|
only for the nil-values).
|
||||||
|
|
||||||
|
Usage: omitnil
|
||||||
|
|
||||||
# Dive
|
# Dive
|
||||||
|
|
||||||
This tells the validator to dive into a slice, array or map and validate that
|
This tells the validator to dive into a slice, array or map and validate that
|
||||||
|
|
8
vendor/github.com/go-playground/validator/v10/errors.go
generated
vendored
8
vendor/github.com/go-playground/validator/v10/errors.go
generated
vendored
|
@ -257,15 +257,19 @@ func (fe *fieldError) Error() string {
|
||||||
// NOTE: if no registered translation can be found, it returns the original
|
// NOTE: if no registered translation can be found, it returns the original
|
||||||
// untranslated error message.
|
// untranslated error message.
|
||||||
func (fe *fieldError) Translate(ut ut.Translator) string {
|
func (fe *fieldError) Translate(ut ut.Translator) string {
|
||||||
|
var fn TranslationFunc
|
||||||
|
|
||||||
m, ok := fe.v.transTagFunc[ut]
|
m, ok := fe.v.transTagFunc[ut]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fe.Error()
|
return fe.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn, ok := m[fe.tag]
|
fn, ok = m[fe.tag]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fe.Error()
|
fn, ok = m[fe.actualTag]
|
||||||
|
if !ok {
|
||||||
|
return fe.Error()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fn(ut, fe)
|
return fn(ut, fe)
|
||||||
|
|
10
vendor/github.com/go-playground/validator/v10/options.go
generated
vendored
10
vendor/github.com/go-playground/validator/v10/options.go
generated
vendored
|
@ -14,3 +14,13 @@ func WithRequiredStructEnabled() Option {
|
||||||
v.requiredStructEnabled = true
|
v.requiredStructEnabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithPrivateFieldValidation activates validation for unexported fields via the use of the `unsafe` package.
|
||||||
|
//
|
||||||
|
// By opting into this feature you are acknowledging that you are aware of the risks and accept any current or future
|
||||||
|
// consequences of using this feature.
|
||||||
|
func WithPrivateFieldValidation() Option {
|
||||||
|
return func(v *Validate) {
|
||||||
|
v.privateFieldValidation = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2
vendor/github.com/go-playground/validator/v10/regexes.go
generated
vendored
2
vendor/github.com/go-playground/validator/v10/regexes.go
generated
vendored
|
@ -22,6 +22,7 @@ const (
|
||||||
base64RawURLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2,4})$"
|
base64RawURLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2,4})$"
|
||||||
iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
|
iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
|
||||||
iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
|
iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
|
||||||
|
iSSNRegexString = "^(?:[0-9]{4}-[0-9]{3}[0-9X])$"
|
||||||
uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
||||||
uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
||||||
uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
||||||
|
@ -93,6 +94,7 @@ var (
|
||||||
base64RawURLRegex = regexp.MustCompile(base64RawURLRegexString)
|
base64RawURLRegex = regexp.MustCompile(base64RawURLRegexString)
|
||||||
iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
|
iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
|
||||||
iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
|
iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
|
||||||
|
iSSNRegex = regexp.MustCompile(iSSNRegexString)
|
||||||
uUID3Regex = regexp.MustCompile(uUID3RegexString)
|
uUID3Regex = regexp.MustCompile(uUID3RegexString)
|
||||||
uUID4Regex = regexp.MustCompile(uUID4RegexString)
|
uUID4Regex = regexp.MustCompile(uUID4RegexString)
|
||||||
uUID5Regex = regexp.MustCompile(uUID5RegexString)
|
uUID5Regex = regexp.MustCompile(uUID5RegexString)
|
||||||
|
|
17
vendor/github.com/go-playground/validator/v10/util.go
generated
vendored
17
vendor/github.com/go-playground/validator/v10/util.go
generated
vendored
|
@ -1,7 +1,9 @@
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -292,3 +294,18 @@ func panicIf(err error) {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if field value matches regex. If fl.Field can be cast to Stringer, it uses the Stringer interfaces
|
||||||
|
// String() return value. Otherwise, it uses fl.Field's String() value.
|
||||||
|
func fieldMatchesRegexByStringerValOrString(regex *regexp.Regexp, fl FieldLevel) bool {
|
||||||
|
switch fl.Field().Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return regex.MatchString(fl.Field().String())
|
||||||
|
default:
|
||||||
|
if stringer, ok := fl.Field().Interface().(fmt.Stringer); ok {
|
||||||
|
return regex.MatchString(stringer.String())
|
||||||
|
} else {
|
||||||
|
return regex.MatchString(fl.Field().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
56
vendor/github.com/go-playground/validator/v10/validator.go
generated
vendored
56
vendor/github.com/go-playground/validator/v10/validator.go
generated
vendored
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// per validate construct
|
// per validate construct
|
||||||
|
@ -112,6 +113,10 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ct.typeof == typeOmitNil && (kind != reflect.Invalid && current.IsNil()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ct.hasTag {
|
if ct.hasTag {
|
||||||
if kind == reflect.Invalid {
|
if kind == reflect.Invalid {
|
||||||
v.str1 = string(append(ns, cf.altName...))
|
v.str1 = string(append(ns, cf.altName...))
|
||||||
|
@ -152,7 +157,7 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
|
||||||
structNs: v.str2,
|
structNs: v.str2,
|
||||||
fieldLen: uint8(len(cf.altName)),
|
fieldLen: uint8(len(cf.altName)),
|
||||||
structfieldLen: uint8(len(cf.name)),
|
structfieldLen: uint8(len(cf.name)),
|
||||||
value: current.Interface(),
|
value: getValue(current),
|
||||||
param: ct.param,
|
param: ct.param,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
typ: current.Type(),
|
typ: current.Type(),
|
||||||
|
@ -233,6 +238,26 @@ OUTER:
|
||||||
ct = ct.next
|
ct = ct.next
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
case typeOmitNil:
|
||||||
|
v.slflParent = parent
|
||||||
|
v.flField = current
|
||||||
|
v.cf = cf
|
||||||
|
v.ct = ct
|
||||||
|
|
||||||
|
switch field := v.Field(); field.Kind() {
|
||||||
|
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
|
||||||
|
if field.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if v.fldIsPointer && field.Interface() == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ct = ct.next
|
||||||
|
continue
|
||||||
|
|
||||||
case typeEndKeys:
|
case typeEndKeys:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -386,7 +411,7 @@ OUTER:
|
||||||
structNs: v.str2,
|
structNs: v.str2,
|
||||||
fieldLen: uint8(len(cf.altName)),
|
fieldLen: uint8(len(cf.altName)),
|
||||||
structfieldLen: uint8(len(cf.name)),
|
structfieldLen: uint8(len(cf.name)),
|
||||||
value: current.Interface(),
|
value: getValue(current),
|
||||||
param: ct.param,
|
param: ct.param,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
typ: typ,
|
typ: typ,
|
||||||
|
@ -406,7 +431,7 @@ OUTER:
|
||||||
structNs: v.str2,
|
structNs: v.str2,
|
||||||
fieldLen: uint8(len(cf.altName)),
|
fieldLen: uint8(len(cf.altName)),
|
||||||
structfieldLen: uint8(len(cf.name)),
|
structfieldLen: uint8(len(cf.name)),
|
||||||
value: current.Interface(),
|
value: getValue(current),
|
||||||
param: ct.param,
|
param: ct.param,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
typ: typ,
|
typ: typ,
|
||||||
|
@ -446,7 +471,7 @@ OUTER:
|
||||||
structNs: v.str2,
|
structNs: v.str2,
|
||||||
fieldLen: uint8(len(cf.altName)),
|
fieldLen: uint8(len(cf.altName)),
|
||||||
structfieldLen: uint8(len(cf.name)),
|
structfieldLen: uint8(len(cf.name)),
|
||||||
value: current.Interface(),
|
value: getValue(current),
|
||||||
param: ct.param,
|
param: ct.param,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
typ: typ,
|
typ: typ,
|
||||||
|
@ -460,3 +485,26 @@ OUTER:
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getValue(val reflect.Value) interface{} {
|
||||||
|
if val.CanInterface() {
|
||||||
|
return val.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.CanAddr() {
|
||||||
|
return reflect.NewAt(val.Type(), unsafe.Pointer(val.UnsafeAddr())).Elem().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch val.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return val.Int()
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return val.Uint()
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return val.Complex()
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return val.Float()
|
||||||
|
default:
|
||||||
|
return val.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
30
vendor/github.com/go-playground/validator/v10/validator_instance.go
generated
vendored
30
vendor/github.com/go-playground/validator/v10/validator_instance.go
generated
vendored
|
@ -22,6 +22,7 @@ const (
|
||||||
structOnlyTag = "structonly"
|
structOnlyTag = "structonly"
|
||||||
noStructLevelTag = "nostructlevel"
|
noStructLevelTag = "nostructlevel"
|
||||||
omitempty = "omitempty"
|
omitempty = "omitempty"
|
||||||
|
omitnil = "omitnil"
|
||||||
isdefault = "isdefault"
|
isdefault = "isdefault"
|
||||||
requiredWithoutAllTag = "required_without_all"
|
requiredWithoutAllTag = "required_without_all"
|
||||||
requiredWithoutTag = "required_without"
|
requiredWithoutTag = "required_without"
|
||||||
|
@ -79,20 +80,21 @@ type internalValidationFuncWrapper struct {
|
||||||
|
|
||||||
// Validate contains the validator settings and cache
|
// Validate contains the validator settings and cache
|
||||||
type Validate struct {
|
type Validate struct {
|
||||||
tagName string
|
tagName string
|
||||||
pool *sync.Pool
|
pool *sync.Pool
|
||||||
tagNameFunc TagNameFunc
|
tagNameFunc TagNameFunc
|
||||||
structLevelFuncs map[reflect.Type]StructLevelFuncCtx
|
structLevelFuncs map[reflect.Type]StructLevelFuncCtx
|
||||||
customFuncs map[reflect.Type]CustomTypeFunc
|
customFuncs map[reflect.Type]CustomTypeFunc
|
||||||
aliases map[string]string
|
aliases map[string]string
|
||||||
validations map[string]internalValidationFuncWrapper
|
validations map[string]internalValidationFuncWrapper
|
||||||
transTagFunc map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
|
transTagFunc map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
|
||||||
rules map[reflect.Type]map[string]string
|
rules map[reflect.Type]map[string]string
|
||||||
tagCache *tagCache
|
tagCache *tagCache
|
||||||
structCache *structCache
|
structCache *structCache
|
||||||
hasCustomFuncs bool
|
hasCustomFuncs bool
|
||||||
hasTagNameFunc bool
|
hasTagNameFunc bool
|
||||||
requiredStructEnabled bool
|
requiredStructEnabled bool
|
||||||
|
privateFieldValidation bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new instance of 'validate' with sane defaults.
|
// New returns a new instance of 'validate' with sane defaults.
|
||||||
|
|
427
vendor/github.com/klauspost/cpuid/v2/cpuid.go
generated
vendored
427
vendor/github.com/klauspost/cpuid/v2/cpuid.go
generated
vendored
|
@ -67,195 +67,200 @@ const (
|
||||||
// Keep index -1 as unknown
|
// Keep index -1 as unknown
|
||||||
UNKNOWN = -1
|
UNKNOWN = -1
|
||||||
|
|
||||||
// Add features
|
// x86 features
|
||||||
ADX FeatureID = iota // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
|
ADX FeatureID = iota // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
|
||||||
AESNI // Advanced Encryption Standard New Instructions
|
AESNI // Advanced Encryption Standard New Instructions
|
||||||
AMD3DNOW // AMD 3DNOW
|
AMD3DNOW // AMD 3DNOW
|
||||||
AMD3DNOWEXT // AMD 3DNowExt
|
AMD3DNOWEXT // AMD 3DNowExt
|
||||||
AMXBF16 // Tile computational operations on BFLOAT16 numbers
|
AMXBF16 // Tile computational operations on BFLOAT16 numbers
|
||||||
AMXFP16 // Tile computational operations on FP16 numbers
|
AMXFP16 // Tile computational operations on FP16 numbers
|
||||||
AMXINT8 // Tile computational operations on 8-bit integers
|
AMXINT8 // Tile computational operations on 8-bit integers
|
||||||
AMXTILE // Tile architecture
|
AMXTILE // Tile architecture
|
||||||
APX_F // Intel APX
|
APX_F // Intel APX
|
||||||
AVX // AVX functions
|
AVX // AVX functions
|
||||||
AVX10 // If set the Intel AVX10 Converged Vector ISA is supported
|
AVX10 // If set the Intel AVX10 Converged Vector ISA is supported
|
||||||
AVX10_128 // If set indicates that AVX10 128-bit vector support is present
|
AVX10_128 // If set indicates that AVX10 128-bit vector support is present
|
||||||
AVX10_256 // If set indicates that AVX10 256-bit vector support is present
|
AVX10_256 // If set indicates that AVX10 256-bit vector support is present
|
||||||
AVX10_512 // If set indicates that AVX10 512-bit vector support is present
|
AVX10_512 // If set indicates that AVX10 512-bit vector support is present
|
||||||
AVX2 // AVX2 functions
|
AVX2 // AVX2 functions
|
||||||
AVX512BF16 // AVX-512 BFLOAT16 Instructions
|
AVX512BF16 // AVX-512 BFLOAT16 Instructions
|
||||||
AVX512BITALG // AVX-512 Bit Algorithms
|
AVX512BITALG // AVX-512 Bit Algorithms
|
||||||
AVX512BW // AVX-512 Byte and Word Instructions
|
AVX512BW // AVX-512 Byte and Word Instructions
|
||||||
AVX512CD // AVX-512 Conflict Detection Instructions
|
AVX512CD // AVX-512 Conflict Detection Instructions
|
||||||
AVX512DQ // AVX-512 Doubleword and Quadword Instructions
|
AVX512DQ // AVX-512 Doubleword and Quadword Instructions
|
||||||
AVX512ER // AVX-512 Exponential and Reciprocal Instructions
|
AVX512ER // AVX-512 Exponential and Reciprocal Instructions
|
||||||
AVX512F // AVX-512 Foundation
|
AVX512F // AVX-512 Foundation
|
||||||
AVX512FP16 // AVX-512 FP16 Instructions
|
AVX512FP16 // AVX-512 FP16 Instructions
|
||||||
AVX512IFMA // AVX-512 Integer Fused Multiply-Add Instructions
|
AVX512IFMA // AVX-512 Integer Fused Multiply-Add Instructions
|
||||||
AVX512PF // AVX-512 Prefetch Instructions
|
AVX512PF // AVX-512 Prefetch Instructions
|
||||||
AVX512VBMI // AVX-512 Vector Bit Manipulation Instructions
|
AVX512VBMI // AVX-512 Vector Bit Manipulation Instructions
|
||||||
AVX512VBMI2 // AVX-512 Vector Bit Manipulation Instructions, Version 2
|
AVX512VBMI2 // AVX-512 Vector Bit Manipulation Instructions, Version 2
|
||||||
AVX512VL // AVX-512 Vector Length Extensions
|
AVX512VL // AVX-512 Vector Length Extensions
|
||||||
AVX512VNNI // AVX-512 Vector Neural Network Instructions
|
AVX512VNNI // AVX-512 Vector Neural Network Instructions
|
||||||
AVX512VP2INTERSECT // AVX-512 Intersect for D/Q
|
AVX512VP2INTERSECT // AVX-512 Intersect for D/Q
|
||||||
AVX512VPOPCNTDQ // AVX-512 Vector Population Count Doubleword and Quadword
|
AVX512VPOPCNTDQ // AVX-512 Vector Population Count Doubleword and Quadword
|
||||||
AVXIFMA // AVX-IFMA instructions
|
AVXIFMA // AVX-IFMA instructions
|
||||||
AVXNECONVERT // AVX-NE-CONVERT instructions
|
AVXNECONVERT // AVX-NE-CONVERT instructions
|
||||||
AVXSLOW // Indicates the CPU performs 2 128 bit operations instead of one
|
AVXSLOW // Indicates the CPU performs 2 128 bit operations instead of one
|
||||||
AVXVNNI // AVX (VEX encoded) VNNI neural network instructions
|
AVXVNNI // AVX (VEX encoded) VNNI neural network instructions
|
||||||
AVXVNNIINT8 // AVX-VNNI-INT8 instructions
|
AVXVNNIINT8 // AVX-VNNI-INT8 instructions
|
||||||
BHI_CTRL // Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598
|
BHI_CTRL // Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598
|
||||||
BMI1 // Bit Manipulation Instruction Set 1
|
BMI1 // Bit Manipulation Instruction Set 1
|
||||||
BMI2 // Bit Manipulation Instruction Set 2
|
BMI2 // Bit Manipulation Instruction Set 2
|
||||||
CETIBT // Intel CET Indirect Branch Tracking
|
CETIBT // Intel CET Indirect Branch Tracking
|
||||||
CETSS // Intel CET Shadow Stack
|
CETSS // Intel CET Shadow Stack
|
||||||
CLDEMOTE // Cache Line Demote
|
CLDEMOTE // Cache Line Demote
|
||||||
CLMUL // Carry-less Multiplication
|
CLMUL // Carry-less Multiplication
|
||||||
CLZERO // CLZERO instruction supported
|
CLZERO // CLZERO instruction supported
|
||||||
CMOV // i686 CMOV
|
CMOV // i686 CMOV
|
||||||
CMPCCXADD // CMPCCXADD instructions
|
CMPCCXADD // CMPCCXADD instructions
|
||||||
CMPSB_SCADBS_SHORT // Fast short CMPSB and SCASB
|
CMPSB_SCADBS_SHORT // Fast short CMPSB and SCASB
|
||||||
CMPXCHG8 // CMPXCHG8 instruction
|
CMPXCHG8 // CMPXCHG8 instruction
|
||||||
CPBOOST // Core Performance Boost
|
CPBOOST // Core Performance Boost
|
||||||
CPPC // AMD: Collaborative Processor Performance Control
|
CPPC // AMD: Collaborative Processor Performance Control
|
||||||
CX16 // CMPXCHG16B Instruction
|
CX16 // CMPXCHG16B Instruction
|
||||||
EFER_LMSLE_UNS // AMD: =Core::X86::Msr::EFER[LMSLE] is not supported, and MBZ
|
EFER_LMSLE_UNS // AMD: =Core::X86::Msr::EFER[LMSLE] is not supported, and MBZ
|
||||||
ENQCMD // Enqueue Command
|
ENQCMD // Enqueue Command
|
||||||
ERMS // Enhanced REP MOVSB/STOSB
|
ERMS // Enhanced REP MOVSB/STOSB
|
||||||
F16C // Half-precision floating-point conversion
|
F16C // Half-precision floating-point conversion
|
||||||
FLUSH_L1D // Flush L1D cache
|
FLUSH_L1D // Flush L1D cache
|
||||||
FMA3 // Intel FMA 3. Does not imply AVX.
|
FMA3 // Intel FMA 3. Does not imply AVX.
|
||||||
FMA4 // Bulldozer FMA4 functions
|
FMA4 // Bulldozer FMA4 functions
|
||||||
FP128 // AMD: When set, the internal FP/SIMD execution datapath is no more than 128-bits wide
|
FP128 // AMD: When set, the internal FP/SIMD execution datapath is no more than 128-bits wide
|
||||||
FP256 // AMD: When set, the internal FP/SIMD execution datapath is no more than 256-bits wide
|
FP256 // AMD: When set, the internal FP/SIMD execution datapath is no more than 256-bits wide
|
||||||
FSRM // Fast Short Rep Mov
|
FSRM // Fast Short Rep Mov
|
||||||
FXSR // FXSAVE, FXRESTOR instructions, CR4 bit 9
|
FXSR // FXSAVE, FXRESTOR instructions, CR4 bit 9
|
||||||
FXSROPT // FXSAVE/FXRSTOR optimizations
|
FXSROPT // FXSAVE/FXRSTOR optimizations
|
||||||
GFNI // Galois Field New Instructions. May require other features (AVX, AVX512VL,AVX512F) based on usage.
|
GFNI // Galois Field New Instructions. May require other features (AVX, AVX512VL,AVX512F) based on usage.
|
||||||
HLE // Hardware Lock Elision
|
HLE // Hardware Lock Elision
|
||||||
HRESET // If set CPU supports history reset and the IA32_HRESET_ENABLE MSR
|
HRESET // If set CPU supports history reset and the IA32_HRESET_ENABLE MSR
|
||||||
HTT // Hyperthreading (enabled)
|
HTT // Hyperthreading (enabled)
|
||||||
HWA // Hardware assert supported. Indicates support for MSRC001_10
|
HWA // Hardware assert supported. Indicates support for MSRC001_10
|
||||||
HYBRID_CPU // This part has CPUs of more than one type.
|
HYBRID_CPU // This part has CPUs of more than one type.
|
||||||
HYPERVISOR // This bit has been reserved by Intel & AMD for use by hypervisors
|
HYPERVISOR // This bit has been reserved by Intel & AMD for use by hypervisors
|
||||||
IA32_ARCH_CAP // IA32_ARCH_CAPABILITIES MSR (Intel)
|
IA32_ARCH_CAP // IA32_ARCH_CAPABILITIES MSR (Intel)
|
||||||
IA32_CORE_CAP // IA32_CORE_CAPABILITIES MSR
|
IA32_CORE_CAP // IA32_CORE_CAPABILITIES MSR
|
||||||
IBPB // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB)
|
IBPB // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB)
|
||||||
IBRS // AMD: Indirect Branch Restricted Speculation
|
IBPB_BRTYPE // Indicates that MSR 49h (PRED_CMD) bit 0 (IBPB) flushes all branch type predictions from the CPU branch predictor
|
||||||
IBRS_PREFERRED // AMD: IBRS is preferred over software solution
|
IBRS // AMD: Indirect Branch Restricted Speculation
|
||||||
IBRS_PROVIDES_SMP // AMD: IBRS provides Same Mode Protection
|
IBRS_PREFERRED // AMD: IBRS is preferred over software solution
|
||||||
IBS // Instruction Based Sampling (AMD)
|
IBRS_PROVIDES_SMP // AMD: IBRS provides Same Mode Protection
|
||||||
IBSBRNTRGT // Instruction Based Sampling Feature (AMD)
|
IBS // Instruction Based Sampling (AMD)
|
||||||
IBSFETCHSAM // Instruction Based Sampling Feature (AMD)
|
IBSBRNTRGT // Instruction Based Sampling Feature (AMD)
|
||||||
IBSFFV // Instruction Based Sampling Feature (AMD)
|
IBSFETCHSAM // Instruction Based Sampling Feature (AMD)
|
||||||
IBSOPCNT // Instruction Based Sampling Feature (AMD)
|
IBSFFV // Instruction Based Sampling Feature (AMD)
|
||||||
IBSOPCNTEXT // Instruction Based Sampling Feature (AMD)
|
IBSOPCNT // Instruction Based Sampling Feature (AMD)
|
||||||
IBSOPSAM // Instruction Based Sampling Feature (AMD)
|
IBSOPCNTEXT // Instruction Based Sampling Feature (AMD)
|
||||||
IBSRDWROPCNT // Instruction Based Sampling Feature (AMD)
|
IBSOPSAM // Instruction Based Sampling Feature (AMD)
|
||||||
IBSRIPINVALIDCHK // Instruction Based Sampling Feature (AMD)
|
IBSRDWROPCNT // Instruction Based Sampling Feature (AMD)
|
||||||
IBS_FETCH_CTLX // AMD: IBS fetch control extended MSR supported
|
IBSRIPINVALIDCHK // Instruction Based Sampling Feature (AMD)
|
||||||
IBS_OPDATA4 // AMD: IBS op data 4 MSR supported
|
IBS_FETCH_CTLX // AMD: IBS fetch control extended MSR supported
|
||||||
IBS_OPFUSE // AMD: Indicates support for IbsOpFuse
|
IBS_OPDATA4 // AMD: IBS op data 4 MSR supported
|
||||||
IBS_PREVENTHOST // Disallowing IBS use by the host supported
|
IBS_OPFUSE // AMD: Indicates support for IbsOpFuse
|
||||||
IBS_ZEN4 // AMD: Fetch and Op IBS support IBS extensions added with Zen4
|
IBS_PREVENTHOST // Disallowing IBS use by the host supported
|
||||||
IDPRED_CTRL // IPRED_DIS
|
IBS_ZEN4 // AMD: Fetch and Op IBS support IBS extensions added with Zen4
|
||||||
INT_WBINVD // WBINVD/WBNOINVD are interruptible.
|
IDPRED_CTRL // IPRED_DIS
|
||||||
INVLPGB // NVLPGB and TLBSYNC instruction supported
|
INT_WBINVD // WBINVD/WBNOINVD are interruptible.
|
||||||
KEYLOCKER // Key locker
|
INVLPGB // NVLPGB and TLBSYNC instruction supported
|
||||||
KEYLOCKERW // Key locker wide
|
KEYLOCKER // Key locker
|
||||||
LAHF // LAHF/SAHF in long mode
|
KEYLOCKERW // Key locker wide
|
||||||
LAM // If set, CPU supports Linear Address Masking
|
LAHF // LAHF/SAHF in long mode
|
||||||
LBRVIRT // LBR virtualization
|
LAM // If set, CPU supports Linear Address Masking
|
||||||
LZCNT // LZCNT instruction
|
LBRVIRT // LBR virtualization
|
||||||
MCAOVERFLOW // MCA overflow recovery support.
|
LZCNT // LZCNT instruction
|
||||||
MCDT_NO // Processor do not exhibit MXCSR Configuration Dependent Timing behavior and do not need to mitigate it.
|
MCAOVERFLOW // MCA overflow recovery support.
|
||||||
MCOMMIT // MCOMMIT instruction supported
|
MCDT_NO // Processor do not exhibit MXCSR Configuration Dependent Timing behavior and do not need to mitigate it.
|
||||||
MD_CLEAR // VERW clears CPU buffers
|
MCOMMIT // MCOMMIT instruction supported
|
||||||
MMX // standard MMX
|
MD_CLEAR // VERW clears CPU buffers
|
||||||
MMXEXT // SSE integer functions or AMD MMX ext
|
MMX // standard MMX
|
||||||
MOVBE // MOVBE instruction (big-endian)
|
MMXEXT // SSE integer functions or AMD MMX ext
|
||||||
MOVDIR64B // Move 64 Bytes as Direct Store
|
MOVBE // MOVBE instruction (big-endian)
|
||||||
MOVDIRI // Move Doubleword as Direct Store
|
MOVDIR64B // Move 64 Bytes as Direct Store
|
||||||
MOVSB_ZL // Fast Zero-Length MOVSB
|
MOVDIRI // Move Doubleword as Direct Store
|
||||||
MOVU // AMD: MOVU SSE instructions are more efficient and should be preferred to SSE MOVL/MOVH. MOVUPS is more efficient than MOVLPS/MOVHPS. MOVUPD is more efficient than MOVLPD/MOVHPD
|
MOVSB_ZL // Fast Zero-Length MOVSB
|
||||||
MPX // Intel MPX (Memory Protection Extensions)
|
MOVU // AMD: MOVU SSE instructions are more efficient and should be preferred to SSE MOVL/MOVH. MOVUPS is more efficient than MOVLPS/MOVHPS. MOVUPD is more efficient than MOVLPD/MOVHPD
|
||||||
MSRIRC // Instruction Retired Counter MSR available
|
MPX // Intel MPX (Memory Protection Extensions)
|
||||||
MSRLIST // Read/Write List of Model Specific Registers
|
MSRIRC // Instruction Retired Counter MSR available
|
||||||
MSR_PAGEFLUSH // Page Flush MSR available
|
MSRLIST // Read/Write List of Model Specific Registers
|
||||||
NRIPS // Indicates support for NRIP save on VMEXIT
|
MSR_PAGEFLUSH // Page Flush MSR available
|
||||||
NX // NX (No-Execute) bit
|
NRIPS // Indicates support for NRIP save on VMEXIT
|
||||||
OSXSAVE // XSAVE enabled by OS
|
NX // NX (No-Execute) bit
|
||||||
PCONFIG // PCONFIG for Intel Multi-Key Total Memory Encryption
|
OSXSAVE // XSAVE enabled by OS
|
||||||
POPCNT // POPCNT instruction
|
PCONFIG // PCONFIG for Intel Multi-Key Total Memory Encryption
|
||||||
PPIN // AMD: Protected Processor Inventory Number support. Indicates that Protected Processor Inventory Number (PPIN) capability can be enabled
|
POPCNT // POPCNT instruction
|
||||||
PREFETCHI // PREFETCHIT0/1 instructions
|
PPIN // AMD: Protected Processor Inventory Number support. Indicates that Protected Processor Inventory Number (PPIN) capability can be enabled
|
||||||
PSFD // Predictive Store Forward Disable
|
PREFETCHI // PREFETCHIT0/1 instructions
|
||||||
RDPRU // RDPRU instruction supported
|
PSFD // Predictive Store Forward Disable
|
||||||
RDRAND // RDRAND instruction is available
|
RDPRU // RDPRU instruction supported
|
||||||
RDSEED // RDSEED instruction is available
|
RDRAND // RDRAND instruction is available
|
||||||
RDTSCP // RDTSCP Instruction
|
RDSEED // RDSEED instruction is available
|
||||||
RRSBA_CTRL // Restricted RSB Alternate
|
RDTSCP // RDTSCP Instruction
|
||||||
RTM // Restricted Transactional Memory
|
RRSBA_CTRL // Restricted RSB Alternate
|
||||||
RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort.
|
RTM // Restricted Transactional Memory
|
||||||
SERIALIZE // Serialize Instruction Execution
|
RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort.
|
||||||
SEV // AMD Secure Encrypted Virtualization supported
|
SBPB // Indicates support for the Selective Branch Predictor Barrier
|
||||||
SEV_64BIT // AMD SEV guest execution only allowed from a 64-bit host
|
SERIALIZE // Serialize Instruction Execution
|
||||||
SEV_ALTERNATIVE // AMD SEV Alternate Injection supported
|
SEV // AMD Secure Encrypted Virtualization supported
|
||||||
SEV_DEBUGSWAP // Full debug state swap supported for SEV-ES guests
|
SEV_64BIT // AMD SEV guest execution only allowed from a 64-bit host
|
||||||
SEV_ES // AMD SEV Encrypted State supported
|
SEV_ALTERNATIVE // AMD SEV Alternate Injection supported
|
||||||
SEV_RESTRICTED // AMD SEV Restricted Injection supported
|
SEV_DEBUGSWAP // Full debug state swap supported for SEV-ES guests
|
||||||
SEV_SNP // AMD SEV Secure Nested Paging supported
|
SEV_ES // AMD SEV Encrypted State supported
|
||||||
SGX // Software Guard Extensions
|
SEV_RESTRICTED // AMD SEV Restricted Injection supported
|
||||||
SGXLC // Software Guard Extensions Launch Control
|
SEV_SNP // AMD SEV Secure Nested Paging supported
|
||||||
SHA // Intel SHA Extensions
|
SGX // Software Guard Extensions
|
||||||
SME // AMD Secure Memory Encryption supported
|
SGXLC // Software Guard Extensions Launch Control
|
||||||
SME_COHERENT // AMD Hardware cache coherency across encryption domains enforced
|
SHA // Intel SHA Extensions
|
||||||
SPEC_CTRL_SSBD // Speculative Store Bypass Disable
|
SME // AMD Secure Memory Encryption supported
|
||||||
SRBDS_CTRL // SRBDS mitigation MSR available
|
SME_COHERENT // AMD Hardware cache coherency across encryption domains enforced
|
||||||
SSE // SSE functions
|
SPEC_CTRL_SSBD // Speculative Store Bypass Disable
|
||||||
SSE2 // P4 SSE functions
|
SRBDS_CTRL // SRBDS mitigation MSR available
|
||||||
SSE3 // Prescott SSE3 functions
|
SRSO_MSR_FIX // Indicates that software may use MSR BP_CFG[BpSpecReduce] to mitigate SRSO.
|
||||||
SSE4 // Penryn SSE4.1 functions
|
SRSO_NO // Indicates the CPU is not subject to the SRSO vulnerability
|
||||||
SSE42 // Nehalem SSE4.2 functions
|
SRSO_USER_KERNEL_NO // Indicates the CPU is not subject to the SRSO vulnerability across user/kernel boundaries
|
||||||
SSE4A // AMD Barcelona microarchitecture SSE4a instructions
|
SSE // SSE functions
|
||||||
SSSE3 // Conroe SSSE3 functions
|
SSE2 // P4 SSE functions
|
||||||
STIBP // Single Thread Indirect Branch Predictors
|
SSE3 // Prescott SSE3 functions
|
||||||
STIBP_ALWAYSON // AMD: Single Thread Indirect Branch Prediction Mode has Enhanced Performance and may be left Always On
|
SSE4 // Penryn SSE4.1 functions
|
||||||
STOSB_SHORT // Fast short STOSB
|
SSE42 // Nehalem SSE4.2 functions
|
||||||
SUCCOR // Software uncorrectable error containment and recovery capability.
|
SSE4A // AMD Barcelona microarchitecture SSE4a instructions
|
||||||
SVM // AMD Secure Virtual Machine
|
SSSE3 // Conroe SSSE3 functions
|
||||||
SVMDA // Indicates support for the SVM decode assists.
|
STIBP // Single Thread Indirect Branch Predictors
|
||||||
SVMFBASID // SVM, Indicates that TLB flush events, including CR3 writes and CR4.PGE toggles, flush only the current ASID's TLB entries. Also indicates support for the extended VMCBTLB_Control
|
STIBP_ALWAYSON // AMD: Single Thread Indirect Branch Prediction Mode has Enhanced Performance and may be left Always On
|
||||||
SVML // AMD SVM lock. Indicates support for SVM-Lock.
|
STOSB_SHORT // Fast short STOSB
|
||||||
SVMNP // AMD SVM nested paging
|
SUCCOR // Software uncorrectable error containment and recovery capability.
|
||||||
SVMPF // SVM pause intercept filter. Indicates support for the pause intercept filter
|
SVM // AMD Secure Virtual Machine
|
||||||
SVMPFT // SVM PAUSE filter threshold. Indicates support for the PAUSE filter cycle count threshold
|
SVMDA // Indicates support for the SVM decode assists.
|
||||||
SYSCALL // System-Call Extension (SCE): SYSCALL and SYSRET instructions.
|
SVMFBASID // SVM, Indicates that TLB flush events, including CR3 writes and CR4.PGE toggles, flush only the current ASID's TLB entries. Also indicates support for the extended VMCBTLB_Control
|
||||||
SYSEE // SYSENTER and SYSEXIT instructions
|
SVML // AMD SVM lock. Indicates support for SVM-Lock.
|
||||||
TBM // AMD Trailing Bit Manipulation
|
SVMNP // AMD SVM nested paging
|
||||||
TDX_GUEST // Intel Trust Domain Extensions Guest
|
SVMPF // SVM pause intercept filter. Indicates support for the pause intercept filter
|
||||||
TLB_FLUSH_NESTED // AMD: Flushing includes all the nested translations for guest translations
|
SVMPFT // SVM PAUSE filter threshold. Indicates support for the PAUSE filter cycle count threshold
|
||||||
TME // Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE.
|
SYSCALL // System-Call Extension (SCE): SYSCALL and SYSRET instructions.
|
||||||
TOPEXT // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX.
|
SYSEE // SYSENTER and SYSEXIT instructions
|
||||||
TSCRATEMSR // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104
|
TBM // AMD Trailing Bit Manipulation
|
||||||
TSXLDTRK // Intel TSX Suspend Load Address Tracking
|
TDX_GUEST // Intel Trust Domain Extensions Guest
|
||||||
VAES // Vector AES. AVX(512) versions requires additional checks.
|
TLB_FLUSH_NESTED // AMD: Flushing includes all the nested translations for guest translations
|
||||||
VMCBCLEAN // VMCB clean bits. Indicates support for VMCB clean bits.
|
TME // Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE.
|
||||||
VMPL // AMD VM Permission Levels supported
|
TOPEXT // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX.
|
||||||
VMSA_REGPROT // AMD VMSA Register Protection supported
|
TSCRATEMSR // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104
|
||||||
VMX // Virtual Machine Extensions
|
TSXLDTRK // Intel TSX Suspend Load Address Tracking
|
||||||
VPCLMULQDQ // Carry-Less Multiplication Quadword. Requires AVX for 3 register versions.
|
VAES // Vector AES. AVX(512) versions requires additional checks.
|
||||||
VTE // AMD Virtual Transparent Encryption supported
|
VMCBCLEAN // VMCB clean bits. Indicates support for VMCB clean bits.
|
||||||
WAITPKG // TPAUSE, UMONITOR, UMWAIT
|
VMPL // AMD VM Permission Levels supported
|
||||||
WBNOINVD // Write Back and Do Not Invalidate Cache
|
VMSA_REGPROT // AMD VMSA Register Protection supported
|
||||||
WRMSRNS // Non-Serializing Write to Model Specific Register
|
VMX // Virtual Machine Extensions
|
||||||
X87 // FPU
|
VPCLMULQDQ // Carry-Less Multiplication Quadword. Requires AVX for 3 register versions.
|
||||||
XGETBV1 // Supports XGETBV with ECX = 1
|
VTE // AMD Virtual Transparent Encryption supported
|
||||||
XOP // Bulldozer XOP functions
|
WAITPKG // TPAUSE, UMONITOR, UMWAIT
|
||||||
XSAVE // XSAVE, XRESTOR, XSETBV, XGETBV
|
WBNOINVD // Write Back and Do Not Invalidate Cache
|
||||||
XSAVEC // Supports XSAVEC and the compacted form of XRSTOR.
|
WRMSRNS // Non-Serializing Write to Model Specific Register
|
||||||
XSAVEOPT // XSAVEOPT available
|
X87 // FPU
|
||||||
XSAVES // Supports XSAVES/XRSTORS and IA32_XSS
|
XGETBV1 // Supports XGETBV with ECX = 1
|
||||||
|
XOP // Bulldozer XOP functions
|
||||||
|
XSAVE // XSAVE, XRESTOR, XSETBV, XGETBV
|
||||||
|
XSAVEC // Supports XSAVEC and the compacted form of XRSTOR.
|
||||||
|
XSAVEOPT // XSAVEOPT available
|
||||||
|
XSAVES // Supports XSAVES/XRSTORS and IA32_XSS
|
||||||
|
|
||||||
// ARM features:
|
// ARM features:
|
||||||
AESARM // AES instructions
|
AESARM // AES instructions
|
||||||
|
@ -309,10 +314,11 @@ type CPUInfo struct {
|
||||||
L2 int // L2 Cache (per core or shared). Will be -1 if undetected
|
L2 int // L2 Cache (per core or shared). Will be -1 if undetected
|
||||||
L3 int // L3 Cache (per core, per ccx or shared). Will be -1 if undetected
|
L3 int // L3 Cache (per core, per ccx or shared). Will be -1 if undetected
|
||||||
}
|
}
|
||||||
SGX SGXSupport
|
SGX SGXSupport
|
||||||
AVX10Level uint8
|
AMDMemEncryption AMDMemEncryptionSupport
|
||||||
maxFunc uint32
|
AVX10Level uint8
|
||||||
maxExFunc uint32
|
maxFunc uint32
|
||||||
|
maxExFunc uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
var cpuid func(op uint32) (eax, ebx, ecx, edx uint32)
|
var cpuid func(op uint32) (eax, ebx, ecx, edx uint32)
|
||||||
|
@ -1079,6 +1085,32 @@ func hasSGX(available, lc bool) (rval SGXSupport) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AMDMemEncryptionSupport struct {
|
||||||
|
Available bool
|
||||||
|
CBitPossition uint32
|
||||||
|
NumVMPL uint32
|
||||||
|
PhysAddrReduction uint32
|
||||||
|
NumEntryptedGuests uint32
|
||||||
|
MinSevNoEsAsid uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasAMDMemEncryption(available bool) (rval AMDMemEncryptionSupport) {
|
||||||
|
rval.Available = available
|
||||||
|
if !available {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, b, c, d := cpuidex(0x8000001f, 0)
|
||||||
|
|
||||||
|
rval.CBitPossition = b & 0x3f
|
||||||
|
rval.PhysAddrReduction = (b >> 6) & 0x3F
|
||||||
|
rval.NumVMPL = (b >> 12) & 0xf
|
||||||
|
rval.NumEntryptedGuests = c
|
||||||
|
rval.MinSevNoEsAsid = d
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func support() flagSet {
|
func support() flagSet {
|
||||||
var fs flagSet
|
var fs flagSet
|
||||||
mfi := maxFunctionID()
|
mfi := maxFunctionID()
|
||||||
|
@ -1418,6 +1450,15 @@ func support() flagSet {
|
||||||
fs.setIf((a>>24)&1 == 1, VMSA_REGPROT)
|
fs.setIf((a>>24)&1 == 1, VMSA_REGPROT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if maxExtendedFunction() >= 0x80000021 && vend == AMD {
|
||||||
|
a, _, _, _ := cpuid(0x80000021)
|
||||||
|
fs.setIf((a>>31)&1 == 1, SRSO_MSR_FIX)
|
||||||
|
fs.setIf((a>>30)&1 == 1, SRSO_USER_KERNEL_NO)
|
||||||
|
fs.setIf((a>>29)&1 == 1, SRSO_NO)
|
||||||
|
fs.setIf((a>>28)&1 == 1, IBPB_BRTYPE)
|
||||||
|
fs.setIf((a>>27)&1 == 1, SBPB)
|
||||||
|
}
|
||||||
|
|
||||||
if mfi >= 0x20 {
|
if mfi >= 0x20 {
|
||||||
// Microsoft has decided to purposefully hide the information
|
// Microsoft has decided to purposefully hide the information
|
||||||
// of the guest TEE when VMs are being created using Hyper-V.
|
// of the guest TEE when VMs are being created using Hyper-V.
|
||||||
|
|
1
vendor/github.com/klauspost/cpuid/v2/detect_x86.go
generated
vendored
1
vendor/github.com/klauspost/cpuid/v2/detect_x86.go
generated
vendored
|
@ -27,6 +27,7 @@ func addInfo(c *CPUInfo, safe bool) {
|
||||||
c.Family, c.Model, c.Stepping = familyModel()
|
c.Family, c.Model, c.Stepping = familyModel()
|
||||||
c.featureSet = support()
|
c.featureSet = support()
|
||||||
c.SGX = hasSGX(c.featureSet.inSet(SGX), c.featureSet.inSet(SGXLC))
|
c.SGX = hasSGX(c.featureSet.inSet(SGX), c.featureSet.inSet(SGXLC))
|
||||||
|
c.AMDMemEncryption = hasAMDMemEncryption(c.featureSet.inSet(SME) || c.featureSet.inSet(SEV))
|
||||||
c.ThreadsPerCore = threadsPerCore()
|
c.ThreadsPerCore = threadsPerCore()
|
||||||
c.LogicalCores = logicalCores()
|
c.LogicalCores = logicalCores()
|
||||||
c.PhysicalCores = physicalCores()
|
c.PhysicalCores = physicalCores()
|
||||||
|
|
289
vendor/github.com/klauspost/cpuid/v2/featureid_string.go
generated
vendored
289
vendor/github.com/klauspost/cpuid/v2/featureid_string.go
generated
vendored
|
@ -81,152 +81,157 @@ func _() {
|
||||||
_ = x[IA32_ARCH_CAP-71]
|
_ = x[IA32_ARCH_CAP-71]
|
||||||
_ = x[IA32_CORE_CAP-72]
|
_ = x[IA32_CORE_CAP-72]
|
||||||
_ = x[IBPB-73]
|
_ = x[IBPB-73]
|
||||||
_ = x[IBRS-74]
|
_ = x[IBPB_BRTYPE-74]
|
||||||
_ = x[IBRS_PREFERRED-75]
|
_ = x[IBRS-75]
|
||||||
_ = x[IBRS_PROVIDES_SMP-76]
|
_ = x[IBRS_PREFERRED-76]
|
||||||
_ = x[IBS-77]
|
_ = x[IBRS_PROVIDES_SMP-77]
|
||||||
_ = x[IBSBRNTRGT-78]
|
_ = x[IBS-78]
|
||||||
_ = x[IBSFETCHSAM-79]
|
_ = x[IBSBRNTRGT-79]
|
||||||
_ = x[IBSFFV-80]
|
_ = x[IBSFETCHSAM-80]
|
||||||
_ = x[IBSOPCNT-81]
|
_ = x[IBSFFV-81]
|
||||||
_ = x[IBSOPCNTEXT-82]
|
_ = x[IBSOPCNT-82]
|
||||||
_ = x[IBSOPSAM-83]
|
_ = x[IBSOPCNTEXT-83]
|
||||||
_ = x[IBSRDWROPCNT-84]
|
_ = x[IBSOPSAM-84]
|
||||||
_ = x[IBSRIPINVALIDCHK-85]
|
_ = x[IBSRDWROPCNT-85]
|
||||||
_ = x[IBS_FETCH_CTLX-86]
|
_ = x[IBSRIPINVALIDCHK-86]
|
||||||
_ = x[IBS_OPDATA4-87]
|
_ = x[IBS_FETCH_CTLX-87]
|
||||||
_ = x[IBS_OPFUSE-88]
|
_ = x[IBS_OPDATA4-88]
|
||||||
_ = x[IBS_PREVENTHOST-89]
|
_ = x[IBS_OPFUSE-89]
|
||||||
_ = x[IBS_ZEN4-90]
|
_ = x[IBS_PREVENTHOST-90]
|
||||||
_ = x[IDPRED_CTRL-91]
|
_ = x[IBS_ZEN4-91]
|
||||||
_ = x[INT_WBINVD-92]
|
_ = x[IDPRED_CTRL-92]
|
||||||
_ = x[INVLPGB-93]
|
_ = x[INT_WBINVD-93]
|
||||||
_ = x[KEYLOCKER-94]
|
_ = x[INVLPGB-94]
|
||||||
_ = x[KEYLOCKERW-95]
|
_ = x[KEYLOCKER-95]
|
||||||
_ = x[LAHF-96]
|
_ = x[KEYLOCKERW-96]
|
||||||
_ = x[LAM-97]
|
_ = x[LAHF-97]
|
||||||
_ = x[LBRVIRT-98]
|
_ = x[LAM-98]
|
||||||
_ = x[LZCNT-99]
|
_ = x[LBRVIRT-99]
|
||||||
_ = x[MCAOVERFLOW-100]
|
_ = x[LZCNT-100]
|
||||||
_ = x[MCDT_NO-101]
|
_ = x[MCAOVERFLOW-101]
|
||||||
_ = x[MCOMMIT-102]
|
_ = x[MCDT_NO-102]
|
||||||
_ = x[MD_CLEAR-103]
|
_ = x[MCOMMIT-103]
|
||||||
_ = x[MMX-104]
|
_ = x[MD_CLEAR-104]
|
||||||
_ = x[MMXEXT-105]
|
_ = x[MMX-105]
|
||||||
_ = x[MOVBE-106]
|
_ = x[MMXEXT-106]
|
||||||
_ = x[MOVDIR64B-107]
|
_ = x[MOVBE-107]
|
||||||
_ = x[MOVDIRI-108]
|
_ = x[MOVDIR64B-108]
|
||||||
_ = x[MOVSB_ZL-109]
|
_ = x[MOVDIRI-109]
|
||||||
_ = x[MOVU-110]
|
_ = x[MOVSB_ZL-110]
|
||||||
_ = x[MPX-111]
|
_ = x[MOVU-111]
|
||||||
_ = x[MSRIRC-112]
|
_ = x[MPX-112]
|
||||||
_ = x[MSRLIST-113]
|
_ = x[MSRIRC-113]
|
||||||
_ = x[MSR_PAGEFLUSH-114]
|
_ = x[MSRLIST-114]
|
||||||
_ = x[NRIPS-115]
|
_ = x[MSR_PAGEFLUSH-115]
|
||||||
_ = x[NX-116]
|
_ = x[NRIPS-116]
|
||||||
_ = x[OSXSAVE-117]
|
_ = x[NX-117]
|
||||||
_ = x[PCONFIG-118]
|
_ = x[OSXSAVE-118]
|
||||||
_ = x[POPCNT-119]
|
_ = x[PCONFIG-119]
|
||||||
_ = x[PPIN-120]
|
_ = x[POPCNT-120]
|
||||||
_ = x[PREFETCHI-121]
|
_ = x[PPIN-121]
|
||||||
_ = x[PSFD-122]
|
_ = x[PREFETCHI-122]
|
||||||
_ = x[RDPRU-123]
|
_ = x[PSFD-123]
|
||||||
_ = x[RDRAND-124]
|
_ = x[RDPRU-124]
|
||||||
_ = x[RDSEED-125]
|
_ = x[RDRAND-125]
|
||||||
_ = x[RDTSCP-126]
|
_ = x[RDSEED-126]
|
||||||
_ = x[RRSBA_CTRL-127]
|
_ = x[RDTSCP-127]
|
||||||
_ = x[RTM-128]
|
_ = x[RRSBA_CTRL-128]
|
||||||
_ = x[RTM_ALWAYS_ABORT-129]
|
_ = x[RTM-129]
|
||||||
_ = x[SERIALIZE-130]
|
_ = x[RTM_ALWAYS_ABORT-130]
|
||||||
_ = x[SEV-131]
|
_ = x[SBPB-131]
|
||||||
_ = x[SEV_64BIT-132]
|
_ = x[SERIALIZE-132]
|
||||||
_ = x[SEV_ALTERNATIVE-133]
|
_ = x[SEV-133]
|
||||||
_ = x[SEV_DEBUGSWAP-134]
|
_ = x[SEV_64BIT-134]
|
||||||
_ = x[SEV_ES-135]
|
_ = x[SEV_ALTERNATIVE-135]
|
||||||
_ = x[SEV_RESTRICTED-136]
|
_ = x[SEV_DEBUGSWAP-136]
|
||||||
_ = x[SEV_SNP-137]
|
_ = x[SEV_ES-137]
|
||||||
_ = x[SGX-138]
|
_ = x[SEV_RESTRICTED-138]
|
||||||
_ = x[SGXLC-139]
|
_ = x[SEV_SNP-139]
|
||||||
_ = x[SHA-140]
|
_ = x[SGX-140]
|
||||||
_ = x[SME-141]
|
_ = x[SGXLC-141]
|
||||||
_ = x[SME_COHERENT-142]
|
_ = x[SHA-142]
|
||||||
_ = x[SPEC_CTRL_SSBD-143]
|
_ = x[SME-143]
|
||||||
_ = x[SRBDS_CTRL-144]
|
_ = x[SME_COHERENT-144]
|
||||||
_ = x[SSE-145]
|
_ = x[SPEC_CTRL_SSBD-145]
|
||||||
_ = x[SSE2-146]
|
_ = x[SRBDS_CTRL-146]
|
||||||
_ = x[SSE3-147]
|
_ = x[SRSO_MSR_FIX-147]
|
||||||
_ = x[SSE4-148]
|
_ = x[SRSO_NO-148]
|
||||||
_ = x[SSE42-149]
|
_ = x[SRSO_USER_KERNEL_NO-149]
|
||||||
_ = x[SSE4A-150]
|
_ = x[SSE-150]
|
||||||
_ = x[SSSE3-151]
|
_ = x[SSE2-151]
|
||||||
_ = x[STIBP-152]
|
_ = x[SSE3-152]
|
||||||
_ = x[STIBP_ALWAYSON-153]
|
_ = x[SSE4-153]
|
||||||
_ = x[STOSB_SHORT-154]
|
_ = x[SSE42-154]
|
||||||
_ = x[SUCCOR-155]
|
_ = x[SSE4A-155]
|
||||||
_ = x[SVM-156]
|
_ = x[SSSE3-156]
|
||||||
_ = x[SVMDA-157]
|
_ = x[STIBP-157]
|
||||||
_ = x[SVMFBASID-158]
|
_ = x[STIBP_ALWAYSON-158]
|
||||||
_ = x[SVML-159]
|
_ = x[STOSB_SHORT-159]
|
||||||
_ = x[SVMNP-160]
|
_ = x[SUCCOR-160]
|
||||||
_ = x[SVMPF-161]
|
_ = x[SVM-161]
|
||||||
_ = x[SVMPFT-162]
|
_ = x[SVMDA-162]
|
||||||
_ = x[SYSCALL-163]
|
_ = x[SVMFBASID-163]
|
||||||
_ = x[SYSEE-164]
|
_ = x[SVML-164]
|
||||||
_ = x[TBM-165]
|
_ = x[SVMNP-165]
|
||||||
_ = x[TDX_GUEST-166]
|
_ = x[SVMPF-166]
|
||||||
_ = x[TLB_FLUSH_NESTED-167]
|
_ = x[SVMPFT-167]
|
||||||
_ = x[TME-168]
|
_ = x[SYSCALL-168]
|
||||||
_ = x[TOPEXT-169]
|
_ = x[SYSEE-169]
|
||||||
_ = x[TSCRATEMSR-170]
|
_ = x[TBM-170]
|
||||||
_ = x[TSXLDTRK-171]
|
_ = x[TDX_GUEST-171]
|
||||||
_ = x[VAES-172]
|
_ = x[TLB_FLUSH_NESTED-172]
|
||||||
_ = x[VMCBCLEAN-173]
|
_ = x[TME-173]
|
||||||
_ = x[VMPL-174]
|
_ = x[TOPEXT-174]
|
||||||
_ = x[VMSA_REGPROT-175]
|
_ = x[TSCRATEMSR-175]
|
||||||
_ = x[VMX-176]
|
_ = x[TSXLDTRK-176]
|
||||||
_ = x[VPCLMULQDQ-177]
|
_ = x[VAES-177]
|
||||||
_ = x[VTE-178]
|
_ = x[VMCBCLEAN-178]
|
||||||
_ = x[WAITPKG-179]
|
_ = x[VMPL-179]
|
||||||
_ = x[WBNOINVD-180]
|
_ = x[VMSA_REGPROT-180]
|
||||||
_ = x[WRMSRNS-181]
|
_ = x[VMX-181]
|
||||||
_ = x[X87-182]
|
_ = x[VPCLMULQDQ-182]
|
||||||
_ = x[XGETBV1-183]
|
_ = x[VTE-183]
|
||||||
_ = x[XOP-184]
|
_ = x[WAITPKG-184]
|
||||||
_ = x[XSAVE-185]
|
_ = x[WBNOINVD-185]
|
||||||
_ = x[XSAVEC-186]
|
_ = x[WRMSRNS-186]
|
||||||
_ = x[XSAVEOPT-187]
|
_ = x[X87-187]
|
||||||
_ = x[XSAVES-188]
|
_ = x[XGETBV1-188]
|
||||||
_ = x[AESARM-189]
|
_ = x[XOP-189]
|
||||||
_ = x[ARMCPUID-190]
|
_ = x[XSAVE-190]
|
||||||
_ = x[ASIMD-191]
|
_ = x[XSAVEC-191]
|
||||||
_ = x[ASIMDDP-192]
|
_ = x[XSAVEOPT-192]
|
||||||
_ = x[ASIMDHP-193]
|
_ = x[XSAVES-193]
|
||||||
_ = x[ASIMDRDM-194]
|
_ = x[AESARM-194]
|
||||||
_ = x[ATOMICS-195]
|
_ = x[ARMCPUID-195]
|
||||||
_ = x[CRC32-196]
|
_ = x[ASIMD-196]
|
||||||
_ = x[DCPOP-197]
|
_ = x[ASIMDDP-197]
|
||||||
_ = x[EVTSTRM-198]
|
_ = x[ASIMDHP-198]
|
||||||
_ = x[FCMA-199]
|
_ = x[ASIMDRDM-199]
|
||||||
_ = x[FP-200]
|
_ = x[ATOMICS-200]
|
||||||
_ = x[FPHP-201]
|
_ = x[CRC32-201]
|
||||||
_ = x[GPA-202]
|
_ = x[DCPOP-202]
|
||||||
_ = x[JSCVT-203]
|
_ = x[EVTSTRM-203]
|
||||||
_ = x[LRCPC-204]
|
_ = x[FCMA-204]
|
||||||
_ = x[PMULL-205]
|
_ = x[FP-205]
|
||||||
_ = x[SHA1-206]
|
_ = x[FPHP-206]
|
||||||
_ = x[SHA2-207]
|
_ = x[GPA-207]
|
||||||
_ = x[SHA3-208]
|
_ = x[JSCVT-208]
|
||||||
_ = x[SHA512-209]
|
_ = x[LRCPC-209]
|
||||||
_ = x[SM3-210]
|
_ = x[PMULL-210]
|
||||||
_ = x[SM4-211]
|
_ = x[SHA1-211]
|
||||||
_ = x[SVE-212]
|
_ = x[SHA2-212]
|
||||||
_ = x[lastID-213]
|
_ = x[SHA3-213]
|
||||||
|
_ = x[SHA512-214]
|
||||||
|
_ = x[SM3-215]
|
||||||
|
_ = x[SM4-216]
|
||||||
|
_ = x[SVE-217]
|
||||||
|
_ = x[lastID-218]
|
||||||
_ = x[firstID-0]
|
_ = x[firstID-0]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXTILEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
|
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXTILEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBPB_BRTYPEIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSBPBSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSRSO_MSR_FIXSRSO_NOSRSO_USER_KERNEL_NOSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
|
||||||
|
|
||||||
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 62, 67, 70, 75, 84, 93, 102, 106, 116, 128, 136, 144, 152, 160, 167, 177, 187, 195, 205, 216, 224, 234, 252, 267, 274, 286, 293, 300, 311, 319, 323, 327, 333, 338, 346, 351, 357, 361, 370, 388, 396, 403, 407, 411, 425, 431, 435, 439, 448, 452, 456, 461, 466, 470, 474, 481, 485, 488, 494, 497, 500, 510, 520, 533, 546, 550, 554, 568, 585, 588, 598, 609, 615, 623, 634, 642, 654, 670, 684, 695, 705, 720, 728, 739, 749, 756, 765, 775, 779, 782, 789, 794, 805, 812, 819, 827, 830, 836, 841, 850, 857, 865, 869, 872, 878, 885, 898, 903, 905, 912, 919, 925, 929, 938, 942, 947, 953, 959, 965, 975, 978, 994, 1003, 1006, 1015, 1030, 1043, 1049, 1063, 1070, 1073, 1078, 1081, 1084, 1096, 1110, 1120, 1123, 1127, 1131, 1135, 1140, 1145, 1150, 1155, 1169, 1180, 1186, 1189, 1194, 1203, 1207, 1212, 1217, 1223, 1230, 1235, 1238, 1247, 1263, 1266, 1272, 1282, 1290, 1294, 1303, 1307, 1319, 1322, 1332, 1335, 1342, 1350, 1357, 1360, 1367, 1370, 1375, 1381, 1389, 1395, 1401, 1409, 1414, 1421, 1428, 1436, 1443, 1448, 1453, 1460, 1464, 1466, 1470, 1473, 1478, 1483, 1488, 1492, 1496, 1500, 1506, 1509, 1512, 1515, 1521}
|
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 62, 67, 70, 75, 84, 93, 102, 106, 116, 128, 136, 144, 152, 160, 167, 177, 187, 195, 205, 216, 224, 234, 252, 267, 274, 286, 293, 300, 311, 319, 323, 327, 333, 338, 346, 351, 357, 361, 370, 388, 396, 403, 407, 411, 425, 431, 435, 439, 448, 452, 456, 461, 466, 470, 474, 481, 485, 488, 494, 497, 500, 510, 520, 533, 546, 550, 561, 565, 579, 596, 599, 609, 620, 626, 634, 645, 653, 665, 681, 695, 706, 716, 731, 739, 750, 760, 767, 776, 786, 790, 793, 800, 805, 816, 823, 830, 838, 841, 847, 852, 861, 868, 876, 880, 883, 889, 896, 909, 914, 916, 923, 930, 936, 940, 949, 953, 958, 964, 970, 976, 986, 989, 1005, 1009, 1018, 1021, 1030, 1045, 1058, 1064, 1078, 1085, 1088, 1093, 1096, 1099, 1111, 1125, 1135, 1147, 1154, 1173, 1176, 1180, 1184, 1188, 1193, 1198, 1203, 1208, 1222, 1233, 1239, 1242, 1247, 1256, 1260, 1265, 1270, 1276, 1283, 1288, 1291, 1300, 1316, 1319, 1325, 1335, 1343, 1347, 1356, 1360, 1372, 1375, 1385, 1388, 1395, 1403, 1410, 1413, 1420, 1423, 1428, 1434, 1442, 1448, 1454, 1462, 1467, 1474, 1481, 1489, 1496, 1501, 1506, 1513, 1517, 1519, 1523, 1526, 1531, 1536, 1541, 1545, 1549, 1553, 1559, 1562, 1565, 1568, 1574}
|
||||||
|
|
||||||
func (i FeatureID) String() string {
|
func (i FeatureID) String() string {
|
||||||
if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {
|
if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {
|
||||||
|
|
1
vendor/github.com/leodido/go-urn/.gitignore
generated
vendored
1
vendor/github.com/leodido/go-urn/.gitignore
generated
vendored
|
@ -10,3 +10,4 @@
|
||||||
|
|
||||||
vendor/
|
vendor/
|
||||||
/removecomments
|
/removecomments
|
||||||
|
/snake2camel
|
126
vendor/github.com/leodido/go-urn/README.md
generated
vendored
126
vendor/github.com/leodido/go-urn/README.md
generated
vendored
|
@ -2,21 +2,34 @@
|
||||||
|
|
||||||
**A parser for URNs**.
|
**A parser for URNs**.
|
||||||
|
|
||||||
> As seen on [RFC 2141](https://tools.ietf.org/html/rfc2141#ref-1).
|
> As seen on [RFC 2141](https://datatracker.ietf.org/doc/html/rfc2141), [RFC 7643](https://datatracker.ietf.org/doc/html/rfc7643#section-10), and on [RFC 8141](https://datatracker.ietf.org/doc/html/rfc8141).
|
||||||
|
|
||||||
[API documentation](https://godoc.org/github.com/leodido/go-urn).
|
[API documentation](https://godoc.org/github.com/leodido/go-urn).
|
||||||
|
|
||||||
|
Starting with version 1.3 this library also supports [RFC 7643 SCIM URNs](https://datatracker.ietf.org/doc/html/rfc7643#section-10).
|
||||||
|
|
||||||
|
Starting with version 1.4 this library also supports [RFC 8141 URNs (2017)](https://datatracker.ietf.org/doc/html/rfc8141).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```
|
||||||
go get github.com/leodido/go-urn
|
go get github.com/leodido/go-urn
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
1. RFC 2141 URNs parsing (default)
|
||||||
|
2. RFC 8141 URNs parsing (supersedes RFC 2141)
|
||||||
|
3. RFC 7643 SCIM URNs parsing
|
||||||
|
4. Normalization as per RFCs
|
||||||
|
5. Lexical equivalence as per RFCs
|
||||||
|
6. Precise, fine-grained errors
|
||||||
|
|
||||||
## Performances
|
## Performances
|
||||||
|
|
||||||
This implementation results to be really fast.
|
This implementation results to be really fast.
|
||||||
|
|
||||||
Usually below ½ microsecond on my machine<sup>[1](#mymachine)</sup>.
|
Usually below 400 ns on my machine<sup>[1](#mymachine)</sup>.
|
||||||
|
|
||||||
Notice it also performs, while parsing:
|
Notice it also performs, while parsing:
|
||||||
|
|
||||||
|
@ -24,35 +37,36 @@ Notice it also performs, while parsing:
|
||||||
2. specific-string normalization
|
2. specific-string normalization
|
||||||
|
|
||||||
```
|
```
|
||||||
ok/00/urn:a:b______________________________________/-4 20000000 265 ns/op 182 B/op 6 allocs/op
|
ok/00/urn:a:b______________________________________/-10 51372006 109.0 ns/op 275 B/op 3 allocs/op
|
||||||
ok/01/URN:foo:a123,456_____________________________/-4 30000000 296 ns/op 200 B/op 6 allocs/op
|
ok/01/URN:foo:a123,456_____________________________/-10 36024072 160.8 ns/op 296 B/op 6 allocs/op
|
||||||
ok/02/urn:foo:a123%2c456___________________________/-4 20000000 331 ns/op 208 B/op 6 allocs/op
|
ok/02/urn:foo:a123%2C456___________________________/-10 31901007 188.4 ns/op 320 B/op 7 allocs/op
|
||||||
ok/03/urn:ietf:params:scim:schemas:core:2.0:User___/-4 20000000 430 ns/op 280 B/op 6 allocs/op
|
ok/03/urn:ietf:params:scim:schemas:core:2.0:User___/-10 22736756 266.6 ns/op 376 B/op 6 allocs/op
|
||||||
ok/04/urn:ietf:params:scim:schemas:extension:enterp/-4 20000000 411 ns/op 312 B/op 6 allocs/op
|
ok/04/urn:ietf:params:scim:schemas:extension:enterp/-10 18291859 335.2 ns/op 408 B/op 6 allocs/op
|
||||||
ok/05/urn:ietf:params:scim:schemas:extension:enterp/-4 20000000 472 ns/op 344 B/op 6 allocs/op
|
ok/05/urn:ietf:params:scim:schemas:extension:enterp/-10 15283087 379.4 ns/op 440 B/op 6 allocs/op
|
||||||
ok/06/urn:burnout:nss______________________________/-4 30000000 257 ns/op 192 B/op 6 allocs/op
|
ok/06/urn:burnout:nss______________________________/-10 39407593 155.1 ns/op 288 B/op 6 allocs/op
|
||||||
ok/07/urn:abcdefghilmnopqrstuvzabcdefghilm:x_______/-4 20000000 375 ns/op 213 B/op 6 allocs/op
|
ok/07/urn:abcdefghilmnopqrstuvzabcdefghilm:x_______/-10 27832718 211.4 ns/op 307 B/op 4 allocs/op
|
||||||
ok/08/urn:urnurnurn:urn____________________________/-4 30000000 265 ns/op 197 B/op 6 allocs/op
|
ok/08/urn:urnurnurn:urn____________________________/-10 33269596 168.1 ns/op 293 B/op 6 allocs/op
|
||||||
ok/09/urn:ciao:@!=%2c(xyz)+a,b.*@g=$_'_____________/-4 20000000 307 ns/op 248 B/op 6 allocs/op
|
ok/09/urn:ciao:!!*_________________________________/-10 41100675 148.8 ns/op 288 B/op 6 allocs/op
|
||||||
ok/10/URN:x:abc%1dz%2f%3az_________________________/-4 30000000 259 ns/op 212 B/op 6 allocs/op
|
ok/10/urn:ciao:=@__________________________________/-10 37214253 149.7 ns/op 284 B/op 6 allocs/op
|
||||||
no/11/URN:-xxx:x___________________________________/-4 20000000 445 ns/op 320 B/op 6 allocs/op
|
ok/11/urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'_____________/-10 26534240 229.8 ns/op 336 B/op 7 allocs/op
|
||||||
no/12/urn::colon:nss_______________________________/-4 20000000 461 ns/op 320 B/op 6 allocs/op
|
ok/12/URN:x:abc%1Dz%2F%3az_________________________/-10 28166396 211.8 ns/op 336 B/op 7 allocs/op
|
||||||
no/13/urn:abcdefghilmnopqrstuvzabcdefghilmn:specifi/-4 10000000 660 ns/op 320 B/op 6 allocs/op
|
no/13/URN:---xxx:x_________________________________/-10 23635159 255.6 ns/op 419 B/op 5 allocs/op
|
||||||
no/14/URN:a!?:x____________________________________/-4 20000000 507 ns/op 320 B/op 6 allocs/op
|
no/14/urn::colon:nss_______________________________/-10 23594779 258.4 ns/op 419 B/op 5 allocs/op
|
||||||
no/15/urn:urn:NSS__________________________________/-4 20000000 429 ns/op 288 B/op 6 allocs/op
|
no/15/URN:@,:x_____________________________________/-10 23742535 261.5 ns/op 419 B/op 5 allocs/op
|
||||||
no/16/urn:white_space:NSS__________________________/-4 20000000 482 ns/op 320 B/op 6 allocs/op
|
no/16/URN:URN:NSS__________________________________/-10 27432714 223.3 ns/op 371 B/op 5 allocs/op
|
||||||
no/17/urn:concat:no_spaces_________________________/-4 20000000 539 ns/op 328 B/op 7 allocs/op
|
no/17/urn:UrN:NSS__________________________________/-10 26922117 224.9 ns/op 371 B/op 5 allocs/op
|
||||||
no/18/urn:a:/______________________________________/-4 20000000 470 ns/op 320 B/op 7 allocs/op
|
no/18/urn:a:%______________________________________/-10 24926733 224.6 ns/op 371 B/op 5 allocs/op
|
||||||
no/19/urn:UrN:NSS__________________________________/-4 20000000 399 ns/op 288 B/op 6 allocs/op
|
no/19/urn:urn:NSS__________________________________/-10 27652641 220.7 ns/op 371 B/op 5 allocs/op
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
* <a name="mymachine">[1]</a>: Apple M1 Pro
|
||||||
|
|
||||||
* <a name="mymachine">[1]</a>: Intel Core i7-7600U CPU @ 2.80GHz
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
For more examples take a look at the [examples file](examples_test.go).
|
||||||
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -64,6 +78,35 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
var uid = "URN:foo:a123,456"
|
var uid = "URN:foo:a123,456"
|
||||||
|
|
||||||
|
// Parse the input string as a RFC 2141 URN only
|
||||||
|
u, e := urn.NewMachine().Parse(uid)
|
||||||
|
if e != nil {
|
||||||
|
fmt.Errorf(err)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(u.ID)
|
||||||
|
fmt.Println(u.SS)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// foo
|
||||||
|
// a123,456
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/leodido/go-urn"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var uid = "URN:foo:a123,456"
|
||||||
|
|
||||||
|
// Parse the input string as a RFC 2141 URN only
|
||||||
u, ok := urn.Parse([]byte(uid))
|
u, ok := urn.Parse([]byte(uid))
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("error parsing urn")
|
panic("error parsing urn")
|
||||||
|
@ -78,4 +121,33 @@ func main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
[![Analytics](https://ga-beacon.appspot.com/UA-49657176-1/go-urn?flat)](https://github.com/igrigorik/ga-beacon)
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/leodido/go-urn"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
input := "urn:ietf:params:scim:api:messages:2.0:ListResponse"
|
||||||
|
|
||||||
|
// Parsing the input string as a RFC 7643 SCIM URN
|
||||||
|
u, ok := urn.Parse([]byte(input), urn.WithParsingMode(urn.RFC7643Only))
|
||||||
|
if !ok {
|
||||||
|
panic("error parsing urn")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(u.IsSCIM())
|
||||||
|
scim := u.SCIM()
|
||||||
|
fmt.Println(scim.Type.String())
|
||||||
|
fmt.Println(scim.Name)
|
||||||
|
fmt.Println(scim.Other)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// api
|
||||||
|
// messages
|
||||||
|
// 2.0:ListResponse
|
||||||
|
}
|
||||||
|
```
|
10
vendor/github.com/leodido/go-urn/kind.go
generated
vendored
Normal file
10
vendor/github.com/leodido/go-urn/kind.go
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package urn
|
||||||
|
|
||||||
|
type Kind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
NONE Kind = iota
|
||||||
|
RFC2141
|
||||||
|
RFC7643
|
||||||
|
RFC8141
|
||||||
|
)
|
6292
vendor/github.com/leodido/go-urn/machine.go
generated
vendored
6292
vendor/github.com/leodido/go-urn/machine.go
generated
vendored
File diff suppressed because it is too large
Load diff
285
vendor/github.com/leodido/go-urn/machine.go.rl
generated
vendored
285
vendor/github.com/leodido/go-urn/machine.go.rl
generated
vendored
|
@ -2,15 +2,28 @@ package urn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
scimschema "github.com/leodido/go-urn/scim/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errPrefix = "expecting the prefix to be the \"urn\" string (whatever case) [col %d]"
|
errPrefix = "expecting the prefix to be the \"urn\" string (whatever case) [col %d]"
|
||||||
errIdentifier = "expecting the identifier to be string (1..31 alnum chars, also containing dashes but not at its start) [col %d]"
|
errIdentifier = "expecting the identifier to be string (1..31 alnum chars, also containing dashes but not at its beginning) [col %d]"
|
||||||
errSpecificString = "expecting the specific string to be a string containing alnum, hex, or others ([()+,-.:=@;$_!*']) chars [col %d]"
|
errSpecificString = "expecting the specific string to be a string containing alnum, hex, or others ([()+,-.:=@;$_!*']) chars [col %d]"
|
||||||
errNoUrnWithinID = "expecting the identifier to not contain the \"urn\" reserved string [col %d]"
|
errNoUrnWithinID = "expecting the identifier to not contain the \"urn\" reserved string [col %d]"
|
||||||
errHex = "expecting the specific string hex chars to be well-formed (%%alnum{2}) [col %d]"
|
errHex = "expecting the percent encoded chars to be well-formed (%%alnum{2}) [col %d]"
|
||||||
errParse = "parsing error [col %d]"
|
errSCIMNamespace = "expecing the SCIM namespace identifier (ietf:params:scim) [col %d]"
|
||||||
|
errSCIMType = "expecting a correct SCIM type (schemas, api, param) [col %d]"
|
||||||
|
errSCIMName = "expecting one or more alnum char in the SCIM name part [col %d]"
|
||||||
|
errSCIMOther = "expecting a well-formed other SCIM part [col %d]"
|
||||||
|
errSCIMOtherIncomplete = "expecting a not empty SCIM other part after colon [col %d]"
|
||||||
|
err8141InformalID = "informal URN namespace must be in the form urn-[1-9][0-9] [col %d]"
|
||||||
|
err8141SpecificString = "expecting the specific string to contain alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] not in first position) chars [col %d]"
|
||||||
|
err8141Identifier = "expecting the indentifier to be a string with (length 2 to 32 chars) containing alnum (or dashes) not starting or ending with a dash [col %d]"
|
||||||
|
err8141RComponentStart = "expecting only one r-component (starting with the ?+ sequence) [col %d]"
|
||||||
|
err8141QComponentStart = "expecting only one q-component (starting with the ?= sequence) [col %d]"
|
||||||
|
err8141MalformedRComp = "expecting a non-empty r-component containing alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] but not at its beginning) [col %d]"
|
||||||
|
err8141MalformedQComp = "expecting a non-empty q-component containing alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] but not at its beginning) [col %d]"
|
||||||
)
|
)
|
||||||
|
|
||||||
%%{
|
%%{
|
||||||
|
@ -24,25 +37,42 @@ action mark {
|
||||||
}
|
}
|
||||||
|
|
||||||
action tolower {
|
action tolower {
|
||||||
m.tolower = append(m.tolower, m.p - m.pb)
|
// List of positions in the buffer to later lowercase
|
||||||
|
output.tolower = append(output.tolower, m.p - m.pb)
|
||||||
}
|
}
|
||||||
|
|
||||||
action set_pre {
|
action set_pre {
|
||||||
output.prefix = string(m.text())
|
output.prefix = string(m.text())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action throw_pre_urn_err {
|
||||||
|
if m.parsingMode != RFC8141Only {
|
||||||
|
// Throw an error when:
|
||||||
|
// - we are entering here matching the the prefix in the namespace identifier part
|
||||||
|
// - looking ahead (3 chars) we find a colon
|
||||||
|
if pos := m.p + 3; pos < m.pe && m.data[pos] == 58 && output.prefix != "" {
|
||||||
|
m.err = fmt.Errorf(errNoUrnWithinID, pos)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
action set_nid {
|
action set_nid {
|
||||||
output.ID = string(m.text())
|
output.ID = string(m.text())
|
||||||
}
|
}
|
||||||
|
|
||||||
action set_nss {
|
action set_nss {
|
||||||
raw := m.text()
|
output.SS = string(m.text())
|
||||||
output.SS = string(raw)
|
|
||||||
// Iterate upper letters lowering them
|
// Iterate upper letters lowering them
|
||||||
for _, i := range m.tolower {
|
for _, i := range output.tolower {
|
||||||
raw[i] = raw[i] + 32
|
m.data[m.pb+i] = m.data[m.pb+i] + 32
|
||||||
|
}
|
||||||
|
output.norm = string(m.text())
|
||||||
|
// Revert the buffer to the original
|
||||||
|
for _, i := range output.tolower {
|
||||||
|
m.data[m.pb+i] = m.data[m.pb+i] - 32
|
||||||
}
|
}
|
||||||
output.norm = string(raw)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
action err_pre {
|
action err_pre {
|
||||||
|
@ -70,20 +100,20 @@ action err_urn {
|
||||||
}
|
}
|
||||||
|
|
||||||
action err_hex {
|
action err_hex {
|
||||||
m.err = fmt.Errorf(errHex, m.p)
|
if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
|
||||||
fhold;
|
m.err = fmt.Errorf(errHex, m.p)
|
||||||
fgoto fail;
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
action err_parse {
|
action base_type {
|
||||||
m.err = fmt.Errorf(errParse, m.p)
|
output.kind = RFC2141;
|
||||||
fhold;
|
|
||||||
fgoto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pre = ([uU][rR][nN] @err(err_pre)) >mark %set_pre;
|
pre = ([uU] @err(err_pre) [rR] @err(err_pre) [nN] @err(err_pre)) >mark >throw_pre_urn_err %set_pre;
|
||||||
|
|
||||||
nid = (alnum >mark (alnum | '-'){0,31}) %set_nid;
|
nid = (alnum >mark (alnum | '-'){0,31}) $err(err_nid) %set_nid;
|
||||||
|
|
||||||
hex = '%' (digit | lower | upper >tolower){2} $err(err_hex);
|
hex = '%' (digit | lower | upper >tolower){2} $err(err_hex);
|
||||||
|
|
||||||
|
@ -91,9 +121,179 @@ sss = (alnum | [()+,\-.:=@;$_!*']);
|
||||||
|
|
||||||
nss = (sss | hex)+ $err(err_nss);
|
nss = (sss | hex)+ $err(err_nss);
|
||||||
|
|
||||||
|
nid_not_urn = (nid - pre %err(err_urn));
|
||||||
|
|
||||||
|
urn = pre ':' @err(err_pre) (nid_not_urn ':' nss >mark %set_nss) %eof(base_type);
|
||||||
|
|
||||||
|
### SCIM BEG
|
||||||
|
|
||||||
|
action err_scim_nid {
|
||||||
|
m.err = fmt.Errorf(errSCIMNamespace, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
action err_scim_type {
|
||||||
|
m.err = fmt.Errorf(errSCIMType, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
action err_scim_name {
|
||||||
|
m.err = fmt.Errorf(errSCIMName, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
action err_scim_other {
|
||||||
|
if m.p == m.pe {
|
||||||
|
m.err = fmt.Errorf(errSCIMOtherIncomplete, m.p-1)
|
||||||
|
} else {
|
||||||
|
m.err = fmt.Errorf(errSCIMOther, m.p)
|
||||||
|
}
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
action scim_type {
|
||||||
|
output.kind = RFC7643;
|
||||||
|
}
|
||||||
|
|
||||||
|
action create_scim {
|
||||||
|
output.scim = &SCIM{};
|
||||||
|
}
|
||||||
|
|
||||||
|
action set_scim_type {
|
||||||
|
output.scim.Type = scimschema.TypeFromString(string(m.text()))
|
||||||
|
}
|
||||||
|
|
||||||
|
action mark_scim_name {
|
||||||
|
output.scim.pos = m.p
|
||||||
|
}
|
||||||
|
|
||||||
|
action set_scim_name {
|
||||||
|
output.scim.Name = string(m.data[output.scim.pos:m.p])
|
||||||
|
}
|
||||||
|
|
||||||
|
action mark_scim_other {
|
||||||
|
output.scim.pos = m.p
|
||||||
|
}
|
||||||
|
|
||||||
|
action set_scim_other {
|
||||||
|
output.scim.Other = string(m.data[output.scim.pos:m.p])
|
||||||
|
}
|
||||||
|
|
||||||
|
scim_nid = 'ietf:params:scim' >mark %set_nid %create_scim $err(err_scim_nid);
|
||||||
|
|
||||||
|
scim_other = ':' (sss | hex)+ >mark_scim_other %set_scim_other $err(err_scim_other);
|
||||||
|
|
||||||
|
scim_name = (alnum)+ >mark_scim_name %set_scim_name $err(err_scim_name);
|
||||||
|
|
||||||
|
scim_type = ('schemas' | 'api' | 'param') >mark %set_scim_type $err(err_scim_type);
|
||||||
|
|
||||||
|
scim_only := pre ':' @err(err_pre) (scim_nid ':' scim_type ':' scim_name scim_other? %set_nss) %eof(scim_type);
|
||||||
|
|
||||||
|
### SCIM END
|
||||||
|
|
||||||
|
### 8141 BEG
|
||||||
|
|
||||||
|
action err_nss_8141 {
|
||||||
|
m.err = fmt.Errorf(err8141SpecificString, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
action err_nid_8141 {
|
||||||
|
m.err = fmt.Errorf(err8141Identifier, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
action rfc8141_type {
|
||||||
|
output.kind = RFC8141;
|
||||||
|
}
|
||||||
|
|
||||||
|
action set_r_component {
|
||||||
|
output.rComponent = string(m.text())
|
||||||
|
}
|
||||||
|
|
||||||
|
action set_q_component {
|
||||||
|
output.qComponent = string(m.text())
|
||||||
|
}
|
||||||
|
|
||||||
|
action set_f_component {
|
||||||
|
output.fComponent = string(m.text())
|
||||||
|
}
|
||||||
|
|
||||||
|
action informal_nid_match {
|
||||||
|
fhold;
|
||||||
|
m.err = fmt.Errorf(err8141InformalID, m.p);
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
action mark_r_start {
|
||||||
|
if output.rStart {
|
||||||
|
m.err = fmt.Errorf(err8141RComponentStart, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
output.rStart = true
|
||||||
|
}
|
||||||
|
|
||||||
|
action mark_q_start {
|
||||||
|
if output.qStart {
|
||||||
|
m.err = fmt.Errorf(err8141QComponentStart, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
output.qStart = true
|
||||||
|
}
|
||||||
|
|
||||||
|
action err_malformed_r_component {
|
||||||
|
m.err = fmt.Errorf(err8141MalformedRComp, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
action err_malformed_q_component {
|
||||||
|
m.err = fmt.Errorf(err8141MalformedQComp, m.p)
|
||||||
|
fhold;
|
||||||
|
fgoto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
pchar = (sss | '~' | '&' | hex);
|
||||||
|
|
||||||
|
component = pchar (pchar | '/' | '?')*;
|
||||||
|
|
||||||
|
r_start = ('?+') %mark_r_start;
|
||||||
|
|
||||||
|
r_component = r_start <: (r_start | component)+ $err(err_malformed_r_component) >mark %set_r_component;
|
||||||
|
|
||||||
|
q_start = ('?=') %mark_q_start;
|
||||||
|
|
||||||
|
q_component = q_start <: (q_start | component)+ $err(err_malformed_q_component) >mark %set_q_component;
|
||||||
|
|
||||||
|
rq_components = (r_component :>> q_component? | q_component);
|
||||||
|
|
||||||
|
fragment = (pchar | '/' | '?')*;
|
||||||
|
|
||||||
|
f_component = '#' fragment >mark %set_f_component;
|
||||||
|
|
||||||
|
nss_rfc8141 = (pchar >mark (pchar | '/')*) $err(err_nss_8141) %set_nss;
|
||||||
|
|
||||||
|
nid_rfc8141 = (alnum >mark (alnum | '-'){0,30} alnum) $err(err_nid_8141) %set_nid;
|
||||||
|
|
||||||
|
informal_id = pre ('-' [a-zA-z0] %to(informal_nid_match));
|
||||||
|
|
||||||
|
nid_rfc8141_not_urn = (nid_rfc8141 - informal_id?);
|
||||||
|
|
||||||
|
rfc8141_only := pre ':' @err(err_pre) nid_rfc8141_not_urn ':' nss_rfc8141 rq_components? f_component? %eof(rfc8141_type);
|
||||||
|
|
||||||
|
### 8141 END
|
||||||
|
|
||||||
fail := (any - [\n\r])* @err{ fgoto main; };
|
fail := (any - [\n\r])* @err{ fgoto main; };
|
||||||
|
|
||||||
main := (pre ':' (nid - pre %err(err_urn)) $err(err_nid) ':' nss >mark %set_nss) $err(err_parse);
|
main := urn;
|
||||||
|
|
||||||
}%%
|
}%%
|
||||||
|
|
||||||
|
@ -103,6 +303,7 @@ main := (pre ':' (nid - pre %err(err_urn)) $err(err_nid) ':' nss >mark %set_nss)
|
||||||
type Machine interface {
|
type Machine interface {
|
||||||
Error() error
|
Error() error
|
||||||
Parse(input []byte) (*URN, error)
|
Parse(input []byte) (*URN, error)
|
||||||
|
WithParsingMode(ParsingMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
type machine struct {
|
type machine struct {
|
||||||
|
@ -110,12 +311,24 @@ type machine struct {
|
||||||
cs int
|
cs int
|
||||||
p, pe, eof, pb int
|
p, pe, eof, pb int
|
||||||
err error
|
err error
|
||||||
tolower []int
|
startParsingAt int
|
||||||
|
parsingMode ParsingMode
|
||||||
|
parsingModeSet bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMachine creates a new FSM able to parse RFC 2141 strings.
|
// NewMachine creates a new FSM able to parse RFC 2141 strings.
|
||||||
func NewMachine() Machine {
|
func NewMachine(options ...Option) Machine {
|
||||||
m := &machine{}
|
m := &machine{
|
||||||
|
parsingModeSet: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range options {
|
||||||
|
o(m)
|
||||||
|
}
|
||||||
|
// Set default parsing mode
|
||||||
|
if !m.parsingModeSet {
|
||||||
|
m.WithParsingMode(DefaultParsingMode)
|
||||||
|
}
|
||||||
|
|
||||||
%% access m.;
|
%% access m.;
|
||||||
%% variable p m.p;
|
%% variable p m.p;
|
||||||
|
@ -137,7 +350,7 @@ func (m *machine) text() []byte {
|
||||||
return m.data[m.pb:m.p]
|
return m.data[m.pb:m.p]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse parses the input byte array as a RFC 2141 string.
|
// Parse parses the input byte array as a RFC 2141 or RFC7643 string.
|
||||||
func (m *machine) Parse(input []byte) (*URN, error) {
|
func (m *machine) Parse(input []byte) (*URN, error) {
|
||||||
m.data = input
|
m.data = input
|
||||||
m.p = 0
|
m.p = 0
|
||||||
|
@ -145,10 +358,11 @@ func (m *machine) Parse(input []byte) (*URN, error) {
|
||||||
m.pe = len(input)
|
m.pe = len(input)
|
||||||
m.eof = len(input)
|
m.eof = len(input)
|
||||||
m.err = nil
|
m.err = nil
|
||||||
m.tolower = []int{}
|
m.cs = m.startParsingAt
|
||||||
output := &URN{}
|
output := &URN{
|
||||||
|
tolower: []int{},
|
||||||
|
}
|
||||||
|
|
||||||
%% write init;
|
|
||||||
%% write exec;
|
%% write exec;
|
||||||
|
|
||||||
if m.cs < first_final || m.cs == en_fail {
|
if m.cs < first_final || m.cs == en_fail {
|
||||||
|
@ -157,3 +371,16 @@ func (m *machine) Parse(input []byte) (*URN, error) {
|
||||||
|
|
||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *machine) WithParsingMode(x ParsingMode) {
|
||||||
|
m.parsingMode = x
|
||||||
|
switch m.parsingMode {
|
||||||
|
case RFC2141Only:
|
||||||
|
m.startParsingAt = en_main
|
||||||
|
case RFC8141Only:
|
||||||
|
m.startParsingAt = en_rfc8141_only
|
||||||
|
case RFC7643Only:
|
||||||
|
m.startParsingAt = en_scim_only
|
||||||
|
}
|
||||||
|
m.parsingModeSet = true
|
||||||
|
}
|
18
vendor/github.com/leodido/go-urn/makefile
generated
vendored
18
vendor/github.com/leodido/go-urn/makefile
generated
vendored
|
@ -15,18 +15,24 @@ clean:
|
||||||
.PHONY: images
|
.PHONY: images
|
||||||
images: docs/urn.png
|
images: docs/urn.png
|
||||||
|
|
||||||
|
.PHONY: snake2camel
|
||||||
|
snake2camel:
|
||||||
|
@cd ./tools/snake2camel; go build -o ../../snake2camel .
|
||||||
|
|
||||||
.PHONY: removecomments
|
.PHONY: removecomments
|
||||||
removecomments:
|
removecomments:
|
||||||
@cd ./tools/removecomments; go build -o ../../removecomments .
|
@cd ./tools/removecomments; go build -o ../../removecomments .
|
||||||
|
|
||||||
machine.go: machine.go.rl
|
machine.go: machine.go.rl
|
||||||
|
|
||||||
|
machine.go: snake2camel
|
||||||
|
|
||||||
machine.go: removecomments
|
machine.go: removecomments
|
||||||
|
|
||||||
machine.go:
|
machine.go:
|
||||||
$(RAGEL) -Z -G2 -e -o $@ $<
|
$(RAGEL) -Z -G1 -e -o $@ $<
|
||||||
@./removecomments $@
|
@./removecomments $@
|
||||||
$(MAKE) -s file=$@ snake2camel
|
@./snake2camel $@
|
||||||
$(GOFMT) $@
|
$(GOFMT) $@
|
||||||
|
|
||||||
docs/urn.dot: machine.go.rl
|
docs/urn.dot: machine.go.rl
|
||||||
|
@ -43,11 +49,3 @@ bench: *_test.go machine.go
|
||||||
.PHONY: tests
|
.PHONY: tests
|
||||||
tests: *_test.go
|
tests: *_test.go
|
||||||
$(GO_TEST) ./...
|
$(GO_TEST) ./...
|
||||||
|
|
||||||
.PHONY: snake2camel
|
|
||||||
snake2camel:
|
|
||||||
@awk -i inplace '{ \
|
|
||||||
while ( match($$0, /(.*)([a-z]+[0-9]*)_([a-zA-Z0-9])(.*)/, cap) ) \
|
|
||||||
$$0 = cap[1] cap[2] toupper(cap[3]) cap[4]; \
|
|
||||||
print \
|
|
||||||
}' $(file)
|
|
||||||
|
|
9
vendor/github.com/leodido/go-urn/options.go
generated
vendored
Normal file
9
vendor/github.com/leodido/go-urn/options.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package urn
|
||||||
|
|
||||||
|
type Option func(Machine)
|
||||||
|
|
||||||
|
func WithParsingMode(mode ParsingMode) Option {
|
||||||
|
return func(m Machine) {
|
||||||
|
m.WithParsingMode(mode)
|
||||||
|
}
|
||||||
|
}
|
12
vendor/github.com/leodido/go-urn/parsing_mode.go
generated
vendored
Normal file
12
vendor/github.com/leodido/go-urn/parsing_mode.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package urn
|
||||||
|
|
||||||
|
type ParsingMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Default ParsingMode = iota
|
||||||
|
RFC2141Only
|
||||||
|
RFC7643Only
|
||||||
|
RFC8141Only
|
||||||
|
)
|
||||||
|
|
||||||
|
const DefaultParsingMode = RFC2141Only
|
48
vendor/github.com/leodido/go-urn/scim.go
generated
vendored
Normal file
48
vendor/github.com/leodido/go-urn/scim.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package urn
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
scimschema "github.com/leodido/go-urn/scim/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const errInvalidSCIMURN = "invalid SCIM URN: %s"
|
||||||
|
|
||||||
|
type SCIM struct {
|
||||||
|
Type scimschema.Type
|
||||||
|
Name string
|
||||||
|
Other string
|
||||||
|
pos int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SCIM) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(s.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SCIM) UnmarshalJSON(bytes []byte) error {
|
||||||
|
var str string
|
||||||
|
if err := json.Unmarshal(bytes, &str); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Parse as SCIM
|
||||||
|
value, ok := Parse([]byte(str), WithParsingMode(RFC7643Only))
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf(errInvalidSCIMURN, str)
|
||||||
|
}
|
||||||
|
if value.RFC() != RFC7643 {
|
||||||
|
return fmt.Errorf(errInvalidSCIMURN, str)
|
||||||
|
}
|
||||||
|
*s = *value.SCIM()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SCIM) String() string {
|
||||||
|
ret := fmt.Sprintf("urn:ietf:params:scim:%s:%s", s.Type.String(), s.Name)
|
||||||
|
if s.Other != "" {
|
||||||
|
ret += fmt.Sprintf(":%s", s.Other)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
36
vendor/github.com/leodido/go-urn/scim/schema/type.go
generated
vendored
Normal file
36
vendor/github.com/leodido/go-urn/scim/schema/type.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package scimschema
|
||||||
|
|
||||||
|
type Type int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Unsupported Type = iota
|
||||||
|
Schemas
|
||||||
|
API
|
||||||
|
Param
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t Type) String() string {
|
||||||
|
switch t {
|
||||||
|
case Schemas:
|
||||||
|
return "schemas"
|
||||||
|
case API:
|
||||||
|
return "api"
|
||||||
|
case Param:
|
||||||
|
return "param"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func TypeFromString(input string) Type {
|
||||||
|
switch input {
|
||||||
|
case "schemas":
|
||||||
|
return Schemas
|
||||||
|
case "api":
|
||||||
|
return API
|
||||||
|
case "param":
|
||||||
|
return Param
|
||||||
|
}
|
||||||
|
|
||||||
|
return Unsupported
|
||||||
|
}
|
73
vendor/github.com/leodido/go-urn/urn.go
generated
vendored
73
vendor/github.com/leodido/go-urn/urn.go
generated
vendored
|
@ -16,10 +16,18 @@ const errInvalidURN = "invalid URN: %s"
|
||||||
//
|
//
|
||||||
// Details at https://tools.ietf.org/html/rfc2141.
|
// Details at https://tools.ietf.org/html/rfc2141.
|
||||||
type URN struct {
|
type URN struct {
|
||||||
prefix string // Static prefix. Equal to "urn" when empty.
|
prefix string // Static prefix. Equal to "urn" when empty.
|
||||||
ID string // Namespace identifier
|
ID string // Namespace identifier (NID)
|
||||||
SS string // Namespace specific string
|
SS string // Namespace specific string (NSS)
|
||||||
norm string // Normalized namespace specific string
|
norm string // Normalized namespace specific string
|
||||||
|
kind Kind
|
||||||
|
scim *SCIM
|
||||||
|
rComponent string // RFC8141
|
||||||
|
qComponent string // RFC8141
|
||||||
|
fComponent string // RFC8141
|
||||||
|
rStart bool // RFC8141
|
||||||
|
qStart bool // RFC8141
|
||||||
|
tolower []int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize turns the receiving URN into its norm version.
|
// Normalize turns the receiving URN into its norm version.
|
||||||
|
@ -30,12 +38,21 @@ func (u *URN) Normalize() *URN {
|
||||||
prefix: "urn",
|
prefix: "urn",
|
||||||
ID: strings.ToLower(u.ID),
|
ID: strings.ToLower(u.ID),
|
||||||
SS: u.norm,
|
SS: u.norm,
|
||||||
|
// rComponent: u.rComponent,
|
||||||
|
// qComponent: u.qComponent,
|
||||||
|
// fComponent: u.fComponent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal checks the lexical equivalence of the current URN with another one.
|
// Equal checks the lexical equivalence of the current URN with another one.
|
||||||
func (u *URN) Equal(x *URN) bool {
|
func (u *URN) Equal(x *URN) bool {
|
||||||
return *u.Normalize() == *x.Normalize()
|
if x == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
nu := u.Normalize()
|
||||||
|
nx := x.Normalize()
|
||||||
|
|
||||||
|
return nu.prefix == nx.prefix && nu.ID == nx.ID && nu.SS == nx.SS
|
||||||
}
|
}
|
||||||
|
|
||||||
// String reassembles the URN into a valid URN string.
|
// String reassembles the URN into a valid URN string.
|
||||||
|
@ -51,14 +68,23 @@ func (u *URN) String() string {
|
||||||
res += "urn"
|
res += "urn"
|
||||||
}
|
}
|
||||||
res += u.prefix + ":" + u.ID + ":" + u.SS
|
res += u.prefix + ":" + u.ID + ":" + u.SS
|
||||||
|
if u.rComponent != "" {
|
||||||
|
res += "?+" + u.rComponent
|
||||||
|
}
|
||||||
|
if u.qComponent != "" {
|
||||||
|
res += "?=" + u.qComponent
|
||||||
|
}
|
||||||
|
if u.fComponent != "" {
|
||||||
|
res += "#" + u.fComponent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse is responsible to create an URN instance from a byte array matching the correct URN syntax.
|
// Parse is responsible to create an URN instance from a byte array matching the correct URN syntax (RFC 2141).
|
||||||
func Parse(u []byte) (*URN, bool) {
|
func Parse(u []byte, options ...Option) (*URN, bool) {
|
||||||
urn, err := NewMachine().Parse(u)
|
urn, err := NewMachine(options...).Parse(u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -71,7 +97,7 @@ func (u URN) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(u.String())
|
return json.Marshal(u.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON unmarshals a URN from JSON string form (e.g. `"urn:oid:1.2.3.4"`).
|
// UnmarshalJSON unmarshals a URN from JSON string form (e.g. `"urn:oid:1.2.3.4"`).
|
||||||
func (u *URN) UnmarshalJSON(bytes []byte) error {
|
func (u *URN) UnmarshalJSON(bytes []byte) error {
|
||||||
var str string
|
var str string
|
||||||
if err := json.Unmarshal(bytes, &str); err != nil {
|
if err := json.Unmarshal(bytes, &str); err != nil {
|
||||||
|
@ -82,5 +108,34 @@ func (u *URN) UnmarshalJSON(bytes []byte) error {
|
||||||
} else {
|
} else {
|
||||||
*u = *value
|
*u = *value
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *URN) IsSCIM() bool {
|
||||||
|
return u.kind == RFC7643
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URN) SCIM() *SCIM {
|
||||||
|
if u.kind != RFC7643 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.scim
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URN) RFC() Kind {
|
||||||
|
return u.kind
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URN) FComponent() string {
|
||||||
|
return u.fComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URN) QComponent() string {
|
||||||
|
return u.qComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URN) RComponent() string {
|
||||||
|
return u.rComponent
|
||||||
|
}
|
||||||
|
|
30
vendor/github.com/leodido/go-urn/urn8141.go
generated
vendored
Normal file
30
vendor/github.com/leodido/go-urn/urn8141.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package urn
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const errInvalidURN8141 = "invalid URN per RFC 8141: %s"
|
||||||
|
|
||||||
|
type URN8141 struct {
|
||||||
|
*URN
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u URN8141) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(u.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URN8141) UnmarshalJSON(bytes []byte) error {
|
||||||
|
var str string
|
||||||
|
if err := json.Unmarshal(bytes, &str); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if value, ok := Parse([]byte(str), WithParsingMode(RFC8141Only)); !ok {
|
||||||
|
return fmt.Errorf(errInvalidURN8141, str)
|
||||||
|
} else {
|
||||||
|
*u = URN8141{value}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
23
vendor/github.com/ugorji/go/codec/cbor.go
generated
vendored
23
vendor/github.com/ugorji/go/codec/cbor.go
generated
vendored
|
@ -123,6 +123,11 @@ type cborEncDriver struct {
|
||||||
encDriverNoopContainerWriter
|
encDriverNoopContainerWriter
|
||||||
h *CborHandle
|
h *CborHandle
|
||||||
|
|
||||||
|
// scratch buffer for: encode time, numbers, etc
|
||||||
|
//
|
||||||
|
// RFC3339Nano uses 35 chars: 2006-01-02T15:04:05.999999999Z07:00
|
||||||
|
b [40]byte
|
||||||
|
|
||||||
e Encoder
|
e Encoder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +209,7 @@ func (e *cborEncDriver) EncodeTime(t time.Time) {
|
||||||
e.EncodeNil()
|
e.EncodeNil()
|
||||||
} else if e.h.TimeRFC3339 {
|
} else if e.h.TimeRFC3339 {
|
||||||
e.encUint(0, cborBaseTag)
|
e.encUint(0, cborBaseTag)
|
||||||
e.encStringBytesS(cborBaseString, t.Format(time.RFC3339Nano))
|
e.encStringBytesS(cborBaseString, stringView(fmtTime(t, time.RFC3339Nano, e.b[:0])))
|
||||||
} else {
|
} else {
|
||||||
e.encUint(1, cborBaseTag)
|
e.encUint(1, cborBaseTag)
|
||||||
t = t.UTC().Round(time.Microsecond)
|
t = t.UTC().Round(time.Microsecond)
|
||||||
|
@ -427,12 +432,13 @@ func (d *cborDecDriver) decLen() int {
|
||||||
return int(d.decUint())
|
return int(d.decUint())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
|
func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte, major byte) []byte {
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
for !d.CheckBreak() {
|
for !d.CheckBreak() {
|
||||||
if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorString {
|
chunkMajor := d.bd >> 5
|
||||||
d.d.errorf("invalid indefinite string/bytes %x (%s); got major %v, expected %v or %v",
|
if chunkMajor != major {
|
||||||
d.bd, cbordesc(d.bd), major, cborMajorBytes, cborMajorString)
|
d.d.errorf("malformed indefinite string/bytes %x (%s); contains chunk with major type %v, expected %v",
|
||||||
|
d.bd, cbordesc(d.bd), chunkMajor, major)
|
||||||
}
|
}
|
||||||
n := uint(d.decLen())
|
n := uint(d.decLen())
|
||||||
oldLen := uint(len(bs))
|
oldLen := uint(len(bs))
|
||||||
|
@ -445,6 +451,9 @@ func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
|
||||||
bs = bs[:newLen]
|
bs = bs[:newLen]
|
||||||
}
|
}
|
||||||
d.d.decRd.readb(bs[oldLen:newLen])
|
d.d.decRd.readb(bs[oldLen:newLen])
|
||||||
|
if d.h.ValidateUnicode && major == cborMajorString && !utf8.Valid(bs[oldLen:newLen]) {
|
||||||
|
d.d.errorf("indefinite-length text string contains chunk that is not a valid utf-8 sequence: 0x%x", bs[oldLen:newLen])
|
||||||
|
}
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
}
|
}
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
|
@ -580,9 +589,9 @@ func (d *cborDecDriver) DecodeBytes(bs []byte) (bsOut []byte) {
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
if bs == nil {
|
if bs == nil {
|
||||||
d.d.decByteState = decByteStateReuseBuf
|
d.d.decByteState = decByteStateReuseBuf
|
||||||
return d.decAppendIndefiniteBytes(d.d.b[:0])
|
return d.decAppendIndefiniteBytes(d.d.b[:0], d.bd>>5)
|
||||||
}
|
}
|
||||||
return d.decAppendIndefiniteBytes(bs[:0])
|
return d.decAppendIndefiniteBytes(bs[:0], d.bd>>5)
|
||||||
}
|
}
|
||||||
if d.bd == cborBdIndefiniteArray {
|
if d.bd == cborBdIndefiniteArray {
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
|
|
13
vendor/github.com/ugorji/go/codec/decode.go
generated
vendored
13
vendor/github.com/ugorji/go/codec/decode.go
generated
vendored
|
@ -1399,6 +1399,10 @@ func NewDecoderString(s string, h Handle) *Decoder {
|
||||||
return NewDecoderBytes(bytesView(s), h)
|
return NewDecoderBytes(bytesView(s), h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) HandleName() string {
|
||||||
|
return d.hh.Name()
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Decoder) r() *decRd {
|
func (d *Decoder) r() *decRd {
|
||||||
return &d.decRd
|
return &d.decRd
|
||||||
}
|
}
|
||||||
|
@ -1580,14 +1584,9 @@ func (d *Decoder) MustDecode(v interface{}) {
|
||||||
d.calls--
|
d.calls--
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release releases shared (pooled) resources.
|
// Release is a no-op.
|
||||||
//
|
//
|
||||||
// It is important to call Release() when done with a Decoder, so those resources
|
// Deprecated: Pooled resources are not used with a Decoder.
|
||||||
// are released instantly for use by subsequently created Decoders.
|
|
||||||
//
|
|
||||||
// By default, Release() is automatically called unless the option ExplicitRelease is set.
|
|
||||||
//
|
|
||||||
// Deprecated: Release is a no-op as pooled resources are not used with an Decoder.
|
|
||||||
// This method is kept for compatibility reasons only.
|
// This method is kept for compatibility reasons only.
|
||||||
func (d *Decoder) Release() {
|
func (d *Decoder) Release() {
|
||||||
}
|
}
|
||||||
|
|
11
vendor/github.com/ugorji/go/codec/encode.go
generated
vendored
11
vendor/github.com/ugorji/go/codec/encode.go
generated
vendored
|
@ -984,6 +984,10 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) HandleName() string {
|
||||||
|
return e.hh.Name()
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Encoder) init(h Handle) {
|
func (e *Encoder) init(h Handle) {
|
||||||
initHandle(h)
|
initHandle(h)
|
||||||
e.err = errEncoderNotInitialized
|
e.err = errEncoderNotInitialized
|
||||||
|
@ -1150,12 +1154,9 @@ func (e *Encoder) MustEncode(v interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release releases shared (pooled) resources.
|
// Release is a no-op.
|
||||||
//
|
//
|
||||||
// It is important to call Release() when done with an Encoder, so those resources
|
// Deprecated: Pooled resources are not used with an Encoder.
|
||||||
// are released instantly for use by subsequently created Encoders.
|
|
||||||
//
|
|
||||||
// Deprecated: Release is a no-op as pooled resources are not used with an Encoder.
|
|
||||||
// This method is kept for compatibility reasons only.
|
// This method is kept for compatibility reasons only.
|
||||||
func (e *Encoder) Release() {
|
func (e *Encoder) Release() {
|
||||||
}
|
}
|
||||||
|
|
16
vendor/github.com/ugorji/go/codec/gen.go
generated
vendored
16
vendor/github.com/ugorji/go/codec/gen.go
generated
vendored
|
@ -8,7 +8,7 @@ package codec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base32"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/format"
|
"go/format"
|
||||||
|
@ -190,7 +190,11 @@ var (
|
||||||
errGenExpectArrayOrMap = errors.New("unexpected type - expecting array/map/slice")
|
errGenExpectArrayOrMap = errors.New("unexpected type - expecting array/map/slice")
|
||||||
errGenUnexpectedTypeFastpath = errors.New("fast-path: unexpected type - requires map or slice")
|
errGenUnexpectedTypeFastpath = errors.New("fast-path: unexpected type - requires map or slice")
|
||||||
|
|
||||||
genBase64enc = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789__")
|
// don't use base64, only 63 characters allowed in valid go identifiers
|
||||||
|
// ie ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_
|
||||||
|
//
|
||||||
|
// don't use numbers, as a valid go identifer must start with a letter.
|
||||||
|
genTypenameEnc = base32.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef")
|
||||||
genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`)
|
genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2303,8 +2307,6 @@ func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// best way to get the package name inclusive
|
// best way to get the package name inclusive
|
||||||
// return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
|
|
||||||
// return ptrPfx + genBase64enc.EncodeToString([]byte(tstr))
|
|
||||||
if t.Name() != "" && genQNameRegex.MatchString(tstr) {
|
if t.Name() != "" && genQNameRegex.MatchString(tstr) {
|
||||||
return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
|
return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2315,12 +2317,12 @@ func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// genCustomNameForType base64encodes the t.String() value in such a way
|
// genCustomNameForType base32 encodes the t.String() value in such a way
|
||||||
// that it can be used within a function name.
|
// that it can be used within a function name.
|
||||||
func genCustomTypeName(tstr string) string {
|
func genCustomTypeName(tstr string) string {
|
||||||
len2 := genBase64enc.EncodedLen(len(tstr))
|
len2 := genTypenameEnc.EncodedLen(len(tstr))
|
||||||
bufx := make([]byte, len2)
|
bufx := make([]byte, len2)
|
||||||
genBase64enc.Encode(bufx, []byte(tstr))
|
genTypenameEnc.Encode(bufx, []byte(tstr))
|
||||||
for i := len2 - 1; i >= 0; i-- {
|
for i := len2 - 1; i >= 0; i-- {
|
||||||
if bufx[i] == '=' {
|
if bufx[i] == '=' {
|
||||||
len2--
|
len2--
|
||||||
|
|
31
vendor/github.com/ugorji/go/codec/helper.go
generated
vendored
31
vendor/github.com/ugorji/go/codec/helper.go
generated
vendored
|
@ -110,8 +110,7 @@ package codec
|
||||||
//
|
//
|
||||||
// ------------------------------------------
|
// ------------------------------------------
|
||||||
// Bounds Checking
|
// Bounds Checking
|
||||||
// - Allow bytesDecReader to incur "bounds check error", and
|
// - Allow bytesDecReader to incur "bounds check error", and recover that as an io error.
|
||||||
// recover that as an io.EOF.
|
|
||||||
// This allows the bounds check branch to always be taken by the branch predictor,
|
// This allows the bounds check branch to always be taken by the branch predictor,
|
||||||
// giving better performance (in theory), while ensuring that the code is shorter.
|
// giving better performance (in theory), while ensuring that the code is shorter.
|
||||||
//
|
//
|
||||||
|
@ -857,26 +856,10 @@ type BasicHandle struct {
|
||||||
// Once a Handle has been initialized (used), do not modify this option. It will be ignored.
|
// Once a Handle has been initialized (used), do not modify this option. It will be ignored.
|
||||||
TimeNotBuiltin bool
|
TimeNotBuiltin bool
|
||||||
|
|
||||||
// ExplicitRelease configures whether Release() is implicitly called after an encode or
|
// ExplicitRelease is ignored and has no effect.
|
||||||
// decode call.
|
|
||||||
//
|
//
|
||||||
// If you will hold onto an Encoder or Decoder for re-use, by calling Reset(...)
|
// Deprecated: Pools are only used for long-lived objects shared across goroutines.
|
||||||
// on it or calling (Must)Encode repeatedly into a given []byte or io.Writer,
|
// It is maintained for backward compatibility.
|
||||||
// then you do not want it to be implicitly closed after each Encode/Decode call.
|
|
||||||
// Doing so will unnecessarily return resources to the shared pool, only for you to
|
|
||||||
// grab them right after again to do another Encode/Decode call.
|
|
||||||
//
|
|
||||||
// Instead, you configure ExplicitRelease=true, and you explicitly call Release() when
|
|
||||||
// you are truly done.
|
|
||||||
//
|
|
||||||
// As an alternative, you can explicitly set a finalizer - so its resources
|
|
||||||
// are returned to the shared pool before it is garbage-collected. Do it as below:
|
|
||||||
// runtime.SetFinalizer(e, (*Encoder).Release)
|
|
||||||
// runtime.SetFinalizer(d, (*Decoder).Release)
|
|
||||||
//
|
|
||||||
// Deprecated: This is not longer used as pools are only used for long-lived objects
|
|
||||||
// which are shared across goroutines.
|
|
||||||
// Setting this value has no effect. It is maintained for backward compatibility.
|
|
||||||
ExplicitRelease bool
|
ExplicitRelease bool
|
||||||
|
|
||||||
// ---- cache line
|
// ---- cache line
|
||||||
|
@ -2489,7 +2472,7 @@ func panicValToErr(h errDecorator, v interface{}, err *error) {
|
||||||
case runtime.Error:
|
case runtime.Error:
|
||||||
d, dok := h.(*Decoder)
|
d, dok := h.(*Decoder)
|
||||||
if dok && d.bytes && isSliceBoundsError(xerr.Error()) {
|
if dok && d.bytes && isSliceBoundsError(xerr.Error()) {
|
||||||
*err = io.EOF
|
*err = io.ErrUnexpectedEOF
|
||||||
} else {
|
} else {
|
||||||
h.wrapErr(xerr, err)
|
h.wrapErr(xerr, err)
|
||||||
}
|
}
|
||||||
|
@ -2803,7 +2786,7 @@ func freelistCapacity(length int) (capacity int) {
|
||||||
// bytesFreelist is a list of byte buffers, sorted by cap.
|
// bytesFreelist is a list of byte buffers, sorted by cap.
|
||||||
//
|
//
|
||||||
// In anecdotal testing (running go test -tsd 1..6), we couldn't get
|
// In anecdotal testing (running go test -tsd 1..6), we couldn't get
|
||||||
// the length ofthe list > 4 at any time. So we believe a linear search
|
// the length of the list > 4 at any time. So we believe a linear search
|
||||||
// without bounds checking is sufficient.
|
// without bounds checking is sufficient.
|
||||||
//
|
//
|
||||||
// Typical usage model:
|
// Typical usage model:
|
||||||
|
@ -2821,7 +2804,7 @@ func freelistCapacity(length int) (capacity int) {
|
||||||
// v1 := v0
|
// v1 := v0
|
||||||
// ... use v1 ...
|
// ... use v1 ...
|
||||||
// blist.put(v1)
|
// blist.put(v1)
|
||||||
// if byteSliceAddr(v0) != byteSliceAddr(v1) {
|
// if !byteSliceSameData(v0, v1) {
|
||||||
// blist.put(v0)
|
// blist.put(v0)
|
||||||
// }
|
// }
|
||||||
type bytesFreelist [][]byte
|
type bytesFreelist [][]byte
|
||||||
|
|
3
vendor/github.com/ugorji/go/codec/json.go
generated
vendored
3
vendor/github.com/ugorji/go/codec/json.go
generated
vendored
|
@ -1301,6 +1301,9 @@ func (d *jsonDecDriver) DecodeNaked() {
|
||||||
// Note also that the float values for NaN, +Inf or -Inf are encoded as null,
|
// Note also that the float values for NaN, +Inf or -Inf are encoded as null,
|
||||||
// as suggested by NOTE 4 of the ECMA-262 ECMAScript Language Specification 5.1 edition.
|
// as suggested by NOTE 4 of the ECMA-262 ECMAScript Language Specification 5.1 edition.
|
||||||
// see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf .
|
// see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf .
|
||||||
|
//
|
||||||
|
// Note the following behaviour differences vs std-library encoding/json package:
|
||||||
|
// - struct field names matched in case-sensitive manner
|
||||||
type JsonHandle struct {
|
type JsonHandle struct {
|
||||||
textEncodingType
|
textEncodingType
|
||||||
BasicHandle
|
BasicHandle
|
||||||
|
|
2
vendor/github.com/ugorji/go/codec/msgpack.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/msgpack.go
generated
vendored
|
@ -1174,7 +1174,7 @@ func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error {
|
||||||
|
|
||||||
func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
|
func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
|
||||||
if cls := c.cls.load(); cls.closed {
|
if cls := c.cls.load(); cls.closed {
|
||||||
return io.EOF
|
return io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
|
|
||||||
// We read the response header by hand
|
// We read the response header by hand
|
||||||
|
|
4
vendor/github.com/ugorji/go/codec/reader.go
generated
vendored
4
vendor/github.com/ugorji/go/codec/reader.go
generated
vendored
|
@ -350,9 +350,9 @@ func (z *ioDecReader) unreadn1() {
|
||||||
|
|
||||||
// bytesDecReader is a decReader that reads off a byte slice with zero copying
|
// bytesDecReader is a decReader that reads off a byte slice with zero copying
|
||||||
//
|
//
|
||||||
// Note: we do not try to convert index'ing out of bounds to an io.EOF.
|
// Note: we do not try to convert index'ing out of bounds to an io error.
|
||||||
// instead, we let it bubble up to the exported Encode/Decode method
|
// instead, we let it bubble up to the exported Encode/Decode method
|
||||||
// and recover it as an io.EOF.
|
// and recover it as an io error.
|
||||||
//
|
//
|
||||||
// Every function here MUST defensively check bounds either explicitly
|
// Every function here MUST defensively check bounds either explicitly
|
||||||
// or via a bounds check.
|
// or via a bounds check.
|
||||||
|
|
9
vendor/golang.org/x/net/http2/transport.go
generated
vendored
9
vendor/golang.org/x/net/http2/transport.go
generated
vendored
|
@ -2911,6 +2911,15 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
|
||||||
fl = &cs.flow
|
fl = &cs.flow
|
||||||
}
|
}
|
||||||
if !fl.add(int32(f.Increment)) {
|
if !fl.add(int32(f.Increment)) {
|
||||||
|
// For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR
|
||||||
|
if cs != nil {
|
||||||
|
rl.endStreamError(cs, StreamError{
|
||||||
|
StreamID: f.StreamID,
|
||||||
|
Code: ErrCodeFlowControl,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return ConnectionError(ErrCodeFlowControl)
|
return ConnectionError(ErrCodeFlowControl)
|
||||||
}
|
}
|
||||||
cc.cond.Broadcast()
|
cc.cond.Broadcast()
|
||||||
|
|
2
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
2
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
|
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
2
vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
generated
vendored
2
vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
generated
vendored
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build darwin && go1.12
|
//go:build darwin
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
12
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
12
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
|
@ -13,6 +13,7 @@
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||||
func Uname(uname *Utsname) error {
|
func Uname(uname *Utsname) error {
|
||||||
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
|
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
|
||||||
n := unsafe.Sizeof(uname.Sysname)
|
n := unsafe.Sizeof(uname.Sysname)
|
||||||
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
|
// Suppress ENOMEM errors to be compatible with the C library __xuname() implementation.
|
||||||
|
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
|
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
|
||||||
n = unsafe.Sizeof(uname.Nodename)
|
n = unsafe.Sizeof(uname.Nodename)
|
||||||
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
|
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
|
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
|
||||||
n = unsafe.Sizeof(uname.Release)
|
n = unsafe.Sizeof(uname.Release)
|
||||||
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
|
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mib = []_C_int{CTL_KERN, KERN_VERSION}
|
mib = []_C_int{CTL_KERN, KERN_VERSION}
|
||||||
n = unsafe.Sizeof(uname.Version)
|
n = unsafe.Sizeof(uname.Version)
|
||||||
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
|
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +207,7 @@ func Uname(uname *Utsname) error {
|
||||||
|
|
||||||
mib = []_C_int{CTL_HW, HW_MACHINE}
|
mib = []_C_int{CTL_HW, HW_MACHINE}
|
||||||
n = unsafe.Sizeof(uname.Machine)
|
n = unsafe.Sizeof(uname.Machine)
|
||||||
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
|
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
99
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
99
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
|
@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error {
|
||||||
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
|
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
|
||||||
//sys Fsopen(fsName string, flags int) (fd int, err error)
|
//sys Fsopen(fsName string, flags int) (fd int, err error)
|
||||||
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
|
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
|
||||||
|
|
||||||
|
//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error)
|
||||||
|
|
||||||
|
func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {
|
||||||
|
var keyp *byte
|
||||||
|
if keyp, err = BytePtrFromString(key); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fsconfig(fd, cmd, keyp, value, aux)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetFlag is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_FLAG.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
func FsconfigSetFlag(fd int, key string) (err error) {
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetString is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_STRING.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
// value is the parameter value to set.
|
||||||
|
func FsconfigSetString(fd int, key string, value string) (err error) {
|
||||||
|
var valuep *byte
|
||||||
|
if valuep, err = BytePtrFromString(value); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetBinary is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_BINARY.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
// value is the parameter value to set.
|
||||||
|
func FsconfigSetBinary(fd int, key string, value []byte) (err error) {
|
||||||
|
if len(value) == 0 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetPath is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_PATH.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
// path is a non-empty path for specified key.
|
||||||
|
// atfd is a file descriptor at which to start lookup from or AT_FDCWD.
|
||||||
|
func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {
|
||||||
|
var valuep *byte
|
||||||
|
if valuep, err = BytePtrFromString(path); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetPathEmpty is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as
|
||||||
|
// FconfigSetPath but with AT_PATH_EMPTY implied.
|
||||||
|
func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {
|
||||||
|
var valuep *byte
|
||||||
|
if valuep, err = BytePtrFromString(path); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetFd is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_FD.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
// value is a file descriptor to be assigned to specified key.
|
||||||
|
func FsconfigSetFd(fd int, key string, value int) (err error) {
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigCreate is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_CMD_CREATE.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
func FsconfigCreate(fd int) (err error) {
|
||||||
|
return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigReconfigure is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_CMD_RECONFIGURE.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
func FsconfigReconfigure(fd int) (err error) {
|
||||||
|
return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
|
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
|
||||||
//sysnb Getpgid(pid int) (pgid int, err error)
|
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||||
|
|
||||||
|
|
10
vendor/golang.org/x/sys/unix/zsyscall_linux.go
generated
vendored
10
vendor/golang.org/x/sys/unix/zsyscall_linux.go
generated
vendored
|
@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) {
|
||||||
|
_, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Getdents(fd int, buf []byte) (n int, err error) {
|
func Getdents(fd int, buf []byte) (n int, err error) {
|
||||||
var _p0 unsafe.Pointer
|
var _p0 unsafe.Pointer
|
||||||
if len(buf) > 0 {
|
if len(buf) > 0 {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue