diff --git a/fungible/cc/go.mod b/fungible/cc/go.mod index d744e243..4db57eb3 100644 --- a/fungible/cc/go.mod +++ b/fungible/cc/go.mod @@ -47,13 +47,13 @@ require ( github.com/huin/goupnp v1.0.0 // indirect github.com/hyperledger/fabric v1.4.0-rc1.0.20220808214918-83596078d0c3 // indirect github.com/hyperledger/fabric-amcl v0.0.0-20210603140002-2670f91851c8 // indirect - github.com/ipfs/go-cid v0.1.0 // indirect + github.com/ipfs/go-cid v0.3.2 // indirect github.com/ipfs/go-datastore v0.5.1 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect github.com/ipfs/go-ipns v0.1.2 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipld/go-ipld-prime v0.9.0 // indirect + github.com/ipld/go-ipld-prime v0.19.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -90,7 +90,6 @@ require ( github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect github.com/minio/sha256-simd v1.0.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -102,8 +101,8 @@ require ( github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.0.3 // indirect - github.com/multiformats/go-multicodec v0.4.1 // indirect - github.com/multiformats/go-multihash v0.1.0 // indirect + github.com/multiformats/go-multicodec v0.6.0 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect github.com/multiformats/go-multistream v0.3.1 // indirect github.com/multiformats/go-varint v0.0.6 // indirect github.com/nxadm/tail v1.4.8 // indirect @@ -112,7 +111,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 // indirect + github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect github.com/prometheus/client_golang v1.12.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect @@ -130,7 +129,7 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect diff --git a/fungible/cc/go.sum b/fungible/cc/go.sum index bfa76617..352fefdc 100644 --- a/fungible/cc/go.sum +++ b/fungible/cc/go.sum @@ -238,6 +238,7 @@ github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiD github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= @@ -328,8 +329,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -449,8 +450,8 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0= -github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= +github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= +github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= @@ -495,8 +496,9 @@ github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Ax github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.9.0 h1:N2OjJMb+fhyFPwPnVvJcWU/NsumP8etal+d2v3G4eww= github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= +github.com/ipld/go-ipld-prime v0.19.0 h1:5axC7rJmPc17Emw6TelxGwnzALk0PdupZ2oj2roDj04= +github.com/ipld/go-ipld-prime v0.19.0/go.mod h1:Q9j3BaVXwaA3o5JUDNvptDDr/x8+F7FG6XJ8WI3ILg4= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -557,8 +559,8 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.0.0/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= @@ -838,7 +840,6 @@ github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUM github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= @@ -914,8 +915,8 @@ github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/g github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multicodec v0.2.0/go.mod h1:/y4YVwkfMyry5kFbMTbLJKErhycTIftytRV+llXdyS4= -github.com/multiformats/go-multicodec v0.4.1 h1:BSJbf+zpghcZMZrwTYBGwy0CPcVZGWiC72Cp8bBd4R4= -github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= +github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= +github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -924,8 +925,8 @@ github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpK github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA= -github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= @@ -1017,8 +1018,9 @@ github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6J github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 h1:CskT+S6Ay54OwxBGB0R3Rsx4Muto6UnEYTyKJbyRIAI= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= +github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -1281,8 +1283,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1562,7 +1564,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/certifier.go b/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/certifier.go deleted file mode 100644 index 258e77da..00000000 --- a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/certifier.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package tcc - -import ( - "github.com/pkg/errors" - - "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" - - "github.com/hyperledger-labs/fabric-token-sdk/token" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/network" - token2 "github.com/hyperledger-labs/fabric-token-sdk/token/token" -) - -type GetTokenView struct { - Network string - Channel string - Namespace string - IDs []*token2.ID -} - -func NewGetTokensView(channel string, namespace string, ids ...*token2.ID) *GetTokenView { - return &GetTokenView{Channel: channel, Namespace: namespace, IDs: ids} -} - -func (r *GetTokenView) Call(context view.Context) (interface{}, error) { - if len(r.IDs) == 0 { - return nil, errors.Errorf("no token ids provided") - } - tms := token.GetManagementService( - context, - token.WithNetwork(r.Network), - token.WithChannel(r.Channel), - token.WithNamespace(r.Namespace), - ) - tokens, err := network.GetInstance(context, tms.Network(), tms.Channel()).QueryTokens(context, tms.Namespace(), r.IDs) - if err != nil { - return nil, errors.Wrapf(err, "failed querying tokens") - } - return tokens, nil -} diff --git a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/params.go b/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/params.go deleted file mode 100644 index f0352510..00000000 --- a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/params.go +++ /dev/null @@ -1,8 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ -package tcc - -const Params = `` diff --git a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/rwset.go b/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/rwset.go deleted file mode 100644 index 20c574f5..00000000 --- a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/rwset.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ -package tcc - -import ( - "github.com/hyperledger/fabric-chaincode-go/shim" -) - -type rwsWrapper struct { - stub shim.ChaincodeStubInterface -} - -func (rwset *rwsWrapper) SetState(namespace string, key string, value []byte) error { - return rwset.stub.PutState(key, value) -} - -func (rwset *rwsWrapper) GetState(namespace string, key string) ([]byte, error) { - return rwset.stub.GetState(key) -} - -func (rwset *rwsWrapper) DeleteState(namespace string, key string) error { - return rwset.stub.DelState(key) -} - -func (rwset *rwsWrapper) Bytes() ([]byte, error) { - return nil, nil -} - -func (rwset *rwsWrapper) Done() { -} - -func (rwset *rwsWrapper) Equals(r interface{}, namespace string) error { - panic("implement me") -} diff --git a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/shim.go b/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/shim.go deleted file mode 100644 index d17eb1ca..00000000 --- a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/shim.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ -package tcc - -import ( - "github.com/hyperledger/fabric-chaincode-go/shim" -) - -//go:generate counterfeiter -o mock/chaincode_stub_interface.go -fake-name ChaincodeStubInterface . ChaincodeStubInterface - -// ChaincodeStubInterface is used by deployable chaincode apps to access and -// modify their ledgers -type ChaincodeStubInterface interface { - shim.ChaincodeStubInterface -} diff --git a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/tcc.go b/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/tcc.go deleted file mode 100644 index 536fb68a..00000000 --- a/fungible/cc/vendor/github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc/tcc.go +++ /dev/null @@ -1,343 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package tcc - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "runtime/debug" - "sync" - - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/flogging" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/tracing" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/tracker/metrics" - "github.com/hyperledger-labs/fabric-token-sdk/token" - "github.com/hyperledger-labs/fabric-token-sdk/token/services/vault/translator" - token2 "github.com/hyperledger-labs/fabric-token-sdk/token/token" - "github.com/hyperledger/fabric-chaincode-go/shim" - pb "github.com/hyperledger/fabric-protos-go/peer" - "github.com/pkg/errors" -) - -var logger = flogging.MustGetLogger("token-sdk.tcc") - -const ( - InvokeFunction = "invoke" - QueryPublicParamsFunction = "queryPublicParams" - AddCertifierFunction = "addCertifier" - QueryTokensFunctions = "queryTokens" - AreTokensSpent = "areTokensSpent" - - PublicParamsPathVarEnv = "PUBLIC_PARAMS_FILE_PATH" -) - -type Agent interface { - EmitKey(val float32, event ...string) -} - -type SetupAction struct { - SetupParameters []byte -} - -func (a *SetupAction) GetSetupParameters() ([]byte, error) { - return a.SetupParameters, nil -} - -//go:generate counterfeiter -o mock/validator.go -fake-name Validator . Validator - -type Validator interface { - UnmarshallAndVerify(ledger token.Ledger, binding string, raw []byte) ([]interface{}, error) -} - -//go:generate counterfeiter -o mock/public_parameters_manager.go -fake-name PublicParametersManager . PublicParametersManager - -type PublicParametersManager interface { - GraphHiding() bool -} - -type TokenChaincode struct { - initOnce sync.Once - LogLevel string - Validator Validator - PublicParametersManager PublicParametersManager - - PPDigest []byte - TokenServicesFactory func([]byte) (PublicParametersManager, Validator, error) - - MetricsEnabled bool - MetricsServer string - MetricsLock sync.Mutex - MetricsAgent Agent -} - -func (cc *TokenChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { - logger.Infof("init token chaincode...") - - ppRaw, err := cc.Params(Params) - if err != nil { - return shim.Error(fmt.Sprintf("failed to get public parameters: %s", err)) - } - - w := translator.New("", &rwsWrapper{stub: stub}, "") - if err := w.Write(&SetupAction{SetupParameters: ppRaw}); err != nil { - return shim.Error(err.Error()) - } - - return shim.Success(nil) -} - -func (cc *TokenChaincode) Invoke(stub shim.ChaincodeStubInterface) (res pb.Response) { - defer func() { - if r := recover(); r != nil { - logger.Errorf("invoke triggered panic: %s\n%s\n", r, debug.Stack()) - res = shim.Error(fmt.Sprintf("failed responding [%s]", r)) - } else { - logger.Infof("execution terminated with status [%d]", res.Status) - } - }() - - args := stub.GetArgs() - switch l := len(args); l { - case 0: - return shim.Error("missing parameters") - default: - agent, err := cc.NewMetricsAgent(string(args[0])) - if err != nil { - return shim.Error(err.Error()) - } - agent.EmitKey(0, "tcc", "start", "TokenChaincodeInvoke"+string(args[0]), stub.GetTxID()) - defer agent.EmitKey(0, "tcc", "end", "TokenChaincodeInvoke"+string(args[0]), stub.GetTxID()) - - logger.Infof("running function [%s]", string(args[0])) - switch f := string(args[0]); f { - case InvokeFunction: - if len(args) != 1 { - return shim.Error("empty token request") - } - // extract token request from transient - t, err := stub.GetTransient() - if err != nil { - return shim.Error("failed getting transient") - } - tokenRequest, ok := t["token_request"] - if !ok { - return shim.Error("failed getting token request, entry not found") - } - return cc.ProcessRequest(tokenRequest, stub) - case QueryPublicParamsFunction: - return cc.QueryPublicParams(stub) - case QueryTokensFunctions: - if len(args) != 2 { - return shim.Error("request to retrieve tokens is empty") - } - return cc.QueryTokens(args[1], stub) - case AreTokensSpent: - if len(args) != 2 { - return shim.Error("request to check if tokens are spent is empty") - } - return cc.AreTokensSpent(args[1], stub) - default: - return shim.Error(fmt.Sprintf("function not [%s] recognized", f)) - } - } -} - -func (cc *TokenChaincode) Params(builtInParams string) ([]byte, error) { - params := cc.ReadParamsFromFile() - if params == "" { - if len(builtInParams) == 0 { - return nil, errors.New("no params provided") - } else { - params = builtInParams - } - } - - ppRaw, err := base64.StdEncoding.DecodeString(params) - if err != nil { - return nil, errors.WithMessagef(err, "failed decoding params [%s]", params) - } - - return ppRaw, nil -} - -func (cc *TokenChaincode) GetValidator(builtInParams string) (Validator, error) { - var firstInitError error - cc.initOnce.Do(func() { - if err := cc.Initialize(builtInParams); err != nil { - firstInitError = err - } - }) - - if firstInitError != nil { - return nil, firstInitError - } - return cc.Validator, nil -} - -func (cc *TokenChaincode) Initialize(builtInParams string) error { - logger.Infof("reading public parameters...") - - ppRaw, err := cc.Params(builtInParams) - if err != nil { - return errors.WithMessagef(err, "failed reading public parameters") - } - - logger.Infof("instantiate public parameter manager and validator...") - ppm, validator, err := cc.TokenServicesFactory(ppRaw) - logger.Infof("instantiate public parameter manager and validator done with err [%v]", err) - if err != nil { - return errors.Wrap(err, "failed to instantiate public parameter manager and validator") - } - cc.PublicParametersManager = ppm - cc.Validator = validator - - return nil -} - -func (cc *TokenChaincode) ReadParamsFromFile() string { - publicParamsPath := os.Getenv(PublicParamsPathVarEnv) - if publicParamsPath == "" { - fmt.Println("no PUBLIC_PARAMS_FILE_PATH provided") - return "" - } - - fmt.Println("reading " + publicParamsPath + " ...") - paramsAsBytes, err := ioutil.ReadFile(publicParamsPath) - if err != nil { - fmt.Printf( - "unable to read file %s (%s). continue looking pub params from init args or cc\n", publicParamsPath, err.Error(), - ) - return "" - } - - return base64.StdEncoding.EncodeToString(paramsAsBytes) -} - -func (cc *TokenChaincode) ProcessRequest(raw []byte, stub shim.ChaincodeStubInterface) pb.Response { - cc.MetricsAgent.EmitKey(0, "tcc", "start", "TokenChaincodeProcessRequestGetValidator", stub.GetTxID()) - validator, err := cc.GetValidator(Params) - cc.MetricsAgent.EmitKey(0, "tcc", "end", "TokenChaincodeProcessRequestGetValidator", stub.GetTxID()) - if err != nil { - return shim.Error(err.Error()) - } - - // Verify - cc.MetricsAgent.EmitKey(0, "tcc", "start", "TokenChaincodeProcessRequestUnmarshallAndVerify", stub.GetTxID()) - actions, err := validator.UnmarshallAndVerify(stub, stub.GetTxID(), raw) - if err != nil { - return shim.Error("failed to verify token request: " + err.Error()) - } - cc.MetricsAgent.EmitKey(0, "tcc", "end", "TokenChaincodeProcessRequestUnmarshallAndVerify", stub.GetTxID()) - - // Write - cc.MetricsAgent.EmitKey(0, "tcc", "start", "TokenChaincodeProcessRequestWrite", stub.GetTxID()) - - w := translator.New(stub.GetTxID(), &rwsWrapper{stub: stub}, "") - for _, action := range actions { - err = w.Write(action) - if err != nil { - return shim.Error("failed to write token action: " + err.Error()) - } - } - err = w.CommitTokenRequest(raw, false) - if err != nil { - return shim.Error("failed to write token request:" + err.Error()) - } - cc.MetricsAgent.EmitKey(0, "tcc", "end", "TokenChaincodeProcessRequest", stub.GetTxID()) - - return shim.Success(nil) -} - -func (cc *TokenChaincode) QueryPublicParams(stub shim.ChaincodeStubInterface) pb.Response { - w := translator.New(stub.GetTxID(), &rwsWrapper{stub: stub}, "") - raw, err := w.ReadSetupParameters() - if err != nil { - shim.Error("failed to retrieve public parameters: " + err.Error()) - } - if len(raw) == 0 { - return shim.Error("need to initialize public parameters") - } - return shim.Success(raw) -} - -func (cc *TokenChaincode) QueryTokens(idsRaw []byte, stub shim.ChaincodeStubInterface) pb.Response { - var ids []*token2.ID - if err := json.Unmarshal(idsRaw, &ids); err != nil { - logger.Errorf("failed unmarshalling tokens ids: [%s]", err) - return shim.Error(err.Error()) - } - - logger.Debugf("query tokens [%v]...", ids) - - w := translator.New(stub.GetTxID(), &rwsWrapper{stub: stub}, "") - res, err := w.QueryTokens(ids) - if err != nil { - logger.Errorf("failed query tokens [%v]: [%s]", ids, err) - return shim.Error(fmt.Sprintf("failed query tokens [%v]: [%s]", ids, err)) - } - raw, err := json.Marshal(res) - if err != nil { - logger.Errorf("failed marshalling tokens: [%s]", err) - return shim.Error(fmt.Sprintf("failed marshalling tokens: [%s]", err)) - } - return shim.Success(raw) -} - -func (cc *TokenChaincode) AreTokensSpent(idsRaw []byte, stub shim.ChaincodeStubInterface) pb.Response { - _, err := cc.GetValidator(Params) - if err != nil { - return shim.Error(err.Error()) - } - - var ids []string - if err := json.Unmarshal(idsRaw, &ids); err != nil { - logger.Errorf("failed unmarshalling tokens ids: [%s]", err) - return shim.Error(err.Error()) - } - - logger.Debugf("check if tokens are spent [%v]...", ids) - - w := translator.New(stub.GetTxID(), &rwsWrapper{stub: stub}, "") - res, err := w.AreTokensSpent(ids, cc.PublicParametersManager.GraphHiding()) - if err != nil { - logger.Errorf("failed to check if tokens are spent [%v]: [%s]", ids, err) - return shim.Error(fmt.Sprintf("failed to check if tokens are spent [%v]: [%s]", ids, err)) - } - raw, err := json.Marshal(res) - if err != nil { - logger.Errorf("failed marshalling spent flags: [%s]", err) - return shim.Error(fmt.Sprintf("failed marshalling spent flags: [%s]", err)) - } - return shim.Success(raw) -} - -func (cc *TokenChaincode) NewMetricsAgent(id string) (Agent, error) { - cc.MetricsLock.Lock() - defer cc.MetricsLock.Unlock() - - if cc.MetricsAgent != nil { - return cc.MetricsAgent, nil - } - - if !cc.MetricsEnabled { - cc.MetricsAgent = metrics.NewNullAgent() - return cc.MetricsAgent, nil - } - - var err error - cc.MetricsAgent, err = metrics.NewStatsdAgent( - tracing.Host(id), - tracing.StatsDSink(cc.MetricsServer), - ) - if err != nil { - return nil, err - } - return cc.MetricsAgent, nil -} diff --git a/fungible/cc/vendor/github.com/ipfs/go-cid/README.md b/fungible/cc/vendor/github.com/ipfs/go-cid/README.md index 4f54343a..89da0412 100644 --- a/fungible/cc/vendor/github.com/ipfs/go-cid/README.md +++ b/fungible/cc/vendor/github.com/ipfs/go-cid/README.md @@ -59,10 +59,17 @@ fmt.Println("Got CID: ", c) #### Creating a CID from scratch ```go + +import ( + cid "github.com/ipfs/go-cid" + mc "github.com/multiformats/go-multicodec" + mh "github.com/multiformats/go-multihash" +) + // Create a cid manually by specifying the 'prefix' parameters pref := cid.Prefix{ Version: 1, - Codec: cid.Raw, + Codec: mc.Raw, MhType: mh.SHA2_256, MhLength: -1, // default length } diff --git a/fungible/cc/vendor/github.com/ipfs/go-cid/cid.go b/fungible/cc/vendor/github.com/ipfs/go-cid/cid.go index dc807500..651c94df 100644 --- a/fungible/cc/vendor/github.com/ipfs/go-cid/cid.go +++ b/fungible/cc/vendor/github.com/ipfs/go-cid/cid.go @@ -10,7 +10,7 @@ // // A CIDv1 has four parts: // -// ::= +// ::= // // As shown above, the CID implementation relies heavily on Multiformats, // particularly Multibase @@ -22,6 +22,7 @@ package cid import ( "bytes" "encoding" + "encoding/binary" "encoding/json" "errors" "fmt" @@ -46,19 +47,21 @@ var ( ErrInvalidEncoding = errors.New("invalid base encoding") ) -// These are multicodec-packed content types. The should match -// the codes described in the authoritative document: -// https://github.com/multiformats/multicodec/blob/master/table.csv +// Consts below are DEPRECATED and left only for legacy reasons: +// +// Modern code should use consts from go-multicodec instead: +// const ( - Raw = 0x55 - - DagProtobuf = 0x70 - DagCBOR = 0x71 - Libp2pKey = 0x72 - - GitRaw = 0x78 - - DagJOSE = 0x85 + // common ones + Raw = 0x55 + DagProtobuf = 0x70 // https://ipld.io/docs/codecs/known/dag-pb/ + DagCBOR = 0x71 // https://ipld.io/docs/codecs/known/dag-cbor/ + DagJSON = 0x0129 // https://ipld.io/docs/codecs/known/dag-json/ + Libp2pKey = 0x72 // https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#peer-ids + + // other + GitRaw = 0x78 + DagJOSE = 0x85 // https://ipld.io/specs/codecs/dag-jose/spec/ EthBlock = 0x90 EthBlockList = 0x91 EthTxTrie = 0x92 @@ -80,64 +83,6 @@ const ( FilCommitmentSealed = 0xf102 ) -// Codecs maps the name of a codec to its type -var Codecs = map[string]uint64{ - "v0": DagProtobuf, - "raw": Raw, - "protobuf": DagProtobuf, - "cbor": DagCBOR, - "libp2p-key": Libp2pKey, - "git-raw": GitRaw, - "eth-block": EthBlock, - "eth-block-list": EthBlockList, - "eth-tx-trie": EthTxTrie, - "eth-tx": EthTx, - "eth-tx-receipt-trie": EthTxReceiptTrie, - "eth-tx-receipt": EthTxReceipt, - "eth-state-trie": EthStateTrie, - "eth-account-snapshot": EthAccountSnapshot, - "eth-storage-trie": EthStorageTrie, - "bitcoin-block": BitcoinBlock, - "bitcoin-tx": BitcoinTx, - "zcash-block": ZcashBlock, - "zcash-tx": ZcashTx, - "decred-block": DecredBlock, - "decred-tx": DecredTx, - "dash-block": DashBlock, - "dash-tx": DashTx, - "fil-commitment-unsealed": FilCommitmentUnsealed, - "fil-commitment-sealed": FilCommitmentSealed, - "dag-jose": DagJOSE, -} - -// CodecToStr maps the numeric codec to its name -var CodecToStr = map[uint64]string{ - Raw: "raw", - DagProtobuf: "protobuf", - DagCBOR: "cbor", - GitRaw: "git-raw", - EthBlock: "eth-block", - EthBlockList: "eth-block-list", - EthTxTrie: "eth-tx-trie", - EthTx: "eth-tx", - EthTxReceiptTrie: "eth-tx-receipt-trie", - EthTxReceipt: "eth-tx-receipt", - EthStateTrie: "eth-state-trie", - EthAccountSnapshot: "eth-account-snapshot", - EthStorageTrie: "eth-storage-trie", - BitcoinBlock: "bitcoin-block", - BitcoinTx: "bitcoin-tx", - ZcashBlock: "zcash-block", - ZcashTx: "zcash-tx", - DecredBlock: "decred-block", - DecredTx: "decred-tx", - DashBlock: "dash-block", - DashTx: "dash-tx", - FilCommitmentUnsealed: "fil-commitment-unsealed", - FilCommitmentSealed: "fil-commitment-sealed", - DagJOSE: "dag-jose", -} - // tryNewCidV0 tries to convert a multihash into a CIDv0 CID and returns an // error on failure. func tryNewCidV0(mhash mh.Multihash) (Cid, error) { @@ -173,16 +118,24 @@ func NewCidV0(mhash mh.Multihash) Cid { // Panics if the multihash is invalid. func NewCidV1(codecType uint64, mhash mh.Multihash) Cid { hashlen := len(mhash) - // two 8 bytes (max) numbers plus hash - buf := make([]byte, 1+varint.UvarintSize(codecType)+hashlen) - n := varint.PutUvarint(buf, 1) - n += varint.PutUvarint(buf[n:], codecType) - cn := copy(buf[n:], mhash) + + // Two 8 bytes (max) numbers plus hash. + // We use strings.Builder to only allocate once. + var b strings.Builder + b.Grow(1 + varint.UvarintSize(codecType) + hashlen) + + b.WriteByte(1) + + var buf [binary.MaxVarintLen64]byte + n := varint.PutUvarint(buf[:], codecType) + b.Write(buf[:n]) + + cn, _ := b.Write(mhash) if cn != hashlen { panic("copy hash length is inconsistent") } - return Cid{string(buf[:n+hashlen])} + return Cid{b.String()} } var ( @@ -228,10 +181,19 @@ func Parse(v interface{}) (Cid, error) { } } +// MustParse calls Parse but will panic on error. +func MustParse(v interface{}) Cid { + c, err := Parse(v) + if err != nil { + panic(err) + } + return c +} + // Decode parses a Cid-encoded string and returns a Cid object. // For CidV1, a Cid-encoded string is primarily a multibase string: // -// +// // // The base-encoded string represents a: // @@ -287,7 +249,7 @@ func ExtractEncoding(v string) (mbase.Encoding, error) { // Cast takes a Cid data slice, parses it and returns a Cid. // For CidV1, the data buffer is in the form: // -// +// // // CidV0 are also supported. In particular, data buffers starting // with length 34 bytes, which starts with bytes [18,32...] are considered @@ -416,7 +378,13 @@ func (c Cid) Hash() mh.Multihash { // Bytes returns the byte representation of a Cid. // The output of bytes can be parsed back into a Cid // with Cast(). +// +// If c.Defined() == false, it return a nil slice and may not +// be parsable with Cast(). func (c Cid) Bytes() []byte { + if !c.Defined() { + return nil + } return []byte(c.str) } @@ -497,7 +465,7 @@ func (c *Cid) UnmarshalJSON(b []byte) error { // MarshalJSON procudes a JSON representation of a Cid, which looks as follows: // -// { "/": "" } +// { "/": "" } // // Note that this formatting comes from the IPLD specification // (https://github.com/ipld/specs/tree/master/ipld) @@ -554,7 +522,8 @@ func (c Cid) Prefix() Prefix { // and the Multihash length. It does not contains // any actual content information. // NOTE: The use -1 in MhLength to mean default length is deprecated, -// use the V0Builder or V1Builder structures instead +// +// use the V0Builder or V1Builder structures instead type Prefix struct { Version uint64 Codec uint64 @@ -593,7 +562,7 @@ func (p Prefix) Sum(data []byte) (Cid, error) { // Bytes returns a byte representation of a Prefix. It looks like: // -// +// func (p Prefix) Bytes() []byte { size := varint.UvarintSize(p.Version) size += varint.UvarintSize(p.Codec) diff --git a/fungible/cc/vendor/github.com/ipfs/go-cid/cid_fuzz.go b/fungible/cc/vendor/github.com/ipfs/go-cid/cid_fuzz.go index 0bdd7e67..af1ab46b 100644 --- a/fungible/cc/vendor/github.com/ipfs/go-cid/cid_fuzz.go +++ b/fungible/cc/vendor/github.com/ipfs/go-cid/cid_fuzz.go @@ -1,4 +1,4 @@ -// +build gofuzz +//go:build gofuzz package cid diff --git a/fungible/cc/vendor/github.com/ipfs/go-cid/version.json b/fungible/cc/vendor/github.com/ipfs/go-cid/version.json new file mode 100644 index 00000000..908483a3 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipfs/go-cid/version.json @@ -0,0 +1,3 @@ +{ + "version": "v0.3.2" +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/.gitattributes b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/.gitattributes new file mode 100644 index 00000000..8f94f9de --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/.gitattributes @@ -0,0 +1 @@ +**/testdata/fuzz/** binary diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/.gitmodules b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/.gitmodules new file mode 100644 index 00000000..c42608b8 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".ipld"] + path = .ipld + url = https://github.com/ipld/ipld/ diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/CHANGELOG.md b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/CHANGELOG.md index e5344155..c855f134 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/CHANGELOG.md +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/CHANGELOG.md @@ -11,7 +11,6 @@ Much of this code is used in other libraries and products, and we do take some c (If you're ever wondering about stability of a feature, ask -- or contribute more tests ;)) - [Planned/Upcoming Changes](#planned-upcoming-changes) -- [Changes on master branch but not yet Released](#unreleased-on-master) - [Released Changes Log](#released-changes) @@ -20,34 +19,491 @@ Planned/Upcoming Changes Here are some outlines of changes we intend to make that affect the public API: -- ... the critical list is empty, for now :) +- **IPLD Amend**: is likely to land soon; it implements a more efficient underlying architecture to support IPLD Patch and related features. IPLD Amend adds an interface to allow incremental changes to `Node`s in an efficient way. Whereas IPLD Patch is a protocol for expressing changes. We're still working on figuring out exactly where it fits in the stack and making sure it won't be disruptive but early benchmarks are very promising for both Patch and traversal-based transforms. See https://github.com/ipld/go-ipld-prime/pull/445 for more. +- **Layered `Node` implementation optimizations**: When layering different implementations of `Node` builders or consumers, having to defer through basicnode types can lead to large inefficiencies of memory and speed. We are looking at ways to improve this situation, including ways to *assemble* layered assemblers. See https://github.com/ipld/go-ipld-prime/issues/443 for discussion and some initial plans. +- **Selectors**: There have been some recurring wishes to do something about the Selector package layout. There's no intended or prioritized date for this. See https://github.com/ipld/go-ipld-prime/issues/236 for more. +- **Absent / "Not found" values**: There may be some upcoming changes to exactly how "not found" values are handled in order to clarify and standardize the subject. There's no finalized date for this. See https://github.com/ipld/go-ipld-prime/issues/360 for more. -This is not an exhaustive list of planned changes, and does not include any internal changes, new features, performance improvements, and so forth. -It's purely a list of things you might want to know about as a downstream consumer planning your update cycles. +Released Changes +---------------- -We will make these changes "soon" (for some definition of "soon"). -They are currently not written on the master branch. -The definition of "soon" may vary, in service of a goal to sequence any public API changes in a way that's smooth to migrate over, and make those changes appear at an overall bearable chronological frequency. -Tagged releases will be made when any of these changes land, so you can upgrade intentionally. +### v0.19.0 +_2022 October 13_ -Unreleased on master --------------------- +go-ipld-prime's release policy says that: -Changes here are on the master branch, but not in any tagged release yet. -When a release tag is made, this block of bullet points will just slide down to the [Released Changes](#released-changes) section. +> even numbers should be easy upgrades; odd numbers may change things -- _nothing yet :)_ +The major change in this release is a bump to Go 1.18, and as such we're suggesting this should be an "easy upgrade". + +#### 馃洜 Breaking Changes + +Update go.mod to Go 1.18. + +#### 馃敠 Highlights + +* **Codecs**: [Correct JSON codec Bytes handling](https://github.com/ipld/go-ipld-prime/pull/472). This change does not impact DAG-JSON, which is the generally recommended codec for JSON output as the JSON codec cannot properly handle Bytes or Links. +* **Dependencies**: + * Update to go-multihash@v0.2.1: https://github.com/multiformats/go-multihash/releases/tag/v0.2.1 + * Update to go-multicodec@v0.6.0: https://github.com/multiformats/go-multicodec/releases/tag/v0.6.0 + * Update to go-cid@v0.3.2: https://github.com/ipfs/go-cid/compare/v0.2.0...v0.3.2 + +### v0.18.0 + +_2022 August 01_ + +go-ipld-prime's release policy says that: + +> even numbers should be easy upgrades; odd numbers may change things + +So, as an even number, this v0.18.0 release should be a smooth ride for upgraders from v0.17.0. We have 3 major feature additions, all focused on [Bindnode](https://pkg.go.dev/github.com/ipld/go-ipld-prime/node/bindnode). + +#### 馃敠 Highlights + +* **Bindnode**: [Custom Go type converters](https://github.com/ipld/go-ipld-prime/pull/414) - Bindnode performs bidirectional mapping of Go types to the IPLD Data Model, and in doing so, it assumes a straightforward mapping of values to their encoded forms. But there are common cases where a Go type doesn't have a straightforward path to serialization, either because the encoded form needs a custom layout, or because bindnode doesn't have enough information to infer a serialization pattern. Custom Go type converters for bindnode allow a user to supply a pair of converter functions for a Go type that dictate how to map that type to an IPLD Data Model kind. See the **[bindnode documentation](https://pkg.go.dev/github.com/ipld/go-ipld-prime/node/bindnode)** for more information. +* **Bindnode**: [Type registry](https://github.com/ipld/go-ipld-prime/pull/437) - Setting up Go type mappings with Bindnode involves some boilerplate. A basic type registry is now available that takes some of this boilerplate away; giving you a single place to register, and perform conversions to and from Go types, Data Model (`Node`) forms or directly through serialization. See the **[bindnode/registry documentation](https://pkg.go.dev/github.com/ipld/go-ipld-prime/node/bindnode/registry)** for more information. +* **Bindnode** [Full `uint64` support](https://github.com/ipld/go-ipld-prime/pull/414/commits/87211682cb963ef1c98fa63909f67a8b02d1108c) - the `uint64` support introduced in go-ipld-prime@v0.17.0 has been wired into Bindnode. The Data Model (`Node`) forms expose integers as `int64` values, which is lossy for unsigned 64-bit integers. Bindnode Go types using `uint64` values are now lossless in round-trips through serialization to codecs that support the full range (DAG-CBOR most notably). + +You can see all of these new features in action using Filecoin Go types, allowing a mapping between Go types, Data Model (`Node`) forms, and their DAG-CBOR serialized forms with [data-transfer vouchers](https://github.com/filecoin-project/go-fil-markets/pull/713). These features also allow us to interact with the original Go types, without modification, including `big.Int` serialization to `Bytes`, Filecoin `Signature` serialization to a byte-prefix discriminated `Bytes` and more. Since the Go types are unchanged, they can also simultaneously support [cbor-gen](https://github.com/whyrusleeping/cbor-gen) serialization, allowing an easier migration path. + +### v0.17.0 + +_2022 Jun 15_ + +go-ipld-prime's release policy says that: + +> even numbers should be easy upgrades; odd numbers may change things + +In that spirit, this v0.17.0 release includes some potentially breaking changes. Although minor, they are marked below and they may lead to behavioral changes in your use of this library. + +#### 馃洜 Breaking Changes + +* **Codecs**: + * DAG-CBOR, DAG-JSON: [Error on `cid.Undef` links in dag{json,cbor} encoding](https://github.com/ipld/go-ipld-prime/pull/433) - previously, encoding Link nodes that were empty CIDs (uninitialized zero-value or explicitly `cid.Undef`) would have passed through the DAG-CBOR or DAG-JSON codecs, silently producing erroneous output that wouldn't successfully pass back through a decode. (Rod Vagg) +* **Bindnode**: + * [Panic early if API has been passed ptr-to-ptr](https://github.com/ipld/go-ipld-prime/pull/427) - previous usage of bindnode using pointers-to-pointers may have deferred (or in some cases avoided) panics until deeper usage of the API, this change makes it earlier to make it clear that pointer-to-pointer is not appropriate usage. (Rod Vagg) +* **Build**: + * [Drop Go 1.16.x testing & begin testing Go 1.18.x](https://github.com/ipld/go-ipld-prime/pull/394) (Daniel Mart铆) + * Note also that in this release, the [github.com/ipfs/**go-cid**](https://github.com/ipfs/go-cid) dependency is upgraded from 0.0.4 to 0.2.0 which includes a breaking change with the removal of the `cid.Codecs` and `cid.CodecToStr` maps which may disruptive. See [the go-cid@0.2.0 release page for details](https://github.com/ipfs/go-cid/releases/tag/v0.2.0). + +#### 馃敠 Highlights + +* **Data Model**: + * [Introduce `UIntNode` interface, used within DAG-CBOR codec to quietly support full uint64 range](https://github.com/ipld/go-ipld-prime/pull/413) (Rod Vagg) +* **Bindnode**: + * Fuzzing and hardening for production use (Daniel Mart铆) + * Refuse to decode empty union values (Daniel Mart铆) + * [Allow nilable types for IPLD `optional`/`nullable`](https://github.com/ipld/go-ipld-prime/pull/401) (Daniel Mart铆) + * [More helpful error message for common enum value footgun](https://github.com/ipld/go-ipld-prime/pull/430) (Rod Vagg) + * [Infer links and `Any` from Go types](https://github.com/ipld/go-ipld-prime/pull/432) (Rod Vagg) +* **Schemas**: + * DMT: Proper checking for unknown union members (Daniel Mart铆) + * DMT: Enum representations must be valid members (Daniel Mart铆) + * DMT: Reject duplicate or missing union representation members (Daniel Mart铆) + * DSL: [Support `stringjoin` struct representation and `stringprefix` union representation](https://github.com/ipld/go-ipld-prime/pull/397) (Eric Evenchick) + * DMT, DSL: [Enable inline types](https://github.com/ipld/go-ipld-prime/pull/404) (Rod Vagg) +* **Patch**: + * [Add initial version of IPLD Patch feature](https://github.com/ipld/go-ipld-prime/pull/350) (Eric Myhre) *(helped across the line by mauve and Rod Vagg)* +* **Codecs**: + * DAG-CBOR: [Reject extraneous content after valid (complete) CBOR object](https://github.com/ipld/go-ipld-prime/pull/386) (Rod Vagg) + * DAG-CBOR: [add `DecodeOptions.ExperimentalDeterminism`](https://github.com/ipld/go-ipld-prime/pull/390) (currently only checking map sorting order) (Daniel Mart铆) + * Printer: [Fix printing of floats](https://github.com/ipld/go-ipld-prime/pull/412) (Dustin Long) + * DAG-JSON: [Add option to not parse beyond end of structure](https://github.com/ipld/go-ipld-prime/pull/435) (Petar Maymounkov) +* **Build**: + * Fix [macOS](https://github.com/ipld/go-ipld-prime/pull/400) and [Windows](https://github.com/ipld/go-ipld-prime/pull/405) testing (Rod Vagg) + * [Fix 32-bit build support](https://github.com/ipld/go-ipld-prime/pull/407) (Rod Vagg) + * [Make staticcheck and govet happy across codebase](https://github.com/ipld/go-ipld-prime/pull/406) (Rod Vagg) + * Enable full [unified-ci](https://github.com/protocol/.github) GitHub Actions suite, including auto-updating (Rod Vagg) + * [Enable dependabot, with monthly checks](https://github.com/ipld/go-ipld-prime/pull/417) (and update all dependencies) (Rod Vagg) + +Special thanks to **Daniel Mart铆** for many bindnode improvements and hardening, fuzzing across the library and improvements to the Schema DMT and DSL. + +### v0.16.0 + +_2022 March 09_ + +- New: `traversal.WalkTransforming` is finally implemented! (It's been a stub for quite a while.) This works similarly to the other transform features, but can do more than change to the structure during a single walk. +- New: Selectors support partial/ranged match on bytes or strings nodes. (This is also a new feature for Selectors, recently specified.) + [[#375](https://github.com/ipld/go-ipld-prime/pull/375); seealso specs in [ipld#184](https://github.com/ipld/ipld/pull/184)] +- New: there's a `datamodel.LargeBytesNode` interface, which makes it possible to handle "large" blobs of bytes as a `Node`, without necessarily forcing them all into memory at once. (This is optional; you add the methods to match the interface if your Node implementation supports the feature.) + [[#372](https://github.com/ipld/go-ipld-prime/pull/372)] + - Slightly more specifically: this interface is `Node` plus a method that returns an `io.ReadSeeker`. (Pretty standard golang I/O and byte slice management concepts should carry you from there in the usual ways.) + - This is a **really big deal** -- for example, this means that an [ADL](https://ipld.io/docs/advanced-data-layouts/) can support reading of arbitrarily large bytes without an issue. (Hello, transparently readable large sharded blobs!) +- New: there's a "resume" (or, skipahead) mechanism for traversals and selectors. Engage it by simply setting the `traversal.Config.StartAtPath` field. + [[#358](https://github.com/ipld/go-ipld-prime/pull/358)] +- New: `dagcbor` now has a `EncodedLength(Node) int` function, which can calculate the expected serial message length without actually encoding. (The usefulness of this may be situational, but it's there if you want it.) +- Improved: `bindnode`, yet again, in more ways that can easily be summarized. + - Better support for pointers in more places in your golang types. + - Many panics either fixed or routed into calmer errors. + - Unsigned intergers are now supported in your golang types. + - Some fixes for AssignNode working correctly (e.g. at the type or representation level, as appropriate; sometimes previously it would use the type level incorrectly). + - Various fixes to handling absent fields correctly. + - A `datamodel.Node` can now be used for an `any` field. +- Fixed: selectors now behave correctly for a recursion clause that just contains a recursion edge immedately. (It's still not a sensible selector, really, but it's valid.) Previously this would panic, which was nasty. +- Fixed: `bindnode` now correctly doesn't include absent fields in the count of length when looking at the representation-level view of structs. +- Improved: all our batteries-included codecs double check while encoding that the number iterator steps over a map matches its self-reported length. (This doesn't matter in many cases, but does defend you a little better against a `Node` implementation with a bug, if you happen to be so unlucky.) +- Improved: miscellaneous performance work in the `schema/*` area. + +Thank you to @mvdan, @warpfork, @hannahhoward, @rvagg, @willscott, @arajasek and others +for all their work that went into making this release (as well as all the point releases in v0.14.x leading up to it) happen. + +Finally, please note that we're starting to try out some new (and slightly more formal) governance and review and merge processes. +Check out https://github.com/ipld/go-ipld-prime/issues/370 for more information. +The aim is to make things generally more inclusive and involve more contributors! +This is still experimental and may be subject to change, but if you'd like to have better expectations about who can review and what the process should be like, we hope this will be a step in a helpful direction. +(Feedback about this experiment welcome!) + + +### v0.14.x + +(There were releases `v0.14.1`, `v0.14.2`, `v0.14.3`, and `v0.14.4` -- but all were in rapid succession, very minor, and hitting the same areas; we'll keep the notes brief and condensed.) + +- New: Selectors can include clauses for signalling the use of ADLs! + [[#301](https://github.com/ipld/go-ipld-prime/pull/301); seealso specs in [ipld#149](https://github.com/ipld/ipld/pull/149)+[ipld#170](https://github.com/ipld/ipld/pull/170)] + - Also kindly note that there are expected to be many ways of signalling ADL invocations -- this is only one of them. + See the IPLD website for more on this topic as a whole: https://ipld.io/docs/advanced-data-layouts/signalling/ +- Improved: `bindnode`, in ways more various than can easily be summarized. + - The `cidlink.Link` type can be bound to links in the data. + - Enums are now supported. + - The `any` typekind is now supported. +- Improved: both the `schema/dmt` and `schema/dsl` packages (and in some cases, the `schema` package itself) continue to be improved and become more complete. + - Structs with tuple representation are now supported. + - Enums with int representation are now supported. + - The `any` typekind is now supported. +- Changed: the dag-json codec will tolerate padded base64 in bytes content upon read. It does so silently. (It is not still possible to emit this kind of serial data with this library; it is noncanonical.) + [[#309](https://github.com/ipld/go-ipld-prime/pull/309)] +- Changed: the cbor and dag-cbor codec will now tolerate CBOR's "undef" token. It will coerce it to a null token when reading. Previously, encountering the undef token would result in a parse error. (It is still not possible to emit this token with this library.) + [[#308](https://github.com/ipld/go-ipld-prime/pull/308)] +- New: the `traversal` package gained a `WalkLocal` function. This simply does a walk that does not cross any links. + + +### v0.14.0 + +_2021 November 11_ + +This release is a smooth-sailing release, and mostly contains new features, quality-of-life improvements, +and some significant improvements to the completeness and usability of features that have been in development across previous releases. +There shouldn't be a lot of surprises, and upgrading should be easy. + +Some of the biggest improvements include: `bindnode` now supports most IPLD features and is increasingly stable; +the `schema` system now has functioning `schema/dmt` and `schema/dsl` packages, and can parse schema documents smoothly(!); +if you haven't seen the `printer` package that first quietly appeared in `v0.12.2`, you should definitely check it out now; +and we have some new `storage` APIs that might be worth checking out, too. +There are also many, many other smaller improvements. + +See the complete list and further deatils below +(and don't forget to check out the notes under the other `v0.12.*` headings, if you haven't absorbed those updates already, too!): + +- New: `datamodel.Copy`: a helper function to do a shallow copy from one node to another. + - You don't often need this, because nodes are supposed to be immutable! + But it still sometimes comes in handy, for example, if you want to change the memory layout you're using by moving data into a different node implementation. +- Improved: documentation of APIs. (Especially, for subtler bits like `NodeAssembler.AssignNode`.) +- New: `datamodel.Link` now requires a `Binary()` function. In contrast to `Link.String()` (which is supposed to return something printable), `Link.Binary()` should give you the rawest thing possible. (It's equivalent to `go-cid.CID.KeyString`.) +- New: **a new storage API**, including one **batteries-included** filesystem storage implementation, and **adapters** to several other different storage APIs. [[#265](https://github.com/ipld/go-ipld-prime/pull/265), [#279](https://github.com/ipld/go-ipld-prime/pull/279)] + - The primary goal of this is the "batteries included" part: using the new `storage/fsstore` package, you should now be able to make simple applications with IPLD and use a simple sharded disk storage system (it'll look vaguely like a `.git/objects` directory), and do it in about five minutes and without pulling in any additional complex dependencies. + - If you want to develop new storage systems or make adapters to them: the APIs in `storage` package are designed to be implemented easily. + - The `storage` APIs are designed entirely around types found in the golang standard library. You do not need to import anything in the `storage` package in order to implement its interfaces! + - The minimal APIs that a storage system has to implement are _very_ small. Two functions. Every additional feature, or optimization that you can offer: those all have their own interfaces, and we use feature-detection on them. You can implement as much or as little as you like. + - As a user of the storage APIs: use the functions in the `storage` package. Those functions take a storage system as a parameter, and will do feature detection _for you_. + - This means you can always write your code to call the APIs you _want_, and the `storage` functions will figure out how to map it onto the storage system that you _have_ (whatever it supports) in the most efficient way it can. + - As a user of the `LinkSystem` API: you can ignore most of this! If you want to use the new `storage` APIs, there are setup methods on `LinkSystem` that will take them as a parameter. If you have existing code wired up with the previous APIs, it still works too. + - As someone who already has code and wonders how to migrate: + - If you're using the `linking.Storage*Opener` API: you don't have to do anything. Those still work too. + - If you were using code from other repos like `ipfs/go-ipfs-blockstore` or `ipfs/go-datastore` or so on: those have adapters now in the `storage/*adapter` packages! You should now be able to use those more easily, with less custom glue code. (There's also now a migration readme in the repo root: check that out.) + - If you would like to ask: "is it fast?" -- yes. You'll find that the new `storage/fsstore`, our batteries-included filesystem storage system, is comparable (or beating) the `go-ds-flatfs` package that you may have been using in the past. (More benchmarks and any performance improvement patches will of course be welcome -- but at the very least, there's no reason to hold back on using the new system.) +- New: `LinkSystem` has some new methods: `LoadRaw` and `LoadPlusRaw` give you the ability to get data model nodes loaded, and _also_ receive the raw binary blobs. + - This can be useful if you're building an application that's piping data around to other serial APIs without necessarily transforming it. (No need to reserialize if that's your journey.) +- New: a CLI tool has begun development! + - ... and almost immediately been removed again, to live in its own repo: check out https://github.com/ipld/go-ipldtool . +- Improved: many more things about `bindnode`. + - `bindnode` now understands `go-cid.CID` fields. + - Kinded unions are much more completely supported. + - Many TODO panics have gone away, replaced by finished features. + - `bindnode` will increasingly check that the golang types you give it can be structurally matched to the schema if you provide one, which gives better errors earlier, and increases the ease and safety of use drastically. +- Improved: the `schema/dmt` and `schema/dsl` packages are increasingly complete. + - There are also now helper functions in the root package which will do the whole journey of "load a file, parse the Schema DSL, compile and typecheck the DMT, and give you the type info in handy golang interfaces", all at once! Check out `ipld.LoadSchema`! +- New: there is a codegen feature for `bindnode` which will produce very terse golang structs matching a schema and ready to be bound back to `bindnode`! + - This competes with the older `gengo` code generator -- by comparison, the `bindnode` code generator produces much, _much_ less code. (However, be advised that the performance characteristics are probably also markedly different; and we do not have sufficient benchmarks to comment on this at this time.) +- Internal: many tests are being ported to `quicktest`. There should be no external impact to this, but we look forward to removing some of the other test libraries from our dependency tree in the near future. +- Improved: `printer` now supports links and bytes! +- Improved: `printer` is now more resilient and works even on relatively misbehaved `Node` implementations, such as those which implement `schema.TypedNode` but then rudely and nonsensically return nil type info. (We don't expect all code to be resilient against misbehaved `Node` implementations... but for a debug tool in particular? It's good to have it handle as much as it can.) + + +This, and the last few releases tagged in the `v0.12.*` series, include invaluable contributions from +@mvdan, @warpfork, @rvagg, @willscott, @masih, @hannahhoward, @aschmahmann, @ribasushi, +and probably yet more others who have contributed through code and design reviews, +or by using these libraries and demanding they continue to become better. +Thanks to each and every one of the people who carry this project forward! + + +### v0.12.3 + +_2021 September 30_ + +(This is a minor release; we'll keep the notes brief.) + +- Fixed: using `SkipMe` in a traversal now skips only that subtree of nodes, not the remainder of the block! + [[#251](https://github.com/ipld/go-ipld-prime/pull/251)] +- New: `traversal` features now have budgets! You can set a "budget" value, and watch it monotonically decrement as your operations procede. This makes it easy to put limits on the amount of work you'll do. + [[#260](https://github.com/ipld/go-ipld-prime/pull/260)] +- New: `traversal` features can be configured to visit links they encounter only once (and ignore them if seen again). + [[#252](https://github.com/ipld/go-ipld-prime/pull/252)] + - Note that this is not without caveats: this is not merely an optimization; enabling it _may_ produce logically different outcomes, depending on what your selector is. + This is because links are ignored when seen again, even if they're seen for a different _reason_, via a different path, etc. +- Fixed: a very nasty off-by-one in unions produced by the "gogen" codegen. + [[#257](https://github.com/ipld/go-ipld-prime/pull/257)] +- Improved: the test suites for typed nodes now provide much better coverage (to prevent something like the above from happening again, even in other implementations). +- New: `schema/dsl`! This package contains parsers for the IPLD Schema DSL, and produces data structures in `schema/dmt` form. +- Removed: other misc partially-complete packages. (This will surely bother no one; it's just cleanup.) +- Removed: `codec/jst`. If you were using that, [`jst` has its own repo](https://github.com/warpfork/go-jst/) now. +- Improved: `traversal` now uses the error wrapping ("`%w`") feature in more places. +- Changed: `printer` keeps empty maps and lists and strings on a single line. +- Changed: `schema.TypeName` is now just an alias of `string`. This may result in somewhat less casting; or, you might not notice it. +- Improved: the `schema/dmt` package continues to be improved and become more complete. + - Some changes also track fixes in the schema spec, upstream. (Or caused those fixes!) +- New/Improved: the `schema` package describes several more things which it always should have. Enums, for example. + + + +### v0.12.2 + +_2021 September 8_ + +(This is a minor release; we'll keep the notes brief.) + +- New: the `printer` package has appeared, and aims to provide an information-rich, debug-readable, human-friendly output of data from an IPLD node tree. [[#238](https://github.com/ipld/go-ipld-prime/pull/238/)] + - This works for both plain data model data, and for typed data, and annotates type information if present. + - Note that this is _not_ a codec: it's specifically _richer_ than that. Conversely, this printer format is not designed to be parsed back to data model data. Use a codec for a codec's job; use the printer for debugging and inspection jobs. +- Fixed/Improved: more things about the `bindnode` system. (It's still early and improving fast.) +- Fixed: json codec, cbor codec, and their dag variants all now return ErrUnexpectedEOF in the conditions you'd expect. (Previously they sometimes just returned EOF, which could be surprising.) +- Changed/Improved: the `schema/dmt` package is now implemented using `bindnode`, and there's a more complete `Compile()` feature. (This is still very early, in this tag. More to come here soon.) + + + +### v0.12.1 + +_2021 August 30_ + +(This is a minor release; we'll keep the notes brief.) + +- Fixed/Improved: many things about the `bindnode` system. (It's still early and improving fast.) +- Changed: the strings for `schema.TypeKind_*` are lowercase. (The docs and specs all act this way, and always have; it was a strange error for this code to have titlecase.) +- New: the root package contains more helper methods for encoding and decoding operations + + + +### v0.12.0 + +_2021 August 19_ + +This release is a momentous one. It contains a sizable refactor: +we've extracted some of the most key interfaces to a new package, called `datamodel`! + +It's also an even numbered release tag, which we generally use to indicate "upgrading should be smooth sailing". +Surprisingly, despite the magnitude of the refactor, we mean that, too. +Golang's "alias" feature has been used _heavily_ for this change process, +and downstream code that worked on the previous release should continue to work on this release too, without syntactic changes. + +Why did we do this? + +The root package, `ipld`, is now going to be a place where we can put helpful functions. +Synthesis functions that put all the pieces of IPLD together for you. +The functions you're probably looking for; the high-level stuff that gets work done. + +Previously, the root package was _guts_: the lowest level interfaces, the more core stuff... +which was cool to see (arguably), but tended not to be the things you'd want to see _first_ as a new user. +And because everything _else_ in the world depended on those interface, +we could never put interesting high-level functions in the same package +(or if we tried, compilation would fail, because of import cycles)... +which meant any time we wanted to add helper functions for getting useful work done, +we'd be stuck cramming them off into subpackages somewhere. +While this worked, the discoverability for a new user was terribly arduous. + +We hope this pivot to how we organize the code helps you find your way through IPLD! + +We haven't yet added many of the new helper features to the updated root package. +Those will come in the very near future. +(Follow along with commits on the master branch if you want to try the new APIs early!) +This release is being made just to cover the refactor, before we steam along any further. + +Your existing code should continue working without changes because the root `ipld` package +still contains all the same types -- just as aliases. +You can choose to update your code to use the types where they've moved to +(which is mostly the `datamodel` package), or, if you prefer... just leave it as-is. +Some aliases may be removed over time; if so, they'll be marked with a comment to that effect, +and there should be plenty of warning and time to change. + +In some cases, continuing to use the `ipld` package directly will remain acceptable indefinitely. +The new intention is that common work should often be possible to do only by +importing the `ipld` package, and users should only need to dive into +the more specific subpackages if they been to need direct access to more detailed APIs +for performance or other reasons. + +That's it for the big refactor news. + +There's also some sweet new features in bindnode, +and a few other important fixes to recently introduced features. + +In detail: + +- Changed: that massive refactor, described above. Gosh it's big. + [[#228](https://github.com/ipld/go-ipld-prime/pull/228)] +- New: the selectors system is tested against the language-agnostic selector specs, from the IPLD specs+docs repo! + [[#231](https://github.com/ipld/go-ipld-prime/pull/231)] + - This uses a new fixture format, called [testmark](https://github.com/warpfork/go-testmark#what-is-the-testmark-format), which is managed by a library called [go-testmark](https://pkg.go.dev/github.com/warpfork/go-testmark). + - The fixtures are drawn in by a git submodule. The actual fixture content remains in the [ipld/ipld](https://github.com/ipld/ipld/) repo. + - These new tests will be run if you have cloned the git submodule (and of course, by CI). If you do not clone the submodule that contains the fixtures, the tests will quietly skip. + - We hope this will be a template for how to do more testing in the future, while keeping it closely coordinated with specs, and in sync with other implementations of IPLD in other languages! +- Improved: bindnode: in a variety of ways. + [[#226](https://github.com/ipld/go-ipld-prime/pull/226)] + - Several error messages are improved. + - Kinded unions support complex recipients even for string kinds. (E.g., putting a struct with stringjoin representation inside a kinded union now works correctly.) + - Stringprefix unions now work even with no explicit delimiter. + - Please note that bindnode is, and remains, considered experimental. While we're improving it, it's still something to use at your own risk. +- Changed/Improved: bindnode: unions are now handled completely differently (and much better). + [[#223](https://github.com/ipld/go-ipld-prime/pull/223)] + - In short: now they expect a golang struct which has a field for each of the possible members, and each of them should be a pointer. This is type safe and works reasonably idiomatically in golang. + - This is a fairly huge improvement, because it fixes the "bindnode unions force downshift into anonymous types" problem, which was tracked as [issue#210](https://github.com/ipld/go-ipld-prime/issues/210). +- Fixed: the selector `ExploreRecursive.stopAt` feature now actually... works. It was completely broken when it was introduced in the last release. (Tests. They're important.) + [[#229](https://github.com/ipld/go-ipld-prime/pull/229)] + - Notice how we've also now got selector tests driven by fixtures appearing in this release. Hopefully that decreases the odds of something like this happening again. + + + +### v0.11.0 + +_2021 August 12_ + +This release is an odd numbered release, which means it may contain breaking changes. + +Unfortunately, the changes here may be particularly, tricky, as well -- for the most part, they're not compile-time detectable. +They're behavioral changes. Much more subtle. Run tests on your systems before accepting these changes. +Specifically: several codecs now enforce sorting when emitting serial data. + +There's also some details of what's changing that makes it milder than it first sounds: +most of the changes are around codecs becoming *more* spec-compliant. +So, for example, if you were using another IPLD library that always enforced sorting on e.g. DAG-CBOR, +you won't be surprised or experience it much like a "change" when using this version of go-ipld-prime, which now also enforces such sorting in that codec. + +Also! At least one huge and awesome new feature: `bindnode`. +This is a new implementation of `ipld.Node` which can bind to native golang structures using reflection, +which provides a new and easy-to-use way to move data in and out of golang structures (or traverse them, etc!) with IPLD interfaces and codecs. + +See the full change list for details: + +- New: some new helpful constructors for making Selectors out of serial forms can now be found in the `traversal/selector/parse` package. + [[#199](https://github.com/ipld/go-ipld-prime/pull/199)] + - Some constants are also included which show some examples of creating common selectors from JSON. +- Fixed: cbor, dag-cbor, json, and dag-json codecs now all accept parsing a block that contains just a null token alone. (Previously, this returned an "unexpected EOF" error, which was silly.) + [[#217](https://github.com/ipld/go-ipld-prime/pull/217)] +- Fixed (upstream): json floats are actually supported. (You might've had this already, if anything dragged in a newer version of the `refmt` library. We just make sure to require this ourselves in our `go.mod` file now.) + [[#215](https://github.com/ipld/go-ipld-prime/pull/215)] +- New: Selectors now support some kinds of conditions. Specifically, `ExploreRecursive` clauses can contain a `stopAt` condition, and the condition system now supports `Condition_IsLink`, which can be used to do an equality check for CIDs. + [[#214](https://github.com/ipld/go-ipld-prime/pull/214)] +- Fixed: in codegen'd types, the `LinkTargetNodePrototype` on links was returning the wrong prototype; now it returns the right one. + [[#211](https://github.com/ipld/go-ipld-prime/pull/211)] +- New: `schema.TypedPrototype` interface, which is like `ipld.NodePrototype` but also has methods for asking `Type() schema.Type` and `Representation() ipld.NodePrototype`, both of which should probably instantly make sense to you. + [[#195](https://github.com/ipld/go-ipld-prime/pull/195)] +- Changed: the dag-json and dag-cbor codecs now apply sorting. + [[#203](https://github.com/ipld/go-ipld-prime/pull/203), [#204](https://github.com/ipld/go-ipld-prime/pull/204)] + - This means all serial data created with these codecs is sorted as advised by their respective specifications. + Previously, the implementations of these codecs was order-preserving, and emitted data in whatever order the `ipld.Node` yielded it. + - There may be new performance costs originating from this sorting. + - The codecs do not reject other orderings when parsing serial data. + The `ipld.Node` trees resulting from deserialization will still preserve the serialized order. + However, it has now become impossible to re-encode data in that same preserved order. + - If doing your own encoding, there are customization options in `dagcbor.EncodeOptions.MapSortMode` and `dagjson.EncodeOptions.MapSortMode`. + (However, note that these options are not available to you while using any systems that only operate in terms of multicodec codes.) + - _Be cautious of this change._ It is now extremely easy to write code which puts data into an `ipld.Node` in memory in one order, + then save and load that data using these codecs, and end up with different data as a result because the sorting changes the order of data. + For some applications, this may not be a problem; for others, it may be surprising. + In particular, mind this carefully in the presense of other order-sensitive logic -- for example, + such as when using Selectors, whose behaviors also depend on ordering of data returned when iterating over an `ipld.Node`. +- Fixed/Changed: the dag-json codec no longer emits whitespace (!). It is now spec-compliant. + [[#202](https://github.com/ipld/go-ipld-prime/pull/202)] + - This means hashes of content produced by dag-json codec will change. This is unfortunate, but the previous implementation was woefully and wildly out of sync with the spec, and addressing that is a predominating concern. +- Removed: `fluent/quip` has been dropped. `fluent/qp` is superior. `fluent/quip` was too easy to use incorrectly, so we no longer offer it. + [[#197](https://github.com/ipld/go-ipld-prime/pull/197)] + - This was an experimental package introduced a few releases ago, together with caveats that we may choose to drop it. The warning was purposeful! + We don't believe that this will be too painful of a change; not many things depended on the `fluent/quip` variant, and those that did should not be difficult to rewrite to `fluent/qp`. +- New: `node/basic.Chooser` is a function that implements `traversal.LinkTargetNodePrototypeChooser`. It's a small handy quality-of-life increase if you need to supply such a function, which is common. + [[#198](https://github.com/ipld/go-ipld-prime/pull/198)] +- New: `bindnode`! **This is a huge feature.** The beginnings of it may have been visible in v0.10.0, but it's grown into a usable thing we're ready to talk about. + - Bindnode lets you write golang types and structures, and "bind" them into being IPLD Nodes and supporting Data Model operations by using golang reflection. + - The result of working with `bindnode` is somewhere between using basicnode and using codegen: + it's going to provide some structural constraints (like codegen) and provide moderate performance (it lets you use structs rather than memory-expensive maps; but reflection is still going to be slower than codegen). + - However, most importantly, `bindnode` is *nice to use*. It doesn't have a huge barrier to entry like codegen does. + - `bindnode` can be used with _or without_ IPLD Schemas. For basic golang types, a schema can be inferred automatically. For more advanced features (e.g. any representation customization), you can provide a Schema. + - Please note that though it is now usable, bindnode remains _in development_. There is not yet any promise that it will be frozen against changes. + - In fact, several changes are expected; in particular, be advised there is some sizable change expected around the shape of golang types expected for unions. +- Improved: tests for behavior of schema typed nodes are now extracted to a package, where they are reusable. + - The same tests now cover the `bindnode` implementation, as well as being used in tests of our codegen outputs. + - Previously, these tests were already mostly agnostic of implementation, but had been thrown into packages in a way that made them hard to reuse. +- Improved (or Fixed, depending on your point of view): dag-json codec now supports bytes as per the spec. + [[#166](https://github.com/ipld/go-ipld-prime/pull/166),[#216](https://github.com/ipld/go-ipld-prime/pull/216)] + - Bytes are encoded in roughly this form: `{"/":{"bytes":"base64data"}}`. + - Note: the json codec does _not_ include this behavior; this is behavior specific to dag-json. + + + +### v0.10.0 + +_2021 June 02_ + +v0.10.0 is a mild release, containing _no_ breaking changes, but lots of cool new stuff. Update at your earliest convenience. + +There's a bunch of cool new features in here, some of which are significant power-ups for the ecosystem (e.g. the `NodeReifier` API), so we recommend updating as soon as possible. + +There's also some sizable performance improvements available for generated code, so go forth and update your generated code too! + +Check out the full feature list: + +- New: an `ipld.DeepEqual` method lets you easily compare two `ipld.Node` for equality. (This is useful in case you have nodes with two different internal implementations, different memory layouts, etc, such that native golang equality would not be semantically correct.) + [[#174](https://github.com/ipld/go-ipld-prime/pull/174)] +- New: the multicodec package exposes a `multicodec.Registry` type, and also some `multicodec.List*` methods. + [[#172](https://github.com/ipld/go-ipld-prime/pull/172), [#176](https://github.com/ipld/go-ipld-prime/pull/176)] + - Please be cautious of using these `List*` methods. It's very possible to create race conditions with these, especially if using them on the global default registry instance. + If we detect that these access methods seem to produce a source of bugs and design errors in downstream usage, they will be removed. + Consider doing whatever you're doing by buildling your own registry systems, and attaching whatever semantics your system desires to those systems, rather than shoehorning this intentionally limited system into doing things it isn't made to do. +- Improved: the dag-json codec now actually supports bytes! + (Perhaps surprisingly, this was a relatively recent addition to the dag-json spec. We've now caught up with it.) + [[#166](https://github.com/ipld/go-ipld-prime/pull/166)] +- Improved: the codegen system now gofmt's the generated code immediately. You no longer need to do this manually in a separate step. + [[#163](https://github.com/ipld/go-ipld-prime/pull/163)] +- Improved: the codegen system is slightly faster at emitting code (due to use of more buffering during writes). + [[#161](https://github.com/ipld/go-ipld-prime/pull/161)] +- Improved: the codegen system will now avoid pointers in the generated "Maybe" types, if they're known to be small in memory (and thus, reasonable to inline). + [[#160](https://github.com/ipld/go-ipld-prime/pull/160)] + - This is quite likely to result in performance improvements for most programs, as it decreases the number of small memory allocations done, and amount of time spent on dereferencing, cache misses, etc. + Some workloads demonstrated over 10% speed increases, and 40% decreases in allocation counts. + (Of course, run your own benchmarks; not all workloads are equal.) +- New: `ipld.LinkSystem` now contains a "reification" hook system. **This is really cool.** + - The center of this is the `ipld.LinkSystem.NodeReifier` field, and the `ipld.NodeReifier` function type. + - The `ipld.NodeReifier` function type is simply `func(LinkContext, Node, *LinkSystem) (Node, error)`. + - The purpose and intention of this is: you can use this hooking point in order to decide where to engage advanced IPLD features like [ADLs](https://ipld.io/glossary/#adl). + One can use a `NodeReifier` to decide what ADLs to use and when... even when in the middle of a traversal. + - For example: one could write a NodeReifier that says "when I'm in a path that ends with '`foosys/*/hamt`', i'm going to try to load that as if it's a HAMT ADL". + With that hook in place, you'd then be able to walks over whole forests of data with `traversal.*` functions, and they would automatically load the relevant ADL for you transparently every time that pattern is encountered, without disrupting or complicating the walk. + - In the future, we might begin to offer more structural and declaratively configurable approaches to this, and eventually, attempt to standardize them. + For now: you can build any solution you like using this hook system. (And we'll probably plug in any future declarative systems via these same hooks, too.) + - All this appeared in [#158](https://github.com/ipld/go-ipld-prime/pull/158). +- New: `ipld.LinkSystem` now contains a boolean flag for `TrustedStorage`. If set to true, it will cause methods like `Load` to _skip hashing_ when loading content. **_Do not do this unless you know what you're doing._** + [[#149](https://github.com/ipld/go-ipld-prime/pull/149)] +- New: a json (as opposed to dag-json) codec is now available from this repo. It does roughly what you'd expect. (It's like dag-json, but explicitly rejects encoding links and bytes, and correspondingly does not have dag-json's special decoding behaviors that produce those kinds.) + [[#152](https://github.com/ipld/go-ipld-prime/pull/152)] +- New: a cbor (as opposed to dag-cbor) codec is now available from this repo. Same story as the json codec: it just explicitly doesn't support links (because you should use dag-cbor if you want that). + [[#153](https://github.com/ipld/go-ipld-prime/pull/153)] + +This contained a ton of contributions from lots of people: especially thanks to @mvdan, @hannahhoward, and @willscott for invaluable contributions. -Released Changes ----------------- ### v0.9.0 _2021 March 15_ -v0.9.0 is a pretty significant release, including several neat new convenience features, but most noticiably, significantly reworking how linking works. +v0.9.0 is a pretty significant release, including several neat new convenience features, but most noticeably, significantly reworking how linking works. Almost any code that deals with storing and linking data will need some adaptation to handle this release. We're sorry about the effort this may require, but it should be worth it. @@ -65,7 +521,7 @@ in this case there simply weren't enough interesting points in between to be wor - The PR can be found here: https://github.com/ipld/go-ipld-prime/pull/143 - `Link.Load` -> `LinkSystem.Load` (or, new: `LinkSystem.Fill`, which lets you control memory allocation more explicitly). - `LinkBuilder.Build` -> `LinkSystem.Store`. - - `LinkSystem.ComputeLink` is a new feature that prodices a Link without needing to store the data anywhere. + - `LinkSystem.ComputeLink` is a new feature that produces a Link without needing to store the data anywhere. - The `ipld.Loader` function is now most analogous to `ipld.BlockReadOpener`. You now put it into use by assigning it to a `LinkLoader`'s `StorageReadOpener` field. - The `ipld.Storer` function is now most analogous to `ipld.BlockWriteOpener`. You now put it into use by assigning it to a `LinkLoader`'s `StorageWriteOpener` field. - 99% of the time, you'll probably start with `linking/cid.DefaultLinkSystem()`. You can assign to fields of this to customize it further, but it'll get you started with multihashes and multicodecs and all the behavior you expect when working with CIDs. @@ -75,7 +531,7 @@ in this case there simply weren't enough interesting points in between to be wor - In the _future_, further improvements will come from this: we're now much, much closer to making a bunch of transitive dependencies become optional (especially, various hashers, which currently, whenever you pull in the `linking/cid` package, come due to `go-cid`, and are quite large). When these improvements land (again, they're not in this release), you'll need to update your applications to import hashers you need if they're not in the golang standard library. For now: there's no change. - Change: multicodec registration is now in the `go-ipld-prime/multicodec` package. - Previously, this registry was in the `linking/cid` package. These things are now better decoupled. - - This wil require packages which register codecs to make some very small updates: e.g. `s/cidlink.RegisterMulticodecDecoder/multicodec.RegisterDecoder/`, and correspondingly, update the package imports at the top of the file. + - This will require packages which register codecs to make some very small updates: e.g. `s/cidlink.RegisterMulticodecDecoder/multicodec.RegisterDecoder/`, and correspondingly, update the package imports at the top of the file. - New: some pre-made storage options (e.g. satisfying the `ipld.StorageReadOpener` and `ipld.StorageWriteOpener` function interfaces) have appeared! Find these in the `go-ipld-prime/storage` package. - Currently this only includes a simple in-memory storage option. This may be useful for testing and examples, but probably not much else :) - These are mostly intended to be illustrative. You should still expect to find better storage mechanisms in other repos. @@ -188,9 +644,6 @@ Therefore, we suggest upgrading to this one first, beacuse it's an easy waypoint - These APIs are brand new and are _extremely subject to change_, much more so than any other packages in this repo. If you work with them at this stage, _do_ expect to need to update your code when things shift. -Released Changes ----------------- - ### v0.5.0 _2020 July 2_ diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/HACKME.md b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/HACKME.md index 971a3767..08d32c2e 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/HACKME.md +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/HACKME.md @@ -57,16 +57,16 @@ effective instructions for how one could build a copy of that node, using the same implementation details. By example, if some node `n` was made as a `basicnode.plainString`, -then `n.Prototype()` will be `basicnode.Prototype__String{}`, +then `n.Prototype()` will be `basicnode.Prototype.String`, and `n.Prototype().NewBuilder().AssignString("xyz")` can be presumed to work. Note there are also limits to this: if a node was built in a flexible way, the prototype it reports later may only report what it is now, and not return that same flexibility again. By example, if something was made as an "any" -- i.e., -via `basicnode.Prototype__Any{}.NewBuilder()`, and then *happened* to be assigned a string value -- +via `basicnode.Prototype.Any.NewBuilder()`, and then *happened* to be assigned a string value -- the resulting node will still carry a `Prototype()` property that returns -`Prototype__String` -- **not** `Prototype__Any`. +`basicnode.Prototype.String` -- **not** `basicnode.Prototype.Any`. #### NodePrototype meets generic transformation @@ -102,7 +102,7 @@ and might be wrapped with additional rules (such as map key uniqueness, field name expectations, etc). (Note that it's also not an exclusive statement about what `AssignNode(Node)` will -accept; e.g. in many situations, while a `Prototype__MyStringType` might be the prototype +accept; e.g. in many situations, while a `Prototype.MyStringType` might be the prototype returned, any string kinded node can be used in `AssignNode(Node)` and will be appropriately converted.) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/HACKME_releases.md b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/HACKME_releases.md new file mode 100644 index 00000000..b67097b2 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/HACKME_releases.md @@ -0,0 +1,69 @@ +# Making go-ipld-prime Releases + +## Versioning strategy + +go-ipld-prime follows **[WarpVer](https://gist.github.com/warpfork/98d2f4060c68a565e8ad18ea4814c25f)**, a form of SemVer that never bumps the major version number and uses minor version numbers to indicate degree of *changeness*: **even numbers should be easy upgrades; odd numbers may change things**. The patch version number is rarely used in this scheme. + +## CHANGELOG.md + +There is a CHANGELOG.md, it should be relevant and updated. Notable items in the commit history since the last release should be included. Where possible and practical, links to relevant pull requests or other issues with discussions on the items should be included. + +To find the list of commits, it is recommended that you use a tool that can provide some extra metadata to help with matching commits to pull requests. [changelog-maker](https://github.com/nodejs/changelog-maker) can help with this (requires Node.js be installed and the `npx` command be available): + +``` +npx changelog-maker --start-ref=v0.16.0 --reverse=true --find-matching-prs=true --md=true ipld go-ipld-prime +``` + +Alternatively, you can use `git log` and perform mapping to pull requests manually, e.g.: + +``` +git log --all --graph --date-order --abbrev-commit --decorate --oneline +``` + +*(where `--start-ref` points to name of the previous release tag)* + +### Curate and summarize + +The CHANGELOG should be informative for developers wanting to know what changes may pose a risk (highlight these!) and what changes introduce features they may be interested in using. + +1. Group commits to subsystem to create a two-level list. Subsections can include "Data Model", "Schemas", "Bindnode", "Selectors", "Codecs", and the meta-category of "Build" to describe changes local to the repository and not necessarily relevant to API consumers. +2. If there are breaking, or potentially breaking changes, list them under a `#### 馃洜 Breaking Changes` section. +3. Otherwise, prune the list of commits down to the set of changes relevant to users, and list them under a `#### 馃敠 Highlights` section. + +Note that there is also a **Planned/Upcoming Changes** section near the top of the CHANGELOG.md. Update this to remove _done_ items and add other items that may be nearing completion but not yet released. + +### Call-outs + +Add "special thanks" call-outs to individuals who have contributed meaningful changes to the release. + +## Propose a release + +After updating the CHANGELOG.md entry, also bump the version number appropriately in **version.json** file so the auto-release procedure can take care of tagging for you. + +Commit and propose the changes via a pull request to ipld/go-ipld-prime. + +## Release + +After a reasonable amount of time for feedback (usually at least a full global business day), the changes can be merged and a release tag will be created by the GitHub Actions. + +Use the GitHub UI to make a [release](https://github.com/ipld/go-ipld-prime/releases), copying in the contents of the CHANGELOG.md for that release. + +Drop in a note to the appropriate Matrix/Discord/Slack channel(s) for IPLD about the release. + +Optional: Protocol Labs staff can send an email to shipped@protocol.ai to describe the release, these are typically well-read and appreciated. + +## Checklist + +Prior to opening a release proposal pull request, create an issue with the following markdown checklist to help ensure the requisite steps are taken. The issue can also be used to alert subscribed developers to the timeframe and the approximate scope of changes in the release. + +```markdown +* [ ] Add new h3 to `CHANGELOG.md` under **Released Changes** with curated and subsystem-grouped list of changes and links to relevant PRs + * [ ] Highlight any potentially breaking or disruptive changes under "馃洜 Breaking Changes", including extended descriptions to help users make compatibility judgements + * [ ] Add special-thanks call-outs to contributors making significant contributions +* [ ] Update **Planned/Upcoming Changes** section to remove completed items and add newly upcoming, but incomplete items +* [ ] Bump version number appropriately in `version.json` +* [ ] Propose release via pull request, merge after enough time for async global feedback +* [ ] Create GitHub [release](https://github.com/ipld/go-ipld-prime/releases) with the new tag, copying the new `CHANGELOG.md` contents +* [ ] Announce on relevant Discord/Matrix/Slack channel(s) +* [ ] (Optional) Announce to shipped@protocol.ai +``` diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/README.md b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/README.md index d734c9c6..9506a584 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/README.md +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/README.md @@ -28,10 +28,11 @@ if you want to write your own extensions, whether for new Node implementations or new codecs, or new higher-order order functions!) - `github.com/ipld/go-ipld-prime` -- imported as just `ipld` -- contains the core interfaces for IPLD. The most important interfaces are `Node`, `NodeBuilder`, `Path`, and `Link`. -- `github.com/ipld/go-ipld-prime/node/basic` -- imported as `basicnode` -- provides concrete implementations of `Node` and `NodeBuilder` which work for any kind of data. +- `github.com/ipld/go-ipld-prime/node/basicnode` -- provides concrete implementations of `Node` and `NodeBuilder` which work for any kind of data, using unstructured memory. +- `github.com/ipld/go-ipld-prime/node/bindnode` -- provides concrete implementations of `Node` and `NodeBuilder` which store data in native golang structures, interacting with it via reflection. Also supports IPLD Schemas! - `github.com/ipld/go-ipld-prime/traversal` -- contains higher-order functions for traversing graphs of data easily. - `github.com/ipld/go-ipld-prime/traversal/selector` -- contains selectors, which are sort of like regexps, but for trees and graphs of IPLD data! -- `github.com/ipld/go-ipld-prime/codec -- parent package of all the codec implementations! +- `github.com/ipld/go-ipld-prime/codec` -- parent package of all the codec implementations! - `github.com/ipld/go-ipld-prime/codec/dagcbor` -- implementations of marshalling and unmarshalling as CBOR (a fast, binary serialization format). - `github.com/ipld/go-ipld-prime/codec/dagjson` -- implementations of marshalling and unmarshalling as JSON (a popular human readable format). - `github.com/ipld/go-ipld-prime/linking/cid` -- imported as `cidlink` -- provides concrete implementations of `Link` as a CID. Also, the multicodec registry. @@ -39,6 +40,39 @@ or new codecs, or new higher-order order functions!) - `github.com/ipld/go-ipld-prime/node/typed` -- provides concrete implementations of `schema.TypedNode` which decorate a basic `Node` at runtime to have additional features described by IPLD Schemas. +Getting Started +--------------- + +Let's say you want to create some data programmatically, +and then serialize it, or save it as [blocks]. + +You've got a ton of different options, depending on what golang convention you want to use: + +- the `qp` package -- [example](https://pkg.go.dev/github.com/ipld/go-ipld-prime/fluent/qp#example-package) +- the `bindnode` system, if you want to use golang types -- [example](https://pkg.go.dev/github.com/ipld/go-ipld-prime/node/bindnode#example-Wrap-NoSchema), [example with schema](https://pkg.go.dev/github.com/ipld/go-ipld-prime/node/bindnode#example-Wrap-WithSchema) +- or the [`NodeBuilder`](https://pkg.go.dev/github.com/ipld/go-ipld-prime/datamodel#NodeBuilder) interfaces, raw (verbose; not recommended) +- or even some codegen systems! + +Once you've got a Node full of data, +you can serialize it: + +https://pkg.go.dev/github.com/ipld/go-ipld-prime#example-package-CreateDataAndMarshal + +But probably you want to do more than that; +probably you want to store this data as a block, +and get a CID that links back to it. +For this you use `LinkSystem`: + +https://pkg.go.dev/github.com/ipld/go-ipld-prime/linking#example-LinkSystem.Store + +Hopefully these pointers give you some useful getting-started focal points. +The API docs should help from here on out. +We also highly recommend scanning the [godocs](https://pkg.go.dev/github.com/ipld/go-ipld-prime) for other pieces of example code, in various packages! + +Let us know in [issues](https://github.com/ipld/go-ipld-prime/issues), [chat, or other community spaces](https://ipld.io/docs/intro/community/) if you need more help, +or have suggestions on how we can improve the getting-started experiences! + + Other IPLD Libraries -------------------- @@ -46,8 +80,15 @@ Other IPLD Libraries The IPLD specifications are designed to be language-agnostic. Many implementations exist in a variety of languages. -For overall behaviors and specifications, refer to the specs repo: - https://github.com/ipld/specs/ +For overall behaviors and specifications, refer to the IPLD website, or its source, in IPLD meta repo: +- https://ipld.io/ +- https://github.com/ipld/ipld/ +You should find specs in the `specs/` dir there, +human-friendly docs in the `docs/` dir, +and information about _why_ things are designed the way they are mostly in the `design/` directories. + +There are also pages in the IPLD website specifically about golang IPLD libraries, +and your alternatives: https://ipld.io/libraries/golang/ ### distinctions from go-ipld-interface&go-ipld-cbor @@ -88,45 +129,66 @@ We now consider many of the earlier golang IPLD libraries to be defacto deprecat and you should expect new features *here*, rather than in those libraries. (Those libraries still won't be going away anytime soon, but we really don't recomend new construction on them.) +### migrating + +**For recommendations on where to start when migrating:** +see [README_migrationGuide](./README_migrationGuide.md). +That document will provide examples of which old concepts and API names map to which new APIs, +and should help set you on the right track. + ### unixfsv1 -Be advised that faculties for dealing with unixfsv1 data are still limited. -You can find some tools for dealing with dag-pb (the underlying codec) in the [ipld/go-codec-dagpb](https://github.com/ipld/go-codec-dagpb) repo, -and there are also some tools retrofitting some of unixfsv1's other features to be perceivable using an ADL in the [ipfs/go-unixfsnode](https://github.com/ipfs/go-unixfsnode) repo... -however, a "some assembly required" advisory may still be in effect; check the readmes in those repos for details on what they support. +Lots of people who hear about IPLD have heard about it through IPFS. +IPFS has IPLD-native APIs, but IPFS *also* makes heavy use of a specific system called "UnixFSv1", +so people often wonder if UnixFSv1 is supported in IPLD libraries. +The answer is "yes" -- but it's not part of the core. +UnixFSv1 is now treated as an [ADL](https://ipld.io/glossary/#adl), +and a go-ipld-prime compatible implementation can be found +in the [ipfs/go-unixfsnode](https://github.com/ipfs/go-unixfsnode) repo. -Change Policy -------------- +Additionally, the codec used in UnixFSv1 -- dag-pb -- +can be found implemented in the [ipld/go-codec-dagpb](https://github.com/ipld/go-codec-dagpb) repo. -The go-ipld-prime library is already usable. We are also still in development, and may still change things. +A "some assembly required" advisory may still be in effect for these pieces; +check the readmes in those repos for details on what they support. -A changelog can be found at [CHANGELOG.md](CHANGELOG.md). +The move to making UnixFSv1 a non-core system has been an arduous retrofit. +However, framing it as an ADL also provides many advantages: -Using a commit hash to pin versions precisely when depending on this library is advisable (as it is with any other). +- it demonstrates that ADLs as a plugin system _work_, and others can develop new systems in this pattern! +- it has made pathing over UnixFSv1 much more standard and well-defined +- this standardization means systems like [Selectors](https://ipld.io/glossary/#selectors) work naturally over UnixFSv1... +- ... which in turn means anything using them (ex: CAR export; graphsync; etc) can very easily be asked to produce a merkle-proof + for a path over UnixFSv1 data, without requiring the querier to know about the internals. Whew! -We may sometimes tag releases, but it's just as acceptable to track commits on master without the indirection. +We hope users and developers alike will find value in how these systems are now layered. -The following are all norms you can expect of changes to this codebase: -- The `master` branch will not be force-pushed. - - (exceptional circumstances may exist, but such exceptions will only be considered valid for about as long after push as the "$N-second-rule" about dropped food). - - Therefore, commit hashes on master are gold to link against. -- All other branches *will* be force-pushed. - - Therefore, commit hashes not reachable from the master branch are inadvisable to link against. -- If it's on master, it's understood to be good, in as much as we can tell. -- Development proceeds -- both starting from and ending on -- the `master` branch. - - There are no other long-running supported-but-not-master branches. - - The existence of tags at any particular commit do not indicate that we will consider starting a long running and supported diverged branch from that point, nor start doing backports, etc. -- All changes are presumed breaking until proven otherwise; and we don't have the time and attention budget at this point for doing the "proven otherwise". - - All consumers updating their libraries should run their own compiler, linking, and test suites before assuming the update applies cleanly -- as is good practice regardless. - - Any idea of semver indicating more or less breakage should be treated as a street vendor selling potions of levitation -- it's likely best disregarded. -None of this is to say we'll go breaking things willy-nilly for fun; but it *is* to say: +Change Policy +------------- + +The go-ipld-prime library is ready to use, and we value stability highly. -- Staying close to master is always better than not staying close to master; -- and trust your compiler and your tests rather than tea-leaf patterns in a tag string. +We make releases periodically. +However, using a commit hash to pin versions precisely when depending on this library is also perfectly acceptable. +(Only commit hashes on the master branch can be expected to persist, however; +depending on a commit hash in a branch is not recommended. See [development branches](#development-branches).) + +We maintain a [CHANGELOG](CHANGELOG.md)! +Please read it, when updating! + +We do make reasonable attempts to minimize the degree of changes to the library which will create "breaking change" experiences for downstream consumers, +and we do document these in the changelog (often, even with specific migration instructions). +However, we do also still recommend running your own compile and test suites as a matter of course after updating. + +You can help make developing this library easier by staying up-to-date as a downstream consumer! +When we do discover a need for API changes, we typically try to introduce the new API first, +and do at least one release tag in which the old API is deprecated (but not yet removed). +We will all be able to develop software faster, together, as an ecosystem, +if libraries can keep reasonably closely up-to-date with the most recent tags. ### Version Names @@ -140,7 +202,8 @@ When a tag is made, version number steps in go-ipld-prime advance as follows: [This is WarpVer](https://gist.github.com/warpfork/98d2f4060c68a565e8ad18ea4814c25f). These version numbers are provided as hints about what to expect, -but ultimately, you should always invoke your compiler and your tests to tell you about compatibility. +but ultimately, you should always invoke your compiler and your tests to tell you about compatibility, +as well as read the [changelog](CHANGELOG.md). ### Updating @@ -154,3 +217,20 @@ so if you're cautious about absorbing changes, you should update to the even num run all your tests, and *then* upgrade to the odd number. Usually the step to the even number should go off without a hitch, but if you *do* get problems from advancing to an even number tag, A) you can be pretty sure it's a bug, and B) you didn't have to edit a bunch of code before finding that out. + + +### Development branches + +The following are norms you can expect of changes to this codebase, and the treatment of branches: + +- The `master` branch will not be force-pushed. + - (exceptional circumstances may exist, but such exceptions will only be considered valid for about as long after push as the "$N-second-rule" about dropped food). + - Therefore, commit hashes on master are gold to link against. +- All other branches *can* be force-pushed. + - Therefore, commit hashes not reachable from the master branch are inadvisable to link against. +- If it's on master, it's understood to be good, in as much as we can tell. + - Changes and features don't get merged until their tests pass! + - Packages of "alpha" developmental status may exist, and be more subject to change than other more finalized parts of the repo, but their self-tests will at least pass. +- Development proceeds -- both starting from and ending on -- the `master` branch. + - There are no other long-running supported-but-not-master branches. + - The existence of tags at any particular commit do not indicate that we will consider starting a long running and supported diverged branch from that point, nor start doing backports, etc. diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/README_migrationGuide.md b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/README_migrationGuide.md new file mode 100644 index 00000000..28ceba7a --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/README_migrationGuide.md @@ -0,0 +1,59 @@ +A short guide to migrating to go-ipld-prime from other repos +============================================================ + +Here are some quick notes on APIs that you might've been using +if you worked with IPLD in golang before go-ipld-prime, +and a pointer to what you should check out for an equivalent +in order to upgrade your code to use go-ipld-prime. + +(Let us know if there are more pointers we should add to this list to ease your journey, +or someone else's future journey!) + +- Were you using [ipfs/go-datastore](https://pkg.go.dev/github.com/ipfs/go-datastore) APIs? + - You can wrap those in `storage/dsadapter` and keep using them. + You can also plug that into `linking.LinkSystem` to get higher level IPLD operations. + - Or if you were only using datastore because of some specific implementation of it, like, say `flatfs`? + Then check out the possibility of moving all the way directly to new implementations like `storage/fsstore`. +- Were you using [ipfs/go-ipfs-blockstore](https://pkg.go.dev/github.com/ipfs/go-ipfs-blockstore) APIs? + - You can wrap those in `storage/bsadapter` and keep using them. + You can also plug that into `linking.LinkSystem` to get higher level IPLD operations. + (This is almost exactly the same; we've just simplified in the interface, made it easier to implement, and cleaned up inconsistencies with the other interfaces in this migration guide which were already very very similar.) +- Were you using [ipfs/go-blockservice](https://pkg.go.dev/github.com/ipfs/go-blockservice) APIs? + - You can wrap those in `storage/bsrvadapter` and keep using them. + You can also plug that into `linking.LinkSystem` to get higher level IPLD operations. + - Be judicious about whether you actually want to do this. + Plugging in the potential to experience unknown network latencies into code that's expecting predictable local lookup speeds + may have undesirable performance outcomes. (But if you want to do it, go ahead...) +- Were you using [ipfs/go-ipld-format.DAGService](https://pkg.go.dev/github.com/ipfs/go-ipld-format#DAGService)? + - If you're using the `Add` and `Get` methods: those are now on `linking.LinkSystem`, as `Store` and `Load`. + - If you're using the `*Many` methods: those don't have direct replacements; + we don't use APIs that force that style of future-aggregation anymore, because it's bad for pipelining. + Just use `Store` and `Load`. +- Were you using [ipfs/go-ipld-format.Node](https://pkg.go.dev/github.com/ipfs/go-ipld-format#Node)? + - That's actually a semantic doozy -- we use the word "node" _much_ differently now. + See https://ipld.io/glossary/#node for an introduction. + (Long story short: the old "node" was often more like a whole block, and the new "node" is more like an AST node: there's lots of "node" in a "block" now.) + - There's an `datamodel.Node` interface -- it's probably what you want. + (You just might have to update how you think about it -- see above bullet point about semantics shift.) + It's also aliased as the `ipld.Node` interface here right in the root package, because it's such an important and central interface that you'll be using it all the time. + - Are you specifically looking for how to get a list of links out of a block? + That's a `LinkSystem.Load` followed by applying `traversal.SelectLinks` on the node it gives you: now you've got the list of links from that node (and its children, recursively, as long as they came from the same block of raw data), tada! +- Are you looking for the equivalent of [ipfs/go-ipld-format.Link](https://pkg.go.dev/github.com/ipfs/go-ipld-format#Link)? + - That's actually a feature specific to dag-pb, and arguably even specific to unixfsv1. + There is no equivalent in go-ipld-prime as a result. + But you'll find it in other libraries that are modern and go-ipld-prime based: see below. +- Were you using some feature specific to dag-pb? + - There's an updated dag-pb codec found in https://github.com/ipld/go-codec-dagpb -- it should have what you need. + - Does it turn out you actually meant you're using some feature specific to unixfsv1? + (Yeah -- that comes up a lot. It's one of the reasons we're deprecating so many of the old libraries -- they make it _really_ easy to confuse this.) + Then hang on for the next bullet point, which is for you! :) +- Were you using some features of unixfsv1? + - Check out the https://github.com/ipfs/go-unixfsnode library -- it should have what you need. + - Pathing, like what used to be found in ipfs/go-path? That's here now. + - Sharding? That's here now too. + - You probably don't need incentives if you're here already, but can we quickly mention that... you can use Selectors over these? Neat! + +If you're encountering more questions about how to migrate some code, +please jump in to the ipld chat via either [matrix](https://matrix.to/#/#ipld:ipfs.io) or discord (or any other bridge) +and ask! +We want to grow this list of pointers to be as encompassing and helpful as possible. diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/adl.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/adl.go new file mode 100644 index 00000000..bb761896 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/adl.go @@ -0,0 +1,7 @@ +package ipld + +import ( + "github.com/ipld/go-ipld-prime/adl" +) + +type ADL = adl.ADL diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/adl/interface.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/adl/interface.go new file mode 100644 index 00000000..5cd77223 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/adl/interface.go @@ -0,0 +1,25 @@ +package adl + +import ( + "github.com/ipld/go-ipld-prime/datamodel" +) + +// ADL is an interface denoting an Advanced Data Layout, +// which is something that supports all the datamodel.Node operations, +// but may be doing so using some custom internal logic. +// +// For more details, see the docs at +// https://ipld.io/docs/advanced-data-layouts/ . +// +// This interface doesn't specify much new behavior, but it does include +// the requirement of a way to tell an examiner about your "substrate", +// since this concept does seem to be present in all ADLs. +type ADL interface { + datamodel.Node + + // Substrate returns the underlying Data Model node, which can be used + // to encode an ADL's raw layout. + // + // Note that the substrate of an ADL can contain other ADLs! + Substrate() datamodel.Node +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec.go new file mode 100644 index 00000000..26ed3b07 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec.go @@ -0,0 +1,10 @@ +package ipld + +import ( + "github.com/ipld/go-ipld-prime/codec" +) + +type ( + Encoder = codec.Encoder + Decoder = codec.Decoder +) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/README.md b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/README.md new file mode 100644 index 00000000..a2bb0e7b --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/README.md @@ -0,0 +1,77 @@ +Codecs +====== + +The `go-ipld-prime/codec` package is a grouping package. +The subpackages contains some codecs which reside in this repo. + +The codecs included here are our "batteries included" codecs, +but they are not otherwise special. + +It is not necessary for a codec to be a subpackage here to be a valid codec to use with go-ipld; +anything that implements the `codec.Encoder` and `codec.Decoder` interfaces is fine. + + +Terminology +----------- + +We generally refer to "codecs" as having an "encode" function and "decode" function. + +We consider "encoding" to be the process of going from {Data Model} to {serial data}, +and "decoding" to be the process of going from {serial data} to {Data Model}. + +### Codec vs Multicodec + +A "codec" is _any_ function that goes from {Data Model} to {serial data}, or vice versa. + +A "multicodec" is a function which does that and is _also_ specifically recognized and described in +the tables in https://github.com/multiformats/multicodec/ . + +Multicodecs generally leave no further room for customization and configuration, +because their entire behavior is supposed to be specified by a multicodec indicator code number. + +Our codecs, in the child packages of this one, usually offer configuration options. +They also usually offer exactly one function, which does *not* allow configuration, +which is supplying a multicodec-compatible behavior. +You'll see this marked in the docs on those functions. + +### Marshal vs Encode + +It's common to see the terms "marshal" and "unmarshal" used in golang. + +Those terms are usually describing when structured data is transformed into linearized, tokenized data +(and then, perhaps, all the way to serially encoded data), or vice versa. + +We would use the words the same way... except we don't end up using them, +because that feature doesn't really come up in our codec layer. + +In IPLD, we would describe mapping some typed data into Data Model as "marshalling". +(It's one step shy of tokenizing, but barely: Data Model does already have defined ordering for every element of data.) +And we do have systems that do this: +`bindnode` and our codegen systems both do this, implicitly, when they give you an `ipld.Node` of the representation of some data. + +We just don't end up talking about it as "marshalling" because of how it's done implicitly by those systems. +As a result, all of our features relating to codecs only end up speaking about "encoding" and "decoding". + +### Legacy code + +There are some appearances of the words "marshal" and "unmarshal" in some of our subpackages here. + +That verbiage is generally on the way out. +For functions and structures with those names, you'll notice their docs marking them as deprecated. + + +Why have "batteries-included" codecs? +------------------------------------- + +These codecs live in this repo because they're commonly used, highly supported, +and general-purpose codecs that we recommend for widespread usage in new developments. + +Also, it's just plain nice to have something in-repo for development purposes. +It makes sure that if we try to make any API changes, we immediately see if they'd make codecs harder to implement. +We also use the batteries-included codecs for debugging, for test fixtures, and for benchmarking. + +Further yet, the batteries-included codecs let us offer getting-started APIs. +For example, we offer some helper APIs which use codecs like e.g. JSON to give consumers of the libraries +one-step helper methods that "do the right thing" with zero config... so long as they happen to use that codec. +Even for consumers who don't use those codecs, such functions then serve as natural documentation +and examples for what to do to put their codec of choice to work. diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/api.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/api.go new file mode 100644 index 00000000..6fa2c271 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/api.go @@ -0,0 +1,128 @@ +package codec + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +// The following two types define the two directions of transform that a codec can be expected to perform: +// from Node to serial stream (aka "encoding", sometimes also described as "marshalling"), +// and from serial stream to Node (via a NodeAssembler) (aka "decoding", sometimes also described as "unmarshalling"). +// +// You'll find a couple of implementations matching this shape in subpackages of 'codec'. +// (These are the handful of encoders and decoders we ship as "batteries included".) +// Other encoder and decoder implementations can be found in other repositories/modules. +// It should also be easy to implement encodecs and decoders of your own! +// +// Encoder and Decoder functions can be used on their own, but are also often used via the `ipld/linking.LinkSystem` construction, +// which handles all the other related operations necessary for a content-addressed storage system at once. +// +// Encoder and Decoder functions can be registered in the multicodec table in the `ipld/multicodec` package +// if they're providing functionality that matches the expectations for a multicodec identifier. +// This table will be used by some common EncoderChooser and DecoderChooser implementations +// (namely, the ones in LinkSystems produced by the `linking/cid` package). +// It's not strictly necessary to register functions there, though; you can also just use them directly. +// +// There are furthermore several conventions that codec packages are recommended to follow, but are only conventions: +// +// Most codec packages should have a ReusableEncoder and ResuableDecoder type, +// which contain any working memory needed by the implementation, as well as any configuration options, +// and those types should have an Encode and Decode function respectively which match these function types. +// They may alternatively have EncoderConfig and DecoderConfig types, which have similar purpose, +// but aren't promising memory reuse if kept around. +// +// By convention, a codec package that expects to fulfill a multicodec contract will also have +// a package-scope exported function called Encode or Decode which also matches this interface, +// and is the equivalent of creating a zero-value ReusableEncoder or ReusableDecoder (aka, default config) +// and using its Encode or Decode methods. +// This package-scope function may also internally use a sync.Pool +// to keep some ReusableEncoder values on hand to avoid unnecesary allocations. +// +// Note that an EncoderConfig or DecoderConfig type that supports configuration options +// does not functionally expose those options when invoked by the multicodec system -- +// multicodec indicator codes do not provide room for extended configuration info. +// Codecs that expose configuration options are doing so for library users to enjoy; +// it does not mean those non-default configurations will necessarly be available +// in all scenarios that use codecs indirectly. +// There is also no standard interface for such configurations: by nature, +// if they exist at all, they tend to vary per codec. +type ( + // Encoder defines the shape of a function which traverses a Node tree + // and emits its data in a serialized form into an io.Writer. + // + // The dual of Encoder is a Decoder, which takes a NodeAssembler + // and fills it with deserialized data consumed from an io.Reader. + // Typically, Decoder and Encoder functions will be found in pairs, + // and will be expected to be able to round-trip each other's data. + // + // Encoder functions can be used directly. + // Encoder functions are also often used via a LinkSystem when working with content-addressed storage. + // LinkSystem methods will helpfully handle the entire process of traversing a Node tree, + // encoding this data, hashing it, streaming it to the writer, and committing it -- all as one step. + // + // An Encoder works with Nodes. + // If you have a native golang structure, and want to serialize it using an Encoder, + // you'll need to figure out how to transform that golang structure into an ipld.Node tree first. + // + // It may be useful to understand "multicodecs" when working with Encoders. + // In IPLD, a system called "multicodecs" is typically used to describe encoding foramts. + // A "multicodec indicator" is a number which describes an encoding; + // the Link implementations used in IPLD (CIDs) store a multicodec indicator in the Link; + // and in this library, a multicodec registry exists in the `codec` package, + // and can be used to associate a multicodec indicator number with an Encoder function. + // The default EncoderChooser in a LinkSystem will use this multicodec registry to select Encoder functions. + // However, you can construct a LinkSystem that uses any EncoderChooser you want. + // It is also possible to have and use Encoder functions that aren't registered as a multicodec at all... + // we just recommend being cautious of this, because it may make your data less recognizable + // when working with other systems that use multicodec indicators as part of their communication. + Encoder func(datamodel.Node, io.Writer) error + + // Decoder defines the shape of a function which produces a Node tree + // by reading serialized data from an io.Reader. + // (Decoder doesn't itself return a Node directly, but rather takes a NodeAssembler as an argument, + // because this allows the caller more control over the Node implementation, + // as well as some control over allocations.) + // + // The dual of Decoder is an Encoder, which takes a Node and + // emits its data in a serialized form into an io.Writer. + // Typically, Decoder and Encoder functions will be found in pairs, + // and will be expected to be able to round-trip each other's data. + // + // Decoder functions can be used directly. + // Decoder functions are also often used via a LinkSystem when working with content-addressed storage. + // LinkSystem methods will helpfully handle the entire process of opening block readers, + // verifying the hash of the data stream, and applying a Decoder to build Nodes -- all as one step. + // + // A Decoder works with Nodes. + // If you have a native golang structure, and want to populate it with data using a Decoder, + // you'll need to either get a NodeAssembler which proxies data into that structure directly, + // or assemble a Node as intermediate storage and copy the data to the native structure as a separate step. + // + // It may be useful to understand "multicodecs" when working with Decoders. + // See the documentation on the Encoder function interface for more discussion of multicodecs, + // the multicodec table, and how this is typically connected to linking. + Decoder func(datamodel.NodeAssembler, io.Reader) error +) + +// ------------------- +// Errors +// + +type ErrBudgetExhausted struct{} + +func (e ErrBudgetExhausted) Error() string { + return "decoder resource budget exhausted (message too long or too complex)" +} + +// --------------------- +// Other valuable and reused constants +// + +type MapSortMode uint8 + +const ( + MapSortMode_None MapSortMode = iota + MapSortMode_Lexical + MapSortMode_RFC7049 +) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/doc.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/doc.go new file mode 100644 index 00000000..9203c947 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/doc.go @@ -0,0 +1,42 @@ +/* +The dagcbor package provides a DAG-CBOR codec implementation. + +The Encode and Decode functions match the codec.Encoder and codec.Decoder function interfaces, +and can be registered with the go-ipld-prime/multicodec package for easy usage with systems such as CIDs. + +Importing this package will automatically have the side-effect of registering Encode and Decode +with the go-ipld-prime/multicodec registry, associating them with the standard multicodec indicator numbers for DAG-CBOR. + +This implementation follows most of the rules of DAG-CBOR, namely: + +- by and large, it does emit and parse CBOR! + +- only explicit-length maps and lists will be emitted by Encode; + +- only tag 42 is accepted, and it must parse as a CID; + +- only 64 bit floats will be emitted by Encode. + +This implementation is also not strict about certain rules: + +- Encode is order-passthrough when emitting maps (it does not sort, nor abort in error if unsorted data is encountered). +To emit sorted data, the node should be sorted before applying the Encode function. + +- Decode is order-passthrough when parsing maps (it does not sort, nor abort in error if unsorted data is encountered). +To be strict about the ordering of data, additional validation must be applied to the result of the Decode function. + +- Decode will accept indeterminate length lists and maps without complaint. +(These should not be allowed according to the DAG-CBOR spec, nor will the Encode function re-emit such values, +so this behavior should almost certainly be seen as a bug.) + +- Decode does not consistently verify that ints and floats use the smallest representation possible (or, the 64-bit version, in the float case). +(Only these numeric encodings should be allowed according to the DAG-CBOR spec, and the Encode function will not re-emit variations, +so this behavior should almost certainly be seen as a bug.) + +A note for future contributors: some functions in this package expose references to packages from the refmt module, and/or use them internally. +Please avoid adding new code which expands the visibility of these references. +In future work, we'd like to reduce or break this relationship entirely +(in part, to reduce dependency sprawl, and in part because several of +the imprecisions noted above stem from that library's lack of strictness). +*/ +package dagcbor diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/marshal.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/marshal.go index a4db0605..a7ee1620 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/marshal.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/marshal.go @@ -2,60 +2,72 @@ package dagcbor import ( "fmt" + "io" + "sort" + "github.com/polydawn/refmt/cbor" "github.com/polydawn/refmt/shared" "github.com/polydawn/refmt/tok" - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/codec" + "github.com/ipld/go-ipld-prime/datamodel" cidlink "github.com/ipld/go-ipld-prime/linking/cid" ) -// This should be identical to the general feature in the parent package, -// except for the `case ipld.Kind_Link` block, +// This file should be identical to the general feature in the parent package, +// except for the `case datamodel.Kind_Link` block, // which is dag-cbor's special sauce for schemafree links. -func Marshal(n ipld.Node, sink shared.TokenSink) error { + +// EncodeOptions can be used to customize the behavior of an encoding function. +// The Encode method on this struct fits the codec.Encoder function interface. +type EncodeOptions struct { + // If true, allow encoding of Link nodes as CBOR tag(42); + // otherwise, reject them as unencodable. + AllowLinks bool + + // Control the sorting of map keys, using one of the `codec.MapSortMode_*` constants. + MapSortMode codec.MapSortMode +} + +// Encode walks the given datamodel.Node and serializes it to the given io.Writer. +// Encode fits the codec.Encoder function interface. +// +// The behavior of the encoder can be customized by setting fields in the EncodeOptions struct before calling this method. +func (cfg EncodeOptions) Encode(n datamodel.Node, w io.Writer) error { + // Probe for a builtin fast path. Shortcut to that if possible. + type detectFastPath interface { + EncodeDagCbor(io.Writer) error + } + if n2, ok := n.(detectFastPath); ok { + return n2.EncodeDagCbor(w) + } + // Okay, generic inspection path. + return Marshal(n, cbor.NewEncoder(w), cfg) +} + +// Future work: we would like to remove the Marshal function, +// and in particular, stop seeing types from refmt (like shared.TokenSink) be visible. +// Right now, some kinds of configuration (e.g. for whitespace and prettyprint) are only available through interacting with the refmt types; +// we should improve our API so that this can be done with only our own types in this package. + +// Marshal is a deprecated function. +// Please consider switching to EncodeOptions.Encode instead. +func Marshal(n datamodel.Node, sink shared.TokenSink, options EncodeOptions) error { var tk tok.Token - return marshal(n, &tk, sink) + return marshal(n, &tk, sink, options) } -func marshal(n ipld.Node, tk *tok.Token, sink shared.TokenSink) error { +func marshal(n datamodel.Node, tk *tok.Token, sink shared.TokenSink, options EncodeOptions) error { switch n.Kind() { - case ipld.Kind_Invalid: + case datamodel.Kind_Invalid: return fmt.Errorf("cannot traverse a node that is absent") - case ipld.Kind_Null: + case datamodel.Kind_Null: tk.Type = tok.TNull _, err := sink.Step(tk) return err - case ipld.Kind_Map: - // Emit start of map. - tk.Type = tok.TMapOpen - tk.Length = int(n.Length()) // TODO: overflow check - if _, err := sink.Step(tk); err != nil { - return err - } - // Emit map contents (and recurse). - for itr := n.MapIterator(); !itr.Done(); { - k, v, err := itr.Next() - if err != nil { - return err - } - tk.Type = tok.TString - tk.Str, err = k.AsString() - if err != nil { - return err - } - if _, err := sink.Step(tk); err != nil { - return err - } - if err := marshal(v, tk, sink); err != nil { - return err - } - } - // Emit map close. - tk.Type = tok.TMapClose - _, err := sink.Step(tk) - return err - case ipld.Kind_List: + case datamodel.Kind_Map: + return marshalMap(n, tk, sink, options) + case datamodel.Kind_List: // Emit start of list. tk.Type = tok.TArrOpen l := n.Length() @@ -69,7 +81,7 @@ func marshal(n ipld.Node, tk *tok.Token, sink shared.TokenSink) error { if err != nil { return err } - if err := marshal(v, tk, sink); err != nil { + if err := marshal(v, tk, sink, options); err != nil { return err } } @@ -77,7 +89,7 @@ func marshal(n ipld.Node, tk *tok.Token, sink shared.TokenSink) error { tk.Type = tok.TArrClose _, err := sink.Step(tk) return err - case ipld.Kind_Bool: + case datamodel.Kind_Bool: v, err := n.AsBool() if err != nil { return err @@ -86,16 +98,25 @@ func marshal(n ipld.Node, tk *tok.Token, sink shared.TokenSink) error { tk.Bool = v _, err = sink.Step(tk) return err - case ipld.Kind_Int: - v, err := n.AsInt() - if err != nil { - return err + case datamodel.Kind_Int: + if uin, ok := n.(datamodel.UintNode); ok { + v, err := uin.AsUint() + if err != nil { + return err + } + tk.Type = tok.TUint + tk.Uint = v + } else { + v, err := n.AsInt() + if err != nil { + return err + } + tk.Type = tok.TInt + tk.Int = v } - tk.Type = tok.TInt - tk.Int = int64(v) - _, err = sink.Step(tk) + _, err := sink.Step(tk) return err - case ipld.Kind_Float: + case datamodel.Kind_Float: v, err := n.AsFloat() if err != nil { return err @@ -104,7 +125,7 @@ func marshal(n ipld.Node, tk *tok.Token, sink shared.TokenSink) error { tk.Float64 = v _, err = sink.Step(tk) return err - case ipld.Kind_String: + case datamodel.Kind_String: v, err := n.AsString() if err != nil { return err @@ -113,7 +134,7 @@ func marshal(n ipld.Node, tk *tok.Token, sink shared.TokenSink) error { tk.Str = v _, err = sink.Step(tk) return err - case ipld.Kind_Bytes: + case datamodel.Kind_Bytes: v, err := n.AsBytes() if err != nil { return err @@ -122,13 +143,19 @@ func marshal(n ipld.Node, tk *tok.Token, sink shared.TokenSink) error { tk.Bytes = v _, err = sink.Step(tk) return err - case ipld.Kind_Link: + case datamodel.Kind_Link: + if !options.AllowLinks { + return fmt.Errorf("cannot Marshal ipld links to CBOR") + } v, err := n.AsLink() if err != nil { return err } switch lnk := v.(type) { case cidlink.Link: + if !lnk.Cid.Defined() { + return fmt.Errorf("encoding undefined CIDs are not supported by this codec") + } tk.Type = tok.TBytes tk.Bytes = append([]byte{0}, lnk.Bytes()...) tk.Tagged = true @@ -143,3 +170,212 @@ func marshal(n ipld.Node, tk *tok.Token, sink shared.TokenSink) error { panic("unreachable") } } + +func marshalMap(n datamodel.Node, tk *tok.Token, sink shared.TokenSink, options EncodeOptions) error { + // Emit start of map. + tk.Type = tok.TMapOpen + expectedLength := int(n.Length()) + tk.Length = expectedLength // TODO: overflow check + if _, err := sink.Step(tk); err != nil { + return err + } + if options.MapSortMode != codec.MapSortMode_None { + // Collect map entries, then sort by key + type entry struct { + key string + value datamodel.Node + } + entries := []entry{} + for itr := n.MapIterator(); !itr.Done(); { + k, v, err := itr.Next() + if err != nil { + return err + } + keyStr, err := k.AsString() + if err != nil { + return err + } + entries = append(entries, entry{keyStr, v}) + } + if len(entries) != expectedLength { + return fmt.Errorf("map Length() does not match number of MapIterator() entries") + } + // Apply the desired sort function. + switch options.MapSortMode { + case codec.MapSortMode_Lexical: + sort.Slice(entries, func(i, j int) bool { + return entries[i].key < entries[j].key + }) + case codec.MapSortMode_RFC7049: + sort.Slice(entries, func(i, j int) bool { + // RFC7049 style sort as per DAG-CBOR spec + li, lj := len(entries[i].key), len(entries[j].key) + if li == lj { + return entries[i].key < entries[j].key + } + return li < lj + }) + } + // Emit map contents (and recurse). + for _, e := range entries { + tk.Type = tok.TString + tk.Str = e.key + if _, err := sink.Step(tk); err != nil { + return err + } + if err := marshal(e.value, tk, sink, options); err != nil { + return err + } + } + } else { // no sorting + // Emit map contents (and recurse). + var entryCount int + for itr := n.MapIterator(); !itr.Done(); { + k, v, err := itr.Next() + if err != nil { + return err + } + entryCount++ + tk.Type = tok.TString + tk.Str, err = k.AsString() + if err != nil { + return err + } + if _, err := sink.Step(tk); err != nil { + return err + } + if err := marshal(v, tk, sink, options); err != nil { + return err + } + } + if entryCount != expectedLength { + return fmt.Errorf("map Length() does not match number of MapIterator() entries") + } + } + // Emit map close. + tk.Type = tok.TMapClose + _, err := sink.Step(tk) + return err +} + +// EncodedLength will calculate the length in bytes that the encoded form of the +// provided Node will occupy. +// +// Note that this function requires a full walk of the Node's graph, which may +// not necessarily be a trivial cost and will incur some allocations. Using this +// method to calculate buffers to pre-allocate may not result in performance +// gains, but rather incur an overall cost. Use with care. +func EncodedLength(n datamodel.Node) (int64, error) { + switch n.Kind() { + case datamodel.Kind_Invalid: + return 0, fmt.Errorf("cannot traverse a node that is absent") + case datamodel.Kind_Null: + return 1, nil // 0xf6 + case datamodel.Kind_Map: + length := uintLength(uint64(n.Length())) // length prefixed major 5 + for itr := n.MapIterator(); !itr.Done(); { + k, v, err := itr.Next() + if err != nil { + return 0, err + } + keyLength, err := EncodedLength(k) + if err != nil { + return 0, err + } + length += keyLength + valueLength, err := EncodedLength(v) + if err != nil { + return 0, err + } + length += valueLength + } + return length, nil + case datamodel.Kind_List: + nl := n.Length() + length := uintLength(uint64(nl)) // length prefixed major 4 + for i := int64(0); i < nl; i++ { + v, err := n.LookupByIndex(i) + if err != nil { + return 0, err + } + innerLength, err := EncodedLength(v) + if err != nil { + return 0, err + } + length += innerLength + } + return length, nil + case datamodel.Kind_Bool: + return 1, nil // 0xf4 or 0xf5 + case datamodel.Kind_Int: + v, err := n.AsInt() + if err != nil { + return 0, err + } + if v < 0 { + v = -v - 1 // negint is stored as one less than actual + } + return uintLength(uint64(v)), nil // major 0 or 1, as small as possible + case datamodel.Kind_Float: + return 9, nil // always major 7 and 64-bit float + case datamodel.Kind_String: + v, err := n.AsString() + if err != nil { + return 0, err + } + + return uintLength(uint64(len(v))) + int64(len(v)), nil // length prefixed major 3 + case datamodel.Kind_Bytes: + v, err := n.AsBytes() + if err != nil { + return 0, err + } + return uintLength(uint64(len(v))) + int64(len(v)), nil // length prefixed major 2 + case datamodel.Kind_Link: + v, err := n.AsLink() + if err != nil { + return 0, err + } + switch lnk := v.(type) { + case cidlink.Link: + length := int64(2) // tag,42: 0xd82a + bl := int64(len(lnk.Bytes())) + 1 // additional 0x00 in front of the CID bytes + length += uintLength(uint64(bl)) + bl // length prefixed major 2 + return length, err + default: + return 0, fmt.Errorf("schemafree link emission only supported by this codec for CID type links") + } + default: + panic("unreachable") + } +} + +// Calculate how many bytes an integer, and therefore also the leading bytes of +// a length-prefixed token. CBOR will pack it up into the smallest possible +// uint representation, even merging it with the major if it's <=23. + +type boundaryLength struct { + upperBound uint64 + length int64 +} + +var lengthBoundaries = []boundaryLength{ + {24, 1}, // packed major|minor + {256, 2}, // major, 8-bit length + {65536, 3}, // major, 16-bit length + {4294967296, 5}, // major, 32-bit length + {0, 9}, // major, 64-bit length +} + +func uintLength(ii uint64) int64 { + for _, lb := range lengthBoundaries { + if ii < lb.upperBound { + return lb.length + } + } + // maximum number of bytes to pack this int + // if this int is used as a length prefix for a map, list, string or bytes + // then we likely have a very bad Node that shouldn't be encoded, but the + // encoder may raise problems with that if the memory allocator doesn't first. + return lengthBoundaries[len(lengthBoundaries)-1].length +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/multicodec.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/multicodec.go index 85871049..b15ee30b 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/multicodec.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/multicodec.go @@ -3,15 +3,14 @@ package dagcbor import ( "io" - "github.com/polydawn/refmt/cbor" - - "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/codec" + "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/multicodec" ) var ( - _ ipld.Decoder = Decode - _ ipld.Encoder = Encode + _ codec.Decoder = Decode + _ codec.Encoder = Encode ) func init() { @@ -19,26 +18,31 @@ func init() { multicodec.RegisterDecoder(0x71, Decode) } -func Decode(na ipld.NodeAssembler, r io.Reader) error { - // Probe for a builtin fast path. Shortcut to that if possible. - type detectFastPath interface { - DecodeDagCbor(io.Reader) error - } - if na2, ok := na.(detectFastPath); ok { - return na2.DecodeDagCbor(r) - } - // Okay, generic builder path. - return Unmarshal(na, cbor.NewDecoder(cbor.DecodeOptions{}, r)) +// Decode deserializes data from the given io.Reader and feeds it into the given datamodel.NodeAssembler. +// Decode fits the codec.Decoder function interface. +// +// A similar function is available on DecodeOptions type if you would like to customize any of the decoding details. +// This function uses the defaults for the dag-cbor codec +// (meaning: links (indicated by tag 42) are decoded). +// +// This is the function that will be registered in the default multicodec registry during package init time. +func Decode(na datamodel.NodeAssembler, r io.Reader) error { + return DecodeOptions{ + AllowLinks: true, + }.Decode(na, r) } -func Encode(n ipld.Node, w io.Writer) error { - // Probe for a builtin fast path. Shortcut to that if possible. - type detectFastPath interface { - EncodeDagCbor(io.Writer) error - } - if n2, ok := n.(detectFastPath); ok { - return n2.EncodeDagCbor(w) - } - // Okay, generic inspection path. - return Marshal(n, cbor.NewEncoder(w)) +// Encode walks the given datamodel.Node and serializes it to the given io.Writer. +// Encode fits the codec.Encoder function interface. +// +// A similar function is available on EncodeOptions type if you would like to customize any of the encoding details. +// This function uses the defaults for the dag-cbor codec +// (meaning: links are encoded, and map keys are sorted (with RFC7049 ordering!) during encode). +// +// This is the function that will be registered in the default multicodec registry during package init time. +func Encode(n datamodel.Node, w io.Writer) error { + return EncodeOptions{ + AllowLinks: true, + MapSortMode: codec.MapSortMode_RFC7049, + }.Encode(n, w) } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/unmarshal.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/unmarshal.go index ee066318..47c35f0a 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/unmarshal.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codec/dagcbor/unmarshal.go @@ -3,19 +3,23 @@ package dagcbor import ( "errors" "fmt" + "io" "math" cid "github.com/ipfs/go-cid" + "github.com/polydawn/refmt/cbor" "github.com/polydawn/refmt/shared" "github.com/polydawn/refmt/tok" - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" cidlink "github.com/ipld/go-ipld-prime/linking/cid" + "github.com/ipld/go-ipld-prime/node/basicnode" ) var ( ErrInvalidMultibase = errors.New("invalid multibase on IPLD link") ErrAllocationBudgetExceeded = errors.New("message structure demanded too many resources to process") + ErrTrailingBytes = errors.New("unexpected content after end of cbor object") ) const ( @@ -23,52 +27,122 @@ const ( listEntryGasScore = 4 ) -// This should be identical to the general feature in the parent package, +// This file should be identical to the general feature in the parent package, // except for the `case tok.TBytes` block, // which has dag-cbor's special sauce for detecting schemafree links. -func Unmarshal(na ipld.NodeAssembler, tokSrc shared.TokenSource) error { +// DecodeOptions can be used to customize the behavior of a decoding function. +// The Decode method on this struct fits the codec.Decoder function interface. +type DecodeOptions struct { + // If true, parse DAG-CBOR tag(42) as Link nodes, otherwise reject them + AllowLinks bool + + // TODO: ExperimentalDeterminism enforces map key order, but not the other parts + // of the spec such as integers or floats. See the fuzz failures spotted in + // https://github.com/ipld/go-ipld-prime/pull/389. + // When we're done implementing strictness, deprecate the option in favor of + // StrictDeterminism, but keep accepting both for backwards compatibility. + + // ExperimentalDeterminism requires decoded DAG-CBOR bytes to be canonical as per + // the spec. For example, this means that integers and floats be encoded in + // a particular way, and map keys be sorted. + // + // The decoder does not enforce this requirement by default, as the codec + // was originally implemented without these rules. Because of that, there's + // a significant amount of published data that isn't canonical but should + // still decode with the default settings for backwards compatibility. + // + // Note that this option is experimental as it only implements partial strictness. + ExperimentalDeterminism bool +} + +// Decode deserializes data from the given io.Reader and feeds it into the given datamodel.NodeAssembler. +// Decode fits the codec.Decoder function interface. +// +// The behavior of the decoder can be customized by setting fields in the DecodeOptions struct before calling this method. +func (cfg DecodeOptions) Decode(na datamodel.NodeAssembler, r io.Reader) error { + // Probe for a builtin fast path. Shortcut to that if possible. + type detectFastPath interface { + DecodeDagCbor(io.Reader) error + } + if na2, ok := na.(detectFastPath); ok { + return na2.DecodeDagCbor(r) + } + // Okay, generic builder path. + err := Unmarshal(na, cbor.NewDecoder(cbor.DecodeOptions{ + CoerceUndefToNull: true, + }, r), cfg) + + if err != nil { + return err + } + + var buf [1]byte + _, err = io.ReadFull(r, buf[:]) + switch err { + case io.EOF: + return nil + case nil: + return ErrTrailingBytes + default: + return err + } +} + +// Future work: we would like to remove the Unmarshal function, +// and in particular, stop seeing types from refmt (like shared.TokenSource) be visible. +// Right now, some kinds of configuration (e.g. for whitespace and prettyprint) are only available through interacting with the refmt types; +// we should improve our API so that this can be done with only our own types in this package. + +// Unmarshal is a deprecated function. +// Please consider switching to DecodeOptions.Decode instead. +func Unmarshal(na datamodel.NodeAssembler, tokSrc shared.TokenSource, options DecodeOptions) error { // Have a gas budget, which will be decremented as we allocate memory, and an error returned when execeeded (or about to be exceeded). // This is a DoS defense mechanism. // It's *roughly* in units of bytes (but only very, VERY roughly) -- it also treats words as 1 in many cases. // FUTURE: this ought be configurable somehow. (How, and at what granularity though?) - var gas int = 1048576 * 10 - return unmarshal1(na, tokSrc, &gas) + var gas int64 = 1048576 * 10 + return unmarshal1(na, tokSrc, &gas, options) } -func unmarshal1(na ipld.NodeAssembler, tokSrc shared.TokenSource, gas *int) error { +func unmarshal1(na datamodel.NodeAssembler, tokSrc shared.TokenSource, gas *int64, options DecodeOptions) error { var tk tok.Token done, err := tokSrc.Step(&tk) + if err == io.EOF { + return io.ErrUnexpectedEOF + } if err != nil { return err } - if done && !tk.Type.IsValue() { + if done && !tk.Type.IsValue() && tk.Type != tok.TNull { return fmt.Errorf("unexpected eof") } - return unmarshal2(na, tokSrc, &tk, gas) + return unmarshal2(na, tokSrc, &tk, gas, options) } // starts with the first token already primed. Necessary to get recursion -// to flow right without a peek+unpeek system. -func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, gas *int) error { +// +// to flow right without a peek+unpeek system. +func unmarshal2(na datamodel.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, gas *int64, options DecodeOptions) error { // FUTURE: check for schema.TypedNodeBuilder that's going to parse a Link (they can slurp any token kind they want). switch tk.Type { case tok.TMapOpen: - expectLen := tk.Length - allocLen := tk.Length + expectLen := int64(tk.Length) + allocLen := int64(tk.Length) if tk.Length == -1 { - expectLen = math.MaxInt32 + expectLen = math.MaxInt64 allocLen = 0 } else { if *gas-allocLen < 0 { // halt early if this will clearly demand too many resources return ErrAllocationBudgetExceeded } } - ma, err := na.BeginMap(int64(allocLen)) + ma, err := na.BeginMap(allocLen) if err != nil { return err } - observedLen := 0 + var observedLen int64 + lastKey := "" for { _, err := tokSrc.Step(tk) if err != nil { @@ -76,12 +150,12 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, } switch tk.Type { case tok.TMapClose: - if expectLen != math.MaxInt32 && observedLen != expectLen { + if expectLen != math.MaxInt64 && observedLen != expectLen { return fmt.Errorf("unexpected mapClose before declared length") } return ma.Finish() case tok.TString: - *gas -= len(tk.Str) + mapEntryGasScore + *gas -= int64(len(tk.Str) + mapEntryGasScore) if *gas < 0 { return ErrAllocationBudgetExceeded } @@ -93,11 +167,17 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, if observedLen > expectLen { return fmt.Errorf("unexpected continuation of map elements beyond declared length") } + if observedLen > 1 && options.ExperimentalDeterminism { + if len(lastKey) > len(tk.Str) || lastKey > tk.Str { + return fmt.Errorf("map key %q is not after %q as per RFC7049", tk.Str, lastKey) + } + } + lastKey = tk.Str mva, err := ma.AssembleEntry(tk.Str) if err != nil { // return in error if the key was rejected return err } - err = unmarshal1(mva, tokSrc, gas) + err = unmarshal1(mva, tokSrc, gas, options) if err != nil { // return in error if some part of the recursion errored return err } @@ -105,21 +185,21 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, case tok.TMapClose: return fmt.Errorf("unexpected mapClose token") case tok.TArrOpen: - expectLen := tk.Length - allocLen := tk.Length + expectLen := int64(tk.Length) + allocLen := int64(tk.Length) if tk.Length == -1 { - expectLen = math.MaxInt32 + expectLen = math.MaxInt64 allocLen = 0 } else { if *gas-allocLen < 0 { // halt early if this will clearly demand too many resources return ErrAllocationBudgetExceeded } } - la, err := na.BeginList(int64(allocLen)) + la, err := na.BeginList(allocLen) if err != nil { return err } - observedLen := 0 + var observedLen int64 for { _, err := tokSrc.Step(tk) if err != nil { @@ -127,7 +207,7 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, } switch tk.Type { case tok.TArrClose: - if expectLen != math.MaxInt32 && observedLen != expectLen { + if expectLen != math.MaxInt64 && observedLen != expectLen { return fmt.Errorf("unexpected arrClose before declared length") } return la.Finish() @@ -140,7 +220,7 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, if observedLen > expectLen { return fmt.Errorf("unexpected continuation of array elements beyond declared length") } - err := unmarshal2(la.AssembleValue(), tokSrc, tk, gas) + err := unmarshal2(la.AssembleValue(), tokSrc, tk, gas, options) if err != nil { // return in error if some part of the recursion errored return err } @@ -151,13 +231,13 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, case tok.TNull: return na.AssignNull() case tok.TString: - *gas -= len(tk.Str) + *gas -= int64(len(tk.Str)) if *gas < 0 { return ErrAllocationBudgetExceeded } return na.AssignString(tk.Str) case tok.TBytes: - *gas -= len(tk.Bytes) + *gas -= int64(len(tk.Bytes)) if *gas < 0 { return ErrAllocationBudgetExceeded } @@ -166,6 +246,9 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, } switch tk.Tag { case linkTag: + if !options.AllowLinks { + return fmt.Errorf("unhandled cbor tag %d", tk.Tag) + } if len(tk.Bytes) < 1 || tk.Bytes[0] != 0 { return ErrInvalidMultibase } @@ -173,7 +256,7 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, if err != nil { return err } - return na.AssignLink(cidlink.Link{elCid}) + return na.AssignLink(cidlink.Link{Cid: elCid}) default: return fmt.Errorf("unhandled cbor tag %d", tk.Tag) } @@ -194,7 +277,12 @@ func unmarshal2(na ipld.NodeAssembler, tokSrc shared.TokenSource, tk *tok.Token, if *gas < 0 { return ErrAllocationBudgetExceeded } - return na.AssignInt(int64(tk.Uint)) // FIXME overflow check + // note that this pushes any overflow errors up the stack when AsInt() may + // be called on a UintNode that is too large to cast to an int64 + if tk.Uint > math.MaxInt64 { + return na.AssignNode(basicnode.NewUint(tk.Uint)) + } + return na.AssignInt(int64(tk.Uint)) case tok.TFloat64: *gas -= 1 if *gas < 0 { diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codecHelpers.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codecHelpers.go new file mode 100644 index 00000000..7dcaa2dd --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/codecHelpers.go @@ -0,0 +1,170 @@ +package ipld + +import ( + "bytes" + "io" + "reflect" + + "github.com/ipld/go-ipld-prime/node/basicnode" + "github.com/ipld/go-ipld-prime/node/bindnode" + "github.com/ipld/go-ipld-prime/schema" +) + +// Encode serializes the given Node using the given Encoder function, +// returning the serialized data or an error. +// +// The exact result data will depend the node content and on the encoder function, +// but for example, using a json codec on a node with kind map will produce +// a result starting in `{`, etc. +// +// Encode will automatically switch to encoding the representation form of the Node, +// if it discovers the Node matches the schema.TypedNode interface. +// This is probably what you want, in most cases; +// if this is not desired, you can use the underlaying functions directly +// (just look at the source of this function for an example of how!). +// +// If you would like this operation, but applied directly to a golang type instead of a Node, +// look to the Marshal function. +func Encode(n Node, encFn Encoder) ([]byte, error) { + var buf bytes.Buffer + err := EncodeStreaming(&buf, n, encFn) + return buf.Bytes(), err +} + +// EncodeStreaming is like Encode, but emits output to an io.Writer. +func EncodeStreaming(wr io.Writer, n Node, encFn Encoder) error { + if tn, ok := n.(schema.TypedNode); ok { + n = tn.Representation() + } + return encFn(n, wr) +} + +// Decode parses the given bytes into a Node using the given Decoder function, +// returning a new Node or an error. +// +// The new Node that is returned will be the implementation from the node/basicnode package. +// This implementation of Node will work for storing any kind of data, +// but note that because it is general, it is also not necessarily optimized. +// If you want more control over what kind of Node implementation (and thus memory layout) is used, +// or want to use features like IPLD Schemas (which can be engaged by using a schema.TypedPrototype), +// then look to the DecodeUsingPrototype family of functions, +// which accept more parameters in order to give you that kind of control. +// +// If you would like this operation, but applied directly to a golang type instead of a Node, +// look to the Unmarshal function. +func Decode(b []byte, decFn Decoder) (Node, error) { + return DecodeUsingPrototype(b, decFn, basicnode.Prototype.Any) +} + +// DecodeStreaming is like Decode, but works on an io.Reader for input. +func DecodeStreaming(r io.Reader, decFn Decoder) (Node, error) { + return DecodeStreamingUsingPrototype(r, decFn, basicnode.Prototype.Any) +} + +// DecodeUsingPrototype is like Decode, but with a NodePrototype parameter, +// which gives you control over the Node type you'll receive, +// and thus control over the memory layout, and ability to use advanced features like schemas. +// (Decode is simply this function, but hardcoded to use basicnode.Prototype.Any.) +// +// DecodeUsingPrototype internally creates a NodeBuilder, and thows it away when done. +// If building a high performance system, and creating data of the same shape repeatedly, +// you may wish to use NodeBuilder directly, so that you can control and avoid these allocations. +// +// For symmetry with the behavior of Encode, DecodeUsingPrototype will automatically +// switch to using the representation form of the node for decoding +// if it discovers the NodePrototype matches the schema.TypedPrototype interface. +// This is probably what you want, in most cases; +// if this is not desired, you can use the underlaying functions directly +// (just look at the source of this function for an example of how!). +func DecodeUsingPrototype(b []byte, decFn Decoder, np NodePrototype) (Node, error) { + return DecodeStreamingUsingPrototype(bytes.NewReader(b), decFn, np) +} + +// DecodeStreamingUsingPrototype is like DecodeUsingPrototype, but works on an io.Reader for input. +func DecodeStreamingUsingPrototype(r io.Reader, decFn Decoder, np NodePrototype) (Node, error) { + if tnp, ok := np.(schema.TypedPrototype); ok { + np = tnp.Representation() + } + nb := np.NewBuilder() + if err := decFn(nb, r); err != nil { + return nil, err + } + return nb.Build(), nil +} + +// Marshal accepts a pointer to a Go value and an IPLD schema type, +// and encodes the representation form of that data (which may be configured with the schema!) +// using the given Encoder function. +// +// Marshal uses the node/bindnode subsystem. +// See the documentation in that package for more details about its workings. +// Please note that this subsystem is relatively experimental at this time. +// +// The schema.Type parameter is optional, and can be nil. +// If given, it controls what kind of schema.Type (and what kind of representation strategy!) +// to use when processing the data. +// If absent, a default schema.Type will be inferred based on the golang type +// (so, a struct in go will be inferred to have a schema with a similar struct, and the default representation strategy (e.g. map), etc). +// Note that not all features of IPLD Schemas can be inferred from golang types alone. +// For example, to use union types, the schema parameter will be required. +// Similarly, to use most kinds of non-default representation strategy, the schema parameter is needed in order to convey that intention. +func Marshal(encFn Encoder, bind interface{}, typ schema.Type) ([]byte, error) { + n := bindnode.Wrap(bind, typ) + return Encode(n.Representation(), encFn) +} + +// MarshalStreaming is like Marshal, but emits output to an io.Writer. +func MarshalStreaming(wr io.Writer, encFn Encoder, bind interface{}, typ schema.Type) error { + n := bindnode.Wrap(bind, typ) + return EncodeStreaming(wr, n.Representation(), encFn) +} + +// Unmarshal accepts a pointer to a Go value and an IPLD schema type, +// and fills the value with data by decoding into it with the given Decoder function. +// +// Unmarshal uses the node/bindnode subsystem. +// See the documentation in that package for more details about its workings. +// Please note that this subsystem is relatively experimental at this time. +// +// The schema.Type parameter is optional, and can be nil. +// If given, it controls what kind of schema.Type (and what kind of representation strategy!) +// to use when processing the data. +// If absent, a default schema.Type will be inferred based on the golang type +// (so, a struct in go will be inferred to have a schema with a similar struct, and the default representation strategy (e.g. map), etc). +// Note that not all features of IPLD Schemas can be inferred from golang types alone. +// For example, to use union types, the schema parameter will be required. +// Similarly, to use most kinds of non-default representation strategy, the schema parameter is needed in order to convey that intention. +// +// In contrast to some other unmarshal conventions common in golang, +// notice that we also return a Node value. +// This Node points to the same data as the value you handed in as the bind parameter, +// while making it available to read and iterate and handle as a ipld datamodel.Node. +// If you don't need that interface, or intend to re-bind it later, you can discard that value. +// +// The 'bind' parameter may be nil. +// In that case, the type of the nil is still used to infer what kind of value to return, +// and a Node will still be returned based on that type. +// bindnode.Unwrap can be used on that Node and will still return something +// of the same golang type as the typed nil that was given as the 'bind' parameter. +func Unmarshal(b []byte, decFn Decoder, bind interface{}, typ schema.Type) (Node, error) { + return UnmarshalStreaming(bytes.NewReader(b), decFn, bind, typ) +} + +// UnmarshalStreaming is like Unmarshal, but works on an io.Reader for input. +func UnmarshalStreaming(r io.Reader, decFn Decoder, bind interface{}, typ schema.Type) (Node, error) { + // Decode is fairly straightforward. + np := bindnode.Prototype(bind, typ) + n, err := DecodeStreamingUsingPrototype(r, decFn, np.Representation()) + if err != nil { + return nil, err + } + // ... but our approach above allocated new memory, and we have to copy it back out. + // In the future, the bindnode API could be improved to make this easier. + if !reflect.ValueOf(bind).IsNil() { + reflect.ValueOf(bind).Elem().Set(reflect.ValueOf(bindnode.Unwrap(n)).Elem()) + } + // ... and we also have to re-bind a new node to the 'bind' value, + // because probably the user will be surprised if mutating 'bind' doesn't affect the Node later. + n = bindnode.Wrap(bind, typ) + return n, err +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel.go new file mode 100644 index 00000000..888114e9 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel.go @@ -0,0 +1,114 @@ +package ipld + +import ( + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/linking" + "github.com/ipld/go-ipld-prime/schema" +) + +type ( + Kind = datamodel.Kind + Node = datamodel.Node + NodeAssembler = datamodel.NodeAssembler + NodeBuilder = datamodel.NodeBuilder + NodePrototype = datamodel.NodePrototype + MapIterator = datamodel.MapIterator + MapAssembler = datamodel.MapAssembler + ListIterator = datamodel.ListIterator + ListAssembler = datamodel.ListAssembler + + Link = datamodel.Link + LinkPrototype = datamodel.LinkPrototype + + Path = datamodel.Path + PathSegment = datamodel.PathSegment +) + +var ( + Null = datamodel.Null + Absent = datamodel.Absent +) + +const ( + Kind_Invalid = datamodel.Kind_Invalid + Kind_Map = datamodel.Kind_Map + Kind_List = datamodel.Kind_List + Kind_Null = datamodel.Kind_Null + Kind_Bool = datamodel.Kind_Bool + Kind_Int = datamodel.Kind_Int + Kind_Float = datamodel.Kind_Float + Kind_String = datamodel.Kind_String + Kind_Bytes = datamodel.Kind_Bytes + Kind_Link = datamodel.Kind_Link +) + +// Future: These aliases for the `KindSet_*` values may be dropped someday. +// I don't think they're very important to have cluttering up namespace here. +// They're included for a brief transitional period, largely for the sake of codegen things which have referred to them, but may disappear in the future. +var ( + KindSet_Recursive = datamodel.KindSet_Recursive + KindSet_Scalar = datamodel.KindSet_Scalar + KindSet_JustMap = datamodel.KindSet_JustMap + KindSet_JustList = datamodel.KindSet_JustList + KindSet_JustNull = datamodel.KindSet_JustNull + KindSet_JustBool = datamodel.KindSet_JustBool + KindSet_JustInt = datamodel.KindSet_JustInt + KindSet_JustFloat = datamodel.KindSet_JustFloat + KindSet_JustString = datamodel.KindSet_JustString + KindSet_JustBytes = datamodel.KindSet_JustBytes + KindSet_JustLink = datamodel.KindSet_JustLink +) + +// Future: These error type aliases may be dropped someday. +// Being able to see them as having more than one package name is not helpful to clarity. +// They are left here for now for a brief transitional period, because it was relatively easy to do so. +type ( + ErrWrongKind = datamodel.ErrWrongKind + ErrNotExists = datamodel.ErrNotExists + ErrRepeatedMapKey = datamodel.ErrRepeatedMapKey + ErrInvalidSegmentForList = datamodel.ErrInvalidSegmentForList + ErrIteratorOverread = datamodel.ErrIteratorOverread + ErrInvalidKey = schema.ErrInvalidKey + ErrMissingRequiredField = schema.ErrMissingRequiredField + ErrHashMismatch = linking.ErrHashMismatch +) + +// Future: a bunch of these alias methods for path creation may be dropped someday. +// They don't hurt anything, but I don't think they add much clarity either, vs the amount of namespace noise they create; +// many of the high level convenience functions we add here in the root package will probably refer to datamodel.Path, and that should be sufficient to create clarity for new users for where to look for more on pathing. +// They are here for now for a transitional period, but may eventually be revisited and perhaps removed. + +// NewPath is an alias for datamodel.NewPath. +// +// Pathing is a concept defined in the data model layer of IPLD. +func NewPath(segments []PathSegment) Path { + return datamodel.NewPath(segments) +} + +// ParsePath is an alias for datamodel.ParsePath. +// +// Pathing is a concept defined in the data model layer of IPLD. +func ParsePath(pth string) Path { + return datamodel.ParsePath(pth) +} + +// ParsePathSegment is an alias for datamodel.ParsePathSegment. +// +// Pathing is a concept defined in the data model layer of IPLD. +func ParsePathSegment(s string) PathSegment { + return datamodel.ParsePathSegment(s) +} + +// PathSegmentOfString is an alias for datamodel.PathSegmentOfString. +// +// Pathing is a concept defined in the data model layer of IPLD. +func PathSegmentOfString(s string) PathSegment { + return datamodel.PathSegmentOfString(s) +} + +// PathSegmentOfInt is an alias for datamodel.PathSegmentOfInt. +// +// Pathing is a concept defined in the data model layer of IPLD. +func PathSegmentOfInt(i int64) PathSegment { + return datamodel.PathSegmentOfInt(i) +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/copy.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/copy.go new file mode 100644 index 00000000..70adb8f8 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/copy.go @@ -0,0 +1,109 @@ +package datamodel + +import ( + "fmt" +) + +// Copy does an explicit shallow copy of a Node's data into a NodeAssembler. +// +// This can be used to flip data from one memory layout to another +// (for example, from basicnode to using using bindnode, +// or to codegenerated node implementations, +// or to or from ADL nodes, etc). +// +// The copy is implemented by ranging over the contents if it's a recursive kind, +// and for each of them, using `AssignNode` on the child values; +// for scalars, it's just calling the appropriate `Assign*` method. +// +// Many NodeAssembler implementations use this as a fallback behavior in their +// `AssignNode` method (that is, they call to this function after all other special +// faster shortcuts they might prefer to employ, such as direct struct copying +// if they share internal memory layouts, etc, have been tried already). +func Copy(n Node, na NodeAssembler) error { + switch n.Kind() { + case Kind_Null: + if n.IsAbsent() { + return fmt.Errorf("copying an absent node makes no sense") + } + return na.AssignNull() + case Kind_Bool: + v, err := n.AsBool() + if err != nil { + return fmt.Errorf("node violated contract: promised to be %v kind, but AsBool method returned %w", n.Kind(), err) + } + return na.AssignBool(v) + case Kind_Int: + v, err := n.AsInt() + if err != nil { + return fmt.Errorf("node violated contract: promised to be %v kind, but AsInt method returned %w", n.Kind(), err) + } + return na.AssignInt(v) + case Kind_Float: + v, err := n.AsFloat() + if err != nil { + return fmt.Errorf("node violated contract: promised to be %v kind, but AsFloat method returned %w", n.Kind(), err) + } + return na.AssignFloat(v) + case Kind_String: + v, err := n.AsString() + if err != nil { + return fmt.Errorf("node violated contract: promised to be %v kind, but AsString method returned %w", n.Kind(), err) + } + return na.AssignString(v) + case Kind_Bytes: + v, err := n.AsBytes() + if err != nil { + return fmt.Errorf("node violated contract: promised to be %v kind, but AsBytes method returned %w", n.Kind(), err) + } + return na.AssignBytes(v) + case Kind_Link: + v, err := n.AsLink() + if err != nil { + return fmt.Errorf("node violated contract: promised to be %v kind, but AsLink method returned %w", n.Kind(), err) + } + return na.AssignLink(v) + case Kind_Map: + ma, err := na.BeginMap(n.Length()) + if err != nil { + return err + } + itr := n.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if v.IsAbsent() { + continue + } + if err := ma.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := ma.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return ma.Finish() + case Kind_List: + la, err := na.BeginList(n.Length()) + if err != nil { + return err + } + itr := n.ListIterator() + for !itr.Done() { + _, v, err := itr.Next() + if err != nil { + return err + } + if v.IsAbsent() { + continue + } + if err := la.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return la.Finish() + default: + return fmt.Errorf("node has invalid kind %v", n.Kind()) + } +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/doc.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/doc.go new file mode 100644 index 00000000..1f3b9316 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/doc.go @@ -0,0 +1,13 @@ +// The datamodel package defines the most essential interfaces for describing IPLD Data -- +// such as Node, NodePrototype, NodeBuilder, Link, and Path. +// +// Note that since interfaces in this package are the core of the library, +// choices made here maximize correctness and performance -- these choices +// are *not* always the choices that would maximize ergonomics. +// (Ergonomics can come on top; performance generally can't.) +// You'll want to check out other packages for functions with more ergonomics; +// for example, 'fluent' and its subpackages provide lots of ways to work with data; +// 'traversal' provides some ergonomic features for walking around data graphs; +// any use of schemas will provide a bunch of useful data validation options; +// or you can make your own function decorators that do what *you* need. +package datamodel diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/equal.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/equal.go new file mode 100644 index 00000000..8c476113 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/equal.go @@ -0,0 +1,156 @@ +package datamodel + +// DeepEqual reports whether x and y are "deeply equal" as IPLD nodes. +// This is similar to reflect.DeepEqual, but based around the Node interface. +// +// Two nodes must have the same kind to be deeply equal. +// If either node has the invalid kind, the nodes are not deeply equal. +// +// Two nodes of scalar kinds (null, bool, int, float, string, bytes, link) +// are deeply equal if their Go values, as returned by AsKind methods, are equal as +// per Go's == comparison operator. +// +// Note that Links are compared in a shallow way, without being followed. +// This will generally be enough, as it's rare to have two different links to the +// same IPLD data by using a different codec or multihash type. +// +// Two nodes of recursive kinds (map, list) +// must have the same length to be deeply equal. +// Their elements, as reported by iterators, must be deeply equal. +// The elements are compared in the iterator's order, +// meaning two maps sorting the same keys differently might not be equal. +// +// Note that this function panics if either Node returns an error. +// We only call valid methods for each Kind, +// so an error should only happen if a Node implementation breaks that contract. +// It is generally not recommended to call DeepEqual on ADL nodes. +func DeepEqual(x, y Node) bool { + if x == nil || y == nil { + return x == y + } + xk, yk := x.Kind(), y.Kind() + if xk != yk { + return false + } + + switch xk { + + // Scalar kinds. + case Kind_Null: + return x.IsNull() == y.IsNull() + case Kind_Bool: + xv, err := x.AsBool() + if err != nil { + panic(err) + } + yv, err := y.AsBool() + if err != nil { + panic(err) + } + return xv == yv + case Kind_Int: + xv, err := x.AsInt() + if err != nil { + panic(err) + } + yv, err := y.AsInt() + if err != nil { + panic(err) + } + return xv == yv + case Kind_Float: + xv, err := x.AsFloat() + if err != nil { + panic(err) + } + yv, err := y.AsFloat() + if err != nil { + panic(err) + } + return xv == yv + case Kind_String: + xv, err := x.AsString() + if err != nil { + panic(err) + } + yv, err := y.AsString() + if err != nil { + panic(err) + } + return xv == yv + case Kind_Bytes: + xv, err := x.AsBytes() + if err != nil { + panic(err) + } + yv, err := y.AsBytes() + if err != nil { + panic(err) + } + return string(xv) == string(yv) + case Kind_Link: + xv, err := x.AsLink() + if err != nil { + panic(err) + } + yv, err := y.AsLink() + if err != nil { + panic(err) + } + // Links are just compared via ==. + // This requires the types to exactly match, + // and the values to be equal as per == too. + // This will generally work, + // as ipld-prime assumes link types to be consistent. + return xv == yv + + // Recursive kinds. + case Kind_Map: + if x.Length() != y.Length() { + return false + } + xitr := x.MapIterator() + yitr := y.MapIterator() + for !xitr.Done() && !yitr.Done() { + xkey, xval, err := xitr.Next() + if err != nil { + panic(err) + } + ykey, yval, err := yitr.Next() + if err != nil { + panic(err) + } + if !DeepEqual(xkey, ykey) { + return false + } + if !DeepEqual(xval, yval) { + return false + } + } + return true + case Kind_List: + if x.Length() != y.Length() { + return false + } + xitr := x.ListIterator() + yitr := y.ListIterator() + for !xitr.Done() && !yitr.Done() { + _, xval, err := xitr.Next() + if err != nil { + panic(err) + } + _, yval, err := yitr.Next() + if err != nil { + panic(err) + } + if !DeepEqual(xval, yval) { + return false + } + } + return true + + // As per the docs, other kinds such as Invalid are not deeply equal. + default: + return false + } +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/errors.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/errors.go new file mode 100644 index 00000000..58bfd640 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/errors.go @@ -0,0 +1,107 @@ +package datamodel + +import ( + "fmt" +) + +// ErrWrongKind may be returned from functions on the Node interface when +// a method is invoked which doesn't make sense for the Kind that node +// concretely contains. +// +// For example, calling AsString on a map will return ErrWrongKind. +// Calling Lookup on an int will similarly return ErrWrongKind. +type ErrWrongKind struct { + // TypeName may optionally indicate the named type of a node the function + // was called on (if the node was typed!), or, may be the empty string. + TypeName string + + // MethodName is literally the string for the operation attempted, e.g. + // "AsString". + // + // For methods on nodebuilders, we say e.g. "NodeBuilder.CreateMap". + MethodName string + + // ApprorpriateKind describes which Kinds the erroring method would + // make sense for. + AppropriateKind KindSet + + // ActualKind describes the Kind of the node the method was called on. + // + // In the case of typed nodes, this will typically refer to the 'natural' + // data-model kind for such a type (e.g., structs will say 'map' here). + ActualKind Kind + + // TODO: it may be desirable for this error to be able to describe the schema typekind, too, if applicable. + // Of course this presents certain package import graph problems. Solution to this that maximizes user usability is unclear. +} + +func (e ErrWrongKind) Error() string { + if e.TypeName == "" { + return fmt.Sprintf("func called on wrong kind: %q called on a %s node, but only makes sense on %s", e.MethodName, e.ActualKind, e.AppropriateKind) + } else { + return fmt.Sprintf("func called on wrong kind: %q called on a %s node (kind: %s), but only makes sense on %s", e.MethodName, e.TypeName, e.ActualKind, e.AppropriateKind) + } +} + +// TODO: revisit the claim below about ErrNoSuchField. I think we moved back away from that, or want to. + +// ErrNotExists may be returned from the lookup functions of the Node interface +// to indicate a missing value. +// +// Note that schema.ErrNoSuchField is another type of error which sometimes +// occurs in similar places as ErrNotExists. ErrNoSuchField is preferred +// when handling data with constraints provided by a schema that mean that +// a field can *never* exist (as differentiated from a map key which is +// simply absent in some data). +type ErrNotExists struct { + Segment PathSegment +} + +func (e ErrNotExists) Error() string { + return fmt.Sprintf("key not found: %q", e.Segment) +} + +// ErrRepeatedMapKey is an error indicating that a key was inserted +// into a map that already contains that key. +// +// This error may be returned by any methods that add data to a map -- +// any of the methods on a NodeAssembler that was yielded by MapAssembler.AssignKey(), +// or from the MapAssembler.AssignDirectly() method. +type ErrRepeatedMapKey struct { + Key Node +} + +func (e ErrRepeatedMapKey) Error() string { + return fmt.Sprintf("cannot repeat map key %q", e.Key) +} + +// ErrInvalidSegmentForList is returned when using Node.LookupBySegment and the +// given PathSegment can't be applied to a list because it's unparsable as a number. +type ErrInvalidSegmentForList struct { + // TypeName may indicate the named type of a node the function was called on, + // or be empty string if working on untyped data. + TypeName string + + // TroubleSegment is the segment we couldn't use. + TroubleSegment PathSegment + + // Reason may explain more about why the PathSegment couldn't be used; + // in practice, it's probably a 'strconv.NumError'. + Reason error +} + +func (e ErrInvalidSegmentForList) Error() string { + v := "invalid segment for lookup on a list" + if e.TypeName != "" { + v += " of type " + e.TypeName + } + return v + fmt.Sprintf(": %q: %s", e.TroubleSegment.s, e.Reason) +} + +// ErrIteratorOverread is returned when calling 'Next' on a MapIterator or +// ListIterator when it is already done. +type ErrIteratorOverread struct{} + +func (e ErrIteratorOverread) Error() string { + return "iterator overread" +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/kind.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/kind.go similarity index 96% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/kind.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/kind.go index 3e5e1af3..fe6e8368 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/kind.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/kind.go @@ -1,4 +1,4 @@ -package ipld +package datamodel // Kind represents the primitive kind in the IPLD data model. // All of these kinds map directly onto serializable data. @@ -69,6 +69,9 @@ var ( ) func (x KindSet) String() string { + if len(x) == 0 { + return "" + } s := "" for i := 0; i < len(x)-1; i++ { s += x[i].String() + " or " diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/link.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/link.go similarity index 59% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/link.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/link.go index 104fbbd0..f52354ad 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/link.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/link.go @@ -1,8 +1,4 @@ -package ipld - -import ( - "context" -) +package datamodel // Link is a special kind of value in IPLD which can be "loaded" to access more nodes. // @@ -13,7 +9,7 @@ import ( // but when "loaded", the result can be any other IPLD kind: // maps, lists, strings, etc. // -// Link is an interface in the go-ipld-prime implementation, +// Link is an interface in the go-ipld implementation, // but the most common instantiation of it comes from the `linking/cid` package, // and represents CIDs (see https://github.com/multiformats/cid). // @@ -38,12 +34,25 @@ type Link interface { // There is no contract that requires that the string be able to be parsed back into a Link value, // but the string should be unique (e.g. not elide any parts of the hash). String() string + + // Binary should return the densest possible encoding of the Link. + // The value need not be printable or human-readable; + // the golang string type is used for immutability and for ease of use as a map key. + // As with the String method, the returned value may not elide any parts of the hash. + // + // Note that there is still no contract that the returned value be able to be parsed back into a Link value; + // not even in the case of `lnk.Prototype().BuildLink(lnk.Binary()[:])`. + // This is because the value returned by this method may contain data that the LinkPrototype would also restate. + // (For a concrete example: if using CIDs, this method will return a binary string that includes + // the cid version indicator, the multicodec and multihash indicators, etc, in addition to the hash itself -- + // whereas the LinkPrototype.BuildLink function still expects to receive only the hash itself alone.) + Binary() string } // LinkPrototype encapsulates any implementation details and parameters // necessary for creating a Link, expect for the hash result itself. // -// LinkPrototype, like Link, is an interface in go-ipld-prime, +// LinkPrototype, like Link, is an interface in go-ipld, // but the most common instantiation of it comes from the `linking/cid` package, // and represents CIDs (see https://github.com/multiformats/cid). // If using CIDs as an implementation, LinkPrototype will encapsulate information @@ -57,43 +66,3 @@ type LinkPrototype interface { // The hashsum reference must not be retained (the caller is free to reuse it). BuildLink(hashsum []byte) Link } - -// LinkContext is a structure carrying ancilary information that may be used -// while loading or storing data -- see its usage in BlockReadOpener, BlockWriteOpener, -// and in the methods on LinkSystem which handle loading and storing data. -// -// A zero value for LinkContext is generally acceptable in any functions that use it. -// In this case, any operations that need a Context will use Context.Background -// (thus being uncancellable) and simply have no additional information to work with. -type LinkContext struct { - // Ctx is the familiar golang Context pattern. - // Use this for cancellation, or attaching additional info - // (for example, perhaps to pass auth tokens through to the storage functions). - Ctx context.Context - - // Path where the link was encountered. May be zero. - // - // Functions in the traversal package will set this automatically. - LinkPath Path - - // When traversing data or encoding: the Node containing the link -- - // it may have additional type info, etc, that can be accessed. - // When building / decoding: not present. - // - // Functions in the traversal package will set this automatically. - LinkNode Node - - // When building data or decoding: the NodeAssembler that will be receiving the link -- - // it may have additional type info, etc, that can be accessed. - // When traversing / encoding: not present. - // - // Functions in the traversal package will set this automatically. - LinkNodeAssembler NodeAssembler - - // Parent of the LinkNode. May be zero. - // - // Functions in the traversal package will set this automatically. - ParentNode Node - - // REVIEW: ParentNode in LinkContext -- so far, this has only ever been hypothetically useful. Keep or drop? -} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/node.go similarity index 81% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/node.go index 61139be1..625f472d 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/node.go @@ -1,4 +1,6 @@ -package ipld +package datamodel + +import "io" // Node represents a value in IPLD. Any point in a tree of data is a node: // scalar values (like int64, string, etc) are nodes, and @@ -41,7 +43,7 @@ package ipld // // For concrete implementations of Node, check out the "./node/" folder, // and the packages within it. -// "node/basic" should probably be your first start; the Node and NodeBuilder +// "node/basicnode" should probably be your first start; the Node and NodeBuilder // implementations in that package work for any data. // Other packages are optimized for specific use-cases. // Codegen tools can also be used to produce concrete implementations of Node; @@ -114,13 +116,16 @@ type Node interface { // before itr.Done becomes true. MapIterator() MapIterator - // ListIterator returns an iterator which yields key-value pairs - // traversing the node. + // ListIterator returns an iterator which traverses the node and yields indicies and list entries. // If the node kind is anything other than a list, nil will be returned. // // The iterator will yield every entry in the list; that is, it // can be expected that itr.Next will be called node.Length times // before itr.Done becomes true. + // + // List iteration is ordered, and indices yielded during iteration will range from 0 to Node.Length-1. + // (The IPLD Data Model definition of lists only defines that it is an ordered list of elements; + // the definition does not include a concept of sparseness, so the indices are always sequential.) ListIterator() ListIterator // Length returns the length of a list, or the number of entries in a map, @@ -162,17 +167,38 @@ type Node interface { Prototype() NodePrototype } -// ADL represents an Advanced Data Layout, a special kind of Node which -// implements custom logic while still behaving like an IPLD node. +// UintNode is an optional interface that can be used to represent an Int node +// that provides access to the full uint64 range. // -// For more details, see the docs at -// https://github.com/ipld/specs/blob/master/schemas/authoring-guide.md. -type ADL interface { +// EXPERIMENTAL: this API is experimental and may be changed or removed in a +// future use. A future iteration may replace this with a BigInt interface to +// access a larger range of integers that may be enabled by alternative codecs. +type UintNode interface { Node - // Substrate returns the underlying Data Model node, which can be used - // to encode an ADL's raw layout. - Substrate() Node + // AsUint returns a uint64 representing the underlying integer if possible. + // This may return an error if the Node represents a negative integer that + // cannot be represented as a uint64. + AsUint() (uint64, error) +} + +// LargeBytesNode is an optional interface extending a Bytes node that allows its +// contents to be accessed through an io.ReadSeeker instead of a []byte slice. Use of +// an io.Reader is encouraged, as it allows for streaming large byte slices +// without allocating a large slice in memory. +type LargeBytesNode interface { + Node + // AsLargeBytes returns an io.ReadSeeker that can be used to read the contents of the node. + // Note that the presence of this method / interface does not imply that the node + // can always return a valid io.ReadSeeker, and the error value must also be checked + // for support. + // It is not guaranteed that all implementations will implement the full semantics of + // Seek, in particular, they may refuse to seek to the end of a large bytes node if + // it is not possible to do so efficiently. + // The io.ReadSeeker returned by AsLargeBytes must be a seperate instance from subsequent + // calls to AsLargeBytes. Calls to read or seek on one returned instance should NOT + // affect the read position of other returned instances. + AsLargeBytes() (io.ReadSeeker, error) } // NodePrototype describes a node implementation (all Node have a NodePrototype), @@ -236,8 +262,10 @@ type MapIterator interface { // An error value can also be returned at any step: in the case of advanced // data structures with incremental loading, it's possible to encounter // cancellation or I/O errors at any point in iteration. - // If an error is returned, the boolean will always be false (so it's - // correct to check the bool first and short circuit to continuing if true). + // If an error will be returned by the next call to Next, + // then the boolean returned by the Done method will be false + // (meaning it's acceptable to check Done first and move on if it's true, + // since that both means the iterator is complete and that there is no error). // If an error is returned, the key and value may be nil. Next() (key Node, value Node, err error) @@ -256,16 +284,20 @@ type MapIterator interface { // Sequential calls to Next() will yield index-value pairs; // Done() describes whether iteration should continue. // -// A loop which iterates from 0 to Node.Length is a valid -// alternative to using a ListIterator. +// ListIterator's Next method returns an index for convenience, +// but this number will always start at 0 and increment by 1 monotonically. +// A loop which iterates from 0 to Node.Length while calling Node.LookupByIndex +// is equivalent to using a ListIterator. type ListIterator interface { // Next returns the next index and value. // // An error value can also be returned at any step: in the case of advanced // data structures with incremental loading, it's possible to encounter // cancellation or I/O errors at any point in iteration. - // If an error is returned, the boolean will always be false (so it's - // correct to check the bool first and short circuit to continuing if true). + // If an error will be returned by the next call to Next, + // then the boolean returned by the Done method will be false + // (meaning it's acceptable to check Done first and move on if it's true, + // since that both means the iterator is complete and that there is no error). // If an error is returned, the key and value may be nil. Next() (idx int64, value Node, err error) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/nodeBuilder.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/nodeBuilder.go similarity index 73% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/nodeBuilder.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/nodeBuilder.go index 7b197ccf..4ff03cc5 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/nodeBuilder.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/nodeBuilder.go @@ -1,18 +1,38 @@ -package ipld +package datamodel // NodeAssembler is the interface that describes all the ways we can set values // in a node that's under construction. // -// To create a Node, you should start with a NodeBuilder (which contains a +// A NodeAssembler is about filling in data. +// To create a new Node, you should start with a NodeBuilder (which contains a // superset of the NodeAssembler methods, and can return the finished Node // from its `Build` method). +// While continuing to build a recursive structure from there, +// you'll see NodeAssembler for all the child values. +// +// For filling scalar data, there's a `Assign{Kind}` method for each kind; +// after calling one of these methods, the data is filled in, and the assembler is done. +// For recursives, there are `BeginMap` and `BeginList` methods, +// which return an object that needs further manipulation to fill in the contents. +// +// There is also one special method: `AssignNode`. +// `AssignNode` takes another `Node` as a parameter, +// and should should internally call one of the other `Assign*` or `Begin*` (and subsequent) functions +// as appropriate for the kind of the `Node` it is given. +// This is roughly equivalent to using the `Copy` function (and is often implemented using it!), but +// `AssignNode` may also try to take faster shortcuts in some implementations, when it detects they're possible. +// (For example, for typed nodes, if they're the same type, lots of checking can be skipped. +// For nodes implemented with pointers, lots of copying can be skipped. +// For nodes that can detect the argument has the same memory layout, faster copy mechanisms can be used; etc.) // // Why do both this and the NodeBuilder interface exist? -// When creating trees of nodes, recursion works over the NodeAssembler interface. -// This is important to efficient library internals, because avoiding the +// In short: NodeBuilder is when you want to cause an allocation; +// NodeAssembler can be used to just "fill in" memory. +// (In the internal gritty details: separate interfaces, one of which lacks a +// `Build` method, helps us write efficient library internals: avoiding the // requirement to be able to return a Node at any random point in the process // relieves internals from needing to implement 'freeze' features. -// (This is useful in turn because implementing those 'freeze' features in a +// This is useful in turn because implementing those 'freeze' features in a // language without first-class/compile-time support for them (as golang is) // would tend to push complexity and costs to execution time; we'd rather not.) type NodeAssembler interface { @@ -69,7 +89,8 @@ type MapAssembler interface { // just feed data and check errors), but it's here. // // For all Data Model maps, this will answer with a basic concept of "string". - // For Schema typed maps, this may answer with a more complex type (potentially even a struct type). + // For Schema typed maps, this may answer with a more complex type + // (potentially even a struct type or union type -- anything that can have a string representation). KeyPrototype() NodePrototype // ValuePrototype returns a NodePrototype that knows how to build values this map can contain. @@ -128,6 +149,14 @@ type NodeBuilder interface { // all responsibility for validating the assembled data and returning // any errors from that process. // (Correspondingly, there is no error return from this method.) + // + // Note that building via a representation-level NodePrototype or NodeBuilder + // returns a node at the type level which implements schema.TypedNode. + // To obtain the representation-level node, you can do: + // + // // builder is at the representation level, so it returns typed nodes + // node := builder.Build().(schema.TypedNode) + // reprNode := node.Representation() Build() Node // Resets the builder. It can hereafter be used again. diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/path.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/path.go similarity index 94% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/path.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/path.go index 9a49bdac..b336b6fa 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/path.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/path.go @@ -1,4 +1,4 @@ -package ipld +package datamodel import ( "strings" @@ -171,7 +171,7 @@ func (p Path) Join(p2 Path) Path { return p } -// AppendSegmentString is as per Join, but a shortcut when appending single segments using strings. +// AppendSegment is as per Join, but a shortcut when appending single segments. func (p Path) AppendSegment(ps PathSegment) Path { l := len(p.segments) combinedSegments := make([]PathSegment, l+1) @@ -181,11 +181,16 @@ func (p Path) AppendSegment(ps PathSegment) Path { return p } -// AppendSegmentString is as per Join, but a shortcut when appending single segments using strings. +// AppendSegmentString is as per AppendSegment, but a shortcut when the segment is a string. func (p Path) AppendSegmentString(ps string) Path { return p.AppendSegment(PathSegmentOfString(ps)) } +// AppendSegmentInt is as per AppendSegment, but a shortcut when the segment is an int. +func (p Path) AppendSegmentInt(ps int64) Path { + return p.AppendSegment(PathSegmentOfInt(ps)) +} + // Parent returns a path with the last of its segments popped off (or // the zero path if it's already empty). func (p Path) Parent() Path { @@ -208,6 +213,14 @@ func (p Path) Last() PathSegment { return p.segments[len(p.segments)-1] } +// Pop returns a path with all segments except the last. +func (p Path) Pop() Path { + if len(p.segments) < 1 { + return Path{} + } + return Path{p.segments[0 : len(p.segments)-1]} +} + // Shift returns the first segment of the path together with the remaining path after that first segment. // If applied to a zero-length path, it returns an empty segment and the same zero-length path. func (p Path) Shift() (PathSegment, Path) { diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/pathSegment.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/pathSegment.go similarity index 99% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/pathSegment.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/pathSegment.go index 94badb78..e6bf3aa3 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/pathSegment.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/pathSegment.go @@ -1,4 +1,4 @@ -package ipld +package datamodel import ( "strconv" @@ -35,7 +35,6 @@ import ( // You should probably use the string values of the PathSegment as map keys. // (This has the additional bonus of hitting a special fastpath that the golang // built-in maps have specifically for plain string keys.) -// type PathSegment struct { /* A quick implementation note about the Go compiler and "union" semantics: diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/unit.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/unit.go similarity index 73% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/unit.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/unit.go index 8cc4647f..afc2e3e1 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/unit.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/datamodel/unit.go @@ -1,5 +1,11 @@ -package ipld +package datamodel +// Null is the one kind of node we can have a true singleton implementation of. +// This is that value. +// The Null Node has Kind() == Kind_Null, returns IsNull() == true, +// returns ErrWrongKind to most other inquiries (as you'd expect), +// and returns a NodePrototype with a NewBuilder method that simply panics +// (because why would you ever try to build a new "null"?). var Null Node = nullNode{} type nullNode struct{} @@ -59,9 +65,26 @@ func (nullNode) Prototype() NodePrototype { type nullPrototype struct{} func (nullPrototype) NewBuilder() NodeBuilder { - panic("cannot build null nodes") // TODO: okay, fine, we could grind out a simple closing of the loop here. + panic("cannot build null nodes") } +// Absent is the _other_ kind of node (besides Null) we can have a true singleton implementation of. +// This is the singleton value for Absent. +// The Absent Node has Kind() == Kind_Null, returns IsNull() == false (!), +// returns IsAbsent() == true, +// returns ErrWrongKind to most other inquiries (as you'd expect), +// and returns a NodePrototype with a NewBuilder method that simply panics +// (because why would you ever try to build a new "nothing"?). +// +// Despite its presence in the datamodel package, "absent" is not really a data model concept. +// Absent should not really be seen in any datamodel Node implementations, for example. +// Absent is seen used in the realm of schemas and typed data, because there, +// there's a concept of data that has been described, and yet is not currently present; +// it is this concept that "absent" is used to express. +// Absent also sometimes shows up as a distinct case in codecs or other diagnostic printing, +// and suchlike miscellaneous places; it is for these reasons that it's here in the datamodel package, +// because it would end up imported somewhat universally for those diagnostic purposes anyway. +// (This may be worth a design review at some point, but holds up well enough for now.) var Absent Node = absentNode{} type absentNode struct{} @@ -121,5 +144,5 @@ func (absentNode) Prototype() NodePrototype { type absentPrototype struct{} func (absentPrototype) NewBuilder() NodeBuilder { - panic("cannot build absent nodes") // this definitely stays true. + panic("cannot build absent nodes") } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/doc.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/doc.go index f304558a..5aca0d84 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/doc.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/doc.go @@ -1,50 +1,68 @@ // go-ipld-prime is a series of go interfaces for manipulating IPLD data. // -// See https://github.com/ipld/specs for more information about the basics +// See https://ipld.io/ for more information about the basics // of "What is IPLD?". // -// See https://github.com/ipld/go-ipld-prime/tree/master/doc/README.md -// for more documentation about go-ipld-prime's architecture and usage. -// // Here in the godoc, the first couple of types to look at should be: // // - Node -// - NodeBuilder (and NodeAssembler) +// - NodeBuilder and NodeAssembler +// - NodePrototype. // // These types provide a generic description of the data model. // +// A Node is a piece of IPLD data which can be inspected. +// A NodeAssembler is used to create Nodes. +// (A NodeBuilder is just like a NodeAssembler, but allocates memory +// (whereas a NodeAssembler just fills up memory; using these carefully +// allows construction of very efficient code.) +// +// Different NodePrototypes can be used to describe Nodes which follow certain logical rules +// (e.g., we use these as part of implementing Schemas), +// and can also be used so that programs can use different memory layouts for different data +// (which can be useful for constructing efficient programs when data has known shape for +// which we can use specific or compacted memory layouts). +// // If working with linked data (data which is split into multiple // trees of Nodes, loaded separately, and connected by some kind of // "link" reference), the next types you should look at are: // -// - Link -// - LinkBuilder -// - Loader -// - Storer +// - LinkSystem +// - ... and its fields. // -// All of these types are interfaces. There are several implementations you -// can choose; we've provided some in subpackages, or you can bring your own. +// The most typical use of LinkSystem is to use the linking/cid package +// to get a LinkSystem that works with CIDs: // -// Particularly interesting subpackages include: +// lsys := cidlink.DefaultLinkSystem() // -// - node/* -- various Node + NodeBuilder implementations -// - node/basic -- the first Node implementation you should try -// - codec/* -- functions for serializing and deserializing Nodes -// - linking/* -- various Link + LinkBuilder implementations -// - traversal -- functions for walking Node graphs (including -// automatic link loading) and visiting -// - must -- helpful functions for streamlining error handling -// - fluent -- alternative Node interfaces that flip errors to panics -// - schema -- interfaces for working with IPLD Schemas and Nodes -// which use Schema types and constraints -// -// Note that since interfaces in this package are the core of the library, -// choices made here maximize correctness and performance -- these choices -// are *not* always the choices that would maximize ergonomics. -// (Ergonomics can come on top; performance generally can't.) -// You can check out the 'must' or 'fluent' packages for more ergonomics; -// 'traversal' provides some ergnomics features for certain uses; -// any use of schemas with codegen tooling will provide more ergnomic options; -// or you can make your own function decorators that do what *you* need. +// ... and then assign the StorageWriteOpener and StorageReadOpener fields +// in order to control where data is stored to and read from. +// Methods on the LinkSystem then provide the functions typically used +// to get data in and out of Nodes so you can work with it. +// +// This root package gathers some of the most important ease-of-use functions +// all in one place, but is mostly aliases out to features originally found +// in other more specific sub-packages. (If you're interested in keeping +// your binary sizes small, and don't use some of the features of this library, +// you'll probably want to look into using the relevant sub-packages directly.) +// +// Particularly interesting subpackages include: // +// - datamodel -- the most essential interfaces for describing data live here, +// describing Node, NodePrototype, NodeBuilder, Link, and Path. +// - node/* -- various Node + NodeBuilder implementations. +// - node/basicnode -- the first Node implementation you should try. +// - codec/* -- functions for serializing and deserializing Nodes. +// - linking -- the LinkSystem, which is a facade to all data loading and storing and hashing. +// - linking/* -- ways to bind concrete Link implementations (namely, +// the linking/cidlink package, which connects the go-cid library to our datamodel.Link interface). +// - traversal -- functions for walking Node graphs (including automatic link loading) +// and visiting them programmatically. +// - traversal/selector -- functions for working with IPLD Selectors, +// which are a language-agnostic declarative format for describing graph walks. +// - fluent/* -- various options for making datamodel Node and NodeBuilder easier to work with. +// - schema -- interfaces for working with IPLD Schemas, which can bring constraints +// and validation systems to otherwise schemaless and unstructured IPLD data. +// - adl/* -- examples of creating and using Advanced Data Layouts (in short, custom Node implementations) +// to do complex data structures transparently within the IPLD Data Model. package ipld diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/errors.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/errors.go deleted file mode 100644 index 2376d94b..00000000 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/errors.go +++ /dev/null @@ -1,185 +0,0 @@ -package ipld - -import ( - "fmt" - "strings" -) - -// ErrWrongKind may be returned from functions on the Node interface when -// a method is invoked which doesn't make sense for the Kind that node -// concretely contains. -// -// For example, calling AsString on a map will return ErrWrongKind. -// Calling Lookup on an int will similarly return ErrWrongKind. -type ErrWrongKind struct { - // TypeName may optionally indicate the named type of a node the function - // was called on (if the node was typed!), or, may be the empty string. - TypeName string - - // MethodName is literally the string for the operation attempted, e.g. - // "AsString". - // - // For methods on nodebuilders, we say e.g. "NodeBuilder.CreateMap". - MethodName string - - // ApprorpriateKind describes which Kinds the erroring method would - // make sense for. - AppropriateKind KindSet - - // ActualKind describes the Kind of the node the method was called on. - // - // In the case of typed nodes, this will typically refer to the 'natural' - // data-model kind for such a type (e.g., structs will say 'map' here). - ActualKind Kind -} - -func (e ErrWrongKind) Error() string { - if e.TypeName == "" { - return fmt.Sprintf("func called on wrong kind: %s called on a %s node, but only makes sense on %s", e.MethodName, e.ActualKind, e.AppropriateKind) - } else { - return fmt.Sprintf("func called on wrong kind: %s called on a %s node (kind: %s), but only makes sense on %s", e.MethodName, e.TypeName, e.ActualKind, e.AppropriateKind) - } -} - -// ErrNotExists may be returned from the lookup functions of the Node interface -// to indicate a missing value. -// -// Note that schema.ErrNoSuchField is another type of error which sometimes -// occurs in similar places as ErrNotExists. ErrNoSuchField is preferred -// when handling data with constraints provided by a schema that mean that -// a field can *never* exist (as differentiated from a map key which is -// simply absent in some data). -type ErrNotExists struct { - Segment PathSegment -} - -func (e ErrNotExists) Error() string { - return fmt.Sprintf("key not found: %q", e.Segment) -} - -// ErrRepeatedMapKey is an error indicating that a key was inserted -// into a map that already contains that key. -// -// This error may be returned by any methods that add data to a map -- -// any of the methods on a NodeAssembler that was yielded by MapAssembler.AssignKey(), -// or from the MapAssembler.AssignDirectly() method. -type ErrRepeatedMapKey struct { - Key Node -} - -func (e ErrRepeatedMapKey) Error() string { - return fmt.Sprintf("cannot repeat map key %q", e.Key) -} - -// ErrInvalidKey indicates a key is invalid for some reason. -// -// This is only possible for typed nodes; specifically, it may show up when -// handling struct types, or maps with interesting key types. -// (Other kinds of key invalidity that happen for untyped maps -// fall under ErrRepeatedMapKey or ErrWrongKind.) -// (Union types use ErrInvalidUnionDiscriminant instead of ErrInvalidKey, -// even when their representation strategy is maplike.) -type ErrInvalidKey struct { - // TypeName will indicate the named type of a node the function was called on. - TypeName string - - // Key is the key that was rejected. - Key Node - - // Reason, if set, may provide details (for example, the reason a key couldn't be converted to a type). - // If absent, it'll be presumed "no such field". - // ErrUnmatchable may show up as a reason for typed maps with complex keys. - Reason error -} - -func (e ErrInvalidKey) Error() string { - if e.Reason == nil { - return fmt.Sprintf("invalid key for map %s: %q: no such field", e.TypeName, e.Key) - } else { - return fmt.Sprintf("invalid key for map %s: %q: %s", e.TypeName, e.Key, e.Reason) - } -} - -// ErrInvalidSegmentForList is returned when using Node.LookupBySegment and the -// given PathSegment can't be applied to a list because it's unparsable as a number. -type ErrInvalidSegmentForList struct { - // TypeName may indicate the named type of a node the function was called on, - // or be empty string if working on untyped data. - TypeName string - - // TroubleSegment is the segment we couldn't use. - TroubleSegment PathSegment - - // Reason may explain more about why the PathSegment couldn't be used; - // in practice, it's probably a 'strconv.NumError'. - Reason error -} - -func (e ErrInvalidSegmentForList) Error() string { - v := "invalid segment for lookup on a list" - if e.TypeName != "" { - v += " of type " + e.TypeName - } - return v + fmt.Sprintf(": %q: %s", e.TroubleSegment.s, e.Reason) -} - -// ErrHashMismatch is the error returned when loading data and verifying its hash -// and finding that the loaded data doesn't re-hash to the expected value. -// It is typically seen returned by functions like LinkSystem.Load or LinkSystem.Fill. -type ErrHashMismatch struct { - Actual Link - Expected Link -} - -func (e ErrHashMismatch) Error() string { - return fmt.Sprintf("hash mismatch! %v (actual) != %v (expected)", e.Actual, e.Expected) -} - -// ErrUnmatchable is the error raised when processing data with IPLD Schemas and -// finding data which cannot be matched into the schema. -// It will be returned by NodeAssemblers and NodeBuilders when they are fed unmatchable data. -// As a result, it will also often be seen returned from unmarshalling -// when unmarshalling into schema-constrained NodeAssemblers. -// -// ErrUnmatchable provides the name of the type in the schema that data couldn't be matched to, -// and wraps another error as the more detailed reason. -type ErrUnmatchable struct { - // TypeName will indicate the named type of a node the function was called on. - TypeName string - - // Reason must always be present. ErrUnmatchable doesn't say much otherwise. - Reason error -} - -func (e ErrUnmatchable) Error() string { - return fmt.Sprintf("matching data to schema of %s rejected: %s", e.TypeName, e.Reason) -} - -// Reasonf returns a new ErrUnmatchable with a Reason field set to the Errorf of the arguments. -// It's a helper function for creating untyped error reasons without importing the fmt package. -func (e ErrUnmatchable) Reasonf(format string, a ...interface{}) ErrUnmatchable { - return ErrUnmatchable{e.TypeName, fmt.Errorf(format, a...)} -} - -// ErrIteratorOverread is returned when calling 'Next' on a MapIterator or -// ListIterator when it is already done. -type ErrIteratorOverread struct{} - -func (e ErrIteratorOverread) Error() string { - return "iterator overread" -} - -type ErrCannotBeNull struct{} // Review: arguably either ErrInvalidKindForNodePrototype. - -// ErrMissingRequiredField is returned when calling 'Finish' on a NodeAssembler -// for a Struct that has not has all required fields set. -type ErrMissingRequiredField struct { - Missing []string -} - -func (e ErrMissingRequiredField) Error() string { - return "missing required fields: " + strings.Join(e.Missing, ",") -} - -type ErrListOverrun struct{} // only possible for typed nodes -- specifically, struct types with list (aka tuple) representations. -type ErrInvalidUnionDiscriminant struct{} // only possible for typed nodes -- specifically, union types. diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking.go index 658e2622..4e0c7a73 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking.go @@ -1,169 +1,17 @@ package ipld import ( - "context" - "io" + "github.com/ipld/go-ipld-prime/linking" ) -// This file contains all the functions on LinkSystem. -// These are the helpful, user-facing functions we expect folks to use "most of the time" when loading and storing data. - -// Varations: -// - Load vs Store vs ComputeLink -// - With or without LinkContext? -// - Brevity would be nice but I can't think of what to name the functions, so: everything takes LinkContext. Zero value is fine though. -// - [for load direction only]: Prototype (and return Node|error) or Assembler (and just return error)? -// - naming: Load vs Fill. -// - 'Must' variants. - -// Can we get as far as a `QuickLoad(lnk Link) (Node, error)` function, which doesn't even ask you for a NodePrototype? -// No, not quite. (Alas.) If we tried to do so, and make it use `basicnode.Prototype`, we'd have import cycles; ded. - -func (lsys *LinkSystem) Load(lnkCtx LinkContext, lnk Link, np NodePrototype) (Node, error) { - nb := np.NewBuilder() - if err := lsys.Fill(lnkCtx, lnk, nb); err != nil { - return nil, err - } - return nb.Build(), nil -} - -func (lsys *LinkSystem) MustLoad(lnkCtx LinkContext, lnk Link, np NodePrototype) Node { - if n, err := lsys.Load(lnkCtx, lnk, np); err != nil { - panic(err) - } else { - return n - } -} - -func (lsys *LinkSystem) Fill(lnkCtx LinkContext, lnk Link, na NodeAssembler) error { - if lnkCtx.Ctx == nil { - lnkCtx.Ctx = context.Background() - } - // Choose all the parts. - decoder, err := lsys.DecoderChooser(lnk) - if err != nil { - return ErrLinkingSetup{"could not choose a decoder", err} - } - hasher, err := lsys.HasherChooser(lnk.Prototype()) - if err != nil { - return ErrLinkingSetup{"could not choose a hasher", err} - } - if lsys.StorageReadOpener == nil { - return ErrLinkingSetup{"no storage configured for reading", io.ErrClosedPipe} // REVIEW: better cause? - } - // Open storage, read it, verify it, and feed the codec to assemble the nodes. - // We have two paths through this: if a `Bytes() []byte` method is handy, we'll assume it's faster than going through reader. - // These diverge significantly, because if we give up on streaming, it makes sense to do the full hash check first before decoding at all. - reader, err := lsys.StorageReadOpener(lnkCtx, lnk) - if err != nil { - return err - } - if buf, ok := reader.(interface{ Bytes() []byte }); ok { - // Flush everything to the hasher in one big slice. - hasher.Write(buf.Bytes()) - hash := hasher.Sum(nil) - // Bit of a jig to get something we can do the hash equality check on. - lnk2 := lnk.Prototype().BuildLink(hash) - if lnk2 != lnk { - return ErrHashMismatch{Actual: lnk2, Expected: lnk} - } - // Perform decoding (knowing the hash is already verified). - // Note that the decoder recieves the same reader as we started with, - // and as a result, is also free to detect a `Bytes() []byte` accessor and do any optimizations it wishes to based on that. - return decoder(na, reader) - } else { - // Tee the stream so that the hasher is fed as the unmarshal progresses through the stream. - // Note: the tee means *the decoder doesn't get to see the original reader type*. - // This is part of why the `Bytes() []byte` branch above is useful; the decoder loses any ability to do a similar check - // and optimization when the tee is in the middle. - tee := io.TeeReader(reader, hasher) - decodeErr := decoder(na, tee) - if decodeErr != nil { // It is important to security to check the hash before returning any other observation about the content. - // This copy is for data remaining the block that wasn't already pulled through the TeeReader by the decoder. - _, err := io.Copy(hasher, reader) - if err != nil { - return err - } - } - hash := hasher.Sum(nil) - // Bit of a jig to get something we can do the hash equality check on. - lnk2 := lnk.Prototype().BuildLink(hash) - if lnk2 != lnk { - return ErrHashMismatch{Actual: lnk2, Expected: lnk} - } - if decodeErr != nil { - return decodeErr - } - return nil - } -} - -func (lsys *LinkSystem) MustFill(lnkCtx LinkContext, lnk Link, na NodeAssembler) { - if err := lsys.Fill(lnkCtx, lnk, na); err != nil { - panic(err) - } -} - -func (lsys *LinkSystem) Store(lnkCtx LinkContext, lp LinkPrototype, n Node) (Link, error) { - if lnkCtx.Ctx == nil { - lnkCtx.Ctx = context.Background() - } - // Choose all the parts. - encoder, err := lsys.EncoderChooser(lp) - if err != nil { - return nil, ErrLinkingSetup{"could not choose an encoder", err} - } - hasher, err := lsys.HasherChooser(lp) - if err != nil { - return nil, ErrLinkingSetup{"could not choose a hasher", err} - } - if lsys.StorageWriteOpener == nil { - return nil, ErrLinkingSetup{"no storage configured for writing", io.ErrClosedPipe} // REVIEW: better cause? - } - // Open storage write stream, feed serial data to the storage and the hasher, and funnel the codec output into both. - writer, commitFn, err := lsys.StorageWriteOpener(lnkCtx) - if err != nil { - return nil, err - } - tee := io.MultiWriter(writer, hasher) - err = encoder(n, tee) - if err != nil { - return nil, err - } - lnk := lp.BuildLink(hasher.Sum(nil)) - return lnk, commitFn(lnk) -} - -func (lsys *LinkSystem) MustStore(lnkCtx LinkContext, lp LinkPrototype, n Node) Link { - if lnk, err := lsys.Store(lnkCtx, lp, n); err != nil { - panic(err) - } else { - return lnk - } -} - -// ComputeLink returns a Link for the given data, but doesn't do anything else -// (e.g. it doesn't try to store any of the serial-form data anywhere else). -func (lsys *LinkSystem) ComputeLink(lp LinkPrototype, n Node) (Link, error) { - encoder, err := lsys.EncoderChooser(lp) - if err != nil { - return nil, ErrLinkingSetup{"could not choose an encoder", err} - } - hasher, err := lsys.HasherChooser(lp) - if err != nil { - return nil, ErrLinkingSetup{"could not choose a hasher", err} - } - err = encoder(n, hasher) - if err != nil { - return nil, err - } - return lp.BuildLink(hasher.Sum(nil)), nil -} +type ( + LinkSystem = linking.LinkSystem + LinkContext = linking.LinkContext +) -func (lsys *LinkSystem) MustComputeLink(lp LinkPrototype, n Node) Link { - if lnk, err := lsys.ComputeLink(lp, n); err != nil { - panic(err) - } else { - return lnk - } -} +type ( + BlockReadOpener = linking.BlockReadOpener + BlockWriteOpener = linking.BlockWriteOpener + BlockWriteCommitter = linking.BlockWriteCommitter + NodeReifier = linking.NodeReifier +) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/cidLink.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/cidLink.go index 31f1e703..9685ce61 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/cidLink.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/cidLink.go @@ -4,38 +4,41 @@ import ( "fmt" cid "github.com/ipfs/go-cid" - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" multihash "github.com/multiformats/go-multihash" ) var ( - _ ipld.Link = Link{} - _ ipld.LinkPrototype = LinkPrototype{} + _ datamodel.Link = Link{} + _ datamodel.LinkPrototype = LinkPrototype{} ) -// Link implements the ipld.Link interface using a CID. +// Link implements the datamodel.Link interface using a CID. // See https://github.com/ipfs/go-cid for more information about CIDs. // // When using this value, typically you'll use it as `Link`, and not `*Link`. -// This includes when handling the value as an `ipld.Link` interface -- the non-pointer form is typically preferable. -// This is because the ipld.Link inteface is often desirable to be able to use as a golang map key, +// This includes when handling the value as an `datamodel.Link` interface -- the non-pointer form is typically preferable. +// This is because the datamodel.Link inteface is often desirable to be able to use as a golang map key, // and in that context, pointers would not result in the desired behavior. type Link struct { cid.Cid } -func (lnk Link) Prototype() ipld.LinkPrototype { +func (lnk Link) Prototype() datamodel.LinkPrototype { return LinkPrototype{lnk.Cid.Prefix()} } func (lnk Link) String() string { return lnk.Cid.String() } +func (lnk Link) Binary() string { + return lnk.Cid.KeyString() +} type LinkPrototype struct { cid.Prefix } -func (lp LinkPrototype) BuildLink(hashsum []byte) ipld.Link { +func (lp LinkPrototype) BuildLink(hashsum []byte) datamodel.Link { // Does this method body look surprisingly complex? I agree. // We actually have to do all this work. The go-cid package doesn't expose a constructor that just lets us directly set the bytes and the prefix numbers next to each other. // No, `cid.Prefix.Sum` is not the method you are looking for: that expects the whole data body. @@ -45,7 +48,7 @@ func (lp LinkPrototype) BuildLink(hashsum []byte) ipld.Link { p := lp.Prefix length := p.MhLength - if p.MhType == multihash.ID { + if p.MhType == multihash.IDENTITY { length = -1 } if p.Version == 0 && (p.MhType != multihash.SHA2_256 || diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/linksystem.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/linksystem.go index 2c5a996a..89b7a790 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/linksystem.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/linksystem.go @@ -6,16 +6,34 @@ import ( "github.com/multiformats/go-multihash/core" - "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/codec" + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/linking" "github.com/ipld/go-ipld-prime/multicodec" ) -func DefaultLinkSystem() ipld.LinkSystem { - return ipld.LinkSystem{ - EncoderChooser: func(lp ipld.LinkPrototype) (ipld.Encoder, error) { +// DefaultLinkSystem returns a linking.LinkSystem which uses cidlink.Link for datamodel.Link. +// During selection of encoders, decoders, and hashers, it examines the multicodec indicator numbers and multihash indicator numbers from the CID, +// and uses the default global multicodec registry (see the go-ipld-prime/multicodec package) for resolving codec implementations, +// and the default global multihash registry (see the go-multihash/core package) for resolving multihash implementations. +// +// No storage functions are present in the returned LinkSystem. +// The caller can assign those themselves as desired. +func DefaultLinkSystem() linking.LinkSystem { + return LinkSystemUsingMulticodecRegistry(multicodec.DefaultRegistry) +} + +// LinkSystemUsingMulticodecRegistry is similar to DefaultLinkSystem, but accepts a multicodec.Registry as a parameter. +// +// This can help create a LinkSystem which uses different multicodec implementations than the global registry. +// (Sometimes this can be desired if you want some parts of a program to support a more limited suite of codecs than other parts of the program, +// or needed to use a different multicodec registry than the global one for synchronization purposes, or etc.) +func LinkSystemUsingMulticodecRegistry(mcReg multicodec.Registry) linking.LinkSystem { + return linking.LinkSystem{ + EncoderChooser: func(lp datamodel.LinkPrototype) (codec.Encoder, error) { switch lp2 := lp.(type) { case LinkPrototype: - fn, err := multicodec.LookupEncoder(lp2.GetCodec()) + fn, err := mcReg.LookupEncoder(lp2.GetCodec()) if err != nil { return nil, err } @@ -24,11 +42,11 @@ func DefaultLinkSystem() ipld.LinkSystem { return nil, fmt.Errorf("this encoderChooser can only handle cidlink.LinkPrototype; got %T", lp) } }, - DecoderChooser: func(lnk ipld.Link) (ipld.Decoder, error) { + DecoderChooser: func(lnk datamodel.Link) (codec.Decoder, error) { lp := lnk.Prototype() switch lp2 := lp.(type) { case LinkPrototype: - fn, err := multicodec.LookupDecoder(lp2.GetCodec()) + fn, err := mcReg.LookupDecoder(lp2.GetCodec()) if err != nil { return nil, err } @@ -37,7 +55,7 @@ func DefaultLinkSystem() ipld.LinkSystem { return nil, fmt.Errorf("this decoderChooser can only handle cidlink.LinkPrototype; got %T", lp) } }, - HasherChooser: func(lp ipld.LinkPrototype) (hash.Hash, error) { + HasherChooser: func(lp datamodel.LinkPrototype) (hash.Hash, error) { switch lp2 := lp.(type) { case LinkPrototype: h, err := multihash.GetHasher(lp2.MhType) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/memorystorage.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/memorystorage.go new file mode 100644 index 00000000..cf1e3849 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/cid/memorystorage.go @@ -0,0 +1,56 @@ +package cidlink + +import ( + "bytes" + "fmt" + "io" + "os" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/linking" +) + +// Memory is a simple in-memory storage for cidlinks. It's the same as `storage.Memory` +// but uses typical multihash semantics used when reading/writing cidlinks. +// +// Using multihash as the storage key rather than the whole CID will remove the +// distinction between CIDv0 and their CIDv1 counterpart. It also removes the +// distinction between CIDs where the multihash is the same but the codec is +// different, e.g. `dag-cbor` and a `raw` version of the same data. +type Memory struct { + Bag map[string][]byte +} + +func (store *Memory) beInitialized() { + if store.Bag != nil { + return + } + store.Bag = make(map[string][]byte) +} + +func (store *Memory) OpenRead(lnkCtx linking.LinkContext, lnk datamodel.Link) (io.Reader, error) { + store.beInitialized() + cl, ok := lnk.(Link) + if !ok { + return nil, fmt.Errorf("incompatible link type: %T", lnk) + } + data, exists := store.Bag[string(cl.Hash())] + if !exists { + return nil, os.ErrNotExist + } + return bytes.NewReader(data), nil +} + +func (store *Memory) OpenWrite(lnkCtx linking.LinkContext) (io.Writer, linking.BlockWriteCommitter, error) { + store.beInitialized() + buf := bytes.Buffer{} + return &buf, func(lnk datamodel.Link) error { + cl, ok := lnk.(Link) + if !ok { + return fmt.Errorf("incompatible link type: %T", lnk) + } + + store.Bag[string(cl.Hash())] = buf.Bytes() + return nil + }, nil +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/errors.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/errors.go new file mode 100644 index 00000000..1c3b549c --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/errors.go @@ -0,0 +1,30 @@ +package linking + +import ( + "fmt" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +// ErrLinkingSetup is returned by methods on LinkSystem when some part of the system is not set up correctly, +// or when one of the components refuses to handle a Link or LinkPrototype given. +// (It is not yielded for errors from the storage nor codec systems once they've started; those errors rise without interference.) +type ErrLinkingSetup struct { + Detail string // Perhaps an enum here as well, which states which internal function was to blame? + Cause error +} + +func (e ErrLinkingSetup) Error() string { return fmt.Sprintf("%s: %v", e.Detail, e.Cause) } +func (e ErrLinkingSetup) Unwrap() error { return e.Cause } + +// ErrHashMismatch is the error returned when loading data and verifying its hash +// and finding that the loaded data doesn't re-hash to the expected value. +// It is typically seen returned by functions like LinkSystem.Load or LinkSystem.Fill. +type ErrHashMismatch struct { + Actual datamodel.Link + Expected datamodel.Link +} + +func (e ErrHashMismatch) Error() string { + return fmt.Sprintf("hash mismatch! %v (actual) != %v (expected)", e.Actual, e.Expected) +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/functions.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/functions.go new file mode 100644 index 00000000..af0e72e9 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/functions.go @@ -0,0 +1,290 @@ +package linking + +import ( + "bytes" + "context" + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +// This file contains all the functions on LinkSystem. +// These are the helpful, user-facing functions we expect folks to use "most of the time" when loading and storing data. + +// Varations: +// - Load vs Store vs ComputeLink +// - Load vs LoadPlusRaw +// - With or without LinkContext? +// - Brevity would be nice but I can't think of what to name the functions, so: everything takes LinkContext. Zero value is fine though. +// - [for load direction only]: Prototype (and return Node|error) or Assembler (and just return error)? +// - naming: Load vs Fill. +// - 'Must' variants. + +// Can we get as far as a `QuickLoad(lnk Link) (Node, error)` function, which doesn't even ask you for a NodePrototype? +// No, not quite. (Alas.) If we tried to do so, and make it use `basicnode.Prototype`, we'd have import cycles; ded. + +// Load looks up some data identified by a Link, and does everything necessary to turn it into usable data. +// In detail, that means it: +// brings that data into memory, +// verifies the hash, +// parses it into the Data Model using a codec, +// and returns an IPLD Node. +// +// Where the data will be loaded from is determined by the configuration of the LinkSystem +// (namely, the StorageReadOpener callback, which can either be set directly, +// or configured via the SetReadStorage function). +// +// The in-memory form used for the returned Node is determined by the given NodePrototype parameter. +// A new builder and a new node will be allocated, via NodePrototype.NewBuilder. +// (If you'd like more control over memory allocation, you may wish to see the Fill function instead.) +// +// A schema may also be used, and apply additional data validation during loading, +// by using a schema.TypedNodePrototype as the NodePrototype argument. +// +// The LinkContext parameter may be used to pass contextual information down to the loading layer. +// +// Which hashing function is used to validate the loaded data is determined by LinkSystem.HasherChooser. +// Which codec is used to parse the loaded data into the Data Model is determined by LinkSystem.DecoderChooser. +// +// The LinkSystem.NodeReifier callback is also applied before returning the Node, +// and so Load may also thereby return an ADL. +func (lsys *LinkSystem) Load(lnkCtx LinkContext, lnk datamodel.Link, np datamodel.NodePrototype) (datamodel.Node, error) { + nb := np.NewBuilder() + if err := lsys.Fill(lnkCtx, lnk, nb); err != nil { + return nil, err + } + nd := nb.Build() + if lsys.NodeReifier == nil { + return nd, nil + } + return lsys.NodeReifier(lnkCtx, nd, lsys) +} + +// MustLoad is identical to Load, but panics in the case of errors. +// +// This function is meant for convenience of use in test and demo code, but should otherwise probably be avoided. +func (lsys *LinkSystem) MustLoad(lnkCtx LinkContext, lnk datamodel.Link, np datamodel.NodePrototype) datamodel.Node { + if n, err := lsys.Load(lnkCtx, lnk, np); err != nil { + panic(err) + } else { + return n + } +} + +// LoadPlusRaw is similar to Load, but additionally retains and returns the byte slice of the raw data parsed. +// +// Be wary of using this with large data, since it will hold all data in memory at once. +// For more control over streaming, you may want to construct a LinkSystem where you wrap the storage opener callbacks, +// and thus can access the streams (and tee them, or whatever you need to do) as they're opened. +// This function is meant for convenience when data sizes are small enough that fitting them into memory at once is not a problem. +func (lsys *LinkSystem) LoadPlusRaw(lnkCtx LinkContext, lnk datamodel.Link, np datamodel.NodePrototype) (datamodel.Node, []byte, error) { + // Choose all the parts. + decoder, err := lsys.DecoderChooser(lnk) + if err != nil { + return nil, nil, ErrLinkingSetup{"could not choose a decoder", err} + } + // Use LoadRaw to get the data. + // If we're going to have everything in memory at once, we might as well do that first, and then give the codec and the hasher the whole thing at once. + block, err := lsys.LoadRaw(lnkCtx, lnk) + if err != nil { + return nil, block, err + } + // Create a NodeBuilder. + // Deploy the codec. + // Build the node. + nb := np.NewBuilder() + if err := decoder(nb, bytes.NewBuffer(block)); err != nil { + return nil, block, err + } + nd := nb.Build() + // Consider applying NodeReifier, if applicable. + if lsys.NodeReifier == nil { + return nd, block, nil + } + nd, err = lsys.NodeReifier(lnkCtx, nd, lsys) + return nd, block, err +} + +// LoadRaw looks up some data identified by a Link, brings that data into memory, +// verifies the hash, and returns it directly as a byte slice. +// +// LoadRaw does not return a data model view of the data, +// nor does it verify that a codec can parse the data at all! +// Use this function at your own risk; it does not provide the same guarantees as the Load or Fill functions do. +func (lsys *LinkSystem) LoadRaw(lnkCtx LinkContext, lnk datamodel.Link) ([]byte, error) { + if lnkCtx.Ctx == nil { + lnkCtx.Ctx = context.Background() + } + // Choose all the parts. + hasher, err := lsys.HasherChooser(lnk.Prototype()) + if err != nil { + return nil, ErrLinkingSetup{"could not choose a hasher", err} + } + if lsys.StorageReadOpener == nil { + return nil, ErrLinkingSetup{"no storage configured for reading", io.ErrClosedPipe} // REVIEW: better cause? + } + // Open storage: get the data. + // FUTURE: this could probably use storage.ReadableStorage.Get instead of streaming and a buffer, if we refactored LinkSystem to carry that interface through. + reader, err := lsys.StorageReadOpener(lnkCtx, lnk) + if err != nil { + return nil, err + } + if closer, ok := reader.(io.Closer); ok { + defer closer.Close() + } + var buf bytes.Buffer + if _, err := io.Copy(&buf, reader); err != nil { + return nil, err + } + // Compute the hash. + // (Then do a bit of a jig to build a link out of it -- because that's what we do the actual hash equality check on.) + hasher.Write(buf.Bytes()) + hash := hasher.Sum(nil) + lnk2 := lnk.Prototype().BuildLink(hash) + if lnk2 != lnk { + return nil, ErrHashMismatch{Actual: lnk2, Expected: lnk} + } + // No codec to deploy; this is the raw load function. + // So we're done. + return buf.Bytes(), nil +} + +// Fill is similar to Load, but allows more control over memory allocations. +// Instead of taking a NodePrototype parameter, Fill takes a NodeAssembler parameter: +// this allows you to use your own NodeBuilder (and reset it, etc, thus controlling allocations), +// or, to fill in some part of a larger structure. +// +// Note that Fill does not regard NodeReifier, even if one has been configured. +// (This is in contrast to Load, which does regard a NodeReifier if one is configured, and thus may return an ADL node). +func (lsys *LinkSystem) Fill(lnkCtx LinkContext, lnk datamodel.Link, na datamodel.NodeAssembler) error { + if lnkCtx.Ctx == nil { + lnkCtx.Ctx = context.Background() + } + // Choose all the parts. + decoder, err := lsys.DecoderChooser(lnk) + if err != nil { + return ErrLinkingSetup{"could not choose a decoder", err} + } + hasher, err := lsys.HasherChooser(lnk.Prototype()) + if err != nil { + return ErrLinkingSetup{"could not choose a hasher", err} + } + if lsys.StorageReadOpener == nil { + return ErrLinkingSetup{"no storage configured for reading", io.ErrClosedPipe} // REVIEW: better cause? + } + // Open storage; get a reader stream. + reader, err := lsys.StorageReadOpener(lnkCtx, lnk) + if err != nil { + return err + } + if closer, ok := reader.(io.Closer); ok { + defer closer.Close() + } + // TrustedStorage indicates the data coming out of this reader has already been hashed and verified earlier. + // As a result, we can skip rehashing it + if lsys.TrustedStorage { + return decoder(na, reader) + } + // Tee the stream so that the hasher is fed as the unmarshal progresses through the stream. + tee := io.TeeReader(reader, hasher) + // The actual read is then dragged forward by the codec. + decodeErr := decoder(na, tee) + if decodeErr != nil { + // It is important to security to check the hash before returning any other observation about the content, + // so, if the decode process returns any error, we have several steps to take before potentially returning it. + // First, we try to copy any data remaining that wasn't already pulled through the TeeReader by the decoder, + // so that the hasher can reach the end of the stream. + // If _that_ errors, return the I/O level error. + // We hang onto decodeErr for a while: we can't return that until all the way after we check the hash equality. + _, err := io.Copy(hasher, reader) + if err != nil { + return err + } + } + // Compute the hash. + // (Then do a bit of a jig to build a link out of it -- because that's what we do the actual hash equality check on.) + hash := hasher.Sum(nil) + lnk2 := lnk.Prototype().BuildLink(hash) + if lnk2 != lnk { + return ErrHashMismatch{Actual: lnk2, Expected: lnk} + } + // If we got all the way through IO and through the hash check: + // now, finally, if we did get an error from the codec, we can admit to that. + if decodeErr != nil { + return decodeErr + } + return nil +} + +// MustFill is identical to Fill, but panics in the case of errors. +// +// This function is meant for convenience of use in test and demo code, but should otherwise probably be avoided. +func (lsys *LinkSystem) MustFill(lnkCtx LinkContext, lnk datamodel.Link, na datamodel.NodeAssembler) { + if err := lsys.Fill(lnkCtx, lnk, na); err != nil { + panic(err) + } +} + +func (lsys *LinkSystem) Store(lnkCtx LinkContext, lp datamodel.LinkPrototype, n datamodel.Node) (datamodel.Link, error) { + if lnkCtx.Ctx == nil { + lnkCtx.Ctx = context.Background() + } + // Choose all the parts. + encoder, err := lsys.EncoderChooser(lp) + if err != nil { + return nil, ErrLinkingSetup{"could not choose an encoder", err} + } + hasher, err := lsys.HasherChooser(lp) + if err != nil { + return nil, ErrLinkingSetup{"could not choose a hasher", err} + } + if lsys.StorageWriteOpener == nil { + return nil, ErrLinkingSetup{"no storage configured for writing", io.ErrClosedPipe} // REVIEW: better cause? + } + // Open storage write stream, feed serial data to the storage and the hasher, and funnel the codec output into both. + writer, commitFn, err := lsys.StorageWriteOpener(lnkCtx) + if err != nil { + return nil, err + } + tee := io.MultiWriter(writer, hasher) + err = encoder(n, tee) + if err != nil { + return nil, err + } + lnk := lp.BuildLink(hasher.Sum(nil)) + return lnk, commitFn(lnk) +} + +func (lsys *LinkSystem) MustStore(lnkCtx LinkContext, lp datamodel.LinkPrototype, n datamodel.Node) datamodel.Link { + if lnk, err := lsys.Store(lnkCtx, lp, n); err != nil { + panic(err) + } else { + return lnk + } +} + +// ComputeLink returns a Link for the given data, but doesn't do anything else +// (e.g. it doesn't try to store any of the serial-form data anywhere else). +func (lsys *LinkSystem) ComputeLink(lp datamodel.LinkPrototype, n datamodel.Node) (datamodel.Link, error) { + encoder, err := lsys.EncoderChooser(lp) + if err != nil { + return nil, ErrLinkingSetup{"could not choose an encoder", err} + } + hasher, err := lsys.HasherChooser(lp) + if err != nil { + return nil, ErrLinkingSetup{"could not choose a hasher", err} + } + err = encoder(n, hasher) + if err != nil { + return nil, err + } + return lp.BuildLink(hasher.Sum(nil)), nil +} + +func (lsys *LinkSystem) MustComputeLink(lp datamodel.LinkPrototype, n datamodel.Node) datamodel.Link { + if lnk, err := lsys.ComputeLink(lp, n); err != nil { + panic(err) + } else { + return lnk + } +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/setup.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/setup.go new file mode 100644 index 00000000..6d3175c7 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/setup.go @@ -0,0 +1,41 @@ +package linking + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/storage" +) + +// SetReadStorage configures how the LinkSystem will look for information to load, +// setting it to look at the given storage.ReadableStorage. +// +// This will overwrite the LinkSystem.StorageReadOpener field. +// +// This mechanism only supports setting exactly one ReadableStorage. +// If you would like to make a more complex configuration +// (for example, perhaps using information from a LinkContext to decide which storage area to use?) +// then you should set LinkSystem.StorageReadOpener to a custom callback of your own creation instead. +func (lsys *LinkSystem) SetReadStorage(store storage.ReadableStorage) { + lsys.StorageReadOpener = func(lctx LinkContext, lnk datamodel.Link) (io.Reader, error) { + return storage.GetStream(lctx.Ctx, store, lnk.Binary()) + } +} + +// SetWriteStorage configures how the LinkSystem will store information, +// setting it to write into the given storage.WritableStorage. +// +// This will overwrite the LinkSystem.StorageWriteOpener field. +// +// This mechanism only supports setting exactly one WritableStorage. +// If you would like to make a more complex configuration +// (for example, perhaps using information from a LinkContext to decide which storage area to use?) +// then you should set LinkSystem.StorageWriteOpener to a custom callback of your own creation instead. +func (lsys *LinkSystem) SetWriteStorage(store storage.WritableStorage) { + lsys.StorageWriteOpener = func(lctx LinkContext) (io.Writer, BlockWriteCommitter, error) { + wr, wrcommit, err := storage.PutStream(lctx.Ctx, store) + return wr, func(lnk datamodel.Link) error { + return wrcommit(lnk.Binary()) + }, err + } +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linksystem.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/types.go similarity index 54% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/linksystem.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/types.go index 88942198..84fd36e7 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linksystem.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/linking/types.go @@ -1,9 +1,12 @@ -package ipld +package linking import ( - "fmt" + "context" "hash" "io" + + "github.com/ipld/go-ipld-prime/codec" + "github.com/ipld/go-ipld-prime/datamodel" ) // LinkSystem is a struct that composes all the individual functions @@ -27,86 +30,16 @@ import ( // Custom wrapping of BlockWriteOpener and BlockReadOpener are also common, // and may be reasonable if one wants to build application features that are block-aware. type LinkSystem struct { - EncoderChooser func(LinkPrototype) (Encoder, error) - DecoderChooser func(Link) (Decoder, error) - HasherChooser func(LinkPrototype) (hash.Hash, error) + EncoderChooser func(datamodel.LinkPrototype) (codec.Encoder, error) + DecoderChooser func(datamodel.Link) (codec.Decoder, error) + HasherChooser func(datamodel.LinkPrototype) (hash.Hash, error) StorageWriteOpener BlockWriteOpener StorageReadOpener BlockReadOpener + TrustedStorage bool + NodeReifier NodeReifier + KnownReifiers map[string]NodeReifier } -// The following two types define the two directions of transform that a codec can be expected to perform: -// from Node to serial stream, and from serial stream to Node (via a NodeAssembler). -// -// You'll find a couple of implementations matching this shape in subpackages of 'codec' in this module -// (these are the handful of encoders and decoders we ship as "batteries included"). -// Other encoder and decoder implementations can be found in other repositories/modules. -// It should also be easy to implement encodecs and decoders of your own! -// -// Encoder and Decoder functions can be used on their own, but are also often used via the LinkSystem construction, -// which handles all the other related operations necessary for a content-addressed storage system at once. -// -// Encoder and Decoder functions can be registered in the multicodec table in the `codec` package -// if they're providing functionality that matches the expectations for a multicodec identifier. -// This table will be used by some common EncoderChooser and DecoderChooser implementations -// (namely, the ones in LinkSystems produced by the `linking/cid` package). -type ( - // Encoder defines the shape of a function which traverses a Node tree - // and emits its data in a serialized form into an io.Writer. - // - // The dual of Encoder is a Decoder, which takes a NodeAssembler - // and fills it with deserialized data consumed from an io.Reader. - // Typically, Decoder and Encoder functions will be found in pairs, - // and will be expected to be able to round-trip each other's data. - // - // Encoder functions can be used directly. - // Encoder functions are also often used via a LinkSystem when working with content-addressed storage. - // LinkSystem methods will helpfully handle the entire process of traversing a Node tree, - // encoding this data, hashing it, streaming it to the writer, and committing it -- all as one step. - // - // An Encoder works with Nodes. - // If you have a native golang structure, and want to serialize it using an Encoder, - // you'll need to figure out how to transform that golang structure into an ipld.Node tree first. - // - // It may be useful to understand "multicodecs" when working with Encoders. - // In IPLD, a system called "multicodecs" is typically used to describe encoding foramts. - // A "multicodec indicator" is a number which describes an encoding; - // the Link implementations used in IPLD (CIDs) store a multicodec indicator in the Link; - // and in this library, a multicodec registry exists in the `codec` package, - // and can be used to associate a multicodec indicator number with an Encoder function. - // The default EncoderChooser in a LinkSystem will use this multicodec registry to select Encoder functions. - // However, you can construct a LinkSystem that uses any EncoderChooser you want. - // It is also possible to have and use Encoder functions that aren't registered as a multicodec at all... - // we just recommend being cautious of this, because it may make your data less recognizable - // when working with other systems that use multicodec indicators as part of their communication. - Encoder func(Node, io.Writer) error - - // Decoder defines the shape of a function which produces a Node tree - // by reading serialized data from an io.Reader. - // (Decoder doesn't itself return a Node directly, but rather takes a NodeAssembler as an argument, - // because this allows the caller more control over the Node implementation, - // as well as some control over allocations.) - // - // The dual of Decoder is an Encoder, which takes a Node and - // emits its data in a serialized form into an io.Writer. - // Typically, Decoder and Encoder functions will be found in pairs, - // and will be expected to be able to round-trip each other's data. - // - // Decoder functions can be used directly. - // Decoder functions are also often used via a LinkSystem when working with content-addressed storage. - // LinkSystem methods will helpfully handle the entire process of opening block readers, - // verifying the hash of the data stream, and applying a Decoder to build Nodes -- all as one step. - // - // A Decoder works with Nodes. - // If you have a native golang structure, and want to populate it with data using a Decoder, - // you'll need to either get a NodeAssembler which proxies data into that structure directly, - // or assemble a Node as intermediate storage and copy the data to the native structure as a separate step. - // - // It may be useful to understand "multicodecs" when working with Decoders. - // See the documentation on the Encoder function interface for more discussion of multicodecs, - // the multicodec table, and how this is typically connected to linking. - Decoder func(NodeAssembler, io.Reader) error -) - // The following three types are the key functionality we need from a "blockstore". // // Some libraries might provide a "blockstore" object that has these as methods; @@ -152,9 +85,12 @@ type ( // and hash in the Link parameter before returning. // (This is something that the LinkSystem composition will handle if you're using it.) // - // Some implementations of BlockWriteOpener and BlockReadOpener may be - // found in the storage package. Applications are also free to write their own. - BlockReadOpener func(LinkContext, Link) (io.Reader, error) + // BlockReadOpener can also be created out of storage.ReadableStorage and attached to a LinkSystem + // via the LinkSystem.SetReadStorage method. + // + // Users of a BlockReadOpener function should also check the io.Reader + // for matching the io.Closer interface, and use the Close function as appropriate if present. + BlockReadOpener func(LinkContext, datamodel.Link) (io.Reader, error) // BlockWriteOpener defines the shape of a function used to open a writer // into which data can be streamed, and which will eventually be "commited". @@ -186,8 +122,8 @@ type ( // and when the BlockWriteCommiter is called, it will flush the writes // and then use a rename operation to place the tempfile in a permanent path based the Link.) // - // Some implementations of BlockWriteOpener and BlockReadOpener may be - // found in the storage package. Applications are also free to write their own. + // BlockWriteOpener can also be created out of storage.WritableStorage and attached to a LinkSystem + // via the LinkSystem.SetWriteStorage method. BlockWriteOpener func(LinkContext) (io.Writer, BlockWriteCommitter, error) // BlockWriteCommitter defines the shape of a function which, together @@ -204,16 +140,60 @@ type ( // in a content-addressable fashion. // See the documentation of BlockWriteOpener for more description of this // and an example of how this is likely to be reduced to practice. - BlockWriteCommitter func(Link) error + BlockWriteCommitter func(datamodel.Link) error + + // NodeReifier defines the shape of a function that given a node with no schema + // or a basic schema, constructs Advanced Data Layout node + // + // The LinkSystem itself is passed to the NodeReifier along with a link context + // because Node interface methods on an ADL may actually traverse links to other + // pieces of context addressed data that need to be loaded with the Link system + // + // A NodeReifier return one of three things: + // - original node, no error = no reification occurred, just use original node + // - reified node, no error = the simple node was converted to an ADL + // - nil, error = the simple node should have been converted to an ADL but something + // went wrong when we tried to do so + // + NodeReifier func(LinkContext, datamodel.Node, *LinkSystem) (datamodel.Node, error) ) -// ErrLinkingSetup is returned by methods on LinkSystem when some part of the system is not set up correctly, -// or when one of the components refuses to handle a Link or LinkPrototype given. -// (It is not yielded for errors from the storage nor codec systems once they've started; those errors rise without interference.) -type ErrLinkingSetup struct { - Detail string // Perhaps an enum here as well, which states which internal function was to blame? - Cause error -} +// LinkContext is a structure carrying ancilary information that may be used +// while loading or storing data -- see its usage in BlockReadOpener, BlockWriteOpener, +// and in the methods on LinkSystem which handle loading and storing data. +// +// A zero value for LinkContext is generally acceptable in any functions that use it. +// In this case, any operations that need a context.Context will quietly use Context.Background +// (thus being uncancellable) and simply have no additional information to work with. +type LinkContext struct { + // Ctx is the familiar golang Context pattern. + // Use this for cancellation, or attaching additional info + // (for example, perhaps to pass auth tokens through to the storage functions). + Ctx context.Context + + // Path where the link was encountered. May be zero. + // + // Functions in the traversal package will set this automatically. + LinkPath datamodel.Path + + // When traversing data or encoding: the Node containing the link -- + // it may have additional type info, etc, that can be accessed. + // When building / decoding: not present. + // + // Functions in the traversal package will set this automatically. + LinkNode datamodel.Node + + // When building data or decoding: the NodeAssembler that will be receiving the link -- + // it may have additional type info, etc, that can be accessed. + // When traversing / encoding: not present. + // + // Functions in the traversal package will set this automatically. + LinkNodeAssembler datamodel.NodeAssembler + + // Parent of the LinkNode. May be zero. + // + // Functions in the traversal package will set this automatically. + ParentNode datamodel.Node -func (e ErrLinkingSetup) Error() string { return fmt.Sprintf("%s: %v", e.Detail, e.Cause) } -func (e ErrLinkingSetup) Unwrap() error { return e.Cause } + // REVIEW: ParentNode in LinkContext -- so far, this has only ever been hypothetically useful. Keep or drop? +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/defaultRegistry.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/defaultRegistry.go new file mode 100644 index 00000000..573d2b77 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/defaultRegistry.go @@ -0,0 +1,117 @@ +package multicodec + +import ( + "github.com/ipld/go-ipld-prime/codec" +) + +// DefaultRegistry is a multicodec.Registry instance which is global to the program, +// and is used as a default set of codecs. +// +// Some systems (for example, cidlink.DefaultLinkSystem) will use this default registry, +// which makes it easier to write programs that pass fewer explicit arguments around. +// However, these are *only* for default behaviors; +// variations of functions which allow explicit non-default options should always be available +// (for example, cidlink also has other LinkSystem constructor functions which accept an explicit multicodec.Registry, +// and the LookupEncoder and LookupDecoder functions in any LinkSystem can be replaced). +// +// Since this registry is global, mind that there are also some necessary tradeoffs and limitations: +// It can be difficult to control exactly what's present in this global registry +// (Libraries may register codecs in this registry as a side-effect of importing, so even transitive dependencies can affect its content!). +// Also, this registry is only considered safe to modify at package init time. +// If these are concerns for your program, you can create your own multicodec.Registry values, +// and eschew using the global default. +var DefaultRegistry = Registry{} + +// RegisterEncoder updates the global DefaultRegistry to map a multicodec indicator number to the given codec.Encoder function. +// The encoder functions registered can be subsequently looked up using LookupEncoder. +// It is a shortcut to the RegisterEncoder method on the global DefaultRegistry. +// +// Packages which implement an IPLD codec and have a multicodec number associated with them +// are encouraged to register themselves at package init time using this function. +// (Doing this at package init time ensures the default global registry is populated +// without causing race conditions for application code.) +// +// No effort is made to detect conflicting registrations in this map. +// If your dependency tree is such that this becomes a problem, +// there are two ways to address this: +// If RegisterEncoder is called with the same indicator code more than once, the last call wins. +// In practice, this means that if an application has a strong opinion about what implementation for a certain codec, +// then this can be done by making a Register call with that effect at init time in the application's main package. +// This should have the desired effect because the root of the import tree has its init time effect last. +// Alternatively, one can just avoid use of this registry entirely: +// do this by making a LinkSystem that uses a custom EncoderChooser function. +func RegisterEncoder(indicator uint64, encodeFunc codec.Encoder) { + DefaultRegistry.RegisterEncoder(indicator, encodeFunc) +} + +// LookupEncoder yields a codec.Encoder function matching a multicodec indicator code number. +// It is a shortcut to the LookupEncoder method on the global DefaultRegistry. +// +// To be available from this lookup function, an encoder must have been registered +// for this indicator number by an earlier call to the RegisterEncoder function. +func LookupEncoder(indicator uint64) (codec.Encoder, error) { + return DefaultRegistry.LookupEncoder(indicator) +} + +// ListEncoders returns a list of multicodec indicators for which a codec.Encoder is registered. +// The list is in no particular order. +// It is a shortcut to the ListEncoders method on the global DefaultRegistry. +// +// Be judicious about trying to use this function outside of debugging. +// Because the global default registry is global and easily modified, +// and can be changed by any of the transitive dependencies of your program, +// its contents are not particularly stable. +// In particular, it is not recommended to make any behaviors of your program conditional +// based on information returned by this function -- if your program needs conditional +// behavior based on registred codecs, you may want to consider taking more explicit control +// and using your own non-default registry. +func ListEncoders() []uint64 { + return DefaultRegistry.ListEncoders() +} + +// RegisterDecoder updates the global DefaultRegistry a map a multicodec indicator number to the given codec.Decoder function. +// The decoder functions registered can be subsequently looked up using LookupDecoder. +// It is a shortcut to the RegisterDecoder method on the global DefaultRegistry. +// +// Packages which implement an IPLD codec and have a multicodec number associated with them +// are encouraged to register themselves in this map at package init time. +// (Doing this at package init time ensures the default global registry is populated +// without causing race conditions for application code.) +// +// No effort is made to detect conflicting registrations in this map. +// If your dependency tree is such that this becomes a problem, +// there are two ways to address this: +// If RegisterDecoder is called with the same indicator code more than once, the last call wins. +// In practice, this means that if an application has a strong opinion about what implementation for a certain codec, +// then this can be done by making a Register call with that effect at init time in the application's main package. +// This should have the desired effect because the root of the import tree has its init time effect last. +// Alternatively, one can just avoid use of this registry entirely: +// do this by making a LinkSystem that uses a custom DecoderChooser function. +func RegisterDecoder(indicator uint64, decodeFunc codec.Decoder) { + DefaultRegistry.RegisterDecoder(indicator, decodeFunc) +} + +// LookupDecoder yields a codec.Decoder function matching a multicodec indicator code number. +// It is a shortcut to the LookupDecoder method on the global DefaultRegistry. +// +// To be available from this lookup function, an decoder must have been registered +// for this indicator number by an earlier call to the RegisterDecoder function. +func LookupDecoder(indicator uint64) (codec.Decoder, error) { + return DefaultRegistry.LookupDecoder(indicator) +} + +// ListDecoders returns a list of multicodec indicators for which a codec.Decoder is registered. +// The list is in no particular order. +// It is a shortcut to the ListDecoders method on the global DefaultRegistry. +// +// Be judicious about trying to use this function outside of debugging. +// Because the global default registry is global and easily modified, +// and can be changed by any of the transitive dependencies of your program, +// its contents are not particularly stable. +// In particular, it is not recommended to make any behaviors of your program conditional +// based on information returned by this function -- if your program needs conditional +// behavior based on registred codecs, you may want to consider taking more explicit control +// and using your own non-default registry. +func ListDecoders() []uint64 { + return DefaultRegistry.ListDecoders() +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/multicodec.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/multicodec.go deleted file mode 100644 index 2898834d..00000000 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/multicodec.go +++ /dev/null @@ -1,110 +0,0 @@ -package multicodec - -import ( - "fmt" - - "github.com/ipld/go-ipld-prime" -) - -var encoderRegistry = make(map[uint64]ipld.Encoder) -var decoderRegistry = make(map[uint64]ipld.Decoder) - -// RegisterEncoder updates a simple map of multicodec indicator number to ipld.Encoder function. -// The encoder functions registered can be subsequently looked up using LookupEncoder. -// -// Packages which implement an IPLD codec and have a multicodec number reserved in -// https://github.com/multiformats/multicodec/blob/master/table.csv -// are encouraged to register themselves in this map at package init time. -// (Doing this at package init time ensures this map can be accessed without race conditions.) -// -// This registry map is only used for default behaviors. -// For example, linking/cid.DefaultLinkSystem will use LookupEncoder to access this registry map -// and select encoders to use when serializing data for linking and storage. -// LinkSystem itself is not hardcoded to use the global LookupEncoder feature; -// therefore, you don't want to rely on this mapping, you can always construct your own LinkSystem. -// -// No effort is made to detect conflicting registrations in this map. -// If your dependency tree is such that this becomes a problem, -// there are two ways to address this: -// If RegisterEncoder is called with the same indicator code more than once, the last call wins. -// In practice, this means that if an application has a strong opinion about what implementation for a certain codec, -// then this can be done by making a Register call with that effect at init time in the application's main package. -// This should have the desired effect because the root of the import tree has its init time effect last. -// Alternatively, one can just avoid use of this registry entirely: -// do this by making a LinkSystem that uses a custom EncoderChooser function. -func RegisterEncoder(indicator uint64, encodeFunc ipld.Encoder) { - // This function could arguably be just a bare map access. - // We introduced a function primarily for the interest of potential future changes. - // E.g. one could introduce logging here to help detect unintended conflicting registrations. - // (We probably won't do this, but you can do it yourself as a printf debug hack. :)) - - if encodeFunc == nil { - panic("not sensible to attempt to register a nil function") - } - encoderRegistry[indicator] = encodeFunc -} - -// LookupEncoder yields an ipld.Encoder function matching a multicodec indicator code number. -// -// Multicodec indicator numbers are specified in -// https://github.com/multiformats/multicodec/blob/master/table.csv -// -// To be available from this lookup function, an encoder must have been registered -// for this indicator number by an earlier call to the RegisterEncoder function. -func LookupEncoder(indicator uint64) (ipld.Encoder, error) { - encodeFunc, exists := encoderRegistry[indicator] - if !exists { - return nil, fmt.Errorf("no encoder registered for multicodec code %d (0x%x)", indicator, indicator) - } - return encodeFunc, nil -} - -// RegisterDecoder updates a simple map of multicodec indicator number to ipld.Decoder function. -// The decoder functions registered can be subsequently looked up using LookupDecoder. -// -// Packages which implement an IPLD codec and have a multicodec number reserved in -// https://github.com/multiformats/multicodec/blob/master/table.csv -// are encouraged to register themselves in this map at package init time. -// (Doing this at package init time ensures this map can be accessed without race conditions.) -// -// This registry map is only used for default behaviors. -// For example, linking/cid.DefaultLinkSystem will use LookupDecoder to access this registry map -// and select decoders to use when serializing data for linking and storage. -// LinkSystem itself is not hardcoded to use the global LookupDecoder feature; -// therefore, you don't want to rely on this mapping, you can always construct your own LinkSystem. -// -// No effort is made to detect conflicting registrations in this map. -// If your dependency tree is such that this becomes a problem, -// there are two ways to address this: -// If RegisterDecoder is called with the same indicator code more than once, the last call wins. -// In practice, this means that if an application has a strong opinion about what implementation for a certain codec, -// then this can be done by making a Register call with that effect at init time in the application's main package. -// This should have the desired effect because the root of the import tree has its init time effect last. -// Alternatively, one can just avoid use of this registry entirely: -// do this by making a LinkSystem that uses a custom DecoderChooser function. -func RegisterDecoder(indicator uint64, decodeFunc ipld.Decoder) { - // This function could arguably be just a bare map access. - // We introduced a function primarily for the interest of potential future changes. - // E.g. one could introduce logging here to help detect unintended conflicting registrations. - // (We probably won't do this, but you can do it yourself as a printf debug hack. :)) - - if decodeFunc == nil { - panic("not sensible to attempt to register a nil function") - } - decoderRegistry[indicator] = decodeFunc -} - -// LookupDecoder yields an ipld.Decoder function matching a multicodec indicator code number. -// -// Multicodec indicator numbers are specified in -// https://github.com/multiformats/multicodec/blob/master/table.csv -// -// To be available from this lookup function, an decoder must have been registered -// for this indicator number by an earlier call to the RegisterDecoder function. -func LookupDecoder(indicator uint64) (ipld.Decoder, error) { - decodeFunc, exists := decoderRegistry[indicator] - if !exists { - return nil, fmt.Errorf("no decoder registered for multicodec code %d (0x%x)", indicator, indicator) - } - return decodeFunc, nil -} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/registry.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/registry.go new file mode 100644 index 00000000..4093c8e2 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/multicodec/registry.go @@ -0,0 +1,105 @@ +package multicodec + +import ( + "fmt" + + "github.com/ipld/go-ipld-prime/codec" +) + +// Registry is a structure for storing mappings of multicodec indicator numbers to codec.Encoder and codec.Decoder functions. +// +// The most typical usage of this structure is in combination with a codec.LinkSystem. +// For example, a linksystem using CIDs and a custom multicodec registry can be constructed +// using cidlink.LinkSystemUsingMulticodecRegistry. +// +// Registry includes no mutexing. If using Registry in a concurrent context, you must handle synchronization yourself. +// (Typically, it is recommended to do initialization earlier in a program, before fanning out goroutines; +// this avoids the need for mutexing overhead.) +// +// go-ipld also has a default registry, which has the same methods as this structure, but are at package scope. +// Some systems, like cidlink.DefaultLinkSystem, will use this default registry. +// However, this default registry is global to the entire program. +// This Registry type is for helping if you wish to make your own registry which does not share that global state. +// +// Multicodec indicator numbers are specified in +// https://github.com/multiformats/multicodec/blob/master/table.csv . +// You should not use indicator numbers which are not specified in that table +// (however, there is nothing in this implementation that will attempt to stop you, either; please behave). +type Registry struct { + encoders map[uint64]codec.Encoder + decoders map[uint64]codec.Decoder +} + +func (r *Registry) ensureInit() { + if r.encoders != nil { + return + } + r.encoders = make(map[uint64]codec.Encoder) + r.decoders = make(map[uint64]codec.Decoder) +} + +// RegisterEncoder updates a simple map of multicodec indicator number to codec.Encoder function. +// The encoder functions registered can be subsequently looked up using LookupEncoder. +func (r *Registry) RegisterEncoder(indicator uint64, encodeFunc codec.Encoder) { + r.ensureInit() + if encodeFunc == nil { + panic("not sensible to attempt to register a nil function") + } + r.encoders[indicator] = encodeFunc +} + +// LookupEncoder yields a codec.Encoder function matching a multicodec indicator code number. +// +// To be available from this lookup function, an encoder must have been registered +// for this indicator number by an earlier call to the RegisterEncoder function. +func (r *Registry) LookupEncoder(indicator uint64) (codec.Encoder, error) { + encodeFunc, exists := r.encoders[indicator] + if !exists { + return nil, fmt.Errorf("no encoder registered for multicodec code %d (0x%x)", indicator, indicator) + } + return encodeFunc, nil +} + +// ListEncoders returns a list of multicodec indicators for which a codec.Encoder is registered. +// The list is in no particular order. +func (r *Registry) ListEncoders() []uint64 { + encoders := make([]uint64, 0, len(r.encoders)) + for e := range r.encoders { + encoders = append(encoders, e) + } + return encoders +} + +// TODO(mvdan): turn most of these uint64s into multicodec.Code + +// RegisterDecoder updates a simple map of multicodec indicator number to codec.Decoder function. +// The decoder functions registered can be subsequently looked up using LookupDecoder. +func (r *Registry) RegisterDecoder(indicator uint64, decodeFunc codec.Decoder) { + r.ensureInit() + if decodeFunc == nil { + panic("not sensible to attempt to register a nil function") + } + r.decoders[indicator] = decodeFunc +} + +// LookupDecoder yields a codec.Decoder function matching a multicodec indicator code number. +// +// To be available from this lookup function, an decoder must have been registered +// for this indicator number by an earlier call to the RegisterDecoder function. +func (r *Registry) LookupDecoder(indicator uint64) (codec.Decoder, error) { + decodeFunc, exists := r.decoders[indicator] + if !exists { + return nil, fmt.Errorf("no decoder registered for multicodec code %d (0x%x)", indicator, indicator) + } + return decodeFunc, nil +} + +// ListDecoders returns a list of multicodec indicators for which a codec.Decoder is registered. +// The list is in no particular order. +func (r *Registry) ListDecoders() []uint64 { + decoders := make([]uint64, 0, len(r.decoders)) + for d := range r.decoders { + decoders = append(decoders, d) + } + return decoders +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/deprecated.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/deprecated.go new file mode 100644 index 00000000..e32032cd --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/deprecated.go @@ -0,0 +1,36 @@ +// This is a transitional package: please move your references to `node/basicnode`. +// The new package is identical: we've renamed the import path only. +// +// All content in this package is a thin wrapper around `node/basicnode`. +// Please update at your earliest convenience. +// +// This package will eventually be removed. +package basicnode + +import ( + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/linking" + "github.com/ipld/go-ipld-prime/node/basicnode" +) + +var Prototype = basicnode.Prototype + +func Chooser(_ datamodel.Link, _ linking.LinkContext) (datamodel.NodePrototype, error) { + return basicnode.Chooser(nil, linking.LinkContext{}) +} +func NewBool(value bool) datamodel.Node { return basicnode.NewBool(value) } +func NewBytes(value []byte) datamodel.Node { return basicnode.NewBytes(value) } +func NewFloat(value float64) datamodel.Node { return basicnode.NewFloat(value) } +func NewInt(value int64) datamodel.Node { return basicnode.NewInt(value) } +func NewLink(value datamodel.Link) datamodel.Node { return basicnode.NewLink(value) } +func NewString(value string) datamodel.Node { return basicnode.NewString(value) } + +type Prototype__Any = basicnode.Prototype__Any +type Prototype__Bool = basicnode.Prototype__Bool +type Prototype__Bytes = basicnode.Prototype__Bytes +type Prototype__Float = basicnode.Prototype__Float +type Prototype__Int = basicnode.Prototype__Int +type Prototype__Link = basicnode.Prototype__Link +type Prototype__List = basicnode.Prototype__List +type Prototype__Map = basicnode.Prototype__Map +type Prototype__String = basicnode.Prototype__String diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/int.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/int.go deleted file mode 100644 index 75676e9c..00000000 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/int.go +++ /dev/null @@ -1,144 +0,0 @@ -package basicnode - -import ( - ipld "github.com/ipld/go-ipld-prime" - "github.com/ipld/go-ipld-prime/node/mixins" -) - -var ( - _ ipld.Node = plainInt(0) - _ ipld.NodePrototype = Prototype__Int{} - _ ipld.NodeBuilder = &plainInt__Builder{} - _ ipld.NodeAssembler = &plainInt__Assembler{} -) - -func NewInt(value int64) ipld.Node { - v := plainInt(value) - return &v -} - -// plainInt is a simple boxed int that complies with ipld.Node. -type plainInt int64 - -// -- Node interface methods --> - -func (plainInt) Kind() ipld.Kind { - return ipld.Kind_Int -} -func (plainInt) LookupByString(string) (ipld.Node, error) { - return mixins.Int{TypeName: "int"}.LookupByString("") -} -func (plainInt) LookupByNode(key ipld.Node) (ipld.Node, error) { - return mixins.Int{TypeName: "int"}.LookupByNode(nil) -} -func (plainInt) LookupByIndex(idx int64) (ipld.Node, error) { - return mixins.Int{TypeName: "int"}.LookupByIndex(0) -} -func (plainInt) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { - return mixins.Int{TypeName: "int"}.LookupBySegment(seg) -} -func (plainInt) MapIterator() ipld.MapIterator { - return nil -} -func (plainInt) ListIterator() ipld.ListIterator { - return nil -} -func (plainInt) Length() int64 { - return -1 -} -func (plainInt) IsAbsent() bool { - return false -} -func (plainInt) IsNull() bool { - return false -} -func (plainInt) AsBool() (bool, error) { - return mixins.Int{TypeName: "int"}.AsBool() -} -func (n plainInt) AsInt() (int64, error) { - return int64(n), nil -} -func (plainInt) AsFloat() (float64, error) { - return mixins.Int{TypeName: "int"}.AsFloat() -} -func (plainInt) AsString() (string, error) { - return mixins.Int{TypeName: "int"}.AsString() -} -func (plainInt) AsBytes() ([]byte, error) { - return mixins.Int{TypeName: "int"}.AsBytes() -} -func (plainInt) AsLink() (ipld.Link, error) { - return mixins.Int{TypeName: "int"}.AsLink() -} -func (plainInt) Prototype() ipld.NodePrototype { - return Prototype__Int{} -} - -// -- NodePrototype --> - -type Prototype__Int struct{} - -func (Prototype__Int) NewBuilder() ipld.NodeBuilder { - var w plainInt - return &plainInt__Builder{plainInt__Assembler{w: &w}} -} - -// -- NodeBuilder --> - -type plainInt__Builder struct { - plainInt__Assembler -} - -func (nb *plainInt__Builder) Build() ipld.Node { - return nb.w -} -func (nb *plainInt__Builder) Reset() { - var w plainInt - *nb = plainInt__Builder{plainInt__Assembler{w: &w}} -} - -// -- NodeAssembler --> - -type plainInt__Assembler struct { - w *plainInt -} - -func (plainInt__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - return mixins.IntAssembler{TypeName: "int"}.BeginMap(0) -} -func (plainInt__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return mixins.IntAssembler{TypeName: "int"}.BeginList(0) -} -func (plainInt__Assembler) AssignNull() error { - return mixins.IntAssembler{TypeName: "int"}.AssignNull() -} -func (plainInt__Assembler) AssignBool(bool) error { - return mixins.IntAssembler{TypeName: "int"}.AssignBool(false) -} -func (na *plainInt__Assembler) AssignInt(v int64) error { - *na.w = plainInt(v) - return nil -} -func (plainInt__Assembler) AssignFloat(float64) error { - return mixins.IntAssembler{TypeName: "int"}.AssignFloat(0) -} -func (plainInt__Assembler) AssignString(string) error { - return mixins.IntAssembler{TypeName: "int"}.AssignString("") -} -func (plainInt__Assembler) AssignBytes([]byte) error { - return mixins.IntAssembler{TypeName: "int"}.AssignBytes(nil) -} -func (plainInt__Assembler) AssignLink(ipld.Link) error { - return mixins.IntAssembler{TypeName: "int"}.AssignLink(nil) -} -func (na *plainInt__Assembler) AssignNode(v ipld.Node) error { - if v2, err := v.AsInt(); err != nil { - return err - } else { - *na.w = plainInt(v2) - return nil - } -} -func (plainInt__Assembler) Prototype() ipld.NodePrototype { - return Prototype__Int{} -} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/HACKME.md b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/HACKME.md similarity index 99% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/HACKME.md rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/HACKME.md index bf2f74a9..dad98f5f 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/HACKME.md +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/HACKME.md @@ -134,7 +134,7 @@ The 'Prototype' singleton is one way to access the NodePrototype in this package their exported types are another equivalent way. ```go -basicnode.Prototype.Map = basicnode.Prototype__Map{} +basicnode.Prototype.Map = basicnode.Prototype.Map ``` It is recommended to use the singleton style; diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/any.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/any.go similarity index 59% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/any.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/any.go index 159707a2..cc248463 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/any.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/any.go @@ -1,33 +1,30 @@ package basicnode import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/linking" ) var ( - //_ ipld.Node = &anyNode{} - _ ipld.NodePrototype = Prototype__Any{} - _ ipld.NodeBuilder = &anyBuilder{} - //_ ipld.NodeAssembler = &anyAssembler{} + //_ datamodel.Node = &anyNode{} + _ datamodel.NodePrototype = Prototype__Any{} + _ datamodel.NodeBuilder = &anyBuilder{} + //_ datamodel.NodeAssembler = &anyAssembler{} ) -// anyNode is a union meant for alloc amortization; see anyAssembler. -// Note that anyBuilder doesn't use anyNode, because it's not aiming to amortize anything. +// Note that we don't use a "var _" declaration to assert that Chooser +// implements traversal.LinkTargetNodePrototypeChooser, to keep basicnode's +// dependencies fairly light. + +// Chooser implements traversal.LinkTargetNodePrototypeChooser. // -// REVIEW: if there's any point in keeping this around. It's here for completeness, -// but not currently used anywhere in package, and also not currently exported. -// type anyNode struct { -// kind ipld.Kind +// It can be used directly when loading links into the "any" prototype, +// or with another chooser layer on top, such as: // -// plainMap -// plainList -// plainBool -// plainInt -// plainFloat -// plainString -// plainBytes -// plainLink -// } +// prototypeChooser := dagpb.AddSupportToChooser(basicnode.Chooser) +func Chooser(_ datamodel.Link, _ linking.LinkContext) (datamodel.NodePrototype, error) { + return Prototype.Any, nil +} // -- Node interface methods --> @@ -37,7 +34,7 @@ var ( type Prototype__Any struct{} -func (Prototype__Any) NewBuilder() ipld.NodeBuilder { +func (Prototype__Any) NewBuilder() datamodel.NodeBuilder { return &anyBuilder{} } @@ -57,7 +54,7 @@ type anyBuilder struct { // kind is set on first interaction, and used to select which builder to delegate 'Build' to! // As soon as it's been set to a value other than zero (being "Invalid"), all other Assign/Begin calls will fail since something is already in progress. // May also be set to the magic value '99', which means "i dunno, I'm just carrying another node of unknown prototype". - kind ipld.Kind + kind datamodel.Kind // Only one of the following ends up being used... // but we don't know in advance which one, so all are embeded here. @@ -70,117 +67,117 @@ type anyBuilder struct { mapBuilder plainMap__Builder listBuilder plainList__Builder - scalarNode ipld.Node + scalarNode datamodel.Node } func (nb *anyBuilder) Reset() { *nb = anyBuilder{} } -func (nb *anyBuilder) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - if nb.kind != ipld.Kind_Invalid { +func (nb *anyBuilder) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_Map + nb.kind = datamodel.Kind_Map nb.mapBuilder.w = &plainMap{} return nb.mapBuilder.BeginMap(sizeHint) } -func (nb *anyBuilder) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - if nb.kind != ipld.Kind_Invalid { +func (nb *anyBuilder) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_List + nb.kind = datamodel.Kind_List nb.listBuilder.w = &plainList{} return nb.listBuilder.BeginList(sizeHint) } func (nb *anyBuilder) AssignNull() error { - if nb.kind != ipld.Kind_Invalid { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_Null + nb.kind = datamodel.Kind_Null return nil } func (nb *anyBuilder) AssignBool(v bool) error { - if nb.kind != ipld.Kind_Invalid { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_Bool + nb.kind = datamodel.Kind_Bool nb.scalarNode = NewBool(v) return nil } func (nb *anyBuilder) AssignInt(v int64) error { - if nb.kind != ipld.Kind_Invalid { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_Int + nb.kind = datamodel.Kind_Int nb.scalarNode = NewInt(v) return nil } func (nb *anyBuilder) AssignFloat(v float64) error { - if nb.kind != ipld.Kind_Invalid { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_Float + nb.kind = datamodel.Kind_Float nb.scalarNode = NewFloat(v) return nil } func (nb *anyBuilder) AssignString(v string) error { - if nb.kind != ipld.Kind_Invalid { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_String + nb.kind = datamodel.Kind_String nb.scalarNode = NewString(v) return nil } func (nb *anyBuilder) AssignBytes(v []byte) error { - if nb.kind != ipld.Kind_Invalid { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_Bytes + nb.kind = datamodel.Kind_Bytes nb.scalarNode = NewBytes(v) return nil } -func (nb *anyBuilder) AssignLink(v ipld.Link) error { - if nb.kind != ipld.Kind_Invalid { +func (nb *anyBuilder) AssignLink(v datamodel.Link) error { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } - nb.kind = ipld.Kind_Link + nb.kind = datamodel.Kind_Link nb.scalarNode = NewLink(v) return nil } -func (nb *anyBuilder) AssignNode(v ipld.Node) error { - if nb.kind != ipld.Kind_Invalid { +func (nb *anyBuilder) AssignNode(v datamodel.Node) error { + if nb.kind != datamodel.Kind_Invalid { panic("misuse") } nb.kind = 99 nb.scalarNode = v return nil } -func (anyBuilder) Prototype() ipld.NodePrototype { - return Prototype__Any{} +func (anyBuilder) Prototype() datamodel.NodePrototype { + return Prototype.Any } -func (nb *anyBuilder) Build() ipld.Node { +func (nb *anyBuilder) Build() datamodel.Node { switch nb.kind { - case ipld.Kind_Invalid: + case datamodel.Kind_Invalid: panic("misuse") - case ipld.Kind_Map: + case datamodel.Kind_Map: return nb.mapBuilder.Build() - case ipld.Kind_List: + case datamodel.Kind_List: return nb.listBuilder.Build() - case ipld.Kind_Null: - return ipld.Null - case ipld.Kind_Bool: + case datamodel.Kind_Null: + return datamodel.Null + case datamodel.Kind_Bool: return nb.scalarNode - case ipld.Kind_Int: + case datamodel.Kind_Int: return nb.scalarNode - case ipld.Kind_Float: + case datamodel.Kind_Float: return nb.scalarNode - case ipld.Kind_String: + case datamodel.Kind_String: return nb.scalarNode - case ipld.Kind_Bytes: + case datamodel.Kind_Bytes: return nb.scalarNode - case ipld.Kind_Link: + case datamodel.Kind_Link: return nb.scalarNode case 99: return nb.scalarNode diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/bool.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bool.go similarity index 64% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/bool.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bool.go index 3e9df965..ecf85fad 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/bool.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bool.go @@ -1,46 +1,46 @@ package basicnode import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/mixins" ) var ( - _ ipld.Node = plainBool(false) - _ ipld.NodePrototype = Prototype__Bool{} - _ ipld.NodeBuilder = &plainBool__Builder{} - _ ipld.NodeAssembler = &plainBool__Assembler{} + _ datamodel.Node = plainBool(false) + _ datamodel.NodePrototype = Prototype__Bool{} + _ datamodel.NodeBuilder = &plainBool__Builder{} + _ datamodel.NodeAssembler = &plainBool__Assembler{} ) -func NewBool(value bool) ipld.Node { +func NewBool(value bool) datamodel.Node { v := plainBool(value) return &v } -// plainBool is a simple boxed boolean that complies with ipld.Node. +// plainBool is a simple boxed boolean that complies with datamodel.Node. type plainBool bool // -- Node interface methods --> -func (plainBool) Kind() ipld.Kind { - return ipld.Kind_Bool +func (plainBool) Kind() datamodel.Kind { + return datamodel.Kind_Bool } -func (plainBool) LookupByString(string) (ipld.Node, error) { +func (plainBool) LookupByString(string) (datamodel.Node, error) { return mixins.Bool{TypeName: "bool"}.LookupByString("") } -func (plainBool) LookupByNode(key ipld.Node) (ipld.Node, error) { +func (plainBool) LookupByNode(key datamodel.Node) (datamodel.Node, error) { return mixins.Bool{TypeName: "bool"}.LookupByNode(nil) } -func (plainBool) LookupByIndex(idx int64) (ipld.Node, error) { +func (plainBool) LookupByIndex(idx int64) (datamodel.Node, error) { return mixins.Bool{TypeName: "bool"}.LookupByIndex(0) } -func (plainBool) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { +func (plainBool) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { return mixins.Bool{TypeName: "bool"}.LookupBySegment(seg) } -func (plainBool) MapIterator() ipld.MapIterator { +func (plainBool) MapIterator() datamodel.MapIterator { return nil } -func (plainBool) ListIterator() ipld.ListIterator { +func (plainBool) ListIterator() datamodel.ListIterator { return nil } func (plainBool) Length() int64 { @@ -67,10 +67,10 @@ func (plainBool) AsString() (string, error) { func (plainBool) AsBytes() ([]byte, error) { return mixins.Bool{TypeName: "bool"}.AsBytes() } -func (plainBool) AsLink() (ipld.Link, error) { +func (plainBool) AsLink() (datamodel.Link, error) { return mixins.Bool{TypeName: "bool"}.AsLink() } -func (plainBool) Prototype() ipld.NodePrototype { +func (plainBool) Prototype() datamodel.NodePrototype { return Prototype__Bool{} } @@ -78,7 +78,7 @@ func (plainBool) Prototype() ipld.NodePrototype { type Prototype__Bool struct{} -func (Prototype__Bool) NewBuilder() ipld.NodeBuilder { +func (Prototype__Bool) NewBuilder() datamodel.NodeBuilder { var w plainBool return &plainBool__Builder{plainBool__Assembler{w: &w}} } @@ -89,7 +89,7 @@ type plainBool__Builder struct { plainBool__Assembler } -func (nb *plainBool__Builder) Build() ipld.Node { +func (nb *plainBool__Builder) Build() datamodel.Node { return nb.w } func (nb *plainBool__Builder) Reset() { @@ -103,10 +103,10 @@ type plainBool__Assembler struct { w *plainBool } -func (plainBool__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (plainBool__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { return mixins.BoolAssembler{TypeName: "bool"}.BeginMap(0) } -func (plainBool__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (plainBool__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { return mixins.BoolAssembler{TypeName: "bool"}.BeginList(0) } func (plainBool__Assembler) AssignNull() error { @@ -128,10 +128,10 @@ func (plainBool__Assembler) AssignString(string) error { func (plainBool__Assembler) AssignBytes([]byte) error { return mixins.BoolAssembler{TypeName: "bool"}.AssignBytes(nil) } -func (plainBool__Assembler) AssignLink(ipld.Link) error { +func (plainBool__Assembler) AssignLink(datamodel.Link) error { return mixins.BoolAssembler{TypeName: "bool"}.AssignLink(nil) } -func (na *plainBool__Assembler) AssignNode(v ipld.Node) error { +func (na *plainBool__Assembler) AssignNode(v datamodel.Node) error { if v2, err := v.AsBool(); err != nil { return err } else { @@ -139,6 +139,6 @@ func (na *plainBool__Assembler) AssignNode(v ipld.Node) error { return nil } } -func (plainBool__Assembler) Prototype() ipld.NodePrototype { +func (plainBool__Assembler) Prototype() datamodel.NodePrototype { return Prototype__Bool{} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/bytes.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bytes.go similarity index 59% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/bytes.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bytes.go index d1586b05..566c32fe 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/bytes.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bytes.go @@ -1,46 +1,49 @@ package basicnode import ( - ipld "github.com/ipld/go-ipld-prime" + "bytes" + "io" + + "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/mixins" ) var ( - _ ipld.Node = plainBytes(nil) - _ ipld.NodePrototype = Prototype__Bytes{} - _ ipld.NodeBuilder = &plainBytes__Builder{} - _ ipld.NodeAssembler = &plainBytes__Assembler{} + _ datamodel.Node = plainBytes(nil) + _ datamodel.NodePrototype = Prototype__Bytes{} + _ datamodel.NodeBuilder = &plainBytes__Builder{} + _ datamodel.NodeAssembler = &plainBytes__Assembler{} ) -func NewBytes(value []byte) ipld.Node { +func NewBytes(value []byte) datamodel.Node { v := plainBytes(value) return &v } -// plainBytes is a simple boxed byte slice that complies with ipld.Node. +// plainBytes is a simple boxed byte slice that complies with datamodel.Node. type plainBytes []byte // -- Node interface methods --> -func (plainBytes) Kind() ipld.Kind { - return ipld.Kind_Bytes +func (plainBytes) Kind() datamodel.Kind { + return datamodel.Kind_Bytes } -func (plainBytes) LookupByString(string) (ipld.Node, error) { +func (plainBytes) LookupByString(string) (datamodel.Node, error) { return mixins.Bytes{TypeName: "bytes"}.LookupByString("") } -func (plainBytes) LookupByNode(key ipld.Node) (ipld.Node, error) { +func (plainBytes) LookupByNode(key datamodel.Node) (datamodel.Node, error) { return mixins.Bytes{TypeName: "bytes"}.LookupByNode(nil) } -func (plainBytes) LookupByIndex(idx int64) (ipld.Node, error) { +func (plainBytes) LookupByIndex(idx int64) (datamodel.Node, error) { return mixins.Bytes{TypeName: "bytes"}.LookupByIndex(0) } -func (plainBytes) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { +func (plainBytes) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { return mixins.Bytes{TypeName: "bytes"}.LookupBySegment(seg) } -func (plainBytes) MapIterator() ipld.MapIterator { +func (plainBytes) MapIterator() datamodel.MapIterator { return nil } -func (plainBytes) ListIterator() ipld.ListIterator { +func (plainBytes) ListIterator() datamodel.ListIterator { return nil } func (plainBytes) Length() int64 { @@ -67,18 +70,21 @@ func (plainBytes) AsString() (string, error) { func (n plainBytes) AsBytes() ([]byte, error) { return []byte(n), nil } -func (plainBytes) AsLink() (ipld.Link, error) { +func (plainBytes) AsLink() (datamodel.Link, error) { return mixins.Bytes{TypeName: "bytes"}.AsLink() } -func (plainBytes) Prototype() ipld.NodePrototype { +func (plainBytes) Prototype() datamodel.NodePrototype { return Prototype__Bytes{} } +func (n plainBytes) AsLargeBytes() (io.ReadSeeker, error) { + return bytes.NewReader(n), nil +} // -- NodePrototype --> type Prototype__Bytes struct{} -func (Prototype__Bytes) NewBuilder() ipld.NodeBuilder { +func (Prototype__Bytes) NewBuilder() datamodel.NodeBuilder { var w plainBytes return &plainBytes__Builder{plainBytes__Assembler{w: &w}} } @@ -89,7 +95,7 @@ type plainBytes__Builder struct { plainBytes__Assembler } -func (nb *plainBytes__Builder) Build() ipld.Node { +func (nb *plainBytes__Builder) Build() datamodel.Node { return nb.w } func (nb *plainBytes__Builder) Reset() { @@ -100,13 +106,13 @@ func (nb *plainBytes__Builder) Reset() { // -- NodeAssembler --> type plainBytes__Assembler struct { - w *plainBytes + w datamodel.Node } -func (plainBytes__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (plainBytes__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { return mixins.BytesAssembler{TypeName: "bytes"}.BeginMap(0) } -func (plainBytes__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (plainBytes__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { return mixins.BytesAssembler{TypeName: "bytes"}.BeginList(0) } func (plainBytes__Assembler) AssignNull() error { @@ -125,20 +131,27 @@ func (plainBytes__Assembler) AssignString(string) error { return mixins.BytesAssembler{TypeName: "bytes"}.AssignString("") } func (na *plainBytes__Assembler) AssignBytes(v []byte) error { - *na.w = plainBytes(v) + na.w = datamodel.Node(plainBytes(v)) return nil } -func (plainBytes__Assembler) AssignLink(ipld.Link) error { +func (plainBytes__Assembler) AssignLink(datamodel.Link) error { return mixins.BytesAssembler{TypeName: "bytes"}.AssignLink(nil) } -func (na *plainBytes__Assembler) AssignNode(v ipld.Node) error { +func (na *plainBytes__Assembler) AssignNode(v datamodel.Node) error { + if lb, ok := v.(datamodel.LargeBytesNode); ok { + lbn, err := lb.AsLargeBytes() + if err == nil { + na.w = streamBytes{lbn} + return nil + } + } if v2, err := v.AsBytes(); err != nil { return err } else { - *na.w = plainBytes(v2) + na.w = plainBytes(v2) return nil } } -func (plainBytes__Assembler) Prototype() ipld.NodePrototype { +func (plainBytes__Assembler) Prototype() datamodel.NodePrototype { return Prototype__Bytes{} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bytes_stream.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bytes_stream.go new file mode 100644 index 00000000..ad238bcf --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/bytes_stream.go @@ -0,0 +1,81 @@ +package basicnode + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/mixins" +) + +var ( + _ datamodel.Node = streamBytes{nil} + _ datamodel.NodePrototype = Prototype__Bytes{} + _ datamodel.NodeBuilder = &plainBytes__Builder{} + _ datamodel.NodeAssembler = &plainBytes__Assembler{} +) + +func NewBytesFromReader(rs io.ReadSeeker) datamodel.Node { + return streamBytes{rs} +} + +// streamBytes is a boxed reader that complies with datamodel.Node. +type streamBytes struct { + io.ReadSeeker +} + +// -- Node interface methods --> + +func (streamBytes) Kind() datamodel.Kind { + return datamodel.Kind_Bytes +} +func (streamBytes) LookupByString(string) (datamodel.Node, error) { + return mixins.Bytes{TypeName: "bytes"}.LookupByString("") +} +func (streamBytes) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return mixins.Bytes{TypeName: "bytes"}.LookupByNode(nil) +} +func (streamBytes) LookupByIndex(idx int64) (datamodel.Node, error) { + return mixins.Bytes{TypeName: "bytes"}.LookupByIndex(0) +} +func (streamBytes) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return mixins.Bytes{TypeName: "bytes"}.LookupBySegment(seg) +} +func (streamBytes) MapIterator() datamodel.MapIterator { + return nil +} +func (streamBytes) ListIterator() datamodel.ListIterator { + return nil +} +func (streamBytes) Length() int64 { + return -1 +} +func (streamBytes) IsAbsent() bool { + return false +} +func (streamBytes) IsNull() bool { + return false +} +func (streamBytes) AsBool() (bool, error) { + return mixins.Bytes{TypeName: "bytes"}.AsBool() +} +func (streamBytes) AsInt() (int64, error) { + return mixins.Bytes{TypeName: "bytes"}.AsInt() +} +func (streamBytes) AsFloat() (float64, error) { + return mixins.Bytes{TypeName: "bytes"}.AsFloat() +} +func (streamBytes) AsString() (string, error) { + return mixins.Bytes{TypeName: "bytes"}.AsString() +} +func (n streamBytes) AsBytes() ([]byte, error) { + return io.ReadAll(n) +} +func (streamBytes) AsLink() (datamodel.Link, error) { + return mixins.Bytes{TypeName: "bytes"}.AsLink() +} +func (streamBytes) Prototype() datamodel.NodePrototype { + return Prototype__Bytes{} +} +func (n streamBytes) AsLargeBytes() (io.ReadSeeker, error) { + return n.ReadSeeker, nil +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/float.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/float.go similarity index 64% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/float.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/float.go index 04db0179..f00db30d 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/float.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/float.go @@ -1,46 +1,46 @@ package basicnode import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/mixins" ) var ( - _ ipld.Node = plainFloat(0) - _ ipld.NodePrototype = Prototype__Float{} - _ ipld.NodeBuilder = &plainFloat__Builder{} - _ ipld.NodeAssembler = &plainFloat__Assembler{} + _ datamodel.Node = plainFloat(0) + _ datamodel.NodePrototype = Prototype__Float{} + _ datamodel.NodeBuilder = &plainFloat__Builder{} + _ datamodel.NodeAssembler = &plainFloat__Assembler{} ) -func NewFloat(value float64) ipld.Node { +func NewFloat(value float64) datamodel.Node { v := plainFloat(value) return &v } -// plainFloat is a simple boxed float that complies with ipld.Node. +// plainFloat is a simple boxed float that complies with datamodel.Node. type plainFloat float64 // -- Node interface methods --> -func (plainFloat) Kind() ipld.Kind { - return ipld.Kind_Float +func (plainFloat) Kind() datamodel.Kind { + return datamodel.Kind_Float } -func (plainFloat) LookupByString(string) (ipld.Node, error) { +func (plainFloat) LookupByString(string) (datamodel.Node, error) { return mixins.Float{TypeName: "float"}.LookupByString("") } -func (plainFloat) LookupByNode(key ipld.Node) (ipld.Node, error) { +func (plainFloat) LookupByNode(key datamodel.Node) (datamodel.Node, error) { return mixins.Float{TypeName: "float"}.LookupByNode(nil) } -func (plainFloat) LookupByIndex(idx int64) (ipld.Node, error) { +func (plainFloat) LookupByIndex(idx int64) (datamodel.Node, error) { return mixins.Float{TypeName: "float"}.LookupByIndex(0) } -func (plainFloat) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { +func (plainFloat) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { return mixins.Float{TypeName: "float"}.LookupBySegment(seg) } -func (plainFloat) MapIterator() ipld.MapIterator { +func (plainFloat) MapIterator() datamodel.MapIterator { return nil } -func (plainFloat) ListIterator() ipld.ListIterator { +func (plainFloat) ListIterator() datamodel.ListIterator { return nil } func (plainFloat) Length() int64 { @@ -67,10 +67,10 @@ func (plainFloat) AsString() (string, error) { func (plainFloat) AsBytes() ([]byte, error) { return mixins.Float{TypeName: "float"}.AsBytes() } -func (plainFloat) AsLink() (ipld.Link, error) { +func (plainFloat) AsLink() (datamodel.Link, error) { return mixins.Float{TypeName: "float"}.AsLink() } -func (plainFloat) Prototype() ipld.NodePrototype { +func (plainFloat) Prototype() datamodel.NodePrototype { return Prototype__Float{} } @@ -78,7 +78,7 @@ func (plainFloat) Prototype() ipld.NodePrototype { type Prototype__Float struct{} -func (Prototype__Float) NewBuilder() ipld.NodeBuilder { +func (Prototype__Float) NewBuilder() datamodel.NodeBuilder { var w plainFloat return &plainFloat__Builder{plainFloat__Assembler{w: &w}} } @@ -89,7 +89,7 @@ type plainFloat__Builder struct { plainFloat__Assembler } -func (nb *plainFloat__Builder) Build() ipld.Node { +func (nb *plainFloat__Builder) Build() datamodel.Node { return nb.w } func (nb *plainFloat__Builder) Reset() { @@ -103,10 +103,10 @@ type plainFloat__Assembler struct { w *plainFloat } -func (plainFloat__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (plainFloat__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { return mixins.FloatAssembler{TypeName: "float"}.BeginMap(0) } -func (plainFloat__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (plainFloat__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { return mixins.FloatAssembler{TypeName: "float"}.BeginList(0) } func (plainFloat__Assembler) AssignNull() error { @@ -128,10 +128,10 @@ func (plainFloat__Assembler) AssignString(string) error { func (plainFloat__Assembler) AssignBytes([]byte) error { return mixins.FloatAssembler{TypeName: "float"}.AssignBytes(nil) } -func (plainFloat__Assembler) AssignLink(ipld.Link) error { +func (plainFloat__Assembler) AssignLink(datamodel.Link) error { return mixins.FloatAssembler{TypeName: "float"}.AssignLink(nil) } -func (na *plainFloat__Assembler) AssignNode(v ipld.Node) error { +func (na *plainFloat__Assembler) AssignNode(v datamodel.Node) error { if v2, err := v.AsFloat(); err != nil { return err } else { @@ -139,6 +139,6 @@ func (na *plainFloat__Assembler) AssignNode(v ipld.Node) error { return nil } } -func (plainFloat__Assembler) Prototype() ipld.NodePrototype { +func (plainFloat__Assembler) Prototype() datamodel.NodePrototype { return Prototype__Float{} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/int.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/int.go new file mode 100644 index 00000000..3ef4653d --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/int.go @@ -0,0 +1,226 @@ +package basicnode + +import ( + "fmt" + "math" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/mixins" +) + +var ( + _ datamodel.Node = plainInt(0) + _ datamodel.Node = plainUint(0) + _ datamodel.UintNode = plainUint(0) + _ datamodel.NodePrototype = Prototype__Int{} + _ datamodel.NodeBuilder = &plainInt__Builder{} + _ datamodel.NodeAssembler = &plainInt__Assembler{} +) + +func NewInt(value int64) datamodel.Node { + return plainInt(value) +} + +// NewUint creates a new uint64-backed Node which will behave as a plain Int +// node but also conforms to the datamodel.UintNode interface which can access +// the full uint64 range. +// +// EXPERIMENTAL: this API is experimental and may be changed or removed in a +// future release. +func NewUint(value uint64) datamodel.Node { + return plainUint(value) +} + +// plainInt is a simple boxed int that complies with datamodel.Node. +type plainInt int64 + +// -- Node interface methods for plainInt --> + +func (plainInt) Kind() datamodel.Kind { + return datamodel.Kind_Int +} +func (plainInt) LookupByString(string) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByString("") +} +func (plainInt) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByNode(nil) +} +func (plainInt) LookupByIndex(idx int64) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByIndex(0) +} +func (plainInt) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupBySegment(seg) +} +func (plainInt) MapIterator() datamodel.MapIterator { + return nil +} +func (plainInt) ListIterator() datamodel.ListIterator { + return nil +} +func (plainInt) Length() int64 { + return -1 +} +func (plainInt) IsAbsent() bool { + return false +} +func (plainInt) IsNull() bool { + return false +} +func (plainInt) AsBool() (bool, error) { + return mixins.Int{TypeName: "int"}.AsBool() +} +func (n plainInt) AsInt() (int64, error) { + return int64(n), nil +} +func (plainInt) AsFloat() (float64, error) { + return mixins.Int{TypeName: "int"}.AsFloat() +} +func (plainInt) AsString() (string, error) { + return mixins.Int{TypeName: "int"}.AsString() +} +func (plainInt) AsBytes() ([]byte, error) { + return mixins.Int{TypeName: "int"}.AsBytes() +} +func (plainInt) AsLink() (datamodel.Link, error) { + return mixins.Int{TypeName: "int"}.AsLink() +} +func (plainInt) Prototype() datamodel.NodePrototype { + return Prototype__Int{} +} + +// plainUint is a simple boxed uint64 that complies with datamodel.Node, +// allowing representation of the uint64 range above the int64 maximum via the +// UintNode interface +type plainUint uint64 + +// -- Node interface methods for plainUint --> + +func (plainUint) Kind() datamodel.Kind { + return datamodel.Kind_Int +} +func (plainUint) LookupByString(string) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByString("") +} +func (plainUint) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByNode(nil) +} +func (plainUint) LookupByIndex(idx int64) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByIndex(0) +} +func (plainUint) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupBySegment(seg) +} +func (plainUint) MapIterator() datamodel.MapIterator { + return nil +} +func (plainUint) ListIterator() datamodel.ListIterator { + return nil +} +func (plainUint) Length() int64 { + return -1 +} +func (plainUint) IsAbsent() bool { + return false +} +func (plainUint) IsNull() bool { + return false +} +func (plainUint) AsBool() (bool, error) { + return mixins.Int{TypeName: "int"}.AsBool() +} +func (n plainUint) AsInt() (int64, error) { + if uint64(n) > uint64(math.MaxInt64) { + return -1, fmt.Errorf("unsigned integer out of range of int64 type") + } + return int64(n), nil +} +func (plainUint) AsFloat() (float64, error) { + return mixins.Int{TypeName: "int"}.AsFloat() +} +func (plainUint) AsString() (string, error) { + return mixins.Int{TypeName: "int"}.AsString() +} +func (plainUint) AsBytes() ([]byte, error) { + return mixins.Int{TypeName: "int"}.AsBytes() +} +func (plainUint) AsLink() (datamodel.Link, error) { + return mixins.Int{TypeName: "int"}.AsLink() +} +func (plainUint) Prototype() datamodel.NodePrototype { + return Prototype__Int{} +} + +// allows plainUint to conform to the plainUint interface + +func (n plainUint) AsUint() (uint64, error) { + return uint64(n), nil +} + +// -- NodePrototype --> + +type Prototype__Int struct{} + +func (Prototype__Int) NewBuilder() datamodel.NodeBuilder { + var w plainInt + return &plainInt__Builder{plainInt__Assembler{w: &w}} +} + +// -- NodeBuilder --> + +type plainInt__Builder struct { + plainInt__Assembler +} + +func (nb *plainInt__Builder) Build() datamodel.Node { + return nb.w +} +func (nb *plainInt__Builder) Reset() { + var w plainInt + *nb = plainInt__Builder{plainInt__Assembler{w: &w}} +} + +// -- NodeAssembler --> + +type plainInt__Assembler struct { + w *plainInt +} + +func (plainInt__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return mixins.IntAssembler{TypeName: "int"}.BeginMap(0) +} +func (plainInt__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return mixins.IntAssembler{TypeName: "int"}.BeginList(0) +} +func (plainInt__Assembler) AssignNull() error { + return mixins.IntAssembler{TypeName: "int"}.AssignNull() +} +func (plainInt__Assembler) AssignBool(bool) error { + return mixins.IntAssembler{TypeName: "int"}.AssignBool(false) +} +func (na *plainInt__Assembler) AssignInt(v int64) error { + *na.w = plainInt(v) + return nil +} +func (plainInt__Assembler) AssignFloat(float64) error { + return mixins.IntAssembler{TypeName: "int"}.AssignFloat(0) +} +func (plainInt__Assembler) AssignString(string) error { + return mixins.IntAssembler{TypeName: "int"}.AssignString("") +} +func (plainInt__Assembler) AssignBytes([]byte) error { + return mixins.IntAssembler{TypeName: "int"}.AssignBytes(nil) +} +func (plainInt__Assembler) AssignLink(datamodel.Link) error { + return mixins.IntAssembler{TypeName: "int"}.AssignLink(nil) +} +func (na *plainInt__Assembler) AssignNode(v datamodel.Node) error { + if v2, err := v.AsInt(); err != nil { + return err + } else { + *na.w = plainInt(v2) + return nil + } +} +func (plainInt__Assembler) Prototype() datamodel.NodePrototype { + return Prototype__Int{} +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/link.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/link.go similarity index 63% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/link.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/link.go index 3542bc04..41d2cf0d 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/link.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/link.go @@ -1,47 +1,47 @@ package basicnode import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/mixins" ) var ( - _ ipld.Node = &plainLink{} - _ ipld.NodePrototype = Prototype__Link{} - _ ipld.NodeBuilder = &plainLink__Builder{} - _ ipld.NodeAssembler = &plainLink__Assembler{} + _ datamodel.Node = &plainLink{} + _ datamodel.NodePrototype = Prototype__Link{} + _ datamodel.NodeBuilder = &plainLink__Builder{} + _ datamodel.NodeAssembler = &plainLink__Assembler{} ) -func NewLink(value ipld.Link) ipld.Node { +func NewLink(value datamodel.Link) datamodel.Node { return &plainLink{value} } -// plainLink is a simple box around a Link that complies with ipld.Node. +// plainLink is a simple box around a Link that complies with datamodel.Node. type plainLink struct { - x ipld.Link + x datamodel.Link } // -- Node interface methods --> -func (plainLink) Kind() ipld.Kind { - return ipld.Kind_Link +func (plainLink) Kind() datamodel.Kind { + return datamodel.Kind_Link } -func (plainLink) LookupByString(string) (ipld.Node, error) { +func (plainLink) LookupByString(string) (datamodel.Node, error) { return mixins.Link{TypeName: "link"}.LookupByString("") } -func (plainLink) LookupByNode(key ipld.Node) (ipld.Node, error) { +func (plainLink) LookupByNode(key datamodel.Node) (datamodel.Node, error) { return mixins.Link{TypeName: "link"}.LookupByNode(nil) } -func (plainLink) LookupByIndex(idx int64) (ipld.Node, error) { +func (plainLink) LookupByIndex(idx int64) (datamodel.Node, error) { return mixins.Link{TypeName: "link"}.LookupByIndex(0) } -func (plainLink) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { +func (plainLink) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { return mixins.Link{TypeName: "link"}.LookupBySegment(seg) } -func (plainLink) MapIterator() ipld.MapIterator { +func (plainLink) MapIterator() datamodel.MapIterator { return nil } -func (plainLink) ListIterator() ipld.ListIterator { +func (plainLink) ListIterator() datamodel.ListIterator { return nil } func (plainLink) Length() int64 { @@ -68,10 +68,10 @@ func (plainLink) AsString() (string, error) { func (plainLink) AsBytes() ([]byte, error) { return mixins.Link{TypeName: "link"}.AsBytes() } -func (n *plainLink) AsLink() (ipld.Link, error) { +func (n *plainLink) AsLink() (datamodel.Link, error) { return n.x, nil } -func (plainLink) Prototype() ipld.NodePrototype { +func (plainLink) Prototype() datamodel.NodePrototype { return Prototype__Link{} } @@ -79,7 +79,7 @@ func (plainLink) Prototype() ipld.NodePrototype { type Prototype__Link struct{} -func (Prototype__Link) NewBuilder() ipld.NodeBuilder { +func (Prototype__Link) NewBuilder() datamodel.NodeBuilder { var w plainLink return &plainLink__Builder{plainLink__Assembler{w: &w}} } @@ -90,7 +90,7 @@ type plainLink__Builder struct { plainLink__Assembler } -func (nb *plainLink__Builder) Build() ipld.Node { +func (nb *plainLink__Builder) Build() datamodel.Node { return nb.w } func (nb *plainLink__Builder) Reset() { @@ -104,10 +104,10 @@ type plainLink__Assembler struct { w *plainLink } -func (plainLink__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (plainLink__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { return mixins.LinkAssembler{TypeName: "link"}.BeginMap(0) } -func (plainLink__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (plainLink__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { return mixins.LinkAssembler{TypeName: "link"}.BeginList(0) } func (plainLink__Assembler) AssignNull() error { @@ -128,11 +128,11 @@ func (plainLink__Assembler) AssignString(string) error { func (plainLink__Assembler) AssignBytes([]byte) error { return mixins.LinkAssembler{TypeName: "link"}.AssignBytes(nil) } -func (na *plainLink__Assembler) AssignLink(v ipld.Link) error { +func (na *plainLink__Assembler) AssignLink(v datamodel.Link) error { na.w.x = v return nil } -func (na *plainLink__Assembler) AssignNode(v ipld.Node) error { +func (na *plainLink__Assembler) AssignNode(v datamodel.Node) error { if v2, err := v.AsLink(); err != nil { return err } else { @@ -140,6 +140,6 @@ func (na *plainLink__Assembler) AssignNode(v ipld.Node) error { return nil } } -func (plainLink__Assembler) Prototype() ipld.NodePrototype { +func (plainLink__Assembler) Prototype() datamodel.NodePrototype { return Prototype__Link{} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/list.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/list.go similarity index 72% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/list.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/list.go index f8679272..6f7582bb 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/list.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/list.go @@ -1,52 +1,52 @@ package basicnode import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/mixins" ) var ( - _ ipld.Node = &plainList{} - _ ipld.NodePrototype = Prototype__List{} - _ ipld.NodeBuilder = &plainList__Builder{} - _ ipld.NodeAssembler = &plainList__Assembler{} + _ datamodel.Node = &plainList{} + _ datamodel.NodePrototype = Prototype__List{} + _ datamodel.NodeBuilder = &plainList__Builder{} + _ datamodel.NodeAssembler = &plainList__Assembler{} ) -// plainList is a concrete type that provides a list-kind ipld.Node. +// plainList is a concrete type that provides a list-kind datamodel.Node. // It can contain any kind of value. // plainList is also embedded in the 'any' struct and usable from there. type plainList struct { - x []ipld.Node + x []datamodel.Node } // -- Node interface methods --> -func (plainList) Kind() ipld.Kind { - return ipld.Kind_List +func (plainList) Kind() datamodel.Kind { + return datamodel.Kind_List } -func (plainList) LookupByString(string) (ipld.Node, error) { +func (plainList) LookupByString(string) (datamodel.Node, error) { return mixins.List{TypeName: "list"}.LookupByString("") } -func (plainList) LookupByNode(ipld.Node) (ipld.Node, error) { +func (plainList) LookupByNode(datamodel.Node) (datamodel.Node, error) { return mixins.List{TypeName: "list"}.LookupByNode(nil) } -func (n *plainList) LookupByIndex(idx int64) (ipld.Node, error) { +func (n *plainList) LookupByIndex(idx int64) (datamodel.Node, error) { if n.Length() <= idx { - return nil, ipld.ErrNotExists{Segment: ipld.PathSegmentOfInt(idx)} + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfInt(idx)} } return n.x[idx], nil } -func (n *plainList) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { +func (n *plainList) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { idx, err := seg.Index() if err != nil { - return nil, ipld.ErrInvalidSegmentForList{TroubleSegment: seg, Reason: err} + return nil, datamodel.ErrInvalidSegmentForList{TroubleSegment: seg, Reason: err} } return n.LookupByIndex(idx) } -func (plainList) MapIterator() ipld.MapIterator { +func (plainList) MapIterator() datamodel.MapIterator { return nil } -func (n *plainList) ListIterator() ipld.ListIterator { +func (n *plainList) ListIterator() datamodel.ListIterator { return &plainList_ListIterator{n, 0} } func (n *plainList) Length() int64 { @@ -73,11 +73,11 @@ func (plainList) AsString() (string, error) { func (plainList) AsBytes() ([]byte, error) { return mixins.List{TypeName: "list"}.AsBytes() } -func (plainList) AsLink() (ipld.Link, error) { +func (plainList) AsLink() (datamodel.Link, error) { return mixins.List{TypeName: "list"}.AsLink() } -func (plainList) Prototype() ipld.NodePrototype { - return Prototype__List{} +func (plainList) Prototype() datamodel.NodePrototype { + return Prototype.List } type plainList_ListIterator struct { @@ -85,9 +85,9 @@ type plainList_ListIterator struct { idx int } -func (itr *plainList_ListIterator) Next() (idx int64, v ipld.Node, _ error) { +func (itr *plainList_ListIterator) Next() (idx int64, v datamodel.Node, _ error) { if itr.Done() { - return -1, nil, ipld.ErrIteratorOverread{} + return -1, nil, datamodel.ErrIteratorOverread{} } v = itr.n.x[itr.idx] idx = int64(itr.idx) @@ -102,7 +102,7 @@ func (itr *plainList_ListIterator) Done() bool { type Prototype__List struct{} -func (Prototype__List) NewBuilder() ipld.NodeBuilder { +func (Prototype__List) NewBuilder() datamodel.NodeBuilder { return &plainList__Builder{plainList__Assembler{w: &plainList{}}} } @@ -112,7 +112,7 @@ type plainList__Builder struct { plainList__Assembler } -func (nb *plainList__Builder) Build() ipld.Node { +func (nb *plainList__Builder) Build() datamodel.Node { if nb.state != laState_finished { panic("invalid state: assembler must be 'finished' before Build can be called!") } @@ -147,15 +147,15 @@ const ( laState_finished // 'w' will also be nil, but this is a politer statement ) -func (plainList__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (plainList__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { return mixins.ListAssembler{TypeName: "list"}.BeginMap(0) } -func (na *plainList__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (na *plainList__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { if sizeHint < 0 { sizeHint = 0 } // Allocate storage space. - na.w.x = make([]ipld.Node, 0, sizeHint) + na.w.x = make([]datamodel.Node, 0, sizeHint) // That's it; return self as the ListAssembler. We already have all the right methods on this structure. return na, nil } @@ -177,10 +177,10 @@ func (plainList__Assembler) AssignString(string) error { func (plainList__Assembler) AssignBytes([]byte) error { return mixins.ListAssembler{TypeName: "list"}.AssignBytes(nil) } -func (plainList__Assembler) AssignLink(ipld.Link) error { +func (plainList__Assembler) AssignLink(datamodel.Link) error { return mixins.ListAssembler{TypeName: "list"}.AssignLink(nil) } -func (na *plainList__Assembler) AssignNode(v ipld.Node) error { +func (na *plainList__Assembler) AssignNode(v datamodel.Node) error { // Sanity check, then update, assembler state. // Update of state to 'finished' comes later; where exactly depends on if shortcuts apply. if na.state != laState_initial { @@ -198,8 +198,8 @@ func (na *plainList__Assembler) AssignNode(v ipld.Node) error { } // If the above shortcut didn't work, resort to a generic copy. // We call AssignNode for all the child values, giving them a chance to hit shortcuts even if we didn't. - if v.Kind() != ipld.Kind_List { - return ipld.ErrWrongKind{TypeName: "list", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustList, ActualKind: v.Kind()} + if v.Kind() != datamodel.Kind_List { + return datamodel.ErrWrongKind{TypeName: "list", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustList, ActualKind: v.Kind()} } itr := v.ListIterator() for !itr.Done() { @@ -213,15 +213,15 @@ func (na *plainList__Assembler) AssignNode(v ipld.Node) error { } return na.Finish() } -func (plainList__Assembler) Prototype() ipld.NodePrototype { - return Prototype__List{} +func (plainList__Assembler) Prototype() datamodel.NodePrototype { + return Prototype.List } // -- ListAssembler --> // AssembleValue is part of conforming to ListAssembler, which we do on // plainList__Assembler so that BeginList can just return a retyped pointer rather than new object. -func (la *plainList__Assembler) AssembleValue() ipld.NodeAssembler { +func (la *plainList__Assembler) AssembleValue() datamodel.NodeAssembler { // Sanity check, then update, assembler state. if la.state != laState_initial { panic("misuse") @@ -243,20 +243,20 @@ func (la *plainList__Assembler) Finish() error { // validators could run and report errors promptly, if this type had any. return nil } -func (plainList__Assembler) ValuePrototype(_ int64) ipld.NodePrototype { - return Prototype__Any{} +func (plainList__Assembler) ValuePrototype(_ int64) datamodel.NodePrototype { + return Prototype.Any } // -- ListAssembler.ValueAssembler --> -func (lva *plainList__ValueAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (lva *plainList__ValueAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { ma := plainList__ValueAssemblerMap{} ma.ca.w = &plainMap{} ma.p = lva.la _, err := ma.ca.BeginMap(sizeHint) return &ma, err } -func (lva *plainList__ValueAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (lva *plainList__ValueAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { la := plainList__ValueAssemblerList{} la.ca.w = &plainList{} la.p = lva.la @@ -264,7 +264,7 @@ func (lva *plainList__ValueAssembler) BeginList(sizeHint int64) (ipld.ListAssemb return &la, err } func (lva *plainList__ValueAssembler) AssignNull() error { - return lva.AssignNode(ipld.Null) + return lva.AssignNode(datamodel.Null) } func (lva *plainList__ValueAssembler) AssignBool(v bool) error { vb := plainBool(v) @@ -286,18 +286,18 @@ func (lva *plainList__ValueAssembler) AssignBytes(v []byte) error { vb := plainBytes(v) return lva.AssignNode(&vb) } -func (lva *plainList__ValueAssembler) AssignLink(v ipld.Link) error { +func (lva *plainList__ValueAssembler) AssignLink(v datamodel.Link) error { vb := plainLink{v} return lva.AssignNode(&vb) } -func (lva *plainList__ValueAssembler) AssignNode(v ipld.Node) error { +func (lva *plainList__ValueAssembler) AssignNode(v datamodel.Node) error { lva.la.w.x = append(lva.la.w.x, v) lva.la.state = laState_initial lva.la = nil // invalidate self to prevent further incorrect use. return nil } -func (plainList__ValueAssembler) Prototype() ipld.NodePrototype { - return Prototype__Any{} +func (plainList__ValueAssembler) Prototype() datamodel.NodePrototype { + return Prototype.Any } type plainList__ValueAssemblerMap struct { @@ -309,20 +309,20 @@ type plainList__ValueAssemblerMap struct { // just embedding plainMap__Assembler also behaves correctly, // but causes a lot of unnecessary autogenerated functions in the final binary. -func (ma *plainList__ValueAssemblerMap) AssembleEntry(k string) (ipld.NodeAssembler, error) { +func (ma *plainList__ValueAssemblerMap) AssembleEntry(k string) (datamodel.NodeAssembler, error) { return ma.ca.AssembleEntry(k) } -func (ma *plainList__ValueAssemblerMap) AssembleKey() ipld.NodeAssembler { +func (ma *plainList__ValueAssemblerMap) AssembleKey() datamodel.NodeAssembler { return ma.ca.AssembleKey() } -func (ma *plainList__ValueAssemblerMap) AssembleValue() ipld.NodeAssembler { +func (ma *plainList__ValueAssemblerMap) AssembleValue() datamodel.NodeAssembler { return ma.ca.AssembleValue() } -func (plainList__ValueAssemblerMap) KeyPrototype() ipld.NodePrototype { +func (plainList__ValueAssemblerMap) KeyPrototype() datamodel.NodePrototype { return Prototype__String{} } -func (plainList__ValueAssemblerMap) ValuePrototype(_ string) ipld.NodePrototype { - return Prototype__Any{} +func (plainList__ValueAssemblerMap) ValuePrototype(_ string) datamodel.NodePrototype { + return Prototype.Any } func (ma *plainList__ValueAssemblerMap) Finish() error { @@ -343,11 +343,11 @@ type plainList__ValueAssemblerList struct { // just embedding plainList__Assembler also behaves correctly, // but causes a lot of unnecessary autogenerated functions in the final binary. -func (la *plainList__ValueAssemblerList) AssembleValue() ipld.NodeAssembler { +func (la *plainList__ValueAssemblerList) AssembleValue() datamodel.NodeAssembler { return la.ca.AssembleValue() } -func (plainList__ValueAssemblerList) ValuePrototype(_ int64) ipld.NodePrototype { - return Prototype__Any{} +func (plainList__ValueAssemblerList) ValuePrototype(_ int64) datamodel.NodePrototype { + return Prototype.Any } func (la *plainList__ValueAssemblerList) Finish() error { diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/map.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/map.go similarity index 72% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/map.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/map.go index 83d6f998..9a86fc52 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/map.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/map.go @@ -3,60 +3,60 @@ package basicnode import ( "fmt" - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/mixins" ) var ( - _ ipld.Node = &plainMap{} - _ ipld.NodePrototype = Prototype__Map{} - _ ipld.NodeBuilder = &plainMap__Builder{} - _ ipld.NodeAssembler = &plainMap__Assembler{} + _ datamodel.Node = &plainMap{} + _ datamodel.NodePrototype = Prototype__Map{} + _ datamodel.NodeBuilder = &plainMap__Builder{} + _ datamodel.NodeAssembler = &plainMap__Assembler{} ) -// plainMap is a concrete type that provides a map-kind ipld.Node. +// plainMap is a concrete type that provides a map-kind datamodel.Node. // It can contain any kind of value. // plainMap is also embedded in the 'any' struct and usable from there. type plainMap struct { - m map[string]ipld.Node // string key -- even if a runtime schema wrapper is using us for storage, we must have a comparable type here, and string is all we know. - t []plainMap__Entry // table for fast iteration, order keeping, and yielding pointers to enable alloc/conv amortization. + m map[string]datamodel.Node // string key -- even if a runtime schema wrapper is using us for storage, we must have a comparable type here, and string is all we know. + t []plainMap__Entry // table for fast iteration, order keeping, and yielding pointers to enable alloc/conv amortization. } type plainMap__Entry struct { - k plainString // address of this used when we return keys as nodes, such as in iterators. Need in one place to amortize shifts to heap when ptr'ing for iface. - v ipld.Node // identical to map values. keeping them here simplifies iteration. (in codegen'd maps, this position is also part of amortization, but in this implementation, that's less useful.) + k plainString // address of this used when we return keys as nodes, such as in iterators. Need in one place to amortize shifts to heap when ptr'ing for iface. + v datamodel.Node // identical to map values. keeping them here simplifies iteration. (in codegen'd maps, this position is also part of amortization, but in this implementation, that's less useful.) // note on alternate implementations: 'v' could also use the 'any' type, and thus amortize value allocations. the memory size trade would be large however, so we don't, here. } // -- Node interface methods --> -func (plainMap) Kind() ipld.Kind { - return ipld.Kind_Map +func (plainMap) Kind() datamodel.Kind { + return datamodel.Kind_Map } -func (n *plainMap) LookupByString(key string) (ipld.Node, error) { +func (n *plainMap) LookupByString(key string) (datamodel.Node, error) { v, exists := n.m[key] if !exists { - return nil, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} } return v, nil } -func (n *plainMap) LookupByNode(key ipld.Node) (ipld.Node, error) { +func (n *plainMap) LookupByNode(key datamodel.Node) (datamodel.Node, error) { ks, err := key.AsString() if err != nil { return nil, err } return n.LookupByString(ks) } -func (plainMap) LookupByIndex(idx int64) (ipld.Node, error) { +func (plainMap) LookupByIndex(idx int64) (datamodel.Node, error) { return mixins.Map{TypeName: "map"}.LookupByIndex(0) } -func (n *plainMap) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { +func (n *plainMap) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { return n.LookupByString(seg.String()) } -func (n *plainMap) MapIterator() ipld.MapIterator { +func (n *plainMap) MapIterator() datamodel.MapIterator { return &plainMap_MapIterator{n, 0} } -func (plainMap) ListIterator() ipld.ListIterator { +func (plainMap) ListIterator() datamodel.ListIterator { return nil } func (n *plainMap) Length() int64 { @@ -83,11 +83,11 @@ func (plainMap) AsString() (string, error) { func (plainMap) AsBytes() ([]byte, error) { return mixins.Map{TypeName: "map"}.AsBytes() } -func (plainMap) AsLink() (ipld.Link, error) { +func (plainMap) AsLink() (datamodel.Link, error) { return mixins.Map{TypeName: "map"}.AsLink() } -func (plainMap) Prototype() ipld.NodePrototype { - return Prototype__Map{} +func (plainMap) Prototype() datamodel.NodePrototype { + return Prototype.Map } type plainMap_MapIterator struct { @@ -95,9 +95,9 @@ type plainMap_MapIterator struct { idx int } -func (itr *plainMap_MapIterator) Next() (k ipld.Node, v ipld.Node, _ error) { +func (itr *plainMap_MapIterator) Next() (k datamodel.Node, v datamodel.Node, _ error) { if itr.Done() { - return nil, nil, ipld.ErrIteratorOverread{} + return nil, nil, datamodel.ErrIteratorOverread{} } k = &itr.n.t[itr.idx].k v = itr.n.t[itr.idx].v @@ -112,7 +112,7 @@ func (itr *plainMap_MapIterator) Done() bool { type Prototype__Map struct{} -func (Prototype__Map) NewBuilder() ipld.NodeBuilder { +func (Prototype__Map) NewBuilder() datamodel.NodeBuilder { return &plainMap__Builder{plainMap__Assembler{w: &plainMap{}}} } @@ -122,7 +122,7 @@ type plainMap__Builder struct { plainMap__Assembler } -func (nb *plainMap__Builder) Build() ipld.Node { +func (nb *plainMap__Builder) Build() datamodel.Node { if nb.state != maState_finished { panic("invalid state: assembler must be 'finished' before Build can be called!") } @@ -162,17 +162,17 @@ const ( maState_finished // 'w' will also be nil, but this is a politer statement ) -func (na *plainMap__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (na *plainMap__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { if sizeHint < 0 { sizeHint = 0 } // Allocate storage space. na.w.t = make([]plainMap__Entry, 0, sizeHint) - na.w.m = make(map[string]ipld.Node, sizeHint) + na.w.m = make(map[string]datamodel.Node, sizeHint) // That's it; return self as the MapAssembler. We already have all the right methods on this structure. return na, nil } -func (plainMap__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (plainMap__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { return mixins.MapAssembler{TypeName: "map"}.BeginList(0) } func (plainMap__Assembler) AssignNull() error { @@ -193,10 +193,10 @@ func (plainMap__Assembler) AssignString(string) error { func (plainMap__Assembler) AssignBytes([]byte) error { return mixins.MapAssembler{TypeName: "map"}.AssignBytes(nil) } -func (plainMap__Assembler) AssignLink(ipld.Link) error { +func (plainMap__Assembler) AssignLink(datamodel.Link) error { return mixins.MapAssembler{TypeName: "map"}.AssignLink(nil) } -func (na *plainMap__Assembler) AssignNode(v ipld.Node) error { +func (na *plainMap__Assembler) AssignNode(v datamodel.Node) error { // Sanity check assembler state. // Update of state to 'finished' comes later; where exactly depends on if shortcuts apply. if na.state != maState_initial { @@ -214,8 +214,8 @@ func (na *plainMap__Assembler) AssignNode(v ipld.Node) error { } // If the above shortcut didn't work, resort to a generic copy. // We call AssignNode for all the child values, giving them a chance to hit shortcuts even if we didn't. - if v.Kind() != ipld.Kind_Map { - return ipld.ErrWrongKind{TypeName: "map", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: v.Kind()} + if v.Kind() != datamodel.Kind_Map { + return datamodel.ErrWrongKind{TypeName: "map", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: v.Kind()} } itr := v.MapIterator() for !itr.Done() { @@ -232,15 +232,15 @@ func (na *plainMap__Assembler) AssignNode(v ipld.Node) error { } return na.Finish() } -func (plainMap__Assembler) Prototype() ipld.NodePrototype { - return Prototype__Map{} +func (plainMap__Assembler) Prototype() datamodel.NodePrototype { + return Prototype.Map } // -- MapAssembler --> // AssembleEntry is part of conforming to MapAssembler, which we do on // plainMap__Assembler so that BeginMap can just return a retyped pointer rather than new object. -func (ma *plainMap__Assembler) AssembleEntry(k string) (ipld.NodeAssembler, error) { +func (ma *plainMap__Assembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { // Sanity check assembler state. // Update of state comes after possible key rejection. if ma.state != maState_initial { @@ -249,7 +249,7 @@ func (ma *plainMap__Assembler) AssembleEntry(k string) (ipld.NodeAssembler, erro // Check for dup keys; error if so. _, exists := ma.w.m[k] if exists { - return nil, ipld.ErrRepeatedMapKey{Key: plainString(k)} + return nil, datamodel.ErrRepeatedMapKey{Key: plainString(k)} } ma.state = maState_midValue ma.w.t = append(ma.w.t, plainMap__Entry{k: plainString(k)}) @@ -260,7 +260,7 @@ func (ma *plainMap__Assembler) AssembleEntry(k string) (ipld.NodeAssembler, erro // AssembleKey is part of conforming to MapAssembler, which we do on // plainMap__Assembler so that BeginMap can just return a retyped pointer rather than new object. -func (ma *plainMap__Assembler) AssembleKey() ipld.NodeAssembler { +func (ma *plainMap__Assembler) AssembleKey() datamodel.NodeAssembler { // Sanity check, then update, assembler state. if ma.state != maState_initial { panic("misuse") @@ -273,7 +273,7 @@ func (ma *plainMap__Assembler) AssembleKey() ipld.NodeAssembler { // AssembleValue is part of conforming to MapAssembler, which we do on // plainMap__Assembler so that BeginMap can just return a retyped pointer rather than new object. -func (ma *plainMap__Assembler) AssembleValue() ipld.NodeAssembler { +func (ma *plainMap__Assembler) AssembleValue() datamodel.NodeAssembler { // Sanity check, then update, assembler state. if ma.state != maState_expectValue { panic("misuse") @@ -295,19 +295,19 @@ func (ma *plainMap__Assembler) Finish() error { // validators could run and report errors promptly, if this type had any. return nil } -func (plainMap__Assembler) KeyPrototype() ipld.NodePrototype { +func (plainMap__Assembler) KeyPrototype() datamodel.NodePrototype { return Prototype__String{} } -func (plainMap__Assembler) ValuePrototype(_ string) ipld.NodePrototype { - return Prototype__Any{} +func (plainMap__Assembler) ValuePrototype(_ string) datamodel.NodePrototype { + return Prototype.Any } // -- MapAssembler.KeyAssembler --> -func (plainMap__KeyAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (plainMap__KeyAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { return mixins.StringAssembler{TypeName: "string"}.BeginMap(0) } -func (plainMap__KeyAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (plainMap__KeyAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { return mixins.StringAssembler{TypeName: "string"}.BeginList(0) } func (plainMap__KeyAssembler) AssignNull() error { @@ -329,7 +329,7 @@ func (mka *plainMap__KeyAssembler) AssignString(v string) error { if exists { mka.ma.state = maState_initial mka.ma = nil // invalidate self to prevent further incorrect use. - return ipld.ErrRepeatedMapKey{Key: plainString(v)} + return datamodel.ErrRepeatedMapKey{Key: plainString(v)} } // Assign the key into the end of the entry table; // we'll be doing map insertions after we get the value in hand. @@ -345,30 +345,30 @@ func (mka *plainMap__KeyAssembler) AssignString(v string) error { func (plainMap__KeyAssembler) AssignBytes([]byte) error { return mixins.StringAssembler{TypeName: "string"}.AssignBytes(nil) } -func (plainMap__KeyAssembler) AssignLink(ipld.Link) error { +func (plainMap__KeyAssembler) AssignLink(datamodel.Link) error { return mixins.StringAssembler{TypeName: "string"}.AssignLink(nil) } -func (mka *plainMap__KeyAssembler) AssignNode(v ipld.Node) error { +func (mka *plainMap__KeyAssembler) AssignNode(v datamodel.Node) error { vs, err := v.AsString() if err != nil { return fmt.Errorf("cannot assign non-string node into map key assembler") // FIXME:errors: this doesn't quite fit in ErrWrongKind cleanly; new error type? } return mka.AssignString(vs) } -func (plainMap__KeyAssembler) Prototype() ipld.NodePrototype { +func (plainMap__KeyAssembler) Prototype() datamodel.NodePrototype { return Prototype__String{} } // -- MapAssembler.ValueAssembler --> -func (mva *plainMap__ValueAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (mva *plainMap__ValueAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { ma := plainMap__ValueAssemblerMap{} ma.ca.w = &plainMap{} ma.p = mva.ma _, err := ma.ca.BeginMap(sizeHint) return &ma, err } -func (mva *plainMap__ValueAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (mva *plainMap__ValueAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { la := plainMap__ValueAssemblerList{} la.ca.w = &plainList{} la.p = mva.ma @@ -376,7 +376,7 @@ func (mva *plainMap__ValueAssembler) BeginList(sizeHint int64) (ipld.ListAssembl return &la, err } func (mva *plainMap__ValueAssembler) AssignNull() error { - return mva.AssignNode(ipld.Null) + return mva.AssignNode(datamodel.Null) } func (mva *plainMap__ValueAssembler) AssignBool(v bool) error { vb := plainBool(v) @@ -398,11 +398,11 @@ func (mva *plainMap__ValueAssembler) AssignBytes(v []byte) error { vb := plainBytes(v) return mva.AssignNode(&vb) } -func (mva *plainMap__ValueAssembler) AssignLink(v ipld.Link) error { +func (mva *plainMap__ValueAssembler) AssignLink(v datamodel.Link) error { vb := plainLink{v} return mva.AssignNode(&vb) } -func (mva *plainMap__ValueAssembler) AssignNode(v ipld.Node) error { +func (mva *plainMap__ValueAssembler) AssignNode(v datamodel.Node) error { l := len(mva.ma.w.t) - 1 mva.ma.w.t[l].v = v mva.ma.w.m[string(mva.ma.w.t[l].k)] = v @@ -410,8 +410,8 @@ func (mva *plainMap__ValueAssembler) AssignNode(v ipld.Node) error { mva.ma = nil // invalidate self to prevent further incorrect use. return nil } -func (plainMap__ValueAssembler) Prototype() ipld.NodePrototype { - return Prototype__Any{} +func (plainMap__ValueAssembler) Prototype() datamodel.NodePrototype { + return Prototype.Any } type plainMap__ValueAssemblerMap struct { @@ -423,20 +423,20 @@ type plainMap__ValueAssemblerMap struct { // just embedding plainMap__Assembler also behaves correctly, // but causes a lot of unnecessary autogenerated functions in the final binary. -func (ma *plainMap__ValueAssemblerMap) AssembleEntry(k string) (ipld.NodeAssembler, error) { +func (ma *plainMap__ValueAssemblerMap) AssembleEntry(k string) (datamodel.NodeAssembler, error) { return ma.ca.AssembleEntry(k) } -func (ma *plainMap__ValueAssemblerMap) AssembleKey() ipld.NodeAssembler { +func (ma *plainMap__ValueAssemblerMap) AssembleKey() datamodel.NodeAssembler { return ma.ca.AssembleKey() } -func (ma *plainMap__ValueAssemblerMap) AssembleValue() ipld.NodeAssembler { +func (ma *plainMap__ValueAssemblerMap) AssembleValue() datamodel.NodeAssembler { return ma.ca.AssembleValue() } -func (plainMap__ValueAssemblerMap) KeyPrototype() ipld.NodePrototype { +func (plainMap__ValueAssemblerMap) KeyPrototype() datamodel.NodePrototype { return Prototype__String{} } -func (plainMap__ValueAssemblerMap) ValuePrototype(_ string) ipld.NodePrototype { - return Prototype__Any{} +func (plainMap__ValueAssemblerMap) ValuePrototype(_ string) datamodel.NodePrototype { + return Prototype.Any } func (ma *plainMap__ValueAssemblerMap) Finish() error { @@ -457,11 +457,11 @@ type plainMap__ValueAssemblerList struct { // just embedding plainList__Assembler also behaves correctly, // but causes a lot of unnecessary autogenerated functions in the final binary. -func (la *plainMap__ValueAssemblerList) AssembleValue() ipld.NodeAssembler { +func (la *plainMap__ValueAssemblerList) AssembleValue() datamodel.NodeAssembler { return la.ca.AssembleValue() } -func (plainMap__ValueAssemblerList) ValuePrototype(_ int64) ipld.NodePrototype { - return Prototype__Any{} +func (plainMap__ValueAssemblerList) ValuePrototype(_ int64) datamodel.NodePrototype { + return Prototype.Any } func (la *plainMap__ValueAssemblerList) Finish() error { diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/prototypes.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/prototypes.go similarity index 82% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/prototypes.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/prototypes.go index d3f2c1fd..5e0af9a9 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/prototypes.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/prototypes.go @@ -3,11 +3,11 @@ package basicnode // Prototype embeds a NodePrototype for every kind of Node implementation in this package. // You can use it like this: // -// basicnode.Prototype.Map.NewBuilder().BeginMap() //... +// basicnode.Prototype.Map.NewBuilder().BeginMap() //... // // and: // -// basicnode.Prototype.String.NewBuilder().AssignString("x") // ... +// basicnode.Prototype.String.NewBuilder().AssignString("x") // ... // // Most of the prototypes are for one particular Kind of node (e.g. string, int, etc); // you can use the "Any" style if you want a builder that can accept any kind of data. diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/string.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/string.go similarity index 66% rename from fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/string.go rename to fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/string.go index 37ac6405..3d9856c8 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basic/string.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/basicnode/string.go @@ -1,23 +1,23 @@ package basicnode import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/mixins" ) var ( - _ ipld.Node = plainString("") - _ ipld.NodePrototype = Prototype__String{} - _ ipld.NodeBuilder = &plainString__Builder{} - _ ipld.NodeAssembler = &plainString__Assembler{} + _ datamodel.Node = plainString("") + _ datamodel.NodePrototype = Prototype__String{} + _ datamodel.NodeBuilder = &plainString__Builder{} + _ datamodel.NodeAssembler = &plainString__Assembler{} ) -func NewString(value string) ipld.Node { +func NewString(value string) datamodel.Node { v := plainString(value) return &v } -// plainString is a simple boxed string that complies with ipld.Node. +// plainString is a simple boxed string that complies with datamodel.Node. // It's useful for many things, such as boxing map keys. // // The implementation is a simple typedef of a string; @@ -27,25 +27,25 @@ type plainString string // -- Node interface methods --> -func (plainString) Kind() ipld.Kind { - return ipld.Kind_String +func (plainString) Kind() datamodel.Kind { + return datamodel.Kind_String } -func (plainString) LookupByString(string) (ipld.Node, error) { +func (plainString) LookupByString(string) (datamodel.Node, error) { return mixins.String{TypeName: "string"}.LookupByString("") } -func (plainString) LookupByNode(key ipld.Node) (ipld.Node, error) { +func (plainString) LookupByNode(key datamodel.Node) (datamodel.Node, error) { return mixins.String{TypeName: "string"}.LookupByNode(nil) } -func (plainString) LookupByIndex(idx int64) (ipld.Node, error) { +func (plainString) LookupByIndex(idx int64) (datamodel.Node, error) { return mixins.String{TypeName: "string"}.LookupByIndex(0) } -func (plainString) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { +func (plainString) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { return mixins.String{TypeName: "string"}.LookupBySegment(seg) } -func (plainString) MapIterator() ipld.MapIterator { +func (plainString) MapIterator() datamodel.MapIterator { return nil } -func (plainString) ListIterator() ipld.ListIterator { +func (plainString) ListIterator() datamodel.ListIterator { return nil } func (plainString) Length() int64 { @@ -72,10 +72,10 @@ func (x plainString) AsString() (string, error) { func (plainString) AsBytes() ([]byte, error) { return mixins.String{TypeName: "string"}.AsBytes() } -func (plainString) AsLink() (ipld.Link, error) { +func (plainString) AsLink() (datamodel.Link, error) { return mixins.String{TypeName: "string"}.AsLink() } -func (plainString) Prototype() ipld.NodePrototype { +func (plainString) Prototype() datamodel.NodePrototype { return Prototype__String{} } @@ -83,7 +83,7 @@ func (plainString) Prototype() ipld.NodePrototype { type Prototype__String struct{} -func (Prototype__String) NewBuilder() ipld.NodeBuilder { +func (Prototype__String) NewBuilder() datamodel.NodeBuilder { var w plainString return &plainString__Builder{plainString__Assembler{w: &w}} } @@ -94,7 +94,7 @@ type plainString__Builder struct { plainString__Assembler } -func (nb *plainString__Builder) Build() ipld.Node { +func (nb *plainString__Builder) Build() datamodel.Node { return nb.w } func (nb *plainString__Builder) Reset() { @@ -108,10 +108,10 @@ type plainString__Assembler struct { w *plainString } -func (plainString__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { +func (plainString__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { return mixins.StringAssembler{TypeName: "string"}.BeginMap(0) } -func (plainString__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { +func (plainString__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { return mixins.StringAssembler{TypeName: "string"}.BeginList(0) } func (plainString__Assembler) AssignNull() error { @@ -133,10 +133,10 @@ func (na *plainString__Assembler) AssignString(v string) error { func (plainString__Assembler) AssignBytes([]byte) error { return mixins.StringAssembler{TypeName: "string"}.AssignBytes(nil) } -func (plainString__Assembler) AssignLink(ipld.Link) error { +func (plainString__Assembler) AssignLink(datamodel.Link) error { return mixins.StringAssembler{TypeName: "string"}.AssignLink(nil) } -func (na *plainString__Assembler) AssignNode(v ipld.Node) error { +func (na *plainString__Assembler) AssignNode(v datamodel.Node) error { if v2, err := v.AsString(); err != nil { return err } else { @@ -144,6 +144,6 @@ func (na *plainString__Assembler) AssignNode(v ipld.Node) error { return nil } } -func (plainString__Assembler) Prototype() ipld.NodePrototype { +func (plainString__Assembler) Prototype() datamodel.NodePrototype { return Prototype__String{} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/api.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/api.go new file mode 100644 index 00000000..a816cfce --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/api.go @@ -0,0 +1,335 @@ +// Package bindnode provides a datamodel.Node implementation via Go reflection. +// +// This package is EXPERIMENTAL; its behavior and API might change as it's still +// in development. +package bindnode + +import ( + "reflect" + + "github.com/ipfs/go-cid" + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/schema" +) + +// Prototype implements a schema.TypedPrototype given a Go pointer type and an +// IPLD schema type. Note that the result is also a datamodel.NodePrototype. +// +// If both the Go type and schema type are supplied, it is assumed that they are +// compatible with one another. +// +// If either the Go type or schema type are nil, we infer the missing type from +// the other provided type. For example, we can infer an unnamed Go struct type +// for a schema struct type, and we can infer a schema Int type for a Go int64 +// type. The inferring logic is still a work in progress and subject to change. +// At this time, inferring IPLD Unions and Enums from Go types is not supported. +// +// When supplying a non-nil ptrType, Prototype only obtains the Go pointer type +// from it, so its underlying value will typically be nil. For example: +// +// proto := bindnode.Prototype((*goType)(nil), schemaType) +func Prototype(ptrType interface{}, schemaType schema.Type, options ...Option) schema.TypedPrototype { + if ptrType == nil && schemaType == nil { + panic("bindnode: either ptrType or schemaType must not be nil") + } + + cfg := applyOptions(options...) + + // TODO: if both are supplied, verify that they are compatible + + var goType reflect.Type + if ptrType == nil { + goType = inferGoType(schemaType, make(map[schema.TypeName]inferredStatus), 0) + } else { + goPtrType := reflect.TypeOf(ptrType) + if goPtrType.Kind() != reflect.Ptr { + panic("bindnode: ptrType must be a pointer") + } + goType = goPtrType.Elem() + if goType.Kind() == reflect.Ptr { + panic("bindnode: ptrType must not be a pointer to a pointer") + } + + if schemaType == nil { + schemaType = inferSchema(goType, 0) + } else { + verifyCompatibility(cfg, make(map[seenEntry]bool), goType, schemaType) + } + } + + return &_prototype{cfg: cfg, schemaType: schemaType, goType: goType} +} + +type converter struct { + kind schema.TypeKind + + customFromBool func(bool) (interface{}, error) + customToBool func(interface{}) (bool, error) + + customFromInt func(int64) (interface{}, error) + customToInt func(interface{}) (int64, error) + + customFromFloat func(float64) (interface{}, error) + customToFloat func(interface{}) (float64, error) + + customFromString func(string) (interface{}, error) + customToString func(interface{}) (string, error) + + customFromBytes func([]byte) (interface{}, error) + customToBytes func(interface{}) ([]byte, error) + + customFromLink func(cid.Cid) (interface{}, error) + customToLink func(interface{}) (cid.Cid, error) + + customFromAny func(datamodel.Node) (interface{}, error) + customToAny func(interface{}) (datamodel.Node, error) +} + +type config map[reflect.Type]*converter + +// this mainly exists to short-circuit the nonPtrType() call; the `Type()` variant +// exists for completeness +func (c config) converterFor(val reflect.Value) *converter { + if len(c) == 0 { + return nil + } + return c[nonPtrType(val)] +} + +func (c config) converterForType(typ reflect.Type) *converter { + if len(c) == 0 { + return nil + } + return c[typ] +} + +// Option is able to apply custom options to the bindnode API +type Option func(config) + +// TypedBoolConverter adds custom converter functions for a particular +// type as identified by a pointer in the first argument. +// The fromFunc is of the form: func(bool) (interface{}, error) +// and toFunc is of the form: func(interface{}) (bool, error) +// where interface{} is a pointer form of the type we are converting. +// +// TypedBoolConverter is an EXPERIMENTAL API and may be removed or +// changed in a future release. +func TypedBoolConverter(ptrVal interface{}, from func(bool) (interface{}, error), to func(interface{}) (bool, error)) Option { + customType := nonPtrType(reflect.ValueOf(ptrVal)) + converter := &converter{ + kind: schema.TypeKind_Bool, + customFromBool: from, + customToBool: to, + } + return func(cfg config) { + cfg[customType] = converter + } +} + +// TypedIntConverter adds custom converter functions for a particular +// type as identified by a pointer in the first argument. +// The fromFunc is of the form: func(int64) (interface{}, error) +// and toFunc is of the form: func(interface{}) (int64, error) +// where interface{} is a pointer form of the type we are converting. +// +// TypedIntConverter is an EXPERIMENTAL API and may be removed or +// changed in a future release. +func TypedIntConverter(ptrVal interface{}, from func(int64) (interface{}, error), to func(interface{}) (int64, error)) Option { + customType := nonPtrType(reflect.ValueOf(ptrVal)) + converter := &converter{ + kind: schema.TypeKind_Int, + customFromInt: from, + customToInt: to, + } + return func(cfg config) { + cfg[customType] = converter + } +} + +// TypedFloatConverter adds custom converter functions for a particular +// type as identified by a pointer in the first argument. +// The fromFunc is of the form: func(float64) (interface{}, error) +// and toFunc is of the form: func(interface{}) (float64, error) +// where interface{} is a pointer form of the type we are converting. +// +// TypedFloatConverter is an EXPERIMENTAL API and may be removed or +// changed in a future release. +func TypedFloatConverter(ptrVal interface{}, from func(float64) (interface{}, error), to func(interface{}) (float64, error)) Option { + customType := nonPtrType(reflect.ValueOf(ptrVal)) + converter := &converter{ + kind: schema.TypeKind_Float, + customFromFloat: from, + customToFloat: to, + } + return func(cfg config) { + cfg[customType] = converter + } +} + +// TypedStringConverter adds custom converter functions for a particular +// type as identified by a pointer in the first argument. +// The fromFunc is of the form: func(string) (interface{}, error) +// and toFunc is of the form: func(interface{}) (string, error) +// where interface{} is a pointer form of the type we are converting. +// +// TypedStringConverter is an EXPERIMENTAL API and may be removed or +// changed in a future release. +func TypedStringConverter(ptrVal interface{}, from func(string) (interface{}, error), to func(interface{}) (string, error)) Option { + customType := nonPtrType(reflect.ValueOf(ptrVal)) + converter := &converter{ + kind: schema.TypeKind_String, + customFromString: from, + customToString: to, + } + return func(cfg config) { + cfg[customType] = converter + } +} + +// TypedBytesConverter adds custom converter functions for a particular +// type as identified by a pointer in the first argument. +// The fromFunc is of the form: func([]byte) (interface{}, error) +// and toFunc is of the form: func(interface{}) ([]byte, error) +// where interface{} is a pointer form of the type we are converting. +// +// TypedBytesConverter is an EXPERIMENTAL API and may be removed or +// changed in a future release. +func TypedBytesConverter(ptrVal interface{}, from func([]byte) (interface{}, error), to func(interface{}) ([]byte, error)) Option { + customType := nonPtrType(reflect.ValueOf(ptrVal)) + converter := &converter{ + kind: schema.TypeKind_Bytes, + customFromBytes: from, + customToBytes: to, + } + return func(cfg config) { + cfg[customType] = converter + } +} + +// TypedLinkConverter adds custom converter functions for a particular +// type as identified by a pointer in the first argument. +// The fromFunc is of the form: func([]byte) (interface{}, error) +// and toFunc is of the form: func(interface{}) ([]byte, error) +// where interface{} is a pointer form of the type we are converting. +// +// Beware that this API is only compatible with cidlink.Link types in the data +// model and may result in errors if attempting to convert from other +// datamodel.Link types. +// +// TypedLinkConverter is an EXPERIMENTAL API and may be removed or +// changed in a future release. +func TypedLinkConverter(ptrVal interface{}, from func(cid.Cid) (interface{}, error), to func(interface{}) (cid.Cid, error)) Option { + customType := nonPtrType(reflect.ValueOf(ptrVal)) + converter := &converter{ + kind: schema.TypeKind_Link, + customFromLink: from, + customToLink: to, + } + return func(cfg config) { + cfg[customType] = converter + } +} + +// TypedAnyConverter adds custom converter functions for a particular +// type as identified by a pointer in the first argument. +// The fromFunc is of the form: func(datamodel.Node) (interface{}, error) +// and toFunc is of the form: func(interface{}) (datamodel.Node, error) +// where interface{} is a pointer form of the type we are converting. +// +// This method should be able to deal with all forms of Any and return an error +// if the expected data forms don't match the expected. +// +// TypedAnyConverter is an EXPERIMENTAL API and may be removed or +// changed in a future release. +func TypedAnyConverter(ptrVal interface{}, from func(datamodel.Node) (interface{}, error), to func(interface{}) (datamodel.Node, error)) Option { + customType := nonPtrType(reflect.ValueOf(ptrVal)) + converter := &converter{ + kind: schema.TypeKind_Any, + customFromAny: from, + customToAny: to, + } + return func(cfg config) { + cfg[customType] = converter + } +} + +func applyOptions(opt ...Option) config { + if len(opt) == 0 { + // no need to allocate, we access it via converterFor and converterForType + // which are safe for nil maps + return nil + } + cfg := make(map[reflect.Type]*converter) + for _, o := range opt { + o(cfg) + } + return cfg +} + +// Wrap implements a schema.TypedNode given a non-nil pointer to a Go value and an +// IPLD schema type. Note that the result is also a datamodel.Node. +// +// Wrap is meant to be used when one already has a Go value with data. +// As such, ptrVal must not be nil. +// +// Similar to Prototype, if schemaType is non-nil it is assumed to be compatible +// with the Go type, and otherwise it's inferred from the Go type. +func Wrap(ptrVal interface{}, schemaType schema.Type, options ...Option) schema.TypedNode { + if ptrVal == nil { + panic("bindnode: ptrVal must not be nil") + } + goPtrVal := reflect.ValueOf(ptrVal) + if goPtrVal.Kind() != reflect.Ptr { + panic("bindnode: ptrVal must be a pointer") + } + if goPtrVal.IsNil() { + // Note that this can happen if ptrVal was a typed nil. + panic("bindnode: ptrVal must not be nil") + } + cfg := applyOptions(options...) + goVal := goPtrVal.Elem() + if goVal.Kind() == reflect.Ptr { + panic("bindnode: ptrVal must not be a pointer to a pointer") + } + if schemaType == nil { + schemaType = inferSchema(goVal.Type(), 0) + } else { + // TODO(rvagg): explore ways to make this skippable by caching in the schema.Type + // passed in to this function; e.g. if you call Prototype(), then you've gone through + // this already, then calling .Type() on that could return a bindnode version of + // schema.Type that has the config cached and can be assumed to have been checked or + // inferred. + verifyCompatibility(cfg, make(map[seenEntry]bool), goVal.Type(), schemaType) + } + return newNode(cfg, schemaType, goVal) +} + +// TODO: consider making our own Node interface, like: +// +// type WrappedNode interface { +// datamodel.Node +// Unwrap() (ptrVal interface) +// } +// +// Pros: API is easier to understand, harder to mix up with other datamodel.Nodes. +// Cons: One usually only has a datamodel.Node, and type assertions can be weird. + +// Unwrap takes a datamodel.Node implemented by Prototype or Wrap, +// and returns a pointer to the inner Go value. +// +// Unwrap returns nil if the node isn't implemented by this package. +func Unwrap(node datamodel.Node) (ptrVal interface{}) { + var val reflect.Value + switch node := node.(type) { + case *_node: + val = node.val + case *_nodeRepr: + val = node.val + default: + return nil + } + if val.Kind() == reflect.Ptr { + panic("bindnode: didn't expect val to be a pointer") + } + return val.Addr().Interface() +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/generate.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/generate.go new file mode 100644 index 00000000..aebc934b --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/generate.go @@ -0,0 +1,139 @@ +package bindnode + +import ( + "bytes" + "fmt" + "go/format" + "io" + "strings" + + "github.com/ipld/go-ipld-prime/schema" +) + +// TODO(mvdan): deduplicate with inferGoType once reflect supports creating named types + +func produceGoType(goTypes map[string]string, typ schema.Type) (name, src string) { + if typ, ok := typ.(interface{ IsAnonymous() bool }); ok { + if typ.IsAnonymous() { + panic("TODO: does this ever happen?") + } + } + + name = string(typ.Name()) + + switch typ.(type) { + case *schema.TypeBool: + return goTypeBool.String(), "" + case *schema.TypeInt: + return goTypeInt.String(), "" + case *schema.TypeFloat: + return goTypeFloat.String(), "" + case *schema.TypeString: + return goTypeString.String(), "" + case *schema.TypeBytes: + return goTypeBytes.String(), "" + case *schema.TypeLink: + return goTypeLink.String(), "" // datamodel.Link + case *schema.TypeAny: + return goTypeNode.String(), "" // datamodel.Node + } + + // Results are cached in goTypes. + if src := goTypes[name]; src != "" { + return name, src + } + + src = produceGoTypeInner(goTypes, name, typ) + goTypes[name] = src + return name, src +} + +func produceGoTypeInner(goTypes map[string]string, name string, typ schema.Type) (src string) { + // Avoid infinite cycles. + // produceGoType will fill in the final type later. + goTypes[name] = "WIP" + + switch typ := typ.(type) { + case *schema.TypeEnum: + // TODO: also generate named constants for the members. + return goTypeString.String() + case *schema.TypeStruct: + var b strings.Builder + fmt.Fprintf(&b, "struct {\n") + fields := typ.Fields() + for _, field := range fields { + fmt.Fprintf(&b, "%s ", fieldNameFromSchema(field.Name())) + ftypGo, _ := produceGoType(goTypes, field.Type()) + if field.IsNullable() { + fmt.Fprintf(&b, "*") + } + if field.IsOptional() { + fmt.Fprintf(&b, "*") + } + fmt.Fprintf(&b, "%s\n", ftypGo) + } + fmt.Fprintf(&b, "\n}") + return b.String() + case *schema.TypeMap: + ktyp, _ := produceGoType(goTypes, typ.KeyType()) + vtyp, _ := produceGoType(goTypes, typ.ValueType()) + if typ.ValueIsNullable() { + vtyp = "*" + vtyp + } + return fmt.Sprintf(`struct { + Keys []%s + Values map[%s]%s + }`, ktyp, ktyp, vtyp) + case *schema.TypeList: + etyp, _ := produceGoType(goTypes, typ.ValueType()) + if typ.ValueIsNullable() { + etyp = "*" + etyp + } + return fmt.Sprintf("[]%s", etyp) + case *schema.TypeUnion: + var b strings.Builder + fmt.Fprintf(&b, "struct{\n") + members := typ.Members() + for _, ftyp := range members { + ftypGo, _ := produceGoType(goTypes, ftyp) + fmt.Fprintf(&b, "%s ", fieldNameFromSchema(string(ftyp.Name()))) + fmt.Fprintf(&b, "*%s\n", ftypGo) + } + fmt.Fprintf(&b, "\n}") + return b.String() + } + panic(fmt.Sprintf("%T\n", typ)) +} + +// ProduceGoTypes infers Go types from an IPLD schema in ts +// and writes their Go source code type declarations to w. +// Note that just the types are written, +// without a package declaration nor any imports. +// +// This gives a good starting point when wanting to use bindnode with Go types, +// but users will generally want to own and modify the types afterward, +// so they can add documentation or tweak the types as needed. +func ProduceGoTypes(w io.Writer, ts *schema.TypeSystem) error { + goTypes := make(map[string]string) + var buf bytes.Buffer + for _, name := range ts.Names() { + schemaType := ts.TypeByName(string(name)) + if name != schemaType.Name() { + panic(fmt.Sprintf("%s vs %s", name, schemaType.Name())) + } + _, src := produceGoType(goTypes, schemaType) + if src == "" { + continue // scalar type used directly + } + fmt.Fprintf(&buf, "type %s %s\n", name, src) + } + + src, err := format.Source(buf.Bytes()) + if err != nil { + return err + } + if _, err := w.Write(src); err != nil { + return err + } + return nil +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/infer.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/infer.go new file mode 100644 index 00000000..6b1c4849 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/infer.go @@ -0,0 +1,507 @@ +package bindnode + +import ( + "fmt" + "go/token" + "reflect" + "strings" + + "github.com/ipfs/go-cid" + "github.com/ipld/go-ipld-prime/datamodel" + cidlink "github.com/ipld/go-ipld-prime/linking/cid" + "github.com/ipld/go-ipld-prime/schema" +) + +var ( + goTypeBool = reflect.TypeOf(false) + goTypeInt = reflect.TypeOf(int(0)) + goTypeFloat = reflect.TypeOf(0.0) + goTypeString = reflect.TypeOf("") + goTypeBytes = reflect.TypeOf([]byte{}) + goTypeLink = reflect.TypeOf((*datamodel.Link)(nil)).Elem() + goTypeNode = reflect.TypeOf((*datamodel.Node)(nil)).Elem() + goTypeCidLink = reflect.TypeOf((*cidlink.Link)(nil)).Elem() + goTypeCid = reflect.TypeOf((*cid.Cid)(nil)).Elem() + + schemaTypeBool = schema.SpawnBool("Bool") + schemaTypeInt = schema.SpawnInt("Int") + schemaTypeFloat = schema.SpawnFloat("Float") + schemaTypeString = schema.SpawnString("String") + schemaTypeBytes = schema.SpawnBytes("Bytes") + schemaTypeLink = schema.SpawnLink("Link") + schemaTypeAny = schema.SpawnAny("Any") +) + +// Consider exposing these APIs later, if they might be useful. + +type seenEntry struct { + goType reflect.Type + schemaType schema.Type +} + +// verifyCompatibility is the primary way we check that the schema type(s) +// matches the Go type(s); so we do this before we can proceed operating on it. +// verifyCompatibility doesn't return an error, it panics鈥攖he errors here are +// not runtime errors, they're programmer errors because your schema doesn't +// match your Go type +func verifyCompatibility(cfg config, seen map[seenEntry]bool, goType reflect.Type, schemaType schema.Type) { + // TODO(mvdan): support **T as well? + if goType.Kind() == reflect.Ptr { + goType = goType.Elem() + } + + // Avoid endless loops. + // + // TODO(mvdan): this is easy but fairly allocation-happy. + // Plus, one map per call means we don't reuse work. + if seen[seenEntry{goType, schemaType}] { + return + } + seen[seenEntry{goType, schemaType}] = true + + doPanic := func(format string, args ...interface{}) { + panicFormat := "bindnode: schema type %s is not compatible with Go type %s" + panicArgs := []interface{}{schemaType.Name(), goType.String()} + + if format != "" { + panicFormat += ": " + format + } + panicArgs = append(panicArgs, args...) + panic(fmt.Sprintf(panicFormat, panicArgs...)) + } + switch schemaType := schemaType.(type) { + case *schema.TypeBool: + if customConverter := cfg.converterForType(goType); customConverter != nil { + if customConverter.kind != schema.TypeKind_Bool { + doPanic("kind mismatch; custom converter for type is not for Bool") + } + } else if goType.Kind() != reflect.Bool { + doPanic("kind mismatch; need boolean") + } + case *schema.TypeInt: + if customConverter := cfg.converterForType(goType); customConverter != nil { + if customConverter.kind != schema.TypeKind_Int { + doPanic("kind mismatch; custom converter for type is not for Int") + } + } else if kind := goType.Kind(); !kindInt[kind] && !kindUint[kind] { + doPanic("kind mismatch; need integer") + } + case *schema.TypeFloat: + if customConverter := cfg.converterForType(goType); customConverter != nil { + if customConverter.kind != schema.TypeKind_Float { + doPanic("kind mismatch; custom converter for type is not for Float") + } + } else { + switch goType.Kind() { + case reflect.Float32, reflect.Float64: + default: + doPanic("kind mismatch; need float") + } + } + case *schema.TypeString: + // TODO: allow []byte? + if customConverter := cfg.converterForType(goType); customConverter != nil { + if customConverter.kind != schema.TypeKind_String { + doPanic("kind mismatch; custom converter for type is not for String") + } + } else if goType.Kind() != reflect.String { + doPanic("kind mismatch; need string") + } + case *schema.TypeBytes: + // TODO: allow string? + if customConverter := cfg.converterForType(goType); customConverter != nil { + if customConverter.kind != schema.TypeKind_Bytes { + doPanic("kind mismatch; custom converter for type is not for Bytes") + } + } else if goType.Kind() != reflect.Slice { + doPanic("kind mismatch; need slice of bytes") + } else if goType.Elem().Kind() != reflect.Uint8 { + doPanic("kind mismatch; need slice of bytes") + } + case *schema.TypeEnum: + if _, ok := schemaType.RepresentationStrategy().(schema.EnumRepresentation_Int); ok { + if kind := goType.Kind(); kind != reflect.String && !kindInt[kind] && !kindUint[kind] { + doPanic("kind mismatch; need string or integer") + } + } else { + if goType.Kind() != reflect.String { + doPanic("kind mismatch; need string") + } + } + case *schema.TypeList: + if goType.Kind() != reflect.Slice { + doPanic("kind mismatch; need slice") + } + goType = goType.Elem() + if schemaType.ValueIsNullable() { + if ptr, nilable := ptrOrNilable(goType.Kind()); !nilable { + doPanic("nullable types must be nilable") + } else if ptr { + goType = goType.Elem() + } + } + verifyCompatibility(cfg, seen, goType, schemaType.ValueType()) + case *schema.TypeMap: + // struct { + // Keys []K + // Values map[K]V + // } + if goType.Kind() != reflect.Struct { + doPanic("kind mismatch; need struct{Keys []K; Values map[K]V}") + } + if goType.NumField() != 2 { + doPanic("%d vs 2 fields", goType.NumField()) + } + + fieldKeys := goType.Field(0) + if fieldKeys.Type.Kind() != reflect.Slice { + doPanic("kind mismatch; need struct{Keys []K; Values map[K]V}") + } + verifyCompatibility(cfg, seen, fieldKeys.Type.Elem(), schemaType.KeyType()) + + fieldValues := goType.Field(1) + if fieldValues.Type.Kind() != reflect.Map { + doPanic("kind mismatch; need struct{Keys []K; Values map[K]V}") + } + keyType := fieldValues.Type.Key() + verifyCompatibility(cfg, seen, keyType, schemaType.KeyType()) + + elemType := fieldValues.Type.Elem() + if schemaType.ValueIsNullable() { + if ptr, nilable := ptrOrNilable(elemType.Kind()); !nilable { + doPanic("nullable types must be nilable") + } else if ptr { + elemType = elemType.Elem() + } + } + verifyCompatibility(cfg, seen, elemType, schemaType.ValueType()) + case *schema.TypeStruct: + if goType.Kind() != reflect.Struct { + doPanic("kind mismatch; need struct") + } + + schemaFields := schemaType.Fields() + if goType.NumField() != len(schemaFields) { + doPanic("%d vs %d fields", goType.NumField(), len(schemaFields)) + } + for i, schemaField := range schemaFields { + schemaType := schemaField.Type() + goType := goType.Field(i).Type + switch { + case schemaField.IsOptional() && schemaField.IsNullable(): + // TODO: https://github.com/ipld/go-ipld-prime/issues/340 will + // help here, to avoid the double pointer. We can't use nilable + // but non-pointer types because that's just one "nil" state. + // TODO: deal with custom converters in this case + if goType.Kind() != reflect.Ptr { + doPanic("optional and nullable fields must use double pointers (**)") + } + goType = goType.Elem() + if goType.Kind() != reflect.Ptr { + doPanic("optional and nullable fields must use double pointers (**)") + } + goType = goType.Elem() + case schemaField.IsOptional(): + if ptr, nilable := ptrOrNilable(goType.Kind()); !nilable { + doPanic("optional fields must be nilable") + } else if ptr { + goType = goType.Elem() + } + case schemaField.IsNullable(): + if ptr, nilable := ptrOrNilable(goType.Kind()); !nilable { + if customConverter := cfg.converterForType(goType); customConverter == nil { + doPanic("nullable fields must be nilable") + } + } else if ptr { + goType = goType.Elem() + } + } + verifyCompatibility(cfg, seen, goType, schemaType) + } + case *schema.TypeUnion: + if goType.Kind() != reflect.Struct { + doPanic("kind mismatch; need struct for an union") + } + + schemaMembers := schemaType.Members() + if goType.NumField() != len(schemaMembers) { + doPanic("%d vs %d members", goType.NumField(), len(schemaMembers)) + } + + for i, schemaType := range schemaMembers { + goType := goType.Field(i).Type + if ptr, nilable := ptrOrNilable(goType.Kind()); !nilable { + doPanic("union members must be nilable") + } else if ptr { + goType = goType.Elem() + } + verifyCompatibility(cfg, seen, goType, schemaType) + } + case *schema.TypeLink: + if customConverter := cfg.converterForType(goType); customConverter != nil { + if customConverter.kind != schema.TypeKind_Link { + doPanic("kind mismatch; custom converter for type is not for Link") + } + } else if goType != goTypeLink && goType != goTypeCidLink && goType != goTypeCid { + doPanic("links in Go must be datamodel.Link, cidlink.Link, or cid.Cid") + } + case *schema.TypeAny: + if customConverter := cfg.converterForType(goType); customConverter != nil { + if customConverter.kind != schema.TypeKind_Any { + doPanic("kind mismatch; custom converter for type is not for Any") + } + } else if goType != goTypeNode { + doPanic("Any in Go must be datamodel.Node") + } + default: + panic(fmt.Sprintf("%T", schemaType)) + } +} + +func ptrOrNilable(kind reflect.Kind) (ptr, nilable bool) { + switch kind { + case reflect.Ptr: + return true, true + case reflect.Interface, reflect.Map, reflect.Slice: + return false, true + default: + return false, false + } +} + +// If we recurse past a large number of levels, we're mostly stuck in a loop. +// Prevent burning CPU or causing OOM crashes. +// If a user really wrote an IPLD schema or Go type with such deep nesting, +// it's likely they are trying to abuse the system as well. +const maxRecursionLevel = 1 << 10 + +type inferredStatus int + +const ( + _ inferredStatus = iota + inferringInProcess + inferringDone +) + +// inferGoType can build a Go type given a schema +func inferGoType(typ schema.Type, status map[schema.TypeName]inferredStatus, level int) reflect.Type { + if level > maxRecursionLevel { + panic(fmt.Sprintf("inferGoType: refusing to recurse past %d levels", maxRecursionLevel)) + } + name := typ.Name() + if status[name] == inferringInProcess { + panic("bindnode: inferring Go types from cyclic schemas is not supported since Go reflection does not support creating named types") + } + status[name] = inferringInProcess + defer func() { status[name] = inferringDone }() + switch typ := typ.(type) { + case *schema.TypeBool: + return goTypeBool + case *schema.TypeInt: + return goTypeInt + case *schema.TypeFloat: + return goTypeFloat + case *schema.TypeString: + return goTypeString + case *schema.TypeBytes: + return goTypeBytes + case *schema.TypeStruct: + fields := typ.Fields() + fieldsGo := make([]reflect.StructField, len(fields)) + for i, field := range fields { + ftypGo := inferGoType(field.Type(), status, level+1) + if field.IsNullable() { + ftypGo = reflect.PtrTo(ftypGo) + } + if field.IsOptional() { + ftypGo = reflect.PtrTo(ftypGo) + } + fieldsGo[i] = reflect.StructField{ + Name: fieldNameFromSchema(field.Name()), + Type: ftypGo, + } + } + return reflect.StructOf(fieldsGo) + case *schema.TypeMap: + ktyp := inferGoType(typ.KeyType(), status, level+1) + vtyp := inferGoType(typ.ValueType(), status, level+1) + if typ.ValueIsNullable() { + vtyp = reflect.PtrTo(vtyp) + } + // We need an extra field to keep the map ordered, + // since IPLD maps must have stable iteration order. + // We could sort when iterating, but that's expensive. + // Keeping the insertion order is easy and intuitive. + // + // struct { + // Keys []K + // Values map[K]V + // } + fieldsGo := []reflect.StructField{ + { + Name: "Keys", + Type: reflect.SliceOf(ktyp), + }, + { + Name: "Values", + Type: reflect.MapOf(ktyp, vtyp), + }, + } + return reflect.StructOf(fieldsGo) + case *schema.TypeList: + etyp := inferGoType(typ.ValueType(), status, level+1) + if typ.ValueIsNullable() { + etyp = reflect.PtrTo(etyp) + } + return reflect.SliceOf(etyp) + case *schema.TypeUnion: + // type goUnion struct { + // Type1 *Type1 + // Type2 *Type2 + // ... + // } + members := typ.Members() + fieldsGo := make([]reflect.StructField, len(members)) + for i, ftyp := range members { + ftypGo := inferGoType(ftyp, status, level+1) + fieldsGo[i] = reflect.StructField{ + Name: fieldNameFromSchema(ftyp.Name()), + Type: reflect.PtrTo(ftypGo), + } + } + return reflect.StructOf(fieldsGo) + case *schema.TypeLink: + return goTypeLink + case *schema.TypeEnum: + // TODO: generate int for int reprs by default? + return goTypeString + case *schema.TypeAny: + return goTypeNode + case nil: + panic("bindnode: unexpected nil schema.Type") + } + panic(fmt.Sprintf("%T", typ)) +} + +// from IPLD Schema field names like "foo" to Go field names like "Foo". +func fieldNameFromSchema(name string) string { + fieldName := strings.Title(name) //lint:ignore SA1019 cases.Title doesn't work for this + if !token.IsIdentifier(fieldName) { + panic(fmt.Sprintf("bindnode: inferred field name %q is not a valid Go identifier", fieldName)) + } + return fieldName +} + +var defaultTypeSystem schema.TypeSystem + +func init() { + defaultTypeSystem.Init() + + defaultTypeSystem.Accumulate(schemaTypeBool) + defaultTypeSystem.Accumulate(schemaTypeInt) + defaultTypeSystem.Accumulate(schemaTypeFloat) + defaultTypeSystem.Accumulate(schemaTypeString) + defaultTypeSystem.Accumulate(schemaTypeBytes) + defaultTypeSystem.Accumulate(schemaTypeLink) + defaultTypeSystem.Accumulate(schemaTypeAny) +} + +// TODO: support IPLD maps and unions in inferSchema + +// TODO: support bringing your own TypeSystem? + +// TODO: we should probably avoid re-spawning the same types if the TypeSystem +// has them, and test that that works as expected + +// inferSchema can build a schema from a Go type +func inferSchema(typ reflect.Type, level int) schema.Type { + if level > maxRecursionLevel { + panic(fmt.Sprintf("inferSchema: refusing to recurse past %d levels", maxRecursionLevel)) + } + switch typ.Kind() { + case reflect.Bool: + return schemaTypeBool + case reflect.Int64: + return schemaTypeInt + case reflect.Float64: + return schemaTypeFloat + case reflect.String: + return schemaTypeString + case reflect.Struct: + // these types must match exactly since we need symmetry of being able to + // get the values an also assign values to them + if typ == goTypeCid || typ == goTypeCidLink { + return schemaTypeLink + } + + fieldsSchema := make([]schema.StructField, typ.NumField()) + for i := range fieldsSchema { + field := typ.Field(i) + ftyp := field.Type + ftypSchema := inferSchema(ftyp, level+1) + fieldsSchema[i] = schema.SpawnStructField( + field.Name, // TODO: allow configuring the name with tags + ftypSchema.Name(), + + // TODO: support nullable/optional with tags + false, + false, + ) + } + name := typ.Name() + if name == "" { + panic("TODO: anonymous composite types") + } + typSchema := schema.SpawnStruct(name, fieldsSchema, nil) + defaultTypeSystem.Accumulate(typSchema) + return typSchema + case reflect.Slice: + if typ.Elem().Kind() == reflect.Uint8 { + // Special case for []byte. + return schemaTypeBytes + } + + nullable := false + if typ.Elem().Kind() == reflect.Ptr { + nullable = true + } + etypSchema := inferSchema(typ.Elem(), level+1) + name := typ.Name() + if name == "" { + name = "List_" + etypSchema.Name() + } + typSchema := schema.SpawnList(name, etypSchema.Name(), nullable) + defaultTypeSystem.Accumulate(typSchema) + return typSchema + case reflect.Interface: + // these types must match exactly since we need symmetry of being able to + // get the values an also assign values to them + if typ == goTypeLink { + return schemaTypeLink + } + if typ == goTypeNode { + return schemaTypeAny + } + panic("bindnode: unable to infer from interface") + } + panic(fmt.Sprintf("bindnode: unable to infer from type %s", typ.Kind().String())) +} + +// There are currently 27 reflect.Kind iota values, +// so 32 should be plenty to ensure we don't panic in practice. + +var kindInt = [32]bool{ + reflect.Int: true, + reflect.Int8: true, + reflect.Int16: true, + reflect.Int32: true, + reflect.Int64: true, +} + +var kindUint = [32]bool{ + reflect.Uint: true, + reflect.Uint8: true, + reflect.Uint16: true, + reflect.Uint32: true, + reflect.Uint64: true, +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/node.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/node.go new file mode 100644 index 00000000..7930fa10 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/node.go @@ -0,0 +1,1754 @@ +package bindnode + +import ( + "fmt" + "math" + "reflect" + "runtime" + "strings" + + "github.com/ipfs/go-cid" + "github.com/ipld/go-ipld-prime/datamodel" + cidlink "github.com/ipld/go-ipld-prime/linking/cid" + "github.com/ipld/go-ipld-prime/node/basicnode" + "github.com/ipld/go-ipld-prime/node/mixins" + "github.com/ipld/go-ipld-prime/schema" +) + +// Assert that we implement all the interfaces as expected. +// Grouped by the interfaces to implement, roughly. +var ( + _ datamodel.NodePrototype = (*_prototype)(nil) + _ schema.TypedPrototype = (*_prototype)(nil) + _ datamodel.NodePrototype = (*_prototypeRepr)(nil) + + _ datamodel.Node = (*_node)(nil) + _ schema.TypedNode = (*_node)(nil) + _ datamodel.Node = (*_nodeRepr)(nil) + + _ datamodel.Node = (*_uintNode)(nil) + _ schema.TypedNode = (*_uintNode)(nil) + _ datamodel.UintNode = (*_uintNode)(nil) + _ datamodel.Node = (*_uintNodeRepr)(nil) + _ datamodel.UintNode = (*_uintNodeRepr)(nil) + + _ datamodel.NodeBuilder = (*_builder)(nil) + _ datamodel.NodeBuilder = (*_builderRepr)(nil) + _ datamodel.NodeAssembler = (*_assembler)(nil) + _ datamodel.NodeAssembler = (*_assemblerRepr)(nil) + + _ datamodel.MapAssembler = (*_structAssembler)(nil) + _ datamodel.MapAssembler = (*_structAssemblerRepr)(nil) + _ datamodel.MapIterator = (*_structIterator)(nil) + _ datamodel.MapIterator = (*_structIteratorRepr)(nil) + + _ datamodel.ListAssembler = (*_listAssembler)(nil) + _ datamodel.ListAssembler = (*_listAssemblerRepr)(nil) + _ datamodel.ListIterator = (*_listIterator)(nil) + _ datamodel.ListIterator = (*_tupleIteratorRepr)(nil) + + _ datamodel.MapAssembler = (*_unionAssembler)(nil) + _ datamodel.MapAssembler = (*_unionAssemblerRepr)(nil) + _ datamodel.MapIterator = (*_unionIterator)(nil) + _ datamodel.MapIterator = (*_unionIteratorRepr)(nil) +) + +type _prototype struct { + cfg config + schemaType schema.Type + goType reflect.Type // non-pointer +} + +func (w *_prototype) NewBuilder() datamodel.NodeBuilder { + return &_builder{_assembler{ + cfg: w.cfg, + schemaType: w.schemaType, + val: reflect.New(w.goType).Elem(), + }} +} + +func (w *_prototype) Type() schema.Type { + return w.schemaType +} + +func (w *_prototype) Representation() datamodel.NodePrototype { + return (*_prototypeRepr)(w) +} + +type _node struct { + cfg config + schemaType schema.Type + + val reflect.Value // non-pointer +} + +// TODO: only expose TypedNode methods if the schema was explicit. +// type _typedNode struct { +// _node +// } + +func newNode(cfg config, schemaType schema.Type, val reflect.Value) schema.TypedNode { + if schemaType.TypeKind() == schema.TypeKind_Int && nonPtrVal(val).Kind() == reflect.Uint64 { + // special case for uint64 values so we can handle the >int64 range + // we give this treatment to all uint64s, regardless of current value + // because we have no guarantees the value won't change underneath us + return &_uintNode{ + cfg: cfg, + schemaType: schemaType, + val: val, + } + } + return &_node{cfg, schemaType, val} +} + +func (w *_node) Type() schema.Type { + return w.schemaType +} + +func (w *_node) Representation() datamodel.Node { + return (*_nodeRepr)(w) +} + +func (w *_node) Kind() datamodel.Kind { + return actualKind(w.schemaType) +} + +// matching schema level types to data model kinds, since our Node and Builder +// interfaces operate on kinds +func compatibleKind(schemaType schema.Type, kind datamodel.Kind) error { + switch sch := schemaType.(type) { + case *schema.TypeAny: + return nil + default: + actual := actualKind(sch) // ActsLike data model + if actual == kind { + return nil + } + + // Error + methodName := "" + if pc, _, _, ok := runtime.Caller(1); ok { + if fn := runtime.FuncForPC(pc); fn != nil { + methodName = fn.Name() + // Go from "pkg/path.Type.Method" to just "Method". + methodName = methodName[strings.LastIndexByte(methodName, '.')+1:] + } + } + return datamodel.ErrWrongKind{ + TypeName: schemaType.Name(), + MethodName: methodName, + AppropriateKind: datamodel.KindSet{kind}, + ActualKind: actual, + } + } +} + +func actualKind(schemaType schema.Type) datamodel.Kind { + return schemaType.TypeKind().ActsLike() +} + +func nonPtrVal(val reflect.Value) reflect.Value { + // TODO: support **T as well as *T? + if val.Kind() == reflect.Ptr { + if val.IsNil() { + // TODO: error in this case? + return reflect.Value{} + } + val = val.Elem() + } + return val +} + +func ptrVal(val reflect.Value) reflect.Value { + if val.Kind() == reflect.Ptr { + return val + } + return val.Addr() +} + +func nonPtrType(val reflect.Value) reflect.Type { + typ := val.Type() + if typ.Kind() == reflect.Ptr { + return typ.Elem() + } + return typ +} + +// where we need to cal Set(), ensure the Value we're setting is a pointer or +// not, depending on the field we're setting into. +func matchSettable(val interface{}, to reflect.Value) reflect.Value { + setVal := nonPtrVal(reflect.ValueOf(val)) + if !setVal.Type().AssignableTo(to.Type()) && setVal.Type().ConvertibleTo(to.Type()) { + setVal = setVal.Convert(to.Type()) + } + return setVal +} + +func (w *_node) LookupByString(key string) (datamodel.Node, error) { + switch typ := w.schemaType.(type) { + case *schema.TypeStruct: + field := typ.Field(key) + if field == nil { + return nil, schema.ErrInvalidKey{ + TypeName: typ.Name(), + Key: basicnode.NewString(key), + } + } + fval := nonPtrVal(w.val).FieldByName(fieldNameFromSchema(key)) + if !fval.IsValid() { + return nil, fmt.Errorf("bindnode TODO: go-schema mismatch") + } + if field.IsOptional() { + if fval.IsNil() { + return datamodel.Absent, nil + } + if fval.Kind() == reflect.Ptr { + fval = fval.Elem() + } + } + if field.IsNullable() { + if fval.IsNil() { + return datamodel.Null, nil + } + if fval.Kind() == reflect.Ptr { + fval = fval.Elem() + } + } + if _, ok := field.Type().(*schema.TypeAny); ok { + if customConverter := w.cfg.converterFor(fval); customConverter != nil { + // field is an Any and we have a custom type converter for the type + return customConverter.customToAny(ptrVal(fval).Interface()) + } + // field is an Any, safely assume a Node in fval + return nonPtrVal(fval).Interface().(datamodel.Node), nil + } + return newNode(w.cfg, field.Type(), fval), nil + case *schema.TypeMap: + // maps can only be structs with a Values map + var kval reflect.Value + valuesVal := nonPtrVal(w.val).FieldByName("Values") + switch ktyp := typ.KeyType().(type) { + case *schema.TypeString: + // plain String keys, so safely use the map key as is + kval = reflect.ValueOf(key) + default: + // key is something other than a string that we need to assemble via + // the string representation form, use _assemblerRepr to reverse from + // string to the type that indexes the map + asm := &_assembler{ + cfg: w.cfg, + schemaType: ktyp, + val: reflect.New(valuesVal.Type().Key()).Elem(), + } + if err := (*_assemblerRepr)(asm).AssignString(key); err != nil { + return nil, err + } + kval = asm.val + } + fval := valuesVal.MapIndex(kval) + if !fval.IsValid() { // not found + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} + } + // TODO: Error/panic if fval.IsNil() && !typ.ValueIsNullable()? + // Otherwise we could have two non-equal Go values (nil map, + // non-nil-but-empty map) which represent the exact same IPLD + // node when the field is not nullable. + if typ.ValueIsNullable() { + if fval.IsNil() { + return datamodel.Null, nil + } + fval = fval.Elem() + } + if _, ok := typ.ValueType().(*schema.TypeAny); ok { + if customConverter := w.cfg.converterFor(fval); customConverter != nil { + // value is an Any and we have a custom type converter for the type + return customConverter.customToAny(ptrVal(fval).Interface()) + } + // value is an Any, safely assume a Node in fval + return nonPtrVal(fval).Interface().(datamodel.Node), nil + } + return newNode(w.cfg, typ.ValueType(), fval), nil + case *schema.TypeUnion: + // treat a union similar to a struct, but we have the member names more + // easily accessible to match to 'key' + var idx int + var mtyp schema.Type + for i, member := range typ.Members() { + if member.Name() == key { + idx = i + mtyp = member + break + } + } + if mtyp == nil { // not found + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} + } + // TODO: we could look up the right Go field straight away via idx. + haveIdx, mval := unionMember(nonPtrVal(w.val)) + if haveIdx != idx { // mismatching type + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} + } + return newNode(w.cfg, mtyp, mval), nil + } + return nil, datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "LookupByString", + AppropriateKind: datamodel.KindSet_JustMap, + ActualKind: w.Kind(), + } +} + +var invalidValue reflect.Value + +// unionMember finds which union member is set in the corresponding Go struct. +func unionMember(val reflect.Value) (int, reflect.Value) { + // The first non-nil field is a match. + for i := 0; i < val.NumField(); i++ { + elemVal := val.Field(i) + if elemVal.Kind() != reflect.Ptr { + panic("bindnode bug: found unexpected non-pointer in a union field") + } + if elemVal.IsNil() { + continue + } + return i, elemVal.Elem() + } + return -1, invalidValue +} + +func unionSetMember(val reflect.Value, memberIdx int, memberPtr reflect.Value) { + // Reset the entire union struct to zero, to clear any non-nil pointers. + val.Set(reflect.Zero(val.Type())) + + // Set the index pointer to the given value. + val.Field(memberIdx).Set(memberPtr) +} + +func (w *_node) LookupByIndex(idx int64) (datamodel.Node, error) { + switch typ := w.schemaType.(type) { + case *schema.TypeList: + val := nonPtrVal(w.val) + // we should be able assume that val is something we can Len() and Index() + if idx < 0 || int(idx) >= val.Len() { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfInt(idx)} + } + val = val.Index(int(idx)) + _, isAny := typ.ValueType().(*schema.TypeAny) + if isAny { + if customConverter := w.cfg.converterFor(val); customConverter != nil { + // values are Any and we have a converter for this type that will give us + // a datamodel.Node + return customConverter.customToAny(ptrVal(val).Interface()) + } + } + if typ.ValueIsNullable() { + if val.IsNil() { + return datamodel.Null, nil + } + // nullable elements are assumed to be pointers + val = val.Elem() + } + if isAny { + // Any always yields a plain datamodel.Node + return nonPtrVal(val).Interface().(datamodel.Node), nil + } + return newNode(w.cfg, typ.ValueType(), val), nil + } + return nil, datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "LookupByIndex", + AppropriateKind: datamodel.KindSet_JustList, + ActualKind: w.Kind(), + } +} + +func (w *_node) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + switch w.Kind() { + case datamodel.Kind_Map: + return w.LookupByString(seg.String()) + case datamodel.Kind_List: + idx, err := seg.Index() + if err != nil { + return nil, err + } + return w.LookupByIndex(idx) + } + return nil, datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "LookupBySegment", + AppropriateKind: datamodel.KindSet_Recursive, + ActualKind: w.Kind(), + } +} + +func (w *_node) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + switch w.Kind() { + case datamodel.Kind_Map: + s, err := key.AsString() + if err != nil { + return nil, err + } + return w.LookupByString(s) + case datamodel.Kind_List: + i, err := key.AsInt() + if err != nil { + return nil, err + } + return w.LookupByIndex(i) + } + return nil, datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "LookupByNode", + AppropriateKind: datamodel.KindSet_Recursive, + ActualKind: w.Kind(), + } +} + +func (w *_node) MapIterator() datamodel.MapIterator { + val := nonPtrVal(w.val) + // structs, unions and maps can all iterate but they each have different + // access semantics for the underlying type, so we need a different iterator + // for each + switch typ := w.schemaType.(type) { + case *schema.TypeStruct: + return &_structIterator{ + cfg: w.cfg, + schemaType: typ, + fields: typ.Fields(), + val: val, + } + case *schema.TypeUnion: + return &_unionIterator{ + cfg: w.cfg, + schemaType: typ, + members: typ.Members(), + val: val, + } + case *schema.TypeMap: + // we can assume a: struct{Keys []string, Values map[x]y} + return &_mapIterator{ + cfg: w.cfg, + schemaType: typ, + keysVal: val.FieldByName("Keys"), + valuesVal: val.FieldByName("Values"), + } + } + return nil +} + +func (w *_node) ListIterator() datamodel.ListIterator { + val := nonPtrVal(w.val) + switch typ := w.schemaType.(type) { + case *schema.TypeList: + return &_listIterator{cfg: w.cfg, schemaType: typ, val: val} + } + return nil +} + +func (w *_node) Length() int64 { + val := nonPtrVal(w.val) + switch w.Kind() { + case datamodel.Kind_Map: + switch typ := w.schemaType.(type) { + case *schema.TypeStruct: + return int64(len(typ.Fields())) + case *schema.TypeUnion: + return 1 + } + return int64(val.FieldByName("Keys").Len()) + case datamodel.Kind_List: + return int64(val.Len()) + } + return -1 +} + +// TODO: better story around pointers and absent/null + +func (w *_node) IsAbsent() bool { + return false +} + +func (w *_node) IsNull() bool { + return false +} + +// The AsX methods are matter of fetching the non-pointer form of the underlying +// value and returning the appropriate Go type. The user may have registered +// custom converters for the kind being converted, in which case the underlying +// type may not be the type we need, but the converter will supply it for us. + +func (w *_node) AsBool() (bool, error) { + if err := compatibleKind(w.schemaType, datamodel.Kind_Bool); err != nil { + return false, err + } + if customConverter := w.cfg.converterFor(w.val); customConverter != nil { + // user has registered a converter that takes the underlying type and returns a bool + return customConverter.customToBool(ptrVal(w.val).Interface()) + } + return nonPtrVal(w.val).Bool(), nil +} + +func (w *_node) AsInt() (int64, error) { + if err := compatibleKind(w.schemaType, datamodel.Kind_Int); err != nil { + return 0, err + } + if customConverter := w.cfg.converterFor(w.val); customConverter != nil { + // user has registered a converter that takes the underlying type and returns an int + return customConverter.customToInt(ptrVal(w.val).Interface()) + } + val := nonPtrVal(w.val) + if kindUint[val.Kind()] { + u := val.Uint() + if u > math.MaxInt64 { + return 0, fmt.Errorf("bindnode: integer overflow, %d is too large for an int64", u) + } + return int64(u), nil + } + return val.Int(), nil +} + +func (w *_node) AsFloat() (float64, error) { + if err := compatibleKind(w.schemaType, datamodel.Kind_Float); err != nil { + return 0, err + } + if customConverter := w.cfg.converterFor(w.val); customConverter != nil { + // user has registered a converter that takes the underlying type and returns a float + return customConverter.customToFloat(ptrVal(w.val).Interface()) + } + return nonPtrVal(w.val).Float(), nil +} + +func (w *_node) AsString() (string, error) { + if err := compatibleKind(w.schemaType, datamodel.Kind_String); err != nil { + return "", err + } + if customConverter := w.cfg.converterFor(w.val); customConverter != nil { + // user has registered a converter that takes the underlying type and returns a string + return customConverter.customToString(ptrVal(w.val).Interface()) + } + return nonPtrVal(w.val).String(), nil +} + +func (w *_node) AsBytes() ([]byte, error) { + if err := compatibleKind(w.schemaType, datamodel.Kind_Bytes); err != nil { + return nil, err + } + if customConverter := w.cfg.converterFor(w.val); customConverter != nil { + // user has registered a converter that takes the underlying type and returns a []byte + return customConverter.customToBytes(ptrVal(w.val).Interface()) + } + return nonPtrVal(w.val).Bytes(), nil +} + +func (w *_node) AsLink() (datamodel.Link, error) { + if err := compatibleKind(w.schemaType, datamodel.Kind_Link); err != nil { + return nil, err + } + if customConverter := w.cfg.converterFor(w.val); customConverter != nil { + // user has registered a converter that takes the underlying type and returns a cid.Cid + cid, err := customConverter.customToLink(ptrVal(w.val).Interface()) + if err != nil { + return nil, err + } + return cidlink.Link{Cid: cid}, nil + } + switch val := nonPtrVal(w.val).Interface().(type) { + case datamodel.Link: + return val, nil + case cid.Cid: + return cidlink.Link{Cid: val}, nil + default: + return nil, fmt.Errorf("bindnode: unexpected link type %T", val) + } +} + +func (w *_node) Prototype() datamodel.NodePrototype { + return &_prototype{cfg: w.cfg, schemaType: w.schemaType, goType: w.val.Type()} +} + +type _builder struct { + _assembler +} + +func (w *_builder) Build() datamodel.Node { + // TODO: should we panic if no Assign call was made, just like codegen? + return newNode(w.cfg, w.schemaType, w.val) +} + +func (w *_builder) Reset() { + panic("bindnode TODO: Reset") +} + +type _assembler struct { + cfg config + schemaType schema.Type + val reflect.Value // non-pointer + + // finish is used as an optional post-assemble step. + // For example, assigning to a kinded union uses a finish func + // to set the right union member in the Go union struct, + // which isn't known before the assemble has finished. + finish func() error + + nullable bool // true if field or map value is nullable +} + +// createNonPtrVal is used for Set() operations on the underlying value +func (w *_assembler) createNonPtrVal() reflect.Value { + val := w.val + // TODO: if val is not a pointer, we reuse its value. + // If it is a pointer, we allocate a new one and replace it. + // We should probably never reuse the existing value. + + // TODO: support **T as well as *T? + if val.Kind() == reflect.Ptr { + // TODO: Sometimes we call createNonPtrVal before an assignment actually + // happens. Does that matter? + // If it matters and we only want to modify the destination value on + // success, then we should make use of the "finish" func. + val.Set(reflect.New(val.Type().Elem())) + val = val.Elem() + } + return val +} + +func (w *_assembler) Representation() datamodel.NodeAssembler { + return (*_assemblerRepr)(w) +} + +// basicMapAssembler is for assembling basicnode values, it's only use is for +// Any fields that end up needing a BeginMap() +type basicMapAssembler struct { + datamodel.MapAssembler + + builder datamodel.NodeBuilder + parent *_assembler + converter *converter +} + +func (w *basicMapAssembler) Finish() error { + if err := w.MapAssembler.Finish(); err != nil { + return err + } + basicNode := w.builder.Build() + if w.converter != nil { + // we can assume an Any converter because basicMapAssembler is only for Any + // the user has registered the ability to convert a datamodel.Node to the + // underlying Go type which may not be a datamodel.Node + typ, err := w.converter.customFromAny(basicNode) + if err != nil { + return err + } + w.parent.createNonPtrVal().Set(matchSettable(typ, reflect.ValueOf(basicNode))) + } else { + w.parent.createNonPtrVal().Set(reflect.ValueOf(basicNode)) + } + if w.parent.finish != nil { + if err := w.parent.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + switch typ := w.schemaType.(type) { + case *schema.TypeAny: + basicBuilder := basicnode.Prototype.Any.NewBuilder() + mapAsm, err := basicBuilder.BeginMap(sizeHint) + if err != nil { + return nil, err + } + converter := w.cfg.converterFor(w.val) + return &basicMapAssembler{MapAssembler: mapAsm, builder: basicBuilder, parent: w, converter: converter}, nil + case *schema.TypeStruct: + val := w.createNonPtrVal() + // _structAssembler walks through the fields in order as the entries are + // assembled, verifyCompatibility() should mean it's safe to assume that + // they match the schema, but we need to keep track of the fields that are + // set in case of premature Finish() + doneFields := make([]bool, val.NumField()) + return &_structAssembler{ + cfg: w.cfg, + schemaType: typ, + val: val, + doneFields: doneFields, + finish: w.finish, + }, nil + case *schema.TypeMap: + // assume a struct{Keys []string, Values map[x]y} that we can fill with + // _mapAssembler + val := w.createNonPtrVal() + keysVal := val.FieldByName("Keys") + valuesVal := val.FieldByName("Values") + if valuesVal.IsNil() { + valuesVal.Set(reflect.MakeMap(valuesVal.Type())) + } + return &_mapAssembler{ + cfg: w.cfg, + schemaType: typ, + keysVal: keysVal, + valuesVal: valuesVal, + finish: w.finish, + }, nil + case *schema.TypeUnion: + // we can use _unionAssembler to assemble a union as if it were a map with + // a single entry + val := w.createNonPtrVal() + return &_unionAssembler{ + cfg: w.cfg, + schemaType: typ, + val: val, + finish: w.finish, + }, nil + } + return nil, datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "BeginMap", + AppropriateKind: datamodel.KindSet_JustMap, + ActualKind: actualKind(w.schemaType), + } +} + +// basicListAssembler is for assembling basicnode values, it's only use is for +// Any fields that end up needing a BeginList() +type basicListAssembler struct { + datamodel.ListAssembler + + builder datamodel.NodeBuilder + parent *_assembler + converter *converter +} + +func (w *basicListAssembler) Finish() error { + if err := w.ListAssembler.Finish(); err != nil { + return err + } + basicNode := w.builder.Build() + if w.converter != nil { + // we can assume an Any converter because basicListAssembler is only for Any + // the user has registered the ability to convert a datamodel.Node to the + // underlying Go type which may not be a datamodel.Node + typ, err := w.converter.customFromAny(basicNode) + if err != nil { + return err + } + w.parent.createNonPtrVal().Set(matchSettable(typ, reflect.ValueOf(basicNode))) + } else { + w.parent.createNonPtrVal().Set(reflect.ValueOf(basicNode)) + } + if w.parent.finish != nil { + if err := w.parent.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + switch typ := w.schemaType.(type) { + case *schema.TypeAny: + basicBuilder := basicnode.Prototype.Any.NewBuilder() + listAsm, err := basicBuilder.BeginList(sizeHint) + if err != nil { + return nil, err + } + converter := w.cfg.converterFor(w.val) + return &basicListAssembler{ListAssembler: listAsm, builder: basicBuilder, parent: w, converter: converter}, nil + case *schema.TypeList: + // we should be able to safely assume we're dealing with a Go slice here, + // so _listAssembler can append to that + val := w.createNonPtrVal() + return &_listAssembler{ + cfg: w.cfg, + schemaType: typ, + val: val, + finish: w.finish, + }, nil + } + return nil, datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "BeginList", + AppropriateKind: datamodel.KindSet_JustList, + ActualKind: actualKind(w.schemaType), + } +} + +func (w *_assembler) AssignNull() error { + _, isAny := w.schemaType.(*schema.TypeAny) + if customConverter := w.cfg.converterFor(w.val); customConverter != nil && isAny { + // an Any field that is being assigned a Null, we pass the Null directly to + // the converter, regardless of whether this field is nullable or not + typ, err := customConverter.customFromAny(datamodel.Null) + if err != nil { + return err + } + w.createNonPtrVal().Set(matchSettable(typ, w.val)) + } else { + if !w.nullable { + return datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "AssignNull", + // TODO + } + } + // set the zero value for the underlying type as a stand-in for Null + w.val.Set(reflect.Zero(w.val.Type())) + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) AssignBool(b bool) error { + if err := compatibleKind(w.schemaType, datamodel.Kind_Bool); err != nil { + return err + } + customConverter := w.cfg.converterFor(w.val) + _, isAny := w.schemaType.(*schema.TypeAny) + if customConverter != nil { + var typ interface{} + var err error + if isAny { + // field is an Any, so the converter will be an Any converter that wants + // a datamodel.Node to convert to whatever the underlying Go type is + if typ, err = customConverter.customFromAny(basicnode.NewBool(b)); err != nil { + return err + } + } else { + // field is a Bool, but the user has registered a converter from a bool to + // whatever the underlying Go type is + if typ, err = customConverter.customFromBool(b); err != nil { + return err + } + } + w.createNonPtrVal().Set(matchSettable(typ, w.val)) + } else { + if isAny { + // Any means the Go type must receive a datamodel.Node + w.createNonPtrVal().Set(reflect.ValueOf(basicnode.NewBool(b))) + } else { + w.createNonPtrVal().SetBool(b) + } + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) assignUInt(uin datamodel.UintNode) error { + if err := compatibleKind(w.schemaType, datamodel.Kind_Int); err != nil { + return err + } + _, isAny := w.schemaType.(*schema.TypeAny) + // TODO: customConverter for uint?? + if isAny { + // Any means the Go type must receive a datamodel.Node + w.createNonPtrVal().Set(reflect.ValueOf(uin)) + } else { + i, err := uin.AsUint() + if err != nil { + return err + } + if kindUint[w.val.Kind()] { + w.createNonPtrVal().SetUint(i) + } else { + // TODO: check for overflow + w.createNonPtrVal().SetInt(int64(i)) + } + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) AssignInt(i int64) error { + if err := compatibleKind(w.schemaType, datamodel.Kind_Int); err != nil { + return err + } + // TODO: check for overflow + customConverter := w.cfg.converterFor(w.val) + _, isAny := w.schemaType.(*schema.TypeAny) + if customConverter != nil { + var typ interface{} + var err error + if isAny { + // field is an Any, so the converter will be an Any converter that wants + // a datamodel.Node to convert to whatever the underlying Go type is + if typ, err = customConverter.customFromAny(basicnode.NewInt(i)); err != nil { + return err + } + } else { + // field is an Int, but the user has registered a converter from an int to + // whatever the underlying Go type is + if typ, err = customConverter.customFromInt(i); err != nil { + return err + } + } + w.createNonPtrVal().Set(matchSettable(typ, w.val)) + } else { + if isAny { + // Any means the Go type must receive a datamodel.Node + w.createNonPtrVal().Set(reflect.ValueOf(basicnode.NewInt(i))) + } else if kindUint[w.val.Kind()] { + if i < 0 { + // TODO: write a test + return fmt.Errorf("bindnode: cannot assign negative integer to %s", w.val.Type()) + } + w.createNonPtrVal().SetUint(uint64(i)) + } else { + w.createNonPtrVal().SetInt(i) + } + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) AssignFloat(f float64) error { + if err := compatibleKind(w.schemaType, datamodel.Kind_Float); err != nil { + return err + } + customConverter := w.cfg.converterFor(w.val) + _, isAny := w.schemaType.(*schema.TypeAny) + if customConverter != nil { + var typ interface{} + var err error + if isAny { + // field is an Any, so the converter will be an Any converter that wants + // a datamodel.Node to convert to whatever the underlying Go type is + if typ, err = customConverter.customFromAny(basicnode.NewFloat(f)); err != nil { + return err + } + } else { + // field is a Float, but the user has registered a converter from a float + // to whatever the underlying Go type is + if typ, err = customConverter.customFromFloat(f); err != nil { + return err + } + } + w.createNonPtrVal().Set(matchSettable(typ, w.val)) + } else { + if isAny { + // Any means the Go type must receive a datamodel.Node + w.createNonPtrVal().Set(reflect.ValueOf(basicnode.NewFloat(f))) + } else { + w.createNonPtrVal().SetFloat(f) + } + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) AssignString(s string) error { + if err := compatibleKind(w.schemaType, datamodel.Kind_String); err != nil { + return err + } + customConverter := w.cfg.converterFor(w.val) + _, isAny := w.schemaType.(*schema.TypeAny) + if customConverter != nil { + var typ interface{} + var err error + if isAny { + // field is an Any, so the converter will be an Any converter that wants + // a datamodel.Node to convert to whatever the underlying Go type is + if typ, err = customConverter.customFromAny(basicnode.NewString(s)); err != nil { + return err + } + } else { + // field is a String, but the user has registered a converter from a + // string to whatever the underlying Go type is + if typ, err = customConverter.customFromString(s); err != nil { + return err + } + } + w.createNonPtrVal().Set(matchSettable(typ, w.val)) + } else { + if isAny { + // Any means the Go type must receive a datamodel.Node + w.createNonPtrVal().Set(reflect.ValueOf(basicnode.NewString(s))) + } else { + w.createNonPtrVal().SetString(s) + } + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) AssignBytes(p []byte) error { + if err := compatibleKind(w.schemaType, datamodel.Kind_Bytes); err != nil { + return err + } + customConverter := w.cfg.converterFor(w.val) + _, isAny := w.schemaType.(*schema.TypeAny) + if customConverter != nil { + var typ interface{} + var err error + if isAny { + // field is an Any, so the converter will be an Any converter that wants + // a datamodel.Node to convert to whatever the underlying Go type is + if typ, err = customConverter.customFromAny(basicnode.NewBytes(p)); err != nil { + return err + } + } else { + // field is a Bytes, but the user has registered a converter from a []byte + // to whatever the underlying Go type is + if typ, err = customConverter.customFromBytes(p); err != nil { + return err + } + } + w.createNonPtrVal().Set(matchSettable(typ, w.val)) + } else { + if isAny { + // Any means the Go type must receive a datamodel.Node + w.createNonPtrVal().Set(reflect.ValueOf(basicnode.NewBytes(p))) + } else { + w.createNonPtrVal().SetBytes(p) + } + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) AssignLink(link datamodel.Link) error { + val := w.createNonPtrVal() + // TODO: newVal.Type() panics if link==nil; add a test and fix. + customConverter := w.cfg.converterFor(w.val) + if _, ok := w.schemaType.(*schema.TypeAny); ok { + if customConverter != nil { + // field is an Any, so the converter will be an Any converter that wants + // a datamodel.Node to convert to whatever the underlying Go type is + typ, err := customConverter.customFromAny(basicnode.NewLink(link)) + if err != nil { + return err + } + w.createNonPtrVal().Set(matchSettable(typ, w.val)) + } else { + // Any means the Go type must receive a datamodel.Node + val.Set(reflect.ValueOf(basicnode.NewLink(link))) + } + } else if customConverter != nil { + if cl, ok := link.(cidlink.Link); ok { + // field is a Link, but the user has registered a converter from a cid.Cid + // to whatever the underlying Go type is + typ, err := customConverter.customFromLink(cl.Cid) + if err != nil { + return err + } + w.createNonPtrVal().Set(matchSettable(typ, w.val)) + } else { + return fmt.Errorf("bindnode: custom converter can only receive a cidlink.Link through AssignLink") + } + } else if newVal := reflect.ValueOf(link); newVal.Type().AssignableTo(val.Type()) { + // Directly assignable. + val.Set(newVal) + } else if newVal.Type() == goTypeCidLink && goTypeCid.AssignableTo(val.Type()) { + // Unbox a cidlink.Link to assign to a go-cid.Cid value. + newVal = newVal.FieldByName("Cid") + val.Set(newVal) + } else if actual := actualKind(w.schemaType); actual != datamodel.Kind_Link { + // We're assigning a Link to a schema type that isn't a Link. + return datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "AssignLink", + AppropriateKind: datamodel.KindSet_JustLink, + ActualKind: actualKind(w.schemaType), + } + } else { + // The schema type is a Link, but we somehow can't assign to the Go value. + // Almost certainly a bug; we should have verified for compatibility upfront. + return fmt.Errorf("bindnode bug: AssignLink with %s argument can't be used on Go type %s", + newVal.Type(), val.Type()) + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_assembler) AssignNode(node datamodel.Node) error { + // TODO: does this ever trigger? + // newVal := reflect.ValueOf(node) + // if newVal.Type().AssignableTo(w.val.Type()) { + // w.val.Set(newVal) + // return nil + // } + if uintNode, ok := node.(datamodel.UintNode); ok { + return w.assignUInt(uintNode) + } + return datamodel.Copy(node, w) +} + +func (w *_assembler) Prototype() datamodel.NodePrototype { + return &_prototype{cfg: w.cfg, schemaType: w.schemaType, goType: w.val.Type()} +} + +// _structAssembler is used for Struct assembling via BeginMap() +type _structAssembler struct { + // TODO: embed _assembler? + + cfg config + + schemaType *schema.TypeStruct + val reflect.Value // non-pointer + finish func() error + + // TODO: more state checks + + // TODO: Consider if we could do this in a cheaper way, + // such as looking at the reflect.Value directly. + // If not, at least avoid an extra alloc. + doneFields []bool + + // TODO: optimize for structs + + curKey _assembler + + nextIndex int // only used by repr.go +} + +func (w *_structAssembler) AssembleKey() datamodel.NodeAssembler { + w.curKey = _assembler{ + cfg: w.cfg, + schemaType: schemaTypeString, + val: reflect.New(goTypeString).Elem(), + } + return &w.curKey +} + +func (w *_structAssembler) AssembleValue() datamodel.NodeAssembler { + // TODO: optimize this to do one lookup by name + name := w.curKey.val.String() + field := w.schemaType.Field(name) + if field == nil { + // TODO: should've been raised when the key was submitted instead. + // TODO: should make well-typed errors for this. + return _errorAssembler{fmt.Errorf("bindnode TODO: invalid key: %q is not a field in type %s", name, w.schemaType.Name())} + // panic(schema.ErrInvalidKey{ + // TypeName: w.schemaType.Name(), + // Key: basicnode.NewString(name), + // }) + } + ftyp, ok := w.val.Type().FieldByName(fieldNameFromSchema(name)) + if !ok { + // It is unfortunate this is not detected proactively earlier during bind. + return _errorAssembler{fmt.Errorf("schema type %q has field %q, we expect go struct to have field %q", w.schemaType.Name(), field.Name(), fieldNameFromSchema(name))} + } + if len(ftyp.Index) > 1 { + return _errorAssembler{fmt.Errorf("bindnode TODO: embedded fields")} + } + w.doneFields[ftyp.Index[0]] = true + fval := w.val.FieldByIndex(ftyp.Index) + if field.IsOptional() { + if fval.Kind() == reflect.Ptr { + // ptrVal = new(T); val = *ptrVal + fval.Set(reflect.New(fval.Type().Elem())) + fval = fval.Elem() + } else { + // val = *new(T) + fval.Set(reflect.New(fval.Type()).Elem()) + } + } + // TODO: reuse same assembler for perf? + return &_assembler{ + cfg: w.cfg, + schemaType: field.Type(), + val: fval, + nullable: field.IsNullable(), + } +} + +func (w *_structAssembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + if err := w.AssembleKey().AssignString(k); err != nil { + return nil, err + } + am := w.AssembleValue() + return am, nil +} + +func (w *_structAssembler) Finish() error { + fields := w.schemaType.Fields() + var missing []string + for i, field := range fields { + if !field.IsOptional() && !w.doneFields[i] { + missing = append(missing, field.Name()) + } + } + if len(missing) > 0 { + return schema.ErrMissingRequiredField{Missing: missing} + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_structAssembler) KeyPrototype() datamodel.NodePrototype { + // TODO: if the user provided their own schema with their own typesystem, + // the schemaTypeString here may be using the wrong typesystem. + return &_prototype{cfg: w.cfg, schemaType: schemaTypeString, goType: goTypeString} +} + +func (w *_structAssembler) ValuePrototype(k string) datamodel.NodePrototype { + panic("bindnode TODO: struct ValuePrototype") +} + +type _errorAssembler struct { + err error +} + +func (w _errorAssembler) BeginMap(int64) (datamodel.MapAssembler, error) { return nil, w.err } +func (w _errorAssembler) BeginList(int64) (datamodel.ListAssembler, error) { return nil, w.err } +func (w _errorAssembler) AssignNull() error { return w.err } +func (w _errorAssembler) AssignBool(bool) error { return w.err } +func (w _errorAssembler) AssignInt(int64) error { return w.err } +func (w _errorAssembler) AssignFloat(float64) error { return w.err } +func (w _errorAssembler) AssignString(string) error { return w.err } +func (w _errorAssembler) AssignBytes([]byte) error { return w.err } +func (w _errorAssembler) AssignLink(datamodel.Link) error { return w.err } +func (w _errorAssembler) AssignNode(datamodel.Node) error { return w.err } +func (w _errorAssembler) Prototype() datamodel.NodePrototype { return nil } + +// used for Maps which we can assume are of type: struct{Keys []string, Values map[x]y}, +// where we have Keys in keysVal and Values in valuesVal +type _mapAssembler struct { + cfg config + schemaType *schema.TypeMap + keysVal reflect.Value // non-pointer + valuesVal reflect.Value // non-pointer + finish func() error + + // TODO: more state checks + + curKey _assembler +} + +func (w *_mapAssembler) AssembleKey() datamodel.NodeAssembler { + w.curKey = _assembler{ + cfg: w.cfg, + schemaType: w.schemaType.KeyType(), + val: reflect.New(w.valuesVal.Type().Key()).Elem(), + } + return &w.curKey +} + +func (w *_mapAssembler) AssembleValue() datamodel.NodeAssembler { + kval := w.curKey.val + val := reflect.New(w.valuesVal.Type().Elem()).Elem() + finish := func() error { + // TODO: check for duplicates in keysVal + w.keysVal.Set(reflect.Append(w.keysVal, kval)) + + w.valuesVal.SetMapIndex(kval, val) + return nil + } + return &_assembler{ + cfg: w.cfg, + schemaType: w.schemaType.ValueType(), + val: val, + nullable: w.schemaType.ValueIsNullable(), + finish: finish, + } +} + +func (w *_mapAssembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + if err := w.AssembleKey().AssignString(k); err != nil { + return nil, err + } + am := w.AssembleValue() + return am, nil +} + +func (w *_mapAssembler) Finish() error { + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_mapAssembler) KeyPrototype() datamodel.NodePrototype { + return &_prototype{cfg: w.cfg, schemaType: w.schemaType.KeyType(), goType: w.valuesVal.Type().Key()} +} + +func (w *_mapAssembler) ValuePrototype(k string) datamodel.NodePrototype { + return &_prototype{cfg: w.cfg, schemaType: w.schemaType.ValueType(), goType: w.valuesVal.Type().Elem()} +} + +// _listAssembler is for operating directly on slices, which we have in val +type _listAssembler struct { + cfg config + schemaType *schema.TypeList + val reflect.Value // non-pointer + finish func() error +} + +func (w *_listAssembler) AssembleValue() datamodel.NodeAssembler { + goType := w.val.Type().Elem() + // TODO: use a finish func to append + w.val.Set(reflect.Append(w.val, reflect.New(goType).Elem())) + return &_assembler{ + cfg: w.cfg, + schemaType: w.schemaType.ValueType(), + val: w.val.Index(w.val.Len() - 1), + nullable: w.schemaType.ValueIsNullable(), + } +} + +func (w *_listAssembler) Finish() error { + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_listAssembler) ValuePrototype(idx int64) datamodel.NodePrototype { + return &_prototype{cfg: w.cfg, schemaType: w.schemaType.ValueType(), goType: w.val.Type().Elem()} +} + +// when assembling as a Map but we anticipate a single value, which we need to +// look up in the union members +type _unionAssembler struct { + cfg config + schemaType *schema.TypeUnion + val reflect.Value // non-pointer + finish func() error + + // TODO: more state checks + + curKey _assembler +} + +func (w *_unionAssembler) AssembleKey() datamodel.NodeAssembler { + w.curKey = _assembler{ + cfg: w.cfg, + schemaType: schemaTypeString, + val: reflect.New(goTypeString).Elem(), + } + return &w.curKey +} + +func (w *_unionAssembler) AssembleValue() datamodel.NodeAssembler { + name := w.curKey.val.String() + var idx int + var mtyp schema.Type + for i, member := range w.schemaType.Members() { + if member.Name() == name { + idx = i + mtyp = member + break + } + } + if mtyp == nil { + return _errorAssembler{fmt.Errorf("bindnode TODO: missing member %s in %s", name, w.schemaType.Name())} + // return nil, datamodel.ErrInvalidKey{ + // TypeName: w.schemaType.Name(), + // Key: basicnode.NewString(name), + // } + } + + goType := w.val.Field(idx).Type().Elem() + valPtr := reflect.New(goType) + finish := func() error { + unionSetMember(w.val, idx, valPtr) + return nil + } + return &_assembler{ + cfg: w.cfg, + schemaType: mtyp, + val: valPtr.Elem(), + finish: finish, + } +} + +func (w *_unionAssembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + if err := w.AssembleKey().AssignString(k); err != nil { + return nil, err + } + am := w.AssembleValue() + return am, nil +} + +func (w *_unionAssembler) Finish() error { + // TODO(rvagg): I think this might allow setting multiple members of the union + // we need a test for this. + haveIdx, _ := unionMember(w.val) + if haveIdx < 0 { + return schema.ErrNotUnionStructure{TypeName: w.schemaType.Name(), Detail: "a union must have exactly one entry"} + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil +} + +func (w *_unionAssembler) KeyPrototype() datamodel.NodePrototype { + return &_prototype{cfg: w.cfg, schemaType: schemaTypeString, goType: goTypeString} +} + +func (w *_unionAssembler) ValuePrototype(k string) datamodel.NodePrototype { + panic("bindnode TODO: union ValuePrototype") +} + +// _structIterator is for iterating over Struct types which operate over Go +// structs. The iteration order is dictated by Go field declaration order which +// should match the schema for this type. +type _structIterator struct { + // TODO: support embedded fields? + cfg config + + schemaType *schema.TypeStruct + fields []schema.StructField + val reflect.Value // non-pointer + nextIndex int + + // these are only used in repr.go + reprEnd int +} + +func (w *_structIterator) Next() (key, value datamodel.Node, _ error) { + if w.Done() { + return nil, nil, datamodel.ErrIteratorOverread{} + } + field := w.fields[w.nextIndex] + val := w.val.Field(w.nextIndex) + w.nextIndex++ + key = basicnode.NewString(field.Name()) + if field.IsOptional() { + if val.IsNil() { + return key, datamodel.Absent, nil + } + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + } + _, isAny := field.Type().(*schema.TypeAny) + if isAny { + if customConverter := w.cfg.converterFor(val); customConverter != nil { + // field is an Any and we have an Any converter which takes the underlying + // struct field value and returns a datamodel.Node + v, err := customConverter.customToAny(ptrVal(val).Interface()) + if err != nil { + return nil, nil, err + } + return key, v, nil + } + } + if field.IsNullable() { + if val.IsNil() { + return key, datamodel.Null, nil + } + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + } + if isAny { + // field holds a datamodel.Node + return key, nonPtrVal(val).Interface().(datamodel.Node), nil + } + return key, newNode(w.cfg, field.Type(), val), nil +} + +func (w *_structIterator) Done() bool { + return w.nextIndex >= len(w.fields) +} + +// _mapIterator is for iterating over a struct{Keys []string, Values map[x]y}, +// where we have the Keys in keysVal and Values in valuesVal +type _mapIterator struct { + cfg config + schemaType *schema.TypeMap + keysVal reflect.Value // non-pointer + valuesVal reflect.Value // non-pointer + nextIndex int +} + +func (w *_mapIterator) Next() (key, value datamodel.Node, _ error) { + if w.Done() { + return nil, nil, datamodel.ErrIteratorOverread{} + } + goKey := w.keysVal.Index(w.nextIndex) + val := w.valuesVal.MapIndex(goKey) + w.nextIndex++ + + key = newNode(w.cfg, w.schemaType.KeyType(), goKey) + _, isAny := w.schemaType.ValueType().(*schema.TypeAny) + if isAny { + if customConverter := w.cfg.converterFor(val); customConverter != nil { + // values of this map are Any and we have an Any converter which takes the + // underlying map value and returns a datamodel.Node + + // TODO(rvagg): can't call ptrVal on a map value that's not a pointer + // so only map[string]*foo will work for the Values map and an Any + // converter. Should we check in infer.go? + val, err := customConverter.customToAny(ptrVal(val).Interface()) + return key, val, err + } + } + if w.schemaType.ValueIsNullable() { + if val.IsNil() { + return key, datamodel.Null, nil + } + val = val.Elem() // nullable entries are pointers + } + if isAny { + // Values holds datamodel.Nodes + return key, nonPtrVal(val).Interface().(datamodel.Node), nil + } + return key, newNode(w.cfg, w.schemaType.ValueType(), val), nil +} + +func (w *_mapIterator) Done() bool { + return w.nextIndex >= w.keysVal.Len() +} + +// _listIterator is for iterating over slices, which is held in val +type _listIterator struct { + cfg config + schemaType *schema.TypeList + val reflect.Value // non-pointer + nextIndex int +} + +func (w *_listIterator) Next() (index int64, value datamodel.Node, _ error) { + if w.Done() { + return 0, nil, datamodel.ErrIteratorOverread{} + } + idx := int64(w.nextIndex) + val := w.val.Index(w.nextIndex) + w.nextIndex++ + if w.schemaType.ValueIsNullable() { + if val.IsNil() { + return idx, datamodel.Null, nil + } + val = val.Elem() // nullable values are pointers + } + if _, ok := w.schemaType.ValueType().(*schema.TypeAny); ok { + if customConverter := w.cfg.converterFor(val); customConverter != nil { + // values are Any and we have an Any converter which can take whatever + // the underlying Go type in this slice is and return a datamodel.Node + val, err := customConverter.customToAny(ptrVal(val).Interface()) + return idx, val, err + } + // values are Any, assume that they are datamodel.Nodes + return idx, nonPtrVal(val).Interface().(datamodel.Node), nil + } + return idx, newNode(w.cfg, w.schemaType.ValueType(), val), nil +} + +func (w *_listIterator) Done() bool { + return w.nextIndex >= w.val.Len() +} + +type _unionIterator struct { + // TODO: support embedded fields? + cfg config + schemaType *schema.TypeUnion + members []schema.Type + val reflect.Value // non-pointer + + done bool +} + +func (w *_unionIterator) Next() (key, value datamodel.Node, _ error) { + // we can only call this once for a union since a union can only have one + // entry even though it behaves like a Map + if w.Done() { + return nil, nil, datamodel.ErrIteratorOverread{} + } + w.done = true + + haveIdx, mval := unionMember(w.val) + if haveIdx < 0 { + return nil, nil, fmt.Errorf("bindnode: union %s has no member", w.val.Type()) + } + mtyp := w.members[haveIdx] + + node := newNode(w.cfg, mtyp, mval) + key = basicnode.NewString(mtyp.Name()) + return key, node, nil +} + +func (w *_unionIterator) Done() bool { + return w.done +} + +// --- uint64 special case handling + +type _uintNode struct { + cfg config + schemaType schema.Type + + val reflect.Value // non-pointer +} + +func (tu *_uintNode) Type() schema.Type { + return tu.schemaType +} +func (tu *_uintNode) Representation() datamodel.Node { + return (*_uintNodeRepr)(tu) +} +func (_uintNode) Kind() datamodel.Kind { + return datamodel.Kind_Int +} +func (_uintNode) LookupByString(string) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByString("") +} +func (_uintNode) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByNode(nil) +} +func (_uintNode) LookupByIndex(idx int64) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByIndex(0) +} +func (_uintNode) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupBySegment(seg) +} +func (_uintNode) MapIterator() datamodel.MapIterator { + return nil +} +func (_uintNode) ListIterator() datamodel.ListIterator { + return nil +} +func (_uintNode) Length() int64 { + return -1 +} +func (_uintNode) IsAbsent() bool { + return false +} +func (_uintNode) IsNull() bool { + return false +} +func (_uintNode) AsBool() (bool, error) { + return mixins.Int{TypeName: "int"}.AsBool() +} +func (tu *_uintNode) AsInt() (int64, error) { + return (*_uintNodeRepr)(tu).AsInt() +} +func (tu *_uintNode) AsUint() (uint64, error) { + return (*_uintNodeRepr)(tu).AsUint() +} +func (_uintNode) AsFloat() (float64, error) { + return mixins.Int{TypeName: "int"}.AsFloat() +} +func (_uintNode) AsString() (string, error) { + return mixins.Int{TypeName: "int"}.AsString() +} +func (_uintNode) AsBytes() ([]byte, error) { + return mixins.Int{TypeName: "int"}.AsBytes() +} +func (_uintNode) AsLink() (datamodel.Link, error) { + return mixins.Int{TypeName: "int"}.AsLink() +} +func (_uintNode) Prototype() datamodel.NodePrototype { + return basicnode.Prototype__Int{} +} + +// we need this for _uintNode#Representation() so we don't return a TypeNode +type _uintNodeRepr _uintNode + +func (_uintNodeRepr) Kind() datamodel.Kind { + return datamodel.Kind_Int +} +func (_uintNodeRepr) LookupByString(string) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByString("") +} +func (_uintNodeRepr) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByNode(nil) +} +func (_uintNodeRepr) LookupByIndex(idx int64) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupByIndex(0) +} +func (_uintNodeRepr) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return mixins.Int{TypeName: "int"}.LookupBySegment(seg) +} +func (_uintNodeRepr) MapIterator() datamodel.MapIterator { + return nil +} +func (_uintNodeRepr) ListIterator() datamodel.ListIterator { + return nil +} +func (_uintNodeRepr) Length() int64 { + return -1 +} +func (_uintNodeRepr) IsAbsent() bool { + return false +} +func (_uintNodeRepr) IsNull() bool { + return false +} +func (_uintNodeRepr) AsBool() (bool, error) { + return mixins.Int{TypeName: "int"}.AsBool() +} +func (tu *_uintNodeRepr) AsInt() (int64, error) { + if err := compatibleKind(tu.schemaType, datamodel.Kind_Int); err != nil { + return 0, err + } + if customConverter := tu.cfg.converterFor(tu.val); customConverter != nil { + // user has registered a converter that takes the underlying type and returns an int + return customConverter.customToInt(ptrVal(tu.val).Interface()) + } + val := nonPtrVal(tu.val) + // we can assume it's a uint64 at this point + u := val.Uint() + if u > math.MaxInt64 { + return 0, fmt.Errorf("bindnode: integer overflow, %d is too large for an int64", u) + } + return int64(u), nil +} +func (tu *_uintNodeRepr) AsUint() (uint64, error) { + if err := compatibleKind(tu.schemaType, datamodel.Kind_Int); err != nil { + return 0, err + } + // TODO(rvagg): do we want a converter option for uint values? do we combine it + // with int converters? + // we can assume it's a uint64 at this point + return nonPtrVal(tu.val).Uint(), nil +} +func (_uintNodeRepr) AsFloat() (float64, error) { + return mixins.Int{TypeName: "int"}.AsFloat() +} +func (_uintNodeRepr) AsString() (string, error) { + return mixins.Int{TypeName: "int"}.AsString() +} +func (_uintNodeRepr) AsBytes() ([]byte, error) { + return mixins.Int{TypeName: "int"}.AsBytes() +} +func (_uintNodeRepr) AsLink() (datamodel.Link, error) { + return mixins.Int{TypeName: "int"}.AsLink() +} +func (_uintNodeRepr) Prototype() datamodel.NodePrototype { + return basicnode.Prototype__Int{} +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/repr.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/repr.go new file mode 100644 index 00000000..993defbd --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/bindnode/repr.go @@ -0,0 +1,1124 @@ +package bindnode + +import ( + "fmt" + "reflect" + "strings" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/basicnode" + "github.com/ipld/go-ipld-prime/schema" +) + +func reprNode(node datamodel.Node) datamodel.Node { + if node, ok := node.(schema.TypedNode); ok { + return node.Representation() + } + // datamodel.Absent and datamodel.Null are not typed. + // TODO: is this a problem? surely a typed struct's fields are always + // typed, even when absent or null. + return node +} + +func reprStrategy(typ schema.Type) interface{} { + // Can't use an interface check, as each method has a different result type. + // TODO: consider inlining this type switch at each call site, + // as the call sites need the underlying schema.Type too. + switch typ := typ.(type) { + case *schema.TypeStruct: + return typ.RepresentationStrategy() + case *schema.TypeUnion: + return typ.RepresentationStrategy() + case *schema.TypeEnum: + return typ.RepresentationStrategy() + } + return nil +} + +type _prototypeRepr _prototype + +func (w *_prototypeRepr) NewBuilder() datamodel.NodeBuilder { + return &_builderRepr{_assemblerRepr{ + cfg: w.cfg, + schemaType: w.schemaType, + val: reflect.New(w.goType).Elem(), + }} +} + +type _nodeRepr _node + +func (w *_nodeRepr) Kind() datamodel.Kind { + switch reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Stringjoin: + return datamodel.Kind_String + case schema.StructRepresentation_Map: + return datamodel.Kind_Map + case schema.StructRepresentation_Tuple: + return datamodel.Kind_List + case schema.UnionRepresentation_Keyed: + return datamodel.Kind_Map + case schema.UnionRepresentation_Kinded: + haveIdx, _ := unionMember(w.val) + if haveIdx < 0 { + panic(fmt.Sprintf("bindnode: kinded union %s has no member", w.val.Type())) + } + mtyp := w.schemaType.(*schema.TypeUnion).Members()[haveIdx] + return mtyp.RepresentationBehavior() + case schema.UnionRepresentation_Stringprefix: + return datamodel.Kind_String + case schema.EnumRepresentation_Int: + return datamodel.Kind_Int + case schema.EnumRepresentation_String: + return datamodel.Kind_String + default: + return (*_node)(w).Kind() + } +} + +func outboundMappedKey(stg schema.StructRepresentation_Map, key string) string { + // TODO: why doesn't stg just allow us to "get" by the key string? + field := schema.SpawnStructField(key, "", false, false) + mappedKey := stg.GetFieldKey(field) + return mappedKey +} + +func inboundMappedKey(typ *schema.TypeStruct, stg schema.StructRepresentation_Map, key string) string { + // TODO: can't do a "reverse" lookup... needs better API probably. + fields := typ.Fields() + for _, field := range fields { + mappedKey := stg.GetFieldKey(field) + if key == mappedKey { + return field.Name() + } + } + return key // fallback to the same key +} + +func outboundMappedType(stg schema.UnionRepresentation_Keyed, key string) string { + // TODO: why doesn't stg just allow us to "get" by the key string? + typ := schema.SpawnBool(key) + mappedKey := stg.GetDiscriminant(typ) + return mappedKey +} + +func inboundMappedType(typ *schema.TypeUnion, stg schema.UnionRepresentation_Keyed, key string) string { + // TODO: can't do a "reverse" lookup... needs better API probably. + for _, member := range typ.Members() { + mappedKey := stg.GetDiscriminant(member) + if key == mappedKey { + // println(key, "rev-mapped to", field.Name()) + return member.Name() + } + } + // println(key, "had no mapping") + return key // fallback to the same key +} + +// asKinded can be called on a kinded union node to obtain a node +// representing one of its members, identified by kind. +func (w *_nodeRepr) asKinded(stg schema.UnionRepresentation_Kinded, kind datamodel.Kind) *_nodeRepr { + name := stg.GetMember(kind) + members := w.schemaType.(*schema.TypeUnion).Members() + for i, member := range members { + if member.Name() != name { + continue + } + w2 := *w + w2.val = w.val.Field(i).Elem() + w2.schemaType = member + return &w2 + } + panic("bindnode TODO: GetMember result is missing?") +} + +func (w *_nodeRepr) LookupByString(key string) (datamodel.Node, error) { + if stg, ok := reprStrategy(w.schemaType).(schema.UnionRepresentation_Kinded); ok { + w = w.asKinded(stg, datamodel.Kind_Map) + } + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Map: + revKey := inboundMappedKey(w.schemaType.(*schema.TypeStruct), stg, key) + v, err := (*_node)(w).LookupByString(revKey) + if err != nil { + return nil, err + } + return reprNode(v), nil + case schema.UnionRepresentation_Keyed: + revKey := inboundMappedType(w.schemaType.(*schema.TypeUnion), stg, key) + v, err := (*_node)(w).LookupByString(revKey) + if err != nil { + return nil, err + } + return reprNode(v), nil + default: + v, err := (*_node)(w).LookupByString(key) + if err != nil { + return nil, err + } + return reprNode(v), nil + } +} + +func (w *_nodeRepr) LookupByIndex(idx int64) (datamodel.Node, error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_List).LookupByIndex(idx) + case schema.StructRepresentation_Tuple: + fields := w.schemaType.(*schema.TypeStruct).Fields() + if idx < 0 || int(idx) >= len(fields) { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfInt(idx)} + } + field := fields[idx] + v, err := (*_node)(w).LookupByString(field.Name()) + if err != nil { + return nil, err + } + return reprNode(v), nil + default: + v, err := (*_node)(w).LookupByIndex(idx) + if err != nil { + return nil, err + } + return reprNode(v), nil + } +} + +func (w *_nodeRepr) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + switch w.Kind() { + case datamodel.Kind_Map: + return w.LookupByString(seg.String()) + case datamodel.Kind_List: + idx, err := seg.Index() + if err != nil { + return nil, err + } + return w.LookupByIndex(idx) + } + return nil, datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "LookupBySegment", + AppropriateKind: datamodel.KindSet_Recursive, + ActualKind: w.Kind(), + } +} + +func (w *_nodeRepr) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + switch w.Kind() { + case datamodel.Kind_Map: + s, err := key.AsString() + if err != nil { + return nil, err + } + return w.LookupByString(s) + case datamodel.Kind_List: + i, err := key.AsInt() + if err != nil { + return nil, err + } + return w.LookupByIndex(i) + } + return nil, datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "LookupByNode", + AppropriateKind: datamodel.KindSet_Recursive, + ActualKind: w.Kind(), + } +} + +func (w *_nodeRepr) MapIterator() datamodel.MapIterator { + // TODO: we can try to reuse reprStrategy here and elsewhere + if stg, ok := reprStrategy(w.schemaType).(schema.UnionRepresentation_Kinded); ok { + w = w.asKinded(stg, datamodel.Kind_Map) + } + switch reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Map: + itr := (*_node)(w).MapIterator().(*_structIterator) + // When we reach the last non-absent field, we should stop. + itr.reprEnd = int(w.lengthMinusTrailingAbsents()) + return (*_structIteratorRepr)(itr) + case schema.UnionRepresentation_Keyed: + itr := (*_node)(w).MapIterator().(*_unionIterator) + return (*_unionIteratorRepr)(itr) + default: + iter, _ := (*_node)(w).MapIterator().(*_mapIterator) + if iter == nil { + return nil + } + return (*_mapIteratorRepr)(iter) + } +} + +type _mapIteratorRepr _mapIterator + +func (w *_mapIteratorRepr) Next() (key, value datamodel.Node, _ error) { + k, v, err := (*_mapIterator)(w).Next() + if err != nil { + return nil, nil, err + } + return reprNode(k), reprNode(v), nil +} + +func (w *_mapIteratorRepr) Done() bool { + return w.nextIndex >= w.keysVal.Len() +} + +func (w *_nodeRepr) ListIterator() datamodel.ListIterator { + if stg, ok := reprStrategy(w.schemaType).(schema.UnionRepresentation_Kinded); ok { + w = w.asKinded(stg, datamodel.Kind_List) + } + switch reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Tuple: + typ := w.schemaType.(*schema.TypeStruct) + iter := _tupleIteratorRepr{cfg: w.cfg, schemaType: typ, fields: typ.Fields(), val: w.val} + iter.reprEnd = int(w.lengthMinusTrailingAbsents()) + return &iter + default: + iter, _ := (*_node)(w).ListIterator().(*_listIterator) + if iter == nil { + return nil + } + return (*_listIteratorRepr)(iter) + } +} + +type _listIteratorRepr _listIterator + +func (w *_listIteratorRepr) Next() (index int64, value datamodel.Node, _ error) { + idx, v, err := (*_listIterator)(w).Next() + if err != nil { + return idx, nil, err + } + return idx, reprNode(v), nil +} + +func (w *_listIteratorRepr) Done() bool { + return w.nextIndex >= w.val.Len() +} + +func (w *_nodeRepr) lengthMinusAbsents() int64 { + fields := w.schemaType.(*schema.TypeStruct).Fields() + n := int64(len(fields)) + for i, field := range fields { + if field.IsOptional() && w.val.Field(i).IsNil() { + n-- + } + } + return n +} + +type _tupleIteratorRepr struct { + // TODO: support embedded fields? + cfg config + schemaType *schema.TypeStruct + fields []schema.StructField + val reflect.Value // non-pointer + nextIndex int + + // these are only used in repr.go + reprEnd int +} + +func (w *_tupleIteratorRepr) Next() (index int64, value datamodel.Node, _ error) { +_skipAbsent: + _, value, err := (*_structIterator)(w).Next() + if err != nil { + return 0, nil, err + } + if w.nextIndex > w.reprEnd { + goto _skipAbsent + } + return int64(w.nextIndex), reprNode(value), nil +} + +func (w *_tupleIteratorRepr) Done() bool { + return w.nextIndex >= w.reprEnd +} + +func (w *_nodeRepr) lengthMinusTrailingAbsents() int64 { + fields := w.schemaType.(*schema.TypeStruct).Fields() + for i := len(fields) - 1; i >= 0; i-- { + field := fields[i] + if !field.IsOptional() || !w.val.Field(i).IsNil() { + return int64(i + 1) + } + } + return 0 +} + +func (w *_nodeRepr) Length() int64 { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Stringjoin: + return -1 + case schema.StructRepresentation_Map: + return w.lengthMinusAbsents() + case schema.StructRepresentation_Tuple: + return w.lengthMinusTrailingAbsents() + case schema.UnionRepresentation_Keyed: + return (*_node)(w).Length() + case schema.UnionRepresentation_Kinded: + w = w.asKinded(stg, w.Kind()) + return (*_node)(w).Length() + default: + return (*_node)(w).Length() + } +} + +func (w *_nodeRepr) IsAbsent() bool { + if reprStrategy(w.schemaType) == nil { + return (*_node)(w).IsAbsent() + } + return false +} + +func (w *_nodeRepr) IsNull() bool { + if reprStrategy(w.schemaType) == nil { + return (*_node)(w).IsNull() + } + return false +} + +func (w *_nodeRepr) AsBool() (bool, error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Bool).AsBool() + default: + return (*_node)(w).AsBool() + } +} + +func (w *_nodeRepr) AsInt() (int64, error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Int).AsInt() + case schema.EnumRepresentation_Int: + kind := w.val.Kind() + if kind == reflect.String { + s, err := (*_node)(w).AsString() + if err != nil { + return 0, err + } + mapped, ok := stg[s] + if !ok { + // We assume that the schema strategy is correct, + // so we can only fail if the stored string isn't a valid member. + return 0, fmt.Errorf("AsInt: %q is not a valid member of enum %s", s, w.schemaType.Name()) + } + // TODO: the strategy type should probably use int64 rather than int + return int64(mapped), nil + } + var i int + // TODO: check for overflows + if kindInt[kind] { + i = int(w.val.Int()) + } else if kindUint[kind] { + i = int(w.val.Uint()) + } else { + return 0, fmt.Errorf("AsInt: unexpected kind: %s", kind) + } + for _, reprInt := range stg { + if reprInt == i { + return int64(i), nil + } + } + // We assume that the schema strategy is correct, + // so we can only fail if the stored string isn't a valid member. + return 0, fmt.Errorf("AsInt: %d is not a valid member of enum %s", i, w.schemaType.Name()) + default: + return (*_node)(w).AsInt() + } +} + +func (w *_nodeRepr) AsFloat() (float64, error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Float).AsFloat() + default: + return (*_node)(w).AsFloat() + } +} + +func (w *_nodeRepr) AsString() (string, error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Stringjoin: + var b strings.Builder + itr := (*_node)(w).MapIterator() + first := true + for !itr.Done() { + _, v, err := itr.Next() + if err != nil { + return "", err + } + s, err := reprNode(v).AsString() + if err != nil { + return "", err + } + if first { + first = false + } else { + b.WriteString(stg.GetDelim()) + } + b.WriteString(s) + } + return b.String(), nil + case schema.UnionRepresentation_Stringprefix: + haveIdx, mval := unionMember(w.val) + mtyp := w.schemaType.(*schema.TypeUnion).Members()[haveIdx] + + w2 := *w + w2.val = mval + w2.schemaType = mtyp + s, err := w2.AsString() + if err != nil { + return "", err + } + + name := stg.GetDiscriminant(mtyp) + return name + stg.GetDelim() + s, nil + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_String).AsString() + case schema.EnumRepresentation_String: + s, err := (*_node)(w).AsString() + if err != nil { + return "", err + } + if mapped := stg[s]; mapped != "" { + return mapped, nil + } + members := w.schemaType.(*schema.TypeEnum).Members() + for _, member := range members { + if s == member { + return s, nil + } + } + for k, v := range stg { + // a programming error? we may have the enum string value rather than the type + if v == s { + return "", fmt.Errorf("AsString: %q is not a valid member of enum %s (bindnode works at the type level; did you mean %q?)", s, w.schemaType.Name(), k) + } + } + return "", fmt.Errorf("AsString: %q is not a valid member of enum %s", s, w.schemaType.Name()) + default: + return (*_node)(w).AsString() + } +} + +func (w *_nodeRepr) AsBytes() ([]byte, error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Bytes).AsBytes() + default: + return (*_node)(w).AsBytes() + } +} + +func (w *_nodeRepr) AsLink() (datamodel.Link, error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Link).AsLink() + default: + return (*_node)(w).AsLink() + } +} + +func (w *_nodeRepr) Prototype() datamodel.NodePrototype { + return (*_prototypeRepr)((*_node)(w).Prototype().(*_prototype)) +} + +type _builderRepr struct { + _assemblerRepr +} + +// TODO: returning a repr node here is probably good, but there's a gotcha: one +// can go from a typed node to a repr node via the Representation method, but +// not the other way. That's probably why codegen returns a typed node here. +// The solution might be to add a way to go from the repr node to its parent +// typed node. + +func (w *_builderRepr) Build() datamodel.Node { + // TODO: see the notes above. + // return &_nodeRepr{schemaType: w.schemaType, val: w.val} + return &_node{cfg: w.cfg, schemaType: w.schemaType, val: w.val} +} + +func (w *_builderRepr) Reset() { + panic("bindnode TODO: Reset") +} + +type _assemblerRepr struct { + cfg config + schemaType schema.Type + val reflect.Value // non-pointer + finish func() error + + nullable bool +} + +func assemblerRepr(am datamodel.NodeAssembler) datamodel.NodeAssembler { + switch am := am.(type) { + case *_assembler: + return (*_assemblerRepr)(am) + case _errorAssembler: + return am + default: + panic(fmt.Sprintf("unexpected NodeAssembler type: %T", am)) + } +} + +func (w *_assemblerRepr) asKinded(stg schema.UnionRepresentation_Kinded, kind datamodel.Kind) datamodel.NodeAssembler { + name := stg.GetMember(kind) + members := w.schemaType.(*schema.TypeUnion).Members() + kindSet := make([]datamodel.Kind, 0, len(members)) + for idx, member := range members { + if member.Name() != name { + kindSet = append(kindSet, member.RepresentationBehavior()) + continue + } + w2 := *w + goType := w.val.Field(idx).Type().Elem() + valPtr := reflect.New(goType) + w2.val = valPtr.Elem() + w2.schemaType = member + + // Layer a new finish func on top, to set Index/Value. + w2.finish = func() error { + unionSetMember(w.val, idx, valPtr) + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil + } + return &w2 + } + return _errorAssembler{datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name() + ".Repr", + MethodName: "", // TODO: we could fill it via runtime.Callers + AppropriateKind: datamodel.KindSet(kindSet), + ActualKind: kind, + }} +} + +func (w *_assemblerRepr) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + if stg, ok := reprStrategy(w.schemaType).(schema.UnionRepresentation_Kinded); ok { + return w.asKinded(stg, datamodel.Kind_Map).BeginMap(sizeHint) + } + asm, err := (*_assembler)(w).BeginMap(sizeHint) + if err != nil { + return nil, err + } + switch asm := asm.(type) { + case *_structAssembler: + return (*_structAssemblerRepr)(asm), nil + case *_mapAssembler: + return (*_mapAssemblerRepr)(asm), nil + case *_unionAssembler: + return (*_unionAssemblerRepr)(asm), nil + case *basicMapAssembler: + return asm, nil + default: + return nil, fmt.Errorf("bindnode BeginMap TODO: %T", asm) + } +} + +func (w *_assemblerRepr) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_List).BeginList(sizeHint) + case schema.StructRepresentation_Tuple: + asm, err := (*_assembler)(w).BeginMap(sizeHint) + if err != nil { + return nil, err + } + return (*_listStructAssemblerRepr)(asm.(*_structAssembler)), nil + default: + asm, err := (*_assembler)(w).BeginList(sizeHint) + if err != nil { + return nil, err + } + if _, ok := asm.(*basicListAssembler); ok { + return asm, nil + } + return (*_listAssemblerRepr)(asm.(*_listAssembler)), nil + } +} + +func (w *_assemblerRepr) AssignNull() error { + return (*_assembler)(w).AssignNull() +} + +func (w *_assemblerRepr) AssignBool(b bool) error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Bool).AssignBool(b) + default: + return (*_assembler)(w).AssignBool(b) + } +} + +func (w *_assemblerRepr) assignUInt(uin datamodel.UintNode) error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Int).(*_assemblerRepr).assignUInt(uin) + case schema.EnumRepresentation_Int: + uin, err := uin.AsUint() + if err != nil { + return err + } + return fmt.Errorf("AssignInt: %d is not a valid member of enum %s", uin, w.schemaType.Name()) + default: + return (*_assembler)(w).assignUInt(uin) + } +} + +func (w *_assemblerRepr) AssignInt(i int64) error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Int).AssignInt(i) + case schema.EnumRepresentation_Int: + for member, reprInt := range stg { + if int64(reprInt) != i { + continue + } + val := (*_assembler)(w).createNonPtrVal() + kind := val.Kind() + if kind == reflect.String { + // Reuse AssignString so we don't have to repeat ten lines. + return (*_assembler)(w).AssignString(member) + } + // Short-cut to storing the repr int directly, akin to node.go's AssignInt. + if kindInt[kind] { + val.SetInt(i) + } else if kindUint[kind] { + if i < 0 { + // TODO: write a test + return fmt.Errorf("bindnode: cannot assign negative integer to %s", w.val.Type()) + } + val.SetUint(uint64(i)) + } else { + return fmt.Errorf("AsInt: unexpected kind: %s", val.Kind()) + } + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil + } + return fmt.Errorf("AssignInt: %d is not a valid member of enum %s", i, w.schemaType.Name()) + default: + return (*_assembler)(w).AssignInt(i) + } +} + +func (w *_assemblerRepr) AssignFloat(f float64) error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Float).AssignFloat(f) + default: + return (*_assembler)(w).AssignFloat(f) + } +} + +func (w *_assemblerRepr) AssignString(s string) error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Stringjoin: + fields := w.schemaType.(*schema.TypeStruct).Fields() + parts := strings.Split(s, stg.GetDelim()) + if len(parts) != len(fields) { + return fmt.Errorf("bindnode TODO: len mismatch") + } + mapAsm, err := (*_assembler)(w).BeginMap(-1) + if err != nil { + return err + } + for i, field := range fields { + entryAsm, err := mapAsm.AssembleEntry(field.Name()) + if err != nil { + return err + } + entryAsm = assemblerRepr(entryAsm) + if err := entryAsm.AssignString(parts[i]); err != nil { + return err + } + } + return mapAsm.Finish() + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_String).AssignString(s) + case schema.UnionRepresentation_Stringprefix: + hasDelim := stg.GetDelim() != "" + + var prefix, remainder string + if hasDelim { + parts := strings.SplitN(s, stg.GetDelim(), 2) + if len(parts) != 2 { + return fmt.Errorf("schema rejects data: the union type %s expects delimiter %q, and it was not found in the data %q", w.schemaType.Name(), stg.GetDelim(), s) + } + prefix, remainder = parts[0], parts[1] + } + + members := w.schemaType.(*schema.TypeUnion).Members() + for idx, member := range members { + descrm := stg.GetDiscriminant(member) + if hasDelim { + if stg.GetDiscriminant(member) != prefix { + continue + } + } else { + if !strings.HasPrefix(s, descrm) { + continue + } + remainder = s[len(descrm):] + } + + // TODO: DRY: this has much in common with the asKinded method; it differs only in that we picked idx already in a different way. + w2 := *w + goType := w.val.Field(idx).Type().Elem() + valPtr := reflect.New(goType) + w2.val = valPtr.Elem() + w2.schemaType = member + w2.finish = func() error { + unionSetMember(w.val, idx, valPtr) + if w.finish != nil { + if err := w.finish(); err != nil { + return err + } + } + return nil + } + return w2.AssignString(remainder) + } + return fmt.Errorf("schema rejects data: the union type %s requires a known prefix, and it was not found in the data %q", w.schemaType.Name(), s) + case schema.EnumRepresentation_String: + // Note that we need to do a reverse lookup. + for member, mapped := range stg { + if mapped == s { + return (*_assembler)(w).AssignString(member) + } + } + members := w.schemaType.(*schema.TypeEnum).Members() + for _, member := range members { + if s == member { + return (*_assembler)(w).AssignString(member) + } + } + return fmt.Errorf("AssignString: %q is not a valid member of enum %s", s, w.schemaType.Name()) + case schema.EnumRepresentation_Int: + return datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name(), + MethodName: "AssignString", + AppropriateKind: datamodel.KindSet_JustInt, + ActualKind: datamodel.Kind_String, + } + default: + return (*_assembler)(w).AssignString(s) + } +} + +func (w *_assemblerRepr) AssignBytes(p []byte) error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Bytes).AssignBytes(p) + default: + return (*_assembler)(w).AssignBytes(p) + } +} + +func (w *_assemblerRepr) AssignLink(link datamodel.Link) error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Kinded: + return w.asKinded(stg, datamodel.Kind_Link).AssignLink(link) + default: + return (*_assembler)(w).AssignLink(link) + } +} + +func (w *_assemblerRepr) AssignNode(node datamodel.Node) error { + // TODO: attempt to take a shortcut, like assembler.AssignNode + if uintNode, ok := node.(datamodel.UintNode); ok { + return w.assignUInt(uintNode) + } + return datamodel.Copy(node, w) +} + +func (w *_assemblerRepr) Prototype() datamodel.NodePrototype { + panic("bindnode TODO: Assembler.Prototype") +} + +type _structAssemblerRepr _structAssembler + +func (w *_structAssemblerRepr) AssembleKey() datamodel.NodeAssembler { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Map: + return (*_structAssembler)(w).AssembleKey() + case schema.StructRepresentation_Stringjoin, + schema.StructRepresentation_StringPairs: + // TODO: perhaps the ErrorWrongKind type should also be extended to explicitly describe whether the method was applied on bare DM, type-level, or repr-level. + return _errorAssembler{datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name() + ".Repr", + MethodName: "AssembleKey", + AppropriateKind: datamodel.KindSet_JustMap, + ActualKind: datamodel.Kind_String, + }} + case schema.StructRepresentation_Tuple: + return _errorAssembler{datamodel.ErrWrongKind{ + TypeName: w.schemaType.Name() + ".Repr", + MethodName: "AssembleKey", + AppropriateKind: datamodel.KindSet_JustMap, + ActualKind: datamodel.Kind_List, + }} + default: + return _errorAssembler{fmt.Errorf("bindnode AssembleKey TODO: %T", stg)} + } +} + +func (w *_structAssemblerRepr) AssembleValue() datamodel.NodeAssembler { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Map: + key := w.curKey.val.String() + revKey := inboundMappedKey(w.schemaType, stg, key) + w.curKey.val.SetString(revKey) + + valAsm := (*_structAssembler)(w).AssembleValue() + valAsm = assemblerRepr(valAsm) + return valAsm + default: + return _errorAssembler{fmt.Errorf("bindnode AssembleValue TODO: %T", stg)} + } +} + +func (w *_structAssemblerRepr) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + if err := w.AssembleKey().AssignString(k); err != nil { + return nil, err + } + am := w.AssembleValue() + return am, nil +} + +func (w *_structAssemblerRepr) Finish() error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Map: + err := (*_structAssembler)(w).Finish() + if err, ok := err.(schema.ErrMissingRequiredField); ok { + for i, name := range err.Missing { + serial := outboundMappedKey(stg, name) + if serial != name { + err.Missing[i] += fmt.Sprintf(" (serial:%q)", serial) + } + } + } + return err + default: + return fmt.Errorf("bindnode Finish TODO: %T", stg) + } +} + +func (w *_structAssemblerRepr) KeyPrototype() datamodel.NodePrototype { + panic("bindnode TODO") +} + +func (w *_structAssemblerRepr) ValuePrototype(k string) datamodel.NodePrototype { + panic("bindnode TODO: struct ValuePrototype") +} + +type _mapAssemblerRepr _mapAssembler + +func (w *_mapAssemblerRepr) AssembleKey() datamodel.NodeAssembler { + asm := (*_mapAssembler)(w).AssembleKey() + return (*_assemblerRepr)(asm.(*_assembler)) +} + +func (w *_mapAssemblerRepr) AssembleValue() datamodel.NodeAssembler { + asm := (*_mapAssembler)(w).AssembleValue() + return (*_assemblerRepr)(asm.(*_assembler)) +} + +func (w *_mapAssemblerRepr) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + if err := w.AssembleKey().AssignString(k); err != nil { + return nil, err + } + am := w.AssembleValue() + return am, nil +} + +func (w *_mapAssemblerRepr) Finish() error { + return (*_mapAssembler)(w).Finish() +} + +func (w *_mapAssemblerRepr) KeyPrototype() datamodel.NodePrototype { + panic("bindnode TODO") +} + +func (w *_mapAssemblerRepr) ValuePrototype(k string) datamodel.NodePrototype { + panic("bindnode TODO: struct ValuePrototype") +} + +type _listStructAssemblerRepr _structAssembler + +func (w *_listStructAssemblerRepr) AssembleValue() datamodel.NodeAssembler { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Tuple: + fields := w.schemaType.Fields() + if w.nextIndex >= len(fields) { + return _errorAssembler{datamodel.ErrNotExists{ + Segment: datamodel.PathSegmentOfInt(int64(w.nextIndex)), + }} + } + field := fields[w.nextIndex] + w.doneFields[w.nextIndex] = true + w.nextIndex++ + + entryAsm, err := (*_structAssembler)(w).AssembleEntry(field.Name()) + if err != nil { + return _errorAssembler{err} + } + entryAsm = assemblerRepr(entryAsm) + return entryAsm + default: + return _errorAssembler{fmt.Errorf("bindnode AssembleValue TODO: %T", stg)} + } +} + +func (w *_listStructAssemblerRepr) Finish() error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Tuple: + return (*_structAssembler)(w).Finish() + default: + return fmt.Errorf("bindnode Finish TODO: %T", stg) + } +} + +func (w *_listStructAssemblerRepr) ValuePrototype(idx int64) datamodel.NodePrototype { + panic("bindnode TODO: list ValuePrototype") +} + +// Note that lists do not have any representation strategy right now. +type _listAssemblerRepr _listAssembler + +func (w *_listAssemblerRepr) AssembleValue() datamodel.NodeAssembler { + asm := (*_listAssembler)(w).AssembleValue() + return (*_assemblerRepr)(asm.(*_assembler)) +} + +func (w *_listAssemblerRepr) Finish() error { + return (*_listAssembler)(w).Finish() +} + +func (w *_listAssemblerRepr) ValuePrototype(idx int64) datamodel.NodePrototype { + panic("bindnode TODO: list ValuePrototype") +} + +type _unionAssemblerRepr _unionAssembler + +func (w *_unionAssemblerRepr) AssembleKey() datamodel.NodeAssembler { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Keyed: + return (*_unionAssembler)(w).AssembleKey() + default: + return _errorAssembler{fmt.Errorf("bindnode AssembleKey TODO: %T", stg)} + } +} + +func (w *_unionAssemblerRepr) AssembleValue() datamodel.NodeAssembler { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Keyed: + key := w.curKey.val.String() + revKey := inboundMappedType(w.schemaType, stg, key) + w.curKey.val.SetString(revKey) + + valAsm := (*_unionAssembler)(w).AssembleValue() + valAsm = assemblerRepr(valAsm) + return valAsm + default: + return _errorAssembler{fmt.Errorf("bindnode AssembleValue TODO: %T", stg)} + } +} + +func (w *_unionAssemblerRepr) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + if err := w.AssembleKey().AssignString(k); err != nil { + return nil, err + } + am := w.AssembleValue() + return am, nil +} + +func (w *_unionAssemblerRepr) Finish() error { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Keyed: + return (*_unionAssembler)(w).Finish() + default: + return fmt.Errorf("bindnode Finish TODO: %T", stg) + } +} + +func (w *_unionAssemblerRepr) KeyPrototype() datamodel.NodePrototype { + panic("bindnode TODO") +} + +func (w *_unionAssemblerRepr) ValuePrototype(k string) datamodel.NodePrototype { + panic("bindnode TODO: union ValuePrototype") +} + +type _structIteratorRepr _structIterator + +func (w *_structIteratorRepr) Next() (key, value datamodel.Node, _ error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Map: + _skipAbsent: + key, value, err := (*_structIterator)(w).Next() + if err != nil { + return nil, nil, err + } + if value.IsAbsent() { + goto _skipAbsent + } + keyStr, _ := key.AsString() + mappedKey := outboundMappedKey(stg, keyStr) + if mappedKey != keyStr { + key = basicnode.NewString(mappedKey) + } + return key, reprNode(value), nil + default: + return nil, nil, fmt.Errorf("bindnode Next TODO: %T", stg) + } +} + +func (w *_structIteratorRepr) Done() bool { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.StructRepresentation_Map: + // TODO: the fact that repr map iterators skip absents should be + // documented somewhere + return w.nextIndex >= w.reprEnd + default: + panic(fmt.Sprintf("bindnode Done TODO: %T", stg)) + } +} + +type _unionIteratorRepr _unionIterator + +func (w *_unionIteratorRepr) Next() (key, value datamodel.Node, _ error) { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Keyed: + key, value, err := (*_unionIterator)(w).Next() + if err != nil { + return nil, nil, err + } + keyStr, _ := key.AsString() + mappedKey := outboundMappedType(stg, keyStr) + if mappedKey != keyStr { + key = basicnode.NewString(mappedKey) + } + return key, reprNode(value), nil + default: + return nil, nil, fmt.Errorf("bindnode Next TODO: %T", stg) + } +} + +func (w *_unionIteratorRepr) Done() bool { + switch stg := reprStrategy(w.schemaType).(type) { + case schema.UnionRepresentation_Keyed: + return (*_unionIterator)(w).Done() + default: + panic(fmt.Sprintf("bindnode Done TODO: %T", stg)) + } +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/bool.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/bool.go index decfa23c..90f0f370 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/bool.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/bool.go @@ -1,7 +1,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // Bool can be embedded in a struct to provide all the methods that @@ -19,25 +19,25 @@ type Bool struct { TypeName string } -func (Bool) Kind() ipld.Kind { - return ipld.Kind_Bool +func (Bool) Kind() datamodel.Kind { + return datamodel.Kind_Bool } -func (x Bool) LookupByString(string) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Bool} +func (x Bool) LookupByString(string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Bool} } -func (x Bool) LookupByNode(key ipld.Node) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Bool} +func (x Bool) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Bool} } -func (x Bool) LookupByIndex(idx int64) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Bool} +func (x Bool) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Bool} } -func (x Bool) LookupBySegment(ipld.PathSegment) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: ipld.KindSet_Recursive, ActualKind: ipld.Kind_Bool} +func (x Bool) LookupBySegment(datamodel.PathSegment) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: datamodel.KindSet_Recursive, ActualKind: datamodel.Kind_Bool} } -func (Bool) MapIterator() ipld.MapIterator { +func (Bool) MapIterator() datamodel.MapIterator { return nil } -func (Bool) ListIterator() ipld.ListIterator { +func (Bool) ListIterator() datamodel.ListIterator { return nil } func (Bool) Length() int64 { @@ -50,19 +50,19 @@ func (Bool) IsNull() bool { return false } func (x Bool) AsInt() (int64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Bool} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Bool} } func (x Bool) AsFloat() (float64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Bool} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Bool} } func (x Bool) AsString() (string, error) { - return "", ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Bool} + return "", datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Bool} } func (x Bool) AsBytes() ([]byte, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Bool} + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Bool} } -func (x Bool) AsLink() (ipld.Link, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Bool} +func (x Bool) AsLink() (datamodel.Link, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Bool} } // BoolAssembler has similar purpose as Bool, but for (you guessed it) @@ -71,27 +71,27 @@ type BoolAssembler struct { TypeName string } -func (x BoolAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Bool} +func (x BoolAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Bool} } -func (x BoolAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Bool} +func (x BoolAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Bool} } func (x BoolAssembler) AssignNull() error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: ipld.KindSet_JustNull, ActualKind: ipld.Kind_Bool} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: datamodel.KindSet_JustNull, ActualKind: datamodel.Kind_Bool} } func (x BoolAssembler) AssignInt(int64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Bool} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Bool} } func (x BoolAssembler) AssignFloat(float64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Bool} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Bool} } func (x BoolAssembler) AssignString(string) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Bool} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Bool} } func (x BoolAssembler) AssignBytes([]byte) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Bool} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Bool} } -func (x BoolAssembler) AssignLink(ipld.Link) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Bool} +func (x BoolAssembler) AssignLink(datamodel.Link) error { + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Bool} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/bytes.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/bytes.go index 05a4e3bf..56a828aa 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/bytes.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/bytes.go @@ -1,7 +1,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // Bytes can be embedded in a struct to provide all the methods that @@ -19,25 +19,25 @@ type Bytes struct { TypeName string } -func (Bytes) Kind() ipld.Kind { - return ipld.Kind_Bytes +func (Bytes) Kind() datamodel.Kind { + return datamodel.Kind_Bytes } -func (x Bytes) LookupByString(string) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Bytes} +func (x Bytes) LookupByString(string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Bytes} } -func (x Bytes) LookupByNode(key ipld.Node) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Bytes} +func (x Bytes) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Bytes} } -func (x Bytes) LookupByIndex(idx int64) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Bytes} +func (x Bytes) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Bytes} } -func (x Bytes) LookupBySegment(ipld.PathSegment) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: ipld.KindSet_Recursive, ActualKind: ipld.Kind_Bytes} +func (x Bytes) LookupBySegment(datamodel.PathSegment) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: datamodel.KindSet_Recursive, ActualKind: datamodel.Kind_Bytes} } -func (Bytes) MapIterator() ipld.MapIterator { +func (Bytes) MapIterator() datamodel.MapIterator { return nil } -func (Bytes) ListIterator() ipld.ListIterator { +func (Bytes) ListIterator() datamodel.ListIterator { return nil } func (Bytes) Length() int64 { @@ -50,19 +50,19 @@ func (Bytes) IsNull() bool { return false } func (x Bytes) AsBool() (bool, error) { - return false, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Bytes} + return false, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Bytes} } func (x Bytes) AsInt() (int64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Bytes} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Bytes} } func (x Bytes) AsFloat() (float64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Bytes} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Bytes} } func (x Bytes) AsString() (string, error) { - return "", ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Bytes} + return "", datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Bytes} } -func (x Bytes) AsLink() (ipld.Link, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Bytes} +func (x Bytes) AsLink() (datamodel.Link, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Bytes} } // BytesAssembler has similar purpose as Bytes, but for (you guessed it) @@ -71,27 +71,27 @@ type BytesAssembler struct { TypeName string } -func (x BytesAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Bytes} +func (x BytesAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Bytes} } -func (x BytesAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Bytes} +func (x BytesAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Bytes} } func (x BytesAssembler) AssignNull() error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: ipld.KindSet_JustNull, ActualKind: ipld.Kind_Bytes} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: datamodel.KindSet_JustNull, ActualKind: datamodel.Kind_Bytes} } func (x BytesAssembler) AssignBool(bool) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Bytes} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Bytes} } func (x BytesAssembler) AssignInt(int64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Bytes} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Bytes} } func (x BytesAssembler) AssignFloat(float64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Bytes} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Bytes} } func (x BytesAssembler) AssignString(string) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Bytes} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Bytes} } -func (x BytesAssembler) AssignLink(ipld.Link) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Bytes} +func (x BytesAssembler) AssignLink(datamodel.Link) error { + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Bytes} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/float.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/float.go index c42d6678..dba1bf00 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/float.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/float.go @@ -1,7 +1,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // Float can be embedded in a struct to provide all the methods that @@ -19,25 +19,25 @@ type Float struct { TypeName string } -func (Float) Kind() ipld.Kind { - return ipld.Kind_Float +func (Float) Kind() datamodel.Kind { + return datamodel.Kind_Float } -func (x Float) LookupByString(string) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Float} +func (x Float) LookupByString(string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Float} } -func (x Float) LookupByNode(key ipld.Node) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Float} +func (x Float) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Float} } -func (x Float) LookupByIndex(idx int64) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Float} +func (x Float) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Float} } -func (x Float) LookupBySegment(ipld.PathSegment) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: ipld.KindSet_Recursive, ActualKind: ipld.Kind_Float} +func (x Float) LookupBySegment(datamodel.PathSegment) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: datamodel.KindSet_Recursive, ActualKind: datamodel.Kind_Float} } -func (Float) MapIterator() ipld.MapIterator { +func (Float) MapIterator() datamodel.MapIterator { return nil } -func (Float) ListIterator() ipld.ListIterator { +func (Float) ListIterator() datamodel.ListIterator { return nil } func (Float) Length() int64 { @@ -50,19 +50,19 @@ func (Float) IsNull() bool { return false } func (x Float) AsBool() (bool, error) { - return false, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Float} + return false, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Float} } func (x Float) AsInt() (int64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Float} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Float} } func (x Float) AsString() (string, error) { - return "", ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Float} + return "", datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Float} } func (x Float) AsBytes() ([]byte, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Float} + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Float} } -func (x Float) AsLink() (ipld.Link, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Float} +func (x Float) AsLink() (datamodel.Link, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Float} } // FloatAssembler has similar purpose as Float, but for (you guessed it) @@ -71,27 +71,27 @@ type FloatAssembler struct { TypeName string } -func (x FloatAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Float} +func (x FloatAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Float} } -func (x FloatAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Float} +func (x FloatAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Float} } func (x FloatAssembler) AssignNull() error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: ipld.KindSet_JustNull, ActualKind: ipld.Kind_Float} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: datamodel.KindSet_JustNull, ActualKind: datamodel.Kind_Float} } func (x FloatAssembler) AssignBool(bool) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Float} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Float} } func (x FloatAssembler) AssignInt(int64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Float} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Float} } func (x FloatAssembler) AssignString(string) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Float} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Float} } func (x FloatAssembler) AssignBytes([]byte) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Float} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Float} } -func (x FloatAssembler) AssignLink(ipld.Link) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Float} +func (x FloatAssembler) AssignLink(datamodel.Link) error { + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Float} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/int.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/int.go index 724b8150..062bc21c 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/int.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/int.go @@ -1,7 +1,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // Int can be embedded in a struct to provide all the methods that @@ -19,25 +19,25 @@ type Int struct { TypeName string } -func (Int) Kind() ipld.Kind { - return ipld.Kind_Int +func (Int) Kind() datamodel.Kind { + return datamodel.Kind_Int } -func (x Int) LookupByString(string) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Int} +func (x Int) LookupByString(string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Int} } -func (x Int) LookupByNode(key ipld.Node) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Int} +func (x Int) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Int} } -func (x Int) LookupByIndex(idx int64) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Int} +func (x Int) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Int} } -func (x Int) LookupBySegment(ipld.PathSegment) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: ipld.KindSet_Recursive, ActualKind: ipld.Kind_Int} +func (x Int) LookupBySegment(datamodel.PathSegment) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: datamodel.KindSet_Recursive, ActualKind: datamodel.Kind_Int} } -func (Int) MapIterator() ipld.MapIterator { +func (Int) MapIterator() datamodel.MapIterator { return nil } -func (Int) ListIterator() ipld.ListIterator { +func (Int) ListIterator() datamodel.ListIterator { return nil } func (Int) Length() int64 { @@ -50,19 +50,19 @@ func (Int) IsNull() bool { return false } func (x Int) AsBool() (bool, error) { - return false, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Int} + return false, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Int} } func (x Int) AsFloat() (float64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Int} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Int} } func (x Int) AsString() (string, error) { - return "", ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Int} + return "", datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Int} } func (x Int) AsBytes() ([]byte, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Int} + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Int} } -func (x Int) AsLink() (ipld.Link, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Int} +func (x Int) AsLink() (datamodel.Link, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Int} } // IntAssembler has similar purpose as Int, but for (you guessed it) @@ -71,27 +71,27 @@ type IntAssembler struct { TypeName string } -func (x IntAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Int} +func (x IntAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Int} } -func (x IntAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Int} +func (x IntAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Int} } func (x IntAssembler) AssignNull() error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: ipld.KindSet_JustNull, ActualKind: ipld.Kind_Int} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: datamodel.KindSet_JustNull, ActualKind: datamodel.Kind_Int} } func (x IntAssembler) AssignBool(bool) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Int} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Int} } func (x IntAssembler) AssignFloat(float64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Int} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Int} } func (x IntAssembler) AssignString(string) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Int} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Int} } func (x IntAssembler) AssignBytes([]byte) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Int} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Int} } -func (x IntAssembler) AssignLink(ipld.Link) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Int} +func (x IntAssembler) AssignLink(datamodel.Link) error { + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Int} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/link.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/link.go index a13836ae..9fb1dff9 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/link.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/link.go @@ -1,7 +1,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // Link can be embedded in a struct to provide all the methods that @@ -19,25 +19,25 @@ type Link struct { TypeName string } -func (Link) Kind() ipld.Kind { - return ipld.Kind_Link +func (Link) Kind() datamodel.Kind { + return datamodel.Kind_Link } -func (x Link) LookupByString(string) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Link} +func (x Link) LookupByString(string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Link} } -func (x Link) LookupByNode(key ipld.Node) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Link} +func (x Link) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Link} } -func (x Link) LookupByIndex(idx int64) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Link} +func (x Link) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Link} } -func (x Link) LookupBySegment(ipld.PathSegment) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: ipld.KindSet_Recursive, ActualKind: ipld.Kind_Link} +func (x Link) LookupBySegment(datamodel.PathSegment) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: datamodel.KindSet_Recursive, ActualKind: datamodel.Kind_Link} } -func (Link) MapIterator() ipld.MapIterator { +func (Link) MapIterator() datamodel.MapIterator { return nil } -func (Link) ListIterator() ipld.ListIterator { +func (Link) ListIterator() datamodel.ListIterator { return nil } func (Link) Length() int64 { @@ -50,19 +50,19 @@ func (Link) IsNull() bool { return false } func (x Link) AsBool() (bool, error) { - return false, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Link} + return false, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Link} } func (x Link) AsInt() (int64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Link} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Link} } func (x Link) AsFloat() (float64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Link} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Link} } func (x Link) AsString() (string, error) { - return "", ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Link} + return "", datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Link} } func (x Link) AsBytes() ([]byte, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Link} + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Link} } // LinkAssembler has similar purpose as Link, but for (you guessed it) @@ -71,27 +71,27 @@ type LinkAssembler struct { TypeName string } -func (x LinkAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_Link} +func (x LinkAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_Link} } -func (x LinkAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Link} +func (x LinkAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Link} } func (x LinkAssembler) AssignNull() error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: ipld.KindSet_JustNull, ActualKind: ipld.Kind_Link} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: datamodel.KindSet_JustNull, ActualKind: datamodel.Kind_Link} } func (x LinkAssembler) AssignBool(bool) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Link} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Link} } func (x LinkAssembler) AssignInt(int64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Link} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Link} } func (x LinkAssembler) AssignFloat(float64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Link} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Link} } func (x LinkAssembler) AssignString(string) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Link} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Link} } func (x LinkAssembler) AssignBytes([]byte) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Link} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Link} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/list.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/list.go index 250830dd..d48f2a29 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/list.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/list.go @@ -1,7 +1,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // List can be embedded in a struct to provide all the methods that @@ -19,16 +19,16 @@ type List struct { TypeName string } -func (List) Kind() ipld.Kind { - return ipld.Kind_List +func (List) Kind() datamodel.Kind { + return datamodel.Kind_List } -func (x List) LookupByString(string) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_List} +func (x List) LookupByString(string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_List} } -func (x List) LookupByNode(key ipld.Node) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_List} +func (x List) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_List} } -func (List) MapIterator() ipld.MapIterator { +func (List) MapIterator() datamodel.MapIterator { return nil } func (List) IsAbsent() bool { @@ -38,22 +38,22 @@ func (List) IsNull() bool { return false } func (x List) AsBool() (bool, error) { - return false, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_List} + return false, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_List} } func (x List) AsInt() (int64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_List} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_List} } func (x List) AsFloat() (float64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_List} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_List} } func (x List) AsString() (string, error) { - return "", ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_List} + return "", datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_List} } func (x List) AsBytes() ([]byte, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_List} + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_List} } -func (x List) AsLink() (ipld.Link, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_List} +func (x List) AsLink() (datamodel.Link, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_List} } // ListAssembler has similar purpose as List, but for (you guessed it) @@ -62,27 +62,27 @@ type ListAssembler struct { TypeName string } -func (x ListAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_List} +func (x ListAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_List} } func (x ListAssembler) AssignNull() error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: ipld.KindSet_JustNull, ActualKind: ipld.Kind_List} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: datamodel.KindSet_JustNull, ActualKind: datamodel.Kind_List} } func (x ListAssembler) AssignBool(bool) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_List} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_List} } func (x ListAssembler) AssignInt(int64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_List} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_List} } func (x ListAssembler) AssignFloat(float64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_List} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_List} } func (x ListAssembler) AssignString(string) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_List} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_List} } func (x ListAssembler) AssignBytes([]byte) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_List} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_List} } -func (x ListAssembler) AssignLink(ipld.Link) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_List} +func (x ListAssembler) AssignLink(datamodel.Link) error { + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_List} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/map.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/map.go index b9958768..d5f7c2c4 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/map.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/map.go @@ -1,7 +1,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // Map can be embedded in a struct to provide all the methods that @@ -19,13 +19,13 @@ type Map struct { TypeName string } -func (Map) Kind() ipld.Kind { - return ipld.Kind_Map +func (Map) Kind() datamodel.Kind { + return datamodel.Kind_Map } -func (x Map) LookupByIndex(idx int64) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Map} +func (x Map) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Map} } -func (Map) ListIterator() ipld.ListIterator { +func (Map) ListIterator() datamodel.ListIterator { return nil } func (Map) IsAbsent() bool { @@ -35,22 +35,22 @@ func (Map) IsNull() bool { return false } func (x Map) AsBool() (bool, error) { - return false, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Map} + return false, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Map} } func (x Map) AsInt() (int64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Map} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Map} } func (x Map) AsFloat() (float64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Map} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Map} } func (x Map) AsString() (string, error) { - return "", ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Map} + return "", datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Map} } func (x Map) AsBytes() ([]byte, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Map} + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Map} } -func (x Map) AsLink() (ipld.Link, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Map} +func (x Map) AsLink() (datamodel.Link, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Map} } // MapAssembler has similar purpose as Map, but for (you guessed it) @@ -59,27 +59,27 @@ type MapAssembler struct { TypeName string } -func (x MapAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_Map} +func (x MapAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_Map} } func (x MapAssembler) AssignNull() error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: ipld.KindSet_JustNull, ActualKind: ipld.Kind_Map} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: datamodel.KindSet_JustNull, ActualKind: datamodel.Kind_Map} } func (x MapAssembler) AssignBool(bool) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_Map} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_Map} } func (x MapAssembler) AssignInt(int64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_Map} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_Map} } func (x MapAssembler) AssignFloat(float64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_Map} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_Map} } func (x MapAssembler) AssignString(string) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: ipld.KindSet_JustString, ActualKind: ipld.Kind_Map} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignString", AppropriateKind: datamodel.KindSet_JustString, ActualKind: datamodel.Kind_Map} } func (x MapAssembler) AssignBytes([]byte) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_Map} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_Map} } -func (x MapAssembler) AssignLink(ipld.Link) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_Map} +func (x MapAssembler) AssignLink(datamodel.Link) error { + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_Map} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/string.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/string.go index a8d9e8fd..8149818f 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/string.go +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/string.go @@ -1,7 +1,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // String can be embedded in a struct to provide all the methods that @@ -19,25 +19,25 @@ type String struct { TypeName string } -func (String) Kind() ipld.Kind { - return ipld.Kind_String +func (String) Kind() datamodel.Kind { + return datamodel.Kind_String } -func (x String) LookupByString(string) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_String} +func (x String) LookupByString(string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByString", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_String} } -func (x String) LookupByNode(key ipld.Node) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_String} +func (x String) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_String} } -func (x String) LookupByIndex(idx int64) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_String} +func (x String) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupByIndex", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_String} } -func (x String) LookupBySegment(ipld.PathSegment) (ipld.Node, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: ipld.KindSet_Recursive, ActualKind: ipld.Kind_String} +func (x String) LookupBySegment(datamodel.PathSegment) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "LookupBySegment", AppropriateKind: datamodel.KindSet_Recursive, ActualKind: datamodel.Kind_String} } -func (String) MapIterator() ipld.MapIterator { +func (String) MapIterator() datamodel.MapIterator { return nil } -func (String) ListIterator() ipld.ListIterator { +func (String) ListIterator() datamodel.ListIterator { return nil } func (String) Length() int64 { @@ -50,19 +50,19 @@ func (String) IsNull() bool { return false } func (x String) AsBool() (bool, error) { - return false, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_String} + return false, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_String} } func (x String) AsInt() (int64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_String} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_String} } func (x String) AsFloat() (float64, error) { - return 0, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_String} + return 0, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_String} } func (x String) AsBytes() ([]byte, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_String} + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_String} } -func (x String) AsLink() (ipld.Link, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_String} +func (x String) AsLink() (datamodel.Link, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AsLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_String} } // StringAssembler has similar purpose as String, but for (you guessed it) @@ -71,27 +71,27 @@ type StringAssembler struct { TypeName string } -func (x StringAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: ipld.KindSet_JustMap, ActualKind: ipld.Kind_String} +func (x StringAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginMap", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: datamodel.Kind_String} } -func (x StringAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return nil, ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: ipld.KindSet_JustList, ActualKind: ipld.Kind_String} +func (x StringAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return nil, datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "BeginList", AppropriateKind: datamodel.KindSet_JustList, ActualKind: datamodel.Kind_String} } func (x StringAssembler) AssignNull() error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: ipld.KindSet_JustNull, ActualKind: ipld.Kind_String} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignNull", AppropriateKind: datamodel.KindSet_JustNull, ActualKind: datamodel.Kind_String} } func (x StringAssembler) AssignBool(bool) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: ipld.KindSet_JustBool, ActualKind: ipld.Kind_String} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBool", AppropriateKind: datamodel.KindSet_JustBool, ActualKind: datamodel.Kind_String} } func (x StringAssembler) AssignInt(int64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: ipld.KindSet_JustInt, ActualKind: ipld.Kind_String} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignInt", AppropriateKind: datamodel.KindSet_JustInt, ActualKind: datamodel.Kind_String} } func (x StringAssembler) AssignFloat(float64) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: ipld.KindSet_JustFloat, ActualKind: ipld.Kind_String} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignFloat", AppropriateKind: datamodel.KindSet_JustFloat, ActualKind: datamodel.Kind_String} } func (x StringAssembler) AssignBytes([]byte) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: ipld.KindSet_JustBytes, ActualKind: ipld.Kind_String} + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignBytes", AppropriateKind: datamodel.KindSet_JustBytes, ActualKind: datamodel.Kind_String} } -func (x StringAssembler) AssignLink(ipld.Link) error { - return ipld.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: ipld.KindSet_JustLink, ActualKind: ipld.Kind_String} +func (x StringAssembler) AssignLink(datamodel.Link) error { + return datamodel.ErrWrongKind{TypeName: x.TypeName, MethodName: "AssignLink", AppropriateKind: datamodel.KindSet_JustLink, ActualKind: datamodel.Kind_String} } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/tmplMixin.txt b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/tmplMixin.txt index 18c78a8e..d74a2542 100644 --- a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/tmplMixin.txt +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/node/mixins/tmplMixin.txt @@ -5,7 +5,7 @@ package mixins import ( - ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/datamodel" ) // @Kind@ can be embedded in a struct to provide all the methods that diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/operations.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/operations.go new file mode 100644 index 00000000..570f7e58 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/operations.go @@ -0,0 +1,13 @@ +package ipld + +import ( + "github.com/ipld/go-ipld-prime/datamodel" +) + +// DeepEqual reports whether x and y are "deeply equal" as IPLD nodes. +// This is similar to reflect.DeepEqual, but based around the Node interface. +// +// This is exactly equivalent to the datamodel.DeepEqual function. +func DeepEqual(x, y Node) bool { + return datamodel.DeepEqual(x, y) +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema.go new file mode 100644 index 00000000..27ba6f24 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema.go @@ -0,0 +1,43 @@ +package ipld + +import ( + "bytes" + "io" + "os" + + "github.com/ipld/go-ipld-prime/schema" + schemadmt "github.com/ipld/go-ipld-prime/schema/dmt" + schemadsl "github.com/ipld/go-ipld-prime/schema/dsl" +) + +// LoadSchemaBytes is a shortcut for LoadSchema for the common case where +// the schema is available as a buffer or a string, such as via go:embed. +func LoadSchemaBytes(src []byte) (*schema.TypeSystem, error) { + return LoadSchema("", bytes.NewReader(src)) +} + +// LoadSchemaBytes is a shortcut for LoadSchema for the common case where +// the schema is a file on disk. +func LoadSchemaFile(path string) (*schema.TypeSystem, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + return LoadSchema(path, f) +} + +// LoadSchema parses an IPLD Schema in its DSL form +// and compiles its types into a standalone TypeSystem. +func LoadSchema(name string, r io.Reader) (*schema.TypeSystem, error) { + sch, err := schemadsl.Parse(name, r) + if err != nil { + return nil, err + } + ts := new(schema.TypeSystem) + ts.Init() + if err := schemadmt.Compile(ts, sch); err != nil { + return nil, err + } + return ts, nil +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/compile.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/compile.go new file mode 100644 index 00000000..f512ccca --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/compile.go @@ -0,0 +1,412 @@ +package schemadmt + +import ( + "fmt" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/schema" +) + +// Compile transforms a schema in DMT form into a TypeSystem. +// +// Note that this API is EXPERIMENTAL and will likely change. +// It is also unfinished and buggy. +func Compile(ts *schema.TypeSystem, node *Schema) error { + // Prelude; probably belongs elsewhere. + { + ts.Accumulate(schema.SpawnBool("Bool")) + ts.Accumulate(schema.SpawnInt("Int")) + ts.Accumulate(schema.SpawnFloat("Float")) + ts.Accumulate(schema.SpawnString("String")) + ts.Accumulate(schema.SpawnBytes("Bytes")) + + ts.Accumulate(schema.SpawnAny("Any")) + + ts.Accumulate(schema.SpawnMap("Map", "String", "Any", false)) + ts.Accumulate(schema.SpawnList("List", "Any", false)) + + // Should be &Any, really. + ts.Accumulate(schema.SpawnLink("Link")) + + // TODO: schema package lacks support? + // ts.Accumulate(schema.SpawnUnit("Null", NullRepr)) + } + + for _, name := range node.Types.Keys { + defn := node.Types.Values[name] + + // TODO: once ./schema supports anonymous/inline types, remove the ts argument. + typ, err := spawnType(ts, name, defn) + if err != nil { + return err + } + ts.Accumulate(typ) + } + + // TODO: if this fails and the user forgot to check Compile's returned error, + // we can leave the TypeSystem in an unfortunate broken state: + // they can obtain types out of the TypeSystem and they are non-nil, + // but trying to use them in any way may result in panics. + // Consider making that less prone to misuse, such as making it illegal to + // call TypeByName until ValidateGraph is happy. + if errs := ts.ValidateGraph(); errs != nil { + // Return the first error. + for _, err := range errs { + return err + } + } + return nil +} + +// Note that the parser and compiler support defaults. We're lacking support in bindnode. +func todoFromImplicitlyFalseBool(b *bool) bool { + if b == nil { + return false + } + return *b +} + +func anonTypeName(nameOrDefn TypeNameOrInlineDefn) string { + if nameOrDefn.TypeName != nil { + return *nameOrDefn.TypeName + } + defn := *nameOrDefn.InlineDefn + switch { + case defn.TypeDefnMap != nil: + defn := defn.TypeDefnMap + return fmt.Sprintf("Map__%s__%s", defn.KeyType, anonTypeName(defn.ValueType)) + case defn.TypeDefnList != nil: + defn := defn.TypeDefnList + return fmt.Sprintf("List__%s", anonTypeName(defn.ValueType)) + case defn.TypeDefnLink != nil: + return anonLinkName(*defn.TypeDefnLink) + default: + panic(fmt.Errorf("%#v", defn)) + } +} + +func anonLinkName(defn TypeDefnLink) string { + if defn.ExpectedType != nil { + return fmt.Sprintf("Link__%s", *defn.ExpectedType) + } + return "Link__Link" +} + +func parseKind(s string) datamodel.Kind { + switch s { + case "map": + return datamodel.Kind_Map + case "list": + return datamodel.Kind_List + case "null": + return datamodel.Kind_Null + case "bool": + return datamodel.Kind_Bool + case "int": + return datamodel.Kind_Int + case "float": + return datamodel.Kind_Float + case "string": + return datamodel.Kind_String + case "bytes": + return datamodel.Kind_Bytes + case "link": + return datamodel.Kind_Link + default: + return datamodel.Kind_Invalid + } +} + +func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (schema.Type, error) { + switch { + // Scalar types without parameters. + case defn.TypeDefnBool != nil: + return schema.SpawnBool(name), nil + case defn.TypeDefnString != nil: + return schema.SpawnString(name), nil + case defn.TypeDefnBytes != nil: + return schema.SpawnBytes(name), nil + case defn.TypeDefnInt != nil: + return schema.SpawnInt(name), nil + case defn.TypeDefnFloat != nil: + return schema.SpawnFloat(name), nil + + case defn.TypeDefnList != nil: + typ := defn.TypeDefnList + tname := "" + if typ.ValueType.TypeName != nil { + tname = *typ.ValueType.TypeName + } else if tname = anonTypeName(typ.ValueType); ts.TypeByName(tname) == nil { + anonDefn := TypeDefn{ + TypeDefnMap: typ.ValueType.InlineDefn.TypeDefnMap, + TypeDefnList: typ.ValueType.InlineDefn.TypeDefnList, + TypeDefnLink: typ.ValueType.InlineDefn.TypeDefnLink, + } + anonType, err := spawnType(ts, tname, anonDefn) + if err != nil { + return nil, err + } + ts.Accumulate(anonType) + } + switch { + case typ.Representation == nil || + typ.Representation.ListRepresentation_List != nil: + // default behavior + default: + return nil, fmt.Errorf("TODO: support other list repr in schema package") + } + return schema.SpawnList(name, + tname, + todoFromImplicitlyFalseBool(typ.ValueNullable), + ), nil + case defn.TypeDefnMap != nil: + typ := defn.TypeDefnMap + tname := "" + if typ.ValueType.TypeName != nil { + tname = *typ.ValueType.TypeName + } else if tname = anonTypeName(typ.ValueType); ts.TypeByName(tname) == nil { + anonDefn := TypeDefn{ + TypeDefnMap: typ.ValueType.InlineDefn.TypeDefnMap, + TypeDefnList: typ.ValueType.InlineDefn.TypeDefnList, + TypeDefnLink: typ.ValueType.InlineDefn.TypeDefnLink, + } + anonType, err := spawnType(ts, tname, anonDefn) + if err != nil { + return nil, err + } + ts.Accumulate(anonType) + } + switch { + case typ.Representation == nil || + typ.Representation.MapRepresentation_Map != nil: + // default behavior + case typ.Representation.MapRepresentation_Stringpairs != nil: + return nil, fmt.Errorf("TODO: support stringpairs map repr in schema package") + default: + return nil, fmt.Errorf("TODO: support other map repr in schema package") + } + return schema.SpawnMap(name, + typ.KeyType, + tname, + todoFromImplicitlyFalseBool(typ.ValueNullable), + ), nil + case defn.TypeDefnStruct != nil: + typ := defn.TypeDefnStruct + var fields []schema.StructField + for _, fname := range typ.Fields.Keys { + field := typ.Fields.Values[fname] + tname := "" + if field.Type.TypeName != nil { + tname = *field.Type.TypeName + } else if tname = anonTypeName(field.Type); ts.TypeByName(tname) == nil { + // Note that TypeDefn and InlineDefn aren't the same enum. + anonDefn := TypeDefn{ + TypeDefnMap: field.Type.InlineDefn.TypeDefnMap, + TypeDefnList: field.Type.InlineDefn.TypeDefnList, + TypeDefnLink: field.Type.InlineDefn.TypeDefnLink, + } + anonType, err := spawnType(ts, tname, anonDefn) + if err != nil { + return nil, err + } + ts.Accumulate(anonType) + } + fields = append(fields, schema.SpawnStructField(fname, + tname, + todoFromImplicitlyFalseBool(field.Optional), + todoFromImplicitlyFalseBool(field.Nullable), + )) + } + var repr schema.StructRepresentation + switch { + case typ.Representation.StructRepresentation_Map != nil: + rp := typ.Representation.StructRepresentation_Map + if rp.Fields == nil { + repr = schema.SpawnStructRepresentationMap2(nil, nil) + break + } + renames := make(map[string]string, len(rp.Fields.Keys)) + implicits := make(map[string]schema.ImplicitValue, len(rp.Fields.Keys)) + for _, name := range rp.Fields.Keys { + details := rp.Fields.Values[name] + if details.Rename != nil { + renames[name] = *details.Rename + } + if imp := details.Implicit; imp != nil { + var sumVal schema.ImplicitValue + switch { + case imp.Bool != nil: + sumVal = schema.ImplicitValue_Bool(*imp.Bool) + case imp.String != nil: + sumVal = schema.ImplicitValue_String(*imp.String) + case imp.Int != nil: + sumVal = schema.ImplicitValue_Int(*imp.Int) + default: + panic("TODO: implicit value kind") + } + implicits[name] = sumVal + } + + } + repr = schema.SpawnStructRepresentationMap2(renames, implicits) + case typ.Representation.StructRepresentation_Tuple != nil: + rp := typ.Representation.StructRepresentation_Tuple + if rp.FieldOrder == nil { + repr = schema.SpawnStructRepresentationTuple() + break + } + return nil, fmt.Errorf("TODO: support for tuples with field orders in the schema package") + case typ.Representation.StructRepresentation_Stringjoin != nil: + join := typ.Representation.StructRepresentation_Stringjoin.Join + if join == "" { + return nil, fmt.Errorf("stringjoin has empty join value") + } + repr = schema.SpawnStructRepresentationStringjoin(join) + default: + return nil, fmt.Errorf("TODO: support other struct repr in schema package") + } + return schema.SpawnStruct(name, + fields, + repr, + ), nil + case defn.TypeDefnUnion != nil: + typ := defn.TypeDefnUnion + var members []schema.TypeName + for _, member := range typ.Members { + if member.TypeName != nil { + members = append(members, *member.TypeName) + } else { + tname := anonLinkName(*member.UnionMemberInlineDefn.TypeDefnLink) + members = append(members, tname) + if ts.TypeByName(tname) == nil { + anonDefn := TypeDefn{ + TypeDefnLink: member.UnionMemberInlineDefn.TypeDefnLink, + } + anonType, err := spawnType(ts, tname, anonDefn) + if err != nil { + return nil, err + } + ts.Accumulate(anonType) + } + } + } + remainingMembers := make(map[string]bool) + for _, memberName := range members { + remainingMembers[memberName] = true + } + validMember := func(memberName string) error { + switch remaining, known := remainingMembers[memberName]; { + case remaining: + remainingMembers[memberName] = false + return nil + case !known: + return fmt.Errorf("%q is not a valid member of union %q", memberName, name) + default: + return fmt.Errorf("%q is duplicate in the union repr of %q", memberName, name) + } + } + + var repr schema.UnionRepresentation + switch { + case typ.Representation.UnionRepresentation_Kinded != nil: + rp := typ.Representation.UnionRepresentation_Kinded + table := make(map[datamodel.Kind]schema.TypeName, len(rp.Keys)) + for _, kindStr := range rp.Keys { + kind := parseKind(kindStr) + member := rp.Values[kindStr] + switch { + case member.TypeName != nil: + memberName := *member.TypeName + validMember(memberName) + table[kind] = memberName + case member.UnionMemberInlineDefn != nil: + tname := anonLinkName(*member.UnionMemberInlineDefn.TypeDefnLink) + validMember(tname) + table[kind] = tname + } + } + repr = schema.SpawnUnionRepresentationKinded(table) + case typ.Representation.UnionRepresentation_Keyed != nil: + rp := typ.Representation.UnionRepresentation_Keyed + table := make(map[string]schema.TypeName, len(rp.Keys)) + for _, key := range rp.Keys { + member := rp.Values[key] + switch { + case member.TypeName != nil: + memberName := *member.TypeName + validMember(memberName) + table[key] = memberName + case member.UnionMemberInlineDefn != nil: + tname := anonLinkName(*member.UnionMemberInlineDefn.TypeDefnLink) + validMember(tname) + table[key] = tname + } + } + repr = schema.SpawnUnionRepresentationKeyed(table) + case typ.Representation.UnionRepresentation_StringPrefix != nil: + prefixes := typ.Representation.UnionRepresentation_StringPrefix.Prefixes + for _, key := range prefixes.Keys { + validMember(prefixes.Values[key]) + } + repr = schema.SpawnUnionRepresentationStringprefix("", prefixes.Values) + default: + return nil, fmt.Errorf("TODO: support other union repr in schema package") + } + for memberName, remaining := range remainingMembers { + if remaining { + return nil, fmt.Errorf("%q is not present in the union repr of %q", memberName, name) + } + } + return schema.SpawnUnion(name, + members, + repr, + ), nil + case defn.TypeDefnEnum != nil: + typ := defn.TypeDefnEnum + var repr schema.EnumRepresentation + + // TODO: we should probably also reject duplicates. + validMember := func(name string) bool { + for _, memberName := range typ.Members { + if memberName == name { + return true + } + } + return false + } + switch { + case typ.Representation.EnumRepresentation_String != nil: + rp := typ.Representation.EnumRepresentation_String + for memberName := range rp.Values { + if !validMember(memberName) { + return nil, fmt.Errorf("%q is not a valid member of enum %q", memberName, name) + } + } + repr = schema.EnumRepresentation_String(rp.Values) + case typ.Representation.EnumRepresentation_Int != nil: + rp := typ.Representation.EnumRepresentation_Int + for memberName := range rp.Values { + if !validMember(memberName) { + return nil, fmt.Errorf("%q is not a valid member of enum %q", memberName, name) + } + } + repr = schema.EnumRepresentation_Int(rp.Values) + default: + return nil, fmt.Errorf("TODO: support other enum repr in schema package") + } + return schema.SpawnEnum(name, + typ.Members, + repr, + ), nil + case defn.TypeDefnLink != nil: + typ := defn.TypeDefnLink + if typ.ExpectedType == nil { + return schema.SpawnLink(name), nil + } + return schema.SpawnLinkReference(name, *typ.ExpectedType), nil + case defn.TypeDefnAny != nil: + return schema.SpawnAny(name), nil + default: + panic(fmt.Errorf("%#v", defn)) + } +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/export.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/export.go new file mode 100644 index 00000000..222f0cea --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/export.go @@ -0,0 +1,9 @@ +//go:build schemadmtgen + +package schemadmt + +import "github.com/ipld/go-ipld-prime/schema" + +func InternalTypeSystem() *schema.TypeSystem { + return &schemaTypeSystem +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/schema.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/schema.go new file mode 100644 index 00000000..f8001c28 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/schema.go @@ -0,0 +1,442 @@ +package schemadmt + +import ( + "fmt" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/bindnode" + "github.com/ipld/go-ipld-prime/schema" +) + +// This schema follows https://ipld.io/specs/schemas/schema-schema.ipldsch. + +var Type struct { + Schema schema.TypedPrototype +} + +//go:generate go run -tags=schemadmtgen gen.go + +var schemaTypeSystem schema.TypeSystem + +func init() { + var ts schema.TypeSystem + ts.Init() + + // I've elided all references to Advancedlayouts stuff for the moment. + // (Not because it's particularly hard or problematic; I just want to draw a slightly smaller circle first.) + + // Prelude + ts.Accumulate(schema.SpawnString("String")) + ts.Accumulate(schema.SpawnBool("Bool")) + ts.Accumulate(schema.SpawnInt("Int")) + ts.Accumulate(schema.SpawnFloat("Float")) + ts.Accumulate(schema.SpawnBytes("Bytes")) + + // Schema-schema! + // In the same order as the spec's ipldsch file. + // Note that ADL stuff is excluded for now, as per above. + ts.Accumulate(schema.SpawnString("TypeName")) + ts.Accumulate(schema.SpawnStruct("Schema", + []schema.StructField{ + schema.SpawnStructField("types", "Map__TypeName__TypeDefn", false, false), + // also: `advanced AdvancedDataLayoutMap`, but as commented above, we'll pursue this later. + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnMap("Map__TypeName__TypeDefn", + "TypeName", "TypeDefn", false, + )) + ts.Accumulate(schema.SpawnUnion("TypeDefn", + []schema.TypeName{ + "TypeDefnBool", + "TypeDefnString", + "TypeDefnBytes", + "TypeDefnInt", + "TypeDefnFloat", + "TypeDefnMap", + "TypeDefnList", + "TypeDefnLink", + "TypeDefnUnion", + "TypeDefnStruct", + "TypeDefnEnum", + "TypeDefnUnit", + "TypeDefnAny", + "TypeDefnCopy", + }, + // TODO: spec uses inline repr. + schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{ + "bool": "TypeDefnBool", + "string": "TypeDefnString", + "bytes": "TypeDefnBytes", + "int": "TypeDefnInt", + "float": "TypeDefnFloat", + "map": "TypeDefnMap", + "list": "TypeDefnList", + "link": "TypeDefnLink", + "union": "TypeDefnUnion", + "struct": "TypeDefnStruct", + "enum": "TypeDefnEnum", + "unit": "TypeDefnUnit", + "any": "TypeDefnAny", + "copy": "TypeDefnCopy", + }), + )) + ts.Accumulate(schema.SpawnUnion("TypeNameOrInlineDefn", + []schema.TypeName{ + "TypeName", + "InlineDefn", + }, + schema.SpawnUnionRepresentationKinded(map[datamodel.Kind]schema.TypeName{ + datamodel.Kind_String: "TypeName", + datamodel.Kind_Map: "InlineDefn", + }), + )) + ts.Accumulate(schema.SpawnUnion("InlineDefn", + []schema.TypeName{ + "TypeDefnMap", + "TypeDefnList", + "TypeDefnLink", + }, + schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{ + "map": "TypeDefnMap", + "list": "TypeDefnList", + "link": "TypeDefnLink", + }), + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnBool", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnString", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnBytes", + []schema.StructField{}, + // No BytesRepresentation, since we omit ADL stuff. + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnInt", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnFloat", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnMap", + []schema.StructField{ + schema.SpawnStructField("keyType", "TypeName", false, false), + schema.SpawnStructField("valueType", "TypeNameOrInlineDefn", false, false), + schema.SpawnStructField("valueNullable", "Bool", true, false), // TODO: wants to use the "implicit" feature, but not supported yet + schema.SpawnStructField("representation", "MapRepresentation", true, false), // XXXXXX + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnUnion("MapRepresentation", + []schema.TypeName{ + "MapRepresentation_Map", + "MapRepresentation_Stringpairs", + "MapRepresentation_Listpairs", + }, + schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{ + "map": "MapRepresentation_Map", + "stringpairs": "MapRepresentation_Stringpairs", + "listpairs": "MapRepresentation_Listpairs", + }), + )) + ts.Accumulate(schema.SpawnStruct("MapRepresentation_Map", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("MapRepresentation_Stringpairs", + []schema.StructField{ + schema.SpawnStructField("innerDelim", "String", false, false), + schema.SpawnStructField("entryDelim", "String", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("MapRepresentation_Listpairs", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnList", + []schema.StructField{ + schema.SpawnStructField("valueType", "TypeNameOrInlineDefn", false, false), + schema.SpawnStructField("valueNullable", "Bool", true, false), // TODO: wants to use the "implicit" feature, but not supported yet + schema.SpawnStructField("representation", "ListRepresentation", true, false), // XXXXXX + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnUnion("ListRepresentation", + []schema.TypeName{ + "ListRepresentation_List", + }, + schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{ + "list": "ListRepresentation_List", + }), + )) + ts.Accumulate(schema.SpawnStruct("ListRepresentation_List", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnUnion", + []schema.StructField{ + // n.b. we could conceivably allow TypeNameOrInlineDefn here rather than just TypeName. but... we'd rather not: imagine what that means about the type-level behavior of the union: the name munge for the anonymous type would suddenly become load-bearing. would rather not. + schema.SpawnStructField("members", "List__UnionMember", false, false), + schema.SpawnStructField("representation", "UnionRepresentation", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnList("List__UnionMember", + "UnionMember", false, + )) + ts.Accumulate(schema.SpawnUnion("UnionMember", + []schema.TypeName{ + "TypeName", + "UnionMemberInlineDefn", + }, + schema.SpawnUnionRepresentationKinded(map[datamodel.Kind]schema.TypeName{ + datamodel.Kind_String: "TypeName", + datamodel.Kind_Map: "UnionMemberInlineDefn", + }), + )) + ts.Accumulate(schema.SpawnUnion("UnionMemberInlineDefn", + []schema.TypeName{ + "TypeDefnLink", + }, + schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{ + "link": "TypeDefnLink", + }), + )) + ts.Accumulate(schema.SpawnList("List__TypeName", // todo: this is a slight hack: should be an anon inside TypeDefnUnion.members. + "TypeName", false, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnLink", + []schema.StructField{ + schema.SpawnStructField("expectedType", "TypeName", true, false), // todo: this uses an implicit with a value of 'any' in the schema-schema, but that's been questioned before. maybe it should simply be an optional. + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnUnion("UnionRepresentation", + []schema.TypeName{ + "UnionRepresentation_Kinded", + "UnionRepresentation_Keyed", + "UnionRepresentation_Envelope", + "UnionRepresentation_Inline", + "UnionRepresentation_StringPrefix", + "UnionRepresentation_BytesPrefix", + }, + schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{ + "kinded": "UnionRepresentation_Kinded", + "keyed": "UnionRepresentation_Keyed", + "envelope": "UnionRepresentation_Envelope", + "inline": "UnionRepresentation_Inline", + "stringprefix": "UnionRepresentation_StringPrefix", + "byteprefix": "UnionRepresentation_BytesPrefix", + }), + )) + ts.Accumulate(schema.SpawnMap("UnionRepresentation_Kinded", + "RepresentationKind", "UnionMember", false, + )) + ts.Accumulate(schema.SpawnMap("UnionRepresentation_Keyed", + "String", "UnionMember", false, + )) + ts.Accumulate(schema.SpawnMap("Map__String__UnionMember", + "TypeName", "TypeDefn", false, + )) + ts.Accumulate(schema.SpawnStruct("UnionRepresentation_Envelope", + []schema.StructField{ + schema.SpawnStructField("discriminantKey", "String", false, false), + schema.SpawnStructField("contentKey", "String", false, false), + schema.SpawnStructField("discriminantTable", "Map__String__UnionMember", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("UnionRepresentation_Inline", + []schema.StructField{ + schema.SpawnStructField("discriminantKey", "String", false, false), + schema.SpawnStructField("discriminantTable", "Map__String__TypeName", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("UnionRepresentation_StringPrefix", + []schema.StructField{ + schema.SpawnStructField("prefixes", "Map__String__TypeName", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("UnionRepresentation_BytesPrefix", + []schema.StructField{ + schema.SpawnStructField("prefixes", "Map__HexString__TypeName", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnMap("Map__HexString__TypeName", + "String", "TypeName", false, + )) + ts.Accumulate(schema.SpawnString("HexString")) + ts.Accumulate(schema.SpawnMap("Map__String__TypeName", + "String", "TypeName", false, + )) + ts.Accumulate(schema.SpawnMap("Map__TypeName__Int", + "String", "Int", false, + )) + ts.Accumulate(schema.SpawnString("RepresentationKind")) // todo: RepresentationKind is supposed to be an enum, but we're puting it to a string atm. + ts.Accumulate(schema.SpawnStruct("TypeDefnStruct", + []schema.StructField{ + schema.SpawnStructField("fields", "Map__FieldName__StructField", false, false), // todo: dodging inline defn's again. + schema.SpawnStructField("representation", "StructRepresentation", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnMap("Map__FieldName__StructField", + "FieldName", "StructField", false, + )) + ts.Accumulate(schema.SpawnString("FieldName")) + ts.Accumulate(schema.SpawnStruct("StructField", + []schema.StructField{ + schema.SpawnStructField("type", "TypeNameOrInlineDefn", false, false), + schema.SpawnStructField("optional", "Bool", true, false), // todo: wants to use the "implicit" feature, but not supported yet + schema.SpawnStructField("nullable", "Bool", true, false), // todo: wants to use the "implicit" feature, but not supported yet + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnUnion("StructRepresentation", + []schema.TypeName{ + "StructRepresentation_Map", + "StructRepresentation_Tuple", + "StructRepresentation_Stringpairs", + "StructRepresentation_Stringjoin", + "StructRepresentation_Listpairs", + }, + schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{ + "map": "StructRepresentation_Map", + "tuple": "StructRepresentation_Tuple", + "stringpairs": "StructRepresentation_Stringpairs", + "stringjoin": "StructRepresentation_Stringjoin", + "listpairs": "StructRepresentation_Listpairs", + }), + )) + ts.Accumulate(schema.SpawnStruct("StructRepresentation_Map", + []schema.StructField{ + schema.SpawnStructField("fields", "Map__FieldName__StructRepresentation_Map_FieldDetails", true, false), // todo: dodging inline defn's again. + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnMap("Map__FieldName__StructRepresentation_Map_FieldDetails", + "FieldName", "StructRepresentation_Map_FieldDetails", false, + )) + ts.Accumulate(schema.SpawnStruct("StructRepresentation_Map_FieldDetails", + []schema.StructField{ + schema.SpawnStructField("rename", "String", true, false), + schema.SpawnStructField("implicit", "AnyScalar", true, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("StructRepresentation_Tuple", + []schema.StructField{ + schema.SpawnStructField("fieldOrder", "List__FieldName", true, false), // todo: dodging inline defn's again. + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnList("List__FieldName", + "FieldName", false, + )) + ts.Accumulate(schema.SpawnStruct("StructRepresentation_Stringpairs", + []schema.StructField{ + schema.SpawnStructField("innerDelim", "String", false, false), + schema.SpawnStructField("entryDelim", "String", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("StructRepresentation_Stringjoin", + []schema.StructField{ + schema.SpawnStructField("join", "String", false, false), // review: "delim" would seem more consistent with others -- but this is currently what the schema-schema says. + schema.SpawnStructField("fieldOrder", "List__FieldName", true, false), // todo: dodging inline defn's again. + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("StructRepresentation_Listpairs", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnEnum", + []schema.StructField{ + schema.SpawnStructField("members", "List__EnumMember", false, false), + schema.SpawnStructField("representation", "EnumRepresentation", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("Unit", // todo: we should formalize the introdution of unit as first class type kind. + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnList("List__EnumMember", + "EnumMember", false, + )) + ts.Accumulate(schema.SpawnString("EnumMember")) + ts.Accumulate(schema.SpawnUnion("EnumRepresentation", + []schema.TypeName{ + "EnumRepresentation_String", + "EnumRepresentation_Int", + }, + schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{ + "string": "EnumRepresentation_String", + "int": "EnumRepresentation_Int", + }), + )) + ts.Accumulate(schema.SpawnMap("EnumRepresentation_String", + "EnumMember", "String", false, + )) + ts.Accumulate(schema.SpawnMap("EnumRepresentation_Int", + "EnumMember", "Int", false, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnUnit", + []schema.StructField{ + schema.SpawnStructField("representation", "UnitRepresentation", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnString("UnitRepresentation")) // TODO: enum + ts.Accumulate(schema.SpawnStruct("TypeDefnAny", + []schema.StructField{}, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnStruct("TypeDefnCopy", + []schema.StructField{ + schema.SpawnStructField("fromType", "TypeName", false, false), + }, + schema.StructRepresentation_Map{}, + )) + ts.Accumulate(schema.SpawnUnion("AnyScalar", + []schema.TypeName{ + "Bool", + "String", + "Bytes", + "Int", + "Float", + }, + schema.SpawnUnionRepresentationKinded(map[datamodel.Kind]schema.TypeName{ + datamodel.Kind_Bool: "Bool", + datamodel.Kind_String: "String", + datamodel.Kind_Bytes: "Bytes", + datamodel.Kind_Int: "Int", + datamodel.Kind_Float: "Float", + }), + )) + + if errs := ts.ValidateGraph(); errs != nil { + for _, err := range errs { + fmt.Printf("- %s\n", err) + } + panic("not happening") + } + + schemaTypeSystem = ts + + Type.Schema = bindnode.Prototype( + (*Schema)(nil), + schemaTypeSystem.TypeByName("Schema"), + ) +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/types.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/types.go new file mode 100644 index 00000000..61c773f6 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dmt/types.go @@ -0,0 +1,215 @@ +package schemadmt + +type Schema struct { + Types Map__TypeName__TypeDefn +} +type Map__TypeName__TypeDefn struct { + Keys []string + Values map[string]TypeDefn +} +type TypeDefn struct { + TypeDefnBool *TypeDefnBool + TypeDefnString *TypeDefnString + TypeDefnBytes *TypeDefnBytes + TypeDefnInt *TypeDefnInt + TypeDefnFloat *TypeDefnFloat + TypeDefnMap *TypeDefnMap + TypeDefnList *TypeDefnList + TypeDefnLink *TypeDefnLink + TypeDefnUnion *TypeDefnUnion + TypeDefnStruct *TypeDefnStruct + TypeDefnEnum *TypeDefnEnum + TypeDefnUnit *TypeDefnUnit + TypeDefnAny *TypeDefnAny + TypeDefnCopy *TypeDefnCopy +} +type TypeNameOrInlineDefn struct { + TypeName *string + InlineDefn *InlineDefn +} +type InlineDefn struct { + TypeDefnMap *TypeDefnMap + TypeDefnList *TypeDefnList + TypeDefnLink *TypeDefnLink +} +type TypeDefnBool struct { +} +type TypeDefnString struct { +} +type TypeDefnBytes struct { +} +type TypeDefnInt struct { +} +type TypeDefnFloat struct { +} +type TypeDefnMap struct { + KeyType string + ValueType TypeNameOrInlineDefn + ValueNullable *bool + Representation *MapRepresentation +} +type MapRepresentation struct { + MapRepresentation_Map *MapRepresentation_Map + MapRepresentation_Stringpairs *MapRepresentation_Stringpairs + MapRepresentation_Listpairs *MapRepresentation_Listpairs +} +type MapRepresentation_Map struct { +} +type MapRepresentation_Stringpairs struct { + InnerDelim string + EntryDelim string +} +type MapRepresentation_Listpairs struct { +} +type TypeDefnList struct { + ValueType TypeNameOrInlineDefn + ValueNullable *bool + Representation *ListRepresentation +} +type ListRepresentation struct { + ListRepresentation_List *ListRepresentation_List +} +type ListRepresentation_List struct { +} +type TypeDefnUnion struct { + Members List__UnionMember + Representation UnionRepresentation +} +type List__UnionMember []UnionMember +type UnionMember struct { + TypeName *string + UnionMemberInlineDefn *UnionMemberInlineDefn +} +type UnionMemberInlineDefn struct { + TypeDefnLink *TypeDefnLink +} +type List__TypeName []string +type TypeDefnLink struct { + ExpectedType *string +} +type UnionRepresentation struct { + UnionRepresentation_Kinded *UnionRepresentation_Kinded + UnionRepresentation_Keyed *UnionRepresentation_Keyed + UnionRepresentation_Envelope *UnionRepresentation_Envelope + UnionRepresentation_Inline *UnionRepresentation_Inline + UnionRepresentation_StringPrefix *UnionRepresentation_StringPrefix + UnionRepresentation_BytesPrefix *UnionRepresentation_BytesPrefix +} +type UnionRepresentation_Kinded struct { + Keys []string + Values map[string]UnionMember +} +type UnionRepresentation_Keyed struct { + Keys []string + Values map[string]UnionMember +} +type Map__String__UnionMember struct { + Keys []string + Values map[string]TypeDefn +} +type UnionRepresentation_Envelope struct { + DiscriminantKey string + ContentKey string + DiscriminantTable Map__String__UnionMember +} +type UnionRepresentation_Inline struct { + DiscriminantKey string + DiscriminantTable Map__String__TypeName +} +type UnionRepresentation_StringPrefix struct { + Prefixes Map__String__TypeName +} +type UnionRepresentation_BytesPrefix struct { + Prefixes Map__HexString__TypeName +} +type Map__HexString__TypeName struct { + Keys []string + Values map[string]string +} +type Map__String__TypeName struct { + Keys []string + Values map[string]string +} +type Map__TypeName__Int struct { + Keys []string + Values map[string]int +} +type TypeDefnStruct struct { + Fields Map__FieldName__StructField + Representation StructRepresentation +} +type Map__FieldName__StructField struct { + Keys []string + Values map[string]StructField +} +type StructField struct { + Type TypeNameOrInlineDefn + Optional *bool + Nullable *bool +} +type StructRepresentation struct { + StructRepresentation_Map *StructRepresentation_Map + StructRepresentation_Tuple *StructRepresentation_Tuple + StructRepresentation_Stringpairs *StructRepresentation_Stringpairs + StructRepresentation_Stringjoin *StructRepresentation_Stringjoin + StructRepresentation_Listpairs *StructRepresentation_Listpairs +} +type StructRepresentation_Map struct { + Fields *Map__FieldName__StructRepresentation_Map_FieldDetails +} +type Map__FieldName__StructRepresentation_Map_FieldDetails struct { + Keys []string + Values map[string]StructRepresentation_Map_FieldDetails +} +type StructRepresentation_Map_FieldDetails struct { + Rename *string + Implicit *AnyScalar +} +type StructRepresentation_Tuple struct { + FieldOrder *List__FieldName +} +type List__FieldName []string +type StructRepresentation_Stringpairs struct { + InnerDelim string + EntryDelim string +} +type StructRepresentation_Stringjoin struct { + Join string + FieldOrder *List__FieldName +} +type StructRepresentation_Listpairs struct { +} +type TypeDefnEnum struct { + Members List__EnumMember + Representation EnumRepresentation +} +type Unit struct { +} +type List__EnumMember []string +type EnumRepresentation struct { + EnumRepresentation_String *EnumRepresentation_String + EnumRepresentation_Int *EnumRepresentation_Int +} +type EnumRepresentation_String struct { + Keys []string + Values map[string]string +} +type EnumRepresentation_Int struct { + Keys []string + Values map[string]int +} +type TypeDefnUnit struct { + Representation string +} +type TypeDefnAny struct { +} +type TypeDefnCopy struct { + FromType string +} +type AnyScalar struct { + Bool *bool + String *string + Bytes *[]uint8 + Int *int + Float *float64 +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dsl/parse.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dsl/parse.go new file mode 100644 index 00000000..b1cf2e0b --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/dsl/parse.go @@ -0,0 +1,734 @@ +package schemadsl + +import ( + "bufio" + "bytes" + "fmt" + "io" + "os" + "reflect" + "strconv" + "strings" + + dmt "github.com/ipld/go-ipld-prime/schema/dmt" +) + +var globalTrue = true + +// TODO: fuzz testing + +func ParseBytes(src []byte) (*dmt.Schema, error) { + return Parse("", bytes.NewReader(src)) +} + +func ParseFile(path string) (*dmt.Schema, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + return Parse(path, f) +} + +func Parse(name string, r io.Reader) (*dmt.Schema, error) { + p := &parser{ + path: name, + br: bufio.NewReader(r), + line: 1, + col: 1, + } + + sch := &dmt.Schema{} + sch.Types.Values = make(map[string]dmt.TypeDefn) + + for { + tok, err := p.consumeToken() + if err == io.EOF { + break + } + + switch tok { + case "type": + name, err := p.consumeName() + if err != nil { + return nil, err + } + defn, err := p.typeDefn() + if err != nil { + return nil, err + } + mapAppend(&sch.Types, name, defn) + case "advanced": + return nil, p.errf("TODO: advanced") + default: + return nil, p.errf("unexpected token: %q", tok) + } + } + return sch, nil +} + +func mapAppend(mapPtr, k, v interface{}) { + // TODO: delete with generics + // TODO: error on dupes + + mval := reflect.ValueOf(mapPtr).Elem() + kval := reflect.ValueOf(k) + vval := reflect.ValueOf(v) + + keys := mval.FieldByName("Keys") + keys.Set(reflect.Append(keys, kval)) + + values := mval.FieldByName("Values") + if values.IsNil() { + values.Set(reflect.MakeMap(values.Type())) + } + values.SetMapIndex(kval, vval) +} + +type parser struct { + path string + br *bufio.Reader + + peekedToken string + + line, col int +} + +func (p *parser) forwardError(err error) error { + var prefix string + if p.path != "" { + prefix = p.path + ":" + } + return fmt.Errorf("%s%d:%d: %s", prefix, p.line, p.col, err) +} + +func (p *parser) errf(format string, args ...interface{}) error { + return p.forwardError(fmt.Errorf(format, args...)) +} + +func (p *parser) consumeToken() (string, error) { + if tok := p.peekedToken; tok != "" { + p.peekedToken = "" + return tok, nil + } + for { + // TODO: use runes for better unicode support + b, err := p.br.ReadByte() + if err == io.EOF { + return "", err // TODO: ErrUnexpectedEOF? + } + if err != nil { + return "", p.forwardError(err) + } + p.col++ + switch b { + case ' ', '\t', '\r': // skip whitespace + continue + case '\n': // skip newline + // TODO: should we require a newline after each type def, struct field, etc? + p.line++ + p.col = 1 + continue + case '"': // quoted string + quoted, err := p.br.ReadString('"') + if err != nil { + return "", p.forwardError(err) + } + return "\"" + quoted, nil + case '{', '}', '[', ']', '(', ')', ':', '&': // simple token + return string(b), nil + case '#': // comment + _, err := p.br.ReadString('\n') + if err != nil { + return "", p.forwardError(err) + } + // tokenize the newline + if err := p.br.UnreadByte(); err != nil { + panic(err) // should never happen + } + continue + default: // string token or name + var sb strings.Builder + sb.WriteByte(b) + for { + b, err := p.br.ReadByte() + if err == io.EOF { + // Token ends at the end of the whole input. + return sb.String(), nil + } + if err != nil { + return "", p.forwardError(err) + } + // TODO: should probably allow unicode letters and numbers, like Go? + switch { + case b >= 'a' && b <= 'z', b >= 'A' && b <= 'Z': + case b >= '0' && b <= '9': + case b == '_': + default: + if err := p.br.UnreadByte(); err != nil { + panic(err) // should never happen + } + return sb.String(), nil + } + sb.WriteByte(b) + } + } + } +} + +func (p *parser) consumePeeked() { + if p.peekedToken == "" { + panic("consumePeeked requires a peeked token to be present") + } + p.peekedToken = "" +} + +func (p *parser) peekToken() (string, error) { + if tok := p.peekedToken; tok != "" { + return tok, nil + } + tok, err := p.consumeToken() + if err != nil { + if err == io.EOF { + // peekToken is often used when a token is optional. + // If we hit io.EOF, that's not an error. + // TODO: consider making peekToken just not return an error? + return "", nil + } + return "", err + } + p.peekedToken = tok + return tok, nil +} + +func (p *parser) consumeName() (string, error) { + tok, err := p.consumeToken() + if err != nil { + return "", err + } + switch tok { + case "\"", "{", "}", "[", "]", "(", ")", ":": + return "", p.errf("expected a name, got %q", tok) + } + if tok[0] == '"' { + return "", p.errf("expected a name, got string %s", tok) + } + return tok, nil +} + +func (p *parser) consumeString() (string, error) { + tok, err := p.consumeToken() + if err != nil { + return "", err + } + if tok[0] != '"' { + return "", p.errf("expected a string, got %q", tok) + } + // Unquote, too. + return tok[1 : len(tok)-1], nil +} + +func (p *parser) consumeStringMap() (map[string]string, error) { + result := map[string]string{} +loop: + for { + tok, err := p.peekToken() + if err != nil { + return result, err + } + switch tok { + case "{": + p.consumePeeked() + case "}": + p.consumePeeked() + break loop + default: + key, err := p.consumeName() + if err != nil { + return result, err + } + value, err := p.consumeString() + if err != nil { + return result, err + } + result[key] = value + } + } + return result, nil +} + +func (p *parser) consumeRequired(tok string) error { + got, err := p.consumeToken() + if err != nil { + return err + } + if got != tok { + return p.errf("expected %q, got %q", tok, got) + } + return nil +} + +func (p *parser) typeDefn() (dmt.TypeDefn, error) { + var defn dmt.TypeDefn + kind, err := p.consumeToken() + if err != nil { + return defn, err + } + + switch kind { + case "struct": + if err := p.consumeRequired("{"); err != nil { + return defn, err + } + defn.TypeDefnStruct, err = p.typeStruct() + case "union": + if err := p.consumeRequired("{"); err != nil { + return defn, err + } + defn.TypeDefnUnion, err = p.typeUnion() + case "enum": + if err := p.consumeRequired("{"); err != nil { + return defn, err + } + defn.TypeDefnEnum, err = p.typeEnum() + case "bool": + defn.TypeDefnBool = &dmt.TypeDefnBool{} + case "bytes": + defn.TypeDefnBytes = &dmt.TypeDefnBytes{} + case "float": + defn.TypeDefnFloat = &dmt.TypeDefnFloat{} + case "int": + defn.TypeDefnInt = &dmt.TypeDefnInt{} + case "link": + defn.TypeDefnLink = &dmt.TypeDefnLink{} + case "any": + defn.TypeDefnAny = &dmt.TypeDefnAny{} + case "&": + target, err := p.consumeName() + if err != nil { + return defn, err + } + defn.TypeDefnLink = &dmt.TypeDefnLink{ExpectedType: &target} + case "string": + defn.TypeDefnString = &dmt.TypeDefnString{} + case "{": + defn.TypeDefnMap, err = p.typeMap() + case "[": + defn.TypeDefnList, err = p.typeList() + case "=": + from, err := p.consumeName() + if err != nil { + return defn, err + } + defn.TypeDefnCopy = &dmt.TypeDefnCopy{FromType: from} + default: + err = p.errf("unknown type keyword: %q", kind) + } + + return defn, err +} + +func (p *parser) typeStruct() (*dmt.TypeDefnStruct, error) { + repr := &dmt.StructRepresentation_Map{} + repr.Fields = &dmt.Map__FieldName__StructRepresentation_Map_FieldDetails{} + + defn := &dmt.TypeDefnStruct{} + for { + tok, err := p.consumeToken() + if err != nil { + return nil, err + } + + if tok == "}" { + break + } + name := tok + + var field dmt.StructField + loop: + for { + tok, err := p.peekToken() + if err != nil { + return nil, err + } + switch tok { + case "optional": + if field.Optional != nil { + return nil, p.errf("multiple optional keywords") + } + field.Optional = &globalTrue + p.consumePeeked() + case "nullable": + if field.Nullable != nil { + return nil, p.errf("multiple nullable keywords") + } + field.Nullable = &globalTrue + p.consumePeeked() + default: + var err error + field.Type, err = p.typeNameOrInlineDefn() + if err != nil { + return nil, err + } + break loop + } + } + tok, err = p.peekToken() + if err != nil { + return nil, err + } + if tok == "(" { + details := dmt.StructRepresentation_Map_FieldDetails{} + p.consumePeeked() + parenLoop: + for { + tok, err = p.consumeToken() + if err != nil { + return nil, err + } + switch tok { + case ")": + break parenLoop + case "rename": + str, err := p.consumeString() + if err != nil { + return nil, err + } + details.Rename = &str + case "implicit": + scalar, err := p.consumeToken() + if err != nil { + return nil, err + } + var anyScalar dmt.AnyScalar + switch { + case scalar[0] == '"': // string + s, err := strconv.Unquote(scalar) + if err != nil { + return nil, p.forwardError(err) + } + anyScalar.String = &s + case scalar == "true", scalar == "false": // bool + t := scalar == "true" + anyScalar.Bool = &t + case scalar[0] >= '0' && scalar[0] <= '0': + n, err := strconv.Atoi(scalar) + if err != nil { + return nil, p.forwardError(err) + } + anyScalar.Int = &n + default: + return nil, p.errf("unsupported implicit scalar: %s", scalar) + } + + details.Implicit = &anyScalar + } + } + mapAppend(repr.Fields, name, details) + } + + mapAppend(&defn.Fields, name, field) + } + + reprName := "map" // default repr + if tok, err := p.peekToken(); err == nil && tok == "representation" { + p.consumePeeked() + name, err := p.consumeName() + if err != nil { + return nil, err + } + reprName = name + } + if reprName != "map" && len(repr.Fields.Keys) > 0 { + return nil, p.errf("rename and implicit are only supported for struct map representations") + } + switch reprName { + case "map": + if len(repr.Fields.Keys) == 0 { + // Fields is optional; omit it if empty. + repr.Fields = nil + } + defn.Representation.StructRepresentation_Map = repr + return defn, nil + case "tuple": + defn.Representation.StructRepresentation_Tuple = &dmt.StructRepresentation_Tuple{} + return defn, nil + // TODO: support custom fieldorder + case "stringjoin": + optMap, err := p.consumeStringMap() + if err != nil { + return nil, err + } + join, hasJoin := optMap["join"] + if !hasJoin { + return nil, p.errf("no join value provided for stringjoin repr") + } + defn.Representation.StructRepresentation_Stringjoin = &dmt.StructRepresentation_Stringjoin{ + Join: join, + } + return defn, nil + default: + return nil, p.errf("unknown struct repr: %q", reprName) + } +} + +func (p *parser) typeNameOrInlineDefn() (dmt.TypeNameOrInlineDefn, error) { + var typ dmt.TypeNameOrInlineDefn + tok, err := p.consumeToken() + if err != nil { + return typ, err + } + + switch tok { + case "&": + expectedName, err := p.consumeName() + if err != nil { + return typ, err + } + typ.InlineDefn = &dmt.InlineDefn{TypeDefnLink: &dmt.TypeDefnLink{ExpectedType: &expectedName}} + case "[": + tlist, err := p.typeList() + if err != nil { + return typ, err + } + typ.InlineDefn = &dmt.InlineDefn{TypeDefnList: tlist} + case "{": + tmap, err := p.typeMap() + if err != nil { + return typ, err + } + typ.InlineDefn = &dmt.InlineDefn{TypeDefnMap: tmap} + default: + typ.TypeName = &tok + } + return typ, nil +} + +func (p *parser) typeList() (*dmt.TypeDefnList, error) { + defn := &dmt.TypeDefnList{} + tok, err := p.peekToken() + if err != nil { + return nil, err + } + if tok == "nullable" { + defn.ValueNullable = &globalTrue + p.consumePeeked() + } + + defn.ValueType, err = p.typeNameOrInlineDefn() + if err != nil { + return nil, err + } + + if err := p.consumeRequired("]"); err != nil { + return defn, err + } + + // TODO: repr + return defn, nil +} + +func (p *parser) typeMap() (*dmt.TypeDefnMap, error) { + defn := &dmt.TypeDefnMap{} + + var err error + defn.KeyType, err = p.consumeName() + if err != nil { + return nil, err + } + if err := p.consumeRequired(":"); err != nil { + return defn, err + } + + tok, err := p.peekToken() + if err != nil { + return nil, err + } + if tok == "nullable" { + defn.ValueNullable = &globalTrue + p.consumePeeked() + } + + defn.ValueType, err = p.typeNameOrInlineDefn() + if err != nil { + return nil, err + } + + if err := p.consumeRequired("}"); err != nil { + return defn, err + } + + return defn, nil +} + +func (p *parser) typeUnion() (*dmt.TypeDefnUnion, error) { + defn := &dmt.TypeDefnUnion{} + var reprKeys []string + + for { + tok, err := p.consumeToken() + if err != nil { + return nil, err + } + if tok == "}" { + break + } + if tok != "|" { + return nil, p.errf("expected %q or %q, got %q", "}", "|", tok) + } + var member dmt.UnionMember + nameOrInline, err := p.typeNameOrInlineDefn() + if err != nil { + return nil, err + } + + if nameOrInline.TypeName != nil { + member.TypeName = nameOrInline.TypeName + } else { + if nameOrInline.InlineDefn.TypeDefnLink != nil { + member.UnionMemberInlineDefn = &dmt.UnionMemberInlineDefn{TypeDefnLink: nameOrInline.InlineDefn.TypeDefnLink} + } else { + return nil, p.errf("expected a name or inline link, got neither") + } + } + defn.Members = append(defn.Members, member) + + key, err := p.consumeToken() + if err != nil { + return nil, err + } + reprKeys = append(reprKeys, key) + } + if err := p.consumeRequired("representation"); err != nil { + return nil, err + } + reprName, err := p.consumeName() + if err != nil { + return nil, err + } + switch reprName { + case "keyed": + repr := &dmt.UnionRepresentation_Keyed{} + for i, keyStr := range reprKeys { + key, err := strconv.Unquote(keyStr) + if err != nil { + return nil, p.forwardError(err) + } + mapAppend(repr, key, defn.Members[i]) + } + defn.Representation.UnionRepresentation_Keyed = repr + case "kinded": + repr := &dmt.UnionRepresentation_Kinded{} + // TODO: verify keys are valid kinds? enum should do it for us? + for i, key := range reprKeys { + mapAppend(repr, key, defn.Members[i]) + } + defn.Representation.UnionRepresentation_Kinded = repr + case "stringprefix": + repr := &dmt.UnionRepresentation_StringPrefix{ + Prefixes: dmt.Map__String__TypeName{ + Values: map[string]string{}, + }, + } + for i, key := range reprKeys { + // unquote prefix string + if len(key) < 2 || key[0] != '"' || key[len(key)-1] != '"' { + return nil, p.errf("invalid stringprefix %q", key) + } + key = key[1 : len(key)-1] + + // add prefix to prefixes map + repr.Prefixes.Keys = append(repr.Prefixes.Keys, key) + repr.Prefixes.Values[key] = *defn.Members[i].TypeName + } + defn.Representation.UnionRepresentation_StringPrefix = repr + default: + return nil, p.errf("TODO: union repr %q", reprName) + } + return defn, nil +} + +func (p *parser) typeEnum() (*dmt.TypeDefnEnum, error) { + defn := &dmt.TypeDefnEnum{} + var reprKeys []string + + for { + tok, err := p.consumeToken() + if err != nil { + return nil, err + } + if tok == "}" { + break + } + if tok != "|" { + return nil, p.errf("expected %q or %q, got %q", "}", "|", tok) + } + name, err := p.consumeToken() + if err != nil { + return nil, err + } + defn.Members = append(defn.Members, name) + + if tok, err := p.peekToken(); err == nil && tok == "(" { + p.consumePeeked() + key, err := p.consumeToken() + if err != nil { + return nil, err + } + reprKeys = append(reprKeys, key) + if err := p.consumeRequired(")"); err != nil { + return defn, err + } + } else { + reprKeys = append(reprKeys, "") + } + } + + reprName := "string" // default repr + if tok, err := p.peekToken(); err == nil && tok == "representation" { + p.consumePeeked() + name, err := p.consumeName() + if err != nil { + return nil, err + } + reprName = name + } + switch reprName { + case "string": + repr := &dmt.EnumRepresentation_String{} + for i, key := range reprKeys { + if key == "" { + continue // no key; defaults to the name + } + if key[0] != '"' { + return nil, p.errf("enum string representation used with non-string key: %s", key) + } + unquoted, err := strconv.Unquote(key) + if err != nil { + return nil, p.forwardError(err) + } + mapAppend(repr, defn.Members[i], unquoted) + } + defn.Representation.EnumRepresentation_String = repr + case "int": + repr := &dmt.EnumRepresentation_Int{} + for i, key := range reprKeys { + if key[0] != '"' { + return nil, p.errf("enum int representation used with non-string key: %s", key) + } + unquoted, err := strconv.Unquote(key) + if err != nil { + return nil, p.forwardError(err) + } + parsed, err := strconv.Atoi(unquoted) + if err != nil { + return nil, p.forwardError(err) + } + mapAppend(repr, defn.Members[i], parsed) + } + defn.Representation.EnumRepresentation_Int = repr + default: + return nil, p.errf("unknown enum repr: %q", reprName) + } + return defn, nil +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/errors.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/errors.go new file mode 100644 index 00000000..9135fe99 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/errors.go @@ -0,0 +1,128 @@ +package schema + +import ( + "fmt" + "strings" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +// TODO: errors in this package remain somewhat slapdash. +// +// - datamodel.ErrUnmatchable is used as a catch-all in some places, and contains who-knows-what values wrapped in the Reason field. +// - sometimes this wraps things like strconv errors... and on the one hand, i'm kinda okay with that; on the other, maybe saying a bit more with types before getting to that kind of shrug would be nice. +// - we probably want to use `Type` values, right? +// - or do we: because then we probably need a `Repr bool` next to it, or lots of messages would be nonsensical. +// - this is *currently* problematic because we don't actually generate type info consts yet. Hopefully soon; but the pain, meanwhile, is... substantial. +// - "substantial" is an understatement. it makes incremental development almost impossible because stringifying error reports turn into nil pointer crashes! +// - other ipld-wide errors like `datamodel.ErrWrongKind` *sometimes* refer to a TypeName... but don't *have* to, because they also arise at the merely-datamodel level; what would we do with these? +// - it's undesirable (not to mention intensely forbidden for import cycle reasons) for those error types to refer to schema.Type. +// - if we must have TypeName treated stringily in some cases, is it really useful to use full type info in other cases -- inconsistently? +// - regardless of where we end up with this, some sort of an embed for helping deal with munging and printing this would probably be wise. +// - generally, whether you should expect an "datamodel.Err*" or a "schema.Err*" from various methods is quite unclear. +// - it's possible that we should wrap *all* schema-level errors in a single "datamodel.ErrSchemaNoMatch" error of some kind, to fix the above. (and maybe that's what ErrUnmatchable really is.) as yet undecided. + +// ErrUnmatchable is the error raised when processing data with IPLD Schemas and +// finding data which cannot be matched into the schema. +// It will be returned by NodeAssemblers and NodeBuilders when they are fed unmatchable data. +// As a result, it will also often be seen returned from unmarshalling +// when unmarshalling into schema-constrained NodeAssemblers. +// +// ErrUnmatchable provides the name of the type in the schema that data couldn't be matched to, +// and wraps another error as the more detailed reason. +type ErrUnmatchable struct { + // TypeName will indicate the named type of a node the function was called on. + TypeName string + + // Reason must always be present. ErrUnmatchable doesn't say much otherwise. + Reason error +} + +func (e ErrUnmatchable) Error() string { + return fmt.Sprintf("matching data to schema of %s rejected: %s", e.TypeName, e.Reason) +} + +// Reasonf returns a new ErrUnmatchable with a Reason field set to the Errorf of the arguments. +// It's a helper function for creating untyped error reasons without importing the fmt package. +func (e ErrUnmatchable) Reasonf(format string, a ...interface{}) ErrUnmatchable { + return ErrUnmatchable{e.TypeName, fmt.Errorf(format, a...)} +} + +// ErrMissingRequiredField is returned when calling 'Finish' on a NodeAssembler +// for a Struct that has not has all required fields set. +type ErrMissingRequiredField struct { + Missing []string +} + +func (e ErrMissingRequiredField) Error() string { + return "missing required fields: " + strings.Join(e.Missing, ",") +} + +// ErrInvalidKey indicates a key is invalid for some reason. +// +// This is only possible for typed nodes; specifically, it may show up when +// handling struct types, or maps with interesting key types. +// (Other kinds of key invalidity that happen for untyped maps +// fall under ErrRepeatedMapKey or ErrWrongKind.) +// (Union types use ErrInvalidUnionDiscriminant instead of ErrInvalidKey, +// even when their representation strategy is maplike.) +type ErrInvalidKey struct { + // TypeName will indicate the named type of a node the function was called on. + TypeName string + + // Key is the key that was rejected. + Key datamodel.Node + + // Reason, if set, may provide details (for example, the reason a key couldn't be converted to a type). + // If absent, it'll be presumed "no such field". + // ErrUnmatchable may show up as a reason for typed maps with complex keys. + Reason error +} + +func (e ErrInvalidKey) Error() string { + if e.Reason == nil { + return fmt.Sprintf("invalid key for map %s: %q: no such field", e.TypeName, e.Key) + } else { + return fmt.Sprintf("invalid key for map %s: %q: %s", e.TypeName, e.Key, e.Reason) + } +} + +// ErrNoSuchField may be returned from lookup functions on the Node +// interface when a field is requested which doesn't exist, +// or from assigning data into on a MapAssembler for a struct +// when the key doesn't match a field name in the structure +// (or, when assigning data into a ListAssembler and the list size has +// reached out of bounds, in case of a struct with list-like representations!). +type ErrNoSuchField struct { + Type Type + + Field datamodel.PathSegment +} + +func (e ErrNoSuchField) Error() string { + if e.Type == nil { + return fmt.Sprintf("no such field: {typeinfomissing}.%s", e.Field) + } + return fmt.Sprintf("no such field: %s.%s", e.Type.Name(), e.Field) +} + +// ErrNotUnionStructure means data was fed into a union assembler that can't match the union. +// +// This could have one of several reasons, which are explained in the detail text: +// +// - there are too many entries in the map; +// - the keys of critical entries aren't found; +// - keys are found that aren't any of the expected critical keys; +// - etc. +// +// TypeName is currently a string... see comments at the top of this file for +// remarks on the issues we need to address about these identifiers in errors in general. +type ErrNotUnionStructure struct { + TypeName string + + Detail string +} + +func (e ErrNotUnionStructure) Error() string { + return fmt.Sprintf("cannot match schema: union structure constraints for %s caused rejection: %s", e.TypeName, e.Detail) +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/kind.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/kind.go new file mode 100644 index 00000000..8478edd2 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/kind.go @@ -0,0 +1,112 @@ +package schema + +import ( + "github.com/ipld/go-ipld-prime/datamodel" +) + +// TypeKind is an enum of kind in the IPLD Schema system. +// +// Note that schema.TypeKind is distinct from datamodel.Kind! +// Schema kinds include concepts such as "struct" and "enum", which are +// concepts only introduced by the Schema layer, and not present in the +// Data Model layer. +type TypeKind uint8 + +const ( + TypeKind_Invalid TypeKind = 0 + TypeKind_Map TypeKind = '{' + TypeKind_List TypeKind = '[' + TypeKind_Unit TypeKind = '1' + TypeKind_Bool TypeKind = 'b' + TypeKind_Int TypeKind = 'i' + TypeKind_Float TypeKind = 'f' + TypeKind_String TypeKind = 's' + TypeKind_Bytes TypeKind = 'x' + TypeKind_Link TypeKind = '/' + TypeKind_Struct TypeKind = '$' + TypeKind_Union TypeKind = '^' + TypeKind_Enum TypeKind = '%' + TypeKind_Any TypeKind = '?' +) + +func (k TypeKind) String() string { + switch k { + case TypeKind_Invalid: + return "invalid" + case TypeKind_Map: + return "map" + case TypeKind_Any: + return "any" + case TypeKind_List: + return "list" + case TypeKind_Unit: + return "unit" + case TypeKind_Bool: + return "bool" + case TypeKind_Int: + return "int" + case TypeKind_Float: + return "float" + case TypeKind_String: + return "string" + case TypeKind_Bytes: + return "bytes" + case TypeKind_Link: + return "link" + case TypeKind_Struct: + return "struct" + case TypeKind_Union: + return "union" + case TypeKind_Enum: + return "enum" + default: + panic("invalid enumeration value!") + } +} + +// ActsLike returns a constant from the datamodel.Kind enum describing what +// this schema.TypeKind acts like at the Data Model layer. +// +// Things with similar names are generally conserved +// (e.g. "map" acts like "map"); +// concepts added by the schema layer have to be mapped onto something +// (e.g. "struct" acts like "map"). +// +// Note that this mapping describes how a typed Node will *act*, programmatically; +// it does not necessarily describe how it will be *serialized* +// (for example, a struct will always act like a map, even if it has a tuple +// representation strategy and thus becomes a list when serialized). +func (k TypeKind) ActsLike() datamodel.Kind { + switch k { + case TypeKind_Invalid: + return datamodel.Kind_Invalid + case TypeKind_Map: + return datamodel.Kind_Map + case TypeKind_List: + return datamodel.Kind_List + case TypeKind_Unit: + return datamodel.Kind_Bool // maps to 'true'. // REVIEW: odd that this doesn't map to 'null'? // TODO this should be standardized in the specs, in a table. + case TypeKind_Bool: + return datamodel.Kind_Bool + case TypeKind_Int: + return datamodel.Kind_Int + case TypeKind_Float: + return datamodel.Kind_Float + case TypeKind_String: + return datamodel.Kind_String + case TypeKind_Bytes: + return datamodel.Kind_Bytes + case TypeKind_Link: + return datamodel.Kind_Link + case TypeKind_Struct: + return datamodel.Kind_Map // clear enough: fields are keys. + case TypeKind_Union: + return datamodel.Kind_Map + case TypeKind_Enum: + return datamodel.Kind_String // 'AsString' is the one clear thing to define. + case TypeKind_Any: + return datamodel.Kind_Invalid // TODO: maybe ActsLike should return (Kind, bool) + default: + panic("invalid enumeration value!") + } +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/maybe.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/maybe.go new file mode 100644 index 00000000..bdc46933 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/maybe.go @@ -0,0 +1,9 @@ +package schema + +type Maybe uint8 + +const ( + Maybe_Absent = Maybe(0) + Maybe_Null = Maybe(1) + Maybe_Value = Maybe(2) +) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/tmpBuilders.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/tmpBuilders.go new file mode 100644 index 00000000..eb7a8be4 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/tmpBuilders.go @@ -0,0 +1,220 @@ +package schema + +import ( + "fmt" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +// Everything in this file is __a temporary hack__ and will be __removed__. +// +// These methods will only hang around until more of the "ast" packages are finished; +// thereafter, building schema.Type and schema.TypeSystem values will only be +// possible through first constructing a schema AST, and *then* using Reify(), +// which will validate things correctly, cycle-check, cross-link, etc. +// +// (Meanwhile, we're using these methods in the codegen prototypes.) + +// These methods use Type objects as parameters when pointing to other things, +// but this is... turning out consistently problematic. +// Even when we're doing this hacky direct-call doesn't-need-to-be-serializable temp stuff, +// as written, this doesn't actually let us express cyclic things viably! +// The same initialization questions are also going to come up again when we try to make +// concrete values in the output of codegen. +// Maybe it's actually just a bad idea to have our reified Type types use Type pointers at all. +// (I will never get tired of the tongue twisters, evidently.) +// I'm not actually using that much, and it's always avoidable (it's trivial to replace with a map lookup bouncing through a 'ts' variable somewhere). +// And having the AST gen'd types be... just... the thing... sounds nice. It could save a lot of work. +// (It would mean the golang types don't tell you whether the values have been checked for global properties or not, but, eh.) +// (It's not really compatible with "Prototype and Type are the same thing for codegen'd stuff", either (or, we need more interfaces, and to *really* lean into them), but maybe that's okay.) + +func SpawnTypeSystem(types ...Type) (*TypeSystem, []error) { + ts := TypeSystem{} + ts.Init() + for _, typ := range types { + ts.Accumulate(typ) + } + if errs := ts.ValidateGraph(); errs != nil { + return nil, errs + } + return &ts, nil +} +func MustTypeSystem(types ...Type) *TypeSystem { + if ts, err := SpawnTypeSystem(types...); err != nil { + panic(err) + } else { + return ts + } +} + +func SpawnString(name TypeName) *TypeString { + return &TypeString{typeBase{name, nil}} +} + +func SpawnBool(name TypeName) *TypeBool { + return &TypeBool{typeBase{name, nil}} +} + +func SpawnInt(name TypeName) *TypeInt { + return &TypeInt{typeBase{name, nil}} +} + +func SpawnFloat(name TypeName) *TypeFloat { + return &TypeFloat{typeBase{name, nil}} +} + +func SpawnBytes(name TypeName) *TypeBytes { + return &TypeBytes{typeBase{name, nil}} +} + +func SpawnLink(name TypeName) *TypeLink { + return &TypeLink{typeBase{name, nil}, "", false} +} + +func SpawnLinkReference(name TypeName, pointsTo TypeName) *TypeLink { + return &TypeLink{typeBase{name, nil}, pointsTo, true} +} + +func SpawnList(name TypeName, valueType TypeName, nullable bool) *TypeList { + return &TypeList{typeBase{name, nil}, false, valueType, nullable} +} + +func SpawnMap(name TypeName, keyType TypeName, valueType TypeName, nullable bool) *TypeMap { + return &TypeMap{typeBase{name, nil}, false, keyType, valueType, nullable} +} + +func SpawnAny(name TypeName) *TypeAny { + return &TypeAny{typeBase{name, nil}} +} + +func SpawnStruct(name TypeName, fields []StructField, repr StructRepresentation) *TypeStruct { + v := &TypeStruct{ + typeBase{name, nil}, + fields, + make(map[string]StructField, len(fields)), + repr, + } + for i := range fields { + fields[i].parent = v + v.fieldsMap[fields[i].name] = fields[i] + } + switch repr.(type) { + case StructRepresentation_Stringjoin: + for _, f := range fields { + if f.IsMaybe() { + panic("neither nullable nor optional is supported on struct stringjoin representation") + } + } + case nil: + v.representation = SpawnStructRepresentationMap(nil) + } + return v +} +func SpawnStructField(name string, typ TypeName, optional bool, nullable bool) StructField { + return StructField{nil /*populated later*/, name, typ, optional, nullable} +} +func SpawnStructRepresentationMap(renames map[string]string) StructRepresentation_Map { + return StructRepresentation_Map{renames, nil} +} +func SpawnStructRepresentationMap2(renames map[string]string, implicits map[string]ImplicitValue) StructRepresentation_Map { + return StructRepresentation_Map{renames, implicits} +} +func SpawnStructRepresentationTuple() StructRepresentation_Tuple { + return StructRepresentation_Tuple{} +} +func SpawnStructRepresentationStringjoin(delim string) StructRepresentation_Stringjoin { + return StructRepresentation_Stringjoin{delim} +} + +func SpawnUnion(name TypeName, members []TypeName, repr UnionRepresentation) *TypeUnion { + return &TypeUnion{typeBase{name, nil}, members, repr} +} +func SpawnUnionRepresentationKeyed(table map[string]TypeName) UnionRepresentation_Keyed { + return UnionRepresentation_Keyed{table} +} +func SpawnUnionRepresentationKinded(table map[datamodel.Kind]TypeName) UnionRepresentation_Kinded { + return UnionRepresentation_Kinded{table} +} +func SpawnUnionRepresentationStringprefix(delim string, table map[string]TypeName) UnionRepresentation_Stringprefix { + return UnionRepresentation_Stringprefix{delim, table} +} + +func SpawnEnum(name TypeName, members []string, repr EnumRepresentation) *TypeEnum { + return &TypeEnum{typeBase{name, nil}, members, repr} +} + +// The methods relating to TypeSystem are also mutation-heavy and placeholdery. + +func (ts *TypeSystem) Init() { + ts.namedTypes = make(map[TypeName]Type) +} +func (ts *TypeSystem) Accumulate(typ Type) { + typ._Type(ts) + name := typ.Name() + if _, ok := ts.namedTypes[name]; ok { + panic(fmt.Sprintf("duplicate type name: %s", name)) + } + ts.namedTypes[name] = typ + ts.names = append(ts.names, name) +} +func (ts TypeSystem) GetTypes() map[TypeName]Type { + return ts.namedTypes +} +func (ts TypeSystem) TypeByName(n string) Type { + return ts.namedTypes[n] +} +func (ts TypeSystem) Names() []TypeName { + return ts.names +} + +// ValidateGraph checks that all type names referenced are defined. +// +// It does not do any other validations of individual type's sensibleness +// (that should've happened when they were created +// (although also note many of those validates are NYI, +// and are roadmapped for after we research self-hosting)). +func (ts TypeSystem) ValidateGraph() []error { + var ee []error + for tn, t := range ts.namedTypes { + switch t2 := t.(type) { + case *TypeBool, + *TypeInt, + *TypeFloat, + *TypeString, + *TypeBytes, + *TypeEnum: + continue // nothing to check: these are leaf nodes and refer to no other types. + case *TypeLink: + if !t2.hasReferencedType { + continue + } + if _, ok := ts.namedTypes[t2.referencedType]; !ok { + ee = append(ee, fmt.Errorf("type %s refers to missing type %s (as link reference type)", tn, t2.referencedType)) + } + case *TypeStruct: + for _, f := range t2.fields { + if _, ok := ts.namedTypes[f.typ]; !ok { + ee = append(ee, fmt.Errorf("type %s refers to missing type %s (in field %q)", tn, f.typ, f.name)) + } + } + case *TypeMap: + if _, ok := ts.namedTypes[t2.keyType]; !ok { + ee = append(ee, fmt.Errorf("type %s refers to missing type %s (as key type)", tn, t2.keyType)) + } + if _, ok := ts.namedTypes[t2.valueType]; !ok { + ee = append(ee, fmt.Errorf("type %s refers to missing type %s (as value type)", tn, t2.valueType)) + } + case *TypeList: + if _, ok := ts.namedTypes[t2.valueType]; !ok { + ee = append(ee, fmt.Errorf("type %s refers to missing type %s (as value type)", tn, t2.valueType)) + } + case *TypeUnion: + for _, mn := range t2.members { + if _, ok := ts.namedTypes[mn]; !ok { + ee = append(ee, fmt.Errorf("type %s refers to missing type %s (as a member)", tn, mn)) + } + } + } + } + return ee +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/type.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/type.go new file mode 100644 index 00000000..e322aad7 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/type.go @@ -0,0 +1,270 @@ +package schema + +import ( + "github.com/ipld/go-ipld-prime/datamodel" +) + +type TypeName = string + +// typesystem.Type is an union interface; each of the `Type*` concrete types +// in this package are one of its members. +// +// Specifically, +// +// TypeBool +// TypeString +// TypeBytes +// TypeInt +// TypeFloat +// TypeMap +// TypeList +// TypeLink +// TypeUnion +// TypeStruct +// TypeEnum +// +// are all of the kinds of Type. +// +// This is a closed union; you can switch upon the above members without +// including a default case. The membership is closed by the unexported +// '_Type' method; you may use the BurntSushi/go-sumtype tool to check +// your switches for completeness. +// +// Many interesting properties of each Type are only defined for that specific +// type, so it's typical to use a type switch to handle each type of Type. +// (Your humble author is truly sorry for the word-mash that results from +// attempting to describe the types that describe the typesystem.Type.) +// +// For example, to inspect the kind of fields in a struct: you might +// cast a `Type` interface into `TypeStruct`, and then the `Fields()` on +// that `TypeStruct` can be inspected. (`Fields()` isn't defined for any +// other kind of Type.) +type Type interface { + // Unexported marker method to force the union closed. + // Also used to set the internal pointer back to the universe its part of. + _Type(*TypeSystem) + + // Returns a pointer to the TypeSystem this Type is a member of. + TypeSystem() *TypeSystem + + // Returns the string name of the Type. This name is unique within the + // universe this type is a member of, *unless* this type is Anonymous, + // in which case a string describing the type will still be returned, but + // that string will not be required to be unique. + Name() TypeName + + // Returns the TypeKind of this Type. + // + // The returned value is a 1:1 association with which of the concrete + // "schema.Type*" structs this interface can be cast to. + // + // Note that a schema.TypeKind is a different enum than datamodel.Kind; + // and furthermore, there's no strict relationship between them. + // schema.TypedNode values can be described by *two* distinct Kinds: + // one which describes how the Node itself will act, + // and another which describes how the Node presents for serialization. + // For some combinations of Type and representation strategy, one or both + // of the Kinds can be determined statically; but not always: + // it can sometimes be necessary to inspect the value quite concretely + // (e.g., `schema.TypedNode{}.Representation().Kind()`) in order to find + // out exactly how a node will be serialized! This is because some types + // can vary in representation kind based on their value (specifically, + // kinded-representation unions have this property). + TypeKind() TypeKind + + // RepresentationBehavior returns a description of how the representation + // of this type will behave in terms of the IPLD Data Model. + // This property varies based on the representation strategy of a type. + // + // In one case, the representation behavior cannot be known statically, + // and varies based on the data: kinded unions have this trait. + // + // This property is used by kinded unions, which require that their members + // all have distinct representation behavior. + // (It follows that a kinded union cannot have another kinded union as a member.) + // + // You may also be interested in a related property that might have been called "TypeBehavior". + // However, this method doesn't exist, because it's a deterministic property of `TypeKind()`! + // You can use `TypeKind.ActsLike()` to get type-level behavioral information. + RepresentationBehavior() datamodel.Kind +} + +var ( + _ Type = &TypeBool{} + _ Type = &TypeString{} + _ Type = &TypeBytes{} + _ Type = &TypeInt{} + _ Type = &TypeFloat{} + _ Type = &TypeAny{} + _ Type = &TypeMap{} + _ Type = &TypeList{} + _ Type = &TypeLink{} + _ Type = &TypeUnion{} + _ Type = &TypeStruct{} + _ Type = &TypeEnum{} +) + +type typeBase struct { + name TypeName + universe *TypeSystem +} + +type TypeBool struct { + typeBase +} + +type TypeString struct { + typeBase +} + +type TypeBytes struct { + typeBase +} + +type TypeInt struct { + typeBase +} + +type TypeFloat struct { + typeBase +} + +type TypeAny struct { + typeBase +} + +type TypeMap struct { + typeBase + anonymous bool + keyType TypeName // must be Kind==string (e.g. Type==String|Enum). + valueType TypeName + valueNullable bool +} + +type TypeList struct { + typeBase + anonymous bool + valueType TypeName + valueNullable bool +} + +type TypeLink struct { + typeBase + referencedType TypeName + hasReferencedType bool + // ...? +} + +type TypeUnion struct { + typeBase + // Members are listed in the order they appear in the schema. + // To find the discriminant info, you must look inside the representation; they all contain a 'table' of some kind in which the member types are the values. + // Note that multiple appearances of the same type as distinct members of the union is not possible. + // While we could do this... A: that's... odd, and nearly never called for; B: not possible with kinded mode; C: imagine the golang-native type switch! it's impossible. + // We rely on this clarity in many ways: most visibly, the type-level Node implementation for a union always uses the type names as if they were map keys! This behavior is consistent for all union representations. + members []TypeName + representation UnionRepresentation +} + +type UnionRepresentation interface{ _UnionRepresentation() } + +func (UnionRepresentation_Keyed) _UnionRepresentation() {} +func (UnionRepresentation_Kinded) _UnionRepresentation() {} +func (UnionRepresentation_Envelope) _UnionRepresentation() {} +func (UnionRepresentation_Inline) _UnionRepresentation() {} +func (UnionRepresentation_Stringprefix) _UnionRepresentation() {} + +// A bunch of these tables in union representation might be easier to use if flipped; +// we almost always index into them by type (since that's what we have an ordered list of); +// and they're unique in both directions, so it's equally valid either way. +// The order they're currently written in matches the serial form in the schema AST. + +type UnionRepresentation_Keyed struct { + table map[string]TypeName // key is user-defined freetext +} +type UnionRepresentation_Kinded struct { + table map[datamodel.Kind]TypeName +} + +//lint:ignore U1000 implementation TODO +type UnionRepresentation_Envelope struct { + discriminantKey string + contentKey string + table map[string]TypeName // key is user-defined freetext +} + +//lint:ignore U1000 implementation TODO +type UnionRepresentation_Inline struct { + discriminantKey string + table map[string]TypeName // key is user-defined freetext +} +type UnionRepresentation_Stringprefix struct { + delim string + table map[string]TypeName // key is user-defined freetext +} + +type TypeStruct struct { + typeBase + // n.b. `Fields` is an (order-preserving!) map in the schema-schema; + // but it's a list here, with the keys denormalized into the value, + // because that's typically how we use it. + fields []StructField + fieldsMap map[string]StructField // same content, indexed for lookup. + representation StructRepresentation +} +type StructField struct { + parent *TypeStruct + name string + typ TypeName + optional bool + nullable bool +} + +type StructRepresentation interface{ _StructRepresentation() } + +func (StructRepresentation_Map) _StructRepresentation() {} +func (StructRepresentation_Tuple) _StructRepresentation() {} +func (StructRepresentation_StringPairs) _StructRepresentation() {} +func (StructRepresentation_Stringjoin) _StructRepresentation() {} + +type StructRepresentation_Map struct { + renames map[string]string + implicits map[string]ImplicitValue +} +type StructRepresentation_Tuple struct{} + +//lint:ignore U1000 implementation TODO +type StructRepresentation_StringPairs struct{ sep1, sep2 string } +type StructRepresentation_Stringjoin struct{ sep string } + +type TypeEnum struct { + typeBase + members []string + representation EnumRepresentation +} + +type EnumRepresentation interface{ _EnumRepresentation() } + +func (EnumRepresentation_String) _EnumRepresentation() {} +func (EnumRepresentation_Int) _EnumRepresentation() {} + +type EnumRepresentation_String map[string]string +type EnumRepresentation_Int map[string]int + +// ImplicitValue is an sum type holding values that are implicits. +// It's not an 'Any' value because it can't be recursive +// (or to be slightly more specific, it can be one of the recursive kinds, +// but if so, only its empty value is valid here). +type ImplicitValue interface{ _ImplicitValue() } + +func (ImplicitValue_EmptyList) _ImplicitValue() {} +func (ImplicitValue_EmptyMap) _ImplicitValue() {} +func (ImplicitValue_String) _ImplicitValue() {} +func (ImplicitValue_Int) _ImplicitValue() {} +func (ImplicitValue_Bool) _ImplicitValue() {} + +type ImplicitValue_EmptyList struct{} +type ImplicitValue_EmptyMap struct{} +type ImplicitValue_String string +type ImplicitValue_Int int +type ImplicitValue_Bool bool diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typeMethods.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typeMethods.go new file mode 100644 index 00000000..c623c3fb --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typeMethods.go @@ -0,0 +1,287 @@ +package schema + +import ( + "github.com/ipld/go-ipld-prime/datamodel" +) + +/* cookie-cutter standard interface stuff */ + +func (t *typeBase) _Type(ts *TypeSystem) { + t.universe = ts +} +func (t typeBase) TypeSystem() *TypeSystem { return t.universe } +func (t typeBase) Name() TypeName { return t.name } + +func (TypeBool) TypeKind() TypeKind { return TypeKind_Bool } +func (TypeString) TypeKind() TypeKind { return TypeKind_String } +func (TypeBytes) TypeKind() TypeKind { return TypeKind_Bytes } +func (TypeInt) TypeKind() TypeKind { return TypeKind_Int } +func (TypeFloat) TypeKind() TypeKind { return TypeKind_Float } +func (TypeAny) TypeKind() TypeKind { return TypeKind_Any } +func (TypeMap) TypeKind() TypeKind { return TypeKind_Map } +func (TypeList) TypeKind() TypeKind { return TypeKind_List } +func (TypeLink) TypeKind() TypeKind { return TypeKind_Link } +func (TypeUnion) TypeKind() TypeKind { return TypeKind_Union } +func (TypeStruct) TypeKind() TypeKind { return TypeKind_Struct } +func (TypeEnum) TypeKind() TypeKind { return TypeKind_Enum } + +func (TypeBool) RepresentationBehavior() datamodel.Kind { return datamodel.Kind_Bool } +func (TypeString) RepresentationBehavior() datamodel.Kind { return datamodel.Kind_String } +func (TypeBytes) RepresentationBehavior() datamodel.Kind { return datamodel.Kind_Bytes } +func (TypeInt) RepresentationBehavior() datamodel.Kind { return datamodel.Kind_Int } +func (TypeFloat) RepresentationBehavior() datamodel.Kind { return datamodel.Kind_Float } +func (TypeMap) RepresentationBehavior() datamodel.Kind { return datamodel.Kind_Map } +func (TypeList) RepresentationBehavior() datamodel.Kind { return datamodel.Kind_List } +func (TypeLink) RepresentationBehavior() datamodel.Kind { return datamodel.Kind_Link } +func (t TypeUnion) RepresentationBehavior() datamodel.Kind { + switch t.representation.(type) { + case UnionRepresentation_Keyed: + return datamodel.Kind_Map + case UnionRepresentation_Kinded: + return datamodel.Kind_Invalid // you can't know with this one, until you see the value (and thus can its inhabitant's behavior)! + case UnionRepresentation_Envelope: + return datamodel.Kind_Map + case UnionRepresentation_Inline: + return datamodel.Kind_Map + case UnionRepresentation_Stringprefix: + return datamodel.Kind_String + default: + panic("unreachable") + } +} +func (t TypeStruct) RepresentationBehavior() datamodel.Kind { + switch t.representation.(type) { + case StructRepresentation_Map: + return datamodel.Kind_Map + case StructRepresentation_Tuple: + return datamodel.Kind_List + case StructRepresentation_StringPairs: + return datamodel.Kind_String + case StructRepresentation_Stringjoin: + return datamodel.Kind_String + default: + panic("unreachable") + } +} +func (t TypeEnum) RepresentationBehavior() datamodel.Kind { + // TODO: this should have a representation strategy switch too; sometimes that will indicate int representation behavior. + return datamodel.Kind_String +} +func (t TypeAny) RepresentationBehavior() datamodel.Kind { + return datamodel.Kind_Invalid // TODO: what can we possibly do here? +} + +/* interesting methods per Type type */ + +// beware: many of these methods will change when we successfully bootstrap self-hosting. +// +// The current methods return reified Type objects; in the future, there might be less of that. +// Returning reified Type objects requires bouncing lookups through the typesystem map; +// this is unavoidable because we need to handle cycles in definitions. +// However, the extra (and cyclic) pointers that requires won't necessarily jive well if +// we remake the Type types to have close resemblances to the Data Model tree data.) +// +// It's also unfortunate that some of the current methods collide in name with +// the names of the Data Model fields. We might reshuffling things to reduce this. +// +// At any rate, all of these changes will come as a sweep once we +// get a self-hosting gen of the schema-schema, not before +// (the effort of updating template references is substantial). + +// IsAnonymous is returns true if the type was unnamed. Unnamed types will +// claim to have a Name property like `{Foo:Bar}`, and this is not guaranteed +// to be a unique string for all types in the universe. +func (t TypeMap) IsAnonymous() bool { + return t.anonymous +} + +// KeyType returns the Type of the map keys. +// +// Note that map keys will must always be some type which is representable as a +// string in the IPLD Data Model (e.g. either TypeString or TypeEnum). +func (t TypeMap) KeyType() Type { + return t.universe.namedTypes[t.keyType] +} + +// ValueType returns the Type of the map values. +func (t TypeMap) ValueType() Type { + return t.universe.namedTypes[t.valueType] +} + +// ValueIsNullable returns a bool describing if the map values are permitted +// to be null. +func (t TypeMap) ValueIsNullable() bool { + return t.valueNullable +} + +// IsAnonymous is returns true if the type was unnamed. Unnamed types will +// claim to have a Name property like `[Foo]`, and this is not guaranteed +// to be a unique string for all types in the universe. +func (t TypeList) IsAnonymous() bool { + return t.anonymous +} + +// ValueType returns to the Type of the list values. +func (t TypeList) ValueType() Type { + return t.universe.namedTypes[t.valueType] +} + +// ValueIsNullable returns a bool describing if the list values are permitted +// to be null. +func (t TypeList) ValueIsNullable() bool { + return t.valueNullable +} + +// Members returns the list of all types that are possible inhabitants of this union. +func (t TypeUnion) Members() []Type { + a := make([]Type, len(t.members)) + for i := range t.members { + a[i] = t.universe.namedTypes[t.members[i]] + } + return a +} + +func (t TypeUnion) RepresentationStrategy() UnionRepresentation { + return t.representation +} + +func (r UnionRepresentation_Keyed) GetDiscriminant(t Type) string { + for d, t2 := range r.table { + if t2 == t.Name() { + return d + } + } + panic("that type isn't a member of this union") +} + +func (r UnionRepresentation_Stringprefix) GetDelim() string { + return r.delim +} + +func (r UnionRepresentation_Stringprefix) GetDiscriminant(t Type) string { + for d, t2 := range r.table { + if t2 == t.Name() { + return d + } + } + panic("that type isn't a member of this union") +} + +// GetMember returns type info for the member matching the kind argument, +// or may return nil if that kind is not mapped to a member of this union. +func (r UnionRepresentation_Kinded) GetMember(k datamodel.Kind) TypeName { + return r.table[k] +} + +// Fields returns a slice of descriptions of the object's fields. +func (t TypeStruct) Fields() []StructField { + return t.fields +} + +// Field looks up a StructField by name, or returns nil if no such field. +func (t TypeStruct) Field(name string) *StructField { + if v, ok := t.fieldsMap[name]; ok { + return &v + } + return nil +} + +// Parent returns the type information that this field describes a part of. +// +// While in many cases, you may know the parent already from context, +// there may still be situations where want to pass around a field and +// not need to continue passing down the parent type with it; this method +// helps your code be less redundant in such a situation. +// (You'll find this useful for looking up any rename directives, for example, +// when holding onto a field, since that requires looking up information from +// the representation strategy, which is a property of the type as a whole.) +func (f StructField) Parent() *TypeStruct { return f.parent } + +// Name returns the string name of this field. The name is the string that +// will be used as a map key if the structure this field is a member of is +// serialized as a map representation. +func (f StructField) Name() string { return f.name } + +// Type returns the Type of this field's value. Note the field may +// also be unset if it is either Optional or Nullable. +func (f StructField) Type() Type { return f.parent.universe.namedTypes[f.typ] } + +// IsOptional returns true if the field is allowed to be absent from the object. +// If IsOptional is false, the field may be absent from the serial representation +// of the object entirely. +// +// Note being optional is different than saying the value is permitted to be null! +// A field may be both nullable and optional simultaneously, or either, or neither. +func (f StructField) IsOptional() bool { return f.optional } + +// IsNullable returns true if the field value is allowed to be null. +// +// If is Nullable is false, note that it's still possible that the field value +// will be absent if the field is Optional! Being nullable is unrelated to +// whether the field's presence is optional as a whole. +// +// Note that a field may be both nullable and optional simultaneously, +// or either, or neither. +func (f StructField) IsNullable() bool { return f.nullable } + +// IsMaybe returns true if the field value is allowed to be either null or absent. +// +// This is a simple "or" of the two properties, +// but this method is a shorthand that turns out useful often. +func (f StructField) IsMaybe() bool { return f.nullable || f.optional } + +func (t TypeStruct) RepresentationStrategy() StructRepresentation { + return t.representation +} + +func (r StructRepresentation_Map) GetFieldKey(field StructField) string { + if n, ok := r.renames[field.name]; ok { + return n + } + return field.name +} + +func (r StructRepresentation_Map) FieldHasRename(field StructField) bool { + _, ok := r.renames[field.name] + return ok +} + +// FieldImplicit returns the 'implicit' value for a field, or nil, if there isn't one. +// +// Because this returns the golang ImplicitValue type, which is an interface, +// golang type switching is needed to distinguish what it holds. +// (In other words, be warned that this function is not very friendly to use from templating engines.) +func (r StructRepresentation_Map) FieldImplicit(field StructField) ImplicitValue { + if r.implicits == nil { + return nil + } + return r.implicits[field.name] +} + +func (r StructRepresentation_Stringjoin) GetDelim() string { + return r.sep +} + +// Members returns a slice the strings which are valid inhabitants of this enum. +func (t TypeEnum) Members() []string { + return t.members +} + +func (t TypeEnum) RepresentationStrategy() EnumRepresentation { + return t.representation +} + +// Links can keep a referenced type, which is a hint only about the data on the +// other side of the link, no something that can be explicitly validated without +// loading the link + +// HasReferencedType returns true if the link has a hint about the type it references +// false if it's generic +func (t TypeLink) HasReferencedType() bool { + return t.hasReferencedType +} + +// ReferencedType returns the type hint for the node on the other side of the link +func (t TypeLink) ReferencedType() Type { + return t.universe.namedTypes[t.referencedType] +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typedNode.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typedNode.go new file mode 100644 index 00000000..4a09bfe4 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typedNode.go @@ -0,0 +1,85 @@ +package schema + +import ( + "github.com/ipld/go-ipld-prime/datamodel" +) + +// schema.TypedNode is a superset of the datamodel.Node interface, and has additional behaviors. +// +// A schema.TypedNode can be inspected for its schema.Type and schema.TypeKind, +// which conveys much more and richer information than the Data Model layer +// datamodel.Kind. +// +// There are many different implementations of schema.TypedNode. +// One implementation can wrap any other existing datamodel.Node (i.e., it's zero-copy) +// and promises that it has *already* been validated to match the typesystem.Type; +// another implementation similarly wraps any other existing datamodel.Node, but +// defers to the typesystem validation checking to fields that are accessed; +// and when using code generation tools, all of the generated native Golang +// types produced by the codegen will each individually implement schema.TypedNode. +// +// Typed nodes sometimes have slightly different behaviors than plain nodes: +// For example, when looking up fields on a typed node that's a struct, +// the error returned for a lookup with a key that's not a field name will +// be ErrNoSuchField (instead of ErrNotExists). +// These behaviors apply to the schema.TypedNode only and not their representations; +// continuing the example, the .Representation().LookupByString() method on +// that same node for the same key as plain `.LookupByString()` will still +// return ErrNotExists, because the representation isn't a schema.TypedNode! +type TypedNode interface { + // schema.TypedNode acts just like a regular Node for almost all purposes; + // which datamodel.Kind it acts as is determined by the TypeKind. + // (Note that the representation strategy of the type does *not* affect + // the Kind of schema.TypedNode -- rather, the representation strategy + // affects the `.Representation().Kind()`.) + // + // For example: if the `.Type().TypeKind()` of this node is "struct", + // it will act like Kind() == "map" + // (even if Type().(Struct).ReprStrategy() is "tuple"). + datamodel.Node + + // Type returns a reference to the reified schema.Type value. + Type() Type + + // Representation returns a datamodel.Node which sees the data in this node + // in its representation form. + // + // For example: if the `.Type().TypeKind()` of this node is "struct", + // `.Representation().TypeKind()` may vary based on its representation strategy: + // if the representation strategy is "map", then it will be Kind=="map"; + // if the streatgy is "tuple", then it will be Kind=="list". + Representation() datamodel.Node +} + +// schema.TypedLinkNode is a superset of the schema.TypedNode interface, and has one additional behavior. +// +// A schema.TypedLinkNode contains a hint for the appropriate node builder to use for loading data +// on the other side of the link contained within the node, so that it can be assembled +// into a node representation and validated against the schema as quickly as possible +// +// So, for example, if you wanted to support loading the other side of a link +// with a code-gen'd node builder while utilizing the automatic loading facilities +// of the traversal package, you could write a LinkNodeBuilderChooser as follows: +// +// func LinkNodeBuilderChooser(lnk datamodel.Link, lnkCtx linking.LinkContext) datamodel.NodePrototype { +// if tlnkNd, ok := lnkCtx.LinkNode.(schema.TypedLinkNode); ok { +// return tlnkNd.LinkTargetNodePrototype() +// } +// return basicnode.Prototype.Any +// } +type TypedLinkNode interface { + LinkTargetNodePrototype() datamodel.NodePrototype +} + +// TypedPrototype is a superset of the datamodel.Nodeprototype interface, and has +// additional behaviors, much like TypedNode for datamodel.Node. +type TypedPrototype interface { + datamodel.NodePrototype + + // Type returns a reference to the reified schema.Type value. + Type() Type + + // Representation returns a datamodel.NodePrototype for the representation + // form of the prototype. + Representation() datamodel.NodePrototype +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typesystem.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typesystem.go new file mode 100644 index 00000000..cace862f --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/typesystem.go @@ -0,0 +1,18 @@ +package schema + +type TypeSystem struct { + // namedTypes is the set of all named types in this universe. + // The map's key is the value's Name() property and must be unique. + // + // The IsAnonymous property is false for all values in this map that + // support the IsAnonymous property. + // + // Each Type in the universe may only refer to other types in their + // definition if those type are either A) in this namedTypes map, + // or B) are IsAnonymous==true. + namedTypes map[TypeName]Type + + // names are the same set of names stored in namedTypes, + // but in insertion order. + names []TypeName +} diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/validate.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/validate.go new file mode 100644 index 00000000..c9465261 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/schema/validate.go @@ -0,0 +1,70 @@ +package schema + +/* + Okay, so. There are several fun considerations for a "validate" method. + + --- + + There's two radically different approaches to "validate"/"reify": + + - Option 1: Look at the schema.Type info and check if a data node seems + to match it -- recursing on the type info. + - Option 2: Use the schema.Type{}.RepresentationNodeBuilder() to feed data + into it -- recursing on what the nodebuilder already expresses. + + (Option 2 also need to take a `memStorage ipld.NodeBuilder` param, btw, + for handling all the cases where we *aren't* doing codegen.) + + Option 1 provides a little more opportunity for returning multiple errors. + Option 2 will generally have a hard time with that (nodebuilers are not + necessarily in a valid state after their first error encounter). + + As a result of having these two options at all, we may indeed end up with + at least two very different functions -- despite seeming to do similar + things, their interior will radically diverge. + + --- + + We may also need to consider distinct reification paths: we may want one + that returns a new node tree which is eagerly converted to schema.TypedNode + recursively; and another that returns a lazyNode which wraps things + with their typed node constraints only as they're requested. + (Note that the latter would have interesting implications for any code + which has expectations about pointer equality consistency.) + + --- + + A further fun issue which needs consideration: well, I'll just save a snip + of prospective docs I wrote while trying to iterate on these functions: + + // Note that using Validate on a node that's already a schema.TypedNode is likely + // to be nonsensical. In many schemas, the schema.TypedNode tree is actually a + // different depth than its representational tree (e.g. unions can cause this), + + ... and that's ... that's a fairly sizable issue that needs resolving. + There's a couple of different ways to handle some of the behaviors around + unions, and some of them make the tradeoff described above, and I'm really + unsure if all the implications have been sussed out yet. We should defer + writing code that depends on this issue until gathering some more info. + + --- + + One more note: about returning multiple errors from a Validate function: + there's an upper bound of the utility of the thing. Going farther than the + first parse error is nice, but it will still hit limits: for example, + upon encountering a union and failing to match it, we can't generally + produce further errors from anywhere deeper in the tree without them being + combinatorial "if previous juncture X was type Y, then..." nonsense. + (This applies to all recursive kinds to some degree, but it's especially + rough with unions. For most of the others, it's flatly a missing field, + or an excessive field, or a leaf error; with unions it can be hard to tell.) + + --- + + And finally: both "Validate" and "Reify" methods might actually belong + in the schema.TypedNode package -- if they make *any* reference to `schema.TypedNode`, + then they have no choice (otherwise, cyclic imports would occur). + If we make a "Validate" that works purely on the schema.Type info, and + returns *only* errors: only then we can have it in the schema package. + +*/ diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/README_adapters.md b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/README_adapters.md new file mode 100644 index 00000000..7ce07748 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/README_adapters.md @@ -0,0 +1,125 @@ +Storage Adapters +================ + +The go-ipld-prime storage APIs were introduced in the v0.14.x ranges of go-ipld-prime, +which happened in fall 2021. + +There are many other pieces of code in the IPLD (and even more so, the IPFS) ecosystem +which predate this, and have interfaces that are very _similar_, but not quite exactly the same. + +In order to keep using that code, we've built a series of adapters. + +You can see these in packages beneath this one: + +- `go-ipld-prime/storage/bsadapter` is an adapter to `github.com/ipfs/go-ipfs-blockstore`. +- `go-ipld-prime/storage/dsadapter` is an adapter to `github.com/ipfs/go-datastore`. +- `go-ipld-prime/storage/bsrvadapter` is an adapter to `github.com/ipfs/go-blockservice`. + +Note that there are also other packages which implement the go-ipld-prime storage APIs, +but are not considered "adapters" -- these just implement the storage APIs directly: + +- `go-ipld-prime/storage/memstore` is a simple in-memory storage system. +- `go-ipld-prime/storage/fsstore` is a simple filesystem-backed storage system + (comparable to, and compatible with [flatfs](https://pkg.go.dev/github.com/ipfs/go-ds-flatfs), + if you're familiar with that -- but higher efficiency). + +Finally, note that there are some shared benchmarks across all this: + +- check out `go-ipld-prime/storage/benchmarks`! + + +Why structured like this? +------------------------- + +### Why is there adapter code at all? + +The `go-ipld-prime/storage` interfaces are a newer generation. + +A new generation of APIs was desirable because it unifies the old APIs, +and also because we were able to improves and update several things in the process. +(You can see some of the list of improvements in https://github.com/ipld/go-ipld-prime/pull/265, +where these APIs were first introduced.) +The new generation of APIs avoids several types present in the old APIs which forced otherwise-avoidable allocations. +(See notes later in this document about "which adapter should I use" for more on that.) +Finally, the new generation of APIs is carefully designed to support minimal implementations, +by carefully avoiding use of non-standard-library types in key API definitions, +and by keeping most advanced features behind a standardized convention of feature detection. + +Because the newer generation of APIs are not exactly the same as the multiple older APIs we're unifying and updating, +some amount of adapter code is necessary. + +(Fortunately, it's not much! But it's not "none", either.) + +### Why have this code in a shared place? + +The glue code to connect `go-datastore` and the other older APIs +to the new `go-ipld-prime/storage` APIs is fairly minimal... +but there's also no reason for anyone to write it twice, +so we want to put it somewhere easy to share. + +### Why do the adapters have their own go modules? + +A separate module is used because it's important that go-ipld-prime can be used +without forming a dependency on `go-datastore` (or the other relevant modules, per adapter). + +We want this so that there's a reasonable deprecation pathway -- it must be +possible to write new code that doesn't take on transitive dependencies to old code. + +(As a bonus, looking at the module dependency graphs makes an interestingly +clear statement about why minimal APIs that don't force transitive dependencies are a good idea!) + +### Why is this code all together in this repo? + +We put these separate modules in the same git repo as `go-ipld-prime`... because we can. + +Technically, neither the storage adapter modules nor the `go-ipld-prime` module depend on each other -- +they just have interfaces that are aligned with each other -- so it's very easy to +hold them as separate go modules in the same repo, even though that can otherwise sometimes be tricky. + +You may want to make a point of pulling updated versions of the storage adapters that you use +when pulling updates to go-ipld-prime, though. + +### Could we put these adapters upstream into the other relevant repos? + +Certainly! + +We started with them here because it seemed developmentally lower-friction. +That may change; these APIs could move. +This code is just interface satisfaction, so even having multiple copies of it is utterly harmless. + + +Which of `dsadapter` vs `bsadapter` vs `bsrvadapter` should I use? +------------------------------------------------------------------ + +None of them, ideally. +A direct implementation of the storage APIs will almost certainly be able to perform better than any of these adapters. +(Check out the `fsstore` package, for example.) + +Failing that: use the adapter matching whatever you've got on hand in your code. + +There is no correct choice. + +`dsadapter` suffers avoidable excessive allocs in processing its key type, +due to choices in the interior of `github.com/ipfs/go-datastore`. +It is also unable to support streaming operation, should you desire it. + +`bsadapter` and `bsrvadapter` both also suffer overhead due to their key type, +because they require a transformation back from the plain binary strings used in the storage API to the concrete go-cid type, +which spends some avoidable CPU time (and also, at present, causes avoidable allocs because of some interesting absenses in `go-cid`). +Additionally, they suffer avoidable allocs because they wrap the raw binary data in a "block" type, +which is an interface, and thus heap-escapes; and we need none of that in the storage APIs, and just return the raw data. +They are also unable to support streaming operation, should you desire it. + +It's best to choose the shortest path and use the adapter to whatever layer you need to get to -- +for example, if you really want to use a `go-datastore` implementation, +*don't* use `bsadapter` and have it wrap a `go-blockstore` that wraps a `go-datastore` if you can help it: +instead, use `dsadapter` and wrap the `go-datastore` without any extra layers of indirection. +You should prefer this because most of the notes above about avoidable allocs are true when +the legacy interfaces are communicating with each other, as well... +so the less you use the internal layering of the legacy interfaces, the better off you'll be. + +Using a direct implementation of the storage APIs will suffer none of these overheads, +and so will always be your best bet if possible. + +If you have to use one of these adapters, hopefully the performance overheads fall within an acceptable margin. +If not: we'll be overjoyed to accept help porting things. diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/api.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/api.go new file mode 100644 index 00000000..29a41de0 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/api.go @@ -0,0 +1,173 @@ +package storage + +import ( + "context" + "io" +) + +// --- basics ---> + +// Storage is one of the base interfaces in the storage APIs. +// This type is rarely seen by itself alone (and never useful to implement alone), +// but is included in both ReadableStorage and WritableStorage. +// Because it's included in both the of the other two useful base interfaces, +// you can define functions that work on either one of them +// by using this type to describe your function's parameters. +// +// Library functions that work with storage systems should take either +// ReadableStorage, or WritableStorage, or Storage, as a parameter, +// depending on whether the function deals with the reading of data, +// or the writing of data, or may be found on either, respectively. +// +// An implementation of Storage may also support many other methods. +// At the very least, it should also support one of either ReadableStorage or WritableStorage. +// It may support even more interfaces beyond that for additional feature detection. +// See the package-wide docs for more discussion of this design. +// +// The Storage interface does not include much of use in itself alone, +// because ReadableStorage and WritableStorage are meant to be the most used types in declarations. +// However, it does include the Has function, because that function is reasonable to require ubiquitously from all implementations, +// and it serves as a reasonable marker to make sure the Storage interface is not trivially satisfied. +type Storage interface { + Has(ctx context.Context, key string) (bool, error) +} + +// ReadableStorage is one of the base interfaces in the storage APIs; +// a storage system should implement at minimum either this, or WritableStorage, +// depending on whether it supports reading or writing. +// (One type may also implement both.) +// +// ReadableStorage implementations must at minimum provide +// a way to ask the store whether it contains a key, +// and a way to ask it to return the value. +// +// Library functions that work with storage systems should take either +// ReadableStorage, or WritableStorage, or Storage, as a parameter, +// depending on whether the function deals with the reading of data, +// or the writing of data, or may be found on either, respectively. +// +// An implementation of ReadableStorage may also support many other methods -- +// for example, it may additionally match StreamingReadableStorage, or yet more interfaces. +// Usually, you should not need to check for this yourself; instead, +// you should use the storage package's functions to ask for the desired mode of interaction. +// Those functions will will accept any ReadableStorage as an argument, +// detect the additional interfaces automatically and use them if present, +// or, fall back to synthesizing equivalent behaviors from the basics. +// See the package-wide docs for more discussion of this design. +type ReadableStorage interface { + Storage + Get(ctx context.Context, key string) ([]byte, error) +} + +// WritableStorage is one of the base interfaces in the storage APIs; +// a storage system should implement at minimum either this, or ReadableStorage, +// depending on whether it supports reading or writing. +// (One type may also implement both.) +// +// WritableStorage implementations must at minimum provide +// a way to ask the store whether it contains a key, +// and a way to put a value into storage indexed by some key. +// +// Library functions that work with storage systems should take either +// ReadableStorage, or WritableStorage, or Storage, as a parameter, +// depending on whether the function deals with the reading of data, +// or the writing of data, or may be found on either, respectively. +// +// An implementation of WritableStorage may also support many other methods -- +// for example, it may additionally match StreamingWritableStorage, or yet more interfaces. +// Usually, you should not need to check for this yourself; instead, +// you should use the storage package's functions to ask for the desired mode of interaction. +// Those functions will will accept any WritableStorage as an argument, +// detect the additional interfaces automatically and use them if present, +// or, fall back to synthesizing equivalent behaviors from the basics. +// See the package-wide docs for more discussion of this design. +type WritableStorage interface { + Storage + Put(ctx context.Context, key string, content []byte) error +} + +// --- streaming ---> + +type StreamingReadableStorage interface { + GetStream(ctx context.Context, key string) (io.ReadCloser, error) +} + +// StreamingWritableStorage is a feature-detection interface that advertises support for streaming writes. +// It is normal for APIs to use WritableStorage in their exported API surface, +// and then internally check if that value implements StreamingWritableStorage if they wish to use streaming operations. +// +// Streaming writes can be preferable to the all-in-one style of writing of WritableStorage.Put, +// because with streaming writes, the high water mark for memory usage can be kept lower. +// On the other hand, streaming writes can incur slightly higher allocation counts, +// which may cause some performance overhead when handling many small writes in sequence. +// +// The PutStream function returns three parameters: an io.Writer (as you'd expect), another function, and an error. +// The function returned is called a "WriteCommitter". +// The final error value is as usual: it will contain an error value if the write could not be begun. +// ("WriteCommitter" will be refered to as such throughout the docs, but we don't give it a named type -- +// unfortunately, this is important, because we don't want to force implementers of storage systems to import this package just for a type name.) +// +// The WriteCommitter function should be called when you're done writing, +// at which time you give it the key you want to commit the data as. +// It will close and flush any streams, and commit the data to its final location under this key. +// (If the io.Writer is also an io.WriteCloser, it is not necessary to call Close on it, +// because using the WriteCommiter will do this for you.) +// +// Because these storage APIs are meant to work well for content-addressed systems, +// the key argument is not provided at the start of the write -- it's provided at the end. +// (This gives the opportunity to be computing a hash of the contents as they're written to the stream.) +// +// As a special case, giving a key of the zero string to the WriteCommiter will +// instead close and remove any temp files, and store nothing. +// An error may still be returned from the WriteCommitter if there is an error cleaning up +// any temporary storage buffers that were created. +// +// Continuing to write to the io.Writer after calling the WriteCommitter function will result in errors. +// Calling the WriteCommitter function more than once will result in errors. +type StreamingWritableStorage interface { + PutStream(ctx context.Context) (io.Writer, func(key string) error, error) +} + +// --- other specializations ---> + +// VectorWritableStorage is an API for writing several slices of bytes at once into storage. +// It's meant a feature-detection interface; not all storage implementations need to provide this feature. +// This kind of API can be useful for maximizing performance in scenarios where +// data is already loaded completely into memory, but scattered across several non-contiguous regions. +type VectorWritableStorage interface { + PutVec(ctx context.Context, key string, blobVec [][]byte) error +} + +// PeekableStorage is a feature-detection interface which a storage implementation can use to advertise +// the ability to look at a piece of data, and return it in shared memory. +// The PeekableStorage.Peek method is essentially the same as ReadableStorage.Get -- +// but by contrast, ReadableStorage is expected to return a safe copy. +// PeekableStorage can be used when the caller knows they will not mutate the returned slice. +// +// An io.Closer is returned along with the byte slice. +// The Close method on the Closer must be called when the caller is done with the byte slice; +// otherwise, memory leaks may result. +// (Implementers of this interface may be expecting to reuse the byte slice after Close is called.) +// +// Note that Peek does not imply that the caller can use the byte slice freely; +// doing so may result in storage corruption or other undefined behavior. +type PeekableStorage interface { + Peek(ctx context.Context, key string) ([]byte, io.Closer, error) +} + +// the following are all hypothetical additional future interfaces (in varying degress of speculativeness): + +// FUTURE: an EnumerableStorage API, that lets you list all keys present? + +// FUTURE: a cleanup API (for getting rid of tmp files that might've been left behind on rough shutdown)? + +// FUTURE: a sync-forcing API? + +// FUTURE: a delete API? sure. (just document carefully what its consistency model is -- i.e. basically none.) +// (hunch: if you do want some sort of consistency model -- consider offering a whole family of methods that have some sort of generation or sequencing number on them.) + +// FUTURE: a force-overwrite API? (not useful for a content-address system. but maybe a gesture towards wider reusability is acceptable to have on offer.) + +// FUTURE: a size estimation API? (unclear if we need to standardize this, but we could. an offer, anyway.) + +// FUTURE: a GC API? (dubious -- doing it well probably crosses logical domains, and should not be tied down here.) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/doc.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/doc.go new file mode 100644 index 00000000..210ffab5 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/doc.go @@ -0,0 +1,75 @@ +// The storage package contains interfaces for storage systems, and functions for using them. +// +// These are very low-level storage primitives. +// The interfaces here deal only with raw keys and raw binary blob values. +// +// In IPLD, you can often avoid dealing with storage directly yourself, +// and instead use linking.LinkSystem to handle serialization, hashing, and storage all at once. +// (You'll hand some values that match interfaces from this package to LinkSystem when configuring it.) +// It's probably best to work at that level and above as much as possible. +// If you do need to interact with storage more directly, the read on. +// +// The most basic APIs are ReadableStorage and WritableStorage. +// When writing code that works with storage systems, these two interfaces should be seen in almost all situations: +// user code is recommended to think in terms of these types; +// functions provided by this package will accept parameters of these types and work on them; +// implementations are expected to provide these types first; +// and any new library code is recommended to keep with the theme: use these interfaces preferentially. +// +// Users should decide which actions they want to take using a storage system, +// find the appropriate function in this package (n.b., package function -- not a method on an interface! +// You will likely find one of each, with the same name: pick the package function!), +// and use that function, providing it the storage system (e.g. either ReadableStorage, WritableStorage, or sometimes just Storage) +// as a parameter. +// That function will then use feature-detection (checking for matches to the other, +// more advanced and more specific interfaces in this package) and choose the best way +// to satisfy the request; or, if it can't feature-detect any relevant features, +// the function will fall back to synthesizing the requested behavior out of the most basic API. +// Using the package functions, and letting them do the feature detection for you, +// should provide the most consistent user experience and minimize the amount of work you need to do. +// (Bonus: It also gives us a convenient place to smooth out any future library migrations for you!) +// +// If writing new APIs that are meant to work reusably for any storage implementation: +// APIs should usually be designed around accepting ReadableStorage or WritableStorage as parameters +// (depending on which direction of data flow the API is regarding). +// and use the other interfaces (e.g. StreamingReadableStorage) thereafter internally for feature detection. +// For APIs which may sometimes be found relating to either a read or a write direction of data flow, +// the Storage interface may be used in order to define a function that should accept either ReadableStorage or WritableStorage. +// In other words: when writing reusable APIs, one should follow the same pattern as this package's own functions do. +// +// Similarly, implementers of storage systems should always implement either ReadableStorage or WritableStorage first. +// Only after satisfying one of those should the implementation then move on to further supporting +// additional interfaces in this package (all of which are meant to support feature-detection). +// Beyond one of the basic two, all the other interfaces are optional: +// you can implement them if you want to advertise additional features, +// or advertise fastpaths that your storage system supports; +// but you don't have implement any of those additional interfaces if you don't want to, +// or if your implementation can't offer useful fastpaths for them. +// +// Storage systems as described by this package are allowed to make some interesting trades. +// Generally, write operations are allowed to be first-write-wins. +// Furthermore, there is no requirement that the system return an error if a subsequent write to the same key has different content. +// These rules are reasonable for a content-addressed storage system, and allow great optimizations to be made. +// +// Note that all of the interfaces in this package only use types that are present in the golang standard library. +// This is intentional, and was done very carefully. +// If implementing a storage system, you should find it possible to do so *without* importing this package. +// Because only standard library types are present in the interface contracts, +// it's possible to implement types that align with the interfaces without refering to them. +// +// Note that where keys are discussed in this package, they use the golang string type -- +// however, they may be binary. (The golang string type allows arbitrary bytes in general, +// and here, we both use that, and explicitly disavow the usual "norm" that the string type implies UTF-8. +// This is roughly the same as the practical truth that appears when using e.g. os.OpenFile and other similar functions.) +// If you are creating a storage implementation where the underlying medium does not support arbitrary binary keys, +// then it is strongly recommend that your storage implementation should support being configured with +// an "escaping function", which should typically simply be of the form `func(string) string`. +// Additional, your storage implementation's documentation should also clearly describe its internal limitations, +// so that users have enough information to write an escaping function which +// maps their domain into the domain your storage implementation can handle. +package storage + +// also note: +// LinkContext stays *out* of this package. It's a chooser-related thing. +// LinkSystem can think about it (and your callbacks over there can think about it), and that's the end of its road. +// (Future: probably LinkSystem should have SetStorage and SetupStorageChooser methods for helping you set things up -- where the former doesn't discuss LinkContext at all.) diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/funcs.go b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/funcs.go new file mode 100644 index 00000000..a39df154 --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/storage/funcs.go @@ -0,0 +1,122 @@ +package storage + +import ( + "bytes" + "context" + "fmt" + "io" +) + +/* + This file contains equivalents of every method that can be feature-detected on a storage system. + You can always call these functions, and give them the most basic storage interface, + and they'll attempt to feature-detect their way to the best possible implementation of the behavior, + or they'll fall back to synthesizing the same behavior from more basic interfaces. + + Long story short: you can always use these functions as an end user, and get the behavior you want -- + regardless of how much explicit support the storage implementation has for the exact behavior you requested. +*/ + +func Has(ctx context.Context, store Storage, key string) (bool, error) { + // Okay, not much going on here -- this function is only here for consistency of style. + return store.Has(ctx, key) +} + +func Get(ctx context.Context, store ReadableStorage, key string) ([]byte, error) { + // Okay, not much going on here -- this function is only here for consistency of style. + return store.Get(ctx, key) +} + +func Put(ctx context.Context, store WritableStorage, key string, content []byte) error { + // Okay, not much going on here -- this function is only here for consistency of style. + return store.Put(ctx, key, content) +} + +// GetStream returns a streaming reader. +// This function will feature-detect the StreamingReadableStorage interface, and use that if possible; +// otherwise it will fall back to using basic ReadableStorage methods transparently +// (at the cost of loading all the data into memory at once and up front). +func GetStream(ctx context.Context, store ReadableStorage, key string) (io.ReadCloser, error) { + // Prefer the feature itself, first. + if streamable, ok := store.(StreamingReadableStorage); ok { + return streamable.GetStream(ctx, key) + } + // Fallback to basic. + blob, err := store.Get(ctx, key) + return noopCloser{bytes.NewReader(blob)}, err +} + +// PutStream returns an io.Writer and a WriteCommitter callback. +// (See the docs on StreamingWritableStorage.PutStream for details on what that means.) +// This function will feature-detect the StreamingWritableStorage interface, and use that if possible; +// otherwise it will fall back to using basic WritableStorage methods transparently +// (at the cost of needing to buffer all of the content in memory while the write is in progress). +func PutStream(ctx context.Context, store WritableStorage) (io.Writer, func(key string) error, error) { + // Prefer the feature itself, first. + if streamable, ok := store.(StreamingWritableStorage); ok { + return streamable.PutStream(ctx) + } + // Fallback to basic. + var buf bytes.Buffer + var written bool + return &buf, func(key string) error { + if written { + return fmt.Errorf("WriteCommitter already used") + } + written = true + return store.Put(ctx, key, buf.Bytes()) + }, nil +} + +// PutVec is an API for writing several slices of bytes at once into storage. +// This kind of API can be useful for maximizing performance in scenarios where +// data is already loaded completely into memory, but scattered across several non-contiguous regions. +// This function will feature-detect the VectorWritableStorage interface, and use that if possible; +// otherwise it will fall back to using StreamingWritableStorage, +// or failing that, fall further back to basic WritableStorage methods, transparently. +func PutVec(ctx context.Context, store WritableStorage, key string, blobVec [][]byte) error { + // Prefer the feature itself, first. + if putvable, ok := store.(VectorWritableStorage); ok { + return putvable.PutVec(ctx, key, blobVec) + } + // Fallback to streaming mode. + // ... or, fallback to basic, and use emulated streaming. Still presumably preferable to doing a big giant memcopy. + // Conveniently, the PutStream function makes that transparent for our implementation, too. + wr, wrcommit, err := PutStream(ctx, store) + if err != nil { + return err + } + for _, blob := range blobVec { + _, err := wr.Write(blob) + if err != nil { + return err + } + } + return wrcommit(key) +} + +// Peek accessess the same data as Get, but indicates that the caller promises not to mutate the returned byte slice. +// (By contrast, Get is expected to return a safe copy.) +// This function will feature-detect the PeekableStorage interface, and use that if possible; +// otherwise it will fall back to using basic ReadableStorage methods transparently +// (meaning that a no-copy fastpath simply wasn't available). +// +// An io.Closer is returned along with the byte slice. +// The Close method on the Closer must be called when the caller is done with the byte slice; +// otherwise, memory leaks may result. +// (Implementers of this interface may be expecting to reuse the byte slice after Close is called.) +func Peek(ctx context.Context, store ReadableStorage, key string) ([]byte, io.Closer, error) { + // Prefer the feature itself, first. + if peekable, ok := store.(PeekableStorage); ok { + return peekable.Peek(ctx, key) + } + // Fallback to basic. + bs, err := store.Get(ctx, key) + return bs, noopCloser{nil}, err +} + +type noopCloser struct { + io.Reader +} + +func (noopCloser) Close() error { return nil } diff --git a/fungible/cc/vendor/github.com/ipld/go-ipld-prime/version.json b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/version.json new file mode 100644 index 00000000..0a972ecb --- /dev/null +++ b/fungible/cc/vendor/github.com/ipld/go-ipld-prime/version.json @@ -0,0 +1,3 @@ +{ + "version": "v0.19.0" +} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/.gitignore b/fungible/cc/vendor/github.com/minio/blake2b-simd/.gitignore deleted file mode 100644 index c56069fe..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.test \ No newline at end of file diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/.travis.yml b/fungible/cc/vendor/github.com/minio/blake2b-simd/.travis.yml deleted file mode 100644 index 545066eb..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -sudo: required -dist: trusty -language: go - -os: -- linux -- osx - -osx_image: xcode7.2 - -go: -- 1.6 -- 1.5 - -env: -- ARCH=x86_64 -- ARCH=i686 - -script: -- diff -au <(gofmt -d .) <(printf "") -- go test -race -v ./... diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/README.md b/fungible/cc/vendor/github.com/minio/blake2b-simd/README.md deleted file mode 100644 index 31fcbf74..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/README.md +++ /dev/null @@ -1,144 +0,0 @@ -BLAKE2b-SIMD -============ - -Pure Go implementation of BLAKE2b using SIMD optimizations. - -Introduction ------------- - -This package was initially based on the pure go [BLAKE2b](https://github.com/dchest/blake2b) implementation of Dmitry Chestnykh and merged with the (`cgo` dependent) AVX optimized [BLAKE2](https://github.com/codahale/blake2) implementation (which in turn is based on the [official implementation](https://github.com/BLAKE2/BLAKE2). It does so by using [Go's Assembler](https://golang.org/doc/asm) for amd64 architectures with a golang only fallback for other architectures. - -In addition to AVX there is also support for AVX2 as well as SSE. Best performance is obtained with AVX2 which gives roughly a **4X** performance increase approaching hashing speeds of **1GB/sec** on a single core. - -Benchmarks ----------- - -This is a summary of the performance improvements. Full details are shown below. - -| Technology | 128K | -| ---------- |:-----:| -| AVX2 | 3.94x | -| AVX | 3.28x | -| SSE | 2.85x | - -asm2plan9s ----------- - -In order to be able to work more easily with AVX2/AVX instructions, a separate tool was developed to convert AVX2/AVX instructions into the corresponding BYTE sequence as accepted by Go assembly. See [asm2plan9s](https://github.com/minio/asm2plan9s) for more information. - -bt2sum ------- - -[bt2sum](https://github.com/s3git/bt2sum) is a utility that takes advantages of the BLAKE2b SIMD optimizations to compute check sums using the BLAKE2 Tree hashing mode in so called 'unlimited fanout' mode. - -Technical details ------------------ - -BLAKE2b is a hashing algorithm that operates on 64-bit integer values. The AVX2 version uses the 256-bit wide YMM registers in order to essentially process four operations in parallel. AVX and SSE operate on 128-bit values simultaneously (two operations in parallel). Below are excerpts from `compressAvx2_amd64.s`, `compressAvx_amd64.s`, and `compress_generic.go` respectively. - -``` - VPADDQ YMM0,YMM0,YMM1 /* v0 += v4, v1 += v5, v2 += v6, v3 += v7 */ -``` - -``` - VPADDQ XMM0,XMM0,XMM2 /* v0 += v4, v1 += v5 */ - VPADDQ XMM1,XMM1,XMM3 /* v2 += v6, v3 += v7 */ -``` - -``` - v0 += v4 - v1 += v5 - v2 += v6 - v3 += v7 -``` - -Detailed benchmarks -------------------- - -Example performance metrics were generated on Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz - 6 physical cores, 12 logical cores running Ubuntu GNU/Linux with kernel version 4.4.0-24-generic (vanilla with no optimizations). - -### AVX2 - -``` -$ benchcmp go.txt avx2.txt -benchmark old ns/op new ns/op delta -BenchmarkHash64-12 1481 849 -42.67% -BenchmarkHash128-12 1428 746 -47.76% -BenchmarkHash1K-12 6379 2227 -65.09% -BenchmarkHash8K-12 37219 11714 -68.53% -BenchmarkHash32K-12 140716 35935 -74.46% -BenchmarkHash128K-12 561656 142634 -74.60% - -benchmark old MB/s new MB/s speedup -BenchmarkHash64-12 43.20 75.37 1.74x -BenchmarkHash128-12 89.64 171.35 1.91x -BenchmarkHash1K-12 160.52 459.69 2.86x -BenchmarkHash8K-12 220.10 699.32 3.18x -BenchmarkHash32K-12 232.87 911.85 3.92x -BenchmarkHash128K-12 233.37 918.93 3.94x -``` - -### AVX2: Comparison to other hashing techniques - -``` -$ go test -bench=Comparison -BenchmarkComparisonMD5-12 1000 1726121 ns/op 607.48 MB/s -BenchmarkComparisonSHA1-12 500 2005164 ns/op 522.94 MB/s -BenchmarkComparisonSHA256-12 300 5531036 ns/op 189.58 MB/s -BenchmarkComparisonSHA512-12 500 3423030 ns/op 306.33 MB/s -BenchmarkComparisonBlake2B-12 1000 1232690 ns/op 850.64 MB/s -``` - -Benchmarks below were generated on a MacBook Pro with a 2.7 GHz Intel Core i7. - -### AVX - -``` -$ benchcmp go.txt avx.txt -benchmark old ns/op new ns/op delta -BenchmarkHash64-8 813 458 -43.67% -BenchmarkHash128-8 766 401 -47.65% -BenchmarkHash1K-8 4881 1763 -63.88% -BenchmarkHash8K-8 36127 12273 -66.03% -BenchmarkHash32K-8 140582 43155 -69.30% -BenchmarkHash128K-8 567850 173246 -69.49% - -benchmark old MB/s new MB/s speedup -BenchmarkHash64-8 78.63 139.57 1.78x -BenchmarkHash128-8 166.98 318.73 1.91x -BenchmarkHash1K-8 209.76 580.68 2.77x -BenchmarkHash8K-8 226.76 667.46 2.94x -BenchmarkHash32K-8 233.09 759.29 3.26x -BenchmarkHash128K-8 230.82 756.56 3.28x -``` - -### SSE - -``` -$ benchcmp go.txt sse.txt -benchmark old ns/op new ns/op delta -BenchmarkHash64-8 813 478 -41.21% -BenchmarkHash128-8 766 411 -46.34% -BenchmarkHash1K-8 4881 1870 -61.69% -BenchmarkHash8K-8 36127 12427 -65.60% -BenchmarkHash32K-8 140582 49512 -64.78% -BenchmarkHash128K-8 567850 199040 -64.95% - -benchmark old MB/s new MB/s speedup -BenchmarkHash64-8 78.63 133.78 1.70x -BenchmarkHash128-8 166.98 311.23 1.86x -BenchmarkHash1K-8 209.76 547.37 2.61x -BenchmarkHash8K-8 226.76 659.20 2.91x -BenchmarkHash32K-8 233.09 661.81 2.84x -BenchmarkHash128K-8 230.82 658.52 2.85x -``` - -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. diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/appveyor.yml b/fungible/cc/vendor/github.com/minio/blake2b-simd/appveyor.yml deleted file mode 100644 index 77595feb..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/appveyor.yml +++ /dev/null @@ -1,32 +0,0 @@ -# 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\blake2b-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 diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/blake2b.go b/fungible/cc/vendor/github.com/minio/blake2b-simd/blake2b.go deleted file mode 100644 index 538466a1..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/blake2b.go +++ /dev/null @@ -1,301 +0,0 @@ -// Written in 2012 by Dmitry Chestnykh. -// -// To the extent possible under law, the author have dedicated all copyright -// and related and neighboring rights to this software to the public domain -// worldwide. This software is distributed without any warranty. -// http://creativecommons.org/publicdomain/zero/1.0/ - -// Package blake2b implements BLAKE2b cryptographic hash function. -package blake2b - -import ( - "encoding/binary" - "errors" - "hash" -) - -const ( - BlockSize = 128 // block size of algorithm - Size = 64 // maximum digest size - SaltSize = 16 // maximum salt size - PersonSize = 16 // maximum personalization string size - KeySize = 64 // maximum size of key -) - -type digest struct { - h [8]uint64 // current chain value - t [2]uint64 // message bytes counter - f [2]uint64 // finalization flags - x [BlockSize]byte // buffer for data not yet compressed - nx int // number of bytes in buffer - - ih [8]uint64 // initial chain value (after config) - paddedKey [BlockSize]byte // copy of key, padded with zeros - isKeyed bool // indicates whether hash was keyed - size uint8 // digest size in bytes - isLastNode bool // indicates processing of the last node in tree hashing -} - -// Initialization values. -var iv = [8]uint64{ - 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, - 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, 0x9b05688c2b3e6c1f, - 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, -} - -// Config is used to configure hash function parameters and keying. -// All parameters are optional. -type Config struct { - Size uint8 // digest size (if zero, default size of 64 bytes is used) - Key []byte // key for prefix-MAC - Salt []byte // salt (if < 16 bytes, padded with zeros) - Person []byte // personalization (if < 16 bytes, padded with zeros) - Tree *Tree // parameters for tree hashing -} - -// Tree represents parameters for tree hashing. -type Tree struct { - Fanout uint8 // fanout - MaxDepth uint8 // maximal depth - LeafSize uint32 // leaf maximal byte length (0 for unlimited) - NodeOffset uint64 // node offset (0 for first, leftmost or leaf) - NodeDepth uint8 // node depth (0 for leaves) - InnerHashSize uint8 // inner hash byte length - IsLastNode bool // indicates processing of the last node of layer -} - -var ( - defaultConfig = &Config{Size: Size} - config256 = &Config{Size: 32} -) - -func verifyConfig(c *Config) error { - if c.Size > Size { - return errors.New("digest size is too large") - } - if len(c.Key) > KeySize { - return errors.New("key is too large") - } - if len(c.Salt) > SaltSize { - // Smaller salt is okay: it will be padded with zeros. - return errors.New("salt is too large") - } - if len(c.Person) > PersonSize { - // Smaller personalization is okay: it will be padded with zeros. - return errors.New("personalization is too large") - } - if c.Tree != nil { - if c.Tree.Fanout == 1 { - return errors.New("fanout of 1 is not allowed in tree mode") - } - if c.Tree.MaxDepth < 2 { - return errors.New("incorrect tree depth") - } - if c.Tree.InnerHashSize < 1 || c.Tree.InnerHashSize > Size { - return errors.New("incorrect tree inner hash size") - } - } - return nil -} - -// New returns a new hash.Hash configured with the given Config. -// Config can be nil, in which case the default one is used, calculating 64-byte digest. -// Returns non-nil error if Config contains invalid parameters. -func New(c *Config) (hash.Hash, error) { - if c == nil { - c = defaultConfig - } else { - if c.Size == 0 { - // Set default size if it's zero. - c.Size = Size - } - if err := verifyConfig(c); err != nil { - return nil, err - } - } - d := new(digest) - d.initialize(c) - return d, nil -} - -// initialize initializes digest with the given -// config, which must be non-nil and verified. -func (d *digest) initialize(c *Config) { - // Create parameter block. - var p [BlockSize]byte - p[0] = c.Size - p[1] = uint8(len(c.Key)) - if c.Salt != nil { - copy(p[32:], c.Salt) - } - if c.Person != nil { - copy(p[48:], c.Person) - } - if c.Tree != nil { - p[2] = c.Tree.Fanout - p[3] = c.Tree.MaxDepth - binary.LittleEndian.PutUint32(p[4:], c.Tree.LeafSize) - binary.LittleEndian.PutUint64(p[8:], c.Tree.NodeOffset) - p[16] = c.Tree.NodeDepth - p[17] = c.Tree.InnerHashSize - } else { - p[2] = 1 - p[3] = 1 - } - - // Initialize. - d.size = c.Size - for i := 0; i < 8; i++ { - d.h[i] = iv[i] ^ binary.LittleEndian.Uint64(p[i*8:]) - } - if c.Tree != nil && c.Tree.IsLastNode { - d.isLastNode = true - } - - // Process key. - if c.Key != nil { - copy(d.paddedKey[:], c.Key) - d.Write(d.paddedKey[:]) - d.isKeyed = true - } - // Save a copy of initialized state. - copy(d.ih[:], d.h[:]) -} - -// New512 returns a new hash.Hash computing the BLAKE2b 64-byte checksum. -func New512() hash.Hash { - d := new(digest) - d.initialize(defaultConfig) - return d -} - -// New256 returns a new hash.Hash computing the BLAKE2b 32-byte checksum. -func New256() hash.Hash { - d := new(digest) - d.initialize(config256) - return d -} - -// NewMAC returns a new hash.Hash computing BLAKE2b prefix- -// Message Authentication Code of the given size in bytes -// (up to 64) with the given key (up to 64 bytes in length). -func NewMAC(outBytes uint8, key []byte) hash.Hash { - d, err := New(&Config{Size: outBytes, Key: key}) - if err != nil { - panic(err.Error()) - } - return d -} - -// Reset resets the state of digest to the initial state -// after configuration and keying. -func (d *digest) Reset() { - copy(d.h[:], d.ih[:]) - d.t[0] = 0 - d.t[1] = 0 - d.f[0] = 0 - d.f[1] = 0 - d.nx = 0 - if d.isKeyed { - d.Write(d.paddedKey[:]) - } -} - -// Size returns the digest size in bytes. -func (d *digest) Size() int { return int(d.size) } - -// BlockSize returns the algorithm block size in bytes. -func (d *digest) BlockSize() int { return BlockSize } - -func (d *digest) Write(p []byte) (nn int, err error) { - nn = len(p) - left := BlockSize - d.nx - if len(p) > left { - // Process buffer. - copy(d.x[d.nx:], p[:left]) - p = p[left:] - compress(d, d.x[:]) - d.nx = 0 - } - // Process full blocks except for the last one. - if len(p) > BlockSize { - n := len(p) &^ (BlockSize - 1) - if n == len(p) { - n -= BlockSize - } - compress(d, p[:n]) - p = p[n:] - } - // Fill buffer. - d.nx += copy(d.x[d.nx:], p) - return -} - -// Sum returns the calculated checksum. -func (d *digest) Sum(in []byte) []byte { - // Make a copy of d so that caller can keep writing and summing. - d0 := *d - hash := d0.checkSum() - return append(in, hash[:d0.size]...) -} - -func (d *digest) checkSum() [Size]byte { - // Do not create unnecessary copies of the key. - if d.isKeyed { - for i := 0; i < len(d.paddedKey); i++ { - d.paddedKey[i] = 0 - } - } - - dec := BlockSize - uint64(d.nx) - if d.t[0] < dec { - d.t[1]-- - } - d.t[0] -= dec - - // Pad buffer with zeros. - for i := d.nx; i < len(d.x); i++ { - d.x[i] = 0 - } - // Set last block flag. - d.f[0] = 0xffffffffffffffff - if d.isLastNode { - d.f[1] = 0xffffffffffffffff - } - // Compress last block. - compress(d, d.x[:]) - - var out [Size]byte - j := 0 - for _, s := range d.h[:(d.size-1)/8+1] { - out[j+0] = byte(s >> 0) - out[j+1] = byte(s >> 8) - out[j+2] = byte(s >> 16) - out[j+3] = byte(s >> 24) - out[j+4] = byte(s >> 32) - out[j+5] = byte(s >> 40) - out[j+6] = byte(s >> 48) - out[j+7] = byte(s >> 56) - j += 8 - } - return out -} - -// Sum512 returns a 64-byte BLAKE2b hash of data. -func Sum512(data []byte) [64]byte { - var d digest - d.initialize(defaultConfig) - d.Write(data) - return d.checkSum() -} - -// Sum256 returns a 32-byte BLAKE2b hash of data. -func Sum256(data []byte) (out [32]byte) { - var d digest - d.initialize(config256) - d.Write(data) - sum := d.checkSum() - copy(out[:], sum[:32]) - return -} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.go b/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.go deleted file mode 100644 index ec53599f..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.go +++ /dev/null @@ -1,47 +0,0 @@ -//+build !noasm -//+build !appengine - -/* - * 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 blake2b - -//go:noescape -func compressAVX2Loop(p []uint8, in, iv, t, f, shffle, out []uint64) - -func compressAVX2(d *digest, p []uint8) { - var ( - in [8]uint64 - out [8]uint64 - shffle [8]uint64 - ) - - // vector for PSHUFB instruction - shffle[0] = 0x0201000706050403 - shffle[1] = 0x0a09080f0e0d0c0b - shffle[2] = 0x0201000706050403 - shffle[3] = 0x0a09080f0e0d0c0b - shffle[4] = 0x0100070605040302 - shffle[5] = 0x09080f0e0d0c0b0a - shffle[6] = 0x0100070605040302 - shffle[7] = 0x09080f0e0d0c0b0a - - in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7] = d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] - - compressAVX2Loop(p, in[:], iv[:], d.t[:], d.f[:], shffle[:], out[:]) - - d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7] -} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.s b/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.s deleted file mode 100644 index 24df234b..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.s +++ /dev/null @@ -1,671 +0,0 @@ -//+build !noasm !appengine - -// -// 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 AVX2 implementation from https://github.com/sneves/blake2-avx2/blob/master/blake2b-common.h -// -// Use github.com/fwessels/asm2plan9s on this file to assemble instructions to their Plan9 equivalent -// -// Assembly code below essentially follows the ROUND macro (see blake2b-round.h) which is defined as: -// #define ROUND(r) \ -// LOAD_MSG_ ##r ##_1(b0, b1); \ -// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// LOAD_MSG_ ##r ##_2(b0, b1); \ -// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ -// LOAD_MSG_ ##r ##_3(b0, b1); \ -// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// LOAD_MSG_ ##r ##_4(b0, b1); \ -// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); -// -// as well as the go equivalent in https://github.com/dchest/blake2b/blob/master/block.go -// -// As in the macro, G1/G2 in the 1st and 2nd half are identical (so literal copy of assembly) -// -// Rounds are also the same, except for the loading of the message (and rounds 1 & 11 and -// rounds 2 & 12 are identical) -// - -#define G1 \ - \ // G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); - BYTE $0xc5; BYTE $0xfd; BYTE $0xd4; BYTE $0xc4 \ // VPADDQ YMM0,YMM0,YMM4 /* v0 += m[0], v1 += m[2], v2 += m[4], v3 += m[6] */ - BYTE $0xc5; BYTE $0xfd; BYTE $0xd4; BYTE $0xc1 \ // VPADDQ YMM0,YMM0,YMM1 /* v0 += v4, v1 += v5, v2 += v6, v3 += v7 */ - BYTE $0xc5; BYTE $0xe5; BYTE $0xef; BYTE $0xd8 \ // VPXOR YMM3,YMM3,YMM0 /* v12 ^= v0, v13 ^= v1, v14 ^= v2, v15 ^= v3 */ - BYTE $0xc5; BYTE $0xfd; BYTE $0x70; BYTE $0xdb; BYTE $0xb1 \ // VPSHUFD YMM3,YMM3,0xb1 /* v12 = v12<<(64-32) | v12>>32, v13 = */ - BYTE $0xc5; BYTE $0xed; BYTE $0xd4; BYTE $0xd3 \ // VPADDQ YMM2,YMM2,YMM3 /* v8 += v12, v9 += v13, v10 += v14, v11 += v15 */ - BYTE $0xc5; BYTE $0xf5; BYTE $0xef; BYTE $0xca \ // VPXOR YMM1,YMM1,YMM2 /* v4 ^= v8, v5 ^= v9, v6 ^= v10, v7 ^= v11 */ - BYTE $0xc4; BYTE $0xe2; BYTE $0x75; BYTE $0x00; BYTE $0xce // VPSHUFB YMM1,YMM1,YMM6 /* v4 = v4<<(64-24) | v4>>24, ..., ..., v7 = v7<<(64-24) | v7>>24 */ - -#define G2 \ - BYTE $0xc5; BYTE $0xfd; BYTE $0xd4; BYTE $0xc5 \ // VPADDQ YMM0,YMM0,YMM5 /* v0 += m[1], v1 += m[3], v2 += m[5], v3 += m[7] */ - BYTE $0xc5; BYTE $0xfd; BYTE $0xd4; BYTE $0xc1 \ // VPADDQ YMM0,YMM0,YMM1 /* v0 += v4, v1 += v5, v2 += v6, v3 += v7 */ - BYTE $0xc5; BYTE $0xe5; BYTE $0xef; BYTE $0xd8 \ // VPXOR YMM3,YMM3,YMM0 /* v12 ^= v0, v13 ^= v1, v14 ^= v2, v15 ^= v3 */ - BYTE $0xc4; BYTE $0xe2; BYTE $0x65; BYTE $0x00; BYTE $0xdf \ // VPSHUFB YMM3,YMM3,YMM7 /* v12 = v12<<(64-16) | v12>>16, ..., ..., v15 = v15<<(64-16) | v15>>16 */ - BYTE $0xc5; BYTE $0xed; BYTE $0xd4; BYTE $0xd3 \ // VPADDQ YMM2,YMM2,YMM3 /* v8 += v12, v9 += v13, v10 += v14, v11 += v15 */ - BYTE $0xc5; BYTE $0xf5; BYTE $0xef; BYTE $0xca \ // VPXOR YMM1,YMM1,YMM2 /* v4 ^= v8, v5 ^= v9, v6 ^= v10, v7 ^= v11 */ - BYTE $0xc5; BYTE $0x75; BYTE $0xd4; BYTE $0xf9 \ // VPADDQ YMM15,YMM1,YMM1 /* temp reg = reg*2 */ - BYTE $0xc5; BYTE $0xf5; BYTE $0x73; BYTE $0xd1; BYTE $0x3f \ // VPSRLQ YMM1,YMM1,0x3f /* reg = reg>>63 */ - BYTE $0xc4; BYTE $0xc1; BYTE $0x75; BYTE $0xef; BYTE $0xcf // VPXOR YMM1,YMM1,YMM15 /* ORed together: v4 = v4<<(64-63) | v4>>63, v5 = v5<<(64-63) | v5>>63 */ - -#define DIAGONALIZE \ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb \ // VPERMQ YMM3, YMM3, 0x93 - BYTE $0x93 \ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2 \ // VPERMQ YMM2, YMM2, 0x4e - BYTE $0x4e \ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 \ // VPERMQ YMM1, YMM1, 0x39 - BYTE $0x39 \ - // DO NOT DELETE -- macro delimiter (previous line extended) - -#define UNDIAGONALIZE \ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb \ // VPERMQ YMM3, YMM3, 0x39 - BYTE $0x39 \ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2 \ // VPERMQ YMM2, YMM2, 0x4e - BYTE $0x4e \ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 \ // VPERMQ YMM1, YMM1, 0x93 - BYTE $0x93 \ - // DO NOT DELETE -- macro delimiter (previous line extended) - -#define LOAD_SHUFFLE \ - MOVQ shffle+120(FP), SI \ // SI: &shuffle - BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x36 \ // VMOVDQU YMM6, [rsi] - BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x7e; BYTE $0x20 // VMOVDQU YMM7, 32[rsi] - -// func compressAVX2Loop(compressSSE(p []uint8, in, iv, t, f, shffle, out []uint64) -TEXT 路compressAVX2Loop(SB), 7, $0 - - // REGISTER USE - // Y0 - Y3: v0 - v15 - // Y4 - Y5: m[0] - m[7] - // Y6 - Y7: shuffle value - // Y8 - Y9: temp registers - // Y10 -Y13: copy of full message - // Y15: temp register - - // Load digest - MOVQ in+24(FP), SI // SI: &in - BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x06 // VMOVDQU YMM0, [rsi] - BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x4e; BYTE $0x20 // VMOVDQU YMM1, 32[rsi] - - // Already store digest into &out (so we can reload it later generically) - MOVQ out+144(FP), SI // SI: &out - BYTE $0xc5; BYTE $0xfe; BYTE $0x7f; BYTE $0x06 // VMOVDQU [rsi], YMM0 - BYTE $0xc5; BYTE $0xfe; BYTE $0x7f; BYTE $0x4e; BYTE $0x20 // VMOVDQU 32[rsi], YMM1 - - // Initialize message pointer and loop counter - MOVQ message+0(FP), DX // DX: &p (message) - MOVQ message_len+8(FP), R8 // R8: len(message) - SHRQ $7, R8 // len(message) / 128 - CMPQ R8, $0 - JEQ complete - -loop: - // Increment counter - MOVQ t+72(FP), SI // SI: &t - MOVQ 0(SI), R9 // - ADDQ $128, R9 // /* d.t[0] += BlockSize */ - MOVQ R9, 0(SI) // - CMPQ R9, $128 // /* if d.t[0] < BlockSize { */ - JGE noincr // - MOVQ 8(SI), R9 // - ADDQ $1, R9 // /* d.t[1]++ */ - MOVQ R9, 8(SI) // -noincr: // /* } */ - - // Load initialization vector - MOVQ iv+48(FP), SI // SI: &iv - BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x16 // VMOVDQU YMM2, [rsi] - BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x5e; BYTE $0x20 // VMOVDQU YMM3, 32[rsi] - MOVQ t+72(FP), SI // SI: &t - BYTE $0xc4; BYTE $0x63; BYTE $0x3d; BYTE $0x38; BYTE $0x06 // VINSERTI128 YMM8, YMM8, [rsi], 0 /* Y8 = t[0]+t[1] */ - BYTE $0x00 - MOVQ t+96(FP), SI // SI: &f - BYTE $0xc4; BYTE $0x63; BYTE $0x3d; BYTE $0x38; BYTE $0x06 // VINSERTI128 YMM8, YMM8, [rsi], 1 /* Y8 = t[0]+t[1]+f[0]+f[1] */ - BYTE $0x01 - BYTE $0xc4; BYTE $0xc1; BYTE $0x65; BYTE $0xef; BYTE $0xd8 // VPXOR YMM3,YMM3,YMM8 /* Y3 = Y3 ^ Y8 */ - - BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x12 // VMOVDQU YMM10, [rdx] /* Y10 = m[0]+ m[1]+ m[2]+ m[3] */ - BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x5a; BYTE $0x20 // VMOVDQU YMM11, 32[rdx] /* Y11 = m[4]+ m[5]+ m[6]+ m[7] */ - BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x62; BYTE $0x40 // VMOVDQU YMM12, 64[rdx] /* Y12 = m[8]+ m[9]+m[10]+m[11] */ - BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x6a; BYTE $0x60 // VMOVDQU YMM13, 96[rdx] /* Y13 = m[12]+m[13]+m[14]+m[15] */ - - LOAD_SHUFFLE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0xc1; BYTE $0x2d; BYTE $0x6c; BYTE $0xe3 // VPUNPCKLQDQ YMM4, YMM10, YMM11 /* m[0], m[4], m[2], m[6] */ - BYTE $0xc4; BYTE $0xc1; BYTE $0x2d; BYTE $0x6d; BYTE $0xeb // VPUNPCKHQDQ YMM5, YMM10, YMM11 /* m[1], m[5], m[3], m[7] */ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xe4 // VPERMQ YMM4, YMM4, 0xd8 /* 0x1101 1000 = 0xd8 */ - BYTE $0xd8 - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xed // VPERMQ YMM5, YMM5, 0xd8 /* 0x1101 1000 = 0xd8 */ - BYTE $0xd8 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0xc1; BYTE $0x1d; BYTE $0x6c; BYTE $0xe5 // VPUNPCKLQDQ YMM4, YMM12, YMM13 /* m[8], m[12], m[10], m[14] */ - BYTE $0xc4; BYTE $0xc1; BYTE $0x1d; BYTE $0x6d; BYTE $0xed // VPUNPCKHQDQ YMM5, YMM12, YMM13 /* m[9], m[13], m[11], m[15] */ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xe4 // VPERMQ YMM4, YMM4, 0xd8 /* 0x1101 1000 = 0xd8 */ - BYTE $0xd8 - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xed // VPERMQ YMM5, YMM5, 0xd8 /* 0x1101 1000 = 0xd8 */ - BYTE $0xd8 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 2 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM11, YMM13 /* m[4], ____, ____, m[14] */ - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x03 /* m[14], m[4], ____, ____ */ /* xxxx 0011 = 0x03 */ - BYTE $0x03 - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xcd // VPUNPCKHQDQ YMM9, YMM12, YMM13 /* m[9], m[13], ____, ____ */ - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 /* m[9], m[13], ____, ____ */ /* 0010 0000 = 0x20 */ - BYTE $0x20 - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc4 // VPERMQ YMM8, YMM12, 0x02 /* m[10], m[8], ____, ____ */ /* xxxx 0010 = 0x02 */ - BYTE $0x02 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x30 /* ____, ____, m[15], ____ */ /* xx11 xxxx = 0x30 */ - BYTE $0x30 - BYTE $0xc4; BYTE $0x41; BYTE $0x35; BYTE $0x6c; BYTE $0xcb // VPUNPCKLQDQ YMM9, YMM9, YMM11 /* ____, ____, m[15], m[6] */ - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 /* m[9], m[13], m[15], m[6] */ /* 0011 0000 = 0x30 */ - BYTE $0x30 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc2 // VPERMQ YMM8, YMM10, 0x01 /* m[1], m[0], ____, ____ */ /* xxxx 0001 = 0x01 */ - BYTE $0x01 - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM11, YMM12 /* m[5], ____, ____, m[11] */ - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x03 /* m[11], m[5], ____, ____ */ /* xxxx 0011 = 0x03 */ - BYTE $0x03 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 /* m[1], m[0], m[11], m[5] */ /* 0010 0000 = 0x20 */ - BYTE $0x20 - - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM10, YMM13 /* ___, m[12], m[2], ____ */ - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x09 /* m[12], m[2], ____, ____ */ /* xxxx 1001 = 0x09 */ - BYTE $0x09 - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM11, YMM10 /* ____, ____, m[7], m[3] */ - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 /* m[9], m[13], m[15], m[6] */ /* 0011 0000 = 0x30 */ - BYTE $0x30 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 3 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc5 // VPERMQ YMM8, YMM13, 0x00 - BYTE $0x00 - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc0 // VPUNPCKHQDQ YMM8, YMM12, YMM8 - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xcd // VPUNPCKHQDQ YMM9, YMM11, YMM13 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x21 - BYTE $0x21 - - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6c; BYTE $0xc2 // VPUNPCKLQDQ YMM8, YMM12, YMM10 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x55 - BYTE $0x55 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM10, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 - BYTE $0x30 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc2 // VPERMQ YMM8, YMM10, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM12, YMM8 - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM11, YMM12 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 - BYTE $0x31 - - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM13, YMM11 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcb // VPERMQ YMM9, YMM11, 0x00 - BYTE $0x00 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM10, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 - BYTE $0x21 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 4 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xc2 // VPUNPCKHQDQ YMM8, YMM11, YMM10 - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM13, YMM12 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x21 - BYTE $0x21 - - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc2 // VPUNPCKHQDQ YMM8, YMM12, YMM10 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x08 - BYTE $0x08 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x20 - BYTE $0x20 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc3 // VPERMQ YMM8, YMM11, 0x55 - BYTE $0x55 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM10, YMM8 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM11, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x21 - BYTE $0x21 - - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc4 // VPUNPCKLQDQ YMM8, YMM11, YMM12 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xcc // VPUNPCKLQDQ YMM9, YMM10, YMM12 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 - BYTE $0x21 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 5 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc3 // VPUNPCKHQDQ YMM8, YMM12, YMM11 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xcc // VPUNPCKLQDQ YMM9, YMM10, YMM12 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x30 - BYTE $0x30 - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc3 // VPERMQ YMM8, YMM11, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM10, YMM8 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM11, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x20 - BYTE $0x20 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc4 // VPERMQ YMM8, YMM12, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM13, YMM8 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xca // VPERMQ YMM9, YMM10, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM11, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 - BYTE $0x31 - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc5 // VPERMQ YMM8, YMM13, 0x00 - BYTE $0x00 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xc0 // VPUNPCKHQDQ YMM8, YMM10, YMM8 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x55 - BYTE $0x55 - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM12, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x20 - BYTE $0x20 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 6 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM10, YMM11 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xcc // VPUNPCKLQDQ YMM9, YMM10, YMM12 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x21 - BYTE $0x21 - - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc4 // VPUNPCKLQDQ YMM8, YMM13, YMM12 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM12, YMM10 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 - BYTE $0x30 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc3 // VPERMQ YMM8, YMM11, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM13, YMM10 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x30 - BYTE $0x30 - - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc3 // VPUNPCKHQDQ YMM8, YMM13, YMM11 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0x55 - BYTE $0x55 - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM13, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 - BYTE $0x30 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 7 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc2 // VPERMQ YMM8, YMM10, 0x55 - BYTE $0x55 - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM13, YMM8 - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xcb // VPUNPCKLQDQ YMM9, YMM13, YMM11 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x30 - BYTE $0x30 - - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xc5 // VPUNPCKHQDQ YMM8, YMM11, YMM13 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0xaa - BYTE $0xaa - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM13, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x20 - BYTE $0x20 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM10, YMM11 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0x01 - BYTE $0x01 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 - BYTE $0x20 - - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xc2 // VPUNPCKHQDQ YMM8, YMM11, YMM10 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM10, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x31 - BYTE $0x31 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 8 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc3 // VPUNPCKHQDQ YMM8, YMM13, YMM11 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xca // VPERMQ YMM9, YMM10, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM13, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 - BYTE $0x20 - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc5 // VPERMQ YMM8, YMM13, 0xaa - BYTE $0xaa - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc0 // VPUNPCKHQDQ YMM8, YMM12, YMM8 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM10, YMM12 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 - BYTE $0x21 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xc5 // VPUNPCKHQDQ YMM8, YMM11, YMM13 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6c; BYTE $0xca // VPUNPCKLQDQ YMM9, YMM12, YMM10 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x0c - BYTE $0x0c - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 - BYTE $0x20 - - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM10, YMM11 - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xcc // VPUNPCKLQDQ YMM9, YMM11, YMM12 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 - BYTE $0x30 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 9 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM11, YMM13 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xca // VPERMQ YMM9, YMM10, 0x00 - BYTE $0x00 - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM12, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 - BYTE $0x31 - - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc4 // VPUNPCKHQDQ YMM8, YMM13, YMM12 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0x00 - BYTE $0x00 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM10, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x31 - BYTE $0x31 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0xaa - BYTE $0xaa - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM10, YMM9 - BYTE $0xc4; BYTE $0xc3; BYTE $0x15; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM13, YMM9, 0x20 - BYTE $0x20 - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc3 // VPERMQ YMM8, YMM11, 0xff - BYTE $0xff - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM10, YMM8 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcb // VPERMQ YMM9, YMM11, 0x04 - BYTE $0x04 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 - BYTE $0x21 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 10 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc4 // VPERMQ YMM8, YMM12, 0x20 - BYTE $0x20 - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM11, YMM10 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 - BYTE $0x31 - - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM10, YMM11 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcb // VPERMQ YMM9, YMM11, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x31 - BYTE $0x31 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc4 // VPUNPCKHQDQ YMM8, YMM13, YMM12 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xcd // VPUNPCKHQDQ YMM9, YMM10, YMM13 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 - BYTE $0x60 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 - BYTE $0x31 - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc5 // VPERMQ YMM8, YMM13, 0xaa - BYTE $0xaa - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc0 // VPUNPCKHQDQ YMM8, YMM12, YMM8 - BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xca // VPUNPCKLQDQ YMM9, YMM13, YMM10 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 - BYTE $0x21 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 1 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0xc1; BYTE $0x2d; BYTE $0x6c; BYTE $0xe3 // VPUNPCKLQDQ YMM4, YMM10, YMM11 /* m[0], m[4], m[2], m[6] */ - BYTE $0xc4; BYTE $0xc1; BYTE $0x2d; BYTE $0x6d; BYTE $0xeb // VPUNPCKHQDQ YMM5, YMM10, YMM11 /* m[1], m[5], m[3], m[7] */ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xe4 // VPERMQ YMM4, YMM4, 0xd8 /* 0x1101 1000 = 0xd8 */ - BYTE $0xd8 - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xed // VPERMQ YMM5, YMM5, 0xd8 /* 0x1101 1000 = 0xd8 */ - BYTE $0xd8 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0xc1; BYTE $0x1d; BYTE $0x6c; BYTE $0xe5 // VPUNPCKLQDQ YMM4, YMM12, YMM13 /* m[8], m[12], m[10], m[14] */ - BYTE $0xc4; BYTE $0xc1; BYTE $0x1d; BYTE $0x6d; BYTE $0xed // VPUNPCKHQDQ YMM5, YMM12, YMM13 /* m[9], m[13], m[11], m[15] */ - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xe4 // VPERMQ YMM4, YMM4, 0xd8 /* 0x1101 1000 = 0xd8 */ - BYTE $0xd8 - BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xed // VPERMQ YMM5, YMM5, 0xd8 /* 0x1101 1000 = 0xd8 */ - BYTE $0xd8 - - G1 - G2 - - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 2 - /////////////////////////////////////////////////////////////////////////// - - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM11, YMM13 /* m[4], ____, ____, m[14] */ - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x03 /* m[14], m[4], ____, ____ */ /* xxxx 0011 = 0x03 */ - BYTE $0x03 - BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xcd // VPUNPCKHQDQ YMM9, YMM12, YMM13 /* m[9], m[13], ____, ____ */ - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 /* m[9], m[13], ____, ____ */ /* 0010 0000 = 0x20 */ - BYTE $0x20 - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc4 // VPERMQ YMM8, YMM12, 0x02 /* m[10], m[8], ____, ____ */ /* xxxx 0010 = 0x02 */ - BYTE $0x02 - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x30 /* ____, ____, m[15], ____ */ /* xx11 xxxx = 0x30 */ - BYTE $0x30 - BYTE $0xc4; BYTE $0x41; BYTE $0x35; BYTE $0x6c; BYTE $0xcb // VPUNPCKLQDQ YMM9, YMM9, YMM11 /* ____, ____, m[15], m[6] */ - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 /* m[9], m[13], m[15], m[6] */ /* 0011 0000 = 0x30 */ - BYTE $0x30 - - G1 - G2 - - DIAGONALIZE - - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc2 // VPERMQ YMM8, YMM10, 0x01 /* m[1], m[0], ____, ____ */ /* xxxx 0001 = 0x01 */ - BYTE $0x01 - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM11, YMM12 /* m[5], ____, ____, m[11] */ - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x03 /* m[11], m[5], ____, ____ */ /* xxxx 0011 = 0x03 */ - BYTE $0x03 - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 /* m[1], m[0], m[11], m[5] */ /* 0010 0000 = 0x20 */ - BYTE $0x20 - - BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM10, YMM13 /* ___, m[12], m[2], ____ */ - BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x09 /* m[12], m[2], ____, ____ */ /* xxxx 1001 = 0x09 */ - BYTE $0x09 - BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM11, YMM10 /* ____, ____, m[7], m[3] */ - BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 /* m[9], m[13], m[15], m[6] */ /* 0011 0000 = 0x30 */ - BYTE $0x30 - - G1 - G2 - - UNDIAGONALIZE - - // Reload digest (most current value store in &out) - MOVQ out+144(FP), SI // SI: &in - BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x26 // VMOVDQU YMM12, [rsi] - BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x6e; BYTE $0x20 // VMOVDQU YMM13, 32[rsi] - - BYTE $0xc5; BYTE $0xfd; BYTE $0xef; BYTE $0xc2 // VPXOR YMM0,YMM0,YMM2 /* X0 = X0 ^ X4, X1 = X1 ^ X5 */ - BYTE $0xc4; BYTE $0xc1; BYTE $0x7d; BYTE $0xef; BYTE $0xc4 // VPXOR YMM0,YMM0,YMM12 /* X0 = X0 ^ X12, X1 = X1 ^ X13 */ - BYTE $0xc5; BYTE $0xf5; BYTE $0xef; BYTE $0xcb // VPXOR YMM1,YMM1,YMM3 /* X2 = X2 ^ X6, X3 = X3 ^ X7 */ - BYTE $0xc4; BYTE $0xc1; BYTE $0x75; BYTE $0xef; BYTE $0xcd // VPXOR YMM1,YMM1,YMM13 /* X2 = X2 ^ X14, X3 = X3 ^ X15 */ - - // Store digest into &out - MOVQ out+144(FP), SI // SI: &out - BYTE $0xc5; BYTE $0xfe; BYTE $0x7f; BYTE $0x06 // VMOVDQU [rsi], YMM0 - BYTE $0xc5; BYTE $0xfe; BYTE $0x7f; BYTE $0x4e; BYTE $0x20 // VMOVDQU 32[rsi], YMM1 - - // Increment message pointer and check if there's more to do - ADDQ $128, DX // message += 128 - SUBQ $1, R8 - JNZ loop - -complete: - BYTE $0xc5; BYTE $0xf8; BYTE $0x77 // VZEROUPPER /* Prevent further context switches */ - RET - diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.go b/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.go deleted file mode 100644 index cfa12c04..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.go +++ /dev/null @@ -1,41 +0,0 @@ -//+build !noasm -//+build !appengine - -/* - * 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 blake2b - -//go:noescape -func blockAVXLoop(p []uint8, in, iv, t, f, shffle, out []uint64) - -func compressAVX(d *digest, p []uint8) { - var ( - in [8]uint64 - out [8]uint64 - shffle [2]uint64 - ) - - // vector for PSHUFB instruction - shffle[0] = 0x0201000706050403 - shffle[1] = 0x0a09080f0e0d0c0b - - in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7] = d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] - - blockAVXLoop(p, in[:], iv[:], d.t[:], d.f[:], shffle[:], out[:]) - - d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7] -} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.s b/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.s deleted file mode 100644 index f68e1739..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.s +++ /dev/null @@ -1,682 +0,0 @@ -//+build !noasm !appengine - -// -// 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 SSE implementation from https://github.com/BLAKE2/BLAKE2/blob/master/sse/blake2b.c -// -// Use github.com/fwessels/asm2plan9s on this file to assemble instructions to their Plan9 equivalent -// -// Assembly code below essentially follows the ROUND macro (see blake2b-round.h) which is defined as: -// #define ROUND(r) \ -// LOAD_MSG_ ##r ##_1(b0, b1); \ -// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// LOAD_MSG_ ##r ##_2(b0, b1); \ -// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ -// LOAD_MSG_ ##r ##_3(b0, b1); \ -// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// LOAD_MSG_ ##r ##_4(b0, b1); \ -// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); -// -// as well as the go equivalent in https://github.com/dchest/blake2b/blob/master/block.go -// -// As in the macro, G1/G2 in the 1st and 2nd half are identical (so literal copy of assembly) -// -// Rounds are also the same, except for the loading of the message (and rounds 1 & 11 and -// rounds 2 & 12 are identical) -// - -#define G1 \ - \ // G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); - LONG $0xd479c1c4; BYTE $0xc0 \ // VPADDQ XMM0,XMM0,XMM8 /* v0 += m[0], v1 += m[2] */ - LONG $0xd471c1c4; BYTE $0xc9 \ // VPADDQ XMM1,XMM1,XMM9 /* v2 += m[4], v3 += m[6] */ - LONG $0xc2d4f9c5 \ // VPADDQ XMM0,XMM0,XMM2 /* v0 += v4, v1 += v5 */ - LONG $0xcbd4f1c5 \ // VPADDQ XMM1,XMM1,XMM3 /* v2 += v6, v3 += v7 */ - LONG $0xf0efc9c5 \ // VPXOR XMM6,XMM6,XMM0 /* v12 ^= v0, v13 ^= v1 */ - LONG $0xf9efc1c5 \ // VPXOR XMM7,XMM7,XMM1 /* v14 ^= v2, v15 ^= v3 */ - LONG $0xf670f9c5; BYTE $0xb1 \ // VPSHUFD XMM6,XMM6,0xb1 /* v12 = v12<<(64-32) | v12>>32, v13 = v13<<(64-32) | v13>>32 */ - LONG $0xff70f9c5; BYTE $0xb1 \ // VPSHUFD XMM7,XMM7,0xb1 /* v14 = v14<<(64-32) | v14>>32, v15 = v15<<(64-32) | v15>>32 */ - LONG $0xe6d4d9c5 \ // VPADDQ XMM4,XMM4,XMM6 /* v8 += v12, v9 += v13 */ - LONG $0xefd4d1c5 \ // VPADDQ XMM5,XMM5,XMM7 /* v10 += v14, v11 += v15 */ - LONG $0xd4efe9c5 \ // VPXOR XMM2,XMM2,XMM4 /* v4 ^= v8, v5 ^= v9 */ - LONG $0xddefe1c5 \ // VPXOR XMM3,XMM3,XMM5 /* v6 ^= v10, v7 ^= v11 */ - LONG $0x0069c2c4; BYTE $0xd4 \ // VPSHUFB XMM2,XMM2,XMM12 /* v4 = v4<<(64-24) | v4>>24, v5 = v5<<(64-24) | v5>>24 */ - LONG $0x0061c2c4; BYTE $0xdc // VPSHUFB XMM3,XMM3,XMM12 /* v6 = v6<<(64-24) | v6>>24, v7 = v7<<(64-24) | v7>>24 */ - -#define G2 \ - \ // G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); - LONG $0xd479c1c4; BYTE $0xc2 \ // VPADDQ XMM0,XMM0,XMM10 /* v0 += m[1], v1 += m[3] */ - LONG $0xd471c1c4; BYTE $0xcb \ // VPADDQ XMM1,XMM1,XMM11 /* v2 += m[5], v3 += m[7] */ - LONG $0xc2d4f9c5 \ // VPADDQ XMM0,XMM0,XMM2 /* v0 += v4, v1 += v5 */ - LONG $0xcbd4f1c5 \ // VPADDQ XMM1,XMM1,XMM3 /* v2 += v6, v3 += v7 */ - LONG $0xf0efc9c5 \ // VPXOR XMM6,XMM6,XMM0 /* v12 ^= v0, v13 ^= v1 */ - LONG $0xf9efc1c5 \ // VPXOR XMM7,XMM7,XMM1 /* v14 ^= v2, v15 ^= v3 */ - LONG $0xf670fbc5; BYTE $0x39 \ // VPSHUFLW XMM6,XMM6,0x39 /* combined with next ... */ - LONG $0xf670fac5; BYTE $0x39 \ // VPSHUFHW XMM6,XMM6,0x39 /* v12 = v12<<(64-16) | v12>>16, v13 = v13<<(64-16) | v13>>16 */ - LONG $0xff70fbc5; BYTE $0x39 \ // VPSHUFLW XMM7,XMM7,0x39 /* combined with next ... */ - LONG $0xff70fac5; BYTE $0x39 \ // VPSHUFHW XMM7,XMM7,0x39 /* v14 = v14<<(64-16) | v14>>16, v15 = v15<<(64-16) | v15>>16 */ - LONG $0xe6d4d9c5 \ // VPADDQ XMM4,XMM4,XMM6 /* v8 += v12, v9 += v13 */ - LONG $0xefd4d1c5 \ // VPADDQ XMM5,XMM5,XMM7 /* v10 += v14, v11 += v15 */ - LONG $0xd4efe9c5 \ // VPXOR XMM2,XMM2,XMM4 /* v4 ^= v8, v5 ^= v9 */ - LONG $0xddefe1c5 \ // VPXOR XMM3,XMM3,XMM5 /* v6 ^= v10, v7 ^= v11 */ - LONG $0xfad469c5 \ // VPADDQ XMM15,XMM2,XMM2 /* temp reg = reg*2 */ - LONG $0xd273e9c5; BYTE $0x3f \ // VPSRLQ XMM2,XMM2,0x3f /* reg = reg>>63 */ - LONG $0xef69c1c4; BYTE $0xd7 \ // VPXOR XMM2,XMM2,XMM15 /* ORed together: v4 = v4<<(64-63) | v4>>63, v5 = v5<<(64-63) | v5>>63 */ - LONG $0xfbd461c5 \ // VPADDQ XMM15,XMM3,XMM3 /* temp reg = reg*2 */ - LONG $0xd373e1c5; BYTE $0x3f \ // VPSRLQ XMM3,XMM3,0x3f /* reg = reg>>63 */ - LONG $0xef61c1c4; BYTE $0xdf // VPXOR XMM3,XMM3,XMM15 /* ORed together: v6 = v6<<(64-63) | v6>>63, v7 = v7<<(64-63) | v7>>63 */ - -#define DIAGONALIZE \ - \ // DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); - MOVOU X6, X13 \ /* t0 = row4l;\ */ - MOVOU X2, X14 \ /* t1 = row2l;\ */ - MOVOU X4, X6 \ /* row4l = row3l;\ */ - MOVOU X5, X4 \ /* row3l = row3h;\ */ - MOVOU X6, X5 \ /* row3h = row4l;\ */ - LONG $0x6c1141c4; BYTE $0xfd \ // VPUNPCKLQDQ XMM15, XMM13, XMM13 /* _mm_unpacklo_epi64(t0, t0) */ - LONG $0x6d41c1c4; BYTE $0xf7 \ // VPUNPCKHQDQ XMM6, XMM7, XMM15 /* row4l = _mm_unpackhi_epi64(row4h, ); \ */ - LONG $0xff6c41c5 \ // VPUNPCKLQDQ XMM15, XMM7, XMM7 /* _mm_unpacklo_epi64(row4h, row4h) */ - LONG $0x6d11c1c4; BYTE $0xff \ // VPUNPCKHQDQ XMM7, XMM13, XMM15 /* row4h = _mm_unpackhi_epi64(t0, ); \ */ - LONG $0xfb6c61c5 \ // VPUNPCKLQDQ XMM15, XMM3, XMM3 /* _mm_unpacklo_epi64(row2h, row2h) */ - LONG $0x6d69c1c4; BYTE $0xd7 \ // VPUNPCKHQDQ XMM2, XMM2, XMM15 /* row2l = _mm_unpackhi_epi64(row2l, ); \ */ - LONG $0x6c0941c4; BYTE $0xfe \ // VPUNPCKLQDQ XMM15, XMM14, XMM14 /* _mm_unpacklo_epi64(t1, t1) */ - LONG $0x6d61c1c4; BYTE $0xdf // VPUNPCKHQDQ XMM3, XMM3, XMM15 /* row2h = _mm_unpackhi_epi64(row2h, ) */ - -#define UNDIAGONALIZE \ - \ // UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); - MOVOU X4, X13 \ /* t0 = row3l;\ */ - MOVOU X5, X4 \ /* row3l = row3h;\ */ - MOVOU X13, X5 \ /* row3h = t0;\ */ - MOVOU X2, X13 \ /* t0 = row2l;\ */ - MOVOU X6, X14 \ /* t1 = row4l;\ */ - LONG $0xfa6c69c5 \ // VPUNPCKLQDQ XMM15, XMM2, XMM2 /* _mm_unpacklo_epi64(row2l, row2l) */ - LONG $0x6d61c1c4; BYTE $0xd7 \ // VPUNPCKHQDQ XMM2, XMM3, XMM15 /* row2l = _mm_unpackhi_epi64(row2h, ); \ */ - LONG $0xfb6c61c5 \ // VPUNPCKLQDQ XMM15, XMM3, XMM3 /* _mm_unpacklo_epi64(row2h, row2h) */ - LONG $0x6d11c1c4; BYTE $0xdf \ // VPUNPCKHQDQ XMM3, XMM13, XMM15 /* row2h = _mm_unpackhi_epi64(t0, ); \ */ - LONG $0xff6c41c5 \ // VPUNPCKLQDQ XMM15, XMM7, XMM7 /* _mm_unpacklo_epi64(row4h, row4h) */ - LONG $0x6d49c1c4; BYTE $0xf7 \ // VPUNPCKHQDQ XMM6, XMM6, XMM15 /* row4l = _mm_unpackhi_epi64(row4l, ); \ */ - LONG $0x6c0941c4; BYTE $0xfe \ // VPUNPCKLQDQ XMM15, XMM14, XMM14 /* _mm_unpacklo_epi64(t1, t1) */ - LONG $0x6d41c1c4; BYTE $0xff // VPUNPCKHQDQ XMM7, XMM7, XMM15 /* row4h = _mm_unpackhi_epi64(row4h, ) */ - -#define LOAD_SHUFFLE \ - \ // Load shuffle value - MOVQ shffle+120(FP), SI \ // SI: &shuffle - MOVOU 0(SI), X12 // X12 = 03040506 07000102 0b0c0d0e 0f08090a - -// func blockAVXLoop(p []uint8, in, iv, t, f, shffle, out []uint64) -TEXT 路blockAVXLoop(SB), 7, $0 - // REGISTER USE - // R8: loop counter - // DX: message pointer - // SI: temp pointer for loading - // X0 - X7: v0 - v15 - // X8 - X11: m[0] - m[7] - // X12: shuffle value - // X13 - X15: temp registers - - // Load digest - MOVQ in+24(FP), SI // SI: &in - MOVOU 0(SI), X0 // X0 = in[0]+in[1] /* row1l = LOAD( &S->h[0] ); */ - MOVOU 16(SI), X1 // X1 = in[2]+in[3] /* row1h = LOAD( &S->h[2] ); */ - MOVOU 32(SI), X2 // X2 = in[4]+in[5] /* row2l = LOAD( &S->h[4] ); */ - MOVOU 48(SI), X3 // X3 = in[6]+in[7] /* row2h = LOAD( &S->h[6] ); */ - - // Already store digest into &out (so we can reload it later generically) - MOVQ out+144(FP), SI // SI: &out - MOVOU X0, 0(SI) // out[0]+out[1] = X0 - MOVOU X1, 16(SI) // out[2]+out[3] = X1 - MOVOU X2, 32(SI) // out[4]+out[5] = X2 - MOVOU X3, 48(SI) // out[6]+out[7] = X3 - - // Initialize message pointer and loop counter - MOVQ message+0(FP), DX // DX: &p (message) - MOVQ message_len+8(FP), R8 // R8: len(message) - SHRQ $7, R8 // len(message) / 128 - CMPQ R8, $0 - JEQ complete - -loop: - // Increment counter - MOVQ t+72(FP), SI // SI: &t - MOVQ 0(SI), R9 - ADDQ $128, R9 // /* d.t[0] += BlockSize */ - MOVQ R9, 0(SI) - CMPQ R9, $128 // /* if d.t[0] < BlockSize { */ - JGE noincr - MOVQ 8(SI), R9 - ADDQ $1, R9 // /* d.t[1]++ */ - MOVQ R9, 8(SI) -noincr: // /* } */ - - // Load initialization vector - MOVQ iv+48(FP), SI // SI: &iv - MOVOU 0(SI), X4 // X4 = iv[0]+iv[1] /* row3l = LOAD( &blake2b_IV[0] ); */ - MOVOU 16(SI), X5 // X5 = iv[2]+iv[3] /* row3h = LOAD( &blake2b_IV[2] ); */ - MOVOU 32(SI), X6 // X6 = iv[4]+iv[5] /* LOAD( &blake2b_IV[4] ) */ - MOVOU 48(SI), X7 // X7 = iv[6]+iv[7] /* LOAD( &blake2b_IV[6] ) */ - MOVQ t+72(FP), SI // SI: &t - MOVOU 0(SI), X8 // X8 = t[0]+t[1] /* LOAD( &S->t[0] ) */ - PXOR X8, X6 // X6 = X6 ^ X8 /* row4l = _mm_xor_si128( , ); */ - MOVQ t+96(FP), SI // SI: &f - MOVOU 0(SI), X8 // X8 = f[0]+f[1] /* LOAD( &S->f[0] ) */ - PXOR X8, X7 // X7 = X7 ^ X8 /* row4h = _mm_xor_si128( , ); */ - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+m[1] - MOVOU 16(DX), X13 // X13 = m[2]+m[3] - MOVOU 32(DX), X14 // X14 = m[4]+m[5] - MOVOU 48(DX), X15 // X15 = m[6]+m[7] - LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[0], m[2] */ - LONG $0x6c0941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM14, XMM15 /* m[4], m[6] */ - LONG $0x6d1941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM12, XMM13 /* m[1], m[3] */ - LONG $0x6d0941c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM14, XMM15 /* m[5], m[7] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 64(DX), X12 // X12 = m[8]+ m[9] - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[8],m[10] */ - LONG $0x6c0941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM14, XMM15 /* m[12],m[14] */ - LONG $0x6d1941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM12, XMM13 /* m[9],m[11] */ - LONG $0x6d0941c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM14, XMM15 /* m[13],m[15] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 2 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 112(DX), X12 // X12 = m[14]+m[15] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 96(DX), X15 // X15 = m[12]+m[13] - LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[14], m[4] */ - LONG $0x6d0941c4; BYTE $0xcf // VPUNPCKHQDQ XMM9, XMM14, XMM15 /* m[9], m[13] */ - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU 48(DX), X15 // X15 = m[6]+ m[7] - LONG $0x6c1141c4; BYTE $0xd6 // VPUNPCKLQDQ XMM10, XMM13, XMM14 /* m[10], m[8] */ - LONG $0x0f0143c4; WORD $0x08dc // VPALIGNR XMM11, XMM15, XMM12, 0x8 /* m[15], m[6] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - LONG $0x0f1943c4; WORD $0x08c4 // VPALIGNR XMM8, XMM12, XMM12, 0x8 /* m[1], m[0] */ - LONG $0x6d0941c4; BYTE $0xcd // VPUNPCKHQDQ XMM9, XMM14, XMM13 /* m[11], m[5] */ - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - LONG $0x6c0941c4; BYTE $0xd4 // VPUNPCKLQDQ XMM10, XMM14, XMM12 /* m[12], m[2] */ - LONG $0x6d1141c4; BYTE $0xdc // VPUNPCKHQDQ XMM11, XMM13, XMM12 /* m[7], m[3] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 3 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 32(DX), X12 // X12 = m[4]+ m[5] - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x0f0943c4; WORD $0x08c5 // VPALIGNR XMM8, XMM14, XMM13, 0x8 /* m[11], m[12] */ - LONG $0x6d1941c4; BYTE $0xcf // VPUNPCKHQDQ XMM9, XMM12, XMM15 /* m[5], m[15] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 16(DX), X13 // X13 = m[2]+ m[3] - MOVOU 64(DX), X15 // X15 = m[8]+ m[9] - LONG $0x6c0141c4; BYTE $0xd4 // VPUNPCKLQDQ XMM10, XMM15, XMM12 /* m[8], m[0] */ - LONG $0x6d0941c4; BYTE $0xde // VPUNPCKHQDQ XMM11, XMM14, XMM14 /* ___, m[13] */ - LONG $0x6c1141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM13, XMM11 /* m[2], ___ */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - LONG $0x6d1941c4; BYTE $0xc4 // VPUNPCKHQDQ XMM8, XMM12, XMM12 /* ___, m[3] */ - LONG $0x6c0141c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM15, XMM8 /* m[10], ___ */ - LONG $0x6d1141c4; BYTE $0xce // VPUNPCKHQDQ XMM9, XMM13, XMM14 /* m[7], m[9] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X14 // X14 = m[4]+ m[5] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6c0141c4; BYTE $0xd5 // VPUNPCKLQDQ XMM10, XMM15, XMM13 /* m[14], m[6] */ - LONG $0x0f0943c4; WORD $0x08dc // VPALIGNR XMM11, XMM14, XMM12, 0x8 /* m[1], m[4] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 4 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 96(DX), X15 // X15 = m[12]+m[13] - LONG $0x6d1141c4; BYTE $0xc4 // VPUNPCKHQDQ XMM8, XMM13, XMM12 /* m[7], m[3] */ - LONG $0x6d0141c4; BYTE $0xce // VPUNPCKHQDQ XMM9, XMM15, XMM14 /* m[13], m[11] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 64(DX), X13 // X13 = m[8]+ m[9] - MOVOU 112(DX), X14 // X14 = m[14]+m[15] - LONG $0x6d1141c4; BYTE $0xd4 // VPUNPCKHQDQ XMM10, XMM13, XMM12 /* m[9], m[1] */ - LONG $0x6c0141c4; BYTE $0xde // VPUNPCKLQDQ XMM11, XMM15, XMM14 /* m[12], m[14] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d1141c4; BYTE $0xc5 // VPUNPCKHQDQ XMM8, XMM13, XMM13 /* ___, m[5] */ - LONG $0x6c1941c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM12, XMM8 /* m[2], ____ */ - LONG $0x6d0141c4; BYTE $0xcf // VPUNPCKHQDQ XMM9, XMM15, XMM15 /* ___, m[15] */ - LONG $0x6c1141c4; BYTE $0xc9 // VPUNPCKLQDQ XMM9, XMM13, XMM9 /* m[4], ____ */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 64(DX), X15 // X15 = m[8]+ m[9] - LONG $0x6c1141c4; BYTE $0xd6 // VPUNPCKLQDQ XMM10, XMM13, XMM14 /* m[6], m[10] */ - LONG $0x6c1941c4; BYTE $0xdf // VPUNPCKLQDQ XMM11, XMM12, XMM15 /* m[0], m[8] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 5 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - LONG $0x6d0941c4; BYTE $0xc5 // VPUNPCKHQDQ XMM8, XMM14, XMM13 /* m[9], m[5] */ - LONG $0x6c1941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM12, XMM15 /* m[2], m[10] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X14 // X14 = m[6]+ m[7] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d0941c4; BYTE $0xd6 // VPUNPCKHQDQ XMM10, XMM14, XMM14 /* ___, m[7] */ - LONG $0x6c1941c4; BYTE $0xd2 // VPUNPCKLQDQ XMM10, XMM12, XMM10 /* m[0], ____ */ - LONG $0x6d0141c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM15, XMM15 /* ___, m[15] */ - LONG $0x6c1141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM13, XMM11 /* m[4], ____ */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d0941c4; BYTE $0xc6 // VPUNPCKHQDQ XMM8, XMM14, XMM14 /* ___, m[11] */ - LONG $0x6c0141c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM15, XMM8 /* m[14], ____ */ - LONG $0x6d1941c4; BYTE $0xcc // VPUNPCKHQDQ XMM9, XMM12, XMM12 /* ___, m[3] */ - LONG $0x6c1141c4; BYTE $0xc9 // VPUNPCKLQDQ XMM9, XMM13, XMM9 /* m[6], ____ */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 64(DX), X13 // X13 = m[8]+ m[9] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - LONG $0x0f0943c4; WORD $0x08d4 // VPALIGNR XMM10, XMM14, XMM12, 0x8 /* m[1], m[12] */ - LONG $0x6d0941c4; BYTE $0xde // VPUNPCKHQDQ XMM11, XMM14, XMM14 /* ___, m[13] */ - LONG $0x6c1141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM13, XMM11 /* m[8], ____ */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 6 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 16(DX), X13 // X13 = m[2]+ m[3] - MOVOU 48(DX), X14 // X14 = m[6]+ m[7] - MOVOU 64(DX), X15 // X15 = m[8]+ m[9] - LONG $0x6c1141c4; BYTE $0xc6 // VPUNPCKLQDQ XMM8, XMM13, XMM14 /* m[2], m[6] */ - LONG $0x6c1941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM12, XMM15 /* m[0], m[8] */ - MOVOU 80(DX), X12 // X12 = m[10]+m[11] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - LONG $0x6c0941c4; BYTE $0xd4 // VPUNPCKLQDQ XMM10, XMM14, XMM12 /* m[12], m[10] */ - LONG $0x6d1941c4; BYTE $0xdd // VPUNPCKHQDQ XMM11, XMM12, XMM13 /* m[11], m[3] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 48(DX), X14 // X14 = m[6]+ m[7] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d0941c4; BYTE $0xc6 // VPUNPCKHQDQ XMM8, XMM14, XMM14 /* ___, m[7] */ - LONG $0x6c1141c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM13, XMM8 /* m[4], ____ */ - LONG $0x6d0141c4; BYTE $0xcc // VPUNPCKHQDQ XMM9, XMM15, XMM12 /* m[15], m[1] */ - MOVOU 64(DX), X12 // X12 = m[8]+ m[9] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - LONG $0x6d0941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM14, XMM13 /* m[13], m[5] */ - LONG $0x6d1941c4; BYTE $0xdc // VPUNPCKHQDQ XMM11, XMM12, XMM12 /* ___, m[9] */ - LONG $0x6c0141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM15, XMM11 /* m[14], ____ */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 7 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d1941c4; BYTE $0xc4 // VPUNPCKHQDQ XMM8, XMM12, XMM12 /* ___, m[1] */ - LONG $0x6c0941c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM14, XMM8 /* m[12], ____ */ - LONG $0x6c0141c4; BYTE $0xcd // VPUNPCKLQDQ XMM9, XMM15, XMM13 /* m[14], m[4] */ - MOVOU 80(DX), X12 // X12 = m[10]+m[11] - LONG $0x6d1141c4; BYTE $0xd7 // VPUNPCKHQDQ XMM10, XMM13, XMM15 /* m[5], m[15] */ - LONG $0x0f1943c4; WORD $0x08de // VPALIGNR XMM11, XMM12, XMM14, 0x8 /* m[13], m[10] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[0], m[6] */ - LONG $0x0f0943c4; WORD $0x08ce // VPALIGNR XMM9, XMM14, XMM14, 0x8 /* m[9], m[8] */ - MOVOU 16(DX), X14 // X14 = m[2]+ m[3] - LONG $0x6d1141c4; BYTE $0xd6 // VPUNPCKHQDQ XMM10, XMM13, XMM14 /* m[7], m[3] */ - LONG $0x6d0141c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM15, XMM15 /* ___, m[11] */ - LONG $0x6c0941c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM14, XMM11 /* m[2], ____ */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 8 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d0941c4; BYTE $0xc5 // VPUNPCKHQDQ XMM8, XMM14, XMM13 /* m[13], m[7] */ - LONG $0x6d1941c4; BYTE $0xcc // VPUNPCKHQDQ XMM9, XMM12, XMM12 /* ___, m[3] */ - LONG $0x6c0941c4; BYTE $0xc9 // VPUNPCKLQDQ XMM9, XMM14, XMM9 /* m[12], ____ */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 64(DX), X13 // X13 = m[8]+ m[9] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - LONG $0x0f0143c4; WORD $0x08d6 // VPALIGNR XMM10, XMM15, XMM14, 0x8 /* m[11], m[14] */ - LONG $0x6d1941c4; BYTE $0xdd // VPUNPCKHQDQ XMM11, XMM12, XMM13 /* m[1], m[9] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d1141c4; BYTE $0xc7 // VPUNPCKHQDQ XMM8, XMM13, XMM15 /* m[5], m[15] */ - LONG $0x6c0941c4; BYTE $0xcc // VPUNPCKLQDQ XMM9, XMM14, XMM12 /* m[8], m[2] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X14 // X14 = m[6]+ m[7] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - LONG $0x6c1941c4; BYTE $0xd5 // VPUNPCKLQDQ XMM10, XMM12, XMM13 /* m[0], m[4] */ - LONG $0x6c0941c4; BYTE $0xdf // VPUNPCKLQDQ XMM11, XMM14, XMM15 /* m[6], m[10] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 9 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6c1141c4; BYTE $0xc7 // VPUNPCKLQDQ XMM8, XMM13, XMM15 /* m[6], m[14] */ - LONG $0x0f1943c4; WORD $0x08ce // VPALIGNR XMM9, XMM12, XMM14, 0x8 /* m[11], m[0] */ - MOVOU 16(DX), X13 // X13 = m[2]+ m[3] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - LONG $0x6d0141c4; BYTE $0xd6 // VPUNPCKHQDQ XMM10, XMM15, XMM14 /* m[15], m[9] */ - LONG $0x0f0943c4; WORD $0x08dd // VPALIGNR XMM11, XMM14, XMM13, 0x8 /* m[3], m[8] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 16(DX), X13 // X13 = m[2]+ m[3] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 96(DX), X15 // X15 = m[12]+m[13] - LONG $0x6d0141c4; BYTE $0xc7 // VPUNPCKHQDQ XMM8, XMM15, XMM15 /* ___, m[13] */ - LONG $0x6c0141c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM15, XMM8 /* m[12], ____ */ - LONG $0x0f0943c4; WORD $0x08cc // VPALIGNR XMM9, XMM14, XMM12, 0x8 /* m[1], m[10] */ - MOVOU 32(DX), X12 // X12 = m[4]+ m[5] - MOVOU 48(DX), X15 // X15 = m[6]+ m[7] - LONG $0x6d0141c4; BYTE $0xd7 // VPUNPCKHQDQ XMM10, XMM15, XMM15 /* ___, m[7] */ - LONG $0x6c1141c4; BYTE $0xd2 // VPUNPCKLQDQ XMM10, XMM13, XMM10 /* m[2], ____ */ - LONG $0x6d1941c4; BYTE $0xdc // VPUNPCKHQDQ XMM11, XMM12, XMM12 /* ___, m[5] */ - LONG $0x6c1941c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM12, XMM11 /* m[4], ____ */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 0 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - LONG $0x6c0141c4; BYTE $0xc6 // VPUNPCKLQDQ XMM8, XMM15, XMM14 /* m[10], m[8] */ - LONG $0x6d1141c4; BYTE $0xcc // VPUNPCKHQDQ XMM9, XMM13, XMM12 /* m[7], m[1] */ - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 32(DX), X14 // X14 = m[4]+ m[5] - LONG $0x6c1941c4; BYTE $0xd6 // VPUNPCKLQDQ XMM10, XMM12, XMM14 /* m[2], m[4] */ - LONG $0x6d0941c4; BYTE $0xde // VPUNPCKHQDQ XMM11, XMM14, XMM14 /* ___, m[5] */ - LONG $0x6c1141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM13, XMM11 /* m[6], ____ */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 64(DX), X13 // X13 = m[8]+ m[9] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d0141c4; BYTE $0xc5 // VPUNPCKHQDQ XMM8, XMM15, XMM13 /* m[15], m[9] */ - LONG $0x6d1941c4; BYTE $0xce // VPUNPCKHQDQ XMM9, XMM12, XMM14 /* m[3], m[13] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - LONG $0x0f0143c4; WORD $0x08d5 // VPALIGNR XMM10, XMM15, XMM13, 0x8 /* m[11], m[14] */ - LONG $0x6c0941c4; BYTE $0xdc // VPUNPCKLQDQ XMM11, XMM14, XMM12 /* m[12], m[0] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 1 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+m[1] - MOVOU 16(DX), X13 // X13 = m[2]+m[3] - MOVOU 32(DX), X14 // X14 = m[4]+m[5] - MOVOU 48(DX), X15 // X15 = m[6]+m[7] - LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[0], m[2] */ - LONG $0x6c0941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM14, XMM15 /* m[4], m[6] */ - LONG $0x6d1941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM12, XMM13 /* m[1], m[3] */ - LONG $0x6d0941c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM14, XMM15 /* m[5], m[7] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 64(DX), X12 // X12 = m[8]+ m[9] - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[8],m[10] */ - LONG $0x6c0941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM14, XMM15 /* m[12],m[14] */ - LONG $0x6d1941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM12, XMM13 /* m[9],m[11] */ - LONG $0x6d0941c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM14, XMM15 /* m[13],m[15] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 2 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 112(DX), X12 // X12 = m[14]+m[15] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 96(DX), X15 // X15 = m[12]+m[13] - LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[14], m[4] */ - LONG $0x6d0941c4; BYTE $0xcf // VPUNPCKHQDQ XMM9, XMM14, XMM15 /* m[9], m[13] */ - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU 48(DX), X15 // X15 = m[6]+ m[7] - LONG $0x6c1141c4; BYTE $0xd6 // VPUNPCKLQDQ XMM10, XMM13, XMM14 /* m[10], m[8] */ - LONG $0x0f0143c4; WORD $0x08dc // VPALIGNR XMM11, XMM15, XMM12, 0x8 /* m[15], m[6] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - LONG $0x0f1943c4; WORD $0x08c4 // VPALIGNR XMM8, XMM12, XMM12, 0x8 /* m[1], m[0] */ - LONG $0x6d0941c4; BYTE $0xcd // VPUNPCKHQDQ XMM9, XMM14, XMM13 /* m[11], m[5] */ - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - LONG $0x6c0941c4; BYTE $0xd4 // VPUNPCKLQDQ XMM10, XMM14, XMM12 /* m[12], m[2] */ - LONG $0x6d1141c4; BYTE $0xdc // VPUNPCKHQDQ XMM11, XMM13, XMM12 /* m[7], m[3] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - // Reload digest (most current value store in &out) - MOVQ out+144(FP), SI // SI: &in - MOVOU 0(SI), X12 // X12 = in[0]+in[1] /* row1l = LOAD( &S->h[0] ); */ - MOVOU 16(SI), X13 // X13 = in[2]+in[3] /* row1h = LOAD( &S->h[2] ); */ - MOVOU 32(SI), X14 // X14 = in[4]+in[5] /* row2l = LOAD( &S->h[4] ); */ - MOVOU 48(SI), X15 // X15 = in[6]+in[7] /* row2h = LOAD( &S->h[6] ); */ - - // Final computations and prepare for storing - PXOR X4, X0 // X0 = X0 ^ X4 /* row1l = _mm_xor_si128( row3l, row1l ); */ - PXOR X5, X1 // X1 = X1 ^ X5 /* row1h = _mm_xor_si128( row3h, row1h ); */ - PXOR X12, X0 // X0 = X0 ^ X12 /* STORE( &S->h[0], _mm_xor_si128( LOAD( &S->h[0] ), row1l ) ); */ - PXOR X13, X1 // X1 = X1 ^ X13 /* STORE( &S->h[2], _mm_xor_si128( LOAD( &S->h[2] ), row1h ) ); */ - PXOR X6, X2 // X2 = X2 ^ X6 /* row2l = _mm_xor_si128( row4l, row2l ); */ - PXOR X7, X3 // X3 = X3 ^ X7 /* row2h = _mm_xor_si128( row4h, row2h ); */ - PXOR X14, X2 // X2 = X2 ^ X14 /* STORE( &S->h[4], _mm_xor_si128( LOAD( &S->h[4] ), row2l ) ); */ - PXOR X15, X3 // X3 = X3 ^ X15 /* STORE( &S->h[6], _mm_xor_si128( LOAD( &S->h[6] ), row2h ) ); */ - - // Store digest into &out - MOVQ out+144(FP), SI // SI: &out - MOVOU X0, 0(SI) // out[0]+out[1] = X0 - MOVOU X1, 16(SI) // out[2]+out[3] = X1 - MOVOU X2, 32(SI) // out[4]+out[5] = X2 - MOVOU X3, 48(SI) // out[6]+out[7] = X3 - - // Increment message pointer and check if there's more to do - ADDQ $128, DX // message += 128 - SUBQ $1, R8 - JNZ loop - -complete: - RET diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressSse_amd64.go b/fungible/cc/vendor/github.com/minio/blake2b-simd/compressSse_amd64.go deleted file mode 100644 index d539a7ad..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressSse_amd64.go +++ /dev/null @@ -1,41 +0,0 @@ -//+build !noasm -//+build !appengine - -/* - * 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 blake2b - -//go:noescape -func blockSSELoop(p []uint8, in, iv, t, f, shffle, out []uint64) - -func compressSSE(d *digest, p []uint8) { - var ( - in [8]uint64 - out [8]uint64 - shffle [2]uint64 - ) - - // vector for PSHUFB instruction - shffle[0] = 0x0201000706050403 - shffle[1] = 0x0a09080f0e0d0c0b - - in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7] = d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] - - blockSSELoop(p, in[:], iv[:], d.t[:], d.f[:], shffle[:], out[:]) - - d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7] -} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressSse_amd64.s b/fungible/cc/vendor/github.com/minio/blake2b-simd/compressSse_amd64.s deleted file mode 100644 index 6f31c949..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compressSse_amd64.s +++ /dev/null @@ -1,770 +0,0 @@ -//+build !noasm !appengine - -// -// 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 SSE implementation from https://github.com/BLAKE2/BLAKE2/blob/master/sse/blake2b.c -// -// Use github.com/fwessels/asm2plan9s on this file to assemble instructions to their Plan9 equivalent -// -// Assembly code below essentially follows the ROUND macro (see blake2b-round.h) which is defined as: -// #define ROUND(r) \ -// LOAD_MSG_ ##r ##_1(b0, b1); \ -// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// LOAD_MSG_ ##r ##_2(b0, b1); \ -// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ -// LOAD_MSG_ ##r ##_3(b0, b1); \ -// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// LOAD_MSG_ ##r ##_4(b0, b1); \ -// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ -// UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); -// -// as well as the go equivalent in https://github.com/dchest/blake2b/blob/master/block.go -// -// As in the macro, G1/G2 in the 1st and 2nd half are identical (so literal copy of assembly) -// -// Rounds are also the same, except for the loading of the message (and rounds 1 & 11 and -// rounds 2 & 12 are identical) -// - -#define G1 \ - \ // G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); - LONG $0xd40f4166; BYTE $0xc0 \ // PADDQ XMM0,XMM8 /* v0 += m[0], v1 += m[2] */ - LONG $0xd40f4166; BYTE $0xc9 \ // PADDQ XMM1,XMM9 /* v2 += m[4], v3 += m[6] */ - LONG $0xc2d40f66 \ // PADDQ XMM0,XMM2 /* v0 += v4, v1 += v5 */ - LONG $0xcbd40f66 \ // PADDQ XMM1,XMM3 /* v2 += v6, v3 += v7 */ - LONG $0xf0ef0f66 \ // PXOR XMM6,XMM0 /* v12 ^= v0, v13 ^= v1 */ - LONG $0xf9ef0f66 \ // PXOR XMM7,XMM1 /* v14 ^= v2, v15 ^= v3 */ - LONG $0xf6700f66; BYTE $0xb1 \ // PSHUFD XMM6,XMM6,0xb1 /* v12 = v12<<(64-32) | v12>>32, v13 = v13<<(64-32) | v13>>32 */ - LONG $0xff700f66; BYTE $0xb1 \ // PSHUFD XMM7,XMM7,0xb1 /* v14 = v14<<(64-32) | v14>>32, v15 = v15<<(64-32) | v15>>32 */ - LONG $0xe6d40f66 \ // PADDQ XMM4,XMM6 /* v8 += v12, v9 += v13 */ - LONG $0xefd40f66 \ // PADDQ XMM5,XMM7 /* v10 += v14, v11 += v15 */ - LONG $0xd4ef0f66 \ // PXOR XMM2,XMM4 /* v4 ^= v8, v5 ^= v9 */ - LONG $0xddef0f66 \ // PXOR XMM3,XMM5 /* v6 ^= v10, v7 ^= v11 */ - LONG $0x380f4166; WORD $0xd400 \ // PSHUFB XMM2,XMM12 /* v4 = v4<<(64-24) | v4>>24, v5 = v5<<(64-24) | v5>>24 */ - LONG $0x380f4166; WORD $0xdc00 // PSHUFB XMM3,XMM12 /* v6 = v6<<(64-24) | v6>>24, v7 = v7<<(64-24) | v7>>24 */ - -#define G2 \ - \ // G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); - LONG $0xd40f4166; BYTE $0xc2 \ // PADDQ XMM0,XMM10 /* v0 += m[1], v1 += m[3] */ - LONG $0xd40f4166; BYTE $0xcb \ // PADDQ XMM1,XMM11 /* v2 += m[5], v3 += m[7] */ - LONG $0xc2d40f66 \ // PADDQ XMM0,XMM2 /* v0 += v4, v1 += v5 */ - LONG $0xcbd40f66 \ // PADDQ XMM1,XMM3 /* v2 += v6, v3 += v7 */ - LONG $0xf0ef0f66 \ // PXOR XMM6,XMM0 /* v12 ^= v0, v13 ^= v1 */ - LONG $0xf9ef0f66 \ // PXOR XMM7,XMM1 /* v14 ^= v2, v15 ^= v3 */ - LONG $0xf6700ff2; BYTE $0x39 \ // PSHUFLW XMM6,XMM6,0x39 /* combined with next ... */ - LONG $0xf6700ff3; BYTE $0x39 \ // PSHUFHW XMM6,XMM6,0x39 /* v12 = v12<<(64-16) | v12>>16, v13 = v13<<(64-16) | v13>>16 */ - LONG $0xff700ff2; BYTE $0x39 \ // PSHUFLW XMM7,XMM7,0x39 /* combined with next ... */ - LONG $0xff700ff3; BYTE $0x39 \ // PSHUFHW XMM7,XMM7,0x39 /* v14 = v14<<(64-16) | v14>>16, v15 = v15<<(64-16) | v15>>16 */ - LONG $0xe6d40f66 \ // PADDQ XMM4,XMM6 /* v8 += v12, v9 += v13 */ - LONG $0xefd40f66 \ // PADDQ XMM5,XMM7 /* v10 += v14, v11 += v15 */ - LONG $0xd4ef0f66 \ // PXOR XMM2,XMM4 /* v4 ^= v8, v5 ^= v9 */ - LONG $0xddef0f66 \ // PXOR XMM3,XMM5 /* v6 ^= v10, v7 ^= v11 */ - MOVOU X2, X15 \ - LONG $0xd40f4466; BYTE $0xfa \ // PADDQ XMM15,XMM2 /* temp reg = reg*2 */ - LONG $0xd2730f66; BYTE $0x3f \ // PSRLQ XMM2,0x3f /* reg = reg>>63 */ - LONG $0xef0f4166; BYTE $0xd7 \ // PXOR XMM2,XMM15 /* ORed together: v4 = v4<<(64-63) | v4>>63, v5 = v5<<(64-63) | v5>>63 */ - MOVOU X3, X15 \ - LONG $0xd40f4466; BYTE $0xfb \ // PADDQ XMM15,XMM3 /* temp reg = reg*2 */ - LONG $0xd3730f66; BYTE $0x3f \ // PSRLQ XMM3,0x3f /* reg = reg>>63 */ - LONG $0xef0f4166; BYTE $0xdf // PXOR XMM3,XMM15 /* ORed together: v6 = v6<<(64-63) | v6>>63, v7 = v7<<(64-63) | v7>>63 */ - -#define DIAGONALIZE \ - \ // DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); - MOVOU X6, X13 \ /* t0 = row4l;\ */ - MOVOU X2, X14 \ /* t1 = row2l;\ */ - MOVOU X4, X6 \ /* row4l = row3l;\ */ - MOVOU X5, X4 \ /* row3l = row3h;\ */ - MOVOU X6, X5 \ /* row3h = row4l;\ */ - LONG $0x6c0f4566; BYTE $0xfd \ // PUNPCKLQDQ XMM15, XMM13 /* _mm_unpacklo_epi64(t0, t0) */ - MOVOU X7, X6 \ - LONG $0x6d0f4166; BYTE $0xf7 \ // PUNPCKHQDQ XMM6, XMM15 /* row4l = _mm_unpackhi_epi64(row4h, ); \ */ - LONG $0x6c0f4466; BYTE $0xff \ // PUNPCKLQDQ XMM15, XMM7 /* _mm_unpacklo_epi64(row4h, row4h) */ - MOVOU X13, X7 \ - LONG $0x6d0f4166; BYTE $0xff \ // PUNPCKHQDQ XMM7, XMM15 /* row4h = _mm_unpackhi_epi64(t0, ); \ */ - LONG $0x6c0f4466; BYTE $0xfb \ // PUNPCKLQDQ XMM15, XMM3 /* _mm_unpacklo_epi64(row2h, row2h) */ - LONG $0x6d0f4166; BYTE $0xd7 \ // PUNPCKHQDQ XMM2, XMM15 /* row2l = _mm_unpackhi_epi64(row2l, ); \ */ - LONG $0x6c0f4566; BYTE $0xfe \ // PUNPCKLQDQ XMM15, XMM14 /* _mm_unpacklo_epi64(t1, t1) */ - LONG $0x6d0f4166; BYTE $0xdf // PUNPCKHQDQ XMM3, XMM15 /* row2h = _mm_unpackhi_epi64(row2h, ) */ - -#define UNDIAGONALIZE \ - \ // UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); - MOVOU X4, X13 \ /* t0 = row3l;\ */ - MOVOU X5, X4 \ /* row3l = row3h;\ */ - MOVOU X13, X5 \ /* row3h = t0;\ */ - MOVOU X2, X13 \ /* t0 = row2l;\ */ - MOVOU X6, X14 \ /* t1 = row4l;\ */ - LONG $0x6c0f4466; BYTE $0xfa \ // PUNPCKLQDQ XMM15, XMM2 /* _mm_unpacklo_epi64(row2l, row2l) */ - MOVOU X3, X2 \ - LONG $0x6d0f4166; BYTE $0xd7 \ // PUNPCKHQDQ XMM2, XMM15 /* row2l = _mm_unpackhi_epi64(row2h, ); \ */ - LONG $0x6c0f4466; BYTE $0xfb \ // PUNPCKLQDQ XMM15, XMM3 /* _mm_unpacklo_epi64(row2h, row2h) */ - MOVOU X13, X3 \ - LONG $0x6d0f4166; BYTE $0xdf \ // PUNPCKHQDQ XMM3, XMM15 /* row2h = _mm_unpackhi_epi64(t0, ); \ */ - LONG $0x6c0f4466; BYTE $0xff \ // PUNPCKLQDQ XMM15, XMM7 /* _mm_unpacklo_epi64(row4h, row4h) */ - LONG $0x6d0f4166; BYTE $0xf7 \ // PUNPCKHQDQ XMM6, XMM15 /* row4l = _mm_unpackhi_epi64(row4l, ); \ */ - LONG $0x6c0f4566; BYTE $0xfe \ // PUNPCKLQDQ XMM15, XMM14 /* _mm_unpacklo_epi64(t1, t1) */ - LONG $0x6d0f4166; BYTE $0xff // PUNPCKHQDQ XMM7, XMM15 /* row4h = _mm_unpackhi_epi64(row4h, ) */ - -#define LOAD_SHUFFLE \ - \ // Load shuffle value - MOVQ shffle+120(FP), SI \ // SI: &shuffle - MOVOU 0(SI), X12 // X12 = 03040506 07000102 0b0c0d0e 0f08090a - -// func blockSSELoop(p []uint8, in, iv, t, f, shffle, out []uint64) -TEXT 路blockSSELoop(SB), 7, $0 - // REGISTER USE - // R8: loop counter - // DX: message pointer - // SI: temp pointer for loading - // X0 - X7: v0 - v15 - // X8 - X11: m[0] - m[7] - // X12: shuffle value - // X13 - X15: temp registers - - // Load digest - MOVQ in+24(FP), SI // SI: &in - MOVOU 0(SI), X0 // X0 = in[0]+in[1] /* row1l = LOAD( &S->h[0] ); */ - MOVOU 16(SI), X1 // X1 = in[2]+in[3] /* row1h = LOAD( &S->h[2] ); */ - MOVOU 32(SI), X2 // X2 = in[4]+in[5] /* row2l = LOAD( &S->h[4] ); */ - MOVOU 48(SI), X3 // X3 = in[6]+in[7] /* row2h = LOAD( &S->h[6] ); */ - - // Already store digest into &out (so we can reload it later generically) - MOVQ out+144(FP), SI // SI: &out - MOVOU X0, 0(SI) // out[0]+out[1] = X0 - MOVOU X1, 16(SI) // out[2]+out[3] = X1 - MOVOU X2, 32(SI) // out[4]+out[5] = X2 - MOVOU X3, 48(SI) // out[6]+out[7] = X3 - - // Initialize message pointer and loop counter - MOVQ message+0(FP), DX // DX: &p (message) - MOVQ message_len+8(FP), R8 // R8: len(message) - SHRQ $7, R8 // len(message) / 128 - CMPQ R8, $0 - JEQ complete - -loop: - // Increment counter - MOVQ t+72(FP), SI // SI: &t - MOVQ 0(SI), R9 - ADDQ $128, R9 // /* d.t[0] += BlockSize */ - MOVQ R9, 0(SI) - CMPQ R9, $128 // /* if d.t[0] < BlockSize { */ - JGE noincr - MOVQ 8(SI), R9 - ADDQ $1, R9 // /* d.t[1]++ */ - MOVQ R9, 8(SI) - -noincr: // /* } */ - - // Load initialization vector - MOVQ iv+48(FP), SI // SI: &iv - MOVOU 0(SI), X4 // X4 = iv[0]+iv[1] /* row3l = LOAD( &blake2b_IV[0] ); */ - MOVOU 16(SI), X5 // X5 = iv[2]+iv[3] /* row3h = LOAD( &blake2b_IV[2] ); */ - MOVOU 32(SI), X6 // X6 = iv[4]+iv[5] /* LOAD( &blake2b_IV[4] ) */ - MOVOU 48(SI), X7 // X7 = iv[6]+iv[7] /* LOAD( &blake2b_IV[6] ) */ - MOVQ t+72(FP), SI // SI: &t - MOVOU 0(SI), X8 // X8 = t[0]+t[1] /* LOAD( &S->t[0] ) */ - PXOR X8, X6 // X6 = X6 ^ X8 /* row4l = _mm_xor_si128( , ); */ - MOVQ t+96(FP), SI // SI: &f - MOVOU 0(SI), X8 // X8 = f[0]+f[1] /* LOAD( &S->f[0] ) */ - PXOR X8, X7 // X7 = X7 ^ X8 /* row4h = _mm_xor_si128( , ); */ - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+m[1] - MOVOU 16(DX), X13 // X13 = m[2]+m[3] - MOVOU 32(DX), X14 // X14 = m[4]+m[5] - MOVOU 48(DX), X15 // X15 = m[6]+m[7] - MOVOU X12, X8 - LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[0], m[2] */ - MOVOU X14, X9 - LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[4], m[6] */ - MOVOU X12, X10 - LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[1], m[3] */ - MOVOU X14, X11 - LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* m[5], m[7] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 64(DX), X12 // X12 = m[8]+ m[9] - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X12, X8 - LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[8],m[10] */ - MOVOU X14, X9 - LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[12],m[14] */ - MOVOU X12, X10 - LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[9],m[11] */ - MOVOU X14, X11 - LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* m[13],m[15] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 2 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 112(DX), X12 // X12 = m[14]+m[15] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 96(DX), X15 // X15 = m[12]+m[13] - MOVOU X12, X8 - LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[14], m[4] */ - MOVOU X14, X9 - LONG $0x6d0f4566; BYTE $0xcf // PUNPCKHQDQ XMM9, XMM15 /* m[9], m[13] */ - MOVOU 80(DX), X10 // X10 = m[10]+m[11] - MOVOU 48(DX), X11 // X11 = m[6]+ m[7] - LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[10], m[8] */ - LONG $0x3a0f4566; WORD $0xdc0f; BYTE $0x08 // PALIGNR XMM11, XMM12, 0x8 /* m[15], m[6] */; ; ; ; ; - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU X12, X8 - LONG $0x3a0f4566; WORD $0xc40f; BYTE $0x08 // PALIGNR XMM8, XMM12, 0x8 /* m[1], m[0] */ - MOVOU X14, X9 - LONG $0x6d0f4566; BYTE $0xcd // PUNPCKHQDQ XMM9, XMM13 /* m[11], m[5] */ - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X11 // X11 = m[6]+ m[7] - MOVOU 96(DX), X10 // X10 = m[12]+m[13] - LONG $0x6c0f4566; BYTE $0xd4 // PUNPCKLQDQ XMM10, XMM12 /* m[12], m[2] */ - LONG $0x6d0f4566; BYTE $0xdc // PUNPCKHQDQ XMM11, XMM12 /* m[7], m[3] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 3 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 32(DX), X12 // X12 = m[4]+ m[5] - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X14, X8 - LONG $0x3a0f4566; WORD $0xc50f; BYTE $0x08 // PALIGNR XMM8, XMM13, 0x8 /* m[11], m[12] */ - MOVOU X12, X9 - LONG $0x6d0f4566; BYTE $0xcf // PUNPCKHQDQ XMM9, XMM15 /* m[5], m[15] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 16(DX), X13 // X13 = m[2]+ m[3] - MOVOU 64(DX), X10 // X10 = m[8]+ m[9] - LONG $0x6c0f4566; BYTE $0xd4 // PUNPCKLQDQ XMM10, XMM12 /* m[8], m[0] */ - LONG $0x6d0f4566; BYTE $0xf6 // PUNPCKHQDQ XMM14, XMM14 /* ___, m[13] */ - MOVOU X13, X11 - LONG $0x6c0f4566; BYTE $0xde // PUNPCKLQDQ XMM11, XMM14 /* m[2], ___ */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - MOVOU X12, X9 - LONG $0x6d0f4566; BYTE $0xcc // PUNPCKHQDQ XMM9, XMM12 /* ___, m[3] */ - MOVOU X15, X8 - LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[10], ___ */ - MOVOU X13, X9 - LONG $0x6d0f4566; BYTE $0xce // PUNPCKHQDQ XMM9, XMM14 /* m[7], m[9] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X11 // X11 = m[4]+ m[5] - MOVOU 112(DX), X10 // X10 = m[14]+m[15] - LONG $0x6c0f4566; BYTE $0xd5 // PUNPCKLQDQ XMM10, XMM13 /* m[14], m[6] */ - LONG $0x3a0f4566; WORD $0xdc0f; BYTE $0x08 // PALIGNR XMM11, XMM12, 0x8 /* m[1], m[4] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 4 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 96(DX), X15 // X15 = m[12]+m[13] - MOVOU X13, X8 - LONG $0x6d0f4566; BYTE $0xc4 // PUNPCKHQDQ XMM8, XMM12 /* m[7], m[3] */ - MOVOU X15, X9 - LONG $0x6d0f4566; BYTE $0xce // PUNPCKHQDQ XMM9, XMM14 /* m[13], m[11] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 64(DX), X10 // X10 = m[8]+ m[9] - MOVOU 112(DX), X14 // X14 = m[14]+m[15] - LONG $0x6d0f4566; BYTE $0xd4 // PUNPCKHQDQ XMM10, XMM12 /* m[9], m[1] */ - MOVOU X15, X11 - LONG $0x6c0f4566; BYTE $0xde // PUNPCKLQDQ XMM11, XMM14 /* m[12], m[14] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X13, X9 - LONG $0x6d0f4566; BYTE $0xcd // PUNPCKHQDQ XMM9, XMM13 /* ___, m[5] */ - MOVOU X12, X8 - LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[2], ____ */ - MOVOU X15, X10 - LONG $0x6d0f4566; BYTE $0xd7 // PUNPCKHQDQ XMM10, XMM15 /* ___, m[15] */ - MOVOU X13, X9 - LONG $0x6c0f4566; BYTE $0xca // PUNPCKLQDQ XMM9, XMM10 /* m[4], ____ */ - MOVOU 0(DX), X11 // X11 = m[0]+ m[1] - MOVOU 48(DX), X10 // X10 = m[6]+ m[7] - MOVOU 64(DX), X15 // X15 = m[8]+ m[9] - LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[6], m[10] */ - LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[0], m[8] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 5 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - MOVOU X14, X8 - LONG $0x6d0f4566; BYTE $0xc5 // PUNPCKHQDQ XMM8, XMM13 /* m[9], m[5] */ - MOVOU X12, X9 - LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[2], m[10] */ - MOVOU 0(DX), X10 // X10 = m[0]+ m[1] - MOVOU 48(DX), X14 // X14 = m[6]+ m[7] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d0f4566; BYTE $0xf6 // PUNPCKHQDQ XMM14, XMM14 /* ___, m[7] */ - LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[0], ____ */ - LONG $0x6d0f4566; BYTE $0xff // PUNPCKHQDQ XMM15, XMM15 /* ___, m[15] */ - MOVOU X13, X11 - LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[4], ____ */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - LONG $0x6d0f4566; BYTE $0xf6 // PUNPCKHQDQ XMM14, XMM14 /* ___, m[11] */ - MOVOU X15, X8 - LONG $0x6c0f4566; BYTE $0xc6 // PUNPCKLQDQ XMM8, XMM14 /* m[14], ____ */ - LONG $0x6d0f4566; BYTE $0xe4 // PUNPCKHQDQ XMM12, XMM12 /* ___, m[3] */ - MOVOU X13, X9 - LONG $0x6c0f4566; BYTE $0xcc // PUNPCKLQDQ XMM9, XMM12 /* m[6], ____ */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 64(DX), X11 // X11 = m[8]+ m[9] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU X14, X10 - LONG $0x3a0f4566; WORD $0xd40f; BYTE $0x08 // PALIGNR XMM10, XMM12, 0x8 /* m[1], m[12] */ - LONG $0x6d0f4566; BYTE $0xf6 // PUNPCKHQDQ XMM14, XMM14 /* ___, m[13] */ - LONG $0x6c0f4566; BYTE $0xde // PUNPCKLQDQ XMM11, XMM14 /* m[8], ____ */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 6 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 16(DX), X13 // X13 = m[2]+ m[3] - MOVOU 48(DX), X14 // X14 = m[6]+ m[7] - MOVOU 64(DX), X15 // X15 = m[8]+ m[9] - MOVOU X13, X8 - LONG $0x6c0f4566; BYTE $0xc6 // PUNPCKLQDQ XMM8, XMM14 /* m[2], m[6] */ - MOVOU X12, X9 - LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[0], m[8] */ - MOVOU 80(DX), X12 // X12 = m[10]+m[11] - MOVOU 96(DX), X10 // X10 = m[12]+m[13] - LONG $0x6c0f4566; BYTE $0xd4 // PUNPCKLQDQ XMM10, XMM12 /* m[12], m[10] */ - MOVOU X12, X11 - LONG $0x6d0f4566; BYTE $0xdd // PUNPCKHQDQ XMM11, XMM13 /* m[11], m[3] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 48(DX), X14 // X14 = m[6]+ m[7] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X14, X9 - LONG $0x6d0f4566; BYTE $0xce // PUNPCKHQDQ XMM9, XMM14 /* ___, m[7] */ - MOVOU X13, X8 - LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[4], ____ */ - MOVOU X15, X9 - LONG $0x6d0f4566; BYTE $0xcc // PUNPCKHQDQ XMM9, XMM12 /* m[15], m[1] */ - MOVOU 64(DX), X12 // X12 = m[8]+ m[9] - MOVOU 96(DX), X10 // X10 = m[12]+m[13] - LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[13], m[5] */ - LONG $0x6d0f4566; BYTE $0xe4 // PUNPCKHQDQ XMM12, XMM12 /* ___, m[9] */ - MOVOU X15, X11 - LONG $0x6c0f4566; BYTE $0xdc // PUNPCKLQDQ XMM11, XMM12 /* m[14], ____ */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 7 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X12, X9 - LONG $0x6d0f4566; BYTE $0xcc // PUNPCKHQDQ XMM9, XMM12 /* ___, m[1] */ - MOVOU X14, X8 - LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[12], ____ */ - MOVOU X15, X9 - LONG $0x6c0f4566; BYTE $0xcd // PUNPCKLQDQ XMM9, XMM13 /* m[14], m[4] */ - MOVOU 80(DX), X11 // X11 = m[10]+m[11] - MOVOU X13, X10 - LONG $0x6d0f4566; BYTE $0xd7 // PUNPCKHQDQ XMM10, XMM15 /* m[5], m[15] */ - LONG $0x3a0f4566; WORD $0xde0f; BYTE $0x08 // PALIGNR XMM11, XMM14, 0x8 /* m[13], m[10] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - MOVOU X12, X8 - LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[0], m[6] */ - MOVOU X14, X9 - LONG $0x3a0f4566; WORD $0xce0f; BYTE $0x08 // PALIGNR XMM9, XMM14, 0x8 /* m[9], m[8] */ - MOVOU 16(DX), X11 // X14 = m[2]+ m[3] - MOVOU X13, X10 - LONG $0x6d0f4566; BYTE $0xd3 // PUNPCKHQDQ XMM10, XMM11 /* m[7], m[3] */ - LONG $0x6d0f4566; BYTE $0xff // PUNPCKHQDQ XMM15, XMM15 /* ___, m[11] */ - LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[2], ____ */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 8 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X14, X8 - LONG $0x6d0f4566; BYTE $0xc5 // PUNPCKHQDQ XMM8, XMM13 /* m[13], m[7] */ - MOVOU X12, X10 - LONG $0x6d0f4566; BYTE $0xd4 // PUNPCKHQDQ XMM10, XMM12 /* ___, m[3] */ - MOVOU X14, X9 - LONG $0x6c0f4566; BYTE $0xca // PUNPCKLQDQ XMM9, XMM10 /* m[12], ____ */ - MOVOU 0(DX), X11 // X11 = m[0]+ m[1] - MOVOU 64(DX), X13 // X13 = m[8]+ m[9] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU X15, X10 - LONG $0x3a0f4566; WORD $0xd60f; BYTE $0x08 // PALIGNR XMM10, XMM14, 0x8 /* m[11], m[14] */ - LONG $0x6d0f4566; BYTE $0xdd // PUNPCKHQDQ XMM11, XMM13 /* m[1], m[9] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X13, X8 - LONG $0x6d0f4566; BYTE $0xc7 // PUNPCKHQDQ XMM8, XMM15 /* m[5], m[15] */ - MOVOU X14, X9 - LONG $0x6c0f4566; BYTE $0xcc // PUNPCKLQDQ XMM9, XMM12 /* m[8], m[2] */ - MOVOU 0(DX), X10 // X10 = m[0]+ m[1] - MOVOU 48(DX), X11 // X11 = m[6]+ m[7] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - LONG $0x6c0f4566; BYTE $0xd5 // PUNPCKLQDQ XMM10, XMM13 /* m[0], m[4] */ - LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[6], m[10] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 9 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X13, X8 - LONG $0x6c0f4566; BYTE $0xc7 // PUNPCKLQDQ XMM8, XMM15 /* m[6], m[14] */ - MOVOU X12, X9 - LONG $0x3a0f4566; WORD $0xce0f; BYTE $0x08 // PALIGNR XMM9, XMM14, 0x8 /* m[11], m[0] */ - MOVOU 16(DX), X13 // X13 = m[2]+ m[3] - MOVOU 64(DX), X11 // X11 = m[8]+ m[9] - MOVOU X15, X10 - LONG $0x6d0f4566; BYTE $0xd3 // PUNPCKHQDQ XMM10, XMM11 /* m[15], m[9] */ - LONG $0x3a0f4566; WORD $0xdd0f; BYTE $0x08 // PALIGNR XMM11, XMM13, 0x8 /* m[3], m[8] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 16(DX), X13 // X13 = m[2]+ m[3] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU 96(DX), X15 // X15 = m[12]+m[13] - MOVOU X15, X9 - LONG $0x6d0f4566; BYTE $0xcf // PUNPCKHQDQ XMM9, XMM15 /* ___, m[13] */ - MOVOU X15, X8 - LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[12], ____ */ - MOVOU X14, X9 - LONG $0x3a0f4566; WORD $0xcc0f; BYTE $0x08 // PALIGNR XMM9, XMM12, 0x8 /* m[1], m[10] */ - MOVOU 32(DX), X12 // X12 = m[4]+ m[5] - MOVOU 48(DX), X15 // X15 = m[6]+ m[7] - MOVOU X15, X11 - LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* ___, m[7] */ - MOVOU X13, X10 - LONG $0x6c0f4566; BYTE $0xd3 // PUNPCKLQDQ XMM10, XMM11 /* m[2], ____ */ - MOVOU X12, X15 - LONG $0x6d0f4566; BYTE $0xfc // PUNPCKHQDQ XMM15, XMM12 /* ___, m[5] */ - MOVOU X12, X11 - LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[4], ____ */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 0 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 48(DX), X13 // X13 = m[6]+ m[7] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 80(DX), X15 // X15 = m[10]+m[11] - MOVOU X15, X8 - LONG $0x6c0f4566; BYTE $0xc6 // PUNPCKLQDQ XMM8, XMM14 /* m[10], m[8] */ - MOVOU X13, X9 - LONG $0x6d0f4566; BYTE $0xcc // PUNPCKHQDQ XMM9, XMM12 /* m[7], m[1] */ - MOVOU 16(DX), X10 // X10 = m[2]+ m[3] - MOVOU 32(DX), X14 // X14 = m[4]+ m[5] - LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[2], m[4] */ - MOVOU X14, X15 - LONG $0x6d0f4566; BYTE $0xfe // PUNPCKHQDQ XMM15, XMM14 /* ___, m[5] */ - MOVOU X13, X11 - LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[6], ____ */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 64(DX), X13 // X13 = m[8]+ m[9] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X15, X8 - LONG $0x6d0f4566; BYTE $0xc5 // PUNPCKHQDQ XMM8, XMM13 /* m[15], m[9] */ - MOVOU X12, X9 - LONG $0x6d0f4566; BYTE $0xce // PUNPCKHQDQ XMM9, XMM14 /* m[3], m[13] */ - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU X15, X10 - LONG $0x3a0f4566; WORD $0xd50f; BYTE $0x08 // PALIGNR XMM10, XMM13, 0x8 /* m[11], m[14] */ - MOVOU X14, X11 - LONG $0x6c0f4566; BYTE $0xdc // PUNPCKLQDQ XMM11, XMM12 /* m[12], m[0] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 1 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+m[1] - MOVOU 16(DX), X13 // X13 = m[2]+m[3] - MOVOU 32(DX), X14 // X14 = m[4]+m[5] - MOVOU 48(DX), X15 // X15 = m[6]+m[7] - MOVOU X12, X8 - LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[0], m[2] */ - MOVOU X14, X9 - LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[4], m[6] */ - MOVOU X12, X10 - LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[1], m[3] */ - MOVOU X14, X11 - LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* m[5], m[7] */ - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 64(DX), X12 // X12 = m[8]+ m[9] - MOVOU 80(DX), X13 // X13 = m[10]+m[11] - MOVOU 96(DX), X14 // X14 = m[12]+m[13] - MOVOU 112(DX), X15 // X15 = m[14]+m[15] - MOVOU X12, X8 - LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[8],m[10] */ - MOVOU X14, X9 - LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[12],m[14] */ - MOVOU X12, X10 - LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[9],m[11] */ - MOVOU X14, X11 - LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* m[13],m[15] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - /////////////////////////////////////////////////////////////////////////// - // R O U N D 1 2 - /////////////////////////////////////////////////////////////////////////// - - // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) - MOVOU 112(DX), X12 // X12 = m[14]+m[15] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 64(DX), X14 // X14 = m[8]+ m[9] - MOVOU 96(DX), X15 // X15 = m[12]+m[13] - MOVOU X12, X8 - LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[14], m[4] */ - MOVOU X14, X9 - LONG $0x6d0f4566; BYTE $0xcf // PUNPCKHQDQ XMM9, XMM15 /* m[9], m[13] */ - MOVOU 80(DX), X10 // X10 = m[10]+m[11] - MOVOU 48(DX), X11 // X11 = m[6]+ m[7] - LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[10], m[8] */ - LONG $0x3a0f4566; WORD $0xdc0f; BYTE $0x08 // PALIGNR XMM11, XMM12, 0x8 /* m[15], m[6] */; ; ; ; ; - - LOAD_SHUFFLE - G1 - G2 - DIAGONALIZE - - // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) - MOVOU 0(DX), X12 // X12 = m[0]+ m[1] - MOVOU 32(DX), X13 // X13 = m[4]+ m[5] - MOVOU 80(DX), X14 // X14 = m[10]+m[11] - MOVOU X12, X8 - LONG $0x3a0f4566; WORD $0xc40f; BYTE $0x08 // PALIGNR XMM8, XMM12, 0x8 /* m[1], m[0] */ - MOVOU X14, X9 - LONG $0x6d0f4566; BYTE $0xcd // PUNPCKHQDQ XMM9, XMM13 /* m[11], m[5] */ - MOVOU 16(DX), X12 // X12 = m[2]+ m[3] - MOVOU 48(DX), X11 // X11 = m[6]+ m[7] - MOVOU 96(DX), X10 // X10 = m[12]+m[13] - LONG $0x6c0f4566; BYTE $0xd4 // PUNPCKLQDQ XMM10, XMM12 /* m[12], m[2] */ - LONG $0x6d0f4566; BYTE $0xdc // PUNPCKHQDQ XMM11, XMM12 /* m[7], m[3] */ - - LOAD_SHUFFLE - G1 - G2 - UNDIAGONALIZE - - // Reload digest (most current value store in &out) - MOVQ out+144(FP), SI // SI: &in - MOVOU 0(SI), X12 // X12 = in[0]+in[1] /* row1l = LOAD( &S->h[0] ); */ - MOVOU 16(SI), X13 // X13 = in[2]+in[3] /* row1h = LOAD( &S->h[2] ); */ - MOVOU 32(SI), X14 // X14 = in[4]+in[5] /* row2l = LOAD( &S->h[4] ); */ - MOVOU 48(SI), X15 // X15 = in[6]+in[7] /* row2h = LOAD( &S->h[6] ); */ - - // Final computations and prepare for storing - PXOR X4, X0 // X0 = X0 ^ X4 /* row1l = _mm_xor_si128( row3l, row1l ); */ - PXOR X5, X1 // X1 = X1 ^ X5 /* row1h = _mm_xor_si128( row3h, row1h ); */ - PXOR X12, X0 // X0 = X0 ^ X12 /* STORE( &S->h[0], _mm_xor_si128( LOAD( &S->h[0] ), row1l ) ); */ - PXOR X13, X1 // X1 = X1 ^ X13 /* STORE( &S->h[2], _mm_xor_si128( LOAD( &S->h[2] ), row1h ) ); */ - PXOR X6, X2 // X2 = X2 ^ X6 /* row2l = _mm_xor_si128( row4l, row2l ); */ - PXOR X7, X3 // X3 = X3 ^ X7 /* row2h = _mm_xor_si128( row4h, row2h ); */ - PXOR X14, X2 // X2 = X2 ^ X14 /* STORE( &S->h[4], _mm_xor_si128( LOAD( &S->h[4] ), row2l ) ); */ - PXOR X15, X3 // X3 = X3 ^ X15 /* STORE( &S->h[6], _mm_xor_si128( LOAD( &S->h[6] ), row2h ) ); */ - - // Store digest into &out - MOVQ out+144(FP), SI // SI: &out - MOVOU X0, 0(SI) // out[0]+out[1] = X0 - MOVOU X1, 16(SI) // out[2]+out[3] = X1 - MOVOU X2, 32(SI) // out[4]+out[5] = X2 - MOVOU X3, 48(SI) // out[6]+out[7] = X3 - - // Increment message pointer and check if there's more to do - ADDQ $128, DX // message += 128 - SUBQ $1, R8 - JNZ loop - -complete: - RET diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_amd64.go b/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_amd64.go deleted file mode 100644 index 4fc5e388..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_amd64.go +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 blake2b - -func compress(d *digest, p []uint8) { - // Verifies if AVX2 or AVX is available, use optimized code path. - if avx2 { - compressAVX2(d, p) - } else if avx { - compressAVX(d, p) - } else if ssse3 { - compressSSE(d, p) - } else { - compressGeneric(d, p) - } -} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_generic.go b/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_generic.go deleted file mode 100644 index e9e16e8b..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_generic.go +++ /dev/null @@ -1,1419 +0,0 @@ -// Written in 2012 by Dmitry Chestnykh. -// -// To the extent possible under law, the author have dedicated all copyright -// and related and neighboring rights to this software to the public domain -// worldwide. This software is distributed without any warranty. -// http://creativecommons.org/publicdomain/zero/1.0/ - -package blake2b - -func compressGeneric(d *digest, p []uint8) { - h0, h1, h2, h3, h4, h5, h6, h7 := d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] - - for len(p) >= BlockSize { - // Increment counter. - d.t[0] += BlockSize - if d.t[0] < BlockSize { - d.t[1]++ - } - // Initialize compression function. - v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7 - v8 := iv[0] - v9 := iv[1] - v10 := iv[2] - v11 := iv[3] - v12 := iv[4] ^ d.t[0] - v13 := iv[5] ^ d.t[1] - v14 := iv[6] ^ d.f[0] - v15 := iv[7] ^ d.f[1] - - j := 0 - var m [16]uint64 - for i := range m { - m[i] = uint64(p[j]) | uint64(p[j+1])<<8 | uint64(p[j+2])<<16 | - uint64(p[j+3])<<24 | uint64(p[j+4])<<32 | uint64(p[j+5])<<40 | - uint64(p[j+6])<<48 | uint64(p[j+7])<<56 - j += 8 - } - - // Round 1. - v0 += m[0] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[2] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[4] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[6] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[5] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[7] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[3] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[1] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[8] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[10] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[12] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[14] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[13] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[15] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[11] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[9] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 2. - v0 += m[14] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[4] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[9] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[13] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[15] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[6] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[8] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[10] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[1] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[0] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[11] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[5] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[7] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[3] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[2] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[12] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 3. - v0 += m[11] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[12] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[5] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[15] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[2] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[13] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[0] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[8] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[10] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[3] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[7] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[9] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[1] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[4] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[6] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[14] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 4. - v0 += m[7] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[3] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[13] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[11] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[12] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[14] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[1] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[9] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[2] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[5] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[4] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[15] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[0] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[8] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[10] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[6] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 5. - v0 += m[9] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[5] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[2] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[10] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[4] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[15] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[7] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[0] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[14] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[11] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[6] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[3] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[8] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[13] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[12] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[1] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 6. - v0 += m[2] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[6] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[0] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[8] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[11] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[3] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[10] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[12] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[4] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[7] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[15] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[1] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[14] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[9] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[5] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[13] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 7. - v0 += m[12] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[1] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[14] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[4] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[13] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[10] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[15] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[5] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[0] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[6] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[9] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[8] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[2] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[11] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[3] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[7] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 8. - v0 += m[13] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[7] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[12] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[3] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[1] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[9] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[14] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[11] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[5] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[15] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[8] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[2] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[6] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[10] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[4] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[0] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 9. - v0 += m[6] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[14] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[11] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[0] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[3] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[8] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[9] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[15] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[12] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[13] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[1] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[10] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[4] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[5] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[7] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[2] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 10. - v0 += m[10] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[8] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[7] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[1] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[6] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[5] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[4] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[2] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[15] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[9] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[3] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[13] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[12] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[0] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[14] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[11] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 11. - v0 += m[0] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[2] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[4] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[6] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[5] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[7] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[3] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[1] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[8] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[10] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[12] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[14] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[13] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[15] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[11] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[9] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - // Round 12. - v0 += m[14] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-32) | v12>>32 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-24) | v4>>24 - v1 += m[4] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-32) | v13>>32 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-24) | v5>>24 - v2 += m[9] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-32) | v14>>32 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-24) | v6>>24 - v3 += m[13] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-32) | v15>>32 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-24) | v7>>24 - v2 += m[15] - v2 += v6 - v14 ^= v2 - v14 = v14<<(64-16) | v14>>16 - v10 += v14 - v6 ^= v10 - v6 = v6<<(64-63) | v6>>63 - v3 += m[6] - v3 += v7 - v15 ^= v3 - v15 = v15<<(64-16) | v15>>16 - v11 += v15 - v7 ^= v11 - v7 = v7<<(64-63) | v7>>63 - v1 += m[8] - v1 += v5 - v13 ^= v1 - v13 = v13<<(64-16) | v13>>16 - v9 += v13 - v5 ^= v9 - v5 = v5<<(64-63) | v5>>63 - v0 += m[10] - v0 += v4 - v12 ^= v0 - v12 = v12<<(64-16) | v12>>16 - v8 += v12 - v4 ^= v8 - v4 = v4<<(64-63) | v4>>63 - v0 += m[1] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-32) | v15>>32 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-24) | v5>>24 - v1 += m[0] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-32) | v12>>32 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-24) | v6>>24 - v2 += m[11] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-32) | v13>>32 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-24) | v7>>24 - v3 += m[5] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-32) | v14>>32 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-24) | v4>>24 - v2 += m[7] - v2 += v7 - v13 ^= v2 - v13 = v13<<(64-16) | v13>>16 - v8 += v13 - v7 ^= v8 - v7 = v7<<(64-63) | v7>>63 - v3 += m[3] - v3 += v4 - v14 ^= v3 - v14 = v14<<(64-16) | v14>>16 - v9 += v14 - v4 ^= v9 - v4 = v4<<(64-63) | v4>>63 - v1 += m[2] - v1 += v6 - v12 ^= v1 - v12 = v12<<(64-16) | v12>>16 - v11 += v12 - v6 ^= v11 - v6 = v6<<(64-63) | v6>>63 - v0 += m[12] - v0 += v5 - v15 ^= v0 - v15 = v15<<(64-16) | v15>>16 - v10 += v15 - v5 ^= v10 - v5 = v5<<(64-63) | v5>>63 - - h0 ^= v0 ^ v8 - h1 ^= v1 ^ v9 - h2 ^= v2 ^ v10 - h3 ^= v3 ^ v11 - h4 ^= v4 ^ v12 - h5 ^= v5 ^ v13 - h6 ^= v6 ^ v14 - h7 ^= v7 ^ v15 - - p = p[BlockSize:] - } - d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = h0, h1, h2, h3, h4, h5, h6, h7 -} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_noasm.go b/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_noasm.go deleted file mode 100644 index d3c67584..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/compress_noasm.go +++ /dev/null @@ -1,23 +0,0 @@ -//+build !amd64 noasm appengine - -/* - * 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 blake2b - -func compress(d *digest, p []uint8) { - compressGeneric(d, p) -} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid.go b/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid.go deleted file mode 100644 index a9f95508..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid.go +++ /dev/null @@ -1,60 +0,0 @@ -// +build 386,!gccgo amd64,!gccgo - -// Copyright 2016 Frank Wessels -// -// 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 blake2b - -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) - -// True when SIMD instructions are available. -var avx2 = haveAVX2() -var avx = haveAVX() -var ssse3 = haveSSSE3() - -// haveAVX returns true when there is AVX support -func haveAVX() bool { - _, _, c, _ := cpuid(1) - - // Check XGETBV, OXSAVE and AVX bits - if c&(1<<26) != 0 && c&(1<<27) != 0 && c&(1<<28) != 0 { - // Check for OS support - eax, _ := xgetbv(0) - return (eax & 0x6) == 0x6 - } - return false -} - -// haveAVX2 returns true when there is AVX2 support -func haveAVX2() bool { - mfi, _, _, _ := cpuid(0) - - // Check AVX2, AVX2 requires OS support, but BMI1/2 don't. - if mfi >= 7 && haveAVX() { - _, ebx, _, _ := cpuidex(7, 0) - return (ebx & 0x00000020) != 0 - } - return false -} - -// haveSSSE3 returns true when there is SSSE3 support -func haveSSSE3() bool { - - _, _, c, _ := cpuid(1) - - return (c & 0x00000200) != 0 -} diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid_386.s b/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid_386.s deleted file mode 100644 index fa38814e..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid_386.s +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. - -// +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 diff --git a/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid_amd64.s b/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid_amd64.s deleted file mode 100644 index fb45a656..00000000 --- a/fungible/cc/vendor/github.com/minio/blake2b-simd/cpuid_amd64.s +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. - -// +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 diff --git a/fungible/cc/vendor/github.com/multiformats/go-multicodec/README.md b/fungible/cc/vendor/github.com/multiformats/go-multicodec/README.md index ed858e13..d8f7c955 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multicodec/README.md +++ b/fungible/cc/vendor/github.com/multiformats/go-multicodec/README.md @@ -19,20 +19,46 @@ go get github.com/multiformats/go-multicodec + +## Type + +`Code` describes an integer reserved in the multicodec table, defined at [multiformats/multicodec/table.csv](https://github.com/multiformats/multicodec/blob/master/table.csv). + +```go +type Code uint64 +``` + ## Usage +### Importing Code constant + ```go package main import "github.com/multiformats/go-multicodec" func main() { - _ = multicodec.Sha2_256 + code := multicodec.Sha2_256 // Code + name := multicodec.Sha2_256.String() } ``` The corresponding `name` value for each codec from the [multicodecs table](https://raw.githubusercontent.com/multiformats/multicodec/master/table.csv) can be accessed via its `String` method. For example, `multicodec.Sha2_256.String()` will return `sha2-256`. +### Code from string + +```go +var multicodec.Code code +err := code.Set("libp2p-key") +``` + + +### Code from uint64 + +```go +rawCode := multicodec.Code(0x55) +``` + ## Generator To generate the constants yourself: diff --git a/fungible/cc/vendor/github.com/multiformats/go-multicodec/code.go b/fungible/cc/vendor/github.com/multiformats/go-multicodec/code.go index 454465c7..ed6b1dd8 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multicodec/code.go +++ b/fungible/cc/vendor/github.com/multiformats/go-multicodec/code.go @@ -9,7 +9,7 @@ import ( //go:generate go run gen.go //go:generate gofmt -w code_table.go -//go:generate go run golang.org/x/tools/cmd/stringer@v0.1.7 -type=Code -linecomment +//go:generate go run golang.org/x/tools/cmd/stringer@v0.1.10 -type=Code -linecomment // Code describes an integer reserved in the multicodec table, defined at // github.com/multiformats/multicodec. diff --git a/fungible/cc/vendor/github.com/multiformats/go-multicodec/version.json b/fungible/cc/vendor/github.com/multiformats/go-multicodec/version.json index 26a7d478..42c14d1b 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multicodec/version.json +++ b/fungible/cc/vendor/github.com/multiformats/go-multicodec/version.json @@ -1,3 +1,3 @@ { - "version": "v0.4.1" + "version": "v0.6.0" } diff --git a/fungible/cc/vendor/github.com/multiformats/go-multihash/core/magic.go b/fungible/cc/vendor/github.com/multiformats/go-multihash/core/magic.go index d604026a..b85e9a61 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multihash/core/magic.go +++ b/fungible/cc/vendor/github.com/multiformats/go-multihash/core/magic.go @@ -5,6 +5,9 @@ import "errors" // ErrSumNotSupported is returned when the Sum function code is not implemented var ErrSumNotSupported = errors.New("no such hash registered") +// ErrLenTooLarge is returned when the hash function cannot produce the requested number of bytes +var ErrLenTooLarge = errors.New("requested length was too large for digest") + // constants const ( IDENTITY = 0x00 diff --git a/fungible/cc/vendor/github.com/multiformats/go-multihash/core/registry.go b/fungible/cc/vendor/github.com/multiformats/go-multihash/core/registry.go index af27836b..4077f2ba 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multihash/core/registry.go +++ b/fungible/cc/vendor/github.com/multiformats/go-multihash/core/registry.go @@ -10,7 +10,8 @@ import ( ) // registry is a simple map which maps a multihash indicator number -// to a standard golang Hash interface. +// to a function : (size:int) -> ((hasher:hash.Hash), (bool:success)) +// The function may error (i.e., return (nil, false)) to signify that the hasher can't return that many bytes. // // Multihash indicator numbers are reserved and described in // https://github.com/multiformats/multicodec/blob/master/table.csv . @@ -18,7 +19,7 @@ import ( // // Hashers which are available in the golang stdlib will be registered automatically. // Others can be added using the Register function. -var registry = make(map[uint64]func() hash.Hash) +var registry = make(map[uint64]func(int) (h hash.Hash, ok bool)) // Register adds a new hash to the set available from GetHasher and Sum. // @@ -37,8 +38,34 @@ func Register(indicator uint64, hasherFactory func() hash.Hash) { if hasherFactory == nil { panic("not sensible to attempt to register a nil function") } + maxSize := hasherFactory().Size() + registry[indicator] = func(size int) (hash.Hash, bool) { + if size > maxSize { + return nil, false + } + return hasherFactory(), true + } + DefaultLengths[indicator] = maxSize +} + +// RegisterVariableSize is like Register, but adds a new variable-sized hasher factory that takes a +// size hint. +// +// When passed -1, the hasher should produce digests with the hash-function's default length. When +// passed a non-negative integer, the hasher should try to produce digests of at least the specified +// size. +func RegisterVariableSize(indicator uint64, hasherFactory func(sizeHint int) (hash.Hash, bool)) { + if hasherFactory == nil { + panic("not sensible to attempt to register a nil function") + } + + if hasher, ok := hasherFactory(-1); !ok { + panic("failed to determine default hash length for hasher") + } else { + DefaultLengths[indicator] = hasher.Size() + } + registry[indicator] = hasherFactory - DefaultLengths[indicator] = hasherFactory().Size() } // GetHasher returns a new hash.Hash according to the indicator code number provided. @@ -54,11 +81,26 @@ func Register(indicator uint64, hasherFactory func() hash.Hash) { // // If an error is returned, it will match `errors.Is(err, ErrSumNotSupported)`. func GetHasher(indicator uint64) (hash.Hash, error) { + return GetVariableHasher(indicator, -1) +} + +// GetVariableHasher returns a new hash.Hash according to the indicator code number provided, with +// the specified size hint. +// +// NOTE: The size hint is only a hint. Hashers will attempt to produce at least the number of requested bytes, but may not. +// +// This function can fail if either the hash code is not registered, or the passed size hint is +// statically incompatible with the specified hash function. +func GetVariableHasher(indicator uint64, sizeHint int) (hash.Hash, error) { factory, exists := registry[indicator] if !exists { return nil, fmt.Errorf("unknown multihash code %d (0x%x): %w", indicator, indicator, ErrSumNotSupported) } - return factory(), nil + hasher, ok := factory(sizeHint) + if !ok { + return nil, ErrLenTooLarge + } + return hasher, nil } // DefaultLengths maps a multihash indicator code to the output size for that hash, in units of bytes. @@ -68,7 +110,7 @@ func GetHasher(indicator uint64) (hash.Hash, error) { var DefaultLengths = map[uint64]int{} func init() { - Register(IDENTITY, func() hash.Hash { return &identityMultihash{} }) + RegisterVariableSize(IDENTITY, func(_ int) (hash.Hash, bool) { return &identityMultihash{}, true }) Register(MD5, md5.New) Register(SHA1, sha1.New) Register(SHA2_224, sha256.New224) diff --git a/fungible/cc/vendor/github.com/multiformats/go-multihash/multihash.go b/fungible/cc/vendor/github.com/multiformats/go-multihash/multihash.go index 42ab977f..58e631df 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multihash/multihash.go +++ b/fungible/cc/vendor/github.com/multiformats/go-multihash/multihash.go @@ -27,11 +27,12 @@ var ( // ErrInconsistentLen is returned when a decoded multihash has an inconsistent length type ErrInconsistentLen struct { - dm *DecodedMultihash + dm *DecodedMultihash + lengthFound int } func (e ErrInconsistentLen) Error() string { - return fmt.Sprintf("multihash length inconsistent: expected %d, got %d", e.dm.Length, len(e.dm.Digest)) + return fmt.Sprintf("multihash length inconsistent: expected %d; got %d", e.dm.Length, e.lengthFound) } // constants @@ -143,6 +144,7 @@ var Codes = map[uint64]string{ MD5: "md5", } +// reads a varint from buf and returns bytes read. func uvarint(buf []byte) (uint64, []byte, error) { n, c, err := varint.FromUvarint(buf) if err != nil { @@ -233,7 +235,7 @@ func Decode(buf []byte) (*DecodedMultihash, error) { } if len(buf) != rlen { - return nil, ErrInconsistentLen{dm} + return nil, ErrInconsistentLen{dm, rlen} } return dm, nil @@ -264,8 +266,8 @@ func EncodeName(buf []byte, name string) ([]byte, error) { // Note: the returned digest is a slice over the passed in data and should be // copied if the buffer will be reused func readMultihashFromBuf(buf []byte) (int, uint64, []byte, error) { - bufl := len(buf) - if bufl < 2 { + initBufLength := len(buf) + if initBufLength < 2 { return 0, 0, nil, ErrTooShort } @@ -289,7 +291,8 @@ func readMultihashFromBuf(buf []byte) (int, uint64, []byte, error) { return 0, 0, nil, errors.New("length greater than remaining number of bytes in buffer") } - rlen := (bufl - len(buf)) + int(length) + // rlen is the advertised size of the CID + rlen := (initBufLength - len(buf)) + int(length) return rlen, code, buf[:length], nil } diff --git a/fungible/cc/vendor/github.com/multiformats/go-multihash/register/blake2/multihash_blake2.go b/fungible/cc/vendor/github.com/multiformats/go-multihash/register/blake2/multihash_blake2.go index de8f51c4..6794df76 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multihash/register/blake2/multihash_blake2.go +++ b/fungible/cc/vendor/github.com/multiformats/go-multihash/register/blake2/multihash_blake2.go @@ -1,21 +1,21 @@ /* - This package has no purpose except to perform registration of multihashes. +This package has no purpose except to perform registration of multihashes. - It is meant to be used as a side-effecting import, e.g. +It is meant to be used as a side-effecting import, e.g. - import ( - _ "github.com/multiformats/go-multihash/register/blake2" - ) + import ( + _ "github.com/multiformats/go-multihash/register/blake2" + ) - This package registers several multihashes for the blake2 family - (both the 's' and the 'b' variants, and in a variety of sizes). +This package registers several multihashes for the blake2 family +(both the 's' and the 'b' variants, and in a variety of sizes). */ package blake2 import ( "hash" - "github.com/minio/blake2b-simd" + "golang.org/x/crypto/blake2b" "golang.org/x/crypto/blake2s" "github.com/multiformats/go-multihash/core" @@ -31,29 +31,21 @@ const ( func init() { // blake2s // This package only enables support for 32byte (256 bit) blake2s. - multihash.Register(blake2s_min+31, func() hash.Hash { h, _ := blake2s.New256(nil); return h }) + multihash.Register(blake2s_min+31, func() hash.Hash { + h, err := blake2s.New256(nil) + if err != nil { + panic(err) + } + return h + }) // blake2b // There's a whole range of these. for c := uint64(blake2b_min); c <= blake2b_max; c++ { size := int(c - blake2b_min + 1) - // special case these lengths to avoid allocations. - switch size { - case 32: - multihash.Register(c, blake2b.New256) - continue - case 64: - multihash.Register(c, blake2b.New512) - continue - } - - // Ok, allocate away. - // (The config object here being a pointer is a tad unfortunate, - // but we manage amortize it away by making them just once anyway.) - cfg := &blake2b.Config{Size: uint8(size)} multihash.Register(c, func() hash.Hash { - hasher, err := blake2b.New(cfg) + hasher, err := blake2b.New(size, nil) if err != nil { panic(err) } diff --git a/fungible/cc/vendor/github.com/multiformats/go-multihash/register/blake3/multihash_blake3.go b/fungible/cc/vendor/github.com/multiformats/go-multihash/register/blake3/multihash_blake3.go index c67058b9..143fb57d 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multihash/register/blake3/multihash_blake3.go +++ b/fungible/cc/vendor/github.com/multiformats/go-multihash/register/blake3/multihash_blake3.go @@ -17,7 +17,17 @@ import ( "github.com/multiformats/go-multihash/core" ) -func init() { - multihash.Register(multihash.BLAKE3, func() hash.Hash { h := blake3.New(32, nil); return h }) +const DefaultSize = 32 +const MaxSize = 128 +func init() { + multihash.RegisterVariableSize(multihash.BLAKE3, func(size int) (hash.Hash, bool) { + if size == -1 { + size = DefaultSize + } else if size > MaxSize || size <= 0 { + return nil, false + } + h := blake3.New(size, nil) + return h, true + }) } diff --git a/fungible/cc/vendor/github.com/multiformats/go-multihash/sum.go b/fungible/cc/vendor/github.com/multiformats/go-multihash/sum.go index d7d75c55..d40b5aab 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multihash/sum.go +++ b/fungible/cc/vendor/github.com/multiformats/go-multihash/sum.go @@ -1,7 +1,6 @@ package multihash import ( - "errors" "fmt" "hash" "io" @@ -12,14 +11,14 @@ import ( // ErrSumNotSupported is returned when the Sum function code is not implemented var ErrSumNotSupported = mhreg.ErrSumNotSupported -var ErrLenTooLarge = errors.New("requested length was too large for digest") +var ErrLenTooLarge = mhreg.ErrLenTooLarge // Sum obtains the cryptographic sum of a given buffer. The length parameter // indicates the length of the resulting digest. Passing a negative value uses // default length values for the selected hash function. func Sum(data []byte, code uint64, length int) (Multihash, error) { // Get the algorithm. - hasher, err := GetHasher(code) + hasher, err := mhreg.GetVariableHasher(code, length) if err != nil { return nil, err } @@ -35,7 +34,7 @@ func Sum(data []byte, code uint64, length int) (Multihash, error) { // value uses default length values for the selected hash function. func SumStream(r io.Reader, code uint64, length int) (Multihash, error) { // Get the algorithm. - hasher, err := GetHasher(code) + hasher, err := mhreg.GetVariableHasher(code, length) if err != nil { return nil, err } diff --git a/fungible/cc/vendor/github.com/multiformats/go-multihash/version.json b/fungible/cc/vendor/github.com/multiformats/go-multihash/version.json index 07c6dd80..88bcb867 100644 --- a/fungible/cc/vendor/github.com/multiformats/go-multihash/version.json +++ b/fungible/cc/vendor/github.com/multiformats/go-multihash/version.json @@ -1,3 +1,3 @@ { - "version": "v0.1.0" + "version": "v0.2.1" } diff --git a/fungible/cc/vendor/modules.txt b/fungible/cc/vendor/modules.txt index eca4b520..c6afc773 100644 --- a/fungible/cc/vendor/modules.txt +++ b/fungible/cc/vendor/modules.txt @@ -210,7 +210,6 @@ github.com/hyperledger-labs/fabric-token-sdk/token/services/interop/encoding github.com/hyperledger-labs/fabric-token-sdk/token/services/interop/htlc github.com/hyperledger-labs/fabric-token-sdk/token/services/network github.com/hyperledger-labs/fabric-token-sdk/token/services/network/driver -github.com/hyperledger-labs/fabric-token-sdk/token/services/network/fabric/tcc github.com/hyperledger-labs/fabric-token-sdk/token/services/network/processor github.com/hyperledger-labs/fabric-token-sdk/token/services/owner github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx @@ -260,8 +259,8 @@ github.com/hyperledger/fabric-protos-go/ledger/queryresult github.com/hyperledger/fabric-protos-go/ledger/rwset github.com/hyperledger/fabric-protos-go/msp github.com/hyperledger/fabric-protos-go/peer -# github.com/ipfs/go-cid v0.1.0 -## explicit; go 1.15 +# github.com/ipfs/go-cid v0.3.2 +## explicit; go 1.18 github.com/ipfs/go-cid # github.com/ipfs/go-datastore v0.5.1 ## explicit; go 1.16 @@ -285,14 +284,24 @@ github.com/ipfs/go-log/writer # github.com/ipfs/go-log/v2 v2.5.1 ## explicit; go 1.16 github.com/ipfs/go-log/v2 -# github.com/ipld/go-ipld-prime v0.9.0 -## explicit; go 1.14 +# github.com/ipld/go-ipld-prime v0.19.0 +## explicit; go 1.18 github.com/ipld/go-ipld-prime +github.com/ipld/go-ipld-prime/adl +github.com/ipld/go-ipld-prime/codec github.com/ipld/go-ipld-prime/codec/dagcbor +github.com/ipld/go-ipld-prime/datamodel +github.com/ipld/go-ipld-prime/linking github.com/ipld/go-ipld-prime/linking/cid github.com/ipld/go-ipld-prime/multicodec github.com/ipld/go-ipld-prime/node/basic +github.com/ipld/go-ipld-prime/node/basicnode +github.com/ipld/go-ipld-prime/node/bindnode github.com/ipld/go-ipld-prime/node/mixins +github.com/ipld/go-ipld-prime/schema +github.com/ipld/go-ipld-prime/schema/dmt +github.com/ipld/go-ipld-prime/schema/dsl +github.com/ipld/go-ipld-prime/storage # github.com/jackpal/go-nat-pmp v1.0.2 ## explicit github.com/jackpal/go-nat-pmp @@ -497,9 +506,6 @@ github.com/mikioh/tcpinfo # github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc ## explicit github.com/mikioh/tcpopt -# github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 -## explicit -github.com/minio/blake2b-simd # github.com/minio/sha256-simd v1.0.0 ## explicit; go 1.13 github.com/minio/sha256-simd @@ -555,11 +561,11 @@ github.com/multiformats/go-multiaddr-fmt # github.com/multiformats/go-multibase v0.0.3 ## explicit; go 1.11 github.com/multiformats/go-multibase -# github.com/multiformats/go-multicodec v0.4.1 -## explicit; go 1.16 +# github.com/multiformats/go-multicodec v0.6.0 +## explicit; go 1.18 github.com/multiformats/go-multicodec -# github.com/multiformats/go-multihash v0.1.0 -## explicit; go 1.16 +# github.com/multiformats/go-multihash v0.2.1 +## explicit; go 1.17 github.com/multiformats/go-multihash github.com/multiformats/go-multihash/core github.com/multiformats/go-multihash/register/all @@ -623,7 +629,7 @@ github.com/pkg/errors # github.com/pmezard/go-difflib v1.0.0 ## explicit github.com/pmezard/go-difflib/difflib -# github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 +# github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e ## explicit github.com/polydawn/refmt/cbor github.com/polydawn/refmt/obj @@ -699,7 +705,7 @@ go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore go.uber.org/zap/zapgrpc -# golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 +# golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e ## explicit; go 1.17 golang.org/x/crypto/blake2b golang.org/x/crypto/blake2s