forked from TrueCloudLab/rclone
Tardigrade Backend: Dependencies
This commit is contained in:
parent
962fbc8257
commit
03b629064a
544 changed files with 86690 additions and 2 deletions
1
go.mod
1
go.mod
|
@ -67,6 +67,7 @@ require (
|
|||
google.golang.org/api v0.21.1-0.20200411000818-c8cf5cff125e
|
||||
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
storj.io/uplink v1.0.5
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
|
56
go.sum
56
go.sum
|
@ -52,6 +52,7 @@ github.com/aalpar/deheap v0.0.0-20191229192855-f837f7a9ba26 h1:vn0bf9tSbwrl9aBeG
|
|||
github.com/aalpar/deheap v0.0.0-20191229192855-f837f7a9ba26/go.mod h1:EJFoWbcEEVK22GYKONJjtMNamGYe6p+3x1Pr6zV5gFs=
|
||||
github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=
|
||||
github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
|
@ -78,6 +79,18 @@ github.com/billziss-gh/cgofuse v1.2.0 h1:FMdQSygSBpD4yEPENJcmvfCdmNWMVkPLlD7wWdl
|
|||
github.com/billziss-gh/cgofuse v1.2.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
|
||||
github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/btcutil v1.0.1 h1:GKOz8BnRjYrb/JTKgaOk+zh26NWNdSNvdvv0xoAZMSA=
|
||||
github.com/btcsuite/btcutil v1.0.1/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/calebcase/tmpfile v1.0.1 h1:vD8FSrbsbexhep39/6mvtbIHS3GzIRqiprDNCF6QqSk=
|
||||
github.com/calebcase/tmpfile v1.0.1/go.mod h1:iErLeG/iqJr8LaQ/gYRv4GXdqssi3jg4iSzvrA06/lw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
|
@ -97,6 +110,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
|
|||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -125,6 +139,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
|||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
|
@ -189,12 +204,14 @@ github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbc
|
|||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jlaffaye/ftp v0.0.0-20190624084859-c1312a7102bf/go.mod h1:lli8NYPQOFy3O++YmYbqVgOcQ1JPCwdOy+5zSjKJ9qY=
|
||||
github.com/jlaffaye/ftp v0.0.0-20191218041957-e1b8fdd0dcc3 h1:QyB6CQGLB65Al72mAIbqrkGRk56JdGMHgBziM3F0FCw=
|
||||
github.com/jlaffaye/ftp v0.0.0-20191218041957-e1b8fdd0dcc3/go.mod h1:PwUeyujmhaGohgOf0kJKxPfk3HcRv8QD/wAUN44go4k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
|
@ -209,6 +226,7 @@ github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uia
|
|||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
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/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
|
@ -242,6 +260,8 @@ github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuuj
|
|||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
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/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg=
|
||||
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
|
@ -263,8 +283,10 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
|
|||
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs=
|
||||
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ=
|
||||
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.9.0 h1:SZjF721BByVj8QH636/8S2DnX4n0Re3SteMmw3N+tzc=
|
||||
github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.6.0 h1:8XTW0fcJZEq9q+Upcyws4JSGua2MFysCL5xkaSgHc+M=
|
||||
github.com/onsi/gomega v1.6.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
|
@ -332,11 +354,17 @@ github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:X
|
|||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1 h1:xHQewZjohU9/wUsyC99navCjQDNHtTgUOM/J1jAbzfw=
|
||||
github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1/go.mod h1:7NL9UAYQnRM5iKHUCld3tf02fKb5Dft+41+VckASUy0=
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.0-20191108235033-eacca33b3037/go.mod h1:JcK1pCbReQsOsMKF/POFSZCq7drXFybgGmbc27tuwes=
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.4/go.mod h1:JcK1pCbReQsOsMKF/POFSZCq7drXFybgGmbc27tuwes=
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.5/go.mod h1:JcK1pCbReQsOsMKF/POFSZCq7drXFybgGmbc27tuwes=
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.6 h1:BKPrEaLokVAxlwHkD7jawViBa/IU9/bgXbZLWgjbdSM=
|
||||
github.com/spacemonkeygo/monkit/v3 v3.0.6/go.mod h1:kj1ViJhlyADa7DiA4xVnTuPA46lFKbM7mxQTrXCuJP4=
|
||||
github.com/spacemonkeygo/monotime v0.0.0-20180824235756-e3f48a95f98a/go.mod h1:ul4bvvnCOPZgq8w0nTkSmWVg/hauVpFS97Am1YM1XXo=
|
||||
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/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs=
|
||||
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
|
@ -365,6 +393,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
|||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ=
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/vivint/infectious v0.0.0-20190108171102-2455b059135b h1:dLkqBELopfQNhe8S9ucnSf+HhiUCgK/hPIjVG0f9GlY=
|
||||
github.com/vivint/infectious v0.0.0-20190108171102-2455b059135b/go.mod h1:5oyMAv4hrBEKqBwORFsiqIrCNCmL2qcZLQTdJLYeYIc=
|
||||
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
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=
|
||||
|
@ -374,6 +404,14 @@ github.com/youmark/pkcs8 v0.0.0-20191102193632-94c173a94d60 h1:Ud2neINE1YFEwrcJ4
|
|||
github.com/youmark/pkcs8 v0.0.0-20191102193632-94c173a94d60/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yunify/qingstor-sdk-go/v3 v3.2.0 h1:9sB2WZMgjwSUNZhrgvaNGazVltoFUUfuS9f0uCWtTr8=
|
||||
github.com/yunify/qingstor-sdk-go/v3 v3.2.0/go.mod h1:KciFNuMu6F4WLk9nGwwK69sCGKLCdd9f97ac/wfumS4=
|
||||
github.com/zeebo/admission/v2 v2.0.0/go.mod h1:gSeHGelDHW7Vq6UyJo2boeSt/6Dsnqpisv0i4YZSOyM=
|
||||
github.com/zeebo/admission/v3 v3.0.1/go.mod h1:BP3isIv9qa2A7ugEratNq1dnl2oZRXaQUGdU7WXKtbw=
|
||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g=
|
||||
github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
|
||||
github.com/zeebo/float16 v0.1.0/go.mod h1:fssGvvXu+XS8MH57cKmyrLB/cqioYeYX/2mXCN3a5wo=
|
||||
github.com/zeebo/incenc v0.0.0-20180505221441-0d92902eec54/go.mod h1:EI8LcOBDlSL3POyqwC1eJhOYlMBMidES+613EtmmT5w=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
|
@ -384,11 +422,15 @@ go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
|
|||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
goftp.io/server v0.3.2 h1:bcsI4ijbvFZkA4rrUtIE/t1jNhT+0uSkiTQ4ASjZAXQ=
|
||||
goftp.io/server v0.3.2/go.mod h1:wfeAZeQgacupLVl+Ex3ozYFaAGNfCKYZiZNxLzgw6z4=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -398,6 +440,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -446,6 +490,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
@ -488,6 +533,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200107144601-ef85f5a75ddf/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -611,3 +657,9 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
|
|||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
storj.io/common v0.0.0-20200429074521-4ba140e4b747 h1:Ne1x0M80uNyN6tHIs15CGJqHbreKbvH5BOq4jdWsqMc=
|
||||
storj.io/common v0.0.0-20200429074521-4ba140e4b747/go.mod h1:lfsaMdtHwrUOtSYkw73meCyZMUYiaFBKVqx6zgeSz2o=
|
||||
storj.io/drpc v0.0.11 h1:6vLxfpSbwCLtqzAoXzXx/SxBqBtbzbmquXPqfcWKqfw=
|
||||
storj.io/drpc v0.0.11/go.mod h1:TiFc2obNjL9/3isMW1Rpxjy8V9uE0B2HMeMFGiiI7Iw=
|
||||
storj.io/uplink v1.0.5 h1:RH6LUZQPOJZ01JpM0YmghDu5xyex5gyn32NSCzsPSr4=
|
||||
storj.io/uplink v1.0.5/go.mod h1:GkChEUgHFuUR2WNpqFw3NeqglXz6/zp6n5Rxt0IVfHw=
|
||||
|
|
16
vendor/github.com/btcsuite/btcutil/LICENSE
generated
vendored
Normal file
16
vendor/github.com/btcsuite/btcutil/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
ISC License
|
||||
|
||||
Copyright (c) 2013-2017 The btcsuite developers
|
||||
Copyright (c) 2016-2017 The Lightning Network Developers
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
34
vendor/github.com/btcsuite/btcutil/base58/README.md
generated
vendored
Normal file
34
vendor/github.com/btcsuite/btcutil/base58/README.md
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
base58
|
||||
==========
|
||||
|
||||
[![Build Status](http://img.shields.io/travis/btcsuite/btcutil.svg)](https://travis-ci.org/btcsuite/btcutil)
|
||||
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
|
||||
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcutil/base58)
|
||||
|
||||
Package base58 provides an API for encoding and decoding to and from the
|
||||
modified base58 encoding. It also provides an API to do Base58Check encoding,
|
||||
as described [here](https://en.bitcoin.it/wiki/Base58Check_encoding).
|
||||
|
||||
A comprehensive suite of tests is provided to ensure proper functionality.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/btcsuite/btcutil/base58
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
* [Decode Example](http://godoc.org/github.com/btcsuite/btcutil/base58#example-Decode)
|
||||
Demonstrates how to decode modified base58 encoded data.
|
||||
* [Encode Example](http://godoc.org/github.com/btcsuite/btcutil/base58#example-Encode)
|
||||
Demonstrates how to encode data using the modified base58 encoding scheme.
|
||||
* [CheckDecode Example](http://godoc.org/github.com/btcsuite/btcutil/base58#example-CheckDecode)
|
||||
Demonstrates how to decode Base58Check encoded data.
|
||||
* [CheckEncode Example](http://godoc.org/github.com/btcsuite/btcutil/base58#example-CheckEncode)
|
||||
Demonstrates how to encode data using the Base58Check encoding scheme.
|
||||
|
||||
## License
|
||||
|
||||
Package base58 is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
49
vendor/github.com/btcsuite/btcutil/base58/alphabet.go
generated
vendored
Normal file
49
vendor/github.com/btcsuite/btcutil/base58/alphabet.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) 2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// AUTOGENERATED by genalphabet.go; do not edit.
|
||||
|
||||
package base58
|
||||
|
||||
const (
|
||||
// alphabet is the modified base58 alphabet used by Bitcoin.
|
||||
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
alphabetIdx0 = '1'
|
||||
)
|
||||
|
||||
var b58 = [256]byte{
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 255, 255, 255, 255, 255, 255,
|
||||
255, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 255, 17, 18, 19, 20, 21, 255,
|
||||
22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 255, 255, 255, 255, 255,
|
||||
255, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 255, 44, 45, 46,
|
||||
47, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 56, 57, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
}
|
75
vendor/github.com/btcsuite/btcutil/base58/base58.go
generated
vendored
Normal file
75
vendor/github.com/btcsuite/btcutil/base58/base58.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) 2013-2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package base58
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
)
|
||||
|
||||
//go:generate go run genalphabet.go
|
||||
|
||||
var bigRadix = big.NewInt(58)
|
||||
var bigZero = big.NewInt(0)
|
||||
|
||||
// Decode decodes a modified base58 string to a byte slice.
|
||||
func Decode(b string) []byte {
|
||||
answer := big.NewInt(0)
|
||||
j := big.NewInt(1)
|
||||
|
||||
scratch := new(big.Int)
|
||||
for i := len(b) - 1; i >= 0; i-- {
|
||||
tmp := b58[b[i]]
|
||||
if tmp == 255 {
|
||||
return []byte("")
|
||||
}
|
||||
scratch.SetInt64(int64(tmp))
|
||||
scratch.Mul(j, scratch)
|
||||
answer.Add(answer, scratch)
|
||||
j.Mul(j, bigRadix)
|
||||
}
|
||||
|
||||
tmpval := answer.Bytes()
|
||||
|
||||
var numZeros int
|
||||
for numZeros = 0; numZeros < len(b); numZeros++ {
|
||||
if b[numZeros] != alphabetIdx0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
flen := numZeros + len(tmpval)
|
||||
val := make([]byte, flen)
|
||||
copy(val[numZeros:], tmpval)
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
// Encode encodes a byte slice to a modified base58 string.
|
||||
func Encode(b []byte) string {
|
||||
x := new(big.Int)
|
||||
x.SetBytes(b)
|
||||
|
||||
answer := make([]byte, 0, len(b)*136/100)
|
||||
for x.Cmp(bigZero) > 0 {
|
||||
mod := new(big.Int)
|
||||
x.DivMod(x, bigRadix, mod)
|
||||
answer = append(answer, alphabet[mod.Int64()])
|
||||
}
|
||||
|
||||
// leading zero bytes
|
||||
for _, i := range b {
|
||||
if i != 0 {
|
||||
break
|
||||
}
|
||||
answer = append(answer, alphabetIdx0)
|
||||
}
|
||||
|
||||
// reverse
|
||||
alen := len(answer)
|
||||
for i := 0; i < alen/2; i++ {
|
||||
answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
|
||||
}
|
||||
|
||||
return string(answer)
|
||||
}
|
52
vendor/github.com/btcsuite/btcutil/base58/base58check.go
generated
vendored
Normal file
52
vendor/github.com/btcsuite/btcutil/base58/base58check.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package base58
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// ErrChecksum indicates that the checksum of a check-encoded string does not verify against
|
||||
// the checksum.
|
||||
var ErrChecksum = errors.New("checksum error")
|
||||
|
||||
// ErrInvalidFormat indicates that the check-encoded string has an invalid format.
|
||||
var ErrInvalidFormat = errors.New("invalid format: version and/or checksum bytes missing")
|
||||
|
||||
// checksum: first four bytes of sha256^2
|
||||
func checksum(input []byte) (cksum [4]byte) {
|
||||
h := sha256.Sum256(input)
|
||||
h2 := sha256.Sum256(h[:])
|
||||
copy(cksum[:], h2[:4])
|
||||
return
|
||||
}
|
||||
|
||||
// CheckEncode prepends a version byte and appends a four byte checksum.
|
||||
func CheckEncode(input []byte, version byte) string {
|
||||
b := make([]byte, 0, 1+len(input)+4)
|
||||
b = append(b, version)
|
||||
b = append(b, input[:]...)
|
||||
cksum := checksum(b)
|
||||
b = append(b, cksum[:]...)
|
||||
return Encode(b)
|
||||
}
|
||||
|
||||
// CheckDecode decodes a string that was encoded with CheckEncode and verifies the checksum.
|
||||
func CheckDecode(input string) (result []byte, version byte, err error) {
|
||||
decoded := Decode(input)
|
||||
if len(decoded) < 5 {
|
||||
return nil, 0, ErrInvalidFormat
|
||||
}
|
||||
version = decoded[0]
|
||||
var cksum [4]byte
|
||||
copy(cksum[:], decoded[len(decoded)-4:])
|
||||
if checksum(decoded[:len(decoded)-4]) != cksum {
|
||||
return nil, 0, ErrChecksum
|
||||
}
|
||||
payload := decoded[1 : len(decoded)-4]
|
||||
result = append(result, payload...)
|
||||
return
|
||||
}
|
17
vendor/github.com/btcsuite/btcutil/base58/cov_report.sh
generated
vendored
Normal file
17
vendor/github.com/btcsuite/btcutil/base58/cov_report.sh
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script uses gocov to generate a test coverage report.
|
||||
# The gocov tool my be obtained with the following command:
|
||||
# go get github.com/axw/gocov/gocov
|
||||
#
|
||||
# It will be installed to $GOPATH/bin, so ensure that location is in your $PATH.
|
||||
|
||||
# Check for gocov.
|
||||
type gocov >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo >&2 "This script requires the gocov tool."
|
||||
echo >&2 "You may obtain it with the following command:"
|
||||
echo >&2 "go get github.com/axw/gocov/gocov"
|
||||
exit 1
|
||||
fi
|
||||
gocov test | gocov report
|
29
vendor/github.com/btcsuite/btcutil/base58/doc.go
generated
vendored
Normal file
29
vendor/github.com/btcsuite/btcutil/base58/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) 2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package base58 provides an API for working with modified base58 and Base58Check
|
||||
encodings.
|
||||
|
||||
Modified Base58 Encoding
|
||||
|
||||
Standard base58 encoding is similar to standard base64 encoding except, as the
|
||||
name implies, it uses a 58 character alphabet which results in an alphanumeric
|
||||
string and allows some characters which are problematic for humans to be
|
||||
excluded. Due to this, there can be various base58 alphabets.
|
||||
|
||||
The modified base58 alphabet used by Bitcoin, and hence this package, omits the
|
||||
0, O, I, and l characters that look the same in many fonts and are therefore
|
||||
hard to humans to distinguish.
|
||||
|
||||
Base58Check Encoding Scheme
|
||||
|
||||
The Base58Check encoding scheme is primarily used for Bitcoin addresses at the
|
||||
time of this writing, however it can be used to generically encode arbitrary
|
||||
byte arrays into human-readable strings along with a version byte that can be
|
||||
used to differentiate the same payload. For Bitcoin addresses, the extra
|
||||
version is used to differentiate the network of otherwise identical public keys
|
||||
which helps prevent using an address intended for one network on another.
|
||||
*/
|
||||
package base58
|
45
vendor/github.com/calebcase/tmpfile/.golangci.yml
generated
vendored
Normal file
45
vendor/github.com/calebcase/tmpfile/.golangci.yml
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
run:
|
||||
deadline: 10m
|
||||
issues-exit-code: 1
|
||||
tests: true
|
||||
|
||||
skip-files:
|
||||
- "^doc.*\\.go$"
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- dogsled
|
||||
- errcheck
|
||||
- gocritic
|
||||
- gofmt
|
||||
- golint
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nakedret
|
||||
- scopelint
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- unconvert
|
||||
- varcheck
|
||||
fast: false
|
||||
|
||||
output:
|
||||
format: colored-line-number
|
||||
print-issued-lines: true
|
||||
print-linter-name: true
|
||||
|
||||
linters-settings:
|
||||
gocyclo:
|
||||
min-complexity: 10
|
||||
maligned:
|
||||
suggest-new: true
|
||||
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
new: false
|
||||
exclude-use-default: false
|
202
vendor/github.com/calebcase/tmpfile/LICENSE
generated
vendored
Normal file
202
vendor/github.com/calebcase/tmpfile/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
27
vendor/github.com/calebcase/tmpfile/LICENSE.golang
generated
vendored
Normal file
27
vendor/github.com/calebcase/tmpfile/LICENSE.golang
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
vendor/github.com/calebcase/tmpfile/README.md
generated
vendored
Normal file
30
vendor/github.com/calebcase/tmpfile/README.md
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
[![Documentation][godoc.badge]][godoc]
|
||||
[![Test Status][workflow.tests.badge]][workflow.tests]
|
||||
|
||||
# Cross Platform Temporary Files
|
||||
|
||||
This library attempts to bridge the gap between the what is provided in
|
||||
[ioutil.TempFile][ioutil.tempfile] and the best practice of ensuring temporary
|
||||
files are ***always*** deleted when the application exits.
|
||||
|
||||
The normal way to do this on a POSIX system is to use the behavior of
|
||||
[unlink][posix.unlink] to immediately remove the directory entry for the
|
||||
temporary file. The OS then ensures that when all open file handles on the file
|
||||
are close that the file resources are removed. Unfortunately, despite Go having
|
||||
[os.Remove][os.remove] this does not work on Windows because on Windows it is
|
||||
necessary to open the files with special flags
|
||||
([FILE_SHARE_DELETE][windows.flags.share],
|
||||
[FILE_FLAG_DELETE_ON_CLOSE][windows.flags.on_close]) to enable removing a file
|
||||
that is open (and ioutil does not do this).
|
||||
|
||||
---
|
||||
|
||||
[godoc.badge]: https://godoc.org/github.com/calebcase/tmpfile?status.svg
|
||||
[godoc]: https://godoc.org/github.com/calebcase/tmpfile
|
||||
[ioutil.tempfile]: https://golang.org/pkg/io/ioutil/#TempFile
|
||||
[os.remove]: https://golang.org/pkg/os/#Remove
|
||||
[posix.unlink]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html
|
||||
[windows.flags.on_close]: https://github.com/golang/sys/blob/master/windows/types_windows.go#L108
|
||||
[windows.flags.share]: https://github.com/golang/sys/blob/master/windows/types_windows.go#L71
|
||||
[workflow.tests.badge]: https://github.com/calebcase/tmpfile/workflows/tests/badge.svg
|
||||
[workflow.tests]: https://github.com/calebcase/tmpfile/actions?query=workflow%3Atests
|
9
vendor/github.com/calebcase/tmpfile/doc.go
generated
vendored
Normal file
9
vendor/github.com/calebcase/tmpfile/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Package tmpfile provides a cross platform facility for creating temporary
|
||||
// files that are automatically cleaned up (even in the event of an unexpected
|
||||
// process exit).
|
||||
//
|
||||
// tmpfile provides support for at least Linux, OSX, and Windows. Generally any
|
||||
// POSIX system that adheres to the semantics of unlink
|
||||
// (https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html)
|
||||
// should work. Special handling is provided for other platforms.
|
||||
package tmpfile
|
5
vendor/github.com/calebcase/tmpfile/go.mod
generated
vendored
Normal file
5
vendor/github.com/calebcase/tmpfile/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
module github.com/calebcase/tmpfile
|
||||
|
||||
go 1.13
|
||||
|
||||
require golang.org/x/sys v0.0.0-20191210023423-ac6580df4449
|
2
vendor/github.com/calebcase/tmpfile/go.sum
generated
vendored
Normal file
2
vendor/github.com/calebcase/tmpfile/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
25
vendor/github.com/calebcase/tmpfile/tmpfile.go
generated
vendored
Normal file
25
vendor/github.com/calebcase/tmpfile/tmpfile.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
// +build !windows
|
||||
|
||||
package tmpfile
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// New creates a new temporary file in the directory dir using ioutil.TempFile
|
||||
// and then unlinks the file with os.Remove to ensure the file is deleted when
|
||||
// the calling process exists.
|
||||
func New(dir, pattern string) (f *os.File, err error) {
|
||||
f, err = ioutil.TempFile(dir, pattern)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = os.Remove(f.Name())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
94
vendor/github.com/calebcase/tmpfile/tmpfile_windows.go
generated
vendored
Normal file
94
vendor/github.com/calebcase/tmpfile/tmpfile_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
// Copyright 2010 The Go Authors. All rights reserved. Use of this source code
|
||||
// is governed by a BSD-style license that can be found in the LICENSE.golang
|
||||
// file.
|
||||
//
|
||||
// This is a copied and modified version of the code provided in:
|
||||
// https://golang.org/src/io/ioutil/tempfile.go
|
||||
|
||||
package tmpfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Random number state.
|
||||
// We generate random temporary file names so that there's a good
|
||||
// chance the file doesn't exist yet - keeps the number of tries in
|
||||
// TempFile to a minimum.
|
||||
var rand uint32
|
||||
var randmu sync.Mutex
|
||||
|
||||
func reseed() uint32 {
|
||||
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
|
||||
}
|
||||
|
||||
func nextRandom() string {
|
||||
randmu.Lock()
|
||||
r := rand
|
||||
if r == 0 {
|
||||
r = reseed()
|
||||
}
|
||||
r = r*1664525 + 1013904223 // constants from Numerical Recipes
|
||||
rand = r
|
||||
randmu.Unlock()
|
||||
return strconv.Itoa(int(1e9 + r%1e9))[1:]
|
||||
}
|
||||
|
||||
// New creates a new temporary file in the directory dir using the same method
|
||||
// as ioutil.TempFile and then unlinks the file with os.Remove to ensure the
|
||||
// file is deleted when the calling process exists.
|
||||
func New(dir, pattern string) (f *os.File, err error) {
|
||||
if dir == "" {
|
||||
dir = os.TempDir()
|
||||
}
|
||||
|
||||
var prefix, suffix string
|
||||
if pos := strings.LastIndex(pattern, "*"); pos != -1 {
|
||||
prefix, suffix = pattern[:pos], pattern[pos+1:]
|
||||
} else {
|
||||
prefix = pattern
|
||||
}
|
||||
|
||||
nconflict := 0
|
||||
for i := 0; i < 10000; i++ {
|
||||
name := filepath.Join(dir, prefix+nextRandom()+suffix)
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
|
||||
handle, err := windows.CreateFile(
|
||||
windows.StringToUTF16Ptr(name), // File Name
|
||||
windows.GENERIC_READ|windows.GENERIC_WRITE|windows.DELETE, // Desired Access
|
||||
windows.FILE_SHARE_DELETE, // Share Mode
|
||||
nil, // Security Attributes
|
||||
windows.CREATE_NEW, // Create Disposition
|
||||
windows.FILE_ATTRIBUTE_TEMPORARY|windows.FILE_FLAG_DELETE_ON_CLOSE, // Flags & Attributes
|
||||
0, // Template File
|
||||
)
|
||||
if os.IsExist(err) {
|
||||
if nconflict++; nconflict > 10 {
|
||||
randmu.Lock()
|
||||
rand = reseed()
|
||||
randmu.Unlock()
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
f = os.NewFile(uintptr(handle), name)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
err = os.Remove(f.Name())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
15
vendor/github.com/gogo/protobuf/AUTHORS
generated
vendored
Normal file
15
vendor/github.com/gogo/protobuf/AUTHORS
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
# This is the official list of GoGo authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS file, which
|
||||
# lists people. For example, employees are listed in CONTRIBUTORS,
|
||||
# but not in AUTHORS, because the employer holds the copyright.
|
||||
|
||||
# Names should be added to this file as one of
|
||||
# Organization's name
|
||||
# Individual's name <submission email address>
|
||||
# Individual's name <submission email address> <email2> <emailN>
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Sendgrid, Inc
|
||||
Vastech SA (PTY) LTD
|
||||
Walter Schulze <awalterschulze@gmail.com>
|
23
vendor/github.com/gogo/protobuf/CONTRIBUTORS
generated
vendored
Normal file
23
vendor/github.com/gogo/protobuf/CONTRIBUTORS
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
Anton Povarov <anton.povarov@gmail.com>
|
||||
Brian Goff <cpuguy83@gmail.com>
|
||||
Clayton Coleman <ccoleman@redhat.com>
|
||||
Denis Smirnov <denis.smirnov.91@gmail.com>
|
||||
DongYun Kang <ceram1000@gmail.com>
|
||||
Dwayne Schultz <dschultz@pivotal.io>
|
||||
Georg Apitz <gapitz@pivotal.io>
|
||||
Gustav Paul <gustav.paul@gmail.com>
|
||||
Johan Brandhorst <johan.brandhorst@gmail.com>
|
||||
John Shahid <jvshahid@gmail.com>
|
||||
John Tuley <john@tuley.org>
|
||||
Laurent <laurent@adyoulike.com>
|
||||
Patrick Lee <patrick@dropbox.com>
|
||||
Peter Edge <peter.edge@gmail.com>
|
||||
Roger Johansson <rogeralsing@gmail.com>
|
||||
Sam Nguyen <sam.nguyen@sendgrid.com>
|
||||
Sergio Arbeo <serabe@gmail.com>
|
||||
Stephen J Day <stephen.day@docker.com>
|
||||
Tamir Duberstein <tamird@gmail.com>
|
||||
Todd Eisenberger <teisenberger@dropbox.com>
|
||||
Tormod Erevik Lea <tormodlea@gmail.com>
|
||||
Vyacheslav Kim <kane@sendgrid.com>
|
||||
Walter Schulze <awalterschulze@gmail.com>
|
35
vendor/github.com/gogo/protobuf/LICENSE
generated
vendored
Normal file
35
vendor/github.com/gogo/protobuf/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
|
||||
Protocol Buffers for Go with Gadgets
|
||||
|
||||
Go support for Protocol Buffers - Google's data interchange format
|
||||
|
||||
Copyright 2010 The Go Authors. All rights reserved.
|
||||
https://github.com/golang/protobuf
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
43
vendor/github.com/gogo/protobuf/proto/Makefile
generated
vendored
Normal file
43
vendor/github.com/gogo/protobuf/proto/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Go support for Protocol Buffers - Google's data interchange format
|
||||
#
|
||||
# Copyright 2010 The Go Authors. All rights reserved.
|
||||
# https://github.com/golang/protobuf
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
install:
|
||||
go install
|
||||
|
||||
test: install generate-test-pbs
|
||||
go test
|
||||
|
||||
|
||||
generate-test-pbs:
|
||||
make install
|
||||
make -C test_proto
|
||||
make -C proto3_proto
|
||||
make
|
258
vendor/github.com/gogo/protobuf/proto/clone.go
generated
vendored
Normal file
258
vendor/github.com/gogo/protobuf/proto/clone.go
generated
vendored
Normal file
|
@ -0,0 +1,258 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Protocol buffer deep copy and merge.
|
||||
// TODO: RawMessage.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Clone returns a deep copy of a protocol buffer.
|
||||
func Clone(src Message) Message {
|
||||
in := reflect.ValueOf(src)
|
||||
if in.IsNil() {
|
||||
return src
|
||||
}
|
||||
out := reflect.New(in.Type().Elem())
|
||||
dst := out.Interface().(Message)
|
||||
Merge(dst, src)
|
||||
return dst
|
||||
}
|
||||
|
||||
// Merger is the interface representing objects that can merge messages of the same type.
|
||||
type Merger interface {
|
||||
// Merge merges src into this message.
|
||||
// Required and optional fields that are set in src will be set to that value in dst.
|
||||
// Elements of repeated fields will be appended.
|
||||
//
|
||||
// Merge may panic if called with a different argument type than the receiver.
|
||||
Merge(src Message)
|
||||
}
|
||||
|
||||
// generatedMerger is the custom merge method that generated protos will have.
|
||||
// We must add this method since a generate Merge method will conflict with
|
||||
// many existing protos that have a Merge data field already defined.
|
||||
type generatedMerger interface {
|
||||
XXX_Merge(src Message)
|
||||
}
|
||||
|
||||
// Merge merges src into dst.
|
||||
// Required and optional fields that are set in src will be set to that value in dst.
|
||||
// Elements of repeated fields will be appended.
|
||||
// Merge panics if src and dst are not the same type, or if dst is nil.
|
||||
func Merge(dst, src Message) {
|
||||
if m, ok := dst.(Merger); ok {
|
||||
m.Merge(src)
|
||||
return
|
||||
}
|
||||
|
||||
in := reflect.ValueOf(src)
|
||||
out := reflect.ValueOf(dst)
|
||||
if out.IsNil() {
|
||||
panic("proto: nil destination")
|
||||
}
|
||||
if in.Type() != out.Type() {
|
||||
panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src))
|
||||
}
|
||||
if in.IsNil() {
|
||||
return // Merge from nil src is a noop
|
||||
}
|
||||
if m, ok := dst.(generatedMerger); ok {
|
||||
m.XXX_Merge(src)
|
||||
return
|
||||
}
|
||||
mergeStruct(out.Elem(), in.Elem())
|
||||
}
|
||||
|
||||
func mergeStruct(out, in reflect.Value) {
|
||||
sprop := GetProperties(in.Type())
|
||||
for i := 0; i < in.NumField(); i++ {
|
||||
f := in.Type().Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
|
||||
}
|
||||
|
||||
if emIn, ok := in.Addr().Interface().(extensionsBytes); ok {
|
||||
emOut := out.Addr().Interface().(extensionsBytes)
|
||||
bIn := emIn.GetExtensions()
|
||||
bOut := emOut.GetExtensions()
|
||||
*bOut = append(*bOut, *bIn...)
|
||||
} else if emIn, err := extendable(in.Addr().Interface()); err == nil {
|
||||
emOut, _ := extendable(out.Addr().Interface())
|
||||
mIn, muIn := emIn.extensionsRead()
|
||||
if mIn != nil {
|
||||
mOut := emOut.extensionsWrite()
|
||||
muIn.Lock()
|
||||
mergeExtension(mOut, mIn)
|
||||
muIn.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
uf := in.FieldByName("XXX_unrecognized")
|
||||
if !uf.IsValid() {
|
||||
return
|
||||
}
|
||||
uin := uf.Bytes()
|
||||
if len(uin) > 0 {
|
||||
out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
|
||||
}
|
||||
}
|
||||
|
||||
// mergeAny performs a merge between two values of the same type.
|
||||
// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
|
||||
// prop is set if this is a struct field (it may be nil).
|
||||
func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
|
||||
if in.Type() == protoMessageType {
|
||||
if !in.IsNil() {
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
|
||||
} else {
|
||||
Merge(out.Interface().(Message), in.Interface().(Message))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
switch in.Kind() {
|
||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||
if !viaPtr && isProto3Zero(in) {
|
||||
return
|
||||
}
|
||||
out.Set(in)
|
||||
case reflect.Interface:
|
||||
// Probably a oneof field; copy non-nil values.
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
// Allocate destination if it is not set, or set to a different type.
|
||||
// Otherwise we will merge as normal.
|
||||
if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
|
||||
out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
|
||||
}
|
||||
mergeAny(out.Elem(), in.Elem(), false, nil)
|
||||
case reflect.Map:
|
||||
if in.Len() == 0 {
|
||||
return
|
||||
}
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.MakeMap(in.Type()))
|
||||
}
|
||||
// For maps with value types of *T or []byte we need to deep copy each value.
|
||||
elemKind := in.Type().Elem().Kind()
|
||||
for _, key := range in.MapKeys() {
|
||||
var val reflect.Value
|
||||
switch elemKind {
|
||||
case reflect.Ptr:
|
||||
val = reflect.New(in.Type().Elem().Elem())
|
||||
mergeAny(val, in.MapIndex(key), false, nil)
|
||||
case reflect.Slice:
|
||||
val = in.MapIndex(key)
|
||||
val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
|
||||
default:
|
||||
val = in.MapIndex(key)
|
||||
}
|
||||
out.SetMapIndex(key, val)
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.New(in.Elem().Type()))
|
||||
}
|
||||
mergeAny(out.Elem(), in.Elem(), true, nil)
|
||||
case reflect.Slice:
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
if in.Type().Elem().Kind() == reflect.Uint8 {
|
||||
// []byte is a scalar bytes field, not a repeated field.
|
||||
|
||||
// Edge case: if this is in a proto3 message, a zero length
|
||||
// bytes field is considered the zero value, and should not
|
||||
// be merged.
|
||||
if prop != nil && prop.proto3 && in.Len() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Make a deep copy.
|
||||
// Append to []byte{} instead of []byte(nil) so that we never end up
|
||||
// with a nil result.
|
||||
out.SetBytes(append([]byte{}, in.Bytes()...))
|
||||
return
|
||||
}
|
||||
n := in.Len()
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.MakeSlice(in.Type(), 0, n))
|
||||
}
|
||||
switch in.Type().Elem().Kind() {
|
||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||
out.Set(reflect.AppendSlice(out, in))
|
||||
default:
|
||||
for i := 0; i < n; i++ {
|
||||
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
||||
mergeAny(x, in.Index(i), false, nil)
|
||||
out.Set(reflect.Append(out, x))
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
mergeStruct(out, in)
|
||||
default:
|
||||
// unknown type, so not a protocol buffer
|
||||
log.Printf("proto: don't know how to copy %v", in)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeExtension(out, in map[int32]Extension) {
|
||||
for extNum, eIn := range in {
|
||||
eOut := Extension{desc: eIn.desc}
|
||||
if eIn.value != nil {
|
||||
v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
|
||||
mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
|
||||
eOut.value = v.Interface()
|
||||
}
|
||||
if eIn.enc != nil {
|
||||
eOut.enc = make([]byte, len(eIn.enc))
|
||||
copy(eOut.enc, eIn.enc)
|
||||
}
|
||||
|
||||
out[extNum] = eOut
|
||||
}
|
||||
}
|
39
vendor/github.com/gogo/protobuf/proto/custom_gogo.go
generated
vendored
Normal file
39
vendor/github.com/gogo/protobuf/proto/custom_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import "reflect"
|
||||
|
||||
type custom interface {
|
||||
Marshal() ([]byte, error)
|
||||
Unmarshal(data []byte) error
|
||||
Size() int
|
||||
}
|
||||
|
||||
var customType = reflect.TypeOf((*custom)(nil)).Elem()
|
427
vendor/github.com/gogo/protobuf/proto/decode.go
generated
vendored
Normal file
427
vendor/github.com/gogo/protobuf/proto/decode.go
generated
vendored
Normal file
|
@ -0,0 +1,427 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Routines for decoding protocol buffer data to construct in-memory representations.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// errOverflow is returned when an integer is too large to be represented.
|
||||
var errOverflow = errors.New("proto: integer overflow")
|
||||
|
||||
// ErrInternalBadWireType is returned by generated code when an incorrect
|
||||
// wire type is encountered. It does not get returned to user code.
|
||||
var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
|
||||
|
||||
// DecodeVarint reads a varint-encoded integer from the slice.
|
||||
// It returns the integer and the number of bytes consumed, or
|
||||
// zero if there is not enough.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
func DecodeVarint(buf []byte) (x uint64, n int) {
|
||||
for shift := uint(0); shift < 64; shift += 7 {
|
||||
if n >= len(buf) {
|
||||
return 0, 0
|
||||
}
|
||||
b := uint64(buf[n])
|
||||
n++
|
||||
x |= (b & 0x7F) << shift
|
||||
if (b & 0x80) == 0 {
|
||||
return x, n
|
||||
}
|
||||
}
|
||||
|
||||
// The number is too large to represent in a 64-bit value.
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
|
||||
i := p.index
|
||||
l := len(p.buf)
|
||||
|
||||
for shift := uint(0); shift < 64; shift += 7 {
|
||||
if i >= l {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
b := p.buf[i]
|
||||
i++
|
||||
x |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
p.index = i
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// The number is too large to represent in a 64-bit value.
|
||||
err = errOverflow
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeVarint reads a varint-encoded integer from the Buffer.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
||||
i := p.index
|
||||
buf := p.buf
|
||||
|
||||
if i >= len(buf) {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
} else if buf[i] < 0x80 {
|
||||
p.index++
|
||||
return uint64(buf[i]), nil
|
||||
} else if len(buf)-i < 10 {
|
||||
return p.decodeVarintSlow()
|
||||
}
|
||||
|
||||
var b uint64
|
||||
// we already checked the first byte
|
||||
x = uint64(buf[i]) - 0x80
|
||||
i++
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 7
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 7
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 14
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 14
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 21
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 21
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 28
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 28
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 35
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 35
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 42
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 42
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 49
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 49
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 56
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 56
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 63
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
|
||||
return 0, errOverflow
|
||||
|
||||
done:
|
||||
p.index = i
|
||||
return x, nil
|
||||
}
|
||||
|
||||
// DecodeFixed64 reads a 64-bit integer from the Buffer.
|
||||
// This is the format for the
|
||||
// fixed64, sfixed64, and double protocol buffer types.
|
||||
func (p *Buffer) DecodeFixed64() (x uint64, err error) {
|
||||
// x, err already 0
|
||||
i := p.index + 8
|
||||
if i < 0 || i > len(p.buf) {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
p.index = i
|
||||
|
||||
x = uint64(p.buf[i-8])
|
||||
x |= uint64(p.buf[i-7]) << 8
|
||||
x |= uint64(p.buf[i-6]) << 16
|
||||
x |= uint64(p.buf[i-5]) << 24
|
||||
x |= uint64(p.buf[i-4]) << 32
|
||||
x |= uint64(p.buf[i-3]) << 40
|
||||
x |= uint64(p.buf[i-2]) << 48
|
||||
x |= uint64(p.buf[i-1]) << 56
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeFixed32 reads a 32-bit integer from the Buffer.
|
||||
// This is the format for the
|
||||
// fixed32, sfixed32, and float protocol buffer types.
|
||||
func (p *Buffer) DecodeFixed32() (x uint64, err error) {
|
||||
// x, err already 0
|
||||
i := p.index + 4
|
||||
if i < 0 || i > len(p.buf) {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
p.index = i
|
||||
|
||||
x = uint64(p.buf[i-4])
|
||||
x |= uint64(p.buf[i-3]) << 8
|
||||
x |= uint64(p.buf[i-2]) << 16
|
||||
x |= uint64(p.buf[i-1]) << 24
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
|
||||
// from the Buffer.
|
||||
// This is the format used for the sint64 protocol buffer type.
|
||||
func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
|
||||
x, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
|
||||
// from the Buffer.
|
||||
// This is the format used for the sint32 protocol buffer type.
|
||||
func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
|
||||
x, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
|
||||
// This is the format used for the bytes protocol buffer
|
||||
// type and for embedded messages.
|
||||
func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
|
||||
n, err := p.DecodeVarint()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nb := int(n)
|
||||
if nb < 0 {
|
||||
return nil, fmt.Errorf("proto: bad byte length %d", nb)
|
||||
}
|
||||
end := p.index + nb
|
||||
if end < p.index || end > len(p.buf) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
if !alloc {
|
||||
// todo: check if can get more uses of alloc=false
|
||||
buf = p.buf[p.index:end]
|
||||
p.index += nb
|
||||
return
|
||||
}
|
||||
|
||||
buf = make([]byte, nb)
|
||||
copy(buf, p.buf[p.index:])
|
||||
p.index += nb
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeStringBytes reads an encoded string from the Buffer.
|
||||
// This is the format used for the proto2 string type.
|
||||
func (p *Buffer) DecodeStringBytes() (s string, err error) {
|
||||
buf, err := p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
// Unmarshaler is the interface representing objects that can
|
||||
// unmarshal themselves. The argument points to data that may be
|
||||
// overwritten, so implementations should not keep references to the
|
||||
// buffer.
|
||||
// Unmarshal implementations should not clear the receiver.
|
||||
// Any unmarshaled data should be merged into the receiver.
|
||||
// Callers of Unmarshal that do not want to retain existing data
|
||||
// should Reset the receiver before calling Unmarshal.
|
||||
type Unmarshaler interface {
|
||||
Unmarshal([]byte) error
|
||||
}
|
||||
|
||||
// newUnmarshaler is the interface representing objects that can
|
||||
// unmarshal themselves. The semantics are identical to Unmarshaler.
|
||||
//
|
||||
// This exists to support protoc-gen-go generated messages.
|
||||
// The proto package will stop type-asserting to this interface in the future.
|
||||
//
|
||||
// DO NOT DEPEND ON THIS.
|
||||
type newUnmarshaler interface {
|
||||
XXX_Unmarshal([]byte) error
|
||||
}
|
||||
|
||||
// Unmarshal parses the protocol buffer representation in buf and places the
|
||||
// decoded result in pb. If the struct underlying pb does not match
|
||||
// the data in buf, the results can be unpredictable.
|
||||
//
|
||||
// Unmarshal resets pb before starting to unmarshal, so any
|
||||
// existing data in pb is always removed. Use UnmarshalMerge
|
||||
// to preserve and append to existing data.
|
||||
func Unmarshal(buf []byte, pb Message) error {
|
||||
pb.Reset()
|
||||
if u, ok := pb.(newUnmarshaler); ok {
|
||||
return u.XXX_Unmarshal(buf)
|
||||
}
|
||||
if u, ok := pb.(Unmarshaler); ok {
|
||||
return u.Unmarshal(buf)
|
||||
}
|
||||
return NewBuffer(buf).Unmarshal(pb)
|
||||
}
|
||||
|
||||
// UnmarshalMerge parses the protocol buffer representation in buf and
|
||||
// writes the decoded result to pb. If the struct underlying pb does not match
|
||||
// the data in buf, the results can be unpredictable.
|
||||
//
|
||||
// UnmarshalMerge merges into existing data in pb.
|
||||
// Most code should use Unmarshal instead.
|
||||
func UnmarshalMerge(buf []byte, pb Message) error {
|
||||
if u, ok := pb.(newUnmarshaler); ok {
|
||||
return u.XXX_Unmarshal(buf)
|
||||
}
|
||||
if u, ok := pb.(Unmarshaler); ok {
|
||||
// NOTE: The history of proto have unfortunately been inconsistent
|
||||
// whether Unmarshaler should or should not implicitly clear itself.
|
||||
// Some implementations do, most do not.
|
||||
// Thus, calling this here may or may not do what people want.
|
||||
//
|
||||
// See https://github.com/golang/protobuf/issues/424
|
||||
return u.Unmarshal(buf)
|
||||
}
|
||||
return NewBuffer(buf).Unmarshal(pb)
|
||||
}
|
||||
|
||||
// DecodeMessage reads a count-delimited message from the Buffer.
|
||||
func (p *Buffer) DecodeMessage(pb Message) error {
|
||||
enc, err := p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return NewBuffer(enc).Unmarshal(pb)
|
||||
}
|
||||
|
||||
// DecodeGroup reads a tag-delimited group from the Buffer.
|
||||
// StartGroup tag is already consumed. This function consumes
|
||||
// EndGroup tag.
|
||||
func (p *Buffer) DecodeGroup(pb Message) error {
|
||||
b := p.buf[p.index:]
|
||||
x, y := findEndGroup(b)
|
||||
if x < 0 {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
err := Unmarshal(b[:x], pb)
|
||||
p.index += y
|
||||
return err
|
||||
}
|
||||
|
||||
// Unmarshal parses the protocol buffer representation in the
|
||||
// Buffer and places the decoded result in pb. If the struct
|
||||
// underlying pb does not match the data in the buffer, the results can be
|
||||
// unpredictable.
|
||||
//
|
||||
// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
|
||||
func (p *Buffer) Unmarshal(pb Message) error {
|
||||
// If the object can unmarshal itself, let it.
|
||||
if u, ok := pb.(newUnmarshaler); ok {
|
||||
err := u.XXX_Unmarshal(p.buf[p.index:])
|
||||
p.index = len(p.buf)
|
||||
return err
|
||||
}
|
||||
if u, ok := pb.(Unmarshaler); ok {
|
||||
// NOTE: The history of proto have unfortunately been inconsistent
|
||||
// whether Unmarshaler should or should not implicitly clear itself.
|
||||
// Some implementations do, most do not.
|
||||
// Thus, calling this here may or may not do what people want.
|
||||
//
|
||||
// See https://github.com/golang/protobuf/issues/424
|
||||
err := u.Unmarshal(p.buf[p.index:])
|
||||
p.index = len(p.buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// Slow workaround for messages that aren't Unmarshalers.
|
||||
// This includes some hand-coded .pb.go files and
|
||||
// bootstrap protos.
|
||||
// TODO: fix all of those and then add Unmarshal to
|
||||
// the Message interface. Then:
|
||||
// The cast above and code below can be deleted.
|
||||
// The old unmarshaler can be deleted.
|
||||
// Clients can call Unmarshal directly (can already do that, actually).
|
||||
var info InternalMessageInfo
|
||||
err := info.Unmarshal(pb, p.buf[p.index:])
|
||||
p.index = len(p.buf)
|
||||
return err
|
||||
}
|
63
vendor/github.com/gogo/protobuf/proto/deprecated.go
generated
vendored
Normal file
63
vendor/github.com/gogo/protobuf/proto/deprecated.go
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import "errors"
|
||||
|
||||
// Deprecated: do not use.
|
||||
type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }
|
||||
|
||||
// Deprecated: do not use.
|
||||
func GetStats() Stats { return Stats{} }
|
||||
|
||||
// Deprecated: do not use.
|
||||
func MarshalMessageSet(interface{}) ([]byte, error) {
|
||||
return nil, errors.New("proto: not implemented")
|
||||
}
|
||||
|
||||
// Deprecated: do not use.
|
||||
func UnmarshalMessageSet([]byte, interface{}) error {
|
||||
return errors.New("proto: not implemented")
|
||||
}
|
||||
|
||||
// Deprecated: do not use.
|
||||
func MarshalMessageSetJSON(interface{}) ([]byte, error) {
|
||||
return nil, errors.New("proto: not implemented")
|
||||
}
|
||||
|
||||
// Deprecated: do not use.
|
||||
func UnmarshalMessageSetJSON([]byte, interface{}) error {
|
||||
return errors.New("proto: not implemented")
|
||||
}
|
||||
|
||||
// Deprecated: do not use.
|
||||
func RegisterMessageSetType(Message, int32, string) {}
|
350
vendor/github.com/gogo/protobuf/proto/discard.go
generated
vendored
Normal file
350
vendor/github.com/gogo/protobuf/proto/discard.go
generated
vendored
Normal file
|
@ -0,0 +1,350 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type generatedDiscarder interface {
|
||||
XXX_DiscardUnknown()
|
||||
}
|
||||
|
||||
// DiscardUnknown recursively discards all unknown fields from this message
|
||||
// and all embedded messages.
|
||||
//
|
||||
// When unmarshaling a message with unrecognized fields, the tags and values
|
||||
// of such fields are preserved in the Message. This allows a later call to
|
||||
// marshal to be able to produce a message that continues to have those
|
||||
// unrecognized fields. To avoid this, DiscardUnknown is used to
|
||||
// explicitly clear the unknown fields after unmarshaling.
|
||||
//
|
||||
// For proto2 messages, the unknown fields of message extensions are only
|
||||
// discarded from messages that have been accessed via GetExtension.
|
||||
func DiscardUnknown(m Message) {
|
||||
if m, ok := m.(generatedDiscarder); ok {
|
||||
m.XXX_DiscardUnknown()
|
||||
return
|
||||
}
|
||||
// TODO: Dynamically populate a InternalMessageInfo for legacy messages,
|
||||
// but the master branch has no implementation for InternalMessageInfo,
|
||||
// so it would be more work to replicate that approach.
|
||||
discardLegacy(m)
|
||||
}
|
||||
|
||||
// DiscardUnknown recursively discards all unknown fields.
|
||||
func (a *InternalMessageInfo) DiscardUnknown(m Message) {
|
||||
di := atomicLoadDiscardInfo(&a.discard)
|
||||
if di == nil {
|
||||
di = getDiscardInfo(reflect.TypeOf(m).Elem())
|
||||
atomicStoreDiscardInfo(&a.discard, di)
|
||||
}
|
||||
di.discard(toPointer(&m))
|
||||
}
|
||||
|
||||
type discardInfo struct {
|
||||
typ reflect.Type
|
||||
|
||||
initialized int32 // 0: only typ is valid, 1: everything is valid
|
||||
lock sync.Mutex
|
||||
|
||||
fields []discardFieldInfo
|
||||
unrecognized field
|
||||
}
|
||||
|
||||
type discardFieldInfo struct {
|
||||
field field // Offset of field, guaranteed to be valid
|
||||
discard func(src pointer)
|
||||
}
|
||||
|
||||
var (
|
||||
discardInfoMap = map[reflect.Type]*discardInfo{}
|
||||
discardInfoLock sync.Mutex
|
||||
)
|
||||
|
||||
func getDiscardInfo(t reflect.Type) *discardInfo {
|
||||
discardInfoLock.Lock()
|
||||
defer discardInfoLock.Unlock()
|
||||
di := discardInfoMap[t]
|
||||
if di == nil {
|
||||
di = &discardInfo{typ: t}
|
||||
discardInfoMap[t] = di
|
||||
}
|
||||
return di
|
||||
}
|
||||
|
||||
func (di *discardInfo) discard(src pointer) {
|
||||
if src.isNil() {
|
||||
return // Nothing to do.
|
||||
}
|
||||
|
||||
if atomic.LoadInt32(&di.initialized) == 0 {
|
||||
di.computeDiscardInfo()
|
||||
}
|
||||
|
||||
for _, fi := range di.fields {
|
||||
sfp := src.offset(fi.field)
|
||||
fi.discard(sfp)
|
||||
}
|
||||
|
||||
// For proto2 messages, only discard unknown fields in message extensions
|
||||
// that have been accessed via GetExtension.
|
||||
if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil {
|
||||
// Ignore lock since DiscardUnknown is not concurrency safe.
|
||||
emm, _ := em.extensionsRead()
|
||||
for _, mx := range emm {
|
||||
if m, ok := mx.value.(Message); ok {
|
||||
DiscardUnknown(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if di.unrecognized.IsValid() {
|
||||
*src.offset(di.unrecognized).toBytes() = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (di *discardInfo) computeDiscardInfo() {
|
||||
di.lock.Lock()
|
||||
defer di.lock.Unlock()
|
||||
if di.initialized != 0 {
|
||||
return
|
||||
}
|
||||
t := di.typ
|
||||
n := t.NumField()
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
f := t.Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
|
||||
dfi := discardFieldInfo{field: toField(&f)}
|
||||
tf := f.Type
|
||||
|
||||
// Unwrap tf to get its most basic type.
|
||||
var isPointer, isSlice bool
|
||||
if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
|
||||
isSlice = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if tf.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if isPointer && isSlice && tf.Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name))
|
||||
}
|
||||
|
||||
switch tf.Kind() {
|
||||
case reflect.Struct:
|
||||
switch {
|
||||
case !isPointer:
|
||||
panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name))
|
||||
case isSlice: // E.g., []*pb.T
|
||||
discardInfo := getDiscardInfo(tf)
|
||||
dfi.discard = func(src pointer) {
|
||||
sps := src.getPointerSlice()
|
||||
for _, sp := range sps {
|
||||
if !sp.isNil() {
|
||||
discardInfo.discard(sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., *pb.T
|
||||
discardInfo := getDiscardInfo(tf)
|
||||
dfi.discard = func(src pointer) {
|
||||
sp := src.getPointer()
|
||||
if !sp.isNil() {
|
||||
discardInfo.discard(sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name))
|
||||
default: // E.g., map[K]V
|
||||
if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T)
|
||||
dfi.discard = func(src pointer) {
|
||||
sm := src.asPointerTo(tf).Elem()
|
||||
if sm.Len() == 0 {
|
||||
return
|
||||
}
|
||||
for _, key := range sm.MapKeys() {
|
||||
val := sm.MapIndex(key)
|
||||
DiscardUnknown(val.Interface().(Message))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dfi.discard = func(pointer) {} // Noop
|
||||
}
|
||||
}
|
||||
case reflect.Interface:
|
||||
// Must be oneof field.
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name))
|
||||
default: // E.g., interface{}
|
||||
// TODO: Make this faster?
|
||||
dfi.discard = func(src pointer) {
|
||||
su := src.asPointerTo(tf).Elem()
|
||||
if !su.IsNil() {
|
||||
sv := su.Elem().Elem().Field(0)
|
||||
if sv.Kind() == reflect.Ptr && sv.IsNil() {
|
||||
return
|
||||
}
|
||||
switch sv.Type().Kind() {
|
||||
case reflect.Ptr: // Proto struct (e.g., *T)
|
||||
DiscardUnknown(sv.Interface().(Message))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
di.fields = append(di.fields, dfi)
|
||||
}
|
||||
|
||||
di.unrecognized = invalidField
|
||||
if f, ok := t.FieldByName("XXX_unrecognized"); ok {
|
||||
if f.Type != reflect.TypeOf([]byte{}) {
|
||||
panic("expected XXX_unrecognized to be of type []byte")
|
||||
}
|
||||
di.unrecognized = toField(&f)
|
||||
}
|
||||
|
||||
atomic.StoreInt32(&di.initialized, 1)
|
||||
}
|
||||
|
||||
func discardLegacy(m Message) {
|
||||
v := reflect.ValueOf(m)
|
||||
if v.Kind() != reflect.Ptr || v.IsNil() {
|
||||
return
|
||||
}
|
||||
v = v.Elem()
|
||||
if v.Kind() != reflect.Struct {
|
||||
return
|
||||
}
|
||||
t := v.Type()
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
vf := v.Field(i)
|
||||
tf := f.Type
|
||||
|
||||
// Unwrap tf to get its most basic type.
|
||||
var isPointer, isSlice bool
|
||||
if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
|
||||
isSlice = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if tf.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if isPointer && isSlice && tf.Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name))
|
||||
}
|
||||
|
||||
switch tf.Kind() {
|
||||
case reflect.Struct:
|
||||
switch {
|
||||
case !isPointer:
|
||||
panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name))
|
||||
case isSlice: // E.g., []*pb.T
|
||||
for j := 0; j < vf.Len(); j++ {
|
||||
discardLegacy(vf.Index(j).Interface().(Message))
|
||||
}
|
||||
default: // E.g., *pb.T
|
||||
discardLegacy(vf.Interface().(Message))
|
||||
}
|
||||
case reflect.Map:
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name))
|
||||
default: // E.g., map[K]V
|
||||
tv := vf.Type().Elem()
|
||||
if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T)
|
||||
for _, key := range vf.MapKeys() {
|
||||
val := vf.MapIndex(key)
|
||||
discardLegacy(val.Interface().(Message))
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Interface:
|
||||
// Must be oneof field.
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name))
|
||||
default: // E.g., test_proto.isCommunique_Union interface
|
||||
if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" {
|
||||
vf = vf.Elem() // E.g., *test_proto.Communique_Msg
|
||||
if !vf.IsNil() {
|
||||
vf = vf.Elem() // E.g., test_proto.Communique_Msg
|
||||
vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value
|
||||
if vf.Kind() == reflect.Ptr {
|
||||
discardLegacy(vf.Interface().(Message))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() {
|
||||
if vf.Type() != reflect.TypeOf([]byte{}) {
|
||||
panic("expected XXX_unrecognized to be of type []byte")
|
||||
}
|
||||
vf.Set(reflect.ValueOf([]byte(nil)))
|
||||
}
|
||||
|
||||
// For proto2 messages, only discard unknown fields in message extensions
|
||||
// that have been accessed via GetExtension.
|
||||
if em, err := extendable(m); err == nil {
|
||||
// Ignore lock since discardLegacy is not concurrency safe.
|
||||
emm, _ := em.extensionsRead()
|
||||
for _, mx := range emm {
|
||||
if m, ok := mx.value.(Message); ok {
|
||||
discardLegacy(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
100
vendor/github.com/gogo/protobuf/proto/duration.go
generated
vendored
Normal file
100
vendor/github.com/gogo/protobuf/proto/duration.go
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
// This file implements conversions between google.protobuf.Duration
|
||||
// and time.Duration.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// Range of a Duration in seconds, as specified in
|
||||
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
|
||||
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
|
||||
minSeconds = -maxSeconds
|
||||
)
|
||||
|
||||
// validateDuration determines whether the Duration is valid according to the
|
||||
// definition in google/protobuf/duration.proto. A valid Duration
|
||||
// may still be too large to fit into a time.Duration (the range of Duration
|
||||
// is about 10,000 years, and the range of time.Duration is about 290).
|
||||
func validateDuration(d *duration) error {
|
||||
if d == nil {
|
||||
return errors.New("duration: nil Duration")
|
||||
}
|
||||
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
|
||||
return fmt.Errorf("duration: %#v: seconds out of range", d)
|
||||
}
|
||||
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
|
||||
return fmt.Errorf("duration: %#v: nanos out of range", d)
|
||||
}
|
||||
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
|
||||
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
|
||||
return fmt.Errorf("duration: %#v: seconds and nanos have different signs", d)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DurationFromProto converts a Duration to a time.Duration. DurationFromProto
|
||||
// returns an error if the Duration is invalid or is too large to be
|
||||
// represented in a time.Duration.
|
||||
func durationFromProto(p *duration) (time.Duration, error) {
|
||||
if err := validateDuration(p); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
d := time.Duration(p.Seconds) * time.Second
|
||||
if int64(d/time.Second) != p.Seconds {
|
||||
return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p)
|
||||
}
|
||||
if p.Nanos != 0 {
|
||||
d += time.Duration(p.Nanos)
|
||||
if (d < 0) != (p.Nanos < 0) {
|
||||
return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p)
|
||||
}
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// DurationProto converts a time.Duration to a Duration.
|
||||
func durationProto(d time.Duration) *duration {
|
||||
nanos := d.Nanoseconds()
|
||||
secs := nanos / 1e9
|
||||
nanos -= secs * 1e9
|
||||
return &duration{
|
||||
Seconds: secs,
|
||||
Nanos: int32(nanos),
|
||||
}
|
||||
}
|
49
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
generated
vendored
Normal file
49
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
var durationType = reflect.TypeOf((*time.Duration)(nil)).Elem()
|
||||
|
||||
type duration struct {
|
||||
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
|
||||
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
|
||||
}
|
||||
|
||||
func (m *duration) Reset() { *m = duration{} }
|
||||
func (*duration) ProtoMessage() {}
|
||||
func (*duration) String() string { return "duration<string>" }
|
||||
|
||||
func init() {
|
||||
RegisterType((*duration)(nil), "gogo.protobuf.proto.duration")
|
||||
}
|
203
vendor/github.com/gogo/protobuf/proto/encode.go
generated
vendored
Normal file
203
vendor/github.com/gogo/protobuf/proto/encode.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Routines for encoding data into the wire format for protocol buffers.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var (
|
||||
// errRepeatedHasNil is the error returned if Marshal is called with
|
||||
// a struct with a repeated field containing a nil element.
|
||||
errRepeatedHasNil = errors.New("proto: repeated field has nil element")
|
||||
|
||||
// errOneofHasNil is the error returned if Marshal is called with
|
||||
// a struct with a oneof field containing a nil element.
|
||||
errOneofHasNil = errors.New("proto: oneof field has nil value")
|
||||
|
||||
// ErrNil is the error returned if Marshal is called with nil.
|
||||
ErrNil = errors.New("proto: Marshal called with nil")
|
||||
|
||||
// ErrTooLarge is the error returned if Marshal is called with a
|
||||
// message that encodes to >2GB.
|
||||
ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
|
||||
)
|
||||
|
||||
// The fundamental encoders that put bytes on the wire.
|
||||
// Those that take integer types all accept uint64 and are
|
||||
// therefore of type valueEncoder.
|
||||
|
||||
const maxVarintBytes = 10 // maximum length of a varint
|
||||
|
||||
// EncodeVarint returns the varint encoding of x.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
// Not used by the package itself, but helpful to clients
|
||||
// wishing to use the same encoding.
|
||||
func EncodeVarint(x uint64) []byte {
|
||||
var buf [maxVarintBytes]byte
|
||||
var n int
|
||||
for n = 0; x > 127; n++ {
|
||||
buf[n] = 0x80 | uint8(x&0x7F)
|
||||
x >>= 7
|
||||
}
|
||||
buf[n] = uint8(x)
|
||||
n++
|
||||
return buf[0:n]
|
||||
}
|
||||
|
||||
// EncodeVarint writes a varint-encoded integer to the Buffer.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
func (p *Buffer) EncodeVarint(x uint64) error {
|
||||
for x >= 1<<7 {
|
||||
p.buf = append(p.buf, uint8(x&0x7f|0x80))
|
||||
x >>= 7
|
||||
}
|
||||
p.buf = append(p.buf, uint8(x))
|
||||
return nil
|
||||
}
|
||||
|
||||
// SizeVarint returns the varint encoding size of an integer.
|
||||
func SizeVarint(x uint64) int {
|
||||
switch {
|
||||
case x < 1<<7:
|
||||
return 1
|
||||
case x < 1<<14:
|
||||
return 2
|
||||
case x < 1<<21:
|
||||
return 3
|
||||
case x < 1<<28:
|
||||
return 4
|
||||
case x < 1<<35:
|
||||
return 5
|
||||
case x < 1<<42:
|
||||
return 6
|
||||
case x < 1<<49:
|
||||
return 7
|
||||
case x < 1<<56:
|
||||
return 8
|
||||
case x < 1<<63:
|
||||
return 9
|
||||
}
|
||||
return 10
|
||||
}
|
||||
|
||||
// EncodeFixed64 writes a 64-bit integer to the Buffer.
|
||||
// This is the format for the
|
||||
// fixed64, sfixed64, and double protocol buffer types.
|
||||
func (p *Buffer) EncodeFixed64(x uint64) error {
|
||||
p.buf = append(p.buf,
|
||||
uint8(x),
|
||||
uint8(x>>8),
|
||||
uint8(x>>16),
|
||||
uint8(x>>24),
|
||||
uint8(x>>32),
|
||||
uint8(x>>40),
|
||||
uint8(x>>48),
|
||||
uint8(x>>56))
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeFixed32 writes a 32-bit integer to the Buffer.
|
||||
// This is the format for the
|
||||
// fixed32, sfixed32, and float protocol buffer types.
|
||||
func (p *Buffer) EncodeFixed32(x uint64) error {
|
||||
p.buf = append(p.buf,
|
||||
uint8(x),
|
||||
uint8(x>>8),
|
||||
uint8(x>>16),
|
||||
uint8(x>>24))
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
|
||||
// to the Buffer.
|
||||
// This is the format used for the sint64 protocol buffer type.
|
||||
func (p *Buffer) EncodeZigzag64(x uint64) error {
|
||||
// use signed number to get arithmetic right shift.
|
||||
return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
|
||||
// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
|
||||
// to the Buffer.
|
||||
// This is the format used for the sint32 protocol buffer type.
|
||||
func (p *Buffer) EncodeZigzag32(x uint64) error {
|
||||
// use signed number to get arithmetic right shift.
|
||||
return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
|
||||
}
|
||||
|
||||
// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
|
||||
// This is the format used for the bytes protocol buffer
|
||||
// type and for embedded messages.
|
||||
func (p *Buffer) EncodeRawBytes(b []byte) error {
|
||||
p.EncodeVarint(uint64(len(b)))
|
||||
p.buf = append(p.buf, b...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeStringBytes writes an encoded string to the Buffer.
|
||||
// This is the format used for the proto2 string type.
|
||||
func (p *Buffer) EncodeStringBytes(s string) error {
|
||||
p.EncodeVarint(uint64(len(s)))
|
||||
p.buf = append(p.buf, s...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshaler is the interface representing objects that can marshal themselves.
|
||||
type Marshaler interface {
|
||||
Marshal() ([]byte, error)
|
||||
}
|
||||
|
||||
// EncodeMessage writes the protocol buffer to the Buffer,
|
||||
// prefixed by a varint-encoded length.
|
||||
func (p *Buffer) EncodeMessage(pb Message) error {
|
||||
siz := Size(pb)
|
||||
p.EncodeVarint(uint64(siz))
|
||||
return p.Marshal(pb)
|
||||
}
|
||||
|
||||
// All protocol buffer fields are nillable, but be careful.
|
||||
func isNil(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
return v.IsNil()
|
||||
}
|
||||
return false
|
||||
}
|
33
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
generated
vendored
Normal file
33
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
func NewRequiredNotSetError(field string) *RequiredNotSetError {
|
||||
return &RequiredNotSetError{field}
|
||||
}
|
300
vendor/github.com/gogo/protobuf/proto/equal.go
generated
vendored
Normal file
300
vendor/github.com/gogo/protobuf/proto/equal.go
generated
vendored
Normal file
|
@ -0,0 +1,300 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Protocol buffer comparison.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
Equal returns true iff protocol buffers a and b are equal.
|
||||
The arguments must both be pointers to protocol buffer structs.
|
||||
|
||||
Equality is defined in this way:
|
||||
- Two messages are equal iff they are the same type,
|
||||
corresponding fields are equal, unknown field sets
|
||||
are equal, and extensions sets are equal.
|
||||
- Two set scalar fields are equal iff their values are equal.
|
||||
If the fields are of a floating-point type, remember that
|
||||
NaN != x for all x, including NaN. If the message is defined
|
||||
in a proto3 .proto file, fields are not "set"; specifically,
|
||||
zero length proto3 "bytes" fields are equal (nil == {}).
|
||||
- Two repeated fields are equal iff their lengths are the same,
|
||||
and their corresponding elements are equal. Note a "bytes" field,
|
||||
although represented by []byte, is not a repeated field and the
|
||||
rule for the scalar fields described above applies.
|
||||
- Two unset fields are equal.
|
||||
- Two unknown field sets are equal if their current
|
||||
encoded state is equal.
|
||||
- Two extension sets are equal iff they have corresponding
|
||||
elements that are pairwise equal.
|
||||
- Two map fields are equal iff their lengths are the same,
|
||||
and they contain the same set of elements. Zero-length map
|
||||
fields are equal.
|
||||
- Every other combination of things are not equal.
|
||||
|
||||
The return value is undefined if a and b are not protocol buffers.
|
||||
*/
|
||||
func Equal(a, b Message) bool {
|
||||
if a == nil || b == nil {
|
||||
return a == b
|
||||
}
|
||||
v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
|
||||
if v1.Type() != v2.Type() {
|
||||
return false
|
||||
}
|
||||
if v1.Kind() == reflect.Ptr {
|
||||
if v1.IsNil() {
|
||||
return v2.IsNil()
|
||||
}
|
||||
if v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
v1, v2 = v1.Elem(), v2.Elem()
|
||||
}
|
||||
if v1.Kind() != reflect.Struct {
|
||||
return false
|
||||
}
|
||||
return equalStruct(v1, v2)
|
||||
}
|
||||
|
||||
// v1 and v2 are known to have the same type.
|
||||
func equalStruct(v1, v2 reflect.Value) bool {
|
||||
sprop := GetProperties(v1.Type())
|
||||
for i := 0; i < v1.NumField(); i++ {
|
||||
f := v1.Type().Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
f1, f2 := v1.Field(i), v2.Field(i)
|
||||
if f.Type.Kind() == reflect.Ptr {
|
||||
if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
|
||||
// both unset
|
||||
continue
|
||||
} else if n1 != n2 {
|
||||
// set/unset mismatch
|
||||
return false
|
||||
}
|
||||
f1, f2 = f1.Elem(), f2.Elem()
|
||||
}
|
||||
if !equalAny(f1, f2, sprop.Prop[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
|
||||
em2 := v2.FieldByName("XXX_InternalExtensions")
|
||||
if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
|
||||
em2 := v2.FieldByName("XXX_extensions")
|
||||
if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
uf := v1.FieldByName("XXX_unrecognized")
|
||||
if !uf.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
u1 := uf.Bytes()
|
||||
u2 := v2.FieldByName("XXX_unrecognized").Bytes()
|
||||
return bytes.Equal(u1, u2)
|
||||
}
|
||||
|
||||
// v1 and v2 are known to have the same type.
|
||||
// prop may be nil.
|
||||
func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
|
||||
if v1.Type() == protoMessageType {
|
||||
m1, _ := v1.Interface().(Message)
|
||||
m2, _ := v2.Interface().(Message)
|
||||
return Equal(m1, m2)
|
||||
}
|
||||
switch v1.Kind() {
|
||||
case reflect.Bool:
|
||||
return v1.Bool() == v2.Bool()
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v1.Float() == v2.Float()
|
||||
case reflect.Int32, reflect.Int64:
|
||||
return v1.Int() == v2.Int()
|
||||
case reflect.Interface:
|
||||
// Probably a oneof field; compare the inner values.
|
||||
n1, n2 := v1.IsNil(), v2.IsNil()
|
||||
if n1 || n2 {
|
||||
return n1 == n2
|
||||
}
|
||||
e1, e2 := v1.Elem(), v2.Elem()
|
||||
if e1.Type() != e2.Type() {
|
||||
return false
|
||||
}
|
||||
return equalAny(e1, e2, nil)
|
||||
case reflect.Map:
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
for _, key := range v1.MapKeys() {
|
||||
val2 := v2.MapIndex(key)
|
||||
if !val2.IsValid() {
|
||||
// This key was not found in the second map.
|
||||
return false
|
||||
}
|
||||
if !equalAny(v1.MapIndex(key), val2, nil) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case reflect.Ptr:
|
||||
// Maps may have nil values in them, so check for nil.
|
||||
if v1.IsNil() && v2.IsNil() {
|
||||
return true
|
||||
}
|
||||
if v1.IsNil() != v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
return equalAny(v1.Elem(), v2.Elem(), prop)
|
||||
case reflect.Slice:
|
||||
if v1.Type().Elem().Kind() == reflect.Uint8 {
|
||||
// short circuit: []byte
|
||||
|
||||
// Edge case: if this is in a proto3 message, a zero length
|
||||
// bytes field is considered the zero value.
|
||||
if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {
|
||||
return true
|
||||
}
|
||||
if v1.IsNil() != v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
|
||||
}
|
||||
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < v1.Len(); i++ {
|
||||
if !equalAny(v1.Index(i), v2.Index(i), prop) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case reflect.String:
|
||||
return v1.Interface().(string) == v2.Interface().(string)
|
||||
case reflect.Struct:
|
||||
return equalStruct(v1, v2)
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
return v1.Uint() == v2.Uint()
|
||||
}
|
||||
|
||||
// unknown type, so not a protocol buffer
|
||||
log.Printf("proto: don't know how to compare %v", v1)
|
||||
return false
|
||||
}
|
||||
|
||||
// base is the struct type that the extensions are based on.
|
||||
// x1 and x2 are InternalExtensions.
|
||||
func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
|
||||
em1, _ := x1.extensionsRead()
|
||||
em2, _ := x2.extensionsRead()
|
||||
return equalExtMap(base, em1, em2)
|
||||
}
|
||||
|
||||
func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
|
||||
if len(em1) != len(em2) {
|
||||
return false
|
||||
}
|
||||
|
||||
for extNum, e1 := range em1 {
|
||||
e2, ok := em2[extNum]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
m1, m2 := e1.value, e2.value
|
||||
|
||||
if m1 == nil && m2 == nil {
|
||||
// Both have only encoded form.
|
||||
if bytes.Equal(e1.enc, e2.enc) {
|
||||
continue
|
||||
}
|
||||
// The bytes are different, but the extensions might still be
|
||||
// equal. We need to decode them to compare.
|
||||
}
|
||||
|
||||
if m1 != nil && m2 != nil {
|
||||
// Both are unencoded.
|
||||
if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// At least one is encoded. To do a semantically correct comparison
|
||||
// we need to unmarshal them first.
|
||||
var desc *ExtensionDesc
|
||||
if m := extensionMaps[base]; m != nil {
|
||||
desc = m[extNum]
|
||||
}
|
||||
if desc == nil {
|
||||
// If both have only encoded form and the bytes are the same,
|
||||
// it is handled above. We get here when the bytes are different.
|
||||
// We don't know how to decode it, so just compare them as byte
|
||||
// slices.
|
||||
log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
|
||||
return false
|
||||
}
|
||||
var err error
|
||||
if m1 == nil {
|
||||
m1, err = decodeExtension(e1.enc, desc)
|
||||
}
|
||||
if m2 == nil && err == nil {
|
||||
m2, err = decodeExtension(e2.enc, desc)
|
||||
}
|
||||
if err != nil {
|
||||
// The encoded form is invalid.
|
||||
log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
|
||||
return false
|
||||
}
|
||||
if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
604
vendor/github.com/gogo/protobuf/proto/extensions.go
generated
vendored
Normal file
604
vendor/github.com/gogo/protobuf/proto/extensions.go
generated
vendored
Normal file
|
@ -0,0 +1,604 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Types and routines for supporting protocol buffer extensions.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
|
||||
var ErrMissingExtension = errors.New("proto: missing extension")
|
||||
|
||||
// ExtensionRange represents a range of message extensions for a protocol buffer.
|
||||
// Used in code generated by the protocol compiler.
|
||||
type ExtensionRange struct {
|
||||
Start, End int32 // both inclusive
|
||||
}
|
||||
|
||||
// extendableProto is an interface implemented by any protocol buffer generated by the current
|
||||
// proto compiler that may be extended.
|
||||
type extendableProto interface {
|
||||
Message
|
||||
ExtensionRangeArray() []ExtensionRange
|
||||
extensionsWrite() map[int32]Extension
|
||||
extensionsRead() (map[int32]Extension, sync.Locker)
|
||||
}
|
||||
|
||||
// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
|
||||
// version of the proto compiler that may be extended.
|
||||
type extendableProtoV1 interface {
|
||||
Message
|
||||
ExtensionRangeArray() []ExtensionRange
|
||||
ExtensionMap() map[int32]Extension
|
||||
}
|
||||
|
||||
// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
|
||||
type extensionAdapter struct {
|
||||
extendableProtoV1
|
||||
}
|
||||
|
||||
func (e extensionAdapter) extensionsWrite() map[int32]Extension {
|
||||
return e.ExtensionMap()
|
||||
}
|
||||
|
||||
func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||
return e.ExtensionMap(), notLocker{}
|
||||
}
|
||||
|
||||
// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
|
||||
type notLocker struct{}
|
||||
|
||||
func (n notLocker) Lock() {}
|
||||
func (n notLocker) Unlock() {}
|
||||
|
||||
// extendable returns the extendableProto interface for the given generated proto message.
|
||||
// If the proto message has the old extension format, it returns a wrapper that implements
|
||||
// the extendableProto interface.
|
||||
func extendable(p interface{}) (extendableProto, error) {
|
||||
switch p := p.(type) {
|
||||
case extendableProto:
|
||||
if isNilPtr(p) {
|
||||
return nil, fmt.Errorf("proto: nil %T is not extendable", p)
|
||||
}
|
||||
return p, nil
|
||||
case extendableProtoV1:
|
||||
if isNilPtr(p) {
|
||||
return nil, fmt.Errorf("proto: nil %T is not extendable", p)
|
||||
}
|
||||
return extensionAdapter{p}, nil
|
||||
case extensionsBytes:
|
||||
return slowExtensionAdapter{p}, nil
|
||||
}
|
||||
// Don't allocate a specific error containing %T:
|
||||
// this is the hot path for Clone and MarshalText.
|
||||
return nil, errNotExtendable
|
||||
}
|
||||
|
||||
var errNotExtendable = errors.New("proto: not an extendable proto.Message")
|
||||
|
||||
func isNilPtr(x interface{}) bool {
|
||||
v := reflect.ValueOf(x)
|
||||
return v.Kind() == reflect.Ptr && v.IsNil()
|
||||
}
|
||||
|
||||
// XXX_InternalExtensions is an internal representation of proto extensions.
|
||||
//
|
||||
// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
|
||||
// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
|
||||
//
|
||||
// The methods of XXX_InternalExtensions are not concurrency safe in general,
|
||||
// but calls to logically read-only methods such as has and get may be executed concurrently.
|
||||
type XXX_InternalExtensions struct {
|
||||
// The struct must be indirect so that if a user inadvertently copies a
|
||||
// generated message and its embedded XXX_InternalExtensions, they
|
||||
// avoid the mayhem of a copied mutex.
|
||||
//
|
||||
// The mutex serializes all logically read-only operations to p.extensionMap.
|
||||
// It is up to the client to ensure that write operations to p.extensionMap are
|
||||
// mutually exclusive with other accesses.
|
||||
p *struct {
|
||||
mu sync.Mutex
|
||||
extensionMap map[int32]Extension
|
||||
}
|
||||
}
|
||||
|
||||
// extensionsWrite returns the extension map, creating it on first use.
|
||||
func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
|
||||
if e.p == nil {
|
||||
e.p = new(struct {
|
||||
mu sync.Mutex
|
||||
extensionMap map[int32]Extension
|
||||
})
|
||||
e.p.extensionMap = make(map[int32]Extension)
|
||||
}
|
||||
return e.p.extensionMap
|
||||
}
|
||||
|
||||
// extensionsRead returns the extensions map for read-only use. It may be nil.
|
||||
// The caller must hold the returned mutex's lock when accessing Elements within the map.
|
||||
func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||
if e.p == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return e.p.extensionMap, &e.p.mu
|
||||
}
|
||||
|
||||
// ExtensionDesc represents an extension specification.
|
||||
// Used in generated code from the protocol compiler.
|
||||
type ExtensionDesc struct {
|
||||
ExtendedType Message // nil pointer to the type that is being extended
|
||||
ExtensionType interface{} // nil pointer to the extension type
|
||||
Field int32 // field number
|
||||
Name string // fully-qualified name of extension, for text formatting
|
||||
Tag string // protobuf tag style
|
||||
Filename string // name of the file in which the extension is defined
|
||||
}
|
||||
|
||||
func (ed *ExtensionDesc) repeated() bool {
|
||||
t := reflect.TypeOf(ed.ExtensionType)
|
||||
return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
|
||||
}
|
||||
|
||||
// Extension represents an extension in a message.
|
||||
type Extension struct {
|
||||
// When an extension is stored in a message using SetExtension
|
||||
// only desc and value are set. When the message is marshaled
|
||||
// enc will be set to the encoded form of the message.
|
||||
//
|
||||
// When a message is unmarshaled and contains extensions, each
|
||||
// extension will have only enc set. When such an extension is
|
||||
// accessed using GetExtension (or GetExtensions) desc and value
|
||||
// will be set.
|
||||
desc *ExtensionDesc
|
||||
value interface{}
|
||||
enc []byte
|
||||
}
|
||||
|
||||
// SetRawExtension is for testing only.
|
||||
func SetRawExtension(base Message, id int32, b []byte) {
|
||||
if ebase, ok := base.(extensionsBytes); ok {
|
||||
clearExtension(base, id)
|
||||
ext := ebase.GetExtensions()
|
||||
*ext = append(*ext, b...)
|
||||
return
|
||||
}
|
||||
epb, err := extendable(base)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
extmap := epb.extensionsWrite()
|
||||
extmap[id] = Extension{enc: b}
|
||||
}
|
||||
|
||||
// isExtensionField returns true iff the given field number is in an extension range.
|
||||
func isExtensionField(pb extendableProto, field int32) bool {
|
||||
for _, er := range pb.ExtensionRangeArray() {
|
||||
if er.Start <= field && field <= er.End {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// checkExtensionTypes checks that the given extension is valid for pb.
|
||||
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
|
||||
var pbi interface{} = pb
|
||||
// Check the extended type.
|
||||
if ea, ok := pbi.(extensionAdapter); ok {
|
||||
pbi = ea.extendableProtoV1
|
||||
}
|
||||
if ea, ok := pbi.(slowExtensionAdapter); ok {
|
||||
pbi = ea.extensionsBytes
|
||||
}
|
||||
if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
|
||||
return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a)
|
||||
}
|
||||
// Check the range.
|
||||
if !isExtensionField(pb, extension.Field) {
|
||||
return errors.New("proto: bad extension number; not in declared ranges")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// extPropKey is sufficient to uniquely identify an extension.
|
||||
type extPropKey struct {
|
||||
base reflect.Type
|
||||
field int32
|
||||
}
|
||||
|
||||
var extProp = struct {
|
||||
sync.RWMutex
|
||||
m map[extPropKey]*Properties
|
||||
}{
|
||||
m: make(map[extPropKey]*Properties),
|
||||
}
|
||||
|
||||
func extensionProperties(ed *ExtensionDesc) *Properties {
|
||||
key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
|
||||
|
||||
extProp.RLock()
|
||||
if prop, ok := extProp.m[key]; ok {
|
||||
extProp.RUnlock()
|
||||
return prop
|
||||
}
|
||||
extProp.RUnlock()
|
||||
|
||||
extProp.Lock()
|
||||
defer extProp.Unlock()
|
||||
// Check again.
|
||||
if prop, ok := extProp.m[key]; ok {
|
||||
return prop
|
||||
}
|
||||
|
||||
prop := new(Properties)
|
||||
prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
|
||||
extProp.m[key] = prop
|
||||
return prop
|
||||
}
|
||||
|
||||
// HasExtension returns whether the given extension is present in pb.
|
||||
func HasExtension(pb Message, extension *ExtensionDesc) bool {
|
||||
if epb, doki := pb.(extensionsBytes); doki {
|
||||
ext := epb.GetExtensions()
|
||||
buf := *ext
|
||||
o := 0
|
||||
for o < len(buf) {
|
||||
tag, n := DecodeVarint(buf[o:])
|
||||
fieldNum := int32(tag >> 3)
|
||||
if int32(fieldNum) == extension.Field {
|
||||
return true
|
||||
}
|
||||
wireType := int(tag & 0x7)
|
||||
o += n
|
||||
l, err := size(buf[o:], wireType)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
o += l
|
||||
}
|
||||
return false
|
||||
}
|
||||
// TODO: Check types, field numbers, etc.?
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
extmap, mu := epb.extensionsRead()
|
||||
if extmap == nil {
|
||||
return false
|
||||
}
|
||||
mu.Lock()
|
||||
_, ok := extmap[extension.Field]
|
||||
mu.Unlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
// ClearExtension removes the given extension from pb.
|
||||
func ClearExtension(pb Message, extension *ExtensionDesc) {
|
||||
clearExtension(pb, extension.Field)
|
||||
}
|
||||
|
||||
func clearExtension(pb Message, fieldNum int32) {
|
||||
if epb, ok := pb.(extensionsBytes); ok {
|
||||
offset := 0
|
||||
for offset != -1 {
|
||||
offset = deleteExtension(epb, fieldNum, offset)
|
||||
}
|
||||
return
|
||||
}
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// TODO: Check types, field numbers, etc.?
|
||||
extmap := epb.extensionsWrite()
|
||||
delete(extmap, fieldNum)
|
||||
}
|
||||
|
||||
// GetExtension retrieves a proto2 extended field from pb.
|
||||
//
|
||||
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
|
||||
// then GetExtension parses the encoded field and returns a Go value of the specified type.
|
||||
// If the field is not present, then the default value is returned (if one is specified),
|
||||
// otherwise ErrMissingExtension is reported.
|
||||
//
|
||||
// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),
|
||||
// then GetExtension returns the raw encoded bytes of the field extension.
|
||||
func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
|
||||
if epb, doki := pb.(extensionsBytes); doki {
|
||||
ext := epb.GetExtensions()
|
||||
return decodeExtensionFromBytes(extension, *ext)
|
||||
}
|
||||
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if extension.ExtendedType != nil {
|
||||
// can only check type if this is a complete descriptor
|
||||
if cerr := checkExtensionTypes(epb, extension); cerr != nil {
|
||||
return nil, cerr
|
||||
}
|
||||
}
|
||||
|
||||
emap, mu := epb.extensionsRead()
|
||||
if emap == nil {
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
e, ok := emap[extension.Field]
|
||||
if !ok {
|
||||
// defaultExtensionValue returns the default value or
|
||||
// ErrMissingExtension if there is no default.
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
|
||||
if e.value != nil {
|
||||
// Already decoded. Check the descriptor, though.
|
||||
if e.desc != extension {
|
||||
// This shouldn't happen. If it does, it means that
|
||||
// GetExtension was called twice with two different
|
||||
// descriptors with the same field number.
|
||||
return nil, errors.New("proto: descriptor conflict")
|
||||
}
|
||||
return e.value, nil
|
||||
}
|
||||
|
||||
if extension.ExtensionType == nil {
|
||||
// incomplete descriptor
|
||||
return e.enc, nil
|
||||
}
|
||||
|
||||
v, err := decodeExtension(e.enc, extension)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Remember the decoded version and drop the encoded version.
|
||||
// That way it is safe to mutate what we return.
|
||||
e.value = v
|
||||
e.desc = extension
|
||||
e.enc = nil
|
||||
emap[extension.Field] = e
|
||||
return e.value, nil
|
||||
}
|
||||
|
||||
// defaultExtensionValue returns the default value for extension.
|
||||
// If no default for an extension is defined ErrMissingExtension is returned.
|
||||
func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
|
||||
if extension.ExtensionType == nil {
|
||||
// incomplete descriptor, so no default
|
||||
return nil, ErrMissingExtension
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(extension.ExtensionType)
|
||||
props := extensionProperties(extension)
|
||||
|
||||
sf, _, err := fieldDefault(t, props)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sf == nil || sf.value == nil {
|
||||
// There is no default value.
|
||||
return nil, ErrMissingExtension
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Ptr {
|
||||
// We do not need to return a Ptr, we can directly return sf.value.
|
||||
return sf.value, nil
|
||||
}
|
||||
|
||||
// We need to return an interface{} that is a pointer to sf.value.
|
||||
value := reflect.New(t).Elem()
|
||||
value.Set(reflect.New(value.Type().Elem()))
|
||||
if sf.kind == reflect.Int32 {
|
||||
// We may have an int32 or an enum, but the underlying data is int32.
|
||||
// Since we can't set an int32 into a non int32 reflect.value directly
|
||||
// set it as a int32.
|
||||
value.Elem().SetInt(int64(sf.value.(int32)))
|
||||
} else {
|
||||
value.Elem().Set(reflect.ValueOf(sf.value))
|
||||
}
|
||||
return value.Interface(), nil
|
||||
}
|
||||
|
||||
// decodeExtension decodes an extension encoded in b.
|
||||
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
|
||||
t := reflect.TypeOf(extension.ExtensionType)
|
||||
unmarshal := typeUnmarshaler(t, extension.Tag)
|
||||
|
||||
// t is a pointer to a struct, pointer to basic type or a slice.
|
||||
// Allocate space to store the pointer/slice.
|
||||
value := reflect.New(t).Elem()
|
||||
|
||||
var err error
|
||||
for {
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
wire := int(x) & 7
|
||||
|
||||
b, err = unmarshal(b, valToPointer(value.Addr()), wire)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(b) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return value.Interface(), nil
|
||||
}
|
||||
|
||||
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
|
||||
// The returned slice has the same length as es; missing extensions will appear as nil elements.
|
||||
func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
extensions = make([]interface{}, len(es))
|
||||
for i, e := range es {
|
||||
extensions[i], err = GetExtension(epb, e)
|
||||
if err == ErrMissingExtension {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
|
||||
// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
|
||||
// just the Field field, which defines the extension's field number.
|
||||
func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
registeredExtensions := RegisteredExtensions(pb)
|
||||
|
||||
emap, mu := epb.extensionsRead()
|
||||
if emap == nil {
|
||||
return nil, nil
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
extensions := make([]*ExtensionDesc, 0, len(emap))
|
||||
for extid, e := range emap {
|
||||
desc := e.desc
|
||||
if desc == nil {
|
||||
desc = registeredExtensions[extid]
|
||||
if desc == nil {
|
||||
desc = &ExtensionDesc{Field: extid}
|
||||
}
|
||||
}
|
||||
|
||||
extensions = append(extensions, desc)
|
||||
}
|
||||
return extensions, nil
|
||||
}
|
||||
|
||||
// SetExtension sets the specified extension of pb to the specified value.
|
||||
func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
|
||||
if epb, ok := pb.(extensionsBytes); ok {
|
||||
newb, err := encodeExtension(extension, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bb := epb.GetExtensions()
|
||||
*bb = append(*bb, newb...)
|
||||
return nil
|
||||
}
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkExtensionTypes(epb, extension); err != nil {
|
||||
return err
|
||||
}
|
||||
typ := reflect.TypeOf(extension.ExtensionType)
|
||||
if typ != reflect.TypeOf(value) {
|
||||
return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType)
|
||||
}
|
||||
// nil extension values need to be caught early, because the
|
||||
// encoder can't distinguish an ErrNil due to a nil extension
|
||||
// from an ErrNil due to a missing field. Extensions are
|
||||
// always optional, so the encoder would just swallow the error
|
||||
// and drop all the extensions from the encoded message.
|
||||
if reflect.ValueOf(value).IsNil() {
|
||||
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
|
||||
}
|
||||
|
||||
extmap := epb.extensionsWrite()
|
||||
extmap[extension.Field] = Extension{desc: extension, value: value}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearAllExtensions clears all extensions from pb.
|
||||
func ClearAllExtensions(pb Message) {
|
||||
if epb, doki := pb.(extensionsBytes); doki {
|
||||
ext := epb.GetExtensions()
|
||||
*ext = []byte{}
|
||||
return
|
||||
}
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
m := epb.extensionsWrite()
|
||||
for k := range m {
|
||||
delete(m, k)
|
||||
}
|
||||
}
|
||||
|
||||
// A global registry of extensions.
|
||||
// The generated code will register the generated descriptors by calling RegisterExtension.
|
||||
|
||||
var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
|
||||
|
||||
// RegisterExtension is called from the generated code.
|
||||
func RegisterExtension(desc *ExtensionDesc) {
|
||||
st := reflect.TypeOf(desc.ExtendedType).Elem()
|
||||
m := extensionMaps[st]
|
||||
if m == nil {
|
||||
m = make(map[int32]*ExtensionDesc)
|
||||
extensionMaps[st] = m
|
||||
}
|
||||
if _, ok := m[desc.Field]; ok {
|
||||
panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
|
||||
}
|
||||
m[desc.Field] = desc
|
||||
}
|
||||
|
||||
// RegisteredExtensions returns a map of the registered extensions of a
|
||||
// protocol buffer struct, indexed by the extension number.
|
||||
// The argument pb should be a nil pointer to the struct type.
|
||||
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
|
||||
return extensionMaps[reflect.TypeOf(pb).Elem()]
|
||||
}
|
368
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
generated
vendored
Normal file
368
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,368 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type extensionsBytes interface {
|
||||
Message
|
||||
ExtensionRangeArray() []ExtensionRange
|
||||
GetExtensions() *[]byte
|
||||
}
|
||||
|
||||
type slowExtensionAdapter struct {
|
||||
extensionsBytes
|
||||
}
|
||||
|
||||
func (s slowExtensionAdapter) extensionsWrite() map[int32]Extension {
|
||||
panic("Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.")
|
||||
}
|
||||
|
||||
func (s slowExtensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||
b := s.GetExtensions()
|
||||
m, err := BytesToExtensionsMap(*b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m, notLocker{}
|
||||
}
|
||||
|
||||
func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool {
|
||||
if reflect.ValueOf(pb).IsNil() {
|
||||
return ifnotset
|
||||
}
|
||||
value, err := GetExtension(pb, extension)
|
||||
if err != nil {
|
||||
return ifnotset
|
||||
}
|
||||
if value == nil {
|
||||
return ifnotset
|
||||
}
|
||||
if value.(*bool) == nil {
|
||||
return ifnotset
|
||||
}
|
||||
return *(value.(*bool))
|
||||
}
|
||||
|
||||
func (this *Extension) Equal(that *Extension) bool {
|
||||
if err := this.Encode(); err != nil {
|
||||
return false
|
||||
}
|
||||
if err := that.Encode(); err != nil {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(this.enc, that.enc)
|
||||
}
|
||||
|
||||
func (this *Extension) Compare(that *Extension) int {
|
||||
if err := this.Encode(); err != nil {
|
||||
return 1
|
||||
}
|
||||
if err := that.Encode(); err != nil {
|
||||
return -1
|
||||
}
|
||||
return bytes.Compare(this.enc, that.enc)
|
||||
}
|
||||
|
||||
func SizeOfInternalExtension(m extendableProto) (n int) {
|
||||
info := getMarshalInfo(reflect.TypeOf(m))
|
||||
return info.sizeV1Extensions(m.extensionsWrite())
|
||||
}
|
||||
|
||||
type sortableMapElem struct {
|
||||
field int32
|
||||
ext Extension
|
||||
}
|
||||
|
||||
func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions {
|
||||
s := make(sortableExtensions, 0, len(m))
|
||||
for k, v := range m {
|
||||
s = append(s, &sortableMapElem{field: k, ext: v})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type sortableExtensions []*sortableMapElem
|
||||
|
||||
func (this sortableExtensions) Len() int { return len(this) }
|
||||
|
||||
func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] }
|
||||
|
||||
func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field }
|
||||
|
||||
func (this sortableExtensions) String() string {
|
||||
sort.Sort(this)
|
||||
ss := make([]string, len(this))
|
||||
for i := range this {
|
||||
ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext)
|
||||
}
|
||||
return "map[" + strings.Join(ss, ",") + "]"
|
||||
}
|
||||
|
||||
func StringFromInternalExtension(m extendableProto) string {
|
||||
return StringFromExtensionsMap(m.extensionsWrite())
|
||||
}
|
||||
|
||||
func StringFromExtensionsMap(m map[int32]Extension) string {
|
||||
return newSortableExtensionsFromMap(m).String()
|
||||
}
|
||||
|
||||
func StringFromExtensionsBytes(ext []byte) string {
|
||||
m, err := BytesToExtensionsMap(ext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return StringFromExtensionsMap(m)
|
||||
}
|
||||
|
||||
func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) {
|
||||
return EncodeExtensionMap(m.extensionsWrite(), data)
|
||||
}
|
||||
|
||||
func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
|
||||
o := 0
|
||||
for _, e := range m {
|
||||
if err := e.Encode(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n := copy(data[o:], e.enc)
|
||||
if n != len(e.enc) {
|
||||
return 0, io.ErrShortBuffer
|
||||
}
|
||||
o += n
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {
|
||||
e := m[id]
|
||||
if err := e.Encode(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e.enc, nil
|
||||
}
|
||||
|
||||
func size(buf []byte, wire int) (int, error) {
|
||||
switch wire {
|
||||
case WireVarint:
|
||||
_, n := DecodeVarint(buf)
|
||||
return n, nil
|
||||
case WireFixed64:
|
||||
return 8, nil
|
||||
case WireBytes:
|
||||
v, n := DecodeVarint(buf)
|
||||
return int(v) + n, nil
|
||||
case WireFixed32:
|
||||
return 4, nil
|
||||
case WireStartGroup:
|
||||
offset := 0
|
||||
for {
|
||||
u, n := DecodeVarint(buf[offset:])
|
||||
fwire := int(u & 0x7)
|
||||
offset += n
|
||||
if fwire == WireEndGroup {
|
||||
return offset, nil
|
||||
}
|
||||
s, err := size(buf[offset:], wire)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
offset += s
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire)
|
||||
}
|
||||
|
||||
func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) {
|
||||
m := make(map[int32]Extension)
|
||||
i := 0
|
||||
for i < len(buf) {
|
||||
tag, n := DecodeVarint(buf[i:])
|
||||
if n <= 0 {
|
||||
return nil, fmt.Errorf("unable to decode varint")
|
||||
}
|
||||
fieldNum := int32(tag >> 3)
|
||||
wireType := int(tag & 0x7)
|
||||
l, err := size(buf[i+n:], wireType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
end := i + int(l) + n
|
||||
m[int32(fieldNum)] = Extension{enc: buf[i:end]}
|
||||
i = end
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func NewExtension(e []byte) Extension {
|
||||
ee := Extension{enc: make([]byte, len(e))}
|
||||
copy(ee.enc, e)
|
||||
return ee
|
||||
}
|
||||
|
||||
func AppendExtension(e Message, tag int32, buf []byte) {
|
||||
if ee, eok := e.(extensionsBytes); eok {
|
||||
ext := ee.GetExtensions()
|
||||
*ext = append(*ext, buf...)
|
||||
return
|
||||
}
|
||||
if ee, eok := e.(extendableProto); eok {
|
||||
m := ee.extensionsWrite()
|
||||
ext := m[int32(tag)] // may be missing
|
||||
ext.enc = append(ext.enc, buf...)
|
||||
m[int32(tag)] = ext
|
||||
}
|
||||
}
|
||||
|
||||
func encodeExtension(extension *ExtensionDesc, value interface{}) ([]byte, error) {
|
||||
u := getMarshalInfo(reflect.TypeOf(extension.ExtendedType))
|
||||
ei := u.getExtElemInfo(extension)
|
||||
v := value
|
||||
p := toAddrPointer(&v, ei.isptr)
|
||||
siz := ei.sizer(p, SizeVarint(ei.wiretag))
|
||||
buf := make([]byte, 0, siz)
|
||||
return ei.marshaler(buf, p, ei.wiretag, false)
|
||||
}
|
||||
|
||||
func decodeExtensionFromBytes(extension *ExtensionDesc, buf []byte) (interface{}, error) {
|
||||
o := 0
|
||||
for o < len(buf) {
|
||||
tag, n := DecodeVarint((buf)[o:])
|
||||
fieldNum := int32(tag >> 3)
|
||||
wireType := int(tag & 0x7)
|
||||
if o+n > len(buf) {
|
||||
return nil, fmt.Errorf("unable to decode extension")
|
||||
}
|
||||
l, err := size((buf)[o+n:], wireType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if int32(fieldNum) == extension.Field {
|
||||
if o+n+l > len(buf) {
|
||||
return nil, fmt.Errorf("unable to decode extension")
|
||||
}
|
||||
v, err := decodeExtension((buf)[o:o+n+l], extension)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
o += n + l
|
||||
}
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
|
||||
func (this *Extension) Encode() error {
|
||||
if this.enc == nil {
|
||||
var err error
|
||||
this.enc, err = encodeExtension(this.desc, this.value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this Extension) GoString() string {
|
||||
if err := this.Encode(); err != nil {
|
||||
return fmt.Sprintf("error encoding extension: %v", err)
|
||||
}
|
||||
return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
|
||||
}
|
||||
|
||||
func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error {
|
||||
typ := reflect.TypeOf(pb).Elem()
|
||||
ext, ok := extensionMaps[typ]
|
||||
if !ok {
|
||||
return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String())
|
||||
}
|
||||
desc, ok := ext[fieldNum]
|
||||
if !ok {
|
||||
return errors.New("proto: bad extension number; not in declared ranges")
|
||||
}
|
||||
return SetExtension(pb, desc, value)
|
||||
}
|
||||
|
||||
func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) {
|
||||
typ := reflect.TypeOf(pb).Elem()
|
||||
ext, ok := extensionMaps[typ]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String())
|
||||
}
|
||||
desc, ok := ext[fieldNum]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unregistered field number %d", fieldNum)
|
||||
}
|
||||
return GetExtension(pb, desc)
|
||||
}
|
||||
|
||||
func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions {
|
||||
x := &XXX_InternalExtensions{
|
||||
p: new(struct {
|
||||
mu sync.Mutex
|
||||
extensionMap map[int32]Extension
|
||||
}),
|
||||
}
|
||||
x.p.extensionMap = m
|
||||
return *x
|
||||
}
|
||||
|
||||
func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension {
|
||||
pb := extendable.(extendableProto)
|
||||
return pb.extensionsWrite()
|
||||
}
|
||||
|
||||
func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
|
||||
ext := pb.GetExtensions()
|
||||
for offset < len(*ext) {
|
||||
tag, n1 := DecodeVarint((*ext)[offset:])
|
||||
fieldNum := int32(tag >> 3)
|
||||
wireType := int(tag & 0x7)
|
||||
n2, err := size((*ext)[offset+n1:], wireType)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
newOffset := offset + n1 + n2
|
||||
if fieldNum == theFieldNum {
|
||||
*ext = append((*ext)[:offset], (*ext)[newOffset:]...)
|
||||
return offset
|
||||
}
|
||||
offset = newOffset
|
||||
}
|
||||
return -1
|
||||
}
|
967
vendor/github.com/gogo/protobuf/proto/lib.go
generated
vendored
Normal file
967
vendor/github.com/gogo/protobuf/proto/lib.go
generated
vendored
Normal file
|
@ -0,0 +1,967 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/*
|
||||
Package proto converts data structures to and from the wire format of
|
||||
protocol buffers. It works in concert with the Go source code generated
|
||||
for .proto files by the protocol compiler.
|
||||
|
||||
A summary of the properties of the protocol buffer interface
|
||||
for a protocol buffer variable v:
|
||||
|
||||
- Names are turned from camel_case to CamelCase for export.
|
||||
- There are no methods on v to set fields; just treat
|
||||
them as structure fields.
|
||||
- There are getters that return a field's value if set,
|
||||
and return the field's default value if unset.
|
||||
The getters work even if the receiver is a nil message.
|
||||
- The zero value for a struct is its correct initialization state.
|
||||
All desired fields must be set before marshaling.
|
||||
- A Reset() method will restore a protobuf struct to its zero state.
|
||||
- Non-repeated fields are pointers to the values; nil means unset.
|
||||
That is, optional or required field int32 f becomes F *int32.
|
||||
- Repeated fields are slices.
|
||||
- Helper functions are available to aid the setting of fields.
|
||||
msg.Foo = proto.String("hello") // set field
|
||||
- Constants are defined to hold the default values of all fields that
|
||||
have them. They have the form Default_StructName_FieldName.
|
||||
Because the getter methods handle defaulted values,
|
||||
direct use of these constants should be rare.
|
||||
- Enums are given type names and maps from names to values.
|
||||
Enum values are prefixed by the enclosing message's name, or by the
|
||||
enum's type name if it is a top-level enum. Enum types have a String
|
||||
method, and a Enum method to assist in message construction.
|
||||
- Nested messages, groups and enums have type names prefixed with the name of
|
||||
the surrounding message type.
|
||||
- Extensions are given descriptor names that start with E_,
|
||||
followed by an underscore-delimited list of the nested messages
|
||||
that contain it (if any) followed by the CamelCased name of the
|
||||
extension field itself. HasExtension, ClearExtension, GetExtension
|
||||
and SetExtension are functions for manipulating extensions.
|
||||
- Oneof field sets are given a single field in their message,
|
||||
with distinguished wrapper types for each possible field value.
|
||||
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
||||
|
||||
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
||||
|
||||
- Non-repeated fields of non-message type are values instead of pointers.
|
||||
- Enum types do not get an Enum method.
|
||||
|
||||
The simplest way to describe this is to see an example.
|
||||
Given file test.proto, containing
|
||||
|
||||
package example;
|
||||
|
||||
enum FOO { X = 17; }
|
||||
|
||||
message Test {
|
||||
required string label = 1;
|
||||
optional int32 type = 2 [default=77];
|
||||
repeated int64 reps = 3;
|
||||
optional group OptionalGroup = 4 {
|
||||
required string RequiredField = 5;
|
||||
}
|
||||
oneof union {
|
||||
int32 number = 6;
|
||||
string name = 7;
|
||||
}
|
||||
}
|
||||
|
||||
The resulting file, test.pb.go, is:
|
||||
|
||||
package example
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
type FOO int32
|
||||
const (
|
||||
FOO_X FOO = 17
|
||||
)
|
||||
var FOO_name = map[int32]string{
|
||||
17: "X",
|
||||
}
|
||||
var FOO_value = map[string]int32{
|
||||
"X": 17,
|
||||
}
|
||||
|
||||
func (x FOO) Enum() *FOO {
|
||||
p := new(FOO)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x FOO) String() string {
|
||||
return proto.EnumName(FOO_name, int32(x))
|
||||
}
|
||||
func (x *FOO) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(FOO_value, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = FOO(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
|
||||
Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
|
||||
Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
|
||||
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
||||
// Types that are valid to be assigned to Union:
|
||||
// *Test_Number
|
||||
// *Test_Name
|
||||
Union isTest_Union `protobuf_oneof:"union"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
func (m *Test) Reset() { *m = Test{} }
|
||||
func (m *Test) String() string { return proto.CompactTextString(m) }
|
||||
func (*Test) ProtoMessage() {}
|
||||
|
||||
type isTest_Union interface {
|
||||
isTest_Union()
|
||||
}
|
||||
|
||||
type Test_Number struct {
|
||||
Number int32 `protobuf:"varint,6,opt,name=number"`
|
||||
}
|
||||
type Test_Name struct {
|
||||
Name string `protobuf:"bytes,7,opt,name=name"`
|
||||
}
|
||||
|
||||
func (*Test_Number) isTest_Union() {}
|
||||
func (*Test_Name) isTest_Union() {}
|
||||
|
||||
func (m *Test) GetUnion() isTest_Union {
|
||||
if m != nil {
|
||||
return m.Union
|
||||
}
|
||||
return nil
|
||||
}
|
||||
const Default_Test_Type int32 = 77
|
||||
|
||||
func (m *Test) GetLabel() string {
|
||||
if m != nil && m.Label != nil {
|
||||
return *m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Test) GetType() int32 {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Default_Test_Type
|
||||
}
|
||||
|
||||
func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
|
||||
if m != nil {
|
||||
return m.Optionalgroup
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Test_OptionalGroup struct {
|
||||
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
|
||||
}
|
||||
func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
|
||||
func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
|
||||
|
||||
func (m *Test_OptionalGroup) GetRequiredField() string {
|
||||
if m != nil && m.RequiredField != nil {
|
||||
return *m.RequiredField
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Test) GetNumber() int32 {
|
||||
if x, ok := m.GetUnion().(*Test_Number); ok {
|
||||
return x.Number
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Test) GetName() string {
|
||||
if x, ok := m.GetUnion().(*Test_Name); ok {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
|
||||
}
|
||||
|
||||
To create and play with a Test object:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
pb "./example.pb"
|
||||
)
|
||||
|
||||
func main() {
|
||||
test := &pb.Test{
|
||||
Label: proto.String("hello"),
|
||||
Type: proto.Int32(17),
|
||||
Reps: []int64{1, 2, 3},
|
||||
Optionalgroup: &pb.Test_OptionalGroup{
|
||||
RequiredField: proto.String("good bye"),
|
||||
},
|
||||
Union: &pb.Test_Name{"fred"},
|
||||
}
|
||||
data, err := proto.Marshal(test)
|
||||
if err != nil {
|
||||
log.Fatal("marshaling error: ", err)
|
||||
}
|
||||
newTest := &pb.Test{}
|
||||
err = proto.Unmarshal(data, newTest)
|
||||
if err != nil {
|
||||
log.Fatal("unmarshaling error: ", err)
|
||||
}
|
||||
// Now test and newTest contain the same data.
|
||||
if test.GetLabel() != newTest.GetLabel() {
|
||||
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
|
||||
}
|
||||
// Use a type switch to determine which oneof was set.
|
||||
switch u := test.Union.(type) {
|
||||
case *pb.Test_Number: // u.Number contains the number.
|
||||
case *pb.Test_Name: // u.Name contains the string.
|
||||
}
|
||||
// etc.
|
||||
}
|
||||
*/
|
||||
package proto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
|
||||
// Marshal reports this when a required field is not initialized.
|
||||
// Unmarshal reports this when a required field is missing from the wire data.
|
||||
type RequiredNotSetError struct{ field string }
|
||||
|
||||
func (e *RequiredNotSetError) Error() string {
|
||||
if e.field == "" {
|
||||
return fmt.Sprintf("proto: required field not set")
|
||||
}
|
||||
return fmt.Sprintf("proto: required field %q not set", e.field)
|
||||
}
|
||||
func (e *RequiredNotSetError) RequiredNotSet() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type invalidUTF8Error struct{ field string }
|
||||
|
||||
func (e *invalidUTF8Error) Error() string {
|
||||
if e.field == "" {
|
||||
return "proto: invalid UTF-8 detected"
|
||||
}
|
||||
return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
|
||||
}
|
||||
func (e *invalidUTF8Error) InvalidUTF8() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
|
||||
// This error should not be exposed to the external API as such errors should
|
||||
// be recreated with the field information.
|
||||
var errInvalidUTF8 = &invalidUTF8Error{}
|
||||
|
||||
// isNonFatal reports whether the error is either a RequiredNotSet error
|
||||
// or a InvalidUTF8 error.
|
||||
func isNonFatal(err error) bool {
|
||||
if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
|
||||
return true
|
||||
}
|
||||
if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type nonFatal struct{ E error }
|
||||
|
||||
// Merge merges err into nf and reports whether it was successful.
|
||||
// Otherwise it returns false for any fatal non-nil errors.
|
||||
func (nf *nonFatal) Merge(err error) (ok bool) {
|
||||
if err == nil {
|
||||
return true // not an error
|
||||
}
|
||||
if !isNonFatal(err) {
|
||||
return false // fatal error
|
||||
}
|
||||
if nf.E == nil {
|
||||
nf.E = err // store first instance of non-fatal error
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Message is implemented by generated protocol buffer messages.
|
||||
type Message interface {
|
||||
Reset()
|
||||
String() string
|
||||
ProtoMessage()
|
||||
}
|
||||
|
||||
// A Buffer is a buffer manager for marshaling and unmarshaling
|
||||
// protocol buffers. It may be reused between invocations to
|
||||
// reduce memory usage. It is not necessary to use a Buffer;
|
||||
// the global functions Marshal and Unmarshal create a
|
||||
// temporary Buffer and are fine for most applications.
|
||||
type Buffer struct {
|
||||
buf []byte // encode/decode byte stream
|
||||
index int // read point
|
||||
|
||||
deterministic bool
|
||||
}
|
||||
|
||||
// NewBuffer allocates a new Buffer and initializes its internal data to
|
||||
// the contents of the argument slice.
|
||||
func NewBuffer(e []byte) *Buffer {
|
||||
return &Buffer{buf: e}
|
||||
}
|
||||
|
||||
// Reset resets the Buffer, ready for marshaling a new protocol buffer.
|
||||
func (p *Buffer) Reset() {
|
||||
p.buf = p.buf[0:0] // for reading/writing
|
||||
p.index = 0 // for reading
|
||||
}
|
||||
|
||||
// SetBuf replaces the internal buffer with the slice,
|
||||
// ready for unmarshaling the contents of the slice.
|
||||
func (p *Buffer) SetBuf(s []byte) {
|
||||
p.buf = s
|
||||
p.index = 0
|
||||
}
|
||||
|
||||
// Bytes returns the contents of the Buffer.
|
||||
func (p *Buffer) Bytes() []byte { return p.buf }
|
||||
|
||||
// SetDeterministic sets whether to use deterministic serialization.
|
||||
//
|
||||
// Deterministic serialization guarantees that for a given binary, equal
|
||||
// messages will always be serialized to the same bytes. This implies:
|
||||
//
|
||||
// - Repeated serialization of a message will return the same bytes.
|
||||
// - Different processes of the same binary (which may be executing on
|
||||
// different machines) will serialize equal messages to the same bytes.
|
||||
//
|
||||
// Note that the deterministic serialization is NOT canonical across
|
||||
// languages. It is not guaranteed to remain stable over time. It is unstable
|
||||
// across different builds with schema changes due to unknown fields.
|
||||
// Users who need canonical serialization (e.g., persistent storage in a
|
||||
// canonical form, fingerprinting, etc.) should define their own
|
||||
// canonicalization specification and implement their own serializer rather
|
||||
// than relying on this API.
|
||||
//
|
||||
// If deterministic serialization is requested, map entries will be sorted
|
||||
// by keys in lexographical order. This is an implementation detail and
|
||||
// subject to change.
|
||||
func (p *Buffer) SetDeterministic(deterministic bool) {
|
||||
p.deterministic = deterministic
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper routines for simplifying the creation of optional fields of basic type.
|
||||
*/
|
||||
|
||||
// Bool is a helper routine that allocates a new bool value
|
||||
// to store v and returns a pointer to it.
|
||||
func Bool(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int32 is a helper routine that allocates a new int32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Int32(v int32) *int32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int is a helper routine that allocates a new int32 value
|
||||
// to store v and returns a pointer to it, but unlike Int32
|
||||
// its argument value is an int.
|
||||
func Int(v int) *int32 {
|
||||
p := new(int32)
|
||||
*p = int32(v)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int64 is a helper routine that allocates a new int64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Int64(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float32 is a helper routine that allocates a new float32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Float32(v float32) *float32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float64 is a helper routine that allocates a new float64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Float64(v float64) *float64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint32 is a helper routine that allocates a new uint32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Uint32(v uint32) *uint32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint64 is a helper routine that allocates a new uint64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Uint64(v uint64) *uint64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// String is a helper routine that allocates a new string value
|
||||
// to store v and returns a pointer to it.
|
||||
func String(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// EnumName is a helper function to simplify printing protocol buffer enums
|
||||
// by name. Given an enum map and a value, it returns a useful string.
|
||||
func EnumName(m map[int32]string, v int32) string {
|
||||
s, ok := m[v]
|
||||
if ok {
|
||||
return s
|
||||
}
|
||||
return strconv.Itoa(int(v))
|
||||
}
|
||||
|
||||
// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
|
||||
// from their JSON-encoded representation. Given a map from the enum's symbolic
|
||||
// names to its int values, and a byte buffer containing the JSON-encoded
|
||||
// value, it returns an int32 that can be cast to the enum type by the caller.
|
||||
//
|
||||
// The function can deal with both JSON representations, numeric and symbolic.
|
||||
func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
|
||||
if data[0] == '"' {
|
||||
// New style: enums are strings.
|
||||
var repr string
|
||||
if err := json.Unmarshal(data, &repr); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
val, ok := m[repr]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
// Old style: enums are ints.
|
||||
var val int32
|
||||
if err := json.Unmarshal(data, &val); err != nil {
|
||||
return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// DebugPrint dumps the encoded data in b in a debugging format with a header
|
||||
// including the string s. Used in testing but made available for general debugging.
|
||||
func (p *Buffer) DebugPrint(s string, b []byte) {
|
||||
var u uint64
|
||||
|
||||
obuf := p.buf
|
||||
sindex := p.index
|
||||
p.buf = b
|
||||
p.index = 0
|
||||
depth := 0
|
||||
|
||||
fmt.Printf("\n--- %s ---\n", s)
|
||||
|
||||
out:
|
||||
for {
|
||||
for i := 0; i < depth; i++ {
|
||||
fmt.Print(" ")
|
||||
}
|
||||
|
||||
index := p.index
|
||||
if index == len(p.buf) {
|
||||
break
|
||||
}
|
||||
|
||||
op, err := p.DecodeVarint()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: fetching op err %v\n", index, err)
|
||||
break out
|
||||
}
|
||||
tag := op >> 3
|
||||
wire := op & 7
|
||||
|
||||
switch wire {
|
||||
default:
|
||||
fmt.Printf("%3d: t=%3d unknown wire=%d\n",
|
||||
index, tag, wire)
|
||||
break out
|
||||
|
||||
case WireBytes:
|
||||
var r []byte
|
||||
|
||||
r, err = p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
|
||||
if len(r) <= 6 {
|
||||
for i := 0; i < len(r); i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < 3; i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
fmt.Printf(" ..")
|
||||
for i := len(r) - 3; i < len(r); i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
|
||||
case WireFixed32:
|
||||
u, err = p.DecodeFixed32()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
|
||||
|
||||
case WireFixed64:
|
||||
u, err = p.DecodeFixed64()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
|
||||
|
||||
case WireVarint:
|
||||
u, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
|
||||
|
||||
case WireStartGroup:
|
||||
fmt.Printf("%3d: t=%3d start\n", index, tag)
|
||||
depth++
|
||||
|
||||
case WireEndGroup:
|
||||
depth--
|
||||
fmt.Printf("%3d: t=%3d end\n", index, tag)
|
||||
}
|
||||
}
|
||||
|
||||
if depth != 0 {
|
||||
fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
|
||||
p.buf = obuf
|
||||
p.index = sindex
|
||||
}
|
||||
|
||||
// SetDefaults sets unset protocol buffer fields to their default values.
|
||||
// It only modifies fields that are both unset and have defined defaults.
|
||||
// It recursively sets default values in any non-nil sub-messages.
|
||||
func SetDefaults(pb Message) {
|
||||
setDefaults(reflect.ValueOf(pb), true, false)
|
||||
}
|
||||
|
||||
// v is a struct.
|
||||
func setDefaults(v reflect.Value, recur, zeros bool) {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
defaultMu.RLock()
|
||||
dm, ok := defaults[v.Type()]
|
||||
defaultMu.RUnlock()
|
||||
if !ok {
|
||||
dm = buildDefaultMessage(v.Type())
|
||||
defaultMu.Lock()
|
||||
defaults[v.Type()] = dm
|
||||
defaultMu.Unlock()
|
||||
}
|
||||
|
||||
for _, sf := range dm.scalars {
|
||||
f := v.Field(sf.index)
|
||||
if !f.IsNil() {
|
||||
// field already set
|
||||
continue
|
||||
}
|
||||
dv := sf.value
|
||||
if dv == nil && !zeros {
|
||||
// no explicit default, and don't want to set zeros
|
||||
continue
|
||||
}
|
||||
fptr := f.Addr().Interface() // **T
|
||||
// TODO: Consider batching the allocations we do here.
|
||||
switch sf.kind {
|
||||
case reflect.Bool:
|
||||
b := new(bool)
|
||||
if dv != nil {
|
||||
*b = dv.(bool)
|
||||
}
|
||||
*(fptr.(**bool)) = b
|
||||
case reflect.Float32:
|
||||
f := new(float32)
|
||||
if dv != nil {
|
||||
*f = dv.(float32)
|
||||
}
|
||||
*(fptr.(**float32)) = f
|
||||
case reflect.Float64:
|
||||
f := new(float64)
|
||||
if dv != nil {
|
||||
*f = dv.(float64)
|
||||
}
|
||||
*(fptr.(**float64)) = f
|
||||
case reflect.Int32:
|
||||
// might be an enum
|
||||
if ft := f.Type(); ft != int32PtrType {
|
||||
// enum
|
||||
f.Set(reflect.New(ft.Elem()))
|
||||
if dv != nil {
|
||||
f.Elem().SetInt(int64(dv.(int32)))
|
||||
}
|
||||
} else {
|
||||
// int32 field
|
||||
i := new(int32)
|
||||
if dv != nil {
|
||||
*i = dv.(int32)
|
||||
}
|
||||
*(fptr.(**int32)) = i
|
||||
}
|
||||
case reflect.Int64:
|
||||
i := new(int64)
|
||||
if dv != nil {
|
||||
*i = dv.(int64)
|
||||
}
|
||||
*(fptr.(**int64)) = i
|
||||
case reflect.String:
|
||||
s := new(string)
|
||||
if dv != nil {
|
||||
*s = dv.(string)
|
||||
}
|
||||
*(fptr.(**string)) = s
|
||||
case reflect.Uint8:
|
||||
// exceptional case: []byte
|
||||
var b []byte
|
||||
if dv != nil {
|
||||
db := dv.([]byte)
|
||||
b = make([]byte, len(db))
|
||||
copy(b, db)
|
||||
} else {
|
||||
b = []byte{}
|
||||
}
|
||||
*(fptr.(*[]byte)) = b
|
||||
case reflect.Uint32:
|
||||
u := new(uint32)
|
||||
if dv != nil {
|
||||
*u = dv.(uint32)
|
||||
}
|
||||
*(fptr.(**uint32)) = u
|
||||
case reflect.Uint64:
|
||||
u := new(uint64)
|
||||
if dv != nil {
|
||||
*u = dv.(uint64)
|
||||
}
|
||||
*(fptr.(**uint64)) = u
|
||||
default:
|
||||
log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
|
||||
}
|
||||
}
|
||||
|
||||
for _, ni := range dm.nested {
|
||||
f := v.Field(ni)
|
||||
// f is *T or T or []*T or []T
|
||||
switch f.Kind() {
|
||||
case reflect.Struct:
|
||||
setDefaults(f, recur, zeros)
|
||||
|
||||
case reflect.Ptr:
|
||||
if f.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(f, recur, zeros)
|
||||
|
||||
case reflect.Slice:
|
||||
for i := 0; i < f.Len(); i++ {
|
||||
e := f.Index(i)
|
||||
if e.Kind() == reflect.Ptr && e.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(e, recur, zeros)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, k := range f.MapKeys() {
|
||||
e := f.MapIndex(k)
|
||||
if e.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(e, recur, zeros)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// defaults maps a protocol buffer struct type to a slice of the fields,
|
||||
// with its scalar fields set to their proto-declared non-zero default values.
|
||||
defaultMu sync.RWMutex
|
||||
defaults = make(map[reflect.Type]defaultMessage)
|
||||
|
||||
int32PtrType = reflect.TypeOf((*int32)(nil))
|
||||
)
|
||||
|
||||
// defaultMessage represents information about the default values of a message.
|
||||
type defaultMessage struct {
|
||||
scalars []scalarField
|
||||
nested []int // struct field index of nested messages
|
||||
}
|
||||
|
||||
type scalarField struct {
|
||||
index int // struct field index
|
||||
kind reflect.Kind // element type (the T in *T or []T)
|
||||
value interface{} // the proto-declared default value, or nil
|
||||
}
|
||||
|
||||
// t is a struct type.
|
||||
func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||
sprop := GetProperties(t)
|
||||
for _, prop := range sprop.Prop {
|
||||
fi, ok := sprop.decoderTags.get(prop.Tag)
|
||||
if !ok {
|
||||
// XXX_unrecognized
|
||||
continue
|
||||
}
|
||||
ft := t.Field(fi).Type
|
||||
|
||||
sf, nested, err := fieldDefault(ft, prop)
|
||||
switch {
|
||||
case err != nil:
|
||||
log.Print(err)
|
||||
case nested:
|
||||
dm.nested = append(dm.nested, fi)
|
||||
case sf != nil:
|
||||
sf.index = fi
|
||||
dm.scalars = append(dm.scalars, *sf)
|
||||
}
|
||||
}
|
||||
|
||||
return dm
|
||||
}
|
||||
|
||||
// fieldDefault returns the scalarField for field type ft.
|
||||
// sf will be nil if the field can not have a default.
|
||||
// nestedMessage will be true if this is a nested message.
|
||||
// Note that sf.index is not set on return.
|
||||
func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
|
||||
var canHaveDefault bool
|
||||
switch ft.Kind() {
|
||||
case reflect.Struct:
|
||||
nestedMessage = true // non-nullable
|
||||
|
||||
case reflect.Ptr:
|
||||
if ft.Elem().Kind() == reflect.Struct {
|
||||
nestedMessage = true
|
||||
} else {
|
||||
canHaveDefault = true // proto2 scalar field
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
switch ft.Elem().Kind() {
|
||||
case reflect.Ptr, reflect.Struct:
|
||||
nestedMessage = true // repeated message
|
||||
case reflect.Uint8:
|
||||
canHaveDefault = true // bytes field
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
if ft.Elem().Kind() == reflect.Ptr {
|
||||
nestedMessage = true // map with message values
|
||||
}
|
||||
}
|
||||
|
||||
if !canHaveDefault {
|
||||
if nestedMessage {
|
||||
return nil, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// We now know that ft is a pointer or slice.
|
||||
sf = &scalarField{kind: ft.Elem().Kind()}
|
||||
|
||||
// scalar fields without defaults
|
||||
if !prop.HasDefault {
|
||||
return sf, false, nil
|
||||
}
|
||||
|
||||
// a scalar field: either *T or []byte
|
||||
switch ft.Elem().Kind() {
|
||||
case reflect.Bool:
|
||||
x, err := strconv.ParseBool(prop.Default)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.Float32:
|
||||
x, err := strconv.ParseFloat(prop.Default, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = float32(x)
|
||||
case reflect.Float64:
|
||||
x, err := strconv.ParseFloat(prop.Default, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.Int32:
|
||||
x, err := strconv.ParseInt(prop.Default, 10, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = int32(x)
|
||||
case reflect.Int64:
|
||||
x, err := strconv.ParseInt(prop.Default, 10, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.String:
|
||||
sf.value = prop.Default
|
||||
case reflect.Uint8:
|
||||
// []byte (not *uint8)
|
||||
sf.value = []byte(prop.Default)
|
||||
case reflect.Uint32:
|
||||
x, err := strconv.ParseUint(prop.Default, 10, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = uint32(x)
|
||||
case reflect.Uint64:
|
||||
x, err := strconv.ParseUint(prop.Default, 10, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
default:
|
||||
return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
|
||||
}
|
||||
|
||||
return sf, false, nil
|
||||
}
|
||||
|
||||
// mapKeys returns a sort.Interface to be used for sorting the map keys.
|
||||
// Map fields may have key types of non-float scalars, strings and enums.
|
||||
func mapKeys(vs []reflect.Value) sort.Interface {
|
||||
s := mapKeySorter{vs: vs}
|
||||
|
||||
// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
|
||||
if len(vs) == 0 {
|
||||
return s
|
||||
}
|
||||
switch vs[0].Kind() {
|
||||
case reflect.Int32, reflect.Int64:
|
||||
s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
|
||||
case reflect.Bool:
|
||||
s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true
|
||||
case reflect.String:
|
||||
s.less = func(a, b reflect.Value) bool { return a.String() < b.String() }
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind()))
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
type mapKeySorter struct {
|
||||
vs []reflect.Value
|
||||
less func(a, b reflect.Value) bool
|
||||
}
|
||||
|
||||
func (s mapKeySorter) Len() int { return len(s.vs) }
|
||||
func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
|
||||
func (s mapKeySorter) Less(i, j int) bool {
|
||||
return s.less(s.vs[i], s.vs[j])
|
||||
}
|
||||
|
||||
// isProto3Zero reports whether v is a zero proto3 value.
|
||||
func isProto3Zero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.String:
|
||||
return v.String() == ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
|
||||
// to assert that that code is compatible with this version of the proto package.
|
||||
const GoGoProtoPackageIsVersion2 = true
|
||||
|
||||
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
||||
// to assert that that code is compatible with this version of the proto package.
|
||||
const GoGoProtoPackageIsVersion1 = true
|
||||
|
||||
// InternalMessageInfo is a type used internally by generated .pb.go files.
|
||||
// This type is not intended to be used by non-generated code.
|
||||
// This type is not subject to any compatibility guarantee.
|
||||
type InternalMessageInfo struct {
|
||||
marshal *marshalInfo
|
||||
unmarshal *unmarshalInfo
|
||||
merge *mergeInfo
|
||||
discard *discardInfo
|
||||
}
|
50
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
generated
vendored
Normal file
50
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Sizer interface {
|
||||
Size() int
|
||||
}
|
||||
|
||||
type ProtoSizer interface {
|
||||
ProtoSize() int
|
||||
}
|
||||
|
||||
func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) {
|
||||
s, ok := m[value]
|
||||
if !ok {
|
||||
s = strconv.Itoa(int(value))
|
||||
}
|
||||
return json.Marshal(s)
|
||||
}
|
181
vendor/github.com/gogo/protobuf/proto/message_set.go
generated
vendored
Normal file
181
vendor/github.com/gogo/protobuf/proto/message_set.go
generated
vendored
Normal file
|
@ -0,0 +1,181 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Support for message sets.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
||||
// A message type ID is required for storing a protocol buffer in a message set.
|
||||
var errNoMessageTypeID = errors.New("proto does not have a message type ID")
|
||||
|
||||
// The first two types (_MessageSet_Item and messageSet)
|
||||
// model what the protocol compiler produces for the following protocol message:
|
||||
// message MessageSet {
|
||||
// repeated group Item = 1 {
|
||||
// required int32 type_id = 2;
|
||||
// required string message = 3;
|
||||
// };
|
||||
// }
|
||||
// That is the MessageSet wire format. We can't use a proto to generate these
|
||||
// because that would introduce a circular dependency between it and this package.
|
||||
|
||||
type _MessageSet_Item struct {
|
||||
TypeId *int32 `protobuf:"varint,2,req,name=type_id"`
|
||||
Message []byte `protobuf:"bytes,3,req,name=message"`
|
||||
}
|
||||
|
||||
type messageSet struct {
|
||||
Item []*_MessageSet_Item `protobuf:"group,1,rep"`
|
||||
XXX_unrecognized []byte
|
||||
// TODO: caching?
|
||||
}
|
||||
|
||||
// Make sure messageSet is a Message.
|
||||
var _ Message = (*messageSet)(nil)
|
||||
|
||||
// messageTypeIder is an interface satisfied by a protocol buffer type
|
||||
// that may be stored in a MessageSet.
|
||||
type messageTypeIder interface {
|
||||
MessageTypeId() int32
|
||||
}
|
||||
|
||||
func (ms *messageSet) find(pb Message) *_MessageSet_Item {
|
||||
mti, ok := pb.(messageTypeIder)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
id := mti.MessageTypeId()
|
||||
for _, item := range ms.Item {
|
||||
if *item.TypeId == id {
|
||||
return item
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms *messageSet) Has(pb Message) bool {
|
||||
return ms.find(pb) != nil
|
||||
}
|
||||
|
||||
func (ms *messageSet) Unmarshal(pb Message) error {
|
||||
if item := ms.find(pb); item != nil {
|
||||
return Unmarshal(item.Message, pb)
|
||||
}
|
||||
if _, ok := pb.(messageTypeIder); !ok {
|
||||
return errNoMessageTypeID
|
||||
}
|
||||
return nil // TODO: return error instead?
|
||||
}
|
||||
|
||||
func (ms *messageSet) Marshal(pb Message) error {
|
||||
msg, err := Marshal(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if item := ms.find(pb); item != nil {
|
||||
// reuse existing item
|
||||
item.Message = msg
|
||||
return nil
|
||||
}
|
||||
|
||||
mti, ok := pb.(messageTypeIder)
|
||||
if !ok {
|
||||
return errNoMessageTypeID
|
||||
}
|
||||
|
||||
mtid := mti.MessageTypeId()
|
||||
ms.Item = append(ms.Item, &_MessageSet_Item{
|
||||
TypeId: &mtid,
|
||||
Message: msg,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms *messageSet) Reset() { *ms = messageSet{} }
|
||||
func (ms *messageSet) String() string { return CompactTextString(ms) }
|
||||
func (*messageSet) ProtoMessage() {}
|
||||
|
||||
// Support for the message_set_wire_format message option.
|
||||
|
||||
func skipVarint(buf []byte) []byte {
|
||||
i := 0
|
||||
for ; buf[i]&0x80 != 0; i++ {
|
||||
}
|
||||
return buf[i+1:]
|
||||
}
|
||||
|
||||
// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
||||
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||
func unmarshalMessageSet(buf []byte, exts interface{}) error {
|
||||
var m map[int32]Extension
|
||||
switch exts := exts.(type) {
|
||||
case *XXX_InternalExtensions:
|
||||
m = exts.extensionsWrite()
|
||||
case map[int32]Extension:
|
||||
m = exts
|
||||
default:
|
||||
return errors.New("proto: not an extension map")
|
||||
}
|
||||
|
||||
ms := new(messageSet)
|
||||
if err := Unmarshal(buf, ms); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range ms.Item {
|
||||
id := *item.TypeId
|
||||
msg := item.Message
|
||||
|
||||
// Restore wire type and field number varint, plus length varint.
|
||||
// Be careful to preserve duplicate items.
|
||||
b := EncodeVarint(uint64(id)<<3 | WireBytes)
|
||||
if ext, ok := m[id]; ok {
|
||||
// Existing data; rip off the tag and length varint
|
||||
// so we join the new data correctly.
|
||||
// We can assume that ext.enc is set because we are unmarshaling.
|
||||
o := ext.enc[len(b):] // skip wire type and field number
|
||||
_, n := DecodeVarint(o) // calculate length of length varint
|
||||
o = o[n:] // skip length varint
|
||||
msg = append(o, msg...) // join old data and new data
|
||||
}
|
||||
b = append(b, EncodeVarint(uint64(len(msg)))...)
|
||||
b = append(b, msg...)
|
||||
|
||||
m[id] = Extension{enc: b}
|
||||
}
|
||||
return nil
|
||||
}
|
357
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
generated
vendored
Normal file
357
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
generated
vendored
Normal file
|
@ -0,0 +1,357 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build purego appengine js
|
||||
|
||||
// This file contains an implementation of proto field accesses using package reflect.
|
||||
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||
// be used on App Engine.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const unsafeAllowed = false
|
||||
|
||||
// A field identifies a field in a struct, accessible from a pointer.
|
||||
// In this implementation, a field is identified by the sequence of field indices
|
||||
// passed to reflect's FieldByIndex.
|
||||
type field []int
|
||||
|
||||
// toField returns a field equivalent to the given reflect field.
|
||||
func toField(f *reflect.StructField) field {
|
||||
return f.Index
|
||||
}
|
||||
|
||||
// invalidField is an invalid field identifier.
|
||||
var invalidField = field(nil)
|
||||
|
||||
// zeroField is a noop when calling pointer.offset.
|
||||
var zeroField = field([]int{})
|
||||
|
||||
// IsValid reports whether the field identifier is valid.
|
||||
func (f field) IsValid() bool { return f != nil }
|
||||
|
||||
// The pointer type is for the table-driven decoder.
|
||||
// The implementation here uses a reflect.Value of pointer type to
|
||||
// create a generic pointer. In pointer_unsafe.go we use unsafe
|
||||
// instead of reflect to implement the same (but faster) interface.
|
||||
type pointer struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
// toPointer converts an interface of pointer type to a pointer
|
||||
// that points to the same target.
|
||||
func toPointer(i *Message) pointer {
|
||||
return pointer{v: reflect.ValueOf(*i)}
|
||||
}
|
||||
|
||||
// toAddrPointer converts an interface to a pointer that points to
|
||||
// the interface data.
|
||||
func toAddrPointer(i *interface{}, isptr bool) pointer {
|
||||
v := reflect.ValueOf(*i)
|
||||
u := reflect.New(v.Type())
|
||||
u.Elem().Set(v)
|
||||
return pointer{v: u}
|
||||
}
|
||||
|
||||
// valToPointer converts v to a pointer. v must be of pointer type.
|
||||
func valToPointer(v reflect.Value) pointer {
|
||||
return pointer{v: v}
|
||||
}
|
||||
|
||||
// offset converts from a pointer to a structure to a pointer to
|
||||
// one of its fields.
|
||||
func (p pointer) offset(f field) pointer {
|
||||
return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
|
||||
}
|
||||
|
||||
func (p pointer) isNil() bool {
|
||||
return p.v.IsNil()
|
||||
}
|
||||
|
||||
// grow updates the slice s in place to make it one element longer.
|
||||
// s must be addressable.
|
||||
// Returns the (addressable) new element.
|
||||
func grow(s reflect.Value) reflect.Value {
|
||||
n, m := s.Len(), s.Cap()
|
||||
if n < m {
|
||||
s.SetLen(n + 1)
|
||||
} else {
|
||||
s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem())))
|
||||
}
|
||||
return s.Index(n)
|
||||
}
|
||||
|
||||
func (p pointer) toInt64() *int64 {
|
||||
return p.v.Interface().(*int64)
|
||||
}
|
||||
func (p pointer) toInt64Ptr() **int64 {
|
||||
return p.v.Interface().(**int64)
|
||||
}
|
||||
func (p pointer) toInt64Slice() *[]int64 {
|
||||
return p.v.Interface().(*[]int64)
|
||||
}
|
||||
|
||||
var int32ptr = reflect.TypeOf((*int32)(nil))
|
||||
|
||||
func (p pointer) toInt32() *int32 {
|
||||
return p.v.Convert(int32ptr).Interface().(*int32)
|
||||
}
|
||||
|
||||
// The toInt32Ptr/Slice methods don't work because of enums.
|
||||
// Instead, we must use set/get methods for the int32ptr/slice case.
|
||||
/*
|
||||
func (p pointer) toInt32Ptr() **int32 {
|
||||
return p.v.Interface().(**int32)
|
||||
}
|
||||
func (p pointer) toInt32Slice() *[]int32 {
|
||||
return p.v.Interface().(*[]int32)
|
||||
}
|
||||
*/
|
||||
func (p pointer) getInt32Ptr() *int32 {
|
||||
if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
|
||||
// raw int32 type
|
||||
return p.v.Elem().Interface().(*int32)
|
||||
}
|
||||
// an enum
|
||||
return p.v.Elem().Convert(int32PtrType).Interface().(*int32)
|
||||
}
|
||||
func (p pointer) setInt32Ptr(v int32) {
|
||||
// Allocate value in a *int32. Possibly convert that to a *enum.
|
||||
// Then assign it to a **int32 or **enum.
|
||||
// Note: we can convert *int32 to *enum, but we can't convert
|
||||
// **int32 to **enum!
|
||||
p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem()))
|
||||
}
|
||||
|
||||
// getInt32Slice copies []int32 from p as a new slice.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) getInt32Slice() []int32 {
|
||||
if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
|
||||
// raw int32 type
|
||||
return p.v.Elem().Interface().([]int32)
|
||||
}
|
||||
// an enum
|
||||
// Allocate a []int32, then assign []enum's values into it.
|
||||
// Note: we can't convert []enum to []int32.
|
||||
slice := p.v.Elem()
|
||||
s := make([]int32, slice.Len())
|
||||
for i := 0; i < slice.Len(); i++ {
|
||||
s[i] = int32(slice.Index(i).Int())
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// setInt32Slice copies []int32 into p as a new slice.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) setInt32Slice(v []int32) {
|
||||
if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
|
||||
// raw int32 type
|
||||
p.v.Elem().Set(reflect.ValueOf(v))
|
||||
return
|
||||
}
|
||||
// an enum
|
||||
// Allocate a []enum, then assign []int32's values into it.
|
||||
// Note: we can't convert []enum to []int32.
|
||||
slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v))
|
||||
for i, x := range v {
|
||||
slice.Index(i).SetInt(int64(x))
|
||||
}
|
||||
p.v.Elem().Set(slice)
|
||||
}
|
||||
func (p pointer) appendInt32Slice(v int32) {
|
||||
grow(p.v.Elem()).SetInt(int64(v))
|
||||
}
|
||||
|
||||
func (p pointer) toUint64() *uint64 {
|
||||
return p.v.Interface().(*uint64)
|
||||
}
|
||||
func (p pointer) toUint64Ptr() **uint64 {
|
||||
return p.v.Interface().(**uint64)
|
||||
}
|
||||
func (p pointer) toUint64Slice() *[]uint64 {
|
||||
return p.v.Interface().(*[]uint64)
|
||||
}
|
||||
func (p pointer) toUint32() *uint32 {
|
||||
return p.v.Interface().(*uint32)
|
||||
}
|
||||
func (p pointer) toUint32Ptr() **uint32 {
|
||||
return p.v.Interface().(**uint32)
|
||||
}
|
||||
func (p pointer) toUint32Slice() *[]uint32 {
|
||||
return p.v.Interface().(*[]uint32)
|
||||
}
|
||||
func (p pointer) toBool() *bool {
|
||||
return p.v.Interface().(*bool)
|
||||
}
|
||||
func (p pointer) toBoolPtr() **bool {
|
||||
return p.v.Interface().(**bool)
|
||||
}
|
||||
func (p pointer) toBoolSlice() *[]bool {
|
||||
return p.v.Interface().(*[]bool)
|
||||
}
|
||||
func (p pointer) toFloat64() *float64 {
|
||||
return p.v.Interface().(*float64)
|
||||
}
|
||||
func (p pointer) toFloat64Ptr() **float64 {
|
||||
return p.v.Interface().(**float64)
|
||||
}
|
||||
func (p pointer) toFloat64Slice() *[]float64 {
|
||||
return p.v.Interface().(*[]float64)
|
||||
}
|
||||
func (p pointer) toFloat32() *float32 {
|
||||
return p.v.Interface().(*float32)
|
||||
}
|
||||
func (p pointer) toFloat32Ptr() **float32 {
|
||||
return p.v.Interface().(**float32)
|
||||
}
|
||||
func (p pointer) toFloat32Slice() *[]float32 {
|
||||
return p.v.Interface().(*[]float32)
|
||||
}
|
||||
func (p pointer) toString() *string {
|
||||
return p.v.Interface().(*string)
|
||||
}
|
||||
func (p pointer) toStringPtr() **string {
|
||||
return p.v.Interface().(**string)
|
||||
}
|
||||
func (p pointer) toStringSlice() *[]string {
|
||||
return p.v.Interface().(*[]string)
|
||||
}
|
||||
func (p pointer) toBytes() *[]byte {
|
||||
return p.v.Interface().(*[]byte)
|
||||
}
|
||||
func (p pointer) toBytesSlice() *[][]byte {
|
||||
return p.v.Interface().(*[][]byte)
|
||||
}
|
||||
func (p pointer) toExtensions() *XXX_InternalExtensions {
|
||||
return p.v.Interface().(*XXX_InternalExtensions)
|
||||
}
|
||||
func (p pointer) toOldExtensions() *map[int32]Extension {
|
||||
return p.v.Interface().(*map[int32]Extension)
|
||||
}
|
||||
func (p pointer) getPointer() pointer {
|
||||
return pointer{v: p.v.Elem()}
|
||||
}
|
||||
func (p pointer) setPointer(q pointer) {
|
||||
p.v.Elem().Set(q.v)
|
||||
}
|
||||
func (p pointer) appendPointer(q pointer) {
|
||||
grow(p.v.Elem()).Set(q.v)
|
||||
}
|
||||
|
||||
// getPointerSlice copies []*T from p as a new []pointer.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) getPointerSlice() []pointer {
|
||||
if p.v.IsNil() {
|
||||
return nil
|
||||
}
|
||||
n := p.v.Elem().Len()
|
||||
s := make([]pointer, n)
|
||||
for i := 0; i < n; i++ {
|
||||
s[i] = pointer{v: p.v.Elem().Index(i)}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// setPointerSlice copies []pointer into p as a new []*T.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) setPointerSlice(v []pointer) {
|
||||
if v == nil {
|
||||
p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem())
|
||||
return
|
||||
}
|
||||
s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v))
|
||||
for _, p := range v {
|
||||
s = reflect.Append(s, p.v)
|
||||
}
|
||||
p.v.Elem().Set(s)
|
||||
}
|
||||
|
||||
// getInterfacePointer returns a pointer that points to the
|
||||
// interface data of the interface pointed by p.
|
||||
func (p pointer) getInterfacePointer() pointer {
|
||||
if p.v.Elem().IsNil() {
|
||||
return pointer{v: p.v.Elem()}
|
||||
}
|
||||
return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct
|
||||
}
|
||||
|
||||
func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
|
||||
// TODO: check that p.v.Type().Elem() == t?
|
||||
return p.v
|
||||
}
|
||||
|
||||
func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
return *p
|
||||
}
|
||||
func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
*p = v
|
||||
}
|
||||
func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
return *p
|
||||
}
|
||||
func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
*p = v
|
||||
}
|
||||
func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
return *p
|
||||
}
|
||||
func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
*p = v
|
||||
}
|
||||
func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
return *p
|
||||
}
|
||||
func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
*p = v
|
||||
}
|
||||
|
||||
var atomicLock sync.Mutex
|
59
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
generated
vendored
Normal file
59
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build purego appengine js
|
||||
|
||||
// This file contains an implementation of proto field accesses using package reflect.
|
||||
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||
// be used on App Engine.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// TODO: untested, so probably incorrect.
|
||||
|
||||
func (p pointer) getRef() pointer {
|
||||
return pointer{v: p.v.Addr()}
|
||||
}
|
||||
|
||||
func (p pointer) appendRef(v pointer, typ reflect.Type) {
|
||||
slice := p.getSlice(typ)
|
||||
elem := v.asPointerTo(typ).Elem()
|
||||
newSlice := reflect.Append(slice, elem)
|
||||
slice.Set(newSlice)
|
||||
}
|
||||
|
||||
func (p pointer) getSlice(typ reflect.Type) reflect.Value {
|
||||
sliceTyp := reflect.SliceOf(typ)
|
||||
slice := p.asPointerTo(sliceTyp)
|
||||
slice = slice.Elem()
|
||||
return slice
|
||||
}
|
308
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
generated
vendored
Normal file
308
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
generated
vendored
Normal file
|
@ -0,0 +1,308 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build !purego,!appengine,!js
|
||||
|
||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const unsafeAllowed = true
|
||||
|
||||
// A field identifies a field in a struct, accessible from a pointer.
|
||||
// In this implementation, a field is identified by its byte offset from the start of the struct.
|
||||
type field uintptr
|
||||
|
||||
// toField returns a field equivalent to the given reflect field.
|
||||
func toField(f *reflect.StructField) field {
|
||||
return field(f.Offset)
|
||||
}
|
||||
|
||||
// invalidField is an invalid field identifier.
|
||||
const invalidField = ^field(0)
|
||||
|
||||
// zeroField is a noop when calling pointer.offset.
|
||||
const zeroField = field(0)
|
||||
|
||||
// IsValid reports whether the field identifier is valid.
|
||||
func (f field) IsValid() bool {
|
||||
return f != invalidField
|
||||
}
|
||||
|
||||
// The pointer type below is for the new table-driven encoder/decoder.
|
||||
// The implementation here uses unsafe.Pointer to create a generic pointer.
|
||||
// In pointer_reflect.go we use reflect instead of unsafe to implement
|
||||
// the same (but slower) interface.
|
||||
type pointer struct {
|
||||
p unsafe.Pointer
|
||||
}
|
||||
|
||||
// size of pointer
|
||||
var ptrSize = unsafe.Sizeof(uintptr(0))
|
||||
|
||||
// toPointer converts an interface of pointer type to a pointer
|
||||
// that points to the same target.
|
||||
func toPointer(i *Message) pointer {
|
||||
// Super-tricky - read pointer out of data word of interface value.
|
||||
// Saves ~25ns over the equivalent:
|
||||
// return valToPointer(reflect.ValueOf(*i))
|
||||
return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
|
||||
}
|
||||
|
||||
// toAddrPointer converts an interface to a pointer that points to
|
||||
// the interface data.
|
||||
func toAddrPointer(i *interface{}, isptr bool) pointer {
|
||||
// Super-tricky - read or get the address of data word of interface value.
|
||||
if isptr {
|
||||
// The interface is of pointer type, thus it is a direct interface.
|
||||
// The data word is the pointer data itself. We take its address.
|
||||
return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
|
||||
}
|
||||
// The interface is not of pointer type. The data word is the pointer
|
||||
// to the data.
|
||||
return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
|
||||
}
|
||||
|
||||
// valToPointer converts v to a pointer. v must be of pointer type.
|
||||
func valToPointer(v reflect.Value) pointer {
|
||||
return pointer{p: unsafe.Pointer(v.Pointer())}
|
||||
}
|
||||
|
||||
// offset converts from a pointer to a structure to a pointer to
|
||||
// one of its fields.
|
||||
func (p pointer) offset(f field) pointer {
|
||||
// For safety, we should panic if !f.IsValid, however calling panic causes
|
||||
// this to no longer be inlineable, which is a serious performance cost.
|
||||
/*
|
||||
if !f.IsValid() {
|
||||
panic("invalid field")
|
||||
}
|
||||
*/
|
||||
return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
|
||||
}
|
||||
|
||||
func (p pointer) isNil() bool {
|
||||
return p.p == nil
|
||||
}
|
||||
|
||||
func (p pointer) toInt64() *int64 {
|
||||
return (*int64)(p.p)
|
||||
}
|
||||
func (p pointer) toInt64Ptr() **int64 {
|
||||
return (**int64)(p.p)
|
||||
}
|
||||
func (p pointer) toInt64Slice() *[]int64 {
|
||||
return (*[]int64)(p.p)
|
||||
}
|
||||
func (p pointer) toInt32() *int32 {
|
||||
return (*int32)(p.p)
|
||||
}
|
||||
|
||||
// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.
|
||||
/*
|
||||
func (p pointer) toInt32Ptr() **int32 {
|
||||
return (**int32)(p.p)
|
||||
}
|
||||
func (p pointer) toInt32Slice() *[]int32 {
|
||||
return (*[]int32)(p.p)
|
||||
}
|
||||
*/
|
||||
func (p pointer) getInt32Ptr() *int32 {
|
||||
return *(**int32)(p.p)
|
||||
}
|
||||
func (p pointer) setInt32Ptr(v int32) {
|
||||
*(**int32)(p.p) = &v
|
||||
}
|
||||
|
||||
// getInt32Slice loads a []int32 from p.
|
||||
// The value returned is aliased with the original slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) getInt32Slice() []int32 {
|
||||
return *(*[]int32)(p.p)
|
||||
}
|
||||
|
||||
// setInt32Slice stores a []int32 to p.
|
||||
// The value set is aliased with the input slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) setInt32Slice(v []int32) {
|
||||
*(*[]int32)(p.p) = v
|
||||
}
|
||||
|
||||
// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?
|
||||
func (p pointer) appendInt32Slice(v int32) {
|
||||
s := (*[]int32)(p.p)
|
||||
*s = append(*s, v)
|
||||
}
|
||||
|
||||
func (p pointer) toUint64() *uint64 {
|
||||
return (*uint64)(p.p)
|
||||
}
|
||||
func (p pointer) toUint64Ptr() **uint64 {
|
||||
return (**uint64)(p.p)
|
||||
}
|
||||
func (p pointer) toUint64Slice() *[]uint64 {
|
||||
return (*[]uint64)(p.p)
|
||||
}
|
||||
func (p pointer) toUint32() *uint32 {
|
||||
return (*uint32)(p.p)
|
||||
}
|
||||
func (p pointer) toUint32Ptr() **uint32 {
|
||||
return (**uint32)(p.p)
|
||||
}
|
||||
func (p pointer) toUint32Slice() *[]uint32 {
|
||||
return (*[]uint32)(p.p)
|
||||
}
|
||||
func (p pointer) toBool() *bool {
|
||||
return (*bool)(p.p)
|
||||
}
|
||||
func (p pointer) toBoolPtr() **bool {
|
||||
return (**bool)(p.p)
|
||||
}
|
||||
func (p pointer) toBoolSlice() *[]bool {
|
||||
return (*[]bool)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat64() *float64 {
|
||||
return (*float64)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat64Ptr() **float64 {
|
||||
return (**float64)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat64Slice() *[]float64 {
|
||||
return (*[]float64)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat32() *float32 {
|
||||
return (*float32)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat32Ptr() **float32 {
|
||||
return (**float32)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat32Slice() *[]float32 {
|
||||
return (*[]float32)(p.p)
|
||||
}
|
||||
func (p pointer) toString() *string {
|
||||
return (*string)(p.p)
|
||||
}
|
||||
func (p pointer) toStringPtr() **string {
|
||||
return (**string)(p.p)
|
||||
}
|
||||
func (p pointer) toStringSlice() *[]string {
|
||||
return (*[]string)(p.p)
|
||||
}
|
||||
func (p pointer) toBytes() *[]byte {
|
||||
return (*[]byte)(p.p)
|
||||
}
|
||||
func (p pointer) toBytesSlice() *[][]byte {
|
||||
return (*[][]byte)(p.p)
|
||||
}
|
||||
func (p pointer) toExtensions() *XXX_InternalExtensions {
|
||||
return (*XXX_InternalExtensions)(p.p)
|
||||
}
|
||||
func (p pointer) toOldExtensions() *map[int32]Extension {
|
||||
return (*map[int32]Extension)(p.p)
|
||||
}
|
||||
|
||||
// getPointerSlice loads []*T from p as a []pointer.
|
||||
// The value returned is aliased with the original slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) getPointerSlice() []pointer {
|
||||
// Super-tricky - p should point to a []*T where T is a
|
||||
// message type. We load it as []pointer.
|
||||
return *(*[]pointer)(p.p)
|
||||
}
|
||||
|
||||
// setPointerSlice stores []pointer into p as a []*T.
|
||||
// The value set is aliased with the input slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) setPointerSlice(v []pointer) {
|
||||
// Super-tricky - p should point to a []*T where T is a
|
||||
// message type. We store it as []pointer.
|
||||
*(*[]pointer)(p.p) = v
|
||||
}
|
||||
|
||||
// getPointer loads the pointer at p and returns it.
|
||||
func (p pointer) getPointer() pointer {
|
||||
return pointer{p: *(*unsafe.Pointer)(p.p)}
|
||||
}
|
||||
|
||||
// setPointer stores the pointer q at p.
|
||||
func (p pointer) setPointer(q pointer) {
|
||||
*(*unsafe.Pointer)(p.p) = q.p
|
||||
}
|
||||
|
||||
// append q to the slice pointed to by p.
|
||||
func (p pointer) appendPointer(q pointer) {
|
||||
s := (*[]unsafe.Pointer)(p.p)
|
||||
*s = append(*s, q.p)
|
||||
}
|
||||
|
||||
// getInterfacePointer returns a pointer that points to the
|
||||
// interface data of the interface pointed by p.
|
||||
func (p pointer) getInterfacePointer() pointer {
|
||||
// Super-tricky - read pointer out of data word of interface value.
|
||||
return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]}
|
||||
}
|
||||
|
||||
// asPointerTo returns a reflect.Value that is a pointer to an
|
||||
// object of type t stored at p.
|
||||
func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
|
||||
return reflect.NewAt(t, p.p)
|
||||
}
|
||||
|
||||
func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
|
||||
return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||
}
|
||||
func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
|
||||
}
|
||||
func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
|
||||
return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||
}
|
||||
func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
|
||||
}
|
||||
func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
|
||||
return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||
}
|
||||
func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
|
||||
}
|
||||
func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
|
||||
return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||
}
|
||||
func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
|
||||
}
|
56
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
generated
vendored
Normal file
56
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build !purego,!appengine,!js
|
||||
|
||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (p pointer) getRef() pointer {
|
||||
return pointer{p: (unsafe.Pointer)(&p.p)}
|
||||
}
|
||||
|
||||
func (p pointer) appendRef(v pointer, typ reflect.Type) {
|
||||
slice := p.getSlice(typ)
|
||||
elem := v.asPointerTo(typ).Elem()
|
||||
newSlice := reflect.Append(slice, elem)
|
||||
slice.Set(newSlice)
|
||||
}
|
||||
|
||||
func (p pointer) getSlice(typ reflect.Type) reflect.Value {
|
||||
sliceTyp := reflect.SliceOf(typ)
|
||||
slice := p.asPointerTo(sliceTyp)
|
||||
slice = slice.Elem()
|
||||
return slice
|
||||
}
|
599
vendor/github.com/gogo/protobuf/proto/properties.go
generated
vendored
Normal file
599
vendor/github.com/gogo/protobuf/proto/properties.go
generated
vendored
Normal file
|
@ -0,0 +1,599 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Routines for encoding data into the wire format for protocol buffers.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const debug bool = false
|
||||
|
||||
// Constants that identify the encoding of a value on the wire.
|
||||
const (
|
||||
WireVarint = 0
|
||||
WireFixed64 = 1
|
||||
WireBytes = 2
|
||||
WireStartGroup = 3
|
||||
WireEndGroup = 4
|
||||
WireFixed32 = 5
|
||||
)
|
||||
|
||||
// tagMap is an optimization over map[int]int for typical protocol buffer
|
||||
// use-cases. Encoded protocol buffers are often in tag order with small tag
|
||||
// numbers.
|
||||
type tagMap struct {
|
||||
fastTags []int
|
||||
slowTags map[int]int
|
||||
}
|
||||
|
||||
// tagMapFastLimit is the upper bound on the tag number that will be stored in
|
||||
// the tagMap slice rather than its map.
|
||||
const tagMapFastLimit = 1024
|
||||
|
||||
func (p *tagMap) get(t int) (int, bool) {
|
||||
if t > 0 && t < tagMapFastLimit {
|
||||
if t >= len(p.fastTags) {
|
||||
return 0, false
|
||||
}
|
||||
fi := p.fastTags[t]
|
||||
return fi, fi >= 0
|
||||
}
|
||||
fi, ok := p.slowTags[t]
|
||||
return fi, ok
|
||||
}
|
||||
|
||||
func (p *tagMap) put(t int, fi int) {
|
||||
if t > 0 && t < tagMapFastLimit {
|
||||
for len(p.fastTags) < t+1 {
|
||||
p.fastTags = append(p.fastTags, -1)
|
||||
}
|
||||
p.fastTags[t] = fi
|
||||
return
|
||||
}
|
||||
if p.slowTags == nil {
|
||||
p.slowTags = make(map[int]int)
|
||||
}
|
||||
p.slowTags[t] = fi
|
||||
}
|
||||
|
||||
// StructProperties represents properties for all the fields of a struct.
|
||||
// decoderTags and decoderOrigNames should only be used by the decoder.
|
||||
type StructProperties struct {
|
||||
Prop []*Properties // properties for each field
|
||||
reqCount int // required count
|
||||
decoderTags tagMap // map from proto tag to struct field number
|
||||
decoderOrigNames map[string]int // map from original name to struct field number
|
||||
order []int // list of struct field numbers in tag order
|
||||
|
||||
// OneofTypes contains information about the oneof fields in this message.
|
||||
// It is keyed by the original name of a field.
|
||||
OneofTypes map[string]*OneofProperties
|
||||
}
|
||||
|
||||
// OneofProperties represents information about a specific field in a oneof.
|
||||
type OneofProperties struct {
|
||||
Type reflect.Type // pointer to generated struct type for this oneof field
|
||||
Field int // struct field number of the containing oneof in the message
|
||||
Prop *Properties
|
||||
}
|
||||
|
||||
// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
|
||||
// See encode.go, (*Buffer).enc_struct.
|
||||
|
||||
func (sp *StructProperties) Len() int { return len(sp.order) }
|
||||
func (sp *StructProperties) Less(i, j int) bool {
|
||||
return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
|
||||
}
|
||||
func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
|
||||
|
||||
// Properties represents the protocol-specific behavior of a single struct field.
|
||||
type Properties struct {
|
||||
Name string // name of the field, for error messages
|
||||
OrigName string // original name before protocol compiler (always set)
|
||||
JSONName string // name to use for JSON; determined by protoc
|
||||
Wire string
|
||||
WireType int
|
||||
Tag int
|
||||
Required bool
|
||||
Optional bool
|
||||
Repeated bool
|
||||
Packed bool // relevant for repeated primitives only
|
||||
Enum string // set for enum types only
|
||||
proto3 bool // whether this is known to be a proto3 field
|
||||
oneof bool // whether this is a oneof field
|
||||
|
||||
Default string // default value
|
||||
HasDefault bool // whether an explicit default was provided
|
||||
CustomType string
|
||||
CastType string
|
||||
StdTime bool
|
||||
StdDuration bool
|
||||
WktPointer bool
|
||||
|
||||
stype reflect.Type // set for struct types only
|
||||
ctype reflect.Type // set for custom types only
|
||||
sprop *StructProperties // set for struct types only
|
||||
|
||||
mtype reflect.Type // set for map types only
|
||||
MapKeyProp *Properties // set for map types only
|
||||
MapValProp *Properties // set for map types only
|
||||
}
|
||||
|
||||
// String formats the properties in the protobuf struct field tag style.
|
||||
func (p *Properties) String() string {
|
||||
s := p.Wire
|
||||
s += ","
|
||||
s += strconv.Itoa(p.Tag)
|
||||
if p.Required {
|
||||
s += ",req"
|
||||
}
|
||||
if p.Optional {
|
||||
s += ",opt"
|
||||
}
|
||||
if p.Repeated {
|
||||
s += ",rep"
|
||||
}
|
||||
if p.Packed {
|
||||
s += ",packed"
|
||||
}
|
||||
s += ",name=" + p.OrigName
|
||||
if p.JSONName != p.OrigName {
|
||||
s += ",json=" + p.JSONName
|
||||
}
|
||||
if p.proto3 {
|
||||
s += ",proto3"
|
||||
}
|
||||
if p.oneof {
|
||||
s += ",oneof"
|
||||
}
|
||||
if len(p.Enum) > 0 {
|
||||
s += ",enum=" + p.Enum
|
||||
}
|
||||
if p.HasDefault {
|
||||
s += ",def=" + p.Default
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Parse populates p by parsing a string in the protobuf struct field tag style.
|
||||
func (p *Properties) Parse(s string) {
|
||||
// "bytes,49,opt,name=foo,def=hello!"
|
||||
fields := strings.Split(s, ",") // breaks def=, but handled below.
|
||||
if len(fields) < 2 {
|
||||
fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
|
||||
return
|
||||
}
|
||||
|
||||
p.Wire = fields[0]
|
||||
switch p.Wire {
|
||||
case "varint":
|
||||
p.WireType = WireVarint
|
||||
case "fixed32":
|
||||
p.WireType = WireFixed32
|
||||
case "fixed64":
|
||||
p.WireType = WireFixed64
|
||||
case "zigzag32":
|
||||
p.WireType = WireVarint
|
||||
case "zigzag64":
|
||||
p.WireType = WireVarint
|
||||
case "bytes", "group":
|
||||
p.WireType = WireBytes
|
||||
// no numeric converter for non-numeric types
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
p.Tag, err = strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
outer:
|
||||
for i := 2; i < len(fields); i++ {
|
||||
f := fields[i]
|
||||
switch {
|
||||
case f == "req":
|
||||
p.Required = true
|
||||
case f == "opt":
|
||||
p.Optional = true
|
||||
case f == "rep":
|
||||
p.Repeated = true
|
||||
case f == "packed":
|
||||
p.Packed = true
|
||||
case strings.HasPrefix(f, "name="):
|
||||
p.OrigName = f[5:]
|
||||
case strings.HasPrefix(f, "json="):
|
||||
p.JSONName = f[5:]
|
||||
case strings.HasPrefix(f, "enum="):
|
||||
p.Enum = f[5:]
|
||||
case f == "proto3":
|
||||
p.proto3 = true
|
||||
case f == "oneof":
|
||||
p.oneof = true
|
||||
case strings.HasPrefix(f, "def="):
|
||||
p.HasDefault = true
|
||||
p.Default = f[4:] // rest of string
|
||||
if i+1 < len(fields) {
|
||||
// Commas aren't escaped, and def is always last.
|
||||
p.Default += "," + strings.Join(fields[i+1:], ",")
|
||||
break outer
|
||||
}
|
||||
case strings.HasPrefix(f, "embedded="):
|
||||
p.OrigName = strings.Split(f, "=")[1]
|
||||
case strings.HasPrefix(f, "customtype="):
|
||||
p.CustomType = strings.Split(f, "=")[1]
|
||||
case strings.HasPrefix(f, "casttype="):
|
||||
p.CastType = strings.Split(f, "=")[1]
|
||||
case f == "stdtime":
|
||||
p.StdTime = true
|
||||
case f == "stdduration":
|
||||
p.StdDuration = true
|
||||
case f == "wktptr":
|
||||
p.WktPointer = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
||||
|
||||
// setFieldProps initializes the field properties for submessages and maps.
|
||||
func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
|
||||
isMap := typ.Kind() == reflect.Map
|
||||
if len(p.CustomType) > 0 && !isMap {
|
||||
p.ctype = typ
|
||||
p.setTag(lockGetProp)
|
||||
return
|
||||
}
|
||||
if p.StdTime && !isMap {
|
||||
p.setTag(lockGetProp)
|
||||
return
|
||||
}
|
||||
if p.StdDuration && !isMap {
|
||||
p.setTag(lockGetProp)
|
||||
return
|
||||
}
|
||||
if p.WktPointer && !isMap {
|
||||
p.setTag(lockGetProp)
|
||||
return
|
||||
}
|
||||
switch t1 := typ; t1.Kind() {
|
||||
case reflect.Struct:
|
||||
p.stype = typ
|
||||
case reflect.Ptr:
|
||||
if t1.Elem().Kind() == reflect.Struct {
|
||||
p.stype = t1.Elem()
|
||||
}
|
||||
case reflect.Slice:
|
||||
switch t2 := t1.Elem(); t2.Kind() {
|
||||
case reflect.Ptr:
|
||||
switch t3 := t2.Elem(); t3.Kind() {
|
||||
case reflect.Struct:
|
||||
p.stype = t3
|
||||
}
|
||||
case reflect.Struct:
|
||||
p.stype = t2
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
|
||||
p.mtype = t1
|
||||
p.MapKeyProp = &Properties{}
|
||||
p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
|
||||
p.MapValProp = &Properties{}
|
||||
vtype := p.mtype.Elem()
|
||||
if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
|
||||
// The value type is not a message (*T) or bytes ([]byte),
|
||||
// so we need encoders for the pointer to this type.
|
||||
vtype = reflect.PtrTo(vtype)
|
||||
}
|
||||
|
||||
p.MapValProp.CustomType = p.CustomType
|
||||
p.MapValProp.StdDuration = p.StdDuration
|
||||
p.MapValProp.StdTime = p.StdTime
|
||||
p.MapValProp.WktPointer = p.WktPointer
|
||||
p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||
}
|
||||
p.setTag(lockGetProp)
|
||||
}
|
||||
|
||||
func (p *Properties) setTag(lockGetProp bool) {
|
||||
if p.stype != nil {
|
||||
if lockGetProp {
|
||||
p.sprop = GetProperties(p.stype)
|
||||
} else {
|
||||
p.sprop = getPropertiesLocked(p.stype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
|
||||
)
|
||||
|
||||
// Init populates the properties from a protocol buffer struct tag.
|
||||
func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
|
||||
p.init(typ, name, tag, f, true)
|
||||
}
|
||||
|
||||
func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
|
||||
// "bytes,49,opt,def=hello!"
|
||||
p.Name = name
|
||||
p.OrigName = name
|
||||
if tag == "" {
|
||||
return
|
||||
}
|
||||
p.Parse(tag)
|
||||
p.setFieldProps(typ, f, lockGetProp)
|
||||
}
|
||||
|
||||
var (
|
||||
propertiesMu sync.RWMutex
|
||||
propertiesMap = make(map[reflect.Type]*StructProperties)
|
||||
)
|
||||
|
||||
// GetProperties returns the list of properties for the type represented by t.
|
||||
// t must represent a generated struct type of a protocol message.
|
||||
func GetProperties(t reflect.Type) *StructProperties {
|
||||
if t.Kind() != reflect.Struct {
|
||||
panic("proto: type must have kind struct")
|
||||
}
|
||||
|
||||
// Most calls to GetProperties in a long-running program will be
|
||||
// retrieving details for types we have seen before.
|
||||
propertiesMu.RLock()
|
||||
sprop, ok := propertiesMap[t]
|
||||
propertiesMu.RUnlock()
|
||||
if ok {
|
||||
return sprop
|
||||
}
|
||||
|
||||
propertiesMu.Lock()
|
||||
sprop = getPropertiesLocked(t)
|
||||
propertiesMu.Unlock()
|
||||
return sprop
|
||||
}
|
||||
|
||||
// getPropertiesLocked requires that propertiesMu is held.
|
||||
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||
if prop, ok := propertiesMap[t]; ok {
|
||||
return prop
|
||||
}
|
||||
|
||||
prop := new(StructProperties)
|
||||
// in case of recursive protos, fill this in now.
|
||||
propertiesMap[t] = prop
|
||||
|
||||
// build properties
|
||||
prop.Prop = make([]*Properties, t.NumField())
|
||||
prop.order = make([]int, t.NumField())
|
||||
|
||||
isOneofMessage := false
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
p := new(Properties)
|
||||
name := f.Name
|
||||
p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
|
||||
|
||||
oneof := f.Tag.Get("protobuf_oneof") // special case
|
||||
if oneof != "" {
|
||||
isOneofMessage = true
|
||||
// Oneof fields don't use the traditional protobuf tag.
|
||||
p.OrigName = oneof
|
||||
}
|
||||
prop.Prop[i] = p
|
||||
prop.order[i] = i
|
||||
if debug {
|
||||
print(i, " ", f.Name, " ", t.String(), " ")
|
||||
if p.Tag > 0 {
|
||||
print(p.String())
|
||||
}
|
||||
print("\n")
|
||||
}
|
||||
}
|
||||
|
||||
// Re-order prop.order.
|
||||
sort.Sort(prop)
|
||||
|
||||
type oneofMessage interface {
|
||||
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
||||
}
|
||||
if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
|
||||
var oots []interface{}
|
||||
_, _, _, oots = om.XXX_OneofFuncs()
|
||||
|
||||
// Interpret oneof metadata.
|
||||
prop.OneofTypes = make(map[string]*OneofProperties)
|
||||
for _, oot := range oots {
|
||||
oop := &OneofProperties{
|
||||
Type: reflect.ValueOf(oot).Type(), // *T
|
||||
Prop: new(Properties),
|
||||
}
|
||||
sft := oop.Type.Elem().Field(0)
|
||||
oop.Prop.Name = sft.Name
|
||||
oop.Prop.Parse(sft.Tag.Get("protobuf"))
|
||||
// There will be exactly one interface field that
|
||||
// this new value is assignable to.
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if f.Type.Kind() != reflect.Interface {
|
||||
continue
|
||||
}
|
||||
if !oop.Type.AssignableTo(f.Type) {
|
||||
continue
|
||||
}
|
||||
oop.Field = i
|
||||
break
|
||||
}
|
||||
prop.OneofTypes[oop.Prop.OrigName] = oop
|
||||
}
|
||||
}
|
||||
|
||||
// build required counts
|
||||
// build tags
|
||||
reqCount := 0
|
||||
prop.decoderOrigNames = make(map[string]int)
|
||||
for i, p := range prop.Prop {
|
||||
if strings.HasPrefix(p.Name, "XXX_") {
|
||||
// Internal fields should not appear in tags/origNames maps.
|
||||
// They are handled specially when encoding and decoding.
|
||||
continue
|
||||
}
|
||||
if p.Required {
|
||||
reqCount++
|
||||
}
|
||||
prop.decoderTags.put(p.Tag, i)
|
||||
prop.decoderOrigNames[p.OrigName] = i
|
||||
}
|
||||
prop.reqCount = reqCount
|
||||
|
||||
return prop
|
||||
}
|
||||
|
||||
// A global registry of enum types.
|
||||
// The generated code will register the generated maps by calling RegisterEnum.
|
||||
|
||||
var enumValueMaps = make(map[string]map[string]int32)
|
||||
var enumStringMaps = make(map[string]map[int32]string)
|
||||
|
||||
// RegisterEnum is called from the generated code to install the enum descriptor
|
||||
// maps into the global table to aid parsing text format protocol buffers.
|
||||
func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
|
||||
if _, ok := enumValueMaps[typeName]; ok {
|
||||
panic("proto: duplicate enum registered: " + typeName)
|
||||
}
|
||||
enumValueMaps[typeName] = valueMap
|
||||
if _, ok := enumStringMaps[typeName]; ok {
|
||||
panic("proto: duplicate enum registered: " + typeName)
|
||||
}
|
||||
enumStringMaps[typeName] = unusedNameMap
|
||||
}
|
||||
|
||||
// EnumValueMap returns the mapping from names to integers of the
|
||||
// enum type enumType, or a nil if not found.
|
||||
func EnumValueMap(enumType string) map[string]int32 {
|
||||
return enumValueMaps[enumType]
|
||||
}
|
||||
|
||||
// A registry of all linked message types.
|
||||
// The string is a fully-qualified proto name ("pkg.Message").
|
||||
var (
|
||||
protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers
|
||||
protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types
|
||||
revProtoTypes = make(map[reflect.Type]string)
|
||||
)
|
||||
|
||||
// RegisterType is called from generated code and maps from the fully qualified
|
||||
// proto name to the type (pointer to struct) of the protocol buffer.
|
||||
func RegisterType(x Message, name string) {
|
||||
if _, ok := protoTypedNils[name]; ok {
|
||||
// TODO: Some day, make this a panic.
|
||||
log.Printf("proto: duplicate proto type registered: %s", name)
|
||||
return
|
||||
}
|
||||
t := reflect.TypeOf(x)
|
||||
if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
|
||||
// Generated code always calls RegisterType with nil x.
|
||||
// This check is just for extra safety.
|
||||
protoTypedNils[name] = x
|
||||
} else {
|
||||
protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
|
||||
}
|
||||
revProtoTypes[t] = name
|
||||
}
|
||||
|
||||
// RegisterMapType is called from generated code and maps from the fully qualified
|
||||
// proto name to the native map type of the proto map definition.
|
||||
func RegisterMapType(x interface{}, name string) {
|
||||
if reflect.TypeOf(x).Kind() != reflect.Map {
|
||||
panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
|
||||
}
|
||||
if _, ok := protoMapTypes[name]; ok {
|
||||
log.Printf("proto: duplicate proto type registered: %s", name)
|
||||
return
|
||||
}
|
||||
t := reflect.TypeOf(x)
|
||||
protoMapTypes[name] = t
|
||||
revProtoTypes[t] = name
|
||||
}
|
||||
|
||||
// MessageName returns the fully-qualified proto name for the given message type.
|
||||
func MessageName(x Message) string {
|
||||
type xname interface {
|
||||
XXX_MessageName() string
|
||||
}
|
||||
if m, ok := x.(xname); ok {
|
||||
return m.XXX_MessageName()
|
||||
}
|
||||
return revProtoTypes[reflect.TypeOf(x)]
|
||||
}
|
||||
|
||||
// MessageType returns the message type (pointer to struct) for a named message.
|
||||
// The type is not guaranteed to implement proto.Message if the name refers to a
|
||||
// map entry.
|
||||
func MessageType(name string) reflect.Type {
|
||||
if t, ok := protoTypedNils[name]; ok {
|
||||
return reflect.TypeOf(t)
|
||||
}
|
||||
return protoMapTypes[name]
|
||||
}
|
||||
|
||||
// A registry of all linked proto files.
|
||||
var (
|
||||
protoFiles = make(map[string][]byte) // file name => fileDescriptor
|
||||
)
|
||||
|
||||
// RegisterFile is called from generated code and maps from the
|
||||
// full file name of a .proto file to its compressed FileDescriptorProto.
|
||||
func RegisterFile(filename string, fileDescriptor []byte) {
|
||||
protoFiles[filename] = fileDescriptor
|
||||
}
|
||||
|
||||
// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
|
||||
func FileDescriptor(filename string) []byte { return protoFiles[filename] }
|
36
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
generated
vendored
Normal file
36
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var sizerType = reflect.TypeOf((*Sizer)(nil)).Elem()
|
||||
var protosizerType = reflect.TypeOf((*ProtoSizer)(nil)).Elem()
|
119
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
generated
vendored
Normal file
119
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func Skip(data []byte) (n int, err error) {
|
||||
l := len(data)
|
||||
index := 0
|
||||
for index < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if index >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[index]
|
||||
index++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for {
|
||||
if index >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
index++
|
||||
if data[index-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return index, nil
|
||||
case 1:
|
||||
index += 8
|
||||
return index, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if index >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[index]
|
||||
index++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
index += length
|
||||
return index, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = index
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if index >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[index]
|
||||
index++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := Skip(data[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index = start + next
|
||||
}
|
||||
return index, nil
|
||||
case 4:
|
||||
return index, nil
|
||||
case 5:
|
||||
index += 4
|
||||
return index, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
3006
vendor/github.com/gogo/protobuf/proto/table_marshal.go
generated
vendored
Normal file
3006
vendor/github.com/gogo/protobuf/proto/table_marshal.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
388
vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go
generated
vendored
Normal file
388
vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,388 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
// makeMessageRefMarshaler differs a bit from makeMessageMarshaler
|
||||
// It marshal a message T instead of a *T
|
||||
func makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
siz := u.size(ptr)
|
||||
return siz + SizeVarint(uint64(siz)) + tagsize
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
b = appendVarint(b, wiretag)
|
||||
siz := u.cachedsize(ptr)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
return u.marshal(b, ptr, deterministic)
|
||||
}
|
||||
}
|
||||
|
||||
// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler
|
||||
// It marshals a slice of messages []T instead of []*T
|
||||
func makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(u.typ)
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
e := elem.Interface()
|
||||
v := toAddrPointer(&e, false)
|
||||
siz := u.size(v)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(u.typ)
|
||||
var err, errreq error
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
e := elem.Interface()
|
||||
v := toAddrPointer(&e, false)
|
||||
b = appendVarint(b, wiretag)
|
||||
siz := u.size(v)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b, err = u.marshal(b, v, deterministic)
|
||||
|
||||
if err != nil {
|
||||
if _, ok := err.(*RequiredNotSetError); ok {
|
||||
// Required field in submessage is not set.
|
||||
// We record the error but keep going, to give a complete marshaling.
|
||||
if errreq == nil {
|
||||
errreq = err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err == ErrNil {
|
||||
err = errRepeatedHasNil
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
|
||||
return b, errreq
|
||||
}
|
||||
}
|
||||
|
||||
func makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
if ptr.isNil() {
|
||||
return 0
|
||||
}
|
||||
m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)
|
||||
siz := m.Size()
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
if ptr.isNil() {
|
||||
return b, nil
|
||||
}
|
||||
m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)
|
||||
siz := m.Size()
|
||||
buf, err := m.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
m := ptr.asPointerTo(u.typ).Interface().(custom)
|
||||
siz := m.Size()
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
m := ptr.asPointerTo(u.typ).Interface().(custom)
|
||||
siz := m.Size()
|
||||
buf, err := m.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
t := ptr.asPointerTo(u.typ).Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
siz := Size(ts)
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
t := ptr.asPointerTo(u.typ).Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf, err := Marshal(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(buf)))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
if ptr.isNil() {
|
||||
return 0
|
||||
}
|
||||
t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
siz := Size(ts)
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
if ptr.isNil() {
|
||||
return b, nil
|
||||
}
|
||||
t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf, err := Marshal(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(buf)))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(u.typ)
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
t := elem.Interface().(time.Time)
|
||||
ts, err := timestampProto(t)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
siz := Size(ts)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(u.typ)
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
t := elem.Interface().(time.Time)
|
||||
ts, err := timestampProto(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
siz := Size(ts)
|
||||
buf, err := Marshal(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(reflect.PtrTo(u.typ))
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
t := elem.Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
siz := Size(ts)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(reflect.PtrTo(u.typ))
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
t := elem.Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
siz := Size(ts)
|
||||
buf, err := Marshal(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
d := ptr.asPointerTo(u.typ).Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
siz := Size(dur)
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
d := ptr.asPointerTo(u.typ).Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
buf, err := Marshal(dur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(buf)))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
if ptr.isNil() {
|
||||
return 0
|
||||
}
|
||||
d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
siz := Size(dur)
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
if ptr.isNil() {
|
||||
return b, nil
|
||||
}
|
||||
d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
buf, err := Marshal(dur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(buf)))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(u.typ)
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
d := elem.Interface().(time.Duration)
|
||||
dur := durationProto(d)
|
||||
siz := Size(dur)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(u.typ)
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
d := elem.Interface().(time.Duration)
|
||||
dur := durationProto(d)
|
||||
siz := Size(dur)
|
||||
buf, err := Marshal(dur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(reflect.PtrTo(u.typ))
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
d := elem.Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
siz := Size(dur)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(reflect.PtrTo(u.typ))
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
d := elem.Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
siz := Size(dur)
|
||||
buf, err := Marshal(dur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
657
vendor/github.com/gogo/protobuf/proto/table_merge.go
generated
vendored
Normal file
657
vendor/github.com/gogo/protobuf/proto/table_merge.go
generated
vendored
Normal file
|
@ -0,0 +1,657 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// Merge merges the src message into dst.
|
||||
// This assumes that dst and src of the same type and are non-nil.
|
||||
func (a *InternalMessageInfo) Merge(dst, src Message) {
|
||||
mi := atomicLoadMergeInfo(&a.merge)
|
||||
if mi == nil {
|
||||
mi = getMergeInfo(reflect.TypeOf(dst).Elem())
|
||||
atomicStoreMergeInfo(&a.merge, mi)
|
||||
}
|
||||
mi.merge(toPointer(&dst), toPointer(&src))
|
||||
}
|
||||
|
||||
type mergeInfo struct {
|
||||
typ reflect.Type
|
||||
|
||||
initialized int32 // 0: only typ is valid, 1: everything is valid
|
||||
lock sync.Mutex
|
||||
|
||||
fields []mergeFieldInfo
|
||||
unrecognized field // Offset of XXX_unrecognized
|
||||
}
|
||||
|
||||
type mergeFieldInfo struct {
|
||||
field field // Offset of field, guaranteed to be valid
|
||||
|
||||
// isPointer reports whether the value in the field is a pointer.
|
||||
// This is true for the following situations:
|
||||
// * Pointer to struct
|
||||
// * Pointer to basic type (proto2 only)
|
||||
// * Slice (first value in slice header is a pointer)
|
||||
// * String (first value in string header is a pointer)
|
||||
isPointer bool
|
||||
|
||||
// basicWidth reports the width of the field assuming that it is directly
|
||||
// embedded in the struct (as is the case for basic types in proto3).
|
||||
// The possible values are:
|
||||
// 0: invalid
|
||||
// 1: bool
|
||||
// 4: int32, uint32, float32
|
||||
// 8: int64, uint64, float64
|
||||
basicWidth int
|
||||
|
||||
// Where dst and src are pointers to the types being merged.
|
||||
merge func(dst, src pointer)
|
||||
}
|
||||
|
||||
var (
|
||||
mergeInfoMap = map[reflect.Type]*mergeInfo{}
|
||||
mergeInfoLock sync.Mutex
|
||||
)
|
||||
|
||||
func getMergeInfo(t reflect.Type) *mergeInfo {
|
||||
mergeInfoLock.Lock()
|
||||
defer mergeInfoLock.Unlock()
|
||||
mi := mergeInfoMap[t]
|
||||
if mi == nil {
|
||||
mi = &mergeInfo{typ: t}
|
||||
mergeInfoMap[t] = mi
|
||||
}
|
||||
return mi
|
||||
}
|
||||
|
||||
// merge merges src into dst assuming they are both of type *mi.typ.
|
||||
func (mi *mergeInfo) merge(dst, src pointer) {
|
||||
if dst.isNil() {
|
||||
panic("proto: nil destination")
|
||||
}
|
||||
if src.isNil() {
|
||||
return // Nothing to do.
|
||||
}
|
||||
|
||||
if atomic.LoadInt32(&mi.initialized) == 0 {
|
||||
mi.computeMergeInfo()
|
||||
}
|
||||
|
||||
for _, fi := range mi.fields {
|
||||
sfp := src.offset(fi.field)
|
||||
|
||||
// As an optimization, we can avoid the merge function call cost
|
||||
// if we know for sure that the source will have no effect
|
||||
// by checking if it is the zero value.
|
||||
if unsafeAllowed {
|
||||
if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string
|
||||
continue
|
||||
}
|
||||
if fi.basicWidth > 0 {
|
||||
switch {
|
||||
case fi.basicWidth == 1 && !*sfp.toBool():
|
||||
continue
|
||||
case fi.basicWidth == 4 && *sfp.toUint32() == 0:
|
||||
continue
|
||||
case fi.basicWidth == 8 && *sfp.toUint64() == 0:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dfp := dst.offset(fi.field)
|
||||
fi.merge(dfp, sfp)
|
||||
}
|
||||
|
||||
// TODO: Make this faster?
|
||||
out := dst.asPointerTo(mi.typ).Elem()
|
||||
in := src.asPointerTo(mi.typ).Elem()
|
||||
if emIn, err := extendable(in.Addr().Interface()); err == nil {
|
||||
emOut, _ := extendable(out.Addr().Interface())
|
||||
mIn, muIn := emIn.extensionsRead()
|
||||
if mIn != nil {
|
||||
mOut := emOut.extensionsWrite()
|
||||
muIn.Lock()
|
||||
mergeExtension(mOut, mIn)
|
||||
muIn.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
if mi.unrecognized.IsValid() {
|
||||
if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 {
|
||||
*dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mi *mergeInfo) computeMergeInfo() {
|
||||
mi.lock.Lock()
|
||||
defer mi.lock.Unlock()
|
||||
if mi.initialized != 0 {
|
||||
return
|
||||
}
|
||||
t := mi.typ
|
||||
n := t.NumField()
|
||||
|
||||
props := GetProperties(t)
|
||||
for i := 0; i < n; i++ {
|
||||
f := t.Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
|
||||
mfi := mergeFieldInfo{field: toField(&f)}
|
||||
tf := f.Type
|
||||
|
||||
// As an optimization, we can avoid the merge function call cost
|
||||
// if we know for sure that the source will have no effect
|
||||
// by checking if it is the zero value.
|
||||
if unsafeAllowed {
|
||||
switch tf.Kind() {
|
||||
case reflect.Ptr, reflect.Slice, reflect.String:
|
||||
// As a special case, we assume slices and strings are pointers
|
||||
// since we know that the first field in the SliceSlice or
|
||||
// StringHeader is a data pointer.
|
||||
mfi.isPointer = true
|
||||
case reflect.Bool:
|
||||
mfi.basicWidth = 1
|
||||
case reflect.Int32, reflect.Uint32, reflect.Float32:
|
||||
mfi.basicWidth = 4
|
||||
case reflect.Int64, reflect.Uint64, reflect.Float64:
|
||||
mfi.basicWidth = 8
|
||||
}
|
||||
}
|
||||
|
||||
// Unwrap tf to get at its most basic type.
|
||||
var isPointer, isSlice bool
|
||||
if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
|
||||
isSlice = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if tf.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if isPointer && isSlice && tf.Kind() != reflect.Struct {
|
||||
panic("both pointer and slice for basic type in " + tf.Name())
|
||||
}
|
||||
|
||||
switch tf.Kind() {
|
||||
case reflect.Int32:
|
||||
switch {
|
||||
case isSlice: // E.g., []int32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
// NOTE: toInt32Slice is not defined (see pointer_reflect.go).
|
||||
/*
|
||||
sfsp := src.toInt32Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toInt32Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []int64{}
|
||||
}
|
||||
}
|
||||
*/
|
||||
sfs := src.getInt32Slice()
|
||||
if sfs != nil {
|
||||
dfs := dst.getInt32Slice()
|
||||
dfs = append(dfs, sfs...)
|
||||
if dfs == nil {
|
||||
dfs = []int32{}
|
||||
}
|
||||
dst.setInt32Slice(dfs)
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *int32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
// NOTE: toInt32Ptr is not defined (see pointer_reflect.go).
|
||||
/*
|
||||
sfpp := src.toInt32Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toInt32Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Int32(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
*/
|
||||
sfp := src.getInt32Ptr()
|
||||
if sfp != nil {
|
||||
dfp := dst.getInt32Ptr()
|
||||
if dfp == nil {
|
||||
dst.setInt32Ptr(*sfp)
|
||||
} else {
|
||||
*dfp = *sfp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., int32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toInt32(); v != 0 {
|
||||
*dst.toInt32() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Int64:
|
||||
switch {
|
||||
case isSlice: // E.g., []int64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toInt64Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toInt64Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []int64{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *int64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toInt64Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toInt64Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Int64(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., int64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toInt64(); v != 0 {
|
||||
*dst.toInt64() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Uint32:
|
||||
switch {
|
||||
case isSlice: // E.g., []uint32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toUint32Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toUint32Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []uint32{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *uint32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toUint32Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toUint32Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Uint32(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., uint32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toUint32(); v != 0 {
|
||||
*dst.toUint32() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Uint64:
|
||||
switch {
|
||||
case isSlice: // E.g., []uint64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toUint64Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toUint64Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []uint64{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *uint64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toUint64Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toUint64Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Uint64(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., uint64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toUint64(); v != 0 {
|
||||
*dst.toUint64() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Float32:
|
||||
switch {
|
||||
case isSlice: // E.g., []float32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toFloat32Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toFloat32Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []float32{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *float32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toFloat32Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toFloat32Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Float32(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., float32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toFloat32(); v != 0 {
|
||||
*dst.toFloat32() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Float64:
|
||||
switch {
|
||||
case isSlice: // E.g., []float64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toFloat64Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toFloat64Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []float64{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *float64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toFloat64Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toFloat64Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Float64(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., float64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toFloat64(); v != 0 {
|
||||
*dst.toFloat64() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Bool:
|
||||
switch {
|
||||
case isSlice: // E.g., []bool
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toBoolSlice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toBoolSlice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []bool{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *bool
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toBoolPtr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toBoolPtr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Bool(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., bool
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toBool(); v {
|
||||
*dst.toBool() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
switch {
|
||||
case isSlice: // E.g., []string
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toStringSlice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toStringSlice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []string{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *string
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toStringPtr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toStringPtr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = String(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., string
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toString(); v != "" {
|
||||
*dst.toString() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
isProto3 := props.Prop[i].proto3
|
||||
switch {
|
||||
case isPointer:
|
||||
panic("bad pointer in byte slice case in " + tf.Name())
|
||||
case tf.Elem().Kind() != reflect.Uint8:
|
||||
panic("bad element kind in byte slice case in " + tf.Name())
|
||||
case isSlice: // E.g., [][]byte
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sbsp := src.toBytesSlice()
|
||||
if *sbsp != nil {
|
||||
dbsp := dst.toBytesSlice()
|
||||
for _, sb := range *sbsp {
|
||||
if sb == nil {
|
||||
*dbsp = append(*dbsp, nil)
|
||||
} else {
|
||||
*dbsp = append(*dbsp, append([]byte{}, sb...))
|
||||
}
|
||||
}
|
||||
if *dbsp == nil {
|
||||
*dbsp = [][]byte{}
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., []byte
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sbp := src.toBytes()
|
||||
if *sbp != nil {
|
||||
dbp := dst.toBytes()
|
||||
if !isProto3 || len(*sbp) > 0 {
|
||||
*dbp = append([]byte{}, *sbp...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
switch {
|
||||
case !isPointer:
|
||||
mergeInfo := getMergeInfo(tf)
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
mergeInfo.merge(dst, src)
|
||||
}
|
||||
case isSlice: // E.g., []*pb.T
|
||||
mergeInfo := getMergeInfo(tf)
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sps := src.getPointerSlice()
|
||||
if sps != nil {
|
||||
dps := dst.getPointerSlice()
|
||||
for _, sp := range sps {
|
||||
var dp pointer
|
||||
if !sp.isNil() {
|
||||
dp = valToPointer(reflect.New(tf))
|
||||
mergeInfo.merge(dp, sp)
|
||||
}
|
||||
dps = append(dps, dp)
|
||||
}
|
||||
if dps == nil {
|
||||
dps = []pointer{}
|
||||
}
|
||||
dst.setPointerSlice(dps)
|
||||
}
|
||||
}
|
||||
default: // E.g., *pb.T
|
||||
mergeInfo := getMergeInfo(tf)
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sp := src.getPointer()
|
||||
if !sp.isNil() {
|
||||
dp := dst.getPointer()
|
||||
if dp.isNil() {
|
||||
dp = valToPointer(reflect.New(tf))
|
||||
dst.setPointer(dp)
|
||||
}
|
||||
mergeInfo.merge(dp, sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic("bad pointer or slice in map case in " + tf.Name())
|
||||
default: // E.g., map[K]V
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sm := src.asPointerTo(tf).Elem()
|
||||
if sm.Len() == 0 {
|
||||
return
|
||||
}
|
||||
dm := dst.asPointerTo(tf).Elem()
|
||||
if dm.IsNil() {
|
||||
dm.Set(reflect.MakeMap(tf))
|
||||
}
|
||||
|
||||
switch tf.Elem().Kind() {
|
||||
case reflect.Ptr: // Proto struct (e.g., *T)
|
||||
for _, key := range sm.MapKeys() {
|
||||
val := sm.MapIndex(key)
|
||||
val = reflect.ValueOf(Clone(val.Interface().(Message)))
|
||||
dm.SetMapIndex(key, val)
|
||||
}
|
||||
case reflect.Slice: // E.g. Bytes type (e.g., []byte)
|
||||
for _, key := range sm.MapKeys() {
|
||||
val := sm.MapIndex(key)
|
||||
val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
|
||||
dm.SetMapIndex(key, val)
|
||||
}
|
||||
default: // Basic type (e.g., string)
|
||||
for _, key := range sm.MapKeys() {
|
||||
val := sm.MapIndex(key)
|
||||
dm.SetMapIndex(key, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Interface:
|
||||
// Must be oneof field.
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic("bad pointer or slice in interface case in " + tf.Name())
|
||||
default: // E.g., interface{}
|
||||
// TODO: Make this faster?
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
su := src.asPointerTo(tf).Elem()
|
||||
if !su.IsNil() {
|
||||
du := dst.asPointerTo(tf).Elem()
|
||||
typ := su.Elem().Type()
|
||||
if du.IsNil() || du.Elem().Type() != typ {
|
||||
du.Set(reflect.New(typ.Elem())) // Initialize interface if empty
|
||||
}
|
||||
sv := su.Elem().Elem().Field(0)
|
||||
if sv.Kind() == reflect.Ptr && sv.IsNil() {
|
||||
return
|
||||
}
|
||||
dv := du.Elem().Elem().Field(0)
|
||||
if dv.Kind() == reflect.Ptr && dv.IsNil() {
|
||||
dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty
|
||||
}
|
||||
switch sv.Type().Kind() {
|
||||
case reflect.Ptr: // Proto struct (e.g., *T)
|
||||
Merge(dv.Interface().(Message), sv.Interface().(Message))
|
||||
case reflect.Slice: // E.g. Bytes type (e.g., []byte)
|
||||
dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...)))
|
||||
default: // Basic type (e.g., string)
|
||||
dv.Set(sv)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("merger not found for type:%s", tf))
|
||||
}
|
||||
mi.fields = append(mi.fields, mfi)
|
||||
}
|
||||
|
||||
mi.unrecognized = invalidField
|
||||
if f, ok := t.FieldByName("XXX_unrecognized"); ok {
|
||||
if f.Type != reflect.TypeOf([]byte{}) {
|
||||
panic("expected XXX_unrecognized to be of type []byte")
|
||||
}
|
||||
mi.unrecognized = toField(&f)
|
||||
}
|
||||
|
||||
atomic.StoreInt32(&mi.initialized, 1)
|
||||
}
|
2245
vendor/github.com/gogo/protobuf/proto/table_unmarshal.go
generated
vendored
Normal file
2245
vendor/github.com/gogo/protobuf/proto/table_unmarshal.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
385
vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go
generated
vendored
Normal file
385
vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,385 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func makeUnmarshalMessage(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
// First read the message field to see if something is there.
|
||||
// The semantics of multiple submessages are weird. Instead of
|
||||
// the last one winning (as it is for all other fields), multiple
|
||||
// submessages are merged.
|
||||
v := f // gogo: changed from v := f.getPointer()
|
||||
if v.isNil() {
|
||||
v = valToPointer(reflect.New(sub.typ))
|
||||
f.setPointer(v)
|
||||
}
|
||||
err := sub.unmarshal(v, b[:x])
|
||||
if err != nil {
|
||||
if r, ok := err.(*RequiredNotSetError); ok {
|
||||
r.field = name + "." + r.field
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return b[x:], err
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalMessageSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
v := valToPointer(reflect.New(sub.typ))
|
||||
err := sub.unmarshal(v, b[:x])
|
||||
if err != nil {
|
||||
if r, ok := err.(*RequiredNotSetError); ok {
|
||||
r.field = name + "." + r.field
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
f.appendRef(v, sub.typ) // gogo: changed from f.appendPointer(v)
|
||||
return b[x:], err
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalCustomPtr(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
|
||||
s.Set(reflect.New(sub.typ))
|
||||
m := s.Interface().(custom)
|
||||
if err := m.Unmarshal(b[:x]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalCustomSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := reflect.New(sub.typ)
|
||||
c := m.Interface().(custom)
|
||||
if err := c.Unmarshal(b[:x]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v := valToPointer(m)
|
||||
f.appendRef(v, sub.typ)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalCustom(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
m := f.asPointerTo(sub.typ).Interface().(custom)
|
||||
if err := m.Unmarshal(b[:x]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalTime(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := ×tamp{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := timestampFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := f.asPointerTo(sub.typ).Elem()
|
||||
s.Set(reflect.ValueOf(t))
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalTimePtr(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := ×tamp{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := timestampFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
|
||||
s.Set(reflect.ValueOf(&t))
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalTimePtrSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := ×tamp{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := timestampFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slice := f.getSlice(reflect.PtrTo(sub.typ))
|
||||
newSlice := reflect.Append(slice, reflect.ValueOf(&t))
|
||||
slice.Set(newSlice)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalTimeSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := ×tamp{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := timestampFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slice := f.getSlice(sub.typ)
|
||||
newSlice := reflect.Append(slice, reflect.ValueOf(t))
|
||||
slice.Set(newSlice)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalDurationPtr(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := &duration{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d, err := durationFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
|
||||
s.Set(reflect.ValueOf(&d))
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalDuration(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := &duration{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d, err := durationFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := f.asPointerTo(sub.typ).Elem()
|
||||
s.Set(reflect.ValueOf(d))
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalDurationPtrSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := &duration{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d, err := durationFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slice := f.getSlice(reflect.PtrTo(sub.typ))
|
||||
newSlice := reflect.Append(slice, reflect.ValueOf(&d))
|
||||
slice.Set(newSlice)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalDurationSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := &duration{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d, err := durationFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slice := f.getSlice(sub.typ)
|
||||
newSlice := reflect.Append(slice, reflect.ValueOf(d))
|
||||
slice.Set(newSlice)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
928
vendor/github.com/gogo/protobuf/proto/text.go
generated
vendored
Normal file
928
vendor/github.com/gogo/protobuf/proto/text.go
generated
vendored
Normal file
|
@ -0,0 +1,928 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
// Functions for writing the text protocol buffer format.
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
newline = []byte("\n")
|
||||
spaces = []byte(" ")
|
||||
endBraceNewline = []byte("}\n")
|
||||
backslashN = []byte{'\\', 'n'}
|
||||
backslashR = []byte{'\\', 'r'}
|
||||
backslashT = []byte{'\\', 't'}
|
||||
backslashDQ = []byte{'\\', '"'}
|
||||
backslashBS = []byte{'\\', '\\'}
|
||||
posInf = []byte("inf")
|
||||
negInf = []byte("-inf")
|
||||
nan = []byte("nan")
|
||||
)
|
||||
|
||||
type writer interface {
|
||||
io.Writer
|
||||
WriteByte(byte) error
|
||||
}
|
||||
|
||||
// textWriter is an io.Writer that tracks its indentation level.
|
||||
type textWriter struct {
|
||||
ind int
|
||||
complete bool // if the current position is a complete line
|
||||
compact bool // whether to write out as a one-liner
|
||||
w writer
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteString(s string) (n int, err error) {
|
||||
if !strings.Contains(s, "\n") {
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
w.complete = false
|
||||
return io.WriteString(w.w, s)
|
||||
}
|
||||
// WriteString is typically called without newlines, so this
|
||||
// codepath and its copy are rare. We copy to avoid
|
||||
// duplicating all of Write's logic here.
|
||||
return w.Write([]byte(s))
|
||||
}
|
||||
|
||||
func (w *textWriter) Write(p []byte) (n int, err error) {
|
||||
newlines := bytes.Count(p, newline)
|
||||
if newlines == 0 {
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
n, err = w.w.Write(p)
|
||||
w.complete = false
|
||||
return n, err
|
||||
}
|
||||
|
||||
frags := bytes.SplitN(p, newline, newlines+1)
|
||||
if w.compact {
|
||||
for i, frag := range frags {
|
||||
if i > 0 {
|
||||
if err := w.w.WriteByte(' '); err != nil {
|
||||
return n, err
|
||||
}
|
||||
n++
|
||||
}
|
||||
nn, err := w.w.Write(frag)
|
||||
n += nn
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
for i, frag := range frags {
|
||||
if w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
nn, err := w.w.Write(frag)
|
||||
n += nn
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
if i+1 < len(frags) {
|
||||
if err := w.w.WriteByte('\n'); err != nil {
|
||||
return n, err
|
||||
}
|
||||
n++
|
||||
}
|
||||
}
|
||||
w.complete = len(frags[len(frags)-1]) == 0
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteByte(c byte) error {
|
||||
if w.compact && c == '\n' {
|
||||
c = ' '
|
||||
}
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
err := w.w.WriteByte(c)
|
||||
w.complete = c == '\n'
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *textWriter) indent() { w.ind++ }
|
||||
|
||||
func (w *textWriter) unindent() {
|
||||
if w.ind == 0 {
|
||||
log.Print("proto: textWriter unindented too far")
|
||||
return
|
||||
}
|
||||
w.ind--
|
||||
}
|
||||
|
||||
func writeName(w *textWriter, props *Properties) error {
|
||||
if _, err := w.WriteString(props.OrigName); err != nil {
|
||||
return err
|
||||
}
|
||||
if props.Wire != "group" {
|
||||
return w.WriteByte(':')
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func requiresQuotes(u string) bool {
|
||||
// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
|
||||
for _, ch := range u {
|
||||
switch {
|
||||
case ch == '.' || ch == '/' || ch == '_':
|
||||
continue
|
||||
case '0' <= ch && ch <= '9':
|
||||
continue
|
||||
case 'A' <= ch && ch <= 'Z':
|
||||
continue
|
||||
case 'a' <= ch && ch <= 'z':
|
||||
continue
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isAny reports whether sv is a google.protobuf.Any message
|
||||
func isAny(sv reflect.Value) bool {
|
||||
type wkt interface {
|
||||
XXX_WellKnownType() string
|
||||
}
|
||||
t, ok := sv.Addr().Interface().(wkt)
|
||||
return ok && t.XXX_WellKnownType() == "Any"
|
||||
}
|
||||
|
||||
// writeProto3Any writes an expanded google.protobuf.Any message.
|
||||
//
|
||||
// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
|
||||
// required messages are not linked in).
|
||||
//
|
||||
// It returns (true, error) when sv was written in expanded format or an error
|
||||
// was encountered.
|
||||
func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
|
||||
turl := sv.FieldByName("TypeUrl")
|
||||
val := sv.FieldByName("Value")
|
||||
if !turl.IsValid() || !val.IsValid() {
|
||||
return true, errors.New("proto: invalid google.protobuf.Any message")
|
||||
}
|
||||
|
||||
b, ok := val.Interface().([]byte)
|
||||
if !ok {
|
||||
return true, errors.New("proto: invalid google.protobuf.Any message")
|
||||
}
|
||||
|
||||
parts := strings.Split(turl.String(), "/")
|
||||
mt := MessageType(parts[len(parts)-1])
|
||||
if mt == nil {
|
||||
return false, nil
|
||||
}
|
||||
m := reflect.New(mt.Elem())
|
||||
if err := Unmarshal(b, m.Interface().(Message)); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
w.Write([]byte("["))
|
||||
u := turl.String()
|
||||
if requiresQuotes(u) {
|
||||
writeString(w, u)
|
||||
} else {
|
||||
w.Write([]byte(u))
|
||||
}
|
||||
if w.compact {
|
||||
w.Write([]byte("]:<"))
|
||||
} else {
|
||||
w.Write([]byte("]: <\n"))
|
||||
w.ind++
|
||||
}
|
||||
if err := tm.writeStruct(w, m.Elem()); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if w.compact {
|
||||
w.Write([]byte("> "))
|
||||
} else {
|
||||
w.ind--
|
||||
w.Write([]byte(">\n"))
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
|
||||
if tm.ExpandAny && isAny(sv) {
|
||||
if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
|
||||
return err
|
||||
}
|
||||
}
|
||||
st := sv.Type()
|
||||
sprops := GetProperties(st)
|
||||
for i := 0; i < sv.NumField(); i++ {
|
||||
fv := sv.Field(i)
|
||||
props := sprops.Prop[i]
|
||||
name := st.Field(i).Name
|
||||
|
||||
if name == "XXX_NoUnkeyedLiteral" {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(name, "XXX_") {
|
||||
// There are two XXX_ fields:
|
||||
// XXX_unrecognized []byte
|
||||
// XXX_extensions map[int32]proto.Extension
|
||||
// The first is handled here;
|
||||
// the second is handled at the bottom of this function.
|
||||
if name == "XXX_unrecognized" && !fv.IsNil() {
|
||||
if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||
// Field not filled in. This could be an optional field or
|
||||
// a required field that wasn't filled in. Either way, there
|
||||
// isn't anything we can show for it.
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Slice && fv.IsNil() {
|
||||
// Repeated field that is empty, or a bytes field that is unused.
|
||||
continue
|
||||
}
|
||||
|
||||
if props.Repeated && fv.Kind() == reflect.Slice {
|
||||
// Repeated field.
|
||||
for j := 0; j < fv.Len(); j++ {
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
v := fv.Index(j)
|
||||
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
// A nil message in a repeated field is not valid,
|
||||
// but we can handle that more gracefully than panicking.
|
||||
if _, err := w.Write([]byte("<nil>\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if len(props.Enum) > 0 {
|
||||
if err := tm.writeEnum(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := tm.writeAny(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Map {
|
||||
// Map fields are rendered as a repeated struct with key/value fields.
|
||||
keys := fv.MapKeys()
|
||||
sort.Sort(mapKeys(keys))
|
||||
for _, key := range keys {
|
||||
val := fv.MapIndex(key)
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// open struct
|
||||
if err := w.WriteByte('<'); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.indent()
|
||||
// key
|
||||
if _, err := w.WriteString("key:"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
// nil values aren't legal, but we can avoid panicking because of them.
|
||||
if val.Kind() != reflect.Ptr || !val.IsNil() {
|
||||
// value
|
||||
if _, err := w.WriteString("value:"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, val, props.MapValProp); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// close struct
|
||||
w.unindent()
|
||||
if err := w.WriteByte('>'); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
|
||||
// empty bytes field
|
||||
continue
|
||||
}
|
||||
if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
|
||||
// proto3 non-repeated scalar field; skip if zero value
|
||||
if isProto3Zero(fv) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if fv.Kind() == reflect.Interface {
|
||||
// Check if it is a oneof.
|
||||
if st.Field(i).Tag.Get("protobuf_oneof") != "" {
|
||||
// fv is nil, or holds a pointer to generated struct.
|
||||
// That generated struct has exactly one field,
|
||||
// which has a protobuf struct tag.
|
||||
if fv.IsNil() {
|
||||
continue
|
||||
}
|
||||
inner := fv.Elem().Elem() // interface -> *T -> T
|
||||
tag := inner.Type().Field(0).Tag.Get("protobuf")
|
||||
props = new(Properties) // Overwrite the outer props var, but not its pointee.
|
||||
props.Parse(tag)
|
||||
// Write the value in the oneof, not the oneof itself.
|
||||
fv = inner.Field(0)
|
||||
|
||||
// Special case to cope with malformed messages gracefully:
|
||||
// If the value in the oneof is a nil pointer, don't panic
|
||||
// in writeAny.
|
||||
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||
// Use errors.New so writeAny won't render quotes.
|
||||
msg := errors.New("/* nil */")
|
||||
fv = reflect.ValueOf(&msg).Elem()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(props.Enum) > 0 {
|
||||
if err := tm.writeEnum(w, fv, props); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := tm.writeAny(w, fv, props); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Extensions (the XXX_extensions field).
|
||||
pv := sv
|
||||
if pv.CanAddr() {
|
||||
pv = sv.Addr()
|
||||
} else {
|
||||
pv = reflect.New(sv.Type())
|
||||
pv.Elem().Set(sv)
|
||||
}
|
||||
if _, err := extendable(pv.Interface()); err == nil {
|
||||
if err := tm.writeExtensions(w, pv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeAny writes an arbitrary field.
|
||||
func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
||||
v = reflect.Indirect(v)
|
||||
|
||||
if props != nil {
|
||||
if len(props.CustomType) > 0 {
|
||||
custom, ok := v.Interface().(Marshaler)
|
||||
if ok {
|
||||
data, err := custom.Marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeString(w, string(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
} else if len(props.CastType) > 0 {
|
||||
if _, ok := v.Interface().(interface {
|
||||
String() string
|
||||
}); ok {
|
||||
switch v.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
_, err := fmt.Fprintf(w, "%d", v.Interface())
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if props.StdTime {
|
||||
t, ok := v.Interface().(time.Time)
|
||||
if !ok {
|
||||
return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface())
|
||||
}
|
||||
tproto, err := timestampProto(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
propsCopy := *props // Make a copy so that this is goroutine-safe
|
||||
propsCopy.StdTime = false
|
||||
err = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy)
|
||||
return err
|
||||
} else if props.StdDuration {
|
||||
d, ok := v.Interface().(time.Duration)
|
||||
if !ok {
|
||||
return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface())
|
||||
}
|
||||
dproto := durationProto(d)
|
||||
propsCopy := *props // Make a copy so that this is goroutine-safe
|
||||
propsCopy.StdDuration = false
|
||||
err := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Floats have special cases.
|
||||
if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
|
||||
x := v.Float()
|
||||
var b []byte
|
||||
switch {
|
||||
case math.IsInf(x, 1):
|
||||
b = posInf
|
||||
case math.IsInf(x, -1):
|
||||
b = negInf
|
||||
case math.IsNaN(x):
|
||||
b = nan
|
||||
}
|
||||
if b != nil {
|
||||
_, err := w.Write(b)
|
||||
return err
|
||||
}
|
||||
// Other values are handled below.
|
||||
}
|
||||
|
||||
// We don't attempt to serialise every possible value type; only those
|
||||
// that can occur in protocol buffers.
|
||||
switch v.Kind() {
|
||||
case reflect.Slice:
|
||||
// Should only be a []byte; repeated fields are handled in writeStruct.
|
||||
if err := writeString(w, string(v.Bytes())); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.String:
|
||||
if err := writeString(w, v.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.Struct:
|
||||
// Required/optional group/message.
|
||||
var bra, ket byte = '<', '>'
|
||||
if props != nil && props.Wire == "group" {
|
||||
bra, ket = '{', '}'
|
||||
}
|
||||
if err := w.WriteByte(bra); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.indent()
|
||||
if v.CanAddr() {
|
||||
// Calling v.Interface on a struct causes the reflect package to
|
||||
// copy the entire struct. This is racy with the new Marshaler
|
||||
// since we atomically update the XXX_sizecache.
|
||||
//
|
||||
// Thus, we retrieve a pointer to the struct if possible to avoid
|
||||
// a race since v.Interface on the pointer doesn't copy the struct.
|
||||
//
|
||||
// If v is not addressable, then we are not worried about a race
|
||||
// since it implies that the binary Marshaler cannot possibly be
|
||||
// mutating this value.
|
||||
v = v.Addr()
|
||||
}
|
||||
if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
|
||||
text, err := etm.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = w.Write(text); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
if err := tm.writeStruct(w, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.unindent()
|
||||
if err := w.WriteByte(ket); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
_, err := fmt.Fprint(w, v.Interface())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// equivalent to C's isprint.
|
||||
func isprint(c byte) bool {
|
||||
return c >= 0x20 && c < 0x7f
|
||||
}
|
||||
|
||||
// writeString writes a string in the protocol buffer text format.
|
||||
// It is similar to strconv.Quote except we don't use Go escape sequences,
|
||||
// we treat the string as a byte sequence, and we use octal escapes.
|
||||
// These differences are to maintain interoperability with the other
|
||||
// languages' implementations of the text format.
|
||||
func writeString(w *textWriter, s string) error {
|
||||
// use WriteByte here to get any needed indent
|
||||
if err := w.WriteByte('"'); err != nil {
|
||||
return err
|
||||
}
|
||||
// Loop over the bytes, not the runes.
|
||||
for i := 0; i < len(s); i++ {
|
||||
var err error
|
||||
// Divergence from C++: we don't escape apostrophes.
|
||||
// There's no need to escape them, and the C++ parser
|
||||
// copes with a naked apostrophe.
|
||||
switch c := s[i]; c {
|
||||
case '\n':
|
||||
_, err = w.w.Write(backslashN)
|
||||
case '\r':
|
||||
_, err = w.w.Write(backslashR)
|
||||
case '\t':
|
||||
_, err = w.w.Write(backslashT)
|
||||
case '"':
|
||||
_, err = w.w.Write(backslashDQ)
|
||||
case '\\':
|
||||
_, err = w.w.Write(backslashBS)
|
||||
default:
|
||||
if isprint(c) {
|
||||
err = w.w.WriteByte(c)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w.w, "\\%03o", c)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return w.WriteByte('"')
|
||||
}
|
||||
|
||||
func writeUnknownStruct(w *textWriter, data []byte) (err error) {
|
||||
if !w.compact {
|
||||
if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
b := NewBuffer(data)
|
||||
for b.index < len(b.buf) {
|
||||
x, err := b.DecodeVarint()
|
||||
if err != nil {
|
||||
_, ferr := fmt.Fprintf(w, "/* %v */\n", err)
|
||||
return ferr
|
||||
}
|
||||
wire, tag := x&7, x>>3
|
||||
if wire == WireEndGroup {
|
||||
w.unindent()
|
||||
if _, werr := w.Write(endBraceNewline); werr != nil {
|
||||
return werr
|
||||
}
|
||||
continue
|
||||
}
|
||||
if _, ferr := fmt.Fprint(w, tag); ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
if wire != WireStartGroup {
|
||||
if err = w.WriteByte(':'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !w.compact || wire == WireStartGroup {
|
||||
if err = w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
switch wire {
|
||||
case WireBytes:
|
||||
buf, e := b.DecodeRawBytes(false)
|
||||
if e == nil {
|
||||
_, err = fmt.Fprintf(w, "%q", buf)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w, "/* %v */", e)
|
||||
}
|
||||
case WireFixed32:
|
||||
x, err = b.DecodeFixed32()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
case WireFixed64:
|
||||
x, err = b.DecodeFixed64()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
case WireStartGroup:
|
||||
err = w.WriteByte('{')
|
||||
w.indent()
|
||||
case WireVarint:
|
||||
x, err = b.DecodeVarint()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
default:
|
||||
_, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeUnknownInt(w *textWriter, x uint64, err error) error {
|
||||
if err == nil {
|
||||
_, err = fmt.Fprint(w, x)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w, "/* %v */", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
type int32Slice []int32
|
||||
|
||||
func (s int32Slice) Len() int { return len(s) }
|
||||
func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
|
||||
func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// writeExtensions writes all the extensions in pv.
|
||||
// pv is assumed to be a pointer to a protocol message struct that is extendable.
|
||||
func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
|
||||
emap := extensionMaps[pv.Type().Elem()]
|
||||
e := pv.Interface().(Message)
|
||||
|
||||
var m map[int32]Extension
|
||||
var mu sync.Locker
|
||||
if em, ok := e.(extensionsBytes); ok {
|
||||
eb := em.GetExtensions()
|
||||
var err error
|
||||
m, err = BytesToExtensionsMap(*eb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mu = notLocker{}
|
||||
} else if _, ok := e.(extendableProto); ok {
|
||||
ep, _ := extendable(e)
|
||||
m, mu = ep.extensionsRead()
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Order the extensions by ID.
|
||||
// This isn't strictly necessary, but it will give us
|
||||
// canonical output, which will also make testing easier.
|
||||
|
||||
mu.Lock()
|
||||
ids := make([]int32, 0, len(m))
|
||||
for id := range m {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
sort.Sort(int32Slice(ids))
|
||||
mu.Unlock()
|
||||
|
||||
for _, extNum := range ids {
|
||||
ext := m[extNum]
|
||||
var desc *ExtensionDesc
|
||||
if emap != nil {
|
||||
desc = emap[extNum]
|
||||
}
|
||||
if desc == nil {
|
||||
// Unknown extension.
|
||||
if err := writeUnknownStruct(w, ext.enc); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
pb, err := GetExtension(e, desc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed getting extension: %v", err)
|
||||
}
|
||||
|
||||
// Repeated extensions will appear as a slice.
|
||||
if !desc.repeated() {
|
||||
if err := tm.writeExtension(w, desc.Name, pb); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
v := reflect.ValueOf(pb)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
|
||||
if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *textWriter) writeIndent() {
|
||||
if !w.complete {
|
||||
return
|
||||
}
|
||||
remain := w.ind * 2
|
||||
for remain > 0 {
|
||||
n := remain
|
||||
if n > len(spaces) {
|
||||
n = len(spaces)
|
||||
}
|
||||
w.w.Write(spaces[:n])
|
||||
remain -= n
|
||||
}
|
||||
w.complete = false
|
||||
}
|
||||
|
||||
// TextMarshaler is a configurable text format marshaler.
|
||||
type TextMarshaler struct {
|
||||
Compact bool // use compact text format (one line).
|
||||
ExpandAny bool // expand google.protobuf.Any messages of known types
|
||||
}
|
||||
|
||||
// Marshal writes a given protocol buffer in text format.
|
||||
// The only errors returned are from w.
|
||||
func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
||||
val := reflect.ValueOf(pb)
|
||||
if pb == nil || val.IsNil() {
|
||||
w.Write([]byte("<nil>"))
|
||||
return nil
|
||||
}
|
||||
var bw *bufio.Writer
|
||||
ww, ok := w.(writer)
|
||||
if !ok {
|
||||
bw = bufio.NewWriter(w)
|
||||
ww = bw
|
||||
}
|
||||
aw := &textWriter{
|
||||
w: ww,
|
||||
complete: true,
|
||||
compact: tm.Compact,
|
||||
}
|
||||
|
||||
if etm, ok := pb.(encoding.TextMarshaler); ok {
|
||||
text, err := etm.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = aw.Write(text); err != nil {
|
||||
return err
|
||||
}
|
||||
if bw != nil {
|
||||
return bw.Flush()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// Dereference the received pointer so we don't have outer < and >.
|
||||
v := reflect.Indirect(val)
|
||||
if err := tm.writeStruct(aw, v); err != nil {
|
||||
return err
|
||||
}
|
||||
if bw != nil {
|
||||
return bw.Flush()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Text is the same as Marshal, but returns the string directly.
|
||||
func (tm *TextMarshaler) Text(pb Message) string {
|
||||
var buf bytes.Buffer
|
||||
tm.Marshal(&buf, pb)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
var (
|
||||
defaultTextMarshaler = TextMarshaler{}
|
||||
compactTextMarshaler = TextMarshaler{Compact: true}
|
||||
)
|
||||
|
||||
// TODO: consider removing some of the Marshal functions below.
|
||||
|
||||
// MarshalText writes a given protocol buffer in text format.
|
||||
// The only errors returned are from w.
|
||||
func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
|
||||
|
||||
// MarshalTextString is the same as MarshalText, but returns the string directly.
|
||||
func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
|
||||
|
||||
// CompactText writes a given protocol buffer in compact text format (one line).
|
||||
func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
|
||||
|
||||
// CompactTextString is the same as CompactText, but returns the string directly.
|
||||
func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }
|
57
vendor/github.com/gogo/protobuf/proto/text_gogo.go
generated
vendored
Normal file
57
vendor/github.com/gogo/protobuf/proto/text_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error {
|
||||
m, ok := enumStringMaps[props.Enum]
|
||||
if !ok {
|
||||
if err := tm.writeAny(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
key := int32(0)
|
||||
if v.Kind() == reflect.Ptr {
|
||||
key = int32(v.Elem().Int())
|
||||
} else {
|
||||
key = int32(v.Int())
|
||||
}
|
||||
s, ok := m[key]
|
||||
if !ok {
|
||||
if err := tm.writeAny(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err := fmt.Fprint(w, s)
|
||||
return err
|
||||
}
|
1018
vendor/github.com/gogo/protobuf/proto/text_parser.go
generated
vendored
Normal file
1018
vendor/github.com/gogo/protobuf/proto/text_parser.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
113
vendor/github.com/gogo/protobuf/proto/timestamp.go
generated
vendored
Normal file
113
vendor/github.com/gogo/protobuf/proto/timestamp.go
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
// This file implements operations on google.protobuf.Timestamp.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// Seconds field of the earliest valid Timestamp.
|
||||
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
minValidSeconds = -62135596800
|
||||
// Seconds field just after the latest valid Timestamp.
|
||||
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
maxValidSeconds = 253402300800
|
||||
)
|
||||
|
||||
// validateTimestamp determines whether a Timestamp is valid.
|
||||
// A valid timestamp represents a time in the range
|
||||
// [0001-01-01, 10000-01-01) and has a Nanos field
|
||||
// in the range [0, 1e9).
|
||||
//
|
||||
// If the Timestamp is valid, validateTimestamp returns nil.
|
||||
// Otherwise, it returns an error that describes
|
||||
// the problem.
|
||||
//
|
||||
// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
|
||||
func validateTimestamp(ts *timestamp) error {
|
||||
if ts == nil {
|
||||
return errors.New("timestamp: nil Timestamp")
|
||||
}
|
||||
if ts.Seconds < minValidSeconds {
|
||||
return fmt.Errorf("timestamp: %#v before 0001-01-01", ts)
|
||||
}
|
||||
if ts.Seconds >= maxValidSeconds {
|
||||
return fmt.Errorf("timestamp: %#v after 10000-01-01", ts)
|
||||
}
|
||||
if ts.Nanos < 0 || ts.Nanos >= 1e9 {
|
||||
return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time.
|
||||
// It returns an error if the argument is invalid.
|
||||
//
|
||||
// Unlike most Go functions, if Timestamp returns an error, the first return value
|
||||
// is not the zero time.Time. Instead, it is the value obtained from the
|
||||
// time.Unix function when passed the contents of the Timestamp, in the UTC
|
||||
// locale. This may or may not be a meaningful time; many invalid Timestamps
|
||||
// do map to valid time.Times.
|
||||
//
|
||||
// A nil Timestamp returns an error. The first return value in that case is
|
||||
// undefined.
|
||||
func timestampFromProto(ts *timestamp) (time.Time, error) {
|
||||
// Don't return the zero value on error, because corresponds to a valid
|
||||
// timestamp. Instead return whatever time.Unix gives us.
|
||||
var t time.Time
|
||||
if ts == nil {
|
||||
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
|
||||
} else {
|
||||
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
|
||||
}
|
||||
return t, validateTimestamp(ts)
|
||||
}
|
||||
|
||||
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
|
||||
// It returns an error if the resulting Timestamp is invalid.
|
||||
func timestampProto(t time.Time) (*timestamp, error) {
|
||||
seconds := t.Unix()
|
||||
nanos := int32(t.Sub(time.Unix(seconds, 0)))
|
||||
ts := ×tamp{
|
||||
Seconds: seconds,
|
||||
Nanos: nanos,
|
||||
}
|
||||
if err := validateTimestamp(ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ts, nil
|
||||
}
|
49
vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go
generated
vendored
Normal file
49
vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
var timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
||||
|
||||
type timestamp struct {
|
||||
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
|
||||
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
|
||||
}
|
||||
|
||||
func (m *timestamp) Reset() { *m = timestamp{} }
|
||||
func (*timestamp) ProtoMessage() {}
|
||||
func (*timestamp) String() string { return "timestamp<string>" }
|
||||
|
||||
func init() {
|
||||
RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp")
|
||||
}
|
1888
vendor/github.com/gogo/protobuf/proto/wrappers.go
generated
vendored
Normal file
1888
vendor/github.com/gogo/protobuf/proto/wrappers.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
113
vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go
generated
vendored
Normal file
113
vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
type float64Value struct {
|
||||
Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *float64Value) Reset() { *m = float64Value{} }
|
||||
func (*float64Value) ProtoMessage() {}
|
||||
func (*float64Value) String() string { return "float64<string>" }
|
||||
|
||||
type float32Value struct {
|
||||
Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *float32Value) Reset() { *m = float32Value{} }
|
||||
func (*float32Value) ProtoMessage() {}
|
||||
func (*float32Value) String() string { return "float32<string>" }
|
||||
|
||||
type int64Value struct {
|
||||
Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *int64Value) Reset() { *m = int64Value{} }
|
||||
func (*int64Value) ProtoMessage() {}
|
||||
func (*int64Value) String() string { return "int64<string>" }
|
||||
|
||||
type uint64Value struct {
|
||||
Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *uint64Value) Reset() { *m = uint64Value{} }
|
||||
func (*uint64Value) ProtoMessage() {}
|
||||
func (*uint64Value) String() string { return "uint64<string>" }
|
||||
|
||||
type int32Value struct {
|
||||
Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *int32Value) Reset() { *m = int32Value{} }
|
||||
func (*int32Value) ProtoMessage() {}
|
||||
func (*int32Value) String() string { return "int32<string>" }
|
||||
|
||||
type uint32Value struct {
|
||||
Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *uint32Value) Reset() { *m = uint32Value{} }
|
||||
func (*uint32Value) ProtoMessage() {}
|
||||
func (*uint32Value) String() string { return "uint32<string>" }
|
||||
|
||||
type boolValue struct {
|
||||
Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *boolValue) Reset() { *m = boolValue{} }
|
||||
func (*boolValue) ProtoMessage() {}
|
||||
func (*boolValue) String() string { return "bool<string>" }
|
||||
|
||||
type stringValue struct {
|
||||
Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *stringValue) Reset() { *m = stringValue{} }
|
||||
func (*stringValue) ProtoMessage() {}
|
||||
func (*stringValue) String() string { return "string<string>" }
|
||||
|
||||
type bytesValue struct {
|
||||
Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *bytesValue) Reset() { *m = bytesValue{} }
|
||||
func (*bytesValue) ProtoMessage() {}
|
||||
func (*bytesValue) String() string { return "[]byte<string>" }
|
||||
|
||||
func init() {
|
||||
RegisterType((*float64Value)(nil), "gogo.protobuf.proto.DoubleValue")
|
||||
RegisterType((*float32Value)(nil), "gogo.protobuf.proto.FloatValue")
|
||||
RegisterType((*int64Value)(nil), "gogo.protobuf.proto.Int64Value")
|
||||
RegisterType((*uint64Value)(nil), "gogo.protobuf.proto.UInt64Value")
|
||||
RegisterType((*int32Value)(nil), "gogo.protobuf.proto.Int32Value")
|
||||
RegisterType((*uint32Value)(nil), "gogo.protobuf.proto.UInt32Value")
|
||||
RegisterType((*boolValue)(nil), "gogo.protobuf.proto.BoolValue")
|
||||
RegisterType((*stringValue)(nil), "gogo.protobuf.proto.StringValue")
|
||||
RegisterType((*bytesValue)(nil), "gogo.protobuf.proto.BytesValue")
|
||||
}
|
1
vendor/github.com/minio/sha256-simd/.gitignore
generated
vendored
Normal file
1
vendor/github.com/minio/sha256-simd/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.test
|
24
vendor/github.com/minio/sha256-simd/.travis.yml
generated
vendored
Normal file
24
vendor/github.com/minio/sha256-simd/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
sudo: required
|
||||
dist: trusty
|
||||
language: go
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
go:
|
||||
- tip
|
||||
- 1.11.x
|
||||
|
||||
env:
|
||||
- ARCH=x86_64
|
||||
- ARCH=i686
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
script:
|
||||
- diff -au <(gofmt -d .) <(printf "")
|
||||
- go test -race -v ./...
|
||||
- go tool vet -asmdecl .
|
202
vendor/github.com/minio/sha256-simd/LICENSE
generated
vendored
Normal file
202
vendor/github.com/minio/sha256-simd/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
133
vendor/github.com/minio/sha256-simd/README.md
generated
vendored
Normal file
133
vendor/github.com/minio/sha256-simd/README.md
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
# sha256-simd
|
||||
|
||||
Accelerate SHA256 computations in pure Go using AVX512, SHA Extensions and AVX2 for Intel and ARM64 for ARM. On AVX512 it provides an up to 8x improvement (over 3 GB/s per core) in comparison to AVX2. SHA Extensions give a performance boost of close to 4x over AVX2.
|
||||
|
||||
## Introduction
|
||||
|
||||
This package is designed as a replacement for `crypto/sha256`. For Intel CPUs it has two flavors for AVX512 and AVX2 (AVX/SSE are also supported). For ARM CPUs with the Cryptography Extensions, advantage is taken of the SHA2 instructions resulting in a massive performance improvement.
|
||||
|
||||
This package uses Golang assembly. The AVX512 version is based on the Intel's "multi-buffer crypto library for IPSec" whereas the other Intel implementations are described in "Fast SHA-256 Implementations on Intel Architecture Processors" by J. Guilford et al.
|
||||
|
||||
## New: Support for Intel SHA Extensions
|
||||
|
||||
Support for the Intel SHA Extensions has been added by Kristofer Peterson (@svenski123), originally developed for spacemeshos [here](https://github.com/spacemeshos/POET/issues/23). On CPUs that support it (known thus far Intel Celeron J3455 and AMD Ryzen) it gives a significant boost in performance (with thanks to @AudriusButkevicius for reporting the results; full results [here](https://github.com/minio/sha256-simd/pull/37#issuecomment-451607827)).
|
||||
|
||||
```
|
||||
$ benchcmp avx2.txt sha-ext.txt
|
||||
benchmark AVX2 MB/s SHA Ext MB/s speedup
|
||||
BenchmarkHash5M 514.40 1975.17 3.84x
|
||||
```
|
||||
|
||||
Thanks to Kristofer Peterson, we also added additional performance changes such as optimized padding, endian conversions which sped up all implementations i.e. Intel SHA alone while doubled performance for small sizes, the other changes increased everything roughly 50%.
|
||||
|
||||
## Support for AVX512
|
||||
|
||||
We have added support for AVX512 which results in an up to 8x performance improvement over AVX2 (3.0 GHz Xeon Platinum 8124M CPU):
|
||||
|
||||
```
|
||||
$ benchcmp avx2.txt avx512.txt
|
||||
benchmark AVX2 MB/s AVX512 MB/s speedup
|
||||
BenchmarkHash5M 448.62 3498.20 7.80x
|
||||
```
|
||||
|
||||
The original code was developed by Intel as part of the [multi-buffer crypto library](https://github.com/intel/intel-ipsec-mb) for IPSec or more specifically this [AVX512](https://github.com/intel/intel-ipsec-mb/blob/master/avx512/sha256_x16_avx512.asm) implementation. The key idea behind it is to process a total of 16 checksums in parallel by “transposing” 16 (independent) messages of 64 bytes between a total of 16 ZMM registers (each 64 bytes wide).
|
||||
|
||||
Transposing the input messages means that in order to take full advantage of the speedup you need to have a (server) workload where multiple threads are doing SHA256 calculations in parallel. Unfortunately for this algorithm it is not possible for two message blocks processed in parallel to be dependent on one another — because then the (interim) result of the first part of the message has to be an input into the processing of the second part of the message.
|
||||
|
||||
Whereas the original Intel C implementation requires some sort of explicit scheduling of messages to be processed in parallel, for Golang it makes sense to take advantage of channels in order to group messages together and use channels as well for sending back the results (thereby effectively decoupling the calculations). We have implemented a fairly simple scheduling mechanism that seems to work well in practice.
|
||||
|
||||
Due to this different way of scheduling, we decided to use an explicit method to instantiate the AVX512 version. Essentially one or more AVX512 processing servers ([`Avx512Server`](https://github.com/minio/sha256-simd/blob/master/sha256blockAvx512_amd64.go#L294)) have to be created whereby each server can hash over 3 GB/s on a single core. An `hash.Hash` object ([`Avx512Digest`](https://github.com/minio/sha256-simd/blob/master/sha256blockAvx512_amd64.go#L45)) is then instantiated using one of these servers and used in the regular fashion:
|
||||
|
||||
```go
|
||||
import "github.com/minio/sha256-simd"
|
||||
|
||||
func main() {
|
||||
server := sha256.NewAvx512Server()
|
||||
h512 := sha256.NewAvx512(server)
|
||||
h512.Write(fileBlock)
|
||||
digest := h512.Sum([]byte{})
|
||||
}
|
||||
```
|
||||
|
||||
Note that, because of the scheduling overhead, for small messages (< 1 MB) you will be better off using the regular SHA256 hashing (but those are typically not performance critical anyway). Some other tips to get the best performance:
|
||||
* Have many go routines doing SHA256 calculations in parallel.
|
||||
* Try to Write() messages in multiples of 64 bytes.
|
||||
* Try to keep the overall length of messages to a roughly similar size ie. 5 MB (this way all 16 ‘lanes’ in the AVX512 computations are contributing as much as possible).
|
||||
|
||||
More detailed information can be found in this [blog](https://blog.minio.io/accelerate-sha256-up-to-8x-over-3-gb-s-per-core-with-avx512-a0b1d64f78f) post including scaling across cores.
|
||||
|
||||
## Drop-In Replacement
|
||||
|
||||
The following code snippet shows how you can use `github.com/minio/sha256-simd`. This will automatically select the fastest method for the architecture on which it will be executed.
|
||||
|
||||
```go
|
||||
import "github.com/minio/sha256-simd"
|
||||
|
||||
func main() {
|
||||
...
|
||||
shaWriter := sha256.New()
|
||||
io.Copy(shaWriter, file)
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
Below is the speed in MB/s for a single core (ranked fast to slow) for blocks larger than 1 MB.
|
||||
|
||||
| Processor | SIMD | Speed (MB/s) |
|
||||
| --------------------------------- | ------- | ------------:|
|
||||
| 3.0 GHz Intel Xeon Platinum 8124M | AVX512 | 3498 |
|
||||
| 3.7 GHz AMD Ryzen 7 2700X | SHA Ext | 1979 |
|
||||
| 1.2 GHz ARM Cortex-A53 | ARM64 | 638 |
|
||||
| 3.0 GHz Intel Xeon Platinum 8124M | AVX2 | 449 |
|
||||
| 3.1 GHz Intel Core i7 | AVX | 362 |
|
||||
| 3.1 GHz Intel Core i7 | SSE | 299 |
|
||||
|
||||
## asm2plan9s
|
||||
|
||||
In order to be able to work more easily with AVX512/AVX2 instructions, a separate tool was developed to convert SIMD instructions into the corresponding BYTE sequence as accepted by Go assembly. See [asm2plan9s](https://github.com/minio/asm2plan9s) for more information.
|
||||
|
||||
## Why and benefits
|
||||
|
||||
One of the most performance sensitive parts of the [Minio](https://github.com/minio/minio) object storage server is related to SHA256 hash sums calculations. For instance during multi part uploads each part that is uploaded needs to be verified for data integrity by the server.
|
||||
|
||||
Other applications that can benefit from enhanced SHA256 performance are deduplication in storage systems, intrusion detection, version control systems, integrity checking, etc.
|
||||
|
||||
## ARM SHA Extensions
|
||||
|
||||
The 64-bit ARMv8 core has introduced new instructions for SHA1 and SHA2 acceleration as part of the [Cryptography Extensions](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0501f/CHDFJBCJ.html). Below you can see a small excerpt highlighting one of the rounds as is done for the SHA256 calculation process (for full code see [sha256block_arm64.s](https://github.com/minio/sha256-simd/blob/master/sha256block_arm64.s)).
|
||||
|
||||
```
|
||||
sha256h q2, q3, v9.4s
|
||||
sha256h2 q3, q4, v9.4s
|
||||
sha256su0 v5.4s, v6.4s
|
||||
rev32 v8.16b, v8.16b
|
||||
add v9.4s, v7.4s, v18.4s
|
||||
mov v4.16b, v2.16b
|
||||
sha256h q2, q3, v10.4s
|
||||
sha256h2 q3, q4, v10.4s
|
||||
sha256su0 v6.4s, v7.4s
|
||||
sha256su1 v5.4s, v7.4s, v8.4s
|
||||
```
|
||||
|
||||
### Detailed benchmarks
|
||||
|
||||
Benchmarks generated on a 1.2 Ghz Quad-Core ARM Cortex A53 equipped [Pine64](https://www.pine64.com/).
|
||||
|
||||
```
|
||||
minio@minio-arm:$ benchcmp golang.txt arm64.txt
|
||||
benchmark golang arm64 speedup
|
||||
BenchmarkHash8Bytes-4 0.68 MB/s 5.70 MB/s 8.38x
|
||||
BenchmarkHash1K-4 5.65 MB/s 326.30 MB/s 57.75x
|
||||
BenchmarkHash8K-4 6.00 MB/s 570.63 MB/s 95.11x
|
||||
BenchmarkHash1M-4 6.05 MB/s 638.23 MB/s 105.49x
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Released under the Apache License v2.0. You can find the complete text in the file LICENSE.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome, please send PRs for any enhancements.
|
32
vendor/github.com/minio/sha256-simd/appveyor.yml
generated
vendored
Normal file
32
vendor/github.com/minio/sha256-simd/appveyor.yml
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
# version format
|
||||
version: "{build}"
|
||||
|
||||
# Operating system (build VM template)
|
||||
os: Windows Server 2012 R2
|
||||
|
||||
# Platform.
|
||||
platform: x64
|
||||
|
||||
clone_folder: c:\gopath\src\github.com\minio\sha256-simd
|
||||
|
||||
# environment variables
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
GO15VENDOREXPERIMENT: 1
|
||||
|
||||
# scripts that run after cloning repository
|
||||
install:
|
||||
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
|
||||
- go version
|
||||
- go env
|
||||
|
||||
# to run your custom scripts instead of automatic MSBuild
|
||||
build_script:
|
||||
- go test .
|
||||
- go test -race .
|
||||
|
||||
# to disable automatic tests
|
||||
test: off
|
||||
|
||||
# to disable deployment
|
||||
deploy: off
|
119
vendor/github.com/minio/sha256-simd/cpuid.go
generated
vendored
Normal file
119
vendor/github.com/minio/sha256-simd/cpuid.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package sha256
|
||||
|
||||
// True when SIMD instructions are available.
|
||||
var avx512 bool
|
||||
var avx2 bool
|
||||
var avx bool
|
||||
var sse bool
|
||||
var sse2 bool
|
||||
var sse3 bool
|
||||
var ssse3 bool
|
||||
var sse41 bool
|
||||
var sse42 bool
|
||||
var popcnt bool
|
||||
var sha bool
|
||||
var armSha = haveArmSha()
|
||||
|
||||
func init() {
|
||||
var _xsave bool
|
||||
var _osxsave bool
|
||||
var _avx bool
|
||||
var _avx2 bool
|
||||
var _avx512f bool
|
||||
var _avx512dq bool
|
||||
// var _avx512pf bool
|
||||
// var _avx512er bool
|
||||
// var _avx512cd bool
|
||||
var _avx512bw bool
|
||||
var _avx512vl bool
|
||||
var _sseState bool
|
||||
var _avxState bool
|
||||
var _opmaskState bool
|
||||
var _zmmHI256State bool
|
||||
var _hi16ZmmState bool
|
||||
|
||||
mfi, _, _, _ := cpuid(0)
|
||||
|
||||
if mfi >= 1 {
|
||||
_, _, c, d := cpuid(1)
|
||||
|
||||
sse = (d & (1 << 25)) != 0
|
||||
sse2 = (d & (1 << 26)) != 0
|
||||
sse3 = (c & (1 << 0)) != 0
|
||||
ssse3 = (c & (1 << 9)) != 0
|
||||
sse41 = (c & (1 << 19)) != 0
|
||||
sse42 = (c & (1 << 20)) != 0
|
||||
popcnt = (c & (1 << 23)) != 0
|
||||
_xsave = (c & (1 << 26)) != 0
|
||||
_osxsave = (c & (1 << 27)) != 0
|
||||
_avx = (c & (1 << 28)) != 0
|
||||
}
|
||||
|
||||
if mfi >= 7 {
|
||||
_, b, _, _ := cpuid(7)
|
||||
|
||||
_avx2 = (b & (1 << 5)) != 0
|
||||
_avx512f = (b & (1 << 16)) != 0
|
||||
_avx512dq = (b & (1 << 17)) != 0
|
||||
// _avx512pf = (b & (1 << 26)) != 0
|
||||
// _avx512er = (b & (1 << 27)) != 0
|
||||
// _avx512cd = (b & (1 << 28)) != 0
|
||||
_avx512bw = (b & (1 << 30)) != 0
|
||||
_avx512vl = (b & (1 << 31)) != 0
|
||||
sha = (b & (1 << 29)) != 0
|
||||
}
|
||||
|
||||
// Stop here if XSAVE unsupported or not enabled
|
||||
if !_xsave || !_osxsave {
|
||||
return
|
||||
}
|
||||
|
||||
if _xsave && _osxsave {
|
||||
a, _ := xgetbv(0)
|
||||
|
||||
_sseState = (a & (1 << 1)) != 0
|
||||
_avxState = (a & (1 << 2)) != 0
|
||||
_opmaskState = (a & (1 << 5)) != 0
|
||||
_zmmHI256State = (a & (1 << 6)) != 0
|
||||
_hi16ZmmState = (a & (1 << 7)) != 0
|
||||
} else {
|
||||
_sseState = true
|
||||
}
|
||||
|
||||
// Very unlikely that OS would enable XSAVE and then disable SSE
|
||||
if !_sseState {
|
||||
sse = false
|
||||
sse2 = false
|
||||
sse3 = false
|
||||
ssse3 = false
|
||||
sse41 = false
|
||||
sse42 = false
|
||||
}
|
||||
|
||||
if _avxState {
|
||||
avx = _avx
|
||||
avx2 = _avx2
|
||||
}
|
||||
|
||||
if _opmaskState && _zmmHI256State && _hi16ZmmState {
|
||||
avx512 = (_avx512f &&
|
||||
_avx512dq &&
|
||||
_avx512bw &&
|
||||
_avx512vl)
|
||||
}
|
||||
}
|
24
vendor/github.com/minio/sha256-simd/cpuid_386.go
generated
vendored
Normal file
24
vendor/github.com/minio/sha256-simd/cpuid_386.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package sha256
|
||||
|
||||
func cpuid(op uint32) (eax, ebx, ecx, edx uint32)
|
||||
func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32)
|
||||
func xgetbv(index uint32) (eax, edx uint32)
|
||||
|
||||
func haveArmSha() bool {
|
||||
return false
|
||||
}
|
53
vendor/github.com/minio/sha256-simd/cpuid_386.s
generated
vendored
Normal file
53
vendor/github.com/minio/sha256-simd/cpuid_386.s
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 Klaus Post
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +build 386,!gccgo
|
||||
|
||||
// func cpuid(op uint32) (eax, ebx, ecx, edx uint32)
|
||||
TEXT ·cpuid(SB), 7, $0
|
||||
XORL CX, CX
|
||||
MOVL op+0(FP), AX
|
||||
CPUID
|
||||
MOVL AX, eax+4(FP)
|
||||
MOVL BX, ebx+8(FP)
|
||||
MOVL CX, ecx+12(FP)
|
||||
MOVL DX, edx+16(FP)
|
||||
RET
|
||||
|
||||
// func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32)
|
||||
TEXT ·cpuidex(SB), 7, $0
|
||||
MOVL op+0(FP), AX
|
||||
MOVL op2+4(FP), CX
|
||||
CPUID
|
||||
MOVL AX, eax+8(FP)
|
||||
MOVL BX, ebx+12(FP)
|
||||
MOVL CX, ecx+16(FP)
|
||||
MOVL DX, edx+20(FP)
|
||||
RET
|
||||
|
||||
// func xgetbv(index uint32) (eax, edx uint32)
|
||||
TEXT ·xgetbv(SB), 7, $0
|
||||
MOVL index+0(FP), CX
|
||||
BYTE $0x0f; BYTE $0x01; BYTE $0xd0 // XGETBV
|
||||
MOVL AX, eax+4(FP)
|
||||
MOVL DX, edx+8(FP)
|
||||
RET
|
24
vendor/github.com/minio/sha256-simd/cpuid_amd64.go
generated
vendored
Normal file
24
vendor/github.com/minio/sha256-simd/cpuid_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package sha256
|
||||
|
||||
func cpuid(op uint32) (eax, ebx, ecx, edx uint32)
|
||||
func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32)
|
||||
func xgetbv(index uint32) (eax, edx uint32)
|
||||
|
||||
func haveArmSha() bool {
|
||||
return false
|
||||
}
|
53
vendor/github.com/minio/sha256-simd/cpuid_amd64.s
generated
vendored
Normal file
53
vendor/github.com/minio/sha256-simd/cpuid_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 Klaus Post
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +build amd64,!gccgo
|
||||
|
||||
// func cpuid(op uint32) (eax, ebx, ecx, edx uint32)
|
||||
TEXT ·cpuid(SB), 7, $0
|
||||
XORQ CX, CX
|
||||
MOVL op+0(FP), AX
|
||||
CPUID
|
||||
MOVL AX, eax+8(FP)
|
||||
MOVL BX, ebx+12(FP)
|
||||
MOVL CX, ecx+16(FP)
|
||||
MOVL DX, edx+20(FP)
|
||||
RET
|
||||
|
||||
// func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32)
|
||||
TEXT ·cpuidex(SB), 7, $0
|
||||
MOVL op+0(FP), AX
|
||||
MOVL op2+4(FP), CX
|
||||
CPUID
|
||||
MOVL AX, eax+8(FP)
|
||||
MOVL BX, ebx+12(FP)
|
||||
MOVL CX, ecx+16(FP)
|
||||
MOVL DX, edx+20(FP)
|
||||
RET
|
||||
|
||||
// func xgetbv(index uint32) (eax, edx uint32)
|
||||
TEXT ·xgetbv(SB), 7, $0
|
||||
MOVL index+0(FP), CX
|
||||
BYTE $0x0f; BYTE $0x01; BYTE $0xd0 // XGETBV
|
||||
MOVL AX, eax+8(FP)
|
||||
MOVL DX, edx+12(FP)
|
||||
RET
|
32
vendor/github.com/minio/sha256-simd/cpuid_arm.go
generated
vendored
Normal file
32
vendor/github.com/minio/sha256-simd/cpuid_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package sha256
|
||||
|
||||
func cpuid(op uint32) (eax, ebx, ecx, edx uint32) {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
|
||||
func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
|
||||
func xgetbv(index uint32) (eax, edx uint32) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func haveArmSha() bool {
|
||||
return false
|
||||
}
|
49
vendor/github.com/minio/sha256-simd/cpuid_linux_arm64.go
generated
vendored
Normal file
49
vendor/github.com/minio/sha256-simd/cpuid_linux_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// +build arm64,linux
|
||||
|
||||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package sha256
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func cpuid(op uint32) (eax, ebx, ecx, edx uint32) {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
|
||||
func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
|
||||
func xgetbv(index uint32) (eax, edx uint32) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// File to check for cpu capabilities.
|
||||
const procCPUInfo = "/proc/cpuinfo"
|
||||
|
||||
// Feature to check for.
|
||||
const sha256Feature = "sha2"
|
||||
|
||||
func haveArmSha() bool {
|
||||
cpuInfo, err := ioutil.ReadFile(procCPUInfo)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return bytes.Contains(cpuInfo, []byte(sha256Feature))
|
||||
}
|
34
vendor/github.com/minio/sha256-simd/cpuid_other.go
generated
vendored
Normal file
34
vendor/github.com/minio/sha256-simd/cpuid_other.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// +build ppc64 ppc64le mips mipsle mips64 mips64le s390x wasm
|
||||
|
||||
package sha256
|
||||
|
||||
func cpuid(op uint32) (eax, ebx, ecx, edx uint32) {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
|
||||
func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
|
||||
func xgetbv(index uint32) (eax, edx uint32) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func haveArmSha() bool {
|
||||
return false
|
||||
}
|
35
vendor/github.com/minio/sha256-simd/cpuid_others_arm64.go
generated
vendored
Normal file
35
vendor/github.com/minio/sha256-simd/cpuid_others_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// +build arm64,!linux
|
||||
|
||||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package sha256
|
||||
|
||||
func cpuid(op uint32) (eax, ebx, ecx, edx uint32) {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
|
||||
func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
|
||||
func xgetbv(index uint32) (eax, edx uint32) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// Check for sha2 instruction flag.
|
||||
func haveArmSha() bool {
|
||||
return false
|
||||
}
|
1
vendor/github.com/minio/sha256-simd/go.mod
generated
vendored
Normal file
1
vendor/github.com/minio/sha256-simd/go.mod
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
module github.com/minio/sha256-simd
|
409
vendor/github.com/minio/sha256-simd/sha256.go
generated
vendored
Normal file
409
vendor/github.com/minio/sha256-simd/sha256.go
generated
vendored
Normal file
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"hash"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Size - The size of a SHA256 checksum in bytes.
|
||||
const Size = 32
|
||||
|
||||
// BlockSize - The blocksize of SHA256 in bytes.
|
||||
const BlockSize = 64
|
||||
|
||||
const (
|
||||
chunk = BlockSize
|
||||
init0 = 0x6A09E667
|
||||
init1 = 0xBB67AE85
|
||||
init2 = 0x3C6EF372
|
||||
init3 = 0xA54FF53A
|
||||
init4 = 0x510E527F
|
||||
init5 = 0x9B05688C
|
||||
init6 = 0x1F83D9AB
|
||||
init7 = 0x5BE0CD19
|
||||
)
|
||||
|
||||
// digest represents the partial evaluation of a checksum.
|
||||
type digest struct {
|
||||
h [8]uint32
|
||||
x [chunk]byte
|
||||
nx int
|
||||
len uint64
|
||||
}
|
||||
|
||||
// Reset digest back to default
|
||||
func (d *digest) Reset() {
|
||||
d.h[0] = init0
|
||||
d.h[1] = init1
|
||||
d.h[2] = init2
|
||||
d.h[3] = init3
|
||||
d.h[4] = init4
|
||||
d.h[5] = init5
|
||||
d.h[6] = init6
|
||||
d.h[7] = init7
|
||||
d.nx = 0
|
||||
d.len = 0
|
||||
}
|
||||
|
||||
type blockfuncType int
|
||||
|
||||
const (
|
||||
blockfuncGeneric blockfuncType = iota
|
||||
blockfuncAvx512 blockfuncType = iota
|
||||
blockfuncAvx2 blockfuncType = iota
|
||||
blockfuncAvx blockfuncType = iota
|
||||
blockfuncSsse blockfuncType = iota
|
||||
blockfuncSha blockfuncType = iota
|
||||
blockfuncArm blockfuncType = iota
|
||||
)
|
||||
|
||||
var blockfunc blockfuncType
|
||||
|
||||
func init() {
|
||||
is386bit := runtime.GOARCH == "386"
|
||||
isARM := runtime.GOARCH == "arm"
|
||||
switch {
|
||||
case is386bit || isARM:
|
||||
blockfunc = blockfuncGeneric
|
||||
case sha && ssse3 && sse41:
|
||||
blockfunc = blockfuncSha
|
||||
case avx2:
|
||||
blockfunc = blockfuncAvx2
|
||||
case avx:
|
||||
blockfunc = blockfuncAvx
|
||||
case ssse3:
|
||||
blockfunc = blockfuncSsse
|
||||
case armSha:
|
||||
blockfunc = blockfuncArm
|
||||
default:
|
||||
blockfunc = blockfuncGeneric
|
||||
}
|
||||
}
|
||||
|
||||
// New returns a new hash.Hash computing the SHA256 checksum.
|
||||
func New() hash.Hash {
|
||||
if blockfunc != blockfuncGeneric {
|
||||
d := new(digest)
|
||||
d.Reset()
|
||||
return d
|
||||
}
|
||||
// Fallback to the standard golang implementation
|
||||
// if no features were found.
|
||||
return sha256.New()
|
||||
}
|
||||
|
||||
// Sum256 - single caller sha256 helper
|
||||
func Sum256(data []byte) (result [Size]byte) {
|
||||
var d digest
|
||||
d.Reset()
|
||||
d.Write(data)
|
||||
result = d.checkSum()
|
||||
return
|
||||
}
|
||||
|
||||
// Return size of checksum
|
||||
func (d *digest) Size() int { return Size }
|
||||
|
||||
// Return blocksize of checksum
|
||||
func (d *digest) BlockSize() int { return BlockSize }
|
||||
|
||||
// Write to digest
|
||||
func (d *digest) Write(p []byte) (nn int, err error) {
|
||||
nn = len(p)
|
||||
d.len += uint64(nn)
|
||||
if d.nx > 0 {
|
||||
n := copy(d.x[d.nx:], p)
|
||||
d.nx += n
|
||||
if d.nx == chunk {
|
||||
block(d, d.x[:])
|
||||
d.nx = 0
|
||||
}
|
||||
p = p[n:]
|
||||
}
|
||||
if len(p) >= chunk {
|
||||
n := len(p) &^ (chunk - 1)
|
||||
block(d, p[:n])
|
||||
p = p[n:]
|
||||
}
|
||||
if len(p) > 0 {
|
||||
d.nx = copy(d.x[:], p)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Return sha256 sum in bytes
|
||||
func (d *digest) Sum(in []byte) []byte {
|
||||
// Make a copy of d0 so that caller can keep writing and summing.
|
||||
d0 := *d
|
||||
hash := d0.checkSum()
|
||||
return append(in, hash[:]...)
|
||||
}
|
||||
|
||||
// Intermediate checksum function
|
||||
func (d *digest) checkSum() (digest [Size]byte) {
|
||||
n := d.nx
|
||||
|
||||
var k [64]byte
|
||||
copy(k[:], d.x[:n])
|
||||
|
||||
k[n] = 0x80
|
||||
|
||||
if n >= 56 {
|
||||
block(d, k[:])
|
||||
|
||||
// clear block buffer - go compiles this to optimal 1x xorps + 4x movups
|
||||
// unfortunately expressing this more succinctly results in much worse code
|
||||
k[0] = 0
|
||||
k[1] = 0
|
||||
k[2] = 0
|
||||
k[3] = 0
|
||||
k[4] = 0
|
||||
k[5] = 0
|
||||
k[6] = 0
|
||||
k[7] = 0
|
||||
k[8] = 0
|
||||
k[9] = 0
|
||||
k[10] = 0
|
||||
k[11] = 0
|
||||
k[12] = 0
|
||||
k[13] = 0
|
||||
k[14] = 0
|
||||
k[15] = 0
|
||||
k[16] = 0
|
||||
k[17] = 0
|
||||
k[18] = 0
|
||||
k[19] = 0
|
||||
k[20] = 0
|
||||
k[21] = 0
|
||||
k[22] = 0
|
||||
k[23] = 0
|
||||
k[24] = 0
|
||||
k[25] = 0
|
||||
k[26] = 0
|
||||
k[27] = 0
|
||||
k[28] = 0
|
||||
k[29] = 0
|
||||
k[30] = 0
|
||||
k[31] = 0
|
||||
k[32] = 0
|
||||
k[33] = 0
|
||||
k[34] = 0
|
||||
k[35] = 0
|
||||
k[36] = 0
|
||||
k[37] = 0
|
||||
k[38] = 0
|
||||
k[39] = 0
|
||||
k[40] = 0
|
||||
k[41] = 0
|
||||
k[42] = 0
|
||||
k[43] = 0
|
||||
k[44] = 0
|
||||
k[45] = 0
|
||||
k[46] = 0
|
||||
k[47] = 0
|
||||
k[48] = 0
|
||||
k[49] = 0
|
||||
k[50] = 0
|
||||
k[51] = 0
|
||||
k[52] = 0
|
||||
k[53] = 0
|
||||
k[54] = 0
|
||||
k[55] = 0
|
||||
k[56] = 0
|
||||
k[57] = 0
|
||||
k[58] = 0
|
||||
k[59] = 0
|
||||
k[60] = 0
|
||||
k[61] = 0
|
||||
k[62] = 0
|
||||
k[63] = 0
|
||||
}
|
||||
binary.BigEndian.PutUint64(k[56:64], uint64(d.len)<<3)
|
||||
block(d, k[:])
|
||||
|
||||
{
|
||||
const i = 0
|
||||
binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i])
|
||||
}
|
||||
{
|
||||
const i = 1
|
||||
binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i])
|
||||
}
|
||||
{
|
||||
const i = 2
|
||||
binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i])
|
||||
}
|
||||
{
|
||||
const i = 3
|
||||
binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i])
|
||||
}
|
||||
{
|
||||
const i = 4
|
||||
binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i])
|
||||
}
|
||||
{
|
||||
const i = 5
|
||||
binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i])
|
||||
}
|
||||
{
|
||||
const i = 6
|
||||
binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i])
|
||||
}
|
||||
{
|
||||
const i = 7
|
||||
binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i])
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func block(dig *digest, p []byte) {
|
||||
if blockfunc == blockfuncSha {
|
||||
blockShaGo(dig, p)
|
||||
} else if blockfunc == blockfuncAvx2 {
|
||||
blockAvx2Go(dig, p)
|
||||
} else if blockfunc == blockfuncAvx {
|
||||
blockAvxGo(dig, p)
|
||||
} else if blockfunc == blockfuncSsse {
|
||||
blockSsseGo(dig, p)
|
||||
} else if blockfunc == blockfuncArm {
|
||||
blockArmGo(dig, p)
|
||||
} else if blockfunc == blockfuncGeneric {
|
||||
blockGeneric(dig, p)
|
||||
}
|
||||
}
|
||||
|
||||
func blockGeneric(dig *digest, p []byte) {
|
||||
var w [64]uint32
|
||||
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
|
||||
for len(p) >= chunk {
|
||||
// Can interlace the computation of w with the
|
||||
// rounds below if needed for speed.
|
||||
for i := 0; i < 16; i++ {
|
||||
j := i * 4
|
||||
w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
|
||||
}
|
||||
for i := 16; i < 64; i++ {
|
||||
v1 := w[i-2]
|
||||
t1 := (v1>>17 | v1<<(32-17)) ^ (v1>>19 | v1<<(32-19)) ^ (v1 >> 10)
|
||||
v2 := w[i-15]
|
||||
t2 := (v2>>7 | v2<<(32-7)) ^ (v2>>18 | v2<<(32-18)) ^ (v2 >> 3)
|
||||
w[i] = t1 + w[i-7] + t2 + w[i-16]
|
||||
}
|
||||
|
||||
a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7
|
||||
|
||||
for i := 0; i < 64; i++ {
|
||||
t1 := h + ((e>>6 | e<<(32-6)) ^ (e>>11 | e<<(32-11)) ^ (e>>25 | e<<(32-25))) + ((e & f) ^ (^e & g)) + _K[i] + w[i]
|
||||
|
||||
t2 := ((a>>2 | a<<(32-2)) ^ (a>>13 | a<<(32-13)) ^ (a>>22 | a<<(32-22))) + ((a & b) ^ (a & c) ^ (b & c))
|
||||
|
||||
h = g
|
||||
g = f
|
||||
f = e
|
||||
e = d + t1
|
||||
d = c
|
||||
c = b
|
||||
b = a
|
||||
a = t1 + t2
|
||||
}
|
||||
|
||||
h0 += a
|
||||
h1 += b
|
||||
h2 += c
|
||||
h3 += d
|
||||
h4 += e
|
||||
h5 += f
|
||||
h6 += g
|
||||
h7 += h
|
||||
|
||||
p = p[chunk:]
|
||||
}
|
||||
|
||||
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7
|
||||
}
|
||||
|
||||
var _K = []uint32{
|
||||
0x428a2f98,
|
||||
0x71374491,
|
||||
0xb5c0fbcf,
|
||||
0xe9b5dba5,
|
||||
0x3956c25b,
|
||||
0x59f111f1,
|
||||
0x923f82a4,
|
||||
0xab1c5ed5,
|
||||
0xd807aa98,
|
||||
0x12835b01,
|
||||
0x243185be,
|
||||
0x550c7dc3,
|
||||
0x72be5d74,
|
||||
0x80deb1fe,
|
||||
0x9bdc06a7,
|
||||
0xc19bf174,
|
||||
0xe49b69c1,
|
||||
0xefbe4786,
|
||||
0x0fc19dc6,
|
||||
0x240ca1cc,
|
||||
0x2de92c6f,
|
||||
0x4a7484aa,
|
||||
0x5cb0a9dc,
|
||||
0x76f988da,
|
||||
0x983e5152,
|
||||
0xa831c66d,
|
||||
0xb00327c8,
|
||||
0xbf597fc7,
|
||||
0xc6e00bf3,
|
||||
0xd5a79147,
|
||||
0x06ca6351,
|
||||
0x14292967,
|
||||
0x27b70a85,
|
||||
0x2e1b2138,
|
||||
0x4d2c6dfc,
|
||||
0x53380d13,
|
||||
0x650a7354,
|
||||
0x766a0abb,
|
||||
0x81c2c92e,
|
||||
0x92722c85,
|
||||
0xa2bfe8a1,
|
||||
0xa81a664b,
|
||||
0xc24b8b70,
|
||||
0xc76c51a3,
|
||||
0xd192e819,
|
||||
0xd6990624,
|
||||
0xf40e3585,
|
||||
0x106aa070,
|
||||
0x19a4c116,
|
||||
0x1e376c08,
|
||||
0x2748774c,
|
||||
0x34b0bcb5,
|
||||
0x391c0cb3,
|
||||
0x4ed8aa4a,
|
||||
0x5b9cca4f,
|
||||
0x682e6ff3,
|
||||
0x748f82ee,
|
||||
0x78a5636f,
|
||||
0x84c87814,
|
||||
0x8cc70208,
|
||||
0x90befffa,
|
||||
0xa4506ceb,
|
||||
0xbef9a3f7,
|
||||
0xc67178f2,
|
||||
}
|
22
vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.go
generated
vendored
Normal file
22
vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
//+build !noasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
//go:noescape
|
||||
func blockAvx2(h []uint32, message []uint8)
|
1449
vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.s
generated
vendored
Normal file
1449
vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
686
vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.asm
generated
vendored
Normal file
686
vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.asm
generated
vendored
Normal file
|
@ -0,0 +1,686 @@
|
|||
|
||||
// 16x Parallel implementation of SHA256 for AVX512
|
||||
|
||||
//
|
||||
// Minio Cloud Storage, (C) 2017 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//
|
||||
// This code is based on the Intel Multi-Buffer Crypto for IPSec library
|
||||
// and more specifically the following implementation:
|
||||
// https://github.com/intel/intel-ipsec-mb/blob/master/avx512/sha256_x16_avx512.asm
|
||||
//
|
||||
// For Golang it has been converted into Plan 9 assembly with the help of
|
||||
// github.com/minio/asm2plan9s to assemble the AVX512 instructions
|
||||
//
|
||||
|
||||
// Copyright (c) 2017, Intel Corporation
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Intel Corporation nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#define SHA256_DIGEST_ROW_SIZE 64
|
||||
|
||||
// arg1
|
||||
#define STATE rdi
|
||||
#define STATE_P9 DI
|
||||
// arg2
|
||||
#define INP_SIZE rsi
|
||||
#define INP_SIZE_P9 SI
|
||||
|
||||
#define IDX rcx
|
||||
#define TBL rdx
|
||||
#define TBL_P9 DX
|
||||
|
||||
#define INPUT rax
|
||||
#define INPUT_P9 AX
|
||||
|
||||
#define inp0 r9
|
||||
#define SCRATCH_P9 R12
|
||||
#define SCRATCH r12
|
||||
#define maskp r13
|
||||
#define MASKP_P9 R13
|
||||
#define mask r14
|
||||
#define MASK_P9 R14
|
||||
|
||||
#define A zmm0
|
||||
#define B zmm1
|
||||
#define C zmm2
|
||||
#define D zmm3
|
||||
#define E zmm4
|
||||
#define F zmm5
|
||||
#define G zmm6
|
||||
#define H zmm7
|
||||
#define T1 zmm8
|
||||
#define TMP0 zmm9
|
||||
#define TMP1 zmm10
|
||||
#define TMP2 zmm11
|
||||
#define TMP3 zmm12
|
||||
#define TMP4 zmm13
|
||||
#define TMP5 zmm14
|
||||
#define TMP6 zmm15
|
||||
|
||||
#define W0 zmm16
|
||||
#define W1 zmm17
|
||||
#define W2 zmm18
|
||||
#define W3 zmm19
|
||||
#define W4 zmm20
|
||||
#define W5 zmm21
|
||||
#define W6 zmm22
|
||||
#define W7 zmm23
|
||||
#define W8 zmm24
|
||||
#define W9 zmm25
|
||||
#define W10 zmm26
|
||||
#define W11 zmm27
|
||||
#define W12 zmm28
|
||||
#define W13 zmm29
|
||||
#define W14 zmm30
|
||||
#define W15 zmm31
|
||||
|
||||
|
||||
#define TRANSPOSE16(_r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7, _r8, _r9, _r10, _r11, _r12, _r13, _r14, _r15, _t0, _t1) \
|
||||
\
|
||||
\ // input r0 = {a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0}
|
||||
\ // r1 = {b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0}
|
||||
\ // r2 = {c15 c14 c13 c12 c11 c10 c9 c8 c7 c6 c5 c4 c3 c2 c1 c0}
|
||||
\ // r3 = {d15 d14 d13 d12 d11 d10 d9 d8 d7 d6 d5 d4 d3 d2 d1 d0}
|
||||
\ // r4 = {e15 e14 e13 e12 e11 e10 e9 e8 e7 e6 e5 e4 e3 e2 e1 e0}
|
||||
\ // r5 = {f15 f14 f13 f12 f11 f10 f9 f8 f7 f6 f5 f4 f3 f2 f1 f0}
|
||||
\ // r6 = {g15 g14 g13 g12 g11 g10 g9 g8 g7 g6 g5 g4 g3 g2 g1 g0}
|
||||
\ // r7 = {h15 h14 h13 h12 h11 h10 h9 h8 h7 h6 h5 h4 h3 h2 h1 h0}
|
||||
\ // r8 = {i15 i14 i13 i12 i11 i10 i9 i8 i7 i6 i5 i4 i3 i2 i1 i0}
|
||||
\ // r9 = {j15 j14 j13 j12 j11 j10 j9 j8 j7 j6 j5 j4 j3 j2 j1 j0}
|
||||
\ // r10 = {k15 k14 k13 k12 k11 k10 k9 k8 k7 k6 k5 k4 k3 k2 k1 k0}
|
||||
\ // r11 = {l15 l14 l13 l12 l11 l10 l9 l8 l7 l6 l5 l4 l3 l2 l1 l0}
|
||||
\ // r12 = {m15 m14 m13 m12 m11 m10 m9 m8 m7 m6 m5 m4 m3 m2 m1 m0}
|
||||
\ // r13 = {n15 n14 n13 n12 n11 n10 n9 n8 n7 n6 n5 n4 n3 n2 n1 n0}
|
||||
\ // r14 = {o15 o14 o13 o12 o11 o10 o9 o8 o7 o6 o5 o4 o3 o2 o1 o0}
|
||||
\ // r15 = {p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0}
|
||||
\
|
||||
\ // output r0 = { p0 o0 n0 m0 l0 k0 j0 i0 h0 g0 f0 e0 d0 c0 b0 a0}
|
||||
\ // r1 = { p1 o1 n1 m1 l1 k1 j1 i1 h1 g1 f1 e1 d1 c1 b1 a1}
|
||||
\ // r2 = { p2 o2 n2 m2 l2 k2 j2 i2 h2 g2 f2 e2 d2 c2 b2 a2}
|
||||
\ // r3 = { p3 o3 n3 m3 l3 k3 j3 i3 h3 g3 f3 e3 d3 c3 b3 a3}
|
||||
\ // r4 = { p4 o4 n4 m4 l4 k4 j4 i4 h4 g4 f4 e4 d4 c4 b4 a4}
|
||||
\ // r5 = { p5 o5 n5 m5 l5 k5 j5 i5 h5 g5 f5 e5 d5 c5 b5 a5}
|
||||
\ // r6 = { p6 o6 n6 m6 l6 k6 j6 i6 h6 g6 f6 e6 d6 c6 b6 a6}
|
||||
\ // r7 = { p7 o7 n7 m7 l7 k7 j7 i7 h7 g7 f7 e7 d7 c7 b7 a7}
|
||||
\ // r8 = { p8 o8 n8 m8 l8 k8 j8 i8 h8 g8 f8 e8 d8 c8 b8 a8}
|
||||
\ // r9 = { p9 o9 n9 m9 l9 k9 j9 i9 h9 g9 f9 e9 d9 c9 b9 a9}
|
||||
\ // r10 = {p10 o10 n10 m10 l10 k10 j10 i10 h10 g10 f10 e10 d10 c10 b10 a10}
|
||||
\ // r11 = {p11 o11 n11 m11 l11 k11 j11 i11 h11 g11 f11 e11 d11 c11 b11 a11}
|
||||
\ // r12 = {p12 o12 n12 m12 l12 k12 j12 i12 h12 g12 f12 e12 d12 c12 b12 a12}
|
||||
\ // r13 = {p13 o13 n13 m13 l13 k13 j13 i13 h13 g13 f13 e13 d13 c13 b13 a13}
|
||||
\ // r14 = {p14 o14 n14 m14 l14 k14 j14 i14 h14 g14 f14 e14 d14 c14 b14 a14}
|
||||
\ // r15 = {p15 o15 n15 m15 l15 k15 j15 i15 h15 g15 f15 e15 d15 c15 b15 a15}
|
||||
\
|
||||
\ // process top half
|
||||
vshufps _t0, _r0, _r1, 0x44 \ // t0 = {b13 b12 a13 a12 b9 b8 a9 a8 b5 b4 a5 a4 b1 b0 a1 a0}
|
||||
vshufps _r0, _r0, _r1, 0xEE \ // r0 = {b15 b14 a15 a14 b11 b10 a11 a10 b7 b6 a7 a6 b3 b2 a3 a2}
|
||||
vshufps _t1, _r2, _r3, 0x44 \ // t1 = {d13 d12 c13 c12 d9 d8 c9 c8 d5 d4 c5 c4 d1 d0 c1 c0}
|
||||
vshufps _r2, _r2, _r3, 0xEE \ // r2 = {d15 d14 c15 c14 d11 d10 c11 c10 d7 d6 c7 c6 d3 d2 c3 c2}
|
||||
\
|
||||
vshufps _r3, _t0, _t1, 0xDD \ // r3 = {d13 c13 b13 a13 d9 c9 b9 a9 d5 c5 b5 a5 d1 c1 b1 a1}
|
||||
vshufps _r1, _r0, _r2, 0x88 \ // r1 = {d14 c14 b14 a14 d10 c10 b10 a10 d6 c6 b6 a6 d2 c2 b2 a2}
|
||||
vshufps _r0, _r0, _r2, 0xDD \ // r0 = {d15 c15 b15 a15 d11 c11 b11 a11 d7 c7 b7 a7 d3 c3 b3 a3}
|
||||
vshufps _t0, _t0, _t1, 0x88 \ // t0 = {d12 c12 b12 a12 d8 c8 b8 a8 d4 c4 b4 a4 d0 c0 b0 a0}
|
||||
\
|
||||
\ // use r2 in place of t0
|
||||
vshufps _r2, _r4, _r5, 0x44 \ // r2 = {f13 f12 e13 e12 f9 f8 e9 e8 f5 f4 e5 e4 f1 f0 e1 e0}
|
||||
vshufps _r4, _r4, _r5, 0xEE \ // r4 = {f15 f14 e15 e14 f11 f10 e11 e10 f7 f6 e7 e6 f3 f2 e3 e2}
|
||||
vshufps _t1, _r6, _r7, 0x44 \ // t1 = {h13 h12 g13 g12 h9 h8 g9 g8 h5 h4 g5 g4 h1 h0 g1 g0}
|
||||
vshufps _r6, _r6, _r7, 0xEE \ // r6 = {h15 h14 g15 g14 h11 h10 g11 g10 h7 h6 g7 g6 h3 h2 g3 g2}
|
||||
\
|
||||
vshufps _r7, _r2, _t1, 0xDD \ // r7 = {h13 g13 f13 e13 h9 g9 f9 e9 h5 g5 f5 e5 h1 g1 f1 e1}
|
||||
vshufps _r5, _r4, _r6, 0x88 \ // r5 = {h14 g14 f14 e14 h10 g10 f10 e10 h6 g6 f6 e6 h2 g2 f2 e2}
|
||||
vshufps _r4, _r4, _r6, 0xDD \ // r4 = {h15 g15 f15 e15 h11 g11 f11 e11 h7 g7 f7 e7 h3 g3 f3 e3}
|
||||
vshufps _r2, _r2, _t1, 0x88 \ // r2 = {h12 g12 f12 e12 h8 g8 f8 e8 h4 g4 f4 e4 h0 g0 f0 e0}
|
||||
\
|
||||
\ // use r6 in place of t0
|
||||
vshufps _r6, _r8, _r9, 0x44 \ // r6 = {j13 j12 i13 i12 j9 j8 i9 i8 j5 j4 i5 i4 j1 j0 i1 i0}
|
||||
vshufps _r8, _r8, _r9, 0xEE \ // r8 = {j15 j14 i15 i14 j11 j10 i11 i10 j7 j6 i7 i6 j3 j2 i3 i2}
|
||||
vshufps _t1, _r10, _r11, 0x44 \ // t1 = {l13 l12 k13 k12 l9 l8 k9 k8 l5 l4 k5 k4 l1 l0 k1 k0}
|
||||
vshufps _r10, _r10, _r11, 0xEE \ // r10 = {l15 l14 k15 k14 l11 l10 k11 k10 l7 l6 k7 k6 l3 l2 k3 k2}
|
||||
\
|
||||
vshufps _r11, _r6, _t1, 0xDD \ // r11 = {l13 k13 j13 113 l9 k9 j9 i9 l5 k5 j5 i5 l1 k1 j1 i1}
|
||||
vshufps _r9, _r8, _r10, 0x88 \ // r9 = {l14 k14 j14 114 l10 k10 j10 i10 l6 k6 j6 i6 l2 k2 j2 i2}
|
||||
vshufps _r8, _r8, _r10, 0xDD \ // r8 = {l15 k15 j15 115 l11 k11 j11 i11 l7 k7 j7 i7 l3 k3 j3 i3}
|
||||
vshufps _r6, _r6, _t1, 0x88 \ // r6 = {l12 k12 j12 112 l8 k8 j8 i8 l4 k4 j4 i4 l0 k0 j0 i0}
|
||||
\
|
||||
\ // use r10 in place of t0
|
||||
vshufps _r10, _r12, _r13, 0x44 \ // r10 = {n13 n12 m13 m12 n9 n8 m9 m8 n5 n4 m5 m4 n1 n0 a1 m0}
|
||||
vshufps _r12, _r12, _r13, 0xEE \ // r12 = {n15 n14 m15 m14 n11 n10 m11 m10 n7 n6 m7 m6 n3 n2 a3 m2}
|
||||
vshufps _t1, _r14, _r15, 0x44 \ // t1 = {p13 p12 013 012 p9 p8 09 08 p5 p4 05 04 p1 p0 01 00}
|
||||
vshufps _r14, _r14, _r15, 0xEE \ // r14 = {p15 p14 015 014 p11 p10 011 010 p7 p6 07 06 p3 p2 03 02}
|
||||
\
|
||||
vshufps _r15, _r10, _t1, 0xDD \ // r15 = {p13 013 n13 m13 p9 09 n9 m9 p5 05 n5 m5 p1 01 n1 m1}
|
||||
vshufps _r13, _r12, _r14, 0x88 \ // r13 = {p14 014 n14 m14 p10 010 n10 m10 p6 06 n6 m6 p2 02 n2 m2}
|
||||
vshufps _r12, _r12, _r14, 0xDD \ // r12 = {p15 015 n15 m15 p11 011 n11 m11 p7 07 n7 m7 p3 03 n3 m3}
|
||||
vshufps _r10, _r10, _t1, 0x88 \ // r10 = {p12 012 n12 m12 p8 08 n8 m8 p4 04 n4 m4 p0 00 n0 m0}
|
||||
\
|
||||
\ // At this point, the registers that contain interesting data are:
|
||||
\ // t0, r3, r1, r0, r2, r7, r5, r4, r6, r11, r9, r8, r10, r15, r13, r12
|
||||
\ // Can use t1 and r14 as scratch registers
|
||||
LEAQ PSHUFFLE_TRANSPOSE16_MASK1<>(SB), BX \
|
||||
LEAQ PSHUFFLE_TRANSPOSE16_MASK2<>(SB), R8 \
|
||||
\
|
||||
vmovdqu32 _r14, [rbx] \
|
||||
vpermi2q _r14, _t0, _r2 \ // r14 = {h8 g8 f8 e8 d8 c8 b8 a8 h0 g0 f0 e0 d0 c0 b0 a0}
|
||||
vmovdqu32 _t1, [r8] \
|
||||
vpermi2q _t1, _t0, _r2 \ // t1 = {h12 g12 f12 e12 d12 c12 b12 a12 h4 g4 f4 e4 d4 c4 b4 a4}
|
||||
\
|
||||
vmovdqu32 _r2, [rbx] \
|
||||
vpermi2q _r2, _r3, _r7 \ // r2 = {h9 g9 f9 e9 d9 c9 b9 a9 h1 g1 f1 e1 d1 c1 b1 a1}
|
||||
vmovdqu32 _t0, [r8] \
|
||||
vpermi2q _t0, _r3, _r7 \ // t0 = {h13 g13 f13 e13 d13 c13 b13 a13 h5 g5 f5 e5 d5 c5 b5 a5}
|
||||
\
|
||||
vmovdqu32 _r3, [rbx] \
|
||||
vpermi2q _r3, _r1, _r5 \ // r3 = {h10 g10 f10 e10 d10 c10 b10 a10 h2 g2 f2 e2 d2 c2 b2 a2}
|
||||
vmovdqu32 _r7, [r8] \
|
||||
vpermi2q _r7, _r1, _r5 \ // r7 = {h14 g14 f14 e14 d14 c14 b14 a14 h6 g6 f6 e6 d6 c6 b6 a6}
|
||||
\
|
||||
vmovdqu32 _r1, [rbx] \
|
||||
vpermi2q _r1, _r0, _r4 \ // r1 = {h11 g11 f11 e11 d11 c11 b11 a11 h3 g3 f3 e3 d3 c3 b3 a3}
|
||||
vmovdqu32 _r5, [r8] \
|
||||
vpermi2q _r5, _r0, _r4 \ // r5 = {h15 g15 f15 e15 d15 c15 b15 a15 h7 g7 f7 e7 d7 c7 b7 a7}
|
||||
\
|
||||
vmovdqu32 _r0, [rbx] \
|
||||
vpermi2q _r0, _r6, _r10 \ // r0 = {p8 o8 n8 m8 l8 k8 j8 i8 p0 o0 n0 m0 l0 k0 j0 i0}
|
||||
vmovdqu32 _r4, [r8] \
|
||||
vpermi2q _r4, _r6, _r10 \ // r4 = {p12 o12 n12 m12 l12 k12 j12 i12 p4 o4 n4 m4 l4 k4 j4 i4}
|
||||
\
|
||||
vmovdqu32 _r6, [rbx] \
|
||||
vpermi2q _r6, _r11, _r15 \ // r6 = {p9 o9 n9 m9 l9 k9 j9 i9 p1 o1 n1 m1 l1 k1 j1 i1}
|
||||
vmovdqu32 _r10, [r8] \
|
||||
vpermi2q _r10, _r11, _r15 \ // r10 = {p13 o13 n13 m13 l13 k13 j13 i13 p5 o5 n5 m5 l5 k5 j5 i5}
|
||||
\
|
||||
vmovdqu32 _r11, [rbx] \
|
||||
vpermi2q _r11, _r9, _r13 \ // r11 = {p10 o10 n10 m10 l10 k10 j10 i10 p2 o2 n2 m2 l2 k2 j2 i2}
|
||||
vmovdqu32 _r15, [r8] \
|
||||
vpermi2q _r15, _r9, _r13 \ // r15 = {p14 o14 n14 m14 l14 k14 j14 i14 p6 o6 n6 m6 l6 k6 j6 i6}
|
||||
\
|
||||
vmovdqu32 _r9, [rbx] \
|
||||
vpermi2q _r9, _r8, _r12 \ // r9 = {p11 o11 n11 m11 l11 k11 j11 i11 p3 o3 n3 m3 l3 k3 j3 i3}
|
||||
vmovdqu32 _r13, [r8] \
|
||||
vpermi2q _r13, _r8, _r12 \ // r13 = {p15 o15 n15 m15 l15 k15 j15 i15 p7 o7 n7 m7 l7 k7 j7 i7}
|
||||
\
|
||||
\ // At this point r8 and r12 can be used as scratch registers
|
||||
vshuff64x2 _r8, _r14, _r0, 0xEE \ // r8 = {p8 o8 n8 m8 l8 k8 j8 i8 h8 g8 f8 e8 d8 c8 b8 a8}
|
||||
vshuff64x2 _r0, _r14, _r0, 0x44 \ // r0 = {p0 o0 n0 m0 l0 k0 j0 i0 h0 g0 f0 e0 d0 c0 b0 a0}
|
||||
\
|
||||
vshuff64x2 _r12, _t1, _r4, 0xEE \ // r12 = {p12 o12 n12 m12 l12 k12 j12 i12 h12 g12 f12 e12 d12 c12 b12 a12}
|
||||
vshuff64x2 _r4, _t1, _r4, 0x44 \ // r4 = {p4 o4 n4 m4 l4 k4 j4 i4 h4 g4 f4 e4 d4 c4 b4 a4}
|
||||
\
|
||||
vshuff64x2 _r14, _r7, _r15, 0xEE \ // r14 = {p14 o14 n14 m14 l14 k14 j14 i14 h14 g14 f14 e14 d14 c14 b14 a14}
|
||||
vshuff64x2 _t1, _r7, _r15, 0x44 \ // t1 = {p6 o6 n6 m6 l6 k6 j6 i6 h6 g6 f6 e6 d6 c6 b6 a6}
|
||||
\
|
||||
vshuff64x2 _r15, _r5, _r13, 0xEE \ // r15 = {p15 o15 n15 m15 l15 k15 j15 i15 h15 g15 f15 e15 d15 c15 b15 a15}
|
||||
vshuff64x2 _r7, _r5, _r13, 0x44 \ // r7 = {p7 o7 n7 m7 l7 k7 j7 i7 h7 g7 f7 e7 d7 c7 b7 a7}
|
||||
\
|
||||
vshuff64x2 _r13, _t0, _r10, 0xEE \ // r13 = {p13 o13 n13 m13 l13 k13 j13 i13 h13 g13 f13 e13 d13 c13 b13 a13}
|
||||
vshuff64x2 _r5, _t0, _r10, 0x44 \ // r5 = {p5 o5 n5 m5 l5 k5 j5 i5 h5 g5 f5 e5 d5 c5 b5 a5}
|
||||
\
|
||||
vshuff64x2 _r10, _r3, _r11, 0xEE \ // r10 = {p10 o10 n10 m10 l10 k10 j10 i10 h10 g10 f10 e10 d10 c10 b10 a10}
|
||||
vshuff64x2 _t0, _r3, _r11, 0x44 \ // t0 = {p2 o2 n2 m2 l2 k2 j2 i2 h2 g2 f2 e2 d2 c2 b2 a2}
|
||||
\
|
||||
vshuff64x2 _r11, _r1, _r9, 0xEE \ // r11 = {p11 o11 n11 m11 l11 k11 j11 i11 h11 g11 f11 e11 d11 c11 b11 a11}
|
||||
vshuff64x2 _r3, _r1, _r9, 0x44 \ // r3 = {p3 o3 n3 m3 l3 k3 j3 i3 h3 g3 f3 e3 d3 c3 b3 a3}
|
||||
\
|
||||
vshuff64x2 _r9, _r2, _r6, 0xEE \ // r9 = {p9 o9 n9 m9 l9 k9 j9 i9 h9 g9 f9 e9 d9 c9 b9 a9}
|
||||
vshuff64x2 _r1, _r2, _r6, 0x44 \ // r1 = {p1 o1 n1 m1 l1 k1 j1 i1 h1 g1 f1 e1 d1 c1 b1 a1}
|
||||
\
|
||||
vmovdqu32 _r2, _t0 \ // r2 = {p2 o2 n2 m2 l2 k2 j2 i2 h2 g2 f2 e2 d2 c2 b2 a2}
|
||||
vmovdqu32 _r6, _t1 \ // r6 = {p6 o6 n6 m6 l6 k6 j6 i6 h6 g6 f6 e6 d6 c6 b6 a6}
|
||||
|
||||
|
||||
// CH(A, B, C) = (A&B) ^ (~A&C)
|
||||
// MAJ(E, F, G) = (E&F) ^ (E&G) ^ (F&G)
|
||||
// SIGMA0 = ROR_2 ^ ROR_13 ^ ROR_22
|
||||
// SIGMA1 = ROR_6 ^ ROR_11 ^ ROR_25
|
||||
// sigma0 = ROR_7 ^ ROR_18 ^ SHR_3
|
||||
// sigma1 = ROR_17 ^ ROR_19 ^ SHR_10
|
||||
|
||||
// Main processing loop per round
|
||||
#define PROCESS_LOOP(_WT, _ROUND, _A, _B, _C, _D, _E, _F, _G, _H) \
|
||||
\ // T1 = H + SIGMA1(E) + CH(E, F, G) + Kt + Wt
|
||||
\ // T2 = SIGMA0(A) + MAJ(A, B, C)
|
||||
\ // H=G, G=F, F=E, E=D+T1, D=C, C=B, B=A, A=T1+T2
|
||||
\
|
||||
\ // H becomes T2, then add T1 for A
|
||||
\ // D becomes D + T1 for E
|
||||
\
|
||||
vpaddd T1, _H, TMP3 \ // T1 = H + Kt
|
||||
vmovdqu32 TMP0, _E \
|
||||
vprord TMP1, _E, 6 \ // ROR_6(E)
|
||||
vprord TMP2, _E, 11 \ // ROR_11(E)
|
||||
vprord TMP3, _E, 25 \ // ROR_25(E)
|
||||
vpternlogd TMP0, _F, _G, 0xCA \ // TMP0 = CH(E,F,G)
|
||||
vpaddd T1, T1, _WT \ // T1 = T1 + Wt
|
||||
vpternlogd TMP1, TMP2, TMP3, 0x96 \ // TMP1 = SIGMA1(E)
|
||||
vpaddd T1, T1, TMP0 \ // T1 = T1 + CH(E,F,G)
|
||||
vpaddd T1, T1, TMP1 \ // T1 = T1 + SIGMA1(E)
|
||||
vpaddd _D, _D, T1 \ // D = D + T1
|
||||
\
|
||||
vprord _H, _A, 2 \ // ROR_2(A)
|
||||
vprord TMP2, _A, 13 \ // ROR_13(A)
|
||||
vprord TMP3, _A, 22 \ // ROR_22(A)
|
||||
vmovdqu32 TMP0, _A \
|
||||
vpternlogd TMP0, _B, _C, 0xE8 \ // TMP0 = MAJ(A,B,C)
|
||||
vpternlogd _H, TMP2, TMP3, 0x96 \ // H(T2) = SIGMA0(A)
|
||||
vpaddd _H, _H, TMP0 \ // H(T2) = SIGMA0(A) + MAJ(A,B,C)
|
||||
vpaddd _H, _H, T1 \ // H(A) = H(T2) + T1
|
||||
\
|
||||
vmovdqu32 TMP3, [TBL + ((_ROUND+1)*64)] \ // Next Kt
|
||||
|
||||
|
||||
#define MSG_SCHED_ROUND_16_63(_WT, _WTp1, _WTp9, _WTp14) \
|
||||
vprord TMP4, _WTp14, 17 \ // ROR_17(Wt-2)
|
||||
vprord TMP5, _WTp14, 19 \ // ROR_19(Wt-2)
|
||||
vpsrld TMP6, _WTp14, 10 \ // SHR_10(Wt-2)
|
||||
vpternlogd TMP4, TMP5, TMP6, 0x96 \ // TMP4 = sigma1(Wt-2)
|
||||
\
|
||||
vpaddd _WT, _WT, TMP4 \ // Wt = Wt-16 + sigma1(Wt-2)
|
||||
vpaddd _WT, _WT, _WTp9 \ // Wt = Wt-16 + sigma1(Wt-2) + Wt-7
|
||||
\
|
||||
vprord TMP4, _WTp1, 7 \ // ROR_7(Wt-15)
|
||||
vprord TMP5, _WTp1, 18 \ // ROR_18(Wt-15)
|
||||
vpsrld TMP6, _WTp1, 3 \ // SHR_3(Wt-15)
|
||||
vpternlogd TMP4, TMP5, TMP6, 0x96 \ // TMP4 = sigma0(Wt-15)
|
||||
\
|
||||
vpaddd _WT, _WT, TMP4 \ // Wt = Wt-16 + sigma1(Wt-2) +
|
||||
\ // Wt-7 + sigma0(Wt-15) +
|
||||
|
||||
|
||||
// Note this is reading in a block of data for one lane
|
||||
// When all 16 are read, the data must be transposed to build msg schedule
|
||||
#define MSG_SCHED_ROUND_00_15(_WT, OFFSET, LABEL) \
|
||||
TESTQ $(1<<OFFSET), MASK_P9 \
|
||||
JE LABEL \
|
||||
MOVQ OFFSET*24(INPUT_P9), R9 \
|
||||
vmovups _WT, [inp0+IDX] \
|
||||
LABEL: \
|
||||
|
||||
#define MASKED_LOAD(_WT, OFFSET, LABEL) \
|
||||
TESTQ $(1<<OFFSET), MASK_P9 \
|
||||
JE LABEL \
|
||||
MOVQ OFFSET*24(INPUT_P9), R9 \
|
||||
vmovups _WT,[inp0+IDX] \
|
||||
LABEL: \
|
||||
|
||||
TEXT ·sha256_x16_avx512(SB), 7, $0
|
||||
MOVQ digests+0(FP), STATE_P9 //
|
||||
MOVQ scratch+8(FP), SCRATCH_P9
|
||||
MOVQ mask_len+32(FP), INP_SIZE_P9 // number of blocks to process
|
||||
MOVQ mask+24(FP), MASKP_P9
|
||||
MOVQ (MASKP_P9), MASK_P9
|
||||
kmovq k1, mask
|
||||
LEAQ inputs+48(FP), INPUT_P9
|
||||
|
||||
// Initialize digests
|
||||
vmovdqu32 A, [STATE + 0*SHA256_DIGEST_ROW_SIZE]
|
||||
vmovdqu32 B, [STATE + 1*SHA256_DIGEST_ROW_SIZE]
|
||||
vmovdqu32 C, [STATE + 2*SHA256_DIGEST_ROW_SIZE]
|
||||
vmovdqu32 D, [STATE + 3*SHA256_DIGEST_ROW_SIZE]
|
||||
vmovdqu32 E, [STATE + 4*SHA256_DIGEST_ROW_SIZE]
|
||||
vmovdqu32 F, [STATE + 5*SHA256_DIGEST_ROW_SIZE]
|
||||
vmovdqu32 G, [STATE + 6*SHA256_DIGEST_ROW_SIZE]
|
||||
vmovdqu32 H, [STATE + 7*SHA256_DIGEST_ROW_SIZE]
|
||||
|
||||
MOVQ table+16(FP), TBL_P9
|
||||
|
||||
xor IDX, IDX
|
||||
|
||||
// Read in first block of input data
|
||||
MASKED_LOAD( W0, 0, skipInput0)
|
||||
MASKED_LOAD( W1, 1, skipInput1)
|
||||
MASKED_LOAD( W2, 2, skipInput2)
|
||||
MASKED_LOAD( W3, 3, skipInput3)
|
||||
MASKED_LOAD( W4, 4, skipInput4)
|
||||
MASKED_LOAD( W5, 5, skipInput5)
|
||||
MASKED_LOAD( W6, 6, skipInput6)
|
||||
MASKED_LOAD( W7, 7, skipInput7)
|
||||
MASKED_LOAD( W8, 8, skipInput8)
|
||||
MASKED_LOAD( W9, 9, skipInput9)
|
||||
MASKED_LOAD(W10, 10, skipInput10)
|
||||
MASKED_LOAD(W11, 11, skipInput11)
|
||||
MASKED_LOAD(W12, 12, skipInput12)
|
||||
MASKED_LOAD(W13, 13, skipInput13)
|
||||
MASKED_LOAD(W14, 14, skipInput14)
|
||||
MASKED_LOAD(W15, 15, skipInput15)
|
||||
|
||||
lloop:
|
||||
LEAQ PSHUFFLE_BYTE_FLIP_MASK<>(SB), TBL_P9
|
||||
vmovdqu32 TMP2, [TBL]
|
||||
|
||||
// Get first K from table
|
||||
MOVQ table+16(FP), TBL_P9
|
||||
vmovdqu32 TMP3, [TBL]
|
||||
|
||||
// Save digests for later addition
|
||||
vmovdqu32 [SCRATCH + 64*0], A
|
||||
vmovdqu32 [SCRATCH + 64*1], B
|
||||
vmovdqu32 [SCRATCH + 64*2], C
|
||||
vmovdqu32 [SCRATCH + 64*3], D
|
||||
vmovdqu32 [SCRATCH + 64*4], E
|
||||
vmovdqu32 [SCRATCH + 64*5], F
|
||||
vmovdqu32 [SCRATCH + 64*6], G
|
||||
vmovdqu32 [SCRATCH + 64*7], H
|
||||
|
||||
add IDX, 64
|
||||
|
||||
// Transpose input data
|
||||
TRANSPOSE16(W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, TMP0, TMP1)
|
||||
|
||||
vpshufb W0, W0, TMP2
|
||||
vpshufb W1, W1, TMP2
|
||||
vpshufb W2, W2, TMP2
|
||||
vpshufb W3, W3, TMP2
|
||||
vpshufb W4, W4, TMP2
|
||||
vpshufb W5, W5, TMP2
|
||||
vpshufb W6, W6, TMP2
|
||||
vpshufb W7, W7, TMP2
|
||||
vpshufb W8, W8, TMP2
|
||||
vpshufb W9, W9, TMP2
|
||||
vpshufb W10, W10, TMP2
|
||||
vpshufb W11, W11, TMP2
|
||||
vpshufb W12, W12, TMP2
|
||||
vpshufb W13, W13, TMP2
|
||||
vpshufb W14, W14, TMP2
|
||||
vpshufb W15, W15, TMP2
|
||||
|
||||
// MSG Schedule for W0-W15 is now complete in registers
|
||||
// Process first 48 rounds
|
||||
// Calculate next Wt+16 after processing is complete and Wt is unneeded
|
||||
|
||||
PROCESS_LOOP( W0, 0, A, B, C, D, E, F, G, H)
|
||||
MSG_SCHED_ROUND_16_63( W0, W1, W9, W14)
|
||||
PROCESS_LOOP( W1, 1, H, A, B, C, D, E, F, G)
|
||||
MSG_SCHED_ROUND_16_63( W1, W2, W10, W15)
|
||||
PROCESS_LOOP( W2, 2, G, H, A, B, C, D, E, F)
|
||||
MSG_SCHED_ROUND_16_63( W2, W3, W11, W0)
|
||||
PROCESS_LOOP( W3, 3, F, G, H, A, B, C, D, E)
|
||||
MSG_SCHED_ROUND_16_63( W3, W4, W12, W1)
|
||||
PROCESS_LOOP( W4, 4, E, F, G, H, A, B, C, D)
|
||||
MSG_SCHED_ROUND_16_63( W4, W5, W13, W2)
|
||||
PROCESS_LOOP( W5, 5, D, E, F, G, H, A, B, C)
|
||||
MSG_SCHED_ROUND_16_63( W5, W6, W14, W3)
|
||||
PROCESS_LOOP( W6, 6, C, D, E, F, G, H, A, B)
|
||||
MSG_SCHED_ROUND_16_63( W6, W7, W15, W4)
|
||||
PROCESS_LOOP( W7, 7, B, C, D, E, F, G, H, A)
|
||||
MSG_SCHED_ROUND_16_63( W7, W8, W0, W5)
|
||||
PROCESS_LOOP( W8, 8, A, B, C, D, E, F, G, H)
|
||||
MSG_SCHED_ROUND_16_63( W8, W9, W1, W6)
|
||||
PROCESS_LOOP( W9, 9, H, A, B, C, D, E, F, G)
|
||||
MSG_SCHED_ROUND_16_63( W9, W10, W2, W7)
|
||||
PROCESS_LOOP(W10, 10, G, H, A, B, C, D, E, F)
|
||||
MSG_SCHED_ROUND_16_63(W10, W11, W3, W8)
|
||||
PROCESS_LOOP(W11, 11, F, G, H, A, B, C, D, E)
|
||||
MSG_SCHED_ROUND_16_63(W11, W12, W4, W9)
|
||||
PROCESS_LOOP(W12, 12, E, F, G, H, A, B, C, D)
|
||||
MSG_SCHED_ROUND_16_63(W12, W13, W5, W10)
|
||||
PROCESS_LOOP(W13, 13, D, E, F, G, H, A, B, C)
|
||||
MSG_SCHED_ROUND_16_63(W13, W14, W6, W11)
|
||||
PROCESS_LOOP(W14, 14, C, D, E, F, G, H, A, B)
|
||||
MSG_SCHED_ROUND_16_63(W14, W15, W7, W12)
|
||||
PROCESS_LOOP(W15, 15, B, C, D, E, F, G, H, A)
|
||||
MSG_SCHED_ROUND_16_63(W15, W0, W8, W13)
|
||||
PROCESS_LOOP( W0, 16, A, B, C, D, E, F, G, H)
|
||||
MSG_SCHED_ROUND_16_63( W0, W1, W9, W14)
|
||||
PROCESS_LOOP( W1, 17, H, A, B, C, D, E, F, G)
|
||||
MSG_SCHED_ROUND_16_63( W1, W2, W10, W15)
|
||||
PROCESS_LOOP( W2, 18, G, H, A, B, C, D, E, F)
|
||||
MSG_SCHED_ROUND_16_63( W2, W3, W11, W0)
|
||||
PROCESS_LOOP( W3, 19, F, G, H, A, B, C, D, E)
|
||||
MSG_SCHED_ROUND_16_63( W3, W4, W12, W1)
|
||||
PROCESS_LOOP( W4, 20, E, F, G, H, A, B, C, D)
|
||||
MSG_SCHED_ROUND_16_63( W4, W5, W13, W2)
|
||||
PROCESS_LOOP( W5, 21, D, E, F, G, H, A, B, C)
|
||||
MSG_SCHED_ROUND_16_63( W5, W6, W14, W3)
|
||||
PROCESS_LOOP( W6, 22, C, D, E, F, G, H, A, B)
|
||||
MSG_SCHED_ROUND_16_63( W6, W7, W15, W4)
|
||||
PROCESS_LOOP( W7, 23, B, C, D, E, F, G, H, A)
|
||||
MSG_SCHED_ROUND_16_63( W7, W8, W0, W5)
|
||||
PROCESS_LOOP( W8, 24, A, B, C, D, E, F, G, H)
|
||||
MSG_SCHED_ROUND_16_63( W8, W9, W1, W6)
|
||||
PROCESS_LOOP( W9, 25, H, A, B, C, D, E, F, G)
|
||||
MSG_SCHED_ROUND_16_63( W9, W10, W2, W7)
|
||||
PROCESS_LOOP(W10, 26, G, H, A, B, C, D, E, F)
|
||||
MSG_SCHED_ROUND_16_63(W10, W11, W3, W8)
|
||||
PROCESS_LOOP(W11, 27, F, G, H, A, B, C, D, E)
|
||||
MSG_SCHED_ROUND_16_63(W11, W12, W4, W9)
|
||||
PROCESS_LOOP(W12, 28, E, F, G, H, A, B, C, D)
|
||||
MSG_SCHED_ROUND_16_63(W12, W13, W5, W10)
|
||||
PROCESS_LOOP(W13, 29, D, E, F, G, H, A, B, C)
|
||||
MSG_SCHED_ROUND_16_63(W13, W14, W6, W11)
|
||||
PROCESS_LOOP(W14, 30, C, D, E, F, G, H, A, B)
|
||||
MSG_SCHED_ROUND_16_63(W14, W15, W7, W12)
|
||||
PROCESS_LOOP(W15, 31, B, C, D, E, F, G, H, A)
|
||||
MSG_SCHED_ROUND_16_63(W15, W0, W8, W13)
|
||||
PROCESS_LOOP( W0, 32, A, B, C, D, E, F, G, H)
|
||||
MSG_SCHED_ROUND_16_63( W0, W1, W9, W14)
|
||||
PROCESS_LOOP( W1, 33, H, A, B, C, D, E, F, G)
|
||||
MSG_SCHED_ROUND_16_63( W1, W2, W10, W15)
|
||||
PROCESS_LOOP( W2, 34, G, H, A, B, C, D, E, F)
|
||||
MSG_SCHED_ROUND_16_63( W2, W3, W11, W0)
|
||||
PROCESS_LOOP( W3, 35, F, G, H, A, B, C, D, E)
|
||||
MSG_SCHED_ROUND_16_63( W3, W4, W12, W1)
|
||||
PROCESS_LOOP( W4, 36, E, F, G, H, A, B, C, D)
|
||||
MSG_SCHED_ROUND_16_63( W4, W5, W13, W2)
|
||||
PROCESS_LOOP( W5, 37, D, E, F, G, H, A, B, C)
|
||||
MSG_SCHED_ROUND_16_63( W5, W6, W14, W3)
|
||||
PROCESS_LOOP( W6, 38, C, D, E, F, G, H, A, B)
|
||||
MSG_SCHED_ROUND_16_63( W6, W7, W15, W4)
|
||||
PROCESS_LOOP( W7, 39, B, C, D, E, F, G, H, A)
|
||||
MSG_SCHED_ROUND_16_63( W7, W8, W0, W5)
|
||||
PROCESS_LOOP( W8, 40, A, B, C, D, E, F, G, H)
|
||||
MSG_SCHED_ROUND_16_63( W8, W9, W1, W6)
|
||||
PROCESS_LOOP( W9, 41, H, A, B, C, D, E, F, G)
|
||||
MSG_SCHED_ROUND_16_63( W9, W10, W2, W7)
|
||||
PROCESS_LOOP(W10, 42, G, H, A, B, C, D, E, F)
|
||||
MSG_SCHED_ROUND_16_63(W10, W11, W3, W8)
|
||||
PROCESS_LOOP(W11, 43, F, G, H, A, B, C, D, E)
|
||||
MSG_SCHED_ROUND_16_63(W11, W12, W4, W9)
|
||||
PROCESS_LOOP(W12, 44, E, F, G, H, A, B, C, D)
|
||||
MSG_SCHED_ROUND_16_63(W12, W13, W5, W10)
|
||||
PROCESS_LOOP(W13, 45, D, E, F, G, H, A, B, C)
|
||||
MSG_SCHED_ROUND_16_63(W13, W14, W6, W11)
|
||||
PROCESS_LOOP(W14, 46, C, D, E, F, G, H, A, B)
|
||||
MSG_SCHED_ROUND_16_63(W14, W15, W7, W12)
|
||||
PROCESS_LOOP(W15, 47, B, C, D, E, F, G, H, A)
|
||||
MSG_SCHED_ROUND_16_63(W15, W0, W8, W13)
|
||||
|
||||
// Check if this is the last block
|
||||
sub INP_SIZE, 1
|
||||
JE lastLoop
|
||||
|
||||
// Load next mask for inputs
|
||||
ADDQ $8, MASKP_P9
|
||||
MOVQ (MASKP_P9), MASK_P9
|
||||
|
||||
// Process last 16 rounds
|
||||
// Read in next block msg data for use in first 16 words of msg sched
|
||||
|
||||
PROCESS_LOOP( W0, 48, A, B, C, D, E, F, G, H)
|
||||
MSG_SCHED_ROUND_00_15( W0, 0, skipNext0)
|
||||
PROCESS_LOOP( W1, 49, H, A, B, C, D, E, F, G)
|
||||
MSG_SCHED_ROUND_00_15( W1, 1, skipNext1)
|
||||
PROCESS_LOOP( W2, 50, G, H, A, B, C, D, E, F)
|
||||
MSG_SCHED_ROUND_00_15( W2, 2, skipNext2)
|
||||
PROCESS_LOOP( W3, 51, F, G, H, A, B, C, D, E)
|
||||
MSG_SCHED_ROUND_00_15( W3, 3, skipNext3)
|
||||
PROCESS_LOOP( W4, 52, E, F, G, H, A, B, C, D)
|
||||
MSG_SCHED_ROUND_00_15( W4, 4, skipNext4)
|
||||
PROCESS_LOOP( W5, 53, D, E, F, G, H, A, B, C)
|
||||
MSG_SCHED_ROUND_00_15( W5, 5, skipNext5)
|
||||
PROCESS_LOOP( W6, 54, C, D, E, F, G, H, A, B)
|
||||
MSG_SCHED_ROUND_00_15( W6, 6, skipNext6)
|
||||
PROCESS_LOOP( W7, 55, B, C, D, E, F, G, H, A)
|
||||
MSG_SCHED_ROUND_00_15( W7, 7, skipNext7)
|
||||
PROCESS_LOOP( W8, 56, A, B, C, D, E, F, G, H)
|
||||
MSG_SCHED_ROUND_00_15( W8, 8, skipNext8)
|
||||
PROCESS_LOOP( W9, 57, H, A, B, C, D, E, F, G)
|
||||
MSG_SCHED_ROUND_00_15( W9, 9, skipNext9)
|
||||
PROCESS_LOOP(W10, 58, G, H, A, B, C, D, E, F)
|
||||
MSG_SCHED_ROUND_00_15(W10, 10, skipNext10)
|
||||
PROCESS_LOOP(W11, 59, F, G, H, A, B, C, D, E)
|
||||
MSG_SCHED_ROUND_00_15(W11, 11, skipNext11)
|
||||
PROCESS_LOOP(W12, 60, E, F, G, H, A, B, C, D)
|
||||
MSG_SCHED_ROUND_00_15(W12, 12, skipNext12)
|
||||
PROCESS_LOOP(W13, 61, D, E, F, G, H, A, B, C)
|
||||
MSG_SCHED_ROUND_00_15(W13, 13, skipNext13)
|
||||
PROCESS_LOOP(W14, 62, C, D, E, F, G, H, A, B)
|
||||
MSG_SCHED_ROUND_00_15(W14, 14, skipNext14)
|
||||
PROCESS_LOOP(W15, 63, B, C, D, E, F, G, H, A)
|
||||
MSG_SCHED_ROUND_00_15(W15, 15, skipNext15)
|
||||
|
||||
// Add old digest
|
||||
vmovdqu32 TMP2, A
|
||||
vmovdqu32 A, [SCRATCH + 64*0]
|
||||
vpaddd A{k1}, A, TMP2
|
||||
vmovdqu32 TMP2, B
|
||||
vmovdqu32 B, [SCRATCH + 64*1]
|
||||
vpaddd B{k1}, B, TMP2
|
||||
vmovdqu32 TMP2, C
|
||||
vmovdqu32 C, [SCRATCH + 64*2]
|
||||
vpaddd C{k1}, C, TMP2
|
||||
vmovdqu32 TMP2, D
|
||||
vmovdqu32 D, [SCRATCH + 64*3]
|
||||
vpaddd D{k1}, D, TMP2
|
||||
vmovdqu32 TMP2, E
|
||||
vmovdqu32 E, [SCRATCH + 64*4]
|
||||
vpaddd E{k1}, E, TMP2
|
||||
vmovdqu32 TMP2, F
|
||||
vmovdqu32 F, [SCRATCH + 64*5]
|
||||
vpaddd F{k1}, F, TMP2
|
||||
vmovdqu32 TMP2, G
|
||||
vmovdqu32 G, [SCRATCH + 64*6]
|
||||
vpaddd G{k1}, G, TMP2
|
||||
vmovdqu32 TMP2, H
|
||||
vmovdqu32 H, [SCRATCH + 64*7]
|
||||
vpaddd H{k1}, H, TMP2
|
||||
|
||||
kmovq k1, mask
|
||||
JMP lloop
|
||||
|
||||
lastLoop:
|
||||
// Process last 16 rounds
|
||||
PROCESS_LOOP( W0, 48, A, B, C, D, E, F, G, H)
|
||||
PROCESS_LOOP( W1, 49, H, A, B, C, D, E, F, G)
|
||||
PROCESS_LOOP( W2, 50, G, H, A, B, C, D, E, F)
|
||||
PROCESS_LOOP( W3, 51, F, G, H, A, B, C, D, E)
|
||||
PROCESS_LOOP( W4, 52, E, F, G, H, A, B, C, D)
|
||||
PROCESS_LOOP( W5, 53, D, E, F, G, H, A, B, C)
|
||||
PROCESS_LOOP( W6, 54, C, D, E, F, G, H, A, B)
|
||||
PROCESS_LOOP( W7, 55, B, C, D, E, F, G, H, A)
|
||||
PROCESS_LOOP( W8, 56, A, B, C, D, E, F, G, H)
|
||||
PROCESS_LOOP( W9, 57, H, A, B, C, D, E, F, G)
|
||||
PROCESS_LOOP(W10, 58, G, H, A, B, C, D, E, F)
|
||||
PROCESS_LOOP(W11, 59, F, G, H, A, B, C, D, E)
|
||||
PROCESS_LOOP(W12, 60, E, F, G, H, A, B, C, D)
|
||||
PROCESS_LOOP(W13, 61, D, E, F, G, H, A, B, C)
|
||||
PROCESS_LOOP(W14, 62, C, D, E, F, G, H, A, B)
|
||||
PROCESS_LOOP(W15, 63, B, C, D, E, F, G, H, A)
|
||||
|
||||
// Add old digest
|
||||
vmovdqu32 TMP2, A
|
||||
vmovdqu32 A, [SCRATCH + 64*0]
|
||||
vpaddd A{k1}, A, TMP2
|
||||
vmovdqu32 TMP2, B
|
||||
vmovdqu32 B, [SCRATCH + 64*1]
|
||||
vpaddd B{k1}, B, TMP2
|
||||
vmovdqu32 TMP2, C
|
||||
vmovdqu32 C, [SCRATCH + 64*2]
|
||||
vpaddd C{k1}, C, TMP2
|
||||
vmovdqu32 TMP2, D
|
||||
vmovdqu32 D, [SCRATCH + 64*3]
|
||||
vpaddd D{k1}, D, TMP2
|
||||
vmovdqu32 TMP2, E
|
||||
vmovdqu32 E, [SCRATCH + 64*4]
|
||||
vpaddd E{k1}, E, TMP2
|
||||
vmovdqu32 TMP2, F
|
||||
vmovdqu32 F, [SCRATCH + 64*5]
|
||||
vpaddd F{k1}, F, TMP2
|
||||
vmovdqu32 TMP2, G
|
||||
vmovdqu32 G, [SCRATCH + 64*6]
|
||||
vpaddd G{k1}, G, TMP2
|
||||
vmovdqu32 TMP2, H
|
||||
vmovdqu32 H, [SCRATCH + 64*7]
|
||||
vpaddd H{k1}, H, TMP2
|
||||
|
||||
// Write out digest
|
||||
vmovdqu32 [STATE + 0*SHA256_DIGEST_ROW_SIZE], A
|
||||
vmovdqu32 [STATE + 1*SHA256_DIGEST_ROW_SIZE], B
|
||||
vmovdqu32 [STATE + 2*SHA256_DIGEST_ROW_SIZE], C
|
||||
vmovdqu32 [STATE + 3*SHA256_DIGEST_ROW_SIZE], D
|
||||
vmovdqu32 [STATE + 4*SHA256_DIGEST_ROW_SIZE], E
|
||||
vmovdqu32 [STATE + 5*SHA256_DIGEST_ROW_SIZE], F
|
||||
vmovdqu32 [STATE + 6*SHA256_DIGEST_ROW_SIZE], G
|
||||
vmovdqu32 [STATE + 7*SHA256_DIGEST_ROW_SIZE], H
|
||||
|
||||
VZEROUPPER
|
||||
RET
|
||||
|
||||
//
|
||||
// Tables
|
||||
//
|
||||
|
||||
DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x000(SB)/8, $0x0405060700010203
|
||||
DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x008(SB)/8, $0x0c0d0e0f08090a0b
|
||||
DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x010(SB)/8, $0x0405060700010203
|
||||
DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x018(SB)/8, $0x0c0d0e0f08090a0b
|
||||
DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x020(SB)/8, $0x0405060700010203
|
||||
DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x028(SB)/8, $0x0c0d0e0f08090a0b
|
||||
DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x030(SB)/8, $0x0405060700010203
|
||||
DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x038(SB)/8, $0x0c0d0e0f08090a0b
|
||||
GLOBL PSHUFFLE_BYTE_FLIP_MASK<>(SB), 8, $64
|
||||
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x000(SB)/8, $0x0000000000000000
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x008(SB)/8, $0x0000000000000001
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x010(SB)/8, $0x0000000000000008
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x018(SB)/8, $0x0000000000000009
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x020(SB)/8, $0x0000000000000004
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x028(SB)/8, $0x0000000000000005
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x030(SB)/8, $0x000000000000000C
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x038(SB)/8, $0x000000000000000D
|
||||
GLOBL PSHUFFLE_TRANSPOSE16_MASK1<>(SB), 8, $64
|
||||
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x000(SB)/8, $0x0000000000000002
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x008(SB)/8, $0x0000000000000003
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x010(SB)/8, $0x000000000000000A
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x018(SB)/8, $0x000000000000000B
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x020(SB)/8, $0x0000000000000006
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x028(SB)/8, $0x0000000000000007
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x030(SB)/8, $0x000000000000000E
|
||||
DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x038(SB)/8, $0x000000000000000F
|
||||
GLOBL PSHUFFLE_TRANSPOSE16_MASK2<>(SB), 8, $64
|
500
vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.go
generated
vendored
Normal file
500
vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,500 @@
|
|||
//+build !noasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2017 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"hash"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func sha256X16Avx512(digests *[512]byte, scratch *[512]byte, table *[512]uint64, mask []uint64, inputs [16][]byte)
|
||||
|
||||
// Avx512ServerUID - Do not start at 0 but next multiple of 16 so as to be able to
|
||||
// differentiate with default initialiation value of 0
|
||||
const Avx512ServerUID = 16
|
||||
|
||||
var uidCounter uint64
|
||||
|
||||
// NewAvx512 - initialize sha256 Avx512 implementation.
|
||||
func NewAvx512(a512srv *Avx512Server) hash.Hash {
|
||||
uid := atomic.AddUint64(&uidCounter, 1)
|
||||
return &Avx512Digest{uid: uid, a512srv: a512srv}
|
||||
}
|
||||
|
||||
// Avx512Digest - Type for computing SHA256 using Avx512
|
||||
type Avx512Digest struct {
|
||||
uid uint64
|
||||
a512srv *Avx512Server
|
||||
x [chunk]byte
|
||||
nx int
|
||||
len uint64
|
||||
final bool
|
||||
result [Size]byte
|
||||
}
|
||||
|
||||
// Size - Return size of checksum
|
||||
func (d *Avx512Digest) Size() int { return Size }
|
||||
|
||||
// BlockSize - Return blocksize of checksum
|
||||
func (d Avx512Digest) BlockSize() int { return BlockSize }
|
||||
|
||||
// Reset - reset sha digest to its initial values
|
||||
func (d *Avx512Digest) Reset() {
|
||||
d.a512srv.blocksCh <- blockInput{uid: d.uid, reset: true}
|
||||
d.nx = 0
|
||||
d.len = 0
|
||||
d.final = false
|
||||
}
|
||||
|
||||
// Write to digest
|
||||
func (d *Avx512Digest) Write(p []byte) (nn int, err error) {
|
||||
|
||||
if d.final {
|
||||
return 0, errors.New("Avx512Digest already finalized. Reset first before writing again")
|
||||
}
|
||||
|
||||
nn = len(p)
|
||||
d.len += uint64(nn)
|
||||
if d.nx > 0 {
|
||||
n := copy(d.x[d.nx:], p)
|
||||
d.nx += n
|
||||
if d.nx == chunk {
|
||||
d.a512srv.blocksCh <- blockInput{uid: d.uid, msg: d.x[:]}
|
||||
d.nx = 0
|
||||
}
|
||||
p = p[n:]
|
||||
}
|
||||
if len(p) >= chunk {
|
||||
n := len(p) &^ (chunk - 1)
|
||||
d.a512srv.blocksCh <- blockInput{uid: d.uid, msg: p[:n]}
|
||||
p = p[n:]
|
||||
}
|
||||
if len(p) > 0 {
|
||||
d.nx = copy(d.x[:], p)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Sum - Return sha256 sum in bytes
|
||||
func (d *Avx512Digest) Sum(in []byte) (result []byte) {
|
||||
|
||||
if d.final {
|
||||
return append(in, d.result[:]...)
|
||||
}
|
||||
|
||||
trail := make([]byte, 0, 128)
|
||||
|
||||
len := d.len
|
||||
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
|
||||
var tmp [64]byte
|
||||
tmp[0] = 0x80
|
||||
if len%64 < 56 {
|
||||
trail = append(d.x[:d.nx], tmp[0:56-len%64]...)
|
||||
} else {
|
||||
trail = append(d.x[:d.nx], tmp[0:64+56-len%64]...)
|
||||
}
|
||||
d.nx = 0
|
||||
|
||||
// Length in bits.
|
||||
len <<= 3
|
||||
for i := uint(0); i < 8; i++ {
|
||||
tmp[i] = byte(len >> (56 - 8*i))
|
||||
}
|
||||
trail = append(trail, tmp[0:8]...)
|
||||
|
||||
sumCh := make(chan [Size]byte)
|
||||
d.a512srv.blocksCh <- blockInput{uid: d.uid, msg: trail, final: true, sumCh: sumCh}
|
||||
d.result = <-sumCh
|
||||
d.final = true
|
||||
return append(in, d.result[:]...)
|
||||
}
|
||||
|
||||
var table = [512]uint64{
|
||||
0x428a2f98428a2f98, 0x428a2f98428a2f98, 0x428a2f98428a2f98, 0x428a2f98428a2f98,
|
||||
0x428a2f98428a2f98, 0x428a2f98428a2f98, 0x428a2f98428a2f98, 0x428a2f98428a2f98,
|
||||
0x7137449171374491, 0x7137449171374491, 0x7137449171374491, 0x7137449171374491,
|
||||
0x7137449171374491, 0x7137449171374491, 0x7137449171374491, 0x7137449171374491,
|
||||
0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf,
|
||||
0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf,
|
||||
0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5,
|
||||
0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5,
|
||||
0x3956c25b3956c25b, 0x3956c25b3956c25b, 0x3956c25b3956c25b, 0x3956c25b3956c25b,
|
||||
0x3956c25b3956c25b, 0x3956c25b3956c25b, 0x3956c25b3956c25b, 0x3956c25b3956c25b,
|
||||
0x59f111f159f111f1, 0x59f111f159f111f1, 0x59f111f159f111f1, 0x59f111f159f111f1,
|
||||
0x59f111f159f111f1, 0x59f111f159f111f1, 0x59f111f159f111f1, 0x59f111f159f111f1,
|
||||
0x923f82a4923f82a4, 0x923f82a4923f82a4, 0x923f82a4923f82a4, 0x923f82a4923f82a4,
|
||||
0x923f82a4923f82a4, 0x923f82a4923f82a4, 0x923f82a4923f82a4, 0x923f82a4923f82a4,
|
||||
0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5,
|
||||
0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5,
|
||||
0xd807aa98d807aa98, 0xd807aa98d807aa98, 0xd807aa98d807aa98, 0xd807aa98d807aa98,
|
||||
0xd807aa98d807aa98, 0xd807aa98d807aa98, 0xd807aa98d807aa98, 0xd807aa98d807aa98,
|
||||
0x12835b0112835b01, 0x12835b0112835b01, 0x12835b0112835b01, 0x12835b0112835b01,
|
||||
0x12835b0112835b01, 0x12835b0112835b01, 0x12835b0112835b01, 0x12835b0112835b01,
|
||||
0x243185be243185be, 0x243185be243185be, 0x243185be243185be, 0x243185be243185be,
|
||||
0x243185be243185be, 0x243185be243185be, 0x243185be243185be, 0x243185be243185be,
|
||||
0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3,
|
||||
0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3,
|
||||
0x72be5d7472be5d74, 0x72be5d7472be5d74, 0x72be5d7472be5d74, 0x72be5d7472be5d74,
|
||||
0x72be5d7472be5d74, 0x72be5d7472be5d74, 0x72be5d7472be5d74, 0x72be5d7472be5d74,
|
||||
0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe,
|
||||
0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe,
|
||||
0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7,
|
||||
0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7,
|
||||
0xc19bf174c19bf174, 0xc19bf174c19bf174, 0xc19bf174c19bf174, 0xc19bf174c19bf174,
|
||||
0xc19bf174c19bf174, 0xc19bf174c19bf174, 0xc19bf174c19bf174, 0xc19bf174c19bf174,
|
||||
0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1,
|
||||
0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1,
|
||||
0xefbe4786efbe4786, 0xefbe4786efbe4786, 0xefbe4786efbe4786, 0xefbe4786efbe4786,
|
||||
0xefbe4786efbe4786, 0xefbe4786efbe4786, 0xefbe4786efbe4786, 0xefbe4786efbe4786,
|
||||
0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6,
|
||||
0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6,
|
||||
0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc,
|
||||
0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc,
|
||||
0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f,
|
||||
0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f,
|
||||
0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa,
|
||||
0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa,
|
||||
0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc,
|
||||
0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc,
|
||||
0x76f988da76f988da, 0x76f988da76f988da, 0x76f988da76f988da, 0x76f988da76f988da,
|
||||
0x76f988da76f988da, 0x76f988da76f988da, 0x76f988da76f988da, 0x76f988da76f988da,
|
||||
0x983e5152983e5152, 0x983e5152983e5152, 0x983e5152983e5152, 0x983e5152983e5152,
|
||||
0x983e5152983e5152, 0x983e5152983e5152, 0x983e5152983e5152, 0x983e5152983e5152,
|
||||
0xa831c66da831c66d, 0xa831c66da831c66d, 0xa831c66da831c66d, 0xa831c66da831c66d,
|
||||
0xa831c66da831c66d, 0xa831c66da831c66d, 0xa831c66da831c66d, 0xa831c66da831c66d,
|
||||
0xb00327c8b00327c8, 0xb00327c8b00327c8, 0xb00327c8b00327c8, 0xb00327c8b00327c8,
|
||||
0xb00327c8b00327c8, 0xb00327c8b00327c8, 0xb00327c8b00327c8, 0xb00327c8b00327c8,
|
||||
0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7,
|
||||
0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7,
|
||||
0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3,
|
||||
0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3,
|
||||
0xd5a79147d5a79147, 0xd5a79147d5a79147, 0xd5a79147d5a79147, 0xd5a79147d5a79147,
|
||||
0xd5a79147d5a79147, 0xd5a79147d5a79147, 0xd5a79147d5a79147, 0xd5a79147d5a79147,
|
||||
0x06ca635106ca6351, 0x06ca635106ca6351, 0x06ca635106ca6351, 0x06ca635106ca6351,
|
||||
0x06ca635106ca6351, 0x06ca635106ca6351, 0x06ca635106ca6351, 0x06ca635106ca6351,
|
||||
0x1429296714292967, 0x1429296714292967, 0x1429296714292967, 0x1429296714292967,
|
||||
0x1429296714292967, 0x1429296714292967, 0x1429296714292967, 0x1429296714292967,
|
||||
0x27b70a8527b70a85, 0x27b70a8527b70a85, 0x27b70a8527b70a85, 0x27b70a8527b70a85,
|
||||
0x27b70a8527b70a85, 0x27b70a8527b70a85, 0x27b70a8527b70a85, 0x27b70a8527b70a85,
|
||||
0x2e1b21382e1b2138, 0x2e1b21382e1b2138, 0x2e1b21382e1b2138, 0x2e1b21382e1b2138,
|
||||
0x2e1b21382e1b2138, 0x2e1b21382e1b2138, 0x2e1b21382e1b2138, 0x2e1b21382e1b2138,
|
||||
0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc,
|
||||
0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc,
|
||||
0x53380d1353380d13, 0x53380d1353380d13, 0x53380d1353380d13, 0x53380d1353380d13,
|
||||
0x53380d1353380d13, 0x53380d1353380d13, 0x53380d1353380d13, 0x53380d1353380d13,
|
||||
0x650a7354650a7354, 0x650a7354650a7354, 0x650a7354650a7354, 0x650a7354650a7354,
|
||||
0x650a7354650a7354, 0x650a7354650a7354, 0x650a7354650a7354, 0x650a7354650a7354,
|
||||
0x766a0abb766a0abb, 0x766a0abb766a0abb, 0x766a0abb766a0abb, 0x766a0abb766a0abb,
|
||||
0x766a0abb766a0abb, 0x766a0abb766a0abb, 0x766a0abb766a0abb, 0x766a0abb766a0abb,
|
||||
0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e,
|
||||
0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e,
|
||||
0x92722c8592722c85, 0x92722c8592722c85, 0x92722c8592722c85, 0x92722c8592722c85,
|
||||
0x92722c8592722c85, 0x92722c8592722c85, 0x92722c8592722c85, 0x92722c8592722c85,
|
||||
0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1,
|
||||
0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1,
|
||||
0xa81a664ba81a664b, 0xa81a664ba81a664b, 0xa81a664ba81a664b, 0xa81a664ba81a664b,
|
||||
0xa81a664ba81a664b, 0xa81a664ba81a664b, 0xa81a664ba81a664b, 0xa81a664ba81a664b,
|
||||
0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70,
|
||||
0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70,
|
||||
0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3,
|
||||
0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3,
|
||||
0xd192e819d192e819, 0xd192e819d192e819, 0xd192e819d192e819, 0xd192e819d192e819,
|
||||
0xd192e819d192e819, 0xd192e819d192e819, 0xd192e819d192e819, 0xd192e819d192e819,
|
||||
0xd6990624d6990624, 0xd6990624d6990624, 0xd6990624d6990624, 0xd6990624d6990624,
|
||||
0xd6990624d6990624, 0xd6990624d6990624, 0xd6990624d6990624, 0xd6990624d6990624,
|
||||
0xf40e3585f40e3585, 0xf40e3585f40e3585, 0xf40e3585f40e3585, 0xf40e3585f40e3585,
|
||||
0xf40e3585f40e3585, 0xf40e3585f40e3585, 0xf40e3585f40e3585, 0xf40e3585f40e3585,
|
||||
0x106aa070106aa070, 0x106aa070106aa070, 0x106aa070106aa070, 0x106aa070106aa070,
|
||||
0x106aa070106aa070, 0x106aa070106aa070, 0x106aa070106aa070, 0x106aa070106aa070,
|
||||
0x19a4c11619a4c116, 0x19a4c11619a4c116, 0x19a4c11619a4c116, 0x19a4c11619a4c116,
|
||||
0x19a4c11619a4c116, 0x19a4c11619a4c116, 0x19a4c11619a4c116, 0x19a4c11619a4c116,
|
||||
0x1e376c081e376c08, 0x1e376c081e376c08, 0x1e376c081e376c08, 0x1e376c081e376c08,
|
||||
0x1e376c081e376c08, 0x1e376c081e376c08, 0x1e376c081e376c08, 0x1e376c081e376c08,
|
||||
0x2748774c2748774c, 0x2748774c2748774c, 0x2748774c2748774c, 0x2748774c2748774c,
|
||||
0x2748774c2748774c, 0x2748774c2748774c, 0x2748774c2748774c, 0x2748774c2748774c,
|
||||
0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5,
|
||||
0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5,
|
||||
0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3,
|
||||
0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3,
|
||||
0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a,
|
||||
0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a,
|
||||
0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f,
|
||||
0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f,
|
||||
0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3,
|
||||
0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3,
|
||||
0x748f82ee748f82ee, 0x748f82ee748f82ee, 0x748f82ee748f82ee, 0x748f82ee748f82ee,
|
||||
0x748f82ee748f82ee, 0x748f82ee748f82ee, 0x748f82ee748f82ee, 0x748f82ee748f82ee,
|
||||
0x78a5636f78a5636f, 0x78a5636f78a5636f, 0x78a5636f78a5636f, 0x78a5636f78a5636f,
|
||||
0x78a5636f78a5636f, 0x78a5636f78a5636f, 0x78a5636f78a5636f, 0x78a5636f78a5636f,
|
||||
0x84c8781484c87814, 0x84c8781484c87814, 0x84c8781484c87814, 0x84c8781484c87814,
|
||||
0x84c8781484c87814, 0x84c8781484c87814, 0x84c8781484c87814, 0x84c8781484c87814,
|
||||
0x8cc702088cc70208, 0x8cc702088cc70208, 0x8cc702088cc70208, 0x8cc702088cc70208,
|
||||
0x8cc702088cc70208, 0x8cc702088cc70208, 0x8cc702088cc70208, 0x8cc702088cc70208,
|
||||
0x90befffa90befffa, 0x90befffa90befffa, 0x90befffa90befffa, 0x90befffa90befffa,
|
||||
0x90befffa90befffa, 0x90befffa90befffa, 0x90befffa90befffa, 0x90befffa90befffa,
|
||||
0xa4506ceba4506ceb, 0xa4506ceba4506ceb, 0xa4506ceba4506ceb, 0xa4506ceba4506ceb,
|
||||
0xa4506ceba4506ceb, 0xa4506ceba4506ceb, 0xa4506ceba4506ceb, 0xa4506ceba4506ceb,
|
||||
0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7,
|
||||
0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7,
|
||||
0xc67178f2c67178f2, 0xc67178f2c67178f2, 0xc67178f2c67178f2, 0xc67178f2c67178f2,
|
||||
0xc67178f2c67178f2, 0xc67178f2c67178f2, 0xc67178f2c67178f2, 0xc67178f2c67178f2}
|
||||
|
||||
// Interface function to assembly ode
|
||||
func blockAvx512(digests *[512]byte, input [16][]byte, mask []uint64) [16][Size]byte {
|
||||
|
||||
scratch := [512]byte{}
|
||||
sha256X16Avx512(digests, &scratch, &table, mask, input)
|
||||
|
||||
output := [16][Size]byte{}
|
||||
for i := 0; i < 16; i++ {
|
||||
output[i] = getDigest(i, digests[:])
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func getDigest(index int, state []byte) (sum [Size]byte) {
|
||||
for j := 0; j < 16; j += 2 {
|
||||
for i := index*4 + j*Size; i < index*4+(j+1)*Size; i += Size {
|
||||
binary.BigEndian.PutUint32(sum[j*2:], binary.LittleEndian.Uint32(state[i:i+4]))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Message to send across input channel
|
||||
type blockInput struct {
|
||||
uid uint64
|
||||
msg []byte
|
||||
reset bool
|
||||
final bool
|
||||
sumCh chan [Size]byte
|
||||
}
|
||||
|
||||
// Avx512Server - Type to implement 16x parallel handling of SHA256 invocations
|
||||
type Avx512Server struct {
|
||||
blocksCh chan blockInput // Input channel
|
||||
totalIn int // Total number of inputs waiting to be processed
|
||||
lanes [16]Avx512LaneInfo // Array with info per lane (out of 16)
|
||||
digests map[uint64][Size]byte // Map of uids to (interim) digest results
|
||||
}
|
||||
|
||||
// Avx512LaneInfo - Info for each lane
|
||||
type Avx512LaneInfo struct {
|
||||
uid uint64 // unique identification for this SHA processing
|
||||
block []byte // input block to be processed
|
||||
outputCh chan [Size]byte // channel for output result
|
||||
}
|
||||
|
||||
// NewAvx512Server - Create new object for parallel processing handling
|
||||
func NewAvx512Server() *Avx512Server {
|
||||
a512srv := &Avx512Server{}
|
||||
a512srv.digests = make(map[uint64][Size]byte)
|
||||
a512srv.blocksCh = make(chan blockInput)
|
||||
|
||||
// Start a single thread for reading from the input channel
|
||||
go a512srv.Process()
|
||||
return a512srv
|
||||
}
|
||||
|
||||
// Process - Sole handler for reading from the input channel
|
||||
func (a512srv *Avx512Server) Process() {
|
||||
for {
|
||||
select {
|
||||
case block := <-a512srv.blocksCh:
|
||||
if block.reset {
|
||||
a512srv.reset(block.uid)
|
||||
continue
|
||||
}
|
||||
index := block.uid & 0xf
|
||||
// fmt.Println("Adding message:", block.uid, index)
|
||||
|
||||
if a512srv.lanes[index].block != nil { // If slot is already filled, process all inputs
|
||||
//fmt.Println("Invoking Blocks()")
|
||||
a512srv.blocks()
|
||||
}
|
||||
a512srv.totalIn++
|
||||
a512srv.lanes[index] = Avx512LaneInfo{uid: block.uid, block: block.msg}
|
||||
if block.final {
|
||||
a512srv.lanes[index].outputCh = block.sumCh
|
||||
}
|
||||
if a512srv.totalIn == len(a512srv.lanes) {
|
||||
// fmt.Println("Invoking Blocks() while FULL: ")
|
||||
a512srv.blocks()
|
||||
}
|
||||
|
||||
// TODO: test with larger timeout
|
||||
case <-time.After(1 * time.Microsecond):
|
||||
for _, lane := range a512srv.lanes {
|
||||
if lane.block != nil { // check if there is any input to process
|
||||
// fmt.Println("Invoking Blocks() on TIMEOUT: ")
|
||||
a512srv.blocks()
|
||||
break // we are done
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do a reset for this calculation
|
||||
func (a512srv *Avx512Server) reset(uid uint64) {
|
||||
|
||||
// Check if there is a message still waiting to be processed (and remove if so)
|
||||
for i, lane := range a512srv.lanes {
|
||||
if lane.uid == uid {
|
||||
if lane.block != nil {
|
||||
a512srv.lanes[i] = Avx512LaneInfo{} // clear message
|
||||
a512srv.totalIn--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete entry from hash map
|
||||
delete(a512srv.digests, uid)
|
||||
}
|
||||
|
||||
// Invoke assembly and send results back
|
||||
func (a512srv *Avx512Server) blocks() (err error) {
|
||||
|
||||
inputs := [16][]byte{}
|
||||
for i := range inputs {
|
||||
inputs[i] = a512srv.lanes[i].block
|
||||
}
|
||||
|
||||
mask := expandMask(genMask(inputs))
|
||||
outputs := blockAvx512(a512srv.getDigests(), inputs, mask)
|
||||
|
||||
a512srv.totalIn = 0
|
||||
for i := 0; i < len(outputs); i++ {
|
||||
uid, outputCh := a512srv.lanes[i].uid, a512srv.lanes[i].outputCh
|
||||
a512srv.digests[uid] = outputs[i]
|
||||
a512srv.lanes[i] = Avx512LaneInfo{}
|
||||
|
||||
if outputCh != nil {
|
||||
// Send back result
|
||||
outputCh <- outputs[i]
|
||||
delete(a512srv.digests, uid) // Delete entry from hashmap
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (a512srv *Avx512Server) Write(uid uint64, p []byte) (nn int, err error) {
|
||||
a512srv.blocksCh <- blockInput{uid: uid, msg: p}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Sum - return sha256 sum in bytes for a given sum id.
|
||||
func (a512srv *Avx512Server) Sum(uid uint64, p []byte) [32]byte {
|
||||
sumCh := make(chan [32]byte)
|
||||
a512srv.blocksCh <- blockInput{uid: uid, msg: p, final: true, sumCh: sumCh}
|
||||
return <-sumCh
|
||||
}
|
||||
|
||||
func (a512srv *Avx512Server) getDigests() *[512]byte {
|
||||
digests := [512]byte{}
|
||||
for i, lane := range a512srv.lanes {
|
||||
a, ok := a512srv.digests[lane.uid]
|
||||
if ok {
|
||||
binary.BigEndian.PutUint32(digests[(i+0*16)*4:], binary.LittleEndian.Uint32(a[0:4]))
|
||||
binary.BigEndian.PutUint32(digests[(i+1*16)*4:], binary.LittleEndian.Uint32(a[4:8]))
|
||||
binary.BigEndian.PutUint32(digests[(i+2*16)*4:], binary.LittleEndian.Uint32(a[8:12]))
|
||||
binary.BigEndian.PutUint32(digests[(i+3*16)*4:], binary.LittleEndian.Uint32(a[12:16]))
|
||||
binary.BigEndian.PutUint32(digests[(i+4*16)*4:], binary.LittleEndian.Uint32(a[16:20]))
|
||||
binary.BigEndian.PutUint32(digests[(i+5*16)*4:], binary.LittleEndian.Uint32(a[20:24]))
|
||||
binary.BigEndian.PutUint32(digests[(i+6*16)*4:], binary.LittleEndian.Uint32(a[24:28]))
|
||||
binary.BigEndian.PutUint32(digests[(i+7*16)*4:], binary.LittleEndian.Uint32(a[28:32]))
|
||||
} else {
|
||||
binary.LittleEndian.PutUint32(digests[(i+0*16)*4:], init0)
|
||||
binary.LittleEndian.PutUint32(digests[(i+1*16)*4:], init1)
|
||||
binary.LittleEndian.PutUint32(digests[(i+2*16)*4:], init2)
|
||||
binary.LittleEndian.PutUint32(digests[(i+3*16)*4:], init3)
|
||||
binary.LittleEndian.PutUint32(digests[(i+4*16)*4:], init4)
|
||||
binary.LittleEndian.PutUint32(digests[(i+5*16)*4:], init5)
|
||||
binary.LittleEndian.PutUint32(digests[(i+6*16)*4:], init6)
|
||||
binary.LittleEndian.PutUint32(digests[(i+7*16)*4:], init7)
|
||||
}
|
||||
}
|
||||
return &digests
|
||||
}
|
||||
|
||||
// Helper struct for sorting blocks based on length
|
||||
type lane struct {
|
||||
len uint
|
||||
pos uint
|
||||
}
|
||||
|
||||
type lanes []lane
|
||||
|
||||
func (lns lanes) Len() int { return len(lns) }
|
||||
func (lns lanes) Swap(i, j int) { lns[i], lns[j] = lns[j], lns[i] }
|
||||
func (lns lanes) Less(i, j int) bool { return lns[i].len < lns[j].len }
|
||||
|
||||
// Helper struct for
|
||||
type maskRounds struct {
|
||||
mask uint64
|
||||
rounds uint64
|
||||
}
|
||||
|
||||
func genMask(input [16][]byte) [16]maskRounds {
|
||||
|
||||
// Sort on blocks length small to large
|
||||
var sorted [16]lane
|
||||
for c, inpt := range input {
|
||||
sorted[c] = lane{uint(len(inpt)), uint(c)}
|
||||
}
|
||||
sort.Sort(lanes(sorted[:]))
|
||||
|
||||
// Create mask array including 'rounds' between masks
|
||||
m, round, index := uint64(0xffff), uint64(0), 0
|
||||
var mr [16]maskRounds
|
||||
for _, s := range sorted {
|
||||
if s.len > 0 {
|
||||
if uint64(s.len)>>6 > round {
|
||||
mr[index] = maskRounds{m, (uint64(s.len) >> 6) - round}
|
||||
index++
|
||||
}
|
||||
round = uint64(s.len) >> 6
|
||||
}
|
||||
m = m & ^(1 << uint(s.pos))
|
||||
}
|
||||
|
||||
return mr
|
||||
}
|
||||
|
||||
// TODO: remove function
|
||||
func expandMask(mr [16]maskRounds) []uint64 {
|
||||
size := uint64(0)
|
||||
for _, r := range mr {
|
||||
size += r.rounds
|
||||
}
|
||||
result, index := make([]uint64, size), 0
|
||||
for _, r := range mr {
|
||||
for j := uint64(0); j < r.rounds; j++ {
|
||||
result[index] = r.mask
|
||||
index++
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
267
vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.s
generated
vendored
Normal file
267
vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.s
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
22
vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.go
generated
vendored
Normal file
22
vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
//+build !noasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
//go:noescape
|
||||
func blockAvx(h []uint32, message []uint8, reserved0, reserved1, reserved2, reserved3 uint64)
|
408
vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.s
generated
vendored
Normal file
408
vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,408 @@
|
|||
//+build !noasm,!appengine
|
||||
|
||||
// SHA256 implementation for AVX
|
||||
|
||||
//
|
||||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
//
|
||||
// This code is based on an Intel White-Paper:
|
||||
// "Fast SHA-256 Implementations on Intel Architecture Processors"
|
||||
//
|
||||
// together with the reference implementation from the following authors:
|
||||
// James Guilford <james.guilford@intel.com>
|
||||
// Kirk Yap <kirk.s.yap@intel.com>
|
||||
// Tim Chen <tim.c.chen@linux.intel.com>
|
||||
//
|
||||
// For Golang it has been converted to Plan 9 assembly with the help of
|
||||
// github.com/minio/asm2plan9s to assemble Intel instructions to their Plan9
|
||||
// equivalents
|
||||
//
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define ROTATE_XS \
|
||||
MOVOU X4, X15 \
|
||||
MOVOU X5, X4 \
|
||||
MOVOU X6, X5 \
|
||||
MOVOU X7, X6 \
|
||||
MOVOU X15, X7
|
||||
|
||||
// compute s0 four at a time and s1 two at a time
|
||||
// compute W[-16] + W[-7] 4 at a time
|
||||
#define FOUR_ROUNDS_AND_SCHED(a, b, c, d, e, f, g, h) \
|
||||
MOVL e, R13 \ // y0 = e
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
MOVL a, R14 \ // y1 = a
|
||||
LONG $0x0f41e3c4; WORD $0x04c6 \ // VPALIGNR XMM0,XMM7,XMM6,0x4 /* XTMP0 = W[-7] */
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
XORL e, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
MOVL f, R15 \ // y2 = f
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
XORL a, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
XORL g, R15 \ // y2 = f^g
|
||||
LONG $0xc4fef9c5 \ // VPADDD XMM0,XMM0,XMM4 /* XTMP0 = W[-7] + W[-16] */
|
||||
XORL e, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6) )
|
||||
ANDL e, R15 \ // y2 = (f^g)&e
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
\
|
||||
\ // compute s0
|
||||
\
|
||||
LONG $0x0f51e3c4; WORD $0x04cc \ // VPALIGNR XMM1,XMM5,XMM4,0x4 /* XTMP1 = W[-15] */
|
||||
XORL a, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
XORL g, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ADDL _xfer+48(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
MOVL a, R13 \ // y0 = a
|
||||
ADDL R15, h \ // h = h + S1 + CH + k + w
|
||||
\ // ROTATE_ARGS
|
||||
MOVL a, R15 \ // y2 = a
|
||||
LONG $0xd172e9c5; BYTE $0x07 \ // VPSRLD XMM2,XMM1,0x7 /* */
|
||||
ORL c, R13 \ // y0 = a|c
|
||||
ADDL h, d \ // d = d + h + S1 + CH + k + w
|
||||
ANDL c, R15 \ // y2 = a&c
|
||||
LONG $0xf172e1c5; BYTE $0x19 \ // VPSLLD XMM3,XMM1,0x19 /* */
|
||||
ANDL b, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, h \ // h = h + S1 + CH + k + w + S0
|
||||
LONG $0xdaebe1c5 \ // VPOR XMM3,XMM3,XMM2 /* XTMP1 = W[-15] MY_ROR 7 */
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, h \ // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
\ // ROTATE_ARGS
|
||||
MOVL d, R13 \ // y0 = e
|
||||
MOVL h, R14 \ // y1 = a
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
XORL d, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
MOVL e, R15 \ // y2 = f
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
LONG $0xd172e9c5; BYTE $0x12 \ // VPSRLD XMM2,XMM1,0x12 /* */
|
||||
XORL h, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
XORL f, R15 \ // y2 = f^g
|
||||
LONG $0xd172b9c5; BYTE $0x03 \ // VPSRLD XMM8,XMM1,0x3 /* XTMP4 = W[-15] >> 3 */
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
XORL d, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
|
||||
ANDL d, R15 \ // y2 = (f^g)&e
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
LONG $0xf172f1c5; BYTE $0x0e \ // VPSLLD XMM1,XMM1,0xe /* */
|
||||
XORL h, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
XORL f, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
LONG $0xd9efe1c5 \ // VPXOR XMM3,XMM3,XMM1 /* */
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ADDL _xfer+52(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
LONG $0xdaefe1c5 \ // VPXOR XMM3,XMM3,XMM2 /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR */
|
||||
MOVL h, R13 \ // y0 = a
|
||||
ADDL R15, g \ // h = h + S1 + CH + k + w
|
||||
MOVL h, R15 \ // y2 = a
|
||||
LONG $0xef61c1c4; BYTE $0xc8 \ // VPXOR XMM1,XMM3,XMM8 /* XTMP1 = s0 */
|
||||
ORL b, R13 \ // y0 = a|c
|
||||
ADDL g, c \ // d = d + h + S1 + CH + k + w
|
||||
ANDL b, R15 \ // y2 = a&c
|
||||
\
|
||||
\ // compute low s1
|
||||
\
|
||||
LONG $0xd770f9c5; BYTE $0xfa \ // VPSHUFD XMM2,XMM7,0xfa /* XTMP2 = W[-2] {BBAA} */
|
||||
ANDL a, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, g \ // h = h + S1 + CH + k + w + S0
|
||||
LONG $0xc1fef9c5 \ // VPADDD XMM0,XMM0,XMM1 /* XTMP0 = W[-16] + W[-7] + s0 */
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, g \ // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
\ // ROTATE_ARGS
|
||||
MOVL c, R13 \ // y0 = e
|
||||
MOVL g, R14 \ // y1 = a
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
XORL c, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
MOVL d, R15 \ // y2 = f
|
||||
XORL g, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
LONG $0xd272b9c5; BYTE $0x0a \ // VPSRLD XMM8,XMM2,0xa /* XTMP4 = W[-2] >> 10 {BBAA} */
|
||||
XORL e, R15 \ // y2 = f^g
|
||||
LONG $0xd273e1c5; BYTE $0x13 \ // VPSRLQ XMM3,XMM2,0x13 /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */
|
||||
XORL c, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
|
||||
ANDL c, R15 \ // y2 = (f^g)&e
|
||||
LONG $0xd273e9c5; BYTE $0x11 \ // VPSRLQ XMM2,XMM2,0x11 /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
XORL g, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
XORL e, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
LONG $0xd3efe9c5 \ // VPXOR XMM2,XMM2,XMM3 /* */
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
ADDL _xfer+56(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
LONG $0xc2ef39c5 \ // VPXOR XMM8,XMM8,XMM2 /* XTMP4 = s1 {xBxA} */
|
||||
MOVL g, R13 \ // y0 = a
|
||||
ADDL R15, f \ // h = h + S1 + CH + k + w
|
||||
MOVL g, R15 \ // y2 = a
|
||||
LONG $0x003942c4; BYTE $0xc2 \ // VPSHUFB XMM8,XMM8,XMM10 /* XTMP4 = s1 {00BA} */
|
||||
ORL a, R13 \ // y0 = a|c
|
||||
ADDL f, b \ // d = d + h + S1 + CH + k + w
|
||||
ANDL a, R15 \ // y2 = a&c
|
||||
LONG $0xfe79c1c4; BYTE $0xc0 \ // VPADDD XMM0,XMM0,XMM8 /* XTMP0 = {..., ..., W[1], W[0]} */
|
||||
ANDL h, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, f \ // h = h + S1 + CH + k + w + S0
|
||||
\
|
||||
\ // compute high s1
|
||||
\
|
||||
LONG $0xd070f9c5; BYTE $0x50 \ // VPSHUFD XMM2,XMM0,0x50 /* XTMP2 = W[-2] {DDCC} */
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, f \ // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
\ // ROTATE_ARGS
|
||||
MOVL b, R13 \ // y0 = e
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
MOVL f, R14 \ // y1 = a
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
XORL b, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
MOVL c, R15 \ // y2 = f
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
LONG $0xd272a1c5; BYTE $0x0a \ // VPSRLD XMM11,XMM2,0xa /* XTMP5 = W[-2] >> 10 {DDCC} */
|
||||
XORL f, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
XORL d, R15 \ // y2 = f^g
|
||||
LONG $0xd273e1c5; BYTE $0x13 \ // VPSRLQ XMM3,XMM2,0x13 /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */
|
||||
XORL b, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
|
||||
ANDL b, R15 \ // y2 = (f^g)&e
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
LONG $0xd273e9c5; BYTE $0x11 \ // VPSRLQ XMM2,XMM2,0x11 /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */
|
||||
XORL f, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
XORL d, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
LONG $0xd3efe9c5 \ // VPXOR XMM2,XMM2,XMM3 /* */
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ADDL _xfer+60(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
LONG $0xdaef21c5 \ // VPXOR XMM11,XMM11,XMM2 /* XTMP5 = s1 {xDxC} */
|
||||
MOVL f, R13 \ // y0 = a
|
||||
ADDL R15, e \ // h = h + S1 + CH + k + w
|
||||
MOVL f, R15 \ // y2 = a
|
||||
LONG $0x002142c4; BYTE $0xdc \ // VPSHUFB XMM11,XMM11,XMM12 /* XTMP5 = s1 {DC00} */
|
||||
ORL h, R13 \ // y0 = a|c
|
||||
ADDL e, a \ // d = d + h + S1 + CH + k + w
|
||||
ANDL h, R15 \ // y2 = a&c
|
||||
LONG $0xe0fea1c5 \ // VPADDD XMM4,XMM11,XMM0 /* X0 = {W[3], W[2], W[1], W[0]} */
|
||||
ANDL g, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, e \ // h = h + S1 + CH + k + w + S0
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, e \ // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
\ // ROTATE_ARGS
|
||||
ROTATE_XS
|
||||
|
||||
#define DO_ROUND(a, b, c, d, e, f, g, h, offset) \
|
||||
MOVL e, R13 \ // y0 = e
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
MOVL a, R14 \ // y1 = a
|
||||
XORL e, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
MOVL f, R15 \ // y2 = f
|
||||
XORL a, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
XORL g, R15 \ // y2 = f^g
|
||||
XORL e, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
ANDL e, R15 \ // y2 = (f^g)&e
|
||||
XORL a, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
XORL g, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
ADDL _xfer+offset(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
MOVL a, R13 \ // y0 = a
|
||||
ADDL R15, h \ // h = h + S1 + CH + k + w
|
||||
MOVL a, R15 \ // y2 = a
|
||||
ORL c, R13 \ // y0 = a|c
|
||||
ADDL h, d \ // d = d + h + S1 + CH + k + w
|
||||
ANDL c, R15 \ // y2 = a&c
|
||||
ANDL b, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, h \ // h = h + S1 + CH + k + w + S0
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, h // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
|
||||
// func blockAvx(h []uint32, message []uint8, reserved0, reserved1, reserved2, reserved3 uint64)
|
||||
TEXT ·blockAvx(SB), 7, $0-80
|
||||
|
||||
MOVQ h+0(FP), SI // SI: &h
|
||||
MOVQ message_base+24(FP), R8 // &message
|
||||
MOVQ message_len+32(FP), R9 // length of message
|
||||
CMPQ R9, $0
|
||||
JEQ done_hash
|
||||
ADDQ R8, R9
|
||||
MOVQ R9, reserved2+64(FP) // store end of message
|
||||
|
||||
// Register definition
|
||||
// a --> eax
|
||||
// b --> ebx
|
||||
// c --> ecx
|
||||
// d --> r8d
|
||||
// e --> edx
|
||||
// f --> r9d
|
||||
// g --> r10d
|
||||
// h --> r11d
|
||||
//
|
||||
// y0 --> r13d
|
||||
// y1 --> r14d
|
||||
// y2 --> r15d
|
||||
|
||||
MOVL (0*4)(SI), AX // a = H0
|
||||
MOVL (1*4)(SI), BX // b = H1
|
||||
MOVL (2*4)(SI), CX // c = H2
|
||||
MOVL (3*4)(SI), R8 // d = H3
|
||||
MOVL (4*4)(SI), DX // e = H4
|
||||
MOVL (5*4)(SI), R9 // f = H5
|
||||
MOVL (6*4)(SI), R10 // g = H6
|
||||
MOVL (7*4)(SI), R11 // h = H7
|
||||
|
||||
MOVOU bflipMask<>(SB), X13
|
||||
MOVOU shuf00BA<>(SB), X10 // shuffle xBxA -> 00BA
|
||||
MOVOU shufDC00<>(SB), X12 // shuffle xDxC -> DC00
|
||||
|
||||
MOVQ message_base+24(FP), SI // SI: &message
|
||||
|
||||
loop0:
|
||||
LEAQ constants<>(SB), BP
|
||||
|
||||
// byte swap first 16 dwords
|
||||
MOVOU 0*16(SI), X4
|
||||
LONG $0x0059c2c4; BYTE $0xe5 // VPSHUFB XMM4, XMM4, XMM13
|
||||
MOVOU 1*16(SI), X5
|
||||
LONG $0x0051c2c4; BYTE $0xed // VPSHUFB XMM5, XMM5, XMM13
|
||||
MOVOU 2*16(SI), X6
|
||||
LONG $0x0049c2c4; BYTE $0xf5 // VPSHUFB XMM6, XMM6, XMM13
|
||||
MOVOU 3*16(SI), X7
|
||||
LONG $0x0041c2c4; BYTE $0xfd // VPSHUFB XMM7, XMM7, XMM13
|
||||
|
||||
MOVQ SI, reserved3+72(FP)
|
||||
MOVD $0x3, DI
|
||||
|
||||
// schedule 48 input dwords, by doing 3 rounds of 16 each
|
||||
loop1:
|
||||
LONG $0x4dfe59c5; BYTE $0x00 // VPADDD XMM9, XMM4, 0[RBP] /* Add 1st constant to first part of message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
FOUR_ROUNDS_AND_SCHED(AX, BX, CX, R8, DX, R9, R10, R11)
|
||||
|
||||
LONG $0x4dfe59c5; BYTE $0x10 // VPADDD XMM9, XMM4, 16[RBP] /* Add 2nd constant to message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
FOUR_ROUNDS_AND_SCHED(DX, R9, R10, R11, AX, BX, CX, R8)
|
||||
|
||||
LONG $0x4dfe59c5; BYTE $0x20 // VPADDD XMM9, XMM4, 32[RBP] /* Add 3rd constant to message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
FOUR_ROUNDS_AND_SCHED(AX, BX, CX, R8, DX, R9, R10, R11)
|
||||
|
||||
LONG $0x4dfe59c5; BYTE $0x30 // VPADDD XMM9, XMM4, 48[RBP] /* Add 4th constant to message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
ADDQ $64, BP
|
||||
FOUR_ROUNDS_AND_SCHED(DX, R9, R10, R11, AX, BX, CX, R8)
|
||||
|
||||
SUBQ $1, DI
|
||||
JNE loop1
|
||||
|
||||
MOVD $0x2, DI
|
||||
|
||||
loop2:
|
||||
LONG $0x4dfe59c5; BYTE $0x00 // VPADDD XMM9, XMM4, 0[RBP] /* Add 1st constant to first part of message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
DO_ROUND( AX, BX, CX, R8, DX, R9, R10, R11, 48)
|
||||
DO_ROUND(R11, AX, BX, CX, R8, DX, R9, R10, 52)
|
||||
DO_ROUND(R10, R11, AX, BX, CX, R8, DX, R9, 56)
|
||||
DO_ROUND( R9, R10, R11, AX, BX, CX, R8, DX, 60)
|
||||
|
||||
LONG $0x4dfe51c5; BYTE $0x10 // VPADDD XMM9, XMM5, 16[RBP] /* Add 2nd constant to message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
ADDQ $32, BP
|
||||
DO_ROUND( DX, R9, R10, R11, AX, BX, CX, R8, 48)
|
||||
DO_ROUND( R8, DX, R9, R10, R11, AX, BX, CX, 52)
|
||||
DO_ROUND( CX, R8, DX, R9, R10, R11, AX, BX, 56)
|
||||
DO_ROUND( BX, CX, R8, DX, R9, R10, R11, AX, 60)
|
||||
|
||||
MOVOU X6, X4
|
||||
MOVOU X7, X5
|
||||
|
||||
SUBQ $1, DI
|
||||
JNE loop2
|
||||
|
||||
MOVQ h+0(FP), SI // SI: &h
|
||||
ADDL (0*4)(SI), AX // H0 = a + H0
|
||||
MOVL AX, (0*4)(SI)
|
||||
ADDL (1*4)(SI), BX // H1 = b + H1
|
||||
MOVL BX, (1*4)(SI)
|
||||
ADDL (2*4)(SI), CX // H2 = c + H2
|
||||
MOVL CX, (2*4)(SI)
|
||||
ADDL (3*4)(SI), R8 // H3 = d + H3
|
||||
MOVL R8, (3*4)(SI)
|
||||
ADDL (4*4)(SI), DX // H4 = e + H4
|
||||
MOVL DX, (4*4)(SI)
|
||||
ADDL (5*4)(SI), R9 // H5 = f + H5
|
||||
MOVL R9, (5*4)(SI)
|
||||
ADDL (6*4)(SI), R10 // H6 = g + H6
|
||||
MOVL R10, (6*4)(SI)
|
||||
ADDL (7*4)(SI), R11 // H7 = h + H7
|
||||
MOVL R11, (7*4)(SI)
|
||||
|
||||
MOVQ reserved3+72(FP), SI
|
||||
ADDQ $64, SI
|
||||
CMPQ reserved2+64(FP), SI
|
||||
JNE loop0
|
||||
|
||||
done_hash:
|
||||
RET
|
||||
|
||||
// Constants table
|
||||
DATA constants<>+0x0(SB)/8, $0x71374491428a2f98
|
||||
DATA constants<>+0x8(SB)/8, $0xe9b5dba5b5c0fbcf
|
||||
DATA constants<>+0x10(SB)/8, $0x59f111f13956c25b
|
||||
DATA constants<>+0x18(SB)/8, $0xab1c5ed5923f82a4
|
||||
DATA constants<>+0x20(SB)/8, $0x12835b01d807aa98
|
||||
DATA constants<>+0x28(SB)/8, $0x550c7dc3243185be
|
||||
DATA constants<>+0x30(SB)/8, $0x80deb1fe72be5d74
|
||||
DATA constants<>+0x38(SB)/8, $0xc19bf1749bdc06a7
|
||||
DATA constants<>+0x40(SB)/8, $0xefbe4786e49b69c1
|
||||
DATA constants<>+0x48(SB)/8, $0x240ca1cc0fc19dc6
|
||||
DATA constants<>+0x50(SB)/8, $0x4a7484aa2de92c6f
|
||||
DATA constants<>+0x58(SB)/8, $0x76f988da5cb0a9dc
|
||||
DATA constants<>+0x60(SB)/8, $0xa831c66d983e5152
|
||||
DATA constants<>+0x68(SB)/8, $0xbf597fc7b00327c8
|
||||
DATA constants<>+0x70(SB)/8, $0xd5a79147c6e00bf3
|
||||
DATA constants<>+0x78(SB)/8, $0x1429296706ca6351
|
||||
DATA constants<>+0x80(SB)/8, $0x2e1b213827b70a85
|
||||
DATA constants<>+0x88(SB)/8, $0x53380d134d2c6dfc
|
||||
DATA constants<>+0x90(SB)/8, $0x766a0abb650a7354
|
||||
DATA constants<>+0x98(SB)/8, $0x92722c8581c2c92e
|
||||
DATA constants<>+0xa0(SB)/8, $0xa81a664ba2bfe8a1
|
||||
DATA constants<>+0xa8(SB)/8, $0xc76c51a3c24b8b70
|
||||
DATA constants<>+0xb0(SB)/8, $0xd6990624d192e819
|
||||
DATA constants<>+0xb8(SB)/8, $0x106aa070f40e3585
|
||||
DATA constants<>+0xc0(SB)/8, $0x1e376c0819a4c116
|
||||
DATA constants<>+0xc8(SB)/8, $0x34b0bcb52748774c
|
||||
DATA constants<>+0xd0(SB)/8, $0x4ed8aa4a391c0cb3
|
||||
DATA constants<>+0xd8(SB)/8, $0x682e6ff35b9cca4f
|
||||
DATA constants<>+0xe0(SB)/8, $0x78a5636f748f82ee
|
||||
DATA constants<>+0xe8(SB)/8, $0x8cc7020884c87814
|
||||
DATA constants<>+0xf0(SB)/8, $0xa4506ceb90befffa
|
||||
DATA constants<>+0xf8(SB)/8, $0xc67178f2bef9a3f7
|
||||
|
||||
DATA bflipMask<>+0x00(SB)/8, $0x0405060700010203
|
||||
DATA bflipMask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b
|
||||
|
||||
DATA shuf00BA<>+0x00(SB)/8, $0x0b0a090803020100
|
||||
DATA shuf00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
|
||||
DATA shufDC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
DATA shufDC00<>+0x08(SB)/8, $0x0b0a090803020100
|
||||
|
||||
GLOBL constants<>(SB), 8, $256
|
||||
GLOBL bflipMask<>(SB), (NOPTR+RODATA), $16
|
||||
GLOBL shuf00BA<>(SB), (NOPTR+RODATA), $16
|
||||
GLOBL shufDC00<>(SB), (NOPTR+RODATA), $16
|
6
vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.go
generated
vendored
Normal file
6
vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
//+build !noasm
|
||||
|
||||
package sha256
|
||||
|
||||
//go:noescape
|
||||
func blockSha(h *[8]uint32, message []uint8)
|
266
vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.s
generated
vendored
Normal file
266
vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
//+build !noasm,!appengine
|
||||
|
||||
// SHA intrinsic version of SHA256
|
||||
|
||||
// Kristofer Peterson, (C) 2018.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
DATA K<>+0x00(SB)/4, $0x428a2f98
|
||||
DATA K<>+0x04(SB)/4, $0x71374491
|
||||
DATA K<>+0x08(SB)/4, $0xb5c0fbcf
|
||||
DATA K<>+0x0c(SB)/4, $0xe9b5dba5
|
||||
DATA K<>+0x10(SB)/4, $0x3956c25b
|
||||
DATA K<>+0x14(SB)/4, $0x59f111f1
|
||||
DATA K<>+0x18(SB)/4, $0x923f82a4
|
||||
DATA K<>+0x1c(SB)/4, $0xab1c5ed5
|
||||
DATA K<>+0x20(SB)/4, $0xd807aa98
|
||||
DATA K<>+0x24(SB)/4, $0x12835b01
|
||||
DATA K<>+0x28(SB)/4, $0x243185be
|
||||
DATA K<>+0x2c(SB)/4, $0x550c7dc3
|
||||
DATA K<>+0x30(SB)/4, $0x72be5d74
|
||||
DATA K<>+0x34(SB)/4, $0x80deb1fe
|
||||
DATA K<>+0x38(SB)/4, $0x9bdc06a7
|
||||
DATA K<>+0x3c(SB)/4, $0xc19bf174
|
||||
DATA K<>+0x40(SB)/4, $0xe49b69c1
|
||||
DATA K<>+0x44(SB)/4, $0xefbe4786
|
||||
DATA K<>+0x48(SB)/4, $0x0fc19dc6
|
||||
DATA K<>+0x4c(SB)/4, $0x240ca1cc
|
||||
DATA K<>+0x50(SB)/4, $0x2de92c6f
|
||||
DATA K<>+0x54(SB)/4, $0x4a7484aa
|
||||
DATA K<>+0x58(SB)/4, $0x5cb0a9dc
|
||||
DATA K<>+0x5c(SB)/4, $0x76f988da
|
||||
DATA K<>+0x60(SB)/4, $0x983e5152
|
||||
DATA K<>+0x64(SB)/4, $0xa831c66d
|
||||
DATA K<>+0x68(SB)/4, $0xb00327c8
|
||||
DATA K<>+0x6c(SB)/4, $0xbf597fc7
|
||||
DATA K<>+0x70(SB)/4, $0xc6e00bf3
|
||||
DATA K<>+0x74(SB)/4, $0xd5a79147
|
||||
DATA K<>+0x78(SB)/4, $0x06ca6351
|
||||
DATA K<>+0x7c(SB)/4, $0x14292967
|
||||
DATA K<>+0x80(SB)/4, $0x27b70a85
|
||||
DATA K<>+0x84(SB)/4, $0x2e1b2138
|
||||
DATA K<>+0x88(SB)/4, $0x4d2c6dfc
|
||||
DATA K<>+0x8c(SB)/4, $0x53380d13
|
||||
DATA K<>+0x90(SB)/4, $0x650a7354
|
||||
DATA K<>+0x94(SB)/4, $0x766a0abb
|
||||
DATA K<>+0x98(SB)/4, $0x81c2c92e
|
||||
DATA K<>+0x9c(SB)/4, $0x92722c85
|
||||
DATA K<>+0xa0(SB)/4, $0xa2bfe8a1
|
||||
DATA K<>+0xa4(SB)/4, $0xa81a664b
|
||||
DATA K<>+0xa8(SB)/4, $0xc24b8b70
|
||||
DATA K<>+0xac(SB)/4, $0xc76c51a3
|
||||
DATA K<>+0xb0(SB)/4, $0xd192e819
|
||||
DATA K<>+0xb4(SB)/4, $0xd6990624
|
||||
DATA K<>+0xb8(SB)/4, $0xf40e3585
|
||||
DATA K<>+0xbc(SB)/4, $0x106aa070
|
||||
DATA K<>+0xc0(SB)/4, $0x19a4c116
|
||||
DATA K<>+0xc4(SB)/4, $0x1e376c08
|
||||
DATA K<>+0xc8(SB)/4, $0x2748774c
|
||||
DATA K<>+0xcc(SB)/4, $0x34b0bcb5
|
||||
DATA K<>+0xd0(SB)/4, $0x391c0cb3
|
||||
DATA K<>+0xd4(SB)/4, $0x4ed8aa4a
|
||||
DATA K<>+0xd8(SB)/4, $0x5b9cca4f
|
||||
DATA K<>+0xdc(SB)/4, $0x682e6ff3
|
||||
DATA K<>+0xe0(SB)/4, $0x748f82ee
|
||||
DATA K<>+0xe4(SB)/4, $0x78a5636f
|
||||
DATA K<>+0xe8(SB)/4, $0x84c87814
|
||||
DATA K<>+0xec(SB)/4, $0x8cc70208
|
||||
DATA K<>+0xf0(SB)/4, $0x90befffa
|
||||
DATA K<>+0xf4(SB)/4, $0xa4506ceb
|
||||
DATA K<>+0xf8(SB)/4, $0xbef9a3f7
|
||||
DATA K<>+0xfc(SB)/4, $0xc67178f2
|
||||
GLOBL K<>(SB), RODATA|NOPTR, $256
|
||||
|
||||
DATA SHUF_MASK<>+0x00(SB)/8, $0x0405060700010203
|
||||
DATA SHUF_MASK<>+0x08(SB)/8, $0x0c0d0e0f08090a0b
|
||||
GLOBL SHUF_MASK<>(SB), RODATA|NOPTR, $16
|
||||
|
||||
// Register Usage
|
||||
// BX base address of constant table (constant)
|
||||
// DX hash_state (constant)
|
||||
// SI hash_data.data
|
||||
// DI hash_data.data + hash_data.length - 64 (constant)
|
||||
// X0 scratch
|
||||
// X1 scratch
|
||||
// X2 working hash state // ABEF
|
||||
// X3 working hash state // CDGH
|
||||
// X4 first 16 bytes of block
|
||||
// X5 second 16 bytes of block
|
||||
// X6 third 16 bytes of block
|
||||
// X7 fourth 16 bytes of block
|
||||
// X12 saved hash state // ABEF
|
||||
// X13 saved hash state // CDGH
|
||||
// X15 data shuffle mask (constant)
|
||||
|
||||
TEXT ·blockSha(SB), NOSPLIT, $0-32
|
||||
MOVQ h+0(FP), DX
|
||||
MOVQ message_base+8(FP), SI
|
||||
MOVQ message_len+16(FP), DI
|
||||
LEAQ -64(SI)(DI*1), DI
|
||||
MOVOU (DX), X2
|
||||
MOVOU 16(DX), X1
|
||||
MOVO X2, X3
|
||||
PUNPCKLLQ X1, X2
|
||||
PUNPCKHLQ X1, X3
|
||||
PSHUFD $0x27, X2, X2
|
||||
PSHUFD $0x27, X3, X3
|
||||
MOVO SHUF_MASK<>(SB), X15
|
||||
LEAQ K<>(SB), BX
|
||||
|
||||
JMP TEST
|
||||
|
||||
LOOP:
|
||||
MOVO X2, X12
|
||||
MOVO X3, X13
|
||||
|
||||
// load block and shuffle
|
||||
MOVOU (SI), X4
|
||||
MOVOU 16(SI), X5
|
||||
MOVOU 32(SI), X6
|
||||
MOVOU 48(SI), X7
|
||||
PSHUFB X15, X4
|
||||
PSHUFB X15, X5
|
||||
PSHUFB X15, X6
|
||||
PSHUFB X15, X7
|
||||
|
||||
#define ROUND456 \
|
||||
PADDL X5, X0 \
|
||||
LONG $0xdacb380f \ // SHA256RNDS2 XMM3, XMM2
|
||||
MOVO X5, X1 \
|
||||
LONG $0x0f3a0f66; WORD $0x04cc \ // PALIGNR XMM1, XMM4, 4
|
||||
PADDL X1, X6 \
|
||||
LONG $0xf5cd380f \ // SHA256MSG2 XMM6, XMM5
|
||||
PSHUFD $0x4e, X0, X0 \
|
||||
LONG $0xd3cb380f \ // SHA256RNDS2 XMM2, XMM3
|
||||
LONG $0xe5cc380f // SHA256MSG1 XMM4, XMM5
|
||||
|
||||
#define ROUND567 \
|
||||
PADDL X6, X0 \
|
||||
LONG $0xdacb380f \ // SHA256RNDS2 XMM3, XMM2
|
||||
MOVO X6, X1 \
|
||||
LONG $0x0f3a0f66; WORD $0x04cd \ // PALIGNR XMM1, XMM5, 4
|
||||
PADDL X1, X7 \
|
||||
LONG $0xfecd380f \ // SHA256MSG2 XMM7, XMM6
|
||||
PSHUFD $0x4e, X0, X0 \
|
||||
LONG $0xd3cb380f \ // SHA256RNDS2 XMM2, XMM3
|
||||
LONG $0xeecc380f // SHA256MSG1 XMM5, XMM6
|
||||
|
||||
#define ROUND674 \
|
||||
PADDL X7, X0 \
|
||||
LONG $0xdacb380f \ // SHA256RNDS2 XMM3, XMM2
|
||||
MOVO X7, X1 \
|
||||
LONG $0x0f3a0f66; WORD $0x04ce \ // PALIGNR XMM1, XMM6, 4
|
||||
PADDL X1, X4 \
|
||||
LONG $0xe7cd380f \ // SHA256MSG2 XMM4, XMM7
|
||||
PSHUFD $0x4e, X0, X0 \
|
||||
LONG $0xd3cb380f \ // SHA256RNDS2 XMM2, XMM3
|
||||
LONG $0xf7cc380f // SHA256MSG1 XMM6, XMM7
|
||||
|
||||
#define ROUND745 \
|
||||
PADDL X4, X0 \
|
||||
LONG $0xdacb380f \ // SHA256RNDS2 XMM3, XMM2
|
||||
MOVO X4, X1 \
|
||||
LONG $0x0f3a0f66; WORD $0x04cf \ // PALIGNR XMM1, XMM7, 4
|
||||
PADDL X1, X5 \
|
||||
LONG $0xeccd380f \ // SHA256MSG2 XMM5, XMM4
|
||||
PSHUFD $0x4e, X0, X0 \
|
||||
LONG $0xd3cb380f \ // SHA256RNDS2 XMM2, XMM3
|
||||
LONG $0xfccc380f // SHA256MSG1 XMM7, XMM4
|
||||
|
||||
// rounds 0-3
|
||||
MOVO (BX), X0
|
||||
PADDL X4, X0
|
||||
LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2
|
||||
PSHUFD $0x4e, X0, X0
|
||||
LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3
|
||||
|
||||
// rounds 4-7
|
||||
MOVO 1*16(BX), X0
|
||||
PADDL X5, X0
|
||||
LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2
|
||||
PSHUFD $0x4e, X0, X0
|
||||
LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3
|
||||
LONG $0xe5cc380f // SHA256MSG1 XMM4, XMM5
|
||||
|
||||
// rounds 8-11
|
||||
MOVO 2*16(BX), X0
|
||||
PADDL X6, X0
|
||||
LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2
|
||||
PSHUFD $0x4e, X0, X0
|
||||
LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3
|
||||
LONG $0xeecc380f // SHA256MSG1 XMM5, XMM6
|
||||
|
||||
MOVO 3*16(BX), X0; ROUND674 // rounds 12-15
|
||||
MOVO 4*16(BX), X0; ROUND745 // rounds 16-19
|
||||
MOVO 5*16(BX), X0; ROUND456 // rounds 20-23
|
||||
MOVO 6*16(BX), X0; ROUND567 // rounds 24-27
|
||||
MOVO 7*16(BX), X0; ROUND674 // rounds 28-31
|
||||
MOVO 8*16(BX), X0; ROUND745 // rounds 32-35
|
||||
MOVO 9*16(BX), X0; ROUND456 // rounds 36-39
|
||||
MOVO 10*16(BX), X0; ROUND567 // rounds 40-43
|
||||
MOVO 11*16(BX), X0; ROUND674 // rounds 44-47
|
||||
MOVO 12*16(BX), X0; ROUND745 // rounds 48-51
|
||||
|
||||
// rounds 52-55
|
||||
MOVO 13*16(BX), X0
|
||||
PADDL X5, X0
|
||||
LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2
|
||||
MOVO X5, X1
|
||||
LONG $0x0f3a0f66; WORD $0x04cc // PALIGNR XMM1, XMM4, 4
|
||||
PADDL X1, X6
|
||||
LONG $0xf5cd380f // SHA256MSG2 XMM6, XMM5
|
||||
PSHUFD $0x4e, X0, X0
|
||||
LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3
|
||||
|
||||
// rounds 56-59
|
||||
MOVO 14*16(BX), X0
|
||||
PADDL X6, X0
|
||||
LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2
|
||||
MOVO X6, X1
|
||||
LONG $0x0f3a0f66; WORD $0x04cd // PALIGNR XMM1, XMM5, 4
|
||||
PADDL X1, X7
|
||||
LONG $0xfecd380f // SHA256MSG2 XMM7, XMM6
|
||||
PSHUFD $0x4e, X0, X0
|
||||
LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3
|
||||
|
||||
// rounds 60-63
|
||||
MOVO 15*16(BX), X0
|
||||
PADDL X7, X0
|
||||
LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2
|
||||
PSHUFD $0x4e, X0, X0
|
||||
LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3
|
||||
|
||||
PADDL X12, X2
|
||||
PADDL X13, X3
|
||||
|
||||
ADDQ $64, SI
|
||||
|
||||
TEST:
|
||||
CMPQ SI, DI
|
||||
JBE LOOP
|
||||
|
||||
PSHUFD $0x4e, X3, X0
|
||||
LONG $0x0e3a0f66; WORD $0xf0c2 // PBLENDW XMM0, XMM2, 0xf0
|
||||
PSHUFD $0x4e, X2, X1
|
||||
LONG $0x0e3a0f66; WORD $0x0fcb // PBLENDW XMM1, XMM3, 0x0f
|
||||
PSHUFD $0x1b, X0, X0
|
||||
PSHUFD $0x1b, X1, X1
|
||||
|
||||
MOVOU X0, (DX)
|
||||
MOVOU X1, 16(DX)
|
||||
|
||||
RET
|
22
vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.go
generated
vendored
Normal file
22
vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
//+build !noasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
//go:noescape
|
||||
func blockSsse(h []uint32, message []uint8, reserved0, reserved1, reserved2, reserved3 uint64)
|
429
vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.s
generated
vendored
Normal file
429
vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,429 @@
|
|||
//+build !noasm,!appengine
|
||||
|
||||
// SHA256 implementation for SSSE3
|
||||
|
||||
//
|
||||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
//
|
||||
// This code is based on an Intel White-Paper:
|
||||
// "Fast SHA-256 Implementations on Intel Architecture Processors"
|
||||
//
|
||||
// together with the reference implementation from the following authors:
|
||||
// James Guilford <james.guilford@intel.com>
|
||||
// Kirk Yap <kirk.s.yap@intel.com>
|
||||
// Tim Chen <tim.c.chen@linux.intel.com>
|
||||
//
|
||||
// For Golang it has been converted to Plan 9 assembly with the help of
|
||||
// github.com/minio/asm2plan9s to assemble Intel instructions to their Plan9
|
||||
// equivalents
|
||||
//
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define ROTATE_XS \
|
||||
MOVOU X4, X15 \
|
||||
MOVOU X5, X4 \
|
||||
MOVOU X6, X5 \
|
||||
MOVOU X7, X6 \
|
||||
MOVOU X15, X7
|
||||
|
||||
// compute s0 four at a time and s1 two at a time
|
||||
// compute W[-16] + W[-7] 4 at a time
|
||||
#define FOUR_ROUNDS_AND_SCHED(a, b, c, d, e, f, g, h) \
|
||||
MOVL e, R13 \ // y0 = e
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
MOVL a, R14 \ // y1 = a
|
||||
MOVOU X7, X0 \
|
||||
LONG $0x0f3a0f66; WORD $0x04c6 \ // PALIGNR XMM0,XMM6,0x4 /* XTMP0 = W[-7] */
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
XORL e, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
MOVL f, R15 \ // y2 = f
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
XORL a, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
XORL g, R15 \ // y2 = f^g
|
||||
LONG $0xc4fe0f66 \ // PADDD XMM0,XMM4 /* XTMP0 = W[-7] + W[-16] */
|
||||
XORL e, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6) )
|
||||
ANDL e, R15 \ // y2 = (f^g)&e
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
\
|
||||
\ // compute s0
|
||||
\
|
||||
MOVOU X5, X1 \
|
||||
LONG $0x0f3a0f66; WORD $0x04cc \ // PALIGNR XMM1,XMM4,0x4 /* XTMP1 = W[-15] */
|
||||
XORL a, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
XORL g, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ADDL _xfer+48(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
MOVL a, R13 \ // y0 = a
|
||||
ADDL R15, h \ // h = h + S1 + CH + k + w
|
||||
\ // ROTATE_ARGS
|
||||
MOVL a, R15 \ // y2 = a
|
||||
MOVOU X1, X2 \
|
||||
LONG $0xd2720f66; BYTE $0x07 \ // PSRLD XMM2,0x7 /* */
|
||||
ORL c, R13 \ // y0 = a|c
|
||||
ADDL h, d \ // d = d + h + S1 + CH + k + w
|
||||
ANDL c, R15 \ // y2 = a&c
|
||||
MOVOU X1, X3 \
|
||||
LONG $0xf3720f66; BYTE $0x19 \ // PSLLD XMM3,0x19 /* */
|
||||
ANDL b, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, h \ // h = h + S1 + CH + k + w + S0
|
||||
LONG $0xdaeb0f66 \ // POR XMM3,XMM2 /* XTMP1 = W[-15] MY_ROR 7 */
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, h \ // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
\ // ROTATE_ARGS
|
||||
MOVL d, R13 \ // y0 = e
|
||||
MOVL h, R14 \ // y1 = a
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
XORL d, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
MOVL e, R15 \ // y2 = f
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
MOVOU X1, X2 \
|
||||
LONG $0xd2720f66; BYTE $0x12 \ // PSRLD XMM2,0x12 /* */
|
||||
XORL h, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
XORL f, R15 \ // y2 = f^g
|
||||
MOVOU X1, X8 \
|
||||
LONG $0x720f4166; WORD $0x03d0 \ // PSRLD XMM8,0x3 /* XTMP4 = W[-15] >> 3 */
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
XORL d, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
|
||||
ANDL d, R15 \ // y2 = (f^g)&e
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
LONG $0xf1720f66; BYTE $0x0e \ // PSLLD XMM1,0xe /* */
|
||||
XORL h, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
XORL f, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
LONG $0xd9ef0f66 \ // PXOR XMM3,XMM1 /* */
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ADDL _xfer+52(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
LONG $0xdaef0f66 \ // PXOR XMM3,XMM2 /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR */
|
||||
MOVL h, R13 \ // y0 = a
|
||||
ADDL R15, g \ // h = h + S1 + CH + k + w
|
||||
MOVL h, R15 \ // y2 = a
|
||||
MOVOU X3, X1 \
|
||||
LONG $0xef0f4166; BYTE $0xc8 \ // PXOR XMM1,XMM8 /* XTMP1 = s0 */
|
||||
ORL b, R13 \ // y0 = a|c
|
||||
ADDL g, c \ // d = d + h + S1 + CH + k + w
|
||||
ANDL b, R15 \ // y2 = a&c
|
||||
\
|
||||
\ // compute low s1
|
||||
\
|
||||
LONG $0xd7700f66; BYTE $0xfa \ // PSHUFD XMM2,XMM7,0xfa /* XTMP2 = W[-2] {BBAA} */
|
||||
ANDL a, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, g \ // h = h + S1 + CH + k + w + S0
|
||||
LONG $0xc1fe0f66 \ // PADDD XMM0,XMM1 /* XTMP0 = W[-16] + W[-7] + s0 */
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, g \ // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
\ // ROTATE_ARGS
|
||||
MOVL c, R13 \ // y0 = e
|
||||
MOVL g, R14 \ // y1 = a
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
XORL c, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
MOVL d, R15 \ // y2 = f
|
||||
XORL g, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
MOVOU X2, X8 \
|
||||
LONG $0x720f4166; WORD $0x0ad0 \ // PSRLD XMM8,0xa /* XTMP4 = W[-2] >> 10 {BBAA} */
|
||||
XORL e, R15 \ // y2 = f^g
|
||||
MOVOU X2, X3 \
|
||||
LONG $0xd3730f66; BYTE $0x13 \ // PSRLQ XMM3,0x13 /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */
|
||||
XORL c, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
|
||||
ANDL c, R15 \ // y2 = (f^g)&e
|
||||
LONG $0xd2730f66; BYTE $0x11 \ // PSRLQ XMM2,0x11 /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
XORL g, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
XORL e, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
LONG $0xd3ef0f66 \ // PXOR XMM2,XMM3 /* */
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
ADDL _xfer+56(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
LONG $0xef0f4466; BYTE $0xc2 \ // PXOR XMM8,XMM2 /* XTMP4 = s1 {xBxA} */
|
||||
MOVL g, R13 \ // y0 = a
|
||||
ADDL R15, f \ // h = h + S1 + CH + k + w
|
||||
MOVL g, R15 \ // y2 = a
|
||||
LONG $0x380f4566; WORD $0xc200 \ // PSHUFB XMM8,XMM10 /* XTMP4 = s1 {00BA} */
|
||||
ORL a, R13 \ // y0 = a|c
|
||||
ADDL f, b \ // d = d + h + S1 + CH + k + w
|
||||
ANDL a, R15 \ // y2 = a&c
|
||||
LONG $0xfe0f4166; BYTE $0xc0 \ // PADDD XMM0,XMM8 /* XTMP0 = {..., ..., W[1], W[0]} */
|
||||
ANDL h, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, f \ // h = h + S1 + CH + k + w + S0
|
||||
\
|
||||
\ // compute high s1
|
||||
\
|
||||
LONG $0xd0700f66; BYTE $0x50 \ // PSHUFD XMM2,XMM0,0x50 /* XTMP2 = W[-2] {DDCC} */
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, f \ // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
\ // ROTATE_ARGS
|
||||
MOVL b, R13 \ // y0 = e
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
MOVL f, R14 \ // y1 = a
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
XORL b, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
MOVL c, R15 \ // y2 = f
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
MOVOU X2, X11 \
|
||||
LONG $0x720f4166; WORD $0x0ad3 \ // PSRLD XMM11,0xa /* XTMP5 = W[-2] >> 10 {DDCC} */
|
||||
XORL f, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
XORL d, R15 \ // y2 = f^g
|
||||
MOVOU X2, X3 \
|
||||
LONG $0xd3730f66; BYTE $0x13 \ // PSRLQ XMM3,0x13 /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */
|
||||
XORL b, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
|
||||
ANDL b, R15 \ // y2 = (f^g)&e
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
LONG $0xd2730f66; BYTE $0x11 \ // PSRLQ XMM2,0x11 /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */
|
||||
XORL f, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
XORL d, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
LONG $0xd3ef0f66 \ // PXOR XMM2,XMM3 /* */
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ADDL _xfer+60(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
LONG $0xef0f4466; BYTE $0xda \ // PXOR XMM11,XMM2 /* XTMP5 = s1 {xDxC} */
|
||||
MOVL f, R13 \ // y0 = a
|
||||
ADDL R15, e \ // h = h + S1 + CH + k + w
|
||||
MOVL f, R15 \ // y2 = a
|
||||
LONG $0x380f4566; WORD $0xdc00 \ // PSHUFB XMM11,XMM12 /* XTMP5 = s1 {DC00} */
|
||||
ORL h, R13 \ // y0 = a|c
|
||||
ADDL e, a \ // d = d + h + S1 + CH + k + w
|
||||
ANDL h, R15 \ // y2 = a&c
|
||||
MOVOU X11, X4 \
|
||||
LONG $0xe0fe0f66 \ // PADDD XMM4,XMM0 /* X0 = {W[3], W[2], W[1], W[0]} */
|
||||
ANDL g, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, e \ // h = h + S1 + CH + k + w + S0
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, e \ // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
\ // ROTATE_ARGS
|
||||
ROTATE_XS
|
||||
|
||||
#define DO_ROUND(a, b, c, d, e, f, g, h, offset) \
|
||||
MOVL e, R13 \ // y0 = e
|
||||
ROLL $18, R13 \ // y0 = e >> (25-11)
|
||||
MOVL a, R14 \ // y1 = a
|
||||
XORL e, R13 \ // y0 = e ^ (e >> (25-11))
|
||||
ROLL $23, R14 \ // y1 = a >> (22-13)
|
||||
MOVL f, R15 \ // y2 = f
|
||||
XORL a, R14 \ // y1 = a ^ (a >> (22-13)
|
||||
ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6))
|
||||
XORL g, R15 \ // y2 = f^g
|
||||
XORL e, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
|
||||
ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2))
|
||||
ANDL e, R15 \ // y2 = (f^g)&e
|
||||
XORL a, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
|
||||
ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
|
||||
XORL g, R15 \ // y2 = CH = ((f^g)&e)^g
|
||||
ADDL R13, R15 \ // y2 = S1 + CH
|
||||
ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
|
||||
ADDL _xfer+offset(FP), R15 \ // y2 = k + w + S1 + CH
|
||||
MOVL a, R13 \ // y0 = a
|
||||
ADDL R15, h \ // h = h + S1 + CH + k + w
|
||||
MOVL a, R15 \ // y2 = a
|
||||
ORL c, R13 \ // y0 = a|c
|
||||
ADDL h, d \ // d = d + h + S1 + CH + k + w
|
||||
ANDL c, R15 \ // y2 = a&c
|
||||
ANDL b, R13 \ // y0 = (a|c)&b
|
||||
ADDL R14, h \ // h = h + S1 + CH + k + w + S0
|
||||
ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c)
|
||||
ADDL R13, h // h = h + S1 + CH + k + w + S0 + MAJ
|
||||
|
||||
// func blockSsse(h []uint32, message []uint8, reserved0, reserved1, reserved2, reserved3 uint64)
|
||||
TEXT ·blockSsse(SB), 7, $0-80
|
||||
|
||||
MOVQ h+0(FP), SI // SI: &h
|
||||
MOVQ message_base+24(FP), R8 // &message
|
||||
MOVQ message_len+32(FP), R9 // length of message
|
||||
CMPQ R9, $0
|
||||
JEQ done_hash
|
||||
ADDQ R8, R9
|
||||
MOVQ R9, reserved2+64(FP) // store end of message
|
||||
|
||||
// Register definition
|
||||
// a --> eax
|
||||
// b --> ebx
|
||||
// c --> ecx
|
||||
// d --> r8d
|
||||
// e --> edx
|
||||
// f --> r9d
|
||||
// g --> r10d
|
||||
// h --> r11d
|
||||
//
|
||||
// y0 --> r13d
|
||||
// y1 --> r14d
|
||||
// y2 --> r15d
|
||||
|
||||
MOVL (0*4)(SI), AX // a = H0
|
||||
MOVL (1*4)(SI), BX // b = H1
|
||||
MOVL (2*4)(SI), CX // c = H2
|
||||
MOVL (3*4)(SI), R8 // d = H3
|
||||
MOVL (4*4)(SI), DX // e = H4
|
||||
MOVL (5*4)(SI), R9 // f = H5
|
||||
MOVL (6*4)(SI), R10 // g = H6
|
||||
MOVL (7*4)(SI), R11 // h = H7
|
||||
|
||||
MOVOU bflipMask<>(SB), X13
|
||||
MOVOU shuf00BA<>(SB), X10 // shuffle xBxA -> 00BA
|
||||
MOVOU shufDC00<>(SB), X12 // shuffle xDxC -> DC00
|
||||
|
||||
MOVQ message_base+24(FP), SI // SI: &message
|
||||
|
||||
loop0:
|
||||
LEAQ constants<>(SB), BP
|
||||
|
||||
// byte swap first 16 dwords
|
||||
MOVOU 0*16(SI), X4
|
||||
LONG $0x380f4166; WORD $0xe500 // PSHUFB XMM4, XMM13
|
||||
MOVOU 1*16(SI), X5
|
||||
LONG $0x380f4166; WORD $0xed00 // PSHUFB XMM5, XMM13
|
||||
MOVOU 2*16(SI), X6
|
||||
LONG $0x380f4166; WORD $0xf500 // PSHUFB XMM6, XMM13
|
||||
MOVOU 3*16(SI), X7
|
||||
LONG $0x380f4166; WORD $0xfd00 // PSHUFB XMM7, XMM13
|
||||
|
||||
MOVQ SI, reserved3+72(FP)
|
||||
MOVD $0x3, DI
|
||||
|
||||
// Align
|
||||
// nop WORD PTR [rax+rax*1+0x0]
|
||||
|
||||
// schedule 48 input dwords, by doing 3 rounds of 16 each
|
||||
loop1:
|
||||
MOVOU X4, X9
|
||||
LONG $0xfe0f4466; WORD $0x004d // PADDD XMM9, 0[RBP] /* Add 1st constant to first part of message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
FOUR_ROUNDS_AND_SCHED(AX, BX, CX, R8, DX, R9, R10, R11)
|
||||
|
||||
MOVOU X4, X9
|
||||
LONG $0xfe0f4466; WORD $0x104d // PADDD XMM9, 16[RBP] /* Add 2nd constant to message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
FOUR_ROUNDS_AND_SCHED(DX, R9, R10, R11, AX, BX, CX, R8)
|
||||
|
||||
MOVOU X4, X9
|
||||
LONG $0xfe0f4466; WORD $0x204d // PADDD XMM9, 32[RBP] /* Add 3rd constant to message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
FOUR_ROUNDS_AND_SCHED(AX, BX, CX, R8, DX, R9, R10, R11)
|
||||
|
||||
MOVOU X4, X9
|
||||
LONG $0xfe0f4466; WORD $0x304d // PADDD XMM9, 48[RBP] /* Add 4th constant to message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
ADDQ $64, BP
|
||||
FOUR_ROUNDS_AND_SCHED(DX, R9, R10, R11, AX, BX, CX, R8)
|
||||
|
||||
SUBQ $1, DI
|
||||
JNE loop1
|
||||
|
||||
MOVD $0x2, DI
|
||||
|
||||
loop2:
|
||||
MOVOU X4, X9
|
||||
LONG $0xfe0f4466; WORD $0x004d // PADDD XMM9, 0[RBP] /* Add 1st constant to first part of message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
DO_ROUND( AX, BX, CX, R8, DX, R9, R10, R11, 48)
|
||||
DO_ROUND(R11, AX, BX, CX, R8, DX, R9, R10, 52)
|
||||
DO_ROUND(R10, R11, AX, BX, CX, R8, DX, R9, 56)
|
||||
DO_ROUND( R9, R10, R11, AX, BX, CX, R8, DX, 60)
|
||||
|
||||
MOVOU X5, X9
|
||||
LONG $0xfe0f4466; WORD $0x104d // PADDD XMM9, 16[RBP] /* Add 2nd constant to message */
|
||||
MOVOU X9, reserved0+48(FP)
|
||||
ADDQ $32, BP
|
||||
DO_ROUND( DX, R9, R10, R11, AX, BX, CX, R8, 48)
|
||||
DO_ROUND( R8, DX, R9, R10, R11, AX, BX, CX, 52)
|
||||
DO_ROUND( CX, R8, DX, R9, R10, R11, AX, BX, 56)
|
||||
DO_ROUND( BX, CX, R8, DX, R9, R10, R11, AX, 60)
|
||||
|
||||
MOVOU X6, X4
|
||||
MOVOU X7, X5
|
||||
|
||||
SUBQ $1, DI
|
||||
JNE loop2
|
||||
|
||||
MOVQ h+0(FP), SI // SI: &h
|
||||
ADDL (0*4)(SI), AX // H0 = a + H0
|
||||
MOVL AX, (0*4)(SI)
|
||||
ADDL (1*4)(SI), BX // H1 = b + H1
|
||||
MOVL BX, (1*4)(SI)
|
||||
ADDL (2*4)(SI), CX // H2 = c + H2
|
||||
MOVL CX, (2*4)(SI)
|
||||
ADDL (3*4)(SI), R8 // H3 = d + H3
|
||||
MOVL R8, (3*4)(SI)
|
||||
ADDL (4*4)(SI), DX // H4 = e + H4
|
||||
MOVL DX, (4*4)(SI)
|
||||
ADDL (5*4)(SI), R9 // H5 = f + H5
|
||||
MOVL R9, (5*4)(SI)
|
||||
ADDL (6*4)(SI), R10 // H6 = g + H6
|
||||
MOVL R10, (6*4)(SI)
|
||||
ADDL (7*4)(SI), R11 // H7 = h + H7
|
||||
MOVL R11, (7*4)(SI)
|
||||
|
||||
MOVQ reserved3+72(FP), SI
|
||||
ADDQ $64, SI
|
||||
CMPQ reserved2+64(FP), SI
|
||||
JNE loop0
|
||||
|
||||
done_hash:
|
||||
RET
|
||||
|
||||
// Constants table
|
||||
DATA constants<>+0x0(SB)/8, $0x71374491428a2f98
|
||||
DATA constants<>+0x8(SB)/8, $0xe9b5dba5b5c0fbcf
|
||||
DATA constants<>+0x10(SB)/8, $0x59f111f13956c25b
|
||||
DATA constants<>+0x18(SB)/8, $0xab1c5ed5923f82a4
|
||||
DATA constants<>+0x20(SB)/8, $0x12835b01d807aa98
|
||||
DATA constants<>+0x28(SB)/8, $0x550c7dc3243185be
|
||||
DATA constants<>+0x30(SB)/8, $0x80deb1fe72be5d74
|
||||
DATA constants<>+0x38(SB)/8, $0xc19bf1749bdc06a7
|
||||
DATA constants<>+0x40(SB)/8, $0xefbe4786e49b69c1
|
||||
DATA constants<>+0x48(SB)/8, $0x240ca1cc0fc19dc6
|
||||
DATA constants<>+0x50(SB)/8, $0x4a7484aa2de92c6f
|
||||
DATA constants<>+0x58(SB)/8, $0x76f988da5cb0a9dc
|
||||
DATA constants<>+0x60(SB)/8, $0xa831c66d983e5152
|
||||
DATA constants<>+0x68(SB)/8, $0xbf597fc7b00327c8
|
||||
DATA constants<>+0x70(SB)/8, $0xd5a79147c6e00bf3
|
||||
DATA constants<>+0x78(SB)/8, $0x1429296706ca6351
|
||||
DATA constants<>+0x80(SB)/8, $0x2e1b213827b70a85
|
||||
DATA constants<>+0x88(SB)/8, $0x53380d134d2c6dfc
|
||||
DATA constants<>+0x90(SB)/8, $0x766a0abb650a7354
|
||||
DATA constants<>+0x98(SB)/8, $0x92722c8581c2c92e
|
||||
DATA constants<>+0xa0(SB)/8, $0xa81a664ba2bfe8a1
|
||||
DATA constants<>+0xa8(SB)/8, $0xc76c51a3c24b8b70
|
||||
DATA constants<>+0xb0(SB)/8, $0xd6990624d192e819
|
||||
DATA constants<>+0xb8(SB)/8, $0x106aa070f40e3585
|
||||
DATA constants<>+0xc0(SB)/8, $0x1e376c0819a4c116
|
||||
DATA constants<>+0xc8(SB)/8, $0x34b0bcb52748774c
|
||||
DATA constants<>+0xd0(SB)/8, $0x4ed8aa4a391c0cb3
|
||||
DATA constants<>+0xd8(SB)/8, $0x682e6ff35b9cca4f
|
||||
DATA constants<>+0xe0(SB)/8, $0x78a5636f748f82ee
|
||||
DATA constants<>+0xe8(SB)/8, $0x8cc7020884c87814
|
||||
DATA constants<>+0xf0(SB)/8, $0xa4506ceb90befffa
|
||||
DATA constants<>+0xf8(SB)/8, $0xc67178f2bef9a3f7
|
||||
|
||||
DATA bflipMask<>+0x00(SB)/8, $0x0405060700010203
|
||||
DATA bflipMask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b
|
||||
|
||||
DATA shuf00BA<>+0x00(SB)/8, $0x0b0a090803020100
|
||||
DATA shuf00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
|
||||
DATA shufDC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
DATA shufDC00<>+0x08(SB)/8, $0x0b0a090803020100
|
||||
|
||||
GLOBL constants<>(SB), 8, $256
|
||||
GLOBL bflipMask<>(SB), (NOPTR+RODATA), $16
|
||||
GLOBL shuf00BA<>(SB), (NOPTR+RODATA), $16
|
||||
GLOBL shufDC00<>(SB), (NOPTR+RODATA), $16
|
25
vendor/github.com/minio/sha256-simd/sha256block_386.go
generated
vendored
Normal file
25
vendor/github.com/minio/sha256-simd/sha256block_386.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
//+build !noasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
func blockArmGo(dig *digest, p []byte) {}
|
||||
func blockAvx2Go(dig *digest, p []byte) {}
|
||||
func blockAvxGo(dig *digest, p []byte) {}
|
||||
func blockSsseGo(dig *digest, p []byte) {}
|
||||
func blockShaGo(dig *digest, p []byte) {}
|
53
vendor/github.com/minio/sha256-simd/sha256block_amd64.go
generated
vendored
Normal file
53
vendor/github.com/minio/sha256-simd/sha256block_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
//+build !noasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
func blockArmGo(dig *digest, p []byte) {}
|
||||
|
||||
func blockAvxGo(dig *digest, p []byte) {
|
||||
|
||||
h := []uint32{dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]}
|
||||
|
||||
blockAvx(h[:], p[:], 0, 0, 0, 0)
|
||||
|
||||
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
|
||||
}
|
||||
|
||||
func blockAvx2Go(dig *digest, p []byte) {
|
||||
|
||||
h := []uint32{dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]}
|
||||
|
||||
blockAvx2(h[:], p[:])
|
||||
|
||||
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
|
||||
}
|
||||
|
||||
func blockSsseGo(dig *digest, p []byte) {
|
||||
|
||||
h := []uint32{dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]}
|
||||
|
||||
blockSsse(h[:], p[:], 0, 0, 0, 0)
|
||||
|
||||
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
|
||||
}
|
||||
|
||||
func blockShaGo(dig *digest, p []byte) {
|
||||
|
||||
blockSha(&dig.h, p)
|
||||
}
|
25
vendor/github.com/minio/sha256-simd/sha256block_arm.go
generated
vendored
Normal file
25
vendor/github.com/minio/sha256-simd/sha256block_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
//+build !noasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
func blockAvx2Go(dig *digest, p []byte) {}
|
||||
func blockAvxGo(dig *digest, p []byte) {}
|
||||
func blockSsseGo(dig *digest, p []byte) {}
|
||||
func blockShaGo(dig *digest, p []byte) {}
|
||||
func blockArmGo(dig *digest, p []byte) {}
|
37
vendor/github.com/minio/sha256-simd/sha256block_arm64.go
generated
vendored
Normal file
37
vendor/github.com/minio/sha256-simd/sha256block_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
//+build !noasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
func blockAvx2Go(dig *digest, p []byte) {}
|
||||
func blockAvxGo(dig *digest, p []byte) {}
|
||||
func blockSsseGo(dig *digest, p []byte) {}
|
||||
func blockShaGo(dig *digest, p []byte) {}
|
||||
|
||||
//go:noescape
|
||||
func blockArm(h []uint32, message []uint8)
|
||||
|
||||
func blockArmGo(dig *digest, p []byte) {
|
||||
|
||||
h := []uint32{dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]}
|
||||
|
||||
blockArm(h[:], p[:])
|
||||
|
||||
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h[0], h[1], h[2], h[3], h[4],
|
||||
h[5], h[6], h[7]
|
||||
}
|
192
vendor/github.com/minio/sha256-simd/sha256block_arm64.s
generated
vendored
Normal file
192
vendor/github.com/minio/sha256-simd/sha256block_arm64.s
generated
vendored
Normal file
|
@ -0,0 +1,192 @@
|
|||
//+build !noasm !appengine
|
||||
|
||||
// ARM64 version of SHA256
|
||||
|
||||
//
|
||||
// Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
//
|
||||
// Based on implementation as found in https://github.com/jocover/sha256-armv8
|
||||
//
|
||||
// Use github.com/minio/asm2plan9s on this file to assemble ARM instructions to
|
||||
// their Plan9 equivalents
|
||||
//
|
||||
|
||||
TEXT ·blockArm(SB), 7, $0
|
||||
MOVD h+0(FP), R0
|
||||
MOVD message+24(FP), R1
|
||||
MOVD lenmessage+32(FP), R2 // length of message
|
||||
SUBS $64, R2
|
||||
BMI complete
|
||||
|
||||
// Load constants table pointer
|
||||
MOVD $·constants(SB), R3
|
||||
|
||||
// Cache constants table in registers v16 - v31
|
||||
WORD $0x4cdf2870 // ld1 {v16.4s-v19.4s}, [x3], #64
|
||||
WORD $0x4cdf7800 // ld1 {v0.4s}, [x0], #16
|
||||
WORD $0x4cdf2874 // ld1 {v20.4s-v23.4s}, [x3], #64
|
||||
|
||||
WORD $0x4c407801 // ld1 {v1.4s}, [x0]
|
||||
WORD $0x4cdf2878 // ld1 {v24.4s-v27.4s}, [x3], #64
|
||||
WORD $0xd1004000 // sub x0, x0, #0x10
|
||||
WORD $0x4cdf287c // ld1 {v28.4s-v31.4s}, [x3], #64
|
||||
|
||||
loop:
|
||||
// Main loop
|
||||
WORD $0x4cdf2025 // ld1 {v5.16b-v8.16b}, [x1], #64
|
||||
WORD $0x4ea01c02 // mov v2.16b, v0.16b
|
||||
WORD $0x4ea11c23 // mov v3.16b, v1.16b
|
||||
WORD $0x6e2008a5 // rev32 v5.16b, v5.16b
|
||||
WORD $0x6e2008c6 // rev32 v6.16b, v6.16b
|
||||
WORD $0x4eb084a9 // add v9.4s, v5.4s, v16.4s
|
||||
WORD $0x6e2008e7 // rev32 v7.16b, v7.16b
|
||||
WORD $0x4eb184ca // add v10.4s, v6.4s, v17.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e094062 // sha256h q2, q3, v9.4s
|
||||
WORD $0x5e095083 // sha256h2 q3, q4, v9.4s
|
||||
WORD $0x5e2828c5 // sha256su0 v5.4s, v6.4s
|
||||
WORD $0x6e200908 // rev32 v8.16b, v8.16b
|
||||
WORD $0x4eb284e9 // add v9.4s, v7.4s, v18.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e0a4062 // sha256h q2, q3, v10.4s
|
||||
WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s
|
||||
WORD $0x5e2828e6 // sha256su0 v6.4s, v7.4s
|
||||
WORD $0x5e0860e5 // sha256su1 v5.4s, v7.4s, v8.4s
|
||||
WORD $0x4eb3850a // add v10.4s, v8.4s, v19.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e094062 // sha256h q2, q3, v9.4s
|
||||
WORD $0x5e095083 // sha256h2 q3, q4, v9.4s
|
||||
WORD $0x5e282907 // sha256su0 v7.4s, v8.4s
|
||||
WORD $0x5e056106 // sha256su1 v6.4s, v8.4s, v5.4s
|
||||
WORD $0x4eb484a9 // add v9.4s, v5.4s, v20.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e0a4062 // sha256h q2, q3, v10.4s
|
||||
WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s
|
||||
WORD $0x5e2828a8 // sha256su0 v8.4s, v5.4s
|
||||
WORD $0x5e0660a7 // sha256su1 v7.4s, v5.4s, v6.4s
|
||||
WORD $0x4eb584ca // add v10.4s, v6.4s, v21.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e094062 // sha256h q2, q3, v9.4s
|
||||
WORD $0x5e095083 // sha256h2 q3, q4, v9.4s
|
||||
WORD $0x5e2828c5 // sha256su0 v5.4s, v6.4s
|
||||
WORD $0x5e0760c8 // sha256su1 v8.4s, v6.4s, v7.4s
|
||||
WORD $0x4eb684e9 // add v9.4s, v7.4s, v22.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e0a4062 // sha256h q2, q3, v10.4s
|
||||
WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s
|
||||
WORD $0x5e2828e6 // sha256su0 v6.4s, v7.4s
|
||||
WORD $0x5e0860e5 // sha256su1 v5.4s, v7.4s, v8.4s
|
||||
WORD $0x4eb7850a // add v10.4s, v8.4s, v23.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e094062 // sha256h q2, q3, v9.4s
|
||||
WORD $0x5e095083 // sha256h2 q3, q4, v9.4s
|
||||
WORD $0x5e282907 // sha256su0 v7.4s, v8.4s
|
||||
WORD $0x5e056106 // sha256su1 v6.4s, v8.4s, v5.4s
|
||||
WORD $0x4eb884a9 // add v9.4s, v5.4s, v24.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e0a4062 // sha256h q2, q3, v10.4s
|
||||
WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s
|
||||
WORD $0x5e2828a8 // sha256su0 v8.4s, v5.4s
|
||||
WORD $0x5e0660a7 // sha256su1 v7.4s, v5.4s, v6.4s
|
||||
WORD $0x4eb984ca // add v10.4s, v6.4s, v25.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e094062 // sha256h q2, q3, v9.4s
|
||||
WORD $0x5e095083 // sha256h2 q3, q4, v9.4s
|
||||
WORD $0x5e2828c5 // sha256su0 v5.4s, v6.4s
|
||||
WORD $0x5e0760c8 // sha256su1 v8.4s, v6.4s, v7.4s
|
||||
WORD $0x4eba84e9 // add v9.4s, v7.4s, v26.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e0a4062 // sha256h q2, q3, v10.4s
|
||||
WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s
|
||||
WORD $0x5e2828e6 // sha256su0 v6.4s, v7.4s
|
||||
WORD $0x5e0860e5 // sha256su1 v5.4s, v7.4s, v8.4s
|
||||
WORD $0x4ebb850a // add v10.4s, v8.4s, v27.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e094062 // sha256h q2, q3, v9.4s
|
||||
WORD $0x5e095083 // sha256h2 q3, q4, v9.4s
|
||||
WORD $0x5e282907 // sha256su0 v7.4s, v8.4s
|
||||
WORD $0x5e056106 // sha256su1 v6.4s, v8.4s, v5.4s
|
||||
WORD $0x4ebc84a9 // add v9.4s, v5.4s, v28.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e0a4062 // sha256h q2, q3, v10.4s
|
||||
WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s
|
||||
WORD $0x5e2828a8 // sha256su0 v8.4s, v5.4s
|
||||
WORD $0x5e0660a7 // sha256su1 v7.4s, v5.4s, v6.4s
|
||||
WORD $0x4ebd84ca // add v10.4s, v6.4s, v29.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e094062 // sha256h q2, q3, v9.4s
|
||||
WORD $0x5e095083 // sha256h2 q3, q4, v9.4s
|
||||
WORD $0x5e0760c8 // sha256su1 v8.4s, v6.4s, v7.4s
|
||||
WORD $0x4ebe84e9 // add v9.4s, v7.4s, v30.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e0a4062 // sha256h q2, q3, v10.4s
|
||||
WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s
|
||||
WORD $0x4ebf850a // add v10.4s, v8.4s, v31.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e094062 // sha256h q2, q3, v9.4s
|
||||
WORD $0x5e095083 // sha256h2 q3, q4, v9.4s
|
||||
WORD $0x4ea21c44 // mov v4.16b, v2.16b
|
||||
WORD $0x5e0a4062 // sha256h q2, q3, v10.4s
|
||||
WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s
|
||||
WORD $0x4ea38421 // add v1.4s, v1.4s, v3.4s
|
||||
WORD $0x4ea28400 // add v0.4s, v0.4s, v2.4s
|
||||
|
||||
SUBS $64, R2
|
||||
BPL loop
|
||||
|
||||
// Store result
|
||||
WORD $0x4c00a800 // st1 {v0.4s, v1.4s}, [x0]
|
||||
|
||||
complete:
|
||||
RET
|
||||
|
||||
// Constants table
|
||||
DATA ·constants+0x0(SB)/8, $0x71374491428a2f98
|
||||
DATA ·constants+0x8(SB)/8, $0xe9b5dba5b5c0fbcf
|
||||
DATA ·constants+0x10(SB)/8, $0x59f111f13956c25b
|
||||
DATA ·constants+0x18(SB)/8, $0xab1c5ed5923f82a4
|
||||
DATA ·constants+0x20(SB)/8, $0x12835b01d807aa98
|
||||
DATA ·constants+0x28(SB)/8, $0x550c7dc3243185be
|
||||
DATA ·constants+0x30(SB)/8, $0x80deb1fe72be5d74
|
||||
DATA ·constants+0x38(SB)/8, $0xc19bf1749bdc06a7
|
||||
DATA ·constants+0x40(SB)/8, $0xefbe4786e49b69c1
|
||||
DATA ·constants+0x48(SB)/8, $0x240ca1cc0fc19dc6
|
||||
DATA ·constants+0x50(SB)/8, $0x4a7484aa2de92c6f
|
||||
DATA ·constants+0x58(SB)/8, $0x76f988da5cb0a9dc
|
||||
DATA ·constants+0x60(SB)/8, $0xa831c66d983e5152
|
||||
DATA ·constants+0x68(SB)/8, $0xbf597fc7b00327c8
|
||||
DATA ·constants+0x70(SB)/8, $0xd5a79147c6e00bf3
|
||||
DATA ·constants+0x78(SB)/8, $0x1429296706ca6351
|
||||
DATA ·constants+0x80(SB)/8, $0x2e1b213827b70a85
|
||||
DATA ·constants+0x88(SB)/8, $0x53380d134d2c6dfc
|
||||
DATA ·constants+0x90(SB)/8, $0x766a0abb650a7354
|
||||
DATA ·constants+0x98(SB)/8, $0x92722c8581c2c92e
|
||||
DATA ·constants+0xa0(SB)/8, $0xa81a664ba2bfe8a1
|
||||
DATA ·constants+0xa8(SB)/8, $0xc76c51a3c24b8b70
|
||||
DATA ·constants+0xb0(SB)/8, $0xd6990624d192e819
|
||||
DATA ·constants+0xb8(SB)/8, $0x106aa070f40e3585
|
||||
DATA ·constants+0xc0(SB)/8, $0x1e376c0819a4c116
|
||||
DATA ·constants+0xc8(SB)/8, $0x34b0bcb52748774c
|
||||
DATA ·constants+0xd0(SB)/8, $0x4ed8aa4a391c0cb3
|
||||
DATA ·constants+0xd8(SB)/8, $0x682e6ff35b9cca4f
|
||||
DATA ·constants+0xe0(SB)/8, $0x78a5636f748f82ee
|
||||
DATA ·constants+0xe8(SB)/8, $0x8cc7020884c87814
|
||||
DATA ·constants+0xf0(SB)/8, $0xa4506ceb90befffa
|
||||
DATA ·constants+0xf8(SB)/8, $0xc67178f2bef9a3f7
|
||||
|
||||
GLOBL ·constants(SB), 8, $256
|
||||
|
25
vendor/github.com/minio/sha256-simd/sha256block_other.go
generated
vendored
Normal file
25
vendor/github.com/minio/sha256-simd/sha256block_other.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
//+build noasm appengine ppc64 ppc64le mips mipsle mips64 mips64le s390x wasm
|
||||
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2019 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sha256
|
||||
|
||||
func blockAvx2Go(dig *digest, p []byte) {}
|
||||
func blockAvxGo(dig *digest, p []byte) {}
|
||||
func blockSsseGo(dig *digest, p []byte) {}
|
||||
func blockShaGo(dig *digest, p []byte) {}
|
||||
func blockArmGo(dig *digest, p []byte) {}
|
6
vendor/github.com/spacemonkeygo/errors/.travis.yml
generated
vendored
Normal file
6
vendor/github.com/spacemonkeygo/errors/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.7
|
||||
- 1.8
|
||||
- tip
|
191
vendor/github.com/spacemonkeygo/errors/LICENSE
generated
vendored
Normal file
191
vendor/github.com/spacemonkeygo/errors/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||
owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, "control" means (i) the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including
|
||||
but not limited to software source code, documentation source, and configuration
|
||||
files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object code,
|
||||
generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
||||
available under the License, as indicated by a copyright notice that is included
|
||||
in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version
|
||||
of the Work and any modifications or additions to that Work or Derivative Works
|
||||
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||
on behalf of the copyright owner. For the purposes of this definition,
|
||||
"submitted" means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems, and
|
||||
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||
the purpose of discussing and improving the Work, but excluding communication
|
||||
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have
|
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||
such license applies only to those patent claims licensable by such Contributor
|
||||
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||
submitted. If You institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||
Contribution incorporated within the Work constitutes direct or contributory
|
||||
patent infringement, then any patent licenses granted to You under this License
|
||||
for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution.
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||
in any medium, with or without modifications, and in Source or Object form,
|
||||
provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute,
|
||||
all copyright, patent, trademark, and attribution notices from the Source form
|
||||
of the Work, excluding those notices that do not pertain to any part of the
|
||||
Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
||||
Derivative Works that You distribute must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, excluding those notices
|
||||
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||
following places: within a NOTICE text file distributed as part of the
|
||||
Derivative Works; within the Source form or documentation, if provided along
|
||||
with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of
|
||||
the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works that
|
||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||
provided that such additional attribution notices cannot be construed as
|
||||
modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||
with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions.
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||
conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||
any separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
6. Trademarks.
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks,
|
||||
service marks, or product names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
including, without limitation, any warranties or conditions of TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
8. Limitation of Liability.
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence),
|
||||
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special, incidental,
|
||||
or consequential damages of any character arising as a result of this License or
|
||||
out of the use or inability to use the Work (including but not limited to
|
||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability.
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||
other liability obligations and/or rights consistent with this License. However,
|
||||
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate
|
||||
notice, with the fields enclosed by brackets "[]" replaced with your own
|
||||
identifying information. (Don't include the brackets!) The text should be
|
||||
enclosed in the appropriate comment syntax for the file format. We also
|
||||
recommend that a file or class name and description of purpose be included on
|
||||
the same "printed page" as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
19
vendor/github.com/spacemonkeygo/errors/README.md
generated
vendored
Normal file
19
vendor/github.com/spacemonkeygo/errors/README.md
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
# errors [![Build Status](https://api.travis-ci.org/spacemonkeygo/errors.svg?branch=master)](https://travis-ci.org/spacemonkeygo/errors)
|
||||
|
||||
Please see http://godoc.org/github.com/spacemonkeygo/errors for info
|
||||
|
||||
### License
|
||||
|
||||
Copyright (C) 2014 Space Monkey, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
24
vendor/github.com/spacemonkeygo/errors/config.go
generated
vendored
Normal file
24
vendor/github.com/spacemonkeygo/errors/config.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package errors
|
||||
|
||||
// Config is a configuration struct meant to be used with
|
||||
// github.com/spacemonkeygo/flagfile/utils.Setup
|
||||
// but can be set independently.
|
||||
var Config = struct {
|
||||
Stacklogsize int `default:"4096" usage:"the max stack trace byte length to log"`
|
||||
}{
|
||||
Stacklogsize: 4096,
|
||||
}
|
30
vendor/github.com/spacemonkeygo/errors/ctx17.go
generated
vendored
Normal file
30
vendor/github.com/spacemonkeygo/errors/ctx17.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2016 Space Monkey, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
// TODO: remove this build restriction once appengine supports 1.7
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
var (
|
||||
contextCanceled = context.Canceled
|
||||
contextDeadlineExceeded = context.DeadlineExceeded
|
||||
)
|
32
vendor/github.com/spacemonkeygo/errors/data_keys.go
generated
vendored
Normal file
32
vendor/github.com/spacemonkeygo/errors/data_keys.go
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var (
|
||||
lastId int32 = 0
|
||||
)
|
||||
|
||||
// DataKey's job is to make sure that keys in each error instances namespace
|
||||
// are lexically scoped, thus helping developers not step on each others' toes
|
||||
// between large packages. You can only store data on an error using a DataKey,
|
||||
// and you can only make DataKeys with GenSym().
|
||||
type DataKey struct{ id int32 }
|
||||
|
||||
// GenSym generates a brand new, never-before-seen DataKey
|
||||
func GenSym() DataKey { return DataKey{id: atomic.AddInt32(&lastId, 1)} }
|
205
vendor/github.com/spacemonkeygo/errors/doc.go
generated
vendored
Normal file
205
vendor/github.com/spacemonkeygo/errors/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
Package errors is a flexible error support library for Go
|
||||
|
||||
Motivation
|
||||
|
||||
Go's standard library is intentionally sparse on providing error utilities, and
|
||||
developers coming from other programming languages may miss some features they
|
||||
took for granted [1]. This package is an attempt at providing those features in
|
||||
an idiomatic Go way.
|
||||
|
||||
The main features this package provides (in addition to miscellaneous
|
||||
utilities) are:
|
||||
|
||||
* Error hierarchies
|
||||
* Stack traces
|
||||
* Arbitrary error values
|
||||
|
||||
Error hierarchies
|
||||
|
||||
While Go has very deliberately not implemented class hierarchies, a quick
|
||||
perusal of Go's net and os packages should indicate that sometimes error
|
||||
hierarchies are useful. Go programmers should be familiar with the net.Error
|
||||
interface (and the types that fulfill it) as well as the os helper functions
|
||||
such as os.IsNotExist, os.IsPermission, etc.
|
||||
|
||||
Unfortunately, to implement something similar, a developer will have to
|
||||
implement a struct that matches the error interface as well as any testing
|
||||
methods or any more detailed interfaces they may choose to export. It's not
|
||||
hard, but it is friction, and developers tend to use fmt.Errorf instead due
|
||||
to ease of use, thus missing out on useful features that functions like
|
||||
os.IsNotExist and friends provide.
|
||||
|
||||
The errors package provides reusable components for building similar
|
||||
features while reducing friction as much as possible. With the errors package,
|
||||
the os error handling routines can be mimicked as follows:
|
||||
|
||||
package osmimic
|
||||
|
||||
import (
|
||||
"github.com/spacemonkeygo/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
OSError = errors.NewClass("OS Error")
|
||||
NotExist = OSError.NewClass("Not Exist")
|
||||
)
|
||||
|
||||
func Open(path string) (*File, error) {
|
||||
// actually do something here
|
||||
return nil, NotExist.New("path %#v doesn't exist", path)
|
||||
}
|
||||
|
||||
func MyMethod() error {
|
||||
fh, err := Open(mypath)
|
||||
if err != nil {
|
||||
if NotExist.Contains(err) {
|
||||
// file doesn't exist, do stuff
|
||||
}
|
||||
return err
|
||||
}
|
||||
// do stuff
|
||||
}
|
||||
|
||||
Stack traces
|
||||
|
||||
It doesn't take long during Go development before you may find yourself
|
||||
wondering where an error came from. In other languages, as soon as an error is
|
||||
raised, a stack trace is captured and is displayed as part of the language's
|
||||
error handling. Go error types are simply basic values and no such magic
|
||||
happens to tell you what line or what stack an error came from.
|
||||
|
||||
The errors package fixes this by optionally (but by default) capturing the
|
||||
stack trace as part of your error. This behavior can be turned off and on for
|
||||
specific error classes and comes in two flavors. You can have the stack trace
|
||||
be appended to the error's Error() message, or you can have the stack trace
|
||||
be logged immediately, every time an error of that type is instantiated.
|
||||
|
||||
Every error and error class supports hierarchical settings, in the sense that
|
||||
if a setting was not explicitly set on that error or error class, setting
|
||||
resolution traverses the error class hierarchy until it finds a valid setting,
|
||||
or returns the default.
|
||||
|
||||
See CaptureStack()/NoCaptureStack() and LogOnCreation()/NoLogOnCreation() for
|
||||
how to control this feature.
|
||||
|
||||
Arbitrary error values
|
||||
|
||||
These hierarchical settings (for whether or not errors captured or logged stack
|
||||
traces) were so useful, we generalized the system to allow users to extend
|
||||
the errors system with their own values. A user can tag a specific error with
|
||||
some value given a statically defined key, or tag a whole error class subtree.
|
||||
|
||||
Arbitrary error values can easily handle situtations like net.Error's
|
||||
Temporary() field, where some errors are temporary and others aren't. This can
|
||||
be mimicked as follows:
|
||||
|
||||
package netmimic
|
||||
|
||||
import (
|
||||
"github.com/spacemonkeygo/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
NetError = errors.NewClass("Net Error")
|
||||
OpError = NetError.NewClass("Op Error")
|
||||
|
||||
tempErrorKey = errors.GenSym()
|
||||
)
|
||||
|
||||
func SetIsTemporary() errors.ErrorOption {
|
||||
return errors.SetData(tempErrorKey, true)
|
||||
}
|
||||
|
||||
func IsTemporary(err error) bool {
|
||||
v, ok := errors.GetData(err, tempErrorKey).(bool)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func NetworkOp() error {
|
||||
// actually do something here
|
||||
return OpError.NewWith("failed operation", SetIsTemporary())
|
||||
}
|
||||
|
||||
func Example() error {
|
||||
for {
|
||||
err := NetworkOp()
|
||||
if err != nil {
|
||||
if IsTemporary(err) {
|
||||
// probably should do exponential backoff
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HTTP handling
|
||||
|
||||
Another great example of arbitrary error value functionality is the errhttp
|
||||
subpackage. See the errhttp source for more examples of how to use
|
||||
SetData/GetData.
|
||||
|
||||
The errhttp package really helped clean up our error code. Take a look to
|
||||
see if it can help your error handling with HTTP stacks too.
|
||||
|
||||
http://godoc.org/github.com/spacemonkeygo/errors/errhttp
|
||||
|
||||
Exit recording
|
||||
|
||||
So you have stack traces, which tells you how the error was generated, but
|
||||
perhaps you're interested in keeping track of how the error was handled?
|
||||
|
||||
Every time you call errors.Record(err), it adds the current line information
|
||||
to the error's output. As an example:
|
||||
|
||||
func MyFunction() error {
|
||||
err := Something()
|
||||
if err != nil {
|
||||
if IsTemporary(err) {
|
||||
// manage the temporary error
|
||||
return errors.Record(err)
|
||||
} else {
|
||||
// manage the permanent error
|
||||
return errors.Record(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
errors.Record will help you keep track of which error handling branch your
|
||||
code took.
|
||||
|
||||
ErrorGroup
|
||||
|
||||
There's a few different types of ErrorGroup utilities in this package, but they
|
||||
all work the same way. Make sure to check out the ErrorGroup example.
|
||||
|
||||
CatchPanic
|
||||
|
||||
CatchPanic helps you easily manage functions that you think might panic, and
|
||||
instead return errors. CatchPanic works by taking a pointer to your named error
|
||||
return value. Check out the CatchPanic example for more.
|
||||
|
||||
Footnotes
|
||||
|
||||
[1] This errors package started while porting a large Python codebase to Go.
|
||||
https://www.spacemonkey.com/blog/posts/go-space-monkey
|
||||
*/
|
||||
package errors
|
648
vendor/github.com/spacemonkeygo/errors/errors.go
generated
vendored
Normal file
648
vendor/github.com/spacemonkeygo/errors/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,648 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
logOnCreation = GenSym()
|
||||
captureStack = GenSym()
|
||||
disableInheritance = GenSym()
|
||||
)
|
||||
|
||||
// ErrorClass is the basic hierarchical error type. An ErrorClass generates
|
||||
// actual errors, but the error class controls properties of the errors it
|
||||
// generates, such as where those errors are in the hierarchy, whether or not
|
||||
// they capture the stack on instantiation, and so forth.
|
||||
type ErrorClass struct {
|
||||
parent *ErrorClass
|
||||
name string
|
||||
data map[DataKey]interface{}
|
||||
}
|
||||
|
||||
var (
|
||||
// HierarchicalError is the base class for all hierarchical errors generated
|
||||
// through this class.
|
||||
HierarchicalError = &ErrorClass{
|
||||
parent: nil,
|
||||
name: "Error",
|
||||
data: map[DataKey]interface{}{captureStack: true}}
|
||||
|
||||
// SystemError is the base error class for errors not generated through this
|
||||
// errors library. It is not expected that anyone would ever generate new
|
||||
// errors from a SystemError type or make subclasses.
|
||||
SystemError = &ErrorClass{
|
||||
parent: nil,
|
||||
name: "System Error",
|
||||
data: map[DataKey]interface{}{}}
|
||||
)
|
||||
|
||||
// An ErrorOption is something that controls behavior of specific error
|
||||
// instances. They can be set on ErrorClasses or errors individually.
|
||||
type ErrorOption func(map[DataKey]interface{})
|
||||
|
||||
// SetData will take the given value and store it with the error or error class
|
||||
// and its descendents associated with the given DataKey. Be sure to check out
|
||||
// the example. value can be nil to disable values for subhierarchies.
|
||||
func SetData(key DataKey, value interface{}) ErrorOption {
|
||||
return func(m map[DataKey]interface{}) {
|
||||
m[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
// LogOnCreation tells the error class and its descendents to log the stack
|
||||
// whenever an error of this class is created.
|
||||
func LogOnCreation() ErrorOption {
|
||||
return SetData(logOnCreation, true)
|
||||
}
|
||||
|
||||
// CaptureStack tells the error class and its descendents to capture the stack
|
||||
// whenever an error of this class is created, and output it as part of the
|
||||
// error's Error() method. This is the default.
|
||||
func CaptureStack() ErrorOption {
|
||||
return SetData(captureStack, true)
|
||||
}
|
||||
|
||||
// NoLogOnCreation is the opposite of LogOnCreation and applies to the error,
|
||||
// class, and its descendents. This is the default.
|
||||
func NoLogOnCreation() ErrorOption {
|
||||
return SetData(logOnCreation, false)
|
||||
}
|
||||
|
||||
// NoCaptureStack is the opposite of CaptureStack and applies to the error,
|
||||
// class, and its descendents.
|
||||
func NoCaptureStack() ErrorOption {
|
||||
return SetData(captureStack, false)
|
||||
}
|
||||
|
||||
// If DisableInheritance is provided, the error or error class will belong to
|
||||
// its ancestors, but will not inherit their settings and options. Use with
|
||||
// caution, and may disappear in future releases.
|
||||
func DisableInheritance() ErrorOption {
|
||||
return SetData(disableInheritance, true)
|
||||
}
|
||||
|
||||
func boolWrapper(val interface{}, default_value bool) bool {
|
||||
rv, ok := val.(bool)
|
||||
if ok {
|
||||
return rv
|
||||
}
|
||||
return default_value
|
||||
}
|
||||
|
||||
// NewClass creates an error class with the provided name and options. Classes
|
||||
// generated from this method and not *ErrorClass.NewClass will descend from
|
||||
// the root HierarchicalError base class.
|
||||
func NewClass(name string, options ...ErrorOption) *ErrorClass {
|
||||
return HierarchicalError.NewClass(name, options...)
|
||||
}
|
||||
|
||||
// New is for compatibility with the default Go errors package. It simply
|
||||
// creates an error from the HierarchicalError root class.
|
||||
func New(text string) error {
|
||||
// NewWith doesn't take a format string, even though we have no options.
|
||||
return HierarchicalError.NewWith(text)
|
||||
}
|
||||
|
||||
// NewClass creates an error class with the provided name and options. The new
|
||||
// class will descend from the receiver.
|
||||
func (parent *ErrorClass) NewClass(name string,
|
||||
options ...ErrorOption) *ErrorClass {
|
||||
|
||||
ec := &ErrorClass{
|
||||
parent: parent,
|
||||
name: name,
|
||||
data: make(map[DataKey]interface{})}
|
||||
|
||||
for _, option := range options {
|
||||
option(ec.data)
|
||||
}
|
||||
|
||||
if !boolWrapper(ec.data[disableInheritance], false) {
|
||||
// hoist options for speed
|
||||
for key, val := range parent.data {
|
||||
_, exists := ec.data[key]
|
||||
if !exists {
|
||||
ec.data[key] = val
|
||||
}
|
||||
}
|
||||
return ec
|
||||
} else {
|
||||
delete(ec.data, disableInheritance)
|
||||
}
|
||||
|
||||
return ec
|
||||
}
|
||||
|
||||
// MustAddData allows adding data key value pairs to error classes after they
|
||||
// are created. This is useful for allowing external packages add namespaced
|
||||
// values to errors defined outside of their package. It will panic if the
|
||||
// key is already set in the error class.
|
||||
func (e *ErrorClass) MustAddData(key DataKey, value interface{}) {
|
||||
if _, ex := e.data[key]; ex {
|
||||
panic("key already exists")
|
||||
}
|
||||
e.data[key] = value
|
||||
}
|
||||
|
||||
// GetData will return any data set on the error class for the given key. It
|
||||
// returns nil if there is no data set for that key.
|
||||
func (e *ErrorClass) GetData(key DataKey) interface{} {
|
||||
return e.data[key]
|
||||
}
|
||||
|
||||
// Parent returns this error class' direct ancestor.
|
||||
func (e *ErrorClass) Parent() *ErrorClass {
|
||||
return e.parent
|
||||
}
|
||||
|
||||
// String returns this error class' name
|
||||
func (e *ErrorClass) String() string {
|
||||
if e == nil {
|
||||
return "nil"
|
||||
}
|
||||
return e.name
|
||||
}
|
||||
|
||||
// Is returns true if the receiver class is or is a descendent of parent.
|
||||
func (e *ErrorClass) Is(parent *ErrorClass) bool {
|
||||
for check := e; check != nil; check = check.parent {
|
||||
if check == parent {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// frame logs the pc at some point during execution.
|
||||
type frame struct {
|
||||
pc uintptr
|
||||
}
|
||||
|
||||
// String returns a human readable form of the frame.
|
||||
func (e frame) String() string {
|
||||
if e.pc == 0 {
|
||||
return "unknown.unknown:0"
|
||||
}
|
||||
f := runtime.FuncForPC(e.pc)
|
||||
if f == nil {
|
||||
return "unknown.unknown:0"
|
||||
}
|
||||
file, line := f.FileLine(e.pc)
|
||||
return fmt.Sprintf("%s:%s:%d", f.Name(), filepath.Base(file), line)
|
||||
}
|
||||
|
||||
// callerState records the pc into an frame for two callers up.
|
||||
func callerState(depth int) frame {
|
||||
pc, _, _, ok := runtime.Caller(depth)
|
||||
if !ok {
|
||||
return frame{pc: 0}
|
||||
}
|
||||
return frame{pc: pc}
|
||||
}
|
||||
|
||||
// record will record the pc at the given depth into the error if it is
|
||||
// capable of recording it.
|
||||
func record(err error, depth int) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
cast.exits = append(cast.exits, callerState(depth))
|
||||
return cast
|
||||
}
|
||||
|
||||
// Record will record the current pc on the given error if possible, adding
|
||||
// to the error's recorded exits list. Returns the given error argument.
|
||||
func Record(err error) error {
|
||||
return record(err, 3)
|
||||
}
|
||||
|
||||
// RecordBefore will record the pc depth frames above the current stack frame
|
||||
// on the given error if possible, adding to the error's recorded exits list.
|
||||
// Record(err) is equivalent to RecordBefore(err, 0). Returns the given error
|
||||
// argument.
|
||||
func RecordBefore(err error, depth int) error {
|
||||
return record(err, 3+depth)
|
||||
}
|
||||
|
||||
// Error is the type that represents a specific error instance. It is not
|
||||
// expected that you will work with *Error classes directly. Instead, you
|
||||
// should use the 'error' interface and errors package methods that operate
|
||||
// on errors instances.
|
||||
type Error struct {
|
||||
err error
|
||||
class *ErrorClass
|
||||
stacks [][]frame
|
||||
exits []frame
|
||||
data map[DataKey]interface{}
|
||||
}
|
||||
|
||||
// GetData returns the value associated with the given DataKey on this error
|
||||
// or any of its ancestors. Please see the example for SetData
|
||||
func (e *Error) GetData(key DataKey) interface{} {
|
||||
if e.data != nil {
|
||||
val, ok := e.data[key]
|
||||
if ok {
|
||||
return val
|
||||
}
|
||||
if boolWrapper(e.data[disableInheritance], false) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return e.class.data[key]
|
||||
}
|
||||
|
||||
// GetData returns the value associated with the given DataKey on this error
|
||||
// or any of its ancestors. Please see the example for SetData
|
||||
func GetData(err error, key DataKey) interface{} {
|
||||
cast, ok := err.(*Error)
|
||||
if ok {
|
||||
return cast.GetData(key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *ErrorClass) wrap(err error, classes []*ErrorClass,
|
||||
options []ErrorOption) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if ec, ok := err.(*Error); ok {
|
||||
if ec.Is(e) {
|
||||
if len(options) == 0 {
|
||||
return ec
|
||||
}
|
||||
// if we have options, we have to wrap it cause we don't want to
|
||||
// mutate the existing error.
|
||||
} else {
|
||||
for _, class := range classes {
|
||||
if ec.Is(class) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv := &Error{err: err, class: e}
|
||||
if len(options) > 0 {
|
||||
rv.data = make(map[DataKey]interface{})
|
||||
for _, option := range options {
|
||||
option(rv.data)
|
||||
}
|
||||
}
|
||||
|
||||
if boolWrapper(rv.GetData(captureStack), false) {
|
||||
rv.stacks = [][]frame{getStack(3)}
|
||||
}
|
||||
if boolWrapper(rv.GetData(logOnCreation), false) {
|
||||
LogWithStack(rv.Error())
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
func getStack(depth int) (stack []frame) {
|
||||
var pcs [256]uintptr
|
||||
amount := runtime.Callers(depth+1, pcs[:])
|
||||
stack = make([]frame, amount)
|
||||
for i := 0; i < amount; i++ {
|
||||
stack[i] = frame{pcs[i]}
|
||||
}
|
||||
return stack
|
||||
}
|
||||
|
||||
// AttachStack adds another stack to the current error's stack trace if it
|
||||
// exists
|
||||
func AttachStack(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if len(cast.stacks) < 1 {
|
||||
// only record stacks if this error was supposed to
|
||||
return
|
||||
}
|
||||
cast.stacks = append(cast.stacks, getStack(2))
|
||||
}
|
||||
|
||||
// WrapUnless wraps the given error in the receiver error class unless the
|
||||
// error is already an instance of one of the provided error classes.
|
||||
func (e *ErrorClass) WrapUnless(err error, classes ...*ErrorClass) error {
|
||||
return e.wrap(err, classes, nil)
|
||||
}
|
||||
|
||||
// Wrap wraps the given error in the receiver error class with the provided
|
||||
// error-specific options.
|
||||
func (e *ErrorClass) Wrap(err error, options ...ErrorOption) error {
|
||||
return e.wrap(err, nil, options)
|
||||
}
|
||||
|
||||
// New makes a new error type. It takes a format string.
|
||||
func (e *ErrorClass) New(format string, args ...interface{}) error {
|
||||
return e.wrap(fmt.Errorf(format, args...), nil, nil)
|
||||
}
|
||||
|
||||
// NewWith makes a new error type with the provided error-specific options.
|
||||
func (e *ErrorClass) NewWith(message string, options ...ErrorOption) error {
|
||||
return e.wrap(errors.New(message), nil, options)
|
||||
}
|
||||
|
||||
// Error conforms to the error interface. Error will return the backtrace if
|
||||
// it was captured and any recorded exits.
|
||||
func (e *Error) Error() string {
|
||||
message := strings.TrimRight(e.err.Error(), "\n ")
|
||||
if strings.Contains(message, "\n") {
|
||||
message = fmt.Sprintf("%s:\n %s", e.class.String(),
|
||||
strings.Replace(message, "\n", "\n ", -1))
|
||||
} else {
|
||||
message = fmt.Sprintf("%s: %s", e.class.String(), message)
|
||||
}
|
||||
if stack := e.Stack(); stack != "" {
|
||||
message = fmt.Sprintf(
|
||||
"%s\n\"%s\" backtrace:\n%s", message, e.class, stack)
|
||||
}
|
||||
if exits := e.Exits(); exits != "" {
|
||||
message = fmt.Sprintf(
|
||||
"%s\n\"%s\" exits:\n%s", message, e.class, exits)
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
// Message returns just the error message without the backtrace or exits.
|
||||
func (e *Error) Message() string {
|
||||
message := strings.TrimRight(GetMessage(e.err), "\n ")
|
||||
if strings.Contains(message, "\n") {
|
||||
return fmt.Sprintf("%s:\n %s", e.class.String(),
|
||||
strings.Replace(message, "\n", "\n ", -1))
|
||||
}
|
||||
return fmt.Sprintf("%s: %s", e.class.String(), message)
|
||||
}
|
||||
|
||||
// WrappedErr returns the wrapped error, if the current error is simply
|
||||
// wrapping some previously returned error or system error. You probably want
|
||||
// the package-level WrappedErr
|
||||
func (e *Error) WrappedErr() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
// WrappedErr returns the wrapped error, if the current error is simply
|
||||
// wrapping some previously returned error or system error. If the error isn't
|
||||
// hierarchical it is just returned.
|
||||
func WrappedErr(err error) error {
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
return cast.WrappedErr()
|
||||
}
|
||||
|
||||
// Class will return the appropriate error class for the given error. You
|
||||
// probably want the package-level GetClass.
|
||||
func (e *Error) Class() *ErrorClass {
|
||||
return e.class
|
||||
}
|
||||
|
||||
// Name returns the name of the error: in this case the name of the class the
|
||||
// error belongs to.
|
||||
func (e *Error) Name() (string, bool) {
|
||||
return e.class.name, true
|
||||
}
|
||||
|
||||
// GetClass will return the appropriate error class for the given error.
|
||||
// If the error is not nil, GetClass always returns a hierarchical error class,
|
||||
// and even attempts to determine a class for common system error types.
|
||||
func GetClass(err error) *ErrorClass {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return findSystemErrorClass(err)
|
||||
}
|
||||
return cast.class
|
||||
}
|
||||
|
||||
// Stack will return the stack associated with the error if one is found. You
|
||||
// probably want the package-level GetStack.
|
||||
func (e *Error) Stack() string {
|
||||
if len(e.stacks) > 0 {
|
||||
var frames []string
|
||||
for _, stack := range e.stacks {
|
||||
if frames == nil {
|
||||
frames = make([]string, 0, len(stack))
|
||||
} else {
|
||||
frames = append(frames, "----- attached stack -----")
|
||||
}
|
||||
for _, f := range stack {
|
||||
frames = append(frames, f.String())
|
||||
}
|
||||
}
|
||||
return strings.Join(frames, "\n")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetStack will return the stack associated with the error if one is found.
|
||||
func GetStack(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return cast.Stack()
|
||||
}
|
||||
|
||||
// Exits will return the exits recorded on the error if any are found. You
|
||||
// probably want the package-level GetExits.
|
||||
func (e *Error) Exits() string {
|
||||
if len(e.exits) > 0 {
|
||||
exits := make([]string, len(e.exits))
|
||||
for i, ex := range e.exits {
|
||||
exits[i] = ex.String()
|
||||
}
|
||||
return strings.Join(exits, "\n")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetExits will return the exits recorded on the error if any are found.
|
||||
func GetExits(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return cast.Exits()
|
||||
}
|
||||
|
||||
// GetMessage returns just the error message without the backtrace or exits.
|
||||
func GetMessage(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return err.Error()
|
||||
}
|
||||
return cast.Message()
|
||||
}
|
||||
|
||||
// EquivalenceOption values control behavior of determining whether or not an
|
||||
// error belongs to a specific class.
|
||||
type EquivalenceOption int
|
||||
|
||||
const (
|
||||
// If IncludeWrapped is used, wrapped errors are also used for determining
|
||||
// class membership.
|
||||
IncludeWrapped EquivalenceOption = 1
|
||||
)
|
||||
|
||||
func combineEquivOpts(opts []EquivalenceOption) (rv EquivalenceOption) {
|
||||
for _, opt := range opts {
|
||||
rv |= opt
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
// Is returns whether or not an error belongs to a specific class. Typically
|
||||
// you should use Contains instead.
|
||||
func (e *Error) Is(ec *ErrorClass, opts ...EquivalenceOption) bool {
|
||||
return ec.Contains(e, opts...)
|
||||
}
|
||||
|
||||
// Contains returns whether or not the receiver error class contains the given
|
||||
// error instance.
|
||||
func (e *ErrorClass) Contains(err error, opts ...EquivalenceOption) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return findSystemErrorClass(err).Is(e)
|
||||
}
|
||||
if cast.class.Is(e) {
|
||||
return true
|
||||
}
|
||||
if combineEquivOpts(opts)&IncludeWrapped == 0 {
|
||||
return false
|
||||
}
|
||||
return e.Contains(cast.err, opts...)
|
||||
}
|
||||
|
||||
var (
|
||||
// Useful error classes
|
||||
NotImplementedError = NewClass("Not Implemented Error", LogOnCreation())
|
||||
ProgrammerError = NewClass("Programmer Error", LogOnCreation())
|
||||
PanicError = NewClass("Panic Error", LogOnCreation())
|
||||
|
||||
// The following SystemError descendants are provided such that the GetClass
|
||||
// method has something to return for standard library error types not
|
||||
// defined through this class.
|
||||
//
|
||||
// It is not expected that anyone would create instances of these classes.
|
||||
//
|
||||
// from os
|
||||
SyscallError = SystemError.NewClass("Syscall Error")
|
||||
// from syscall
|
||||
ErrnoError = SystemError.NewClass("Errno Error")
|
||||
// from net
|
||||
NetworkError = SystemError.NewClass("Network Error")
|
||||
UnknownNetworkError = NetworkError.NewClass("Unknown Network Error")
|
||||
AddrError = NetworkError.NewClass("Addr Error")
|
||||
InvalidAddrError = AddrError.NewClass("Invalid Addr Error")
|
||||
NetOpError = NetworkError.NewClass("Network Op Error")
|
||||
NetParseError = NetworkError.NewClass("Network Parse Error")
|
||||
DNSError = NetworkError.NewClass("DNS Error")
|
||||
DNSConfigError = DNSError.NewClass("DNS Config Error")
|
||||
// from io
|
||||
IOError = SystemError.NewClass("IO Error")
|
||||
EOF = IOError.NewClass("EOF")
|
||||
ClosedPipeError = IOError.NewClass("Closed Pipe Error")
|
||||
NoProgressError = IOError.NewClass("No Progress Error")
|
||||
ShortBufferError = IOError.NewClass("Short Buffer Error")
|
||||
ShortWriteError = IOError.NewClass("Short Write Error")
|
||||
UnexpectedEOFError = IOError.NewClass("Unexpected EOF Error")
|
||||
// from context
|
||||
ContextError = SystemError.NewClass("Context Error")
|
||||
ContextCanceled = ContextError.NewClass("Canceled")
|
||||
ContextTimeout = ContextError.NewClass("Timeout")
|
||||
)
|
||||
|
||||
func findSystemErrorClass(err error) *ErrorClass {
|
||||
switch err {
|
||||
case io.EOF:
|
||||
return EOF
|
||||
case io.ErrUnexpectedEOF:
|
||||
return UnexpectedEOFError
|
||||
case io.ErrClosedPipe:
|
||||
return ClosedPipeError
|
||||
case io.ErrNoProgress:
|
||||
return NoProgressError
|
||||
case io.ErrShortBuffer:
|
||||
return ShortBufferError
|
||||
case io.ErrShortWrite:
|
||||
return ShortWriteError
|
||||
case contextCanceled:
|
||||
return ContextCanceled
|
||||
case contextDeadlineExceeded:
|
||||
return ContextTimeout
|
||||
default:
|
||||
break
|
||||
}
|
||||
if isErrnoError(err) {
|
||||
return ErrnoError
|
||||
}
|
||||
switch err.(type) {
|
||||
case *os.SyscallError:
|
||||
return SyscallError
|
||||
case net.UnknownNetworkError:
|
||||
return UnknownNetworkError
|
||||
case *net.AddrError:
|
||||
return AddrError
|
||||
case net.InvalidAddrError:
|
||||
return InvalidAddrError
|
||||
case *net.OpError:
|
||||
return NetOpError
|
||||
case *net.ParseError:
|
||||
return NetParseError
|
||||
case *net.DNSError:
|
||||
return DNSError
|
||||
case *net.DNSConfigError:
|
||||
return DNSConfigError
|
||||
case net.Error:
|
||||
return NetworkError
|
||||
default:
|
||||
return SystemError
|
||||
}
|
||||
}
|
26
vendor/github.com/spacemonkeygo/errors/syscall.go
generated
vendored
Normal file
26
vendor/github.com/spacemonkeygo/errors/syscall.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func isErrnoError(err error) bool {
|
||||
_, ok := err.(syscall.Errno)
|
||||
return ok
|
||||
}
|
21
vendor/github.com/spacemonkeygo/errors/syscall_ae.go
generated
vendored
Normal file
21
vendor/github.com/spacemonkeygo/errors/syscall_ae.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build appengine
|
||||
|
||||
package errors
|
||||
|
||||
func isErrnoError(err error) bool {
|
||||
return false
|
||||
}
|
155
vendor/github.com/spacemonkeygo/errors/utils.go
generated
vendored
Normal file
155
vendor/github.com/spacemonkeygo/errors/utils.go
generated
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// Change this method if you want errors to log somehow else
|
||||
LogMethod = log.Printf
|
||||
|
||||
ErrorGroupError = NewClass("Error Group Error")
|
||||
)
|
||||
|
||||
// LogWithStack will log the given messages with the current stack
|
||||
func LogWithStack(messages ...interface{}) {
|
||||
buf := make([]byte, Config.Stacklogsize)
|
||||
buf = buf[:runtime.Stack(buf, false)]
|
||||
LogMethod("%s\n%s", fmt.Sprintln(messages...), buf)
|
||||
}
|
||||
|
||||
// CatchPanic can be used to catch panics and turn them into errors. See the
|
||||
// example.
|
||||
func CatchPanic(err_ref *error) {
|
||||
r := recover()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
err, ok := r.(error)
|
||||
if ok {
|
||||
*err_ref = PanicError.Wrap(err)
|
||||
return
|
||||
}
|
||||
*err_ref = PanicError.New("%v", r)
|
||||
}
|
||||
|
||||
// ErrorGroup is a type for collecting errors from a bunch of independent
|
||||
// tasks. ErrorGroups are not threadsafe. See the example for usage.
|
||||
type ErrorGroup struct {
|
||||
Errors []error
|
||||
limit int
|
||||
excess int
|
||||
}
|
||||
|
||||
// NewErrorGroup makes a new ErrorGroup
|
||||
func NewErrorGroup() *ErrorGroup { return &ErrorGroup{} }
|
||||
|
||||
// NewBoundedErrorGroup makes a new ErrorGroup that will not track more than
|
||||
// limit errors. Once the limit is reached, the ErrorGroup will track
|
||||
// additional errors as excess.
|
||||
func NewBoundedErrorGroup(limit int) *ErrorGroup {
|
||||
return &ErrorGroup{
|
||||
limit: limit,
|
||||
}
|
||||
}
|
||||
|
||||
// Add is called with errors. nil errors are ignored.
|
||||
func (e *ErrorGroup) Add(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
if e.limit > 0 && len(e.Errors) == e.limit {
|
||||
e.excess++
|
||||
} else {
|
||||
e.Errors = append(e.Errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize will collate all the found errors. If no errors were found, it will
|
||||
// return nil. If one error was found, it will be returned directly. Otherwise
|
||||
// an ErrorGroupError will be returned.
|
||||
func (e *ErrorGroup) Finalize() error {
|
||||
if len(e.Errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(e.Errors) == 1 && e.excess == 0 {
|
||||
return e.Errors[0]
|
||||
}
|
||||
msgs := make([]string, 0, len(e.Errors))
|
||||
for _, err := range e.Errors {
|
||||
msgs = append(msgs, err.Error())
|
||||
}
|
||||
if e.excess > 0 {
|
||||
msgs = append(msgs, fmt.Sprintf("... and %d more.", e.excess))
|
||||
e.excess = 0
|
||||
}
|
||||
e.Errors = nil
|
||||
return ErrorGroupError.New(strings.Join(msgs, "\n"))
|
||||
}
|
||||
|
||||
// LoggingErrorGroup is similar to ErrorGroup except that instead of collecting
|
||||
// all of the errors, it logs the errors immediately and just counts how many
|
||||
// non-nil errors have been seen. See the ErrorGroup example for usage.
|
||||
type LoggingErrorGroup struct {
|
||||
name string
|
||||
total int
|
||||
failed int
|
||||
}
|
||||
|
||||
// NewLoggingErrorGroup returns a new LoggingErrorGroup with the given name.
|
||||
func NewLoggingErrorGroup(name string) *LoggingErrorGroup {
|
||||
return &LoggingErrorGroup{name: name}
|
||||
}
|
||||
|
||||
// Add will handle a given error. If the error is non-nil, total and failed
|
||||
// are both incremented and the error is logged. If the error is nil, only
|
||||
// total is incremented.
|
||||
func (e *LoggingErrorGroup) Add(err error) {
|
||||
e.total++
|
||||
if err != nil {
|
||||
LogMethod("%s: %s", e.name, err)
|
||||
e.failed++
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize returns no error if no failures were observed, otherwise it will
|
||||
// return an ErrorGroupError with statistics about the observed errors.
|
||||
func (e *LoggingErrorGroup) Finalize() (err error) {
|
||||
if e.failed > 0 {
|
||||
err = ErrorGroupError.New("%s: %d of %d failed.", e.name, e.failed,
|
||||
e.total)
|
||||
}
|
||||
e.total = 0
|
||||
e.failed = 0
|
||||
return err
|
||||
}
|
||||
|
||||
type Finalizer interface {
|
||||
Finalize() error
|
||||
}
|
||||
|
||||
// Finalize takes a group of ErrorGroups and joins them together into one error
|
||||
func Finalize(finalizers ...Finalizer) error {
|
||||
var errs ErrorGroup
|
||||
for _, finalizer := range finalizers {
|
||||
errs.Add(finalizer.Finalize())
|
||||
}
|
||||
return errs.Finalize()
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue