[Vendor] Update directly used dependencys (#15593)
* update github.com/blevesearch/bleve v2.0.2 -> v2.0.3 * github.com/denisenkom/go-mssqldb v0.9.0 -> v0.10.0 * github.com/editorconfig/editorconfig-core-go v2.4.1 -> v2.4.2 * github.com/go-chi/cors v1.1.1 -> v1.2.0 * github.com/go-git/go-billy v5.0.0 -> v5.1.0 * github.com/go-git/go-git v5.2.0 -> v5.3.0 * github.com/go-ldap/ldap v3.2.4 -> v3.3.0 * github.com/go-redis/redis v8.6.0 -> v8.8.2 * github.com/go-sql-driver/mysql v1.5.0 -> v1.6.0 * github.com/go-swagger/go-swagger v0.26.1 -> v0.27.0 * github.com/lib/pq v1.9.0 -> v1.10.1 * github.com/mattn/go-sqlite3 v1.14.6 -> v1.14.7 * github.com/go-testfixtures/testfixtures v3.5.0 -> v3.6.0 * github.com/issue9/identicon v1.0.1 -> v1.2.0 * github.com/klauspost/compress v1.11.8 -> v1.12.1 * github.com/mgechev/revive v1.0.3 -> v1.0.6 * github.com/microcosm-cc/bluemonday v1.0.7 -> v1.0.8 * github.com/niklasfasching/go-org v1.4.0 -> v1.5.0 * github.com/olivere/elastic v7.0.22 -> v7.0.24 * github.com/pelletier/go-toml v1.8.1 -> v1.9.0 * github.com/prometheus/client_golang v1.9.0 -> v1.10.0 * github.com/xanzy/go-gitlab v0.44.0 -> v0.48.0 * github.com/yuin/goldmark v1.3.3 -> v1.3.5 * github.com/6543/go-version v1.2.4 -> v1.3.1 * do github.com/lib/pq v1.10.0 -> v1.10.1 again ...release/v1.15
parent
834fc74873
commit
792b4dba2c
81
go.mod
81
go.mod
|
@ -11,81 +11,74 @@ require (
|
|||
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e
|
||||
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee
|
||||
gitea.com/lunny/levelqueue v0.3.0
|
||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.18 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/PuerkitoBio/goquery v1.5.1
|
||||
github.com/RoaringBitmap/roaring v0.5.5 // indirect
|
||||
github.com/RoaringBitmap/roaring v0.6.0 // indirect
|
||||
github.com/alecthomas/chroma v0.8.2
|
||||
github.com/andybalholm/brotli v1.0.1 // indirect
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
|
||||
github.com/blevesearch/bleve/v2 v2.0.2
|
||||
github.com/blevesearch/bleve/v2 v2.0.3
|
||||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
|
||||
github.com/caddyserver/certmagic v0.13.0
|
||||
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af // indirect
|
||||
github.com/chi-middleware/proxy v1.1.1
|
||||
github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 // indirect
|
||||
github.com/couchbase/gomemcached v0.1.2 // indirect
|
||||
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.9.0
|
||||
github.com/denisenkom/go-mssqldb v0.10.0
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2
|
||||
github.com/emirpasic/gods v1.12.0
|
||||
github.com/ethantkoenig/rupture v1.0.0
|
||||
github.com/gliderlabs/ssh v0.3.2
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect
|
||||
github.com/go-chi/chi v1.5.4
|
||||
github.com/go-chi/cors v1.1.1
|
||||
github.com/go-chi/cors v1.2.0
|
||||
github.com/go-enry/go-enry/v2 v2.6.1
|
||||
github.com/go-git/go-billy/v5 v5.0.0
|
||||
github.com/go-git/go-git/v5 v5.2.0
|
||||
github.com/go-ldap/ldap/v3 v3.2.4
|
||||
github.com/go-openapi/errors v0.20.0 // indirect
|
||||
github.com/go-openapi/validate v0.20.2 // indirect
|
||||
github.com/go-redis/redis/v8 v8.6.0
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/go-swagger/go-swagger v0.26.1
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.5.0
|
||||
github.com/go-git/go-billy/v5 v5.1.0
|
||||
github.com/go-git/go-git/v5 v5.3.0
|
||||
github.com/go-ldap/ldap/v3 v3.3.0
|
||||
github.com/go-redis/redis/v8 v8.8.2
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/go-swagger/go-swagger v0.27.0
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.6.0
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
|
||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||
github.com/golang/snappy v0.0.3 // indirect
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/gorilla/context v1.1.1
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gorilla/sessions v1.2.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8 // indirect
|
||||
github.com/hashicorp/go-version v1.2.1
|
||||
github.com/hashicorp/go-version v1.3.1
|
||||
github.com/huandu/xstrings v1.3.2
|
||||
github.com/imdario/mergo v0.3.11 // indirect
|
||||
github.com/issue9/assert v1.3.2 // indirect
|
||||
github.com/issue9/identicon v1.0.1
|
||||
github.com/issue9/identicon v1.2.0
|
||||
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/kevinburke/ssh_config v1.1.0 // indirect
|
||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
||||
github.com/klauspost/compress v1.11.8
|
||||
github.com/klauspost/compress v1.12.1
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/lafriks/xormstore v1.4.0
|
||||
github.com/lib/pq v1.9.0
|
||||
github.com/lib/pq v1.10.1
|
||||
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/markbates/goth v1.67.1
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/mattn/go-runewidth v0.0.12 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.7
|
||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81
|
||||
github.com/mgechev/revive v1.0.3
|
||||
github.com/mgechev/revive v1.0.6
|
||||
github.com/mholt/archiver/v3 v3.5.0
|
||||
github.com/microcosm-cc/bluemonday v1.0.7
|
||||
github.com/miekg/dns v1.1.41 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.8
|
||||
github.com/miekg/dns v1.1.40 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.10
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
|
@ -93,28 +86,23 @@ require (
|
|||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
|
||||
github.com/msteinert/pam v0.0.0-20201130170657-e61372126161
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/niklasfasching/go-org v1.4.0
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/niklasfasching/go-org v1.5.0
|
||||
github.com/oliamb/cutter v0.2.2
|
||||
github.com/olivere/elastic/v7 v7.0.22
|
||||
github.com/pelletier/go-toml v1.8.1
|
||||
github.com/olivere/elastic/v7 v7.0.24
|
||||
github.com/pelletier/go-toml v1.9.0
|
||||
github.com/pierrec/lz4/v4 v4.1.3 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pquerna/otp v1.3.0
|
||||
github.com/prometheus/client_golang v1.9.0
|
||||
github.com/prometheus/common v0.18.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/prometheus/client_golang v1.10.0
|
||||
github.com/quasoft/websspi v1.0.0
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0
|
||||
github.com/sergi/go-diff v1.2.0
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||
github.com/spf13/afero v1.5.1 // indirect
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tinylib/msgp v1.1.5 // indirect
|
||||
github.com/tstranex/u2f v1.0.0
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/unknwon/com v1.0.1
|
||||
|
@ -123,10 +111,9 @@ require (
|
|||
github.com/unrolled/render v1.1.0
|
||||
github.com/urfave/cli v1.22.5
|
||||
github.com/willf/bitset v1.1.11 // indirect
|
||||
github.com/xanzy/go-gitlab v0.44.0
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
github.com/xanzy/go-gitlab v0.48.0
|
||||
github.com/yohcop/openid-go v1.0.0
|
||||
github.com/yuin/goldmark v1.3.3
|
||||
github.com/yuin/goldmark v1.3.5
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
|
||||
github.com/yuin/goldmark-meta v1.0.0
|
||||
go.jolheiser.com/hcaptcha v0.0.4
|
||||
|
@ -135,7 +122,7 @@ require (
|
|||
go.uber.org/zap v1.16.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93
|
||||
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78
|
||||
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08
|
||||
golang.org/x/text v0.3.6
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
|
@ -150,4 +137,4 @@ require (
|
|||
xorm.io/xorm v1.0.7
|
||||
)
|
||||
|
||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.2.4
|
||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
|
||||
|
|
248
go.sum
248
go.sum
|
@ -53,8 +53,8 @@ gitea.com/lunny/levelqueue v0.3.0 h1:MHn1GuSZkxvVEDMyAPqlc7A3cOW+q8RcGhRgH/xtm6I
|
|||
gitea.com/lunny/levelqueue v0.3.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/6543/go-version v1.2.4 h1:MPsSnqNrM0HwA9tnmWNnsMdQMg4/u4fflARjwomoof4=
|
||||
github.com/6543/go-version v1.2.4/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
|
||||
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
|
||||
github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
|
@ -64,8 +64,9 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo
|
|||
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.4.18 h1:yjwCO1nhWEShaA5qsmPOBzAOjRCa2PRLsDNZ5yBWXpg=
|
||||
github.com/Microsoft/go-winio v0.4.18/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
|
@ -77,8 +78,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
|
|||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RoaringBitmap/roaring v0.5.5 h1:naNqvO1mNnghk2UvcsqnzHDBn9DRbCIRy94GmDTRVTQ=
|
||||
github.com/RoaringBitmap/roaring v0.5.5/go.mod h1:puNo5VdzwbaIQxSiDIwfXl4Hnc+fbovcX4IW/dSTtUk=
|
||||
github.com/RoaringBitmap/roaring v0.6.0 h1:tZcn2nJpUrZf+xQY8x+9QY7BxSETMjkdNG4Ts5zahyU=
|
||||
github.com/RoaringBitmap/roaring v0.6.0/go.mod h1:WZ83fjBF/7uBHi6QoFyfGL4+xuV4Qn+xFkm4+vSzrhE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
|
@ -127,12 +128,13 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l
|
|||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/aws/aws-sdk-go v1.35.20/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-sdk-go v1.38.3/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
|
@ -144,8 +146,8 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
|
|||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/blevesearch/bleve/v2 v2.0.1/go.mod h1:OBP2Pktqik8vEiUlGhuWjYx7KiO4zD542+DHqICwM5w=
|
||||
github.com/blevesearch/bleve/v2 v2.0.2 h1:D93VfhOiR6wALovgjsK5XNPeDRrZQlUEIq4YWFeaiTw=
|
||||
github.com/blevesearch/bleve/v2 v2.0.2/go.mod h1:ip+4iafiEq2gCY5rJXe87bT6LkF/OJMCjQEYIfTBfW8=
|
||||
github.com/blevesearch/bleve/v2 v2.0.3 h1:mDrwrsRIA4PDYkfUNjoh5zGECvquuJIA3MJU5ivaO8E=
|
||||
github.com/blevesearch/bleve/v2 v2.0.3/go.mod h1:ip+4iafiEq2gCY5rJXe87bT6LkF/OJMCjQEYIfTBfW8=
|
||||
github.com/blevesearch/bleve_index_api v1.0.0 h1:Ds3XeuTxjXCkG6pgIwWDRyooJKNIuOKemnN0N0IkhTU=
|
||||
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||
|
@ -194,6 +196,9 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
|||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chavacava/garif v0.0.0-20210405163807-87a70f3d418b/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
|
||||
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af h1:spmv8nSH9h5oCQf40jt/ufBCt9j0/58u4G+rkeMqXGI=
|
||||
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
|
||||
github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ=
|
||||
github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
|
@ -248,8 +253,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8=
|
||||
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
|
@ -270,8 +275,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
|
|||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1 h1:ELDiPZji50x20Wvf9FnP4pb7fE3PV/DNhNd6MRlhgfI=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1/go.mod h1:UHV4+gECABtht7ALQkPdc5gzP77D+4WDUOZAfx8ifx8=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2 h1:1lkDpSoAaFLrgYTVJ/eNCV+lkDSv/j9Wm0jcvDfVVEo=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2/go.mod h1:IXeWRVO4LZRoNunhHh/oP6BQvTs94nB2pNvbw32l8tQ=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||
|
@ -308,9 +313,6 @@ github.com/gliderlabs/ssh v0.3.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
|
|||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96 h1:rCXyLrgJ598XNj7KTqPzAvwTzlyvI+clqasoNfLQStE=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.3 h1:u7utq56RUFiynqUzgVMFDymapcOtQ/MZkh3H4QYkxag=
|
||||
|
@ -320,28 +322,29 @@ github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs=
|
|||
github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg=
|
||||
github.com/go-chi/chi/v5 v5.0.1 h1:ALxjCrTf1aflOlkhMnCUP86MubbWFrzB3gkRPReLpTo=
|
||||
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.1.1 h1:eHuqxsIw89iXcWnWUN8R72JMibABJTN/4IOYI5WERvw=
|
||||
github.com/go-chi/cors v1.1.1/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I=
|
||||
github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
|
||||
github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-enry/go-enry/v2 v2.6.1 h1:ckFkMVj2NeHpaQDFDiSjanVjNy2IiuMNivhXDB4c5Q0=
|
||||
github.com/go-enry/go-enry/v2 v2.6.1/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
||||
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
||||
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.1.0 h1:4pl5BV4o7ZG/lterP4S6WzJ6xr49Ba5ET9ygheTYahk=
|
||||
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||
github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI=
|
||||
github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs=
|
||||
github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
|
||||
github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-ldap/ldap/v3 v3.2.4 h1:PFavAq2xTgzo/loE8qNXcQaofAaqIpI4WgaLdv+1l3E=
|
||||
github.com/go-ldap/ldap/v3 v3.2.4/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||
github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ=
|
||||
github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
|
@ -388,7 +391,6 @@ github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2e
|
|||
github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
|
||||
github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
|
||||
github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4=
|
||||
github.com/go-openapi/loads v0.20.1/go.mod h1:/6LfFL8fDvTSX8ypmYXIq3U9Q7nfniSOStW22m864WM=
|
||||
github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc=
|
||||
github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o=
|
||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||
|
@ -397,8 +399,8 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g
|
|||
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
|
||||
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
|
||||
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
|
||||
github.com/go-openapi/runtime v0.19.26 h1:K/6PoVNj5WJXUnMk+VEbELeXjtBkCS1UxTDa04tdXE0=
|
||||
github.com/go-openapi/runtime v0.19.26/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
|
||||
github.com/go-openapi/runtime v0.19.27 h1:4zrQCJoP7rqNCUaApDv1MdPkaa5TuPfO05Lq5WLhX9I=
|
||||
github.com/go-openapi/runtime v0.19.27/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
|
||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||
|
@ -408,7 +410,6 @@ github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHK
|
|||
github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
|
||||
github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
|
||||
github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ=
|
||||
github.com/go-openapi/spec v0.20.2/go.mod h1:RW6Xcbs6LOyWLU/mXGdzn2Qc+3aj+ASfI7rvSZh1Vls=
|
||||
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
|
||||
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
|
||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
|
@ -419,8 +420,9 @@ github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6
|
|||
github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
|
||||
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
|
||||
github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
|
||||
github.com/go-openapi/strfmt v0.20.0 h1:l2omNtmNbMc39IGptl9BuXBEKcZfS8zjrTsPKTiJiDM=
|
||||
github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
|
||||
github.com/go-openapi/strfmt v0.20.1 h1:1VgxvehFne1mbChGeCmZ5pc0LxUf6yaACVSIYAR91Xc=
|
||||
github.com/go-openapi/strfmt v0.20.1/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
|
@ -429,8 +431,9 @@ github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfT
|
|||
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
|
||||
github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
|
||||
github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
|
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
|
||||
|
@ -443,20 +446,21 @@ github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZ
|
|||
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M=
|
||||
github.com/go-redis/redis/v8 v8.6.0 h1:swqbqOrxaPztsj2Hf1p94M3YAgl7hYEpcw21z299hh8=
|
||||
github.com/go-redis/redis/v8 v8.6.0/go.mod h1:DQ9q4Rk2HtwkrwVrdgmphoOQDMfpvcd/nHEwRsicg8s=
|
||||
github.com/go-redis/redis/v8 v8.8.2 h1:O/NcHqobw7SEptA0yA6up6spZVFtwE06SXM8rgLtsP8=
|
||||
github.com/go-redis/redis/v8 v8.8.2/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-swagger/go-swagger v0.26.1 h1:1XUWLnH6hKxHzeKjJfA2gHkSqcT1Zgi4q/PZp2hDdN8=
|
||||
github.com/go-swagger/go-swagger v0.26.1/go.mod h1:zlf/LHplZpdtU2mYXg9Ajd3+9TgHYltv5f/pEM6LjnI=
|
||||
github.com/go-swagger/go-swagger v0.27.0 h1:K7+nkBuf4oS1jTBrdvWqYFpqD69V5CN8HamZzCDDhAI=
|
||||
github.com/go-swagger/go-swagger v0.27.0/go.mod h1:WodZVysInJilkW7e6IRw+dZGp5yW6rlMFZ4cb+THl9A=
|
||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
|
||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.5.0 h1:fFJGHhFdcwy48oTLHvr0WRQ09rGiZE+as9ElvbRWS+c=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.5.0/go.mod h1:P4L3WxgOsCLbAeUC50qX5rdj1ULZfUMqgCbqah3OH5U=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.6.0 h1:fHrJWcZ0TOHA0UcExV0Nwx+5MR9QXVDWYdVfwe4DfmM=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.6.0/go.mod h1:YUBpgqvleDRhkx4MQbzdA7A3G5ca2wLtf9bHbDqNaRQ=
|
||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
||||
|
@ -523,8 +527,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
|
@ -541,12 +547,14 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
|
@ -614,7 +622,6 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj
|
|||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
|
@ -637,16 +644,14 @@ github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq
|
|||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
||||
github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=
|
||||
github.com/issue9/assert v1.3.2/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
||||
github.com/issue9/identicon v1.0.1 h1:pCDfjMDM6xWK0Chxo8Lif+ST/nOEtmXgMITgV1YA9Og=
|
||||
github.com/issue9/identicon v1.0.1/go.mod h1:UKNVkUFI68RPz/RlLhsAr1aX6bBSaYEWRHVfdjrMUmk=
|
||||
github.com/issue9/assert v1.4.1 h1:gUtOpMTeaE4JTe9kACma5foOHBvVt1p5XTFrULDwdXI=
|
||||
github.com/issue9/assert v1.4.1/go.mod h1:Yktk83hAVl1SPSYtd9kjhBizuiBIqUQyj+D5SE2yjVY=
|
||||
github.com/issue9/identicon v1.2.0 h1:ek+UcTTyMW/G0iNbLOAlrPC13eSzXTWhbJSs8PHhHGQ=
|
||||
github.com/issue9/identicon v1.2.0/go.mod h1:A9toNT0ky/1WP5iNFyDmrkNiYH6eX3HcN5V6uH0g0ec=
|
||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
|
@ -693,8 +698,9 @@ github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7 h1:g0fAGBisHaE
|
|||
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
|
@ -720,9 +726,9 @@ github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaR
|
|||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+mdNo/o=
|
||||
github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+4tLukHoB9iqHOu3LmLhRmgUxZo6Vp4=
|
||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
|
@ -731,8 +737,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
|||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.8 h1:difgzQsp5mdAz9v8lm3P/I+EpDKMU/6uTMw1y1FObuo=
|
||||
github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.12.1 h1:/+xsCsk06wE38cyiqOR/o7U2fSftcH72xD+BQXmja/g=
|
||||
github.com/klauspost/compress v1.12.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.5/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
||||
|
@ -765,10 +771,10 @@ github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/Y
|
|||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.1 h1:6VXZrLU0jHBYyAqrSPa+MgPfnSvTPuMgK+k0o5kVFWo=
|
||||
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/libdns/libdns v0.2.0 h1:ewg3ByWrdUrxrje8ChPVMBNcotg7H9LQYg+u5De2RzI=
|
||||
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
|
@ -780,8 +786,8 @@ github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VOb
|
|||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
|
||||
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
|
@ -810,30 +816,29 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y
|
|||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
|
||||
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM=
|
||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
||||
github.com/mgechev/revive v1.0.3 h1:z3FL6IFFN3JKzHYHD8O1ExH9g/4lAGJ5x1+9rPZgsFg=
|
||||
github.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE=
|
||||
github.com/mgechev/revive v1.0.6 h1:MgRQ3ys2uQCyVjelaDhVs8oSvOPYInzGA/nNGMa+MNU=
|
||||
github.com/mgechev/revive v1.0.6/go.mod h1:Lj5gIVxjBlH8REa3icEOkdfchwYc291nShzZ4QYWyMo=
|
||||
github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk=
|
||||
github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
|
||||
github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE=
|
||||
github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
|
||||
github.com/microcosm-cc/bluemonday v1.0.7 h1:6yAQfk4XT+PI/dk1ZeBp1gr3Q2Hd1DR0O3aEyPUJVTE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.7/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI=
|
||||
github.com/microcosm-cc/bluemonday v1.0.8 h1:JGc6zQRHqlp+UlLrsbUbbp0mOaJLV44vvQmBSU0Sfj0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.8/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.40 h1:pyyPFfGMnciYUk/mXpKkVmeMQjfXqt3FAJ2hy7tPiLA=
|
||||
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
|
@ -882,10 +887,9 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
|
|||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/niklasfasching/go-org v1.4.0 h1:qPy4VEdX55f5QcLiaD3X7N/tY5XOgk4y2uEyQa02i7A=
|
||||
github.com/niklasfasching/go-org v1.4.0/go.mod h1:4FWT4U/Anir9ewjwNpbZIzMjG5RaXFafkyWZNEPRdk8=
|
||||
github.com/niklasfasching/go-org v1.5.0 h1:V8IwoSPm/d61bceyWFxxnQLtlvNT+CjiYIhtZLdnMF0=
|
||||
github.com/niklasfasching/go-org v1.5.0/go.mod h1:sSb8ylwnAG+h8MGFDB3R1D5bxf8wA08REfhjShg3kjA=
|
||||
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
|
||||
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
||||
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||
|
@ -893,15 +897,15 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
|||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
|
||||
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
|
||||
github.com/olivere/elastic/v7 v7.0.22 h1:esBA6JJwvYgfms0EVlH7Z+9J4oQ/WUADF2y/nCNDw7s=
|
||||
github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8=
|
||||
github.com/olivere/elastic/v7 v7.0.24 h1:9ZcCQP3Pvgese7TaypYiVAL49sCEphyIwkVxtRf8jb8=
|
||||
github.com/olivere/elastic/v7 v7.0.24/go.mod h1:OuWmD2DiuYhddWegBKPWQuelVKBLrW0fa/VUYgxuGTY=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
@ -932,12 +936,11 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
|
|||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/pelletier/go-toml v1.9.0 h1:NOd0BRdOKpPf0SxkL3HxSQOG7rNh+4kl6PHcBPFs7Q0=
|
||||
github.com/pelletier/go-toml v1.9.0/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ=
|
||||
github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
|
@ -953,7 +956,7 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ
|
|||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
|
||||
github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs=
|
||||
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
|
@ -962,8 +965,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
|
|||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU=
|
||||
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
|
||||
github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg=
|
||||
github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
|
@ -977,7 +980,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
|||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y=
|
||||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
|
@ -986,7 +988,6 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
|
|||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
|
@ -1016,8 +1017,9 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
|
|||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
||||
|
@ -1034,6 +1036,7 @@ github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
|||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck=
|
||||
|
@ -1048,14 +1051,14 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
|
|||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg=
|
||||
github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
|
@ -1064,6 +1067,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
|||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
|
||||
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
|
||||
|
@ -1090,15 +1094,12 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP
|
|||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.5 h1:2gXmtWueD2HefZHQe1QOy9HVzmFrLOVvsXwXBQ0ayy0=
|
||||
github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
|
||||
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
|
||||
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
|
||||
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
|
||||
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
|
@ -1123,11 +1124,13 @@ github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv
|
|||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
|
||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||
github.com/xanzy/go-gitlab v0.44.0 h1:cEiGhqu7EpFGuei2a2etAwB+x6403E5CvpLn35y+GPs=
|
||||
github.com/xanzy/go-gitlab v0.44.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xanzy/go-gitlab v0.48.0 h1:RP9r4pMDIwE2fbtc+QYiC1euDsPGHcAjPkhje4X3QPU=
|
||||
github.com/xanzy/go-gitlab v0.48.0/go.mod h1:UW8JJbyBbqtOyBYNHRo261IRdHUFJr2m0y0z1xUiu+E=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||
|
@ -1136,13 +1139,14 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
|
|||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yohcop/openid-go v1.0.0 h1:EciJ7ZLETHR3wOtxBvKXx9RV6eyHZpCaSZ1inbBaUXE=
|
||||
github.com/yohcop/openid-go v1.0.0/go.mod h1:/408xiwkeItSPJZSTPF7+VtZxPkPrRRpRNK2vjGh6yI=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.3 h1:37BdQwPx8VOSic8eDSWee6QL9mRpZRm9VJp/QugNrW0=
|
||||
github.com/yuin/goldmark v1.3.3/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio=
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
|
||||
github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
|
||||
|
@ -1164,9 +1168,9 @@ go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS
|
|||
go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
|
||||
go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||
go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||
go.mongodb.org/mongo-driver v1.4.5/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||
go.mongodb.org/mongo-driver v1.4.6 h1:rh7GdYmDrb8AQSkF8yteAus8qYOgOASWDOv1BWqBXkU=
|
||||
go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||
go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI=
|
||||
go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
|
@ -1175,15 +1179,16 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
|
||||
go.opentelemetry.io/otel v0.17.0 h1:6MKOu8WY4hmfpQ4oQn34u6rYhnf2sWf1LXYO/UFm71U=
|
||||
go.opentelemetry.io/otel v0.17.0/go.mod h1:Oqtdxmf7UtEvL037ohlgnaYa1h7GtMh0NcSd9eqkC9s=
|
||||
go.opentelemetry.io/otel/metric v0.17.0 h1:t+5EioN8YFXQ2EH+1j6FHCKMUj+57zIDSnSGr/mWuug=
|
||||
go.opentelemetry.io/otel/metric v0.17.0/go.mod h1:hUz9lH1rNXyEwWAhIWCMFWKhYtpASgSnObJFnU26dJ0=
|
||||
go.opentelemetry.io/otel/oteltest v0.17.0 h1:TyAihUowTDLqb4+m5ePAsR71xPJaTBJl4KDArIdi9k4=
|
||||
go.opentelemetry.io/otel/oteltest v0.17.0/go.mod h1:JT/LGFxPwpN+nlsTiinSYjdIx3hZIGqHCpChcIZmdoE=
|
||||
go.opentelemetry.io/otel/trace v0.17.0 h1:SBOj64/GAOyWzs5F680yW1ITIfJkm6cJWL2YAvuL9xY=
|
||||
go.opentelemetry.io/otel/trace v0.17.0/go.mod h1:bIujpqg6ZL6xUTubIUgziI1jSaUPthmabA/ygf/6Cfg=
|
||||
go.opentelemetry.io/otel v0.19.0 h1:Lenfy7QHRXPZVsw/12CWpxX6d/JkrX8wrx2vO8G80Ng=
|
||||
go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
|
||||
go.opentelemetry.io/otel/metric v0.19.0 h1:dtZ1Ju44gkJkYvo+3qGqVXmf88tc+a42edOywypengg=
|
||||
go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
|
||||
go.opentelemetry.io/otel/oteltest v0.19.0 h1:YVfA0ByROYqTwOxqHVZYZExzEpfZor+MU1rU+ip2v9Q=
|
||||
go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
|
||||
go.opentelemetry.io/otel/trace v0.19.0 h1:1ucYlenXIDA1OlHVLDZKX0ObXV5RLaq06DtUKz5e5zc=
|
||||
go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
|
@ -1226,7 +1231,7 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -1262,8 +1267,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
|||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -1318,6 +1324,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/net v0.0.0-20210331060903-cb1fcc7394e5/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
|
@ -1331,8 +1339,9 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 h1:alLDrZkL34Y2bnGHfvC1CYBRBXCXgx8AC2vY4MRtYX4=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78 h1:rPRtHfUb0UKZeZ6GH4K4Nt4YRbE9V1u+QZX5upZXqJQ=
|
||||
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
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=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -1343,9 +1352,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -1358,7 +1366,6 @@ golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -1409,20 +1416,19 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 h1:qyN5bV+96OX8pL78eXDuz6YlDPzCYgdW74H5yE9BoSU=
|
||||
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -1502,9 +1508,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
|
@ -1617,16 +1621,19 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
@ -1651,7 +1658,6 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
* @microsoft/containerplat
|
|
@ -5,21 +5,14 @@ package winio
|
|||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx
|
||||
//sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle
|
||||
|
||||
const (
|
||||
fileBasicInfo = 0
|
||||
fileIDInfo = 0x12
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// FileBasicInfo contains file access time and file attributes information.
|
||||
type FileBasicInfo struct {
|
||||
CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
|
||||
CreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime
|
||||
FileAttributes uint32
|
||||
pad uint32 // padding
|
||||
}
|
||||
|
@ -27,7 +20,7 @@ type FileBasicInfo struct {
|
|||
// GetFileBasicInfo retrieves times and attributes for a file.
|
||||
func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
||||
bi := &FileBasicInfo{}
|
||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
||||
if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||
}
|
||||
runtime.KeepAlive(f)
|
||||
|
@ -36,13 +29,32 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
|||
|
||||
// SetFileBasicInfo sets times and attributes for a file.
|
||||
func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
|
||||
if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
||||
if err := windows.SetFileInformationByHandle(windows.Handle(f.Fd()), windows.FileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
||||
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
|
||||
}
|
||||
runtime.KeepAlive(f)
|
||||
return nil
|
||||
}
|
||||
|
||||
// FileStandardInfo contains extended information for the file.
|
||||
// FILE_STANDARD_INFO in WinBase.h
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info
|
||||
type FileStandardInfo struct {
|
||||
AllocationSize, EndOfFile int64
|
||||
NumberOfLinks uint32
|
||||
DeletePending, Directory bool
|
||||
}
|
||||
|
||||
// GetFileStandardInfo retrieves ended information for the file.
|
||||
func GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) {
|
||||
si := &FileStandardInfo{}
|
||||
if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileStandardInfo, (*byte)(unsafe.Pointer(si)), uint32(unsafe.Sizeof(*si))); err != nil {
|
||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||
}
|
||||
runtime.KeepAlive(f)
|
||||
return si, nil
|
||||
}
|
||||
|
||||
// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
|
||||
// unique on a system.
|
||||
type FileIDInfo struct {
|
||||
|
@ -53,7 +65,7 @@ type FileIDInfo struct {
|
|||
// GetFileID retrieves the unique (volume, file ID) pair for a file.
|
||||
func GetFileID(f *os.File) (*FileIDInfo, error) {
|
||||
fileID := &FileIDInfo{}
|
||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
|
||||
if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileIdInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
|
||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||
}
|
||||
runtime.KeepAlive(f)
|
||||
|
|
|
@ -4,6 +4,6 @@ go 1.12
|
|||
|
||||
require (
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.4.1
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||
)
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build windows
|
||||
|
||||
package winio
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build windows
|
||||
|
||||
// Package guid provides a GUID type. The backing structure for a GUID is
|
||||
// identical to that used by the golang.org/x/sys/windows GUID type.
|
||||
// There are two main binary encodings used for a GUID, the big-endian encoding,
|
||||
|
|
|
@ -30,6 +30,7 @@ const (
|
|||
|
||||
SeBackupPrivilege = "SeBackupPrivilege"
|
||||
SeRestorePrivilege = "SeRestorePrivilege"
|
||||
SeSecurityPrivilege = "SeSecurityPrivilege"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
package winio
|
||||
|
||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
|
||||
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
|
||||
|
|
|
@ -19,6 +19,7 @@ const (
|
|||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
errERROR_EINVAL error = syscall.EINVAL
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
|
@ -26,7 +27,7 @@ var (
|
|||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
return errERROR_EINVAL
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
|
@ -37,243 +38,62 @@ func errnoErr(e syscall.Errno) error {
|
|||
}
|
||||
|
||||
var (
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
|
||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
|
||||
|
||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
||||
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
||||
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
|
||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
||||
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
|
||||
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
|
||||
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
|
||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
||||
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
||||
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||
procbind = modws2_32.NewProc("bind")
|
||||
)
|
||||
|
||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
||||
newport = syscall.Handle(r0)
|
||||
if newport == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
||||
func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
||||
var _p0 uint32
|
||||
if wait {
|
||||
if releaseAll {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
|
||||
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
||||
success = r0 != 0
|
||||
if true {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
||||
}
|
||||
|
||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
||||
}
|
||||
|
||||
func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
||||
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
|
||||
ptr = uintptr(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlNtStatusToDosError(status ntstatus) (winerr error) {
|
||||
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
||||
if r0 != 0 {
|
||||
winerr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
|
||||
}
|
||||
|
||||
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -281,11 +101,7 @@ func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidS
|
|||
func convertSidToStringSid(sid *byte, str **uint16) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -302,29 +118,8 @@ func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision ui
|
|||
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func localFree(mem uintptr) {
|
||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -334,94 +129,62 @@ func getSecurityDescriptorLength(sd uintptr) (len uint32) {
|
|||
return
|
||||
}
|
||||
|
||||
func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
||||
var _p0 uint32
|
||||
if releaseAll {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
||||
success = r0 != 0
|
||||
if true {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func impersonateSelf(level uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func revertToSelf() (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
|
||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
|
||||
}
|
||||
|
||||
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
|
||||
var _p0 uint32
|
||||
if openAsSelf {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
|
||||
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
|
||||
}
|
||||
|
||||
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getCurrentThread() (h syscall.Handle) {
|
||||
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
|
||||
h = syscall.Handle(r0)
|
||||
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupPrivilegeName(_p0, luid, buffer, size)
|
||||
}
|
||||
|
||||
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -442,53 +205,27 @@ func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err err
|
|||
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||
if err != nil {
|
||||
return
|
||||
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
|
||||
var _p0 uint32
|
||||
if openAsSelf {
|
||||
_p0 = 1
|
||||
}
|
||||
return _lookupPrivilegeName(_p0, luid, buffer, size)
|
||||
}
|
||||
|
||||
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
|
||||
}
|
||||
|
||||
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
|
||||
func revertToSelf() (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -501,22 +238,14 @@ func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, proce
|
|||
var _p1 uint32
|
||||
if abort {
|
||||
_p1 = 1
|
||||
} else {
|
||||
_p1 = 0
|
||||
}
|
||||
var _p2 uint32
|
||||
if processSecurity {
|
||||
_p2 = 1
|
||||
} else {
|
||||
_p2 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -529,22 +258,162 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
|
|||
var _p1 uint32
|
||||
if abort {
|
||||
_p1 = 1
|
||||
} else {
|
||||
_p1 = 0
|
||||
}
|
||||
var _p2 uint32
|
||||
if processSecurity {
|
||||
_p2 = 1
|
||||
} else {
|
||||
_p2 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
||||
}
|
||||
|
||||
func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
||||
newport = syscall.Handle(r0)
|
||||
if newport == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
||||
}
|
||||
|
||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getCurrentThread() (h syscall.Handle) {
|
||||
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
|
||||
h = syscall.Handle(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
||||
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
|
||||
ptr = uintptr(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func localFree(mem uintptr) {
|
||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlNtStatusToDosError(status ntstatus) (winerr error) {
|
||||
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
||||
if r0 != 0 {
|
||||
winerr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
||||
var _p0 uint32
|
||||
if wait {
|
||||
_p0 = 1
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -552,11 +421,7 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
|
|||
func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
|
||||
if r1 == socketError {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -3,4 +3,3 @@ roaring-fuzz.zip
|
|||
workdir
|
||||
coverage.out
|
||||
testdata/all3.classic
|
||||
testdata/all3.msgp.snappy
|
||||
|
|
|
@ -17,7 +17,7 @@ branches:
|
|||
only:
|
||||
- master
|
||||
script:
|
||||
- goveralls -v -service travis-ci -ignore arraycontainer_gen.go,bitmapcontainer_gen.go,rle16_gen.go,rle_gen.go,roaringarray_gen.go,rle.go || go test
|
||||
- goveralls -v -service travis-ci -ignore rle16_gen.go,rle_gen.go,rle.go || go test
|
||||
- go test -race -run TestConcurrent*
|
||||
- go build -tags appengine
|
||||
- go test -tags appengine
|
||||
|
|
|
@ -97,10 +97,6 @@ nuke:
|
|||
rm -rf ./target
|
||||
GOPATH=$(GOPATH) go clean -i ./...
|
||||
|
||||
|
||||
ser:
|
||||
go generate
|
||||
|
||||
cover:
|
||||
go test -coverprofile=coverage.out
|
||||
go tool cover -html=coverage.out
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
//go:generate msgp -unexported
|
||||
|
||||
type arrayContainer struct {
|
||||
content []uint16
|
||||
}
|
||||
|
@ -485,7 +483,7 @@ func (ac *arrayContainer) orArrayCardinality(value2 *arrayContainer) int {
|
|||
func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container {
|
||||
value1 := ac
|
||||
maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
|
||||
if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap!^M
|
||||
if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap!
|
||||
bc := newBitmapContainer()
|
||||
for k := 0; k < len(value2.content); k++ {
|
||||
v := value2.content[k]
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
package roaring
|
||||
|
||||
// NOTE: THIS FILE WAS PRODUCED BY THE
|
||||
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
|
||||
// DO NOT EDIT
|
||||
|
||||
import "github.com/tinylib/msgp/msgp"
|
||||
|
||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
||||
func (z *arrayContainer) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zbzg uint32
|
||||
zbzg, err = dc.ReadMapHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zbzg > 0 {
|
||||
zbzg--
|
||||
field, err = dc.ReadMapKeyPtr()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "content":
|
||||
var zbai uint32
|
||||
zbai, err = dc.ReadArrayHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.content) >= int(zbai) {
|
||||
z.content = (z.content)[:zbai]
|
||||
} else {
|
||||
z.content = make([]uint16, zbai)
|
||||
}
|
||||
for zxvk := range z.content {
|
||||
z.content[zxvk], err = dc.ReadUint16()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
err = dc.Skip()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
||||
func (z *arrayContainer) EncodeMsg(en *msgp.Writer) (err error) {
|
||||
// map header, size 1
|
||||
// write "content"
|
||||
err = en.Append(0x81, 0xa7, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteArrayHeader(uint32(len(z.content)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zxvk := range z.content {
|
||||
err = en.WriteUint16(z.content[zxvk])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
||||
func (z *arrayContainer) MarshalMsg(b []byte) (o []byte, err error) {
|
||||
o = msgp.Require(b, z.Msgsize())
|
||||
// map header, size 1
|
||||
// string "content"
|
||||
o = append(o, 0x81, 0xa7, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74)
|
||||
o = msgp.AppendArrayHeader(o, uint32(len(z.content)))
|
||||
for zxvk := range z.content {
|
||||
o = msgp.AppendUint16(o, z.content[zxvk])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
||||
func (z *arrayContainer) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zcmr uint32
|
||||
zcmr, bts, err = msgp.ReadMapHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zcmr > 0 {
|
||||
zcmr--
|
||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "content":
|
||||
var zajw uint32
|
||||
zajw, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.content) >= int(zajw) {
|
||||
z.content = (z.content)[:zajw]
|
||||
} else {
|
||||
z.content = make([]uint16, zajw)
|
||||
}
|
||||
for zxvk := range z.content {
|
||||
z.content[zxvk], bts, err = msgp.ReadUint16Bytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
bts, err = msgp.Skip(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
o = bts
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
||||
func (z *arrayContainer) Msgsize() (s int) {
|
||||
s = 1 + 8 + msgp.ArrayHeaderSize + (len(z.content) * (msgp.Uint16Size))
|
||||
return
|
||||
}
|
|
@ -5,8 +5,6 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
//go:generate msgp -unexported
|
||||
|
||||
type bitmapContainer struct {
|
||||
cardinality int
|
||||
bitmap []uint64
|
||||
|
@ -115,7 +113,7 @@ type bitmapContainerShortIterator struct {
|
|||
|
||||
func (bcsi *bitmapContainerShortIterator) next() uint16 {
|
||||
j := bcsi.i
|
||||
bcsi.i = bcsi.ptr.NextSetBit(bcsi.i + 1)
|
||||
bcsi.i = bcsi.ptr.NextSetBit(uint(bcsi.i) + 1)
|
||||
return uint16(j)
|
||||
}
|
||||
func (bcsi *bitmapContainerShortIterator) hasNext() bool {
|
||||
|
@ -128,7 +126,7 @@ func (bcsi *bitmapContainerShortIterator) peekNext() uint16 {
|
|||
|
||||
func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) {
|
||||
if bcsi.hasNext() && bcsi.peekNext() < minval {
|
||||
bcsi.i = bcsi.ptr.NextSetBit(int(minval))
|
||||
bcsi.i = bcsi.ptr.NextSetBit(uint(minval))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1009,20 +1007,23 @@ func (bc *bitmapContainer) fillArray(container []uint16) {
|
|||
}
|
||||
}
|
||||
|
||||
func (bc *bitmapContainer) NextSetBit(i int) int {
|
||||
x := i / 64
|
||||
if x >= len(bc.bitmap) {
|
||||
func (bc *bitmapContainer) NextSetBit(i uint) int {
|
||||
var (
|
||||
x = i / 64
|
||||
length = uint(len(bc.bitmap))
|
||||
)
|
||||
if x >= length {
|
||||
return -1
|
||||
}
|
||||
w := bc.bitmap[x]
|
||||
w = w >> uint(i%64)
|
||||
if w != 0 {
|
||||
return i + countTrailingZeros(w)
|
||||
return int(i) + countTrailingZeros(w)
|
||||
}
|
||||
x++
|
||||
for ; x < len(bc.bitmap); x++ {
|
||||
for ; x < length; x++ {
|
||||
if bc.bitmap[x] != 0 {
|
||||
return (x * 64) + countTrailingZeros(bc.bitmap[x])
|
||||
return int(x*64) + countTrailingZeros(bc.bitmap[x])
|
||||
}
|
||||
}
|
||||
return -1
|
||||
|
|
|
@ -1,415 +0,0 @@
|
|||
package roaring
|
||||
|
||||
// NOTE: THIS FILE WAS PRODUCED BY THE
|
||||
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
|
||||
// DO NOT EDIT
|
||||
|
||||
import "github.com/tinylib/msgp/msgp"
|
||||
|
||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
||||
func (z *bitmapContainer) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zbzg uint32
|
||||
zbzg, err = dc.ReadMapHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zbzg > 0 {
|
||||
zbzg--
|
||||
field, err = dc.ReadMapKeyPtr()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "cardinality":
|
||||
z.cardinality, err = dc.ReadInt()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "bitmap":
|
||||
var zbai uint32
|
||||
zbai, err = dc.ReadArrayHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.bitmap) >= int(zbai) {
|
||||
z.bitmap = (z.bitmap)[:zbai]
|
||||
} else {
|
||||
z.bitmap = make([]uint64, zbai)
|
||||
}
|
||||
for zxvk := range z.bitmap {
|
||||
z.bitmap[zxvk], err = dc.ReadUint64()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
err = dc.Skip()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
||||
func (z *bitmapContainer) EncodeMsg(en *msgp.Writer) (err error) {
|
||||
// map header, size 2
|
||||
// write "cardinality"
|
||||
err = en.Append(0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteInt(z.cardinality)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// write "bitmap"
|
||||
err = en.Append(0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteArrayHeader(uint32(len(z.bitmap)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zxvk := range z.bitmap {
|
||||
err = en.WriteUint64(z.bitmap[zxvk])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
||||
func (z *bitmapContainer) MarshalMsg(b []byte) (o []byte, err error) {
|
||||
o = msgp.Require(b, z.Msgsize())
|
||||
// map header, size 2
|
||||
// string "cardinality"
|
||||
o = append(o, 0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
|
||||
o = msgp.AppendInt(o, z.cardinality)
|
||||
// string "bitmap"
|
||||
o = append(o, 0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
|
||||
o = msgp.AppendArrayHeader(o, uint32(len(z.bitmap)))
|
||||
for zxvk := range z.bitmap {
|
||||
o = msgp.AppendUint64(o, z.bitmap[zxvk])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
||||
func (z *bitmapContainer) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zcmr uint32
|
||||
zcmr, bts, err = msgp.ReadMapHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zcmr > 0 {
|
||||
zcmr--
|
||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "cardinality":
|
||||
z.cardinality, bts, err = msgp.ReadIntBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "bitmap":
|
||||
var zajw uint32
|
||||
zajw, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.bitmap) >= int(zajw) {
|
||||
z.bitmap = (z.bitmap)[:zajw]
|
||||
} else {
|
||||
z.bitmap = make([]uint64, zajw)
|
||||
}
|
||||
for zxvk := range z.bitmap {
|
||||
z.bitmap[zxvk], bts, err = msgp.ReadUint64Bytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
bts, err = msgp.Skip(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
o = bts
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
||||
func (z *bitmapContainer) Msgsize() (s int) {
|
||||
s = 1 + 12 + msgp.IntSize + 7 + msgp.ArrayHeaderSize + (len(z.bitmap) * (msgp.Uint64Size))
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
||||
func (z *bitmapContainerShortIterator) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zhct uint32
|
||||
zhct, err = dc.ReadMapHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zhct > 0 {
|
||||
zhct--
|
||||
field, err = dc.ReadMapKeyPtr()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "ptr":
|
||||
if dc.IsNil() {
|
||||
err = dc.ReadNil()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
z.ptr = nil
|
||||
} else {
|
||||
if z.ptr == nil {
|
||||
z.ptr = new(bitmapContainer)
|
||||
}
|
||||
var zcua uint32
|
||||
zcua, err = dc.ReadMapHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zcua > 0 {
|
||||
zcua--
|
||||
field, err = dc.ReadMapKeyPtr()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "cardinality":
|
||||
z.ptr.cardinality, err = dc.ReadInt()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "bitmap":
|
||||
var zxhx uint32
|
||||
zxhx, err = dc.ReadArrayHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.ptr.bitmap) >= int(zxhx) {
|
||||
z.ptr.bitmap = (z.ptr.bitmap)[:zxhx]
|
||||
} else {
|
||||
z.ptr.bitmap = make([]uint64, zxhx)
|
||||
}
|
||||
for zwht := range z.ptr.bitmap {
|
||||
z.ptr.bitmap[zwht], err = dc.ReadUint64()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
err = dc.Skip()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case "i":
|
||||
z.i, err = dc.ReadInt()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = dc.Skip()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
||||
func (z *bitmapContainerShortIterator) EncodeMsg(en *msgp.Writer) (err error) {
|
||||
// map header, size 2
|
||||
// write "ptr"
|
||||
err = en.Append(0x82, 0xa3, 0x70, 0x74, 0x72)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if z.ptr == nil {
|
||||
err = en.WriteNil()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// map header, size 2
|
||||
// write "cardinality"
|
||||
err = en.Append(0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteInt(z.ptr.cardinality)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// write "bitmap"
|
||||
err = en.Append(0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteArrayHeader(uint32(len(z.ptr.bitmap)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zwht := range z.ptr.bitmap {
|
||||
err = en.WriteUint64(z.ptr.bitmap[zwht])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// write "i"
|
||||
err = en.Append(0xa1, 0x69)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteInt(z.i)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
||||
func (z *bitmapContainerShortIterator) MarshalMsg(b []byte) (o []byte, err error) {
|
||||
o = msgp.Require(b, z.Msgsize())
|
||||
// map header, size 2
|
||||
// string "ptr"
|
||||
o = append(o, 0x82, 0xa3, 0x70, 0x74, 0x72)
|
||||
if z.ptr == nil {
|
||||
o = msgp.AppendNil(o)
|
||||
} else {
|
||||
// map header, size 2
|
||||
// string "cardinality"
|
||||
o = append(o, 0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
|
||||
o = msgp.AppendInt(o, z.ptr.cardinality)
|
||||
// string "bitmap"
|
||||
o = append(o, 0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
|
||||
o = msgp.AppendArrayHeader(o, uint32(len(z.ptr.bitmap)))
|
||||
for zwht := range z.ptr.bitmap {
|
||||
o = msgp.AppendUint64(o, z.ptr.bitmap[zwht])
|
||||
}
|
||||
}
|
||||
// string "i"
|
||||
o = append(o, 0xa1, 0x69)
|
||||
o = msgp.AppendInt(o, z.i)
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
||||
func (z *bitmapContainerShortIterator) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zlqf uint32
|
||||
zlqf, bts, err = msgp.ReadMapHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zlqf > 0 {
|
||||
zlqf--
|
||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "ptr":
|
||||
if msgp.IsNil(bts) {
|
||||
bts, err = msgp.ReadNilBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
z.ptr = nil
|
||||
} else {
|
||||
if z.ptr == nil {
|
||||
z.ptr = new(bitmapContainer)
|
||||
}
|
||||
var zdaf uint32
|
||||
zdaf, bts, err = msgp.ReadMapHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zdaf > 0 {
|
||||
zdaf--
|
||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "cardinality":
|
||||
z.ptr.cardinality, bts, err = msgp.ReadIntBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "bitmap":
|
||||
var zpks uint32
|
||||
zpks, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.ptr.bitmap) >= int(zpks) {
|
||||
z.ptr.bitmap = (z.ptr.bitmap)[:zpks]
|
||||
} else {
|
||||
z.ptr.bitmap = make([]uint64, zpks)
|
||||
}
|
||||
for zwht := range z.ptr.bitmap {
|
||||
z.ptr.bitmap[zwht], bts, err = msgp.ReadUint64Bytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
bts, err = msgp.Skip(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case "i":
|
||||
z.i, bts, err = msgp.ReadIntBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
bts, err = msgp.Skip(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
o = bts
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
||||
func (z *bitmapContainerShortIterator) Msgsize() (s int) {
|
||||
s = 1 + 4
|
||||
if z.ptr == nil {
|
||||
s += msgp.NilSize
|
||||
} else {
|
||||
s += 1 + 12 + msgp.IntSize + 7 + msgp.ArrayHeaderSize + (len(z.ptr.bitmap) * (msgp.Uint64Size))
|
||||
}
|
||||
s += 2 + msgp.IntSize
|
||||
return
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
package roaring
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
type byteInput interface {
|
||||
// next returns a slice containing the next n bytes from the buffer,
|
||||
// advancing the buffer as if the bytes had been returned by Read.
|
||||
next(n int) ([]byte, error)
|
||||
// readUInt32 reads uint32 with LittleEndian order
|
||||
readUInt32() (uint32, error)
|
||||
// readUInt16 reads uint16 with LittleEndian order
|
||||
readUInt16() (uint16, error)
|
||||
// getReadBytes returns read bytes
|
||||
getReadBytes() int64
|
||||
// skipBytes skips exactly n bytes
|
||||
skipBytes(n int) error
|
||||
}
|
||||
|
||||
func newByteInputFromReader(reader io.Reader) byteInput {
|
||||
return &byteInputAdapter{
|
||||
r: reader,
|
||||
readBytes: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func newByteInput(buf []byte) byteInput {
|
||||
return &byteBuffer{
|
||||
buf: buf,
|
||||
off: 0,
|
||||
}
|
||||
}
|
||||
|
||||
type byteBuffer struct {
|
||||
buf []byte
|
||||
off int
|
||||
}
|
||||
|
||||
// next returns a slice containing the next n bytes from the reader
|
||||
// If there are fewer bytes than the given n, io.ErrUnexpectedEOF will be returned
|
||||
func (b *byteBuffer) next(n int) ([]byte, error) {
|
||||
m := len(b.buf) - b.off
|
||||
|
||||
if n > m {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
data := b.buf[b.off : b.off+n]
|
||||
b.off += n
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// readUInt32 reads uint32 with LittleEndian order
|
||||
func (b *byteBuffer) readUInt32() (uint32, error) {
|
||||
if len(b.buf)-b.off < 4 {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
v := binary.LittleEndian.Uint32(b.buf[b.off:])
|
||||
b.off += 4
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// readUInt16 reads uint16 with LittleEndian order
|
||||
func (b *byteBuffer) readUInt16() (uint16, error) {
|
||||
if len(b.buf)-b.off < 2 {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
v := binary.LittleEndian.Uint16(b.buf[b.off:])
|
||||
b.off += 2
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// getReadBytes returns read bytes
|
||||
func (b *byteBuffer) getReadBytes() int64 {
|
||||
return int64(b.off)
|
||||
}
|
||||
|
||||
// skipBytes skips exactly n bytes
|
||||
func (b *byteBuffer) skipBytes(n int) error {
|
||||
m := len(b.buf) - b.off
|
||||
|
||||
if n > m {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
b.off += n
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// reset resets the given buffer with a new byte slice
|
||||
func (b *byteBuffer) reset(buf []byte) {
|
||||
b.buf = buf
|
||||
b.off = 0
|
||||
}
|
||||
|
||||
type byteInputAdapter struct {
|
||||
r io.Reader
|
||||
readBytes int
|
||||
}
|
||||
|
||||
// next returns a slice containing the next n bytes from the buffer,
|
||||
// advancing the buffer as if the bytes had been returned by Read.
|
||||
func (b *byteInputAdapter) next(n int) ([]byte, error) {
|
||||
buf := make([]byte, n)
|
||||
m, err := io.ReadAtLeast(b.r, buf, n)
|
||||
b.readBytes += m
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// readUInt32 reads uint32 with LittleEndian order
|
||||
func (b *byteInputAdapter) readUInt32() (uint32, error) {
|
||||
buf, err := b.next(4)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint32(buf), nil
|
||||
}
|
||||
|
||||
// readUInt16 reads uint16 with LittleEndian order
|
||||
func (b *byteInputAdapter) readUInt16() (uint16, error) {
|
||||
buf, err := b.next(2)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint16(buf), nil
|
||||
}
|
||||
|
||||
// getReadBytes returns read bytes
|
||||
func (b *byteInputAdapter) getReadBytes() int64 {
|
||||
return int64(b.readBytes)
|
||||
}
|
||||
|
||||
// skipBytes skips exactly n bytes
|
||||
func (b *byteInputAdapter) skipBytes(n int) error {
|
||||
_, err := b.next(n)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// reset resets the given buffer with a new stream
|
||||
func (b *byteInputAdapter) reset(stream io.Reader) {
|
||||
b.r = stream
|
||||
b.readBytes = 0
|
||||
}
|
|
@ -11,7 +11,6 @@ require (
|
|||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae
|
||||
github.com/philhofer/fwd v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/tinylib/msgp v1.1.0
|
||||
github.com/willf/bitset v1.1.10
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||
golang.org/x/tools v0.0.0-20200928182047-19e03678916f // indirect
|
||||
|
|
|
@ -20,8 +20,6 @@ github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
|
||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ByteInput typed interface around io.Reader or raw bytes
|
||||
type ByteInput interface {
|
||||
// Next returns a slice containing the next n bytes from the buffer,
|
||||
// advancing the buffer as if the bytes had been returned by Read.
|
||||
Next(n int) ([]byte, error)
|
||||
// ReadUInt32 reads uint32 with LittleEndian order
|
||||
ReadUInt32() (uint32, error)
|
||||
// ReadUInt16 reads uint16 with LittleEndian order
|
||||
ReadUInt16() (uint16, error)
|
||||
// GetReadBytes returns read bytes
|
||||
GetReadBytes() int64
|
||||
// SkipBytes skips exactly n bytes
|
||||
SkipBytes(n int) error
|
||||
}
|
||||
|
||||
// NewByteInputFromReader creates reader wrapper
|
||||
func NewByteInputFromReader(reader io.Reader) ByteInput {
|
||||
return &ByteInputAdapter{
|
||||
r: reader,
|
||||
readBytes: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// NewByteInput creates raw bytes wrapper
|
||||
func NewByteInput(buf []byte) ByteInput {
|
||||
return &ByteBuffer{
|
||||
buf: buf,
|
||||
off: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// ByteBuffer raw bytes wrapper
|
||||
type ByteBuffer struct {
|
||||
buf []byte
|
||||
off int
|
||||
}
|
||||
|
||||
// Next returns a slice containing the next n bytes from the reader
|
||||
// If there are fewer bytes than the given n, io.ErrUnexpectedEOF will be returned
|
||||
func (b *ByteBuffer) Next(n int) ([]byte, error) {
|
||||
m := len(b.buf) - b.off
|
||||
|
||||
if n > m {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
data := b.buf[b.off : b.off+n]
|
||||
b.off += n
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// ReadUInt32 reads uint32 with LittleEndian order
|
||||
func (b *ByteBuffer) ReadUInt32() (uint32, error) {
|
||||
if len(b.buf)-b.off < 4 {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
v := binary.LittleEndian.Uint32(b.buf[b.off:])
|
||||
b.off += 4
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// ReadUInt16 reads uint16 with LittleEndian order
|
||||
func (b *ByteBuffer) ReadUInt16() (uint16, error) {
|
||||
if len(b.buf)-b.off < 2 {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
v := binary.LittleEndian.Uint16(b.buf[b.off:])
|
||||
b.off += 2
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// GetReadBytes returns read bytes
|
||||
func (b *ByteBuffer) GetReadBytes() int64 {
|
||||
return int64(b.off)
|
||||
}
|
||||
|
||||
// SkipBytes skips exactly n bytes
|
||||
func (b *ByteBuffer) SkipBytes(n int) error {
|
||||
m := len(b.buf) - b.off
|
||||
|
||||
if n > m {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
b.off += n
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reset resets the given buffer with a new byte slice
|
||||
func (b *ByteBuffer) Reset(buf []byte) {
|
||||
b.buf = buf
|
||||
b.off = 0
|
||||
}
|
||||
|
||||
// ByteInputAdapter reader wrapper
|
||||
type ByteInputAdapter struct {
|
||||
r io.Reader
|
||||
readBytes int
|
||||
}
|
||||
|
||||
// Next returns a slice containing the next n bytes from the buffer,
|
||||
// advancing the buffer as if the bytes had been returned by Read.
|
||||
func (b *ByteInputAdapter) Next(n int) ([]byte, error) {
|
||||
buf := make([]byte, n)
|
||||
m, err := io.ReadAtLeast(b.r, buf, n)
|
||||
b.readBytes += m
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// ReadUInt32 reads uint32 with LittleEndian order
|
||||
func (b *ByteInputAdapter) ReadUInt32() (uint32, error) {
|
||||
buf, err := b.Next(4)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint32(buf), nil
|
||||
}
|
||||
|
||||
// ReadUInt16 reads uint16 with LittleEndian order
|
||||
func (b *ByteInputAdapter) ReadUInt16() (uint16, error) {
|
||||
buf, err := b.Next(2)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint16(buf), nil
|
||||
}
|
||||
|
||||
// GetReadBytes returns read bytes
|
||||
func (b *ByteInputAdapter) GetReadBytes() int64 {
|
||||
return int64(b.readBytes)
|
||||
}
|
||||
|
||||
// SkipBytes skips exactly n bytes
|
||||
func (b *ByteInputAdapter) SkipBytes(n int) error {
|
||||
_, err := b.Next(n)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Reset resets the given buffer with a new stream
|
||||
func (b *ByteInputAdapter) Reset(stream io.Reader) {
|
||||
b.r = stream
|
||||
b.readBytes = 0
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// ByteInputAdapterPool shared pool
|
||||
ByteInputAdapterPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &ByteInputAdapter{}
|
||||
},
|
||||
}
|
||||
|
||||
// ByteBufferPool shared pool
|
||||
ByteBufferPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &ByteBuffer{}
|
||||
},
|
||||
}
|
||||
)
|
|
@ -166,7 +166,6 @@ func appenderRoutine(bitmapChan chan<- *Bitmap, resultChan <-chan keyedContainer
|
|||
make([]container, 0, expectedKeys),
|
||||
make([]bool, 0, expectedKeys),
|
||||
false,
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for i := range keys {
|
||||
|
|
|
@ -11,7 +11,8 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/RoaringBitmap/roaring/internal"
|
||||
)
|
||||
|
||||
// Bitmap represents a compressed bitmap where you can add integers.
|
||||
|
@ -52,27 +53,19 @@ func (rb *Bitmap) ToBytes() ([]byte, error) {
|
|||
return rb.highlowcontainer.toBytes()
|
||||
}
|
||||
|
||||
// Deprecated: WriteToMsgpack writes a msgpack2/snappy-streaming compressed serialized
|
||||
// version of this bitmap to stream. The format is not
|
||||
// compatible with the WriteTo() format, and is
|
||||
// experimental: it may produce smaller on disk
|
||||
// footprint and/or be faster to read, depending
|
||||
// on your content. Currently only the Go roaring
|
||||
// implementation supports this format.
|
||||
func (rb *Bitmap) WriteToMsgpack(stream io.Writer) (int64, error) {
|
||||
return 0, rb.highlowcontainer.writeToMsgpack(stream)
|
||||
}
|
||||
|
||||
// ReadFrom reads a serialized version of this bitmap from stream.
|
||||
// The format is compatible with other RoaringBitmap
|
||||
// implementations (Java, C) and is documented here:
|
||||
// https://github.com/RoaringBitmap/RoaringFormatSpec
|
||||
func (rb *Bitmap) ReadFrom(reader io.Reader) (p int64, err error) {
|
||||
stream := byteInputAdapterPool.Get().(*byteInputAdapter)
|
||||
stream.reset(reader)
|
||||
// Since io.Reader is regarded as a stream and cannot be read twice.
|
||||
// So add cookieHeader to accept the 4-byte data that has been read in roaring64.ReadFrom.
|
||||
// It is not necessary to pass cookieHeader when call roaring.ReadFrom to read the roaring32 data directly.
|
||||
func (rb *Bitmap) ReadFrom(reader io.Reader, cookieHeader ...byte) (p int64, err error) {
|
||||
stream := internal.ByteInputAdapterPool.Get().(*internal.ByteInputAdapter)
|
||||
stream.Reset(reader)
|
||||
|
||||
p, err = rb.highlowcontainer.readFrom(stream)
|
||||
byteInputAdapterPool.Put(stream)
|
||||
p, err = rb.highlowcontainer.readFrom(stream, cookieHeader...)
|
||||
internal.ByteInputAdapterPool.Put(stream)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -100,29 +93,15 @@ func (rb *Bitmap) ReadFrom(reader io.Reader) (p int64, err error) {
|
|||
// call CloneCopyOnWriteContainers on all such bitmaps.
|
||||
//
|
||||
func (rb *Bitmap) FromBuffer(buf []byte) (p int64, err error) {
|
||||
stream := byteBufferPool.Get().(*byteBuffer)
|
||||
stream.reset(buf)
|
||||
stream := internal.ByteBufferPool.Get().(*internal.ByteBuffer)
|
||||
stream.Reset(buf)
|
||||
|
||||
p, err = rb.highlowcontainer.readFrom(stream)
|
||||
byteBufferPool.Put(stream)
|
||||
internal.ByteBufferPool.Put(stream)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
byteBufferPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &byteBuffer{}
|
||||
},
|
||||
}
|
||||
|
||||
byteInputAdapterPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &byteInputAdapter{}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// RunOptimize attempts to further compress the runs of consecutive values found in the bitmap
|
||||
func (rb *Bitmap) RunOptimize() {
|
||||
rb.highlowcontainer.runOptimize()
|
||||
|
@ -133,14 +112,6 @@ func (rb *Bitmap) HasRunCompression() bool {
|
|||
return rb.highlowcontainer.hasRunCompression()
|
||||
}
|
||||
|
||||
// Deprecated: ReadFromMsgpack reads a msgpack2/snappy-streaming serialized
|
||||
// version of this bitmap from stream. The format is
|
||||
// expected is that written by the WriteToMsgpack()
|
||||
// call; see additional notes there.
|
||||
func (rb *Bitmap) ReadFromMsgpack(stream io.Reader) (int64, error) {
|
||||
return 0, rb.highlowcontainer.readFromMsgpack(stream)
|
||||
}
|
||||
|
||||
// MarshalBinary implements the encoding.BinaryMarshaler interface for the bitmap
|
||||
// (same as ToBytes)
|
||||
func (rb *Bitmap) MarshalBinary() ([]byte, error) {
|
||||
|
|
|
@ -5,13 +5,9 @@ import (
|
|||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
snappy "github.com/glycerine/go-unsnap-stream"
|
||||
"github.com/tinylib/msgp/msgp"
|
||||
"github.com/RoaringBitmap/roaring/internal"
|
||||
)
|
||||
|
||||
//go:generate msgp -unexported
|
||||
|
||||
type container interface {
|
||||
addOffset(uint16) []container
|
||||
|
||||
|
@ -103,18 +99,6 @@ type roaringArray struct {
|
|||
containers []container `msg:"-"` // don't try to serialize directly.
|
||||
needCopyOnWrite []bool
|
||||
copyOnWrite bool
|
||||
|
||||
// conserz is used at serialization time
|
||||
// to serialize containers. Otherwise empty.
|
||||
conserz []containerSerz
|
||||
}
|
||||
|
||||
// containerSerz facilitates serializing container (tricky to
|
||||
// serialize because it is an interface) by providing a
|
||||
// light wrapper with a type identifier.
|
||||
type containerSerz struct {
|
||||
t contype `msg:"t"` // type
|
||||
r msgp.Raw `msg:"r"` // Raw msgpack of the actual container type
|
||||
}
|
||||
|
||||
func newRoaringArray() *roaringArray {
|
||||
|
@ -246,7 +230,6 @@ func (ra *roaringArray) resize(newsize int) {
|
|||
func (ra *roaringArray) clear() {
|
||||
ra.resize(0)
|
||||
ra.copyOnWrite = false
|
||||
ra.conserz = nil
|
||||
}
|
||||
|
||||
func (ra *roaringArray) clone() *roaringArray {
|
||||
|
@ -566,11 +549,19 @@ func (ra *roaringArray) toBytes() ([]byte, error) {
|
|||
return buf.Bytes(), err
|
||||
}
|
||||
|
||||
func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
||||
cookie, err := stream.readUInt32()
|
||||
|
||||
func (ra *roaringArray) readFrom(stream internal.ByteInput, cookieHeader ...byte) (int64, error) {
|
||||
var cookie uint32
|
||||
var err error
|
||||
if len(cookieHeader) > 0 && len(cookieHeader) != 4 {
|
||||
return int64(len(cookieHeader)), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: incorrect size of cookie header")
|
||||
}
|
||||
if len(cookieHeader) == 4 {
|
||||
cookie = binary.LittleEndian.Uint32(cookieHeader)
|
||||
} else {
|
||||
cookie, err = stream.ReadUInt32()
|
||||
if err != nil {
|
||||
return stream.getReadBytes(), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: %s", err)
|
||||
return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
var size uint32
|
||||
|
@ -580,37 +571,36 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
|||
size = uint32(uint16(cookie>>16) + 1)
|
||||
// create is-run-container bitmap
|
||||
isRunBitmapSize := (int(size) + 7) / 8
|
||||
isRunBitmap, err = stream.next(isRunBitmapSize)
|
||||
isRunBitmap, err = stream.Next(isRunBitmapSize)
|
||||
|
||||
if err != nil {
|
||||
return stream.getReadBytes(), fmt.Errorf("malformed bitmap, failed to read is-run bitmap, got: %s", err)
|
||||
return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read is-run bitmap, got: %s", err)
|
||||
}
|
||||
} else if cookie == serialCookieNoRunContainer {
|
||||
size, err = stream.readUInt32()
|
||||
|
||||
size, err = stream.ReadUInt32()
|
||||
if err != nil {
|
||||
return stream.getReadBytes(), fmt.Errorf("malformed bitmap, failed to read a bitmap size: %s", err)
|
||||
return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read a bitmap size: %s", err)
|
||||
}
|
||||
} else {
|
||||
return stream.getReadBytes(), fmt.Errorf("error in roaringArray.readFrom: did not find expected serialCookie in header")
|
||||
return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: did not find expected serialCookie in header")
|
||||
}
|
||||
|
||||
if size > (1 << 16) {
|
||||
return stream.getReadBytes(), fmt.Errorf("it is logically impossible to have more than (1<<16) containers")
|
||||
return stream.GetReadBytes(), fmt.Errorf("it is logically impossible to have more than (1<<16) containers")
|
||||
}
|
||||
|
||||
// descriptive header
|
||||
buf, err := stream.next(2 * 2 * int(size))
|
||||
buf, err := stream.Next(2 * 2 * int(size))
|
||||
|
||||
if err != nil {
|
||||
return stream.getReadBytes(), fmt.Errorf("failed to read descriptive header: %s", err)
|
||||
return stream.GetReadBytes(), fmt.Errorf("failed to read descriptive header: %s", err)
|
||||
}
|
||||
|
||||
keycard := byteSliceAsUint16Slice(buf)
|
||||
|
||||
if isRunBitmap == nil || size >= noOffsetThreshold {
|
||||
if err := stream.skipBytes(int(size) * 4); err != nil {
|
||||
return stream.getReadBytes(), fmt.Errorf("failed to skip bytes: %s", err)
|
||||
if err := stream.SkipBytes(int(size) * 4); err != nil {
|
||||
return stream.GetReadBytes(), fmt.Errorf("failed to skip bytes: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -641,16 +631,16 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
|||
|
||||
if isRunBitmap != nil && isRunBitmap[i/8]&(1<<(i%8)) != 0 {
|
||||
// run container
|
||||
nr, err := stream.readUInt16()
|
||||
nr, err := stream.ReadUInt16()
|
||||
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to read runtime container size: %s", err)
|
||||
}
|
||||
|
||||
buf, err := stream.next(int(nr) * 4)
|
||||
buf, err := stream.Next(int(nr) * 4)
|
||||
|
||||
if err != nil {
|
||||
return stream.getReadBytes(), fmt.Errorf("failed to read runtime container content: %s", err)
|
||||
return stream.GetReadBytes(), fmt.Errorf("failed to read runtime container content: %s", err)
|
||||
}
|
||||
|
||||
nb := runContainer16{
|
||||
|
@ -661,10 +651,10 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
|||
ra.containers[i] = &nb
|
||||
} else if card > arrayDefaultMaxSize {
|
||||
// bitmap container
|
||||
buf, err := stream.next(arrayDefaultMaxSize * 2)
|
||||
buf, err := stream.Next(arrayDefaultMaxSize * 2)
|
||||
|
||||
if err != nil {
|
||||
return stream.getReadBytes(), fmt.Errorf("failed to read bitmap container: %s", err)
|
||||
return stream.GetReadBytes(), fmt.Errorf("failed to read bitmap container: %s", err)
|
||||
}
|
||||
|
||||
nb := bitmapContainer{
|
||||
|
@ -675,10 +665,10 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
|||
ra.containers[i] = &nb
|
||||
} else {
|
||||
// array container
|
||||
buf, err := stream.next(card * 2)
|
||||
buf, err := stream.Next(card * 2)
|
||||
|
||||
if err != nil {
|
||||
return stream.getReadBytes(), fmt.Errorf("failed to read array container: %s", err)
|
||||
return stream.GetReadBytes(), fmt.Errorf("failed to read array container: %s", err)
|
||||
}
|
||||
|
||||
nb := arrayContainer{
|
||||
|
@ -689,7 +679,7 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
|
|||
}
|
||||
}
|
||||
|
||||
return stream.getReadBytes(), nil
|
||||
return stream.GetReadBytes(), nil
|
||||
}
|
||||
|
||||
func (ra *roaringArray) hasRunCompression() bool {
|
||||
|
@ -702,84 +692,6 @@ func (ra *roaringArray) hasRunCompression() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (ra *roaringArray) writeToMsgpack(stream io.Writer) error {
|
||||
|
||||
ra.conserz = make([]containerSerz, len(ra.containers))
|
||||
for i, v := range ra.containers {
|
||||
switch cn := v.(type) {
|
||||
case *bitmapContainer:
|
||||
bts, err := cn.MarshalMsg(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ra.conserz[i].t = bitmapContype
|
||||
ra.conserz[i].r = bts
|
||||
case *arrayContainer:
|
||||
bts, err := cn.MarshalMsg(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ra.conserz[i].t = arrayContype
|
||||
ra.conserz[i].r = bts
|
||||
case *runContainer16:
|
||||
bts, err := cn.MarshalMsg(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ra.conserz[i].t = run16Contype
|
||||
ra.conserz[i].r = bts
|
||||
default:
|
||||
panic(fmt.Errorf("Unrecognized container implementation: %T", cn))
|
||||
}
|
||||
}
|
||||
w := snappy.NewWriter(stream)
|
||||
err := msgp.Encode(w, ra)
|
||||
ra.conserz = nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (ra *roaringArray) readFromMsgpack(stream io.Reader) error {
|
||||
r := snappy.NewReader(stream)
|
||||
err := msgp.Decode(r, ra)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(ra.containers) != len(ra.keys) {
|
||||
ra.containers = make([]container, len(ra.keys))
|
||||
}
|
||||
|
||||
for i, v := range ra.conserz {
|
||||
switch v.t {
|
||||
case bitmapContype:
|
||||
c := &bitmapContainer{}
|
||||
_, err = c.UnmarshalMsg(v.r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ra.containers[i] = c
|
||||
case arrayContype:
|
||||
c := &arrayContainer{}
|
||||
_, err = c.UnmarshalMsg(v.r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ra.containers[i] = c
|
||||
case run16Contype:
|
||||
c := &runContainer16{}
|
||||
_, err = c.UnmarshalMsg(v.r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ra.containers[i] = c
|
||||
default:
|
||||
return fmt.Errorf("unrecognized contype serialization code: '%v'", v.t)
|
||||
}
|
||||
}
|
||||
ra.conserz = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ra *roaringArray) advanceUntil(min uint16, pos int) int {
|
||||
lower := pos + 1
|
||||
|
||||
|
|
|
@ -1,529 +0,0 @@
|
|||
package roaring
|
||||
|
||||
// NOTE: THIS FILE WAS PRODUCED BY THE
|
||||
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
|
||||
// DO NOT EDIT
|
||||
|
||||
import (
|
||||
"github.com/tinylib/msgp/msgp"
|
||||
)
|
||||
|
||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
||||
func (z *containerSerz) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zxvk uint32
|
||||
zxvk, err = dc.ReadMapHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zxvk > 0 {
|
||||
zxvk--
|
||||
field, err = dc.ReadMapKeyPtr()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "t":
|
||||
{
|
||||
var zbzg uint8
|
||||
zbzg, err = dc.ReadUint8()
|
||||
z.t = contype(zbzg)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "r":
|
||||
err = z.r.DecodeMsg(dc)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = dc.Skip()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
||||
func (z *containerSerz) EncodeMsg(en *msgp.Writer) (err error) {
|
||||
// map header, size 2
|
||||
// write "t"
|
||||
err = en.Append(0x82, 0xa1, 0x74)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteUint8(uint8(z.t))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// write "r"
|
||||
err = en.Append(0xa1, 0x72)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = z.r.EncodeMsg(en)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
||||
func (z *containerSerz) MarshalMsg(b []byte) (o []byte, err error) {
|
||||
o = msgp.Require(b, z.Msgsize())
|
||||
// map header, size 2
|
||||
// string "t"
|
||||
o = append(o, 0x82, 0xa1, 0x74)
|
||||
o = msgp.AppendUint8(o, uint8(z.t))
|
||||
// string "r"
|
||||
o = append(o, 0xa1, 0x72)
|
||||
o, err = z.r.MarshalMsg(o)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
||||
func (z *containerSerz) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zbai uint32
|
||||
zbai, bts, err = msgp.ReadMapHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zbai > 0 {
|
||||
zbai--
|
||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "t":
|
||||
{
|
||||
var zcmr uint8
|
||||
zcmr, bts, err = msgp.ReadUint8Bytes(bts)
|
||||
z.t = contype(zcmr)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "r":
|
||||
bts, err = z.r.UnmarshalMsg(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
bts, err = msgp.Skip(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
o = bts
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
||||
func (z *containerSerz) Msgsize() (s int) {
|
||||
s = 1 + 2 + msgp.Uint8Size + 2 + z.r.Msgsize()
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
||||
func (z *contype) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||
{
|
||||
var zajw uint8
|
||||
zajw, err = dc.ReadUint8()
|
||||
(*z) = contype(zajw)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
||||
func (z contype) EncodeMsg(en *msgp.Writer) (err error) {
|
||||
err = en.WriteUint8(uint8(z))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
||||
func (z contype) MarshalMsg(b []byte) (o []byte, err error) {
|
||||
o = msgp.Require(b, z.Msgsize())
|
||||
o = msgp.AppendUint8(o, uint8(z))
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
||||
func (z *contype) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
||||
{
|
||||
var zwht uint8
|
||||
zwht, bts, err = msgp.ReadUint8Bytes(bts)
|
||||
(*z) = contype(zwht)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
o = bts
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
||||
func (z contype) Msgsize() (s int) {
|
||||
s = msgp.Uint8Size
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: DecodeMsg implements msgp.Decodable
|
||||
func (z *roaringArray) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zlqf uint32
|
||||
zlqf, err = dc.ReadMapHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zlqf > 0 {
|
||||
zlqf--
|
||||
field, err = dc.ReadMapKeyPtr()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "keys":
|
||||
var zdaf uint32
|
||||
zdaf, err = dc.ReadArrayHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.keys) >= int(zdaf) {
|
||||
z.keys = (z.keys)[:zdaf]
|
||||
} else {
|
||||
z.keys = make([]uint16, zdaf)
|
||||
}
|
||||
for zhct := range z.keys {
|
||||
z.keys[zhct], err = dc.ReadUint16()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
case "needCopyOnWrite":
|
||||
var zpks uint32
|
||||
zpks, err = dc.ReadArrayHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.needCopyOnWrite) >= int(zpks) {
|
||||
z.needCopyOnWrite = (z.needCopyOnWrite)[:zpks]
|
||||
} else {
|
||||
z.needCopyOnWrite = make([]bool, zpks)
|
||||
}
|
||||
for zcua := range z.needCopyOnWrite {
|
||||
z.needCopyOnWrite[zcua], err = dc.ReadBool()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
case "copyOnWrite":
|
||||
z.copyOnWrite, err = dc.ReadBool()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "conserz":
|
||||
var zjfb uint32
|
||||
zjfb, err = dc.ReadArrayHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.conserz) >= int(zjfb) {
|
||||
z.conserz = (z.conserz)[:zjfb]
|
||||
} else {
|
||||
z.conserz = make([]containerSerz, zjfb)
|
||||
}
|
||||
for zxhx := range z.conserz {
|
||||
var zcxo uint32
|
||||
zcxo, err = dc.ReadMapHeader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zcxo > 0 {
|
||||
zcxo--
|
||||
field, err = dc.ReadMapKeyPtr()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "t":
|
||||
{
|
||||
var zeff uint8
|
||||
zeff, err = dc.ReadUint8()
|
||||
z.conserz[zxhx].t = contype(zeff)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "r":
|
||||
err = z.conserz[zxhx].r.DecodeMsg(dc)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = dc.Skip()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
err = dc.Skip()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: EncodeMsg implements msgp.Encodable
|
||||
func (z *roaringArray) EncodeMsg(en *msgp.Writer) (err error) {
|
||||
// map header, size 4
|
||||
// write "keys"
|
||||
err = en.Append(0x84, 0xa4, 0x6b, 0x65, 0x79, 0x73)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteArrayHeader(uint32(len(z.keys)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zhct := range z.keys {
|
||||
err = en.WriteUint16(z.keys[zhct])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
// write "needCopyOnWrite"
|
||||
err = en.Append(0xaf, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteArrayHeader(uint32(len(z.needCopyOnWrite)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zcua := range z.needCopyOnWrite {
|
||||
err = en.WriteBool(z.needCopyOnWrite[zcua])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
// write "copyOnWrite"
|
||||
err = en.Append(0xab, 0x63, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteBool(z.copyOnWrite)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// write "conserz"
|
||||
err = en.Append(0xa7, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x7a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteArrayHeader(uint32(len(z.conserz)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zxhx := range z.conserz {
|
||||
// map header, size 2
|
||||
// write "t"
|
||||
err = en.Append(0x82, 0xa1, 0x74)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = en.WriteUint8(uint8(z.conserz[zxhx].t))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// write "r"
|
||||
err = en.Append(0xa1, 0x72)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = z.conserz[zxhx].r.EncodeMsg(en)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: MarshalMsg implements msgp.Marshaler
|
||||
func (z *roaringArray) MarshalMsg(b []byte) (o []byte, err error) {
|
||||
o = msgp.Require(b, z.Msgsize())
|
||||
// map header, size 4
|
||||
// string "keys"
|
||||
o = append(o, 0x84, 0xa4, 0x6b, 0x65, 0x79, 0x73)
|
||||
o = msgp.AppendArrayHeader(o, uint32(len(z.keys)))
|
||||
for zhct := range z.keys {
|
||||
o = msgp.AppendUint16(o, z.keys[zhct])
|
||||
}
|
||||
// string "needCopyOnWrite"
|
||||
o = append(o, 0xaf, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
|
||||
o = msgp.AppendArrayHeader(o, uint32(len(z.needCopyOnWrite)))
|
||||
for zcua := range z.needCopyOnWrite {
|
||||
o = msgp.AppendBool(o, z.needCopyOnWrite[zcua])
|
||||
}
|
||||
// string "copyOnWrite"
|
||||
o = append(o, 0xab, 0x63, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
|
||||
o = msgp.AppendBool(o, z.copyOnWrite)
|
||||
// string "conserz"
|
||||
o = append(o, 0xa7, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x7a)
|
||||
o = msgp.AppendArrayHeader(o, uint32(len(z.conserz)))
|
||||
for zxhx := range z.conserz {
|
||||
// map header, size 2
|
||||
// string "t"
|
||||
o = append(o, 0x82, 0xa1, 0x74)
|
||||
o = msgp.AppendUint8(o, uint8(z.conserz[zxhx].t))
|
||||
// string "r"
|
||||
o = append(o, 0xa1, 0x72)
|
||||
o, err = z.conserz[zxhx].r.MarshalMsg(o)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
|
||||
func (z *roaringArray) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zrsw uint32
|
||||
zrsw, bts, err = msgp.ReadMapHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zrsw > 0 {
|
||||
zrsw--
|
||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "keys":
|
||||
var zxpk uint32
|
||||
zxpk, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.keys) >= int(zxpk) {
|
||||
z.keys = (z.keys)[:zxpk]
|
||||
} else {
|
||||
z.keys = make([]uint16, zxpk)
|
||||
}
|
||||
for zhct := range z.keys {
|
||||
z.keys[zhct], bts, err = msgp.ReadUint16Bytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
case "needCopyOnWrite":
|
||||
var zdnj uint32
|
||||
zdnj, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.needCopyOnWrite) >= int(zdnj) {
|
||||
z.needCopyOnWrite = (z.needCopyOnWrite)[:zdnj]
|
||||
} else {
|
||||
z.needCopyOnWrite = make([]bool, zdnj)
|
||||
}
|
||||
for zcua := range z.needCopyOnWrite {
|
||||
z.needCopyOnWrite[zcua], bts, err = msgp.ReadBoolBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
case "copyOnWrite":
|
||||
z.copyOnWrite, bts, err = msgp.ReadBoolBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "conserz":
|
||||
var zobc uint32
|
||||
zobc, bts, err = msgp.ReadArrayHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if cap(z.conserz) >= int(zobc) {
|
||||
z.conserz = (z.conserz)[:zobc]
|
||||
} else {
|
||||
z.conserz = make([]containerSerz, zobc)
|
||||
}
|
||||
for zxhx := range z.conserz {
|
||||
var zsnv uint32
|
||||
zsnv, bts, err = msgp.ReadMapHeaderBytes(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for zsnv > 0 {
|
||||
zsnv--
|
||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "t":
|
||||
{
|
||||
var zkgt uint8
|
||||
zkgt, bts, err = msgp.ReadUint8Bytes(bts)
|
||||
z.conserz[zxhx].t = contype(zkgt)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case "r":
|
||||
bts, err = z.conserz[zxhx].r.UnmarshalMsg(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
bts, err = msgp.Skip(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
bts, err = msgp.Skip(bts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
o = bts
|
||||
return
|
||||
}
|
||||
|
||||
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
||||
func (z *roaringArray) Msgsize() (s int) {
|
||||
s = 1 + 5 + msgp.ArrayHeaderSize + (len(z.keys) * (msgp.Uint16Size)) + 16 + msgp.ArrayHeaderSize + (len(z.needCopyOnWrite) * (msgp.BoolSize)) + 12 + msgp.BoolSize + 8 + msgp.ArrayHeaderSize
|
||||
for zxhx := range z.conserz {
|
||||
s += 1 + 2 + msgp.Uint8Size + 2 + z.conserz[zxhx].r.Msgsize()
|
||||
}
|
||||
return
|
||||
}
|
|
@ -44,16 +44,11 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
//go:generate msgp -unexported
|
||||
|
||||
// runContainer16 does run-length encoding of sets of
|
||||
// uint16 integers.
|
||||
type runContainer16 struct {
|
||||
iv []interval16
|
||||
card int64
|
||||
|
||||
// avoid allocation during search
|
||||
myOpts searchOptions `msg:"-"`
|
||||
}
|
||||
|
||||
// interval16 is the internal to runContainer16
|
||||
|
@ -120,8 +115,6 @@ func (p uint16Slice) Less(i, j int) bool { return p[i] < p[j] }
|
|||
// Swap swaps elements i and j.
|
||||
func (p uint16Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
//msgp:ignore addHelper
|
||||
|
||||
// addHelper helps build a runContainer16.
|
||||
type addHelper16 struct {
|
||||
runstart uint16
|
||||
|
@ -617,10 +610,7 @@ func (rc *runContainer16) unionCardinality(b *runContainer16) uint64 {
|
|||
|
||||
// indexOfIntervalAtOrAfter is a helper for union.
|
||||
func (rc *runContainer16) indexOfIntervalAtOrAfter(key int64, startIndex int64) int64 {
|
||||
rc.myOpts.startIndex = startIndex
|
||||
rc.myOpts.endxIndex = 0
|
||||
|
||||
w, already, _ := rc.search(key, &rc.myOpts)
|
||||
w, already, _ := rc.searchRange(key, startIndex, 0)
|
||||
if already {
|
||||
return w
|
||||
}
|
||||
|
@ -844,7 +834,7 @@ toploop:
|
|||
|
||||
// get returns true iff key is in the container.
|
||||
func (rc *runContainer16) contains(key uint16) bool {
|
||||
_, in, _ := rc.search(int64(key), nil)
|
||||
_, in, _ := rc.search(int64(key))
|
||||
return in
|
||||
}
|
||||
|
||||
|
@ -853,22 +843,7 @@ func (rc *runContainer16) numIntervals() int {
|
|||
return len(rc.iv)
|
||||
}
|
||||
|
||||
// searchOptions allows us to accelerate search with
|
||||
// prior knowledge of (mostly lower) bounds. This is used by Union
|
||||
// and Intersect.
|
||||
type searchOptions struct {
|
||||
// start here instead of at 0
|
||||
startIndex int64
|
||||
|
||||
// upper bound instead of len(rc.iv);
|
||||
// endxIndex == 0 means ignore the bound and use
|
||||
// endxIndex == n ==len(rc.iv) which is also
|
||||
// naturally the default for search()
|
||||
// when opt = nil.
|
||||
endxIndex int64
|
||||
}
|
||||
|
||||
// search returns alreadyPresent to indicate if the
|
||||
// searchRange returns alreadyPresent to indicate if the
|
||||
// key is already in one of our interval16s.
|
||||
//
|
||||
// If key is alreadyPresent, then whichInterval16 tells
|
||||
|
@ -892,24 +867,16 @@ type searchOptions struct {
|
|||
//
|
||||
// runContainer16.search always returns whichInterval16 < len(rc.iv).
|
||||
//
|
||||
// If not nil, opts can be used to further restrict
|
||||
// the search space.
|
||||
// The search space is from startIndex to endxIndex. If endxIndex is set to zero, then there
|
||||
// no upper bound.
|
||||
//
|
||||
func (rc *runContainer16) search(key int64, opts *searchOptions) (whichInterval16 int64, alreadyPresent bool, numCompares int) {
|
||||
func (rc *runContainer16) searchRange(key int64, startIndex int64, endxIndex int64) (whichInterval16 int64, alreadyPresent bool, numCompares int) {
|
||||
n := int64(len(rc.iv))
|
||||
if n == 0 {
|
||||
return -1, false, 0
|
||||
}
|
||||
|
||||
startIndex := int64(0)
|
||||
endxIndex := n
|
||||
if opts != nil {
|
||||
startIndex = opts.startIndex
|
||||
|
||||
// let endxIndex == 0 mean no effect
|
||||
if opts.endxIndex > 0 {
|
||||
endxIndex = opts.endxIndex
|
||||
}
|
||||
if endxIndex == 0 {
|
||||
endxIndex = n
|
||||
}
|
||||
|
||||
// sort.Search returns the smallest index i
|
||||
|
@ -979,6 +946,34 @@ func (rc *runContainer16) search(key int64, opts *searchOptions) (whichInterval1
|
|||
return
|
||||
}
|
||||
|
||||
// search returns alreadyPresent to indicate if the
|
||||
// key is already in one of our interval16s.
|
||||
//
|
||||
// If key is alreadyPresent, then whichInterval16 tells
|
||||
// you where.
|
||||
//
|
||||
// If key is not already present, then whichInterval16 is
|
||||
// set as follows:
|
||||
//
|
||||
// a) whichInterval16 == len(rc.iv)-1 if key is beyond our
|
||||
// last interval16 in rc.iv;
|
||||
//
|
||||
// b) whichInterval16 == -1 if key is before our first
|
||||
// interval16 in rc.iv;
|
||||
//
|
||||
// c) whichInterval16 is set to the minimum index of rc.iv
|
||||
// which comes strictly before the key;
|
||||
// so rc.iv[whichInterval16].last < key,
|
||||
// and if whichInterval16+1 exists, then key < rc.iv[whichInterval16+1].start
|
||||
// (Note that whichInterval16+1 won't exist when
|
||||
// whichInterval16 is the last interval.)
|
||||
//
|
||||
// runContainer16.search always returns whichInterval16 < len(rc.iv).
|
||||
//
|
||||
func (rc *runContainer16) search(key int64) (whichInterval16 int64, alreadyPresent bool, numCompares int) {
|
||||
return rc.searchRange(key, 0, 0)
|
||||
}
|
||||
|
||||
// cardinality returns the count of the integers stored in the
|
||||
// runContainer16.
|
||||
func (rc *runContainer16) cardinality() int64 {
|
||||
|
@ -1072,7 +1067,7 @@ func (rc *runContainer16) Add(k uint16) (wasNew bool) {
|
|||
|
||||
k64 := int64(k)
|
||||
|
||||
index, present, _ := rc.search(k64, nil)
|
||||
index, present, _ := rc.search(k64)
|
||||
if present {
|
||||
return // already there
|
||||
}
|
||||
|
@ -1147,8 +1142,6 @@ func (rc *runContainer16) Add(k uint16) (wasNew bool) {
|
|||
return
|
||||
}
|
||||
|
||||
//msgp:ignore runIterator
|
||||
|
||||
// runIterator16 advice: you must call hasNext()
|
||||
// before calling next()/peekNext() to insure there are contents.
|
||||
type runIterator16 struct {
|
||||
|
@ -1207,13 +1200,8 @@ func (ri *runIterator16) advanceIfNeeded(minval uint16) {
|
|||
return
|
||||
}
|
||||
|
||||
opt := &searchOptions{
|
||||
startIndex: ri.curIndex,
|
||||
endxIndex: int64(len(ri.rc.iv)),
|
||||
}
|
||||
|
||||
// interval cannot be -1 because of minval > peekNext
|
||||
interval, isPresent, _ := ri.rc.search(int64(minval), opt)
|
||||
interval, isPresent, _ := ri.rc.searchRange(int64(minval), ri.curIndex, int64(len(ri.rc.iv)))
|
||||
|
||||
// if the minval is present, set the curPosIndex at the right position
|
||||
if isPresent {
|
||||
|
@ -1366,7 +1354,7 @@ func (ri *runIterator16) nextMany64(hs uint64, buf []uint64) int {
|
|||
func (rc *runContainer16) removeKey(key uint16) (wasPresent bool) {
|
||||
|
||||
var index int64
|
||||
index, wasPresent, _ = rc.search(int64(key), nil)
|
||||
index, wasPresent, _ = rc.search(int64(key))
|
||||
if !wasPresent {
|
||||
return // already removed, nothing to do.
|
||||
}
|
||||
|
@ -1458,11 +1446,7 @@ func intersectWithLeftover16(astart, alast, bstart, blast int64) (isOverlap, isL
|
|||
}
|
||||
|
||||
func (rc *runContainer16) findNextIntervalThatIntersectsStartingFrom(startIndex int64, key int64) (index int64, done bool) {
|
||||
|
||||
rc.myOpts.startIndex = startIndex
|
||||
rc.myOpts.endxIndex = 0
|
||||
|
||||
w, _, _ := rc.search(key, &rc.myOpts)
|
||||
w, _, _ := rc.searchRange(key, startIndex, 0)
|
||||
// rc.search always returns w < len(rc.iv)
|
||||
if w < startIndex {
|
||||
// not found and comes before lower bound startIndex,
|
||||
|
@ -1603,8 +1587,8 @@ func (rc *runContainer16) isubtract(del interval16) {
|
|||
}
|
||||
|
||||
// INVAR there is some intersection between rc and del
|
||||
istart, startAlready, _ := rc.search(int64(del.start), nil)
|
||||
ilast, lastAlready, _ := rc.search(int64(del.last()), nil)
|
||||
istart, startAlready, _ := rc.search(int64(del.start))
|
||||
ilast, lastAlready, _ := rc.search(int64(del.last()))
|
||||
rc.card = -1
|
||||
if istart == -1 {
|
||||
if ilast == n-1 && !lastAlready {
|
||||
|
@ -2356,7 +2340,7 @@ func (rc *runContainer16) getCardinality() int {
|
|||
func (rc *runContainer16) rank(x uint16) int {
|
||||
n := int64(len(rc.iv))
|
||||
xx := int64(x)
|
||||
w, already, _ := rc.search(xx, nil)
|
||||
w, already, _ := rc.search(xx)
|
||||
if w < 0 {
|
||||
return 0
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,8 +3,6 @@ package roaring
|
|||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
|
||||
"github.com/tinylib/msgp/msgp"
|
||||
)
|
||||
|
||||
// writeTo for runContainer16 follows this
|
||||
|
@ -19,16 +17,3 @@ func (b *runContainer16) writeTo(stream io.Writer) (int, error) {
|
|||
}
|
||||
return stream.Write(buf)
|
||||
}
|
||||
|
||||
func (b *runContainer16) writeToMsgpack(stream io.Writer) (int, error) {
|
||||
bts, err := b.MarshalMsg(nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return stream.Write(bts)
|
||||
}
|
||||
|
||||
func (b *runContainer16) readFromMsgpack(stream io.Reader) (int, error) {
|
||||
err := msgp.Decode(stream, b)
|
||||
return 0, err
|
||||
}
|
||||
|
|
|
@ -177,6 +177,7 @@ func IsPrintableASCII(str string) bool
|
|||
func IsRFC3339(str string) bool
|
||||
func IsRFC3339WithoutZone(str string) bool
|
||||
func IsRGBcolor(str string) bool
|
||||
func IsRegex(str string) bool
|
||||
func IsRequestURI(rawurl string) bool
|
||||
func IsRequestURL(rawurl string) bool
|
||||
func IsRipeMD128(str string) bool
|
||||
|
@ -203,6 +204,7 @@ func IsUUID(str string) bool
|
|||
func IsUUIDv3(str string) bool
|
||||
func IsUUIDv4(str string) bool
|
||||
func IsUUIDv5(str string) bool
|
||||
func IsULID(str string) bool
|
||||
func IsUnixTime(str string) bool
|
||||
func IsUpperCase(str string) bool
|
||||
func IsVariableWidth(str string) bool
|
||||
|
@ -382,6 +384,7 @@ Here is a list of available validators for struct fields (validator - used funct
|
|||
"rfc3339WithoutZone": IsRFC3339WithoutZone,
|
||||
"ISO3166Alpha2": IsISO3166Alpha2,
|
||||
"ISO3166Alpha3": IsISO3166Alpha3,
|
||||
"ulid": IsULID,
|
||||
```
|
||||
Validators with parameters
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ const (
|
|||
SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
|
||||
WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
|
||||
UnixPath string = `^(/[^/\x00]*)+/?$`
|
||||
WinARPath string = `^(?:(?:[a-zA-Z]:|\\\\[a-z0-9_.$●-]+\\[a-z0-9_.$●-]+)\\|\\?[^\\/:*?"<>|\r\n]+\\?)(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
|
||||
UnixARPath string = `^((\.{0,2}/)?([^/\x00]*))+/?$`
|
||||
Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
|
||||
tagName string = "valid"
|
||||
hasLowerCase string = ".*[[:lower:]]"
|
||||
|
@ -50,6 +52,7 @@ const (
|
|||
hasWhitespaceOnly string = "^[[:space:]]+$"
|
||||
IMEI string = "^[0-9a-f]{14}$|^\\d{15}$|^\\d{18}$"
|
||||
IMSI string = "^\\d{14,15}$"
|
||||
E164 string = `^\+?[1-9]\d{1,14}$`
|
||||
)
|
||||
|
||||
// Used by IsFilePath func
|
||||
|
@ -97,6 +100,8 @@ var (
|
|||
rxSSN = regexp.MustCompile(SSN)
|
||||
rxWinPath = regexp.MustCompile(WinPath)
|
||||
rxUnixPath = regexp.MustCompile(UnixPath)
|
||||
rxARWinPath = regexp.MustCompile(WinARPath)
|
||||
rxARUnixPath = regexp.MustCompile(UnixARPath)
|
||||
rxSemver = regexp.MustCompile(Semver)
|
||||
rxHasLowerCase = regexp.MustCompile(hasLowerCase)
|
||||
rxHasUpperCase = regexp.MustCompile(hasUpperCase)
|
||||
|
@ -104,4 +109,5 @@ var (
|
|||
rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly)
|
||||
rxIMEI = regexp.MustCompile(IMEI)
|
||||
rxIMSI = regexp.MustCompile(IMSI)
|
||||
rxE164 = regexp.MustCompile(E164)
|
||||
)
|
||||
|
|
|
@ -165,6 +165,7 @@ var TagMap = map[string]Validator{
|
|||
"ISO3166Alpha3": IsISO3166Alpha3,
|
||||
"ISO4217": IsISO4217,
|
||||
"IMEI": IsIMEI,
|
||||
"ulid": IsULID,
|
||||
}
|
||||
|
||||
// ISO3166Entry stores country codes
|
||||
|
|
|
@ -361,9 +361,96 @@ func IsUUID(str string) bool {
|
|||
return rxUUID.MatchString(str)
|
||||
}
|
||||
|
||||
// Byte to index table for O(1) lookups when unmarshaling.
|
||||
// We use 0xFF as sentinel value for invalid indexes.
|
||||
var ulidDec = [...]byte{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
||||
0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
|
||||
0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, 0x1D, 0x1E,
|
||||
0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
|
||||
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14,
|
||||
0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
|
||||
0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
}
|
||||
|
||||
// EncodedSize is the length of a text encoded ULID.
|
||||
const ulidEncodedSize = 26
|
||||
|
||||
// IsULID checks if the string is a ULID.
|
||||
//
|
||||
// Implementation got from:
|
||||
// https://github.com/oklog/ulid (Apache-2.0 License)
|
||||
//
|
||||
func IsULID(str string) bool {
|
||||
// Check if a base32 encoded ULID is the right length.
|
||||
if len(str) != ulidEncodedSize {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if all the characters in a base32 encoded ULID are part of the
|
||||
// expected base32 character set.
|
||||
if ulidDec[str[0]] == 0xFF ||
|
||||
ulidDec[str[1]] == 0xFF ||
|
||||
ulidDec[str[2]] == 0xFF ||
|
||||
ulidDec[str[3]] == 0xFF ||
|
||||
ulidDec[str[4]] == 0xFF ||
|
||||
ulidDec[str[5]] == 0xFF ||
|
||||
ulidDec[str[6]] == 0xFF ||
|
||||
ulidDec[str[7]] == 0xFF ||
|
||||
ulidDec[str[8]] == 0xFF ||
|
||||
ulidDec[str[9]] == 0xFF ||
|
||||
ulidDec[str[10]] == 0xFF ||
|
||||
ulidDec[str[11]] == 0xFF ||
|
||||
ulidDec[str[12]] == 0xFF ||
|
||||
ulidDec[str[13]] == 0xFF ||
|
||||
ulidDec[str[14]] == 0xFF ||
|
||||
ulidDec[str[15]] == 0xFF ||
|
||||
ulidDec[str[16]] == 0xFF ||
|
||||
ulidDec[str[17]] == 0xFF ||
|
||||
ulidDec[str[18]] == 0xFF ||
|
||||
ulidDec[str[19]] == 0xFF ||
|
||||
ulidDec[str[20]] == 0xFF ||
|
||||
ulidDec[str[21]] == 0xFF ||
|
||||
ulidDec[str[22]] == 0xFF ||
|
||||
ulidDec[str[23]] == 0xFF ||
|
||||
ulidDec[str[24]] == 0xFF ||
|
||||
ulidDec[str[25]] == 0xFF {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if the first character in a base32 encoded ULID will overflow. This
|
||||
// happens because the base32 representation encodes 130 bits, while the
|
||||
// ULID is only 128 bits.
|
||||
//
|
||||
// See https://github.com/oklog/ulid/issues/9 for details.
|
||||
if str[0] > '7' {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// IsCreditCard checks if the string is a credit card.
|
||||
func IsCreditCard(str string) bool {
|
||||
sanitized := notNumberRegexp.ReplaceAllString(str, "")
|
||||
sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "")
|
||||
if !rxCreditCard.MatchString(sanitized) {
|
||||
return false
|
||||
}
|
||||
|
@ -509,6 +596,27 @@ func IsFilePath(str string) (bool, int) {
|
|||
return false, Unknown
|
||||
}
|
||||
|
||||
//IsWinFilePath checks both relative & absolute paths in Windows
|
||||
func IsWinFilePath(str string) bool {
|
||||
if rxARWinPath.MatchString(str) {
|
||||
//check windows path limit see:
|
||||
// http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
|
||||
if len(str[3:]) > 32767 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//IsUnixFilePath checks both relative & absolute paths in Unix
|
||||
func IsUnixFilePath(str string) bool {
|
||||
if rxARUnixPath.MatchString(str) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsDataURI checks if a string is base64 encoded data URI such as an image
|
||||
func IsDataURI(str string) bool {
|
||||
dataURI := strings.Split(str, ",")
|
||||
|
@ -586,11 +694,13 @@ func IsHash(str string, algorithm string) bool {
|
|||
len = "40"
|
||||
} else if algo == "tiger192" {
|
||||
len = "48"
|
||||
} else if algo == "sha256" {
|
||||
} else if algo == "sha3-224" {
|
||||
len = "56"
|
||||
} else if algo == "sha256" || algo == "sha3-256" {
|
||||
len = "64"
|
||||
} else if algo == "sha384" {
|
||||
} else if algo == "sha384" || algo == "sha3-384" {
|
||||
len = "96"
|
||||
} else if algo == "sha512" {
|
||||
} else if algo == "sha512" || algo == "sha3-512" {
|
||||
len = "128"
|
||||
} else {
|
||||
return false
|
||||
|
@ -599,6 +709,26 @@ func IsHash(str string, algorithm string) bool {
|
|||
return Matches(str, "^[a-f0-9]{"+len+"}$")
|
||||
}
|
||||
|
||||
// IsSHA3224 checks is a string is a SHA3-224 hash. Alias for `IsHash(str, "sha3-224")`
|
||||
func IsSHA3224(str string) bool {
|
||||
return IsHash(str, "sha3-224")
|
||||
}
|
||||
|
||||
// IsSHA3256 checks is a string is a SHA3-256 hash. Alias for `IsHash(str, "sha3-256")`
|
||||
func IsSHA3256(str string) bool {
|
||||
return IsHash(str, "sha3-256")
|
||||
}
|
||||
|
||||
// IsSHA3384 checks is a string is a SHA3-384 hash. Alias for `IsHash(str, "sha3-384")`
|
||||
func IsSHA3384(str string) bool {
|
||||
return IsHash(str, "sha3-384")
|
||||
}
|
||||
|
||||
// IsSHA3512 checks is a string is a SHA3-512 hash. Alias for `IsHash(str, "sha3-512")`
|
||||
func IsSHA3512(str string) bool {
|
||||
return IsHash(str, "sha3-512")
|
||||
}
|
||||
|
||||
// IsSHA512 checks is a string is a SHA512 hash. Alias for `IsHash(str, "sha512")`
|
||||
func IsSHA512(str string) bool {
|
||||
return IsHash(str, "sha512")
|
||||
|
@ -819,6 +949,14 @@ func IsRsaPublicKey(str string, keylen int) bool {
|
|||
return bitlen == int(keylen)
|
||||
}
|
||||
|
||||
// IsRegex checks if a give string is a valid regex with RE2 syntax or not
|
||||
func IsRegex(str string) bool {
|
||||
if _, err := regexp.Compile(str); err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func toJSONName(tag string) string {
|
||||
if tag == "" {
|
||||
return ""
|
||||
|
@ -1625,3 +1763,7 @@ func (sv stringValues) Len() int { return len(sv) }
|
|||
func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
|
||||
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
|
||||
func (sv stringValues) get(i int) string { return sv[i].String() }
|
||||
|
||||
func IsE164(str string) bool {
|
||||
return rxE164.MatchString(str)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
*.test
|
||||
*.out
|
||||
.devcontainer/
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 Salvador Cavadini
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,52 @@
|
|||
# garif
|
||||
|
||||
A GO package to create and manipulate SARIF logs.
|
||||
|
||||
SARIF, from _Static Analysis Results Interchange Format_, is a standard JSON-based format for the output of static analysis tools defined and promoted by [OASIS](https://www.oasis-open.org/).
|
||||
|
||||
Current supported version of the standard is [SARIF-v2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html
|
||||
).
|
||||
|
||||
## Usage
|
||||
|
||||
The package provides access to every element of the SARIF model, therefore you are free to manipulate it at every detail.
|
||||
|
||||
The package also provides constructors functions (`New...`) and decorators methods (`With...`) that simplify the creation of SARIF files for common use cases.
|
||||
|
||||
Using these constructors and decorators we can easily create the example SARIF file of the [Microsoft SARIF pages](https://github.com/microsoft/sarif-tutorials/blob/master/docs/1-Introduction.md)
|
||||
|
||||
|
||||
```go
|
||||
import to `github.com/chavacava/garif`
|
||||
|
||||
// ...
|
||||
|
||||
rule := garif.NewRule("no-unused-vars").
|
||||
WithHelpUri("https://eslint.org/docs/rules/no-unused-vars").
|
||||
WithShortDescription("disallow unused variables").
|
||||
WithProperties("category", "Variables")
|
||||
|
||||
driver := garif.NewDriver("ESLint").
|
||||
WithInformationUri("https://eslint.org").
|
||||
WithRules(rule)
|
||||
|
||||
run := garif.NewRun(NewTool(driver)).
|
||||
WithArtifactsURIs("file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js")
|
||||
|
||||
run.WithResult(rule.Id, "'x' is assigned a value but never used.", "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js", 1, 5)
|
||||
|
||||
logFile := garif.NewLogFile([]*Run{run}, Version210)
|
||||
|
||||
logFile.Write(os.Stdout)
|
||||
```
|
||||
|
||||
## Why this package?
|
||||
This package was initiated during my works on adding to [`revive`](https://github.com/mgechev/revive) a SARIF output formatter.
|
||||
I've tried to use [go-sarif](https://github.com/owenrumney/go-sarif) by [Owen Rumney](https://github.com/owenrumney) but it is too focused in the use case of the static analyzer [tfsec](https://tfsec.dev) so I've decided to create a package flexible enough to generate SARIF files in broader cases.
|
||||
|
||||
## More information about SARIF
|
||||
For more information about SARIF, you can visit the [Oasis Open](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif) site.
|
||||
|
||||
|
||||
## Contributing
|
||||
Of course, contributions are welcome!
|
|
@ -0,0 +1,338 @@
|
|||
package garif
|
||||
|
||||
// NewAddress creates a valid Address
|
||||
func NewAddress() *Address {
|
||||
return &Address{}
|
||||
}
|
||||
|
||||
// NewArtifact creates a valid Artifact
|
||||
func NewArtifact() *Artifact {
|
||||
return &Artifact{}
|
||||
}
|
||||
|
||||
// NewArtifactChange creates a valid ArtifactChange
|
||||
func NewArtifactChange(location *ArtifactLocation, replacements ...*Replacement) *ArtifactChange {
|
||||
return &ArtifactChange{
|
||||
ArtifactLocation: location,
|
||||
Replacements: replacements,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArtifactContent creates a valid ArtifactContent
|
||||
func NewArtifactContent() *ArtifactContent {
|
||||
return &ArtifactContent{}
|
||||
}
|
||||
|
||||
// NewArtifactLocation creates a valid ArtifactLocation
|
||||
func NewArtifactLocation() *ArtifactLocation {
|
||||
return &ArtifactLocation{}
|
||||
}
|
||||
|
||||
// NewAttachment creates a valid Attachment
|
||||
func NewAttachment(location *ArtifactLocation) *Attachment {
|
||||
return &Attachment{ArtifactLocation: location}
|
||||
}
|
||||
|
||||
// NewCodeFlow creates a valid CodeFlow
|
||||
func NewCodeFlow(threadFlows ...*ThreadFlow) *CodeFlow {
|
||||
return &CodeFlow{ThreadFlows: threadFlows}
|
||||
}
|
||||
|
||||
// NewConfigurationOverride creates a valid ConfigurationOverride
|
||||
func NewConfigurationOverride(configuration *ReportingConfiguration, descriptor *ReportingDescriptorReference) *ConfigurationOverride {
|
||||
return &ConfigurationOverride{
|
||||
Configuration: configuration,
|
||||
Descriptor: descriptor,
|
||||
}
|
||||
}
|
||||
|
||||
// NewConversion creates a valid Conversion
|
||||
func NewConversion(tool *Tool) *Conversion {
|
||||
return &Conversion{Tool: tool}
|
||||
}
|
||||
|
||||
// NewEdge creates a valid Edge
|
||||
func NewEdge(id, sourceNodeId, targetNodeId string) *Edge {
|
||||
return &Edge{
|
||||
Id: id,
|
||||
SourceNodeId: sourceNodeId,
|
||||
TargetNodeId: targetNodeId,
|
||||
}
|
||||
}
|
||||
|
||||
// NewEdgeTraversal creates a valid EdgeTraversal
|
||||
func NewEdgeTraversal(edgeId string) *EdgeTraversal {
|
||||
return &EdgeTraversal{
|
||||
EdgeId: edgeId,
|
||||
}
|
||||
}
|
||||
|
||||
// NewException creates a valid Exception
|
||||
func NewException() *Exception {
|
||||
return &Exception{}
|
||||
}
|
||||
|
||||
// NewExternalProperties creates a valid ExternalProperties
|
||||
func NewExternalProperties() *ExternalProperties {
|
||||
return &ExternalProperties{}
|
||||
}
|
||||
|
||||
// NewExternalPropertyFileReference creates a valid ExternalPropertyFileReference
|
||||
func NewExternalPropertyFileReference() *ExternalPropertyFileReference {
|
||||
return &ExternalPropertyFileReference{}
|
||||
}
|
||||
|
||||
// NewExternalPropertyFileReferences creates a valid ExternalPropertyFileReferences
|
||||
func NewExternalPropertyFileReferences() *ExternalPropertyFileReferences {
|
||||
return &ExternalPropertyFileReferences{}
|
||||
}
|
||||
|
||||
// NewFix creates a valid Fix
|
||||
func NewFix(artifactChanges ...*ArtifactChange) *Fix {
|
||||
return &Fix{
|
||||
ArtifactChanges: artifactChanges,
|
||||
}
|
||||
}
|
||||
|
||||
// NewGraph creates a valid Graph
|
||||
func NewGraph() *Graph {
|
||||
return &Graph{}
|
||||
}
|
||||
|
||||
// NewGraphTraversal creates a valid GraphTraversal
|
||||
func NewGraphTraversal() *GraphTraversal {
|
||||
return &GraphTraversal{}
|
||||
}
|
||||
|
||||
// NewInvocation creates a valid Invocation
|
||||
func NewInvocation(executionSuccessful bool) *Invocation {
|
||||
return &Invocation{
|
||||
ExecutionSuccessful: executionSuccessful,
|
||||
}
|
||||
}
|
||||
|
||||
// NewLocation creates a valid Location
|
||||
func NewLocation() *Location {
|
||||
return &Location{}
|
||||
}
|
||||
|
||||
// NewLocationRelationship creates a valid LocationRelationship
|
||||
func NewLocationRelationship(target int) *LocationRelationship {
|
||||
return &LocationRelationship{
|
||||
Target: target,
|
||||
}
|
||||
}
|
||||
|
||||
type LogFileVersion string
|
||||
|
||||
const Version210 LogFileVersion = "2.1.0"
|
||||
|
||||
// NewLogFile creates a valid LogFile
|
||||
func NewLogFile(runs []*Run, version LogFileVersion) *LogFile {
|
||||
return &LogFile{
|
||||
Runs: runs,
|
||||
Version: version,
|
||||
}
|
||||
}
|
||||
|
||||
// NewLogicalLocation creates a valid LogicalLocation
|
||||
func NewLogicalLocation() *LogicalLocation {
|
||||
return &LogicalLocation{}
|
||||
}
|
||||
|
||||
// NewMessage creates a valid Message
|
||||
func NewMessage() *Message {
|
||||
return &Message{}
|
||||
}
|
||||
|
||||
// NewMessageFromText creates a valid Message with the given text
|
||||
func NewMessageFromText(text string) *Message {
|
||||
return &Message{
|
||||
Text: text,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMultiformatMessageString creates a valid MultiformatMessageString
|
||||
func NewMultiformatMessageString(text string) *MultiformatMessageString {
|
||||
return &MultiformatMessageString{
|
||||
Text: text,
|
||||
}
|
||||
}
|
||||
|
||||
// NewNode creates a valid Node
|
||||
func NewNode(id string) *Node {
|
||||
return &Node{
|
||||
Id: id,
|
||||
}
|
||||
}
|
||||
|
||||
// NewNotification creates a valid Notification
|
||||
func NewNotification(message *Message) *Notification {
|
||||
return &Notification{
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// NewPhysicalLocation creates a valid PhysicalLocation
|
||||
func NewPhysicalLocation() *PhysicalLocation {
|
||||
return &PhysicalLocation{}
|
||||
}
|
||||
|
||||
// NewPropertyBag creates a valid PropertyBag
|
||||
func NewPropertyBag() *PropertyBag {
|
||||
return &PropertyBag{}
|
||||
}
|
||||
|
||||
// NewRectangle creates a valid Rectangle
|
||||
func NewRectangle() *Rectangle {
|
||||
return &Rectangle{}
|
||||
}
|
||||
|
||||
// NewRegion creates a valid Region
|
||||
func NewRegion() *Region {
|
||||
return &Region{}
|
||||
}
|
||||
|
||||
// NewReplacement creates a valid Replacement
|
||||
func NewReplacement(deletedRegion *Region) *Replacement {
|
||||
return &Replacement{
|
||||
DeletedRegion: deletedRegion,
|
||||
}
|
||||
}
|
||||
|
||||
// NewReportingConfiguration creates a valid ReportingConfiguration
|
||||
func NewReportingConfiguration() *ReportingConfiguration {
|
||||
return &ReportingConfiguration{}
|
||||
}
|
||||
|
||||
// NewReportingDescriptor creates a valid ReportingDescriptor
|
||||
func NewReportingDescriptor(id string) *ReportingDescriptor {
|
||||
return &ReportingDescriptor{
|
||||
Id: id,
|
||||
}
|
||||
}
|
||||
|
||||
// NewRule is an alias for NewReportingDescriptor
|
||||
func NewRule(id string) *ReportingDescriptor {
|
||||
return NewReportingDescriptor(id)
|
||||
}
|
||||
|
||||
// NewReportingDescriptorReference creates a valid ReportingDescriptorReference
|
||||
func NewReportingDescriptorReference() *ReportingDescriptorReference {
|
||||
return &ReportingDescriptorReference{}
|
||||
}
|
||||
|
||||
// NewReportingDescriptorRelationship creates a valid ReportingDescriptorRelationship
|
||||
func NewReportingDescriptorRelationship(target *ReportingDescriptorReference) *ReportingDescriptorRelationship {
|
||||
return &ReportingDescriptorRelationship{
|
||||
Target: target,
|
||||
}
|
||||
}
|
||||
|
||||
// NewResult creates a valid Result
|
||||
func NewResult(message *Message) *Result {
|
||||
return &Result{
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// NewResultProvenance creates a valid ResultProvenance
|
||||
func NewResultProvenance() *ResultProvenance {
|
||||
return &ResultProvenance{}
|
||||
}
|
||||
|
||||
// NewRun creates a valid Run
|
||||
func NewRun(tool *Tool) *Run {
|
||||
return &Run{
|
||||
Tool: tool,
|
||||
}
|
||||
}
|
||||
|
||||
// NewRunAutomationDetails creates a valid RunAutomationDetails
|
||||
func NewRunAutomationDetails() *RunAutomationDetails {
|
||||
return &RunAutomationDetails{}
|
||||
}
|
||||
|
||||
// New creates a valid
|
||||
func NewSpecialLocations() *SpecialLocations {
|
||||
return &SpecialLocations{}
|
||||
}
|
||||
|
||||
// NewStack creates a valid Stack
|
||||
func NewStack(frames ...*StackFrame) *Stack {
|
||||
return &Stack{
|
||||
Frames: frames,
|
||||
}
|
||||
}
|
||||
|
||||
// NewStackFrame creates a valid StackFrame
|
||||
func NewStackFrame() *StackFrame {
|
||||
return &StackFrame{}
|
||||
}
|
||||
|
||||
// NewSuppression creates a valid Suppression
|
||||
func NewSuppression(kind string) *Suppression {
|
||||
return &Suppression{
|
||||
Kind: kind,
|
||||
}
|
||||
}
|
||||
|
||||
// NewThreadFlow creates a valid ThreadFlow
|
||||
func NewThreadFlow(locations []*ThreadFlowLocation) *ThreadFlow {
|
||||
return &ThreadFlow{
|
||||
Locations: locations,
|
||||
}
|
||||
}
|
||||
|
||||
// NewThreadFlowLocation creates a valid ThreadFlowLocation
|
||||
func NewThreadFlowLocation() *ThreadFlowLocation {
|
||||
return &ThreadFlowLocation{}
|
||||
}
|
||||
|
||||
// NewTool creates a valid Tool
|
||||
func NewTool(driver *ToolComponent) *Tool {
|
||||
return &Tool{
|
||||
Driver: driver,
|
||||
}
|
||||
}
|
||||
|
||||
// NewToolComponent creates a valid ToolComponent
|
||||
func NewToolComponent(name string) *ToolComponent {
|
||||
return &ToolComponent{
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// NewDriver is an alias for NewToolComponent
|
||||
func NewDriver(name string) *ToolComponent {
|
||||
return NewToolComponent(name)
|
||||
}
|
||||
|
||||
// NewToolComponentReference creates a valid ToolComponentReference
|
||||
func NewToolComponentReference() *ToolComponentReference {
|
||||
return &ToolComponentReference{}
|
||||
}
|
||||
|
||||
// NewTranslationMetadata creates a valid TranslationMetadata
|
||||
func NewTranslationMetadata(name string) *TranslationMetadata {
|
||||
return &TranslationMetadata{
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// NewVersionControlDetails creates a valid VersionControlDetails
|
||||
func NewVersionControlDetails(repositoryUri string) *VersionControlDetails {
|
||||
return &VersionControlDetails{
|
||||
RepositoryUri: repositoryUri,
|
||||
}
|
||||
}
|
||||
|
||||
// NewWebRequest creates a valid WebRequest
|
||||
func NewWebRequest() *WebRequest {
|
||||
return &WebRequest{}
|
||||
}
|
||||
|
||||
// NewWebResponse creates a valid WebResponse
|
||||
func NewWebResponse() *WebResponse {
|
||||
return &WebResponse{}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package garif
|
||||
|
||||
// WithLineColumn sets a physical location with the given line and column
|
||||
func (l *Location) WithLineColumn(line, column int) *Location {
|
||||
if l.PhysicalLocation == nil {
|
||||
l.PhysicalLocation = NewPhysicalLocation()
|
||||
}
|
||||
|
||||
l.PhysicalLocation.Region = NewRegion()
|
||||
l.PhysicalLocation.Region.StartLine = line
|
||||
l.PhysicalLocation.Region.StartColumn = column
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// WithURI sets a physical location with the given URI
|
||||
func (l *Location) WithURI(uri string) *Location {
|
||||
if l.PhysicalLocation == nil {
|
||||
l.PhysicalLocation = NewPhysicalLocation()
|
||||
}
|
||||
|
||||
l.PhysicalLocation.ArtifactLocation = NewArtifactLocation()
|
||||
l.PhysicalLocation.ArtifactLocation.Uri = uri
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// WithKeyValue sets (overwrites) the value of the given key
|
||||
func (b PropertyBag) WithKeyValue(key string, value interface{}) PropertyBag {
|
||||
b[key] = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithHelpUri sets the help URI for this ReportingDescriptor
|
||||
func (r *ReportingDescriptor) WithHelpUri(uri string) *ReportingDescriptor {
|
||||
r.HelpUri = uri
|
||||
return r
|
||||
}
|
||||
|
||||
// WithProperties adds the key & value to the properties of this ReportingDescriptor
|
||||
func (r *ReportingDescriptor) WithProperties(key string, value interface{}) *ReportingDescriptor {
|
||||
if r.Properties == nil {
|
||||
r.Properties = NewPropertyBag()
|
||||
}
|
||||
|
||||
r.Properties.WithKeyValue(key, value)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// WithArtifactsURIs adds the given URI as artifacts of this Run
|
||||
func (r *Run) WithArtifactsURIs(uris ...string) *Run {
|
||||
if r.Artifacts == nil {
|
||||
r.Artifacts = []*Artifact{}
|
||||
}
|
||||
|
||||
for _, uri := range uris {
|
||||
a := NewArtifact()
|
||||
a.Location = NewArtifactLocation()
|
||||
a.Location.Uri = uri
|
||||
r.Artifacts = append(r.Artifacts, a)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// WithResult adds a result to this Run
|
||||
func (r *Run) WithResult(ruleId string, message string, uri string, line int, column int) *Run {
|
||||
if r.Results == nil {
|
||||
r.Results = []*Result{}
|
||||
}
|
||||
|
||||
msg := NewMessage()
|
||||
msg.Text = message
|
||||
result := NewResult(msg)
|
||||
location := NewLocation().WithURI(uri).WithLineColumn(line, column)
|
||||
|
||||
result.Locations = append(result.Locations, location)
|
||||
result.RuleId = ruleId
|
||||
r.Results = append(r.Results, result)
|
||||
return r
|
||||
}
|
||||
|
||||
// WithInformationUri sets the information URI
|
||||
func (t *ToolComponent) WithInformationUri(uri string) *ToolComponent {
|
||||
t.InformationUri = uri
|
||||
return t
|
||||
}
|
||||
|
||||
// WithRules sets (overwrites) the rules
|
||||
func (t *ToolComponent) WithRules(rules ...*ReportingDescriptor) *ToolComponent {
|
||||
t.Rules = rules
|
||||
return t
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// Package garif defines all the GO structures required to model a SARIF log file.
|
||||
// These structures were created using the JSON-schema sarif-schema-2.1.0.json of SARIF logfiles
|
||||
// available at https://github.com/oasis-tcs/sarif-spec/tree/master/Schemata.
|
||||
//
|
||||
// The package provides constructors for all structures (see constructors.go) These constructors
|
||||
// ensure that the returned structure instantiation is valid with respect to the JSON schema and
|
||||
// should be used in place of plain structure instantiation.
|
||||
// The root structure is LogFile.
|
||||
//
|
||||
// The package provides utility decorators for the most commonly used structures (see decorators.go)
|
||||
package garif
|
|
@ -0,0 +1,5 @@
|
|||
module github.com/chavacava/garif
|
||||
|
||||
go 1.16
|
||||
|
||||
require github.com/stretchr/testify v1.7.0
|
|
@ -0,0 +1,11 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -0,0 +1,26 @@
|
|||
package garif
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Write writes the JSON
|
||||
func (l *LogFile) Write(w io.Writer) error {
|
||||
marshal, err := json.Marshal(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(marshal)
|
||||
return err
|
||||
}
|
||||
|
||||
// PrettyWrite writes indented JSON
|
||||
func (l *LogFile) PrettyWrite(w io.Writer) error {
|
||||
marshal, err := json.MarshalIndent(l, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(marshal)
|
||||
return err
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
|||
/.idea
|
||||
/.connstr
|
||||
.vscode
|
||||
.terraform
|
||||
*.tfstate*
|
||||
*.log
|
||||
*.swp
|
||||
*~
|
|
@ -0,0 +1,10 @@
|
|||
linters:
|
||||
enable:
|
||||
# basic go linters
|
||||
- gofmt
|
||||
- golint
|
||||
- govet
|
||||
|
||||
# sql related linters
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
|
@ -6,19 +6,8 @@ import (
|
|||
"context"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var _ driver.Connector = &accessTokenConnector{}
|
||||
|
||||
// accessTokenConnector wraps Connector and injects a
|
||||
// fresh access token when connecting to the database
|
||||
type accessTokenConnector struct {
|
||||
Connector
|
||||
|
||||
accessTokenProvider func() (string, error)
|
||||
}
|
||||
|
||||
// NewAccessTokenConnector creates a new connector from a DSN and a token provider.
|
||||
// The token provider func will be called when a new connection is requested and should return a valid access token.
|
||||
// The returned connector may be used with sql.OpenDB.
|
||||
|
@ -32,20 +21,10 @@ func NewAccessTokenConnector(dsn string, tokenProvider func() (string, error)) (
|
|||
return nil, err
|
||||
}
|
||||
|
||||
c := &accessTokenConnector{
|
||||
Connector: *conn,
|
||||
accessTokenProvider: tokenProvider,
|
||||
}
|
||||
return c, nil
|
||||
conn.params.fedAuthLibrary = fedAuthLibrarySecurityToken
|
||||
conn.securityTokenProvider = func(ctx context.Context) (string, error) {
|
||||
return tokenProvider()
|
||||
}
|
||||
|
||||
// Connect returns a new database connection
|
||||
func (c *accessTokenConnector) Connect(ctx context.Context) (driver.Conn, error) {
|
||||
var err error
|
||||
c.Connector.params.fedAuthAccessToken, err = c.accessTokenProvider()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("mssql: error retrieving access token: %+v", err)
|
||||
}
|
||||
|
||||
return c.Connector.Connect(ctx)
|
||||
return conn, nil
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ environment:
|
|||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
GOVERSION: 115
|
||||
SQLINSTANCE: SQL2017
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
GOVERSION: 116
|
||||
SQLINSTANCE: SQL2017
|
||||
|
||||
install:
|
||||
- set GOROOT=c:\go%GOVERSION%
|
||||
|
|
|
@ -48,8 +48,8 @@ type tdsBuffer struct {
|
|||
func newTdsBuffer(bufsize uint16, transport io.ReadWriteCloser) *tdsBuffer {
|
||||
return &tdsBuffer{
|
||||
packetSize: int(bufsize),
|
||||
wbuf: make([]byte, 1<<16),
|
||||
rbuf: make([]byte, 1<<16),
|
||||
wbuf: make([]byte, bufsize),
|
||||
rbuf: make([]byte, bufsize),
|
||||
rpos: 8,
|
||||
transport: transport,
|
||||
}
|
||||
|
@ -137,19 +137,28 @@ func (w *tdsBuffer) FinishPacket() error {
|
|||
var headerSize = binary.Size(header{})
|
||||
|
||||
func (r *tdsBuffer) readNextPacket() error {
|
||||
h := header{}
|
||||
var err error
|
||||
err = binary.Read(r.transport, binary.BigEndian, &h)
|
||||
buf := r.rbuf[:headerSize]
|
||||
_, err := io.ReadFull(r.transport, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h := header{
|
||||
PacketType: packetType(buf[0]),
|
||||
Status: buf[1],
|
||||
Size: binary.BigEndian.Uint16(buf[2:4]),
|
||||
Spid: binary.BigEndian.Uint16(buf[4:6]),
|
||||
PacketNo: buf[6],
|
||||
Pad: buf[7],
|
||||
}
|
||||
if int(h.Size) > r.packetSize {
|
||||
return errors.New("Invalid packet size, it is longer than buffer size")
|
||||
return errors.New("invalid packet size, it is longer than buffer size")
|
||||
}
|
||||
if headerSize > int(h.Size) {
|
||||
return errors.New("Invalid packet size, it is shorter than header size")
|
||||
return errors.New("invalid packet size, it is shorter than header size")
|
||||
}
|
||||
_, err = io.ReadFull(r.transport, r.rbuf[headerSize:h.Size])
|
||||
//s := base64.StdEncoding.EncodeToString(r.rbuf[headerSize:h.Size])
|
||||
//fmt.Print(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -45,7 +45,8 @@ type DataValue interface{}
|
|||
|
||||
const (
|
||||
sqlDateFormat = "2006-01-02"
|
||||
sqlTimeFormat = "2006-01-02 15:04:05.999999999Z07:00"
|
||||
sqlDateTimeFormat = "2006-01-02 15:04:05.999999999Z07:00"
|
||||
sqlTimeFormat = "15:04:05.9999999"
|
||||
)
|
||||
|
||||
func (cn *Conn) CreateBulk(table string, columns []string) (_ *Bulk) {
|
||||
|
@ -86,7 +87,7 @@ func (b *Bulk) sendBulkCommand(ctx context.Context) (err error) {
|
|||
b.bulkColumns = append(b.bulkColumns, *bulkCol)
|
||||
b.dlogf("Adding column %s %s %#x", colname, bulkCol.ColName, bulkCol.ti.TypeId)
|
||||
} else {
|
||||
return fmt.Errorf("Column %s does not exist in destination table %s", colname, b.tablename)
|
||||
return fmt.Errorf("column %s does not exist in destination table %s", colname, b.tablename)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,7 +167,7 @@ func (b *Bulk) AddRow(row []interface{}) (err error) {
|
|||
}
|
||||
|
||||
if len(row) != len(b.bulkColumns) {
|
||||
return fmt.Errorf("Row does not have the same number of columns than the destination table %d %d",
|
||||
return fmt.Errorf("row does not have the same number of columns than the destination table %d %d",
|
||||
len(row), len(b.bulkColumns))
|
||||
}
|
||||
|
||||
|
@ -215,7 +216,7 @@ func (b *Bulk) makeRowData(row []interface{}) ([]byte, error) {
|
|||
}
|
||||
|
||||
func (b *Bulk) Done() (rowcount int64, err error) {
|
||||
if b.headerSent == false {
|
||||
if !b.headerSent {
|
||||
//no rows had been sent
|
||||
return 0, nil
|
||||
}
|
||||
|
@ -233,24 +234,13 @@ func (b *Bulk) Done() (rowcount int64, err error) {
|
|||
|
||||
buf.FinishPacket()
|
||||
|
||||
tokchan := make(chan tokenStruct, 5)
|
||||
go processResponse(b.ctx, b.cn.sess, tokchan, nil)
|
||||
reader := startReading(b.cn.sess, b.ctx, nil)
|
||||
err = reader.iterateResponse()
|
||||
if err != nil {
|
||||
return 0, b.cn.checkBadConn(err)
|
||||
}
|
||||
|
||||
var rowCount int64
|
||||
for token := range tokchan {
|
||||
switch token := token.(type) {
|
||||
case doneStruct:
|
||||
if token.Status&doneCount != 0 {
|
||||
rowCount = int64(token.RowCount)
|
||||
}
|
||||
if token.isError() {
|
||||
return 0, token.getError()
|
||||
}
|
||||
case error:
|
||||
return 0, b.cn.checkBadConn(token)
|
||||
}
|
||||
}
|
||||
return rowCount, nil
|
||||
return reader.rowCount, nil
|
||||
}
|
||||
|
||||
func (b *Bulk) createColMetadata() []byte {
|
||||
|
@ -421,7 +411,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
|
|||
res.ti.Size = len(res.buffer)
|
||||
case string:
|
||||
var t time.Time
|
||||
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
|
||||
if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
|
||||
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
||||
}
|
||||
res.buffer = encodeDateTime2(t, int(col.ti.Scale))
|
||||
|
@ -437,7 +427,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
|
|||
res.ti.Size = len(res.buffer)
|
||||
case string:
|
||||
var t time.Time
|
||||
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
|
||||
if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
|
||||
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
||||
}
|
||||
res.buffer = encodeDateTimeOffset(t, int(col.ti.Scale))
|
||||
|
@ -468,7 +458,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
|
|||
case time.Time:
|
||||
t = val
|
||||
case string:
|
||||
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
|
||||
if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
|
||||
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
|
||||
}
|
||||
default:
|
||||
|
@ -485,7 +475,22 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
|
|||
} else {
|
||||
err = fmt.Errorf("mssql: invalid size of column %d", col.ti.Size)
|
||||
}
|
||||
|
||||
case typeTimeN:
|
||||
var t time.Time
|
||||
switch val := val.(type) {
|
||||
case time.Time:
|
||||
res.buffer = encodeTime(val.Hour(), val.Minute(), val.Second(), val.Nanosecond(), int(col.ti.Scale))
|
||||
res.ti.Size = len(res.buffer)
|
||||
case string:
|
||||
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
|
||||
return res, fmt.Errorf("bulk: unable to convert string to time: %v", err)
|
||||
}
|
||||
res.buffer = encodeTime(t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), int(col.ti.Scale))
|
||||
res.ti.Size = len(res.buffer)
|
||||
default:
|
||||
err = fmt.Errorf("mssql: invalid type for time column: %T %s", val, val)
|
||||
return
|
||||
}
|
||||
// case typeMoney, typeMoney4, typeMoneyN:
|
||||
case typeDecimal, typeDecimalN, typeNumeric, typeNumericN:
|
||||
prec := col.ti.Prec
|
||||
|
|
|
@ -37,11 +37,17 @@ type connectParams struct {
|
|||
failOverPartner string
|
||||
failOverPort uint64
|
||||
packetSize uint16
|
||||
fedAuthAccessToken string
|
||||
fedAuthLibrary int
|
||||
fedAuthADALWorkflow byte
|
||||
}
|
||||
|
||||
// default packet size for TDS buffer
|
||||
const defaultPacketSize = 4096
|
||||
|
||||
func parseConnectParams(dsn string) (connectParams, error) {
|
||||
var p connectParams
|
||||
p := connectParams{
|
||||
fedAuthLibrary: fedAuthLibraryReserved,
|
||||
}
|
||||
|
||||
var params map[string]string
|
||||
if strings.HasPrefix(dsn, "odbc:") {
|
||||
|
@ -65,7 +71,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
var err error
|
||||
p.logFlags, err = strconv.ParseUint(strlog, 10, 64)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("Invalid log parameter '%s': %s", strlog, err.Error())
|
||||
return p, fmt.Errorf("invalid log parameter '%s': %s", strlog, err.Error())
|
||||
}
|
||||
}
|
||||
server := params["server"]
|
||||
|
@ -87,20 +93,19 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
var err error
|
||||
p.port, err = strconv.ParseUint(strport, 10, 16)
|
||||
if err != nil {
|
||||
f := "Invalid tcp port '%v': %v"
|
||||
f := "invalid tcp port '%v': %v"
|
||||
return p, fmt.Errorf(f, strport, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-network-packet-size-server-configuration-option
|
||||
// Default packet size remains at 4096 bytes
|
||||
p.packetSize = 4096
|
||||
p.packetSize = defaultPacketSize
|
||||
strpsize, ok := params["packet size"]
|
||||
if ok {
|
||||
var err error
|
||||
psize, err := strconv.ParseUint(strpsize, 0, 16)
|
||||
if err != nil {
|
||||
f := "Invalid packet size '%v': %v"
|
||||
f := "invalid packet size '%v': %v"
|
||||
return p, fmt.Errorf(f, strpsize, err.Error())
|
||||
}
|
||||
|
||||
|
@ -123,7 +128,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
if strconntimeout, ok := params["connection timeout"]; ok {
|
||||
timeout, err := strconv.ParseUint(strconntimeout, 10, 64)
|
||||
if err != nil {
|
||||
f := "Invalid connection timeout '%v': %v"
|
||||
f := "invalid connection timeout '%v': %v"
|
||||
return p, fmt.Errorf(f, strconntimeout, err.Error())
|
||||
}
|
||||
p.conn_timeout = time.Duration(timeout) * time.Second
|
||||
|
@ -132,7 +137,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
if strdialtimeout, ok := params["dial timeout"]; ok {
|
||||
timeout, err := strconv.ParseUint(strdialtimeout, 10, 64)
|
||||
if err != nil {
|
||||
f := "Invalid dial timeout '%v': %v"
|
||||
f := "invalid dial timeout '%v': %v"
|
||||
return p, fmt.Errorf(f, strdialtimeout, err.Error())
|
||||
}
|
||||
p.dial_timeout = time.Duration(timeout) * time.Second
|
||||
|
@ -144,7 +149,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
if keepAlive, ok := params["keepalive"]; ok {
|
||||
timeout, err := strconv.ParseUint(keepAlive, 10, 64)
|
||||
if err != nil {
|
||||
f := "Invalid keepAlive value '%s': %s"
|
||||
f := "invalid keepAlive value '%s': %s"
|
||||
return p, fmt.Errorf(f, keepAlive, err.Error())
|
||||
}
|
||||
p.keepAlive = time.Duration(timeout) * time.Second
|
||||
|
@ -157,7 +162,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
var err error
|
||||
p.encrypt, err = strconv.ParseBool(encrypt)
|
||||
if err != nil {
|
||||
f := "Invalid encrypt '%s': %s"
|
||||
f := "invalid encrypt '%s': %s"
|
||||
return p, fmt.Errorf(f, encrypt, err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +174,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
var err error
|
||||
p.trustServerCertificate, err = strconv.ParseBool(trust)
|
||||
if err != nil {
|
||||
f := "Invalid trust server certificate '%s': %s"
|
||||
f := "invalid trust server certificate '%s': %s"
|
||||
return p, fmt.Errorf(f, trust, err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +214,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
if ok {
|
||||
if appintent == "ReadOnly" {
|
||||
if p.database == "" {
|
||||
return p, fmt.Errorf("Database must be specified when ApplicationIntent is ReadOnly")
|
||||
return p, fmt.Errorf("database must be specified when ApplicationIntent is ReadOnly")
|
||||
}
|
||||
p.typeFlags |= fReadOnlyIntent
|
||||
}
|
||||
|
@ -225,7 +230,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
var err error
|
||||
p.failOverPort, err = strconv.ParseUint(failOverPort, 0, 16)
|
||||
if err != nil {
|
||||
f := "Invalid tcp port '%v': %v"
|
||||
f := "invalid tcp port '%v': %v"
|
||||
return p, fmt.Errorf(f, failOverPort, err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -233,6 +238,30 @@ func parseConnectParams(dsn string) (connectParams, error) {
|
|||
return p, nil
|
||||
}
|
||||
|
||||
// convert connectionParams to url style connection string
|
||||
// used mostly for testing
|
||||
func (p connectParams) toUrl() *url.URL {
|
||||
q := url.Values{}
|
||||
if p.database != "" {
|
||||
q.Add("database", p.database)
|
||||
}
|
||||
if p.logFlags != 0 {
|
||||
q.Add("log", strconv.FormatUint(p.logFlags, 10))
|
||||
}
|
||||
res := url.URL{
|
||||
Scheme: "sqlserver",
|
||||
Host: p.host,
|
||||
User: url.UserPassword(p.user, p.password),
|
||||
}
|
||||
if p.instance != "" {
|
||||
res.Path = p.instance
|
||||
}
|
||||
if len(q) > 0 {
|
||||
res.RawQuery = q.Encode()
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func splitConnectionString(dsn string) (res map[string]string) {
|
||||
res = map[string]string{}
|
||||
parts := strings.Split(dsn, ";")
|
||||
|
@ -340,7 +369,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
|
|||
case parserStateBeforeKey:
|
||||
switch {
|
||||
case c == '=':
|
||||
return res, fmt.Errorf("Unexpected character = at index %d. Expected start of key or semi-colon or whitespace.", i)
|
||||
return res, fmt.Errorf("unexpected character = at index %d. Expected start of key or semi-colon or whitespace", i)
|
||||
case !unicode.IsSpace(c) && c != ';':
|
||||
state = parserStateKey
|
||||
key += string(c)
|
||||
|
@ -419,7 +448,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
|
|||
case unicode.IsSpace(c):
|
||||
// Ignore whitespace
|
||||
default:
|
||||
return res, fmt.Errorf("Unexpected character %c at index %d. Expected semi-colon or whitespace.", c, i)
|
||||
return res, fmt.Errorf("unexpected character %c at index %d. Expected semi-colon or whitespace", c, i)
|
||||
}
|
||||
|
||||
case parserStateEndValue:
|
||||
|
@ -429,7 +458,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
|
|||
case unicode.IsSpace(c):
|
||||
// Ignore whitespace
|
||||
default:
|
||||
return res, fmt.Errorf("Unexpected character %c at index %d. Expected semi-colon or whitespace.", c, i)
|
||||
return res, fmt.Errorf("unexpected character %c at index %d. Expected semi-colon or whitespace", c, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -444,7 +473,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
|
|||
case parserStateBareValue:
|
||||
res[key] = strings.TrimRightFunc(value, unicode.IsSpace)
|
||||
case parserStateBracedValue:
|
||||
return res, fmt.Errorf("Unexpected end of braced value at index %d.", len(dsn))
|
||||
return res, fmt.Errorf("unexpected end of braced value at index %d", len(dsn))
|
||||
case parserStateBracedValueClosingBrace: // End of braced value
|
||||
res[key] = value
|
||||
case parserStateEndValue: // Okay
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package mssql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Federated authentication library affects the login data structure and message sequence.
|
||||
const (
|
||||
// fedAuthLibraryLiveIDCompactToken specifies the Microsoft Live ID Compact Token authentication scheme
|
||||
fedAuthLibraryLiveIDCompactToken = 0x00
|
||||
|
||||
// fedAuthLibrarySecurityToken specifies a token-based authentication where the token is available
|
||||
// without additional information provided during the login sequence.
|
||||
fedAuthLibrarySecurityToken = 0x01
|
||||
|
||||
// fedAuthLibraryADAL specifies a token-based authentication where a token is obtained during the
|
||||
// login sequence using the server SPN and STS URL provided by the server during login.
|
||||
fedAuthLibraryADAL = 0x02
|
||||
|
||||
// fedAuthLibraryReserved is used to indicate that no federated authentication scheme applies.
|
||||
fedAuthLibraryReserved = 0x7F
|
||||
)
|
||||
|
||||
// Federated authentication ADAL workflow affects the mechanism used to authenticate.
|
||||
const (
|
||||
// fedAuthADALWorkflowPassword uses a username/password to obtain a token from Active Directory
|
||||
fedAuthADALWorkflowPassword = 0x01
|
||||
|
||||
// fedAuthADALWorkflowPassword uses the Windows identity to obtain a token from Active Directory
|
||||
fedAuthADALWorkflowIntegrated = 0x02
|
||||
|
||||
// fedAuthADALWorkflowMSI uses the managed identity service to obtain a token
|
||||
fedAuthADALWorkflowMSI = 0x03
|
||||
)
|
||||
|
||||
// newSecurityTokenConnector creates a new connector from a DSN and a token provider.
|
||||
// When invoked, token provider implementations should contact the security token
|
||||
// service specified and obtain the appropriate token, or return an error
|
||||
// to indicate why a token is not available.
|
||||
// The returned connector may be used with sql.OpenDB.
|
||||
func newSecurityTokenConnector(dsn string, tokenProvider func(ctx context.Context) (string, error)) (*Connector, error) {
|
||||
if tokenProvider == nil {
|
||||
return nil, errors.New("mssql: tokenProvider cannot be nil")
|
||||
}
|
||||
|
||||
conn, err := NewConnector(dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn.params.fedAuthLibrary = fedAuthLibrarySecurityToken
|
||||
conn.securityTokenProvider = tokenProvider
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// newADALTokenConnector creates a new connector from a DSN and a Active Directory token provider.
|
||||
// Token provider implementations are called during federated
|
||||
// authentication login sequences where the server provides a service
|
||||
// principal name and security token service endpoint that should be used
|
||||
// to obtain the token. Implementations should contact the security token
|
||||
// service specified and obtain the appropriate token, or return an error
|
||||
// to indicate why a token is not available.
|
||||
//
|
||||
// The returned connector may be used with sql.OpenDB.
|
||||
func newActiveDirectoryTokenConnector(dsn string, adalWorkflow byte, tokenProvider func(ctx context.Context, serverSPN, stsURL string) (string, error)) (*Connector, error) {
|
||||
if tokenProvider == nil {
|
||||
return nil, errors.New("mssql: tokenProvider cannot be nil")
|
||||
}
|
||||
|
||||
conn, err := NewConnector(dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn.params.fedAuthLibrary = fedAuthLibraryADAL
|
||||
conn.params.fedAuthADALWorkflow = adalWorkflow
|
||||
conn.adalTokenProvider = tokenProvider
|
||||
|
||||
return conn, nil
|
||||
}
|
|
@ -58,6 +58,7 @@ func (d *Driver) OpenConnector(dsn string) (*Connector, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Connector{
|
||||
params: params,
|
||||
driver: d,
|
||||
|
@ -100,6 +101,12 @@ type Connector struct {
|
|||
params connectParams
|
||||
driver *Driver
|
||||
|
||||
// callback that can provide a security token during login
|
||||
securityTokenProvider func(ctx context.Context) (string, error)
|
||||
|
||||
// callback that can provide a security token during ADAL login
|
||||
adalTokenProvider func(ctx context.Context, serverSPN, stsURL string) (string, error)
|
||||
|
||||
// SessionInitSQL is executed after marking a given session to be reset.
|
||||
// When not present, the next query will still reset the session to the
|
||||
// database defaults.
|
||||
|
@ -149,14 +156,6 @@ type Conn struct {
|
|||
connectionGood bool
|
||||
|
||||
outs map[string]interface{}
|
||||
returnStatus *ReturnStatus
|
||||
}
|
||||
|
||||
func (c *Conn) setReturnStatus(s ReturnStatus) {
|
||||
if c.returnStatus == nil {
|
||||
return
|
||||
}
|
||||
*c.returnStatus = s
|
||||
}
|
||||
|
||||
func (c *Conn) checkBadConn(err error) error {
|
||||
|
@ -201,20 +200,15 @@ func (c *Conn) clearOuts() {
|
|||
}
|
||||
|
||||
func (c *Conn) simpleProcessResp(ctx context.Context) error {
|
||||
tokchan := make(chan tokenStruct, 5)
|
||||
go processResponse(ctx, c.sess, tokchan, c.outs)
|
||||
reader := startReading(c.sess, ctx, c.outs)
|
||||
c.clearOuts()
|
||||
for tok := range tokchan {
|
||||
switch token := tok.(type) {
|
||||
case doneStruct:
|
||||
if token.isError() {
|
||||
return c.checkBadConn(token.getError())
|
||||
|
||||
var resultError error
|
||||
err := reader.iterateResponse()
|
||||
if err != nil {
|
||||
return c.checkBadConn(err)
|
||||
}
|
||||
case error:
|
||||
return c.checkBadConn(token)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return resultError
|
||||
}
|
||||
|
||||
func (c *Conn) Commit() error {
|
||||
|
@ -239,7 +233,7 @@ func (c *Conn) sendCommitRequest() error {
|
|||
c.sess.log.Printf("Failed to send CommitXact with %v", err)
|
||||
}
|
||||
c.connectionGood = false
|
||||
return fmt.Errorf("Faild to send CommitXact: %v", err)
|
||||
return fmt.Errorf("faild to send CommitXact: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -266,7 +260,7 @@ func (c *Conn) sendRollbackRequest() error {
|
|||
c.sess.log.Printf("Failed to send RollbackXact with %v", err)
|
||||
}
|
||||
c.connectionGood = false
|
||||
return fmt.Errorf("Failed to send RollbackXact: %v", err)
|
||||
return fmt.Errorf("failed to send RollbackXact: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -303,7 +297,7 @@ func (c *Conn) sendBeginRequest(ctx context.Context, tdsIsolation isoLevel) erro
|
|||
c.sess.log.Printf("Failed to send BeginXact with %v", err)
|
||||
}
|
||||
c.connectionGood = false
|
||||
return fmt.Errorf("Failed to send BeginXact: %v", err)
|
||||
return fmt.Errorf("failed to send BeginXact: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -478,7 +472,7 @@ func (s *Stmt) sendQuery(args []namedValue) (err error) {
|
|||
conn.sess.log.Printf("Failed to send Rpc with %v", err)
|
||||
}
|
||||
conn.connectionGood = false
|
||||
return fmt.Errorf("Failed to send RPC: %v", err)
|
||||
return fmt.Errorf("failed to send RPC: %v", err)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
@ -595,14 +589,18 @@ func (s *Stmt) queryContext(ctx context.Context, args []namedValue) (rows driver
|
|||
}
|
||||
|
||||
func (s *Stmt) processQueryResponse(ctx context.Context) (res driver.Rows, err error) {
|
||||
tokchan := make(chan tokenStruct, 5)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
go processResponse(ctx, s.c.sess, tokchan, s.c.outs)
|
||||
reader := startReading(s.c.sess, ctx, s.c.outs)
|
||||
s.c.clearOuts()
|
||||
// process metadata
|
||||
var cols []columnStruct
|
||||
loop:
|
||||
for tok := range tokchan {
|
||||
for {
|
||||
tok, err := reader.nextToken()
|
||||
if err == nil {
|
||||
if tok == nil {
|
||||
break
|
||||
} else {
|
||||
switch token := tok.(type) {
|
||||
// By ignoring DONE token we effectively
|
||||
// skip empty result-sets.
|
||||
|
@ -616,17 +614,21 @@ loop:
|
|||
break loop
|
||||
case doneStruct:
|
||||
if token.isError() {
|
||||
// need to cleanup cancellable context
|
||||
cancel()
|
||||
return nil, s.c.checkBadConn(token.getError())
|
||||
}
|
||||
case ReturnStatus:
|
||||
s.c.setReturnStatus(token)
|
||||
case error:
|
||||
s.c.sess.setReturnStatus(token)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// need to cleanup cancellable context
|
||||
cancel()
|
||||
return nil, s.c.checkBadConn(token)
|
||||
return nil, s.c.checkBadConn(err)
|
||||
}
|
||||
}
|
||||
res = &Rows{stmt: s, tokchan: tokchan, cols: cols, cancel: cancel}
|
||||
res = &Rows{stmt: s, reader: reader, cols: cols, cancel: cancel}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -648,48 +650,46 @@ func (s *Stmt) exec(ctx context.Context, args []namedValue) (res driver.Result,
|
|||
}
|
||||
|
||||
func (s *Stmt) processExec(ctx context.Context) (res driver.Result, err error) {
|
||||
tokchan := make(chan tokenStruct, 5)
|
||||
go processResponse(ctx, s.c.sess, tokchan, s.c.outs)
|
||||
reader := startReading(s.c.sess, ctx, s.c.outs)
|
||||
s.c.clearOuts()
|
||||
var rowCount int64
|
||||
for token := range tokchan {
|
||||
switch token := token.(type) {
|
||||
case doneInProcStruct:
|
||||
if token.Status&doneCount != 0 {
|
||||
rowCount += int64(token.RowCount)
|
||||
err = reader.iterateResponse()
|
||||
if err != nil {
|
||||
return nil, s.c.checkBadConn(err)
|
||||
}
|
||||
case doneStruct:
|
||||
if token.Status&doneCount != 0 {
|
||||
rowCount += int64(token.RowCount)
|
||||
}
|
||||
if token.isError() {
|
||||
return nil, token.getError()
|
||||
}
|
||||
case ReturnStatus:
|
||||
s.c.setReturnStatus(token)
|
||||
case error:
|
||||
return nil, token
|
||||
}
|
||||
}
|
||||
return &Result{s.c, rowCount}, nil
|
||||
return &Result{s.c, reader.rowCount}, nil
|
||||
}
|
||||
|
||||
type Rows struct {
|
||||
stmt *Stmt
|
||||
cols []columnStruct
|
||||
tokchan chan tokenStruct
|
||||
|
||||
reader *tokenProcessor
|
||||
nextCols []columnStruct
|
||||
|
||||
cancel func()
|
||||
}
|
||||
|
||||
func (rc *Rows) Close() error {
|
||||
// need to add a test which returns lots of rows
|
||||
// and check closing after reading only few rows
|
||||
rc.cancel()
|
||||
for _ = range rc.tokchan {
|
||||
}
|
||||
rc.tokchan = nil
|
||||
|
||||
for {
|
||||
tok, err := rc.reader.nextToken()
|
||||
if err == nil {
|
||||
if tok == nil {
|
||||
return nil
|
||||
} else {
|
||||
// continue consuming tokens
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if err == rc.reader.ctx.Err() {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *Rows) Columns() (res []string) {
|
||||
|
@ -707,7 +707,12 @@ func (rc *Rows) Next(dest []driver.Value) error {
|
|||
if rc.nextCols != nil {
|
||||
return io.EOF
|
||||
}
|
||||
for tok := range rc.tokchan {
|
||||
for {
|
||||
tok, err := rc.reader.nextToken()
|
||||
if err == nil {
|
||||
if tok == nil {
|
||||
return io.EOF
|
||||
} else {
|
||||
switch tokdata := tok.(type) {
|
||||
case []columnStruct:
|
||||
rc.nextCols = tokdata
|
||||
|
@ -722,12 +727,14 @@ func (rc *Rows) Next(dest []driver.Value) error {
|
|||
return rc.stmt.c.checkBadConn(tokdata.getError())
|
||||
}
|
||||
case ReturnStatus:
|
||||
rc.stmt.c.setReturnStatus(tokdata)
|
||||
case error:
|
||||
return rc.stmt.c.checkBadConn(tokdata)
|
||||
rc.stmt.c.sess.setReturnStatus(tokdata)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return rc.stmt.c.checkBadConn(err)
|
||||
}
|
||||
}
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
func (rc *Rows) HasNextResultSet() bool {
|
||||
|
@ -895,35 +902,41 @@ func (c *Conn) Ping(ctx context.Context) error {
|
|||
|
||||
var _ driver.ConnBeginTx = &Conn{}
|
||||
|
||||
func convertIsolationLevel(level sql.IsolationLevel) (isoLevel, error) {
|
||||
switch level {
|
||||
case sql.LevelDefault:
|
||||
return isolationUseCurrent, nil
|
||||
case sql.LevelReadUncommitted:
|
||||
return isolationReadUncommited, nil
|
||||
case sql.LevelReadCommitted:
|
||||
return isolationReadCommited, nil
|
||||
case sql.LevelWriteCommitted:
|
||||
return isolationUseCurrent, errors.New("LevelWriteCommitted isolation level is not supported")
|
||||
case sql.LevelRepeatableRead:
|
||||
return isolationRepeatableRead, nil
|
||||
case sql.LevelSnapshot:
|
||||
return isolationSnapshot, nil
|
||||
case sql.LevelSerializable:
|
||||
return isolationSerializable, nil
|
||||
case sql.LevelLinearizable:
|
||||
return isolationUseCurrent, errors.New("LevelLinearizable isolation level is not supported")
|
||||
default:
|
||||
return isolationUseCurrent, errors.New("isolation level is not supported or unknown")
|
||||
}
|
||||
}
|
||||
|
||||
// BeginTx satisfies ConnBeginTx.
|
||||
func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||
if !c.connectionGood {
|
||||
return nil, driver.ErrBadConn
|
||||
}
|
||||
if opts.ReadOnly {
|
||||
return nil, errors.New("Read-only transactions are not supported")
|
||||
return nil, errors.New("read-only transactions are not supported")
|
||||
}
|
||||
|
||||
var tdsIsolation isoLevel
|
||||
switch sql.IsolationLevel(opts.Isolation) {
|
||||
case sql.LevelDefault:
|
||||
tdsIsolation = isolationUseCurrent
|
||||
case sql.LevelReadUncommitted:
|
||||
tdsIsolation = isolationReadUncommited
|
||||
case sql.LevelReadCommitted:
|
||||
tdsIsolation = isolationReadCommited
|
||||
case sql.LevelWriteCommitted:
|
||||
return nil, errors.New("LevelWriteCommitted isolation level is not supported")
|
||||
case sql.LevelRepeatableRead:
|
||||
tdsIsolation = isolationRepeatableRead
|
||||
case sql.LevelSnapshot:
|
||||
tdsIsolation = isolationSnapshot
|
||||
case sql.LevelSerializable:
|
||||
tdsIsolation = isolationSerializable
|
||||
case sql.LevelLinearizable:
|
||||
return nil, errors.New("LevelLinearizable isolation level is not supported")
|
||||
default:
|
||||
return nil, errors.New("Isolation level is not supported or unknown")
|
||||
tdsIsolation, err := convertIsolationLevel(sql.IsolationLevel(opts.Isolation))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.begin(ctx, tdsIsolation)
|
||||
}
|
||||
|
|
|
@ -48,5 +48,5 @@ func (c *Connector) Driver() driver.Driver {
|
|||
}
|
||||
|
||||
func (r *Result) LastInsertId() (int64, error) {
|
||||
return -1, errors.New("LastInsertId is not supported. Please use the OUTPUT clause or add `select ID = convert(bigint, SCOPE_IDENTITY())` to the end of your query.")
|
||||
return -1, errors.New("LastInsertId is not supported. Please use the OUTPUT clause or add `select ID = convert(bigint, SCOPE_IDENTITY())` to the end of your query")
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ func (c *Conn) CheckNamedValue(nv *driver.NamedValue) error {
|
|||
return nil
|
||||
case *ReturnStatus:
|
||||
*v = 0 // By default the return value should be zero.
|
||||
c.returnStatus = v
|
||||
c.sess.returnStatus = v
|
||||
return driver.ErrRemoveArgument
|
||||
case TVP:
|
||||
return nil
|
||||
|
|
|
@ -51,15 +51,15 @@ func (c timeoutConn) RemoteAddr() net.Addr {
|
|||
}
|
||||
|
||||
func (c timeoutConn) SetDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
return c.c.SetDeadline(t)
|
||||
}
|
||||
|
||||
func (c timeoutConn) SetReadDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
return c.c.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
func (c timeoutConn) SetWriteDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
return c.c.SetWriteDeadline(t)
|
||||
}
|
||||
|
||||
// this connection is used during TLS Handshake
|
||||
|
@ -75,7 +75,7 @@ func (c *tlsHandshakeConn) Read(b []byte) (n int, err error) {
|
|||
c.packetPending = false
|
||||
err = c.buf.FinishPacket()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Cannot send handshake packet: %s", err.Error())
|
||||
err = fmt.Errorf("cannot send handshake packet: %s", err.Error())
|
||||
return
|
||||
}
|
||||
c.continueRead = false
|
||||
|
@ -84,7 +84,7 @@ func (c *tlsHandshakeConn) Read(b []byte) (n int, err error) {
|
|||
var packet packetType
|
||||
packet, err = c.buf.BeginRead()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Cannot read handshake packet: %s", err.Error())
|
||||
err = fmt.Errorf("cannot read handshake packet: %s", err.Error())
|
||||
return
|
||||
}
|
||||
if packet != packPrelogin {
|
||||
|
@ -105,27 +105,27 @@ func (c *tlsHandshakeConn) Write(b []byte) (n int, err error) {
|
|||
}
|
||||
|
||||
func (c *tlsHandshakeConn) Close() error {
|
||||
panic("Not implemented")
|
||||
return c.buf.transport.Close()
|
||||
}
|
||||
|
||||
func (c *tlsHandshakeConn) LocalAddr() net.Addr {
|
||||
panic("Not implemented")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *tlsHandshakeConn) RemoteAddr() net.Addr {
|
||||
panic("Not implemented")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *tlsHandshakeConn) SetDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
func (c *tlsHandshakeConn) SetDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *tlsHandshakeConn) SetReadDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
func (c *tlsHandshakeConn) SetReadDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *tlsHandshakeConn) SetWriteDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
func (c *tlsHandshakeConn) SetWriteDeadline(_ time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// this connection just delegates all methods to it's wrapped connection
|
||||
|
@ -148,21 +148,21 @@ func (c passthroughConn) Close() error {
|
|||
}
|
||||
|
||||
func (c passthroughConn) LocalAddr() net.Addr {
|
||||
panic("Not implemented")
|
||||
return c.c.LocalAddr()
|
||||
}
|
||||
|
||||
func (c passthroughConn) RemoteAddr() net.Addr {
|
||||
panic("Not implemented")
|
||||
return c.c.RemoteAddr()
|
||||
}
|
||||
|
||||
func (c passthroughConn) SetDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
return c.c.SetDeadline(t)
|
||||
}
|
||||
|
||||
func (c passthroughConn) SetReadDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
return c.c.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
func (c passthroughConn) SetWriteDeadline(t time.Time) error {
|
||||
panic("Not implemented")
|
||||
return c.c.SetWriteDeadline(t)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"time"
|
||||
"unicode/utf16"
|
||||
|
||||
//lint:ignore SA1019 MD4 is used by legacy NTLM
|
||||
"golang.org/x/crypto/md4"
|
||||
)
|
||||
|
||||
|
@ -126,18 +127,6 @@ func createDesKey(bytes, material []byte) {
|
|||
material[7] = (byte)(bytes[6] << 1)
|
||||
}
|
||||
|
||||
func oddParity(bytes []byte) {
|
||||
for i := 0; i < len(bytes); i++ {
|
||||
b := bytes[i]
|
||||
needsParity := (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ (b >> 1)) & 0x01) == 0
|
||||
if needsParity {
|
||||
bytes[i] = bytes[i] | byte(0x01)
|
||||
} else {
|
||||
bytes[i] = bytes[i] & byte(0xfe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func encryptDes(key []byte, cleartext []byte, ciphertext []byte) {
|
||||
var desKey [8]byte
|
||||
createDesKey(key, desKey[:])
|
||||
|
|
|
@ -22,12 +22,6 @@ type param struct {
|
|||
buffer []byte
|
||||
}
|
||||
|
||||
const (
|
||||
fWithRecomp = 1
|
||||
fNoMetaData = 2
|
||||
fReuseMetaData = 4
|
||||
)
|
||||
|
||||
var (
|
||||
sp_Cursor = procId{1, ""}
|
||||
sp_CursorOpen = procId{2, ""}
|
||||
|
|
|
@ -82,19 +82,20 @@ const (
|
|||
// https://msdn.microsoft.com/en-us/library/dd304214.aspx
|
||||
const (
|
||||
packSQLBatch packetType = 1
|
||||
packRPCRequest = 3
|
||||
packReply = 4
|
||||
packRPCRequest packetType = 3
|
||||
packReply packetType = 4
|
||||
|
||||
// 2.2.1.7 Attention: https://msdn.microsoft.com/en-us/library/dd341449.aspx
|
||||
// 4.19.2 Out-of-Band Attention Signal: https://msdn.microsoft.com/en-us/library/dd305167.aspx
|
||||
packAttention = 6
|
||||
packAttention packetType = 6
|
||||
|
||||
packBulkLoadBCP = 7
|
||||
packTransMgrReq = 14
|
||||
packNormal = 15
|
||||
packLogin7 = 16
|
||||
packSSPIMessage = 17
|
||||
packPrelogin = 18
|
||||
packBulkLoadBCP packetType = 7
|
||||
packFedAuthToken packetType = 8
|
||||
packTransMgrReq packetType = 14
|
||||
packNormal packetType = 15
|
||||
packLogin7 packetType = 16
|
||||
packSSPIMessage packetType = 17
|
||||
packPrelogin packetType = 18
|
||||
)
|
||||
|
||||
// prelogin fields
|
||||
|
@ -118,6 +119,17 @@ const (
|
|||
encryptReq = 3 // Encryption is required.
|
||||
)
|
||||
|
||||
const (
|
||||
featExtSESSIONRECOVERY byte = 0x01
|
||||
featExtFEDAUTH byte = 0x02
|
||||
featExtCOLUMNENCRYPTION byte = 0x04
|
||||
featExtGLOBALTRANSACTIONS byte = 0x05
|
||||
featExtAZURESQLSUPPORT byte = 0x08
|
||||
featExtDATACLASSIFICATION byte = 0x09
|
||||
featExtUTF8SUPPORT byte = 0x0A
|
||||
featExtTERMINATOR byte = 0xFF
|
||||
)
|
||||
|
||||
type tdsSession struct {
|
||||
buf *tdsBuffer
|
||||
loginAck loginAckStruct
|
||||
|
@ -129,6 +141,7 @@ type tdsSession struct {
|
|||
log optionalLogger
|
||||
routedServer string
|
||||
routedPort uint16
|
||||
returnStatus *ReturnStatus
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -155,13 +168,13 @@ func (p keySlice) Less(i, j int) bool { return p[i] < p[j] }
|
|||
func (p keySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/dd357559.aspx
|
||||
func writePrelogin(w *tdsBuffer, fields map[uint8][]byte) error {
|
||||
func writePrelogin(packetType packetType, w *tdsBuffer, fields map[uint8][]byte) error {
|
||||
var err error
|
||||
|
||||
w.BeginPacket(packPrelogin, false)
|
||||
w.BeginPacket(packetType, false)
|
||||
offset := uint16(5*len(fields) + 1)
|
||||
keys := make(keySlice, 0, len(fields))
|
||||
for k, _ := range fields {
|
||||
for k := range fields {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Sort(keys)
|
||||
|
@ -210,12 +223,15 @@ func readPrelogin(r *tdsBuffer) (map[uint8][]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if packet_type != 4 {
|
||||
return nil, errors.New("Invalid respones, expected packet type 4, PRELOGIN RESPONSE")
|
||||
if packet_type != packReply {
|
||||
return nil, errors.New("invalid respones, expected packet type 4, PRELOGIN RESPONSE")
|
||||
}
|
||||
if len(struct_buf) == 0 {
|
||||
return nil, errors.New("invalid empty PRELOGIN response, it must contain at least one byte")
|
||||
}
|
||||
offset := 0
|
||||
results := map[uint8][]byte{}
|
||||
for true {
|
||||
for {
|
||||
rec_type := struct_buf[offset]
|
||||
if rec_type == preloginTERMINATOR {
|
||||
break
|
||||
|
@ -240,6 +256,16 @@ const (
|
|||
fIntSecurity = 0x80
|
||||
)
|
||||
|
||||
// OptionFlags3
|
||||
// http://msdn.microsoft.com/en-us/library/dd304019.aspx
|
||||
const (
|
||||
fChangePassword = 1
|
||||
fSendYukonBinaryXML = 2
|
||||
fUserInstance = 4
|
||||
fUnknownCollationHandling = 8
|
||||
fExtension = 0x10
|
||||
)
|
||||
|
||||
// TypeFlags
|
||||
const (
|
||||
// 4 bits for fSQLType
|
||||
|
@ -247,12 +273,6 @@ const (
|
|||
fReadOnlyIntent = 32
|
||||
)
|
||||
|
||||
// OptionFlags3
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/773a62b6-ee89-4c02-9e5e-344882630aac
|
||||
const (
|
||||
fExtension = 0x10
|
||||
)
|
||||
|
||||
type login struct {
|
||||
TDSVersion uint32
|
||||
PacketSize uint32
|
||||
|
@ -295,7 +315,7 @@ func (e *featureExts) Add(f featureExt) error {
|
|||
}
|
||||
id := f.featureID()
|
||||
if _, exists := e.features[id]; exists {
|
||||
f := "Login error: Feature with ID '%v' is already present in FeatureExt block."
|
||||
f := "login error: Feature with ID '%v' is already present in FeatureExt block"
|
||||
return fmt.Errorf(f, id)
|
||||
}
|
||||
if e.features == nil {
|
||||
|
@ -326,27 +346,49 @@ func (e featureExts) toBytes() []byte {
|
|||
return d
|
||||
}
|
||||
|
||||
type featureExtFedAuthSTS struct {
|
||||
// featureExtFedAuth tracks federated authentication state before and during login
|
||||
type featureExtFedAuth struct {
|
||||
// FedAuthLibrary is populated by the federated authentication provider.
|
||||
FedAuthLibrary int
|
||||
|
||||
// ADALWorkflow is populated by the federated authentication provider.
|
||||
ADALWorkflow byte
|
||||
|
||||
// FedAuthEcho is populated from the prelogin response
|
||||
FedAuthEcho bool
|
||||
|
||||
// FedAuthToken is populated during login with the value from the provider.
|
||||
FedAuthToken string
|
||||
|
||||
// Nonce is populated during login with the value from the provider.
|
||||
Nonce []byte
|
||||
|
||||
// Signature is populated during login with the value from the server.
|
||||
Signature []byte
|
||||
}
|
||||
|
||||
func (e *featureExtFedAuthSTS) featureID() byte {
|
||||
return 0x02
|
||||
func (e *featureExtFedAuth) featureID() byte {
|
||||
return featExtFEDAUTH
|
||||
}
|
||||
|
||||
func (e *featureExtFedAuthSTS) toBytes() []byte {
|
||||
func (e *featureExtFedAuth) toBytes() []byte {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
options := byte(0x01) << 1 // 0x01 => STS bFedAuthLibrary 7BIT
|
||||
options := byte(e.FedAuthLibrary) << 1
|
||||
if e.FedAuthEcho {
|
||||
options |= 1 // fFedAuthEcho
|
||||
}
|
||||
|
||||
d := make([]byte, 5)
|
||||
// Feature extension format depends on the federated auth library.
|
||||
// Options are described at
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/773a62b6-ee89-4c02-9e5e-344882630aac
|
||||
var d []byte
|
||||
|
||||
switch e.FedAuthLibrary {
|
||||
case fedAuthLibrarySecurityToken:
|
||||
d = make([]byte, 5)
|
||||
d[0] = options
|
||||
|
||||
// looks like string in
|
||||
|
@ -359,6 +401,10 @@ func (e *featureExtFedAuthSTS) toBytes() []byte {
|
|||
d = append(d, e.Nonce...)
|
||||
}
|
||||
|
||||
case fedAuthLibraryADAL:
|
||||
d = []byte{options, e.ADALWorkflow}
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
|
@ -418,7 +464,7 @@ func str2ucs2(s string) []byte {
|
|||
|
||||
func ucs22str(s []byte) (string, error) {
|
||||
if len(s)%2 != 0 {
|
||||
return "", fmt.Errorf("Illegal UCS2 string length: %d", len(s))
|
||||
return "", fmt.Errorf("illegal UCS2 string length: %d", len(s))
|
||||
}
|
||||
buf := make([]uint16, len(s)/2)
|
||||
for i := 0; i < len(s); i += 2 {
|
||||
|
@ -436,7 +482,7 @@ func manglePassword(password string) []byte {
|
|||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/dd304019.aspx
|
||||
func sendLogin(w *tdsBuffer, login login) error {
|
||||
func sendLogin(w *tdsBuffer, login *login) error {
|
||||
w.BeginPacket(packLogin7, false)
|
||||
hostname := str2ucs2(login.HostName)
|
||||
username := str2ucs2(login.UserName)
|
||||
|
@ -572,6 +618,36 @@ func sendLogin(w *tdsBuffer, login login) error {
|
|||
return w.FinishPacket()
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/827d9632-2957-4d54-b9ea-384530ae79d0
|
||||
func sendFedAuthInfo(w *tdsBuffer, fedAuth *featureExtFedAuth) (err error) {
|
||||
fedauthtoken := str2ucs2(fedAuth.FedAuthToken)
|
||||
tokenlen := len(fedauthtoken)
|
||||
datalen := 4 + tokenlen + len(fedAuth.Nonce)
|
||||
|
||||
w.BeginPacket(packFedAuthToken, false)
|
||||
err = binary.Write(w, binary.LittleEndian, uint32(datalen))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = binary.Write(w, binary.LittleEndian, uint32(tokenlen))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = w.Write(fedauthtoken)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = w.Write(fedAuth.Nonce)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return w.FinishPacket()
|
||||
}
|
||||
|
||||
func readUcs2(r io.Reader, numchars int) (res string, err error) {
|
||||
buf := make([]byte, numchars*2)
|
||||
_, err = io.ReadFull(r, buf)
|
||||
|
@ -770,12 +846,13 @@ type auth interface {
|
|||
// use the first one that allows a connection.
|
||||
func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn net.Conn, err error) {
|
||||
var ips []net.IP
|
||||
ips, err = net.LookupIP(p.host)
|
||||
if err != nil {
|
||||
ip := net.ParseIP(p.host)
|
||||
if ip == nil {
|
||||
return nil, err
|
||||
ips, err = net.LookupIP(p.host)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ips = []net.IP{ip}
|
||||
}
|
||||
if len(ips) == 1 {
|
||||
|
@ -802,7 +879,7 @@ func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn ne
|
|||
}
|
||||
// Wait for either the *first* successful connection, or all the errors
|
||||
wait_loop:
|
||||
for i, _ := range ips {
|
||||
for i := range ips {
|
||||
select {
|
||||
case conn = <-connChan:
|
||||
// Got a connection to use, close any others
|
||||
|
@ -824,12 +901,123 @@ func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn ne
|
|||
}
|
||||
// Can't do the usual err != nil check, as it is possible to have gotten an error before a successful connection
|
||||
if conn == nil {
|
||||
f := "Unable to open tcp connection with host '%v:%v': %v"
|
||||
f := "unable to open tcp connection with host '%v:%v': %v"
|
||||
return nil, fmt.Errorf(f, p.host, resolveServerPort(p.port), err.Error())
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
func preparePreloginFields(p connectParams, fe *featureExtFedAuth) map[uint8][]byte {
|
||||
instance_buf := []byte(p.instance)
|
||||
instance_buf = append(instance_buf, 0) // zero terminate instance name
|
||||
|
||||
var encrypt byte
|
||||
if p.disableEncryption {
|
||||
encrypt = encryptNotSup
|
||||
} else if p.encrypt {
|
||||
encrypt = encryptOn
|
||||
} else {
|
||||
encrypt = encryptOff
|
||||
}
|
||||
|
||||
fields := map[uint8][]byte{
|
||||
preloginVERSION: {0, 0, 0, 0, 0, 0},
|
||||
preloginENCRYPTION: {encrypt},
|
||||
preloginINSTOPT: instance_buf,
|
||||
preloginTHREADID: {0, 0, 0, 0},
|
||||
preloginMARS: {0}, // MARS disabled
|
||||
}
|
||||
|
||||
if fe.FedAuthLibrary != fedAuthLibraryReserved {
|
||||
fields[preloginFEDAUTHREQUIRED] = []byte{1}
|
||||
}
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
func interpretPreloginResponse(p connectParams, fe *featureExtFedAuth, fields map[uint8][]byte) (encrypt byte, err error) {
|
||||
// If the server returns the preloginFEDAUTHREQUIRED field, then federated authentication
|
||||
// is supported. The actual value may be 0 or 1, where 0 means either SSPI or federated
|
||||
// authentication is allowed, while 1 means only federated authentication is allowed.
|
||||
if fedAuthSupport, ok := fields[preloginFEDAUTHREQUIRED]; ok {
|
||||
if len(fedAuthSupport) != 1 {
|
||||
return 0, fmt.Errorf("Federated authentication flag length should be 1: is %d", len(fedAuthSupport))
|
||||
}
|
||||
|
||||
// We need to be able to echo the value back to the server
|
||||
fe.FedAuthEcho = fedAuthSupport[0] != 0
|
||||
} else if fe.FedAuthLibrary != fedAuthLibraryReserved {
|
||||
return 0, fmt.Errorf("Federated authentication is not supported by the server")
|
||||
}
|
||||
|
||||
encryptBytes, ok := fields[preloginENCRYPTION]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("encrypt negotiation failed")
|
||||
}
|
||||
encrypt = encryptBytes[0]
|
||||
if p.encrypt && (encrypt == encryptNotSup || encrypt == encryptOff) {
|
||||
return 0, fmt.Errorf("server does not support encryption")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func prepareLogin(ctx context.Context, c *Connector, p connectParams, log optionalLogger, auth auth, fe *featureExtFedAuth, packetSize uint32) (l *login, err error) {
|
||||
l = &login{
|
||||
TDSVersion: verTDS74,
|
||||
PacketSize: packetSize,
|
||||
Database: p.database,
|
||||
OptionFlags2: fODBC, // to get unlimited TEXTSIZE
|
||||
HostName: p.workstation,
|
||||
ServerName: p.host,
|
||||
AppName: p.appname,
|
||||
TypeFlags: p.typeFlags,
|
||||
}
|
||||
switch {
|
||||
case fe.FedAuthLibrary == fedAuthLibrarySecurityToken:
|
||||
if p.logFlags&logDebug != 0 {
|
||||
log.Println("Starting federated authentication using security token")
|
||||
}
|
||||
|
||||
fe.FedAuthToken, err = c.securityTokenProvider(ctx)
|
||||
if err != nil {
|
||||
if p.logFlags&logDebug != 0 {
|
||||
log.Printf("Failed to retrieve service principal token for federated authentication security token library: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l.FeatureExt.Add(fe)
|
||||
|
||||
case fe.FedAuthLibrary == fedAuthLibraryADAL:
|
||||
if p.logFlags&logDebug != 0 {
|
||||
log.Println("Starting federated authentication using ADAL")
|
||||
}
|
||||
|
||||
l.FeatureExt.Add(fe)
|
||||
|
||||
case auth != nil:
|
||||
if p.logFlags&logDebug != 0 {
|
||||
log.Println("Starting SSPI login")
|
||||
}
|
||||
|
||||
l.SSPI, err = auth.InitialBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l.OptionFlags2 |= fIntSecurity
|
||||
return l, nil
|
||||
|
||||
default:
|
||||
// Default to SQL server authentication with user and password
|
||||
l.UserName = p.user
|
||||
l.Password = p.password
|
||||
}
|
||||
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func connect(ctx context.Context, c *Connector, log optionalLogger, p connectParams) (res *tdsSession, err error) {
|
||||
dialCtx := ctx
|
||||
if p.dial_timeout > 0 {
|
||||
|
@ -842,24 +1030,24 @@ func connect(ctx context.Context, c *Connector, log optionalLogger, p connectPar
|
|||
// both instance name and port specified
|
||||
// when port is specified instance name is not used
|
||||
// you should not provide instance name when you provide port
|
||||
log.Println("WARN: You specified both instance name and port in the connection string, port will be used and instance name will be ignored");
|
||||
log.Println("WARN: You specified both instance name and port in the connection string, port will be used and instance name will be ignored")
|
||||
}
|
||||
if p.instance != "" && p.port == 0 {
|
||||
p.instance = strings.ToUpper(p.instance)
|
||||
d := c.getDialer(&p)
|
||||
instances, err := getInstances(dialCtx, d, p.host)
|
||||
if err != nil {
|
||||
f := "Unable to get instances from Sql Server Browser on host %v: %v"
|
||||
f := "unable to get instances from Sql Server Browser on host %v: %v"
|
||||
return nil, fmt.Errorf(f, p.host, err.Error())
|
||||
}
|
||||
strport, ok := instances[p.instance]["tcp"]
|
||||
if !ok {
|
||||
f := "No instance matching '%v' returned from host '%v'"
|
||||
f := "no instance matching '%v' returned from host '%v'"
|
||||
return nil, fmt.Errorf(f, p.instance, p.host)
|
||||
}
|
||||
port, err := strconv.ParseUint(strport, 0, 16)
|
||||
if err != nil {
|
||||
f := "Invalid tcp port returned from Sql Server Browser '%v': %v"
|
||||
f := "invalid tcp port returned from Sql Server Browser '%v': %v"
|
||||
return nil, fmt.Errorf(f, strport, err.Error())
|
||||
}
|
||||
p.port = port
|
||||
|
@ -880,25 +1068,14 @@ initiate_connection:
|
|||
logFlags: p.logFlags,
|
||||
}
|
||||
|
||||
instance_buf := []byte(p.instance)
|
||||
instance_buf = append(instance_buf, 0) // zero terminate instance name
|
||||
var encrypt byte
|
||||
if p.disableEncryption {
|
||||
encrypt = encryptNotSup
|
||||
} else if p.encrypt {
|
||||
encrypt = encryptOn
|
||||
} else {
|
||||
encrypt = encryptOff
|
||||
}
|
||||
fields := map[uint8][]byte{
|
||||
preloginVERSION: {0, 0, 0, 0, 0, 0},
|
||||
preloginENCRYPTION: {encrypt},
|
||||
preloginINSTOPT: instance_buf,
|
||||
preloginTHREADID: {0, 0, 0, 0},
|
||||
preloginMARS: {0}, // MARS disabled
|
||||
fedAuth := &featureExtFedAuth{
|
||||
FedAuthLibrary: p.fedAuthLibrary,
|
||||
ADALWorkflow: p.fedAuthADALWorkflow,
|
||||
}
|
||||
|
||||
err = writePrelogin(outbuf, fields)
|
||||
fields := preparePreloginFields(p, fedAuth)
|
||||
|
||||
err = writePrelogin(packPrelogin, outbuf, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -908,13 +1085,9 @@ initiate_connection:
|
|||
return nil, err
|
||||
}
|
||||
|
||||
encryptBytes, ok := fields[preloginENCRYPTION]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Encrypt negotiation failed")
|
||||
}
|
||||
encrypt = encryptBytes[0]
|
||||
if p.encrypt && (encrypt == encryptNotSup || encrypt == encryptOff) {
|
||||
return nil, fmt.Errorf("Server does not support encryption")
|
||||
encrypt, err := interpretPreloginResponse(p, fedAuth, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if encrypt != encryptNotSup {
|
||||
|
@ -922,7 +1095,7 @@ initiate_connection:
|
|||
if p.certificate != "" {
|
||||
pem, err := ioutil.ReadFile(p.certificate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Cannot read certificate %q: %v", p.certificate, err)
|
||||
return nil, fmt.Errorf("cannot read certificate %q: %v", p.certificate, err)
|
||||
}
|
||||
certs := x509.NewCertPool()
|
||||
certs.AppendCertsFromPEM(pem)
|
||||
|
@ -954,54 +1127,46 @@ initiate_connection:
|
|||
}
|
||||
}
|
||||
|
||||
login := login{
|
||||
TDSVersion: verTDS74,
|
||||
PacketSize: uint32(outbuf.PackageSize()),
|
||||
Database: p.database,
|
||||
OptionFlags2: fODBC, // to get unlimited TEXTSIZE
|
||||
HostName: p.workstation,
|
||||
ServerName: p.host,
|
||||
AppName: p.appname,
|
||||
TypeFlags: p.typeFlags,
|
||||
}
|
||||
auth, authOk := getAuth(p.user, p.password, p.serverSPN, p.workstation)
|
||||
switch {
|
||||
case p.fedAuthAccessToken != "": // accesstoken ignores user/password
|
||||
featurext := &featureExtFedAuthSTS{
|
||||
FedAuthEcho: len(fields[preloginFEDAUTHREQUIRED]) > 0 && fields[preloginFEDAUTHREQUIRED][0] == 1,
|
||||
FedAuthToken: p.fedAuthAccessToken,
|
||||
Nonce: fields[preloginNONCEOPT],
|
||||
if authOk {
|
||||
defer auth.Free()
|
||||
} else {
|
||||
auth = nil
|
||||
}
|
||||
login.FeatureExt.Add(featurext)
|
||||
case authOk:
|
||||
login.SSPI, err = auth.InitialBytes()
|
||||
|
||||
login, err := prepareLogin(ctx, c, p, log, auth, fedAuth, uint32(outbuf.PackageSize()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
login.OptionFlags2 |= fIntSecurity
|
||||
defer auth.Free()
|
||||
default:
|
||||
login.UserName = p.user
|
||||
login.Password = p.password
|
||||
}
|
||||
|
||||
err = sendLogin(outbuf, login)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// processing login response
|
||||
success := false
|
||||
// Loop until a packet containing a login acknowledgement is received.
|
||||
// SSPI and federated authentication scenarios may require multiple
|
||||
// packet exchanges to complete the login sequence.
|
||||
for loginAck := false; !loginAck; {
|
||||
reader := startReading(&sess, ctx, nil)
|
||||
|
||||
for {
|
||||
tokchan := make(chan tokenStruct, 5)
|
||||
go processResponse(context.Background(), &sess, tokchan, nil)
|
||||
for tok := range tokchan {
|
||||
tok, err := reader.nextToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tok == nil {
|
||||
break
|
||||
}
|
||||
|
||||
switch token := tok.(type) {
|
||||
case sspiMsg:
|
||||
sspi_msg, err := auth.NextBytes(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sspi_msg != nil && len(sspi_msg) > 0 {
|
||||
if len(sspi_msg) > 0 {
|
||||
outbuf.BeginPacket(packSSPIMessage, false)
|
||||
_, err = outbuf.Write(sspi_msg)
|
||||
if err != nil {
|
||||
|
@ -1013,23 +1178,41 @@ initiate_connection:
|
|||
}
|
||||
sspi_msg = nil
|
||||
}
|
||||
// TODO: for Live ID authentication it may be necessary to
|
||||
// compare fedAuth.Nonce == token.Nonce and keep track of signature
|
||||
//case fedAuthAckStruct:
|
||||
//fedAuth.Signature = token.Signature
|
||||
case fedAuthInfoStruct:
|
||||
// For ADAL workflows this contains the STS URL and server SPN.
|
||||
// If received outside of an ADAL workflow, ignore.
|
||||
if c == nil || c.adalTokenProvider == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Request the AD token given the server SPN and STS URL
|
||||
fedAuth.FedAuthToken, err = c.adalTokenProvider(ctx, token.ServerSPN, token.STSURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now need to send the token as a FEDINFO packet
|
||||
err = sendFedAuthInfo(outbuf, fedAuth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case loginAckStruct:
|
||||
success = true
|
||||
sess.loginAck = token
|
||||
case error:
|
||||
return nil, fmt.Errorf("Login error: %s", token.Error())
|
||||
loginAck = true
|
||||
case doneStruct:
|
||||
if token.isError() {
|
||||
return nil, fmt.Errorf("Login error: %s", token.getError())
|
||||
return nil, fmt.Errorf("login error: %s", token.getError())
|
||||
}
|
||||
goto loginEnd
|
||||
case error:
|
||||
return nil, fmt.Errorf("login error: %s", token.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
loginEnd:
|
||||
if !success {
|
||||
return nil, fmt.Errorf("Login failed")
|
||||
}
|
||||
|
||||
if sess.routedServer != "" {
|
||||
toconn.Close()
|
||||
p.host = sess.routedServer
|
||||
|
@ -1041,3 +1224,9 @@ loginEnd:
|
|||
}
|
||||
return &sess, nil
|
||||
}
|
||||
|
||||
func (sess *tdsSession) setReturnStatus(status ReturnStatus) {
|
||||
if sess.returnStatus != nil {
|
||||
*sess.returnStatus = status
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,11 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:generate stringer -type token
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer -type token
|
||||
|
||||
type token byte
|
||||
|
||||
|
@ -29,6 +28,7 @@ const (
|
|||
tokenNbcRow token = 210 // 0xd2
|
||||
tokenEnvChange token = 227 // 0xE3
|
||||
tokenSSPI token = 237 // 0xED
|
||||
tokenFedAuthInfo token = 238 // 0xEE
|
||||
tokenDone token = 253 // 0xFD
|
||||
tokenDoneProc token = 254
|
||||
tokenDoneInProc token = 255
|
||||
|
@ -70,6 +70,11 @@ const (
|
|||
envRouting = 20
|
||||
)
|
||||
|
||||
const (
|
||||
fedAuthInfoSTSURL = 0x01
|
||||
fedAuthInfoSPN = 0x02
|
||||
)
|
||||
|
||||
// COLMETADATA flags
|
||||
// https://msdn.microsoft.com/en-us/library/dd357363.aspx
|
||||
const (
|
||||
|
@ -105,26 +110,6 @@ func (d doneStruct) getError() Error {
|
|||
|
||||
type doneInProcStruct doneStruct
|
||||
|
||||
var doneFlags2str = map[uint16]string{
|
||||
doneFinal: "final",
|
||||
doneMore: "more",
|
||||
doneError: "error",
|
||||
doneInxact: "inxact",
|
||||
doneCount: "count",
|
||||
doneAttn: "attn",
|
||||
doneSrvError: "srverror",
|
||||
}
|
||||
|
||||
func doneFlags2Str(flags uint16) string {
|
||||
strs := make([]string, 0, len(doneFlags2str))
|
||||
for flag, tag := range doneFlags2str {
|
||||
if flags&flag != 0 {
|
||||
strs = append(strs, tag)
|
||||
}
|
||||
}
|
||||
return strings.Join(strs, "|")
|
||||
}
|
||||
|
||||
// ENVCHANGE stream
|
||||
// http://msdn.microsoft.com/en-us/library/dd303449.aspx
|
||||
func processEnvChg(sess *tdsSession) {
|
||||
|
@ -380,9 +365,8 @@ func processEnvChg(sess *tdsSession) {
|
|||
default:
|
||||
// ignore rest of records because we don't know how to skip those
|
||||
sess.log.Printf("WARN: Unknown ENVCHANGE record detected with type id = %d\n", envtype)
|
||||
break
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,6 +409,78 @@ func parseSSPIMsg(r *tdsBuffer) sspiMsg {
|
|||
return sspiMsg(buf)
|
||||
}
|
||||
|
||||
type fedAuthInfoStruct struct {
|
||||
STSURL string
|
||||
ServerSPN string
|
||||
}
|
||||
|
||||
type fedAuthInfoOpt struct {
|
||||
fedAuthInfoID byte
|
||||
dataLength, dataOffset uint32
|
||||
}
|
||||
|
||||
func parseFedAuthInfo(r *tdsBuffer) fedAuthInfoStruct {
|
||||
size := r.uint32()
|
||||
|
||||
var STSURL, SPN string
|
||||
var err error
|
||||
|
||||
// Each fedAuthInfoOpt is one byte to indicate the info ID,
|
||||
// then a four byte offset and a four byte length.
|
||||
count := r.uint32()
|
||||
offset := uint32(4)
|
||||
opts := make([]fedAuthInfoOpt, count)
|
||||
|
||||
for i := uint32(0); i < count; i++ {
|
||||
fedAuthInfoID := r.byte()
|
||||
dataLength := r.uint32()
|
||||
dataOffset := r.uint32()
|
||||
offset += 1 + 4 + 4
|
||||
|
||||
opts[i] = fedAuthInfoOpt{
|
||||
fedAuthInfoID: fedAuthInfoID,
|
||||
dataLength: dataLength,
|
||||
dataOffset: dataOffset,
|
||||
}
|
||||
}
|
||||
|
||||
data := make([]byte, size-offset)
|
||||
r.ReadFull(data)
|
||||
|
||||
for i := uint32(0); i < count; i++ {
|
||||
if opts[i].dataOffset < offset {
|
||||
badStreamPanicf("Fed auth info opt stated data offset %d is before data begins in packet at %d",
|
||||
opts[i].dataOffset, offset)
|
||||
// returns via panic
|
||||
}
|
||||
|
||||
if opts[i].dataOffset+opts[i].dataLength > size {
|
||||
badStreamPanicf("Fed auth info opt stated data length %d added to stated offset exceeds size of packet %d",
|
||||
opts[i].dataOffset+opts[i].dataLength, size)
|
||||
// returns via panic
|
||||
}
|
||||
|
||||
optData := data[opts[i].dataOffset-offset : opts[i].dataOffset-offset+opts[i].dataLength]
|
||||
switch opts[i].fedAuthInfoID {
|
||||
case fedAuthInfoSTSURL:
|
||||
STSURL, err = ucs22str(optData)
|
||||
case fedAuthInfoSPN:
|
||||
SPN, err = ucs22str(optData)
|
||||
default:
|
||||
err = fmt.Errorf("Unexpected fed auth info opt ID %d", int(opts[i].fedAuthInfoID))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
badStreamPanic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return fedAuthInfoStruct{
|
||||
STSURL: STSURL,
|
||||
ServerSPN: SPN,
|
||||
}
|
||||
}
|
||||
|
||||
type loginAckStruct struct {
|
||||
Interface uint8
|
||||
TDSVersion uint32
|
||||
|
@ -449,19 +505,43 @@ func parseLoginAck(r *tdsBuffer) loginAckStruct {
|
|||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/2eb82f8e-11f0-46dc-b42d-27302fa4701a
|
||||
func parseFeatureExtAck(r *tdsBuffer) {
|
||||
// at most 1 featureAck per feature in featureExt
|
||||
// go-mssqldb will add at most 1 feature, the spec defines 7 different features
|
||||
for i := 0; i < 8; i++ {
|
||||
featureID := r.byte() // FeatureID
|
||||
if featureID == 0xff {
|
||||
return
|
||||
type fedAuthAckStruct struct {
|
||||
Nonce []byte
|
||||
Signature []byte
|
||||
}
|
||||
size := r.uint32() // FeatureAckDataLen
|
||||
d := make([]byte, size)
|
||||
r.ReadFull(d)
|
||||
|
||||
func parseFeatureExtAck(r *tdsBuffer) map[byte]interface{} {
|
||||
ack := map[byte]interface{}{}
|
||||
|
||||
for feature := r.byte(); feature != featExtTERMINATOR; feature = r.byte() {
|
||||
length := r.uint32()
|
||||
|
||||
switch feature {
|
||||
case featExtFEDAUTH:
|
||||
// In theory we need to know the federated authentication library to
|
||||
// know how to parse, but the alternatives provide compatible structures.
|
||||
fedAuthAck := fedAuthAckStruct{}
|
||||
if length >= 32 {
|
||||
fedAuthAck.Nonce = make([]byte, 32)
|
||||
r.ReadFull(fedAuthAck.Nonce)
|
||||
length -= 32
|
||||
}
|
||||
panic("parsed more than 7 featureAck's, protocol implementation error?")
|
||||
if length >= 32 {
|
||||
fedAuthAck.Signature = make([]byte, 32)
|
||||
r.ReadFull(fedAuthAck.Signature)
|
||||
length -= 32
|
||||
}
|
||||
ack[feature] = fedAuthAck
|
||||
|
||||
}
|
||||
|
||||
// Skip unprocessed bytes
|
||||
if length > 0 {
|
||||
io.CopyN(ioutil.Discard, r, int64(length))
|
||||
}
|
||||
}
|
||||
|
||||
return ack
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/dd357363.aspx
|
||||
|
@ -579,7 +659,7 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
|
|||
}
|
||||
var columns []columnStruct
|
||||
errs := make([]Error, 0, 5)
|
||||
for {
|
||||
for tokens := 0; ; tokens += 1 {
|
||||
token := token(sess.buf.byte())
|
||||
if sess.logFlags&logDebug != 0 {
|
||||
sess.log.Printf("got token %v", token)
|
||||
|
@ -588,6 +668,9 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
|
|||
case tokenSSPI:
|
||||
ch <- parseSSPIMsg(sess.buf)
|
||||
return
|
||||
case tokenFedAuthInfo:
|
||||
ch <- parseFedAuthInfo(sess.buf)
|
||||
return
|
||||
case tokenReturnStatus:
|
||||
returnStatus := parseReturnStatus(sess.buf)
|
||||
ch <- returnStatus
|
||||
|
@ -595,7 +678,8 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
|
|||
loginAck := parseLoginAck(sess.buf)
|
||||
ch <- loginAck
|
||||
case tokenFeatureExtAck:
|
||||
parseFeatureExtAck(sess.buf)
|
||||
featureExtAck := parseFeatureExtAck(sess.buf)
|
||||
ch <- featureExtAck
|
||||
case tokenOrder:
|
||||
order := parseOrder(sess.buf)
|
||||
ch <- order
|
||||
|
@ -670,158 +754,137 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
|
|||
}
|
||||
}
|
||||
|
||||
type parseRespIter byte
|
||||
|
||||
const (
|
||||
parseRespIterContinue parseRespIter = iota // Continue parsing current token.
|
||||
parseRespIterNext // Fetch the next token.
|
||||
parseRespIterDone // Done with parsing the response.
|
||||
)
|
||||
|
||||
type parseRespState byte
|
||||
|
||||
const (
|
||||
parseRespStateNormal parseRespState = iota // Normal response state.
|
||||
parseRespStateCancel // Query is canceled, wait for server to confirm.
|
||||
parseRespStateClosing // Waiting for tokens to come through.
|
||||
)
|
||||
|
||||
type parseResp struct {
|
||||
type tokenProcessor struct {
|
||||
tokChan chan tokenStruct
|
||||
ctx context.Context
|
||||
sess *tdsSession
|
||||
ctxDone <-chan struct{}
|
||||
state parseRespState
|
||||
cancelError error
|
||||
outs map[string]interface{}
|
||||
lastRow []interface{}
|
||||
rowCount int64
|
||||
firstError error
|
||||
}
|
||||
|
||||
func (ts *parseResp) sendAttention(ch chan tokenStruct) parseRespIter {
|
||||
if err := sendAttention(ts.sess.buf); err != nil {
|
||||
ts.dlogf("failed to send attention signal %v", err)
|
||||
ch <- err
|
||||
return parseRespIterDone
|
||||
func startReading(sess *tdsSession, ctx context.Context, outs map[string]interface{}) *tokenProcessor {
|
||||
tokChan := make(chan tokenStruct, 5)
|
||||
go processSingleResponse(sess, tokChan, outs)
|
||||
return &tokenProcessor{
|
||||
tokChan: tokChan,
|
||||
ctx: ctx,
|
||||
sess: sess,
|
||||
outs: outs,
|
||||
}
|
||||
ts.state = parseRespStateCancel
|
||||
return parseRespIterContinue
|
||||
}
|
||||
|
||||
func (ts *parseResp) dlog(msg string) {
|
||||
// logging from goroutine is disabled to prevent
|
||||
// data race detection from firing
|
||||
// The race is probably happening when
|
||||
// test logger changes between tests.
|
||||
/*if ts.sess.logFlags&logDebug != 0 {
|
||||
ts.sess.log.Println(msg)
|
||||
func (t *tokenProcessor) iterateResponse() error {
|
||||
for {
|
||||
tok, err := t.nextToken()
|
||||
if err == nil {
|
||||
if tok == nil {
|
||||
return t.firstError
|
||||
} else {
|
||||
switch token := tok.(type) {
|
||||
case []columnStruct:
|
||||
t.sess.columns = token
|
||||
case []interface{}:
|
||||
t.lastRow = token
|
||||
case doneInProcStruct:
|
||||
if token.Status&doneCount != 0 {
|
||||
t.rowCount += int64(token.RowCount)
|
||||
}
|
||||
case doneStruct:
|
||||
if token.Status&doneCount != 0 {
|
||||
t.rowCount += int64(token.RowCount)
|
||||
}
|
||||
if token.isError() && t.firstError == nil {
|
||||
t.firstError = token.getError()
|
||||
}
|
||||
case ReturnStatus:
|
||||
t.sess.setReturnStatus(token)
|
||||
/*case error:
|
||||
if resultError == nil {
|
||||
resultError = token
|
||||
}*/
|
||||
}
|
||||
func (ts *parseResp) dlogf(f string, v ...interface{}) {
|
||||
/*if ts.sess.logFlags&logDebug != 0 {
|
||||
ts.sess.log.Printf(f, v...)
|
||||
}*/
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *parseResp) iter(ctx context.Context, ch chan tokenStruct, tokChan chan tokenStruct) parseRespIter {
|
||||
switch ts.state {
|
||||
func (t tokenProcessor) nextToken() (tokenStruct, error) {
|
||||
// we do this separate non-blocking check on token channel to
|
||||
// prioritize it over cancellation channel
|
||||
select {
|
||||
case tok, more := <-t.tokChan:
|
||||
err, more := tok.(error)
|
||||
if more {
|
||||
// this is an error and not a token
|
||||
return nil, err
|
||||
} else {
|
||||
return tok, nil
|
||||
}
|
||||
default:
|
||||
panic("unknown state")
|
||||
case parseRespStateNormal:
|
||||
select {
|
||||
case tok, ok := <-tokChan:
|
||||
if !ok {
|
||||
ts.dlog("response finished")
|
||||
return parseRespIterDone
|
||||
// there are no tokens on the channel, will need to wait
|
||||
}
|
||||
if err, ok := tok.(net.Error); ok && err.Timeout() {
|
||||
ts.cancelError = err
|
||||
ts.dlog("got timeout error, sending attention signal to server")
|
||||
return ts.sendAttention(ch)
|
||||
}
|
||||
// Pass the token along.
|
||||
ch <- tok
|
||||
return parseRespIterContinue
|
||||
|
||||
case <-ts.ctxDone:
|
||||
ts.ctxDone = nil
|
||||
ts.dlog("got cancel message, sending attention signal to server")
|
||||
return ts.sendAttention(ch)
|
||||
}
|
||||
case parseRespStateCancel: // Read all responses until a DONE or error is received.Auth
|
||||
select {
|
||||
case tok, ok := <-tokChan:
|
||||
if !ok {
|
||||
ts.dlog("response finished but waiting for attention ack")
|
||||
return parseRespIterNext
|
||||
case tok, more := <-t.tokChan:
|
||||
if more {
|
||||
err, ok := tok.(error)
|
||||
if ok {
|
||||
// this is an error and not a token
|
||||
return nil, err
|
||||
} else {
|
||||
return tok, nil
|
||||
}
|
||||
} else {
|
||||
// completed reading response
|
||||
return nil, nil
|
||||
}
|
||||
case <-t.ctx.Done():
|
||||
if err := sendAttention(t.sess.buf); err != nil {
|
||||
// unable to send attention, current connection is bad
|
||||
// notify caller and close channel
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// now the server should send cancellation confirmation
|
||||
// it is possible that we already received full response
|
||||
// just before we sent cancellation request
|
||||
// in this case current response would not contain confirmation
|
||||
// and we would need to read one more response
|
||||
|
||||
// first lets finish reading current response and look
|
||||
// for confirmation in it
|
||||
if readCancelConfirmation(t.tokChan) {
|
||||
// we got confirmation in current response
|
||||
return nil, t.ctx.Err()
|
||||
}
|
||||
// we did not get cancellation confirmation in the current response
|
||||
// read one more response, it must be there
|
||||
t.tokChan = make(chan tokenStruct, 5)
|
||||
go processSingleResponse(t.sess, t.tokChan, t.outs)
|
||||
if readCancelConfirmation(t.tokChan) {
|
||||
return nil, t.ctx.Err()
|
||||
}
|
||||
// we did not get cancellation confirmation, something is not
|
||||
// right, this connection is not usable anymore
|
||||
return nil, errors.New("did not get cancellation confirmation from the server")
|
||||
}
|
||||
}
|
||||
|
||||
func readCancelConfirmation(tokChan chan tokenStruct) bool {
|
||||
for tok := range tokChan {
|
||||
switch tok := tok.(type) {
|
||||
default:
|
||||
// Ignore all other tokens while waiting.
|
||||
// The TDS spec says other tokens may arrive after an attention
|
||||
// signal is sent. Ignore these tokens and continue looking for
|
||||
// a DONE with attention confirm mark.
|
||||
// just skip token
|
||||
case doneStruct:
|
||||
if tok.Status&doneAttn != 0 {
|
||||
ts.dlog("got cancellation confirmation from server")
|
||||
if ts.cancelError != nil {
|
||||
ch <- ts.cancelError
|
||||
ts.cancelError = nil
|
||||
} else {
|
||||
ch <- ctx.Err()
|
||||
}
|
||||
return parseRespIterDone
|
||||
}
|
||||
|
||||
// If an error happens during cancel, pass it along and just stop.
|
||||
// We are uncertain to receive more tokens.
|
||||
case error:
|
||||
ch <- tok
|
||||
ts.state = parseRespStateClosing
|
||||
}
|
||||
return parseRespIterContinue
|
||||
case <-ts.ctxDone:
|
||||
ts.ctxDone = nil
|
||||
ts.state = parseRespStateClosing
|
||||
return parseRespIterContinue
|
||||
}
|
||||
case parseRespStateClosing: // Wait for current token chan to close.
|
||||
if _, ok := <-tokChan; !ok {
|
||||
ts.dlog("response finished")
|
||||
return parseRespIterDone
|
||||
}
|
||||
return parseRespIterContinue
|
||||
}
|
||||
}
|
||||
|
||||
func processResponse(ctx context.Context, sess *tdsSession, ch chan tokenStruct, outs map[string]interface{}) {
|
||||
ts := &parseResp{
|
||||
sess: sess,
|
||||
ctxDone: ctx.Done(),
|
||||
}
|
||||
defer func() {
|
||||
// Ensure any remaining error is piped through
|
||||
// or the query may look like it executed when it actually failed.
|
||||
if ts.cancelError != nil {
|
||||
ch <- ts.cancelError
|
||||
ts.cancelError = nil
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
// Loop over multiple responses.
|
||||
for {
|
||||
ts.dlog("initiating response reading")
|
||||
|
||||
tokChan := make(chan tokenStruct)
|
||||
go processSingleResponse(sess, tokChan, outs)
|
||||
|
||||
// Loop over multiple tokens in response.
|
||||
tokensLoop:
|
||||
for {
|
||||
switch ts.iter(ctx, ch, tokChan) {
|
||||
case parseRespIterContinue:
|
||||
// Nothing, continue to next token.
|
||||
case parseRespIterNext:
|
||||
break tokensLoop
|
||||
case parseRespIterDone:
|
||||
return
|
||||
// got cancellation confirmation, exit
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,29 +1,24 @@
|
|||
// Code generated by "stringer -type token"; DO NOT EDIT
|
||||
// Code generated by "stringer -type token"; DO NOT EDIT.
|
||||
|
||||
package mssql
|
||||
|
||||
import "fmt"
|
||||
import "strconv"
|
||||
|
||||
const (
|
||||
_token_name_0 = "tokenReturnStatus"
|
||||
_token_name_1 = "tokenColMetadata"
|
||||
_token_name_2 = "tokenOrdertokenErrortokenInfo"
|
||||
_token_name_3 = "tokenLoginAck"
|
||||
_token_name_4 = "tokenRowtokenNbcRow"
|
||||
_token_name_5 = "tokenEnvChange"
|
||||
_token_name_6 = "tokenSSPI"
|
||||
_token_name_7 = "tokenDonetokenDoneProctokenDoneInProc"
|
||||
_token_name_2 = "tokenOrdertokenErrortokenInfotokenReturnValuetokenLoginAcktokenFeatureExtAck"
|
||||
_token_name_3 = "tokenRowtokenNbcRow"
|
||||
_token_name_4 = "tokenEnvChange"
|
||||
_token_name_5 = "tokenSSPItokenFedAuthInfo"
|
||||
_token_name_6 = "tokenDonetokenDoneProctokenDoneInProc"
|
||||
)
|
||||
|
||||
var (
|
||||
_token_index_0 = [...]uint8{0, 17}
|
||||
_token_index_1 = [...]uint8{0, 16}
|
||||
_token_index_2 = [...]uint8{0, 10, 20, 29}
|
||||
_token_index_3 = [...]uint8{0, 13}
|
||||
_token_index_4 = [...]uint8{0, 8, 19}
|
||||
_token_index_5 = [...]uint8{0, 14}
|
||||
_token_index_6 = [...]uint8{0, 9}
|
||||
_token_index_7 = [...]uint8{0, 9, 22, 37}
|
||||
_token_index_2 = [...]uint8{0, 10, 20, 29, 45, 58, 76}
|
||||
_token_index_3 = [...]uint8{0, 8, 19}
|
||||
_token_index_5 = [...]uint8{0, 9, 25}
|
||||
_token_index_6 = [...]uint8{0, 9, 22, 37}
|
||||
)
|
||||
|
||||
func (i token) String() string {
|
||||
|
@ -32,22 +27,21 @@ func (i token) String() string {
|
|||
return _token_name_0
|
||||
case i == 129:
|
||||
return _token_name_1
|
||||
case 169 <= i && i <= 171:
|
||||
case 169 <= i && i <= 174:
|
||||
i -= 169
|
||||
return _token_name_2[_token_index_2[i]:_token_index_2[i+1]]
|
||||
case i == 173:
|
||||
return _token_name_3
|
||||
case 209 <= i && i <= 210:
|
||||
i -= 209
|
||||
return _token_name_4[_token_index_4[i]:_token_index_4[i+1]]
|
||||
return _token_name_3[_token_index_3[i]:_token_index_3[i+1]]
|
||||
case i == 227:
|
||||
return _token_name_5
|
||||
case i == 237:
|
||||
return _token_name_6
|
||||
return _token_name_4
|
||||
case 237 <= i && i <= 238:
|
||||
i -= 237
|
||||
return _token_name_5[_token_index_5[i]:_token_index_5[i+1]]
|
||||
case 253 <= i && i <= 255:
|
||||
i -= 253
|
||||
return _token_name_7[_token_index_7[i]:_token_index_7[i+1]]
|
||||
return _token_name_6[_token_index_6[i]:_token_index_6[i+1]]
|
||||
default:
|
||||
return fmt.Sprintf("token(%d)", i)
|
||||
return "token(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ type isoLevel uint8
|
|||
|
||||
const (
|
||||
isolationUseCurrent isoLevel = 0
|
||||
isolationReadUncommited = 1
|
||||
isolationReadCommited = 2
|
||||
isolationRepeatableRead = 3
|
||||
isolationSerializable = 4
|
||||
isolationSnapshot = 5
|
||||
isolationReadUncommited isoLevel = 1
|
||||
isolationReadCommited isoLevel = 2
|
||||
isolationRepeatableRead isoLevel = 3
|
||||
isolationSerializable isoLevel = 4
|
||||
isolationSnapshot isoLevel = 5
|
||||
)
|
||||
|
||||
func sendBeginXact(buf *tdsBuffer, headers []headerStruct, isolation isoLevel, name string, resetSession bool) (err error) {
|
||||
|
|
|
@ -4,6 +4,7 @@ package mssql
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -97,6 +98,9 @@ func (tvp TVP) encode(schema, name string, columnStr []columnStruct, tvpFieldInd
|
|||
for columnStrIdx, fieldIdx := range tvpFieldIndexes {
|
||||
field := refStr.Field(fieldIdx)
|
||||
tvpVal := field.Interface()
|
||||
if tvp.verifyStandardTypeOnNull(buf, tvpVal) {
|
||||
continue
|
||||
}
|
||||
valOf := reflect.ValueOf(tvpVal)
|
||||
elemKind := field.Kind()
|
||||
if elemKind == reflect.Ptr && valOf.IsNil() {
|
||||
|
@ -155,7 +159,7 @@ func (tvp TVP) columnTypes() ([]columnStruct, []int, error) {
|
|||
defaultValues = append(defaultValues, v.Interface())
|
||||
continue
|
||||
}
|
||||
defaultValues = append(defaultValues, reflect.Zero(field.Type).Interface())
|
||||
defaultValues = append(defaultValues, tvp.createZeroType(reflect.Zero(field.Type).Interface()))
|
||||
}
|
||||
|
||||
if columnCount-len(tvpFieldIndexes) == columnCount {
|
||||
|
@ -209,19 +213,23 @@ func getSchemeAndName(tvpName string) (string, string, error) {
|
|||
}
|
||||
splitVal := strings.Split(tvpName, ".")
|
||||
if len(splitVal) > 2 {
|
||||
return "", "", errors.New("wrong tvp name")
|
||||
return "", "", ErrorObjectName
|
||||
}
|
||||
const (
|
||||
openSquareBrackets = "["
|
||||
closeSquareBrackets = "]"
|
||||
)
|
||||
if len(splitVal) == 2 {
|
||||
res := make([]string, 2)
|
||||
for key, value := range splitVal {
|
||||
tmp := strings.Replace(value, "[", "", -1)
|
||||
tmp = strings.Replace(tmp, "]", "", -1)
|
||||
tmp := strings.Replace(value, openSquareBrackets, "", -1)
|
||||
tmp = strings.Replace(tmp, closeSquareBrackets, "", -1)
|
||||
res[key] = tmp
|
||||
}
|
||||
return res[0], res[1], nil
|
||||
}
|
||||
tmp := strings.Replace(splitVal[0], "[", "", -1)
|
||||
tmp = strings.Replace(tmp, "]", "", -1)
|
||||
tmp := strings.Replace(splitVal[0], openSquareBrackets, "", -1)
|
||||
tmp = strings.Replace(tmp, closeSquareBrackets, "", -1)
|
||||
|
||||
return "", tmp, nil
|
||||
}
|
||||
|
@ -229,3 +237,56 @@ func getSchemeAndName(tvpName string) (string, string, error) {
|
|||
func getCountSQLSeparators(str string) int {
|
||||
return strings.Count(str, sqlSeparator)
|
||||
}
|
||||
|
||||
// verify types https://golang.org/pkg/database/sql/
|
||||
func (tvp TVP) createZeroType(fieldVal interface{}) interface{} {
|
||||
const (
|
||||
defaultBool = false
|
||||
defaultFloat64 = float64(0)
|
||||
defaultInt64 = int64(0)
|
||||
defaultString = ""
|
||||
)
|
||||
|
||||
switch fieldVal.(type) {
|
||||
case sql.NullBool:
|
||||
return defaultBool
|
||||
case sql.NullFloat64:
|
||||
return defaultFloat64
|
||||
case sql.NullInt64:
|
||||
return defaultInt64
|
||||
case sql.NullString:
|
||||
return defaultString
|
||||
}
|
||||
return fieldVal
|
||||
}
|
||||
|
||||
// verify types https://golang.org/pkg/database/sql/
|
||||
func (tvp TVP) verifyStandardTypeOnNull(buf *bytes.Buffer, tvpVal interface{}) bool {
|
||||
const (
|
||||
defaultNull = uint8(0)
|
||||
)
|
||||
|
||||
switch val := tvpVal.(type) {
|
||||
case sql.NullBool:
|
||||
if !val.Valid {
|
||||
binary.Write(buf, binary.LittleEndian, defaultNull)
|
||||
return true
|
||||
}
|
||||
case sql.NullFloat64:
|
||||
if !val.Valid {
|
||||
binary.Write(buf, binary.LittleEndian, defaultNull)
|
||||
return true
|
||||
}
|
||||
case sql.NullInt64:
|
||||
if !val.Valid {
|
||||
binary.Write(buf, binary.LittleEndian, defaultNull)
|
||||
return true
|
||||
}
|
||||
case sql.NullString:
|
||||
if !val.Valid {
|
||||
binary.Write(buf, binary.LittleEndian, uint64(_PLP_NULL))
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -665,7 +665,7 @@ func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
|
|||
default:
|
||||
buf = bytes.NewBuffer(make([]byte, 0, size))
|
||||
}
|
||||
for true {
|
||||
for {
|
||||
chunksize := r.uint32()
|
||||
if chunksize == 0 {
|
||||
break
|
||||
|
@ -690,6 +690,10 @@ func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
|
|||
}
|
||||
|
||||
func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) {
|
||||
if buf == nil {
|
||||
err = binary.Write(w, binary.LittleEndian, uint64(_PLP_NULL))
|
||||
return
|
||||
}
|
||||
if err = binary.Write(w, binary.LittleEndian, uint64(_UNKNOWN_PLP_LEN)); err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -807,7 +811,6 @@ func readVarLen(ti *typeInfo, r *tdsBuffer) {
|
|||
default:
|
||||
badStreamPanicf("Invalid type %d", ti.TypeId)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func decodeMoney(buf []byte) []byte {
|
||||
|
@ -834,8 +837,7 @@ func decodeGuid(buf []byte) []byte {
|
|||
}
|
||||
|
||||
func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte {
|
||||
var sign uint8
|
||||
sign = buf[0]
|
||||
sign := buf[0]
|
||||
var dec decimal.Decimal
|
||||
dec.SetPositive(sign != 0)
|
||||
dec.SetPrec(prec)
|
||||
|
@ -1187,7 +1189,7 @@ func makeDecl(ti typeInfo) string {
|
|||
return fmt.Sprintf("char(%d)", ti.Size)
|
||||
case typeBigVarChar, typeVarChar:
|
||||
if ti.Size > 8000 || ti.Size == 0 {
|
||||
return fmt.Sprintf("varchar(max)")
|
||||
return "varchar(max)"
|
||||
} else {
|
||||
return fmt.Sprintf("varchar(%d)", ti.Size)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
linters-settings:
|
||||
golint:
|
||||
min-confidence: 0.3
|
||||
cyclop:
|
||||
max-complexity: 15
|
||||
package-average: 10
|
||||
|
||||
linters:
|
||||
disable:
|
||||
- exhaustivestruct
|
||||
- gomnd
|
||||
- interfacer
|
||||
- maligned
|
||||
presets:
|
||||
- bugs
|
||||
- complexity
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
# Change log
|
||||
|
||||
## v2.4.2 - 2021-03-21
|
||||
|
||||
- Upgrade google/go-cmp v0.5.5
|
||||
([#105](https://github.com/editorconfig/editorconfig-core-go/pull/105));
|
||||
- Upgrade x/mod v0.4.2
|
||||
([#106](https://github.com/editorconfig/editorconfig-core-go/pull/106)).
|
||||
|
||||
## v2.4.1 - 2021-02-25
|
||||
|
||||
- Fix for Go 1.16 os.IsNotExist wrapping
|
||||
|
|
|
@ -121,7 +121,7 @@ func (d *Definition) merge(md *Definition) {
|
|||
}
|
||||
|
||||
// InsertToIniFile writes the definition into a ini file.
|
||||
func (d *Definition) InsertToIniFile(iniFile *ini.File) { // nolint: funlen,gocognit
|
||||
func (d *Definition) InsertToIniFile(iniFile *ini.File) { // nolint: funlen,gocognit,cyclop
|
||||
iniSec := iniFile.Section(d.Selector)
|
||||
|
||||
for k, v := range d.Raw {
|
||||
|
|
|
@ -33,7 +33,7 @@ func FnmatchCase(pattern, name string) (bool, error) {
|
|||
return r.MatchString(name), nil
|
||||
}
|
||||
|
||||
func translate(pattern string) string { // nolint: funlen,gocognit,gocyclo
|
||||
func translate(pattern string) string { // nolint: funlen,gocognit,gocyclo,cyclop
|
||||
index := 0
|
||||
pat := []rune(pattern)
|
||||
length := len(pat)
|
||||
|
|
|
@ -3,8 +3,8 @@ module github.com/editorconfig/editorconfig-core-go/v2
|
|||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.4
|
||||
github.com/google/go-cmp v0.5.5
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
golang.org/x/mod v0.4.1
|
||||
golang.org/x/mod v0.4.2
|
||||
gopkg.in/ini.v1 v1.62.0
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
|
@ -10,8 +10,8 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK
|
|||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
The MIT license.
|
||||
|
||||
Copyright (c) 2014 the go-unsnap-stream authors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
go-unsnap-stream
|
||||
================
|
||||
|
||||
This is a small golang library for decoding and encoding the snappy *streaming* format, specified here: https://github.com/google/snappy/blob/master/framing_format.txt
|
||||
|
||||
Note that the *streaming or framing format* for snappy is different from snappy itself. Think of it as a train of boxcars: the streaming format breaks your data in chunks, applies snappy to each chunk alone, then puts a thin wrapper around the chunk, and sends it along in turn. You can begin decoding before receiving everything. And memory requirements for decoding are sane.
|
||||
|
||||
Strangely, though the streaming format was first proposed in Go[1][2], it was never upated, and I could not locate any other library for Go that would handle the streaming/framed snappy format. Hence this implementation of the spec. There is a command line tool[3] that has a C implementation, but this is the only Go implementation that I am aware of. The reference for the framing/streaming spec seems to be the python implementation[4].
|
||||
|
||||
Update to the previous paragraph: Horray! Good news: Thanks to @nigeltao, we have since learned that the [github.com/golang/snappy](https://github.com/golang/snappy) package now provides the snappy streaming format too. Even though the type level descriptions are a little misleading because they don't mention that they are for the stream format, the [snappy package header documentation](https://godoc.org/github.com/golang/snappy) points out that the [snappy.Reader](https://godoc.org/github.com/golang/snappy#Reader) and [snappy.Writer](https://godoc.org/github.com/golang/snappy#Writer) types do indeed provide stream (vs block) handling. Although I have not benchmarked, you should probably prefer that package as it will likely be maintained more than I have time to devote, and also perhaps better integrated with the underlying snappy as they share the same repo.
|
||||
|
||||
For binary compatibility with the [python implementation](https://pypi.python.org/pypi/python-snappy) in [4], one could use the C-snappy compressor/decompressor code directly; using github.com/dgryski/go-csnappy. In fact we did this for a while to verify byte-for-byte compatiblity, as the native Go implementation produces slightly different binary compression (still conformant with the standard of course), which made test-diffs harder, and some have complained about it being slower than the C.
|
||||
|
||||
However, while the c-snappy was useful for checking compatibility, it introduced dependencies on external C libraries (both the c-snappy library and the C standard library). Our go binary executable that used the go-unsnap-stream library was no longer standalone, and deployment was painful if not impossible if the target had a different C standard library. So we've gone back to using the snappy-go implementation (entirely in Go) for ease of deployment. See the comments at the top of unsnap.go if you wish to use c-snappy instead.
|
||||
|
||||
[1] https://groups.google.com/forum/#!msg/snappy-compression/qvLNe2cSH9s/R19oBC-p7g4J
|
||||
|
||||
[2] https://codereview.appspot.com/5167058
|
||||
|
||||
[3] https://github.com/kubo/snzip
|
||||
|
||||
[4] https://pypi.python.org/pypi/python-snappy
|
Binary file not shown.
Binary file not shown.
|
@ -1,375 +0,0 @@
|
|||
package unsnap
|
||||
|
||||
// copyright (c) 2014, Jason E. Aten
|
||||
// license: MIT
|
||||
|
||||
// Some text from the Golang standard library doc is adapted and
|
||||
// reproduced in fragments below to document the expected behaviors
|
||||
// of the interface functions Read()/Write()/ReadFrom()/WriteTo() that
|
||||
// are implemented here. Those descriptions (see
|
||||
// http://golang.org/pkg/io/#Reader for example) are
|
||||
// copyright 2010 The Go Authors.
|
||||
|
||||
import "io"
|
||||
|
||||
// FixedSizeRingBuf:
|
||||
//
|
||||
// a fixed-size circular ring buffer. Yes, just what is says.
|
||||
//
|
||||
// We keep a pair of ping/pong buffers so that we can linearize
|
||||
// the circular buffer into a contiguous slice if need be.
|
||||
//
|
||||
// For efficiency, a FixedSizeRingBuf may be vastly preferred to
|
||||
// a bytes.Buffer. The ReadWithoutAdvance(), Advance(), and Adopt()
|
||||
// methods are all non-standard methods written for speed.
|
||||
//
|
||||
// For an I/O heavy application, I have replaced bytes.Buffer with
|
||||
// FixedSizeRingBuf and seen memory consumption go from 8GB to 25MB.
|
||||
// Yes, that is a 300x reduction in memory footprint. Everything ran
|
||||
// faster too.
|
||||
//
|
||||
// Note that Bytes(), while inescapable at times, is expensive: avoid
|
||||
// it if possible. Instead it is better to use the FixedSizeRingBuf.Readable
|
||||
// member to get the number of bytes available. Bytes() is expensive because
|
||||
// it may copy the back and then the front of a wrapped buffer A[Use]
|
||||
// into A[1-Use] in order to get a contiguous slice. If possible use ContigLen()
|
||||
// first to get the size that can be read without copying, Read() that
|
||||
// amount, and then Read() a second time -- to avoid the copy.
|
||||
|
||||
type FixedSizeRingBuf struct {
|
||||
A [2][]byte // a pair of ping/pong buffers. Only one is active.
|
||||
Use int // which A buffer is in active use, 0 or 1
|
||||
N int // MaxViewInBytes, the size of A[0] and A[1] in bytes.
|
||||
Beg int // start of data in A[Use]
|
||||
Readable int // number of bytes available to read in A[Use]
|
||||
|
||||
OneMade bool // lazily instantiate the [1] buffer. If we never call Bytes(),
|
||||
// we may never need it. If OneMade is false, the Use must be = 0.
|
||||
}
|
||||
|
||||
func (b *FixedSizeRingBuf) Make2ndBuffer() {
|
||||
if b.OneMade {
|
||||
return
|
||||
}
|
||||
b.A[1] = make([]byte, b.N, b.N)
|
||||
b.OneMade = true
|
||||
}
|
||||
|
||||
// get the length of the largest read that we can provide to a contiguous slice
|
||||
// without an extra linearizing copy of all bytes internally.
|
||||
func (b *FixedSizeRingBuf) ContigLen() int {
|
||||
extent := b.Beg + b.Readable
|
||||
firstContigLen := intMin(extent, b.N) - b.Beg
|
||||
return firstContigLen
|
||||
}
|
||||
|
||||
func NewFixedSizeRingBuf(maxViewInBytes int) *FixedSizeRingBuf {
|
||||
n := maxViewInBytes
|
||||
r := &FixedSizeRingBuf{
|
||||
Use: 0, // 0 or 1, whichever is actually in use at the moment.
|
||||
// If we are asked for Bytes() and we wrap, linearize into the other.
|
||||
|
||||
N: n,
|
||||
Beg: 0,
|
||||
Readable: 0,
|
||||
OneMade: false,
|
||||
}
|
||||
r.A[0] = make([]byte, n, n)
|
||||
|
||||
// r.A[1] initialized lazily now.
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// from the standard library description of Bytes():
|
||||
// Bytes() returns a slice of the contents of the unread portion of the buffer.
|
||||
// If the caller changes the contents of the
|
||||
// returned slice, the contents of the buffer will change provided there
|
||||
// are no intervening method calls on the Buffer.
|
||||
//
|
||||
func (b *FixedSizeRingBuf) Bytes() []byte {
|
||||
|
||||
extent := b.Beg + b.Readable
|
||||
if extent <= b.N {
|
||||
// we fit contiguously in this buffer without wrapping to the other
|
||||
return b.A[b.Use][b.Beg:(b.Beg + b.Readable)]
|
||||
}
|
||||
|
||||
// wrap into the other buffer
|
||||
b.Make2ndBuffer()
|
||||
|
||||
src := b.Use
|
||||
dest := 1 - b.Use
|
||||
|
||||
n := copy(b.A[dest], b.A[src][b.Beg:])
|
||||
n += copy(b.A[dest][n:], b.A[src][0:(extent%b.N)])
|
||||
|
||||
b.Use = dest
|
||||
b.Beg = 0
|
||||
|
||||
return b.A[b.Use][:n]
|
||||
}
|
||||
|
||||
// Read():
|
||||
//
|
||||
// from bytes.Buffer.Read(): Read reads the next len(p) bytes
|
||||
// from the buffer or until the buffer is drained. The return
|
||||
// value n is the number of bytes read. If the buffer has no data
|
||||
// to return, err is io.EOF (unless len(p) is zero); otherwise it is nil.
|
||||
//
|
||||
// from the description of the Reader interface,
|
||||
// http://golang.org/pkg/io/#Reader
|
||||
//
|
||||
/*
|
||||
Reader is the interface that wraps the basic Read method.
|
||||
|
||||
Read reads up to len(p) bytes into p. It returns the number
|
||||
of bytes read (0 <= n <= len(p)) and any error encountered.
|
||||
Even if Read returns n < len(p), it may use all of p as scratch
|
||||
space during the call. If some data is available but not
|
||||
len(p) bytes, Read conventionally returns what is available
|
||||
instead of waiting for more.
|
||||
|
||||
When Read encounters an error or end-of-file condition after
|
||||
successfully reading n > 0 bytes, it returns the number of bytes
|
||||
read. It may return the (non-nil) error from the same call or
|
||||
return the error (and n == 0) from a subsequent call. An instance
|
||||
of this general case is that a Reader returning a non-zero number
|
||||
of bytes at the end of the input stream may return
|
||||
either err == EOF or err == nil. The next Read should
|
||||
return 0, EOF regardless.
|
||||
|
||||
Callers should always process the n > 0 bytes returned before
|
||||
considering the error err. Doing so correctly handles I/O errors
|
||||
that happen after reading some bytes and also both of the
|
||||
allowed EOF behaviors.
|
||||
|
||||
Implementations of Read are discouraged from returning a zero
|
||||
byte count with a nil error, and callers should treat that
|
||||
situation as a no-op.
|
||||
*/
|
||||
//
|
||||
|
||||
func (b *FixedSizeRingBuf) Read(p []byte) (n int, err error) {
|
||||
return b.ReadAndMaybeAdvance(p, true)
|
||||
}
|
||||
|
||||
// if you want to Read the data and leave it in the buffer, so as
|
||||
// to peek ahead for example.
|
||||
func (b *FixedSizeRingBuf) ReadWithoutAdvance(p []byte) (n int, err error) {
|
||||
return b.ReadAndMaybeAdvance(p, false)
|
||||
}
|
||||
|
||||
func (b *FixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error) {
|
||||
if len(p) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if b.Readable == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
extent := b.Beg + b.Readable
|
||||
if extent <= b.N {
|
||||
n += copy(p, b.A[b.Use][b.Beg:extent])
|
||||
} else {
|
||||
n += copy(p, b.A[b.Use][b.Beg:b.N])
|
||||
if n < len(p) {
|
||||
n += copy(p[n:], b.A[b.Use][0:(extent%b.N)])
|
||||
}
|
||||
}
|
||||
if doAdvance {
|
||||
b.Advance(n)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// Write writes len(p) bytes from p to the underlying data stream.
|
||||
// It returns the number of bytes written from p (0 <= n <= len(p))
|
||||
// and any error encountered that caused the write to stop early.
|
||||
// Write must return a non-nil error if it returns n < len(p).
|
||||
//
|
||||
func (b *FixedSizeRingBuf) Write(p []byte) (n int, err error) {
|
||||
for {
|
||||
if len(p) == 0 {
|
||||
// nothing (left) to copy in; notice we shorten our
|
||||
// local copy p (below) as we read from it.
|
||||
return
|
||||
}
|
||||
|
||||
writeCapacity := b.N - b.Readable
|
||||
if writeCapacity <= 0 {
|
||||
// we are all full up already.
|
||||
return n, io.ErrShortWrite
|
||||
}
|
||||
if len(p) > writeCapacity {
|
||||
err = io.ErrShortWrite
|
||||
// leave err set and
|
||||
// keep going, write what we can.
|
||||
}
|
||||
|
||||
writeStart := (b.Beg + b.Readable) % b.N
|
||||
|
||||
upperLim := intMin(writeStart+writeCapacity, b.N)
|
||||
|
||||
k := copy(b.A[b.Use][writeStart:upperLim], p)
|
||||
|
||||
n += k
|
||||
b.Readable += k
|
||||
p = p[k:]
|
||||
|
||||
// we can fill from b.A[b.Use][0:something] from
|
||||
// p's remainder, so loop
|
||||
}
|
||||
}
|
||||
|
||||
// WriteTo and ReadFrom avoid intermediate allocation and copies.
|
||||
|
||||
// WriteTo writes data to w until there's no more data to write
|
||||
// or when an error occurs. The return value n is the number of
|
||||
// bytes written. Any error encountered during the write is also returned.
|
||||
func (b *FixedSizeRingBuf) WriteTo(w io.Writer) (n int64, err error) {
|
||||
|
||||
if b.Readable == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
extent := b.Beg + b.Readable
|
||||
firstWriteLen := intMin(extent, b.N) - b.Beg
|
||||
secondWriteLen := b.Readable - firstWriteLen
|
||||
if firstWriteLen > 0 {
|
||||
m, e := w.Write(b.A[b.Use][b.Beg:(b.Beg + firstWriteLen)])
|
||||
n += int64(m)
|
||||
b.Advance(m)
|
||||
|
||||
if e != nil {
|
||||
return n, e
|
||||
}
|
||||
// all bytes should have been written, by definition of
|
||||
// Write method in io.Writer
|
||||
if m != firstWriteLen {
|
||||
return n, io.ErrShortWrite
|
||||
}
|
||||
}
|
||||
if secondWriteLen > 0 {
|
||||
m, e := w.Write(b.A[b.Use][0:secondWriteLen])
|
||||
n += int64(m)
|
||||
b.Advance(m)
|
||||
|
||||
if e != nil {
|
||||
return n, e
|
||||
}
|
||||
// all bytes should have been written, by definition of
|
||||
// Write method in io.Writer
|
||||
if m != secondWriteLen {
|
||||
return n, io.ErrShortWrite
|
||||
}
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// ReadFrom() reads data from r until EOF or error. The return value n
|
||||
// is the number of bytes read. Any error except io.EOF encountered
|
||||
// during the read is also returned.
|
||||
func (b *FixedSizeRingBuf) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
for {
|
||||
writeCapacity := b.N - b.Readable
|
||||
if writeCapacity <= 0 {
|
||||
// we are all full
|
||||
return n, nil
|
||||
}
|
||||
writeStart := (b.Beg + b.Readable) % b.N
|
||||
upperLim := intMin(writeStart+writeCapacity, b.N)
|
||||
|
||||
m, e := r.Read(b.A[b.Use][writeStart:upperLim])
|
||||
n += int64(m)
|
||||
b.Readable += m
|
||||
if e == io.EOF {
|
||||
return n, nil
|
||||
}
|
||||
if e != nil {
|
||||
return n, e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *FixedSizeRingBuf) Reset() {
|
||||
b.Beg = 0
|
||||
b.Readable = 0
|
||||
b.Use = 0
|
||||
}
|
||||
|
||||
// Advance(): non-standard, but better than Next(),
|
||||
// because we don't have to unwrap our buffer and pay the cpu time
|
||||
// for the copy that unwrapping may need.
|
||||
// Useful in conjuction/after ReadWithoutAdvance() above.
|
||||
func (b *FixedSizeRingBuf) Advance(n int) {
|
||||
if n <= 0 {
|
||||
return
|
||||
}
|
||||
if n > b.Readable {
|
||||
n = b.Readable
|
||||
}
|
||||
b.Readable -= n
|
||||
b.Beg = (b.Beg + n) % b.N
|
||||
}
|
||||
|
||||
// Adopt(): non-standard.
|
||||
//
|
||||
// For efficiency's sake, (possibly) take ownership of
|
||||
// already allocated slice offered in me.
|
||||
//
|
||||
// If me is large we will adopt it, and we will potentially then
|
||||
// write to the me buffer.
|
||||
// If we already have a bigger buffer, copy me into the existing
|
||||
// buffer instead.
|
||||
func (b *FixedSizeRingBuf) Adopt(me []byte) {
|
||||
n := len(me)
|
||||
if n > b.N {
|
||||
b.A[0] = me
|
||||
b.OneMade = false
|
||||
b.N = n
|
||||
b.Use = 0
|
||||
b.Beg = 0
|
||||
b.Readable = n
|
||||
} else {
|
||||
// we already have a larger buffer, reuse it.
|
||||
copy(b.A[0], me)
|
||||
b.Use = 0
|
||||
b.Beg = 0
|
||||
b.Readable = n
|
||||
}
|
||||
}
|
||||
|
||||
func intMax(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func intMin(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
// Get the (beg, end] indices of the tailing empty buffer of bytes slice that from that is free for writing.
|
||||
// Note: not guaranteed to be zeroed. At all.
|
||||
func (b *FixedSizeRingBuf) GetEndmostWritable() (beg int, end int) {
|
||||
extent := b.Beg + b.Readable
|
||||
if extent < b.N {
|
||||
return extent, b.N
|
||||
}
|
||||
|
||||
return extent % b.N, b.Beg
|
||||
}
|
||||
|
||||
// Note: not guaranteed to be zeroed.
|
||||
func (b *FixedSizeRingBuf) GetEndmostWritableSlice() []byte {
|
||||
beg, e := b.GetEndmostWritable()
|
||||
return b.A[b.Use][beg:e]
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
package unsnap
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
// no c lib dependency
|
||||
snappy "github.com/golang/snappy"
|
||||
// or, use the C wrapper for speed
|
||||
//snappy "github.com/dgryski/go-csnappy"
|
||||
)
|
||||
|
||||
// add Write() method for SnappyFile (see unsnap.go)
|
||||
|
||||
// reference for snappy framing/streaming format:
|
||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
// ?spec=svn68&r=71
|
||||
|
||||
//
|
||||
// Write writes len(p) bytes from p to the underlying data stream.
|
||||
// It returns the number of bytes written from p (0 <= n <= len(p)) and
|
||||
// any error encountered that caused the write to stop early. Write
|
||||
// must return a non-nil error if it returns n < len(p).
|
||||
//
|
||||
func (sf *SnappyFile) Write(p []byte) (n int, err error) {
|
||||
|
||||
if sf.SnappyEncodeDecodeOff {
|
||||
return sf.Writer.Write(p)
|
||||
}
|
||||
|
||||
if !sf.Writing {
|
||||
panic("Writing on a read-only SnappyFile")
|
||||
}
|
||||
|
||||
// encoding in snappy can apparently go beyond the original size, beware.
|
||||
// so our buffers must be sized 2*max snappy chunk => 2 * CHUNK_MAX(65536)
|
||||
|
||||
sf.DecBuf.Reset()
|
||||
sf.EncBuf.Reset()
|
||||
|
||||
if !sf.HeaderChunkWritten {
|
||||
sf.HeaderChunkWritten = true
|
||||
_, err = sf.Writer.Write(SnappyStreamHeaderMagic)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
var chunk []byte
|
||||
var chunk_type byte
|
||||
var crc uint32
|
||||
|
||||
for len(p) > 0 {
|
||||
|
||||
// chunk points to input p by default, unencoded input.
|
||||
chunk = p[:IntMin(len(p), CHUNK_MAX)]
|
||||
crc = masked_crc32c(chunk)
|
||||
|
||||
writeme := chunk[:]
|
||||
|
||||
// first write to EncBuf, as a temp, in case we want
|
||||
// to discard and send uncompressed instead.
|
||||
compressed_chunk := snappy.Encode(sf.EncBuf.GetEndmostWritableSlice(), chunk)
|
||||
|
||||
if len(compressed_chunk) <= int((1-_COMPRESSION_THRESHOLD)*float64(len(chunk))) {
|
||||
writeme = compressed_chunk
|
||||
chunk_type = _COMPRESSED_CHUNK
|
||||
} else {
|
||||
// keep writeme pointing at original chunk (uncompressed)
|
||||
chunk_type = _UNCOMPRESSED_CHUNK
|
||||
}
|
||||
|
||||
const crc32Sz = 4
|
||||
var tag32 uint32 = uint32(chunk_type) + (uint32(len(writeme)+crc32Sz) << 8)
|
||||
|
||||
err = binary.Write(sf.Writer, binary.LittleEndian, tag32)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = binary.Write(sf.Writer, binary.LittleEndian, crc)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = sf.Writer.Write(writeme)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
n += len(chunk)
|
||||
p = p[len(chunk):]
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func IntMin(a int, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
hello_snappy
|
Binary file not shown.
|
@ -1,520 +0,0 @@
|
|||
package unsnap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"hash/crc32"
|
||||
|
||||
snappy "github.com/golang/snappy"
|
||||
// The C library can be used, but this makes the binary dependent
|
||||
// lots of extraneous c-libraries; it is no longer stand-alone. Yuck.
|
||||
//
|
||||
// Therefore we comment out the "dgryski/go-csnappy" path and use the
|
||||
// "github.com/golang/snappy/snappy" above instead. If you are
|
||||
// performance limited and can deal with distributing more libraries,
|
||||
// then this is easy to swap.
|
||||
//
|
||||
// If you swap, note that some of the tests won't pass
|
||||
// because snappy-go produces slightly different (but still
|
||||
// conformant) encodings on some data. Here are bindings
|
||||
// to the C-snappy:
|
||||
// snappy "github.com/dgryski/go-csnappy"
|
||||
)
|
||||
|
||||
// SnappyFile: create a drop-in-replacement/wrapper for an *os.File that handles doing the unsnappification online as more is read from it
|
||||
|
||||
type SnappyFile struct {
|
||||
Fname string
|
||||
|
||||
Reader io.Reader
|
||||
Writer io.Writer
|
||||
|
||||
// allow clients to substitute us for an os.File and just switch
|
||||
// off compression if they don't want it.
|
||||
SnappyEncodeDecodeOff bool // if true, we bypass straight to Filep
|
||||
|
||||
EncBuf FixedSizeRingBuf // holds any extra that isn't yet returned, encoded
|
||||
DecBuf FixedSizeRingBuf // holds any extra that isn't yet returned, decoded
|
||||
|
||||
// for writing to stream-framed snappy
|
||||
HeaderChunkWritten bool
|
||||
|
||||
// Sanity check: we can only read, or only write, to one SnappyFile.
|
||||
// EncBuf and DecBuf are used differently in each mode. Verify
|
||||
// that we are consistent with this flag.
|
||||
Writing bool
|
||||
}
|
||||
|
||||
var total int
|
||||
|
||||
// for debugging, show state of buffers
|
||||
func (f *SnappyFile) Dump() {
|
||||
fmt.Printf("EncBuf has length %d and contents:\n%s\n", len(f.EncBuf.Bytes()), string(f.EncBuf.Bytes()))
|
||||
fmt.Printf("DecBuf has length %d and contents:\n%s\n", len(f.DecBuf.Bytes()), string(f.DecBuf.Bytes()))
|
||||
}
|
||||
|
||||
func (f *SnappyFile) Read(p []byte) (n int, err error) {
|
||||
|
||||
if f.SnappyEncodeDecodeOff {
|
||||
return f.Reader.Read(p)
|
||||
}
|
||||
|
||||
if f.Writing {
|
||||
panic("Reading on a write-only SnappyFile")
|
||||
}
|
||||
|
||||
// before we unencrypt more, try to drain the DecBuf first
|
||||
n, _ = f.DecBuf.Read(p)
|
||||
if n > 0 {
|
||||
total += n
|
||||
return n, nil
|
||||
}
|
||||
|
||||
//nEncRead, nDecAdded, err := UnsnapOneFrame(f.Filep, &f.EncBuf, &f.DecBuf, f.Fname)
|
||||
_, _, err = UnsnapOneFrame(f.Reader, &f.EncBuf, &f.DecBuf, f.Fname)
|
||||
if err != nil && err != io.EOF {
|
||||
return
|
||||
}
|
||||
|
||||
n, _ = f.DecBuf.Read(p)
|
||||
|
||||
if n > 0 {
|
||||
total += n
|
||||
return n, nil
|
||||
}
|
||||
if f.DecBuf.Readable == 0 {
|
||||
if f.DecBuf.Readable == 0 && f.EncBuf.Readable == 0 {
|
||||
// only now (when EncBuf is empty) can we give io.EOF.
|
||||
// Any earlier, and we leave stuff un-decoded!
|
||||
return 0, io.EOF
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func Open(name string) (file *SnappyFile, err error) {
|
||||
fp, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// encoding in snappy can apparently go beyond the original size, so
|
||||
// we make our buffers big enough, 2*max snappy chunk => 2 * CHUNK_MAX(65536)
|
||||
|
||||
snap := NewReader(fp)
|
||||
snap.Fname = name
|
||||
return snap, nil
|
||||
}
|
||||
|
||||
func NewReader(r io.Reader) *SnappyFile {
|
||||
return &SnappyFile{
|
||||
Reader: r,
|
||||
EncBuf: *NewFixedSizeRingBuf(CHUNK_MAX * 2), // buffer of snappy encoded bytes
|
||||
DecBuf: *NewFixedSizeRingBuf(CHUNK_MAX * 2), // buffer of snapppy decoded bytes
|
||||
Writing: false,
|
||||
}
|
||||
}
|
||||
|
||||
func NewWriter(w io.Writer) *SnappyFile {
|
||||
return &SnappyFile{
|
||||
Writer: w,
|
||||
EncBuf: *NewFixedSizeRingBuf(65536), // on writing: temp for testing compression
|
||||
DecBuf: *NewFixedSizeRingBuf(65536 * 2), // on writing: final buffer of snappy framed and encoded bytes
|
||||
Writing: true,
|
||||
}
|
||||
}
|
||||
|
||||
func Create(name string) (file *SnappyFile, err error) {
|
||||
fp, err := os.Create(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
snap := NewWriter(fp)
|
||||
snap.Fname = name
|
||||
return snap, nil
|
||||
}
|
||||
|
||||
func (f *SnappyFile) Close() error {
|
||||
if f.Writing {
|
||||
wc, ok := f.Writer.(io.WriteCloser)
|
||||
if ok {
|
||||
return wc.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
rc, ok := f.Reader.(io.ReadCloser)
|
||||
if ok {
|
||||
return rc.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *SnappyFile) Sync() error {
|
||||
file, ok := f.Writer.(*os.File)
|
||||
if ok {
|
||||
return file.Sync()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// for an increment of a frame at a time:
|
||||
// read from r into encBuf (encBuf is still encoded, thus the name), and write unsnappified frames into outDecodedBuf
|
||||
// the returned n: number of bytes read from the encrypted encBuf
|
||||
func UnsnapOneFrame(r io.Reader, encBuf *FixedSizeRingBuf, outDecodedBuf *FixedSizeRingBuf, fname string) (nEnc int64, nDec int64, err error) {
|
||||
// b, err := ioutil.ReadAll(r)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
|
||||
nEnc = 0
|
||||
nDec = 0
|
||||
|
||||
// read up to 65536 bytes from r into encBuf, at least a snappy frame
|
||||
nread, err := io.CopyN(encBuf, r, 65536) // returns nwrotebytes, err
|
||||
nEnc += nread
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
if nread == 0 {
|
||||
if encBuf.Readable == 0 {
|
||||
return nEnc, nDec, io.EOF
|
||||
}
|
||||
// else we have bytes in encBuf, so decode them!
|
||||
err = nil
|
||||
} else {
|
||||
// continue below, processing the nread bytes
|
||||
err = nil
|
||||
}
|
||||
} else {
|
||||
// may be an odd already closed... don't panic on that
|
||||
if strings.Contains(err.Error(), "file already closed") {
|
||||
err = nil
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// flag for printing chunk size alignment messages
|
||||
verbose := false
|
||||
|
||||
const snappyStreamHeaderSz = 10
|
||||
const headerSz = 4
|
||||
const crc32Sz = 4
|
||||
// the magic 18 bytes accounts for the snappy streaming header and the first chunks size and checksum
|
||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
|
||||
chunk := (*encBuf).Bytes()
|
||||
|
||||
// however we exit, advance as
|
||||
// defer func() { (*encBuf).Next(N) }()
|
||||
|
||||
// 65536 is the max size of a snappy framed chunk. See
|
||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt:91
|
||||
// buf := make([]byte, 65536)
|
||||
|
||||
// fmt.Printf("read from file, b is len:%d with value: %#v\n", len(b), b)
|
||||
// fmt.Printf("read from file, bcut is len:%d with value: %#v\n", len(bcut), bcut)
|
||||
|
||||
//fmt.Printf("raw bytes of chunksz are: %v\n", b[11:14])
|
||||
|
||||
fourbytes := make([]byte, 4)
|
||||
chunkCount := 0
|
||||
|
||||
for nDec < 65536 {
|
||||
if len(chunk) == 0 {
|
||||
break
|
||||
}
|
||||
chunkCount++
|
||||
fourbytes[3] = 0
|
||||
copy(fourbytes, chunk[1:4])
|
||||
chunksz := binary.LittleEndian.Uint32(fourbytes)
|
||||
chunk_type := chunk[0]
|
||||
|
||||
switch true {
|
||||
case chunk_type == 0xff:
|
||||
{ // stream identifier
|
||||
|
||||
streamHeader := chunk[:snappyStreamHeaderSz]
|
||||
if 0 != bytes.Compare(streamHeader, []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}) {
|
||||
panic("file had chunk starting with 0xff but then no magic snappy streaming protocol bytes, aborting.")
|
||||
} else {
|
||||
//fmt.Printf("got streaming snappy magic header just fine.\n")
|
||||
}
|
||||
chunk = chunk[snappyStreamHeaderSz:]
|
||||
(*encBuf).Advance(snappyStreamHeaderSz)
|
||||
nEnc += snappyStreamHeaderSz
|
||||
continue
|
||||
}
|
||||
case chunk_type == 0x00:
|
||||
{ // compressed data
|
||||
if verbose {
|
||||
fmt.Fprintf(os.Stderr, "chunksz is %d while total bytes avail are: %d\n", int(chunksz), len(chunk)-4)
|
||||
}
|
||||
|
||||
crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
|
||||
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
|
||||
|
||||
dec, ok := snappy.Decode(nil, section)
|
||||
if ok != nil {
|
||||
// we've probably truncated a snappy frame at this point
|
||||
// ok=snappy: corrupt input
|
||||
// len(dec) == 0
|
||||
//
|
||||
err = fmt.Errorf("could not decode snappy stream: '%s' and len dec=%d and error='%v'\n", fname, len(dec), ok)
|
||||
|
||||
// get back to caller with what we've got so far
|
||||
return nEnc, nDec, err
|
||||
}
|
||||
// fmt.Printf("ok, b is %#v , %#v\n", ok, dec)
|
||||
|
||||
// spit out decoded text
|
||||
// n, err := w.Write(dec)
|
||||
//fmt.Printf("len(dec) = %d, outDecodedBuf.Readable=%d\n", len(dec), outDecodedBuf.Readable)
|
||||
bnb := bytes.NewBuffer(dec)
|
||||
n, err := io.Copy(outDecodedBuf, bnb)
|
||||
if err != nil {
|
||||
//fmt.Printf("got n=%d, err= %s ; when trying to io.Copy(outDecodedBuf: N=%d, Readable=%d)\n", n, err, outDecodedBuf.N, outDecodedBuf.Readable)
|
||||
panic(err)
|
||||
}
|
||||
if n != int64(len(dec)) {
|
||||
panic("could not write all bytes to outDecodedBuf")
|
||||
}
|
||||
nDec += n
|
||||
|
||||
// verify the crc32 rotated checksum
|
||||
m32 := masked_crc32c(dec)
|
||||
if m32 != crc {
|
||||
panic(fmt.Sprintf("crc32 masked failiure. expected: %v but got: %v", crc, m32))
|
||||
} else {
|
||||
//fmt.Printf("\nchecksums match: %v == %v\n", crc, m32)
|
||||
}
|
||||
|
||||
// move to next header
|
||||
inc := (headerSz + int(chunksz))
|
||||
chunk = chunk[inc:]
|
||||
(*encBuf).Advance(inc)
|
||||
nEnc += int64(inc)
|
||||
continue
|
||||
}
|
||||
case chunk_type == 0x01:
|
||||
{ // uncompressed data
|
||||
|
||||
//n, err := w.Write(chunk[(headerSz+crc32Sz):(headerSz + int(chunksz))])
|
||||
n, err := io.Copy(outDecodedBuf, bytes.NewBuffer(chunk[(headerSz+crc32Sz):(headerSz+int(chunksz))]))
|
||||
if verbose {
|
||||
//fmt.Printf("debug: n=%d err=%v chunksz=%d outDecodedBuf='%v'\n", n, err, chunksz, outDecodedBuf)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if n != int64(chunksz-crc32Sz) {
|
||||
panic("could not write all bytes to stdout")
|
||||
}
|
||||
nDec += n
|
||||
|
||||
inc := (headerSz + int(chunksz))
|
||||
chunk = chunk[inc:]
|
||||
(*encBuf).Advance(inc)
|
||||
nEnc += int64(inc)
|
||||
continue
|
||||
}
|
||||
case chunk_type == 0xfe:
|
||||
fallthrough // padding, just skip it
|
||||
case chunk_type >= 0x80 && chunk_type <= 0xfd:
|
||||
{ // Reserved skippable chunks
|
||||
//fmt.Printf("\nin reserved skippable chunks, at nEnc=%v\n", nEnc)
|
||||
inc := (headerSz + int(chunksz))
|
||||
chunk = chunk[inc:]
|
||||
nEnc += int64(inc)
|
||||
(*encBuf).Advance(inc)
|
||||
continue
|
||||
}
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("unrecognized/unsupported chunk type %#v; on fname='%v'", chunk_type, fname)
|
||||
return nEnc, nDec, err
|
||||
}
|
||||
|
||||
} // end for{}
|
||||
|
||||
return nEnc, nDec, err
|
||||
//return int64(N), nil
|
||||
}
|
||||
|
||||
// for whole file at once:
|
||||
//
|
||||
// receive on stdin a stream of bytes in the snappy-streaming framed
|
||||
// format, defined here: http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
// Grab each frame, run it through the snappy decoder, and spit out
|
||||
// each frame all joined back-to-back on stdout.
|
||||
//
|
||||
func Unsnappy(r io.Reader, w io.Writer) (err error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// flag for printing chunk size alignment messages
|
||||
verbose := false
|
||||
|
||||
const snappyStreamHeaderSz = 10
|
||||
const headerSz = 4
|
||||
const crc32Sz = 4
|
||||
// the magic 18 bytes accounts for the snappy streaming header and the first chunks size and checksum
|
||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
|
||||
chunk := b[:]
|
||||
|
||||
// 65536 is the max size of a snappy framed chunk. See
|
||||
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt:91
|
||||
//buf := make([]byte, 65536)
|
||||
|
||||
// fmt.Printf("read from file, b is len:%d with value: %#v\n", len(b), b)
|
||||
// fmt.Printf("read from file, bcut is len:%d with value: %#v\n", len(bcut), bcut)
|
||||
|
||||
//fmt.Printf("raw bytes of chunksz are: %v\n", b[11:14])
|
||||
|
||||
fourbytes := make([]byte, 4)
|
||||
chunkCount := 0
|
||||
|
||||
for {
|
||||
if len(chunk) == 0 {
|
||||
break
|
||||
}
|
||||
chunkCount++
|
||||
fourbytes[3] = 0
|
||||
copy(fourbytes, chunk[1:4])
|
||||
chunksz := binary.LittleEndian.Uint32(fourbytes)
|
||||
chunk_type := chunk[0]
|
||||
|
||||
switch true {
|
||||
case chunk_type == 0xff:
|
||||
{ // stream identifier
|
||||
|
||||
streamHeader := chunk[:snappyStreamHeaderSz]
|
||||
if 0 != bytes.Compare(streamHeader, []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}) {
|
||||
panic("file had chunk starting with 0xff but then no magic snappy streaming protocol bytes, aborting.")
|
||||
} else {
|
||||
//fmt.Printf("got streaming snappy magic header just fine.\n")
|
||||
}
|
||||
chunk = chunk[snappyStreamHeaderSz:]
|
||||
continue
|
||||
}
|
||||
case chunk_type == 0x00:
|
||||
{ // compressed data
|
||||
if verbose {
|
||||
fmt.Fprintf(os.Stderr, "chunksz is %d while total bytes avail are: %d\n", int(chunksz), len(chunk)-4)
|
||||
}
|
||||
|
||||
//crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
|
||||
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
|
||||
|
||||
dec, ok := snappy.Decode(nil, section)
|
||||
if ok != nil {
|
||||
panic("could not decode snappy stream")
|
||||
}
|
||||
// fmt.Printf("ok, b is %#v , %#v\n", ok, dec)
|
||||
|
||||
// spit out decoded text
|
||||
n, err := w.Write(dec)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if n != len(dec) {
|
||||
panic("could not write all bytes to stdout")
|
||||
}
|
||||
|
||||
// TODO: verify the crc32 rotated checksum?
|
||||
|
||||
// move to next header
|
||||
chunk = chunk[(headerSz + int(chunksz)):]
|
||||
continue
|
||||
}
|
||||
case chunk_type == 0x01:
|
||||
{ // uncompressed data
|
||||
|
||||
//crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
|
||||
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
|
||||
|
||||
n, err := w.Write(section)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if n != int(chunksz-crc32Sz) {
|
||||
panic("could not write all bytes to stdout")
|
||||
}
|
||||
|
||||
chunk = chunk[(headerSz + int(chunksz)):]
|
||||
continue
|
||||
}
|
||||
case chunk_type == 0xfe:
|
||||
fallthrough // padding, just skip it
|
||||
case chunk_type >= 0x80 && chunk_type <= 0xfd:
|
||||
{ // Reserved skippable chunks
|
||||
chunk = chunk[(headerSz + int(chunksz)):]
|
||||
continue
|
||||
}
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("unrecognized/unsupported chunk type %#v", chunk_type))
|
||||
}
|
||||
|
||||
} // end for{}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 0xff 0x06 0x00 0x00 sNaPpY
|
||||
var SnappyStreamHeaderMagic = []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}
|
||||
|
||||
const CHUNK_MAX = 65536
|
||||
const _STREAM_TO_STREAM_BLOCK_SIZE = CHUNK_MAX
|
||||
const _STREAM_IDENTIFIER = `sNaPpY`
|
||||
const _COMPRESSED_CHUNK = 0x00
|
||||
const _UNCOMPRESSED_CHUNK = 0x01
|
||||
const _IDENTIFIER_CHUNK = 0xff
|
||||
const _RESERVED_UNSKIPPABLE0 = 0x02 // chunk ranges are [inclusive, exclusive)
|
||||
const _RESERVED_UNSKIPPABLE1 = 0x80
|
||||
const _RESERVED_SKIPPABLE0 = 0x80
|
||||
const _RESERVED_SKIPPABLE1 = 0xff
|
||||
|
||||
// the minimum percent of bytes compression must save to be enabled in automatic
|
||||
// mode
|
||||
const _COMPRESSION_THRESHOLD = .125
|
||||
|
||||
var crctab *crc32.Table
|
||||
|
||||
func init() {
|
||||
crctab = crc32.MakeTable(crc32.Castagnoli) // this is correct table, matches the crc32c.c code used by python
|
||||
}
|
||||
|
||||
func masked_crc32c(data []byte) uint32 {
|
||||
|
||||
// see the framing format specification, http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
var crc uint32 = crc32.Checksum(data, crctab)
|
||||
return (uint32((crc>>15)|(crc<<17)) + 0xa282ead8)
|
||||
}
|
||||
|
||||
func ReadSnappyStreamCompressedFile(filename string) ([]byte, error) {
|
||||
|
||||
snappyFile, err := Open(filename)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
var bb bytes.Buffer
|
||||
_, err = bb.ReadFrom(snappyFile)
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return bb.Bytes(), err
|
||||
}
|
|
@ -17,7 +17,7 @@ func main() {
|
|||
// for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing
|
||||
r.Use(cors.Handler(cors.Options{
|
||||
// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
|
||||
AllowedOrigins: []string{"*"},
|
||||
AllowedOrigins: []string{"https://*", "http://*"},
|
||||
// AllowOriginFunc: func(r *http.Request, origin string) bool { return true },
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
module github.com/go-chi/cors
|
||||
|
||||
go 1.14
|
|
@ -1,4 +1,4 @@
|
|||
# go-billy [![GoDoc](https://godoc.org/gopkg.in/go-git/go-billy.v5?status.svg)](https://pkg.go.dev/github.com/go-git/go-billy) [![Test](https://github.com/go-git/go-billy/workflows/Test/badge.svg)](https://github.com/go-git/go-billy/actions?query=workflow%3ATest)
|
||||
# go-billy [![GoDoc](https://godoc.org/gopkg.in/go-git/go-billy.v5?status.svg)](https://pkg.go.dev/github.com/go-git/go-billy/v5) [![Test](https://github.com/go-git/go-billy/workflows/Test/badge.svg)](https://github.com/go-git/go-billy/actions?query=workflow%3ATest)
|
||||
|
||||
The missing interface filesystem abstraction for Go.
|
||||
Billy implements an interface based on the `os` standard library, allowing to develop applications without dependency on the underlying storage. Makes it virtually free to implement mocks and testing over filesystem operations.
|
||||
|
|
|
@ -89,6 +89,13 @@ type Config struct {
|
|||
Window uint
|
||||
}
|
||||
|
||||
Init struct {
|
||||
// DefaultBranch Allows overriding the default branch name
|
||||
// e.g. when initializing a new repository or when cloning
|
||||
// an empty repository.
|
||||
DefaultBranch string
|
||||
}
|
||||
|
||||
// Remotes list of repository remotes, the key of the map is the name
|
||||
// of the remote, should equal to RemoteConfig.Name.
|
||||
Remotes map[string]*RemoteConfig
|
||||
|
@ -98,6 +105,9 @@ type Config struct {
|
|||
// Branches list of branches, the key is the branch name and should
|
||||
// equal Branch.Name
|
||||
Branches map[string]*Branch
|
||||
// URLs list of url rewrite rules, if repo url starts with URL.InsteadOf value, it will be replaced with the
|
||||
// key instead.
|
||||
URLs map[string]*URL
|
||||
// Raw contains the raw information of a config file. The main goal is
|
||||
// preserve the parsed information from the original format, to avoid
|
||||
// dropping unsupported fields.
|
||||
|
@ -110,6 +120,7 @@ func NewConfig() *Config {
|
|||
Remotes: make(map[string]*RemoteConfig),
|
||||
Submodules: make(map[string]*Submodule),
|
||||
Branches: make(map[string]*Branch),
|
||||
URLs: make(map[string]*URL),
|
||||
Raw: format.New(),
|
||||
}
|
||||
|
||||
|
@ -223,6 +234,8 @@ const (
|
|||
userSection = "user"
|
||||
authorSection = "author"
|
||||
committerSection = "committer"
|
||||
initSection = "init"
|
||||
urlSection = "url"
|
||||
fetchKey = "fetch"
|
||||
urlKey = "url"
|
||||
bareKey = "bare"
|
||||
|
@ -233,6 +246,7 @@ const (
|
|||
rebaseKey = "rebase"
|
||||
nameKey = "name"
|
||||
emailKey = "email"
|
||||
defaultBranchKey = "defaultBranch"
|
||||
|
||||
// DefaultPackWindow holds the number of previous objects used to
|
||||
// generate deltas. The value 10 is the same used by git command.
|
||||
|
@ -251,6 +265,7 @@ func (c *Config) Unmarshal(b []byte) error {
|
|||
|
||||
c.unmarshalCore()
|
||||
c.unmarshalUser()
|
||||
c.unmarshalInit()
|
||||
if err := c.unmarshalPack(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -260,6 +275,10 @@ func (c *Config) Unmarshal(b []byte) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := c.unmarshalURLs(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.unmarshalRemotes()
|
||||
}
|
||||
|
||||
|
@ -313,6 +332,25 @@ func (c *Config) unmarshalRemotes() error {
|
|||
c.Remotes[r.Name] = r
|
||||
}
|
||||
|
||||
// Apply insteadOf url rules
|
||||
for _, r := range c.Remotes {
|
||||
r.applyURLRules(c.URLs)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) unmarshalURLs() error {
|
||||
s := c.Raw.Section(urlSection)
|
||||
for _, sub := range s.Subsections {
|
||||
r := &URL{}
|
||||
if err := r.unmarshal(sub); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.URLs[r.Name] = r
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -344,6 +382,11 @@ func (c *Config) unmarshalBranches() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) unmarshalInit() {
|
||||
s := c.Raw.Section(initSection)
|
||||
c.Init.DefaultBranch = s.Options.Get(defaultBranchKey)
|
||||
}
|
||||
|
||||
// Marshal returns Config encoded as a git-config file.
|
||||
func (c *Config) Marshal() ([]byte, error) {
|
||||
c.marshalCore()
|
||||
|
@ -352,6 +395,8 @@ func (c *Config) Marshal() ([]byte, error) {
|
|||
c.marshalRemotes()
|
||||
c.marshalSubmodules()
|
||||
c.marshalBranches()
|
||||
c.marshalURLs()
|
||||
c.marshalInit()
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if err := format.NewEncoder(buf).Encode(c.Raw); err != nil {
|
||||
|
@ -475,6 +520,27 @@ func (c *Config) marshalBranches() {
|
|||
s.Subsections = newSubsections
|
||||
}
|
||||
|
||||
func (c *Config) marshalURLs() {
|
||||
s := c.Raw.Section(urlSection)
|
||||
s.Subsections = make(format.Subsections, len(c.URLs))
|
||||
|
||||
var i int
|
||||
for _, r := range c.URLs {
|
||||
section := r.marshal()
|
||||
// the submodule section at config is a subset of the .gitmodule file
|
||||
// we should remove the non-valid options for the config file.
|
||||
s.Subsections[i] = section
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) marshalInit() {
|
||||
s := c.Raw.Section(initSection)
|
||||
if c.Init.DefaultBranch != "" {
|
||||
s.SetOption(defaultBranchKey, c.Init.DefaultBranch)
|
||||
}
|
||||
}
|
||||
|
||||
// RemoteConfig contains the configuration for a given remote repository.
|
||||
type RemoteConfig struct {
|
||||
// Name of the remote
|
||||
|
@ -482,6 +548,12 @@ type RemoteConfig struct {
|
|||
// URLs the URLs of a remote repository. It must be non-empty. Fetch will
|
||||
// always use the first URL, while push will use all of them.
|
||||
URLs []string
|
||||
|
||||
// insteadOfRulesApplied have urls been modified
|
||||
insteadOfRulesApplied bool
|
||||
// originalURLs are the urls before applying insteadOf rules
|
||||
originalURLs []string
|
||||
|
||||
// Fetch the default set of "refspec" for fetch operation
|
||||
Fetch []RefSpec
|
||||
|
||||
|
@ -542,7 +614,12 @@ func (c *RemoteConfig) marshal() *format.Subsection {
|
|||
if len(c.URLs) == 0 {
|
||||
c.raw.RemoveOption(urlKey)
|
||||
} else {
|
||||
c.raw.SetOption(urlKey, c.URLs...)
|
||||
urls := c.URLs
|
||||
if c.insteadOfRulesApplied {
|
||||
urls = c.originalURLs
|
||||
}
|
||||
|
||||
c.raw.SetOption(urlKey, urls...)
|
||||
}
|
||||
|
||||
if len(c.Fetch) == 0 {
|
||||
|
@ -562,3 +639,20 @@ func (c *RemoteConfig) marshal() *format.Subsection {
|
|||
func (c *RemoteConfig) IsFirstURLLocal() bool {
|
||||
return url.IsLocalEndpoint(c.URLs[0])
|
||||
}
|
||||
|
||||
func (c *RemoteConfig) applyURLRules(urlRules map[string]*URL) {
|
||||
// save original urls
|
||||
originalURLs := make([]string, len(c.URLs))
|
||||
copy(originalURLs, c.URLs)
|
||||
|
||||
for i, url := range c.URLs {
|
||||
if matchingURLRule := findLongestInsteadOfMatch(url, urlRules); matchingURLRule != nil {
|
||||
c.URLs[i] = matchingURLRule.ApplyInsteadOf(c.URLs[i])
|
||||
c.insteadOfRulesApplied = true
|
||||
}
|
||||
}
|
||||
|
||||
if c.insteadOfRulesApplied {
|
||||
c.originalURLs = originalURLs
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
format "github.com/go-git/go-git/v5/plumbing/format/config"
|
||||
)
|
||||
|
||||
var (
|
||||
errURLEmptyInsteadOf = errors.New("url config: empty insteadOf")
|
||||
)
|
||||
|
||||
// Url defines Url rewrite rules
|
||||
type URL struct {
|
||||
// Name new base url
|
||||
Name string
|
||||
// Any URL that starts with this value will be rewritten to start, instead, with <base>.
|
||||
// When more than one insteadOf strings match a given URL, the longest match is used.
|
||||
InsteadOf string
|
||||
|
||||
// raw representation of the subsection, filled by marshal or unmarshal are
|
||||
// called.
|
||||
raw *format.Subsection
|
||||
}
|
||||
|
||||
// Validate validates fields of branch
|
||||
func (b *URL) Validate() error {
|
||||
if b.InsteadOf == "" {
|
||||
return errURLEmptyInsteadOf
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
insteadOfKey = "insteadOf"
|
||||
)
|
||||
|
||||
func (u *URL) unmarshal(s *format.Subsection) error {
|
||||
u.raw = s
|
||||
|
||||
u.Name = s.Name
|
||||
u.InsteadOf = u.raw.Option(insteadOfKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *URL) marshal() *format.Subsection {
|
||||
if u.raw == nil {
|
||||
u.raw = &format.Subsection{}
|
||||
}
|
||||
|
||||
u.raw.Name = u.Name
|
||||
u.raw.SetOption(insteadOfKey, u.InsteadOf)
|
||||
|
||||
return u.raw
|
||||
}
|
||||
|
||||
func findLongestInsteadOfMatch(remoteURL string, urls map[string]*URL) *URL {
|
||||
var longestMatch *URL
|
||||
for _, u := range urls {
|
||||
if !strings.HasPrefix(remoteURL, u.InsteadOf) {
|
||||
continue
|
||||
}
|
||||
|
||||
// according to spec if there is more than one match, take the logest
|
||||
if longestMatch == nil || len(longestMatch.InsteadOf) < len(u.InsteadOf) {
|
||||
longestMatch = u
|
||||
}
|
||||
}
|
||||
|
||||
return longestMatch
|
||||
}
|
||||
|
||||
func (u *URL) ApplyInsteadOf(url string) string {
|
||||
if !strings.HasPrefix(url, u.InsteadOf) {
|
||||
return url
|
||||
}
|
||||
|
||||
return u.Name + url[len(u.InsteadOf):]
|
||||
}
|
|
@ -1,27 +1,27 @@
|
|||
module github.com/go-git/go-git/v5
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
||||
github.com/emirpasic/gods v1.12.0
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
|
||||
github.com/gliderlabs/ssh v0.2.2
|
||||
github.com/go-git/gcfg v1.5.0
|
||||
github.com/go-git/go-billy/v5 v5.0.0
|
||||
github.com/go-git/go-billy/v5 v5.1.0
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12
|
||||
github.com/google/go-cmp v0.3.0
|
||||
github.com/imdario/mergo v0.3.9
|
||||
github.com/imdario/mergo v0.3.12
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
||||
github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd
|
||||
github.com/jessevdk/go-flags v1.5.0
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/sergi/go-diff v1.1.0
|
||||
github.com/xanzy/ssh-agent v0.2.1
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
|
||||
golang.org/x/text v0.3.2
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f
|
||||
github.com/xanzy/ssh-agent v0.3.0
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897
|
||||
golang.org/x/text v0.3.3
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
)
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
|
@ -18,6 +21,8 @@ github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
|||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.1.0 h1:4pl5BV4o7ZG/lterP4S6WzJ6xr49Ba5ET9ygheTYahk=
|
||||
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
||||
|
@ -26,14 +31,23 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
|||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
|
@ -45,38 +59,62 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
|
|||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
|
@ -60,6 +60,10 @@ type CloneOptions struct {
|
|||
// Tags describe how the tags will be fetched from the remote repository,
|
||||
// by default is AllTags.
|
||||
Tags TagMode
|
||||
// InsecureSkipTLS skips ssl verify if protocol is https
|
||||
InsecureSkipTLS bool
|
||||
// CABundle specify additional ca bundle with system cert pool
|
||||
CABundle []byte
|
||||
}
|
||||
|
||||
// Validate validates the fields and sets the default values.
|
||||
|
@ -105,6 +109,10 @@ type PullOptions struct {
|
|||
// Force allows the pull to update a local branch even when the remote
|
||||
// branch does not descend from it.
|
||||
Force bool
|
||||
// InsecureSkipTLS skips ssl verify if protocol is https
|
||||
InsecureSkipTLS bool
|
||||
// CABundle specify additional ca bundle with system cert pool
|
||||
CABundle []byte
|
||||
}
|
||||
|
||||
// Validate validates the fields and sets the default values.
|
||||
|
@ -155,6 +163,10 @@ type FetchOptions struct {
|
|||
// Force allows the fetch to update a local branch even when the remote
|
||||
// branch does not descend from it.
|
||||
Force bool
|
||||
// InsecureSkipTLS skips ssl verify if protocol is https
|
||||
InsecureSkipTLS bool
|
||||
// CABundle specify additional ca bundle with system cert pool
|
||||
CABundle []byte
|
||||
}
|
||||
|
||||
// Validate validates the fields and sets the default values.
|
||||
|
@ -194,6 +206,13 @@ type PushOptions struct {
|
|||
// Force allows the push to update a remote branch even when the local
|
||||
// branch does not descend from it.
|
||||
Force bool
|
||||
// InsecureSkipTLS skips ssl verify if protocal is https
|
||||
InsecureSkipTLS bool
|
||||
// CABundle specify additional ca bundle with system cert pool
|
||||
CABundle []byte
|
||||
// RequireRemoteRefs only allows a remote ref to be updated if its current
|
||||
// value is the one specified here.
|
||||
RequireRemoteRefs []config.RefSpec
|
||||
}
|
||||
|
||||
// Validate validates the fields and sets the default values.
|
||||
|
@ -552,6 +571,10 @@ func (o *CreateTagOptions) loadConfigTagger(r *Repository) error {
|
|||
type ListOptions struct {
|
||||
// Auth credentials, if required, to use with the remote repository.
|
||||
Auth transport.AuthMethod
|
||||
// InsecureSkipTLS skips ssl verify if protocal is https
|
||||
InsecureSkipTLS bool
|
||||
// CABundle specify additional ca bundle with system cert pool
|
||||
CABundle []byte
|
||||
}
|
||||
|
||||
// CleanOptions describes how a clean should be performed.
|
||||
|
|
|
@ -38,6 +38,10 @@ type UnifiedEncoder struct {
|
|||
// a change.
|
||||
contextLines int
|
||||
|
||||
// srcPrefix and dstPrefix are prepended to file paths when encoding a diff.
|
||||
srcPrefix string
|
||||
dstPrefix string
|
||||
|
||||
// colorConfig is the color configuration. The default is no color.
|
||||
color ColorConfig
|
||||
}
|
||||
|
@ -46,6 +50,8 @@ type UnifiedEncoder struct {
|
|||
func NewUnifiedEncoder(w io.Writer, contextLines int) *UnifiedEncoder {
|
||||
return &UnifiedEncoder{
|
||||
Writer: w,
|
||||
srcPrefix: "a/",
|
||||
dstPrefix: "b/",
|
||||
contextLines: contextLines,
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +62,18 @@ func (e *UnifiedEncoder) SetColor(colorConfig ColorConfig) *UnifiedEncoder {
|
|||
return e
|
||||
}
|
||||
|
||||
// SetSrcPrefix sets e's srcPrefix and returns e.
|
||||
func (e *UnifiedEncoder) SetSrcPrefix(prefix string) *UnifiedEncoder {
|
||||
e.srcPrefix = prefix
|
||||
return e
|
||||
}
|
||||
|
||||
// SetDstPrefix sets e's dstPrefix and returns e.
|
||||
func (e *UnifiedEncoder) SetDstPrefix(prefix string) *UnifiedEncoder {
|
||||
e.dstPrefix = prefix
|
||||
return e
|
||||
}
|
||||
|
||||
// Encode encodes patch.
|
||||
func (e *UnifiedEncoder) Encode(patch Patch) error {
|
||||
sb := &strings.Builder{}
|
||||
|
@ -91,7 +109,8 @@ func (e *UnifiedEncoder) writeFilePatchHeader(sb *strings.Builder, filePatch Fil
|
|||
case from != nil && to != nil:
|
||||
hashEquals := from.Hash() == to.Hash()
|
||||
lines = append(lines,
|
||||
fmt.Sprintf("diff --git a/%s b/%s", from.Path(), to.Path()),
|
||||
fmt.Sprintf("diff --git %s%s %s%s",
|
||||
e.srcPrefix, from.Path(), e.dstPrefix, to.Path()),
|
||||
)
|
||||
if from.Mode() != to.Mode() {
|
||||
lines = append(lines,
|
||||
|
@ -115,22 +134,22 @@ func (e *UnifiedEncoder) writeFilePatchHeader(sb *strings.Builder, filePatch Fil
|
|||
)
|
||||
}
|
||||
if !hashEquals {
|
||||
lines = e.appendPathLines(lines, "a/"+from.Path(), "b/"+to.Path(), isBinary)
|
||||
lines = e.appendPathLines(lines, e.srcPrefix+from.Path(), e.dstPrefix+to.Path(), isBinary)
|
||||
}
|
||||
case from == nil:
|
||||
lines = append(lines,
|
||||
fmt.Sprintf("diff --git a/%s b/%s", to.Path(), to.Path()),
|
||||
fmt.Sprintf("diff --git %s %s", e.srcPrefix+to.Path(), e.dstPrefix+to.Path()),
|
||||
fmt.Sprintf("new file mode %o", to.Mode()),
|
||||
fmt.Sprintf("index %s..%s", plumbing.ZeroHash, to.Hash()),
|
||||
)
|
||||
lines = e.appendPathLines(lines, "/dev/null", "b/"+to.Path(), isBinary)
|
||||
lines = e.appendPathLines(lines, "/dev/null", e.dstPrefix+to.Path(), isBinary)
|
||||
case to == nil:
|
||||
lines = append(lines,
|
||||
fmt.Sprintf("diff --git a/%s b/%s", from.Path(), from.Path()),
|
||||
fmt.Sprintf("diff --git %s %s", e.srcPrefix+from.Path(), e.dstPrefix+from.Path()),
|
||||
fmt.Sprintf("deleted file mode %o", from.Mode()),
|
||||
fmt.Sprintf("index %s..%s", from.Hash(), plumbing.ZeroHash),
|
||||
)
|
||||
lines = e.appendPathLines(lines, "a/"+from.Path(), "/dev/null", isBinary)
|
||||
lines = e.appendPathLines(lines, e.srcPrefix+from.Path(), "/dev/null", isBinary)
|
||||
}
|
||||
|
||||
sb.WriteString(e.color[Meta])
|
||||
|
|
|
@ -125,7 +125,7 @@ func LoadGlobalPatterns(fs billy.Filesystem) (ps []Pattern, err error) {
|
|||
}
|
||||
|
||||
// LoadSystemPatterns loads gitignore patterns from from the gitignore file
|
||||
// declared in a system's /etc/gitconfig file. If the ~/.gitconfig file does
|
||||
// declared in a system's /etc/gitconfig file. If the /etc/gitconfig file does
|
||||
// not exist the function will return nil. If the core.excludesfile property
|
||||
// is not declared, the function will return nil. If the file pointed to by
|
||||
// the core.excludesfile property does not exist, the function will return nil.
|
||||
|
|
9
vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go
generated
vendored
9
vendor/github.com/go-git/go-git/v5/plumbing/protocol/packp/capability/capability.go
generated
vendored
|
@ -230,6 +230,12 @@ const (
|
|||
PushCert Capability = "push-cert"
|
||||
// SymRef symbolic reference support for better negotiation.
|
||||
SymRef Capability = "symref"
|
||||
// ObjectFormat takes a hash algorithm as an argument, indicates that the
|
||||
// server supports the given hash algorithms.
|
||||
ObjectFormat Capability = "object-format"
|
||||
// Filter if present, fetch-pack may send "filter" commands to request a
|
||||
// partial clone or partial fetch and request that the server omit various objects from the packfile
|
||||
Filter Capability = "filter"
|
||||
)
|
||||
|
||||
const DefaultAgent = "go-git/4.x"
|
||||
|
@ -241,10 +247,11 @@ var known = map[Capability]bool{
|
|||
NoProgress: true, IncludeTag: true, ReportStatus: true, DeleteRefs: true,
|
||||
Quiet: true, Atomic: true, PushOptions: true, AllowTipSHA1InWant: true,
|
||||
AllowReachableSHA1InWant: true, PushCert: true, SymRef: true,
|
||||
ObjectFormat: true, Filter: true,
|
||||
}
|
||||
|
||||
var requiresArgument = map[Capability]bool{
|
||||
Agent: true, PushCert: true, SymRef: true,
|
||||
Agent: true, PushCert: true, SymRef: true, ObjectFormat: true,
|
||||
}
|
||||
|
||||
var multipleArgument = map[Capability]bool{
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
gohttp "net/http"
|
||||
|
||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport/file"
|
||||
|
@ -21,6 +24,14 @@ var Protocols = map[string]transport.Transport{
|
|||
"file": file.DefaultClient,
|
||||
}
|
||||
|
||||
var insecureClient = http.NewClient(&gohttp.Client{
|
||||
Transport: &gohttp.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// InstallProtocol adds or modifies an existing protocol.
|
||||
func InstallProtocol(scheme string, c transport.Transport) {
|
||||
if c == nil {
|
||||
|
@ -35,6 +46,31 @@ func InstallProtocol(scheme string, c transport.Transport) {
|
|||
// http://, https://, ssh:// and file://.
|
||||
// See `InstallProtocol` to add or modify protocols.
|
||||
func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) {
|
||||
return getTransport(endpoint)
|
||||
}
|
||||
|
||||
func getTransport(endpoint *transport.Endpoint) (transport.Transport, error) {
|
||||
if endpoint.Protocol == "https" {
|
||||
if endpoint.InsecureSkipTLS {
|
||||
return insecureClient, nil
|
||||
}
|
||||
|
||||
if len(endpoint.CaBundle) != 0 {
|
||||
rootCAs, _ := x509.SystemCertPool()
|
||||
if rootCAs == nil {
|
||||
rootCAs = x509.NewCertPool()
|
||||
}
|
||||
rootCAs.AppendCertsFromPEM(endpoint.CaBundle)
|
||||
return http.NewClient(&gohttp.Client{
|
||||
Transport: &gohttp.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: rootCAs,
|
||||
},
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
}
|
||||
|
||||
f, ok := Protocols[endpoint.Protocol]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported scheme %q", endpoint.Protocol)
|
||||
|
@ -43,6 +79,5 @@ func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) {
|
|||
if f == nil {
|
||||
return nil, fmt.Errorf("malformed client for scheme %q, client is defined as nil", endpoint.Protocol)
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
|
|
@ -58,6 +58,11 @@ type Session interface {
|
|||
// If the repository does not exist, returns ErrRepositoryNotFound.
|
||||
// If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
|
||||
AdvertisedReferences() (*packp.AdvRefs, error)
|
||||
// AdvertisedReferencesContext retrieves the advertised references for a
|
||||
// repository.
|
||||
// If the repository does not exist, returns ErrRepositoryNotFound.
|
||||
// If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
|
||||
AdvertisedReferencesContext(context.Context) (*packp.AdvRefs, error)
|
||||
io.Closer
|
||||
}
|
||||
|
||||
|
@ -107,6 +112,10 @@ type Endpoint struct {
|
|||
Port int
|
||||
// Path is the repository path.
|
||||
Path string
|
||||
// InsecureSkipTLS skips ssl verify if protocal is https
|
||||
InsecureSkipTLS bool
|
||||
// CaBundle specify additional ca bundle with system cert pool
|
||||
CaBundle []byte
|
||||
}
|
||||
|
||||
var defaultPorts = map[string]int{
|
||||
|
|
|
@ -3,6 +3,7 @@ package http
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
@ -32,7 +33,7 @@ func applyHeadersToRequest(req *http.Request, content *bytes.Buffer, host string
|
|||
|
||||
const infoRefsPath = "/info/refs"
|
||||
|
||||
func advertisedReferences(s *session, serviceName string) (ref *packp.AdvRefs, err error) {
|
||||
func advertisedReferences(ctx context.Context, s *session, serviceName string) (ref *packp.AdvRefs, err error) {
|
||||
url := fmt.Sprintf(
|
||||
"%s%s?service=%s",
|
||||
s.endpoint.String(), infoRefsPath, serviceName,
|
||||
|
@ -45,7 +46,7 @@ func advertisedReferences(s *session, serviceName string) (ref *packp.AdvRefs, e
|
|||
|
||||
s.ApplyAuthToRequest(req)
|
||||
applyHeadersToRequest(req, nil, s.endpoint.Host, serviceName)
|
||||
res, err := s.client.Do(req)
|
||||
res, err := s.client.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -25,7 +25,11 @@ func newReceivePackSession(c *http.Client, ep *transport.Endpoint, auth transpor
|
|||
}
|
||||
|
||||
func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||
return advertisedReferences(s.session, transport.ReceivePackServiceName)
|
||||
return advertisedReferences(context.TODO(), s.session, transport.ReceivePackServiceName)
|
||||
}
|
||||
|
||||
func (s *rpSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||
return advertisedReferences(ctx, s.session, transport.ReceivePackServiceName)
|
||||
}
|
||||
|
||||
func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (
|
||||
|
|
|
@ -25,7 +25,11 @@ func newUploadPackSession(c *http.Client, ep *transport.Endpoint, auth transport
|
|||
}
|
||||
|
||||
func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||
return advertisedReferences(s.session, transport.UploadPackServiceName)
|
||||
return advertisedReferences(context.TODO(), s.session, transport.UploadPackServiceName)
|
||||
}
|
||||
|
||||
func (s *upSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||
return advertisedReferences(ctx, s.session, transport.UploadPackServiceName)
|
||||
}
|
||||
|
||||
func (s *upSession) UploadPack(
|
||||
|
|
10
vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go
generated
vendored
10
vendor/github.com/go-git/go-git/v5/plumbing/transport/internal/common/common.go
generated
vendored
|
@ -162,14 +162,18 @@ func (c *client) listenFirstError(r io.Reader) chan string {
|
|||
return errLine
|
||||
}
|
||||
|
||||
// AdvertisedReferences retrieves the advertised references from the server.
|
||||
func (s *session) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||
return s.AdvertisedReferencesContext(context.TODO())
|
||||
}
|
||||
|
||||
// AdvertisedReferences retrieves the advertised references from the server.
|
||||
func (s *session) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||
if s.advRefs != nil {
|
||||
return s.advRefs, nil
|
||||
}
|
||||
|
||||
ar := packp.NewAdvRefs()
|
||||
if err := ar.Decode(s.Stdout); err != nil {
|
||||
if err := ar.Decode(s.StdoutContext(ctx)); err != nil {
|
||||
if err := s.handleAdvRefDecodeError(err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -237,7 +241,7 @@ func (s *session) UploadPack(ctx context.Context, req *packp.UploadPackRequest)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := s.AdvertisedReferences(); err != nil {
|
||||
if _, err := s.AdvertisedReferencesContext(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,10 @@ type upSession struct {
|
|||
}
|
||||
|
||||
func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||
return s.AdvertisedReferencesContext(context.TODO())
|
||||
}
|
||||
|
||||
func (s *upSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||
ar := packp.NewAdvRefs()
|
||||
|
||||
if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
|
||||
|
@ -204,6 +208,10 @@ type rpSession struct {
|
|||
}
|
||||
|
||||
func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
|
||||
return s.AdvertisedReferencesContext(context.TODO())
|
||||
}
|
||||
|
||||
func (s *rpSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
|
||||
ar := packp.NewAdvRefs()
|
||||
|
||||
if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport/internal/common"
|
||||
|
@ -90,8 +91,14 @@ func (c *command) Close() error {
|
|||
//XXX: If did read the full packfile, then the session might be already
|
||||
// closed.
|
||||
_ = c.Session.Close()
|
||||
err := c.client.Close()
|
||||
|
||||
return c.client.Close()
|
||||
//XXX: in go1.16+ we can use errors.Is(err, net.ErrClosed)
|
||||
if err != nil && strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// connect connects to the SSH server, unless a AuthMethod was set with
|
||||
|
|
|
@ -102,14 +102,14 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
|
|||
return fmt.Errorf("remote names don't match: %s != %s", o.RemoteName, r.c.Name)
|
||||
}
|
||||
|
||||
s, err := newSendPackSession(r.c.URLs[0], o.Auth)
|
||||
s, err := newSendPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer ioutil.CheckClose(s, &err)
|
||||
|
||||
ar, err := s.AdvertisedReferences()
|
||||
ar, err := s.AdvertisedReferencesContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -119,6 +119,10 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := r.checkRequireRemoteRefs(o.RequireRemoteRefs, remoteRefs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isDelete := false
|
||||
allDelete := true
|
||||
for _, rs := range o.RefSpecs {
|
||||
|
@ -309,14 +313,14 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
|
|||
o.RefSpecs = r.c.Fetch
|
||||
}
|
||||
|
||||
s, err := newUploadPackSession(r.c.URLs[0], o.Auth)
|
||||
s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer ioutil.CheckClose(s, &err)
|
||||
|
||||
ar, err := s.AdvertisedReferences()
|
||||
ar, err := s.AdvertisedReferencesContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -369,8 +373,8 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
|
|||
return remoteRefs, nil
|
||||
}
|
||||
|
||||
func newUploadPackSession(url string, auth transport.AuthMethod) (transport.UploadPackSession, error) {
|
||||
c, ep, err := newClient(url)
|
||||
func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.UploadPackSession, error) {
|
||||
c, ep, err := newClient(url, auth, insecure, cabundle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -378,8 +382,8 @@ func newUploadPackSession(url string, auth transport.AuthMethod) (transport.Uplo
|
|||
return c.NewUploadPackSession(ep, auth)
|
||||
}
|
||||
|
||||
func newSendPackSession(url string, auth transport.AuthMethod) (transport.ReceivePackSession, error) {
|
||||
c, ep, err := newClient(url)
|
||||
func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.ReceivePackSession, error) {
|
||||
c, ep, err := newClient(url, auth, insecure, cabundle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -387,11 +391,13 @@ func newSendPackSession(url string, auth transport.AuthMethod) (transport.Receiv
|
|||
return c.NewReceivePackSession(ep, auth)
|
||||
}
|
||||
|
||||
func newClient(url string) (transport.Transport, *transport.Endpoint, error) {
|
||||
func newClient(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.Transport, *transport.Endpoint, error) {
|
||||
ep, err := transport.NewEndpoint(url)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ep.InsecureSkipTLS = insecure
|
||||
ep.CaBundle = cabundle
|
||||
|
||||
c, err := client.NewClient(ep)
|
||||
if err != nil {
|
||||
|
@ -1025,14 +1031,14 @@ func (r *Remote) buildFetchedTags(refs memory.ReferenceStorage) (updated bool, e
|
|||
|
||||
// List the references on the remote repository.
|
||||
func (r *Remote) List(o *ListOptions) (rfs []*plumbing.Reference, err error) {
|
||||
s, err := newUploadPackSession(r.c.URLs[0], o.Auth)
|
||||
s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer ioutil.CheckClose(s, &err)
|
||||
|
||||
ar, err := s.AdvertisedReferences()
|
||||
ar, err := s.AdvertisedReferencesContext(context.TODO())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1164,3 +1170,33 @@ outer:
|
|||
|
||||
return r.s.SetShallow(shallows)
|
||||
}
|
||||
|
||||
func (r *Remote) checkRequireRemoteRefs(requires []config.RefSpec, remoteRefs storer.ReferenceStorer) error {
|
||||
for _, require := range requires {
|
||||
if require.IsWildcard() {
|
||||
return fmt.Errorf("wildcards not supported in RequireRemoteRefs, got %s", require.String())
|
||||
}
|
||||
|
||||
name := require.Dst("")
|
||||
remote, err := remoteRefs.Reference(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("remote ref %s required to be %s but is absent", name.String(), require.Src())
|
||||
}
|
||||
|
||||
var requireHash string
|
||||
if require.IsExactSHA1() {
|
||||
requireHash = require.Src()
|
||||
} else {
|
||||
target, err := storer.ResolveReference(remoteRefs, plumbing.ReferenceName(require.Src()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not resolve ref %s in RequireRemoteRefs", require.Src())
|
||||
}
|
||||
requireHash = target.Hash().String()
|
||||
}
|
||||
|
||||
if remote.Hash().String() != requireHash {
|
||||
return fmt.Errorf("remote ref %s required to be %s but is %s", name.String(), requireHash, remote.Hash().String())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -847,6 +847,8 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
|
|||
Progress: o.Progress,
|
||||
Tags: o.Tags,
|
||||
RemoteName: o.RemoteName,
|
||||
InsecureSkipTLS: o.InsecureSkipTLS,
|
||||
CABundle: o.CABundle,
|
||||
}, o.ReferenceName)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue