forked from jshiffer/matterbridge
Update dependencies (#1851)
This commit is contained in:
parent
5604d140e3
commit
4649876956
20
go.mod
20
go.mod
@ -6,13 +6,13 @@ require (
|
||||
github.com/Benau/tgsconverter v0.0.0-20210809170556-99f4a4f6337f
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560
|
||||
github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c
|
||||
github.com/SevereCloud/vksdk/v2 v2.14.0
|
||||
github.com/SevereCloud/vksdk/v2 v2.14.1
|
||||
github.com/bwmarrin/discordgo v0.25.0
|
||||
github.com/d5/tengo/v2 v2.10.1
|
||||
github.com/d5/tengo/v2 v2.12.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/fsnotify/fsnotify v1.5.4
|
||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||
github.com/gomarkdown/markdown v0.0.0-20220603122033-8f3b341fef32
|
||||
github.com/gomarkdown/markdown v0.0.0-20220607163217-45f7c050e2d1
|
||||
github.com/google/gops v0.3.23
|
||||
github.com/gorilla/schema v1.2.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
@ -40,16 +40,16 @@ require (
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
|
||||
github.com/shazow/ssh-chat v1.10.1
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/slack-go/slack v0.10.3
|
||||
github.com/slack-go/slack v0.11.0
|
||||
github.com/spf13/viper v1.12.0
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/stretchr/testify v1.7.2
|
||||
github.com/vincent-petithory/dataurl v1.0.0
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
github.com/yaegashi/msgraph.go v0.1.4
|
||||
github.com/zfjagann/golang-ring v0.0.0-20220330170733-19bcea1b6289
|
||||
go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c
|
||||
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd
|
||||
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401
|
||||
go.mau.fi/whatsmeow v0.0.0-20220624184947-57a69a641154
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
|
||||
golang.org/x/text v0.3.7
|
||||
gomod.garykim.dev/nc-talk v0.3.0
|
||||
google.golang.org/protobuf v1.28.0
|
||||
@ -80,7 +80,7 @@ require (
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/kettek/apng v0.0.0-20191108220231-414630eed80f // indirect
|
||||
github.com/klauspost/compress v1.15.1 // indirect
|
||||
github.com/klauspost/compress v1.15.6 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
||||
github.com/labstack/gommon v0.3.1 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
@ -145,7 +145,7 @@ require (
|
||||
gopkg.in/ini.v1 v1.66.4 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.1.1 // indirect
|
||||
modernc.org/cc/v3 v3.36.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.6 // indirect
|
||||
|
37
go.sum
37
go.sum
@ -160,8 +160,8 @@ github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c/go.mod h1:DNS
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RoaringBitmap/roaring v0.8.0/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
|
||||
github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
||||
github.com/SevereCloud/vksdk/v2 v2.14.0 h1:1lciJC4FWhSQIjjFb3NGyJI7x9sPKk/P6aAvR0ibh1o=
|
||||
github.com/SevereCloud/vksdk/v2 v2.14.0/go.mod h1:J/iPooVfldjVADo47G5aNxkvlRWAsZnMHpri8sZmck4=
|
||||
github.com/SevereCloud/vksdk/v2 v2.14.1 h1:pToB5uvNn6CUpPAs4jINlv5Z9qArTs+muATDOWNFJo8=
|
||||
github.com/SevereCloud/vksdk/v2 v2.14.1/go.mod h1:OW11r2PqGTGc/oxuodjgeqr2uxutasJGTmhjLMHMImg=
|
||||
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
@ -460,8 +460,8 @@ github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1S
|
||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
||||
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
|
||||
github.com/d5/tengo/v2 v2.10.1 h1:Z7vmTAQfdoExNEB9kxgqxvoBBW9bf+8uYMiDyriX5HM=
|
||||
github.com/d5/tengo/v2 v2.10.1/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||
github.com/d5/tengo/v2 v2.12.0 h1:EJLSMheqt1Kv/WjV5D0BvqJ/Qq/J6H3ZBpSZgw6Hn7Y=
|
||||
github.com/d5/tengo/v2 v2.12.0/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||
github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@ -723,8 +723,8 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomarkdown/markdown v0.0.0-20220603122033-8f3b341fef32 h1:QxcGJpbMJw6tHRtrHKJiL11LdX1SXDfV1f4t4mJl3QI=
|
||||
github.com/gomarkdown/markdown v0.0.0-20220603122033-8f3b341fef32/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||
github.com/gomarkdown/markdown v0.0.0-20220607163217-45f7c050e2d1 h1:wAupuFkZ/yq219/mSbqDtMfUZQY0gTYEtoz3/LKtppU=
|
||||
github.com/gomarkdown/markdown v0.0.0-20220607163217-45f7c050e2d1/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@ -1032,8 +1032,9 @@ github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8
|
||||
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=
|
||||
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.6 h1:6D9PcO8QWu0JyaQ2zUMmu16T1T+zjjEpP91guRsvDfY=
|
||||
github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
@ -1561,8 +1562,8 @@ github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 h1:A7o8tOE
|
||||
github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882/go.mod h1:5IwJoz9Pw7JsrCN4/skkxUtSWT7myuUPLhCgv6Q5vvQ=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo=
|
||||
github.com/slack-go/slack v0.10.3 h1:kKYwlKY73AfSrtAk9UHWCXXfitudkDztNI9GYBviLxw=
|
||||
github.com/slack-go/slack v0.10.3/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
|
||||
github.com/slack-go/slack v0.11.0 h1:sBBjQz8LY++6eeWhGJNZpRm5jvLRNnWBFZ/cAq58a6k=
|
||||
github.com/slack-go/slack v0.11.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
@ -1629,8 +1630,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
|
||||
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
|
||||
@ -1774,8 +1776,8 @@ go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+
|
||||
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
|
||||
go.mau.fi/libsignal v0.0.0-20220425070825-c40c839ee6a0 h1:3IQF2bgAyibdo77hTejwuJe4jlypj9QaE4xCQuxrThM=
|
||||
go.mau.fi/libsignal v0.0.0-20220425070825-c40c839ee6a0/go.mod h1:kBOXTvYyDG/q1Ihgvd4J6WenGPh7wtEGvPKF6vmf5ak=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c h1:2pn4sUljgVcFrPl1wyFOA0Qvg8726yzwyC1+qVdPkjM=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c/go.mod h1:iUBgOLNaqShLrR17u0kIiRptIGFH+nbT1tRhaWBEX/c=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220624184947-57a69a641154 h1:jUe0Re+w8/YHfxYryxjVkG3PEQDujCzGhbqsk6Qadtg=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220624184947-57a69a641154/go.mod h1:iUBgOLNaqShLrR17u0kIiRptIGFH+nbT1tRhaWBEX/c=
|
||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
@ -1888,8 +1890,8 @@ golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+o
|
||||
golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20210622092929-e6eecd499c2c/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20220321031419-a8550c1d254a/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd h1:9NbNcTg//wfC5JskFW4Z3sqwVnjmJKHxLAol1bW2qgw=
|
||||
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82 h1:KpZB5pUSBvrHltNEdK/tw0xlPeD13M6M6aGP32gKqiw=
|
||||
golang.org/x/image v0.0.0-20220617043117-41969df76e82/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@ -2031,8 +2033,8 @@ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 h1:zwrSfklXn0gxyLRX/aR+q6cgHbV/ItVyzbPlbA+dkAw=
|
||||
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0=
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -2583,8 +2585,9 @@ gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg=
|
||||
gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
|
||||
gorm.io/gorm v1.21.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
|
||||
|
3
vendor/github.com/SevereCloud/vksdk/v2/.golangci.yml
generated
vendored
3
vendor/github.com/SevereCloud/vksdk/v2/.golangci.yml
generated
vendored
@ -57,6 +57,8 @@ linters:
|
||||
- grouper
|
||||
- decorder
|
||||
- containedctx
|
||||
# - execinquery # FIXME: panic in 1.46.0
|
||||
- nosprintfhostport
|
||||
|
||||
# - wrapcheck # TODO: v3 Fix
|
||||
# - testpackage # TODO: Fix testpackage
|
||||
@ -87,6 +89,7 @@ linters:
|
||||
# - varnamelen
|
||||
# - errchkjson
|
||||
# - maintidx
|
||||
# - nonamedreturns
|
||||
|
||||
# depricated
|
||||
# - maligned
|
||||
|
2
vendor/github.com/SevereCloud/vksdk/v2/doc.go
generated
vendored
2
vendor/github.com/SevereCloud/vksdk/v2/doc.go
generated
vendored
@ -7,6 +7,6 @@ package vksdk
|
||||
|
||||
// Module constants.
|
||||
const (
|
||||
Version = "2.14.0"
|
||||
Version = "2.14.1"
|
||||
API = "5.131"
|
||||
)
|
||||
|
10
vendor/github.com/SevereCloud/vksdk/v2/object/groups.go
generated
vendored
10
vendor/github.com/SevereCloud/vksdk/v2/object/groups.go
generated
vendored
@ -210,7 +210,7 @@ type GroupsGroup struct {
|
||||
MainSection int `json:"main_section,omitempty"`
|
||||
OnlineStatus GroupsOnlineStatus `json:"online_status,omitempty"` // Status of replies in community messages
|
||||
AgeLimits int `json:"age_limits,omitempty"` // Information whether age limit
|
||||
BanInfo GroupsGroupBanInfo `json:"ban_info,omitempty"` // User ban info
|
||||
BanInfo *GroupsGroupBanInfo `json:"ban_info,omitempty"` // User ban info
|
||||
Addresses GroupsAddressesInfo `json:"addresses,omitempty"` // Info about addresses in Groups
|
||||
LiveCovers GroupsLiveCovers `json:"live_covers,omitempty"`
|
||||
CropPhoto UsersCropPhoto `json:"crop_photo,omitempty"`
|
||||
@ -963,10 +963,10 @@ type GroupsOnlineStatus struct {
|
||||
|
||||
// GroupsOwnerXtrBanInfo struct.
|
||||
type GroupsOwnerXtrBanInfo struct {
|
||||
BanInfo GroupsBanInfo `json:"ban_info"`
|
||||
Group GroupsGroup `json:"group"`
|
||||
Profile UsersUser `json:"profile"`
|
||||
Type string `json:"type"`
|
||||
BanInfo *GroupsBanInfo `json:"ban_info"`
|
||||
Group GroupsGroup `json:"group"`
|
||||
Profile UsersUser `json:"profile"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// GroupsSubjectItem struct.
|
||||
|
2
vendor/github.com/SevereCloud/vksdk/v2/object/video.go
generated
vendored
2
vendor/github.com/SevereCloud/vksdk/v2/object/video.go
generated
vendored
@ -31,7 +31,7 @@ type VideoVideo struct {
|
||||
CanLike BaseBoolInt `json:"can_like"`
|
||||
|
||||
// Information whether current user can download the video.
|
||||
CanDownload BaseBoolInt `json:"can_download"`
|
||||
CanDownload int `json:"can_download"`
|
||||
|
||||
// Information whether current user can repost this video.
|
||||
CanRepost BaseBoolInt `json:"can_repost"`
|
||||
|
7
vendor/github.com/d5/tengo/v2/compiler.go
generated
vendored
7
vendor/github.com/d5/tengo/v2/compiler.go
generated
vendored
@ -1220,14 +1220,14 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
|
||||
iterateInstructions(c.scopes[c.scopeIndex].Instructions,
|
||||
func(pos int, opcode parser.Opcode, operands []int) bool {
|
||||
switch {
|
||||
case dsts[pos]:
|
||||
dstIdx++
|
||||
deadCode = false
|
||||
case opcode == parser.OpReturn:
|
||||
if deadCode {
|
||||
return true
|
||||
}
|
||||
deadCode = true
|
||||
case dsts[pos]:
|
||||
dstIdx++
|
||||
deadCode = false
|
||||
case deadCode:
|
||||
return true
|
||||
}
|
||||
@ -1242,6 +1242,7 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
|
||||
var appendReturn bool
|
||||
endPos := len(c.scopes[c.scopeIndex].Instructions)
|
||||
newEndPost := len(newInsts)
|
||||
|
||||
iterateInstructions(newInsts,
|
||||
func(pos int, opcode parser.Opcode, operands []int) bool {
|
||||
switch opcode {
|
||||
|
18
vendor/github.com/d5/tengo/v2/parser/parser.go
generated
vendored
18
vendor/github.com/d5/tengo/v2/parser/parser.go
generated
vendored
@ -375,7 +375,12 @@ func (p *Parser) parseOperand() Expr {
|
||||
case token.Ident:
|
||||
return p.parseIdent()
|
||||
case token.Int:
|
||||
v, _ := strconv.ParseInt(p.tokenLit, 10, 64)
|
||||
v, err := strconv.ParseInt(p.tokenLit, 0, 64)
|
||||
if err == strconv.ErrRange {
|
||||
p.error(p.pos, "number out of range")
|
||||
} else if err != nil {
|
||||
p.error(p.pos, "invalid integer")
|
||||
}
|
||||
x := &IntLit{
|
||||
Value: v,
|
||||
ValuePos: p.pos,
|
||||
@ -383,8 +388,14 @@ func (p *Parser) parseOperand() Expr {
|
||||
}
|
||||
p.next()
|
||||
return x
|
||||
|
||||
case token.Float:
|
||||
v, _ := strconv.ParseFloat(p.tokenLit, 64)
|
||||
v, err := strconv.ParseFloat(p.tokenLit, 64)
|
||||
if err == strconv.ErrRange {
|
||||
p.error(p.pos, "number out of range")
|
||||
} else if err != nil {
|
||||
p.error(p.pos, "invalid float")
|
||||
}
|
||||
x := &FloatLit{
|
||||
Value: v,
|
||||
ValuePos: p.pos,
|
||||
@ -447,10 +458,11 @@ func (p *Parser) parseOperand() Expr {
|
||||
return p.parseErrorExpr()
|
||||
case token.Immutable: // immutable expression
|
||||
return p.parseImmutableExpr()
|
||||
default:
|
||||
p.errorExpected(p.pos, "operand")
|
||||
}
|
||||
|
||||
pos := p.pos
|
||||
p.errorExpected(pos, "operand")
|
||||
p.advance(stmtStart)
|
||||
return &BadExpr{From: pos, To: p.pos}
|
||||
}
|
||||
|
113
vendor/github.com/d5/tengo/v2/parser/scanner.go
generated
vendored
113
vendor/github.com/d5/tengo/v2/parser/scanner.go
generated
vendored
@ -93,9 +93,9 @@ func (s *Scanner) Scan() (
|
||||
token.Export, token.True, token.False, token.Undefined:
|
||||
insertSemi = true
|
||||
}
|
||||
case '0' <= ch && ch <= '9':
|
||||
case ('0' <= ch && ch <= '9') || (ch == '.' && '0' <= s.peek() && s.peek() <= '9'):
|
||||
insertSemi = true
|
||||
tok, literal = s.scanNumber(false)
|
||||
tok, literal = s.scanNumber()
|
||||
default:
|
||||
s.next() // always make progress
|
||||
|
||||
@ -125,16 +125,11 @@ func (s *Scanner) Scan() (
|
||||
case ':':
|
||||
tok = s.switch2(token.Colon, token.Define)
|
||||
case '.':
|
||||
if '0' <= s.ch && s.ch <= '9' {
|
||||
insertSemi = true
|
||||
tok, literal = s.scanNumber(true)
|
||||
} else {
|
||||
tok = token.Period
|
||||
if s.ch == '.' && s.peek() == '.' {
|
||||
s.next()
|
||||
s.next() // consume last '.'
|
||||
tok = token.Ellipsis
|
||||
}
|
||||
tok = token.Period
|
||||
if s.ch == '.' && s.peek() == '.' {
|
||||
s.next()
|
||||
s.next() // consume last '.'
|
||||
tok = token.Ellipsis
|
||||
}
|
||||
case ',':
|
||||
tok = token.Comma
|
||||
@ -379,86 +374,58 @@ func (s *Scanner) scanIdentifier() string {
|
||||
return string(s.src[offs:s.offset])
|
||||
}
|
||||
|
||||
func (s *Scanner) scanMantissa(base int) {
|
||||
for digitVal(s.ch) < base {
|
||||
func (s *Scanner) scanDigits(base int) {
|
||||
for s.ch == '_' || digitVal(s.ch) < base {
|
||||
s.next()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scanner) scanNumber(
|
||||
seenDecimalPoint bool,
|
||||
) (tok token.Token, lit string) {
|
||||
// digitVal(s.ch) < 10
|
||||
func (s *Scanner) scanNumber() (token.Token, string) {
|
||||
offs := s.offset
|
||||
tok = token.Int
|
||||
tok := token.Int
|
||||
base := 10
|
||||
|
||||
defer func() {
|
||||
lit = string(s.src[offs:s.offset])
|
||||
}()
|
||||
|
||||
if seenDecimalPoint {
|
||||
offs--
|
||||
tok = token.Float
|
||||
s.scanMantissa(10)
|
||||
goto exponent
|
||||
}
|
||||
|
||||
if s.ch == '0' {
|
||||
// int or float
|
||||
offs := s.offset
|
||||
// Determine base
|
||||
switch {
|
||||
case s.ch == '0' && lower(s.peek()) == 'b':
|
||||
base = 2
|
||||
s.next()
|
||||
s.next()
|
||||
case s.ch == '0' && lower(s.peek()) == 'o':
|
||||
base = 8
|
||||
s.next()
|
||||
s.next()
|
||||
case s.ch == '0' && lower(s.peek()) == 'x':
|
||||
base = 16
|
||||
s.next()
|
||||
s.next()
|
||||
if s.ch == 'x' || s.ch == 'X' {
|
||||
// hexadecimal int
|
||||
s.next()
|
||||
s.scanMantissa(16)
|
||||
if s.offset-offs <= 2 {
|
||||
// only scanned "0x" or "0X"
|
||||
s.error(offs, "illegal hexadecimal number")
|
||||
}
|
||||
} else {
|
||||
// octal int or float
|
||||
seenDecimalDigit := false
|
||||
s.scanMantissa(8)
|
||||
if s.ch == '8' || s.ch == '9' {
|
||||
// illegal octal int or float
|
||||
seenDecimalDigit = true
|
||||
s.scanMantissa(10)
|
||||
}
|
||||
if s.ch == '.' || s.ch == 'e' || s.ch == 'E' || s.ch == 'i' {
|
||||
goto fraction
|
||||
}
|
||||
// octal int
|
||||
if seenDecimalDigit {
|
||||
s.error(offs, "illegal octal number")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// decimal int or float
|
||||
s.scanMantissa(10)
|
||||
// Scan whole number
|
||||
s.scanDigits(base)
|
||||
|
||||
fraction:
|
||||
if s.ch == '.' {
|
||||
// Scan fractional part
|
||||
if s.ch == '.' && (base == 10 || base == 16) {
|
||||
tok = token.Float
|
||||
s.next()
|
||||
s.scanMantissa(10)
|
||||
s.scanDigits(base)
|
||||
}
|
||||
|
||||
exponent:
|
||||
if s.ch == 'e' || s.ch == 'E' {
|
||||
// Scan exponent
|
||||
if s.ch == 'e' || s.ch == 'E' || s.ch == 'p' || s.ch == 'P' {
|
||||
tok = token.Float
|
||||
s.next()
|
||||
if s.ch == '-' || s.ch == '+' {
|
||||
s.next()
|
||||
}
|
||||
if digitVal(s.ch) < 10 {
|
||||
s.scanMantissa(10)
|
||||
} else {
|
||||
s.error(offs, "illegal floating-point exponent")
|
||||
offs := s.offset
|
||||
s.scanDigits(10)
|
||||
if offs == s.offset {
|
||||
s.error(offs, "exponent has no digits")
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
return tok, string(s.src[offs:s.offset])
|
||||
}
|
||||
|
||||
func (s *Scanner) scanEscape(quote rune) bool {
|
||||
@ -687,3 +654,7 @@ func digitVal(ch rune) int {
|
||||
}
|
||||
return 16 // larger than any legal digit val
|
||||
}
|
||||
|
||||
func lower(c byte) byte {
|
||||
return c | ('x' - 'X')
|
||||
}
|
||||
|
9
vendor/github.com/gomarkdown/markdown/.gitpod.yml
generated
vendored
Normal file
9
vendor/github.com/gomarkdown/markdown/.gitpod.yml
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# This configuration file was automatically generated by Gitpod.
|
||||
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
|
||||
# and commit this file to your remote git repository to share the goodness with others.
|
||||
|
||||
tasks:
|
||||
- init: go get && go build ./... && go test ./...
|
||||
command: go run
|
||||
|
||||
|
6
vendor/github.com/gomarkdown/markdown/parser/block.go
generated
vendored
6
vendor/github.com/gomarkdown/markdown/parser/block.go
generated
vendored
@ -1675,6 +1675,12 @@ func (p *Parser) paragraph(data []byte) int {
|
||||
return i
|
||||
}
|
||||
|
||||
// if there's a block quote, paragraph is over
|
||||
if p.quotePrefix(current) > 0 {
|
||||
p.renderParagraph(data[:i])
|
||||
return i
|
||||
}
|
||||
|
||||
// if there's a fenced code block, paragraph is over
|
||||
if p.extensions&FencedCode != 0 {
|
||||
if p.fencedCodeBlock(current, false) > 0 {
|
||||
|
7
vendor/github.com/klauspost/compress/.gitignore
generated
vendored
7
vendor/github.com/klauspost/compress/.gitignore
generated
vendored
@ -23,3 +23,10 @@ _testmain.go
|
||||
*.test
|
||||
*.prof
|
||||
/s2/cmd/_s2sx/sfx-exe
|
||||
|
||||
# Linux perf files
|
||||
perf.data
|
||||
perf.data.old
|
||||
|
||||
# gdb history
|
||||
.gdb_history
|
||||
|
40
vendor/github.com/klauspost/compress/README.md
generated
vendored
40
vendor/github.com/klauspost/compress/README.md
generated
vendored
@ -17,6 +17,41 @@ This package provides various compression algorithms.
|
||||
|
||||
# changelog
|
||||
|
||||
* May 25, 2022 (v1.15.5)
|
||||
* s2: Add concurrent stream decompression https://github.com/klauspost/compress/pull/602
|
||||
* s2: Fix final emit oob read crash on amd64 https://github.com/klauspost/compress/pull/601
|
||||
* huff0: asm implementation of Decompress1X by @WojciechMula https://github.com/klauspost/compress/pull/596
|
||||
* zstd: Use 1 less goroutine for stream decoding https://github.com/klauspost/compress/pull/588
|
||||
* zstd: Copy literal in 16 byte blocks when possible https://github.com/klauspost/compress/pull/592
|
||||
* zstd: Speed up when WithDecoderLowmem(false) https://github.com/klauspost/compress/pull/599
|
||||
* zstd: faster next state update in BMI2 version of decode by @WojciechMula in https://github.com/klauspost/compress/pull/593
|
||||
* huff0: Do not check max size when reading table. https://github.com/klauspost/compress/pull/586
|
||||
* flate: Inplace hashing for level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/590
|
||||
|
||||
|
||||
* May 11, 2022 (v1.15.4)
|
||||
* huff0: decompress directly into output by @WojciechMula in [#577](https://github.com/klauspost/compress/pull/577)
|
||||
* inflate: Keep dict on stack [#581](https://github.com/klauspost/compress/pull/581)
|
||||
* zstd: Faster decoding memcopy in asm [#583](https://github.com/klauspost/compress/pull/583)
|
||||
* zstd: Fix ignored crc [#580](https://github.com/klauspost/compress/pull/580)
|
||||
|
||||
* May 5, 2022 (v1.15.3)
|
||||
* zstd: Allow to ignore checksum checking by @WojciechMula [#572](https://github.com/klauspost/compress/pull/572)
|
||||
* s2: Fix incorrect seek for io.SeekEnd in [#575](https://github.com/klauspost/compress/pull/575)
|
||||
|
||||
* Apr 26, 2022 (v1.15.2)
|
||||
* zstd: Add x86-64 assembly for decompression on streams and blocks. Contributed by [@WojciechMula](https://github.com/WojciechMula). Typically 2x faster. [#528](https://github.com/klauspost/compress/pull/528) [#531](https://github.com/klauspost/compress/pull/531) [#545](https://github.com/klauspost/compress/pull/545) [#537](https://github.com/klauspost/compress/pull/537)
|
||||
* zstd: Add options to ZipDecompressor and fixes [#539](https://github.com/klauspost/compress/pull/539)
|
||||
* s2: Use sorted search for index [#555](https://github.com/klauspost/compress/pull/555)
|
||||
* Minimum version is Go 1.16, added CI test on 1.18.
|
||||
|
||||
* Mar 11, 2022 (v1.15.1)
|
||||
* huff0: Add x86 assembly of Decode4X by @WojciechMula in [#512](https://github.com/klauspost/compress/pull/512)
|
||||
* zstd: Reuse zip decoders in [#514](https://github.com/klauspost/compress/pull/514)
|
||||
* zstd: Detect extra block data and report as corrupted in [#520](https://github.com/klauspost/compress/pull/520)
|
||||
* zstd: Handle zero sized frame content size stricter in [#521](https://github.com/klauspost/compress/pull/521)
|
||||
* zstd: Add stricter block size checks in [#523](https://github.com/klauspost/compress/pull/523)
|
||||
|
||||
* Mar 3, 2022 (v1.15.0)
|
||||
* zstd: Refactor decoder by @klauspost in [#498](https://github.com/klauspost/compress/pull/498)
|
||||
* zstd: Add stream encoding without goroutines by @klauspost in [#505](https://github.com/klauspost/compress/pull/505)
|
||||
@ -60,6 +95,9 @@ While the release has been extensively tested, it is recommended to testing when
|
||||
* zstd: add arm64 xxhash assembly in [#464](https://github.com/klauspost/compress/pull/464)
|
||||
* Add garbled for binaries for s2 in [#445](https://github.com/klauspost/compress/pull/445)
|
||||
|
||||
<details>
|
||||
<summary>See changes to v1.13.x</summary>
|
||||
|
||||
* Aug 30, 2021 (v1.13.5)
|
||||
* gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425)
|
||||
* s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413)
|
||||
@ -88,6 +126,8 @@ While the release has been extensively tested, it is recommended to testing when
|
||||
* Added [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp#gzip-handler) which allows wrapping HTTP servers and clients with GZIP compressors.
|
||||
* zstd: Detect short invalid signatures [#382](https://github.com/klauspost/compress/pull/382)
|
||||
* zstd: Spawn decoder goroutine only if needed. [#380](https://github.com/klauspost/compress/pull/380)
|
||||
</details>
|
||||
|
||||
|
||||
<details>
|
||||
<summary>See changes to v1.12.x</summary>
|
||||
|
5
vendor/github.com/klauspost/compress/huff0/autogen.go
generated
vendored
5
vendor/github.com/klauspost/compress/huff0/autogen.go
generated
vendored
@ -1,5 +0,0 @@
|
||||
package huff0
|
||||
|
||||
//go:generate go run generate.go
|
||||
//go:generate asmfmt -w decompress_amd64.s
|
||||
//go:generate asmfmt -w decompress_8b_amd64.s
|
10
vendor/github.com/klauspost/compress/huff0/bitreader.go
generated
vendored
10
vendor/github.com/klauspost/compress/huff0/bitreader.go
generated
vendored
@ -165,11 +165,6 @@ func (b *bitReaderShifted) peekBitsFast(n uint8) uint16 {
|
||||
return uint16(b.value >> ((64 - n) & 63))
|
||||
}
|
||||
|
||||
// peekTopBits(n) is equvialent to peekBitFast(64 - n)
|
||||
func (b *bitReaderShifted) peekTopBits(n uint8) uint16 {
|
||||
return uint16(b.value >> n)
|
||||
}
|
||||
|
||||
func (b *bitReaderShifted) advance(n uint8) {
|
||||
b.bitsRead += n
|
||||
b.value <<= n & 63
|
||||
@ -220,11 +215,6 @@ func (b *bitReaderShifted) fill() {
|
||||
}
|
||||
}
|
||||
|
||||
// finished returns true if all bits have been read from the bit stream.
|
||||
func (b *bitReaderShifted) finished() bool {
|
||||
return b.off == 0 && b.bitsRead >= 64
|
||||
}
|
||||
|
||||
func (b *bitReaderShifted) remaining() uint {
|
||||
return b.off*8 + uint(64-b.bitsRead)
|
||||
}
|
||||
|
115
vendor/github.com/klauspost/compress/huff0/bitwriter.go
generated
vendored
115
vendor/github.com/klauspost/compress/huff0/bitwriter.go
generated
vendored
@ -5,8 +5,6 @@
|
||||
|
||||
package huff0
|
||||
|
||||
import "fmt"
|
||||
|
||||
// bitWriter will write bits.
|
||||
// First bit will be LSB of the first byte of output.
|
||||
type bitWriter struct {
|
||||
@ -23,14 +21,6 @@ var bitMask16 = [32]uint16{
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF} /* up to 16 bits */
|
||||
|
||||
// addBits16NC will add up to 16 bits.
|
||||
// It will not check if there is space for them,
|
||||
// so the caller must ensure that it has flushed recently.
|
||||
func (b *bitWriter) addBits16NC(value uint16, bits uint8) {
|
||||
b.bitContainer |= uint64(value&bitMask16[bits&31]) << (b.nBits & 63)
|
||||
b.nBits += bits
|
||||
}
|
||||
|
||||
// addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated.
|
||||
// It will not check if there is space for them, so the caller must ensure that it has flushed recently.
|
||||
func (b *bitWriter) addBits16Clean(value uint16, bits uint8) {
|
||||
@ -70,104 +60,6 @@ func (b *bitWriter) encTwoSymbols(ct cTable, av, bv byte) {
|
||||
b.nBits += encA.nBits + encB.nBits
|
||||
}
|
||||
|
||||
// addBits16ZeroNC will add up to 16 bits.
|
||||
// It will not check if there is space for them,
|
||||
// so the caller must ensure that it has flushed recently.
|
||||
// This is fastest if bits can be zero.
|
||||
func (b *bitWriter) addBits16ZeroNC(value uint16, bits uint8) {
|
||||
if bits == 0 {
|
||||
return
|
||||
}
|
||||
value <<= (16 - bits) & 15
|
||||
value >>= (16 - bits) & 15
|
||||
b.bitContainer |= uint64(value) << (b.nBits & 63)
|
||||
b.nBits += bits
|
||||
}
|
||||
|
||||
// flush will flush all pending full bytes.
|
||||
// There will be at least 56 bits available for writing when this has been called.
|
||||
// Using flush32 is faster, but leaves less space for writing.
|
||||
func (b *bitWriter) flush() {
|
||||
v := b.nBits >> 3
|
||||
switch v {
|
||||
case 0:
|
||||
return
|
||||
case 1:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
)
|
||||
b.bitContainer >>= 1 << 3
|
||||
case 2:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
)
|
||||
b.bitContainer >>= 2 << 3
|
||||
case 3:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
)
|
||||
b.bitContainer >>= 3 << 3
|
||||
case 4:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
)
|
||||
b.bitContainer >>= 4 << 3
|
||||
case 5:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
)
|
||||
b.bitContainer >>= 5 << 3
|
||||
case 6:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
byte(b.bitContainer>>40),
|
||||
)
|
||||
b.bitContainer >>= 6 << 3
|
||||
case 7:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
byte(b.bitContainer>>40),
|
||||
byte(b.bitContainer>>48),
|
||||
)
|
||||
b.bitContainer >>= 7 << 3
|
||||
case 8:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
byte(b.bitContainer>>40),
|
||||
byte(b.bitContainer>>48),
|
||||
byte(b.bitContainer>>56),
|
||||
)
|
||||
b.bitContainer = 0
|
||||
b.nBits = 0
|
||||
return
|
||||
default:
|
||||
panic(fmt.Errorf("bits (%d) > 64", b.nBits))
|
||||
}
|
||||
b.nBits &= 7
|
||||
}
|
||||
|
||||
// flush32 will flush out, so there are at least 32 bits available for writing.
|
||||
func (b *bitWriter) flush32() {
|
||||
if b.nBits < 32 {
|
||||
@ -201,10 +93,3 @@ func (b *bitWriter) close() error {
|
||||
b.flushAlign()
|
||||
return nil
|
||||
}
|
||||
|
||||
// reset and continue writing by appending to out.
|
||||
func (b *bitWriter) reset(out []byte) {
|
||||
b.bitContainer = 0
|
||||
b.nBits = 0
|
||||
b.out = out
|
||||
}
|
||||
|
10
vendor/github.com/klauspost/compress/huff0/bytereader.go
generated
vendored
10
vendor/github.com/klauspost/compress/huff0/bytereader.go
generated
vendored
@ -20,11 +20,6 @@ func (b *byteReader) init(in []byte) {
|
||||
b.off = 0
|
||||
}
|
||||
|
||||
// advance the stream b n bytes.
|
||||
func (b *byteReader) advance(n uint) {
|
||||
b.off += int(n)
|
||||
}
|
||||
|
||||
// Int32 returns a little endian int32 starting at current offset.
|
||||
func (b byteReader) Int32() int32 {
|
||||
v3 := int32(b.b[b.off+3])
|
||||
@ -43,11 +38,6 @@ func (b byteReader) Uint32() uint32 {
|
||||
return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0
|
||||
}
|
||||
|
||||
// unread returns the unread portion of the input.
|
||||
func (b byteReader) unread() []byte {
|
||||
return b.b[b.off:]
|
||||
}
|
||||
|
||||
// remain will return the number of bytes remaining.
|
||||
func (b byteReader) remain() int {
|
||||
return len(b.b) - b.off
|
||||
|
1
vendor/github.com/klauspost/compress/huff0/compress.go
generated
vendored
1
vendor/github.com/klauspost/compress/huff0/compress.go
generated
vendored
@ -404,6 +404,7 @@ func (s *Scratch) canUseTable(c cTable) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
//lint:ignore U1000 used for debugging
|
||||
func (s *Scratch) validateTable(c cTable) bool {
|
||||
if len(c) < int(s.symbolLen) {
|
||||
return false
|
||||
|
113
vendor/github.com/klauspost/compress/huff0/decompress.go
generated
vendored
113
vendor/github.com/klauspost/compress/huff0/decompress.go
generated
vendored
@ -11,7 +11,6 @@ import (
|
||||
|
||||
type dTable struct {
|
||||
single []dEntrySingle
|
||||
double []dEntryDouble
|
||||
}
|
||||
|
||||
// single-symbols decoding
|
||||
@ -19,13 +18,6 @@ type dEntrySingle struct {
|
||||
entry uint16
|
||||
}
|
||||
|
||||
// double-symbols decoding
|
||||
type dEntryDouble struct {
|
||||
seq [4]byte
|
||||
nBits uint8
|
||||
len uint8
|
||||
}
|
||||
|
||||
// Uses special code for all tables that are < 8 bits.
|
||||
const use8BitTables = true
|
||||
|
||||
@ -35,7 +27,7 @@ const use8BitTables = true
|
||||
// If no Scratch is provided a new one is allocated.
|
||||
// The returned Scratch can be used for encoding or decoding input using this table.
|
||||
func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) {
|
||||
s, err = s.prepare(in)
|
||||
s, err = s.prepare(nil)
|
||||
if err != nil {
|
||||
return s, nil, err
|
||||
}
|
||||
@ -236,108 +228,6 @@ func (d *Decoder) buffer() *[4][256]byte {
|
||||
return &[4][256]byte{}
|
||||
}
|
||||
|
||||
// Decompress1X will decompress a 1X encoded stream.
|
||||
// The cap of the output buffer will be the maximum decompressed size.
|
||||
// The length of the supplied input must match the end of a block exactly.
|
||||
func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {
|
||||
if len(d.dt.single) == 0 {
|
||||
return nil, errors.New("no table loaded")
|
||||
}
|
||||
if use8BitTables && d.actualTableLog <= 8 {
|
||||
return d.decompress1X8Bit(dst, src)
|
||||
}
|
||||
var br bitReaderShifted
|
||||
err := br.init(src)
|
||||
if err != nil {
|
||||
return dst, err
|
||||
}
|
||||
maxDecodedSize := cap(dst)
|
||||
dst = dst[:0]
|
||||
|
||||
// Avoid bounds check by always having full sized table.
|
||||
const tlSize = 1 << tableLogMax
|
||||
const tlMask = tlSize - 1
|
||||
dt := d.dt.single[:tlSize]
|
||||
|
||||
// Use temp table to avoid bound checks/append penalty.
|
||||
bufs := d.buffer()
|
||||
buf := &bufs[0]
|
||||
var off uint8
|
||||
|
||||
for br.off >= 8 {
|
||||
br.fillFast()
|
||||
v := dt[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
// Refill
|
||||
br.fillFast()
|
||||
|
||||
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
d.bufs.Put(bufs)
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
|
||||
if len(dst)+int(off) > maxDecodedSize {
|
||||
d.bufs.Put(bufs)
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:off]...)
|
||||
|
||||
// br < 8, so uint8 is fine
|
||||
bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead
|
||||
for bitsLeft > 0 {
|
||||
br.fill()
|
||||
if false && br.bitsRead >= 32 {
|
||||
if br.off >= 4 {
|
||||
v := br.in[br.off-4:]
|
||||
v = v[:4]
|
||||
low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
||||
br.value = (br.value << 32) | uint64(low)
|
||||
br.bitsRead -= 32
|
||||
br.off -= 4
|
||||
} else {
|
||||
for br.off > 0 {
|
||||
br.value = (br.value << 8) | uint64(br.in[br.off-1])
|
||||
br.bitsRead -= 8
|
||||
br.off--
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(dst) >= maxDecodedSize {
|
||||
d.bufs.Put(bufs)
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
nBits := uint8(v.entry)
|
||||
br.advance(nBits)
|
||||
bitsLeft -= nBits
|
||||
dst = append(dst, uint8(v.entry>>8))
|
||||
}
|
||||
d.bufs.Put(bufs)
|
||||
return dst, br.close()
|
||||
}
|
||||
|
||||
// decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8.
|
||||
// The cap of the output buffer will be the maximum decompressed size.
|
||||
// The length of the supplied input must match the end of a block exactly.
|
||||
@ -995,7 +885,6 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) {
|
||||
|
||||
const shift = 56
|
||||
const tlSize = 1 << 8
|
||||
const tlMask = tlSize - 1
|
||||
single := d.dt.single[:tlSize]
|
||||
|
||||
// Use temp table to avoid bound checks/append penalty.
|
||||
|
488
vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s
generated
vendored
488
vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s
generated
vendored
@ -1,488 +0,0 @@
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !noasm
|
||||
|
||||
#include "textflag.h"
|
||||
#include "funcdata.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
#define bufoff 256 // see decompress.go, we're using [4][256]byte table
|
||||
|
||||
// func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted,
|
||||
// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool)
|
||||
TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8
|
||||
#define off R8
|
||||
#define buffer DI
|
||||
#define table SI
|
||||
|
||||
#define br_bits_read R9
|
||||
#define br_value R10
|
||||
#define br_offset R11
|
||||
#define peek_bits R12
|
||||
#define exhausted DX
|
||||
|
||||
#define br0 R13
|
||||
#define br1 R14
|
||||
#define br2 R15
|
||||
#define br3 BP
|
||||
|
||||
MOVQ BP, 0(SP)
|
||||
|
||||
XORQ exhausted, exhausted // exhausted = false
|
||||
XORQ off, off // off = 0
|
||||
|
||||
MOVBQZX peekBits+32(FP), peek_bits
|
||||
MOVQ buf+40(FP), buffer
|
||||
MOVQ tbl+48(FP), table
|
||||
|
||||
MOVQ pbr0+0(FP), br0
|
||||
MOVQ pbr1+8(FP), br1
|
||||
MOVQ pbr2+16(FP), br2
|
||||
MOVQ pbr3+24(FP), br3
|
||||
|
||||
main_loop:
|
||||
|
||||
// const stream = 0
|
||||
// br0.fillFast()
|
||||
MOVBQZX bitReaderShifted_bitsRead(br0), br_bits_read
|
||||
MOVQ bitReaderShifted_value(br0), br_value
|
||||
MOVQ bitReaderShifted_off(br0), br_offset
|
||||
|
||||
// if b.bitsRead >= 32 {
|
||||
CMPQ br_bits_read, $32
|
||||
JB skip_fill0
|
||||
|
||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
||||
SUBQ $4, br_offset // b.off -= 4
|
||||
|
||||
// v := b.in[b.off-4 : b.off]
|
||||
// v = v[:4]
|
||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
||||
MOVQ bitReaderShifted_in(br0), AX
|
||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
||||
|
||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
||||
MOVQ br_bits_read, CX
|
||||
SHLQ CL, AX
|
||||
ORQ AX, br_value
|
||||
|
||||
// exhausted = exhausted || (br0.off < 4)
|
||||
CMPQ br_offset, $4
|
||||
SETLT DL
|
||||
ORB DL, DH
|
||||
|
||||
// }
|
||||
skip_fill0:
|
||||
|
||||
// val0 := br0.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v0 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br0.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val1 := br0.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v1 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br0.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
||||
MOVW BX, 0(buffer)(off*1)
|
||||
|
||||
// SECOND PART:
|
||||
// val2 := br0.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v2 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br0.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val3 := br0.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v3 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br0.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
||||
MOVW BX, 0+2(buffer)(off*1)
|
||||
|
||||
// update the bitrader reader structure
|
||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br0)
|
||||
MOVQ br_value, bitReaderShifted_value(br0)
|
||||
MOVQ br_offset, bitReaderShifted_off(br0)
|
||||
|
||||
// const stream = 1
|
||||
// br1.fillFast()
|
||||
MOVBQZX bitReaderShifted_bitsRead(br1), br_bits_read
|
||||
MOVQ bitReaderShifted_value(br1), br_value
|
||||
MOVQ bitReaderShifted_off(br1), br_offset
|
||||
|
||||
// if b.bitsRead >= 32 {
|
||||
CMPQ br_bits_read, $32
|
||||
JB skip_fill1
|
||||
|
||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
||||
SUBQ $4, br_offset // b.off -= 4
|
||||
|
||||
// v := b.in[b.off-4 : b.off]
|
||||
// v = v[:4]
|
||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
||||
MOVQ bitReaderShifted_in(br1), AX
|
||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
||||
|
||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
||||
MOVQ br_bits_read, CX
|
||||
SHLQ CL, AX
|
||||
ORQ AX, br_value
|
||||
|
||||
// exhausted = exhausted || (br1.off < 4)
|
||||
CMPQ br_offset, $4
|
||||
SETLT DL
|
||||
ORB DL, DH
|
||||
|
||||
// }
|
||||
skip_fill1:
|
||||
|
||||
// val0 := br1.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v0 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br1.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val1 := br1.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v1 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br1.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
||||
MOVW BX, 256(buffer)(off*1)
|
||||
|
||||
// SECOND PART:
|
||||
// val2 := br1.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v2 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br1.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val3 := br1.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v3 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br1.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
||||
MOVW BX, 256+2(buffer)(off*1)
|
||||
|
||||
// update the bitrader reader structure
|
||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br1)
|
||||
MOVQ br_value, bitReaderShifted_value(br1)
|
||||
MOVQ br_offset, bitReaderShifted_off(br1)
|
||||
|
||||
// const stream = 2
|
||||
// br2.fillFast()
|
||||
MOVBQZX bitReaderShifted_bitsRead(br2), br_bits_read
|
||||
MOVQ bitReaderShifted_value(br2), br_value
|
||||
MOVQ bitReaderShifted_off(br2), br_offset
|
||||
|
||||
// if b.bitsRead >= 32 {
|
||||
CMPQ br_bits_read, $32
|
||||
JB skip_fill2
|
||||
|
||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
||||
SUBQ $4, br_offset // b.off -= 4
|
||||
|
||||
// v := b.in[b.off-4 : b.off]
|
||||
// v = v[:4]
|
||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
||||
MOVQ bitReaderShifted_in(br2), AX
|
||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
||||
|
||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
||||
MOVQ br_bits_read, CX
|
||||
SHLQ CL, AX
|
||||
ORQ AX, br_value
|
||||
|
||||
// exhausted = exhausted || (br2.off < 4)
|
||||
CMPQ br_offset, $4
|
||||
SETLT DL
|
||||
ORB DL, DH
|
||||
|
||||
// }
|
||||
skip_fill2:
|
||||
|
||||
// val0 := br2.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v0 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br2.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val1 := br2.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v1 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br2.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
||||
MOVW BX, 512(buffer)(off*1)
|
||||
|
||||
// SECOND PART:
|
||||
// val2 := br2.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v2 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br2.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val3 := br2.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v3 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br2.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
||||
MOVW BX, 512+2(buffer)(off*1)
|
||||
|
||||
// update the bitrader reader structure
|
||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br2)
|
||||
MOVQ br_value, bitReaderShifted_value(br2)
|
||||
MOVQ br_offset, bitReaderShifted_off(br2)
|
||||
|
||||
// const stream = 3
|
||||
// br3.fillFast()
|
||||
MOVBQZX bitReaderShifted_bitsRead(br3), br_bits_read
|
||||
MOVQ bitReaderShifted_value(br3), br_value
|
||||
MOVQ bitReaderShifted_off(br3), br_offset
|
||||
|
||||
// if b.bitsRead >= 32 {
|
||||
CMPQ br_bits_read, $32
|
||||
JB skip_fill3
|
||||
|
||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
||||
SUBQ $4, br_offset // b.off -= 4
|
||||
|
||||
// v := b.in[b.off-4 : b.off]
|
||||
// v = v[:4]
|
||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
||||
MOVQ bitReaderShifted_in(br3), AX
|
||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
||||
|
||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
||||
MOVQ br_bits_read, CX
|
||||
SHLQ CL, AX
|
||||
ORQ AX, br_value
|
||||
|
||||
// exhausted = exhausted || (br3.off < 4)
|
||||
CMPQ br_offset, $4
|
||||
SETLT DL
|
||||
ORB DL, DH
|
||||
|
||||
// }
|
||||
skip_fill3:
|
||||
|
||||
// val0 := br3.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v0 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br3.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val1 := br3.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v1 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br3.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
||||
MOVW BX, 768(buffer)(off*1)
|
||||
|
||||
// SECOND PART:
|
||||
// val2 := br3.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v2 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br3.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val3 := br3.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v3 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br3.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
||||
MOVW BX, 768+2(buffer)(off*1)
|
||||
|
||||
// update the bitrader reader structure
|
||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br3)
|
||||
MOVQ br_value, bitReaderShifted_value(br3)
|
||||
MOVQ br_offset, bitReaderShifted_off(br3)
|
||||
|
||||
ADDQ $4, off // off += 2
|
||||
|
||||
TESTB DH, DH // any br[i].ofs < 4?
|
||||
JNZ end
|
||||
|
||||
CMPQ off, $bufoff
|
||||
JL main_loop
|
||||
|
||||
end:
|
||||
MOVQ 0(SP), BP
|
||||
|
||||
MOVB off, ret+56(FP)
|
||||
RET
|
||||
|
||||
#undef off
|
||||
#undef buffer
|
||||
#undef table
|
||||
|
||||
#undef br_bits_read
|
||||
#undef br_value
|
||||
#undef br_offset
|
||||
#undef peek_bits
|
||||
#undef exhausted
|
||||
|
||||
#undef br0
|
||||
#undef br1
|
||||
#undef br2
|
||||
#undef br3
|
197
vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in
generated
vendored
197
vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in
generated
vendored
@ -1,197 +0,0 @@
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !noasm
|
||||
|
||||
#include "textflag.h"
|
||||
#include "funcdata.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
|
||||
#define bufoff 256 // see decompress.go, we're using [4][256]byte table
|
||||
|
||||
//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted,
|
||||
// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool)
|
||||
TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8
|
||||
#define off R8
|
||||
#define buffer DI
|
||||
#define table SI
|
||||
|
||||
#define br_bits_read R9
|
||||
#define br_value R10
|
||||
#define br_offset R11
|
||||
#define peek_bits R12
|
||||
#define exhausted DX
|
||||
|
||||
#define br0 R13
|
||||
#define br1 R14
|
||||
#define br2 R15
|
||||
#define br3 BP
|
||||
|
||||
MOVQ BP, 0(SP)
|
||||
|
||||
XORQ exhausted, exhausted // exhausted = false
|
||||
XORQ off, off // off = 0
|
||||
|
||||
MOVBQZX peekBits+32(FP), peek_bits
|
||||
MOVQ buf+40(FP), buffer
|
||||
MOVQ tbl+48(FP), table
|
||||
|
||||
MOVQ pbr0+0(FP), br0
|
||||
MOVQ pbr1+8(FP), br1
|
||||
MOVQ pbr2+16(FP), br2
|
||||
MOVQ pbr3+24(FP), br3
|
||||
|
||||
main_loop:
|
||||
{{ define "decode_2_values_x86" }}
|
||||
// const stream = {{ var "id" }}
|
||||
// br{{ var "id"}}.fillFast()
|
||||
MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read
|
||||
MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value
|
||||
MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset
|
||||
|
||||
// if b.bitsRead >= 32 {
|
||||
CMPQ br_bits_read, $32
|
||||
JB skip_fill{{ var "id" }}
|
||||
|
||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
||||
SUBQ $4, br_offset // b.off -= 4
|
||||
|
||||
// v := b.in[b.off-4 : b.off]
|
||||
// v = v[:4]
|
||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
||||
MOVQ bitReaderShifted_in(br{{ var "id" }}), AX
|
||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
||||
|
||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
||||
MOVQ br_bits_read, CX
|
||||
SHLQ CL, AX
|
||||
ORQ AX, br_value
|
||||
|
||||
// exhausted = exhausted || (br{{ var "id"}}.off < 4)
|
||||
CMPQ br_offset, $4
|
||||
SETLT DL
|
||||
ORB DL, DH
|
||||
// }
|
||||
skip_fill{{ var "id" }}:
|
||||
|
||||
// val0 := br{{ var "id"}}.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v0 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br{{ var "id"}}.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val1 := br{{ var "id"}}.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v1 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br{{ var "id"}}.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
||||
MOVW BX, {{ var "bufofs" }}(buffer)(off*1)
|
||||
|
||||
// SECOND PART:
|
||||
// val2 := br{{ var "id"}}.peekTopBits(peekBits)
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v2 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br{{ var "id"}}.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
// val3 := br{{ var "id"}}.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
|
||||
// v3 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br{{ var "id"}}.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CX, br_value // value <<= n
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off+2] = uint8(v2.entry >> 8)
|
||||
// buf[stream][off+3] = uint8(v3.entry >> 8)
|
||||
MOVW BX, {{ var "bufofs" }}+2(buffer)(off*1)
|
||||
|
||||
// update the bitrader reader structure
|
||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }})
|
||||
MOVQ br_value, bitReaderShifted_value(br{{ var "id" }})
|
||||
MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }})
|
||||
{{ end }}
|
||||
|
||||
{{ set "id" "0" }}
|
||||
{{ set "ofs" "0" }}
|
||||
{{ set "bufofs" "0" }} {{/* id * bufoff */}}
|
||||
{{ template "decode_2_values_x86" . }}
|
||||
|
||||
{{ set "id" "1" }}
|
||||
{{ set "ofs" "8" }}
|
||||
{{ set "bufofs" "256" }}
|
||||
{{ template "decode_2_values_x86" . }}
|
||||
|
||||
{{ set "id" "2" }}
|
||||
{{ set "ofs" "16" }}
|
||||
{{ set "bufofs" "512" }}
|
||||
{{ template "decode_2_values_x86" . }}
|
||||
|
||||
{{ set "id" "3" }}
|
||||
{{ set "ofs" "24" }}
|
||||
{{ set "bufofs" "768" }}
|
||||
{{ template "decode_2_values_x86" . }}
|
||||
|
||||
ADDQ $4, off // off += 2
|
||||
|
||||
TESTB DH, DH // any br[i].ofs < 4?
|
||||
JNZ end
|
||||
|
||||
CMPQ off, $bufoff
|
||||
JL main_loop
|
||||
end:
|
||||
MOVQ 0(SP), BP
|
||||
|
||||
MOVB off, ret+56(FP)
|
||||
RET
|
||||
#undef off
|
||||
#undef buffer
|
||||
#undef table
|
||||
|
||||
#undef br_bits_read
|
||||
#undef br_value
|
||||
#undef br_offset
|
||||
#undef peek_bits
|
||||
#undef exhausted
|
||||
|
||||
#undef br0
|
||||
#undef br1
|
||||
#undef br2
|
||||
#undef br3
|
181
vendor/github.com/klauspost/compress/huff0/decompress_amd64.go
generated
vendored
181
vendor/github.com/klauspost/compress/huff0/decompress_amd64.go
generated
vendored
@ -2,30 +2,43 @@
|
||||
// +build amd64,!appengine,!noasm,gc
|
||||
|
||||
// This file contains the specialisation of Decoder.Decompress4X
|
||||
// that uses an asm implementation of its main loop.
|
||||
// and Decoder.Decompress1X that use an asm implementation of thir main loops.
|
||||
package huff0
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/klauspost/compress/internal/cpuinfo"
|
||||
)
|
||||
|
||||
// decompress4x_main_loop_x86 is an x86 assembler implementation
|
||||
// of Decompress4X when tablelog > 8.
|
||||
// go:noescape
|
||||
func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted,
|
||||
peekBits uint8, buf *byte, tbl *dEntrySingle) uint8
|
||||
//go:noescape
|
||||
func decompress4x_main_loop_amd64(ctx *decompress4xContext)
|
||||
|
||||
// decompress4x_8b_loop_x86 is an x86 assembler implementation
|
||||
// of Decompress4X when tablelog <= 8 which decodes 4 entries
|
||||
// per loop.
|
||||
// go:noescape
|
||||
func decompress4x_8b_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted,
|
||||
peekBits uint8, buf *byte, tbl *dEntrySingle) uint8
|
||||
//go:noescape
|
||||
func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext)
|
||||
|
||||
// fallback8BitSize is the size where using Go version is faster.
|
||||
const fallback8BitSize = 800
|
||||
|
||||
type decompress4xContext struct {
|
||||
pbr0 *bitReaderShifted
|
||||
pbr1 *bitReaderShifted
|
||||
pbr2 *bitReaderShifted
|
||||
pbr3 *bitReaderShifted
|
||||
peekBits uint8
|
||||
out *byte
|
||||
dstEvery int
|
||||
tbl *dEntrySingle
|
||||
decoded int
|
||||
limit *byte
|
||||
}
|
||||
|
||||
// Decompress4X will decompress a 4X encoded stream.
|
||||
// The length of the supplied input must match the end of a block exactly.
|
||||
// The *capacity* of the dst slice must match the destination size of
|
||||
@ -42,6 +55,7 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
|
||||
if cap(dst) < fallback8BitSize && use8BitTables {
|
||||
return d.decompress4X8bit(dst, src)
|
||||
}
|
||||
|
||||
var br [4]bitReaderShifted
|
||||
// Decode "jump table"
|
||||
start := 6
|
||||
@ -71,70 +85,28 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
|
||||
const tlMask = tlSize - 1
|
||||
single := d.dt.single[:tlSize]
|
||||
|
||||
// Use temp table to avoid bound checks/append penalty.
|
||||
buf := d.buffer()
|
||||
var off uint8
|
||||
var decoded int
|
||||
|
||||
const debug = false
|
||||
|
||||
// see: bitReaderShifted.peekBitsFast()
|
||||
peekBits := uint8((64 - d.actualTableLog) & 63)
|
||||
|
||||
// Decode 2 values from each decoder/loop.
|
||||
const bufoff = 256
|
||||
for {
|
||||
if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {
|
||||
break
|
||||
if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) {
|
||||
ctx := decompress4xContext{
|
||||
pbr0: &br[0],
|
||||
pbr1: &br[1],
|
||||
pbr2: &br[2],
|
||||
pbr3: &br[3],
|
||||
peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast()
|
||||
out: &out[0],
|
||||
dstEvery: dstEvery,
|
||||
tbl: &single[0],
|
||||
limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last.
|
||||
}
|
||||
|
||||
if use8BitTables {
|
||||
off = decompress4x_8b_loop_x86(&br[0], &br[1], &br[2], &br[3], peekBits, &buf[0][0], &single[0])
|
||||
decompress4x_8b_main_loop_amd64(&ctx)
|
||||
} else {
|
||||
off = decompress4x_main_loop_x86(&br[0], &br[1], &br[2], &br[3], peekBits, &buf[0][0], &single[0])
|
||||
}
|
||||
if debug {
|
||||
fmt.Print("DEBUG: ")
|
||||
fmt.Printf("off=%d,", off)
|
||||
for i := 0; i < 4; i++ {
|
||||
fmt.Printf(" br[%d]={bitsRead=%d, value=%x, off=%d}",
|
||||
i, br[i].bitsRead, br[i].value, br[i].off)
|
||||
}
|
||||
fmt.Println("")
|
||||
decompress4x_main_loop_amd64(&ctx)
|
||||
}
|
||||
|
||||
if off != 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if bufoff > dstEvery {
|
||||
d.bufs.Put(buf)
|
||||
return nil, errors.New("corruption detected: stream overrun 1")
|
||||
}
|
||||
copy(out, buf[0][:])
|
||||
copy(out[dstEvery:], buf[1][:])
|
||||
copy(out[dstEvery*2:], buf[2][:])
|
||||
copy(out[dstEvery*3:], buf[3][:])
|
||||
out = out[bufoff:]
|
||||
decoded += bufoff * 4
|
||||
// There must at least be 3 buffers left.
|
||||
if len(out) < dstEvery*3 {
|
||||
d.bufs.Put(buf)
|
||||
return nil, errors.New("corruption detected: stream overrun 2")
|
||||
}
|
||||
}
|
||||
if off > 0 {
|
||||
ioff := int(off)
|
||||
if len(out) < dstEvery*3+ioff {
|
||||
d.bufs.Put(buf)
|
||||
return nil, errors.New("corruption detected: stream overrun 3")
|
||||
}
|
||||
copy(out, buf[0][:off])
|
||||
copy(out[dstEvery:], buf[1][:off])
|
||||
copy(out[dstEvery*2:], buf[2][:off])
|
||||
copy(out[dstEvery*3:], buf[3][:off])
|
||||
decoded += int(off) * 4
|
||||
out = out[off:]
|
||||
decoded = ctx.decoded
|
||||
out = out[decoded/4:]
|
||||
}
|
||||
|
||||
// Decode remaining.
|
||||
@ -150,7 +122,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
|
||||
for bitsLeft > 0 {
|
||||
br.fill()
|
||||
if offset >= endsAt {
|
||||
d.bufs.Put(buf)
|
||||
return nil, errors.New("corruption detected: stream overrun 4")
|
||||
}
|
||||
|
||||
@ -164,7 +135,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
|
||||
offset++
|
||||
}
|
||||
if offset != endsAt {
|
||||
d.bufs.Put(buf)
|
||||
return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt)
|
||||
}
|
||||
decoded += offset - dstEvery*i
|
||||
@ -173,9 +143,86 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
d.bufs.Put(buf)
|
||||
if dstSize != decoded {
|
||||
return nil, errors.New("corruption detected: short output block")
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// decompress4x_main_loop_x86 is an x86 assembler implementation
|
||||
// of Decompress1X when tablelog > 8.
|
||||
//go:noescape
|
||||
func decompress1x_main_loop_amd64(ctx *decompress1xContext)
|
||||
|
||||
// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation
|
||||
// of Decompress1X when tablelog > 8.
|
||||
//go:noescape
|
||||
func decompress1x_main_loop_bmi2(ctx *decompress1xContext)
|
||||
|
||||
type decompress1xContext struct {
|
||||
pbr *bitReaderShifted
|
||||
peekBits uint8
|
||||
out *byte
|
||||
outCap int
|
||||
tbl *dEntrySingle
|
||||
decoded int
|
||||
}
|
||||
|
||||
// Error reported by asm implementations
|
||||
const error_max_decoded_size_exeeded = -1
|
||||
|
||||
// Decompress1X will decompress a 1X encoded stream.
|
||||
// The cap of the output buffer will be the maximum decompressed size.
|
||||
// The length of the supplied input must match the end of a block exactly.
|
||||
func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {
|
||||
if len(d.dt.single) == 0 {
|
||||
return nil, errors.New("no table loaded")
|
||||
}
|
||||
var br bitReaderShifted
|
||||
err := br.init(src)
|
||||
if err != nil {
|
||||
return dst, err
|
||||
}
|
||||
maxDecodedSize := cap(dst)
|
||||
dst = dst[:maxDecodedSize]
|
||||
|
||||
const tlSize = 1 << tableLogMax
|
||||
const tlMask = tlSize - 1
|
||||
|
||||
if maxDecodedSize >= 4 {
|
||||
ctx := decompress1xContext{
|
||||
pbr: &br,
|
||||
out: &dst[0],
|
||||
outCap: maxDecodedSize,
|
||||
peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast()
|
||||
tbl: &d.dt.single[0],
|
||||
}
|
||||
|
||||
if cpuinfo.HasBMI2() {
|
||||
decompress1x_main_loop_bmi2(&ctx)
|
||||
} else {
|
||||
decompress1x_main_loop_amd64(&ctx)
|
||||
}
|
||||
if ctx.decoded == error_max_decoded_size_exeeded {
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
|
||||
dst = dst[:ctx.decoded]
|
||||
}
|
||||
|
||||
// br < 8, so uint8 is fine
|
||||
bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead
|
||||
for bitsLeft > 0 {
|
||||
br.fill()
|
||||
if len(dst) >= maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
nBits := uint8(v.entry)
|
||||
br.advance(nBits)
|
||||
bitsLeft -= nBits
|
||||
dst = append(dst, uint8(v.entry>>8))
|
||||
}
|
||||
return dst, br.close()
|
||||
}
|
||||
|
1185
vendor/github.com/klauspost/compress/huff0/decompress_amd64.s
generated
vendored
1185
vendor/github.com/klauspost/compress/huff0/decompress_amd64.s
generated
vendored
File diff suppressed because it is too large
Load Diff
195
vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in
generated
vendored
195
vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in
generated
vendored
@ -1,195 +0,0 @@
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !noasm
|
||||
|
||||
#include "textflag.h"
|
||||
#include "funcdata.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
#ifdef GOAMD64_v4
|
||||
#ifndef GOAMD64_v3
|
||||
#define GOAMD64_v3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define bufoff 256 // see decompress.go, we're using [4][256]byte table
|
||||
|
||||
//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted,
|
||||
// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool)
|
||||
TEXT ·decompress4x_main_loop_x86(SB), NOSPLIT, $8
|
||||
#define off R8
|
||||
#define buffer DI
|
||||
#define table SI
|
||||
|
||||
#define br_bits_read R9
|
||||
#define br_value R10
|
||||
#define br_offset R11
|
||||
#define peek_bits R12
|
||||
#define exhausted DX
|
||||
|
||||
#define br0 R13
|
||||
#define br1 R14
|
||||
#define br2 R15
|
||||
#define br3 BP
|
||||
|
||||
MOVQ BP, 0(SP)
|
||||
|
||||
XORQ exhausted, exhausted // exhausted = false
|
||||
XORQ off, off // off = 0
|
||||
|
||||
MOVBQZX peekBits+32(FP), peek_bits
|
||||
MOVQ buf+40(FP), buffer
|
||||
MOVQ tbl+48(FP), table
|
||||
|
||||
MOVQ pbr0+0(FP), br0
|
||||
MOVQ pbr1+8(FP), br1
|
||||
MOVQ pbr2+16(FP), br2
|
||||
MOVQ pbr3+24(FP), br3
|
||||
|
||||
main_loop:
|
||||
{{ define "decode_2_values_x86" }}
|
||||
// const stream = {{ var "id" }}
|
||||
// br{{ var "id"}}.fillFast()
|
||||
MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read
|
||||
MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value
|
||||
MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset
|
||||
|
||||
// We must have at least 2 * max tablelog left
|
||||
CMPQ br_bits_read, $64-22
|
||||
JBE skip_fill{{ var "id" }}
|
||||
|
||||
SUBQ $32, br_bits_read // b.bitsRead -= 32
|
||||
SUBQ $4, br_offset // b.off -= 4
|
||||
|
||||
// v := b.in[b.off-4 : b.off]
|
||||
// v = v[:4]
|
||||
// low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
||||
MOVQ bitReaderShifted_in(br{{ var "id" }}), AX
|
||||
|
||||
// b.value |= uint64(low) << (b.bitsRead & 63)
|
||||
#ifdef GOAMD64_v3
|
||||
SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63)
|
||||
#else
|
||||
MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4])
|
||||
MOVQ br_bits_read, CX
|
||||
SHLQ CL, AX
|
||||
#endif
|
||||
|
||||
ORQ AX, br_value
|
||||
|
||||
// exhausted = exhausted || (br{{ var "id"}}.off < 4)
|
||||
CMPQ br_offset, $4
|
||||
SETLT DL
|
||||
ORB DL, DH
|
||||
// }
|
||||
skip_fill{{ var "id" }}:
|
||||
|
||||
// val0 := br{{ var "id"}}.peekTopBits(peekBits)
|
||||
#ifdef GOAMD64_v3
|
||||
SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask
|
||||
#else
|
||||
MOVQ br_value, AX
|
||||
MOVQ peek_bits, CX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
#endif
|
||||
|
||||
// v0 := table[val0&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v0
|
||||
|
||||
// br{{ var "id"}}.advance(uint8(v0.entry))
|
||||
MOVB AH, BL // BL = uint8(v0.entry >> 8)
|
||||
|
||||
#ifdef GOAMD64_v3
|
||||
MOVBQZX AL, CX
|
||||
SHLXQ AX, br_value, br_value // value <<= n
|
||||
#else
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
#endif
|
||||
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
|
||||
#ifdef GOAMD64_v3
|
||||
SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask
|
||||
#else
|
||||
// val1 := br{{ var "id"}}.peekTopBits(peekBits)
|
||||
MOVQ peek_bits, CX
|
||||
MOVQ br_value, AX
|
||||
SHRQ CL, AX // AX = (value >> peek_bits) & mask
|
||||
#endif
|
||||
|
||||
// v1 := table[val1&mask]
|
||||
MOVW 0(table)(AX*2), AX // AX - v1
|
||||
|
||||
// br{{ var "id"}}.advance(uint8(v1.entry))
|
||||
MOVB AH, BH // BH = uint8(v1.entry >> 8)
|
||||
|
||||
#ifdef GOAMD64_v3
|
||||
MOVBQZX AL, CX
|
||||
SHLXQ AX, br_value, br_value // value <<= n
|
||||
#else
|
||||
MOVBQZX AL, CX
|
||||
SHLQ CL, br_value // value <<= n
|
||||
#endif
|
||||
|
||||
ADDQ CX, br_bits_read // bits_read += n
|
||||
|
||||
|
||||
// these two writes get coalesced
|
||||
// buf[stream][off] = uint8(v0.entry >> 8)
|
||||
// buf[stream][off+1] = uint8(v1.entry >> 8)
|
||||
MOVW BX, {{ var "bufofs" }}(buffer)(off*1)
|
||||
|
||||
// update the bitrader reader structure
|
||||
MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }})
|
||||
MOVQ br_value, bitReaderShifted_value(br{{ var "id" }})
|
||||
MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }})
|
||||
{{ end }}
|
||||
|
||||
{{ set "id" "0" }}
|
||||
{{ set "ofs" "0" }}
|
||||
{{ set "bufofs" "0" }} {{/* id * bufoff */}}
|
||||
{{ template "decode_2_values_x86" . }}
|
||||
|
||||
{{ set "id" "1" }}
|
||||
{{ set "ofs" "8" }}
|
||||
{{ set "bufofs" "256" }}
|
||||
{{ template "decode_2_values_x86" . }}
|
||||
|
||||
{{ set "id" "2" }}
|
||||
{{ set "ofs" "16" }}
|
||||
{{ set "bufofs" "512" }}
|
||||
{{ template "decode_2_values_x86" . }}
|
||||
|
||||
{{ set "id" "3" }}
|
||||
{{ set "ofs" "24" }}
|
||||
{{ set "bufofs" "768" }}
|
||||
{{ template "decode_2_values_x86" . }}
|
||||
|
||||
ADDQ $2, off // off += 2
|
||||
|
||||
TESTB DH, DH // any br[i].ofs < 4?
|
||||
JNZ end
|
||||
|
||||
CMPQ off, $bufoff
|
||||
JL main_loop
|
||||
end:
|
||||
MOVQ 0(SP), BP
|
||||
|
||||
MOVB off, ret+56(FP)
|
||||
RET
|
||||
#undef off
|
||||
#undef buffer
|
||||
#undef table
|
||||
|
||||
#undef br_bits_read
|
||||
#undef br_value
|
||||
#undef br_offset
|
||||
#undef peek_bits
|
||||
#undef exhausted
|
||||
|
||||
#undef br0
|
||||
#undef br1
|
||||
#undef br2
|
||||
#undef br3
|
102
vendor/github.com/klauspost/compress/huff0/decompress_generic.go
generated
vendored
102
vendor/github.com/klauspost/compress/huff0/decompress_generic.go
generated
vendored
@ -191,3 +191,105 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// Decompress1X will decompress a 1X encoded stream.
|
||||
// The cap of the output buffer will be the maximum decompressed size.
|
||||
// The length of the supplied input must match the end of a block exactly.
|
||||
func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {
|
||||
if len(d.dt.single) == 0 {
|
||||
return nil, errors.New("no table loaded")
|
||||
}
|
||||
if use8BitTables && d.actualTableLog <= 8 {
|
||||
return d.decompress1X8Bit(dst, src)
|
||||
}
|
||||
var br bitReaderShifted
|
||||
err := br.init(src)
|
||||
if err != nil {
|
||||
return dst, err
|
||||
}
|
||||
maxDecodedSize := cap(dst)
|
||||
dst = dst[:0]
|
||||
|
||||
// Avoid bounds check by always having full sized table.
|
||||
const tlSize = 1 << tableLogMax
|
||||
const tlMask = tlSize - 1
|
||||
dt := d.dt.single[:tlSize]
|
||||
|
||||
// Use temp table to avoid bound checks/append penalty.
|
||||
bufs := d.buffer()
|
||||
buf := &bufs[0]
|
||||
var off uint8
|
||||
|
||||
for br.off >= 8 {
|
||||
br.fillFast()
|
||||
v := dt[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
// Refill
|
||||
br.fillFast()
|
||||
|
||||
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
d.bufs.Put(bufs)
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
|
||||
if len(dst)+int(off) > maxDecodedSize {
|
||||
d.bufs.Put(bufs)
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:off]...)
|
||||
|
||||
// br < 8, so uint8 is fine
|
||||
bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead
|
||||
for bitsLeft > 0 {
|
||||
br.fill()
|
||||
if false && br.bitsRead >= 32 {
|
||||
if br.off >= 4 {
|
||||
v := br.in[br.off-4:]
|
||||
v = v[:4]
|
||||
low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
|
||||
br.value = (br.value << 32) | uint64(low)
|
||||
br.bitsRead -= 32
|
||||
br.off -= 4
|
||||
} else {
|
||||
for br.off > 0 {
|
||||
br.value = (br.value << 8) | uint64(br.in[br.off-1])
|
||||
br.bitsRead -= 8
|
||||
br.off--
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(dst) >= maxDecodedSize {
|
||||
d.bufs.Put(bufs)
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]
|
||||
nBits := uint8(v.entry)
|
||||
br.advance(nBits)
|
||||
bitsLeft -= nBits
|
||||
dst = append(dst, uint8(v.entry>>8))
|
||||
}
|
||||
d.bufs.Put(bufs)
|
||||
return dst, br.close()
|
||||
}
|
||||
|
34
vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go
generated
vendored
Normal file
34
vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
// Package cpuinfo gives runtime info about the current CPU.
|
||||
//
|
||||
// This is a very limited module meant for use internally
|
||||
// in this project. For more versatile solution check
|
||||
// https://github.com/klauspost/cpuid.
|
||||
package cpuinfo
|
||||
|
||||
// HasBMI1 checks whether an x86 CPU supports the BMI1 extension.
|
||||
func HasBMI1() bool {
|
||||
return hasBMI1
|
||||
}
|
||||
|
||||
// HasBMI2 checks whether an x86 CPU supports the BMI2 extension.
|
||||
func HasBMI2() bool {
|
||||
return hasBMI2
|
||||
}
|
||||
|
||||
// DisableBMI2 will disable BMI2, for testing purposes.
|
||||
// Call returned function to restore previous state.
|
||||
func DisableBMI2() func() {
|
||||
old := hasBMI2
|
||||
hasBMI2 = false
|
||||
return func() {
|
||||
hasBMI2 = old
|
||||
}
|
||||
}
|
||||
|
||||
// HasBMI checks whether an x86 CPU supports both BMI1 and BMI2 extensions.
|
||||
func HasBMI() bool {
|
||||
return HasBMI1() && HasBMI2()
|
||||
}
|
||||
|
||||
var hasBMI1 bool
|
||||
var hasBMI2 bool
|
11
vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go
generated
vendored
Normal file
11
vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
//go:build amd64 && !appengine && !noasm && gc
|
||||
// +build amd64,!appengine,!noasm,gc
|
||||
|
||||
package cpuinfo
|
||||
|
||||
// go:noescape
|
||||
func x86extensions() (bmi1, bmi2 bool)
|
||||
|
||||
func init() {
|
||||
hasBMI1, hasBMI2 = x86extensions()
|
||||
}
|
36
vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s
generated
vendored
Normal file
36
vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !noasm
|
||||
|
||||
#include "textflag.h"
|
||||
#include "funcdata.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
TEXT ·x86extensions(SB), NOSPLIT, $0
|
||||
// 1. determine max EAX value
|
||||
XORQ AX, AX
|
||||
CPUID
|
||||
|
||||
CMPQ AX, $7
|
||||
JB unsupported
|
||||
|
||||
// 2. EAX = 7, ECX = 0 --- see Table 3-8 "Information Returned by CPUID Instruction"
|
||||
MOVQ $7, AX
|
||||
MOVQ $0, CX
|
||||
CPUID
|
||||
|
||||
BTQ $3, BX // bit 3 = BMI1
|
||||
SETCS AL
|
||||
|
||||
BTQ $8, BX // bit 8 = BMI2
|
||||
SETCS AH
|
||||
|
||||
MOVB AL, bmi1+0(FP)
|
||||
MOVB AH, bmi2+1(FP)
|
||||
RET
|
||||
|
||||
unsupported:
|
||||
XORQ AX, AX
|
||||
MOVB AL, bmi1+0(FP)
|
||||
MOVB AL, bmi2+1(FP)
|
||||
RET
|
30
vendor/github.com/klauspost/compress/s2/README.md
generated
vendored
30
vendor/github.com/klauspost/compress/s2/README.md
generated
vendored
@ -19,6 +19,7 @@ This is important, so you don't have to worry about spending CPU cycles on alrea
|
||||
* Adjustable compression (3 levels)
|
||||
* Concurrent stream compression
|
||||
* Faster decompression, even for Snappy compatible content
|
||||
* Concurrent Snappy/S2 stream decompression
|
||||
* Ability to quickly skip forward in compressed stream
|
||||
* Random seeking with indexes
|
||||
* Compatible with reading Snappy compressed content
|
||||
@ -415,6 +416,25 @@ Without assembly decompression is also very fast; single goroutine decompression
|
||||
|
||||
Even though S2 typically compresses better than Snappy, decompression speed is always better.
|
||||
|
||||
### Concurrent Stream Decompression
|
||||
|
||||
For full stream decompression S2 offers a [DecodeConcurrent](https://pkg.go.dev/github.com/klauspost/compress/s2#Reader.DecodeConcurrent)
|
||||
that will decode a full stream using multiple goroutines.
|
||||
|
||||
Example scaling, AMD Ryzen 3950X, 16 cores, decompression using `s2d -bench=3 <input>`, best of 3:
|
||||
|
||||
| Input | `-cpu=1` | `-cpu=2` | `-cpu=4` | `-cpu=8` | `-cpu=16` |
|
||||
|-------------------------------------------|------------|------------|------------|------------|-------------|
|
||||
| enwik10.snappy | 1098.6MB/s | 1819.8MB/s | 3625.6MB/s | 6910.6MB/s | 10818.2MB/s |
|
||||
| enwik10.s2 | 1303.5MB/s | 2606.1MB/s | 4847.9MB/s | 8878.4MB/s | 9592.1MB/s |
|
||||
| sofia-air-quality-dataset.tar.snappy | 1302.0MB/s | 2165.0MB/s | 4244.5MB/s | 8241.0MB/s | 12920.5MB/s |
|
||||
| sofia-air-quality-dataset.tar.s2 | 1399.2MB/s | 2463.2MB/s | 5196.5MB/s | 9639.8MB/s | 11439.5MB/s |
|
||||
| sofia-air-quality-dataset.tar.s2 (no asm) | 837.5MB/s | 1652.6MB/s | 3183.6MB/s | 5945.0MB/s | 9620.7MB/s |
|
||||
|
||||
Scaling can be expected to be pretty linear until memory bandwidth is saturated.
|
||||
|
||||
For now the DecodeConcurrent can only be used for full streams without seeking or combining with regular reads.
|
||||
|
||||
## Block compression
|
||||
|
||||
|
||||
@ -873,7 +893,7 @@ for each entry {
|
||||
}
|
||||
|
||||
// Uncompressed uses previous offset and adds EstBlockSize
|
||||
entry[entryNum].UncompressedOffset = entry[entryNum-1].UncompressedOffset + EstBlockSize
|
||||
entry[entryNum].UncompressedOffset = entry[entryNum-1].UncompressedOffset + EstBlockSize + uOff
|
||||
}
|
||||
|
||||
|
||||
@ -901,6 +921,14 @@ for each entry {
|
||||
}
|
||||
```
|
||||
|
||||
To decode from any given uncompressed offset `(wantOffset)`:
|
||||
|
||||
* Iterate entries until `entry[n].UncompressedOffset > wantOffset`.
|
||||
* Start decoding from `entry[n-1].CompressedOffset`.
|
||||
* Discard `entry[n-1].UncompressedOffset - wantOffset` bytes from the decoded stream.
|
||||
|
||||
See [using indexes](https://github.com/klauspost/compress/tree/master/s2#using-indexes) for functions that perform the operations with a simpler interface.
|
||||
|
||||
# Format Extensions
|
||||
|
||||
* Frame [Stream identifier](https://github.com/google/snappy/blob/master/framing_format.txt#L68) changed from `sNaPpY` to `S2sTwO`.
|
||||
|
289
vendor/github.com/klauspost/compress/s2/decode.go
generated
vendored
289
vendor/github.com/klauspost/compress/s2/decode.go
generated
vendored
@ -11,6 +11,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -169,6 +171,14 @@ func ReaderSkippableCB(id uint8, fn func(r io.Reader) error) ReaderOption {
|
||||
}
|
||||
}
|
||||
|
||||
// ReaderIgnoreCRC will make the reader skip CRC calculation and checks.
|
||||
func ReaderIgnoreCRC() ReaderOption {
|
||||
return func(r *Reader) error {
|
||||
r.ignoreCRC = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Reader is an io.Reader that can read Snappy-compressed bytes.
|
||||
type Reader struct {
|
||||
r io.Reader
|
||||
@ -191,18 +201,19 @@ type Reader struct {
|
||||
paramsOK bool
|
||||
snappyFrame bool
|
||||
ignoreStreamID bool
|
||||
ignoreCRC bool
|
||||
}
|
||||
|
||||
// ensureBufferSize will ensure that the buffer can take at least n bytes.
|
||||
// If false is returned the buffer exceeds maximum allowed size.
|
||||
func (r *Reader) ensureBufferSize(n int) bool {
|
||||
if len(r.buf) >= n {
|
||||
return true
|
||||
}
|
||||
if n > r.maxBufSize {
|
||||
r.err = ErrCorrupt
|
||||
return false
|
||||
}
|
||||
if cap(r.buf) >= n {
|
||||
return true
|
||||
}
|
||||
// Realloc buffer.
|
||||
r.buf = make([]byte, n)
|
||||
return true
|
||||
@ -220,6 +231,7 @@ func (r *Reader) Reset(reader io.Reader) {
|
||||
r.err = nil
|
||||
r.i = 0
|
||||
r.j = 0
|
||||
r.blockStart = 0
|
||||
r.readHeader = r.ignoreStreamID
|
||||
}
|
||||
|
||||
@ -344,7 +356,7 @@ func (r *Reader) Read(p []byte) (int, error) {
|
||||
r.err = err
|
||||
return 0, r.err
|
||||
}
|
||||
if crc(r.decoded[:n]) != checksum {
|
||||
if !r.ignoreCRC && crc(r.decoded[:n]) != checksum {
|
||||
r.err = ErrCRC
|
||||
return 0, r.err
|
||||
}
|
||||
@ -385,7 +397,7 @@ func (r *Reader) Read(p []byte) (int, error) {
|
||||
if !r.readFull(r.decoded[:n], false) {
|
||||
return 0, r.err
|
||||
}
|
||||
if crc(r.decoded[:n]) != checksum {
|
||||
if !r.ignoreCRC && crc(r.decoded[:n]) != checksum {
|
||||
r.err = ErrCRC
|
||||
return 0, r.err
|
||||
}
|
||||
@ -435,6 +447,259 @@ func (r *Reader) Read(p []byte) (int, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// DecodeConcurrent will decode the full stream to w.
|
||||
// This function should not be combined with reading, seeking or other operations.
|
||||
// Up to 'concurrent' goroutines will be used.
|
||||
// If <= 0, runtime.NumCPU will be used.
|
||||
// On success the number of bytes decompressed nil and is returned.
|
||||
// This is mainly intended for bigger streams.
|
||||
func (r *Reader) DecodeConcurrent(w io.Writer, concurrent int) (written int64, err error) {
|
||||
if r.i > 0 || r.j > 0 || r.blockStart > 0 {
|
||||
return 0, errors.New("DecodeConcurrent called after ")
|
||||
}
|
||||
if concurrent <= 0 {
|
||||
concurrent = runtime.NumCPU()
|
||||
}
|
||||
|
||||
// Write to output
|
||||
var errMu sync.Mutex
|
||||
var aErr error
|
||||
setErr := func(e error) (ok bool) {
|
||||
errMu.Lock()
|
||||
defer errMu.Unlock()
|
||||
if e == nil {
|
||||
return aErr == nil
|
||||
}
|
||||
if aErr == nil {
|
||||
aErr = e
|
||||
}
|
||||
return false
|
||||
}
|
||||
hasErr := func() (ok bool) {
|
||||
errMu.Lock()
|
||||
v := aErr != nil
|
||||
errMu.Unlock()
|
||||
return v
|
||||
}
|
||||
|
||||
var aWritten int64
|
||||
toRead := make(chan []byte, concurrent)
|
||||
writtenBlocks := make(chan []byte, concurrent)
|
||||
queue := make(chan chan []byte, concurrent)
|
||||
reUse := make(chan chan []byte, concurrent)
|
||||
for i := 0; i < concurrent; i++ {
|
||||
toRead <- make([]byte, 0, r.maxBufSize)
|
||||
writtenBlocks <- make([]byte, 0, r.maxBufSize)
|
||||
reUse <- make(chan []byte, 1)
|
||||
}
|
||||
// Writer
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for toWrite := range queue {
|
||||
entry := <-toWrite
|
||||
reUse <- toWrite
|
||||
if hasErr() {
|
||||
writtenBlocks <- entry
|
||||
continue
|
||||
}
|
||||
n, err := w.Write(entry)
|
||||
want := len(entry)
|
||||
writtenBlocks <- entry
|
||||
if err != nil {
|
||||
setErr(err)
|
||||
continue
|
||||
}
|
||||
if n != want {
|
||||
setErr(io.ErrShortWrite)
|
||||
continue
|
||||
}
|
||||
aWritten += int64(n)
|
||||
}
|
||||
}()
|
||||
|
||||
// Reader
|
||||
defer func() {
|
||||
close(queue)
|
||||
if r.err != nil {
|
||||
err = r.err
|
||||
setErr(r.err)
|
||||
}
|
||||
wg.Wait()
|
||||
if err == nil {
|
||||
err = aErr
|
||||
}
|
||||
written = aWritten
|
||||
}()
|
||||
|
||||
for !hasErr() {
|
||||
if !r.readFull(r.buf[:4], true) {
|
||||
if r.err == io.EOF {
|
||||
r.err = nil
|
||||
}
|
||||
return 0, r.err
|
||||
}
|
||||
chunkType := r.buf[0]
|
||||
if !r.readHeader {
|
||||
if chunkType != chunkTypeStreamIdentifier {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
r.readHeader = true
|
||||
}
|
||||
chunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16
|
||||
|
||||
// The chunk types are specified at
|
||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
switch chunkType {
|
||||
case chunkTypeCompressedData:
|
||||
r.blockStart += int64(r.j)
|
||||
// Section 4.2. Compressed data (chunk type 0x00).
|
||||
if chunkLen < checksumSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if chunkLen > r.maxBufSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
orgBuf := <-toRead
|
||||
buf := orgBuf[:chunkLen]
|
||||
|
||||
if !r.readFull(buf, false) {
|
||||
return 0, r.err
|
||||
}
|
||||
|
||||
checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
|
||||
buf = buf[checksumSize:]
|
||||
|
||||
n, err := DecodedLen(buf)
|
||||
if err != nil {
|
||||
r.err = err
|
||||
return 0, r.err
|
||||
}
|
||||
if r.snappyFrame && n > maxSnappyBlockSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
|
||||
if n > r.maxBlock {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
wg.Add(1)
|
||||
|
||||
decoded := <-writtenBlocks
|
||||
entry := <-reUse
|
||||
queue <- entry
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
decoded = decoded[:n]
|
||||
_, err := Decode(decoded, buf)
|
||||
toRead <- orgBuf
|
||||
if err != nil {
|
||||
writtenBlocks <- decoded
|
||||
setErr(err)
|
||||
return
|
||||
}
|
||||
if !r.ignoreCRC && crc(decoded) != checksum {
|
||||
writtenBlocks <- decoded
|
||||
setErr(ErrCRC)
|
||||
return
|
||||
}
|
||||
entry <- decoded
|
||||
}()
|
||||
continue
|
||||
|
||||
case chunkTypeUncompressedData:
|
||||
|
||||
// Section 4.3. Uncompressed data (chunk type 0x01).
|
||||
if chunkLen < checksumSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if chunkLen > r.maxBufSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
// Grab write buffer
|
||||
orgBuf := <-writtenBlocks
|
||||
buf := orgBuf[:checksumSize]
|
||||
if !r.readFull(buf, false) {
|
||||
return 0, r.err
|
||||
}
|
||||
checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
|
||||
// Read content.
|
||||
n := chunkLen - checksumSize
|
||||
|
||||
if r.snappyFrame && n > maxSnappyBlockSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if n > r.maxBlock {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
// Read uncompressed
|
||||
buf = orgBuf[:n]
|
||||
if !r.readFull(buf, false) {
|
||||
return 0, r.err
|
||||
}
|
||||
|
||||
if !r.ignoreCRC && crc(buf) != checksum {
|
||||
r.err = ErrCRC
|
||||
return 0, r.err
|
||||
}
|
||||
entry := <-reUse
|
||||
queue <- entry
|
||||
entry <- buf
|
||||
continue
|
||||
|
||||
case chunkTypeStreamIdentifier:
|
||||
// Section 4.1. Stream identifier (chunk type 0xff).
|
||||
if chunkLen != len(magicBody) {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if !r.readFull(r.buf[:len(magicBody)], false) {
|
||||
return 0, r.err
|
||||
}
|
||||
if string(r.buf[:len(magicBody)]) != magicBody {
|
||||
if string(r.buf[:len(magicBody)]) != magicBodySnappy {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
} else {
|
||||
r.snappyFrame = true
|
||||
}
|
||||
} else {
|
||||
r.snappyFrame = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if chunkType <= 0x7f {
|
||||
// Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f).
|
||||
// fmt.Printf("ERR chunktype: 0x%x\n", chunkType)
|
||||
r.err = ErrUnsupported
|
||||
return 0, r.err
|
||||
}
|
||||
// Section 4.4 Padding (chunk type 0xfe).
|
||||
// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).
|
||||
if chunkLen > maxChunkSize {
|
||||
// fmt.Printf("ERR chunkLen: 0x%x\n", chunkLen)
|
||||
r.err = ErrUnsupported
|
||||
return 0, r.err
|
||||
}
|
||||
|
||||
// fmt.Printf("skippable: ID: 0x%x, len: 0x%x\n", chunkType, chunkLen)
|
||||
if !r.skippable(r.buf, chunkLen, false, chunkType) {
|
||||
return 0, r.err
|
||||
}
|
||||
}
|
||||
return 0, r.err
|
||||
}
|
||||
|
||||
// Skip will skip n bytes forward in the decompressed output.
|
||||
// For larger skips this consumes less CPU and is faster than reading output and discarding it.
|
||||
// CRC is not checked on skipped blocks.
|
||||
@ -699,8 +964,16 @@ func (r *ReadSeeker) Seek(offset int64, whence int) (int64, error) {
|
||||
case io.SeekCurrent:
|
||||
offset += r.blockStart + int64(r.i)
|
||||
case io.SeekEnd:
|
||||
offset = -offset
|
||||
if offset > 0 {
|
||||
return 0, errors.New("seek after end of file")
|
||||
}
|
||||
offset = r.index.TotalUncompressed + offset
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
return 0, errors.New("seek before start of file")
|
||||
}
|
||||
|
||||
c, u, err := r.index.Find(offset)
|
||||
if err != nil {
|
||||
return r.blockStart + int64(r.i), err
|
||||
@ -712,10 +985,6 @@ func (r *ReadSeeker) Seek(offset int64, whence int) (int64, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
offset = r.index.TotalUncompressed + offset
|
||||
}
|
||||
|
||||
r.i = r.j // Remove rest of current block.
|
||||
if u < offset {
|
||||
// Forward inside block
|
||||
|
6
vendor/github.com/klauspost/compress/s2/encode.go
generated
vendored
6
vendor/github.com/klauspost/compress/s2/encode.go
generated
vendored
@ -1119,12 +1119,6 @@ func (w *Writer) closeIndex(idx bool) ([]byte, error) {
|
||||
if w.appendIndex {
|
||||
w.written += int64(len(index))
|
||||
}
|
||||
if true {
|
||||
_, err := w.index.Load(index)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if w.pad > 1 {
|
||||
|
28
vendor/github.com/klauspost/compress/s2/encode_best.go
generated
vendored
28
vendor/github.com/klauspost/compress/s2/encode_best.go
generated
vendored
@ -370,7 +370,7 @@ func encodeBlockBestSnappy(dst, src []byte) (d int) {
|
||||
}
|
||||
offset := m.s - m.offset
|
||||
|
||||
return score - emitCopySize(offset, m.length)
|
||||
return score - emitCopyNoRepeatSize(offset, m.length)
|
||||
}
|
||||
|
||||
matchAt := func(offset, s int, first uint32) match {
|
||||
@ -567,6 +567,10 @@ func emitCopySize(offset, length int) int {
|
||||
|
||||
// Offset no more than 2 bytes.
|
||||
if length > 64 {
|
||||
if offset < 2048 {
|
||||
// Emit 8 bytes, then rest as repeats...
|
||||
return 2 + emitRepeatSize(offset, length-8)
|
||||
}
|
||||
// Emit remaining as repeats, at least 4 bytes remain.
|
||||
return 3 + emitRepeatSize(offset, length-60)
|
||||
}
|
||||
@ -577,6 +581,28 @@ func emitCopySize(offset, length int) int {
|
||||
return 2
|
||||
}
|
||||
|
||||
// emitCopyNoRepeatSize returns the size to encode the offset+length
|
||||
//
|
||||
// It assumes that:
|
||||
// 1 <= offset && offset <= math.MaxUint32
|
||||
// 4 <= length && length <= 1 << 24
|
||||
func emitCopyNoRepeatSize(offset, length int) int {
|
||||
if offset >= 65536 {
|
||||
return 5 + 5*(length/64)
|
||||
}
|
||||
|
||||
// Offset no more than 2 bytes.
|
||||
if length > 64 {
|
||||
// Emit remaining as repeats, at least 4 bytes remain.
|
||||
return 3 + 3*(length/60)
|
||||
}
|
||||
if length >= 12 || offset >= 2048 {
|
||||
return 3
|
||||
}
|
||||
// Emit the remaining copy, encoded as 2 bytes.
|
||||
return 2
|
||||
}
|
||||
|
||||
// emitRepeatSize returns the number of bytes required to encode a repeat.
|
||||
// Length must be at least 4 and < 1<<24
|
||||
func emitRepeatSize(offset, length int) int {
|
||||
|
23
vendor/github.com/klauspost/compress/s2/encode_go.go
generated
vendored
23
vendor/github.com/klauspost/compress/s2/encode_go.go
generated
vendored
@ -180,14 +180,23 @@ func emitCopy(dst []byte, offset, length int) int {
|
||||
|
||||
// Offset no more than 2 bytes.
|
||||
if length > 64 {
|
||||
// Emit a length 60 copy, encoded as 3 bytes.
|
||||
// Emit remaining as repeat value (minimum 4 bytes).
|
||||
dst[2] = uint8(offset >> 8)
|
||||
dst[1] = uint8(offset)
|
||||
dst[0] = 59<<2 | tagCopy2
|
||||
length -= 60
|
||||
off := 3
|
||||
if offset < 2048 {
|
||||
// emit 8 bytes as tagCopy1, rest as repeats.
|
||||
dst[1] = uint8(offset)
|
||||
dst[0] = uint8(offset>>8)<<5 | uint8(8-4)<<2 | tagCopy1
|
||||
length -= 8
|
||||
off = 2
|
||||
} else {
|
||||
// Emit a length 60 copy, encoded as 3 bytes.
|
||||
// Emit remaining as repeat value (minimum 4 bytes).
|
||||
dst[2] = uint8(offset >> 8)
|
||||
dst[1] = uint8(offset)
|
||||
dst[0] = 59<<2 | tagCopy2
|
||||
length -= 60
|
||||
}
|
||||
// Emit remaining as repeats, at least 4 bytes remain.
|
||||
return 3 + emitRepeat(dst[3:], offset, length)
|
||||
return off + emitRepeat(dst[off:], offset, length)
|
||||
}
|
||||
if length >= 12 || offset >= 2048 {
|
||||
// Emit the remaining copy, encoded as 3 bytes.
|
||||
|
2
vendor/github.com/klauspost/compress/s2/encodeblock_amd64.go
generated
vendored
2
vendor/github.com/klauspost/compress/s2/encodeblock_amd64.go
generated
vendored
@ -5,6 +5,8 @@
|
||||
|
||||
package s2
|
||||
|
||||
func _dummy_()
|
||||
|
||||
// encodeBlockAsm encodes a non-empty src to a guaranteed-large-enough dst.
|
||||
// Maximum input 4294967295 bytes.
|
||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||
|
1930
vendor/github.com/klauspost/compress/s2/encodeblock_amd64.s
generated
vendored
1930
vendor/github.com/klauspost/compress/s2/encodeblock_amd64.s
generated
vendored
File diff suppressed because it is too large
Load Diff
10
vendor/github.com/klauspost/compress/s2/index.go
generated
vendored
10
vendor/github.com/klauspost/compress/s2/index.go
generated
vendored
@ -10,6 +10,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -100,6 +101,15 @@ func (i *Index) Find(offset int64) (compressedOff, uncompressedOff int64, err er
|
||||
if offset > i.TotalUncompressed {
|
||||
return 0, 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
if len(i.info) > 200 {
|
||||
n := sort.Search(len(i.info), func(n int) bool {
|
||||
return i.info[n].uncompressedOffset > offset
|
||||
})
|
||||
if n == 0 {
|
||||
n = 1
|
||||
}
|
||||
return i.info[n-1].compressedOffset, i.info[n-1].uncompressedOffset, nil
|
||||
}
|
||||
for _, info := range i.info {
|
||||
if info.uncompressedOffset > offset {
|
||||
break
|
||||
|
54
vendor/github.com/klauspost/compress/zstd/README.md
generated
vendored
54
vendor/github.com/klauspost/compress/zstd/README.md
generated
vendored
@ -386,47 +386,31 @@ In practice this means that concurrency is often limited to utilizing about 3 co
|
||||
|
||||
### Benchmarks
|
||||
|
||||
These are some examples of performance compared to [datadog cgo library](https://github.com/DataDog/zstd).
|
||||
|
||||
The first two are streaming decodes and the last are smaller inputs.
|
||||
|
||||
|
||||
Running on AMD Ryzen 9 3950X 16-Core Processor. AMD64 assembly used.
|
||||
|
||||
```
|
||||
BenchmarkDecoderSilesia-8 3 385000067 ns/op 550.51 MB/s 5498 B/op 8 allocs/op
|
||||
BenchmarkDecoderSilesiaCgo-8 6 197666567 ns/op 1072.25 MB/s 270672 B/op 8 allocs/op
|
||||
BenchmarkDecoderSilesia-32 5 206878840 ns/op 1024.50 MB/s 49808 B/op 43 allocs/op
|
||||
BenchmarkDecoderEnwik9-32 1 1271809000 ns/op 786.28 MB/s 72048 B/op 52 allocs/op
|
||||
|
||||
BenchmarkDecoderEnwik9-8 1 2027001600 ns/op 493.34 MB/s 10496 B/op 18 allocs/op
|
||||
BenchmarkDecoderEnwik9Cgo-8 2 979499200 ns/op 1020.93 MB/s 270672 B/op 8 allocs/op
|
||||
Concurrent blocks, performance:
|
||||
|
||||
Concurrent performance:
|
||||
|
||||
BenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-16 28915 42469 ns/op 4340.07 MB/s 114 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-16 116505 9965 ns/op 11900.16 MB/s 16 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-16 8952 134272 ns/op 3588.70 MB/s 915 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-16 11820 102538 ns/op 4161.90 MB/s 594 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-16 34782 34184 ns/op 3661.88 MB/s 60 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-16 27712 43447 ns/op 3500.58 MB/s 99 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/html_x_4.zst-16 62826 18750 ns/op 21845.10 MB/s 104 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-16 631545 1794 ns/op 57078.74 MB/s 2 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-16 1690140 712 ns/op 172938.13 MB/s 1 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/urls.10K.zst-16 10432 113593 ns/op 6180.73 MB/s 1143 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/html.zst-16 113206 10671 ns/op 9596.27 MB/s 15 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-16 1530615 779 ns/op 5229.49 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/kppkn.gtb.zst-16 65217 16192 ns/op 11383.34 MB/s 46 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/geo.protodata.zst-16 292671 4039 ns/op 29363.19 MB/s 6 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/plrabn12.txt.zst-16 26314 46021 ns/op 10470.43 MB/s 293 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/lcet10.txt.zst-16 33897 34900 ns/op 12227.96 MB/s 205 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/asyoulik.txt.zst-16 104348 11433 ns/op 10949.01 MB/s 20 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/alice29.txt.zst-16 75949 15510 ns/op 9805.60 MB/s 32 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/html_x_4.zst-16 173910 6756 ns/op 60624.29 MB/s 37 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/paper-100k.pdf.zst-16 923076 1339 ns/op 76474.87 MB/s 1 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/fireworks.jpeg.zst-16 922920 1351 ns/op 91102.57 MB/s 2 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/urls.10K.zst-16 27649 43618 ns/op 16096.19 MB/s 407 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/html.zst-16 279073 4160 ns/op 24614.18 MB/s 6 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallelCgo/comp-data.bin.zst-16 749938 1579 ns/op 2581.71 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-32 67356 17857 ns/op 10321.96 MB/s 22.48 pct 102 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-32 266656 4421 ns/op 26823.21 MB/s 11.89 pct 19 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-32 20992 56842 ns/op 8477.17 MB/s 39.90 pct 754 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-32 27456 43932 ns/op 9714.01 MB/s 33.27 pct 524 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-32 78432 15047 ns/op 8319.15 MB/s 40.34 pct 66 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-32 65800 18436 ns/op 8249.63 MB/s 37.75 pct 88 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/html_x_4.zst-32 102993 11523 ns/op 35546.09 MB/s 3.637 pct 143 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-32 1000000 1070 ns/op 95720.98 MB/s 80.53 pct 3 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-32 749802 1752 ns/op 70272.35 MB/s 100.0 pct 5 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/urls.10K.zst-32 22640 52934 ns/op 13263.37 MB/s 26.25 pct 1014 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/html.zst-32 226412 5232 ns/op 19572.27 MB/s 14.49 pct 20 B/op 0 allocs/op
|
||||
BenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-32 923041 1276 ns/op 3194.71 MB/s 31.26 pct 0 B/op 0 allocs/op
|
||||
```
|
||||
|
||||
This reflects the performance around May 2020, but this may be out of date.
|
||||
This reflects the performance around May 2022, but this may be out of date.
|
||||
|
||||
## Zstd inside ZIP files
|
||||
|
||||
|
7
vendor/github.com/klauspost/compress/zstd/bitreader.go
generated
vendored
7
vendor/github.com/klauspost/compress/zstd/bitreader.go
generated
vendored
@ -63,13 +63,6 @@ func (b *bitReader) get32BitsFast(n uint8) uint32 {
|
||||
return v
|
||||
}
|
||||
|
||||
func (b *bitReader) get16BitsFast(n uint8) uint16 {
|
||||
const regMask = 64 - 1
|
||||
v := uint16((b.value << (b.bitsRead & regMask)) >> ((regMask + 1 - n) & regMask))
|
||||
b.bitsRead += n
|
||||
return v
|
||||
}
|
||||
|
||||
// fillFast() will make sure at least 32 bits are available.
|
||||
// There must be at least 4 bytes available.
|
||||
func (b *bitReader) fillFast() {
|
||||
|
76
vendor/github.com/klauspost/compress/zstd/bitwriter.go
generated
vendored
76
vendor/github.com/klauspost/compress/zstd/bitwriter.go
generated
vendored
@ -5,8 +5,6 @@
|
||||
|
||||
package zstd
|
||||
|
||||
import "fmt"
|
||||
|
||||
// bitWriter will write bits.
|
||||
// First bit will be LSB of the first byte of output.
|
||||
type bitWriter struct {
|
||||
@ -73,80 +71,6 @@ func (b *bitWriter) addBits16Clean(value uint16, bits uint8) {
|
||||
b.nBits += bits
|
||||
}
|
||||
|
||||
// flush will flush all pending full bytes.
|
||||
// There will be at least 56 bits available for writing when this has been called.
|
||||
// Using flush32 is faster, but leaves less space for writing.
|
||||
func (b *bitWriter) flush() {
|
||||
v := b.nBits >> 3
|
||||
switch v {
|
||||
case 0:
|
||||
case 1:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
)
|
||||
case 2:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
)
|
||||
case 3:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
)
|
||||
case 4:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
)
|
||||
case 5:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
)
|
||||
case 6:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
byte(b.bitContainer>>40),
|
||||
)
|
||||
case 7:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
byte(b.bitContainer>>40),
|
||||
byte(b.bitContainer>>48),
|
||||
)
|
||||
case 8:
|
||||
b.out = append(b.out,
|
||||
byte(b.bitContainer),
|
||||
byte(b.bitContainer>>8),
|
||||
byte(b.bitContainer>>16),
|
||||
byte(b.bitContainer>>24),
|
||||
byte(b.bitContainer>>32),
|
||||
byte(b.bitContainer>>40),
|
||||
byte(b.bitContainer>>48),
|
||||
byte(b.bitContainer>>56),
|
||||
)
|
||||
default:
|
||||
panic(fmt.Errorf("bits (%d) > 64", b.nBits))
|
||||
}
|
||||
b.bitContainer >>= v << 3
|
||||
b.nBits &= 7
|
||||
}
|
||||
|
||||
// flush32 will flush out, so there are at least 32 bits available for writing.
|
||||
func (b *bitWriter) flush32() {
|
||||
if b.nBits < 32 {
|
||||
|
73
vendor/github.com/klauspost/compress/zstd/blockdec.go
generated
vendored
73
vendor/github.com/klauspost/compress/zstd/blockdec.go
generated
vendored
@ -5,9 +5,14 @@
|
||||
package zstd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/klauspost/compress/huff0"
|
||||
@ -38,14 +43,14 @@ const (
|
||||
// maxCompressedBlockSize is the biggest allowed compressed block size (128KB)
|
||||
maxCompressedBlockSize = 128 << 10
|
||||
|
||||
compressedBlockOverAlloc = 16
|
||||
maxCompressedBlockSizeAlloc = 128<<10 + compressedBlockOverAlloc
|
||||
|
||||
// Maximum possible block size (all Raw+Uncompressed).
|
||||
maxBlockSize = (1 << 21) - 1
|
||||
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#literals_section_header
|
||||
maxCompressedLiteralSize = 1 << 18
|
||||
maxRLELiteralSize = 1 << 20
|
||||
maxMatchLen = 131074
|
||||
maxSequences = 0x7f00 + 0xffff
|
||||
maxMatchLen = 131074
|
||||
maxSequences = 0x7f00 + 0xffff
|
||||
|
||||
// We support slightly less than the reference decoder to be able to
|
||||
// use ints on 32 bit archs.
|
||||
@ -97,7 +102,6 @@ type blockDec struct {
|
||||
|
||||
// Block is RLE, this is the size.
|
||||
RLESize uint32
|
||||
tmp [4]byte
|
||||
|
||||
Type blockType
|
||||
|
||||
@ -136,7 +140,7 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error {
|
||||
b.Type = blockType((bh >> 1) & 3)
|
||||
// find size.
|
||||
cSize := int(bh >> 3)
|
||||
maxSize := maxBlockSize
|
||||
maxSize := maxCompressedBlockSizeAlloc
|
||||
switch b.Type {
|
||||
case blockTypeReserved:
|
||||
return ErrReservedBlockType
|
||||
@ -157,9 +161,9 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error {
|
||||
println("Data size on stream:", cSize)
|
||||
}
|
||||
b.RLESize = 0
|
||||
maxSize = maxCompressedBlockSize
|
||||
maxSize = maxCompressedBlockSizeAlloc
|
||||
if windowSize < maxCompressedBlockSize && b.lowMem {
|
||||
maxSize = int(windowSize)
|
||||
maxSize = int(windowSize) + compressedBlockOverAlloc
|
||||
}
|
||||
if cSize > maxCompressedBlockSize || uint64(cSize) > b.WindowSize {
|
||||
if debugDecoder {
|
||||
@ -190,9 +194,9 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error {
|
||||
// Read block data.
|
||||
if cap(b.dataStorage) < cSize {
|
||||
if b.lowMem || cSize > maxCompressedBlockSize {
|
||||
b.dataStorage = make([]byte, 0, cSize)
|
||||
b.dataStorage = make([]byte, 0, cSize+compressedBlockOverAlloc)
|
||||
} else {
|
||||
b.dataStorage = make([]byte, 0, maxCompressedBlockSize)
|
||||
b.dataStorage = make([]byte, 0, maxCompressedBlockSizeAlloc)
|
||||
}
|
||||
}
|
||||
if cap(b.dst) <= maxSize {
|
||||
@ -360,14 +364,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err
|
||||
}
|
||||
if cap(b.literalBuf) < litRegenSize {
|
||||
if b.lowMem {
|
||||
b.literalBuf = make([]byte, litRegenSize)
|
||||
b.literalBuf = make([]byte, litRegenSize, litRegenSize+compressedBlockOverAlloc)
|
||||
} else {
|
||||
if litRegenSize > maxCompressedLiteralSize {
|
||||
// Exceptional
|
||||
b.literalBuf = make([]byte, litRegenSize)
|
||||
} else {
|
||||
b.literalBuf = make([]byte, litRegenSize, maxCompressedLiteralSize)
|
||||
}
|
||||
b.literalBuf = make([]byte, litRegenSize, maxCompressedBlockSize+compressedBlockOverAlloc)
|
||||
}
|
||||
}
|
||||
literals = b.literalBuf[:litRegenSize]
|
||||
@ -397,14 +396,14 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err
|
||||
// Ensure we have space to store it.
|
||||
if cap(b.literalBuf) < litRegenSize {
|
||||
if b.lowMem {
|
||||
b.literalBuf = make([]byte, 0, litRegenSize)
|
||||
b.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc)
|
||||
} else {
|
||||
b.literalBuf = make([]byte, 0, maxCompressedLiteralSize)
|
||||
b.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc)
|
||||
}
|
||||
}
|
||||
var err error
|
||||
// Use our out buffer.
|
||||
huff.MaxDecodedSize = maxCompressedBlockSize
|
||||
huff.MaxDecodedSize = litRegenSize
|
||||
if fourStreams {
|
||||
literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals)
|
||||
} else {
|
||||
@ -429,9 +428,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err
|
||||
// Ensure we have space to store it.
|
||||
if cap(b.literalBuf) < litRegenSize {
|
||||
if b.lowMem {
|
||||
b.literalBuf = make([]byte, 0, litRegenSize)
|
||||
b.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc)
|
||||
} else {
|
||||
b.literalBuf = make([]byte, 0, maxCompressedBlockSize)
|
||||
b.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc)
|
||||
}
|
||||
}
|
||||
huff := hist.huffTree
|
||||
@ -448,7 +447,7 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err
|
||||
return in, err
|
||||
}
|
||||
hist.huffTree = huff
|
||||
huff.MaxDecodedSize = maxCompressedBlockSize
|
||||
huff.MaxDecodedSize = litRegenSize
|
||||
// Use our out buffer.
|
||||
if fourStreams {
|
||||
literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals)
|
||||
@ -463,6 +462,8 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err
|
||||
if len(literals) != litRegenSize {
|
||||
return in, fmt.Errorf("literal output size mismatch want %d, got %d", litRegenSize, len(literals))
|
||||
}
|
||||
// Re-cap to get extra size.
|
||||
literals = b.literalBuf[:len(literals)]
|
||||
if debugDecoder {
|
||||
printf("Decompressed %d literals into %d bytes\n", litCompSize, litRegenSize)
|
||||
}
|
||||
@ -486,10 +487,15 @@ func (b *blockDec) decodeCompressed(hist *history) error {
|
||||
b.dst = append(b.dst, hist.decoders.literals...)
|
||||
return nil
|
||||
}
|
||||
err = hist.decoders.decodeSync(hist)
|
||||
before := len(hist.decoders.out)
|
||||
err = hist.decoders.decodeSync(hist.b[hist.ignoreBuffer:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hist.decoders.maxSyncLen > 0 {
|
||||
hist.decoders.maxSyncLen += uint64(before)
|
||||
hist.decoders.maxSyncLen -= uint64(len(hist.decoders.out))
|
||||
}
|
||||
b.dst = hist.decoders.out
|
||||
hist.recentOffsets = hist.decoders.prevOffset
|
||||
return nil
|
||||
@ -632,6 +638,22 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) {
|
||||
println("initializing sequences:", err)
|
||||
return err
|
||||
}
|
||||
// Extract blocks...
|
||||
if false && hist.dict == nil {
|
||||
fatalErr := func(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
fn := fmt.Sprintf("n-%d-lits-%d-prev-%d-%d-%d-win-%d.blk", hist.decoders.nSeqs, len(hist.decoders.literals), hist.recentOffsets[0], hist.recentOffsets[1], hist.recentOffsets[2], hist.windowSize)
|
||||
var buf bytes.Buffer
|
||||
fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.litLengths.fse))
|
||||
fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.matchLengths.fse))
|
||||
fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.offsets.fse))
|
||||
buf.Write(in)
|
||||
ioutil.WriteFile(filepath.Join("testdata", "seqs", fn), buf.Bytes(), os.ModePerm)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -650,6 +672,7 @@ func (b *blockDec) decodeSequences(hist *history) error {
|
||||
}
|
||||
hist.decoders.windowSize = hist.windowSize
|
||||
hist.decoders.prevOffset = hist.recentOffsets
|
||||
|
||||
err := hist.decoders.decode(b.sequence)
|
||||
hist.recentOffsets = hist.decoders.prevOffset
|
||||
return err
|
||||
|
4
vendor/github.com/klauspost/compress/zstd/bytebuf.go
generated
vendored
4
vendor/github.com/klauspost/compress/zstd/bytebuf.go
generated
vendored
@ -52,10 +52,6 @@ func (b *byteBuf) readBig(n int, dst []byte) ([]byte, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (b *byteBuf) remain() []byte {
|
||||
return *b
|
||||
}
|
||||
|
||||
func (b *byteBuf) readByte() (byte, error) {
|
||||
bb := *b
|
||||
if len(bb) < 1 {
|
||||
|
6
vendor/github.com/klauspost/compress/zstd/bytereader.go
generated
vendored
6
vendor/github.com/klauspost/compress/zstd/bytereader.go
generated
vendored
@ -13,12 +13,6 @@ type byteReader struct {
|
||||
off int
|
||||
}
|
||||
|
||||
// init will initialize the reader and set the input.
|
||||
func (b *byteReader) init(in []byte) {
|
||||
b.b = in
|
||||
b.off = 0
|
||||
}
|
||||
|
||||
// advance the stream b n bytes.
|
||||
func (b *byteReader) advance(n uint) {
|
||||
b.off += int(n)
|
||||
|
121
vendor/github.com/klauspost/compress/zstd/decoder.go
generated
vendored
121
vendor/github.com/klauspost/compress/zstd/decoder.go
generated
vendored
@ -347,18 +347,20 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) {
|
||||
}
|
||||
frame.history.setDict(&dict)
|
||||
}
|
||||
|
||||
if frame.FrameContentSize != fcsUnknown && frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)) {
|
||||
return dst, ErrDecoderSizeExceeded
|
||||
if frame.WindowSize > d.o.maxWindowSize {
|
||||
return dst, ErrWindowSizeExceeded
|
||||
}
|
||||
if frame.FrameContentSize < 1<<30 {
|
||||
// Never preallocate more than 1 GB up front.
|
||||
if frame.FrameContentSize != fcsUnknown {
|
||||
if frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)) {
|
||||
return dst, ErrDecoderSizeExceeded
|
||||
}
|
||||
if cap(dst)-len(dst) < int(frame.FrameContentSize) {
|
||||
dst2 := make([]byte, len(dst), len(dst)+int(frame.FrameContentSize))
|
||||
dst2 := make([]byte, len(dst), len(dst)+int(frame.FrameContentSize)+compressedBlockOverAlloc)
|
||||
copy(dst2, dst)
|
||||
dst = dst2
|
||||
}
|
||||
}
|
||||
|
||||
if cap(dst) == 0 {
|
||||
// Allocate len(input) * 2 by default if nothing is provided
|
||||
// and we didn't get frame content size.
|
||||
@ -437,7 +439,7 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) {
|
||||
println("got", len(d.current.b), "bytes, error:", d.current.err, "data crc:", tmp)
|
||||
}
|
||||
|
||||
if len(next.b) > 0 {
|
||||
if !d.o.ignoreChecksum && len(next.b) > 0 {
|
||||
n, err := d.current.crc.Write(next.b)
|
||||
if err == nil {
|
||||
if n != len(next.b) {
|
||||
@ -449,7 +451,7 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) {
|
||||
got := d.current.crc.Sum64()
|
||||
var tmp [4]byte
|
||||
binary.LittleEndian.PutUint32(tmp[:], uint32(got))
|
||||
if !bytes.Equal(tmp[:], next.d.checkCRC) && !ignoreCRC {
|
||||
if !d.o.ignoreChecksum && !bytes.Equal(tmp[:], next.d.checkCRC) {
|
||||
if debugDecoder {
|
||||
println("CRC Check Failed:", tmp[:], " (got) !=", next.d.checkCRC, "(on stream)")
|
||||
}
|
||||
@ -533,9 +535,15 @@ func (d *Decoder) nextBlockSync() (ok bool) {
|
||||
|
||||
// Update/Check CRC
|
||||
if d.frame.HasCheckSum {
|
||||
d.frame.crc.Write(d.current.b)
|
||||
if !d.o.ignoreChecksum {
|
||||
d.frame.crc.Write(d.current.b)
|
||||
}
|
||||
if d.current.d.Last {
|
||||
d.current.err = d.frame.checkCRC()
|
||||
if !d.o.ignoreChecksum {
|
||||
d.current.err = d.frame.checkCRC()
|
||||
} else {
|
||||
d.current.err = d.frame.consumeCRC()
|
||||
}
|
||||
if d.current.err != nil {
|
||||
println("CRC error:", d.current.err)
|
||||
return false
|
||||
@ -629,60 +637,18 @@ func (d *Decoder) startSyncDecoder(r io.Reader) error {
|
||||
|
||||
// Create Decoder:
|
||||
// ASYNC:
|
||||
// Spawn 4 go routines.
|
||||
// 0: Read frames and decode blocks.
|
||||
// 1: Decode block and literals. Receives hufftree and seqdecs, returns seqdecs and huff tree.
|
||||
// 2: Wait for recentOffsets if needed. Decode sequences, send recentOffsets.
|
||||
// 3: Wait for stream history, execute sequences, send stream history.
|
||||
// Spawn 3 go routines.
|
||||
// 0: Read frames and decode block literals.
|
||||
// 1: Decode sequences.
|
||||
// 2: Execute sequences, send to output.
|
||||
func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output chan decodeOutput) {
|
||||
defer d.streamWg.Done()
|
||||
br := readerWrapper{r: r}
|
||||
|
||||
var seqPrepare = make(chan *blockDec, d.o.concurrent)
|
||||
var seqDecode = make(chan *blockDec, d.o.concurrent)
|
||||
var seqExecute = make(chan *blockDec, d.o.concurrent)
|
||||
|
||||
// Async 1: Prepare blocks...
|
||||
go func() {
|
||||
var hist history
|
||||
var hasErr bool
|
||||
for block := range seqPrepare {
|
||||
if hasErr {
|
||||
if block != nil {
|
||||
seqDecode <- block
|
||||
}
|
||||
continue
|
||||
}
|
||||
if block.async.newHist != nil {
|
||||
if debugDecoder {
|
||||
println("Async 1: new history")
|
||||
}
|
||||
hist.reset()
|
||||
if block.async.newHist.dict != nil {
|
||||
hist.setDict(block.async.newHist.dict)
|
||||
}
|
||||
}
|
||||
if block.err != nil || block.Type != blockTypeCompressed {
|
||||
hasErr = block.err != nil
|
||||
seqDecode <- block
|
||||
continue
|
||||
}
|
||||
|
||||
remain, err := block.decodeLiterals(block.data, &hist)
|
||||
block.err = err
|
||||
hasErr = block.err != nil
|
||||
if err == nil {
|
||||
block.async.literals = hist.decoders.literals
|
||||
block.async.seqData = remain
|
||||
} else if debugDecoder {
|
||||
println("decodeLiterals error:", err)
|
||||
}
|
||||
seqDecode <- block
|
||||
}
|
||||
close(seqDecode)
|
||||
}()
|
||||
|
||||
// Async 2: Decode sequences...
|
||||
// Async 1: Decode sequences...
|
||||
go func() {
|
||||
var hist history
|
||||
var hasErr bool
|
||||
@ -696,7 +662,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch
|
||||
}
|
||||
if block.async.newHist != nil {
|
||||
if debugDecoder {
|
||||
println("Async 2: new history, recent:", block.async.newHist.recentOffsets)
|
||||
println("Async 1: new history, recent:", block.async.newHist.recentOffsets)
|
||||
}
|
||||
hist.decoders = block.async.newHist.decoders
|
||||
hist.recentOffsets = block.async.newHist.recentOffsets
|
||||
@ -750,7 +716,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch
|
||||
}
|
||||
if block.async.newHist != nil {
|
||||
if debugDecoder {
|
||||
println("Async 3: new history")
|
||||
println("Async 2: new history")
|
||||
}
|
||||
hist.windowSize = block.async.newHist.windowSize
|
||||
hist.allocFrameBuffer = block.async.newHist.allocFrameBuffer
|
||||
@ -837,6 +803,33 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch
|
||||
|
||||
decodeStream:
|
||||
for {
|
||||
var hist history
|
||||
var hasErr bool
|
||||
|
||||
decodeBlock := func(block *blockDec) {
|
||||
if hasErr {
|
||||
if block != nil {
|
||||
seqDecode <- block
|
||||
}
|
||||
return
|
||||
}
|
||||
if block.err != nil || block.Type != blockTypeCompressed {
|
||||
hasErr = block.err != nil
|
||||
seqDecode <- block
|
||||
return
|
||||
}
|
||||
|
||||
remain, err := block.decodeLiterals(block.data, &hist)
|
||||
block.err = err
|
||||
hasErr = block.err != nil
|
||||
if err == nil {
|
||||
block.async.literals = hist.decoders.literals
|
||||
block.async.seqData = remain
|
||||
} else if debugDecoder {
|
||||
println("decodeLiterals error:", err)
|
||||
}
|
||||
seqDecode <- block
|
||||
}
|
||||
frame := d.frame
|
||||
if debugDecoder {
|
||||
println("New frame...")
|
||||
@ -863,7 +856,7 @@ decodeStream:
|
||||
case <-ctx.Done():
|
||||
case dec := <-d.decoders:
|
||||
dec.sendErr(err)
|
||||
seqPrepare <- dec
|
||||
decodeBlock(dec)
|
||||
}
|
||||
break decodeStream
|
||||
}
|
||||
@ -883,6 +876,10 @@ decodeStream:
|
||||
if debugDecoder {
|
||||
println("Alloc History:", h.allocFrameBuffer)
|
||||
}
|
||||
hist.reset()
|
||||
if h.dict != nil {
|
||||
hist.setDict(h.dict)
|
||||
}
|
||||
dec.async.newHist = &h
|
||||
dec.async.fcs = frame.FrameContentSize
|
||||
historySent = true
|
||||
@ -909,7 +906,7 @@ decodeStream:
|
||||
}
|
||||
err = dec.err
|
||||
last := dec.Last
|
||||
seqPrepare <- dec
|
||||
decodeBlock(dec)
|
||||
if err != nil {
|
||||
break decodeStream
|
||||
}
|
||||
@ -918,7 +915,7 @@ decodeStream:
|
||||
}
|
||||
}
|
||||
}
|
||||
close(seqPrepare)
|
||||
close(seqDecode)
|
||||
wg.Wait()
|
||||
d.frame.history.b = frameHistCache
|
||||
}
|
||||
|
13
vendor/github.com/klauspost/compress/zstd/decoder_options.go
generated
vendored
13
vendor/github.com/klauspost/compress/zstd/decoder_options.go
generated
vendored
@ -19,6 +19,7 @@ type decoderOptions struct {
|
||||
maxDecodedSize uint64
|
||||
maxWindowSize uint64
|
||||
dicts []dict
|
||||
ignoreChecksum bool
|
||||
}
|
||||
|
||||
func (o *decoderOptions) setDefault() {
|
||||
@ -31,7 +32,7 @@ func (o *decoderOptions) setDefault() {
|
||||
if o.concurrent > 4 {
|
||||
o.concurrent = 4
|
||||
}
|
||||
o.maxDecodedSize = 1 << 63
|
||||
o.maxDecodedSize = 64 << 30
|
||||
}
|
||||
|
||||
// WithDecoderLowmem will set whether to use a lower amount of memory,
|
||||
@ -66,7 +67,7 @@ func WithDecoderConcurrency(n int) DOption {
|
||||
// WithDecoderMaxMemory allows to set a maximum decoded size for in-memory
|
||||
// non-streaming operations or maximum window size for streaming operations.
|
||||
// This can be used to control memory usage of potentially hostile content.
|
||||
// Maximum and default is 1 << 63 bytes.
|
||||
// Maximum is 1 << 63 bytes. Default is 64GiB.
|
||||
func WithDecoderMaxMemory(n uint64) DOption {
|
||||
return func(o *decoderOptions) error {
|
||||
if n == 0 {
|
||||
@ -112,3 +113,11 @@ func WithDecoderMaxWindow(size uint64) DOption {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// IgnoreChecksum allows to forcibly ignore checksum checking.
|
||||
func IgnoreChecksum(b bool) DOption {
|
||||
return func(o *decoderOptions) error {
|
||||
o.ignoreChecksum = b
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
8
vendor/github.com/klauspost/compress/zstd/enc_better.go
generated
vendored
8
vendor/github.com/klauspost/compress/zstd/enc_better.go
generated
vendored
@ -156,8 +156,8 @@ encodeLoop:
|
||||
panic("offset0 was 0")
|
||||
}
|
||||
|
||||
nextHashS := hashLen(cv, betterShortTableBits, betterShortLen)
|
||||
nextHashL := hashLen(cv, betterLongTableBits, betterLongLen)
|
||||
nextHashS := hashLen(cv, betterShortTableBits, betterShortLen)
|
||||
candidateL := e.longTable[nextHashL]
|
||||
candidateS := e.table[nextHashS]
|
||||
|
||||
@ -518,8 +518,8 @@ encodeLoop:
|
||||
}
|
||||
|
||||
// Store this, since we have it.
|
||||
nextHashS := hashLen(cv, betterShortTableBits, betterShortLen)
|
||||
nextHashL := hashLen(cv, betterLongTableBits, betterLongLen)
|
||||
nextHashS := hashLen(cv, betterShortTableBits, betterShortLen)
|
||||
|
||||
// We have at least 4 byte match.
|
||||
// No need to check backwards. We come straight from a match
|
||||
@ -674,8 +674,8 @@ encodeLoop:
|
||||
panic("offset0 was 0")
|
||||
}
|
||||
|
||||
nextHashS := hashLen(cv, betterShortTableBits, betterShortLen)
|
||||
nextHashL := hashLen(cv, betterLongTableBits, betterLongLen)
|
||||
nextHashS := hashLen(cv, betterShortTableBits, betterShortLen)
|
||||
candidateL := e.longTable[nextHashL]
|
||||
candidateS := e.table[nextHashS]
|
||||
|
||||
@ -1047,8 +1047,8 @@ encodeLoop:
|
||||
}
|
||||
|
||||
// Store this, since we have it.
|
||||
nextHashS := hashLen(cv, betterShortTableBits, betterShortLen)
|
||||
nextHashL := hashLen(cv, betterLongTableBits, betterLongLen)
|
||||
nextHashS := hashLen(cv, betterShortTableBits, betterShortLen)
|
||||
|
||||
// We have at least 4 byte match.
|
||||
// No need to check backwards. We come straight from a match
|
||||
|
10
vendor/github.com/klauspost/compress/zstd/enc_dfast.go
generated
vendored
10
vendor/github.com/klauspost/compress/zstd/enc_dfast.go
generated
vendored
@ -127,8 +127,8 @@ encodeLoop:
|
||||
panic("offset0 was 0")
|
||||
}
|
||||
|
||||
nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)
|
||||
nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)
|
||||
nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)
|
||||
candidateL := e.longTable[nextHashL]
|
||||
candidateS := e.table[nextHashS]
|
||||
|
||||
@ -439,8 +439,8 @@ encodeLoop:
|
||||
var t int32
|
||||
for {
|
||||
|
||||
nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)
|
||||
nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)
|
||||
nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)
|
||||
candidateL := e.longTable[nextHashL]
|
||||
candidateS := e.table[nextHashS]
|
||||
|
||||
@ -785,8 +785,8 @@ encodeLoop:
|
||||
panic("offset0 was 0")
|
||||
}
|
||||
|
||||
nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)
|
||||
nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)
|
||||
nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)
|
||||
candidateL := e.longTable[nextHashL]
|
||||
candidateS := e.table[nextHashS]
|
||||
|
||||
@ -969,7 +969,7 @@ encodeLoop:
|
||||
te0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)}
|
||||
te1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)}
|
||||
longHash1 := hashLen(cv0, dFastLongTableBits, dFastLongLen)
|
||||
longHash2 := hashLen(cv0, dFastLongTableBits, dFastLongLen)
|
||||
longHash2 := hashLen(cv1, dFastLongTableBits, dFastLongLen)
|
||||
e.longTable[longHash1] = te0
|
||||
e.longTable[longHash2] = te1
|
||||
e.markLongShardDirty(longHash1)
|
||||
@ -1002,8 +1002,8 @@ encodeLoop:
|
||||
}
|
||||
|
||||
// Store this, since we have it.
|
||||
nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)
|
||||
nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)
|
||||
nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)
|
||||
|
||||
// We have at least 4 byte match.
|
||||
// No need to check backwards. We come straight from a match
|
||||
|
2
vendor/github.com/klauspost/compress/zstd/encoder.go
generated
vendored
2
vendor/github.com/klauspost/compress/zstd/encoder.go
generated
vendored
@ -551,7 +551,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
|
||||
}
|
||||
|
||||
// If we can do everything in one block, prefer that.
|
||||
if len(src) <= maxCompressedBlockSize {
|
||||
if len(src) <= e.o.blockSize {
|
||||
enc.Reset(e.o.dict, true)
|
||||
// Slightly faster with no history and everything in one block.
|
||||
if e.o.crc {
|
||||
|
70
vendor/github.com/klauspost/compress/zstd/framedec.go
generated
vendored
70
vendor/github.com/klauspost/compress/zstd/framedec.go
generated
vendored
@ -253,10 +253,11 @@ func (d *frameDec) reset(br byteBuffer) error {
|
||||
return ErrWindowSizeTooSmall
|
||||
}
|
||||
d.history.windowSize = int(d.WindowSize)
|
||||
if d.o.lowMem && d.history.windowSize < maxBlockSize {
|
||||
if !d.o.lowMem || d.history.windowSize < maxBlockSize {
|
||||
// Alloc 2x window size if not low-mem, or very small window size.
|
||||
d.history.allocFrameBuffer = d.history.windowSize * 2
|
||||
// TODO: Maybe use FrameContent size
|
||||
} else {
|
||||
// Alloc with one additional block
|
||||
d.history.allocFrameBuffer = d.history.windowSize + maxBlockSize
|
||||
}
|
||||
|
||||
@ -290,13 +291,6 @@ func (d *frameDec) checkCRC() error {
|
||||
if !d.HasCheckSum {
|
||||
return nil
|
||||
}
|
||||
var tmp [4]byte
|
||||
got := d.crc.Sum64()
|
||||
// Flip to match file order.
|
||||
tmp[0] = byte(got >> 0)
|
||||
tmp[1] = byte(got >> 8)
|
||||
tmp[2] = byte(got >> 16)
|
||||
tmp[3] = byte(got >> 24)
|
||||
|
||||
// We can overwrite upper tmp now
|
||||
want, err := d.rawInput.readSmall(4)
|
||||
@ -305,7 +299,19 @@ func (d *frameDec) checkCRC() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !bytes.Equal(tmp[:], want) && !ignoreCRC {
|
||||
if d.o.ignoreChecksum {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tmp [4]byte
|
||||
got := d.crc.Sum64()
|
||||
// Flip to match file order.
|
||||
tmp[0] = byte(got >> 0)
|
||||
tmp[1] = byte(got >> 8)
|
||||
tmp[2] = byte(got >> 16)
|
||||
tmp[3] = byte(got >> 24)
|
||||
|
||||
if !bytes.Equal(tmp[:], want) {
|
||||
if debugDecoder {
|
||||
println("CRC Check Failed:", tmp[:], "!=", want)
|
||||
}
|
||||
@ -317,6 +323,19 @@ func (d *frameDec) checkCRC() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// consumeCRC reads the checksum data if the frame has one.
|
||||
func (d *frameDec) consumeCRC() error {
|
||||
if d.HasCheckSum {
|
||||
_, err := d.rawInput.readSmall(4)
|
||||
if err != nil {
|
||||
println("CRC missing?", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// runDecoder will create a sync decoder that will decode a block of data.
|
||||
func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) {
|
||||
saved := d.history.b
|
||||
@ -326,6 +345,19 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) {
|
||||
d.history.ignoreBuffer = len(dst)
|
||||
// Store input length, so we only check new data.
|
||||
crcStart := len(dst)
|
||||
d.history.decoders.maxSyncLen = 0
|
||||
if d.FrameContentSize != fcsUnknown {
|
||||
d.history.decoders.maxSyncLen = d.FrameContentSize + uint64(len(dst))
|
||||
if d.history.decoders.maxSyncLen > d.o.maxDecodedSize {
|
||||
return dst, ErrDecoderSizeExceeded
|
||||
}
|
||||
if uint64(cap(dst)) < d.history.decoders.maxSyncLen {
|
||||
// Alloc for output
|
||||
dst2 := make([]byte, len(dst), d.history.decoders.maxSyncLen+compressedBlockOverAlloc)
|
||||
copy(dst2, dst)
|
||||
dst = dst2
|
||||
}
|
||||
}
|
||||
var err error
|
||||
for {
|
||||
err = dec.reset(d.rawInput, d.WindowSize)
|
||||
@ -360,13 +392,17 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) {
|
||||
if d.FrameContentSize != fcsUnknown && uint64(len(d.history.b)-crcStart) != d.FrameContentSize {
|
||||
err = ErrFrameSizeMismatch
|
||||
} else if d.HasCheckSum {
|
||||
var n int
|
||||
n, err = d.crc.Write(dst[crcStart:])
|
||||
if err == nil {
|
||||
if n != len(dst)-crcStart {
|
||||
err = io.ErrShortWrite
|
||||
} else {
|
||||
err = d.checkCRC()
|
||||
if d.o.ignoreChecksum {
|
||||
err = d.consumeCRC()
|
||||
} else {
|
||||
var n int
|
||||
n, err = d.crc.Write(dst[crcStart:])
|
||||
if err == nil {
|
||||
if n != len(dst)-crcStart {
|
||||
err = io.ErrShortWrite
|
||||
} else {
|
||||
err = d.checkCRC()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
65
vendor/github.com/klauspost/compress/zstd/fse_decoder.go
generated
vendored
65
vendor/github.com/klauspost/compress/zstd/fse_decoder.go
generated
vendored
@ -5,8 +5,10 @@
|
||||
package zstd
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -182,6 +184,29 @@ func (s *fseDecoder) readNCount(b *byteReader, maxSymbol uint16) error {
|
||||
return s.buildDtable()
|
||||
}
|
||||
|
||||
func (s *fseDecoder) mustReadFrom(r io.Reader) {
|
||||
fatalErr := func(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
// dt [maxTablesize]decSymbol // Decompression table.
|
||||
// symbolLen uint16 // Length of active part of the symbol table.
|
||||
// actualTableLog uint8 // Selected tablelog.
|
||||
// maxBits uint8 // Maximum number of additional bits
|
||||
// // used for table creation to avoid allocations.
|
||||
// stateTable [256]uint16
|
||||
// norm [maxSymbolValue + 1]int16
|
||||
// preDefined bool
|
||||
fatalErr(binary.Read(r, binary.LittleEndian, &s.dt))
|
||||
fatalErr(binary.Read(r, binary.LittleEndian, &s.symbolLen))
|
||||
fatalErr(binary.Read(r, binary.LittleEndian, &s.actualTableLog))
|
||||
fatalErr(binary.Read(r, binary.LittleEndian, &s.maxBits))
|
||||
fatalErr(binary.Read(r, binary.LittleEndian, &s.stateTable))
|
||||
fatalErr(binary.Read(r, binary.LittleEndian, &s.norm))
|
||||
fatalErr(binary.Read(r, binary.LittleEndian, &s.preDefined))
|
||||
}
|
||||
|
||||
// decSymbol contains information about a state entry,
|
||||
// Including the state offset base, the output symbol and
|
||||
// the number of bits to read for the low part of the destination state.
|
||||
@ -204,18 +229,10 @@ func (d decSymbol) newState() uint16 {
|
||||
return uint16(d >> 16)
|
||||
}
|
||||
|
||||
func (d decSymbol) baseline() uint32 {
|
||||
return uint32(d >> 32)
|
||||
}
|
||||
|
||||
func (d decSymbol) baselineInt() int {
|
||||
return int(d >> 32)
|
||||
}
|
||||
|
||||
func (d *decSymbol) set(nbits, addBits uint8, newState uint16, baseline uint32) {
|
||||
*d = decSymbol(nbits) | (decSymbol(addBits) << 8) | (decSymbol(newState) << 16) | (decSymbol(baseline) << 32)
|
||||
}
|
||||
|
||||
func (d *decSymbol) setNBits(nBits uint8) {
|
||||
const mask = 0xffffffffffffff00
|
||||
*d = (*d & mask) | decSymbol(nBits)
|
||||
@ -231,11 +248,6 @@ func (d *decSymbol) setNewState(state uint16) {
|
||||
*d = (*d & mask) | decSymbol(state)<<16
|
||||
}
|
||||
|
||||
func (d *decSymbol) setBaseline(baseline uint32) {
|
||||
const mask = 0xffffffff
|
||||
*d = (*d & mask) | decSymbol(baseline)<<32
|
||||
}
|
||||
|
||||
func (d *decSymbol) setExt(addBits uint8, baseline uint32) {
|
||||
const mask = 0xffff00ff
|
||||
*d = (*d & mask) | (decSymbol(addBits) << 8) | (decSymbol(baseline) << 32)
|
||||
@ -352,34 +364,7 @@ func (s *fseState) init(br *bitReader, tableLog uint8, dt []decSymbol) {
|
||||
s.state = dt[br.getBits(tableLog)]
|
||||
}
|
||||
|
||||
// next returns the current symbol and sets the next state.
|
||||
// At least tablelog bits must be available in the bit reader.
|
||||
func (s *fseState) next(br *bitReader) {
|
||||
lowBits := uint16(br.getBits(s.state.nbBits()))
|
||||
s.state = s.dt[s.state.newState()+lowBits]
|
||||
}
|
||||
|
||||
// finished returns true if all bits have been read from the bitstream
|
||||
// and the next state would require reading bits from the input.
|
||||
func (s *fseState) finished(br *bitReader) bool {
|
||||
return br.finished() && s.state.nbBits() > 0
|
||||
}
|
||||
|
||||
// final returns the current state symbol without decoding the next.
|
||||
func (s *fseState) final() (int, uint8) {
|
||||
return s.state.baselineInt(), s.state.addBits()
|
||||
}
|
||||
|
||||
// final returns the current state symbol without decoding the next.
|
||||
func (s decSymbol) final() (int, uint8) {
|
||||
return s.baselineInt(), s.addBits()
|
||||
}
|
||||
|
||||
// nextFast returns the next symbol and sets the next state.
|
||||
// This can only be used if no symbols are 0 bits.
|
||||
// At least tablelog bits must be available in the bit reader.
|
||||
func (s *fseState) nextFast(br *bitReader) (uint32, uint8) {
|
||||
lowBits := br.get16BitsFast(s.state.nbBits())
|
||||
s.state = s.dt[s.state.newState()+lowBits]
|
||||
return s.state.baseline(), s.state.addBits()
|
||||
}
|
||||
|
23
vendor/github.com/klauspost/compress/zstd/fse_encoder.go
generated
vendored
23
vendor/github.com/klauspost/compress/zstd/fse_encoder.go
generated
vendored
@ -76,21 +76,6 @@ func (s *fseEncoder) HistogramFinished(maxSymbol uint8, maxCount int) {
|
||||
s.clearCount = maxCount != 0
|
||||
}
|
||||
|
||||
// prepare will prepare and allocate scratch tables used for both compression and decompression.
|
||||
func (s *fseEncoder) prepare() (*fseEncoder, error) {
|
||||
if s == nil {
|
||||
s = &fseEncoder{}
|
||||
}
|
||||
s.useRLE = false
|
||||
if s.clearCount && s.maxCount == 0 {
|
||||
for i := range s.count {
|
||||
s.count[i] = 0
|
||||
}
|
||||
s.clearCount = false
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// allocCtable will allocate tables needed for compression.
|
||||
// If existing tables a re big enough, they are simply re-used.
|
||||
func (s *fseEncoder) allocCtable() {
|
||||
@ -709,14 +694,6 @@ func (c *cState) init(bw *bitWriter, ct *cTable, first symbolTransform) {
|
||||
c.state = c.stateTable[lu]
|
||||
}
|
||||
|
||||
// encode the output symbol provided and write it to the bitstream.
|
||||
func (c *cState) encode(symbolTT symbolTransform) {
|
||||
nbBitsOut := (uint32(c.state) + symbolTT.deltaNbBits) >> 16
|
||||
dstState := int32(c.state>>(nbBitsOut&15)) + int32(symbolTT.deltaFindState)
|
||||
c.bw.addBits16NC(c.state, uint8(nbBitsOut))
|
||||
c.state = c.stateTable[dstState]
|
||||
}
|
||||
|
||||
// flush will write the tablelog to the output and flush the remaining full bytes.
|
||||
func (c *cState) flush(tableLog uint8) {
|
||||
c.bw.flush32()
|
||||
|
11
vendor/github.com/klauspost/compress/zstd/fuzz.go
generated
vendored
11
vendor/github.com/klauspost/compress/zstd/fuzz.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
//go:build ignorecrc
|
||||
// +build ignorecrc
|
||||
|
||||
// Copyright 2019+ Klaus Post. All rights reserved.
|
||||
// License information can be found in the LICENSE file.
|
||||
// Based on work by Yann Collet, released under BSD License.
|
||||
|
||||
package zstd
|
||||
|
||||
// ignoreCRC can be used for fuzz testing to ignore CRC values...
|
||||
const ignoreCRC = true
|
11
vendor/github.com/klauspost/compress/zstd/fuzz_none.go
generated
vendored
11
vendor/github.com/klauspost/compress/zstd/fuzz_none.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
//go:build !ignorecrc
|
||||
// +build !ignorecrc
|
||||
|
||||
// Copyright 2019+ Klaus Post. All rights reserved.
|
||||
// License information can be found in the LICENSE file.
|
||||
// Based on work by Yann Collet, released under BSD License.
|
||||
|
||||
package zstd
|
||||
|
||||
// ignoreCRC can be used for fuzz testing to ignore CRC values...
|
||||
const ignoreCRC = false
|
6
vendor/github.com/klauspost/compress/zstd/hash.go
generated
vendored
6
vendor/github.com/klauspost/compress/zstd/hash.go
generated
vendored
@ -33,9 +33,3 @@ func hashLen(u uint64, length, mls uint8) uint32 {
|
||||
return (uint32(u) * prime4bytes) >> (32 - length)
|
||||
}
|
||||
}
|
||||
|
||||
// hash3 returns the hash of the lower 3 bytes of u to fit in a hash table with h bits.
|
||||
// Preferably h should be a constant and should always be <32.
|
||||
func hash3(u uint32, h uint8) uint32 {
|
||||
return ((u << (32 - 24)) * prime3bytes) >> ((32 - h) & 31)
|
||||
}
|
||||
|
260
vendor/github.com/klauspost/compress/zstd/seqdec.go
generated
vendored
260
vendor/github.com/klauspost/compress/zstd/seqdec.go
generated
vendored
@ -73,6 +73,7 @@ type sequenceDecs struct {
|
||||
seqSize int
|
||||
windowSize int
|
||||
maxBits uint8
|
||||
maxSyncLen uint64
|
||||
}
|
||||
|
||||
// initialize all 3 decoders from the stream input.
|
||||
@ -98,153 +99,13 @@ func (s *sequenceDecs) initialize(br *bitReader, hist *history, out []byte) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
// decode sequences from the stream with the provided history.
|
||||
func (s *sequenceDecs) decode(seqs []seqVals) error {
|
||||
br := s.br
|
||||
|
||||
// Grab full sizes tables, to avoid bounds checks.
|
||||
llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize]
|
||||
llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state
|
||||
s.seqSize = 0
|
||||
litRemain := len(s.literals)
|
||||
maxBlockSize := maxCompressedBlockSize
|
||||
if s.windowSize < maxBlockSize {
|
||||
maxBlockSize = s.windowSize
|
||||
}
|
||||
for i := range seqs {
|
||||
var ll, mo, ml int
|
||||
if br.off > 4+((maxOffsetBits+16+16)>>3) {
|
||||
// inlined function:
|
||||
// ll, mo, ml = s.nextFast(br, llState, mlState, ofState)
|
||||
|
||||
// Final will not read from stream.
|
||||
var llB, mlB, moB uint8
|
||||
ll, llB = llState.final()
|
||||
ml, mlB = mlState.final()
|
||||
mo, moB = ofState.final()
|
||||
|
||||
// extra bits are stored in reverse order.
|
||||
br.fillFast()
|
||||
mo += br.getBits(moB)
|
||||
if s.maxBits > 32 {
|
||||
br.fillFast()
|
||||
}
|
||||
ml += br.getBits(mlB)
|
||||
ll += br.getBits(llB)
|
||||
|
||||
if moB > 1 {
|
||||
s.prevOffset[2] = s.prevOffset[1]
|
||||
s.prevOffset[1] = s.prevOffset[0]
|
||||
s.prevOffset[0] = mo
|
||||
} else {
|
||||
// mo = s.adjustOffset(mo, ll, moB)
|
||||
// Inlined for rather big speedup
|
||||
if ll == 0 {
|
||||
// There is an exception though, when current sequence's literals_length = 0.
|
||||
// In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2,
|
||||
// an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte.
|
||||
mo++
|
||||
}
|
||||
|
||||
if mo == 0 {
|
||||
mo = s.prevOffset[0]
|
||||
} else {
|
||||
var temp int
|
||||
if mo == 3 {
|
||||
temp = s.prevOffset[0] - 1
|
||||
} else {
|
||||
temp = s.prevOffset[mo]
|
||||
}
|
||||
|
||||
if temp == 0 {
|
||||
// 0 is not valid; input is corrupted; force offset to 1
|
||||
println("WARNING: temp was 0")
|
||||
temp = 1
|
||||
}
|
||||
|
||||
if mo != 1 {
|
||||
s.prevOffset[2] = s.prevOffset[1]
|
||||
}
|
||||
s.prevOffset[1] = s.prevOffset[0]
|
||||
s.prevOffset[0] = temp
|
||||
mo = temp
|
||||
}
|
||||
}
|
||||
br.fillFast()
|
||||
} else {
|
||||
if br.overread() {
|
||||
if debugDecoder {
|
||||
printf("reading sequence %d, exceeded available data\n", i)
|
||||
}
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
ll, mo, ml = s.next(br, llState, mlState, ofState)
|
||||
br.fill()
|
||||
}
|
||||
|
||||
if debugSequences {
|
||||
println("Seq", i, "Litlen:", ll, "mo:", mo, "(abs) ml:", ml)
|
||||
}
|
||||
// Evaluate.
|
||||
// We might be doing this async, so do it early.
|
||||
if mo == 0 && ml > 0 {
|
||||
return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml)
|
||||
}
|
||||
if ml > maxMatchLen {
|
||||
return fmt.Errorf("match len (%d) bigger than max allowed length", ml)
|
||||
}
|
||||
s.seqSize += ll + ml
|
||||
if s.seqSize > maxBlockSize {
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize)
|
||||
}
|
||||
litRemain -= ll
|
||||
if litRemain < 0 {
|
||||
return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, litRemain+ll)
|
||||
}
|
||||
seqs[i] = seqVals{
|
||||
ll: ll,
|
||||
ml: ml,
|
||||
mo: mo,
|
||||
}
|
||||
if i == len(seqs)-1 {
|
||||
// This is the last sequence, so we shouldn't update state.
|
||||
break
|
||||
}
|
||||
|
||||
// Manually inlined, ~ 5-20% faster
|
||||
// Update all 3 states at once. Approx 20% faster.
|
||||
nBits := llState.nbBits() + mlState.nbBits() + ofState.nbBits()
|
||||
if nBits == 0 {
|
||||
llState = llTable[llState.newState()&maxTableMask]
|
||||
mlState = mlTable[mlState.newState()&maxTableMask]
|
||||
ofState = ofTable[ofState.newState()&maxTableMask]
|
||||
} else {
|
||||
bits := br.get32BitsFast(nBits)
|
||||
lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31))
|
||||
llState = llTable[(llState.newState()+lowBits)&maxTableMask]
|
||||
|
||||
lowBits = uint16(bits >> (ofState.nbBits() & 31))
|
||||
lowBits &= bitMask[mlState.nbBits()&15]
|
||||
mlState = mlTable[(mlState.newState()+lowBits)&maxTableMask]
|
||||
|
||||
lowBits = uint16(bits) & bitMask[ofState.nbBits()&15]
|
||||
ofState = ofTable[(ofState.newState()+lowBits)&maxTableMask]
|
||||
}
|
||||
}
|
||||
s.seqSize += litRemain
|
||||
if s.seqSize > maxBlockSize {
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize)
|
||||
}
|
||||
err := br.close()
|
||||
if err != nil {
|
||||
printf("Closing sequences: %v, %+v\n", err, *br)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// execute will execute the decoded sequence with the provided history.
|
||||
// The sequence must be evaluated before being sent.
|
||||
func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error {
|
||||
if len(s.dict) == 0 {
|
||||
return s.executeSimple(seqs, hist)
|
||||
}
|
||||
|
||||
// Ensure we have enough output size...
|
||||
if len(s.out)+s.seqSize > cap(s.out) {
|
||||
addBytes := s.seqSize + len(s.out)
|
||||
@ -327,6 +188,7 @@ func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add final literals
|
||||
copy(out[t:], s.literals)
|
||||
if debugDecoder {
|
||||
@ -341,14 +203,18 @@ func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error {
|
||||
}
|
||||
|
||||
// decode sequences from the stream with the provided history.
|
||||
func (s *sequenceDecs) decodeSync(history *history) error {
|
||||
func (s *sequenceDecs) decodeSync(hist []byte) error {
|
||||
supported, err := s.decodeSyncSimple(hist)
|
||||
if supported {
|
||||
return err
|
||||
}
|
||||
|
||||
br := s.br
|
||||
seqs := s.nSeqs
|
||||
startSize := len(s.out)
|
||||
// Grab full sizes tables, to avoid bounds checks.
|
||||
llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize]
|
||||
llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state
|
||||
hist := history.b[history.ignoreBuffer:]
|
||||
out := s.out
|
||||
maxBlockSize := maxCompressedBlockSize
|
||||
if s.windowSize < maxBlockSize {
|
||||
@ -433,7 +299,7 @@ func (s *sequenceDecs) decodeSync(history *history) error {
|
||||
}
|
||||
size := ll + ml + len(out)
|
||||
if size-startSize > maxBlockSize {
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", size, maxBlockSize)
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", size-startSize, maxBlockSize)
|
||||
}
|
||||
if size > cap(out) {
|
||||
// Not enough size, which can happen under high volume block streaming conditions
|
||||
@ -463,13 +329,13 @@ func (s *sequenceDecs) decodeSync(history *history) error {
|
||||
|
||||
if mo > len(out)+len(hist) || mo > s.windowSize {
|
||||
if len(s.dict) == 0 {
|
||||
return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist))
|
||||
return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)-startSize)
|
||||
}
|
||||
|
||||
// we may be in dictionary.
|
||||
dictO := len(s.dict) - (mo - (len(out) + len(hist)))
|
||||
if dictO < 0 || dictO >= len(s.dict) {
|
||||
return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist))
|
||||
return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)-startSize)
|
||||
}
|
||||
end := dictO + ml
|
||||
if end > len(s.dict) {
|
||||
@ -530,6 +396,7 @@ func (s *sequenceDecs) decodeSync(history *history) error {
|
||||
ofState = ofTable[ofState.newState()&maxTableMask]
|
||||
} else {
|
||||
bits := br.get32BitsFast(nBits)
|
||||
|
||||
lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31))
|
||||
llState = llTable[(llState.newState()+lowBits)&maxTableMask]
|
||||
|
||||
@ -543,8 +410,8 @@ func (s *sequenceDecs) decodeSync(history *history) error {
|
||||
}
|
||||
|
||||
// Check if space for literals
|
||||
if len(s.literals)+len(s.out)-startSize > maxBlockSize {
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", len(s.out), maxBlockSize)
|
||||
if size := len(s.literals) + len(s.out) - startSize; size > maxBlockSize {
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", size, maxBlockSize)
|
||||
}
|
||||
|
||||
// Add final literals
|
||||
@ -552,16 +419,6 @@ func (s *sequenceDecs) decodeSync(history *history) error {
|
||||
return br.close()
|
||||
}
|
||||
|
||||
// update states, at least 27 bits must be available.
|
||||
func (s *sequenceDecs) update(br *bitReader) {
|
||||
// Max 8 bits
|
||||
s.litLengths.state.next(br)
|
||||
// Max 9 bits
|
||||
s.matchLengths.state.next(br)
|
||||
// Max 8 bits
|
||||
s.offsets.state.next(br)
|
||||
}
|
||||
|
||||
var bitMask [16]uint16
|
||||
|
||||
func init() {
|
||||
@ -570,87 +427,6 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// update states, at least 27 bits must be available.
|
||||
func (s *sequenceDecs) updateAlt(br *bitReader) {
|
||||
// Update all 3 states at once. Approx 20% faster.
|
||||
a, b, c := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state
|
||||
|
||||
nBits := a.nbBits() + b.nbBits() + c.nbBits()
|
||||
if nBits == 0 {
|
||||
s.litLengths.state.state = s.litLengths.state.dt[a.newState()]
|
||||
s.matchLengths.state.state = s.matchLengths.state.dt[b.newState()]
|
||||
s.offsets.state.state = s.offsets.state.dt[c.newState()]
|
||||
return
|
||||
}
|
||||
bits := br.get32BitsFast(nBits)
|
||||
lowBits := uint16(bits >> ((c.nbBits() + b.nbBits()) & 31))
|
||||
s.litLengths.state.state = s.litLengths.state.dt[a.newState()+lowBits]
|
||||
|
||||
lowBits = uint16(bits >> (c.nbBits() & 31))
|
||||
lowBits &= bitMask[b.nbBits()&15]
|
||||
s.matchLengths.state.state = s.matchLengths.state.dt[b.newState()+lowBits]
|
||||
|
||||
lowBits = uint16(bits) & bitMask[c.nbBits()&15]
|
||||
s.offsets.state.state = s.offsets.state.dt[c.newState()+lowBits]
|
||||
}
|
||||
|
||||
// nextFast will return new states when there are at least 4 unused bytes left on the stream when done.
|
||||
func (s *sequenceDecs) nextFast(br *bitReader, llState, mlState, ofState decSymbol) (ll, mo, ml int) {
|
||||
// Final will not read from stream.
|
||||
ll, llB := llState.final()
|
||||
ml, mlB := mlState.final()
|
||||
mo, moB := ofState.final()
|
||||
|
||||
// extra bits are stored in reverse order.
|
||||
br.fillFast()
|
||||
mo += br.getBits(moB)
|
||||
if s.maxBits > 32 {
|
||||
br.fillFast()
|
||||
}
|
||||
ml += br.getBits(mlB)
|
||||
ll += br.getBits(llB)
|
||||
|
||||
if moB > 1 {
|
||||
s.prevOffset[2] = s.prevOffset[1]
|
||||
s.prevOffset[1] = s.prevOffset[0]
|
||||
s.prevOffset[0] = mo
|
||||
return
|
||||
}
|
||||
// mo = s.adjustOffset(mo, ll, moB)
|
||||
// Inlined for rather big speedup
|
||||
if ll == 0 {
|
||||
// There is an exception though, when current sequence's literals_length = 0.
|
||||
// In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2,
|
||||
// an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte.
|
||||
mo++
|
||||
}
|
||||
|
||||
if mo == 0 {
|
||||
mo = s.prevOffset[0]
|
||||
return
|
||||
}
|
||||
var temp int
|
||||
if mo == 3 {
|
||||
temp = s.prevOffset[0] - 1
|
||||
} else {
|
||||
temp = s.prevOffset[mo]
|
||||
}
|
||||
|
||||
if temp == 0 {
|
||||
// 0 is not valid; input is corrupted; force offset to 1
|
||||
println("temp was 0")
|
||||
temp = 1
|
||||
}
|
||||
|
||||
if mo != 1 {
|
||||
s.prevOffset[2] = s.prevOffset[1]
|
||||
}
|
||||
s.prevOffset[1] = s.prevOffset[0]
|
||||
s.prevOffset[0] = temp
|
||||
mo = temp
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sequenceDecs) next(br *bitReader, llState, mlState, ofState decSymbol) (ll, mo, ml int) {
|
||||
// Final will not read from stream.
|
||||
ll, llB := llState.final()
|
||||
|
362
vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go
generated
vendored
Normal file
362
vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go
generated
vendored
Normal file
@ -0,0 +1,362 @@
|
||||
//go:build amd64 && !appengine && !noasm && gc
|
||||
// +build amd64,!appengine,!noasm,gc
|
||||
|
||||
package zstd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/klauspost/compress/internal/cpuinfo"
|
||||
)
|
||||
|
||||
type decodeSyncAsmContext struct {
|
||||
llTable []decSymbol
|
||||
mlTable []decSymbol
|
||||
ofTable []decSymbol
|
||||
llState uint64
|
||||
mlState uint64
|
||||
ofState uint64
|
||||
iteration int
|
||||
litRemain int
|
||||
out []byte
|
||||
outPosition int
|
||||
literals []byte
|
||||
litPosition int
|
||||
history []byte
|
||||
windowSize int
|
||||
ll int // set on error (not for all errors, please refer to _generate/gen.go)
|
||||
ml int // set on error (not for all errors, please refer to _generate/gen.go)
|
||||
mo int // set on error (not for all errors, please refer to _generate/gen.go)
|
||||
}
|
||||
|
||||
// sequenceDecs_decodeSync_amd64 implements the main loop of sequenceDecs.decodeSync in x86 asm.
|
||||
//
|
||||
// Please refer to seqdec_generic.go for the reference implementation.
|
||||
//go:noescape
|
||||
func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int
|
||||
|
||||
// sequenceDecs_decodeSync_bmi2 implements the main loop of sequenceDecs.decodeSync in x86 asm with BMI2 extensions.
|
||||
//go:noescape
|
||||
func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int
|
||||
|
||||
// sequenceDecs_decodeSync_safe_amd64 does the same as above, but does not write more than output buffer.
|
||||
//go:noescape
|
||||
func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int
|
||||
|
||||
// sequenceDecs_decodeSync_safe_bmi2 does the same as above, but does not write more than output buffer.
|
||||
//go:noescape
|
||||
func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int
|
||||
|
||||
// decode sequences from the stream with the provided history but without a dictionary.
|
||||
func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {
|
||||
if len(s.dict) > 0 {
|
||||
return false, nil
|
||||
}
|
||||
if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSize {
|
||||
return false, nil
|
||||
}
|
||||
useSafe := false
|
||||
if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc {
|
||||
useSafe = true
|
||||
}
|
||||
if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) {
|
||||
useSafe = true
|
||||
}
|
||||
if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc {
|
||||
useSafe = true
|
||||
}
|
||||
|
||||
br := s.br
|
||||
|
||||
maxBlockSize := maxCompressedBlockSize
|
||||
if s.windowSize < maxBlockSize {
|
||||
maxBlockSize = s.windowSize
|
||||
}
|
||||
|
||||
ctx := decodeSyncAsmContext{
|
||||
llTable: s.litLengths.fse.dt[:maxTablesize],
|
||||
mlTable: s.matchLengths.fse.dt[:maxTablesize],
|
||||
ofTable: s.offsets.fse.dt[:maxTablesize],
|
||||
llState: uint64(s.litLengths.state.state),
|
||||
mlState: uint64(s.matchLengths.state.state),
|
||||
ofState: uint64(s.offsets.state.state),
|
||||
iteration: s.nSeqs - 1,
|
||||
litRemain: len(s.literals),
|
||||
out: s.out,
|
||||
outPosition: len(s.out),
|
||||
literals: s.literals,
|
||||
windowSize: s.windowSize,
|
||||
history: hist,
|
||||
}
|
||||
|
||||
s.seqSize = 0
|
||||
startSize := len(s.out)
|
||||
|
||||
var errCode int
|
||||
if cpuinfo.HasBMI2() {
|
||||
if useSafe {
|
||||
errCode = sequenceDecs_decodeSync_safe_bmi2(s, br, &ctx)
|
||||
} else {
|
||||
errCode = sequenceDecs_decodeSync_bmi2(s, br, &ctx)
|
||||
}
|
||||
} else {
|
||||
if useSafe {
|
||||
errCode = sequenceDecs_decodeSync_safe_amd64(s, br, &ctx)
|
||||
} else {
|
||||
errCode = sequenceDecs_decodeSync_amd64(s, br, &ctx)
|
||||
}
|
||||
}
|
||||
switch errCode {
|
||||
case noError:
|
||||
break
|
||||
|
||||
case errorMatchLenOfsMismatch:
|
||||
return true, fmt.Errorf("zero matchoff and matchlen (%d) > 0", ctx.ml)
|
||||
|
||||
case errorMatchLenTooBig:
|
||||
return true, fmt.Errorf("match len (%d) bigger than max allowed length", ctx.ml)
|
||||
|
||||
case errorMatchOffTooBig:
|
||||
return true, fmt.Errorf("match offset (%d) bigger than current history (%d)",
|
||||
ctx.mo, ctx.outPosition+len(hist)-startSize)
|
||||
|
||||
case errorNotEnoughLiterals:
|
||||
return true, fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available",
|
||||
ctx.ll, ctx.litRemain+ctx.ll)
|
||||
|
||||
case errorNotEnoughSpace:
|
||||
size := ctx.outPosition + ctx.ll + ctx.ml
|
||||
if debugDecoder {
|
||||
println("msl:", s.maxSyncLen, "cap", cap(s.out), "bef:", startSize, "sz:", size-startSize, "mbs:", maxBlockSize, "outsz:", cap(s.out)-startSize)
|
||||
}
|
||||
return true, fmt.Errorf("output (%d) bigger than max block size (%d)", size-startSize, maxBlockSize)
|
||||
|
||||
default:
|
||||
return true, fmt.Errorf("sequenceDecs_decode returned erronous code %d", errCode)
|
||||
}
|
||||
|
||||
s.seqSize += ctx.litRemain
|
||||
if s.seqSize > maxBlockSize {
|
||||
return true, fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize)
|
||||
}
|
||||
err := br.close()
|
||||
if err != nil {
|
||||
printf("Closing sequences: %v, %+v\n", err, *br)
|
||||
return true, err
|
||||
}
|
||||
|
||||
s.literals = s.literals[ctx.litPosition:]
|
||||
t := ctx.outPosition
|
||||
s.out = s.out[:t]
|
||||
|
||||
// Add final literals
|
||||
s.out = append(s.out, s.literals...)
|
||||
if debugDecoder {
|
||||
t += len(s.literals)
|
||||
if t != len(s.out) {
|
||||
panic(fmt.Errorf("length mismatch, want %d, got %d", len(s.out), t))
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
type decodeAsmContext struct {
|
||||
llTable []decSymbol
|
||||
mlTable []decSymbol
|
||||
ofTable []decSymbol
|
||||
llState uint64
|
||||
mlState uint64
|
||||
ofState uint64
|
||||
iteration int
|
||||
seqs []seqVals
|
||||
litRemain int
|
||||
}
|
||||
|
||||
const noError = 0
|
||||
|
||||
// error reported when mo == 0 && ml > 0
|
||||
const errorMatchLenOfsMismatch = 1
|
||||
|
||||
// error reported when ml > maxMatchLen
|
||||
const errorMatchLenTooBig = 2
|
||||
|
||||
// error reported when mo > available history or mo > s.windowSize
|
||||
const errorMatchOffTooBig = 3
|
||||
|
||||
// error reported when the sum of literal lengths exeeceds the literal buffer size
|
||||
const errorNotEnoughLiterals = 4
|
||||
|
||||
// error reported when capacity of `out` is too small
|
||||
const errorNotEnoughSpace = 5
|
||||
|
||||
// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm.
|
||||
//
|
||||
// Please refer to seqdec_generic.go for the reference implementation.
|
||||
//go:noescape
|
||||
func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int
|
||||
|
||||
// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm.
|
||||
//
|
||||
// Please refer to seqdec_generic.go for the reference implementation.
|
||||
//go:noescape
|
||||
func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int
|
||||
|
||||
// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions.
|
||||
//go:noescape
|
||||
func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int
|
||||
|
||||
// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions.
|
||||
//go:noescape
|
||||
func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int
|
||||
|
||||
// decode sequences from the stream without the provided history.
|
||||
func (s *sequenceDecs) decode(seqs []seqVals) error {
|
||||
br := s.br
|
||||
|
||||
maxBlockSize := maxCompressedBlockSize
|
||||
if s.windowSize < maxBlockSize {
|
||||
maxBlockSize = s.windowSize
|
||||
}
|
||||
|
||||
ctx := decodeAsmContext{
|
||||
llTable: s.litLengths.fse.dt[:maxTablesize],
|
||||
mlTable: s.matchLengths.fse.dt[:maxTablesize],
|
||||
ofTable: s.offsets.fse.dt[:maxTablesize],
|
||||
llState: uint64(s.litLengths.state.state),
|
||||
mlState: uint64(s.matchLengths.state.state),
|
||||
ofState: uint64(s.offsets.state.state),
|
||||
seqs: seqs,
|
||||
iteration: len(seqs) - 1,
|
||||
litRemain: len(s.literals),
|
||||
}
|
||||
|
||||
s.seqSize = 0
|
||||
lte56bits := s.maxBits+s.offsets.fse.actualTableLog+s.matchLengths.fse.actualTableLog+s.litLengths.fse.actualTableLog <= 56
|
||||
var errCode int
|
||||
if cpuinfo.HasBMI2() {
|
||||
if lte56bits {
|
||||
errCode = sequenceDecs_decode_56_bmi2(s, br, &ctx)
|
||||
} else {
|
||||
errCode = sequenceDecs_decode_bmi2(s, br, &ctx)
|
||||
}
|
||||
} else {
|
||||
if lte56bits {
|
||||
errCode = sequenceDecs_decode_56_amd64(s, br, &ctx)
|
||||
} else {
|
||||
errCode = sequenceDecs_decode_amd64(s, br, &ctx)
|
||||
}
|
||||
}
|
||||
if errCode != 0 {
|
||||
i := len(seqs) - ctx.iteration - 1
|
||||
switch errCode {
|
||||
case errorMatchLenOfsMismatch:
|
||||
ml := ctx.seqs[i].ml
|
||||
return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml)
|
||||
|
||||
case errorMatchLenTooBig:
|
||||
ml := ctx.seqs[i].ml
|
||||
return fmt.Errorf("match len (%d) bigger than max allowed length", ml)
|
||||
|
||||
case errorNotEnoughLiterals:
|
||||
ll := ctx.seqs[i].ll
|
||||
return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, ctx.litRemain+ll)
|
||||
}
|
||||
|
||||
return fmt.Errorf("sequenceDecs_decode_amd64 returned erronous code %d", errCode)
|
||||
}
|
||||
|
||||
if ctx.litRemain < 0 {
|
||||
return fmt.Errorf("literal count is too big: total available %d, total requested %d",
|
||||
len(s.literals), len(s.literals)-ctx.litRemain)
|
||||
}
|
||||
|
||||
s.seqSize += ctx.litRemain
|
||||
if s.seqSize > maxBlockSize {
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize)
|
||||
}
|
||||
err := br.close()
|
||||
if err != nil {
|
||||
printf("Closing sequences: %v, %+v\n", err, *br)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
type executeAsmContext struct {
|
||||
seqs []seqVals
|
||||
seqIndex int
|
||||
out []byte
|
||||
history []byte
|
||||
literals []byte
|
||||
outPosition int
|
||||
litPosition int
|
||||
windowSize int
|
||||
}
|
||||
|
||||
// sequenceDecs_executeSimple_amd64 implements the main loop of sequenceDecs.executeSimple in x86 asm.
|
||||
//
|
||||
// Returns false if a match offset is too big.
|
||||
//
|
||||
// Please refer to seqdec_generic.go for the reference implementation.
|
||||
//go:noescape
|
||||
func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool
|
||||
|
||||
// Same as above, but with safe memcopies
|
||||
//go:noescape
|
||||
func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool
|
||||
|
||||
// executeSimple handles cases when dictionary is not used.
|
||||
func (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error {
|
||||
// Ensure we have enough output size...
|
||||
if len(s.out)+s.seqSize+compressedBlockOverAlloc > cap(s.out) {
|
||||
addBytes := s.seqSize + len(s.out) + compressedBlockOverAlloc
|
||||
s.out = append(s.out, make([]byte, addBytes)...)
|
||||
s.out = s.out[:len(s.out)-addBytes]
|
||||
}
|
||||
|
||||
if debugDecoder {
|
||||
printf("Execute %d seqs with literals: %d into %d bytes\n", len(seqs), len(s.literals), s.seqSize)
|
||||
}
|
||||
|
||||
var t = len(s.out)
|
||||
out := s.out[:t+s.seqSize]
|
||||
|
||||
ctx := executeAsmContext{
|
||||
seqs: seqs,
|
||||
seqIndex: 0,
|
||||
out: out,
|
||||
history: hist,
|
||||
outPosition: t,
|
||||
litPosition: 0,
|
||||
literals: s.literals,
|
||||
windowSize: s.windowSize,
|
||||
}
|
||||
var ok bool
|
||||
if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc {
|
||||
ok = sequenceDecs_executeSimple_safe_amd64(&ctx)
|
||||
} else {
|
||||
ok = sequenceDecs_executeSimple_amd64(&ctx)
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("match offset (%d) bigger than current history (%d)",
|
||||
seqs[ctx.seqIndex].mo, ctx.outPosition+len(hist))
|
||||
}
|
||||
s.literals = s.literals[ctx.litPosition:]
|
||||
t = ctx.outPosition
|
||||
|
||||
// Add final literals
|
||||
copy(out[t:], s.literals)
|
||||
if debugDecoder {
|
||||
t += len(s.literals)
|
||||
if t != len(out) {
|
||||
panic(fmt.Errorf("length mismatch, want %d, got %d, ss: %d", len(out), t, s.seqSize))
|
||||
}
|
||||
}
|
||||
s.out = out
|
||||
|
||||
return nil
|
||||
}
|
3689
vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s
generated
vendored
Normal file
3689
vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
237
vendor/github.com/klauspost/compress/zstd/seqdec_generic.go
generated
vendored
Normal file
237
vendor/github.com/klauspost/compress/zstd/seqdec_generic.go
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
//go:build !amd64 || appengine || !gc || noasm
|
||||
// +build !amd64 appengine !gc noasm
|
||||
|
||||
package zstd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// decode sequences from the stream with the provided history but without dictionary.
|
||||
func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// decode sequences from the stream without the provided history.
|
||||
func (s *sequenceDecs) decode(seqs []seqVals) error {
|
||||
br := s.br
|
||||
|
||||
// Grab full sizes tables, to avoid bounds checks.
|
||||
llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize]
|
||||
llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state
|
||||
s.seqSize = 0
|
||||
litRemain := len(s.literals)
|
||||
|
||||
maxBlockSize := maxCompressedBlockSize
|
||||
if s.windowSize < maxBlockSize {
|
||||
maxBlockSize = s.windowSize
|
||||
}
|
||||
for i := range seqs {
|
||||
var ll, mo, ml int
|
||||
if br.off > 4+((maxOffsetBits+16+16)>>3) {
|
||||
// inlined function:
|
||||
// ll, mo, ml = s.nextFast(br, llState, mlState, ofState)
|
||||
|
||||
// Final will not read from stream.
|
||||
var llB, mlB, moB uint8
|
||||
ll, llB = llState.final()
|
||||
ml, mlB = mlState.final()
|
||||
mo, moB = ofState.final()
|
||||
|
||||
// extra bits are stored in reverse order.
|
||||
br.fillFast()
|
||||
mo += br.getBits(moB)
|
||||
if s.maxBits > 32 {
|
||||
br.fillFast()
|
||||
}
|
||||
ml += br.getBits(mlB)
|
||||
ll += br.getBits(llB)
|
||||
|
||||
if moB > 1 {
|
||||
s.prevOffset[2] = s.prevOffset[1]
|
||||
s.prevOffset[1] = s.prevOffset[0]
|
||||
s.prevOffset[0] = mo
|
||||
} else {
|
||||
// mo = s.adjustOffset(mo, ll, moB)
|
||||
// Inlined for rather big speedup
|
||||
if ll == 0 {
|
||||
// There is an exception though, when current sequence's literals_length = 0.
|
||||
// In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2,
|
||||
// an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte.
|
||||
mo++
|
||||
}
|
||||
|
||||
if mo == 0 {
|
||||
mo = s.prevOffset[0]
|
||||
} else {
|
||||
var temp int
|
||||
if mo == 3 {
|
||||
temp = s.prevOffset[0] - 1
|
||||
} else {
|
||||
temp = s.prevOffset[mo]
|
||||
}
|
||||
|
||||
if temp == 0 {
|
||||
// 0 is not valid; input is corrupted; force offset to 1
|
||||
println("WARNING: temp was 0")
|
||||
temp = 1
|
||||
}
|
||||
|
||||
if mo != 1 {
|
||||
s.prevOffset[2] = s.prevOffset[1]
|
||||
}
|
||||
s.prevOffset[1] = s.prevOffset[0]
|
||||
s.prevOffset[0] = temp
|
||||
mo = temp
|
||||
}
|
||||
}
|
||||
br.fillFast()
|
||||
} else {
|
||||
if br.overread() {
|
||||
if debugDecoder {
|
||||
printf("reading sequence %d, exceeded available data\n", i)
|
||||
}
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
ll, mo, ml = s.next(br, llState, mlState, ofState)
|
||||
br.fill()
|
||||
}
|
||||
|
||||
if debugSequences {
|
||||
println("Seq", i, "Litlen:", ll, "mo:", mo, "(abs) ml:", ml)
|
||||
}
|
||||
// Evaluate.
|
||||
// We might be doing this async, so do it early.
|
||||
if mo == 0 && ml > 0 {
|
||||
return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml)
|
||||
}
|
||||
if ml > maxMatchLen {
|
||||
return fmt.Errorf("match len (%d) bigger than max allowed length", ml)
|
||||
}
|
||||
s.seqSize += ll + ml
|
||||
if s.seqSize > maxBlockSize {
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize)
|
||||
}
|
||||
litRemain -= ll
|
||||
if litRemain < 0 {
|
||||
return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, litRemain+ll)
|
||||
}
|
||||
seqs[i] = seqVals{
|
||||
ll: ll,
|
||||
ml: ml,
|
||||
mo: mo,
|
||||
}
|
||||
if i == len(seqs)-1 {
|
||||
// This is the last sequence, so we shouldn't update state.
|
||||
break
|
||||
}
|
||||
|
||||
// Manually inlined, ~ 5-20% faster
|
||||
// Update all 3 states at once. Approx 20% faster.
|
||||
nBits := llState.nbBits() + mlState.nbBits() + ofState.nbBits()
|
||||
if nBits == 0 {
|
||||
llState = llTable[llState.newState()&maxTableMask]
|
||||
mlState = mlTable[mlState.newState()&maxTableMask]
|
||||
ofState = ofTable[ofState.newState()&maxTableMask]
|
||||
} else {
|
||||
bits := br.get32BitsFast(nBits)
|
||||
lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31))
|
||||
llState = llTable[(llState.newState()+lowBits)&maxTableMask]
|
||||
|
||||
lowBits = uint16(bits >> (ofState.nbBits() & 31))
|
||||
lowBits &= bitMask[mlState.nbBits()&15]
|
||||
mlState = mlTable[(mlState.newState()+lowBits)&maxTableMask]
|
||||
|
||||
lowBits = uint16(bits) & bitMask[ofState.nbBits()&15]
|
||||
ofState = ofTable[(ofState.newState()+lowBits)&maxTableMask]
|
||||
}
|
||||
}
|
||||
s.seqSize += litRemain
|
||||
if s.seqSize > maxBlockSize {
|
||||
return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize)
|
||||
}
|
||||
err := br.close()
|
||||
if err != nil {
|
||||
printf("Closing sequences: %v, %+v\n", err, *br)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// executeSimple handles cases when a dictionary is not used.
|
||||
func (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error {
|
||||
// Ensure we have enough output size...
|
||||
if len(s.out)+s.seqSize > cap(s.out) {
|
||||
addBytes := s.seqSize + len(s.out)
|
||||
s.out = append(s.out, make([]byte, addBytes)...)
|
||||
s.out = s.out[:len(s.out)-addBytes]
|
||||
}
|
||||
|
||||
if debugDecoder {
|
||||
printf("Execute %d seqs with literals: %d into %d bytes\n", len(seqs), len(s.literals), s.seqSize)
|
||||
}
|
||||
|
||||
var t = len(s.out)
|
||||
out := s.out[:t+s.seqSize]
|
||||
|
||||
for _, seq := range seqs {
|
||||
// Add literals
|
||||
copy(out[t:], s.literals[:seq.ll])
|
||||
t += seq.ll
|
||||
s.literals = s.literals[seq.ll:]
|
||||
|
||||
// Malformed input
|
||||
if seq.mo > t+len(hist) || seq.mo > s.windowSize {
|
||||
return fmt.Errorf("match offset (%d) bigger than current history (%d)", seq.mo, t+len(hist))
|
||||
}
|
||||
|
||||
// Copy from history.
|
||||
if v := seq.mo - t; v > 0 {
|
||||
// v is the start position in history from end.
|
||||
start := len(hist) - v
|
||||
if seq.ml > v {
|
||||
// Some goes into the current block.
|
||||
// Copy remainder of history
|
||||
copy(out[t:], hist[start:])
|
||||
t += v
|
||||
seq.ml -= v
|
||||
} else {
|
||||
copy(out[t:], hist[start:start+seq.ml])
|
||||
t += seq.ml
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// We must be in the current buffer now
|
||||
if seq.ml > 0 {
|
||||
start := t - seq.mo
|
||||
if seq.ml <= t-start {
|
||||
// No overlap
|
||||
copy(out[t:], out[start:start+seq.ml])
|
||||
t += seq.ml
|
||||
} else {
|
||||
// Overlapping copy
|
||||
// Extend destination slice and copy one byte at the time.
|
||||
src := out[start : start+seq.ml]
|
||||
dst := out[t:]
|
||||
dst = dst[:len(src)]
|
||||
t += len(src)
|
||||
// Destination is the space we just added.
|
||||
for i := range src {
|
||||
dst[i] = src[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add final literals
|
||||
copy(out[t:], s.literals)
|
||||
if debugDecoder {
|
||||
t += len(s.literals)
|
||||
if t != len(out) {
|
||||
panic(fmt.Errorf("length mismatch, want %d, got %d, ss: %d", len(out), t, s.seqSize))
|
||||
}
|
||||
}
|
||||
s.out = out
|
||||
|
||||
return nil
|
||||
}
|
59
vendor/github.com/klauspost/compress/zstd/zip.go
generated
vendored
59
vendor/github.com/klauspost/compress/zstd/zip.go
generated
vendored
@ -18,26 +18,44 @@ const ZipMethodWinZip = 93
|
||||
// See https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.9.TXT
|
||||
const ZipMethodPKWare = 20
|
||||
|
||||
var zipReaderPool sync.Pool
|
||||
// zipReaderPool is the default reader pool.
|
||||
var zipReaderPool = sync.Pool{New: func() interface{} {
|
||||
z, err := NewReader(nil, WithDecoderLowmem(true), WithDecoderMaxWindow(128<<20), WithDecoderConcurrency(1))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return z
|
||||
}}
|
||||
|
||||
// newZipReader creates a pooled zip decompressor.
|
||||
func newZipReader(r io.Reader) io.ReadCloser {
|
||||
dec, ok := zipReaderPool.Get().(*Decoder)
|
||||
if ok {
|
||||
dec.Reset(r)
|
||||
} else {
|
||||
d, err := NewReader(r, WithDecoderConcurrency(1), WithDecoderLowmem(true))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dec = d
|
||||
func newZipReader(opts ...DOption) func(r io.Reader) io.ReadCloser {
|
||||
pool := &zipReaderPool
|
||||
if len(opts) > 0 {
|
||||
opts = append([]DOption{WithDecoderLowmem(true), WithDecoderMaxWindow(128 << 20)}, opts...)
|
||||
// Force concurrency 1
|
||||
opts = append(opts, WithDecoderConcurrency(1))
|
||||
// Create our own pool
|
||||
pool = &sync.Pool{}
|
||||
}
|
||||
return func(r io.Reader) io.ReadCloser {
|
||||
dec, ok := pool.Get().(*Decoder)
|
||||
if ok {
|
||||
dec.Reset(r)
|
||||
} else {
|
||||
d, err := NewReader(r, opts...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dec = d
|
||||
}
|
||||
return &pooledZipReader{dec: dec, pool: pool}
|
||||
}
|
||||
return &pooledZipReader{dec: dec}
|
||||
}
|
||||
|
||||
type pooledZipReader struct {
|
||||
mu sync.Mutex // guards Close and Read
|
||||
dec *Decoder
|
||||
mu sync.Mutex // guards Close and Read
|
||||
pool *sync.Pool
|
||||
dec *Decoder
|
||||
}
|
||||
|
||||
func (r *pooledZipReader) Read(p []byte) (n int, err error) {
|
||||
@ -48,8 +66,8 @@ func (r *pooledZipReader) Read(p []byte) (n int, err error) {
|
||||
}
|
||||
dec, err := r.dec.Read(p)
|
||||
if err == io.EOF {
|
||||
err = r.dec.Reset(nil)
|
||||
zipReaderPool.Put(r.dec)
|
||||
r.dec.Reset(nil)
|
||||
r.pool.Put(r.dec)
|
||||
r.dec = nil
|
||||
}
|
||||
return dec, err
|
||||
@ -61,7 +79,7 @@ func (r *pooledZipReader) Close() error {
|
||||
var err error
|
||||
if r.dec != nil {
|
||||
err = r.dec.Reset(nil)
|
||||
zipReaderPool.Put(r.dec)
|
||||
r.pool.Put(r.dec)
|
||||
r.dec = nil
|
||||
}
|
||||
return err
|
||||
@ -115,6 +133,9 @@ func ZipCompressor(opts ...EOption) func(w io.Writer) (io.WriteCloser, error) {
|
||||
|
||||
// ZipDecompressor returns a decompressor that can be registered with zip libraries.
|
||||
// See ZipCompressor for example.
|
||||
func ZipDecompressor() func(r io.Reader) io.ReadCloser {
|
||||
return newZipReader
|
||||
// Options can be specified. WithDecoderConcurrency(1) is forced,
|
||||
// and by default a 128MB maximum decompression window is specified.
|
||||
// The window size can be overridden if required.
|
||||
func ZipDecompressor(opts ...DOption) func(r io.Reader) io.ReadCloser {
|
||||
return newZipReader(opts...)
|
||||
}
|
||||
|
11
vendor/github.com/klauspost/compress/zstd/zstd.go
generated
vendored
11
vendor/github.com/klauspost/compress/zstd/zstd.go
generated
vendored
@ -110,17 +110,6 @@ func printf(format string, a ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// matchLenFast does matching, but will not match the last up to 7 bytes.
|
||||
func matchLenFast(a, b []byte) int {
|
||||
endI := len(a) & (math.MaxInt32 - 7)
|
||||
for i := 0; i < endI; i += 8 {
|
||||
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
|
||||
return i + bits.TrailingZeros64(diff)>>3
|
||||
}
|
||||
}
|
||||
return endI
|
||||
}
|
||||
|
||||
// matchLen returns the maximum length.
|
||||
// a must be the shortest of the two.
|
||||
// The function also returns whether all bytes matched.
|
||||
|
8
vendor/github.com/slack-go/slack/README.md
generated
vendored
8
vendor/github.com/slack-go/slack/README.md
generated
vendored
@ -39,7 +39,7 @@ func main() {
|
||||
// If you set debugging, it will log all requests to the console
|
||||
// Useful when encountering issues
|
||||
// slack.New("YOUR_TOKEN_HERE", slack.OptionDebug(true))
|
||||
groups, err := api.GetUserGroups(false)
|
||||
groups, err := api.GetUserGroups(slack.GetUserGroupsOptionIncludeUsers(false))
|
||||
if err != nil {
|
||||
fmt.Printf("%s\n", err)
|
||||
return
|
||||
@ -86,7 +86,13 @@ See https://github.com/slack-go/slack/blob/master/examples/websocket/websocket.g
|
||||
|
||||
See https://github.com/slack-go/slack/blob/master/examples/eventsapi/events.go
|
||||
|
||||
## Socketmode Event Handler (Experimental)
|
||||
|
||||
When using socket mode, dealing with an event can be pretty lengthy as it requires you to route the event to the right place.
|
||||
|
||||
Instead, you can use `SocketmodeHandler` much like you use an HTTP handler to register which event you would like to listen to and what callback function will process that event when it occurs.
|
||||
|
||||
See [./examples/socketmode_handler/socketmode_handler.go](./examples/socketmode_handler/socketmode_handler.go)
|
||||
## Contributing
|
||||
|
||||
You are more than welcome to contribute to this project. Fork and
|
||||
|
3
vendor/github.com/slack-go/slack/block_input.go
generated
vendored
3
vendor/github.com/slack-go/slack/block_input.go
generated
vendored
@ -19,11 +19,12 @@ func (s InputBlock) BlockType() MessageBlockType {
|
||||
}
|
||||
|
||||
// NewInputBlock returns a new instance of an input block
|
||||
func NewInputBlock(blockID string, label *TextBlockObject, element BlockElement) *InputBlock {
|
||||
func NewInputBlock(blockID string, label, hint *TextBlockObject, element BlockElement) *InputBlock {
|
||||
return &InputBlock{
|
||||
Type: MBTInput,
|
||||
BlockID: blockID,
|
||||
Label: label,
|
||||
Element: element,
|
||||
Hint: hint,
|
||||
}
|
||||
}
|
||||
|
159
vendor/github.com/slack-go/slack/bookmarks.go
generated
vendored
Normal file
159
vendor/github.com/slack-go/slack/bookmarks.go
generated
vendored
Normal file
@ -0,0 +1,159 @@
|
||||
package slack
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type Bookmark struct {
|
||||
ID string `json:"id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
Title string `json:"title"`
|
||||
Link string `json:"link"`
|
||||
Emoji string `json:"emoji"`
|
||||
IconURL string `json:"icon_url"`
|
||||
Type string `json:"type"`
|
||||
Created JSONTime `json:"date_created"`
|
||||
Updated JSONTime `json:"date_updated"`
|
||||
Rank string `json:"rank"`
|
||||
|
||||
LastUpdatedByUserID string `json:"last_updated_by_user_id"`
|
||||
LastUpdatedByTeamID string `json:"last_updated_by_team_id"`
|
||||
|
||||
ShortcutID string `json:"shortcut_id"`
|
||||
EntityID string `json:"entity_id"`
|
||||
AppID string `json:"app_id"`
|
||||
}
|
||||
|
||||
type AddBookmarkParameters struct {
|
||||
Title string // A required title for the bookmark
|
||||
Type string // A required type for the bookmark
|
||||
Link string // URL required for type:link
|
||||
Emoji string // An optional emoji
|
||||
EntityID string
|
||||
ParentID string
|
||||
}
|
||||
|
||||
type EditBookmarkParameters struct {
|
||||
Title *string // Change the title. Set to "" to clear
|
||||
Emoji *string // Change the emoji. Set to "" to clear
|
||||
Link string // Change the link
|
||||
}
|
||||
|
||||
type addBookmarkResponse struct {
|
||||
Bookmark Bookmark `json:"bookmark"`
|
||||
SlackResponse
|
||||
}
|
||||
|
||||
type editBookmarkResponse struct {
|
||||
Bookmark Bookmark `json:"bookmark"`
|
||||
SlackResponse
|
||||
}
|
||||
|
||||
type listBookmarksResponse struct {
|
||||
Bookmarks []Bookmark `json:"bookmarks"`
|
||||
SlackResponse
|
||||
}
|
||||
|
||||
// AddBookmark adds a bookmark in a channel
|
||||
func (api *Client) AddBookmark(channelID string, params AddBookmarkParameters) (Bookmark, error) {
|
||||
return api.AddBookmarkContext(context.Background(), channelID, params)
|
||||
}
|
||||
|
||||
// AddBookmarkContext adds a bookmark in a channel with a custom context
|
||||
func (api *Client) AddBookmarkContext(ctx context.Context, channelID string, params AddBookmarkParameters) (Bookmark, error) {
|
||||
values := url.Values{
|
||||
"channel_id": {channelID},
|
||||
"token": {api.token},
|
||||
"title": {params.Title},
|
||||
"type": {params.Type},
|
||||
}
|
||||
if params.Link != "" {
|
||||
values.Set("link", params.Link)
|
||||
}
|
||||
if params.Emoji != "" {
|
||||
values.Set("emoji", params.Emoji)
|
||||
}
|
||||
if params.EntityID != "" {
|
||||
values.Set("entity_id", params.EntityID)
|
||||
}
|
||||
if params.ParentID != "" {
|
||||
values.Set("parent_id", params.ParentID)
|
||||
}
|
||||
|
||||
response := &addBookmarkResponse{}
|
||||
if err := api.postMethod(ctx, "bookmarks.add", values, response); err != nil {
|
||||
return Bookmark{}, err
|
||||
}
|
||||
|
||||
return response.Bookmark, response.Err()
|
||||
}
|
||||
|
||||
// RemoveBookmark removes a bookmark from a channel
|
||||
func (api *Client) RemoveBookmark(channelID, bookmarkID string) error {
|
||||
return api.RemoveBookmarkContext(context.Background(), channelID, bookmarkID)
|
||||
}
|
||||
|
||||
// RemoveBookmarkContext removes a bookmark from a channel with a custom context
|
||||
func (api *Client) RemoveBookmarkContext(ctx context.Context, channelID, bookmarkID string) error {
|
||||
values := url.Values{
|
||||
"channel_id": {channelID},
|
||||
"token": {api.token},
|
||||
"bookmark_id": {bookmarkID},
|
||||
}
|
||||
|
||||
response := &SlackResponse{}
|
||||
if err := api.postMethod(ctx, "bookmarks.remove", values, response); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return response.Err()
|
||||
}
|
||||
|
||||
// ListBookmarks returns all bookmarks for a channel.
|
||||
func (api *Client) ListBookmarks(channelID string) ([]Bookmark, error) {
|
||||
return api.ListBookmarksContext(context.Background(), channelID)
|
||||
}
|
||||
|
||||
// ListBookmarksContext returns all bookmarks for a channel with a custom context.
|
||||
func (api *Client) ListBookmarksContext(ctx context.Context, channelID string) ([]Bookmark, error) {
|
||||
values := url.Values{
|
||||
"channel_id": {channelID},
|
||||
"token": {api.token},
|
||||
}
|
||||
|
||||
response := &listBookmarksResponse{}
|
||||
err := api.postMethod(ctx, "bookmarks.list", values, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response.Bookmarks, response.Err()
|
||||
}
|
||||
|
||||
func (api *Client) EditBookmark(channelID, bookmarkID string, params EditBookmarkParameters) (Bookmark, error) {
|
||||
return api.EditBookmarkContext(context.Background(), channelID, bookmarkID, params)
|
||||
}
|
||||
|
||||
func (api *Client) EditBookmarkContext(ctx context.Context, channelID, bookmarkID string, params EditBookmarkParameters) (Bookmark, error) {
|
||||
values := url.Values{
|
||||
"channel_id": {channelID},
|
||||
"token": {api.token},
|
||||
"bookmark_id": {bookmarkID},
|
||||
}
|
||||
if params.Link != "" {
|
||||
values.Set("link", params.Link)
|
||||
}
|
||||
if params.Emoji != nil {
|
||||
values.Set("emoji", *params.Emoji)
|
||||
}
|
||||
if params.Title != nil {
|
||||
values.Set("title", *params.Title)
|
||||
}
|
||||
|
||||
response := &editBookmarkResponse{}
|
||||
if err := api.postMethod(ctx, "bookmarks.edit", values, response); err != nil {
|
||||
return Bookmark{}, err
|
||||
}
|
||||
|
||||
return response.Bookmark, response.Err()
|
||||
}
|
4
vendor/github.com/slack-go/slack/misc.go
generated
vendored
4
vendor/github.com/slack-go/slack/misc.go
generated
vendored
@ -18,8 +18,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/slack-go/slack/internal/misc"
|
||||
)
|
||||
|
||||
// SlackResponse handles parsing out errors from the web api.
|
||||
@ -299,7 +297,7 @@ func checkStatusCode(resp *http.Response, d Debug) error {
|
||||
// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
logResponse(resp, d)
|
||||
return misc.StatusCodeError{Code: resp.StatusCode, Status: resp.Status}
|
||||
return StatusCodeError{Code: resp.StatusCode, Status: resp.Status}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
316
vendor/github.com/slack-go/slack/remotefiles.go
generated
vendored
Normal file
316
vendor/github.com/slack-go/slack/remotefiles.go
generated
vendored
Normal file
@ -0,0 +1,316 @@
|
||||
package slack
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_REMOTE_FILES_CHANNEL = ""
|
||||
DEFAULT_REMOTE_FILES_TS_FROM = 0
|
||||
DEFAULT_REMOTE_FILES_TS_TO = -1
|
||||
DEFAULT_REMOTE_FILES_COUNT = 100
|
||||
)
|
||||
|
||||
// RemoteFile contains all the information for a remote file
|
||||
// For more details:
|
||||
// https://api.slack.com/messaging/files/remote
|
||||
type RemoteFile struct {
|
||||
ID string `json:"id"`
|
||||
Created JSONTime `json:"created"`
|
||||
Timestamp JSONTime `json:"timestamp"`
|
||||
Name string `json:"name"`
|
||||
Title string `json:"title"`
|
||||
Mimetype string `json:"mimetype"`
|
||||
Filetype string `json:"filetype"`
|
||||
PrettyType string `json:"pretty_type"`
|
||||
User string `json:"user"`
|
||||
Editable bool `json:"editable"`
|
||||
Size int `json:"size"`
|
||||
Mode string `json:"mode"`
|
||||
IsExternal bool `json:"is_external"`
|
||||
ExternalType string `json:"external_type"`
|
||||
IsPublic bool `json:"is_public"`
|
||||
PublicURLShared bool `json:"public_url_shared"`
|
||||
DisplayAsBot bool `json:"display_as_bot"`
|
||||
Username string `json:"username"`
|
||||
URLPrivate string `json:"url_private"`
|
||||
Permalink string `json:"permalink"`
|
||||
CommentsCount int `json:"comments_count"`
|
||||
IsStarred bool `json:"is_starred"`
|
||||
Shares Share `json:"shares"`
|
||||
Channels []string `json:"channels"`
|
||||
Groups []string `json:"groups"`
|
||||
IMs []string `json:"ims"`
|
||||
ExternalID string `json:"external_id"`
|
||||
ExternalURL string `json:"external_url"`
|
||||
HasRichPreview bool `json:"has_rich_preview"`
|
||||
}
|
||||
|
||||
// RemoteFileParameters contains required and optional parameters for a remote file.
|
||||
//
|
||||
// ExternalID is a user defined GUID, ExternalURL is where the remote file can be accessed,
|
||||
// and Title is the name of the file.
|
||||
//
|
||||
// For more details:
|
||||
// https://api.slack.com/methods/files.remote.add
|
||||
type RemoteFileParameters struct {
|
||||
ExternalID string // required
|
||||
ExternalURL string // required
|
||||
Title string // required
|
||||
Filetype string
|
||||
IndexableFileContents string
|
||||
PreviewImage string
|
||||
PreviewImageReader io.Reader
|
||||
}
|
||||
|
||||
// ListRemoteFilesParameters contains arguments for the ListRemoteFiles method.
|
||||
// For more details:
|
||||
// https://api.slack.com/methods/files.remote.list
|
||||
type ListRemoteFilesParameters struct {
|
||||
Channel string
|
||||
Cursor string
|
||||
Limit int
|
||||
TimestampFrom JSONTime
|
||||
TimestampTo JSONTime
|
||||
}
|
||||
|
||||
type remoteFileResponseFull struct {
|
||||
RemoteFile `json:"file"`
|
||||
Paging `json:"paging"`
|
||||
Files []RemoteFile `json:"files"`
|
||||
SlackResponse
|
||||
}
|
||||
|
||||
func (api *Client) remoteFileRequest(ctx context.Context, path string, values url.Values) (*remoteFileResponseFull, error) {
|
||||
response := &remoteFileResponseFull{}
|
||||
err := api.postMethod(ctx, path, values, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, response.Err()
|
||||
}
|
||||
|
||||
// AddRemoteFile adds a remote file. Unlike regular files, remote files must be explicitly shared.
|
||||
// For more details:
|
||||
// https://api.slack.com/methods/files.remote.add
|
||||
func (api *Client) AddRemoteFile(params RemoteFileParameters) (*RemoteFile, error) {
|
||||
return api.AddRemoteFileContext(context.Background(), params)
|
||||
}
|
||||
|
||||
// AddRemoteFileContext adds a remote file and setting a custom context
|
||||
// For more details see the AddRemoteFile documentation.
|
||||
func (api *Client) AddRemoteFileContext(ctx context.Context, params RemoteFileParameters) (remotefile *RemoteFile, err error) {
|
||||
if params.ExternalID == "" || params.ExternalURL == "" || params.Title == "" {
|
||||
return nil, ErrParametersMissing
|
||||
}
|
||||
response := &remoteFileResponseFull{}
|
||||
values := url.Values{
|
||||
"token": {api.token},
|
||||
"external_id": {params.ExternalID},
|
||||
"external_url": {params.ExternalURL},
|
||||
"title": {params.Title},
|
||||
}
|
||||
if params.Filetype != "" {
|
||||
values.Add("filetype", params.Filetype)
|
||||
}
|
||||
if params.IndexableFileContents != "" {
|
||||
values.Add("indexable_file_contents", params.IndexableFileContents)
|
||||
}
|
||||
if params.PreviewImage != "" {
|
||||
err = postLocalWithMultipartResponse(ctx, api.httpclient, api.endpoint+"files.remote.add", params.PreviewImage, "preview_image", api.token, values, response, api)
|
||||
} else if params.PreviewImageReader != nil {
|
||||
err = postWithMultipartResponse(ctx, api.httpclient, api.endpoint+"files.remote.add", "preview.png", "preview_image", api.token, values, params.PreviewImageReader, response, api)
|
||||
} else {
|
||||
response, err = api.remoteFileRequest(ctx, "files.remote.add", values)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &response.RemoteFile, response.Err()
|
||||
}
|
||||
|
||||
// ListRemoteFiles retrieves all remote files according to the parameters given. Uses cursor based pagination.
|
||||
// For more details:
|
||||
// https://api.slack.com/methods/files.remote.list
|
||||
func (api *Client) ListRemoteFiles(params ListRemoteFilesParameters) ([]RemoteFile, error) {
|
||||
return api.ListRemoteFilesContext(context.Background(), params)
|
||||
}
|
||||
|
||||
// ListRemoteFilesContext retrieves all remote files according to the parameters given with a custom context. Uses cursor based pagination.
|
||||
// For more details see the ListRemoteFiles documentation.
|
||||
func (api *Client) ListRemoteFilesContext(ctx context.Context, params ListRemoteFilesParameters) ([]RemoteFile, error) {
|
||||
values := url.Values{
|
||||
"token": {api.token},
|
||||
}
|
||||
if params.Channel != DEFAULT_REMOTE_FILES_CHANNEL {
|
||||
values.Add("channel", params.Channel)
|
||||
}
|
||||
if params.TimestampFrom != DEFAULT_REMOTE_FILES_TS_FROM {
|
||||
values.Add("ts_from", strconv.FormatInt(int64(params.TimestampFrom), 10))
|
||||
}
|
||||
if params.TimestampTo != DEFAULT_REMOTE_FILES_TS_TO {
|
||||
values.Add("ts_to", strconv.FormatInt(int64(params.TimestampTo), 10))
|
||||
}
|
||||
if params.Limit != DEFAULT_REMOTE_FILES_COUNT {
|
||||
values.Add("limit", strconv.Itoa(params.Limit))
|
||||
}
|
||||
if params.Cursor != "" {
|
||||
values.Add("cursor", params.Cursor)
|
||||
}
|
||||
|
||||
response, err := api.remoteFileRequest(ctx, "files.remote.list", values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
params.Cursor = response.SlackResponse.ResponseMetadata.Cursor
|
||||
|
||||
return response.Files, nil
|
||||
}
|
||||
|
||||
// GetRemoteFileInfo retrieves the complete remote file information.
|
||||
// For more details:
|
||||
// https://api.slack.com/methods/files.remote.info
|
||||
func (api *Client) GetRemoteFileInfo(externalID, fileID string) (remotefile *RemoteFile, err error) {
|
||||
return api.GetRemoteFileInfoContext(context.Background(), externalID, fileID)
|
||||
}
|
||||
|
||||
// GetRemoteFileInfoContext retrieves the complete remote file information given with a custom context.
|
||||
// For more details see the GetRemoteFileInfo documentation.
|
||||
func (api *Client) GetRemoteFileInfoContext(ctx context.Context, externalID, fileID string) (remotefile *RemoteFile, err error) {
|
||||
if fileID == "" && externalID == "" {
|
||||
return nil, fmt.Errorf("either externalID or fileID is required")
|
||||
}
|
||||
if fileID != "" && externalID != "" {
|
||||
return nil, fmt.Errorf("don't provide both externalID and fileID")
|
||||
}
|
||||
values := url.Values{
|
||||
"token": {api.token},
|
||||
}
|
||||
if fileID != "" {
|
||||
values.Add("file", fileID)
|
||||
}
|
||||
if externalID != "" {
|
||||
values.Add("external_id", externalID)
|
||||
}
|
||||
response, err := api.remoteFileRequest(ctx, "files.remote.info", values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response.RemoteFile, err
|
||||
}
|
||||
|
||||
// ShareRemoteFile shares a remote file to channels
|
||||
// For more details:
|
||||
// https://api.slack.com/methods/files.remote.share
|
||||
func (api *Client) ShareRemoteFile(channels []string, externalID, fileID string) (file *RemoteFile, err error) {
|
||||
return api.ShareRemoteFileContext(context.Background(), channels, externalID, fileID)
|
||||
}
|
||||
|
||||
// ShareRemoteFileContext shares a remote file to channels with a custom context.
|
||||
// For more details see the ShareRemoteFile documentation.
|
||||
func (api *Client) ShareRemoteFileContext(ctx context.Context, channels []string, externalID, fileID string) (file *RemoteFile, err error) {
|
||||
if channels == nil || len(channels) == 0 {
|
||||
return nil, ErrParametersMissing
|
||||
}
|
||||
if fileID == "" && externalID == "" {
|
||||
return nil, fmt.Errorf("either externalID or fileID is required")
|
||||
}
|
||||
values := url.Values{
|
||||
"token": {api.token},
|
||||
"channels": {strings.Join(channels, ",")},
|
||||
}
|
||||
if fileID != "" {
|
||||
values.Add("file", fileID)
|
||||
}
|
||||
if externalID != "" {
|
||||
values.Add("external_id", externalID)
|
||||
}
|
||||
response, err := api.remoteFileRequest(ctx, "files.remote.share", values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response.RemoteFile, err
|
||||
}
|
||||
|
||||
// UpdateRemoteFile updates a remote file
|
||||
// For more details:
|
||||
// https://api.slack.com/methods/files.remote.update
|
||||
func (api *Client) UpdateRemoteFile(fileID string, params RemoteFileParameters) (remotefile *RemoteFile, err error) {
|
||||
return api.UpdateRemoteFileContext(context.Background(), fileID, params)
|
||||
}
|
||||
|
||||
// UpdateRemoteFileContext updates a remote file with a custom context
|
||||
// For more details see the UpdateRemoteFile documentation.
|
||||
func (api *Client) UpdateRemoteFileContext(ctx context.Context, fileID string, params RemoteFileParameters) (remotefile *RemoteFile, err error) {
|
||||
response := &remoteFileResponseFull{}
|
||||
values := url.Values{
|
||||
"token": {api.token},
|
||||
}
|
||||
if fileID != "" {
|
||||
values.Add("file", fileID)
|
||||
}
|
||||
if params.ExternalID != "" {
|
||||
values.Add("external_id", params.ExternalID)
|
||||
}
|
||||
if params.ExternalURL != "" {
|
||||
values.Add("external_url", params.ExternalURL)
|
||||
}
|
||||
if params.Title != "" {
|
||||
values.Add("title", params.Title)
|
||||
}
|
||||
if params.Filetype != "" {
|
||||
values.Add("filetype", params.Filetype)
|
||||
}
|
||||
if params.IndexableFileContents != "" {
|
||||
values.Add("indexable_file_contents", params.IndexableFileContents)
|
||||
}
|
||||
if params.PreviewImageReader != nil {
|
||||
err = postWithMultipartResponse(ctx, api.httpclient, api.endpoint+"files.remote.update", "preview.png", "preview_image", api.token, values, params.PreviewImageReader, response, api)
|
||||
} else {
|
||||
response, err = api.remoteFileRequest(ctx, "files.remote.update", values)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &response.RemoteFile, response.Err()
|
||||
}
|
||||
|
||||
// RemoveRemoteFile removes a remote file.
|
||||
// For more details:
|
||||
// https://api.slack.com/methods/files.remote.remove
|
||||
func (api *Client) RemoveRemoteFile(externalID, fileID string) (err error) {
|
||||
return api.RemoveRemoteFileContext(context.Background(), externalID, fileID)
|
||||
}
|
||||
|
||||
// RemoveRemoteFileContext removes a remote file with a custom context
|
||||
// For more information see the RemoveRemoteFiles documentation.
|
||||
func (api *Client) RemoveRemoteFileContext(ctx context.Context, externalID, fileID string) (err error) {
|
||||
if fileID == "" && externalID == "" {
|
||||
return fmt.Errorf("either externalID or fileID is required")
|
||||
}
|
||||
if fileID != "" && externalID != "" {
|
||||
return fmt.Errorf("don't provide both externalID and fileID")
|
||||
}
|
||||
values := url.Values{
|
||||
"token": {api.token},
|
||||
}
|
||||
if fileID != "" {
|
||||
values.Add("file", fileID)
|
||||
}
|
||||
if externalID != "" {
|
||||
values.Add("external_id", externalID)
|
||||
}
|
||||
_, err = api.remoteFileRequest(ctx, "files.remote.remove", values)
|
||||
return err
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package misc
|
||||
package slack
|
||||
|
||||
import (
|
||||
"fmt"
|
37
vendor/github.com/slack-go/slack/views.go
generated
vendored
37
vendor/github.com/slack-go/slack/views.go
generated
vendored
@ -18,24 +18,25 @@ type ViewState struct {
|
||||
|
||||
type View struct {
|
||||
SlackResponse
|
||||
ID string `json:"id"`
|
||||
TeamID string `json:"team_id"`
|
||||
Type ViewType `json:"type"`
|
||||
Title *TextBlockObject `json:"title"`
|
||||
Close *TextBlockObject `json:"close"`
|
||||
Submit *TextBlockObject `json:"submit"`
|
||||
Blocks Blocks `json:"blocks"`
|
||||
PrivateMetadata string `json:"private_metadata"`
|
||||
CallbackID string `json:"callback_id"`
|
||||
State *ViewState `json:"state"`
|
||||
Hash string `json:"hash"`
|
||||
ClearOnClose bool `json:"clear_on_close"`
|
||||
NotifyOnClose bool `json:"notify_on_close"`
|
||||
RootViewID string `json:"root_view_id"`
|
||||
PreviousViewID string `json:"previous_view_id"`
|
||||
AppID string `json:"app_id"`
|
||||
ExternalID string `json:"external_id"`
|
||||
BotID string `json:"bot_id"`
|
||||
ID string `json:"id"`
|
||||
TeamID string `json:"team_id"`
|
||||
Type ViewType `json:"type"`
|
||||
Title *TextBlockObject `json:"title"`
|
||||
Close *TextBlockObject `json:"close"`
|
||||
Submit *TextBlockObject `json:"submit"`
|
||||
Blocks Blocks `json:"blocks"`
|
||||
PrivateMetadata string `json:"private_metadata"`
|
||||
CallbackID string `json:"callback_id"`
|
||||
State *ViewState `json:"state"`
|
||||
Hash string `json:"hash"`
|
||||
ClearOnClose bool `json:"clear_on_close"`
|
||||
NotifyOnClose bool `json:"notify_on_close"`
|
||||
RootViewID string `json:"root_view_id"`
|
||||
PreviousViewID string `json:"previous_view_id"`
|
||||
AppID string `json:"app_id"`
|
||||
ExternalID string `json:"external_id"`
|
||||
BotID string `json:"bot_id"`
|
||||
AppInstalledTeamID string `json:"app_installed_team_id"`
|
||||
}
|
||||
|
||||
type ViewSubmissionCallbackResponseURL struct {
|
||||
|
8
vendor/github.com/slack-go/slack/webhooks.go
generated
vendored
8
vendor/github.com/slack-go/slack/webhooks.go
generated
vendored
@ -5,6 +5,8 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@ -21,6 +23,7 @@ type WebhookMessage struct {
|
||||
ResponseType string `json:"response_type,omitempty"`
|
||||
ReplaceOriginal bool `json:"replace_original,omitempty"`
|
||||
DeleteOriginal bool `json:"delete_original,omitempty"`
|
||||
ReplyBroadcast bool `json:"reply_broadcast,omitempty"`
|
||||
}
|
||||
|
||||
func PostWebhook(url string, msg *WebhookMessage) error {
|
||||
@ -51,7 +54,10 @@ func PostWebhookCustomHTTPContext(ctx context.Context, url string, httpClient *h
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to post webhook: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
io.Copy(ioutil.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
return checkStatusCode(resp, discard{})
|
||||
}
|
||||
|
7
vendor/github.com/slack-go/slack/websocket_managed_conn.go
generated
vendored
7
vendor/github.com/slack-go/slack/websocket_managed_conn.go
generated
vendored
@ -13,7 +13,6 @@ import (
|
||||
|
||||
"github.com/slack-go/slack/internal/backoff"
|
||||
"github.com/slack-go/slack/internal/errorsx"
|
||||
"github.com/slack-go/slack/internal/misc"
|
||||
"github.com/slack-go/slack/internal/timex"
|
||||
)
|
||||
|
||||
@ -127,7 +126,7 @@ func (rtm *RTM) connect(connectionCount int, useRTMStart bool) (*Info, *websocke
|
||||
}
|
||||
|
||||
switch actual := err.(type) {
|
||||
case misc.StatusCodeError:
|
||||
case StatusCodeError:
|
||||
if actual.Code == http.StatusNotFound {
|
||||
rtm.Debugf("invalid auth when connecting with RTM: %s", err)
|
||||
rtm.IncomingEvents <- RTMEvent{"invalid_auth", &InvalidAuthEvent{}}
|
||||
@ -475,7 +474,7 @@ func (rtm *RTM) handleEvent(typeStr string, event json.RawMessage) {
|
||||
v, exists := EventMapping[typeStr]
|
||||
if !exists {
|
||||
rtm.Debugf("RTM Error - received unmapped event %q: %s\n", typeStr, string(event))
|
||||
err := fmt.Errorf("RTM Error: Received unmapped event %q: %s", typeStr, string(event))
|
||||
err := fmt.Errorf("RTM Error: Received unmapped event %q", typeStr)
|
||||
rtm.IncomingEvents <- RTMEvent{"unmarshalling_error", &UnmarshallingErrorEvent{err}}
|
||||
return
|
||||
}
|
||||
@ -484,7 +483,7 @@ func (rtm *RTM) handleEvent(typeStr string, event json.RawMessage) {
|
||||
err := json.Unmarshal(event, recvEvent)
|
||||
if err != nil {
|
||||
rtm.Debugf("RTM Error, could not unmarshall event %q: %s\n", typeStr, string(event))
|
||||
err := fmt.Errorf("RTM Error: Could not unmarshall event %q: %s", typeStr, string(event))
|
||||
err := fmt.Errorf("RTM Error: Could not unmarshall event %q", typeStr)
|
||||
rtm.IncomingEvents <- RTMEvent{"unmarshalling_error", &UnmarshallingErrorEvent{err}}
|
||||
return
|
||||
}
|
||||
|
4
vendor/github.com/slack-go/slack/websocket_subteam.go
generated
vendored
4
vendor/github.com/slack-go/slack/websocket_subteam.go
generated
vendored
@ -14,9 +14,9 @@ type SubteamMembersChangedEvent struct {
|
||||
DatePreviousUpdate JSONTime `json:"date_previous_update"`
|
||||
DateUpdate JSONTime `json:"date_update"`
|
||||
AddedUsers []string `json:"added_users"`
|
||||
AddedUsersCount string `json:"added_users_count"`
|
||||
AddedUsersCount int `json:"added_users_count"`
|
||||
RemovedUsers []string `json:"removed_users"`
|
||||
RemovedUsersCount string `json:"removed_users_count"`
|
||||
RemovedUsersCount int `json:"removed_users_count"`
|
||||
}
|
||||
|
||||
// SubteamSelfAddedEvent represents an event of you have been added to a User Group
|
||||
|
2
vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go
generated
vendored
2
vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go
generated
vendored
@ -9,7 +9,7 @@ package assert
|
||||
|
||||
import "reflect"
|
||||
|
||||
// Wrapper around reflect.Value.CanConvert, for compatability
|
||||
// Wrapper around reflect.Value.CanConvert, for compatibility
|
||||
// reasons.
|
||||
func canConvert(value reflect.Value, to reflect.Type) bool {
|
||||
return value.CanConvert(to)
|
||||
|
10
vendor/github.com/stretchr/testify/suite/suite.go
generated
vendored
10
vendor/github.com/stretchr/testify/suite/suite.go
generated
vendored
@ -7,6 +7,7 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -21,17 +22,22 @@ var matchMethod = flag.String("testify.m", "", "regular expression to select tes
|
||||
// retrieving the current *testing.T context.
|
||||
type Suite struct {
|
||||
*assert.Assertions
|
||||
mu sync.RWMutex
|
||||
require *require.Assertions
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
// T retrieves the current *testing.T context.
|
||||
func (suite *Suite) T() *testing.T {
|
||||
suite.mu.RLock()
|
||||
defer suite.mu.RUnlock()
|
||||
return suite.t
|
||||
}
|
||||
|
||||
// SetT sets the current *testing.T context.
|
||||
func (suite *Suite) SetT(t *testing.T) {
|
||||
suite.mu.Lock()
|
||||
defer suite.mu.Unlock()
|
||||
suite.t = t
|
||||
suite.Assertions = assert.New(t)
|
||||
suite.require = require.New(t)
|
||||
@ -39,6 +45,8 @@ func (suite *Suite) SetT(t *testing.T) {
|
||||
|
||||
// Require returns a require context for suite.
|
||||
func (suite *Suite) Require() *require.Assertions {
|
||||
suite.mu.Lock()
|
||||
defer suite.mu.Unlock()
|
||||
if suite.require == nil {
|
||||
suite.require = require.New(suite.T())
|
||||
}
|
||||
@ -51,6 +59,8 @@ func (suite *Suite) Require() *require.Assertions {
|
||||
// assert.Assertions with require.Assertions), this method is provided so you
|
||||
// can call `suite.Assert().NoError()`.
|
||||
func (suite *Suite) Assert() *assert.Assertions {
|
||||
suite.mu.Lock()
|
||||
defer suite.mu.Unlock()
|
||||
if suite.Assertions == nil {
|
||||
suite.Assertions = assert.New(suite.T())
|
||||
}
|
||||
|
3598
vendor/go.mau.fi/whatsmeow/binary/proto/def.pb.go
vendored
3598
vendor/go.mau.fi/whatsmeow/binary/proto/def.pb.go
vendored
File diff suppressed because it is too large
Load Diff
BIN
vendor/go.mau.fi/whatsmeow/binary/proto/def.pb.raw
vendored
BIN
vendor/go.mau.fi/whatsmeow/binary/proto/def.pb.raw
vendored
Binary file not shown.
158
vendor/go.mau.fi/whatsmeow/binary/proto/def.proto
vendored
158
vendor/go.mau.fi/whatsmeow/binary/proto/def.proto
vendored
@ -31,10 +31,10 @@ message ADVDeviceIdentity {
|
||||
optional uint32 keyIndex = 3;
|
||||
}
|
||||
|
||||
message CompanionProps {
|
||||
message DeviceProps {
|
||||
optional string os = 1;
|
||||
optional AppVersion version = 2;
|
||||
enum CompanionPropsPlatformType {
|
||||
enum DevicePropsPlatformType {
|
||||
UNKNOWN = 0;
|
||||
CHROME = 1;
|
||||
FIREFOX = 2;
|
||||
@ -50,7 +50,7 @@ message CompanionProps {
|
||||
CATALINA = 12;
|
||||
TCL_TV = 13;
|
||||
}
|
||||
optional CompanionPropsPlatformType platformType = 3;
|
||||
optional DevicePropsPlatformType platformType = 3;
|
||||
optional bool requireFullSync = 4;
|
||||
}
|
||||
|
||||
@ -62,39 +62,6 @@ message AppVersion {
|
||||
optional uint32 quinary = 5;
|
||||
}
|
||||
|
||||
message ProtocolMessage {
|
||||
optional MessageKey key = 1;
|
||||
enum ProtocolMessageType {
|
||||
REVOKE = 0;
|
||||
EPHEMERAL_SETTING = 3;
|
||||
EPHEMERAL_SYNC_RESPONSE = 4;
|
||||
HISTORY_SYNC_NOTIFICATION = 5;
|
||||
APP_STATE_SYNC_KEY_SHARE = 6;
|
||||
APP_STATE_SYNC_KEY_REQUEST = 7;
|
||||
MSG_FANOUT_BACKFILL_REQUEST = 8;
|
||||
INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC = 9;
|
||||
APP_STATE_FATAL_EXCEPTION_NOTIFICATION = 10;
|
||||
}
|
||||
optional ProtocolMessageType type = 2;
|
||||
optional uint32 ephemeralExpiration = 4;
|
||||
optional int64 ephemeralSettingTimestamp = 5;
|
||||
optional HistorySyncNotification historySyncNotification = 6;
|
||||
optional AppStateSyncKeyShare appStateSyncKeyShare = 7;
|
||||
optional AppStateSyncKeyRequest appStateSyncKeyRequest = 8;
|
||||
optional InitialSecurityNotificationSettingSync initialSecurityNotificationSettingSync = 9;
|
||||
optional AppStateFatalExceptionNotification appStateFatalExceptionNotification = 10;
|
||||
optional DisappearingMode disappearingMode = 11;
|
||||
}
|
||||
|
||||
message ProductMessage {
|
||||
optional ProductSnapshot product = 1;
|
||||
optional string businessOwnerJid = 2;
|
||||
optional CatalogSnapshot catalog = 4;
|
||||
optional string body = 5;
|
||||
optional string footer = 6;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
|
||||
message ProductSnapshot {
|
||||
optional ImageMessage productImage = 1;
|
||||
optional string productId = 2;
|
||||
@ -123,6 +90,10 @@ message PollVoteMessage {
|
||||
message PollUpdateMessage {
|
||||
optional MessageKey pollCreationMessageKey = 1;
|
||||
optional PollEncValue vote = 2;
|
||||
optional PollUpdateMessageMetadata metadata = 3;
|
||||
}
|
||||
|
||||
message PollUpdateMessageMetadata {
|
||||
}
|
||||
|
||||
message PollEncValue {
|
||||
@ -265,6 +236,12 @@ message ProductListHeaderImage {
|
||||
optional bytes jpegThumbnail = 2;
|
||||
}
|
||||
|
||||
message KeepInChatMessage {
|
||||
optional MessageKey key = 1;
|
||||
optional KeepType keepType = 2;
|
||||
optional int64 timestampMs = 3;
|
||||
}
|
||||
|
||||
message InvoiceMessage {
|
||||
optional string note = 1;
|
||||
optional string token = 2;
|
||||
@ -708,6 +685,11 @@ message Location {
|
||||
optional string name = 3;
|
||||
}
|
||||
|
||||
enum KeepType {
|
||||
UNKNOWN = 0;
|
||||
KEEP_FOR_ALL = 1;
|
||||
UNDO_KEEP_FOR_ALL = 2;
|
||||
}
|
||||
message InteractiveAnnotation {
|
||||
repeated Point polygonVertices = 1;
|
||||
oneof action {
|
||||
@ -926,12 +908,14 @@ message Message {
|
||||
optional InteractiveResponseMessage interactiveResponseMessage = 48;
|
||||
optional PollCreationMessage pollCreationMessage = 49;
|
||||
optional PollUpdateMessage pollUpdateMessage = 50;
|
||||
optional KeepInChatMessage keepInChatMessage = 51;
|
||||
}
|
||||
|
||||
message MessageContextInfo {
|
||||
optional DeviceListMetadata deviceListMetadata = 1;
|
||||
optional int32 deviceListMetadataVersion = 2;
|
||||
optional bytes messageSecret = 3;
|
||||
optional bytes paddingBytes = 4;
|
||||
}
|
||||
|
||||
message VideoMessage {
|
||||
@ -1060,6 +1044,39 @@ message ReactionMessage {
|
||||
optional int64 senderTimestampMs = 4;
|
||||
}
|
||||
|
||||
message ProtocolMessage {
|
||||
optional MessageKey key = 1;
|
||||
enum ProtocolMessageType {
|
||||
REVOKE = 0;
|
||||
EPHEMERAL_SETTING = 3;
|
||||
EPHEMERAL_SYNC_RESPONSE = 4;
|
||||
HISTORY_SYNC_NOTIFICATION = 5;
|
||||
APP_STATE_SYNC_KEY_SHARE = 6;
|
||||
APP_STATE_SYNC_KEY_REQUEST = 7;
|
||||
MSG_FANOUT_BACKFILL_REQUEST = 8;
|
||||
INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC = 9;
|
||||
APP_STATE_FATAL_EXCEPTION_NOTIFICATION = 10;
|
||||
}
|
||||
optional ProtocolMessageType type = 2;
|
||||
optional uint32 ephemeralExpiration = 4;
|
||||
optional int64 ephemeralSettingTimestamp = 5;
|
||||
optional HistorySyncNotification historySyncNotification = 6;
|
||||
optional AppStateSyncKeyShare appStateSyncKeyShare = 7;
|
||||
optional AppStateSyncKeyRequest appStateSyncKeyRequest = 8;
|
||||
optional InitialSecurityNotificationSettingSync initialSecurityNotificationSettingSync = 9;
|
||||
optional AppStateFatalExceptionNotification appStateFatalExceptionNotification = 10;
|
||||
optional DisappearingMode disappearingMode = 11;
|
||||
}
|
||||
|
||||
message ProductMessage {
|
||||
optional ProductSnapshot product = 1;
|
||||
optional string businessOwnerJid = 2;
|
||||
optional CatalogSnapshot catalog = 4;
|
||||
optional string body = 5;
|
||||
optional string footer = 6;
|
||||
optional ContextInfo contextInfo = 17;
|
||||
}
|
||||
|
||||
message EphemeralSetting {
|
||||
optional sfixed32 duration = 1;
|
||||
optional sfixed64 timestamp = 2;
|
||||
@ -1161,6 +1178,17 @@ message Conversation {
|
||||
optional MediaVisibility mediaVisibility = 27;
|
||||
optional uint64 tcTokenSenderTimestamp = 28;
|
||||
optional bool suspended = 29;
|
||||
optional bool terminated = 30;
|
||||
optional uint64 createdAt = 31;
|
||||
optional string createdBy = 32;
|
||||
optional string description = 33;
|
||||
optional bool support = 34;
|
||||
optional bool isParentGroup = 35;
|
||||
optional bool isDefaultSubgroup = 36;
|
||||
optional string parentGroupId = 37;
|
||||
optional string displayName = 38;
|
||||
optional string pnJid = 39;
|
||||
optional bool selfMasked = 40;
|
||||
}
|
||||
|
||||
message AutoDownloadSettings {
|
||||
@ -1192,8 +1220,8 @@ message MsgOpaqueData {
|
||||
optional string loc = 16;
|
||||
optional string pollName = 17;
|
||||
repeated PollOption pollOptions = 18;
|
||||
optional bytes pollEncKey = 19;
|
||||
optional uint32 pollSelectableOptionsCount = 20;
|
||||
optional bytes messageSecret = 21;
|
||||
}
|
||||
|
||||
message PollOption {
|
||||
@ -1559,20 +1587,6 @@ message BizAccountLinkInfo {
|
||||
optional BizAccountLinkInfoAccountType accountType = 5;
|
||||
}
|
||||
|
||||
message NoiseCertificate {
|
||||
optional bytes details = 1;
|
||||
optional bytes signature = 2;
|
||||
}
|
||||
|
||||
// Renamed from NoiseCertificate$Details
|
||||
message NoiseCertificateDetails {
|
||||
optional uint32 serial = 1;
|
||||
optional string issuer = 2;
|
||||
optional uint64 expires = 3;
|
||||
optional string subject = 4;
|
||||
optional bytes key = 5;
|
||||
}
|
||||
|
||||
message HandshakeMessage {
|
||||
optional ClientHello clientHello = 2;
|
||||
optional ServerHello serverHello = 3;
|
||||
@ -1943,6 +1957,7 @@ message WebMessageInfo {
|
||||
GROUP_PARTICIPANT_ACCEPT = 140;
|
||||
GROUP_PARTICIPANT_LINKED_GROUP_JOIN = 141;
|
||||
COMMUNITY_CREATE = 142;
|
||||
EPHEMERAL_KEEP_IN_CHAT = 143;
|
||||
}
|
||||
optional WebMessageInfoStubType messageStubType = 24;
|
||||
optional bool clearMedia = 25;
|
||||
@ -1976,6 +1991,7 @@ message WebMessageInfo {
|
||||
optional string agentId = 47;
|
||||
optional bool statusAlreadyViewed = 48;
|
||||
optional bytes messageSecret = 49;
|
||||
optional KeepInChat keepInChat = 50;
|
||||
}
|
||||
|
||||
message WebFeatures {
|
||||
@ -2148,3 +2164,43 @@ message MediaData {
|
||||
optional string localPath = 1;
|
||||
}
|
||||
|
||||
message KeepInChat {
|
||||
optional KeepType keepType = 1;
|
||||
optional int64 serverTimestamp = 2;
|
||||
optional string deviceJid = 3;
|
||||
}
|
||||
|
||||
message NoiseCertificate {
|
||||
optional bytes details = 1;
|
||||
optional bytes signature = 2;
|
||||
}
|
||||
|
||||
// Renamed from NoiseCertificate$Details
|
||||
message NoiseCertificateDetails {
|
||||
optional uint32 serial = 1;
|
||||
optional string issuer = 2;
|
||||
optional uint64 expires = 3;
|
||||
optional string subject = 4;
|
||||
optional bytes key = 5;
|
||||
}
|
||||
|
||||
message CertChain {
|
||||
optional CertChainNoiseCertificate leaf = 1;
|
||||
optional CertChainNoiseCertificate intermediate = 2;
|
||||
}
|
||||
|
||||
// Renamed from CertChain$NoiseCertificate
|
||||
message CertChainNoiseCertificate {
|
||||
optional bytes details = 1;
|
||||
optional bytes signature = 2;
|
||||
}
|
||||
|
||||
// Renamed from CertChain$NoiseCertificate$Details
|
||||
message CertChainNoiseCertificateDetails {
|
||||
optional uint32 serial = 1;
|
||||
optional uint32 issuerSerial = 2;
|
||||
optional bytes key = 3;
|
||||
optional uint64 notBefore = 4;
|
||||
optional uint64 notAfter = 5;
|
||||
}
|
||||
|
||||
|
18
vendor/go.mau.fi/whatsmeow/message.go
vendored
18
vendor/go.mau.fi/whatsmeow/message.go
vendored
@ -40,6 +40,9 @@ func (cli *Client) handleEncryptedMessage(node *waBinary.Node) {
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to parse message: %v", err)
|
||||
} else {
|
||||
if info.VerifiedName != nil && len(info.VerifiedName.Details.GetVerifiedName()) > 0 {
|
||||
go cli.updateBusinessName(info.Sender, info, info.VerifiedName.Details.GetVerifiedName())
|
||||
}
|
||||
if len(info.PushName) > 0 && info.PushName != "-" {
|
||||
go cli.updatePushName(info.Sender, info, info.PushName)
|
||||
}
|
||||
@ -47,13 +50,17 @@ func (cli *Client) handleEncryptedMessage(node *waBinary.Node) {
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *Client) parseMessageSource(node *waBinary.Node) (source types.MessageSource, err error) {
|
||||
func (cli *Client) parseMessageSource(node *waBinary.Node, requireParticipant bool) (source types.MessageSource, err error) {
|
||||
ag := node.AttrGetter()
|
||||
from := ag.JID("from")
|
||||
if from.Server == types.GroupServer || from.Server == types.BroadcastServer {
|
||||
source.IsGroup = true
|
||||
source.Chat = from
|
||||
source.Sender = ag.JID("participant")
|
||||
if requireParticipant {
|
||||
source.Sender = ag.JID("participant")
|
||||
} else {
|
||||
source.Sender = ag.OptionalJIDOrEmpty("participant")
|
||||
}
|
||||
if source.Sender.User == cli.Store.ID.User {
|
||||
source.IsFromMe = true
|
||||
}
|
||||
@ -80,7 +87,7 @@ func (cli *Client) parseMessageSource(node *waBinary.Node) (source types.Message
|
||||
func (cli *Client) parseMessageInfo(node *waBinary.Node) (*types.MessageInfo, error) {
|
||||
var info types.MessageInfo
|
||||
var err error
|
||||
info.MessageSource, err = cli.parseMessageSource(node)
|
||||
info.MessageSource, err = cli.parseMessageSource(node, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -96,6 +103,11 @@ func (cli *Client) parseMessageInfo(node *waBinary.Node) (*types.MessageInfo, er
|
||||
for _, child := range node.GetChildren() {
|
||||
if child.Tag == "multicast" {
|
||||
info.Multicast = true
|
||||
} else if child.Tag == "verified_name" {
|
||||
info.VerifiedName, err = parseVerifiedNameContent(child)
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to parse verified_name node in %s: %v", info.ID, err)
|
||||
}
|
||||
} else if mediaType, ok := child.AttrGetter().GetString("mediatype", false); ok {
|
||||
info.MediaType = mediaType
|
||||
}
|
||||
|
2
vendor/go.mau.fi/whatsmeow/presence.go
vendored
2
vendor/go.mau.fi/whatsmeow/presence.go
vendored
@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func (cli *Client) handleChatState(node *waBinary.Node) {
|
||||
source, err := cli.parseMessageSource(node)
|
||||
source, err := cli.parseMessageSource(node, true)
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to parse chat state update: %v", err)
|
||||
} else if len(node.GetChildren()) != 1 {
|
||||
|
34
vendor/go.mau.fi/whatsmeow/receipt.go
vendored
34
vendor/go.mau.fi/whatsmeow/receipt.go
vendored
@ -20,7 +20,7 @@ func (cli *Client) handleReceipt(node *waBinary.Node) {
|
||||
receipt, err := cli.parseReceipt(node)
|
||||
if err != nil {
|
||||
cli.Log.Warnf("Failed to parse receipt: %v", err)
|
||||
} else {
|
||||
} else if receipt != nil {
|
||||
if receipt.Type == events.ReceiptTypeRetry {
|
||||
go func() {
|
||||
err := cli.handleRetryReceipt(receipt, node)
|
||||
@ -34,9 +34,29 @@ func (cli *Client) handleReceipt(node *waBinary.Node) {
|
||||
go cli.sendAck(node)
|
||||
}
|
||||
|
||||
func (cli *Client) handleGroupedReceipt(partialReceipt events.Receipt, participants *waBinary.Node) {
|
||||
pag := participants.AttrGetter()
|
||||
partialReceipt.MessageIDs = []types.MessageID{pag.String("key")}
|
||||
for _, child := range participants.GetChildren() {
|
||||
if child.Tag != "user" {
|
||||
cli.Log.Warnf("Unexpected node in grouped receipt participants: %s", child.XMLString())
|
||||
continue
|
||||
}
|
||||
ag := child.AttrGetter()
|
||||
receipt := partialReceipt
|
||||
receipt.Timestamp = ag.UnixTime("t")
|
||||
receipt.MessageSource.Sender = ag.JID("jid")
|
||||
if !ag.OK() {
|
||||
cli.Log.Warnf("Failed to parse user node %s in grouped receipt: %v", child.XMLString(), ag.Error())
|
||||
continue
|
||||
}
|
||||
go cli.dispatchEvent(&receipt)
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *Client) parseReceipt(node *waBinary.Node) (*events.Receipt, error) {
|
||||
ag := node.AttrGetter()
|
||||
source, err := cli.parseMessageSource(node)
|
||||
source, err := cli.parseMessageSource(node, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -45,6 +65,16 @@ func (cli *Client) parseReceipt(node *waBinary.Node) (*events.Receipt, error) {
|
||||
Timestamp: ag.UnixTime("t"),
|
||||
Type: events.ReceiptType(ag.OptionalString("type")),
|
||||
}
|
||||
if source.IsGroup && source.Sender.IsEmpty() {
|
||||
participantTags := node.GetChildrenByTag("participants")
|
||||
if len(participantTags) == 0 {
|
||||
return nil, &ElementMissingError{Tag: "participants", In: "grouped receipt"}
|
||||
}
|
||||
for _, pcp := range participantTags {
|
||||
cli.handleGroupedReceipt(receipt, &pcp)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
mainMessageID := ag.String("id")
|
||||
if !ag.OK() {
|
||||
return nil, fmt.Errorf("failed to parse read receipt attrs: %+v", ag.Errors)
|
||||
|
@ -74,7 +74,7 @@ func (vc WAVersionContainer) ProtoAppVersion() *waProto.AppVersion {
|
||||
}
|
||||
|
||||
// waVersion is the WhatsApp web client version
|
||||
var waVersion = WAVersionContainer{2, 2218, 8}
|
||||
var waVersion = WAVersionContainer{2, 2222, 11}
|
||||
|
||||
// waVersionHash is the md5 hash of a dot-separated waVersion
|
||||
var waVersionHash [16]byte
|
||||
@ -125,14 +125,14 @@ var BaseClientPayload = &waProto.ClientPayload{
|
||||
// Deprecated: renamed to DeviceProps
|
||||
var CompanionProps = DeviceProps
|
||||
|
||||
var DeviceProps = &waProto.CompanionProps{
|
||||
var DeviceProps = &waProto.DeviceProps{
|
||||
Os: proto.String("whatsmeow"),
|
||||
Version: &waProto.AppVersion{
|
||||
Primary: proto.Uint32(0),
|
||||
Secondary: proto.Uint32(1),
|
||||
Tertiary: proto.Uint32(0),
|
||||
},
|
||||
PlatformType: waProto.CompanionProps_UNKNOWN.Enum(),
|
||||
PlatformType: waProto.DeviceProps_UNKNOWN.Enum(),
|
||||
RequireFullSync: proto.Bool(false),
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,8 @@ const (
|
||||
adv_key, adv_details, adv_account_sig, adv_account_sig_key, adv_device_sig,
|
||||
platform, business_name, push_name)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
||||
ON CONFLICT (jid) DO UPDATE SET platform=$12, business_name=$13, push_name=$14
|
||||
ON CONFLICT (jid) DO UPDATE
|
||||
SET platform=excluded.platform, business_name=excluded.business_name, push_name=excluded.push_name
|
||||
`
|
||||
deleteDeviceQuery = `DELETE FROM whatsmeow_device WHERE jid=$1`
|
||||
)
|
||||
|
@ -67,7 +67,7 @@ var _ store.ContactStore = (*SQLStore)(nil)
|
||||
const (
|
||||
putIdentityQuery = `
|
||||
INSERT INTO whatsmeow_identity_keys (our_jid, their_id, identity) VALUES ($1, $2, $3)
|
||||
ON CONFLICT (our_jid, their_id) DO UPDATE SET identity=$3
|
||||
ON CONFLICT (our_jid, their_id) DO UPDATE SET identity=excluded.identity
|
||||
`
|
||||
deleteAllIdentitiesQuery = `DELETE FROM whatsmeow_identity_keys WHERE our_jid=$1 AND their_id LIKE $2`
|
||||
deleteIdentityQuery = `DELETE FROM whatsmeow_identity_keys WHERE our_jid=$1 AND their_id=$2`
|
||||
@ -108,7 +108,7 @@ const (
|
||||
hasSessionQuery = `SELECT true FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id=$2`
|
||||
putSessionQuery = `
|
||||
INSERT INTO whatsmeow_sessions (our_jid, their_id, session) VALUES ($1, $2, $3)
|
||||
ON CONFLICT (our_jid, their_id) DO UPDATE SET session=$3
|
||||
ON CONFLICT (our_jid, their_id) DO UPDATE SET session=excluded.session
|
||||
`
|
||||
deleteAllSessionsQuery = `DELETE FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id LIKE $2`
|
||||
deleteSessionQuery = `DELETE FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id=$2`
|
||||
@ -259,7 +259,7 @@ const (
|
||||
getSenderKeyQuery = `SELECT sender_key FROM whatsmeow_sender_keys WHERE our_jid=$1 AND chat_id=$2 AND sender_id=$3`
|
||||
putSenderKeyQuery = `
|
||||
INSERT INTO whatsmeow_sender_keys (our_jid, chat_id, sender_id, sender_key) VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (our_jid, chat_id, sender_id) DO UPDATE SET sender_key=$4
|
||||
ON CONFLICT (our_jid, chat_id, sender_id) DO UPDATE SET sender_key=excluded.sender_key
|
||||
`
|
||||
)
|
||||
|
||||
@ -279,7 +279,8 @@ func (s *SQLStore) GetSenderKey(group, user string) (key []byte, err error) {
|
||||
const (
|
||||
putAppStateSyncKeyQuery = `
|
||||
INSERT INTO whatsmeow_app_state_sync_keys (jid, key_id, key_data, timestamp, fingerprint) VALUES ($1, $2, $3, $4, $5)
|
||||
ON CONFLICT (jid, key_id) DO UPDATE SET key_data=$3, timestamp=$4, fingerprint=$5
|
||||
ON CONFLICT (jid, key_id) DO UPDATE
|
||||
SET key_data=excluded.key_data, timestamp=excluded.timestamp, fingerprint=excluded.fingerprint
|
||||
`
|
||||
getAppStateSyncKeyQuery = `SELECT key_data, timestamp, fingerprint FROM whatsmeow_app_state_sync_keys WHERE jid=$1 AND key_id=$2`
|
||||
)
|
||||
@ -301,7 +302,7 @@ func (s *SQLStore) GetAppStateSyncKey(id []byte) (*store.AppStateSyncKey, error)
|
||||
const (
|
||||
putAppStateVersionQuery = `
|
||||
INSERT INTO whatsmeow_app_state_version (jid, name, version, hash) VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (jid, name) DO UPDATE SET version=$3, hash=$4
|
||||
ON CONFLICT (jid, name) DO UPDATE SET version=excluded.version, hash=excluded.hash
|
||||
`
|
||||
getAppStateVersionQuery = `SELECT version, hash FROM whatsmeow_app_state_version WHERE jid=$1 AND name=$2`
|
||||
deleteAppStateVersionQuery = `DELETE FROM whatsmeow_app_state_version WHERE jid=$1 AND name=$2`
|
||||
@ -435,11 +436,11 @@ const (
|
||||
`
|
||||
putPushNameQuery = `
|
||||
INSERT INTO whatsmeow_contacts (our_jid, their_jid, push_name) VALUES ($1, $2, $3)
|
||||
ON CONFLICT (our_jid, their_jid) DO UPDATE SET push_name=$3
|
||||
ON CONFLICT (our_jid, their_jid) DO UPDATE SET push_name=excluded.push_name
|
||||
`
|
||||
putBusinessNameQuery = `
|
||||
INSERT INTO whatsmeow_contacts (our_jid, their_jid, business_name) VALUES ($1, $2, $3)
|
||||
ON CONFLICT (our_jid, their_jid) DO UPDATE SET business_name=$3
|
||||
ON CONFLICT (our_jid, their_jid) DO UPDATE SET business_name=excluded.business_name
|
||||
`
|
||||
getContactQuery = `
|
||||
SELECT first_name, full_name, push_name, business_name FROM whatsmeow_contacts WHERE our_jid=$1 AND their_jid=$2
|
||||
@ -470,23 +471,25 @@ func (s *SQLStore) PutPushName(user types.JID, pushName string) (bool, string, e
|
||||
return false, "", nil
|
||||
}
|
||||
|
||||
func (s *SQLStore) PutBusinessName(user types.JID, businessName string) error {
|
||||
func (s *SQLStore) PutBusinessName(user types.JID, businessName string) (bool, string, error) {
|
||||
s.contactCacheLock.Lock()
|
||||
defer s.contactCacheLock.Unlock()
|
||||
|
||||
cached, err := s.getContact(user)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, "", err
|
||||
}
|
||||
if cached.BusinessName != businessName {
|
||||
_, err = s.db.Exec(putBusinessNameQuery, s.JID, user, businessName)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, "", err
|
||||
}
|
||||
previousName := cached.BusinessName
|
||||
cached.BusinessName = businessName
|
||||
cached.Found = true
|
||||
return true, previousName, nil
|
||||
}
|
||||
return nil
|
||||
return false, "", nil
|
||||
}
|
||||
|
||||
func (s *SQLStore) PutContactName(user types.JID, firstName, fullName string) error {
|
||||
@ -643,7 +646,7 @@ func (s *SQLStore) GetAllContacts() (map[types.JID]types.ContactInfo, error) {
|
||||
const (
|
||||
putChatSettingQuery = `
|
||||
INSERT INTO whatsmeow_chat_settings (our_jid, chat_jid, %[1]s) VALUES ($1, $2, $3)
|
||||
ON CONFLICT (our_jid, chat_jid) DO UPDATE SET %[1]s=$3
|
||||
ON CONFLICT (our_jid, chat_jid) DO UPDATE SET %[1]s=excluded.%[1]s
|
||||
`
|
||||
getChatSettingsQuery = `
|
||||
SELECT muted_until, pinned, archived FROM whatsmeow_chat_settings WHERE our_jid=$1 AND chat_jid=$2
|
||||
|
@ -239,7 +239,7 @@ func upgradeV2(tx *sql.Tx, container *Container) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if container.dialect == "postgres" {
|
||||
if container.dialect == "postgres" || container.dialect == "pgx" {
|
||||
_, err = tx.Exec(fillSigKeyPostgres)
|
||||
} else {
|
||||
_, err = tx.Exec(fillSigKeySQLite)
|
||||
|
2
vendor/go.mau.fi/whatsmeow/store/store.go
vendored
2
vendor/go.mau.fi/whatsmeow/store/store.go
vendored
@ -80,7 +80,7 @@ type ContactEntry struct {
|
||||
|
||||
type ContactStore interface {
|
||||
PutPushName(user types.JID, pushName string) (bool, string, error)
|
||||
PutBusinessName(user types.JID, businessName string) error
|
||||
PutBusinessName(user types.JID, businessName string) (bool, string, error)
|
||||
PutContactName(user types.JID, fullName, firstName string) error
|
||||
PutAllContactNames(contacts []ContactEntry) error
|
||||
GetContact(user types.JID) (types.ContactInfo, error)
|
||||
|
@ -30,6 +30,14 @@ type PushName struct {
|
||||
NewPushName string // The new push name that was included in the message.
|
||||
}
|
||||
|
||||
// BusinessName is emitted when a message is received with a different verified business name than the previous value cached for the same user.
|
||||
type BusinessName struct {
|
||||
JID types.JID
|
||||
Message *types.MessageInfo // This is only present if the change was detected in a message.
|
||||
OldBusinessName string
|
||||
NewBusinessName string
|
||||
}
|
||||
|
||||
// Pin is emitted when a chat is pinned or unpinned from another device.
|
||||
type Pin struct {
|
||||
JID types.JID // The chat which was pinned or unpinned.
|
||||
|
1
vendor/go.mau.fi/whatsmeow/types/message.go
vendored
1
vendor/go.mau.fi/whatsmeow/types/message.go
vendored
@ -47,6 +47,7 @@ type MessageInfo struct {
|
||||
Multicast bool
|
||||
MediaType string
|
||||
|
||||
VerifiedName *VerifiedName
|
||||
DeviceSentMeta *DeviceSentMeta // Metadata for direct messages sent from another one of the user's own devices.
|
||||
}
|
||||
|
||||
|
18
vendor/go.mau.fi/whatsmeow/user.go
vendored
18
vendor/go.mau.fi/whatsmeow/user.go
vendored
@ -133,7 +133,7 @@ func (cli *Client) GetUserInfo(jids []types.JID) (map[types.JID]types.UserInfo,
|
||||
info.PictureID, _ = child.GetChildByTag("picture").Attrs["id"].(string)
|
||||
info.Devices = parseDeviceList(jid.User, child.GetChildByTag("devices"))
|
||||
if verifiedName != nil {
|
||||
cli.updateBusinessName(jid, verifiedName.Details.GetVerifiedName())
|
||||
cli.updateBusinessName(jid, nil, verifiedName.Details.GetVerifiedName())
|
||||
}
|
||||
respData[jid] = info
|
||||
}
|
||||
@ -262,13 +262,21 @@ func (cli *Client) updatePushName(user types.JID, messageInfo *types.MessageInfo
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *Client) updateBusinessName(user types.JID, name string) {
|
||||
func (cli *Client) updateBusinessName(user types.JID, messageInfo *types.MessageInfo, name string) {
|
||||
if cli.Store.Contacts == nil {
|
||||
return
|
||||
}
|
||||
err := cli.Store.Contacts.PutBusinessName(user, name)
|
||||
changed, previousName, err := cli.Store.Contacts.PutBusinessName(user, name)
|
||||
if err != nil {
|
||||
cli.Log.Errorf("Failed to save business name of %s in device store: %v", user, err)
|
||||
} else if changed {
|
||||
cli.Log.Debugf("Business name of %s changed from %s to %s, dispatching event", user, previousName, name)
|
||||
cli.dispatchEvent(&events.BusinessName{
|
||||
JID: user,
|
||||
Message: messageInfo,
|
||||
OldBusinessName: previousName,
|
||||
NewBusinessName: name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,6 +288,10 @@ func parseVerifiedName(businessNode waBinary.Node) (*types.VerifiedName, error)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return parseVerifiedNameContent(verifiedNameNode)
|
||||
}
|
||||
|
||||
func parseVerifiedNameContent(verifiedNameNode waBinary.Node) (*types.VerifiedName, error) {
|
||||
rawCert, ok := verifiedNameNode.Content.([]byte)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
|
11
vendor/gopkg.in/yaml.v3/parserc.go
generated
vendored
11
vendor/gopkg.in/yaml.v3/parserc.go
generated
vendored
@ -687,6 +687,9 @@ func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, i
|
||||
func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
|
||||
if first {
|
||||
token := peek_token(parser)
|
||||
if token == nil {
|
||||
return false
|
||||
}
|
||||
parser.marks = append(parser.marks, token.start_mark)
|
||||
skip_token(parser)
|
||||
}
|
||||
@ -786,7 +789,7 @@ func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
|
||||
}
|
||||
|
||||
token := peek_token(parser)
|
||||
if token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {
|
||||
if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {
|
||||
return
|
||||
}
|
||||
|
||||
@ -813,6 +816,9 @@ func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
|
||||
func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
|
||||
if first {
|
||||
token := peek_token(parser)
|
||||
if token == nil {
|
||||
return false
|
||||
}
|
||||
parser.marks = append(parser.marks, token.start_mark)
|
||||
skip_token(parser)
|
||||
}
|
||||
@ -922,6 +928,9 @@ func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_ev
|
||||
func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
|
||||
if first {
|
||||
token := peek_token(parser)
|
||||
if token == nil {
|
||||
return false
|
||||
}
|
||||
parser.marks = append(parser.marks, token.start_mark)
|
||||
skip_token(parser)
|
||||
}
|
||||
|
26
vendor/modules.txt
vendored
26
vendor/modules.txt
vendored
@ -38,7 +38,7 @@ github.com/Rhymen/go-whatsapp/binary/token
|
||||
github.com/Rhymen/go-whatsapp/crypto/cbc
|
||||
github.com/Rhymen/go-whatsapp/crypto/curve25519
|
||||
github.com/Rhymen/go-whatsapp/crypto/hkdf
|
||||
# github.com/SevereCloud/vksdk/v2 v2.14.0
|
||||
# github.com/SevereCloud/vksdk/v2 v2.14.1
|
||||
## explicit; go 1.16
|
||||
github.com/SevereCloud/vksdk/v2
|
||||
github.com/SevereCloud/vksdk/v2/api
|
||||
@ -58,7 +58,7 @@ github.com/blang/semver
|
||||
# github.com/bwmarrin/discordgo v0.25.0
|
||||
## explicit; go 1.13
|
||||
github.com/bwmarrin/discordgo
|
||||
# github.com/d5/tengo/v2 v2.10.1
|
||||
# github.com/d5/tengo/v2 v2.12.0
|
||||
## explicit; go 1.13
|
||||
github.com/d5/tengo/v2
|
||||
github.com/d5/tengo/v2/parser
|
||||
@ -93,7 +93,7 @@ github.com/golang-jwt/jwt
|
||||
## explicit; go 1.9
|
||||
github.com/golang/protobuf/proto
|
||||
github.com/golang/protobuf/protoc-gen-go/descriptor
|
||||
# github.com/gomarkdown/markdown v0.0.0-20220603122033-8f3b341fef32
|
||||
# github.com/gomarkdown/markdown v0.0.0-20220607163217-45f7c050e2d1
|
||||
## explicit; go 1.12
|
||||
github.com/gomarkdown/markdown
|
||||
github.com/gomarkdown/markdown/ast
|
||||
@ -183,11 +183,12 @@ github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1
|
||||
github.com/keybase/go-keybase-chat-bot/kbchat/types/gregor1
|
||||
github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1
|
||||
github.com/keybase/go-keybase-chat-bot/kbchat/types/stellar1
|
||||
# github.com/klauspost/compress v1.15.1
|
||||
## explicit; go 1.15
|
||||
# github.com/klauspost/compress v1.15.6
|
||||
## explicit; go 1.16
|
||||
github.com/klauspost/compress
|
||||
github.com/klauspost/compress/fse
|
||||
github.com/klauspost/compress/huff0
|
||||
github.com/klauspost/compress/internal/cpuinfo
|
||||
github.com/klauspost/compress/internal/snapref
|
||||
github.com/klauspost/compress/s2
|
||||
github.com/klauspost/compress/zstd
|
||||
@ -403,12 +404,11 @@ github.com/sizeofint/webpanimation
|
||||
github.com/skip2/go-qrcode
|
||||
github.com/skip2/go-qrcode/bitset
|
||||
github.com/skip2/go-qrcode/reedsolomon
|
||||
# github.com/slack-go/slack v0.10.3
|
||||
# github.com/slack-go/slack v0.11.0
|
||||
## explicit; go 1.16
|
||||
github.com/slack-go/slack
|
||||
github.com/slack-go/slack/internal/backoff
|
||||
github.com/slack-go/slack/internal/errorsx
|
||||
github.com/slack-go/slack/internal/misc
|
||||
github.com/slack-go/slack/internal/timex
|
||||
github.com/slack-go/slack/slackutilsx
|
||||
# github.com/spf13/afero v1.8.2
|
||||
@ -435,7 +435,7 @@ github.com/spf13/viper/internal/encoding/javaproperties
|
||||
github.com/spf13/viper/internal/encoding/json
|
||||
github.com/spf13/viper/internal/encoding/toml
|
||||
github.com/spf13/viper/internal/encoding/yaml
|
||||
# github.com/stretchr/testify v1.7.1
|
||||
# github.com/stretchr/testify v1.7.2
|
||||
## explicit; go 1.13
|
||||
github.com/stretchr/testify/assert
|
||||
github.com/stretchr/testify/require
|
||||
@ -514,7 +514,7 @@ go.mau.fi/libsignal/util/errorhelper
|
||||
go.mau.fi/libsignal/util/keyhelper
|
||||
go.mau.fi/libsignal/util/medium
|
||||
go.mau.fi/libsignal/util/optional
|
||||
# go.mau.fi/whatsmeow v0.0.0-20220601182603-a8d86cf1812c
|
||||
# go.mau.fi/whatsmeow v0.0.0-20220624184947-57a69a641154
|
||||
## explicit; go 1.17
|
||||
go.mau.fi/whatsmeow
|
||||
go.mau.fi/whatsmeow/appstate
|
||||
@ -567,7 +567,7 @@ golang.org/x/crypto/scrypt
|
||||
golang.org/x/crypto/ssh
|
||||
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
|
||||
golang.org/x/crypto/ssh/terminal
|
||||
# golang.org/x/image v0.0.0-20220601225756-64ec528b34cd
|
||||
# golang.org/x/image v0.0.0-20220617043117-41969df76e82
|
||||
## explicit; go 1.12
|
||||
golang.org/x/image/riff
|
||||
golang.org/x/image/vp8
|
||||
@ -589,8 +589,8 @@ golang.org/x/net/http2/hpack
|
||||
golang.org/x/net/idna
|
||||
golang.org/x/net/publicsuffix
|
||||
golang.org/x/net/websocket
|
||||
# golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401
|
||||
## explicit; go 1.11
|
||||
# golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
|
||||
## explicit; go 1.15
|
||||
golang.org/x/oauth2
|
||||
golang.org/x/oauth2/clientcredentials
|
||||
golang.org/x/oauth2/internal
|
||||
@ -705,7 +705,7 @@ gopkg.in/olahol/melody.v1
|
||||
# gopkg.in/yaml.v2 v2.4.0
|
||||
## explicit; go 1.15
|
||||
gopkg.in/yaml.v2
|
||||
# gopkg.in/yaml.v3 v3.0.0
|
||||
# gopkg.in/yaml.v3 v3.0.1
|
||||
## explicit
|
||||
gopkg.in/yaml.v3
|
||||
# layeh.com/gumble v0.0.0-20200818122324-146f9205029b
|
||||
|
Loading…
Reference in New Issue
Block a user