vendor
This commit is contained in:
parent
6755d3862e
commit
3dbd98694d
16
vendor/github.com/btcsuite/btcd/LICENSE
generated
vendored
Normal file
16
vendor/github.com/btcsuite/btcd/LICENSE
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2013-2017 The btcsuite developers
|
||||
Copyright (c) 2015-2016 The Decred developers
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
68
vendor/github.com/btcsuite/btcd/btcec/README.md
generated
vendored
Normal file
68
vendor/github.com/btcsuite/btcd/btcec/README.md
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
btcec
|
||||
=====
|
||||
|
||||
[](https://travis-ci.org/btcsuite/btcec)
|
||||
[](http://copyfree.org)
|
||||
[](http://godoc.org/github.com/btcsuite/btcd/btcec)
|
||||
|
||||
Package btcec implements elliptic curve cryptography needed for working with
|
||||
Bitcoin (secp256k1 only for now). It is designed so that it may be used with the
|
||||
standard crypto/ecdsa packages provided with go. A comprehensive suite of test
|
||||
is provided to ensure proper functionality. Package btcec was originally based
|
||||
on work from ThePiachu which is licensed under the same terms as Go, but it has
|
||||
signficantly diverged since then. The btcsuite developers original is licensed
|
||||
under the liberal ISC license.
|
||||
|
||||
Although this package was primarily written for btcd, it has intentionally been
|
||||
designed so it can be used as a standalone package for any projects needing to
|
||||
use secp256k1 elliptic curve cryptography.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/btcsuite/btcd/btcec
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
* [Sign Message](http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--SignMessage)
|
||||
Demonstrates signing a message with a secp256k1 private key that is first
|
||||
parsed form raw bytes and serializing the generated signature.
|
||||
|
||||
* [Verify Signature](http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--VerifySignature)
|
||||
Demonstrates verifying a secp256k1 signature against a public key that is
|
||||
first parsed from raw bytes. The signature is also parsed from raw bytes.
|
||||
|
||||
* [Encryption](http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--EncryptMessage)
|
||||
Demonstrates encrypting a message for a public key that is first parsed from
|
||||
raw bytes, then decrypting it using the corresponding private key.
|
||||
|
||||
* [Decryption](http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--DecryptMessage)
|
||||
Demonstrates decrypting a message using a private key that is first parsed
|
||||
from raw bytes.
|
||||
|
||||
## GPG Verification Key
|
||||
|
||||
All official release tags are signed by Conformal so users can ensure the code
|
||||
has not been tampered with and is coming from the btcsuite developers. To
|
||||
verify the signature perform the following:
|
||||
|
||||
- Download the public key from the Conformal website at
|
||||
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
|
||||
|
||||
- Import the public key into your GPG keyring:
|
||||
```bash
|
||||
gpg --import GIT-GPG-KEY-conformal.txt
|
||||
```
|
||||
|
||||
- Verify the release tag with the following command where `TAG_NAME` is a
|
||||
placeholder for the specific tag:
|
||||
```bash
|
||||
git tag -v TAG_NAME
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Package btcec is licensed under the [copyfree](http://copyfree.org) ISC License
|
||||
except for btcec.go and btcec_test.go which is under the same license as Go.
|
||||
|
976
vendor/github.com/btcsuite/btcd/btcec/btcec.go
generated
vendored
Normal file
976
vendor/github.com/btcsuite/btcd/btcec/btcec.go
generated
vendored
Normal file
@ -0,0 +1,976 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Copyright 2011 ThePiachu. All rights reserved.
|
||||
// Copyright 2013-2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
|
||||
// References:
|
||||
// [SECG]: Recommended Elliptic Curve Domain Parameters
|
||||
// http://www.secg.org/sec2-v2.pdf
|
||||
//
|
||||
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
|
||||
|
||||
// This package operates, internally, on Jacobian coordinates. For a given
|
||||
// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
|
||||
// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
|
||||
// calculation can be performed within the transform (as in ScalarMult and
|
||||
// ScalarBaseMult). But even for Add and Double, it's faster to apply and
|
||||
// reverse the transform than to operate in affine coordinates.
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"math/big"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// fieldOne is simply the integer 1 in field representation. It is
|
||||
// used to avoid needing to create it multiple times during the internal
|
||||
// arithmetic.
|
||||
fieldOne = new(fieldVal).SetInt(1)
|
||||
)
|
||||
|
||||
// KoblitzCurve supports a koblitz curve implementation that fits the ECC Curve
|
||||
// interface from crypto/elliptic.
|
||||
type KoblitzCurve struct {
|
||||
*elliptic.CurveParams
|
||||
|
||||
// q is the value (P+1)/4 used to compute the square root of field
|
||||
// elements.
|
||||
q *big.Int
|
||||
|
||||
H int // cofactor of the curve.
|
||||
halfOrder *big.Int // half the order N
|
||||
|
||||
// fieldB is the constant B of the curve as a fieldVal.
|
||||
fieldB *fieldVal
|
||||
|
||||
// byteSize is simply the bit size / 8 and is provided for convenience
|
||||
// since it is calculated repeatedly.
|
||||
byteSize int
|
||||
|
||||
// bytePoints
|
||||
bytePoints *[32][256][3]fieldVal
|
||||
|
||||
// The next 6 values are used specifically for endomorphism
|
||||
// optimizations in ScalarMult.
|
||||
|
||||
// lambda must fulfill lambda^3 = 1 mod N where N is the order of G.
|
||||
lambda *big.Int
|
||||
|
||||
// beta must fulfill beta^3 = 1 mod P where P is the prime field of the
|
||||
// curve.
|
||||
beta *fieldVal
|
||||
|
||||
// See the EndomorphismVectors in gensecp256k1.go to see how these are
|
||||
// derived.
|
||||
a1 *big.Int
|
||||
b1 *big.Int
|
||||
a2 *big.Int
|
||||
b2 *big.Int
|
||||
}
|
||||
|
||||
// Params returns the parameters for the curve.
|
||||
func (curve *KoblitzCurve) Params() *elliptic.CurveParams {
|
||||
return curve.CurveParams
|
||||
}
|
||||
|
||||
// bigAffineToField takes an affine point (x, y) as big integers and converts
|
||||
// it to an affine point as field values.
|
||||
func (curve *KoblitzCurve) bigAffineToField(x, y *big.Int) (*fieldVal, *fieldVal) {
|
||||
x3, y3 := new(fieldVal), new(fieldVal)
|
||||
x3.SetByteSlice(x.Bytes())
|
||||
y3.SetByteSlice(y.Bytes())
|
||||
|
||||
return x3, y3
|
||||
}
|
||||
|
||||
// fieldJacobianToBigAffine takes a Jacobian point (x, y, z) as field values and
|
||||
// converts it to an affine point as big integers.
|
||||
func (curve *KoblitzCurve) fieldJacobianToBigAffine(x, y, z *fieldVal) (*big.Int, *big.Int) {
|
||||
// Inversions are expensive and both point addition and point doubling
|
||||
// are faster when working with points that have a z value of one. So,
|
||||
// if the point needs to be converted to affine, go ahead and normalize
|
||||
// the point itself at the same time as the calculation is the same.
|
||||
var zInv, tempZ fieldVal
|
||||
zInv.Set(z).Inverse() // zInv = Z^-1
|
||||
tempZ.SquareVal(&zInv) // tempZ = Z^-2
|
||||
x.Mul(&tempZ) // X = X/Z^2 (mag: 1)
|
||||
y.Mul(tempZ.Mul(&zInv)) // Y = Y/Z^3 (mag: 1)
|
||||
z.SetInt(1) // Z = 1 (mag: 1)
|
||||
|
||||
// Normalize the x and y values.
|
||||
x.Normalize()
|
||||
y.Normalize()
|
||||
|
||||
// Convert the field values for the now affine point to big.Ints.
|
||||
x3, y3 := new(big.Int), new(big.Int)
|
||||
x3.SetBytes(x.Bytes()[:])
|
||||
y3.SetBytes(y.Bytes()[:])
|
||||
return x3, y3
|
||||
}
|
||||
|
||||
// IsOnCurve returns boolean if the point (x,y) is on the curve.
|
||||
// Part of the elliptic.Curve interface. This function differs from the
|
||||
// crypto/elliptic algorithm since a = 0 not -3.
|
||||
func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool {
|
||||
// Convert big ints to field values for faster arithmetic.
|
||||
fx, fy := curve.bigAffineToField(x, y)
|
||||
|
||||
// Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7
|
||||
y2 := new(fieldVal).SquareVal(fy).Normalize()
|
||||
result := new(fieldVal).SquareVal(fx).Mul(fx).AddInt(7).Normalize()
|
||||
return y2.Equals(result)
|
||||
}
|
||||
|
||||
// addZ1AndZ2EqualsOne adds two Jacobian points that are already known to have
|
||||
// z values of 1 and stores the result in (x3, y3, z3). That is to say
|
||||
// (x1, y1, 1) + (x2, y2, 1) = (x3, y3, z3). It performs faster addition than
|
||||
// the generic add routine since less arithmetic is needed due to the ability to
|
||||
// avoid the z value multiplications.
|
||||
func (curve *KoblitzCurve) addZ1AndZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, z3 *fieldVal) {
|
||||
// To compute the point addition efficiently, this implementation splits
|
||||
// the equation into intermediate elements which are used to minimize
|
||||
// the number of field multiplications using the method shown at:
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl
|
||||
//
|
||||
// In particular it performs the calculations using the following:
|
||||
// H = X2-X1, HH = H^2, I = 4*HH, J = H*I, r = 2*(Y2-Y1), V = X1*I
|
||||
// X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = 2*H
|
||||
//
|
||||
// This results in a cost of 4 field multiplications, 2 field squarings,
|
||||
// 6 field additions, and 5 integer multiplications.
|
||||
|
||||
// When the x coordinates are the same for two points on the curve, the
|
||||
// y coordinates either must be the same, in which case it is point
|
||||
// doubling, or they are opposite and the result is the point at
|
||||
// infinity per the group law for elliptic curve cryptography.
|
||||
x1.Normalize()
|
||||
y1.Normalize()
|
||||
x2.Normalize()
|
||||
y2.Normalize()
|
||||
if x1.Equals(x2) {
|
||||
if y1.Equals(y2) {
|
||||
// Since x1 == x2 and y1 == y2, point doubling must be
|
||||
// done, otherwise the addition would end up dividing
|
||||
// by zero.
|
||||
curve.doubleJacobian(x1, y1, z1, x3, y3, z3)
|
||||
return
|
||||
}
|
||||
|
||||
// Since x1 == x2 and y1 == -y2, the sum is the point at
|
||||
// infinity per the group law.
|
||||
x3.SetInt(0)
|
||||
y3.SetInt(0)
|
||||
z3.SetInt(0)
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate X3, Y3, and Z3 according to the intermediate elements
|
||||
// breakdown above.
|
||||
var h, i, j, r, v fieldVal
|
||||
var negJ, neg2V, negX3 fieldVal
|
||||
h.Set(x1).Negate(1).Add(x2) // H = X2-X1 (mag: 3)
|
||||
i.SquareVal(&h).MulInt(4) // I = 4*H^2 (mag: 4)
|
||||
j.Mul2(&h, &i) // J = H*I (mag: 1)
|
||||
r.Set(y1).Negate(1).Add(y2).MulInt(2) // r = 2*(Y2-Y1) (mag: 6)
|
||||
v.Mul2(x1, &i) // V = X1*I (mag: 1)
|
||||
negJ.Set(&j).Negate(1) // negJ = -J (mag: 2)
|
||||
neg2V.Set(&v).MulInt(2).Negate(2) // neg2V = -(2*V) (mag: 3)
|
||||
x3.Set(&r).Square().Add(&negJ).Add(&neg2V) // X3 = r^2-J-2*V (mag: 6)
|
||||
negX3.Set(x3).Negate(6) // negX3 = -X3 (mag: 7)
|
||||
j.Mul(y1).MulInt(2).Negate(2) // J = -(2*Y1*J) (mag: 3)
|
||||
y3.Set(&v).Add(&negX3).Mul(&r).Add(&j) // Y3 = r*(V-X3)-2*Y1*J (mag: 4)
|
||||
z3.Set(&h).MulInt(2) // Z3 = 2*H (mag: 6)
|
||||
|
||||
// Normalize the resulting field values to a magnitude of 1 as needed.
|
||||
x3.Normalize()
|
||||
y3.Normalize()
|
||||
z3.Normalize()
|
||||
}
|
||||
|
||||
// addZ1EqualsZ2 adds two Jacobian points that are already known to have the
|
||||
// same z value and stores the result in (x3, y3, z3). That is to say
|
||||
// (x1, y1, z1) + (x2, y2, z1) = (x3, y3, z3). It performs faster addition than
|
||||
// the generic add routine since less arithmetic is needed due to the known
|
||||
// equivalence.
|
||||
func (curve *KoblitzCurve) addZ1EqualsZ2(x1, y1, z1, x2, y2, x3, y3, z3 *fieldVal) {
|
||||
// To compute the point addition efficiently, this implementation splits
|
||||
// the equation into intermediate elements which are used to minimize
|
||||
// the number of field multiplications using a slightly modified version
|
||||
// of the method shown at:
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl
|
||||
//
|
||||
// In particular it performs the calculations using the following:
|
||||
// A = X2-X1, B = A^2, C=Y2-Y1, D = C^2, E = X1*B, F = X2*B
|
||||
// X3 = D-E-F, Y3 = C*(E-X3)-Y1*(F-E), Z3 = Z1*A
|
||||
//
|
||||
// This results in a cost of 5 field multiplications, 2 field squarings,
|
||||
// 9 field additions, and 0 integer multiplications.
|
||||
|
||||
// When the x coordinates are the same for two points on the curve, the
|
||||
// y coordinates either must be the same, in which case it is point
|
||||
// doubling, or they are opposite and the result is the point at
|
||||
// infinity per the group law for elliptic curve cryptography.
|
||||
x1.Normalize()
|
||||
y1.Normalize()
|
||||
x2.Normalize()
|
||||
y2.Normalize()
|
||||
if x1.Equals(x2) {
|
||||
if y1.Equals(y2) {
|
||||
// Since x1 == x2 and y1 == y2, point doubling must be
|
||||
// done, otherwise the addition would end up dividing
|
||||
// by zero.
|
||||
curve.doubleJacobian(x1, y1, z1, x3, y3, z3)
|
||||
return
|
||||
}
|
||||
|
||||
// Since x1 == x2 and y1 == -y2, the sum is the point at
|
||||
// infinity per the group law.
|
||||
x3.SetInt(0)
|
||||
y3.SetInt(0)
|
||||
z3.SetInt(0)
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate X3, Y3, and Z3 according to the intermediate elements
|
||||
// breakdown above.
|
||||
var a, b, c, d, e, f fieldVal
|
||||
var negX1, negY1, negE, negX3 fieldVal
|
||||
negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2)
|
||||
negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2)
|
||||
a.Set(&negX1).Add(x2) // A = X2-X1 (mag: 3)
|
||||
b.SquareVal(&a) // B = A^2 (mag: 1)
|
||||
c.Set(&negY1).Add(y2) // C = Y2-Y1 (mag: 3)
|
||||
d.SquareVal(&c) // D = C^2 (mag: 1)
|
||||
e.Mul2(x1, &b) // E = X1*B (mag: 1)
|
||||
negE.Set(&e).Negate(1) // negE = -E (mag: 2)
|
||||
f.Mul2(x2, &b) // F = X2*B (mag: 1)
|
||||
x3.Add2(&e, &f).Negate(3).Add(&d) // X3 = D-E-F (mag: 5)
|
||||
negX3.Set(x3).Negate(5).Normalize() // negX3 = -X3 (mag: 1)
|
||||
y3.Set(y1).Mul(f.Add(&negE)).Negate(3) // Y3 = -(Y1*(F-E)) (mag: 4)
|
||||
y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 5)
|
||||
z3.Mul2(z1, &a) // Z3 = Z1*A (mag: 1)
|
||||
|
||||
// Normalize the resulting field values to a magnitude of 1 as needed.
|
||||
x3.Normalize()
|
||||
y3.Normalize()
|
||||
}
|
||||
|
||||
// addZ2EqualsOne adds two Jacobian points when the second point is already
|
||||
// known to have a z value of 1 (and the z value for the first point is not 1)
|
||||
// and stores the result in (x3, y3, z3). That is to say (x1, y1, z1) +
|
||||
// (x2, y2, 1) = (x3, y3, z3). It performs faster addition than the generic
|
||||
// add routine since less arithmetic is needed due to the ability to avoid
|
||||
// multiplications by the second point's z value.
|
||||
func (curve *KoblitzCurve) addZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, z3 *fieldVal) {
|
||||
// To compute the point addition efficiently, this implementation splits
|
||||
// the equation into intermediate elements which are used to minimize
|
||||
// the number of field multiplications using the method shown at:
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
|
||||
//
|
||||
// In particular it performs the calculations using the following:
|
||||
// Z1Z1 = Z1^2, U2 = X2*Z1Z1, S2 = Y2*Z1*Z1Z1, H = U2-X1, HH = H^2,
|
||||
// I = 4*HH, J = H*I, r = 2*(S2-Y1), V = X1*I
|
||||
// X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = (Z1+H)^2-Z1Z1-HH
|
||||
//
|
||||
// This results in a cost of 7 field multiplications, 4 field squarings,
|
||||
// 9 field additions, and 4 integer multiplications.
|
||||
|
||||
// When the x coordinates are the same for two points on the curve, the
|
||||
// y coordinates either must be the same, in which case it is point
|
||||
// doubling, or they are opposite and the result is the point at
|
||||
// infinity per the group law for elliptic curve cryptography. Since
|
||||
// any number of Jacobian coordinates can represent the same affine
|
||||
// point, the x and y values need to be converted to like terms. Due to
|
||||
// the assumption made for this function that the second point has a z
|
||||
// value of 1 (z2=1), the first point is already "converted".
|
||||
var z1z1, u2, s2 fieldVal
|
||||
x1.Normalize()
|
||||
y1.Normalize()
|
||||
z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1)
|
||||
u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1)
|
||||
s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1)
|
||||
if x1.Equals(&u2) {
|
||||
if y1.Equals(&s2) {
|
||||
// Since x1 == x2 and y1 == y2, point doubling must be
|
||||
// done, otherwise the addition would end up dividing
|
||||
// by zero.
|
||||
curve.doubleJacobian(x1, y1, z1, x3, y3, z3)
|
||||
return
|
||||
}
|
||||
|
||||
// Since x1 == x2 and y1 == -y2, the sum is the point at
|
||||
// infinity per the group law.
|
||||
x3.SetInt(0)
|
||||
y3.SetInt(0)
|
||||
z3.SetInt(0)
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate X3, Y3, and Z3 according to the intermediate elements
|
||||
// breakdown above.
|
||||
var h, hh, i, j, r, rr, v fieldVal
|
||||
var negX1, negY1, negX3 fieldVal
|
||||
negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2)
|
||||
h.Add2(&u2, &negX1) // H = U2-X1 (mag: 3)
|
||||
hh.SquareVal(&h) // HH = H^2 (mag: 1)
|
||||
i.Set(&hh).MulInt(4) // I = 4 * HH (mag: 4)
|
||||
j.Mul2(&h, &i) // J = H*I (mag: 1)
|
||||
negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2)
|
||||
r.Set(&s2).Add(&negY1).MulInt(2) // r = 2*(S2-Y1) (mag: 6)
|
||||
rr.SquareVal(&r) // rr = r^2 (mag: 1)
|
||||
v.Mul2(x1, &i) // V = X1*I (mag: 1)
|
||||
x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4)
|
||||
x3.Add(&rr) // X3 = r^2+X3 (mag: 5)
|
||||
negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6)
|
||||
y3.Set(y1).Mul(&j).MulInt(2).Negate(2) // Y3 = -(2*Y1*J) (mag: 3)
|
||||
y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4)
|
||||
z3.Add2(z1, &h).Square() // Z3 = (Z1+H)^2 (mag: 1)
|
||||
z3.Add(z1z1.Add(&hh).Negate(2)) // Z3 = Z3-(Z1Z1+HH) (mag: 4)
|
||||
|
||||
// Normalize the resulting field values to a magnitude of 1 as needed.
|
||||
x3.Normalize()
|
||||
y3.Normalize()
|
||||
z3.Normalize()
|
||||
}
|
||||
|
||||
// addGeneric adds two Jacobian points (x1, y1, z1) and (x2, y2, z2) without any
|
||||
// assumptions about the z values of the two points and stores the result in
|
||||
// (x3, y3, z3). That is to say (x1, y1, z1) + (x2, y2, z2) = (x3, y3, z3). It
|
||||
// is the slowest of the add routines due to requiring the most arithmetic.
|
||||
func (curve *KoblitzCurve) addGeneric(x1, y1, z1, x2, y2, z2, x3, y3, z3 *fieldVal) {
|
||||
// To compute the point addition efficiently, this implementation splits
|
||||
// the equation into intermediate elements which are used to minimize
|
||||
// the number of field multiplications using the method shown at:
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
|
||||
//
|
||||
// In particular it performs the calculations using the following:
|
||||
// Z1Z1 = Z1^2, Z2Z2 = Z2^2, U1 = X1*Z2Z2, U2 = X2*Z1Z1, S1 = Y1*Z2*Z2Z2
|
||||
// S2 = Y2*Z1*Z1Z1, H = U2-U1, I = (2*H)^2, J = H*I, r = 2*(S2-S1)
|
||||
// V = U1*I
|
||||
// X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*S1*J, Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H
|
||||
//
|
||||
// This results in a cost of 11 field multiplications, 5 field squarings,
|
||||
// 9 field additions, and 4 integer multiplications.
|
||||
|
||||
// When the x coordinates are the same for two points on the curve, the
|
||||
// y coordinates either must be the same, in which case it is point
|
||||
// doubling, or they are opposite and the result is the point at
|
||||
// infinity. Since any number of Jacobian coordinates can represent the
|
||||
// same affine point, the x and y values need to be converted to like
|
||||
// terms.
|
||||
var z1z1, z2z2, u1, u2, s1, s2 fieldVal
|
||||
z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1)
|
||||
z2z2.SquareVal(z2) // Z2Z2 = Z2^2 (mag: 1)
|
||||
u1.Set(x1).Mul(&z2z2).Normalize() // U1 = X1*Z2Z2 (mag: 1)
|
||||
u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1)
|
||||
s1.Set(y1).Mul(&z2z2).Mul(z2).Normalize() // S1 = Y1*Z2*Z2Z2 (mag: 1)
|
||||
s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1)
|
||||
if u1.Equals(&u2) {
|
||||
if s1.Equals(&s2) {
|
||||
// Since x1 == x2 and y1 == y2, point doubling must be
|
||||
// done, otherwise the addition would end up dividing
|
||||
// by zero.
|
||||
curve.doubleJacobian(x1, y1, z1, x3, y3, z3)
|
||||
return
|
||||
}
|
||||
|
||||
// Since x1 == x2 and y1 == -y2, the sum is the point at
|
||||
// infinity per the group law.
|
||||
x3.SetInt(0)
|
||||
y3.SetInt(0)
|
||||
z3.SetInt(0)
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate X3, Y3, and Z3 according to the intermediate elements
|
||||
// breakdown above.
|
||||
var h, i, j, r, rr, v fieldVal
|
||||
var negU1, negS1, negX3 fieldVal
|
||||
negU1.Set(&u1).Negate(1) // negU1 = -U1 (mag: 2)
|
||||
h.Add2(&u2, &negU1) // H = U2-U1 (mag: 3)
|
||||
i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 2)
|
||||
j.Mul2(&h, &i) // J = H*I (mag: 1)
|
||||
negS1.Set(&s1).Negate(1) // negS1 = -S1 (mag: 2)
|
||||
r.Set(&s2).Add(&negS1).MulInt(2) // r = 2*(S2-S1) (mag: 6)
|
||||
rr.SquareVal(&r) // rr = r^2 (mag: 1)
|
||||
v.Mul2(&u1, &i) // V = U1*I (mag: 1)
|
||||
x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4)
|
||||
x3.Add(&rr) // X3 = r^2+X3 (mag: 5)
|
||||
negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6)
|
||||
y3.Mul2(&s1, &j).MulInt(2).Negate(2) // Y3 = -(2*S1*J) (mag: 3)
|
||||
y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4)
|
||||
z3.Add2(z1, z2).Square() // Z3 = (Z1+Z2)^2 (mag: 1)
|
||||
z3.Add(z1z1.Add(&z2z2).Negate(2)) // Z3 = Z3-(Z1Z1+Z2Z2) (mag: 4)
|
||||
z3.Mul(&h) // Z3 = Z3*H (mag: 1)
|
||||
|
||||
// Normalize the resulting field values to a magnitude of 1 as needed.
|
||||
x3.Normalize()
|
||||
y3.Normalize()
|
||||
}
|
||||
|
||||
// addJacobian adds the passed Jacobian points (x1, y1, z1) and (x2, y2, z2)
|
||||
// together and stores the result in (x3, y3, z3).
|
||||
func (curve *KoblitzCurve) addJacobian(x1, y1, z1, x2, y2, z2, x3, y3, z3 *fieldVal) {
|
||||
// A point at infinity is the identity according to the group law for
|
||||
// elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P.
|
||||
if (x1.IsZero() && y1.IsZero()) || z1.IsZero() {
|
||||
x3.Set(x2)
|
||||
y3.Set(y2)
|
||||
z3.Set(z2)
|
||||
return
|
||||
}
|
||||
if (x2.IsZero() && y2.IsZero()) || z2.IsZero() {
|
||||
x3.Set(x1)
|
||||
y3.Set(y1)
|
||||
z3.Set(z1)
|
||||
return
|
||||
}
|
||||
|
||||
// Faster point addition can be achieved when certain assumptions are
|
||||
// met. For example, when both points have the same z value, arithmetic
|
||||
// on the z values can be avoided. This section thus checks for these
|
||||
// conditions and calls an appropriate add function which is accelerated
|
||||
// by using those assumptions.
|
||||
z1.Normalize()
|
||||
z2.Normalize()
|
||||
isZ1One := z1.Equals(fieldOne)
|
||||
isZ2One := z2.Equals(fieldOne)
|
||||
switch {
|
||||
case isZ1One && isZ2One:
|
||||
curve.addZ1AndZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, z3)
|
||||
return
|
||||
case z1.Equals(z2):
|
||||
curve.addZ1EqualsZ2(x1, y1, z1, x2, y2, x3, y3, z3)
|
||||
return
|
||||
case isZ2One:
|
||||
curve.addZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, z3)
|
||||
return
|
||||
}
|
||||
|
||||
// None of the above assumptions are true, so fall back to generic
|
||||
// point addition.
|
||||
curve.addGeneric(x1, y1, z1, x2, y2, z2, x3, y3, z3)
|
||||
}
|
||||
|
||||
// Add returns the sum of (x1,y1) and (x2,y2). Part of the elliptic.Curve
|
||||
// interface.
|
||||
func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
|
||||
// A point at infinity is the identity according to the group law for
|
||||
// elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P.
|
||||
if x1.Sign() == 0 && y1.Sign() == 0 {
|
||||
return x2, y2
|
||||
}
|
||||
if x2.Sign() == 0 && y2.Sign() == 0 {
|
||||
return x1, y1
|
||||
}
|
||||
|
||||
// Convert the affine coordinates from big integers to field values
|
||||
// and do the point addition in Jacobian projective space.
|
||||
fx1, fy1 := curve.bigAffineToField(x1, y1)
|
||||
fx2, fy2 := curve.bigAffineToField(x2, y2)
|
||||
fx3, fy3, fz3 := new(fieldVal), new(fieldVal), new(fieldVal)
|
||||
fOne := new(fieldVal).SetInt(1)
|
||||
curve.addJacobian(fx1, fy1, fOne, fx2, fy2, fOne, fx3, fy3, fz3)
|
||||
|
||||
// Convert the Jacobian coordinate field values back to affine big
|
||||
// integers.
|
||||
return curve.fieldJacobianToBigAffine(fx3, fy3, fz3)
|
||||
}
|
||||
|
||||
// doubleZ1EqualsOne performs point doubling on the passed Jacobian point
|
||||
// when the point is already known to have a z value of 1 and stores
|
||||
// the result in (x3, y3, z3). That is to say (x3, y3, z3) = 2*(x1, y1, 1). It
|
||||
// performs faster point doubling than the generic routine since less arithmetic
|
||||
// is needed due to the ability to avoid multiplication by the z value.
|
||||
func (curve *KoblitzCurve) doubleZ1EqualsOne(x1, y1, x3, y3, z3 *fieldVal) {
|
||||
// This function uses the assumptions that z1 is 1, thus the point
|
||||
// doubling formulas reduce to:
|
||||
//
|
||||
// X3 = (3*X1^2)^2 - 8*X1*Y1^2
|
||||
// Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4
|
||||
// Z3 = 2*Y1
|
||||
//
|
||||
// To compute the above efficiently, this implementation splits the
|
||||
// equation into intermediate elements which are used to minimize the
|
||||
// number of field multiplications in favor of field squarings which
|
||||
// are roughly 35% faster than field multiplications with the current
|
||||
// implementation at the time this was written.
|
||||
//
|
||||
// This uses a slightly modified version of the method shown at:
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl
|
||||
//
|
||||
// In particular it performs the calculations using the following:
|
||||
// A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C)
|
||||
// E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C
|
||||
// Z3 = 2*Y1
|
||||
//
|
||||
// This results in a cost of 1 field multiplication, 5 field squarings,
|
||||
// 6 field additions, and 5 integer multiplications.
|
||||
var a, b, c, d, e, f fieldVal
|
||||
z3.Set(y1).MulInt(2) // Z3 = 2*Y1 (mag: 2)
|
||||
a.SquareVal(x1) // A = X1^2 (mag: 1)
|
||||
b.SquareVal(y1) // B = Y1^2 (mag: 1)
|
||||
c.SquareVal(&b) // C = B^2 (mag: 1)
|
||||
b.Add(x1).Square() // B = (X1+B)^2 (mag: 1)
|
||||
d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3)
|
||||
d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8)
|
||||
e.Set(&a).MulInt(3) // E = 3*A (mag: 3)
|
||||
f.SquareVal(&e) // F = E^2 (mag: 1)
|
||||
x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17)
|
||||
x3.Add(&f) // X3 = F+X3 (mag: 18)
|
||||
f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1)
|
||||
y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9)
|
||||
y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10)
|
||||
|
||||
// Normalize the field values back to a magnitude of 1.
|
||||
x3.Normalize()
|
||||
y3.Normalize()
|
||||
z3.Normalize()
|
||||
}
|
||||
|
||||
// doubleGeneric performs point doubling on the passed Jacobian point without
|
||||
// any assumptions about the z value and stores the result in (x3, y3, z3).
|
||||
// That is to say (x3, y3, z3) = 2*(x1, y1, z1). It is the slowest of the point
|
||||
// doubling routines due to requiring the most arithmetic.
|
||||
func (curve *KoblitzCurve) doubleGeneric(x1, y1, z1, x3, y3, z3 *fieldVal) {
|
||||
// Point doubling formula for Jacobian coordinates for the secp256k1
|
||||
// curve:
|
||||
// X3 = (3*X1^2)^2 - 8*X1*Y1^2
|
||||
// Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4
|
||||
// Z3 = 2*Y1*Z1
|
||||
//
|
||||
// To compute the above efficiently, this implementation splits the
|
||||
// equation into intermediate elements which are used to minimize the
|
||||
// number of field multiplications in favor of field squarings which
|
||||
// are roughly 35% faster than field multiplications with the current
|
||||
// implementation at the time this was written.
|
||||
//
|
||||
// This uses a slightly modified version of the method shown at:
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
|
||||
//
|
||||
// In particular it performs the calculations using the following:
|
||||
// A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C)
|
||||
// E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C
|
||||
// Z3 = 2*Y1*Z1
|
||||
//
|
||||
// This results in a cost of 1 field multiplication, 5 field squarings,
|
||||
// 6 field additions, and 5 integer multiplications.
|
||||
var a, b, c, d, e, f fieldVal
|
||||
z3.Mul2(y1, z1).MulInt(2) // Z3 = 2*Y1*Z1 (mag: 2)
|
||||
a.SquareVal(x1) // A = X1^2 (mag: 1)
|
||||
b.SquareVal(y1) // B = Y1^2 (mag: 1)
|
||||
c.SquareVal(&b) // C = B^2 (mag: 1)
|
||||
b.Add(x1).Square() // B = (X1+B)^2 (mag: 1)
|
||||
d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3)
|
||||
d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8)
|
||||
e.Set(&a).MulInt(3) // E = 3*A (mag: 3)
|
||||
f.SquareVal(&e) // F = E^2 (mag: 1)
|
||||
x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17)
|
||||
x3.Add(&f) // X3 = F+X3 (mag: 18)
|
||||
f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1)
|
||||
y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9)
|
||||
y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10)
|
||||
|
||||
// Normalize the field values back to a magnitude of 1.
|
||||
x3.Normalize()
|
||||
y3.Normalize()
|
||||
z3.Normalize()
|
||||
}
|
||||
|
||||
// doubleJacobian doubles the passed Jacobian point (x1, y1, z1) and stores the
|
||||
// result in (x3, y3, z3).
|
||||
func (curve *KoblitzCurve) doubleJacobian(x1, y1, z1, x3, y3, z3 *fieldVal) {
|
||||
// Doubling a point at infinity is still infinity.
|
||||
if y1.IsZero() || z1.IsZero() {
|
||||
x3.SetInt(0)
|
||||
y3.SetInt(0)
|
||||
z3.SetInt(0)
|
||||
return
|
||||
}
|
||||
|
||||
// Slightly faster point doubling can be achieved when the z value is 1
|
||||
// by avoiding the multiplication on the z value. This section calls
|
||||
// a point doubling function which is accelerated by using that
|
||||
// assumption when possible.
|
||||
if z1.Normalize().Equals(fieldOne) {
|
||||
curve.doubleZ1EqualsOne(x1, y1, x3, y3, z3)
|
||||
return
|
||||
}
|
||||
|
||||
// Fall back to generic point doubling which works with arbitrary z
|
||||
// values.
|
||||
curve.doubleGeneric(x1, y1, z1, x3, y3, z3)
|
||||
}
|
||||
|
||||
// Double returns 2*(x1,y1). Part of the elliptic.Curve interface.
|
||||
func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
|
||||
if y1.Sign() == 0 {
|
||||
return new(big.Int), new(big.Int)
|
||||
}
|
||||
|
||||
// Convert the affine coordinates from big integers to field values
|
||||
// and do the point doubling in Jacobian projective space.
|
||||
fx1, fy1 := curve.bigAffineToField(x1, y1)
|
||||
fx3, fy3, fz3 := new(fieldVal), new(fieldVal), new(fieldVal)
|
||||
fOne := new(fieldVal).SetInt(1)
|
||||
curve.doubleJacobian(fx1, fy1, fOne, fx3, fy3, fz3)
|
||||
|
||||
// Convert the Jacobian coordinate field values back to affine big
|
||||
// integers.
|
||||
return curve.fieldJacobianToBigAffine(fx3, fy3, fz3)
|
||||
}
|
||||
|
||||
// splitK returns a balanced length-two representation of k and their signs.
|
||||
// This is algorithm 3.74 from [GECC].
|
||||
//
|
||||
// One thing of note about this algorithm is that no matter what c1 and c2 are,
|
||||
// the final equation of k = k1 + k2 * lambda (mod n) will hold. This is
|
||||
// provable mathematically due to how a1/b1/a2/b2 are computed.
|
||||
//
|
||||
// c1 and c2 are chosen to minimize the max(k1,k2).
|
||||
func (curve *KoblitzCurve) splitK(k []byte) ([]byte, []byte, int, int) {
|
||||
// All math here is done with big.Int, which is slow.
|
||||
// At some point, it might be useful to write something similar to
|
||||
// fieldVal but for N instead of P as the prime field if this ends up
|
||||
// being a bottleneck.
|
||||
bigIntK := new(big.Int)
|
||||
c1, c2 := new(big.Int), new(big.Int)
|
||||
tmp1, tmp2 := new(big.Int), new(big.Int)
|
||||
k1, k2 := new(big.Int), new(big.Int)
|
||||
|
||||
bigIntK.SetBytes(k)
|
||||
// c1 = round(b2 * k / n) from step 4.
|
||||
// Rounding isn't really necessary and costs too much, hence skipped
|
||||
c1.Mul(curve.b2, bigIntK)
|
||||
c1.Div(c1, curve.N)
|
||||
// c2 = round(b1 * k / n) from step 4 (sign reversed to optimize one step)
|
||||
// Rounding isn't really necessary and costs too much, hence skipped
|
||||
c2.Mul(curve.b1, bigIntK)
|
||||
c2.Div(c2, curve.N)
|
||||
// k1 = k - c1 * a1 - c2 * a2 from step 5 (note c2's sign is reversed)
|
||||
tmp1.Mul(c1, curve.a1)
|
||||
tmp2.Mul(c2, curve.a2)
|
||||
k1.Sub(bigIntK, tmp1)
|
||||
k1.Add(k1, tmp2)
|
||||
// k2 = - c1 * b1 - c2 * b2 from step 5 (note c2's sign is reversed)
|
||||
tmp1.Mul(c1, curve.b1)
|
||||
tmp2.Mul(c2, curve.b2)
|
||||
k2.Sub(tmp2, tmp1)
|
||||
|
||||
// Note Bytes() throws out the sign of k1 and k2. This matters
|
||||
// since k1 and/or k2 can be negative. Hence, we pass that
|
||||
// back separately.
|
||||
return k1.Bytes(), k2.Bytes(), k1.Sign(), k2.Sign()
|
||||
}
|
||||
|
||||
// moduloReduce reduces k from more than 32 bytes to 32 bytes and under. This
|
||||
// is done by doing a simple modulo curve.N. We can do this since G^N = 1 and
|
||||
// thus any other valid point on the elliptic curve has the same order.
|
||||
func (curve *KoblitzCurve) moduloReduce(k []byte) []byte {
|
||||
// Since the order of G is curve.N, we can use a much smaller number
|
||||
// by doing modulo curve.N
|
||||
if len(k) > curve.byteSize {
|
||||
// Reduce k by performing modulo curve.N.
|
||||
tmpK := new(big.Int).SetBytes(k)
|
||||
tmpK.Mod(tmpK, curve.N)
|
||||
return tmpK.Bytes()
|
||||
}
|
||||
|
||||
return k
|
||||
}
|
||||
|
||||
// NAF takes a positive integer k and returns the Non-Adjacent Form (NAF) as two
|
||||
// byte slices. The first is where 1s will be. The second is where -1s will
|
||||
// be. NAF is convenient in that on average, only 1/3rd of its values are
|
||||
// non-zero. This is algorithm 3.30 from [GECC].
|
||||
//
|
||||
// Essentially, this makes it possible to minimize the number of operations
|
||||
// since the resulting ints returned will be at least 50% 0s.
|
||||
func NAF(k []byte) ([]byte, []byte) {
|
||||
// The essence of this algorithm is that whenever we have consecutive 1s
|
||||
// in the binary, we want to put a -1 in the lowest bit and get a bunch
|
||||
// of 0s up to the highest bit of consecutive 1s. This is due to this
|
||||
// identity:
|
||||
// 2^n + 2^(n-1) + 2^(n-2) + ... + 2^(n-k) = 2^(n+1) - 2^(n-k)
|
||||
//
|
||||
// The algorithm thus may need to go 1 more bit than the length of the
|
||||
// bits we actually have, hence bits being 1 bit longer than was
|
||||
// necessary. Since we need to know whether adding will cause a carry,
|
||||
// we go from right-to-left in this addition.
|
||||
var carry, curIsOne, nextIsOne bool
|
||||
// these default to zero
|
||||
retPos := make([]byte, len(k)+1)
|
||||
retNeg := make([]byte, len(k)+1)
|
||||
for i := len(k) - 1; i >= 0; i-- {
|
||||
curByte := k[i]
|
||||
for j := uint(0); j < 8; j++ {
|
||||
curIsOne = curByte&1 == 1
|
||||
if j == 7 {
|
||||
if i == 0 {
|
||||
nextIsOne = false
|
||||
} else {
|
||||
nextIsOne = k[i-1]&1 == 1
|
||||
}
|
||||
} else {
|
||||
nextIsOne = curByte&2 == 2
|
||||
}
|
||||
if carry {
|
||||
if curIsOne {
|
||||
// This bit is 1, so continue to carry
|
||||
// and don't need to do anything.
|
||||
} else {
|
||||
// We've hit a 0 after some number of
|
||||
// 1s.
|
||||
if nextIsOne {
|
||||
// Start carrying again since
|
||||
// a new sequence of 1s is
|
||||
// starting.
|
||||
retNeg[i+1] += 1 << j
|
||||
} else {
|
||||
// Stop carrying since 1s have
|
||||
// stopped.
|
||||
carry = false
|
||||
retPos[i+1] += 1 << j
|
||||
}
|
||||
}
|
||||
} else if curIsOne {
|
||||
if nextIsOne {
|
||||
// If this is the start of at least 2
|
||||
// consecutive 1s, set the current one
|
||||
// to -1 and start carrying.
|
||||
retNeg[i+1] += 1 << j
|
||||
carry = true
|
||||
} else {
|
||||
// This is a singleton, not consecutive
|
||||
// 1s.
|
||||
retPos[i+1] += 1 << j
|
||||
}
|
||||
}
|
||||
curByte >>= 1
|
||||
}
|
||||
}
|
||||
if carry {
|
||||
retPos[0] = 1
|
||||
return retPos, retNeg
|
||||
}
|
||||
return retPos[1:], retNeg[1:]
|
||||
}
|
||||
|
||||
// ScalarMult returns k*(Bx, By) where k is a big endian integer.
|
||||
// Part of the elliptic.Curve interface.
|
||||
func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
|
||||
// Point Q = ∞ (point at infinity).
|
||||
qx, qy, qz := new(fieldVal), new(fieldVal), new(fieldVal)
|
||||
|
||||
// Decompose K into k1 and k2 in order to halve the number of EC ops.
|
||||
// See Algorithm 3.74 in [GECC].
|
||||
k1, k2, signK1, signK2 := curve.splitK(curve.moduloReduce(k))
|
||||
|
||||
// The main equation here to remember is:
|
||||
// k * P = k1 * P + k2 * ϕ(P)
|
||||
//
|
||||
// P1 below is P in the equation, P2 below is ϕ(P) in the equation
|
||||
p1x, p1y := curve.bigAffineToField(Bx, By)
|
||||
p1yNeg := new(fieldVal).NegateVal(p1y, 1)
|
||||
p1z := new(fieldVal).SetInt(1)
|
||||
|
||||
// NOTE: ϕ(x,y) = (βx,y). The Jacobian z coordinate is 1, so this math
|
||||
// goes through.
|
||||
p2x := new(fieldVal).Mul2(p1x, curve.beta)
|
||||
p2y := new(fieldVal).Set(p1y)
|
||||
p2yNeg := new(fieldVal).NegateVal(p2y, 1)
|
||||
p2z := new(fieldVal).SetInt(1)
|
||||
|
||||
// Flip the positive and negative values of the points as needed
|
||||
// depending on the signs of k1 and k2. As mentioned in the equation
|
||||
// above, each of k1 and k2 are multiplied by the respective point.
|
||||
// Since -k * P is the same thing as k * -P, and the group law for
|
||||
// elliptic curves states that P(x, y) = -P(x, -y), it's faster and
|
||||
// simplifies the code to just make the point negative.
|
||||
if signK1 == -1 {
|
||||
p1y, p1yNeg = p1yNeg, p1y
|
||||
}
|
||||
if signK2 == -1 {
|
||||
p2y, p2yNeg = p2yNeg, p2y
|
||||
}
|
||||
|
||||
// NAF versions of k1 and k2 should have a lot more zeros.
|
||||
//
|
||||
// The Pos version of the bytes contain the +1s and the Neg versions
|
||||
// contain the -1s.
|
||||
k1PosNAF, k1NegNAF := NAF(k1)
|
||||
k2PosNAF, k2NegNAF := NAF(k2)
|
||||
k1Len := len(k1PosNAF)
|
||||
k2Len := len(k2PosNAF)
|
||||
|
||||
m := k1Len
|
||||
if m < k2Len {
|
||||
m = k2Len
|
||||
}
|
||||
|
||||
// Add left-to-right using the NAF optimization. See algorithm 3.77
|
||||
// from [GECC]. This should be faster overall since there will be a lot
|
||||
// more instances of 0, hence reducing the number of Jacobian additions
|
||||
// at the cost of 1 possible extra doubling.
|
||||
var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte
|
||||
for i := 0; i < m; i++ {
|
||||
// Since we're going left-to-right, pad the front with 0s.
|
||||
if i < m-k1Len {
|
||||
k1BytePos = 0
|
||||
k1ByteNeg = 0
|
||||
} else {
|
||||
k1BytePos = k1PosNAF[i-(m-k1Len)]
|
||||
k1ByteNeg = k1NegNAF[i-(m-k1Len)]
|
||||
}
|
||||
if i < m-k2Len {
|
||||
k2BytePos = 0
|
||||
k2ByteNeg = 0
|
||||
} else {
|
||||
k2BytePos = k2PosNAF[i-(m-k2Len)]
|
||||
k2ByteNeg = k2NegNAF[i-(m-k2Len)]
|
||||
}
|
||||
|
||||
for j := 7; j >= 0; j-- {
|
||||
// Q = 2 * Q
|
||||
curve.doubleJacobian(qx, qy, qz, qx, qy, qz)
|
||||
|
||||
if k1BytePos&0x80 == 0x80 {
|
||||
curve.addJacobian(qx, qy, qz, p1x, p1y, p1z,
|
||||
qx, qy, qz)
|
||||
} else if k1ByteNeg&0x80 == 0x80 {
|
||||
curve.addJacobian(qx, qy, qz, p1x, p1yNeg, p1z,
|
||||
qx, qy, qz)
|
||||
}
|
||||
|
||||
if k2BytePos&0x80 == 0x80 {
|
||||
curve.addJacobian(qx, qy, qz, p2x, p2y, p2z,
|
||||
qx, qy, qz)
|
||||
} else if k2ByteNeg&0x80 == 0x80 {
|
||||
curve.addJacobian(qx, qy, qz, p2x, p2yNeg, p2z,
|
||||
qx, qy, qz)
|
||||
}
|
||||
k1BytePos <<= 1
|
||||
k1ByteNeg <<= 1
|
||||
k2BytePos <<= 1
|
||||
k2ByteNeg <<= 1
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the Jacobian coordinate field values back to affine big.Ints.
|
||||
return curve.fieldJacobianToBigAffine(qx, qy, qz)
|
||||
}
|
||||
|
||||
// ScalarBaseMult returns k*G where G is the base point of the group and k is a
|
||||
// big endian integer.
|
||||
// Part of the elliptic.Curve interface.
|
||||
func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
|
||||
newK := curve.moduloReduce(k)
|
||||
diff := len(curve.bytePoints) - len(newK)
|
||||
|
||||
// Point Q = ∞ (point at infinity).
|
||||
qx, qy, qz := new(fieldVal), new(fieldVal), new(fieldVal)
|
||||
|
||||
// curve.bytePoints has all 256 byte points for each 8-bit window. The
|
||||
// strategy is to add up the byte points. This is best understood by
|
||||
// expressing k in base-256 which it already sort of is.
|
||||
// Each "digit" in the 8-bit window can be looked up using bytePoints
|
||||
// and added together.
|
||||
for i, byteVal := range newK {
|
||||
p := curve.bytePoints[diff+i][byteVal]
|
||||
curve.addJacobian(qx, qy, qz, &p[0], &p[1], &p[2], qx, qy, qz)
|
||||
}
|
||||
return curve.fieldJacobianToBigAffine(qx, qy, qz)
|
||||
}
|
||||
|
||||
// QPlus1Div4 returns the (P+1)/4 constant for the curve for use in calculating
|
||||
// square roots via exponentiation.
|
||||
//
|
||||
// DEPRECATED: The actual value returned is (P+1)/4, where as the original
|
||||
// method name implies that this value is (((P+1)/4)+1)/4. This method is kept
|
||||
// to maintain backwards compatibility of the API. Use Q() instead.
|
||||
func (curve *KoblitzCurve) QPlus1Div4() *big.Int {
|
||||
return curve.q
|
||||
}
|
||||
|
||||
// Q returns the (P+1)/4 constant for the curve for use in calculating square
|
||||
// roots via exponentiation.
|
||||
func (curve *KoblitzCurve) Q() *big.Int {
|
||||
return curve.q
|
||||
}
|
||||
|
||||
var initonce sync.Once
|
||||
var secp256k1 KoblitzCurve
|
||||
|
||||
func initAll() {
|
||||
initS256()
|
||||
}
|
||||
|
||||
// fromHex converts the passed hex string into a big integer pointer and will
|
||||
// panic is there is an error. This is only provided for the hard-coded
|
||||
// constants so errors in the source code can bet detected. It will only (and
|
||||
// must only) be called for initialization purposes.
|
||||
func fromHex(s string) *big.Int {
|
||||
r, ok := new(big.Int).SetString(s, 16)
|
||||
if !ok {
|
||||
panic("invalid hex in source file: " + s)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func initS256() {
|
||||
// Curve parameters taken from [SECG] section 2.4.1.
|
||||
secp256k1.CurveParams = new(elliptic.CurveParams)
|
||||
secp256k1.P = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")
|
||||
secp256k1.N = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")
|
||||
secp256k1.B = fromHex("0000000000000000000000000000000000000000000000000000000000000007")
|
||||
secp256k1.Gx = fromHex("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798")
|
||||
secp256k1.Gy = fromHex("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")
|
||||
secp256k1.BitSize = 256
|
||||
secp256k1.q = new(big.Int).Div(new(big.Int).Add(secp256k1.P,
|
||||
big.NewInt(1)), big.NewInt(4))
|
||||
secp256k1.H = 1
|
||||
secp256k1.halfOrder = new(big.Int).Rsh(secp256k1.N, 1)
|
||||
secp256k1.fieldB = new(fieldVal).SetByteSlice(secp256k1.B.Bytes())
|
||||
|
||||
// Provided for convenience since this gets computed repeatedly.
|
||||
secp256k1.byteSize = secp256k1.BitSize / 8
|
||||
|
||||
// Deserialize and set the pre-computed table used to accelerate scalar
|
||||
// base multiplication. This is hard-coded data, so any errors are
|
||||
// panics because it means something is wrong in the source code.
|
||||
if err := loadS256BytePoints(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Next 6 constants are from Hal Finney's bitcointalk.org post:
|
||||
// https://bitcointalk.org/index.php?topic=3238.msg45565#msg45565
|
||||
// May he rest in peace.
|
||||
//
|
||||
// They have also been independently derived from the code in the
|
||||
// EndomorphismVectors function in gensecp256k1.go.
|
||||
secp256k1.lambda = fromHex("5363AD4CC05C30E0A5261C028812645A122E22EA20816678DF02967C1B23BD72")
|
||||
secp256k1.beta = new(fieldVal).SetHex("7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE")
|
||||
secp256k1.a1 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
|
||||
secp256k1.b1 = fromHex("-E4437ED6010E88286F547FA90ABFE4C3")
|
||||
secp256k1.a2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8")
|
||||
secp256k1.b2 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
|
||||
|
||||
// Alternatively, we can use the parameters below, however, they seem
|
||||
// to be about 8% slower.
|
||||
// secp256k1.lambda = fromHex("AC9C52B33FA3CF1F5AD9E3FD77ED9BA4A880B9FC8EC739C2E0CFC810B51283CE")
|
||||
// secp256k1.beta = new(fieldVal).SetHex("851695D49A83F8EF919BB86153CBCB16630FB68AED0A766A3EC693D68E6AFA40")
|
||||
// secp256k1.a1 = fromHex("E4437ED6010E88286F547FA90ABFE4C3")
|
||||
// secp256k1.b1 = fromHex("-3086D221A7D46BCDE86C90E49284EB15")
|
||||
// secp256k1.a2 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
|
||||
// secp256k1.b2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8")
|
||||
}
|
||||
|
||||
// S256 returns a Curve which implements secp256k1.
|
||||
func S256() *KoblitzCurve {
|
||||
initonce.Do(initAll)
|
||||
return &secp256k1
|
||||
}
|
216
vendor/github.com/btcsuite/btcd/btcec/ciphering.go
generated
vendored
Normal file
216
vendor/github.com/btcsuite/btcd/btcec/ciphering.go
generated
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
// Copyright (c) 2015-2016 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidMAC occurs when Message Authentication Check (MAC) fails
|
||||
// during decryption. This happens because of either invalid private key or
|
||||
// corrupt ciphertext.
|
||||
ErrInvalidMAC = errors.New("invalid mac hash")
|
||||
|
||||
// errInputTooShort occurs when the input ciphertext to the Decrypt
|
||||
// function is less than 134 bytes long.
|
||||
errInputTooShort = errors.New("ciphertext too short")
|
||||
|
||||
// errUnsupportedCurve occurs when the first two bytes of the encrypted
|
||||
// text aren't 0x02CA (= 712 = secp256k1, from OpenSSL).
|
||||
errUnsupportedCurve = errors.New("unsupported curve")
|
||||
|
||||
errInvalidXLength = errors.New("invalid X length, must be 32")
|
||||
errInvalidYLength = errors.New("invalid Y length, must be 32")
|
||||
errInvalidPadding = errors.New("invalid PKCS#7 padding")
|
||||
|
||||
// 0x02CA = 714
|
||||
ciphCurveBytes = [2]byte{0x02, 0xCA}
|
||||
// 0x20 = 32
|
||||
ciphCoordLength = [2]byte{0x00, 0x20}
|
||||
)
|
||||
|
||||
// GenerateSharedSecret generates a shared secret based on a private key and a
|
||||
// public key using Diffie-Hellman key exchange (ECDH) (RFC 4753).
|
||||
// RFC5903 Section 9 states we should only return x.
|
||||
func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte {
|
||||
x, _ := pubkey.Curve.ScalarMult(pubkey.X, pubkey.Y, privkey.D.Bytes())
|
||||
return x.Bytes()
|
||||
}
|
||||
|
||||
// Encrypt encrypts data for the target public key using AES-256-CBC. It also
|
||||
// generates a private key (the pubkey of which is also in the output). The only
|
||||
// supported curve is secp256k1. The `structure' that it encodes everything into
|
||||
// is:
|
||||
//
|
||||
// struct {
|
||||
// // Initialization Vector used for AES-256-CBC
|
||||
// IV [16]byte
|
||||
// // Public Key: curve(2) + len_of_pubkeyX(2) + pubkeyX +
|
||||
// // len_of_pubkeyY(2) + pubkeyY (curve = 714)
|
||||
// PublicKey [70]byte
|
||||
// // Cipher text
|
||||
// Data []byte
|
||||
// // HMAC-SHA-256 Message Authentication Code
|
||||
// HMAC [32]byte
|
||||
// }
|
||||
//
|
||||
// The primary aim is to ensure byte compatibility with Pyelliptic. Also, refer
|
||||
// to section 5.8.1 of ANSI X9.63 for rationale on this format.
|
||||
func Encrypt(pubkey *PublicKey, in []byte) ([]byte, error) {
|
||||
ephemeral, err := NewPrivateKey(S256())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ecdhKey := GenerateSharedSecret(ephemeral, pubkey)
|
||||
derivedKey := sha512.Sum512(ecdhKey)
|
||||
keyE := derivedKey[:32]
|
||||
keyM := derivedKey[32:]
|
||||
|
||||
paddedIn := addPKCSPadding(in)
|
||||
// IV + Curve params/X/Y + padded plaintext/ciphertext + HMAC-256
|
||||
out := make([]byte, aes.BlockSize+70+len(paddedIn)+sha256.Size)
|
||||
iv := out[:aes.BlockSize]
|
||||
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// start writing public key
|
||||
pb := ephemeral.PubKey().SerializeUncompressed()
|
||||
offset := aes.BlockSize
|
||||
|
||||
// curve and X length
|
||||
copy(out[offset:offset+4], append(ciphCurveBytes[:], ciphCoordLength[:]...))
|
||||
offset += 4
|
||||
// X
|
||||
copy(out[offset:offset+32], pb[1:33])
|
||||
offset += 32
|
||||
// Y length
|
||||
copy(out[offset:offset+2], ciphCoordLength[:])
|
||||
offset += 2
|
||||
// Y
|
||||
copy(out[offset:offset+32], pb[33:])
|
||||
offset += 32
|
||||
|
||||
// start encryption
|
||||
block, err := aes.NewCipher(keyE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(out[offset:len(out)-sha256.Size], paddedIn)
|
||||
|
||||
// start HMAC-SHA-256
|
||||
hm := hmac.New(sha256.New, keyM)
|
||||
hm.Write(out[:len(out)-sha256.Size]) // everything is hashed
|
||||
copy(out[len(out)-sha256.Size:], hm.Sum(nil)) // write checksum
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Decrypt decrypts data that was encrypted using the Encrypt function.
|
||||
func Decrypt(priv *PrivateKey, in []byte) ([]byte, error) {
|
||||
// IV + Curve params/X/Y + 1 block + HMAC-256
|
||||
if len(in) < aes.BlockSize+70+aes.BlockSize+sha256.Size {
|
||||
return nil, errInputTooShort
|
||||
}
|
||||
|
||||
// read iv
|
||||
iv := in[:aes.BlockSize]
|
||||
offset := aes.BlockSize
|
||||
|
||||
// start reading pubkey
|
||||
if !bytes.Equal(in[offset:offset+2], ciphCurveBytes[:]) {
|
||||
return nil, errUnsupportedCurve
|
||||
}
|
||||
offset += 2
|
||||
|
||||
if !bytes.Equal(in[offset:offset+2], ciphCoordLength[:]) {
|
||||
return nil, errInvalidXLength
|
||||
}
|
||||
offset += 2
|
||||
|
||||
xBytes := in[offset : offset+32]
|
||||
offset += 32
|
||||
|
||||
if !bytes.Equal(in[offset:offset+2], ciphCoordLength[:]) {
|
||||
return nil, errInvalidYLength
|
||||
}
|
||||
offset += 2
|
||||
|
||||
yBytes := in[offset : offset+32]
|
||||
offset += 32
|
||||
|
||||
pb := make([]byte, 65)
|
||||
pb[0] = byte(0x04) // uncompressed
|
||||
copy(pb[1:33], xBytes)
|
||||
copy(pb[33:], yBytes)
|
||||
// check if (X, Y) lies on the curve and create a Pubkey if it does
|
||||
pubkey, err := ParsePubKey(pb, S256())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// check for cipher text length
|
||||
if (len(in)-aes.BlockSize-offset-sha256.Size)%aes.BlockSize != 0 {
|
||||
return nil, errInvalidPadding // not padded to 16 bytes
|
||||
}
|
||||
|
||||
// read hmac
|
||||
messageMAC := in[len(in)-sha256.Size:]
|
||||
|
||||
// generate shared secret
|
||||
ecdhKey := GenerateSharedSecret(priv, pubkey)
|
||||
derivedKey := sha512.Sum512(ecdhKey)
|
||||
keyE := derivedKey[:32]
|
||||
keyM := derivedKey[32:]
|
||||
|
||||
// verify mac
|
||||
hm := hmac.New(sha256.New, keyM)
|
||||
hm.Write(in[:len(in)-sha256.Size]) // everything is hashed
|
||||
expectedMAC := hm.Sum(nil)
|
||||
if !hmac.Equal(messageMAC, expectedMAC) {
|
||||
return nil, ErrInvalidMAC
|
||||
}
|
||||
|
||||
// start decryption
|
||||
block, err := aes.NewCipher(keyE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
// same length as ciphertext
|
||||
plaintext := make([]byte, len(in)-offset-sha256.Size)
|
||||
mode.CryptBlocks(plaintext, in[offset:len(in)-sha256.Size])
|
||||
|
||||
return removePKCSPadding(plaintext)
|
||||
}
|
||||
|
||||
// Implement PKCS#7 padding with block size of 16 (AES block size).
|
||||
|
||||
// addPKCSPadding adds padding to a block of data
|
||||
func addPKCSPadding(src []byte) []byte {
|
||||
padding := aes.BlockSize - len(src)%aes.BlockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(src, padtext...)
|
||||
}
|
||||
|
||||
// removePKCSPadding removes padding from data that was added with addPKCSPadding
|
||||
func removePKCSPadding(src []byte) ([]byte, error) {
|
||||
length := len(src)
|
||||
padLength := int(src[length-1])
|
||||
if padLength > aes.BlockSize || length < aes.BlockSize {
|
||||
return nil, errInvalidPadding
|
||||
}
|
||||
|
||||
return src[:length-padLength], nil
|
||||
}
|
21
vendor/github.com/btcsuite/btcd/btcec/doc.go
generated
vendored
Normal file
21
vendor/github.com/btcsuite/btcd/btcec/doc.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package btcec implements support for the elliptic curves needed for bitcoin.
|
||||
|
||||
Bitcoin uses elliptic curve cryptography using koblitz curves
|
||||
(specifically secp256k1) for cryptographic functions. See
|
||||
http://www.secg.org/collateral/sec2_final.pdf for details on the
|
||||
standard.
|
||||
|
||||
This package provides the data structures and functions implementing the
|
||||
crypto/elliptic Curve interface in order to permit using these curves
|
||||
with the standard crypto/ecdsa package provided with go. Helper
|
||||
functionality is provided to parse signatures and public keys from
|
||||
standard formats. It was designed for use with btcd, but should be
|
||||
general enough for other uses of elliptic curve crypto. It was originally based
|
||||
on some initial work by ThePiachu, but has significantly diverged since then.
|
||||
*/
|
||||
package btcec
|
1352
vendor/github.com/btcsuite/btcd/btcec/field.go
generated
vendored
Normal file
1352
vendor/github.com/btcsuite/btcd/btcec/field.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
203
vendor/github.com/btcsuite/btcd/btcec/gensecp256k1.go
generated
vendored
Normal file
203
vendor/github.com/btcsuite/btcd/btcec/gensecp256k1.go
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
// Copyright (c) 2014-2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is ignored during the regular build due to the following build tag.
|
||||
// This build tag is set during go generate.
|
||||
// +build gensecp256k1
|
||||
|
||||
package btcec
|
||||
|
||||
// References:
|
||||
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// secp256k1BytePoints are dummy points used so the code which generates the
|
||||
// real values can compile.
|
||||
var secp256k1BytePoints = ""
|
||||
|
||||
// getDoublingPoints returns all the possible G^(2^i) for i in
|
||||
// 0..n-1 where n is the curve's bit size (256 in the case of secp256k1)
|
||||
// the coordinates are recorded as Jacobian coordinates.
|
||||
func (curve *KoblitzCurve) getDoublingPoints() [][3]fieldVal {
|
||||
doublingPoints := make([][3]fieldVal, curve.BitSize)
|
||||
|
||||
// initialize px, py, pz to the Jacobian coordinates for the base point
|
||||
px, py := curve.bigAffineToField(curve.Gx, curve.Gy)
|
||||
pz := new(fieldVal).SetInt(1)
|
||||
for i := 0; i < curve.BitSize; i++ {
|
||||
doublingPoints[i] = [3]fieldVal{*px, *py, *pz}
|
||||
// P = 2*P
|
||||
curve.doubleJacobian(px, py, pz, px, py, pz)
|
||||
}
|
||||
return doublingPoints
|
||||
}
|
||||
|
||||
// SerializedBytePoints returns a serialized byte slice which contains all of
|
||||
// the possible points per 8-bit window. This is used to when generating
|
||||
// secp256k1.go.
|
||||
func (curve *KoblitzCurve) SerializedBytePoints() []byte {
|
||||
doublingPoints := curve.getDoublingPoints()
|
||||
|
||||
// Segregate the bits into byte-sized windows
|
||||
serialized := make([]byte, curve.byteSize*256*3*10*4)
|
||||
offset := 0
|
||||
for byteNum := 0; byteNum < curve.byteSize; byteNum++ {
|
||||
// Grab the 8 bits that make up this byte from doublingPoints.
|
||||
startingBit := 8 * (curve.byteSize - byteNum - 1)
|
||||
computingPoints := doublingPoints[startingBit : startingBit+8]
|
||||
|
||||
// Compute all points in this window and serialize them.
|
||||
for i := 0; i < 256; i++ {
|
||||
px, py, pz := new(fieldVal), new(fieldVal), new(fieldVal)
|
||||
for j := 0; j < 8; j++ {
|
||||
if i>>uint(j)&1 == 1 {
|
||||
curve.addJacobian(px, py, pz, &computingPoints[j][0],
|
||||
&computingPoints[j][1], &computingPoints[j][2], px, py, pz)
|
||||
}
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
binary.LittleEndian.PutUint32(serialized[offset:], px.n[i])
|
||||
offset += 4
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
binary.LittleEndian.PutUint32(serialized[offset:], py.n[i])
|
||||
offset += 4
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
binary.LittleEndian.PutUint32(serialized[offset:], pz.n[i])
|
||||
offset += 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return serialized
|
||||
}
|
||||
|
||||
// sqrt returns the square root of the provided big integer using Newton's
|
||||
// method. It's only compiled and used during generation of pre-computed
|
||||
// values, so speed is not a huge concern.
|
||||
func sqrt(n *big.Int) *big.Int {
|
||||
// Initial guess = 2^(log_2(n)/2)
|
||||
guess := big.NewInt(2)
|
||||
guess.Exp(guess, big.NewInt(int64(n.BitLen()/2)), nil)
|
||||
|
||||
// Now refine using Newton's method.
|
||||
big2 := big.NewInt(2)
|
||||
prevGuess := big.NewInt(0)
|
||||
for {
|
||||
prevGuess.Set(guess)
|
||||
guess.Add(guess, new(big.Int).Div(n, guess))
|
||||
guess.Div(guess, big2)
|
||||
if guess.Cmp(prevGuess) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return guess
|
||||
}
|
||||
|
||||
// EndomorphismVectors runs the first 3 steps of algorithm 3.74 from [GECC] to
|
||||
// generate the linearly independent vectors needed to generate a balanced
|
||||
// length-two representation of a multiplier such that k = k1 + k2λ (mod N) and
|
||||
// returns them. Since the values will always be the same given the fact that N
|
||||
// and λ are fixed, the final results can be accelerated by storing the
|
||||
// precomputed values with the curve.
|
||||
func (curve *KoblitzCurve) EndomorphismVectors() (a1, b1, a2, b2 *big.Int) {
|
||||
bigMinus1 := big.NewInt(-1)
|
||||
|
||||
// This section uses an extended Euclidean algorithm to generate a
|
||||
// sequence of equations:
|
||||
// s[i] * N + t[i] * λ = r[i]
|
||||
|
||||
nSqrt := sqrt(curve.N)
|
||||
u, v := new(big.Int).Set(curve.N), new(big.Int).Set(curve.lambda)
|
||||
x1, y1 := big.NewInt(1), big.NewInt(0)
|
||||
x2, y2 := big.NewInt(0), big.NewInt(1)
|
||||
q, r := new(big.Int), new(big.Int)
|
||||
qu, qx1, qy1 := new(big.Int), new(big.Int), new(big.Int)
|
||||
s, t := new(big.Int), new(big.Int)
|
||||
ri, ti := new(big.Int), new(big.Int)
|
||||
a1, b1, a2, b2 = new(big.Int), new(big.Int), new(big.Int), new(big.Int)
|
||||
found, oneMore := false, false
|
||||
for u.Sign() != 0 {
|
||||
// q = v/u
|
||||
q.Div(v, u)
|
||||
|
||||
// r = v - q*u
|
||||
qu.Mul(q, u)
|
||||
r.Sub(v, qu)
|
||||
|
||||
// s = x2 - q*x1
|
||||
qx1.Mul(q, x1)
|
||||
s.Sub(x2, qx1)
|
||||
|
||||
// t = y2 - q*y1
|
||||
qy1.Mul(q, y1)
|
||||
t.Sub(y2, qy1)
|
||||
|
||||
// v = u, u = r, x2 = x1, x1 = s, y2 = y1, y1 = t
|
||||
v.Set(u)
|
||||
u.Set(r)
|
||||
x2.Set(x1)
|
||||
x1.Set(s)
|
||||
y2.Set(y1)
|
||||
y1.Set(t)
|
||||
|
||||
// As soon as the remainder is less than the sqrt of n, the
|
||||
// values of a1 and b1 are known.
|
||||
if !found && r.Cmp(nSqrt) < 0 {
|
||||
// When this condition executes ri and ti represent the
|
||||
// r[i] and t[i] values such that i is the greatest
|
||||
// index for which r >= sqrt(n). Meanwhile, the current
|
||||
// r and t values are r[i+1] and t[i+1], respectively.
|
||||
|
||||
// a1 = r[i+1], b1 = -t[i+1]
|
||||
a1.Set(r)
|
||||
b1.Mul(t, bigMinus1)
|
||||
found = true
|
||||
oneMore = true
|
||||
|
||||
// Skip to the next iteration so ri and ti are not
|
||||
// modified.
|
||||
continue
|
||||
|
||||
} else if oneMore {
|
||||
// When this condition executes ri and ti still
|
||||
// represent the r[i] and t[i] values while the current
|
||||
// r and t are r[i+2] and t[i+2], respectively.
|
||||
|
||||
// sum1 = r[i]^2 + t[i]^2
|
||||
rSquared := new(big.Int).Mul(ri, ri)
|
||||
tSquared := new(big.Int).Mul(ti, ti)
|
||||
sum1 := new(big.Int).Add(rSquared, tSquared)
|
||||
|
||||
// sum2 = r[i+2]^2 + t[i+2]^2
|
||||
r2Squared := new(big.Int).Mul(r, r)
|
||||
t2Squared := new(big.Int).Mul(t, t)
|
||||
sum2 := new(big.Int).Add(r2Squared, t2Squared)
|
||||
|
||||
// if (r[i]^2 + t[i]^2) <= (r[i+2]^2 + t[i+2]^2)
|
||||
if sum1.Cmp(sum2) <= 0 {
|
||||
// a2 = r[i], b2 = -t[i]
|
||||
a2.Set(ri)
|
||||
b2.Mul(ti, bigMinus1)
|
||||
} else {
|
||||
// a2 = r[i+2], b2 = -t[i+2]
|
||||
a2.Set(r)
|
||||
b2.Mul(t, bigMinus1)
|
||||
}
|
||||
|
||||
// All done.
|
||||
break
|
||||
}
|
||||
|
||||
ri.Set(r)
|
||||
ti.Set(t)
|
||||
}
|
||||
|
||||
return a1, b1, a2, b2
|
||||
}
|
67
vendor/github.com/btcsuite/btcd/btcec/precompute.go
generated
vendored
Normal file
67
vendor/github.com/btcsuite/btcd/btcec/precompute.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
|
||||
import (
|
||||
"compress/zlib"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:generate go run -tags gensecp256k1 genprecomps.go
|
||||
|
||||
// loadS256BytePoints decompresses and deserializes the pre-computed byte points
|
||||
// used to accelerate scalar base multiplication for the secp256k1 curve. This
|
||||
// approach is used since it allows the compile to use significantly less ram
|
||||
// and be performed much faster than it is with hard-coding the final in-memory
|
||||
// data structure. At the same time, it is quite fast to generate the in-memory
|
||||
// data structure at init time with this approach versus computing the table.
|
||||
func loadS256BytePoints() error {
|
||||
// There will be no byte points to load when generating them.
|
||||
bp := secp256k1BytePoints
|
||||
if len(bp) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decompress the pre-computed table used to accelerate scalar base
|
||||
// multiplication.
|
||||
decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp))
|
||||
r, err := zlib.NewReader(decoder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serialized, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Deserialize the precomputed byte points and set the curve to them.
|
||||
offset := 0
|
||||
var bytePoints [32][256][3]fieldVal
|
||||
for byteNum := 0; byteNum < 32; byteNum++ {
|
||||
// All points in this window.
|
||||
for i := 0; i < 256; i++ {
|
||||
px := &bytePoints[byteNum][i][0]
|
||||
py := &bytePoints[byteNum][i][1]
|
||||
pz := &bytePoints[byteNum][i][2]
|
||||
for i := 0; i < 10; i++ {
|
||||
px.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
|
||||
offset += 4
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
py.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
|
||||
offset += 4
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
pz.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
|
||||
offset += 4
|
||||
}
|
||||
}
|
||||
}
|
||||
secp256k1.bytePoints = &bytePoints
|
||||
return nil
|
||||
}
|
73
vendor/github.com/btcsuite/btcd/btcec/privkey.go
generated
vendored
Normal file
73
vendor/github.com/btcsuite/btcd/btcec/privkey.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright (c) 2013-2016 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// PrivateKey wraps an ecdsa.PrivateKey as a convenience mainly for signing
|
||||
// things with the the private key without having to directly import the ecdsa
|
||||
// package.
|
||||
type PrivateKey ecdsa.PrivateKey
|
||||
|
||||
// PrivKeyFromBytes returns a private and public key for `curve' based on the
|
||||
// private key passed as an argument as a byte slice.
|
||||
func PrivKeyFromBytes(curve elliptic.Curve, pk []byte) (*PrivateKey,
|
||||
*PublicKey) {
|
||||
x, y := curve.ScalarBaseMult(pk)
|
||||
|
||||
priv := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: x,
|
||||
Y: y,
|
||||
},
|
||||
D: new(big.Int).SetBytes(pk),
|
||||
}
|
||||
|
||||
return (*PrivateKey)(priv), (*PublicKey)(&priv.PublicKey)
|
||||
}
|
||||
|
||||
// NewPrivateKey is a wrapper for ecdsa.GenerateKey that returns a PrivateKey
|
||||
// instead of the normal ecdsa.PrivateKey.
|
||||
func NewPrivateKey(curve elliptic.Curve) (*PrivateKey, error) {
|
||||
key, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return (*PrivateKey)(key), nil
|
||||
}
|
||||
|
||||
// PubKey returns the PublicKey corresponding to this private key.
|
||||
func (p *PrivateKey) PubKey() *PublicKey {
|
||||
return (*PublicKey)(&p.PublicKey)
|
||||
}
|
||||
|
||||
// ToECDSA returns the private key as a *ecdsa.PrivateKey.
|
||||
func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey {
|
||||
return (*ecdsa.PrivateKey)(p)
|
||||
}
|
||||
|
||||
// Sign generates an ECDSA signature for the provided hash (which should be the result
|
||||
// of hashing a larger message) using the private key. Produced signature
|
||||
// is deterministic (same message and same key yield the same signature) and canonical
|
||||
// in accordance with RFC6979 and BIP0062.
|
||||
func (p *PrivateKey) Sign(hash []byte) (*Signature, error) {
|
||||
return signRFC6979(p, hash)
|
||||
}
|
||||
|
||||
// PrivKeyBytesLen defines the length in bytes of a serialized private key.
|
||||
const PrivKeyBytesLen = 32
|
||||
|
||||
// Serialize returns the private key number d as a big-endian binary-encoded
|
||||
// number, padded to a length of 32 bytes.
|
||||
func (p *PrivateKey) Serialize() []byte {
|
||||
b := make([]byte, 0, PrivKeyBytesLen)
|
||||
return paddedAppend(PrivKeyBytesLen, b, p.ToECDSA().D.Bytes())
|
||||
}
|
194
vendor/github.com/btcsuite/btcd/btcec/pubkey.go
generated
vendored
Normal file
194
vendor/github.com/btcsuite/btcd/btcec/pubkey.go
generated
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// These constants define the lengths of serialized public keys.
|
||||
const (
|
||||
PubKeyBytesLenCompressed = 33
|
||||
PubKeyBytesLenUncompressed = 65
|
||||
PubKeyBytesLenHybrid = 65
|
||||
)
|
||||
|
||||
func isOdd(a *big.Int) bool {
|
||||
return a.Bit(0) == 1
|
||||
}
|
||||
|
||||
// decompressPoint decompresses a point on the secp256k1 curve given the X point and
|
||||
// the solution to use.
|
||||
func decompressPoint(curve *KoblitzCurve, bigX *big.Int, ybit bool) (*big.Int, error) {
|
||||
var x fieldVal
|
||||
x.SetByteSlice(bigX.Bytes())
|
||||
|
||||
// Compute x^3 + B mod p.
|
||||
var x3 fieldVal
|
||||
x3.SquareVal(&x).Mul(&x)
|
||||
x3.Add(curve.fieldB).Normalize()
|
||||
|
||||
// Now calculate sqrt mod p of x^3 + B
|
||||
// This code used to do a full sqrt based on tonelli/shanks,
|
||||
// but this was replaced by the algorithms referenced in
|
||||
// https://bitcointalk.org/index.php?topic=162805.msg1712294#msg1712294
|
||||
var y fieldVal
|
||||
y.SqrtVal(&x3).Normalize()
|
||||
if ybit != y.IsOdd() {
|
||||
y.Negate(1).Normalize()
|
||||
}
|
||||
|
||||
// Check that y is a square root of x^3 + B.
|
||||
var y2 fieldVal
|
||||
y2.SquareVal(&y).Normalize()
|
||||
if !y2.Equals(&x3) {
|
||||
return nil, fmt.Errorf("invalid square root")
|
||||
}
|
||||
|
||||
// Verify that y-coord has expected parity.
|
||||
if ybit != y.IsOdd() {
|
||||
return nil, fmt.Errorf("ybit doesn't match oddness")
|
||||
}
|
||||
|
||||
return new(big.Int).SetBytes(y.Bytes()[:]), nil
|
||||
}
|
||||
|
||||
const (
|
||||
pubkeyCompressed byte = 0x2 // y_bit + x coord
|
||||
pubkeyUncompressed byte = 0x4 // x coord + y coord
|
||||
pubkeyHybrid byte = 0x6 // y_bit + x coord + y coord
|
||||
)
|
||||
|
||||
// IsCompressedPubKey returns true the the passed serialized public key has
|
||||
// been encoded in compressed format, and false otherwise.
|
||||
func IsCompressedPubKey(pubKey []byte) bool {
|
||||
// The public key is only compressed if it is the correct length and
|
||||
// the format (first byte) is one of the compressed pubkey values.
|
||||
return len(pubKey) == PubKeyBytesLenCompressed &&
|
||||
(pubKey[0]&^byte(0x1) == pubkeyCompressed)
|
||||
}
|
||||
|
||||
// ParsePubKey parses a public key for a koblitz curve from a bytestring into a
|
||||
// ecdsa.Publickey, verifying that it is valid. It supports compressed,
|
||||
// uncompressed and hybrid signature formats.
|
||||
func ParsePubKey(pubKeyStr []byte, curve *KoblitzCurve) (key *PublicKey, err error) {
|
||||
pubkey := PublicKey{}
|
||||
pubkey.Curve = curve
|
||||
|
||||
if len(pubKeyStr) == 0 {
|
||||
return nil, errors.New("pubkey string is empty")
|
||||
}
|
||||
|
||||
format := pubKeyStr[0]
|
||||
ybit := (format & 0x1) == 0x1
|
||||
format &= ^byte(0x1)
|
||||
|
||||
switch len(pubKeyStr) {
|
||||
case PubKeyBytesLenUncompressed:
|
||||
if format != pubkeyUncompressed && format != pubkeyHybrid {
|
||||
return nil, fmt.Errorf("invalid magic in pubkey str: "+
|
||||
"%d", pubKeyStr[0])
|
||||
}
|
||||
|
||||
pubkey.X = new(big.Int).SetBytes(pubKeyStr[1:33])
|
||||
pubkey.Y = new(big.Int).SetBytes(pubKeyStr[33:])
|
||||
// hybrid keys have extra information, make use of it.
|
||||
if format == pubkeyHybrid && ybit != isOdd(pubkey.Y) {
|
||||
return nil, fmt.Errorf("ybit doesn't match oddness")
|
||||
}
|
||||
|
||||
if pubkey.X.Cmp(pubkey.Curve.Params().P) >= 0 {
|
||||
return nil, fmt.Errorf("pubkey X parameter is >= to P")
|
||||
}
|
||||
if pubkey.Y.Cmp(pubkey.Curve.Params().P) >= 0 {
|
||||
return nil, fmt.Errorf("pubkey Y parameter is >= to P")
|
||||
}
|
||||
if !pubkey.Curve.IsOnCurve(pubkey.X, pubkey.Y) {
|
||||
return nil, fmt.Errorf("pubkey isn't on secp256k1 curve")
|
||||
}
|
||||
|
||||
case PubKeyBytesLenCompressed:
|
||||
// format is 0x2 | solution, <X coordinate>
|
||||
// solution determines which solution of the curve we use.
|
||||
/// y^2 = x^3 + Curve.B
|
||||
if format != pubkeyCompressed {
|
||||
return nil, fmt.Errorf("invalid magic in compressed "+
|
||||
"pubkey string: %d", pubKeyStr[0])
|
||||
}
|
||||
pubkey.X = new(big.Int).SetBytes(pubKeyStr[1:33])
|
||||
pubkey.Y, err = decompressPoint(curve, pubkey.X, ybit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
default: // wrong!
|
||||
return nil, fmt.Errorf("invalid pub key length %d",
|
||||
len(pubKeyStr))
|
||||
}
|
||||
|
||||
return &pubkey, nil
|
||||
}
|
||||
|
||||
// PublicKey is an ecdsa.PublicKey with additional functions to
|
||||
// serialize in uncompressed, compressed, and hybrid formats.
|
||||
type PublicKey ecdsa.PublicKey
|
||||
|
||||
// ToECDSA returns the public key as a *ecdsa.PublicKey.
|
||||
func (p *PublicKey) ToECDSA() *ecdsa.PublicKey {
|
||||
return (*ecdsa.PublicKey)(p)
|
||||
}
|
||||
|
||||
// SerializeUncompressed serializes a public key in a 65-byte uncompressed
|
||||
// format.
|
||||
func (p *PublicKey) SerializeUncompressed() []byte {
|
||||
b := make([]byte, 0, PubKeyBytesLenUncompressed)
|
||||
b = append(b, pubkeyUncompressed)
|
||||
b = paddedAppend(32, b, p.X.Bytes())
|
||||
return paddedAppend(32, b, p.Y.Bytes())
|
||||
}
|
||||
|
||||
// SerializeCompressed serializes a public key in a 33-byte compressed format.
|
||||
func (p *PublicKey) SerializeCompressed() []byte {
|
||||
b := make([]byte, 0, PubKeyBytesLenCompressed)
|
||||
format := pubkeyCompressed
|
||||
if isOdd(p.Y) {
|
||||
format |= 0x1
|
||||
}
|
||||
b = append(b, format)
|
||||
return paddedAppend(32, b, p.X.Bytes())
|
||||
}
|
||||
|
||||
// SerializeHybrid serializes a public key in a 65-byte hybrid format.
|
||||
func (p *PublicKey) SerializeHybrid() []byte {
|
||||
b := make([]byte, 0, PubKeyBytesLenHybrid)
|
||||
format := pubkeyHybrid
|
||||
if isOdd(p.Y) {
|
||||
format |= 0x1
|
||||
}
|
||||
b = append(b, format)
|
||||
b = paddedAppend(32, b, p.X.Bytes())
|
||||
return paddedAppend(32, b, p.Y.Bytes())
|
||||
}
|
||||
|
||||
// IsEqual compares this PublicKey instance to the one passed, returning true if
|
||||
// both PublicKeys are equivalent. A PublicKey is equivalent to another, if they
|
||||
// both have the same X and Y coordinate.
|
||||
func (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool {
|
||||
return p.X.Cmp(otherPubKey.X) == 0 &&
|
||||
p.Y.Cmp(otherPubKey.Y) == 0
|
||||
}
|
||||
|
||||
// paddedAppend appends the src byte slice to dst, returning the new slice.
|
||||
// If the length of the source is smaller than the passed size, leading zero
|
||||
// bytes are appended to the dst slice before appending src.
|
||||
func paddedAppend(size uint, dst, src []byte) []byte {
|
||||
for i := 0; i < int(size)-len(src); i++ {
|
||||
dst = append(dst, 0)
|
||||
}
|
||||
return append(dst, src...)
|
||||
}
|
10
vendor/github.com/btcsuite/btcd/btcec/secp256k1.go
generated
vendored
Normal file
10
vendor/github.com/btcsuite/btcd/btcec/secp256k1.go
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
540
vendor/github.com/btcsuite/btcd/btcec/signature.go
generated
vendored
Normal file
540
vendor/github.com/btcsuite/btcd/btcec/signature.go
generated
vendored
Normal file
@ -0,0 +1,540 @@
|
||||
// Copyright (c) 2013-2017 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// Errors returned by canonicalPadding.
|
||||
var (
|
||||
errNegativeValue = errors.New("value may be interpreted as negative")
|
||||
errExcessivelyPaddedValue = errors.New("value is excessively padded")
|
||||
)
|
||||
|
||||
// Signature is a type representing an ecdsa signature.
|
||||
type Signature struct {
|
||||
R *big.Int
|
||||
S *big.Int
|
||||
}
|
||||
|
||||
var (
|
||||
// Used in RFC6979 implementation when testing the nonce for correctness
|
||||
one = big.NewInt(1)
|
||||
|
||||
// oneInitializer is used to fill a byte slice with byte 0x01. It is provided
|
||||
// here to avoid the need to create it multiple times.
|
||||
oneInitializer = []byte{0x01}
|
||||
)
|
||||
|
||||
// Serialize returns the ECDSA signature in the more strict DER format. Note
|
||||
// that the serialized bytes returned do not include the appended hash type
|
||||
// used in Bitcoin signature scripts.
|
||||
//
|
||||
// encoding/asn1 is broken so we hand roll this output:
|
||||
//
|
||||
// 0x30 <length> 0x02 <length r> r 0x02 <length s> s
|
||||
func (sig *Signature) Serialize() []byte {
|
||||
// low 'S' malleability breaker
|
||||
sigS := sig.S
|
||||
if sigS.Cmp(S256().halfOrder) == 1 {
|
||||
sigS = new(big.Int).Sub(S256().N, sigS)
|
||||
}
|
||||
// Ensure the encoded bytes for the r and s values are canonical and
|
||||
// thus suitable for DER encoding.
|
||||
rb := canonicalizeInt(sig.R)
|
||||
sb := canonicalizeInt(sigS)
|
||||
|
||||
// total length of returned signature is 1 byte for each magic and
|
||||
// length (6 total), plus lengths of r and s
|
||||
length := 6 + len(rb) + len(sb)
|
||||
b := make([]byte, length)
|
||||
|
||||
b[0] = 0x30
|
||||
b[1] = byte(length - 2)
|
||||
b[2] = 0x02
|
||||
b[3] = byte(len(rb))
|
||||
offset := copy(b[4:], rb) + 4
|
||||
b[offset] = 0x02
|
||||
b[offset+1] = byte(len(sb))
|
||||
copy(b[offset+2:], sb)
|
||||
return b
|
||||
}
|
||||
|
||||
// Verify calls ecdsa.Verify to verify the signature of hash using the public
|
||||
// key. It returns true if the signature is valid, false otherwise.
|
||||
func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool {
|
||||
return ecdsa.Verify(pubKey.ToECDSA(), hash, sig.R, sig.S)
|
||||
}
|
||||
|
||||
// IsEqual compares this Signature instance to the one passed, returning true
|
||||
// if both Signatures are equivalent. A signature is equivalent to another, if
|
||||
// they both have the same scalar value for R and S.
|
||||
func (sig *Signature) IsEqual(otherSig *Signature) bool {
|
||||
return sig.R.Cmp(otherSig.R) == 0 &&
|
||||
sig.S.Cmp(otherSig.S) == 0
|
||||
}
|
||||
|
||||
// MinSigLen is the minimum length of a DER encoded signature and is when both R
|
||||
// and S are 1 byte each.
|
||||
// 0x30 + <1-byte> + 0x02 + 0x01 + <byte> + 0x2 + 0x01 + <byte>
|
||||
const MinSigLen = 8
|
||||
|
||||
func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) {
|
||||
// Originally this code used encoding/asn1 in order to parse the
|
||||
// signature, but a number of problems were found with this approach.
|
||||
// Despite the fact that signatures are stored as DER, the difference
|
||||
// between go's idea of a bignum (and that they have sign) doesn't agree
|
||||
// with the openssl one (where they do not). The above is true as of
|
||||
// Go 1.1. In the end it was simpler to rewrite the code to explicitly
|
||||
// understand the format which is this:
|
||||
// 0x30 <length of whole message> <0x02> <length of R> <R> 0x2
|
||||
// <length of S> <S>.
|
||||
|
||||
signature := &Signature{}
|
||||
|
||||
if len(sigStr) < MinSigLen {
|
||||
return nil, errors.New("malformed signature: too short")
|
||||
}
|
||||
// 0x30
|
||||
index := 0
|
||||
if sigStr[index] != 0x30 {
|
||||
return nil, errors.New("malformed signature: no header magic")
|
||||
}
|
||||
index++
|
||||
// length of remaining message
|
||||
siglen := sigStr[index]
|
||||
index++
|
||||
|
||||
// siglen should be less than the entire message and greater than
|
||||
// the minimal message size.
|
||||
if int(siglen+2) > len(sigStr) || int(siglen+2) < MinSigLen {
|
||||
return nil, errors.New("malformed signature: bad length")
|
||||
}
|
||||
// trim the slice we're working on so we only look at what matters.
|
||||
sigStr = sigStr[:siglen+2]
|
||||
|
||||
// 0x02
|
||||
if sigStr[index] != 0x02 {
|
||||
return nil,
|
||||
errors.New("malformed signature: no 1st int marker")
|
||||
}
|
||||
index++
|
||||
|
||||
// Length of signature R.
|
||||
rLen := int(sigStr[index])
|
||||
// must be positive, must be able to fit in another 0x2, <len> <s>
|
||||
// hence the -3. We assume that the length must be at least one byte.
|
||||
index++
|
||||
if rLen <= 0 || rLen > len(sigStr)-index-3 {
|
||||
return nil, errors.New("malformed signature: bogus R length")
|
||||
}
|
||||
|
||||
// Then R itself.
|
||||
rBytes := sigStr[index : index+rLen]
|
||||
if der {
|
||||
switch err := canonicalPadding(rBytes); err {
|
||||
case errNegativeValue:
|
||||
return nil, errors.New("signature R is negative")
|
||||
case errExcessivelyPaddedValue:
|
||||
return nil, errors.New("signature R is excessively padded")
|
||||
}
|
||||
}
|
||||
signature.R = new(big.Int).SetBytes(rBytes)
|
||||
index += rLen
|
||||
// 0x02. length already checked in previous if.
|
||||
if sigStr[index] != 0x02 {
|
||||
return nil, errors.New("malformed signature: no 2nd int marker")
|
||||
}
|
||||
index++
|
||||
|
||||
// Length of signature S.
|
||||
sLen := int(sigStr[index])
|
||||
index++
|
||||
// S should be the rest of the string.
|
||||
if sLen <= 0 || sLen > len(sigStr)-index {
|
||||
return nil, errors.New("malformed signature: bogus S length")
|
||||
}
|
||||
|
||||
// Then S itself.
|
||||
sBytes := sigStr[index : index+sLen]
|
||||
if der {
|
||||
switch err := canonicalPadding(sBytes); err {
|
||||
case errNegativeValue:
|
||||
return nil, errors.New("signature S is negative")
|
||||
case errExcessivelyPaddedValue:
|
||||
return nil, errors.New("signature S is excessively padded")
|
||||
}
|
||||
}
|
||||
signature.S = new(big.Int).SetBytes(sBytes)
|
||||
index += sLen
|
||||
|
||||
// sanity check length parsing
|
||||
if index != len(sigStr) {
|
||||
return nil, fmt.Errorf("malformed signature: bad final length %v != %v",
|
||||
index, len(sigStr))
|
||||
}
|
||||
|
||||
// Verify also checks this, but we can be more sure that we parsed
|
||||
// correctly if we verify here too.
|
||||
// FWIW the ecdsa spec states that R and S must be | 1, N - 1 |
|
||||
// but crypto/ecdsa only checks for Sign != 0. Mirror that.
|
||||
if signature.R.Sign() != 1 {
|
||||
return nil, errors.New("signature R isn't 1 or more")
|
||||
}
|
||||
if signature.S.Sign() != 1 {
|
||||
return nil, errors.New("signature S isn't 1 or more")
|
||||
}
|
||||
if signature.R.Cmp(curve.Params().N) >= 0 {
|
||||
return nil, errors.New("signature R is >= curve.N")
|
||||
}
|
||||
if signature.S.Cmp(curve.Params().N) >= 0 {
|
||||
return nil, errors.New("signature S is >= curve.N")
|
||||
}
|
||||
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// ParseSignature parses a signature in BER format for the curve type `curve'
|
||||
// into a Signature type, perfoming some basic sanity checks. If parsing
|
||||
// according to the more strict DER format is needed, use ParseDERSignature.
|
||||
func ParseSignature(sigStr []byte, curve elliptic.Curve) (*Signature, error) {
|
||||
return parseSig(sigStr, curve, false)
|
||||
}
|
||||
|
||||
// ParseDERSignature parses a signature in DER format for the curve type
|
||||
// `curve` into a Signature type. If parsing according to the less strict
|
||||
// BER format is needed, use ParseSignature.
|
||||
func ParseDERSignature(sigStr []byte, curve elliptic.Curve) (*Signature, error) {
|
||||
return parseSig(sigStr, curve, true)
|
||||
}
|
||||
|
||||
// canonicalizeInt returns the bytes for the passed big integer adjusted as
|
||||
// necessary to ensure that a big-endian encoded integer can't possibly be
|
||||
// misinterpreted as a negative number. This can happen when the most
|
||||
// significant bit is set, so it is padded by a leading zero byte in this case.
|
||||
// Also, the returned bytes will have at least a single byte when the passed
|
||||
// value is 0. This is required for DER encoding.
|
||||
func canonicalizeInt(val *big.Int) []byte {
|
||||
b := val.Bytes()
|
||||
if len(b) == 0 {
|
||||
b = []byte{0x00}
|
||||
}
|
||||
if b[0]&0x80 != 0 {
|
||||
paddedBytes := make([]byte, len(b)+1)
|
||||
copy(paddedBytes[1:], b)
|
||||
b = paddedBytes
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// canonicalPadding checks whether a big-endian encoded integer could
|
||||
// possibly be misinterpreted as a negative number (even though OpenSSL
|
||||
// treats all numbers as unsigned), or if there is any unnecessary
|
||||
// leading zero padding.
|
||||
func canonicalPadding(b []byte) error {
|
||||
switch {
|
||||
case b[0]&0x80 == 0x80:
|
||||
return errNegativeValue
|
||||
case len(b) > 1 && b[0] == 0x00 && b[1]&0x80 != 0x80:
|
||||
return errExcessivelyPaddedValue
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// hashToInt converts a hash value to an integer. There is some disagreement
|
||||
// about how this is done. [NSA] suggests that this is done in the obvious
|
||||
// manner, but [SECG] truncates the hash to the bit-length of the curve order
|
||||
// first. We follow [SECG] because that's what OpenSSL does. Additionally,
|
||||
// OpenSSL right shifts excess bits from the number if the hash is too large
|
||||
// and we mirror that too.
|
||||
// This is borrowed from crypto/ecdsa.
|
||||
func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
|
||||
orderBits := c.Params().N.BitLen()
|
||||
orderBytes := (orderBits + 7) / 8
|
||||
if len(hash) > orderBytes {
|
||||
hash = hash[:orderBytes]
|
||||
}
|
||||
|
||||
ret := new(big.Int).SetBytes(hash)
|
||||
excess := len(hash)*8 - orderBits
|
||||
if excess > 0 {
|
||||
ret.Rsh(ret, uint(excess))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// recoverKeyFromSignature recovers a public key from the signature "sig" on the
|
||||
// given message hash "msg". Based on the algorithm found in section 4.1.6 of
|
||||
// SEC 1 Ver 2.0, page 47-48 (53 and 54 in the pdf). This performs the details
|
||||
// in the inner loop in Step 1. The counter provided is actually the j parameter
|
||||
// of the loop * 2 - on the first iteration of j we do the R case, else the -R
|
||||
// case in step 1.6. This counter is used in the bitcoin compressed signature
|
||||
// format and thus we match bitcoind's behaviour here.
|
||||
func recoverKeyFromSignature(curve *KoblitzCurve, sig *Signature, msg []byte,
|
||||
iter int, doChecks bool) (*PublicKey, error) {
|
||||
// 1.1 x = (n * i) + r
|
||||
Rx := new(big.Int).Mul(curve.Params().N,
|
||||
new(big.Int).SetInt64(int64(iter/2)))
|
||||
Rx.Add(Rx, sig.R)
|
||||
if Rx.Cmp(curve.Params().P) != -1 {
|
||||
return nil, errors.New("calculated Rx is larger than curve P")
|
||||
}
|
||||
|
||||
// convert 02<Rx> to point R. (step 1.2 and 1.3). If we are on an odd
|
||||
// iteration then 1.6 will be done with -R, so we calculate the other
|
||||
// term when uncompressing the point.
|
||||
Ry, err := decompressPoint(curve, Rx, iter%2 == 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 1.4 Check n*R is point at infinity
|
||||
if doChecks {
|
||||
nRx, nRy := curve.ScalarMult(Rx, Ry, curve.Params().N.Bytes())
|
||||
if nRx.Sign() != 0 || nRy.Sign() != 0 {
|
||||
return nil, errors.New("n*R does not equal the point at infinity")
|
||||
}
|
||||
}
|
||||
|
||||
// 1.5 calculate e from message using the same algorithm as ecdsa
|
||||
// signature calculation.
|
||||
e := hashToInt(msg, curve)
|
||||
|
||||
// Step 1.6.1:
|
||||
// We calculate the two terms sR and eG separately multiplied by the
|
||||
// inverse of r (from the signature). We then add them to calculate
|
||||
// Q = r^-1(sR-eG)
|
||||
invr := new(big.Int).ModInverse(sig.R, curve.Params().N)
|
||||
|
||||
// first term.
|
||||
invrS := new(big.Int).Mul(invr, sig.S)
|
||||
invrS.Mod(invrS, curve.Params().N)
|
||||
sRx, sRy := curve.ScalarMult(Rx, Ry, invrS.Bytes())
|
||||
|
||||
// second term.
|
||||
e.Neg(e)
|
||||
e.Mod(e, curve.Params().N)
|
||||
e.Mul(e, invr)
|
||||
e.Mod(e, curve.Params().N)
|
||||
minuseGx, minuseGy := curve.ScalarBaseMult(e.Bytes())
|
||||
|
||||
// TODO: this would be faster if we did a mult and add in one
|
||||
// step to prevent the jacobian conversion back and forth.
|
||||
Qx, Qy := curve.Add(sRx, sRy, minuseGx, minuseGy)
|
||||
|
||||
return &PublicKey{
|
||||
Curve: curve,
|
||||
X: Qx,
|
||||
Y: Qy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SignCompact produces a compact signature of the data in hash with the given
|
||||
// private key on the given koblitz curve. The isCompressed parameter should
|
||||
// be used to detail if the given signature should reference a compressed
|
||||
// public key or not. If successful the bytes of the compact signature will be
|
||||
// returned in the format:
|
||||
// <(byte of 27+public key solution)+4 if compressed >< padded bytes for signature R><padded bytes for signature S>
|
||||
// where the R and S parameters are padde up to the bitlengh of the curve.
|
||||
func SignCompact(curve *KoblitzCurve, key *PrivateKey,
|
||||
hash []byte, isCompressedKey bool) ([]byte, error) {
|
||||
sig, err := key.Sign(hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// bitcoind checks the bit length of R and S here. The ecdsa signature
|
||||
// algorithm returns R and S mod N therefore they will be the bitsize of
|
||||
// the curve, and thus correctly sized.
|
||||
for i := 0; i < (curve.H+1)*2; i++ {
|
||||
pk, err := recoverKeyFromSignature(curve, sig, hash, i, true)
|
||||
if err == nil && pk.X.Cmp(key.X) == 0 && pk.Y.Cmp(key.Y) == 0 {
|
||||
result := make([]byte, 1, 2*curve.byteSize+1)
|
||||
result[0] = 27 + byte(i)
|
||||
if isCompressedKey {
|
||||
result[0] += 4
|
||||
}
|
||||
// Not sure this needs rounding but safer to do so.
|
||||
curvelen := (curve.BitSize + 7) / 8
|
||||
|
||||
// Pad R and S to curvelen if needed.
|
||||
bytelen := (sig.R.BitLen() + 7) / 8
|
||||
if bytelen < curvelen {
|
||||
result = append(result,
|
||||
make([]byte, curvelen-bytelen)...)
|
||||
}
|
||||
result = append(result, sig.R.Bytes()...)
|
||||
|
||||
bytelen = (sig.S.BitLen() + 7) / 8
|
||||
if bytelen < curvelen {
|
||||
result = append(result,
|
||||
make([]byte, curvelen-bytelen)...)
|
||||
}
|
||||
result = append(result, sig.S.Bytes()...)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("no valid solution for pubkey found")
|
||||
}
|
||||
|
||||
// RecoverCompact verifies the compact signature "signature" of "hash" for the
|
||||
// Koblitz curve in "curve". If the signature matches then the recovered public
|
||||
// key will be returned as well as a boolen if the original key was compressed
|
||||
// or not, else an error will be returned.
|
||||
func RecoverCompact(curve *KoblitzCurve, signature,
|
||||
hash []byte) (*PublicKey, bool, error) {
|
||||
bitlen := (curve.BitSize + 7) / 8
|
||||
if len(signature) != 1+bitlen*2 {
|
||||
return nil, false, errors.New("invalid compact signature size")
|
||||
}
|
||||
|
||||
iteration := int((signature[0] - 27) & ^byte(4))
|
||||
|
||||
// format is <header byte><bitlen R><bitlen S>
|
||||
sig := &Signature{
|
||||
R: new(big.Int).SetBytes(signature[1 : bitlen+1]),
|
||||
S: new(big.Int).SetBytes(signature[bitlen+1:]),
|
||||
}
|
||||
// The iteration used here was encoded
|
||||
key, err := recoverKeyFromSignature(curve, sig, hash, iteration, false)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return key, ((signature[0] - 27) & 4) == 4, nil
|
||||
}
|
||||
|
||||
// signRFC6979 generates a deterministic ECDSA signature according to RFC 6979 and BIP 62.
|
||||
func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) {
|
||||
|
||||
privkey := privateKey.ToECDSA()
|
||||
N := S256().N
|
||||
halfOrder := S256().halfOrder
|
||||
k := nonceRFC6979(privkey.D, hash)
|
||||
inv := new(big.Int).ModInverse(k, N)
|
||||
r, _ := privkey.Curve.ScalarBaseMult(k.Bytes())
|
||||
r.Mod(r, N)
|
||||
|
||||
if r.Sign() == 0 {
|
||||
return nil, errors.New("calculated R is zero")
|
||||
}
|
||||
|
||||
e := hashToInt(hash, privkey.Curve)
|
||||
s := new(big.Int).Mul(privkey.D, r)
|
||||
s.Add(s, e)
|
||||
s.Mul(s, inv)
|
||||
s.Mod(s, N)
|
||||
|
||||
if s.Cmp(halfOrder) == 1 {
|
||||
s.Sub(N, s)
|
||||
}
|
||||
if s.Sign() == 0 {
|
||||
return nil, errors.New("calculated S is zero")
|
||||
}
|
||||
return &Signature{R: r, S: s}, nil
|
||||
}
|
||||
|
||||
// nonceRFC6979 generates an ECDSA nonce (`k`) deterministically according to RFC 6979.
|
||||
// It takes a 32-byte hash as an input and returns 32-byte nonce to be used in ECDSA algorithm.
|
||||
func nonceRFC6979(privkey *big.Int, hash []byte) *big.Int {
|
||||
|
||||
curve := S256()
|
||||
q := curve.Params().N
|
||||
x := privkey
|
||||
alg := sha256.New
|
||||
|
||||
qlen := q.BitLen()
|
||||
holen := alg().Size()
|
||||
rolen := (qlen + 7) >> 3
|
||||
bx := append(int2octets(x, rolen), bits2octets(hash, curve, rolen)...)
|
||||
|
||||
// Step B
|
||||
v := bytes.Repeat(oneInitializer, holen)
|
||||
|
||||
// Step C (Go zeroes the all allocated memory)
|
||||
k := make([]byte, holen)
|
||||
|
||||
// Step D
|
||||
k = mac(alg, k, append(append(v, 0x00), bx...))
|
||||
|
||||
// Step E
|
||||
v = mac(alg, k, v)
|
||||
|
||||
// Step F
|
||||
k = mac(alg, k, append(append(v, 0x01), bx...))
|
||||
|
||||
// Step G
|
||||
v = mac(alg, k, v)
|
||||
|
||||
// Step H
|
||||
for {
|
||||
// Step H1
|
||||
var t []byte
|
||||
|
||||
// Step H2
|
||||
for len(t)*8 < qlen {
|
||||
v = mac(alg, k, v)
|
||||
t = append(t, v...)
|
||||
}
|
||||
|
||||
// Step H3
|
||||
secret := hashToInt(t, curve)
|
||||
if secret.Cmp(one) >= 0 && secret.Cmp(q) < 0 {
|
||||
return secret
|
||||
}
|
||||
k = mac(alg, k, append(v, 0x00))
|
||||
v = mac(alg, k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// mac returns an HMAC of the given key and message.
|
||||
func mac(alg func() hash.Hash, k, m []byte) []byte {
|
||||
h := hmac.New(alg, k)
|
||||
h.Write(m)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/rfc6979#section-2.3.3
|
||||
func int2octets(v *big.Int, rolen int) []byte {
|
||||
out := v.Bytes()
|
||||
|
||||
// left pad with zeros if it's too short
|
||||
if len(out) < rolen {
|
||||
out2 := make([]byte, rolen)
|
||||
copy(out2[rolen-len(out):], out)
|
||||
return out2
|
||||
}
|
||||
|
||||
// drop most significant bytes if it's too long
|
||||
if len(out) > rolen {
|
||||
out2 := make([]byte, rolen)
|
||||
copy(out2, out[len(out)-rolen:])
|
||||
return out2
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/rfc6979#section-2.3.4
|
||||
func bits2octets(in []byte, curve elliptic.Curve, rolen int) []byte {
|
||||
z1 := hashToInt(in, curve)
|
||||
z2 := new(big.Int).Sub(z1, curve.Params().N)
|
||||
if z2.Sign() < 0 {
|
||||
return int2octets(z1, rolen)
|
||||
}
|
||||
return int2octets(z2, rolen)
|
||||
}
|
28
vendor/github.com/crackcomm/go-gitignore/.gitignore
generated
vendored
Normal file
28
vendor/github.com/crackcomm/go-gitignore/.gitignore
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
# Package test fixtures
|
||||
test_fixtures
|
||||
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
18
vendor/github.com/crackcomm/go-gitignore/.travis.yml
generated
vendored
Normal file
18
vendor/github.com/crackcomm/go-gitignore/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
- tip
|
||||
|
||||
env:
|
||||
- "PATH=$HOME/gopath/bin:$PATH"
|
||||
|
||||
before_install:
|
||||
- go get github.com/stretchr/testify/assert
|
||||
- go get github.com/axw/gocov/gocov
|
||||
- go get github.com/mattn/goveralls
|
||||
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
||||
|
||||
script:
|
||||
- go test -v -covermode=count -coverprofile=coverage.out
|
||||
- goveralls -coverprofile=coverage.out -service travis-ci -repotoken $COVERALLS_TOKEN
|
22
vendor/github.com/crackcomm/go-gitignore/LICENSE
generated
vendored
Normal file
22
vendor/github.com/crackcomm/go-gitignore/LICENSE
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Shaba Abhiram
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
17
vendor/github.com/crackcomm/go-gitignore/README.md
generated
vendored
Normal file
17
vendor/github.com/crackcomm/go-gitignore/README.md
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# go-git-ignore
|
||||
|
||||
[](https://travis-ci.org/sabhiram/go-git-ignore) [](https://coveralls.io/r/sabhiram/go-git-ignore?branch=master)
|
||||
|
||||
A gitignore parser for `Go`
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
go get github.com/sabhiram/go-git-ignore
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
TODO
|
||||
```
|
219
vendor/github.com/crackcomm/go-gitignore/ignore.go
generated
vendored
Normal file
219
vendor/github.com/crackcomm/go-gitignore/ignore.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
ignore is a library which returns a new ignorer object which can
|
||||
test against various paths. This is particularly useful when trying
|
||||
to filter files based on a .gitignore document
|
||||
|
||||
The rules for parsing the input file are the same as the ones listed
|
||||
in the Git docs here: http://git-scm.com/docs/gitignore
|
||||
|
||||
The summarized version of the same has been copied here:
|
||||
|
||||
1. A blank line matches no files, so it can serve as a separator
|
||||
for readability.
|
||||
2. A line starting with # serves as a comment. Put a backslash ("\")
|
||||
in front of the first hash for patterns that begin with a hash.
|
||||
3. Trailing spaces are ignored unless they are quoted with backslash ("\").
|
||||
4. An optional prefix "!" which negates the pattern; any matching file
|
||||
excluded by a previous pattern will become included again. It is not
|
||||
possible to re-include a file if a parent directory of that file is
|
||||
excluded. Git doesn’t list excluded directories for performance reasons,
|
||||
so any patterns on contained files have no effect, no matter where they
|
||||
are defined. Put a backslash ("\") in front of the first "!" for
|
||||
patterns that begin with a literal "!", for example, "\!important!.txt".
|
||||
5. If the pattern ends with a slash, it is removed for the purpose of the
|
||||
following description, but it would only find a match with a directory.
|
||||
In other words, foo/ will match a directory foo and paths underneath it,
|
||||
but will not match a regular file or a symbolic link foo (this is
|
||||
consistent with the way how pathspec works in general in Git).
|
||||
6. If the pattern does not contain a slash /, Git treats it as a shell glob
|
||||
pattern and checks for a match against the pathname relative to the
|
||||
location of the .gitignore file (relative to the toplevel of the work
|
||||
tree if not from a .gitignore file).
|
||||
7. Otherwise, Git treats the pattern as a shell glob suitable for
|
||||
consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the
|
||||
pattern will not match a / in the pathname. For example,
|
||||
"Documentation/*.html" matches "Documentation/git.html" but not
|
||||
"Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".
|
||||
8. A leading slash matches the beginning of the pathname. For example,
|
||||
"/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
|
||||
9. Two consecutive asterisks ("**") in patterns matched against full
|
||||
pathname may have special meaning:
|
||||
i. A leading "**" followed by a slash means match in all directories.
|
||||
For example, "** /foo" matches file or directory "foo" anywhere,
|
||||
the same as pattern "foo". "** /foo/bar" matches file or directory
|
||||
"bar" anywhere that is directly under directory "foo".
|
||||
ii. A trailing "/**" matches everything inside. For example, "abc/**"
|
||||
matches all files inside directory "abc", relative to the location
|
||||
of the .gitignore file, with infinite depth.
|
||||
iii. A slash followed by two consecutive asterisks then a slash matches
|
||||
zero or more directories. For example, "a/** /b" matches "a/b",
|
||||
"a/x/b", "a/x/y/b" and so on.
|
||||
iv. Other consecutive asterisks are considered invalid. */
|
||||
package ignore
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// An IgnoreParser is an interface which exposes two methods:
|
||||
// MatchesPath() - Returns true if the path is targeted by the patterns compiled in the GitIgnore structure
|
||||
type IgnoreParser interface {
|
||||
MatchesPath(f string) bool
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// This function pretty much attempts to mimic the parsing rules
|
||||
// listed above at the start of this file
|
||||
func getPatternFromLine(line string) (*regexp.Regexp, bool) {
|
||||
// Trim OS-specific carriage returns.
|
||||
line = strings.TrimRight(line, "\r")
|
||||
|
||||
// Strip comments [Rule 2]
|
||||
if strings.HasPrefix(line, `#`) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Trim string [Rule 3]
|
||||
// TODO: Handle [Rule 3], when the " " is escaped with a \
|
||||
line = strings.Trim(line, " ")
|
||||
|
||||
// Exit for no-ops and return nil which will prevent us from
|
||||
// appending a pattern against this line
|
||||
if line == "" {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// TODO: Handle [Rule 4] which negates the match for patterns leading with "!"
|
||||
negatePattern := false
|
||||
if line[0] == '!' {
|
||||
negatePattern = true
|
||||
line = line[1:]
|
||||
}
|
||||
|
||||
// Handle [Rule 2, 4], when # or ! is escaped with a \
|
||||
// Handle [Rule 4] once we tag negatePattern, strip the leading ! char
|
||||
if regexp.MustCompile(`^(\#|\!)`).MatchString(line) {
|
||||
line = line[1:]
|
||||
}
|
||||
|
||||
// If we encounter a foo/*.blah in a folder, prepend the / char
|
||||
if regexp.MustCompile(`([^\/+])/.*\*\.`).MatchString(line) && line[0] != '/' {
|
||||
line = "/" + line
|
||||
}
|
||||
|
||||
// Handle escaping the "." char
|
||||
line = regexp.MustCompile(`\.`).ReplaceAllString(line, `\.`)
|
||||
|
||||
magicStar := "#$~"
|
||||
|
||||
// Handle "/**/" usage
|
||||
if strings.HasPrefix(line, "/**/") {
|
||||
line = line[1:]
|
||||
}
|
||||
line = regexp.MustCompile(`/\*\*/`).ReplaceAllString(line, `(/|/.+/)`)
|
||||
line = regexp.MustCompile(`\*\*/`).ReplaceAllString(line, `(|.`+magicStar+`/)`)
|
||||
line = regexp.MustCompile(`/\*\*`).ReplaceAllString(line, `(|/.`+magicStar+`)`)
|
||||
|
||||
// Handle escaping the "*" char
|
||||
line = regexp.MustCompile(`\\\*`).ReplaceAllString(line, `\`+magicStar)
|
||||
line = regexp.MustCompile(`\*`).ReplaceAllString(line, `([^/]*)`)
|
||||
|
||||
// Handle escaping the "?" char
|
||||
line = strings.Replace(line, "?", `\?`, -1)
|
||||
|
||||
line = strings.Replace(line, magicStar, "*", -1)
|
||||
|
||||
// Temporary regex
|
||||
var expr = ""
|
||||
if strings.HasSuffix(line, "/") {
|
||||
expr = line + "(|.*)$"
|
||||
} else {
|
||||
expr = line + "(|/.*)$"
|
||||
}
|
||||
if strings.HasPrefix(expr, "/") {
|
||||
expr = "^(|/)" + expr[1:]
|
||||
} else {
|
||||
expr = "^(|.*/)" + expr
|
||||
}
|
||||
pattern, _ := regexp.Compile(expr)
|
||||
|
||||
return pattern, negatePattern
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// GitIgnore is a struct which contains a slice of regexp.Regexp
|
||||
// patterns
|
||||
type GitIgnore struct {
|
||||
patterns []*regexp.Regexp // List of regexp patterns which this ignore file applies
|
||||
negate []bool // List of booleans which determine if the pattern is negated
|
||||
}
|
||||
|
||||
// Accepts a variadic set of strings, and returns a GitIgnore object which
|
||||
// converts and appends the lines in the input to regexp.Regexp patterns
|
||||
// held within the GitIgnore objects "patterns" field
|
||||
func CompileIgnoreLines(lines ...string) (*GitIgnore, error) {
|
||||
g := new(GitIgnore)
|
||||
for _, line := range lines {
|
||||
pattern, negatePattern := getPatternFromLine(line)
|
||||
if pattern != nil {
|
||||
g.patterns = append(g.patterns, pattern)
|
||||
g.negate = append(g.negate, negatePattern)
|
||||
}
|
||||
}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// Accepts a ignore file as the input, parses the lines out of the file
|
||||
// and invokes the CompileIgnoreLines method
|
||||
func CompileIgnoreFile(fpath string) (*GitIgnore, error) {
|
||||
buffer, error := ioutil.ReadFile(fpath)
|
||||
if error == nil {
|
||||
s := strings.Split(string(buffer), "\n")
|
||||
return CompileIgnoreLines(s...)
|
||||
}
|
||||
return nil, error
|
||||
}
|
||||
|
||||
// Accepts a ignore file as the input, parses the lines out of the file
|
||||
// and invokes the CompileIgnoreLines method with additional lines
|
||||
func CompileIgnoreFileAndLines(fpath string, lines ...string) (*GitIgnore, error) {
|
||||
buffer, error := ioutil.ReadFile(fpath)
|
||||
if error == nil {
|
||||
s := strings.Split(string(buffer), "\n")
|
||||
return CompileIgnoreLines(append(s, lines...)...)
|
||||
}
|
||||
return nil, error
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// MatchesPath is an interface function for the IgnoreParser interface.
|
||||
// It returns true if the given GitIgnore structure would target a given
|
||||
// path string "f"
|
||||
func (g GitIgnore) MatchesPath(f string) bool {
|
||||
// Replace OS-specific path separator.
|
||||
f = strings.Replace(f, string(os.PathSeparator), "/", -1)
|
||||
|
||||
matchesPath := false
|
||||
for idx, pattern := range g.patterns {
|
||||
if pattern.MatchString(f) {
|
||||
// If this is a regular target (not negated with a gitignore exclude "!" etc)
|
||||
if !g.negate[idx] {
|
||||
matchesPath = true
|
||||
// Negated pattern, and matchesPath is already set
|
||||
} else if matchesPath {
|
||||
matchesPath = false
|
||||
}
|
||||
}
|
||||
}
|
||||
return matchesPath
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
15
vendor/github.com/gogo/protobuf/AUTHORS
generated
vendored
Normal file
15
vendor/github.com/gogo/protobuf/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# This is the official list of GoGo authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS file, which
|
||||
# lists people. For example, employees are listed in CONTRIBUTORS,
|
||||
# but not in AUTHORS, because the employer holds the copyright.
|
||||
|
||||
# Names should be added to this file as one of
|
||||
# Organization's name
|
||||
# Individual's name <submission email address>
|
||||
# Individual's name <submission email address> <email2> <emailN>
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Sendgrid, Inc
|
||||
Vastech SA (PTY) LTD
|
||||
Walter Schulze <awalterschulze@gmail.com>
|
23
vendor/github.com/gogo/protobuf/CONTRIBUTORS
generated
vendored
Normal file
23
vendor/github.com/gogo/protobuf/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
Anton Povarov <anton.povarov@gmail.com>
|
||||
Brian Goff <cpuguy83@gmail.com>
|
||||
Clayton Coleman <ccoleman@redhat.com>
|
||||
Denis Smirnov <denis.smirnov.91@gmail.com>
|
||||
DongYun Kang <ceram1000@gmail.com>
|
||||
Dwayne Schultz <dschultz@pivotal.io>
|
||||
Georg Apitz <gapitz@pivotal.io>
|
||||
Gustav Paul <gustav.paul@gmail.com>
|
||||
Johan Brandhorst <johan.brandhorst@gmail.com>
|
||||
John Shahid <jvshahid@gmail.com>
|
||||
John Tuley <john@tuley.org>
|
||||
Laurent <laurent@adyoulike.com>
|
||||
Patrick Lee <patrick@dropbox.com>
|
||||
Peter Edge <peter.edge@gmail.com>
|
||||
Roger Johansson <rogeralsing@gmail.com>
|
||||
Sam Nguyen <sam.nguyen@sendgrid.com>
|
||||
Sergio Arbeo <serabe@gmail.com>
|
||||
Stephen J Day <stephen.day@docker.com>
|
||||
Tamir Duberstein <tamird@gmail.com>
|
||||
Todd Eisenberger <teisenberger@dropbox.com>
|
||||
Tormod Erevik Lea <tormodlea@gmail.com>
|
||||
Vyacheslav Kim <kane@sendgrid.com>
|
||||
Walter Schulze <awalterschulze@gmail.com>
|
35
vendor/github.com/gogo/protobuf/LICENSE
generated
vendored
Normal file
35
vendor/github.com/gogo/protobuf/LICENSE
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
|
||||
Protocol Buffers for Go with Gadgets
|
||||
|
||||
Go support for Protocol Buffers - Google's data interchange format
|
||||
|
||||
Copyright 2010 The Go Authors. All rights reserved.
|
||||
https://github.com/golang/protobuf
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
43
vendor/github.com/gogo/protobuf/proto/Makefile
generated
vendored
Normal file
43
vendor/github.com/gogo/protobuf/proto/Makefile
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# Go support for Protocol Buffers - Google's data interchange format
|
||||
#
|
||||
# Copyright 2010 The Go Authors. All rights reserved.
|
||||
# https://github.com/golang/protobuf
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
install:
|
||||
go install
|
||||
|
||||
test: install generate-test-pbs
|
||||
go test
|
||||
|
||||
|
||||
generate-test-pbs:
|
||||
make install
|
||||
make -C test_proto
|
||||
make -C proto3_proto
|
||||
make
|
258
vendor/github.com/gogo/protobuf/proto/clone.go
generated
vendored
Normal file
258
vendor/github.com/gogo/protobuf/proto/clone.go
generated
vendored
Normal file
@ -0,0 +1,258 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Protocol buffer deep copy and merge.
|
||||
// TODO: RawMessage.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Clone returns a deep copy of a protocol buffer.
|
||||
func Clone(src Message) Message {
|
||||
in := reflect.ValueOf(src)
|
||||
if in.IsNil() {
|
||||
return src
|
||||
}
|
||||
out := reflect.New(in.Type().Elem())
|
||||
dst := out.Interface().(Message)
|
||||
Merge(dst, src)
|
||||
return dst
|
||||
}
|
||||
|
||||
// Merger is the interface representing objects that can merge messages of the same type.
|
||||
type Merger interface {
|
||||
// Merge merges src into this message.
|
||||
// Required and optional fields that are set in src will be set to that value in dst.
|
||||
// Elements of repeated fields will be appended.
|
||||
//
|
||||
// Merge may panic if called with a different argument type than the receiver.
|
||||
Merge(src Message)
|
||||
}
|
||||
|
||||
// generatedMerger is the custom merge method that generated protos will have.
|
||||
// We must add this method since a generate Merge method will conflict with
|
||||
// many existing protos that have a Merge data field already defined.
|
||||
type generatedMerger interface {
|
||||
XXX_Merge(src Message)
|
||||
}
|
||||
|
||||
// Merge merges src into dst.
|
||||
// Required and optional fields that are set in src will be set to that value in dst.
|
||||
// Elements of repeated fields will be appended.
|
||||
// Merge panics if src and dst are not the same type, or if dst is nil.
|
||||
func Merge(dst, src Message) {
|
||||
if m, ok := dst.(Merger); ok {
|
||||
m.Merge(src)
|
||||
return
|
||||
}
|
||||
|
||||
in := reflect.ValueOf(src)
|
||||
out := reflect.ValueOf(dst)
|
||||
if out.IsNil() {
|
||||
panic("proto: nil destination")
|
||||
}
|
||||
if in.Type() != out.Type() {
|
||||
panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src))
|
||||
}
|
||||
if in.IsNil() {
|
||||
return // Merge from nil src is a noop
|
||||
}
|
||||
if m, ok := dst.(generatedMerger); ok {
|
||||
m.XXX_Merge(src)
|
||||
return
|
||||
}
|
||||
mergeStruct(out.Elem(), in.Elem())
|
||||
}
|
||||
|
||||
func mergeStruct(out, in reflect.Value) {
|
||||
sprop := GetProperties(in.Type())
|
||||
for i := 0; i < in.NumField(); i++ {
|
||||
f := in.Type().Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
|
||||
}
|
||||
|
||||
if emIn, ok := in.Addr().Interface().(extensionsBytes); ok {
|
||||
emOut := out.Addr().Interface().(extensionsBytes)
|
||||
bIn := emIn.GetExtensions()
|
||||
bOut := emOut.GetExtensions()
|
||||
*bOut = append(*bOut, *bIn...)
|
||||
} else if emIn, err := extendable(in.Addr().Interface()); err == nil {
|
||||
emOut, _ := extendable(out.Addr().Interface())
|
||||
mIn, muIn := emIn.extensionsRead()
|
||||
if mIn != nil {
|
||||
mOut := emOut.extensionsWrite()
|
||||
muIn.Lock()
|
||||
mergeExtension(mOut, mIn)
|
||||
muIn.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
uf := in.FieldByName("XXX_unrecognized")
|
||||
if !uf.IsValid() {
|
||||
return
|
||||
}
|
||||
uin := uf.Bytes()
|
||||
if len(uin) > 0 {
|
||||
out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
|
||||
}
|
||||
}
|
||||
|
||||
// mergeAny performs a merge between two values of the same type.
|
||||
// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
|
||||
// prop is set if this is a struct field (it may be nil).
|
||||
func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
|
||||
if in.Type() == protoMessageType {
|
||||
if !in.IsNil() {
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
|
||||
} else {
|
||||
Merge(out.Interface().(Message), in.Interface().(Message))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
switch in.Kind() {
|
||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||
if !viaPtr && isProto3Zero(in) {
|
||||
return
|
||||
}
|
||||
out.Set(in)
|
||||
case reflect.Interface:
|
||||
// Probably a oneof field; copy non-nil values.
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
// Allocate destination if it is not set, or set to a different type.
|
||||
// Otherwise we will merge as normal.
|
||||
if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
|
||||
out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
|
||||
}
|
||||
mergeAny(out.Elem(), in.Elem(), false, nil)
|
||||
case reflect.Map:
|
||||
if in.Len() == 0 {
|
||||
return
|
||||
}
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.MakeMap(in.Type()))
|
||||
}
|
||||
// For maps with value types of *T or []byte we need to deep copy each value.
|
||||
elemKind := in.Type().Elem().Kind()
|
||||
for _, key := range in.MapKeys() {
|
||||
var val reflect.Value
|
||||
switch elemKind {
|
||||
case reflect.Ptr:
|
||||
val = reflect.New(in.Type().Elem().Elem())
|
||||
mergeAny(val, in.MapIndex(key), false, nil)
|
||||
case reflect.Slice:
|
||||
val = in.MapIndex(key)
|
||||
val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
|
||||
default:
|
||||
val = in.MapIndex(key)
|
||||
}
|
||||
out.SetMapIndex(key, val)
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.New(in.Elem().Type()))
|
||||
}
|
||||
mergeAny(out.Elem(), in.Elem(), true, nil)
|
||||
case reflect.Slice:
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
if in.Type().Elem().Kind() == reflect.Uint8 {
|
||||
// []byte is a scalar bytes field, not a repeated field.
|
||||
|
||||
// Edge case: if this is in a proto3 message, a zero length
|
||||
// bytes field is considered the zero value, and should not
|
||||
// be merged.
|
||||
if prop != nil && prop.proto3 && in.Len() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Make a deep copy.
|
||||
// Append to []byte{} instead of []byte(nil) so that we never end up
|
||||
// with a nil result.
|
||||
out.SetBytes(append([]byte{}, in.Bytes()...))
|
||||
return
|
||||
}
|
||||
n := in.Len()
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.MakeSlice(in.Type(), 0, n))
|
||||
}
|
||||
switch in.Type().Elem().Kind() {
|
||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||
out.Set(reflect.AppendSlice(out, in))
|
||||
default:
|
||||
for i := 0; i < n; i++ {
|
||||
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
||||
mergeAny(x, in.Index(i), false, nil)
|
||||
out.Set(reflect.Append(out, x))
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
mergeStruct(out, in)
|
||||
default:
|
||||
// unknown type, so not a protocol buffer
|
||||
log.Printf("proto: don't know how to copy %v", in)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeExtension(out, in map[int32]Extension) {
|
||||
for extNum, eIn := range in {
|
||||
eOut := Extension{desc: eIn.desc}
|
||||
if eIn.value != nil {
|
||||
v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
|
||||
mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
|
||||
eOut.value = v.Interface()
|
||||
}
|
||||
if eIn.enc != nil {
|
||||
eOut.enc = make([]byte, len(eIn.enc))
|
||||
copy(eOut.enc, eIn.enc)
|
||||
}
|
||||
|
||||
out[extNum] = eOut
|
||||
}
|
||||
}
|
39
vendor/github.com/gogo/protobuf/proto/custom_gogo.go
generated
vendored
Normal file
39
vendor/github.com/gogo/protobuf/proto/custom_gogo.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import "reflect"
|
||||
|
||||
type custom interface {
|
||||
Marshal() ([]byte, error)
|
||||
Unmarshal(data []byte) error
|
||||
Size() int
|
||||
}
|
||||
|
||||
var customType = reflect.TypeOf((*custom)(nil)).Elem()
|
427
vendor/github.com/gogo/protobuf/proto/decode.go
generated
vendored
Normal file
427
vendor/github.com/gogo/protobuf/proto/decode.go
generated
vendored
Normal file
@ -0,0 +1,427 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Routines for decoding protocol buffer data to construct in-memory representations.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// errOverflow is returned when an integer is too large to be represented.
|
||||
var errOverflow = errors.New("proto: integer overflow")
|
||||
|
||||
// ErrInternalBadWireType is returned by generated code when an incorrect
|
||||
// wire type is encountered. It does not get returned to user code.
|
||||
var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
|
||||
|
||||
// DecodeVarint reads a varint-encoded integer from the slice.
|
||||
// It returns the integer and the number of bytes consumed, or
|
||||
// zero if there is not enough.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
func DecodeVarint(buf []byte) (x uint64, n int) {
|
||||
for shift := uint(0); shift < 64; shift += 7 {
|
||||
if n >= len(buf) {
|
||||
return 0, 0
|
||||
}
|
||||
b := uint64(buf[n])
|
||||
n++
|
||||
x |= (b & 0x7F) << shift
|
||||
if (b & 0x80) == 0 {
|
||||
return x, n
|
||||
}
|
||||
}
|
||||
|
||||
// The number is too large to represent in a 64-bit value.
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
|
||||
i := p.index
|
||||
l := len(p.buf)
|
||||
|
||||
for shift := uint(0); shift < 64; shift += 7 {
|
||||
if i >= l {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
b := p.buf[i]
|
||||
i++
|
||||
x |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
p.index = i
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// The number is too large to represent in a 64-bit value.
|
||||
err = errOverflow
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeVarint reads a varint-encoded integer from the Buffer.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
||||
i := p.index
|
||||
buf := p.buf
|
||||
|
||||
if i >= len(buf) {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
} else if buf[i] < 0x80 {
|
||||
p.index++
|
||||
return uint64(buf[i]), nil
|
||||
} else if len(buf)-i < 10 {
|
||||
return p.decodeVarintSlow()
|
||||
}
|
||||
|
||||
var b uint64
|
||||
// we already checked the first byte
|
||||
x = uint64(buf[i]) - 0x80
|
||||
i++
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 7
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 7
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 14
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 14
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 21
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 21
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 28
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 28
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 35
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 35
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 42
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 42
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 49
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 49
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 56
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 56
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 63
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
|
||||
return 0, errOverflow
|
||||
|
||||
done:
|
||||
p.index = i
|
||||
return x, nil
|
||||
}
|
||||
|
||||
// DecodeFixed64 reads a 64-bit integer from the Buffer.
|
||||
// This is the format for the
|
||||
// fixed64, sfixed64, and double protocol buffer types.
|
||||
func (p *Buffer) DecodeFixed64() (x uint64, err error) {
|
||||
// x, err already 0
|
||||
i := p.index + 8
|
||||
if i < 0 || i > len(p.buf) {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
p.index = i
|
||||
|
||||
x = uint64(p.buf[i-8])
|
||||
x |= uint64(p.buf[i-7]) << 8
|
||||
x |= uint64(p.buf[i-6]) << 16
|
||||
x |= uint64(p.buf[i-5]) << 24
|
||||
x |= uint64(p.buf[i-4]) << 32
|
||||
x |= uint64(p.buf[i-3]) << 40
|
||||
x |= uint64(p.buf[i-2]) << 48
|
||||
x |= uint64(p.buf[i-1]) << 56
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeFixed32 reads a 32-bit integer from the Buffer.
|
||||
// This is the format for the
|
||||
// fixed32, sfixed32, and float protocol buffer types.
|
||||
func (p *Buffer) DecodeFixed32() (x uint64, err error) {
|
||||
// x, err already 0
|
||||
i := p.index + 4
|
||||
if i < 0 || i > len(p.buf) {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
p.index = i
|
||||
|
||||
x = uint64(p.buf[i-4])
|
||||
x |= uint64(p.buf[i-3]) << 8
|
||||
x |= uint64(p.buf[i-2]) << 16
|
||||
x |= uint64(p.buf[i-1]) << 24
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
|
||||
// from the Buffer.
|
||||
// This is the format used for the sint64 protocol buffer type.
|
||||
func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
|
||||
x, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
|
||||
// from the Buffer.
|
||||
// This is the format used for the sint32 protocol buffer type.
|
||||
func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
|
||||
x, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
|
||||
// This is the format used for the bytes protocol buffer
|
||||
// type and for embedded messages.
|
||||
func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
|
||||
n, err := p.DecodeVarint()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nb := int(n)
|
||||
if nb < 0 {
|
||||
return nil, fmt.Errorf("proto: bad byte length %d", nb)
|
||||
}
|
||||
end := p.index + nb
|
||||
if end < p.index || end > len(p.buf) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
if !alloc {
|
||||
// todo: check if can get more uses of alloc=false
|
||||
buf = p.buf[p.index:end]
|
||||
p.index += nb
|
||||
return
|
||||
}
|
||||
|
||||
buf = make([]byte, nb)
|
||||
copy(buf, p.buf[p.index:])
|
||||
p.index += nb
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeStringBytes reads an encoded string from the Buffer.
|
||||
// This is the format used for the proto2 string type.
|
||||
func (p *Buffer) DecodeStringBytes() (s string, err error) {
|
||||
buf, err := p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
// Unmarshaler is the interface representing objects that can
|
||||
// unmarshal themselves. The argument points to data that may be
|
||||
// overwritten, so implementations should not keep references to the
|
||||
// buffer.
|
||||
// Unmarshal implementations should not clear the receiver.
|
||||
// Any unmarshaled data should be merged into the receiver.
|
||||
// Callers of Unmarshal that do not want to retain existing data
|
||||
// should Reset the receiver before calling Unmarshal.
|
||||
type Unmarshaler interface {
|
||||
Unmarshal([]byte) error
|
||||
}
|
||||
|
||||
// newUnmarshaler is the interface representing objects that can
|
||||
// unmarshal themselves. The semantics are identical to Unmarshaler.
|
||||
//
|
||||
// This exists to support protoc-gen-go generated messages.
|
||||
// The proto package will stop type-asserting to this interface in the future.
|
||||
//
|
||||
// DO NOT DEPEND ON THIS.
|
||||
type newUnmarshaler interface {
|
||||
XXX_Unmarshal([]byte) error
|
||||
}
|
||||
|
||||
// Unmarshal parses the protocol buffer representation in buf and places the
|
||||
// decoded result in pb. If the struct underlying pb does not match
|
||||
// the data in buf, the results can be unpredictable.
|
||||
//
|
||||
// Unmarshal resets pb before starting to unmarshal, so any
|
||||
// existing data in pb is always removed. Use UnmarshalMerge
|
||||
// to preserve and append to existing data.
|
||||
func Unmarshal(buf []byte, pb Message) error {
|
||||
pb.Reset()
|
||||
if u, ok := pb.(newUnmarshaler); ok {
|
||||
return u.XXX_Unmarshal(buf)
|
||||
}
|
||||
if u, ok := pb.(Unmarshaler); ok {
|
||||
return u.Unmarshal(buf)
|
||||
}
|
||||
return NewBuffer(buf).Unmarshal(pb)
|
||||
}
|
||||
|
||||
// UnmarshalMerge parses the protocol buffer representation in buf and
|
||||
// writes the decoded result to pb. If the struct underlying pb does not match
|
||||
// the data in buf, the results can be unpredictable.
|
||||
//
|
||||
// UnmarshalMerge merges into existing data in pb.
|
||||
// Most code should use Unmarshal instead.
|
||||
func UnmarshalMerge(buf []byte, pb Message) error {
|
||||
if u, ok := pb.(newUnmarshaler); ok {
|
||||
return u.XXX_Unmarshal(buf)
|
||||
}
|
||||
if u, ok := pb.(Unmarshaler); ok {
|
||||
// NOTE: The history of proto have unfortunately been inconsistent
|
||||
// whether Unmarshaler should or should not implicitly clear itself.
|
||||
// Some implementations do, most do not.
|
||||
// Thus, calling this here may or may not do what people want.
|
||||
//
|
||||
// See https://github.com/golang/protobuf/issues/424
|
||||
return u.Unmarshal(buf)
|
||||
}
|
||||
return NewBuffer(buf).Unmarshal(pb)
|
||||
}
|
||||
|
||||
// DecodeMessage reads a count-delimited message from the Buffer.
|
||||
func (p *Buffer) DecodeMessage(pb Message) error {
|
||||
enc, err := p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return NewBuffer(enc).Unmarshal(pb)
|
||||
}
|
||||
|
||||
// DecodeGroup reads a tag-delimited group from the Buffer.
|
||||
// StartGroup tag is already consumed. This function consumes
|
||||
// EndGroup tag.
|
||||
func (p *Buffer) DecodeGroup(pb Message) error {
|
||||
b := p.buf[p.index:]
|
||||
x, y := findEndGroup(b)
|
||||
if x < 0 {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
err := Unmarshal(b[:x], pb)
|
||||
p.index += y
|
||||
return err
|
||||
}
|
||||
|
||||
// Unmarshal parses the protocol buffer representation in the
|
||||
// Buffer and places the decoded result in pb. If the struct
|
||||
// underlying pb does not match the data in the buffer, the results can be
|
||||
// unpredictable.
|
||||
//
|
||||
// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
|
||||
func (p *Buffer) Unmarshal(pb Message) error {
|
||||
// If the object can unmarshal itself, let it.
|
||||
if u, ok := pb.(newUnmarshaler); ok {
|
||||
err := u.XXX_Unmarshal(p.buf[p.index:])
|
||||
p.index = len(p.buf)
|
||||
return err
|
||||
}
|
||||
if u, ok := pb.(Unmarshaler); ok {
|
||||
// NOTE: The history of proto have unfortunately been inconsistent
|
||||
// whether Unmarshaler should or should not implicitly clear itself.
|
||||
// Some implementations do, most do not.
|
||||
// Thus, calling this here may or may not do what people want.
|
||||
//
|
||||
// See https://github.com/golang/protobuf/issues/424
|
||||
err := u.Unmarshal(p.buf[p.index:])
|
||||
p.index = len(p.buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// Slow workaround for messages that aren't Unmarshalers.
|
||||
// This includes some hand-coded .pb.go files and
|
||||
// bootstrap protos.
|
||||
// TODO: fix all of those and then add Unmarshal to
|
||||
// the Message interface. Then:
|
||||
// The cast above and code below can be deleted.
|
||||
// The old unmarshaler can be deleted.
|
||||
// Clients can call Unmarshal directly (can already do that, actually).
|
||||
var info InternalMessageInfo
|
||||
err := info.Unmarshal(pb, p.buf[p.index:])
|
||||
p.index = len(p.buf)
|
||||
return err
|
||||
}
|
63
vendor/github.com/gogo/protobuf/proto/deprecated.go
generated
vendored
Normal file
63
vendor/github.com/gogo/protobuf/proto/deprecated.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import "errors"
|
||||
|
||||
// Deprecated: do not use.
|
||||
type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }
|
||||
|
||||
// Deprecated: do not use.
|
||||
func GetStats() Stats { return Stats{} }
|
||||
|
||||
// Deprecated: do not use.
|
||||
func MarshalMessageSet(interface{}) ([]byte, error) {
|
||||
return nil, errors.New("proto: not implemented")
|
||||
}
|
||||
|
||||
// Deprecated: do not use.
|
||||
func UnmarshalMessageSet([]byte, interface{}) error {
|
||||
return errors.New("proto: not implemented")
|
||||
}
|
||||
|
||||
// Deprecated: do not use.
|
||||
func MarshalMessageSetJSON(interface{}) ([]byte, error) {
|
||||
return nil, errors.New("proto: not implemented")
|
||||
}
|
||||
|
||||
// Deprecated: do not use.
|
||||
func UnmarshalMessageSetJSON([]byte, interface{}) error {
|
||||
return errors.New("proto: not implemented")
|
||||
}
|
||||
|
||||
// Deprecated: do not use.
|
||||
func RegisterMessageSetType(Message, int32, string) {}
|
350
vendor/github.com/gogo/protobuf/proto/discard.go
generated
vendored
Normal file
350
vendor/github.com/gogo/protobuf/proto/discard.go
generated
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type generatedDiscarder interface {
|
||||
XXX_DiscardUnknown()
|
||||
}
|
||||
|
||||
// DiscardUnknown recursively discards all unknown fields from this message
|
||||
// and all embedded messages.
|
||||
//
|
||||
// When unmarshaling a message with unrecognized fields, the tags and values
|
||||
// of such fields are preserved in the Message. This allows a later call to
|
||||
// marshal to be able to produce a message that continues to have those
|
||||
// unrecognized fields. To avoid this, DiscardUnknown is used to
|
||||
// explicitly clear the unknown fields after unmarshaling.
|
||||
//
|
||||
// For proto2 messages, the unknown fields of message extensions are only
|
||||
// discarded from messages that have been accessed via GetExtension.
|
||||
func DiscardUnknown(m Message) {
|
||||
if m, ok := m.(generatedDiscarder); ok {
|
||||
m.XXX_DiscardUnknown()
|
||||
return
|
||||
}
|
||||
// TODO: Dynamically populate a InternalMessageInfo for legacy messages,
|
||||
// but the master branch has no implementation for InternalMessageInfo,
|
||||
// so it would be more work to replicate that approach.
|
||||
discardLegacy(m)
|
||||
}
|
||||
|
||||
// DiscardUnknown recursively discards all unknown fields.
|
||||
func (a *InternalMessageInfo) DiscardUnknown(m Message) {
|
||||
di := atomicLoadDiscardInfo(&a.discard)
|
||||
if di == nil {
|
||||
di = getDiscardInfo(reflect.TypeOf(m).Elem())
|
||||
atomicStoreDiscardInfo(&a.discard, di)
|
||||
}
|
||||
di.discard(toPointer(&m))
|
||||
}
|
||||
|
||||
type discardInfo struct {
|
||||
typ reflect.Type
|
||||
|
||||
initialized int32 // 0: only typ is valid, 1: everything is valid
|
||||
lock sync.Mutex
|
||||
|
||||
fields []discardFieldInfo
|
||||
unrecognized field
|
||||
}
|
||||
|
||||
type discardFieldInfo struct {
|
||||
field field // Offset of field, guaranteed to be valid
|
||||
discard func(src pointer)
|
||||
}
|
||||
|
||||
var (
|
||||
discardInfoMap = map[reflect.Type]*discardInfo{}
|
||||
discardInfoLock sync.Mutex
|
||||
)
|
||||
|
||||
func getDiscardInfo(t reflect.Type) *discardInfo {
|
||||
discardInfoLock.Lock()
|
||||
defer discardInfoLock.Unlock()
|
||||
di := discardInfoMap[t]
|
||||
if di == nil {
|
||||
di = &discardInfo{typ: t}
|
||||
discardInfoMap[t] = di
|
||||
}
|
||||
return di
|
||||
}
|
||||
|
||||
func (di *discardInfo) discard(src pointer) {
|
||||
if src.isNil() {
|
||||
return // Nothing to do.
|
||||
}
|
||||
|
||||
if atomic.LoadInt32(&di.initialized) == 0 {
|
||||
di.computeDiscardInfo()
|
||||
}
|
||||
|
||||
for _, fi := range di.fields {
|
||||
sfp := src.offset(fi.field)
|
||||
fi.discard(sfp)
|
||||
}
|
||||
|
||||
// For proto2 messages, only discard unknown fields in message extensions
|
||||
// that have been accessed via GetExtension.
|
||||
if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil {
|
||||
// Ignore lock since DiscardUnknown is not concurrency safe.
|
||||
emm, _ := em.extensionsRead()
|
||||
for _, mx := range emm {
|
||||
if m, ok := mx.value.(Message); ok {
|
||||
DiscardUnknown(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if di.unrecognized.IsValid() {
|
||||
*src.offset(di.unrecognized).toBytes() = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (di *discardInfo) computeDiscardInfo() {
|
||||
di.lock.Lock()
|
||||
defer di.lock.Unlock()
|
||||
if di.initialized != 0 {
|
||||
return
|
||||
}
|
||||
t := di.typ
|
||||
n := t.NumField()
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
f := t.Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
|
||||
dfi := discardFieldInfo{field: toField(&f)}
|
||||
tf := f.Type
|
||||
|
||||
// Unwrap tf to get its most basic type.
|
||||
var isPointer, isSlice bool
|
||||
if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
|
||||
isSlice = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if tf.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if isPointer && isSlice && tf.Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name))
|
||||
}
|
||||
|
||||
switch tf.Kind() {
|
||||
case reflect.Struct:
|
||||
switch {
|
||||
case !isPointer:
|
||||
panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name))
|
||||
case isSlice: // E.g., []*pb.T
|
||||
discardInfo := getDiscardInfo(tf)
|
||||
dfi.discard = func(src pointer) {
|
||||
sps := src.getPointerSlice()
|
||||
for _, sp := range sps {
|
||||
if !sp.isNil() {
|
||||
discardInfo.discard(sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., *pb.T
|
||||
discardInfo := getDiscardInfo(tf)
|
||||
dfi.discard = func(src pointer) {
|
||||
sp := src.getPointer()
|
||||
if !sp.isNil() {
|
||||
discardInfo.discard(sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name))
|
||||
default: // E.g., map[K]V
|
||||
if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T)
|
||||
dfi.discard = func(src pointer) {
|
||||
sm := src.asPointerTo(tf).Elem()
|
||||
if sm.Len() == 0 {
|
||||
return
|
||||
}
|
||||
for _, key := range sm.MapKeys() {
|
||||
val := sm.MapIndex(key)
|
||||
DiscardUnknown(val.Interface().(Message))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dfi.discard = func(pointer) {} // Noop
|
||||
}
|
||||
}
|
||||
case reflect.Interface:
|
||||
// Must be oneof field.
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name))
|
||||
default: // E.g., interface{}
|
||||
// TODO: Make this faster?
|
||||
dfi.discard = func(src pointer) {
|
||||
su := src.asPointerTo(tf).Elem()
|
||||
if !su.IsNil() {
|
||||
sv := su.Elem().Elem().Field(0)
|
||||
if sv.Kind() == reflect.Ptr && sv.IsNil() {
|
||||
return
|
||||
}
|
||||
switch sv.Type().Kind() {
|
||||
case reflect.Ptr: // Proto struct (e.g., *T)
|
||||
DiscardUnknown(sv.Interface().(Message))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
di.fields = append(di.fields, dfi)
|
||||
}
|
||||
|
||||
di.unrecognized = invalidField
|
||||
if f, ok := t.FieldByName("XXX_unrecognized"); ok {
|
||||
if f.Type != reflect.TypeOf([]byte{}) {
|
||||
panic("expected XXX_unrecognized to be of type []byte")
|
||||
}
|
||||
di.unrecognized = toField(&f)
|
||||
}
|
||||
|
||||
atomic.StoreInt32(&di.initialized, 1)
|
||||
}
|
||||
|
||||
func discardLegacy(m Message) {
|
||||
v := reflect.ValueOf(m)
|
||||
if v.Kind() != reflect.Ptr || v.IsNil() {
|
||||
return
|
||||
}
|
||||
v = v.Elem()
|
||||
if v.Kind() != reflect.Struct {
|
||||
return
|
||||
}
|
||||
t := v.Type()
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
vf := v.Field(i)
|
||||
tf := f.Type
|
||||
|
||||
// Unwrap tf to get its most basic type.
|
||||
var isPointer, isSlice bool
|
||||
if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
|
||||
isSlice = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if tf.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if isPointer && isSlice && tf.Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name))
|
||||
}
|
||||
|
||||
switch tf.Kind() {
|
||||
case reflect.Struct:
|
||||
switch {
|
||||
case !isPointer:
|
||||
panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name))
|
||||
case isSlice: // E.g., []*pb.T
|
||||
for j := 0; j < vf.Len(); j++ {
|
||||
discardLegacy(vf.Index(j).Interface().(Message))
|
||||
}
|
||||
default: // E.g., *pb.T
|
||||
discardLegacy(vf.Interface().(Message))
|
||||
}
|
||||
case reflect.Map:
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name))
|
||||
default: // E.g., map[K]V
|
||||
tv := vf.Type().Elem()
|
||||
if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T)
|
||||
for _, key := range vf.MapKeys() {
|
||||
val := vf.MapIndex(key)
|
||||
discardLegacy(val.Interface().(Message))
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Interface:
|
||||
// Must be oneof field.
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name))
|
||||
default: // E.g., test_proto.isCommunique_Union interface
|
||||
if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" {
|
||||
vf = vf.Elem() // E.g., *test_proto.Communique_Msg
|
||||
if !vf.IsNil() {
|
||||
vf = vf.Elem() // E.g., test_proto.Communique_Msg
|
||||
vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value
|
||||
if vf.Kind() == reflect.Ptr {
|
||||
discardLegacy(vf.Interface().(Message))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() {
|
||||
if vf.Type() != reflect.TypeOf([]byte{}) {
|
||||
panic("expected XXX_unrecognized to be of type []byte")
|
||||
}
|
||||
vf.Set(reflect.ValueOf([]byte(nil)))
|
||||
}
|
||||
|
||||
// For proto2 messages, only discard unknown fields in message extensions
|
||||
// that have been accessed via GetExtension.
|
||||
if em, err := extendable(m); err == nil {
|
||||
// Ignore lock since discardLegacy is not concurrency safe.
|
||||
emm, _ := em.extensionsRead()
|
||||
for _, mx := range emm {
|
||||
if m, ok := mx.value.(Message); ok {
|
||||
discardLegacy(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
100
vendor/github.com/gogo/protobuf/proto/duration.go
generated
vendored
Normal file
100
vendor/github.com/gogo/protobuf/proto/duration.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
// This file implements conversions between google.protobuf.Duration
|
||||
// and time.Duration.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// Range of a Duration in seconds, as specified in
|
||||
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
|
||||
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
|
||||
minSeconds = -maxSeconds
|
||||
)
|
||||
|
||||
// validateDuration determines whether the Duration is valid according to the
|
||||
// definition in google/protobuf/duration.proto. A valid Duration
|
||||
// may still be too large to fit into a time.Duration (the range of Duration
|
||||
// is about 10,000 years, and the range of time.Duration is about 290).
|
||||
func validateDuration(d *duration) error {
|
||||
if d == nil {
|
||||
return errors.New("duration: nil Duration")
|
||||
}
|
||||
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
|
||||
return fmt.Errorf("duration: %#v: seconds out of range", d)
|
||||
}
|
||||
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
|
||||
return fmt.Errorf("duration: %#v: nanos out of range", d)
|
||||
}
|
||||
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
|
||||
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
|
||||
return fmt.Errorf("duration: %#v: seconds and nanos have different signs", d)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DurationFromProto converts a Duration to a time.Duration. DurationFromProto
|
||||
// returns an error if the Duration is invalid or is too large to be
|
||||
// represented in a time.Duration.
|
||||
func durationFromProto(p *duration) (time.Duration, error) {
|
||||
if err := validateDuration(p); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
d := time.Duration(p.Seconds) * time.Second
|
||||
if int64(d/time.Second) != p.Seconds {
|
||||
return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p)
|
||||
}
|
||||
if p.Nanos != 0 {
|
||||
d += time.Duration(p.Nanos)
|
||||
if (d < 0) != (p.Nanos < 0) {
|
||||
return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p)
|
||||
}
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// DurationProto converts a time.Duration to a Duration.
|
||||
func durationProto(d time.Duration) *duration {
|
||||
nanos := d.Nanoseconds()
|
||||
secs := nanos / 1e9
|
||||
nanos -= secs * 1e9
|
||||
return &duration{
|
||||
Seconds: secs,
|
||||
Nanos: int32(nanos),
|
||||
}
|
||||
}
|
49
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
generated
vendored
Normal file
49
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
var durationType = reflect.TypeOf((*time.Duration)(nil)).Elem()
|
||||
|
||||
type duration struct {
|
||||
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
|
||||
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
|
||||
}
|
||||
|
||||
func (m *duration) Reset() { *m = duration{} }
|
||||
func (*duration) ProtoMessage() {}
|
||||
func (*duration) String() string { return "duration<string>" }
|
||||
|
||||
func init() {
|
||||
RegisterType((*duration)(nil), "gogo.protobuf.proto.duration")
|
||||
}
|
205
vendor/github.com/gogo/protobuf/proto/encode.go
generated
vendored
Normal file
205
vendor/github.com/gogo/protobuf/proto/encode.go
generated
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Routines for encoding data into the wire format for protocol buffers.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var (
|
||||
// errRepeatedHasNil is the error returned if Marshal is called with
|
||||
// a struct with a repeated field containing a nil element.
|
||||
errRepeatedHasNil = errors.New("proto: repeated field has nil element")
|
||||
|
||||
// errOneofHasNil is the error returned if Marshal is called with
|
||||
// a struct with a oneof field containing a nil element.
|
||||
errOneofHasNil = errors.New("proto: oneof field has nil value")
|
||||
|
||||
// ErrNil is the error returned if Marshal is called with nil.
|
||||
ErrNil = errors.New("proto: Marshal called with nil")
|
||||
|
||||
// ErrTooLarge is the error returned if Marshal is called with a
|
||||
// message that encodes to >2GB.
|
||||
ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
|
||||
)
|
||||
|
||||
// The fundamental encoders that put bytes on the wire.
|
||||
// Those that take integer types all accept uint64 and are
|
||||
// therefore of type valueEncoder.
|
||||
|
||||
const maxVarintBytes = 10 // maximum length of a varint
|
||||
|
||||
// EncodeVarint returns the varint encoding of x.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
// Not used by the package itself, but helpful to clients
|
||||
// wishing to use the same encoding.
|
||||
func EncodeVarint(x uint64) []byte {
|
||||
var buf [maxVarintBytes]byte
|
||||
var n int
|
||||
for n = 0; x > 127; n++ {
|
||||
buf[n] = 0x80 | uint8(x&0x7F)
|
||||
x >>= 7
|
||||
}
|
||||
buf[n] = uint8(x)
|
||||
n++
|
||||
return buf[0:n]
|
||||
}
|
||||
|
||||
// EncodeVarint writes a varint-encoded integer to the Buffer.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
func (p *Buffer) EncodeVarint(x uint64) error {
|
||||
for x >= 1<<7 {
|
||||
p.buf = append(p.buf, uint8(x&0x7f|0x80))
|
||||
x >>= 7
|
||||
}
|
||||
p.buf = append(p.buf, uint8(x))
|
||||
return nil
|
||||
}
|
||||
|
||||
// SizeVarint returns the varint encoding size of an integer.
|
||||
func SizeVarint(x uint64) int {
|
||||
switch {
|
||||
case x < 1<<7:
|
||||
return 1
|
||||
case x < 1<<14:
|
||||
return 2
|
||||
case x < 1<<21:
|
||||
return 3
|
||||
case x < 1<<28:
|
||||
return 4
|
||||
case x < 1<<35:
|
||||
return 5
|
||||
case x < 1<<42:
|
||||
return 6
|
||||
case x < 1<<49:
|
||||
return 7
|
||||
case x < 1<<56:
|
||||
return 8
|
||||
case x < 1<<63:
|
||||
return 9
|
||||
}
|
||||
return 10
|
||||
}
|
||||
|
||||
// EncodeFixed64 writes a 64-bit integer to the Buffer.
|
||||
// This is the format for the
|
||||
// fixed64, sfixed64, and double protocol buffer types.
|
||||
func (p *Buffer) EncodeFixed64(x uint64) error {
|
||||
p.buf = append(p.buf,
|
||||
uint8(x),
|
||||
uint8(x>>8),
|
||||
uint8(x>>16),
|
||||
uint8(x>>24),
|
||||
uint8(x>>32),
|
||||
uint8(x>>40),
|
||||
uint8(x>>48),
|
||||
uint8(x>>56))
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeFixed32 writes a 32-bit integer to the Buffer.
|
||||
// This is the format for the
|
||||
// fixed32, sfixed32, and float protocol buffer types.
|
||||
func (p *Buffer) EncodeFixed32(x uint64) error {
|
||||
p.buf = append(p.buf,
|
||||
uint8(x),
|
||||
uint8(x>>8),
|
||||
uint8(x>>16),
|
||||
uint8(x>>24))
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
|
||||
// to the Buffer.
|
||||
// This is the format used for the sint64 protocol buffer type.
|
||||
func (p *Buffer) EncodeZigzag64(x uint64) error {
|
||||
// use signed number to get arithmetic right shift.
|
||||
return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
|
||||
// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
|
||||
// to the Buffer.
|
||||
// This is the format used for the sint32 protocol buffer type.
|
||||
func (p *Buffer) EncodeZigzag32(x uint64) error {
|
||||
// use signed number to get arithmetic right shift.
|
||||
return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
|
||||
}
|
||||
|
||||
// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
|
||||
// This is the format used for the bytes protocol buffer
|
||||
// type and for embedded messages.
|
||||
func (p *Buffer) EncodeRawBytes(b []byte) error {
|
||||
p.EncodeVarint(uint64(len(b)))
|
||||
p.buf = append(p.buf, b...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeStringBytes writes an encoded string to the Buffer.
|
||||
// This is the format used for the proto2 string type.
|
||||
func (p *Buffer) EncodeStringBytes(s string) error {
|
||||
p.EncodeVarint(uint64(len(s)))
|
||||
p.buf = append(p.buf, s...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshaler is the interface representing objects that can marshal themselves.
|
||||
type Marshaler interface {
|
||||
Marshal() ([]byte, error)
|
||||
}
|
||||
|
||||
// EncodeMessage writes the protocol buffer to the Buffer,
|
||||
// prefixed by a varint-encoded length.
|
||||
func (p *Buffer) EncodeMessage(pb Message) error {
|
||||
siz := Size(pb)
|
||||
sizVar := SizeVarint(uint64(siz))
|
||||
p.grow(siz + sizVar)
|
||||
p.EncodeVarint(uint64(siz))
|
||||
return p.Marshal(pb)
|
||||
}
|
||||
|
||||
// All protocol buffer fields are nillable, but be careful.
|
||||
func isNil(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
return v.IsNil()
|
||||
}
|
||||
return false
|
||||
}
|
33
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
generated
vendored
Normal file
33
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
func NewRequiredNotSetError(field string) *RequiredNotSetError {
|
||||
return &RequiredNotSetError{field}
|
||||
}
|
300
vendor/github.com/gogo/protobuf/proto/equal.go
generated
vendored
Normal file
300
vendor/github.com/gogo/protobuf/proto/equal.go
generated
vendored
Normal file
@ -0,0 +1,300 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Protocol buffer comparison.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
Equal returns true iff protocol buffers a and b are equal.
|
||||
The arguments must both be pointers to protocol buffer structs.
|
||||
|
||||
Equality is defined in this way:
|
||||
- Two messages are equal iff they are the same type,
|
||||
corresponding fields are equal, unknown field sets
|
||||
are equal, and extensions sets are equal.
|
||||
- Two set scalar fields are equal iff their values are equal.
|
||||
If the fields are of a floating-point type, remember that
|
||||
NaN != x for all x, including NaN. If the message is defined
|
||||
in a proto3 .proto file, fields are not "set"; specifically,
|
||||
zero length proto3 "bytes" fields are equal (nil == {}).
|
||||
- Two repeated fields are equal iff their lengths are the same,
|
||||
and their corresponding elements are equal. Note a "bytes" field,
|
||||
although represented by []byte, is not a repeated field and the
|
||||
rule for the scalar fields described above applies.
|
||||
- Two unset fields are equal.
|
||||
- Two unknown field sets are equal if their current
|
||||
encoded state is equal.
|
||||
- Two extension sets are equal iff they have corresponding
|
||||
elements that are pairwise equal.
|
||||
- Two map fields are equal iff their lengths are the same,
|
||||
and they contain the same set of elements. Zero-length map
|
||||
fields are equal.
|
||||
- Every other combination of things are not equal.
|
||||
|
||||
The return value is undefined if a and b are not protocol buffers.
|
||||
*/
|
||||
func Equal(a, b Message) bool {
|
||||
if a == nil || b == nil {
|
||||
return a == b
|
||||
}
|
||||
v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
|
||||
if v1.Type() != v2.Type() {
|
||||
return false
|
||||
}
|
||||
if v1.Kind() == reflect.Ptr {
|
||||
if v1.IsNil() {
|
||||
return v2.IsNil()
|
||||
}
|
||||
if v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
v1, v2 = v1.Elem(), v2.Elem()
|
||||
}
|
||||
if v1.Kind() != reflect.Struct {
|
||||
return false
|
||||
}
|
||||
return equalStruct(v1, v2)
|
||||
}
|
||||
|
||||
// v1 and v2 are known to have the same type.
|
||||
func equalStruct(v1, v2 reflect.Value) bool {
|
||||
sprop := GetProperties(v1.Type())
|
||||
for i := 0; i < v1.NumField(); i++ {
|
||||
f := v1.Type().Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
f1, f2 := v1.Field(i), v2.Field(i)
|
||||
if f.Type.Kind() == reflect.Ptr {
|
||||
if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
|
||||
// both unset
|
||||
continue
|
||||
} else if n1 != n2 {
|
||||
// set/unset mismatch
|
||||
return false
|
||||
}
|
||||
f1, f2 = f1.Elem(), f2.Elem()
|
||||
}
|
||||
if !equalAny(f1, f2, sprop.Prop[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
|
||||
em2 := v2.FieldByName("XXX_InternalExtensions")
|
||||
if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
|
||||
em2 := v2.FieldByName("XXX_extensions")
|
||||
if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
uf := v1.FieldByName("XXX_unrecognized")
|
||||
if !uf.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
u1 := uf.Bytes()
|
||||
u2 := v2.FieldByName("XXX_unrecognized").Bytes()
|
||||
return bytes.Equal(u1, u2)
|
||||
}
|
||||
|
||||
// v1 and v2 are known to have the same type.
|
||||
// prop may be nil.
|
||||
func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
|
||||
if v1.Type() == protoMessageType {
|
||||
m1, _ := v1.Interface().(Message)
|
||||
m2, _ := v2.Interface().(Message)
|
||||
return Equal(m1, m2)
|
||||
}
|
||||
switch v1.Kind() {
|
||||
case reflect.Bool:
|
||||
return v1.Bool() == v2.Bool()
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v1.Float() == v2.Float()
|
||||
case reflect.Int32, reflect.Int64:
|
||||
return v1.Int() == v2.Int()
|
||||
case reflect.Interface:
|
||||
// Probably a oneof field; compare the inner values.
|
||||
n1, n2 := v1.IsNil(), v2.IsNil()
|
||||
if n1 || n2 {
|
||||
return n1 == n2
|
||||
}
|
||||
e1, e2 := v1.Elem(), v2.Elem()
|
||||
if e1.Type() != e2.Type() {
|
||||
return false
|
||||
}
|
||||
return equalAny(e1, e2, nil)
|
||||
case reflect.Map:
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
for _, key := range v1.MapKeys() {
|
||||
val2 := v2.MapIndex(key)
|
||||
if !val2.IsValid() {
|
||||
// This key was not found in the second map.
|
||||
return false
|
||||
}
|
||||
if !equalAny(v1.MapIndex(key), val2, nil) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case reflect.Ptr:
|
||||
// Maps may have nil values in them, so check for nil.
|
||||
if v1.IsNil() && v2.IsNil() {
|
||||
return true
|
||||
}
|
||||
if v1.IsNil() != v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
return equalAny(v1.Elem(), v2.Elem(), prop)
|
||||
case reflect.Slice:
|
||||
if v1.Type().Elem().Kind() == reflect.Uint8 {
|
||||
// short circuit: []byte
|
||||
|
||||
// Edge case: if this is in a proto3 message, a zero length
|
||||
// bytes field is considered the zero value.
|
||||
if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {
|
||||
return true
|
||||
}
|
||||
if v1.IsNil() != v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
|
||||
}
|
||||
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < v1.Len(); i++ {
|
||||
if !equalAny(v1.Index(i), v2.Index(i), prop) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case reflect.String:
|
||||
return v1.Interface().(string) == v2.Interface().(string)
|
||||
case reflect.Struct:
|
||||
return equalStruct(v1, v2)
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
return v1.Uint() == v2.Uint()
|
||||
}
|
||||
|
||||
// unknown type, so not a protocol buffer
|
||||
log.Printf("proto: don't know how to compare %v", v1)
|
||||
return false
|
||||
}
|
||||
|
||||
// base is the struct type that the extensions are based on.
|
||||
// x1 and x2 are InternalExtensions.
|
||||
func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
|
||||
em1, _ := x1.extensionsRead()
|
||||
em2, _ := x2.extensionsRead()
|
||||
return equalExtMap(base, em1, em2)
|
||||
}
|
||||
|
||||
func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
|
||||
if len(em1) != len(em2) {
|
||||
return false
|
||||
}
|
||||
|
||||
for extNum, e1 := range em1 {
|
||||
e2, ok := em2[extNum]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
m1, m2 := e1.value, e2.value
|
||||
|
||||
if m1 == nil && m2 == nil {
|
||||
// Both have only encoded form.
|
||||
if bytes.Equal(e1.enc, e2.enc) {
|
||||
continue
|
||||
}
|
||||
// The bytes are different, but the extensions might still be
|
||||
// equal. We need to decode them to compare.
|
||||
}
|
||||
|
||||
if m1 != nil && m2 != nil {
|
||||
// Both are unencoded.
|
||||
if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// At least one is encoded. To do a semantically correct comparison
|
||||
// we need to unmarshal them first.
|
||||
var desc *ExtensionDesc
|
||||
if m := extensionMaps[base]; m != nil {
|
||||
desc = m[extNum]
|
||||
}
|
||||
if desc == nil {
|
||||
// If both have only encoded form and the bytes are the same,
|
||||
// it is handled above. We get here when the bytes are different.
|
||||
// We don't know how to decode it, so just compare them as byte
|
||||
// slices.
|
||||
log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
|
||||
return false
|
||||
}
|
||||
var err error
|
||||
if m1 == nil {
|
||||
m1, err = decodeExtension(e1.enc, desc)
|
||||
}
|
||||
if m2 == nil && err == nil {
|
||||
m2, err = decodeExtension(e2.enc, desc)
|
||||
}
|
||||
if err != nil {
|
||||
// The encoded form is invalid.
|
||||
log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
|
||||
return false
|
||||
}
|
||||
if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
605
vendor/github.com/gogo/protobuf/proto/extensions.go
generated
vendored
Normal file
605
vendor/github.com/gogo/protobuf/proto/extensions.go
generated
vendored
Normal file
@ -0,0 +1,605 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Types and routines for supporting protocol buffer extensions.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
|
||||
var ErrMissingExtension = errors.New("proto: missing extension")
|
||||
|
||||
// ExtensionRange represents a range of message extensions for a protocol buffer.
|
||||
// Used in code generated by the protocol compiler.
|
||||
type ExtensionRange struct {
|
||||
Start, End int32 // both inclusive
|
||||
}
|
||||
|
||||
// extendableProto is an interface implemented by any protocol buffer generated by the current
|
||||
// proto compiler that may be extended.
|
||||
type extendableProto interface {
|
||||
Message
|
||||
ExtensionRangeArray() []ExtensionRange
|
||||
extensionsWrite() map[int32]Extension
|
||||
extensionsRead() (map[int32]Extension, sync.Locker)
|
||||
}
|
||||
|
||||
// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
|
||||
// version of the proto compiler that may be extended.
|
||||
type extendableProtoV1 interface {
|
||||
Message
|
||||
ExtensionRangeArray() []ExtensionRange
|
||||
ExtensionMap() map[int32]Extension
|
||||
}
|
||||
|
||||
// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
|
||||
type extensionAdapter struct {
|
||||
extendableProtoV1
|
||||
}
|
||||
|
||||
func (e extensionAdapter) extensionsWrite() map[int32]Extension {
|
||||
return e.ExtensionMap()
|
||||
}
|
||||
|
||||
func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||
return e.ExtensionMap(), notLocker{}
|
||||
}
|
||||
|
||||
// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
|
||||
type notLocker struct{}
|
||||
|
||||
func (n notLocker) Lock() {}
|
||||
func (n notLocker) Unlock() {}
|
||||
|
||||
// extendable returns the extendableProto interface for the given generated proto message.
|
||||
// If the proto message has the old extension format, it returns a wrapper that implements
|
||||
// the extendableProto interface.
|
||||
func extendable(p interface{}) (extendableProto, error) {
|
||||
switch p := p.(type) {
|
||||
case extendableProto:
|
||||
if isNilPtr(p) {
|
||||
return nil, fmt.Errorf("proto: nil %T is not extendable", p)
|
||||
}
|
||||
return p, nil
|
||||
case extendableProtoV1:
|
||||
if isNilPtr(p) {
|
||||
return nil, fmt.Errorf("proto: nil %T is not extendable", p)
|
||||
}
|
||||
return extensionAdapter{p}, nil
|
||||
case extensionsBytes:
|
||||
return slowExtensionAdapter{p}, nil
|
||||
}
|
||||
// Don't allocate a specific error containing %T:
|
||||
// this is the hot path for Clone and MarshalText.
|
||||
return nil, errNotExtendable
|
||||
}
|
||||
|
||||
var errNotExtendable = errors.New("proto: not an extendable proto.Message")
|
||||
|
||||
func isNilPtr(x interface{}) bool {
|
||||
v := reflect.ValueOf(x)
|
||||
return v.Kind() == reflect.Ptr && v.IsNil()
|
||||
}
|
||||
|
||||
// XXX_InternalExtensions is an internal representation of proto extensions.
|
||||
//
|
||||
// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
|
||||
// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
|
||||
//
|
||||
// The methods of XXX_InternalExtensions are not concurrency safe in general,
|
||||
// but calls to logically read-only methods such as has and get may be executed concurrently.
|
||||
type XXX_InternalExtensions struct {
|
||||
// The struct must be indirect so that if a user inadvertently copies a
|
||||
// generated message and its embedded XXX_InternalExtensions, they
|
||||
// avoid the mayhem of a copied mutex.
|
||||
//
|
||||
// The mutex serializes all logically read-only operations to p.extensionMap.
|
||||
// It is up to the client to ensure that write operations to p.extensionMap are
|
||||
// mutually exclusive with other accesses.
|
||||
p *struct {
|
||||
mu sync.Mutex
|
||||
extensionMap map[int32]Extension
|
||||
}
|
||||
}
|
||||
|
||||
// extensionsWrite returns the extension map, creating it on first use.
|
||||
func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
|
||||
if e.p == nil {
|
||||
e.p = new(struct {
|
||||
mu sync.Mutex
|
||||
extensionMap map[int32]Extension
|
||||
})
|
||||
e.p.extensionMap = make(map[int32]Extension)
|
||||
}
|
||||
return e.p.extensionMap
|
||||
}
|
||||
|
||||
// extensionsRead returns the extensions map for read-only use. It may be nil.
|
||||
// The caller must hold the returned mutex's lock when accessing Elements within the map.
|
||||
func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||
if e.p == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return e.p.extensionMap, &e.p.mu
|
||||
}
|
||||
|
||||
// ExtensionDesc represents an extension specification.
|
||||
// Used in generated code from the protocol compiler.
|
||||
type ExtensionDesc struct {
|
||||
ExtendedType Message // nil pointer to the type that is being extended
|
||||
ExtensionType interface{} // nil pointer to the extension type
|
||||
Field int32 // field number
|
||||
Name string // fully-qualified name of extension, for text formatting
|
||||
Tag string // protobuf tag style
|
||||
Filename string // name of the file in which the extension is defined
|
||||
}
|
||||
|
||||
func (ed *ExtensionDesc) repeated() bool {
|
||||
t := reflect.TypeOf(ed.ExtensionType)
|
||||
return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
|
||||
}
|
||||
|
||||
// Extension represents an extension in a message.
|
||||
type Extension struct {
|
||||
// When an extension is stored in a message using SetExtension
|
||||
// only desc and value are set. When the message is marshaled
|
||||
// enc will be set to the encoded form of the message.
|
||||
//
|
||||
// When a message is unmarshaled and contains extensions, each
|
||||
// extension will have only enc set. When such an extension is
|
||||
// accessed using GetExtension (or GetExtensions) desc and value
|
||||
// will be set.
|
||||
desc *ExtensionDesc
|
||||
value interface{}
|
||||
enc []byte
|
||||
}
|
||||
|
||||
// SetRawExtension is for testing only.
|
||||
func SetRawExtension(base Message, id int32, b []byte) {
|
||||
if ebase, ok := base.(extensionsBytes); ok {
|
||||
clearExtension(base, id)
|
||||
ext := ebase.GetExtensions()
|
||||
*ext = append(*ext, b...)
|
||||
return
|
||||
}
|
||||
epb, err := extendable(base)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
extmap := epb.extensionsWrite()
|
||||
extmap[id] = Extension{enc: b}
|
||||
}
|
||||
|
||||
// isExtensionField returns true iff the given field number is in an extension range.
|
||||
func isExtensionField(pb extendableProto, field int32) bool {
|
||||
for _, er := range pb.ExtensionRangeArray() {
|
||||
if er.Start <= field && field <= er.End {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// checkExtensionTypes checks that the given extension is valid for pb.
|
||||
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
|
||||
var pbi interface{} = pb
|
||||
// Check the extended type.
|
||||
if ea, ok := pbi.(extensionAdapter); ok {
|
||||
pbi = ea.extendableProtoV1
|
||||
}
|
||||
if ea, ok := pbi.(slowExtensionAdapter); ok {
|
||||
pbi = ea.extensionsBytes
|
||||
}
|
||||
if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
|
||||
return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a)
|
||||
}
|
||||
// Check the range.
|
||||
if !isExtensionField(pb, extension.Field) {
|
||||
return errors.New("proto: bad extension number; not in declared ranges")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// extPropKey is sufficient to uniquely identify an extension.
|
||||
type extPropKey struct {
|
||||
base reflect.Type
|
||||
field int32
|
||||
}
|
||||
|
||||
var extProp = struct {
|
||||
sync.RWMutex
|
||||
m map[extPropKey]*Properties
|
||||
}{
|
||||
m: make(map[extPropKey]*Properties),
|
||||
}
|
||||
|
||||
func extensionProperties(ed *ExtensionDesc) *Properties {
|
||||
key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
|
||||
|
||||
extProp.RLock()
|
||||
if prop, ok := extProp.m[key]; ok {
|
||||
extProp.RUnlock()
|
||||
return prop
|
||||
}
|
||||
extProp.RUnlock()
|
||||
|
||||
extProp.Lock()
|
||||
defer extProp.Unlock()
|
||||
// Check again.
|
||||
if prop, ok := extProp.m[key]; ok {
|
||||
return prop
|
||||
}
|
||||
|
||||
prop := new(Properties)
|
||||
prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
|
||||
extProp.m[key] = prop
|
||||
return prop
|
||||
}
|
||||
|
||||
// HasExtension returns whether the given extension is present in pb.
|
||||
func HasExtension(pb Message, extension *ExtensionDesc) bool {
|
||||
if epb, doki := pb.(extensionsBytes); doki {
|
||||
ext := epb.GetExtensions()
|
||||
buf := *ext
|
||||
o := 0
|
||||
for o < len(buf) {
|
||||
tag, n := DecodeVarint(buf[o:])
|
||||
fieldNum := int32(tag >> 3)
|
||||
if int32(fieldNum) == extension.Field {
|
||||
return true
|
||||
}
|
||||
wireType := int(tag & 0x7)
|
||||
o += n
|
||||
l, err := size(buf[o:], wireType)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
o += l
|
||||
}
|
||||
return false
|
||||
}
|
||||
// TODO: Check types, field numbers, etc.?
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
extmap, mu := epb.extensionsRead()
|
||||
if extmap == nil {
|
||||
return false
|
||||
}
|
||||
mu.Lock()
|
||||
_, ok := extmap[extension.Field]
|
||||
mu.Unlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
// ClearExtension removes the given extension from pb.
|
||||
func ClearExtension(pb Message, extension *ExtensionDesc) {
|
||||
clearExtension(pb, extension.Field)
|
||||
}
|
||||
|
||||
func clearExtension(pb Message, fieldNum int32) {
|
||||
if epb, ok := pb.(extensionsBytes); ok {
|
||||
offset := 0
|
||||
for offset != -1 {
|
||||
offset = deleteExtension(epb, fieldNum, offset)
|
||||
}
|
||||
return
|
||||
}
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// TODO: Check types, field numbers, etc.?
|
||||
extmap := epb.extensionsWrite()
|
||||
delete(extmap, fieldNum)
|
||||
}
|
||||
|
||||
// GetExtension retrieves a proto2 extended field from pb.
|
||||
//
|
||||
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
|
||||
// then GetExtension parses the encoded field and returns a Go value of the specified type.
|
||||
// If the field is not present, then the default value is returned (if one is specified),
|
||||
// otherwise ErrMissingExtension is reported.
|
||||
//
|
||||
// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),
|
||||
// then GetExtension returns the raw encoded bytes of the field extension.
|
||||
func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
|
||||
if epb, doki := pb.(extensionsBytes); doki {
|
||||
ext := epb.GetExtensions()
|
||||
return decodeExtensionFromBytes(extension, *ext)
|
||||
}
|
||||
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if extension.ExtendedType != nil {
|
||||
// can only check type if this is a complete descriptor
|
||||
if cerr := checkExtensionTypes(epb, extension); cerr != nil {
|
||||
return nil, cerr
|
||||
}
|
||||
}
|
||||
|
||||
emap, mu := epb.extensionsRead()
|
||||
if emap == nil {
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
e, ok := emap[extension.Field]
|
||||
if !ok {
|
||||
// defaultExtensionValue returns the default value or
|
||||
// ErrMissingExtension if there is no default.
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
|
||||
if e.value != nil {
|
||||
// Already decoded. Check the descriptor, though.
|
||||
if e.desc != extension {
|
||||
// This shouldn't happen. If it does, it means that
|
||||
// GetExtension was called twice with two different
|
||||
// descriptors with the same field number.
|
||||
return nil, errors.New("proto: descriptor conflict")
|
||||
}
|
||||
return e.value, nil
|
||||
}
|
||||
|
||||
if extension.ExtensionType == nil {
|
||||
// incomplete descriptor
|
||||
return e.enc, nil
|
||||
}
|
||||
|
||||
v, err := decodeExtension(e.enc, extension)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Remember the decoded version and drop the encoded version.
|
||||
// That way it is safe to mutate what we return.
|
||||
e.value = v
|
||||
e.desc = extension
|
||||
e.enc = nil
|
||||
emap[extension.Field] = e
|
||||
return e.value, nil
|
||||
}
|
||||
|
||||
// defaultExtensionValue returns the default value for extension.
|
||||
// If no default for an extension is defined ErrMissingExtension is returned.
|
||||
func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
|
||||
if extension.ExtensionType == nil {
|
||||
// incomplete descriptor, so no default
|
||||
return nil, ErrMissingExtension
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(extension.ExtensionType)
|
||||
props := extensionProperties(extension)
|
||||
|
||||
sf, _, err := fieldDefault(t, props)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sf == nil || sf.value == nil {
|
||||
// There is no default value.
|
||||
return nil, ErrMissingExtension
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Ptr {
|
||||
// We do not need to return a Ptr, we can directly return sf.value.
|
||||
return sf.value, nil
|
||||
}
|
||||
|
||||
// We need to return an interface{} that is a pointer to sf.value.
|
||||
value := reflect.New(t).Elem()
|
||||
value.Set(reflect.New(value.Type().Elem()))
|
||||
if sf.kind == reflect.Int32 {
|
||||
// We may have an int32 or an enum, but the underlying data is int32.
|
||||
// Since we can't set an int32 into a non int32 reflect.value directly
|
||||
// set it as a int32.
|
||||
value.Elem().SetInt(int64(sf.value.(int32)))
|
||||
} else {
|
||||
value.Elem().Set(reflect.ValueOf(sf.value))
|
||||
}
|
||||
return value.Interface(), nil
|
||||
}
|
||||
|
||||
// decodeExtension decodes an extension encoded in b.
|
||||
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
|
||||
t := reflect.TypeOf(extension.ExtensionType)
|
||||
unmarshal := typeUnmarshaler(t, extension.Tag)
|
||||
|
||||
// t is a pointer to a struct, pointer to basic type or a slice.
|
||||
// Allocate space to store the pointer/slice.
|
||||
value := reflect.New(t).Elem()
|
||||
|
||||
var err error
|
||||
for {
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
wire := int(x) & 7
|
||||
|
||||
b, err = unmarshal(b, valToPointer(value.Addr()), wire)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(b) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return value.Interface(), nil
|
||||
}
|
||||
|
||||
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
|
||||
// The returned slice has the same length as es; missing extensions will appear as nil elements.
|
||||
func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
extensions = make([]interface{}, len(es))
|
||||
for i, e := range es {
|
||||
extensions[i], err = GetExtension(epb, e)
|
||||
if err == ErrMissingExtension {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
|
||||
// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
|
||||
// just the Field field, which defines the extension's field number.
|
||||
func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
registeredExtensions := RegisteredExtensions(pb)
|
||||
|
||||
emap, mu := epb.extensionsRead()
|
||||
if emap == nil {
|
||||
return nil, nil
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
extensions := make([]*ExtensionDesc, 0, len(emap))
|
||||
for extid, e := range emap {
|
||||
desc := e.desc
|
||||
if desc == nil {
|
||||
desc = registeredExtensions[extid]
|
||||
if desc == nil {
|
||||
desc = &ExtensionDesc{Field: extid}
|
||||
}
|
||||
}
|
||||
|
||||
extensions = append(extensions, desc)
|
||||
}
|
||||
return extensions, nil
|
||||
}
|
||||
|
||||
// SetExtension sets the specified extension of pb to the specified value.
|
||||
func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
|
||||
if epb, ok := pb.(extensionsBytes); ok {
|
||||
ClearExtension(pb, extension)
|
||||
newb, err := encodeExtension(extension, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bb := epb.GetExtensions()
|
||||
*bb = append(*bb, newb...)
|
||||
return nil
|
||||
}
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkExtensionTypes(epb, extension); err != nil {
|
||||
return err
|
||||
}
|
||||
typ := reflect.TypeOf(extension.ExtensionType)
|
||||
if typ != reflect.TypeOf(value) {
|
||||
return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType)
|
||||
}
|
||||
// nil extension values need to be caught early, because the
|
||||
// encoder can't distinguish an ErrNil due to a nil extension
|
||||
// from an ErrNil due to a missing field. Extensions are
|
||||
// always optional, so the encoder would just swallow the error
|
||||
// and drop all the extensions from the encoded message.
|
||||
if reflect.ValueOf(value).IsNil() {
|
||||
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
|
||||
}
|
||||
|
||||
extmap := epb.extensionsWrite()
|
||||
extmap[extension.Field] = Extension{desc: extension, value: value}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearAllExtensions clears all extensions from pb.
|
||||
func ClearAllExtensions(pb Message) {
|
||||
if epb, doki := pb.(extensionsBytes); doki {
|
||||
ext := epb.GetExtensions()
|
||||
*ext = []byte{}
|
||||
return
|
||||
}
|
||||
epb, err := extendable(pb)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
m := epb.extensionsWrite()
|
||||
for k := range m {
|
||||
delete(m, k)
|
||||
}
|
||||
}
|
||||
|
||||
// A global registry of extensions.
|
||||
// The generated code will register the generated descriptors by calling RegisterExtension.
|
||||
|
||||
var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
|
||||
|
||||
// RegisterExtension is called from the generated code.
|
||||
func RegisterExtension(desc *ExtensionDesc) {
|
||||
st := reflect.TypeOf(desc.ExtendedType).Elem()
|
||||
m := extensionMaps[st]
|
||||
if m == nil {
|
||||
m = make(map[int32]*ExtensionDesc)
|
||||
extensionMaps[st] = m
|
||||
}
|
||||
if _, ok := m[desc.Field]; ok {
|
||||
panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
|
||||
}
|
||||
m[desc.Field] = desc
|
||||
}
|
||||
|
||||
// RegisteredExtensions returns a map of the registered extensions of a
|
||||
// protocol buffer struct, indexed by the extension number.
|
||||
// The argument pb should be a nil pointer to the struct type.
|
||||
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
|
||||
return extensionMaps[reflect.TypeOf(pb).Elem()]
|
||||
}
|
389
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
generated
vendored
Normal file
389
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
generated
vendored
Normal file
@ -0,0 +1,389 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type extensionsBytes interface {
|
||||
Message
|
||||
ExtensionRangeArray() []ExtensionRange
|
||||
GetExtensions() *[]byte
|
||||
}
|
||||
|
||||
type slowExtensionAdapter struct {
|
||||
extensionsBytes
|
||||
}
|
||||
|
||||
func (s slowExtensionAdapter) extensionsWrite() map[int32]Extension {
|
||||
panic("Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.")
|
||||
}
|
||||
|
||||
func (s slowExtensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||
b := s.GetExtensions()
|
||||
m, err := BytesToExtensionsMap(*b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m, notLocker{}
|
||||
}
|
||||
|
||||
func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool {
|
||||
if reflect.ValueOf(pb).IsNil() {
|
||||
return ifnotset
|
||||
}
|
||||
value, err := GetExtension(pb, extension)
|
||||
if err != nil {
|
||||
return ifnotset
|
||||
}
|
||||
if value == nil {
|
||||
return ifnotset
|
||||
}
|
||||
if value.(*bool) == nil {
|
||||
return ifnotset
|
||||
}
|
||||
return *(value.(*bool))
|
||||
}
|
||||
|
||||
func (this *Extension) Equal(that *Extension) bool {
|
||||
if err := this.Encode(); err != nil {
|
||||
return false
|
||||
}
|
||||
if err := that.Encode(); err != nil {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(this.enc, that.enc)
|
||||
}
|
||||
|
||||
func (this *Extension) Compare(that *Extension) int {
|
||||
if err := this.Encode(); err != nil {
|
||||
return 1
|
||||
}
|
||||
if err := that.Encode(); err != nil {
|
||||
return -1
|
||||
}
|
||||
return bytes.Compare(this.enc, that.enc)
|
||||
}
|
||||
|
||||
func SizeOfInternalExtension(m extendableProto) (n int) {
|
||||
info := getMarshalInfo(reflect.TypeOf(m))
|
||||
return info.sizeV1Extensions(m.extensionsWrite())
|
||||
}
|
||||
|
||||
type sortableMapElem struct {
|
||||
field int32
|
||||
ext Extension
|
||||
}
|
||||
|
||||
func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions {
|
||||
s := make(sortableExtensions, 0, len(m))
|
||||
for k, v := range m {
|
||||
s = append(s, &sortableMapElem{field: k, ext: v})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type sortableExtensions []*sortableMapElem
|
||||
|
||||
func (this sortableExtensions) Len() int { return len(this) }
|
||||
|
||||
func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] }
|
||||
|
||||
func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field }
|
||||
|
||||
func (this sortableExtensions) String() string {
|
||||
sort.Sort(this)
|
||||
ss := make([]string, len(this))
|
||||
for i := range this {
|
||||
ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext)
|
||||
}
|
||||
return "map[" + strings.Join(ss, ",") + "]"
|
||||
}
|
||||
|
||||
func StringFromInternalExtension(m extendableProto) string {
|
||||
return StringFromExtensionsMap(m.extensionsWrite())
|
||||
}
|
||||
|
||||
func StringFromExtensionsMap(m map[int32]Extension) string {
|
||||
return newSortableExtensionsFromMap(m).String()
|
||||
}
|
||||
|
||||
func StringFromExtensionsBytes(ext []byte) string {
|
||||
m, err := BytesToExtensionsMap(ext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return StringFromExtensionsMap(m)
|
||||
}
|
||||
|
||||
func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) {
|
||||
return EncodeExtensionMap(m.extensionsWrite(), data)
|
||||
}
|
||||
|
||||
func EncodeInternalExtensionBackwards(m extendableProto, data []byte) (n int, err error) {
|
||||
return EncodeExtensionMapBackwards(m.extensionsWrite(), data)
|
||||
}
|
||||
|
||||
func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
|
||||
o := 0
|
||||
for _, e := range m {
|
||||
if err := e.Encode(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n := copy(data[o:], e.enc)
|
||||
if n != len(e.enc) {
|
||||
return 0, io.ErrShortBuffer
|
||||
}
|
||||
o += n
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func EncodeExtensionMapBackwards(m map[int32]Extension, data []byte) (n int, err error) {
|
||||
o := 0
|
||||
end := len(data)
|
||||
for _, e := range m {
|
||||
if err := e.Encode(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n := copy(data[end-len(e.enc):], e.enc)
|
||||
if n != len(e.enc) {
|
||||
return 0, io.ErrShortBuffer
|
||||
}
|
||||
end -= n
|
||||
o += n
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {
|
||||
e := m[id]
|
||||
if err := e.Encode(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e.enc, nil
|
||||
}
|
||||
|
||||
func size(buf []byte, wire int) (int, error) {
|
||||
switch wire {
|
||||
case WireVarint:
|
||||
_, n := DecodeVarint(buf)
|
||||
return n, nil
|
||||
case WireFixed64:
|
||||
return 8, nil
|
||||
case WireBytes:
|
||||
v, n := DecodeVarint(buf)
|
||||
return int(v) + n, nil
|
||||
case WireFixed32:
|
||||
return 4, nil
|
||||
case WireStartGroup:
|
||||
offset := 0
|
||||
for {
|
||||
u, n := DecodeVarint(buf[offset:])
|
||||
fwire := int(u & 0x7)
|
||||
offset += n
|
||||
if fwire == WireEndGroup {
|
||||
return offset, nil
|
||||
}
|
||||
s, err := size(buf[offset:], wire)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
offset += s
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire)
|
||||
}
|
||||
|
||||
func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) {
|
||||
m := make(map[int32]Extension)
|
||||
i := 0
|
||||
for i < len(buf) {
|
||||
tag, n := DecodeVarint(buf[i:])
|
||||
if n <= 0 {
|
||||
return nil, fmt.Errorf("unable to decode varint")
|
||||
}
|
||||
fieldNum := int32(tag >> 3)
|
||||
wireType := int(tag & 0x7)
|
||||
l, err := size(buf[i+n:], wireType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
end := i + int(l) + n
|
||||
m[int32(fieldNum)] = Extension{enc: buf[i:end]}
|
||||
i = end
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func NewExtension(e []byte) Extension {
|
||||
ee := Extension{enc: make([]byte, len(e))}
|
||||
copy(ee.enc, e)
|
||||
return ee
|
||||
}
|
||||
|
||||
func AppendExtension(e Message, tag int32, buf []byte) {
|
||||
if ee, eok := e.(extensionsBytes); eok {
|
||||
ext := ee.GetExtensions()
|
||||
*ext = append(*ext, buf...)
|
||||
return
|
||||
}
|
||||
if ee, eok := e.(extendableProto); eok {
|
||||
m := ee.extensionsWrite()
|
||||
ext := m[int32(tag)] // may be missing
|
||||
ext.enc = append(ext.enc, buf...)
|
||||
m[int32(tag)] = ext
|
||||
}
|
||||
}
|
||||
|
||||
func encodeExtension(extension *ExtensionDesc, value interface{}) ([]byte, error) {
|
||||
u := getMarshalInfo(reflect.TypeOf(extension.ExtendedType))
|
||||
ei := u.getExtElemInfo(extension)
|
||||
v := value
|
||||
p := toAddrPointer(&v, ei.isptr)
|
||||
siz := ei.sizer(p, SizeVarint(ei.wiretag))
|
||||
buf := make([]byte, 0, siz)
|
||||
return ei.marshaler(buf, p, ei.wiretag, false)
|
||||
}
|
||||
|
||||
func decodeExtensionFromBytes(extension *ExtensionDesc, buf []byte) (interface{}, error) {
|
||||
o := 0
|
||||
for o < len(buf) {
|
||||
tag, n := DecodeVarint((buf)[o:])
|
||||
fieldNum := int32(tag >> 3)
|
||||
wireType := int(tag & 0x7)
|
||||
if o+n > len(buf) {
|
||||
return nil, fmt.Errorf("unable to decode extension")
|
||||
}
|
||||
l, err := size((buf)[o+n:], wireType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if int32(fieldNum) == extension.Field {
|
||||
if o+n+l > len(buf) {
|
||||
return nil, fmt.Errorf("unable to decode extension")
|
||||
}
|
||||
v, err := decodeExtension((buf)[o:o+n+l], extension)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
o += n + l
|
||||
}
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
|
||||
func (this *Extension) Encode() error {
|
||||
if this.enc == nil {
|
||||
var err error
|
||||
this.enc, err = encodeExtension(this.desc, this.value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this Extension) GoString() string {
|
||||
if err := this.Encode(); err != nil {
|
||||
return fmt.Sprintf("error encoding extension: %v", err)
|
||||
}
|
||||
return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
|
||||
}
|
||||
|
||||
func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error {
|
||||
typ := reflect.TypeOf(pb).Elem()
|
||||
ext, ok := extensionMaps[typ]
|
||||
if !ok {
|
||||
return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String())
|
||||
}
|
||||
desc, ok := ext[fieldNum]
|
||||
if !ok {
|
||||
return errors.New("proto: bad extension number; not in declared ranges")
|
||||
}
|
||||
return SetExtension(pb, desc, value)
|
||||
}
|
||||
|
||||
func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) {
|
||||
typ := reflect.TypeOf(pb).Elem()
|
||||
ext, ok := extensionMaps[typ]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String())
|
||||
}
|
||||
desc, ok := ext[fieldNum]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unregistered field number %d", fieldNum)
|
||||
}
|
||||
return GetExtension(pb, desc)
|
||||
}
|
||||
|
||||
func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions {
|
||||
x := &XXX_InternalExtensions{
|
||||
p: new(struct {
|
||||
mu sync.Mutex
|
||||
extensionMap map[int32]Extension
|
||||
}),
|
||||
}
|
||||
x.p.extensionMap = m
|
||||
return *x
|
||||
}
|
||||
|
||||
func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension {
|
||||
pb := extendable.(extendableProto)
|
||||
return pb.extensionsWrite()
|
||||
}
|
||||
|
||||
func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
|
||||
ext := pb.GetExtensions()
|
||||
for offset < len(*ext) {
|
||||
tag, n1 := DecodeVarint((*ext)[offset:])
|
||||
fieldNum := int32(tag >> 3)
|
||||
wireType := int(tag & 0x7)
|
||||
n2, err := size((*ext)[offset+n1:], wireType)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
newOffset := offset + n1 + n2
|
||||
if fieldNum == theFieldNum {
|
||||
*ext = append((*ext)[:offset], (*ext)[newOffset:]...)
|
||||
return offset
|
||||
}
|
||||
offset = newOffset
|
||||
}
|
||||
return -1
|
||||
}
|
973
vendor/github.com/gogo/protobuf/proto/lib.go
generated
vendored
Normal file
973
vendor/github.com/gogo/protobuf/proto/lib.go
generated
vendored
Normal file
@ -0,0 +1,973 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/*
|
||||
Package proto converts data structures to and from the wire format of
|
||||
protocol buffers. It works in concert with the Go source code generated
|
||||
for .proto files by the protocol compiler.
|
||||
|
||||
A summary of the properties of the protocol buffer interface
|
||||
for a protocol buffer variable v:
|
||||
|
||||
- Names are turned from camel_case to CamelCase for export.
|
||||
- There are no methods on v to set fields; just treat
|
||||
them as structure fields.
|
||||
- There are getters that return a field's value if set,
|
||||
and return the field's default value if unset.
|
||||
The getters work even if the receiver is a nil message.
|
||||
- The zero value for a struct is its correct initialization state.
|
||||
All desired fields must be set before marshaling.
|
||||
- A Reset() method will restore a protobuf struct to its zero state.
|
||||
- Non-repeated fields are pointers to the values; nil means unset.
|
||||
That is, optional or required field int32 f becomes F *int32.
|
||||
- Repeated fields are slices.
|
||||
- Helper functions are available to aid the setting of fields.
|
||||
msg.Foo = proto.String("hello") // set field
|
||||
- Constants are defined to hold the default values of all fields that
|
||||
have them. They have the form Default_StructName_FieldName.
|
||||
Because the getter methods handle defaulted values,
|
||||
direct use of these constants should be rare.
|
||||
- Enums are given type names and maps from names to values.
|
||||
Enum values are prefixed by the enclosing message's name, or by the
|
||||
enum's type name if it is a top-level enum. Enum types have a String
|
||||
method, and a Enum method to assist in message construction.
|
||||
- Nested messages, groups and enums have type names prefixed with the name of
|
||||
the surrounding message type.
|
||||
- Extensions are given descriptor names that start with E_,
|
||||
followed by an underscore-delimited list of the nested messages
|
||||
that contain it (if any) followed by the CamelCased name of the
|
||||
extension field itself. HasExtension, ClearExtension, GetExtension
|
||||
and SetExtension are functions for manipulating extensions.
|
||||
- Oneof field sets are given a single field in their message,
|
||||
with distinguished wrapper types for each possible field value.
|
||||
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
||||
|
||||
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
||||
|
||||
- Non-repeated fields of non-message type are values instead of pointers.
|
||||
- Enum types do not get an Enum method.
|
||||
|
||||
The simplest way to describe this is to see an example.
|
||||
Given file test.proto, containing
|
||||
|
||||
package example;
|
||||
|
||||
enum FOO { X = 17; }
|
||||
|
||||
message Test {
|
||||
required string label = 1;
|
||||
optional int32 type = 2 [default=77];
|
||||
repeated int64 reps = 3;
|
||||
optional group OptionalGroup = 4 {
|
||||
required string RequiredField = 5;
|
||||
}
|
||||
oneof union {
|
||||
int32 number = 6;
|
||||
string name = 7;
|
||||
}
|
||||
}
|
||||
|
||||
The resulting file, test.pb.go, is:
|
||||
|
||||
package example
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
type FOO int32
|
||||
const (
|
||||
FOO_X FOO = 17
|
||||
)
|
||||
var FOO_name = map[int32]string{
|
||||
17: "X",
|
||||
}
|
||||
var FOO_value = map[string]int32{
|
||||
"X": 17,
|
||||
}
|
||||
|
||||
func (x FOO) Enum() *FOO {
|
||||
p := new(FOO)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x FOO) String() string {
|
||||
return proto.EnumName(FOO_name, int32(x))
|
||||
}
|
||||
func (x *FOO) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(FOO_value, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = FOO(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
|
||||
Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
|
||||
Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
|
||||
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
||||
// Types that are valid to be assigned to Union:
|
||||
// *Test_Number
|
||||
// *Test_Name
|
||||
Union isTest_Union `protobuf_oneof:"union"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
func (m *Test) Reset() { *m = Test{} }
|
||||
func (m *Test) String() string { return proto.CompactTextString(m) }
|
||||
func (*Test) ProtoMessage() {}
|
||||
|
||||
type isTest_Union interface {
|
||||
isTest_Union()
|
||||
}
|
||||
|
||||
type Test_Number struct {
|
||||
Number int32 `protobuf:"varint,6,opt,name=number"`
|
||||
}
|
||||
type Test_Name struct {
|
||||
Name string `protobuf:"bytes,7,opt,name=name"`
|
||||
}
|
||||
|
||||
func (*Test_Number) isTest_Union() {}
|
||||
func (*Test_Name) isTest_Union() {}
|
||||
|
||||
func (m *Test) GetUnion() isTest_Union {
|
||||
if m != nil {
|
||||
return m.Union
|
||||
}
|
||||
return nil
|
||||
}
|
||||
const Default_Test_Type int32 = 77
|
||||
|
||||
func (m *Test) GetLabel() string {
|
||||
if m != nil && m.Label != nil {
|
||||
return *m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Test) GetType() int32 {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Default_Test_Type
|
||||
}
|
||||
|
||||
func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
|
||||
if m != nil {
|
||||
return m.Optionalgroup
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Test_OptionalGroup struct {
|
||||
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
|
||||
}
|
||||
func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
|
||||
func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
|
||||
|
||||
func (m *Test_OptionalGroup) GetRequiredField() string {
|
||||
if m != nil && m.RequiredField != nil {
|
||||
return *m.RequiredField
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Test) GetNumber() int32 {
|
||||
if x, ok := m.GetUnion().(*Test_Number); ok {
|
||||
return x.Number
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Test) GetName() string {
|
||||
if x, ok := m.GetUnion().(*Test_Name); ok {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
|
||||
}
|
||||
|
||||
To create and play with a Test object:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
pb "./example.pb"
|
||||
)
|
||||
|
||||
func main() {
|
||||
test := &pb.Test{
|
||||
Label: proto.String("hello"),
|
||||
Type: proto.Int32(17),
|
||||
Reps: []int64{1, 2, 3},
|
||||
Optionalgroup: &pb.Test_OptionalGroup{
|
||||
RequiredField: proto.String("good bye"),
|
||||
},
|
||||
Union: &pb.Test_Name{"fred"},
|
||||
}
|
||||
data, err := proto.Marshal(test)
|
||||
if err != nil {
|
||||
log.Fatal("marshaling error: ", err)
|
||||
}
|
||||
newTest := &pb.Test{}
|
||||
err = proto.Unmarshal(data, newTest)
|
||||
if err != nil {
|
||||
log.Fatal("unmarshaling error: ", err)
|
||||
}
|
||||
// Now test and newTest contain the same data.
|
||||
if test.GetLabel() != newTest.GetLabel() {
|
||||
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
|
||||
}
|
||||
// Use a type switch to determine which oneof was set.
|
||||
switch u := test.Union.(type) {
|
||||
case *pb.Test_Number: // u.Number contains the number.
|
||||
case *pb.Test_Name: // u.Name contains the string.
|
||||
}
|
||||
// etc.
|
||||
}
|
||||
*/
|
||||
package proto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
|
||||
// Marshal reports this when a required field is not initialized.
|
||||
// Unmarshal reports this when a required field is missing from the wire data.
|
||||
type RequiredNotSetError struct{ field string }
|
||||
|
||||
func (e *RequiredNotSetError) Error() string {
|
||||
if e.field == "" {
|
||||
return fmt.Sprintf("proto: required field not set")
|
||||
}
|
||||
return fmt.Sprintf("proto: required field %q not set", e.field)
|
||||
}
|
||||
func (e *RequiredNotSetError) RequiredNotSet() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type invalidUTF8Error struct{ field string }
|
||||
|
||||
func (e *invalidUTF8Error) Error() string {
|
||||
if e.field == "" {
|
||||
return "proto: invalid UTF-8 detected"
|
||||
}
|
||||
return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
|
||||
}
|
||||
func (e *invalidUTF8Error) InvalidUTF8() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
|
||||
// This error should not be exposed to the external API as such errors should
|
||||
// be recreated with the field information.
|
||||
var errInvalidUTF8 = &invalidUTF8Error{}
|
||||
|
||||
// isNonFatal reports whether the error is either a RequiredNotSet error
|
||||
// or a InvalidUTF8 error.
|
||||
func isNonFatal(err error) bool {
|
||||
if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
|
||||
return true
|
||||
}
|
||||
if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type nonFatal struct{ E error }
|
||||
|
||||
// Merge merges err into nf and reports whether it was successful.
|
||||
// Otherwise it returns false for any fatal non-nil errors.
|
||||
func (nf *nonFatal) Merge(err error) (ok bool) {
|
||||
if err == nil {
|
||||
return true // not an error
|
||||
}
|
||||
if !isNonFatal(err) {
|
||||
return false // fatal error
|
||||
}
|
||||
if nf.E == nil {
|
||||
nf.E = err // store first instance of non-fatal error
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Message is implemented by generated protocol buffer messages.
|
||||
type Message interface {
|
||||
Reset()
|
||||
String() string
|
||||
ProtoMessage()
|
||||
}
|
||||
|
||||
// A Buffer is a buffer manager for marshaling and unmarshaling
|
||||
// protocol buffers. It may be reused between invocations to
|
||||
// reduce memory usage. It is not necessary to use a Buffer;
|
||||
// the global functions Marshal and Unmarshal create a
|
||||
// temporary Buffer and are fine for most applications.
|
||||
type Buffer struct {
|
||||
buf []byte // encode/decode byte stream
|
||||
index int // read point
|
||||
|
||||
deterministic bool
|
||||
}
|
||||
|
||||
// NewBuffer allocates a new Buffer and initializes its internal data to
|
||||
// the contents of the argument slice.
|
||||
func NewBuffer(e []byte) *Buffer {
|
||||
return &Buffer{buf: e}
|
||||
}
|
||||
|
||||
// Reset resets the Buffer, ready for marshaling a new protocol buffer.
|
||||
func (p *Buffer) Reset() {
|
||||
p.buf = p.buf[0:0] // for reading/writing
|
||||
p.index = 0 // for reading
|
||||
}
|
||||
|
||||
// SetBuf replaces the internal buffer with the slice,
|
||||
// ready for unmarshaling the contents of the slice.
|
||||
func (p *Buffer) SetBuf(s []byte) {
|
||||
p.buf = s
|
||||
p.index = 0
|
||||
}
|
||||
|
||||
// Bytes returns the contents of the Buffer.
|
||||
func (p *Buffer) Bytes() []byte { return p.buf }
|
||||
|
||||
// SetDeterministic sets whether to use deterministic serialization.
|
||||
//
|
||||
// Deterministic serialization guarantees that for a given binary, equal
|
||||
// messages will always be serialized to the same bytes. This implies:
|
||||
//
|
||||
// - Repeated serialization of a message will return the same bytes.
|
||||
// - Different processes of the same binary (which may be executing on
|
||||
// different machines) will serialize equal messages to the same bytes.
|
||||
//
|
||||
// Note that the deterministic serialization is NOT canonical across
|
||||
// languages. It is not guaranteed to remain stable over time. It is unstable
|
||||
// across different builds with schema changes due to unknown fields.
|
||||
// Users who need canonical serialization (e.g., persistent storage in a
|
||||
// canonical form, fingerprinting, etc.) should define their own
|
||||
// canonicalization specification and implement their own serializer rather
|
||||
// than relying on this API.
|
||||
//
|
||||
// If deterministic serialization is requested, map entries will be sorted
|
||||
// by keys in lexographical order. This is an implementation detail and
|
||||
// subject to change.
|
||||
func (p *Buffer) SetDeterministic(deterministic bool) {
|
||||
p.deterministic = deterministic
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper routines for simplifying the creation of optional fields of basic type.
|
||||
*/
|
||||
|
||||
// Bool is a helper routine that allocates a new bool value
|
||||
// to store v and returns a pointer to it.
|
||||
func Bool(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int32 is a helper routine that allocates a new int32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Int32(v int32) *int32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int is a helper routine that allocates a new int32 value
|
||||
// to store v and returns a pointer to it, but unlike Int32
|
||||
// its argument value is an int.
|
||||
func Int(v int) *int32 {
|
||||
p := new(int32)
|
||||
*p = int32(v)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int64 is a helper routine that allocates a new int64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Int64(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float32 is a helper routine that allocates a new float32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Float32(v float32) *float32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float64 is a helper routine that allocates a new float64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Float64(v float64) *float64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint32 is a helper routine that allocates a new uint32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Uint32(v uint32) *uint32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint64 is a helper routine that allocates a new uint64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Uint64(v uint64) *uint64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// String is a helper routine that allocates a new string value
|
||||
// to store v and returns a pointer to it.
|
||||
func String(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// EnumName is a helper function to simplify printing protocol buffer enums
|
||||
// by name. Given an enum map and a value, it returns a useful string.
|
||||
func EnumName(m map[int32]string, v int32) string {
|
||||
s, ok := m[v]
|
||||
if ok {
|
||||
return s
|
||||
}
|
||||
return strconv.Itoa(int(v))
|
||||
}
|
||||
|
||||
// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
|
||||
// from their JSON-encoded representation. Given a map from the enum's symbolic
|
||||
// names to its int values, and a byte buffer containing the JSON-encoded
|
||||
// value, it returns an int32 that can be cast to the enum type by the caller.
|
||||
//
|
||||
// The function can deal with both JSON representations, numeric and symbolic.
|
||||
func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
|
||||
if data[0] == '"' {
|
||||
// New style: enums are strings.
|
||||
var repr string
|
||||
if err := json.Unmarshal(data, &repr); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
val, ok := m[repr]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
// Old style: enums are ints.
|
||||
var val int32
|
||||
if err := json.Unmarshal(data, &val); err != nil {
|
||||
return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// DebugPrint dumps the encoded data in b in a debugging format with a header
|
||||
// including the string s. Used in testing but made available for general debugging.
|
||||
func (p *Buffer) DebugPrint(s string, b []byte) {
|
||||
var u uint64
|
||||
|
||||
obuf := p.buf
|
||||
sindex := p.index
|
||||
p.buf = b
|
||||
p.index = 0
|
||||
depth := 0
|
||||
|
||||
fmt.Printf("\n--- %s ---\n", s)
|
||||
|
||||
out:
|
||||
for {
|
||||
for i := 0; i < depth; i++ {
|
||||
fmt.Print(" ")
|
||||
}
|
||||
|
||||
index := p.index
|
||||
if index == len(p.buf) {
|
||||
break
|
||||
}
|
||||
|
||||
op, err := p.DecodeVarint()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: fetching op err %v\n", index, err)
|
||||
break out
|
||||
}
|
||||
tag := op >> 3
|
||||
wire := op & 7
|
||||
|
||||
switch wire {
|
||||
default:
|
||||
fmt.Printf("%3d: t=%3d unknown wire=%d\n",
|
||||
index, tag, wire)
|
||||
break out
|
||||
|
||||
case WireBytes:
|
||||
var r []byte
|
||||
|
||||
r, err = p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
|
||||
if len(r) <= 6 {
|
||||
for i := 0; i < len(r); i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < 3; i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
fmt.Printf(" ..")
|
||||
for i := len(r) - 3; i < len(r); i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
|
||||
case WireFixed32:
|
||||
u, err = p.DecodeFixed32()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
|
||||
|
||||
case WireFixed64:
|
||||
u, err = p.DecodeFixed64()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
|
||||
|
||||
case WireVarint:
|
||||
u, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
|
||||
|
||||
case WireStartGroup:
|
||||
fmt.Printf("%3d: t=%3d start\n", index, tag)
|
||||
depth++
|
||||
|
||||
case WireEndGroup:
|
||||
depth--
|
||||
fmt.Printf("%3d: t=%3d end\n", index, tag)
|
||||
}
|
||||
}
|
||||
|
||||
if depth != 0 {
|
||||
fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
|
||||
p.buf = obuf
|
||||
p.index = sindex
|
||||
}
|
||||
|
||||
// SetDefaults sets unset protocol buffer fields to their default values.
|
||||
// It only modifies fields that are both unset and have defined defaults.
|
||||
// It recursively sets default values in any non-nil sub-messages.
|
||||
func SetDefaults(pb Message) {
|
||||
setDefaults(reflect.ValueOf(pb), true, false)
|
||||
}
|
||||
|
||||
// v is a struct.
|
||||
func setDefaults(v reflect.Value, recur, zeros bool) {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
defaultMu.RLock()
|
||||
dm, ok := defaults[v.Type()]
|
||||
defaultMu.RUnlock()
|
||||
if !ok {
|
||||
dm = buildDefaultMessage(v.Type())
|
||||
defaultMu.Lock()
|
||||
defaults[v.Type()] = dm
|
||||
defaultMu.Unlock()
|
||||
}
|
||||
|
||||
for _, sf := range dm.scalars {
|
||||
f := v.Field(sf.index)
|
||||
if !f.IsNil() {
|
||||
// field already set
|
||||
continue
|
||||
}
|
||||
dv := sf.value
|
||||
if dv == nil && !zeros {
|
||||
// no explicit default, and don't want to set zeros
|
||||
continue
|
||||
}
|
||||
fptr := f.Addr().Interface() // **T
|
||||
// TODO: Consider batching the allocations we do here.
|
||||
switch sf.kind {
|
||||
case reflect.Bool:
|
||||
b := new(bool)
|
||||
if dv != nil {
|
||||
*b = dv.(bool)
|
||||
}
|
||||
*(fptr.(**bool)) = b
|
||||
case reflect.Float32:
|
||||
f := new(float32)
|
||||
if dv != nil {
|
||||
*f = dv.(float32)
|
||||
}
|
||||
*(fptr.(**float32)) = f
|
||||
case reflect.Float64:
|
||||
f := new(float64)
|
||||
if dv != nil {
|
||||
*f = dv.(float64)
|
||||
}
|
||||
*(fptr.(**float64)) = f
|
||||
case reflect.Int32:
|
||||
// might be an enum
|
||||
if ft := f.Type(); ft != int32PtrType {
|
||||
// enum
|
||||
f.Set(reflect.New(ft.Elem()))
|
||||
if dv != nil {
|
||||
f.Elem().SetInt(int64(dv.(int32)))
|
||||
}
|
||||
} else {
|
||||
// int32 field
|
||||
i := new(int32)
|
||||
if dv != nil {
|
||||
*i = dv.(int32)
|
||||
}
|
||||
*(fptr.(**int32)) = i
|
||||
}
|
||||
case reflect.Int64:
|
||||
i := new(int64)
|
||||
if dv != nil {
|
||||
*i = dv.(int64)
|
||||
}
|
||||
*(fptr.(**int64)) = i
|
||||
case reflect.String:
|
||||
s := new(string)
|
||||
if dv != nil {
|
||||
*s = dv.(string)
|
||||
}
|
||||
*(fptr.(**string)) = s
|
||||
case reflect.Uint8:
|
||||
// exceptional case: []byte
|
||||
var b []byte
|
||||
if dv != nil {
|
||||
db := dv.([]byte)
|
||||
b = make([]byte, len(db))
|
||||
copy(b, db)
|
||||
} else {
|
||||
b = []byte{}
|
||||
}
|
||||
*(fptr.(*[]byte)) = b
|
||||
case reflect.Uint32:
|
||||
u := new(uint32)
|
||||
if dv != nil {
|
||||
*u = dv.(uint32)
|
||||
}
|
||||
*(fptr.(**uint32)) = u
|
||||
case reflect.Uint64:
|
||||
u := new(uint64)
|
||||
if dv != nil {
|
||||
*u = dv.(uint64)
|
||||
}
|
||||
*(fptr.(**uint64)) = u
|
||||
default:
|
||||
log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
|
||||
}
|
||||
}
|
||||
|
||||
for _, ni := range dm.nested {
|
||||
f := v.Field(ni)
|
||||
// f is *T or T or []*T or []T
|
||||
switch f.Kind() {
|
||||
case reflect.Struct:
|
||||
setDefaults(f, recur, zeros)
|
||||
|
||||
case reflect.Ptr:
|
||||
if f.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(f, recur, zeros)
|
||||
|
||||
case reflect.Slice:
|
||||
for i := 0; i < f.Len(); i++ {
|
||||
e := f.Index(i)
|
||||
if e.Kind() == reflect.Ptr && e.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(e, recur, zeros)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, k := range f.MapKeys() {
|
||||
e := f.MapIndex(k)
|
||||
if e.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(e, recur, zeros)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// defaults maps a protocol buffer struct type to a slice of the fields,
|
||||
// with its scalar fields set to their proto-declared non-zero default values.
|
||||
defaultMu sync.RWMutex
|
||||
defaults = make(map[reflect.Type]defaultMessage)
|
||||
|
||||
int32PtrType = reflect.TypeOf((*int32)(nil))
|
||||
)
|
||||
|
||||
// defaultMessage represents information about the default values of a message.
|
||||
type defaultMessage struct {
|
||||
scalars []scalarField
|
||||
nested []int // struct field index of nested messages
|
||||
}
|
||||
|
||||
type scalarField struct {
|
||||
index int // struct field index
|
||||
kind reflect.Kind // element type (the T in *T or []T)
|
||||
value interface{} // the proto-declared default value, or nil
|
||||
}
|
||||
|
||||
// t is a struct type.
|
||||
func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||
sprop := GetProperties(t)
|
||||
for _, prop := range sprop.Prop {
|
||||
fi, ok := sprop.decoderTags.get(prop.Tag)
|
||||
if !ok {
|
||||
// XXX_unrecognized
|
||||
continue
|
||||
}
|
||||
ft := t.Field(fi).Type
|
||||
|
||||
sf, nested, err := fieldDefault(ft, prop)
|
||||
switch {
|
||||
case err != nil:
|
||||
log.Print(err)
|
||||
case nested:
|
||||
dm.nested = append(dm.nested, fi)
|
||||
case sf != nil:
|
||||
sf.index = fi
|
||||
dm.scalars = append(dm.scalars, *sf)
|
||||
}
|
||||
}
|
||||
|
||||
return dm
|
||||
}
|
||||
|
||||
// fieldDefault returns the scalarField for field type ft.
|
||||
// sf will be nil if the field can not have a default.
|
||||
// nestedMessage will be true if this is a nested message.
|
||||
// Note that sf.index is not set on return.
|
||||
func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
|
||||
var canHaveDefault bool
|
||||
switch ft.Kind() {
|
||||
case reflect.Struct:
|
||||
nestedMessage = true // non-nullable
|
||||
|
||||
case reflect.Ptr:
|
||||
if ft.Elem().Kind() == reflect.Struct {
|
||||
nestedMessage = true
|
||||
} else {
|
||||
canHaveDefault = true // proto2 scalar field
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
switch ft.Elem().Kind() {
|
||||
case reflect.Ptr, reflect.Struct:
|
||||
nestedMessage = true // repeated message
|
||||
case reflect.Uint8:
|
||||
canHaveDefault = true // bytes field
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
if ft.Elem().Kind() == reflect.Ptr {
|
||||
nestedMessage = true // map with message values
|
||||
}
|
||||
}
|
||||
|
||||
if !canHaveDefault {
|
||||
if nestedMessage {
|
||||
return nil, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// We now know that ft is a pointer or slice.
|
||||
sf = &scalarField{kind: ft.Elem().Kind()}
|
||||
|
||||
// scalar fields without defaults
|
||||
if !prop.HasDefault {
|
||||
return sf, false, nil
|
||||
}
|
||||
|
||||
// a scalar field: either *T or []byte
|
||||
switch ft.Elem().Kind() {
|
||||
case reflect.Bool:
|
||||
x, err := strconv.ParseBool(prop.Default)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.Float32:
|
||||
x, err := strconv.ParseFloat(prop.Default, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = float32(x)
|
||||
case reflect.Float64:
|
||||
x, err := strconv.ParseFloat(prop.Default, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.Int32:
|
||||
x, err := strconv.ParseInt(prop.Default, 10, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = int32(x)
|
||||
case reflect.Int64:
|
||||
x, err := strconv.ParseInt(prop.Default, 10, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.String:
|
||||
sf.value = prop.Default
|
||||
case reflect.Uint8:
|
||||
// []byte (not *uint8)
|
||||
sf.value = []byte(prop.Default)
|
||||
case reflect.Uint32:
|
||||
x, err := strconv.ParseUint(prop.Default, 10, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = uint32(x)
|
||||
case reflect.Uint64:
|
||||
x, err := strconv.ParseUint(prop.Default, 10, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
default:
|
||||
return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
|
||||
}
|
||||
|
||||
return sf, false, nil
|
||||
}
|
||||
|
||||
// mapKeys returns a sort.Interface to be used for sorting the map keys.
|
||||
// Map fields may have key types of non-float scalars, strings and enums.
|
||||
func mapKeys(vs []reflect.Value) sort.Interface {
|
||||
s := mapKeySorter{vs: vs}
|
||||
|
||||
// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
|
||||
if len(vs) == 0 {
|
||||
return s
|
||||
}
|
||||
switch vs[0].Kind() {
|
||||
case reflect.Int32, reflect.Int64:
|
||||
s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
|
||||
case reflect.Bool:
|
||||
s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true
|
||||
case reflect.String:
|
||||
s.less = func(a, b reflect.Value) bool { return a.String() < b.String() }
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind()))
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
type mapKeySorter struct {
|
||||
vs []reflect.Value
|
||||
less func(a, b reflect.Value) bool
|
||||
}
|
||||
|
||||
func (s mapKeySorter) Len() int { return len(s.vs) }
|
||||
func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
|
||||
func (s mapKeySorter) Less(i, j int) bool {
|
||||
return s.less(s.vs[i], s.vs[j])
|
||||
}
|
||||
|
||||
// isProto3Zero reports whether v is a zero proto3 value.
|
||||
func isProto3Zero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.String:
|
||||
return v.String() == ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const (
|
||||
// ProtoPackageIsVersion3 is referenced from generated protocol buffer files
|
||||
// to assert that that code is compatible with this version of the proto package.
|
||||
GoGoProtoPackageIsVersion3 = true
|
||||
|
||||
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
|
||||
// to assert that that code is compatible with this version of the proto package.
|
||||
GoGoProtoPackageIsVersion2 = true
|
||||
|
||||
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
||||
// to assert that that code is compatible with this version of the proto package.
|
||||
GoGoProtoPackageIsVersion1 = true
|
||||
)
|
||||
|
||||
// InternalMessageInfo is a type used internally by generated .pb.go files.
|
||||
// This type is not intended to be used by non-generated code.
|
||||
// This type is not subject to any compatibility guarantee.
|
||||
type InternalMessageInfo struct {
|
||||
marshal *marshalInfo
|
||||
unmarshal *unmarshalInfo
|
||||
merge *mergeInfo
|
||||
discard *discardInfo
|
||||
}
|
50
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
generated
vendored
Normal file
50
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Sizer interface {
|
||||
Size() int
|
||||
}
|
||||
|
||||
type ProtoSizer interface {
|
||||
ProtoSize() int
|
||||
}
|
||||
|
||||
func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) {
|
||||
s, ok := m[value]
|
||||
if !ok {
|
||||
s = strconv.Itoa(int(value))
|
||||
}
|
||||
return json.Marshal(s)
|
||||
}
|
181
vendor/github.com/gogo/protobuf/proto/message_set.go
generated
vendored
Normal file
181
vendor/github.com/gogo/protobuf/proto/message_set.go
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Support for message sets.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
||||
// A message type ID is required for storing a protocol buffer in a message set.
|
||||
var errNoMessageTypeID = errors.New("proto does not have a message type ID")
|
||||
|
||||
// The first two types (_MessageSet_Item and messageSet)
|
||||
// model what the protocol compiler produces for the following protocol message:
|
||||
// message MessageSet {
|
||||
// repeated group Item = 1 {
|
||||
// required int32 type_id = 2;
|
||||
// required string message = 3;
|
||||
// };
|
||||
// }
|
||||
// That is the MessageSet wire format. We can't use a proto to generate these
|
||||
// because that would introduce a circular dependency between it and this package.
|
||||
|
||||
type _MessageSet_Item struct {
|
||||
TypeId *int32 `protobuf:"varint,2,req,name=type_id"`
|
||||
Message []byte `protobuf:"bytes,3,req,name=message"`
|
||||
}
|
||||
|
||||
type messageSet struct {
|
||||
Item []*_MessageSet_Item `protobuf:"group,1,rep"`
|
||||
XXX_unrecognized []byte
|
||||
// TODO: caching?
|
||||
}
|
||||
|
||||
// Make sure messageSet is a Message.
|
||||
var _ Message = (*messageSet)(nil)
|
||||
|
||||
// messageTypeIder is an interface satisfied by a protocol buffer type
|
||||
// that may be stored in a MessageSet.
|
||||
type messageTypeIder interface {
|
||||
MessageTypeId() int32
|
||||
}
|
||||
|
||||
func (ms *messageSet) find(pb Message) *_MessageSet_Item {
|
||||
mti, ok := pb.(messageTypeIder)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
id := mti.MessageTypeId()
|
||||
for _, item := range ms.Item {
|
||||
if *item.TypeId == id {
|
||||
return item
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms *messageSet) Has(pb Message) bool {
|
||||
return ms.find(pb) != nil
|
||||
}
|
||||
|
||||
func (ms *messageSet) Unmarshal(pb Message) error {
|
||||
if item := ms.find(pb); item != nil {
|
||||
return Unmarshal(item.Message, pb)
|
||||
}
|
||||
if _, ok := pb.(messageTypeIder); !ok {
|
||||
return errNoMessageTypeID
|
||||
}
|
||||
return nil // TODO: return error instead?
|
||||
}
|
||||
|
||||
func (ms *messageSet) Marshal(pb Message) error {
|
||||
msg, err := Marshal(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if item := ms.find(pb); item != nil {
|
||||
// reuse existing item
|
||||
item.Message = msg
|
||||
return nil
|
||||
}
|
||||
|
||||
mti, ok := pb.(messageTypeIder)
|
||||
if !ok {
|
||||
return errNoMessageTypeID
|
||||
}
|
||||
|
||||
mtid := mti.MessageTypeId()
|
||||
ms.Item = append(ms.Item, &_MessageSet_Item{
|
||||
TypeId: &mtid,
|
||||
Message: msg,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms *messageSet) Reset() { *ms = messageSet{} }
|
||||
func (ms *messageSet) String() string { return CompactTextString(ms) }
|
||||
func (*messageSet) ProtoMessage() {}
|
||||
|
||||
// Support for the message_set_wire_format message option.
|
||||
|
||||
func skipVarint(buf []byte) []byte {
|
||||
i := 0
|
||||
for ; buf[i]&0x80 != 0; i++ {
|
||||
}
|
||||
return buf[i+1:]
|
||||
}
|
||||
|
||||
// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
||||
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||
func unmarshalMessageSet(buf []byte, exts interface{}) error {
|
||||
var m map[int32]Extension
|
||||
switch exts := exts.(type) {
|
||||
case *XXX_InternalExtensions:
|
||||
m = exts.extensionsWrite()
|
||||
case map[int32]Extension:
|
||||
m = exts
|
||||
default:
|
||||
return errors.New("proto: not an extension map")
|
||||
}
|
||||
|
||||
ms := new(messageSet)
|
||||
if err := Unmarshal(buf, ms); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range ms.Item {
|
||||
id := *item.TypeId
|
||||
msg := item.Message
|
||||
|
||||
// Restore wire type and field number varint, plus length varint.
|
||||
// Be careful to preserve duplicate items.
|
||||
b := EncodeVarint(uint64(id)<<3 | WireBytes)
|
||||
if ext, ok := m[id]; ok {
|
||||
// Existing data; rip off the tag and length varint
|
||||
// so we join the new data correctly.
|
||||
// We can assume that ext.enc is set because we are unmarshaling.
|
||||
o := ext.enc[len(b):] // skip wire type and field number
|
||||
_, n := DecodeVarint(o) // calculate length of length varint
|
||||
o = o[n:] // skip length varint
|
||||
msg = append(o, msg...) // join old data and new data
|
||||
}
|
||||
b = append(b, EncodeVarint(uint64(len(msg)))...)
|
||||
b = append(b, msg...)
|
||||
|
||||
m[id] = Extension{enc: b}
|
||||
}
|
||||
return nil
|
||||
}
|
357
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
generated
vendored
Normal file
357
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
generated
vendored
Normal file
@ -0,0 +1,357 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build purego appengine js
|
||||
|
||||
// This file contains an implementation of proto field accesses using package reflect.
|
||||
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||
// be used on App Engine.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const unsafeAllowed = false
|
||||
|
||||
// A field identifies a field in a struct, accessible from a pointer.
|
||||
// In this implementation, a field is identified by the sequence of field indices
|
||||
// passed to reflect's FieldByIndex.
|
||||
type field []int
|
||||
|
||||
// toField returns a field equivalent to the given reflect field.
|
||||
func toField(f *reflect.StructField) field {
|
||||
return f.Index
|
||||
}
|
||||
|
||||
// invalidField is an invalid field identifier.
|
||||
var invalidField = field(nil)
|
||||
|
||||
// zeroField is a noop when calling pointer.offset.
|
||||
var zeroField = field([]int{})
|
||||
|
||||
// IsValid reports whether the field identifier is valid.
|
||||
func (f field) IsValid() bool { return f != nil }
|
||||
|
||||
// The pointer type is for the table-driven decoder.
|
||||
// The implementation here uses a reflect.Value of pointer type to
|
||||
// create a generic pointer. In pointer_unsafe.go we use unsafe
|
||||
// instead of reflect to implement the same (but faster) interface.
|
||||
type pointer struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
// toPointer converts an interface of pointer type to a pointer
|
||||
// that points to the same target.
|
||||
func toPointer(i *Message) pointer {
|
||||
return pointer{v: reflect.ValueOf(*i)}
|
||||
}
|
||||
|
||||
// toAddrPointer converts an interface to a pointer that points to
|
||||
// the interface data.
|
||||
func toAddrPointer(i *interface{}, isptr bool) pointer {
|
||||
v := reflect.ValueOf(*i)
|
||||
u := reflect.New(v.Type())
|
||||
u.Elem().Set(v)
|
||||
return pointer{v: u}
|
||||
}
|
||||
|
||||
// valToPointer converts v to a pointer. v must be of pointer type.
|
||||
func valToPointer(v reflect.Value) pointer {
|
||||
return pointer{v: v}
|
||||
}
|
||||
|
||||
// offset converts from a pointer to a structure to a pointer to
|
||||
// one of its fields.
|
||||
func (p pointer) offset(f field) pointer {
|
||||
return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
|
||||
}
|
||||
|
||||
func (p pointer) isNil() bool {
|
||||
return p.v.IsNil()
|
||||
}
|
||||
|
||||
// grow updates the slice s in place to make it one element longer.
|
||||
// s must be addressable.
|
||||
// Returns the (addressable) new element.
|
||||
func grow(s reflect.Value) reflect.Value {
|
||||
n, m := s.Len(), s.Cap()
|
||||
if n < m {
|
||||
s.SetLen(n + 1)
|
||||
} else {
|
||||
s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem())))
|
||||
}
|
||||
return s.Index(n)
|
||||
}
|
||||
|
||||
func (p pointer) toInt64() *int64 {
|
||||
return p.v.Interface().(*int64)
|
||||
}
|
||||
func (p pointer) toInt64Ptr() **int64 {
|
||||
return p.v.Interface().(**int64)
|
||||
}
|
||||
func (p pointer) toInt64Slice() *[]int64 {
|
||||
return p.v.Interface().(*[]int64)
|
||||
}
|
||||
|
||||
var int32ptr = reflect.TypeOf((*int32)(nil))
|
||||
|
||||
func (p pointer) toInt32() *int32 {
|
||||
return p.v.Convert(int32ptr).Interface().(*int32)
|
||||
}
|
||||
|
||||
// The toInt32Ptr/Slice methods don't work because of enums.
|
||||
// Instead, we must use set/get methods for the int32ptr/slice case.
|
||||
/*
|
||||
func (p pointer) toInt32Ptr() **int32 {
|
||||
return p.v.Interface().(**int32)
|
||||
}
|
||||
func (p pointer) toInt32Slice() *[]int32 {
|
||||
return p.v.Interface().(*[]int32)
|
||||
}
|
||||
*/
|
||||
func (p pointer) getInt32Ptr() *int32 {
|
||||
if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
|
||||
// raw int32 type
|
||||
return p.v.Elem().Interface().(*int32)
|
||||
}
|
||||
// an enum
|
||||
return p.v.Elem().Convert(int32PtrType).Interface().(*int32)
|
||||
}
|
||||
func (p pointer) setInt32Ptr(v int32) {
|
||||
// Allocate value in a *int32. Possibly convert that to a *enum.
|
||||
// Then assign it to a **int32 or **enum.
|
||||
// Note: we can convert *int32 to *enum, but we can't convert
|
||||
// **int32 to **enum!
|
||||
p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem()))
|
||||
}
|
||||
|
||||
// getInt32Slice copies []int32 from p as a new slice.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) getInt32Slice() []int32 {
|
||||
if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
|
||||
// raw int32 type
|
||||
return p.v.Elem().Interface().([]int32)
|
||||
}
|
||||
// an enum
|
||||
// Allocate a []int32, then assign []enum's values into it.
|
||||
// Note: we can't convert []enum to []int32.
|
||||
slice := p.v.Elem()
|
||||
s := make([]int32, slice.Len())
|
||||
for i := 0; i < slice.Len(); i++ {
|
||||
s[i] = int32(slice.Index(i).Int())
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// setInt32Slice copies []int32 into p as a new slice.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) setInt32Slice(v []int32) {
|
||||
if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
|
||||
// raw int32 type
|
||||
p.v.Elem().Set(reflect.ValueOf(v))
|
||||
return
|
||||
}
|
||||
// an enum
|
||||
// Allocate a []enum, then assign []int32's values into it.
|
||||
// Note: we can't convert []enum to []int32.
|
||||
slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v))
|
||||
for i, x := range v {
|
||||
slice.Index(i).SetInt(int64(x))
|
||||
}
|
||||
p.v.Elem().Set(slice)
|
||||
}
|
||||
func (p pointer) appendInt32Slice(v int32) {
|
||||
grow(p.v.Elem()).SetInt(int64(v))
|
||||
}
|
||||
|
||||
func (p pointer) toUint64() *uint64 {
|
||||
return p.v.Interface().(*uint64)
|
||||
}
|
||||
func (p pointer) toUint64Ptr() **uint64 {
|
||||
return p.v.Interface().(**uint64)
|
||||
}
|
||||
func (p pointer) toUint64Slice() *[]uint64 {
|
||||
return p.v.Interface().(*[]uint64)
|
||||
}
|
||||
func (p pointer) toUint32() *uint32 {
|
||||
return p.v.Interface().(*uint32)
|
||||
}
|
||||
func (p pointer) toUint32Ptr() **uint32 {
|
||||
return p.v.Interface().(**uint32)
|
||||
}
|
||||
func (p pointer) toUint32Slice() *[]uint32 {
|
||||
return p.v.Interface().(*[]uint32)
|
||||
}
|
||||
func (p pointer) toBool() *bool {
|
||||
return p.v.Interface().(*bool)
|
||||
}
|
||||
func (p pointer) toBoolPtr() **bool {
|
||||
return p.v.Interface().(**bool)
|
||||
}
|
||||
func (p pointer) toBoolSlice() *[]bool {
|
||||
return p.v.Interface().(*[]bool)
|
||||
}
|
||||
func (p pointer) toFloat64() *float64 {
|
||||
return p.v.Interface().(*float64)
|
||||
}
|
||||
func (p pointer) toFloat64Ptr() **float64 {
|
||||
return p.v.Interface().(**float64)
|
||||
}
|
||||
func (p pointer) toFloat64Slice() *[]float64 {
|
||||
return p.v.Interface().(*[]float64)
|
||||
}
|
||||
func (p pointer) toFloat32() *float32 {
|
||||
return p.v.Interface().(*float32)
|
||||
}
|
||||
func (p pointer) toFloat32Ptr() **float32 {
|
||||
return p.v.Interface().(**float32)
|
||||
}
|
||||
func (p pointer) toFloat32Slice() *[]float32 {
|
||||
return p.v.Interface().(*[]float32)
|
||||
}
|
||||
func (p pointer) toString() *string {
|
||||
return p.v.Interface().(*string)
|
||||
}
|
||||
func (p pointer) toStringPtr() **string {
|
||||
return p.v.Interface().(**string)
|
||||
}
|
||||
func (p pointer) toStringSlice() *[]string {
|
||||
return p.v.Interface().(*[]string)
|
||||
}
|
||||
func (p pointer) toBytes() *[]byte {
|
||||
return p.v.Interface().(*[]byte)
|
||||
}
|
||||
func (p pointer) toBytesSlice() *[][]byte {
|
||||
return p.v.Interface().(*[][]byte)
|
||||
}
|
||||
func (p pointer) toExtensions() *XXX_InternalExtensions {
|
||||
return p.v.Interface().(*XXX_InternalExtensions)
|
||||
}
|
||||
func (p pointer) toOldExtensions() *map[int32]Extension {
|
||||
return p.v.Interface().(*map[int32]Extension)
|
||||
}
|
||||
func (p pointer) getPointer() pointer {
|
||||
return pointer{v: p.v.Elem()}
|
||||
}
|
||||
func (p pointer) setPointer(q pointer) {
|
||||
p.v.Elem().Set(q.v)
|
||||
}
|
||||
func (p pointer) appendPointer(q pointer) {
|
||||
grow(p.v.Elem()).Set(q.v)
|
||||
}
|
||||
|
||||
// getPointerSlice copies []*T from p as a new []pointer.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) getPointerSlice() []pointer {
|
||||
if p.v.IsNil() {
|
||||
return nil
|
||||
}
|
||||
n := p.v.Elem().Len()
|
||||
s := make([]pointer, n)
|
||||
for i := 0; i < n; i++ {
|
||||
s[i] = pointer{v: p.v.Elem().Index(i)}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// setPointerSlice copies []pointer into p as a new []*T.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) setPointerSlice(v []pointer) {
|
||||
if v == nil {
|
||||
p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem())
|
||||
return
|
||||
}
|
||||
s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v))
|
||||
for _, p := range v {
|
||||
s = reflect.Append(s, p.v)
|
||||
}
|
||||
p.v.Elem().Set(s)
|
||||
}
|
||||
|
||||
// getInterfacePointer returns a pointer that points to the
|
||||
// interface data of the interface pointed by p.
|
||||
func (p pointer) getInterfacePointer() pointer {
|
||||
if p.v.Elem().IsNil() {
|
||||
return pointer{v: p.v.Elem()}
|
||||
}
|
||||
return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct
|
||||
}
|
||||
|
||||
func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
|
||||
// TODO: check that p.v.Type().Elem() == t?
|
||||
return p.v
|
||||
}
|
||||
|
||||
func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
return *p
|
||||
}
|
||||
func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
*p = v
|
||||
}
|
||||
func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
return *p
|
||||
}
|
||||
func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
*p = v
|
||||
}
|
||||
func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
return *p
|
||||
}
|
||||
func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
*p = v
|
||||
}
|
||||
func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
return *p
|
||||
}
|
||||
func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
|
||||
atomicLock.Lock()
|
||||
defer atomicLock.Unlock()
|
||||
*p = v
|
||||
}
|
||||
|
||||
var atomicLock sync.Mutex
|
59
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
generated
vendored
Normal file
59
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build purego appengine js
|
||||
|
||||
// This file contains an implementation of proto field accesses using package reflect.
|
||||
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||
// be used on App Engine.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// TODO: untested, so probably incorrect.
|
||||
|
||||
func (p pointer) getRef() pointer {
|
||||
return pointer{v: p.v.Addr()}
|
||||
}
|
||||
|
||||
func (p pointer) appendRef(v pointer, typ reflect.Type) {
|
||||
slice := p.getSlice(typ)
|
||||
elem := v.asPointerTo(typ).Elem()
|
||||
newSlice := reflect.Append(slice, elem)
|
||||
slice.Set(newSlice)
|
||||
}
|
||||
|
||||
func (p pointer) getSlice(typ reflect.Type) reflect.Value {
|
||||
sliceTyp := reflect.SliceOf(typ)
|
||||
slice := p.asPointerTo(sliceTyp)
|
||||
slice = slice.Elem()
|
||||
return slice
|
||||
}
|
308
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
generated
vendored
Normal file
308
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
generated
vendored
Normal file
@ -0,0 +1,308 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build !purego,!appengine,!js
|
||||
|
||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const unsafeAllowed = true
|
||||
|
||||
// A field identifies a field in a struct, accessible from a pointer.
|
||||
// In this implementation, a field is identified by its byte offset from the start of the struct.
|
||||
type field uintptr
|
||||
|
||||
// toField returns a field equivalent to the given reflect field.
|
||||
func toField(f *reflect.StructField) field {
|
||||
return field(f.Offset)
|
||||
}
|
||||
|
||||
// invalidField is an invalid field identifier.
|
||||
const invalidField = ^field(0)
|
||||
|
||||
// zeroField is a noop when calling pointer.offset.
|
||||
const zeroField = field(0)
|
||||
|
||||
// IsValid reports whether the field identifier is valid.
|
||||
func (f field) IsValid() bool {
|
||||
return f != invalidField
|
||||
}
|
||||
|
||||
// The pointer type below is for the new table-driven encoder/decoder.
|
||||
// The implementation here uses unsafe.Pointer to create a generic pointer.
|
||||
// In pointer_reflect.go we use reflect instead of unsafe to implement
|
||||
// the same (but slower) interface.
|
||||
type pointer struct {
|
||||
p unsafe.Pointer
|
||||
}
|
||||
|
||||
// size of pointer
|
||||
var ptrSize = unsafe.Sizeof(uintptr(0))
|
||||
|
||||
// toPointer converts an interface of pointer type to a pointer
|
||||
// that points to the same target.
|
||||
func toPointer(i *Message) pointer {
|
||||
// Super-tricky - read pointer out of data word of interface value.
|
||||
// Saves ~25ns over the equivalent:
|
||||
// return valToPointer(reflect.ValueOf(*i))
|
||||
return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
|
||||
}
|
||||
|
||||
// toAddrPointer converts an interface to a pointer that points to
|
||||
// the interface data.
|
||||
func toAddrPointer(i *interface{}, isptr bool) pointer {
|
||||
// Super-tricky - read or get the address of data word of interface value.
|
||||
if isptr {
|
||||
// The interface is of pointer type, thus it is a direct interface.
|
||||
// The data word is the pointer data itself. We take its address.
|
||||
return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
|
||||
}
|
||||
// The interface is not of pointer type. The data word is the pointer
|
||||
// to the data.
|
||||
return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
|
||||
}
|
||||
|
||||
// valToPointer converts v to a pointer. v must be of pointer type.
|
||||
func valToPointer(v reflect.Value) pointer {
|
||||
return pointer{p: unsafe.Pointer(v.Pointer())}
|
||||
}
|
||||
|
||||
// offset converts from a pointer to a structure to a pointer to
|
||||
// one of its fields.
|
||||
func (p pointer) offset(f field) pointer {
|
||||
// For safety, we should panic if !f.IsValid, however calling panic causes
|
||||
// this to no longer be inlineable, which is a serious performance cost.
|
||||
/*
|
||||
if !f.IsValid() {
|
||||
panic("invalid field")
|
||||
}
|
||||
*/
|
||||
return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
|
||||
}
|
||||
|
||||
func (p pointer) isNil() bool {
|
||||
return p.p == nil
|
||||
}
|
||||
|
||||
func (p pointer) toInt64() *int64 {
|
||||
return (*int64)(p.p)
|
||||
}
|
||||
func (p pointer) toInt64Ptr() **int64 {
|
||||
return (**int64)(p.p)
|
||||
}
|
||||
func (p pointer) toInt64Slice() *[]int64 {
|
||||
return (*[]int64)(p.p)
|
||||
}
|
||||
func (p pointer) toInt32() *int32 {
|
||||
return (*int32)(p.p)
|
||||
}
|
||||
|
||||
// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.
|
||||
/*
|
||||
func (p pointer) toInt32Ptr() **int32 {
|
||||
return (**int32)(p.p)
|
||||
}
|
||||
func (p pointer) toInt32Slice() *[]int32 {
|
||||
return (*[]int32)(p.p)
|
||||
}
|
||||
*/
|
||||
func (p pointer) getInt32Ptr() *int32 {
|
||||
return *(**int32)(p.p)
|
||||
}
|
||||
func (p pointer) setInt32Ptr(v int32) {
|
||||
*(**int32)(p.p) = &v
|
||||
}
|
||||
|
||||
// getInt32Slice loads a []int32 from p.
|
||||
// The value returned is aliased with the original slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) getInt32Slice() []int32 {
|
||||
return *(*[]int32)(p.p)
|
||||
}
|
||||
|
||||
// setInt32Slice stores a []int32 to p.
|
||||
// The value set is aliased with the input slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) setInt32Slice(v []int32) {
|
||||
*(*[]int32)(p.p) = v
|
||||
}
|
||||
|
||||
// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?
|
||||
func (p pointer) appendInt32Slice(v int32) {
|
||||
s := (*[]int32)(p.p)
|
||||
*s = append(*s, v)
|
||||
}
|
||||
|
||||
func (p pointer) toUint64() *uint64 {
|
||||
return (*uint64)(p.p)
|
||||
}
|
||||
func (p pointer) toUint64Ptr() **uint64 {
|
||||
return (**uint64)(p.p)
|
||||
}
|
||||
func (p pointer) toUint64Slice() *[]uint64 {
|
||||
return (*[]uint64)(p.p)
|
||||
}
|
||||
func (p pointer) toUint32() *uint32 {
|
||||
return (*uint32)(p.p)
|
||||
}
|
||||
func (p pointer) toUint32Ptr() **uint32 {
|
||||
return (**uint32)(p.p)
|
||||
}
|
||||
func (p pointer) toUint32Slice() *[]uint32 {
|
||||
return (*[]uint32)(p.p)
|
||||
}
|
||||
func (p pointer) toBool() *bool {
|
||||
return (*bool)(p.p)
|
||||
}
|
||||
func (p pointer) toBoolPtr() **bool {
|
||||
return (**bool)(p.p)
|
||||
}
|
||||
func (p pointer) toBoolSlice() *[]bool {
|
||||
return (*[]bool)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat64() *float64 {
|
||||
return (*float64)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat64Ptr() **float64 {
|
||||
return (**float64)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat64Slice() *[]float64 {
|
||||
return (*[]float64)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat32() *float32 {
|
||||
return (*float32)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat32Ptr() **float32 {
|
||||
return (**float32)(p.p)
|
||||
}
|
||||
func (p pointer) toFloat32Slice() *[]float32 {
|
||||
return (*[]float32)(p.p)
|
||||
}
|
||||
func (p pointer) toString() *string {
|
||||
return (*string)(p.p)
|
||||
}
|
||||
func (p pointer) toStringPtr() **string {
|
||||
return (**string)(p.p)
|
||||
}
|
||||
func (p pointer) toStringSlice() *[]string {
|
||||
return (*[]string)(p.p)
|
||||
}
|
||||
func (p pointer) toBytes() *[]byte {
|
||||
return (*[]byte)(p.p)
|
||||
}
|
||||
func (p pointer) toBytesSlice() *[][]byte {
|
||||
return (*[][]byte)(p.p)
|
||||
}
|
||||
func (p pointer) toExtensions() *XXX_InternalExtensions {
|
||||
return (*XXX_InternalExtensions)(p.p)
|
||||
}
|
||||
func (p pointer) toOldExtensions() *map[int32]Extension {
|
||||
return (*map[int32]Extension)(p.p)
|
||||
}
|
||||
|
||||
// getPointerSlice loads []*T from p as a []pointer.
|
||||
// The value returned is aliased with the original slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) getPointerSlice() []pointer {
|
||||
// Super-tricky - p should point to a []*T where T is a
|
||||
// message type. We load it as []pointer.
|
||||
return *(*[]pointer)(p.p)
|
||||
}
|
||||
|
||||
// setPointerSlice stores []pointer into p as a []*T.
|
||||
// The value set is aliased with the input slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) setPointerSlice(v []pointer) {
|
||||
// Super-tricky - p should point to a []*T where T is a
|
||||
// message type. We store it as []pointer.
|
||||
*(*[]pointer)(p.p) = v
|
||||
}
|
||||
|
||||
// getPointer loads the pointer at p and returns it.
|
||||
func (p pointer) getPointer() pointer {
|
||||
return pointer{p: *(*unsafe.Pointer)(p.p)}
|
||||
}
|
||||
|
||||
// setPointer stores the pointer q at p.
|
||||
func (p pointer) setPointer(q pointer) {
|
||||
*(*unsafe.Pointer)(p.p) = q.p
|
||||
}
|
||||
|
||||
// append q to the slice pointed to by p.
|
||||
func (p pointer) appendPointer(q pointer) {
|
||||
s := (*[]unsafe.Pointer)(p.p)
|
||||
*s = append(*s, q.p)
|
||||
}
|
||||
|
||||
// getInterfacePointer returns a pointer that points to the
|
||||
// interface data of the interface pointed by p.
|
||||
func (p pointer) getInterfacePointer() pointer {
|
||||
// Super-tricky - read pointer out of data word of interface value.
|
||||
return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]}
|
||||
}
|
||||
|
||||
// asPointerTo returns a reflect.Value that is a pointer to an
|
||||
// object of type t stored at p.
|
||||
func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
|
||||
return reflect.NewAt(t, p.p)
|
||||
}
|
||||
|
||||
func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
|
||||
return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||
}
|
||||
func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
|
||||
}
|
||||
func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
|
||||
return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||
}
|
||||
func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
|
||||
}
|
||||
func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
|
||||
return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||
}
|
||||
func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
|
||||
}
|
||||
func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
|
||||
return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
|
||||
}
|
||||
func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
|
||||
}
|
56
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
generated
vendored
Normal file
56
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build !purego,!appengine,!js
|
||||
|
||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (p pointer) getRef() pointer {
|
||||
return pointer{p: (unsafe.Pointer)(&p.p)}
|
||||
}
|
||||
|
||||
func (p pointer) appendRef(v pointer, typ reflect.Type) {
|
||||
slice := p.getSlice(typ)
|
||||
elem := v.asPointerTo(typ).Elem()
|
||||
newSlice := reflect.Append(slice, elem)
|
||||
slice.Set(newSlice)
|
||||
}
|
||||
|
||||
func (p pointer) getSlice(typ reflect.Type) reflect.Value {
|
||||
sliceTyp := reflect.SliceOf(typ)
|
||||
slice := p.asPointerTo(sliceTyp)
|
||||
slice = slice.Elem()
|
||||
return slice
|
||||
}
|
610
vendor/github.com/gogo/protobuf/proto/properties.go
generated
vendored
Normal file
610
vendor/github.com/gogo/protobuf/proto/properties.go
generated
vendored
Normal file
@ -0,0 +1,610 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Routines for encoding data into the wire format for protocol buffers.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const debug bool = false
|
||||
|
||||
// Constants that identify the encoding of a value on the wire.
|
||||
const (
|
||||
WireVarint = 0
|
||||
WireFixed64 = 1
|
||||
WireBytes = 2
|
||||
WireStartGroup = 3
|
||||
WireEndGroup = 4
|
||||
WireFixed32 = 5
|
||||
)
|
||||
|
||||
// tagMap is an optimization over map[int]int for typical protocol buffer
|
||||
// use-cases. Encoded protocol buffers are often in tag order with small tag
|
||||
// numbers.
|
||||
type tagMap struct {
|
||||
fastTags []int
|
||||
slowTags map[int]int
|
||||
}
|
||||
|
||||
// tagMapFastLimit is the upper bound on the tag number that will be stored in
|
||||
// the tagMap slice rather than its map.
|
||||
const tagMapFastLimit = 1024
|
||||
|
||||
func (p *tagMap) get(t int) (int, bool) {
|
||||
if t > 0 && t < tagMapFastLimit {
|
||||
if t >= len(p.fastTags) {
|
||||
return 0, false
|
||||
}
|
||||
fi := p.fastTags[t]
|
||||
return fi, fi >= 0
|
||||
}
|
||||
fi, ok := p.slowTags[t]
|
||||
return fi, ok
|
||||
}
|
||||
|
||||
func (p *tagMap) put(t int, fi int) {
|
||||
if t > 0 && t < tagMapFastLimit {
|
||||
for len(p.fastTags) < t+1 {
|
||||
p.fastTags = append(p.fastTags, -1)
|
||||
}
|
||||
p.fastTags[t] = fi
|
||||
return
|
||||
}
|
||||
if p.slowTags == nil {
|
||||
p.slowTags = make(map[int]int)
|
||||
}
|
||||
p.slowTags[t] = fi
|
||||
}
|
||||
|
||||
// StructProperties represents properties for all the fields of a struct.
|
||||
// decoderTags and decoderOrigNames should only be used by the decoder.
|
||||
type StructProperties struct {
|
||||
Prop []*Properties // properties for each field
|
||||
reqCount int // required count
|
||||
decoderTags tagMap // map from proto tag to struct field number
|
||||
decoderOrigNames map[string]int // map from original name to struct field number
|
||||
order []int // list of struct field numbers in tag order
|
||||
|
||||
// OneofTypes contains information about the oneof fields in this message.
|
||||
// It is keyed by the original name of a field.
|
||||
OneofTypes map[string]*OneofProperties
|
||||
}
|
||||
|
||||
// OneofProperties represents information about a specific field in a oneof.
|
||||
type OneofProperties struct {
|
||||
Type reflect.Type // pointer to generated struct type for this oneof field
|
||||
Field int // struct field number of the containing oneof in the message
|
||||
Prop *Properties
|
||||
}
|
||||
|
||||
// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
|
||||
// See encode.go, (*Buffer).enc_struct.
|
||||
|
||||
func (sp *StructProperties) Len() int { return len(sp.order) }
|
||||
func (sp *StructProperties) Less(i, j int) bool {
|
||||
return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
|
||||
}
|
||||
func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
|
||||
|
||||
// Properties represents the protocol-specific behavior of a single struct field.
|
||||
type Properties struct {
|
||||
Name string // name of the field, for error messages
|
||||
OrigName string // original name before protocol compiler (always set)
|
||||
JSONName string // name to use for JSON; determined by protoc
|
||||
Wire string
|
||||
WireType int
|
||||
Tag int
|
||||
Required bool
|
||||
Optional bool
|
||||
Repeated bool
|
||||
Packed bool // relevant for repeated primitives only
|
||||
Enum string // set for enum types only
|
||||
proto3 bool // whether this is known to be a proto3 field
|
||||
oneof bool // whether this is a oneof field
|
||||
|
||||
Default string // default value
|
||||
HasDefault bool // whether an explicit default was provided
|
||||
CustomType string
|
||||
CastType string
|
||||
StdTime bool
|
||||
StdDuration bool
|
||||
WktPointer bool
|
||||
|
||||
stype reflect.Type // set for struct types only
|
||||
ctype reflect.Type // set for custom types only
|
||||
sprop *StructProperties // set for struct types only
|
||||
|
||||
mtype reflect.Type // set for map types only
|
||||
MapKeyProp *Properties // set for map types only
|
||||
MapValProp *Properties // set for map types only
|
||||
}
|
||||
|
||||
// String formats the properties in the protobuf struct field tag style.
|
||||
func (p *Properties) String() string {
|
||||
s := p.Wire
|
||||
s += ","
|
||||
s += strconv.Itoa(p.Tag)
|
||||
if p.Required {
|
||||
s += ",req"
|
||||
}
|
||||
if p.Optional {
|
||||
s += ",opt"
|
||||
}
|
||||
if p.Repeated {
|
||||
s += ",rep"
|
||||
}
|
||||
if p.Packed {
|
||||
s += ",packed"
|
||||
}
|
||||
s += ",name=" + p.OrigName
|
||||
if p.JSONName != p.OrigName {
|
||||
s += ",json=" + p.JSONName
|
||||
}
|
||||
if p.proto3 {
|
||||
s += ",proto3"
|
||||
}
|
||||
if p.oneof {
|
||||
s += ",oneof"
|
||||
}
|
||||
if len(p.Enum) > 0 {
|
||||
s += ",enum=" + p.Enum
|
||||
}
|
||||
if p.HasDefault {
|
||||
s += ",def=" + p.Default
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Parse populates p by parsing a string in the protobuf struct field tag style.
|
||||
func (p *Properties) Parse(s string) {
|
||||
// "bytes,49,opt,name=foo,def=hello!"
|
||||
fields := strings.Split(s, ",") // breaks def=, but handled below.
|
||||
if len(fields) < 2 {
|
||||
log.Printf("proto: tag has too few fields: %q", s)
|
||||
return
|
||||
}
|
||||
|
||||
p.Wire = fields[0]
|
||||
switch p.Wire {
|
||||
case "varint":
|
||||
p.WireType = WireVarint
|
||||
case "fixed32":
|
||||
p.WireType = WireFixed32
|
||||
case "fixed64":
|
||||
p.WireType = WireFixed64
|
||||
case "zigzag32":
|
||||
p.WireType = WireVarint
|
||||
case "zigzag64":
|
||||
p.WireType = WireVarint
|
||||
case "bytes", "group":
|
||||
p.WireType = WireBytes
|
||||
// no numeric converter for non-numeric types
|
||||
default:
|
||||
log.Printf("proto: tag has unknown wire type: %q", s)
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
p.Tag, err = strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
outer:
|
||||
for i := 2; i < len(fields); i++ {
|
||||
f := fields[i]
|
||||
switch {
|
||||
case f == "req":
|
||||
p.Required = true
|
||||
case f == "opt":
|
||||
p.Optional = true
|
||||
case f == "rep":
|
||||
p.Repeated = true
|
||||
case f == "packed":
|
||||
p.Packed = true
|
||||
case strings.HasPrefix(f, "name="):
|
||||
p.OrigName = f[5:]
|
||||
case strings.HasPrefix(f, "json="):
|
||||
p.JSONName = f[5:]
|
||||
case strings.HasPrefix(f, "enum="):
|
||||
p.Enum = f[5:]
|
||||
case f == "proto3":
|
||||
p.proto3 = true
|
||||
case f == "oneof":
|
||||
p.oneof = true
|
||||
case strings.HasPrefix(f, "def="):
|
||||
p.HasDefault = true
|
||||
p.Default = f[4:] // rest of string
|
||||
if i+1 < len(fields) {
|
||||
// Commas aren't escaped, and def is always last.
|
||||
p.Default += "," + strings.Join(fields[i+1:], ",")
|
||||
break outer
|
||||
}
|
||||
case strings.HasPrefix(f, "embedded="):
|
||||
p.OrigName = strings.Split(f, "=")[1]
|
||||
case strings.HasPrefix(f, "customtype="):
|
||||
p.CustomType = strings.Split(f, "=")[1]
|
||||
case strings.HasPrefix(f, "casttype="):
|
||||
p.CastType = strings.Split(f, "=")[1]
|
||||
case f == "stdtime":
|
||||
p.StdTime = true
|
||||
case f == "stdduration":
|
||||
p.StdDuration = true
|
||||
case f == "wktptr":
|
||||
p.WktPointer = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
||||
|
||||
// setFieldProps initializes the field properties for submessages and maps.
|
||||
func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
|
||||
isMap := typ.Kind() == reflect.Map
|
||||
if len(p.CustomType) > 0 && !isMap {
|
||||
p.ctype = typ
|
||||
p.setTag(lockGetProp)
|
||||
return
|
||||
}
|
||||
if p.StdTime && !isMap {
|
||||
p.setTag(lockGetProp)
|
||||
return
|
||||
}
|
||||
if p.StdDuration && !isMap {
|
||||
p.setTag(lockGetProp)
|
||||
return
|
||||
}
|
||||
if p.WktPointer && !isMap {
|
||||
p.setTag(lockGetProp)
|
||||
return
|
||||
}
|
||||
switch t1 := typ; t1.Kind() {
|
||||
case reflect.Struct:
|
||||
p.stype = typ
|
||||
case reflect.Ptr:
|
||||
if t1.Elem().Kind() == reflect.Struct {
|
||||
p.stype = t1.Elem()
|
||||
}
|
||||
case reflect.Slice:
|
||||
switch t2 := t1.Elem(); t2.Kind() {
|
||||
case reflect.Ptr:
|
||||
switch t3 := t2.Elem(); t3.Kind() {
|
||||
case reflect.Struct:
|
||||
p.stype = t3
|
||||
}
|
||||
case reflect.Struct:
|
||||
p.stype = t2
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
|
||||
p.mtype = t1
|
||||
p.MapKeyProp = &Properties{}
|
||||
p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
|
||||
p.MapValProp = &Properties{}
|
||||
vtype := p.mtype.Elem()
|
||||
if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
|
||||
// The value type is not a message (*T) or bytes ([]byte),
|
||||
// so we need encoders for the pointer to this type.
|
||||
vtype = reflect.PtrTo(vtype)
|
||||
}
|
||||
|
||||
p.MapValProp.CustomType = p.CustomType
|
||||
p.MapValProp.StdDuration = p.StdDuration
|
||||
p.MapValProp.StdTime = p.StdTime
|
||||
p.MapValProp.WktPointer = p.WktPointer
|
||||
p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||
}
|
||||
p.setTag(lockGetProp)
|
||||
}
|
||||
|
||||
func (p *Properties) setTag(lockGetProp bool) {
|
||||
if p.stype != nil {
|
||||
if lockGetProp {
|
||||
p.sprop = GetProperties(p.stype)
|
||||
} else {
|
||||
p.sprop = getPropertiesLocked(p.stype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
|
||||
)
|
||||
|
||||
// Init populates the properties from a protocol buffer struct tag.
|
||||
func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
|
||||
p.init(typ, name, tag, f, true)
|
||||
}
|
||||
|
||||
func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
|
||||
// "bytes,49,opt,def=hello!"
|
||||
p.Name = name
|
||||
p.OrigName = name
|
||||
if tag == "" {
|
||||
return
|
||||
}
|
||||
p.Parse(tag)
|
||||
p.setFieldProps(typ, f, lockGetProp)
|
||||
}
|
||||
|
||||
var (
|
||||
propertiesMu sync.RWMutex
|
||||
propertiesMap = make(map[reflect.Type]*StructProperties)
|
||||
)
|
||||
|
||||
// GetProperties returns the list of properties for the type represented by t.
|
||||
// t must represent a generated struct type of a protocol message.
|
||||
func GetProperties(t reflect.Type) *StructProperties {
|
||||
if t.Kind() != reflect.Struct {
|
||||
panic("proto: type must have kind struct")
|
||||
}
|
||||
|
||||
// Most calls to GetProperties in a long-running program will be
|
||||
// retrieving details for types we have seen before.
|
||||
propertiesMu.RLock()
|
||||
sprop, ok := propertiesMap[t]
|
||||
propertiesMu.RUnlock()
|
||||
if ok {
|
||||
return sprop
|
||||
}
|
||||
|
||||
propertiesMu.Lock()
|
||||
sprop = getPropertiesLocked(t)
|
||||
propertiesMu.Unlock()
|
||||
return sprop
|
||||
}
|
||||
|
||||
type (
|
||||
oneofFuncsIface interface {
|
||||
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
||||
}
|
||||
oneofWrappersIface interface {
|
||||
XXX_OneofWrappers() []interface{}
|
||||
}
|
||||
)
|
||||
|
||||
// getPropertiesLocked requires that propertiesMu is held.
|
||||
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||
if prop, ok := propertiesMap[t]; ok {
|
||||
return prop
|
||||
}
|
||||
|
||||
prop := new(StructProperties)
|
||||
// in case of recursive protos, fill this in now.
|
||||
propertiesMap[t] = prop
|
||||
|
||||
// build properties
|
||||
prop.Prop = make([]*Properties, t.NumField())
|
||||
prop.order = make([]int, t.NumField())
|
||||
|
||||
isOneofMessage := false
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
p := new(Properties)
|
||||
name := f.Name
|
||||
p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
|
||||
|
||||
oneof := f.Tag.Get("protobuf_oneof") // special case
|
||||
if oneof != "" {
|
||||
isOneofMessage = true
|
||||
// Oneof fields don't use the traditional protobuf tag.
|
||||
p.OrigName = oneof
|
||||
}
|
||||
prop.Prop[i] = p
|
||||
prop.order[i] = i
|
||||
if debug {
|
||||
print(i, " ", f.Name, " ", t.String(), " ")
|
||||
if p.Tag > 0 {
|
||||
print(p.String())
|
||||
}
|
||||
print("\n")
|
||||
}
|
||||
}
|
||||
|
||||
// Re-order prop.order.
|
||||
sort.Sort(prop)
|
||||
|
||||
if isOneofMessage {
|
||||
var oots []interface{}
|
||||
switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
|
||||
case oneofFuncsIface:
|
||||
_, _, _, oots = m.XXX_OneofFuncs()
|
||||
case oneofWrappersIface:
|
||||
oots = m.XXX_OneofWrappers()
|
||||
}
|
||||
if len(oots) > 0 {
|
||||
// Interpret oneof metadata.
|
||||
prop.OneofTypes = make(map[string]*OneofProperties)
|
||||
for _, oot := range oots {
|
||||
oop := &OneofProperties{
|
||||
Type: reflect.ValueOf(oot).Type(), // *T
|
||||
Prop: new(Properties),
|
||||
}
|
||||
sft := oop.Type.Elem().Field(0)
|
||||
oop.Prop.Name = sft.Name
|
||||
oop.Prop.Parse(sft.Tag.Get("protobuf"))
|
||||
// There will be exactly one interface field that
|
||||
// this new value is assignable to.
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if f.Type.Kind() != reflect.Interface {
|
||||
continue
|
||||
}
|
||||
if !oop.Type.AssignableTo(f.Type) {
|
||||
continue
|
||||
}
|
||||
oop.Field = i
|
||||
break
|
||||
}
|
||||
prop.OneofTypes[oop.Prop.OrigName] = oop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build required counts
|
||||
// build tags
|
||||
reqCount := 0
|
||||
prop.decoderOrigNames = make(map[string]int)
|
||||
for i, p := range prop.Prop {
|
||||
if strings.HasPrefix(p.Name, "XXX_") {
|
||||
// Internal fields should not appear in tags/origNames maps.
|
||||
// They are handled specially when encoding and decoding.
|
||||
continue
|
||||
}
|
||||
if p.Required {
|
||||
reqCount++
|
||||
}
|
||||
prop.decoderTags.put(p.Tag, i)
|
||||
prop.decoderOrigNames[p.OrigName] = i
|
||||
}
|
||||
prop.reqCount = reqCount
|
||||
|
||||
return prop
|
||||
}
|
||||
|
||||
// A global registry of enum types.
|
||||
// The generated code will register the generated maps by calling RegisterEnum.
|
||||
|
||||
var enumValueMaps = make(map[string]map[string]int32)
|
||||
var enumStringMaps = make(map[string]map[int32]string)
|
||||
|
||||
// RegisterEnum is called from the generated code to install the enum descriptor
|
||||
// maps into the global table to aid parsing text format protocol buffers.
|
||||
func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
|
||||
if _, ok := enumValueMaps[typeName]; ok {
|
||||
panic("proto: duplicate enum registered: " + typeName)
|
||||
}
|
||||
enumValueMaps[typeName] = valueMap
|
||||
if _, ok := enumStringMaps[typeName]; ok {
|
||||
panic("proto: duplicate enum registered: " + typeName)
|
||||
}
|
||||
enumStringMaps[typeName] = unusedNameMap
|
||||
}
|
||||
|
||||
// EnumValueMap returns the mapping from names to integers of the
|
||||
// enum type enumType, or a nil if not found.
|
||||
func EnumValueMap(enumType string) map[string]int32 {
|
||||
return enumValueMaps[enumType]
|
||||
}
|
||||
|
||||
// A registry of all linked message types.
|
||||
// The string is a fully-qualified proto name ("pkg.Message").
|
||||
var (
|
||||
protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers
|
||||
protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types
|
||||
revProtoTypes = make(map[reflect.Type]string)
|
||||
)
|
||||
|
||||
// RegisterType is called from generated code and maps from the fully qualified
|
||||
// proto name to the type (pointer to struct) of the protocol buffer.
|
||||
func RegisterType(x Message, name string) {
|
||||
if _, ok := protoTypedNils[name]; ok {
|
||||
// TODO: Some day, make this a panic.
|
||||
log.Printf("proto: duplicate proto type registered: %s", name)
|
||||
return
|
||||
}
|
||||
t := reflect.TypeOf(x)
|
||||
if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
|
||||
// Generated code always calls RegisterType with nil x.
|
||||
// This check is just for extra safety.
|
||||
protoTypedNils[name] = x
|
||||
} else {
|
||||
protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
|
||||
}
|
||||
revProtoTypes[t] = name
|
||||
}
|
||||
|
||||
// RegisterMapType is called from generated code and maps from the fully qualified
|
||||
// proto name to the native map type of the proto map definition.
|
||||
func RegisterMapType(x interface{}, name string) {
|
||||
if reflect.TypeOf(x).Kind() != reflect.Map {
|
||||
panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
|
||||
}
|
||||
if _, ok := protoMapTypes[name]; ok {
|
||||
log.Printf("proto: duplicate proto type registered: %s", name)
|
||||
return
|
||||
}
|
||||
t := reflect.TypeOf(x)
|
||||
protoMapTypes[name] = t
|
||||
revProtoTypes[t] = name
|
||||
}
|
||||
|
||||
// MessageName returns the fully-qualified proto name for the given message type.
|
||||
func MessageName(x Message) string {
|
||||
type xname interface {
|
||||
XXX_MessageName() string
|
||||
}
|
||||
if m, ok := x.(xname); ok {
|
||||
return m.XXX_MessageName()
|
||||
}
|
||||
return revProtoTypes[reflect.TypeOf(x)]
|
||||
}
|
||||
|
||||
// MessageType returns the message type (pointer to struct) for a named message.
|
||||
// The type is not guaranteed to implement proto.Message if the name refers to a
|
||||
// map entry.
|
||||
func MessageType(name string) reflect.Type {
|
||||
if t, ok := protoTypedNils[name]; ok {
|
||||
return reflect.TypeOf(t)
|
||||
}
|
||||
return protoMapTypes[name]
|
||||
}
|
||||
|
||||
// A registry of all linked proto files.
|
||||
var (
|
||||
protoFiles = make(map[string][]byte) // file name => fileDescriptor
|
||||
)
|
||||
|
||||
// RegisterFile is called from generated code and maps from the
|
||||
// full file name of a .proto file to its compressed FileDescriptorProto.
|
||||
func RegisterFile(filename string, fileDescriptor []byte) {
|
||||
protoFiles[filename] = fileDescriptor
|
||||
}
|
||||
|
||||
// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
|
||||
func FileDescriptor(filename string) []byte { return protoFiles[filename] }
|
36
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
generated
vendored
Normal file
36
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var sizerType = reflect.TypeOf((*Sizer)(nil)).Elem()
|
||||
var protosizerType = reflect.TypeOf((*ProtoSizer)(nil)).Elem()
|
119
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
generated
vendored
Normal file
119
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func Skip(data []byte) (n int, err error) {
|
||||
l := len(data)
|
||||
index := 0
|
||||
for index < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if index >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[index]
|
||||
index++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for {
|
||||
if index >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
index++
|
||||
if data[index-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return index, nil
|
||||
case 1:
|
||||
index += 8
|
||||
return index, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if index >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[index]
|
||||
index++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
index += length
|
||||
return index, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = index
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if index >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[index]
|
||||
index++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := Skip(data[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index = start + next
|
||||
}
|
||||
return index, nil
|
||||
case 4:
|
||||
return index, nil
|
||||
case 5:
|
||||
index += 4
|
||||
return index, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
3009
vendor/github.com/gogo/protobuf/proto/table_marshal.go
generated
vendored
Normal file
3009
vendor/github.com/gogo/protobuf/proto/table_marshal.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
388
vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go
generated
vendored
Normal file
388
vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go
generated
vendored
Normal file
@ -0,0 +1,388 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
// makeMessageRefMarshaler differs a bit from makeMessageMarshaler
|
||||
// It marshal a message T instead of a *T
|
||||
func makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
siz := u.size(ptr)
|
||||
return siz + SizeVarint(uint64(siz)) + tagsize
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
b = appendVarint(b, wiretag)
|
||||
siz := u.cachedsize(ptr)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
return u.marshal(b, ptr, deterministic)
|
||||
}
|
||||
}
|
||||
|
||||
// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler
|
||||
// It marshals a slice of messages []T instead of []*T
|
||||
func makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(u.typ)
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
e := elem.Interface()
|
||||
v := toAddrPointer(&e, false)
|
||||
siz := u.size(v)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(u.typ)
|
||||
var err, errreq error
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
e := elem.Interface()
|
||||
v := toAddrPointer(&e, false)
|
||||
b = appendVarint(b, wiretag)
|
||||
siz := u.size(v)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b, err = u.marshal(b, v, deterministic)
|
||||
|
||||
if err != nil {
|
||||
if _, ok := err.(*RequiredNotSetError); ok {
|
||||
// Required field in submessage is not set.
|
||||
// We record the error but keep going, to give a complete marshaling.
|
||||
if errreq == nil {
|
||||
errreq = err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err == ErrNil {
|
||||
err = errRepeatedHasNil
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
|
||||
return b, errreq
|
||||
}
|
||||
}
|
||||
|
||||
func makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
if ptr.isNil() {
|
||||
return 0
|
||||
}
|
||||
m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)
|
||||
siz := m.Size()
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
if ptr.isNil() {
|
||||
return b, nil
|
||||
}
|
||||
m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)
|
||||
siz := m.Size()
|
||||
buf, err := m.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
m := ptr.asPointerTo(u.typ).Interface().(custom)
|
||||
siz := m.Size()
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
m := ptr.asPointerTo(u.typ).Interface().(custom)
|
||||
siz := m.Size()
|
||||
buf, err := m.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
t := ptr.asPointerTo(u.typ).Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
siz := Size(ts)
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
t := ptr.asPointerTo(u.typ).Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf, err := Marshal(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(buf)))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
if ptr.isNil() {
|
||||
return 0
|
||||
}
|
||||
t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
siz := Size(ts)
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
if ptr.isNil() {
|
||||
return b, nil
|
||||
}
|
||||
t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf, err := Marshal(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(buf)))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(u.typ)
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
t := elem.Interface().(time.Time)
|
||||
ts, err := timestampProto(t)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
siz := Size(ts)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(u.typ)
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
t := elem.Interface().(time.Time)
|
||||
ts, err := timestampProto(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
siz := Size(ts)
|
||||
buf, err := Marshal(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(reflect.PtrTo(u.typ))
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
t := elem.Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
siz := Size(ts)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(reflect.PtrTo(u.typ))
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
t := elem.Interface().(*time.Time)
|
||||
ts, err := timestampProto(*t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
siz := Size(ts)
|
||||
buf, err := Marshal(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
d := ptr.asPointerTo(u.typ).Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
siz := Size(dur)
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
d := ptr.asPointerTo(u.typ).Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
buf, err := Marshal(dur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(buf)))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
if ptr.isNil() {
|
||||
return 0
|
||||
}
|
||||
d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
siz := Size(dur)
|
||||
return tagsize + SizeVarint(uint64(siz)) + siz
|
||||
}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
if ptr.isNil() {
|
||||
return b, nil
|
||||
}
|
||||
d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
buf, err := Marshal(dur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(len(buf)))
|
||||
b = append(b, buf...)
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(u.typ)
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
d := elem.Interface().(time.Duration)
|
||||
dur := durationProto(d)
|
||||
siz := Size(dur)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(u.typ)
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
d := elem.Interface().(time.Duration)
|
||||
dur := durationProto(d)
|
||||
siz := Size(dur)
|
||||
buf, err := Marshal(dur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
|
||||
return func(ptr pointer, tagsize int) int {
|
||||
s := ptr.getSlice(reflect.PtrTo(u.typ))
|
||||
n := 0
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
d := elem.Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
siz := Size(dur)
|
||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||
}
|
||||
return n
|
||||
},
|
||||
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
|
||||
s := ptr.getSlice(reflect.PtrTo(u.typ))
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
elem := s.Index(i)
|
||||
d := elem.Interface().(*time.Duration)
|
||||
dur := durationProto(*d)
|
||||
siz := Size(dur)
|
||||
buf, err := Marshal(dur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = appendVarint(b, wiretag)
|
||||
b = appendVarint(b, uint64(siz))
|
||||
b = append(b, buf...)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
676
vendor/github.com/gogo/protobuf/proto/table_merge.go
generated
vendored
Normal file
676
vendor/github.com/gogo/protobuf/proto/table_merge.go
generated
vendored
Normal file
@ -0,0 +1,676 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// Merge merges the src message into dst.
|
||||
// This assumes that dst and src of the same type and are non-nil.
|
||||
func (a *InternalMessageInfo) Merge(dst, src Message) {
|
||||
mi := atomicLoadMergeInfo(&a.merge)
|
||||
if mi == nil {
|
||||
mi = getMergeInfo(reflect.TypeOf(dst).Elem())
|
||||
atomicStoreMergeInfo(&a.merge, mi)
|
||||
}
|
||||
mi.merge(toPointer(&dst), toPointer(&src))
|
||||
}
|
||||
|
||||
type mergeInfo struct {
|
||||
typ reflect.Type
|
||||
|
||||
initialized int32 // 0: only typ is valid, 1: everything is valid
|
||||
lock sync.Mutex
|
||||
|
||||
fields []mergeFieldInfo
|
||||
unrecognized field // Offset of XXX_unrecognized
|
||||
}
|
||||
|
||||
type mergeFieldInfo struct {
|
||||
field field // Offset of field, guaranteed to be valid
|
||||
|
||||
// isPointer reports whether the value in the field is a pointer.
|
||||
// This is true for the following situations:
|
||||
// * Pointer to struct
|
||||
// * Pointer to basic type (proto2 only)
|
||||
// * Slice (first value in slice header is a pointer)
|
||||
// * String (first value in string header is a pointer)
|
||||
isPointer bool
|
||||
|
||||
// basicWidth reports the width of the field assuming that it is directly
|
||||
// embedded in the struct (as is the case for basic types in proto3).
|
||||
// The possible values are:
|
||||
// 0: invalid
|
||||
// 1: bool
|
||||
// 4: int32, uint32, float32
|
||||
// 8: int64, uint64, float64
|
||||
basicWidth int
|
||||
|
||||
// Where dst and src are pointers to the types being merged.
|
||||
merge func(dst, src pointer)
|
||||
}
|
||||
|
||||
var (
|
||||
mergeInfoMap = map[reflect.Type]*mergeInfo{}
|
||||
mergeInfoLock sync.Mutex
|
||||
)
|
||||
|
||||
func getMergeInfo(t reflect.Type) *mergeInfo {
|
||||
mergeInfoLock.Lock()
|
||||
defer mergeInfoLock.Unlock()
|
||||
mi := mergeInfoMap[t]
|
||||
if mi == nil {
|
||||
mi = &mergeInfo{typ: t}
|
||||
mergeInfoMap[t] = mi
|
||||
}
|
||||
return mi
|
||||
}
|
||||
|
||||
// merge merges src into dst assuming they are both of type *mi.typ.
|
||||
func (mi *mergeInfo) merge(dst, src pointer) {
|
||||
if dst.isNil() {
|
||||
panic("proto: nil destination")
|
||||
}
|
||||
if src.isNil() {
|
||||
return // Nothing to do.
|
||||
}
|
||||
|
||||
if atomic.LoadInt32(&mi.initialized) == 0 {
|
||||
mi.computeMergeInfo()
|
||||
}
|
||||
|
||||
for _, fi := range mi.fields {
|
||||
sfp := src.offset(fi.field)
|
||||
|
||||
// As an optimization, we can avoid the merge function call cost
|
||||
// if we know for sure that the source will have no effect
|
||||
// by checking if it is the zero value.
|
||||
if unsafeAllowed {
|
||||
if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string
|
||||
continue
|
||||
}
|
||||
if fi.basicWidth > 0 {
|
||||
switch {
|
||||
case fi.basicWidth == 1 && !*sfp.toBool():
|
||||
continue
|
||||
case fi.basicWidth == 4 && *sfp.toUint32() == 0:
|
||||
continue
|
||||
case fi.basicWidth == 8 && *sfp.toUint64() == 0:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dfp := dst.offset(fi.field)
|
||||
fi.merge(dfp, sfp)
|
||||
}
|
||||
|
||||
// TODO: Make this faster?
|
||||
out := dst.asPointerTo(mi.typ).Elem()
|
||||
in := src.asPointerTo(mi.typ).Elem()
|
||||
if emIn, err := extendable(in.Addr().Interface()); err == nil {
|
||||
emOut, _ := extendable(out.Addr().Interface())
|
||||
mIn, muIn := emIn.extensionsRead()
|
||||
if mIn != nil {
|
||||
mOut := emOut.extensionsWrite()
|
||||
muIn.Lock()
|
||||
mergeExtension(mOut, mIn)
|
||||
muIn.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
if mi.unrecognized.IsValid() {
|
||||
if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 {
|
||||
*dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mi *mergeInfo) computeMergeInfo() {
|
||||
mi.lock.Lock()
|
||||
defer mi.lock.Unlock()
|
||||
if mi.initialized != 0 {
|
||||
return
|
||||
}
|
||||
t := mi.typ
|
||||
n := t.NumField()
|
||||
|
||||
props := GetProperties(t)
|
||||
for i := 0; i < n; i++ {
|
||||
f := t.Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
|
||||
mfi := mergeFieldInfo{field: toField(&f)}
|
||||
tf := f.Type
|
||||
|
||||
// As an optimization, we can avoid the merge function call cost
|
||||
// if we know for sure that the source will have no effect
|
||||
// by checking if it is the zero value.
|
||||
if unsafeAllowed {
|
||||
switch tf.Kind() {
|
||||
case reflect.Ptr, reflect.Slice, reflect.String:
|
||||
// As a special case, we assume slices and strings are pointers
|
||||
// since we know that the first field in the SliceSlice or
|
||||
// StringHeader is a data pointer.
|
||||
mfi.isPointer = true
|
||||
case reflect.Bool:
|
||||
mfi.basicWidth = 1
|
||||
case reflect.Int32, reflect.Uint32, reflect.Float32:
|
||||
mfi.basicWidth = 4
|
||||
case reflect.Int64, reflect.Uint64, reflect.Float64:
|
||||
mfi.basicWidth = 8
|
||||
}
|
||||
}
|
||||
|
||||
// Unwrap tf to get at its most basic type.
|
||||
var isPointer, isSlice bool
|
||||
if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
|
||||
isSlice = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if tf.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
tf = tf.Elem()
|
||||
}
|
||||
if isPointer && isSlice && tf.Kind() != reflect.Struct {
|
||||
panic("both pointer and slice for basic type in " + tf.Name())
|
||||
}
|
||||
|
||||
switch tf.Kind() {
|
||||
case reflect.Int32:
|
||||
switch {
|
||||
case isSlice: // E.g., []int32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
// NOTE: toInt32Slice is not defined (see pointer_reflect.go).
|
||||
/*
|
||||
sfsp := src.toInt32Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toInt32Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []int64{}
|
||||
}
|
||||
}
|
||||
*/
|
||||
sfs := src.getInt32Slice()
|
||||
if sfs != nil {
|
||||
dfs := dst.getInt32Slice()
|
||||
dfs = append(dfs, sfs...)
|
||||
if dfs == nil {
|
||||
dfs = []int32{}
|
||||
}
|
||||
dst.setInt32Slice(dfs)
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *int32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
// NOTE: toInt32Ptr is not defined (see pointer_reflect.go).
|
||||
/*
|
||||
sfpp := src.toInt32Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toInt32Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Int32(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
*/
|
||||
sfp := src.getInt32Ptr()
|
||||
if sfp != nil {
|
||||
dfp := dst.getInt32Ptr()
|
||||
if dfp == nil {
|
||||
dst.setInt32Ptr(*sfp)
|
||||
} else {
|
||||
*dfp = *sfp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., int32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toInt32(); v != 0 {
|
||||
*dst.toInt32() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Int64:
|
||||
switch {
|
||||
case isSlice: // E.g., []int64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toInt64Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toInt64Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []int64{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *int64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toInt64Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toInt64Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Int64(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., int64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toInt64(); v != 0 {
|
||||
*dst.toInt64() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Uint32:
|
||||
switch {
|
||||
case isSlice: // E.g., []uint32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toUint32Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toUint32Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []uint32{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *uint32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toUint32Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toUint32Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Uint32(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., uint32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toUint32(); v != 0 {
|
||||
*dst.toUint32() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Uint64:
|
||||
switch {
|
||||
case isSlice: // E.g., []uint64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toUint64Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toUint64Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []uint64{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *uint64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toUint64Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toUint64Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Uint64(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., uint64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toUint64(); v != 0 {
|
||||
*dst.toUint64() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Float32:
|
||||
switch {
|
||||
case isSlice: // E.g., []float32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toFloat32Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toFloat32Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []float32{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *float32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toFloat32Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toFloat32Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Float32(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., float32
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toFloat32(); v != 0 {
|
||||
*dst.toFloat32() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Float64:
|
||||
switch {
|
||||
case isSlice: // E.g., []float64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toFloat64Slice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toFloat64Slice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []float64{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *float64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toFloat64Ptr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toFloat64Ptr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Float64(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., float64
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toFloat64(); v != 0 {
|
||||
*dst.toFloat64() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Bool:
|
||||
switch {
|
||||
case isSlice: // E.g., []bool
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toBoolSlice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toBoolSlice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []bool{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *bool
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toBoolPtr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toBoolPtr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = Bool(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., bool
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toBool(); v {
|
||||
*dst.toBool() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
switch {
|
||||
case isSlice: // E.g., []string
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfsp := src.toStringSlice()
|
||||
if *sfsp != nil {
|
||||
dfsp := dst.toStringSlice()
|
||||
*dfsp = append(*dfsp, *sfsp...)
|
||||
if *dfsp == nil {
|
||||
*dfsp = []string{}
|
||||
}
|
||||
}
|
||||
}
|
||||
case isPointer: // E.g., *string
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sfpp := src.toStringPtr()
|
||||
if *sfpp != nil {
|
||||
dfpp := dst.toStringPtr()
|
||||
if *dfpp == nil {
|
||||
*dfpp = String(**sfpp)
|
||||
} else {
|
||||
**dfpp = **sfpp
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., string
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
if v := *src.toString(); v != "" {
|
||||
*dst.toString() = v
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
isProto3 := props.Prop[i].proto3
|
||||
switch {
|
||||
case isPointer:
|
||||
panic("bad pointer in byte slice case in " + tf.Name())
|
||||
case tf.Elem().Kind() != reflect.Uint8:
|
||||
panic("bad element kind in byte slice case in " + tf.Name())
|
||||
case isSlice: // E.g., [][]byte
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sbsp := src.toBytesSlice()
|
||||
if *sbsp != nil {
|
||||
dbsp := dst.toBytesSlice()
|
||||
for _, sb := range *sbsp {
|
||||
if sb == nil {
|
||||
*dbsp = append(*dbsp, nil)
|
||||
} else {
|
||||
*dbsp = append(*dbsp, append([]byte{}, sb...))
|
||||
}
|
||||
}
|
||||
if *dbsp == nil {
|
||||
*dbsp = [][]byte{}
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // E.g., []byte
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sbp := src.toBytes()
|
||||
if *sbp != nil {
|
||||
dbp := dst.toBytes()
|
||||
if !isProto3 || len(*sbp) > 0 {
|
||||
*dbp = append([]byte{}, *sbp...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
switch {
|
||||
case isSlice && !isPointer: // E.g. []pb.T
|
||||
mergeInfo := getMergeInfo(tf)
|
||||
zero := reflect.Zero(tf)
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
// TODO: Make this faster?
|
||||
dstsp := dst.asPointerTo(f.Type)
|
||||
dsts := dstsp.Elem()
|
||||
srcs := src.asPointerTo(f.Type).Elem()
|
||||
for i := 0; i < srcs.Len(); i++ {
|
||||
dsts = reflect.Append(dsts, zero)
|
||||
srcElement := srcs.Index(i).Addr()
|
||||
dstElement := dsts.Index(dsts.Len() - 1).Addr()
|
||||
mergeInfo.merge(valToPointer(dstElement), valToPointer(srcElement))
|
||||
}
|
||||
if dsts.IsNil() {
|
||||
dsts = reflect.MakeSlice(f.Type, 0, 0)
|
||||
}
|
||||
dstsp.Elem().Set(dsts)
|
||||
}
|
||||
case !isPointer:
|
||||
mergeInfo := getMergeInfo(tf)
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
mergeInfo.merge(dst, src)
|
||||
}
|
||||
case isSlice: // E.g., []*pb.T
|
||||
mergeInfo := getMergeInfo(tf)
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sps := src.getPointerSlice()
|
||||
if sps != nil {
|
||||
dps := dst.getPointerSlice()
|
||||
for _, sp := range sps {
|
||||
var dp pointer
|
||||
if !sp.isNil() {
|
||||
dp = valToPointer(reflect.New(tf))
|
||||
mergeInfo.merge(dp, sp)
|
||||
}
|
||||
dps = append(dps, dp)
|
||||
}
|
||||
if dps == nil {
|
||||
dps = []pointer{}
|
||||
}
|
||||
dst.setPointerSlice(dps)
|
||||
}
|
||||
}
|
||||
default: // E.g., *pb.T
|
||||
mergeInfo := getMergeInfo(tf)
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sp := src.getPointer()
|
||||
if !sp.isNil() {
|
||||
dp := dst.getPointer()
|
||||
if dp.isNil() {
|
||||
dp = valToPointer(reflect.New(tf))
|
||||
dst.setPointer(dp)
|
||||
}
|
||||
mergeInfo.merge(dp, sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic("bad pointer or slice in map case in " + tf.Name())
|
||||
default: // E.g., map[K]V
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
sm := src.asPointerTo(tf).Elem()
|
||||
if sm.Len() == 0 {
|
||||
return
|
||||
}
|
||||
dm := dst.asPointerTo(tf).Elem()
|
||||
if dm.IsNil() {
|
||||
dm.Set(reflect.MakeMap(tf))
|
||||
}
|
||||
|
||||
switch tf.Elem().Kind() {
|
||||
case reflect.Ptr: // Proto struct (e.g., *T)
|
||||
for _, key := range sm.MapKeys() {
|
||||
val := sm.MapIndex(key)
|
||||
val = reflect.ValueOf(Clone(val.Interface().(Message)))
|
||||
dm.SetMapIndex(key, val)
|
||||
}
|
||||
case reflect.Slice: // E.g. Bytes type (e.g., []byte)
|
||||
for _, key := range sm.MapKeys() {
|
||||
val := sm.MapIndex(key)
|
||||
val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
|
||||
dm.SetMapIndex(key, val)
|
||||
}
|
||||
default: // Basic type (e.g., string)
|
||||
for _, key := range sm.MapKeys() {
|
||||
val := sm.MapIndex(key)
|
||||
dm.SetMapIndex(key, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Interface:
|
||||
// Must be oneof field.
|
||||
switch {
|
||||
case isPointer || isSlice:
|
||||
panic("bad pointer or slice in interface case in " + tf.Name())
|
||||
default: // E.g., interface{}
|
||||
// TODO: Make this faster?
|
||||
mfi.merge = func(dst, src pointer) {
|
||||
su := src.asPointerTo(tf).Elem()
|
||||
if !su.IsNil() {
|
||||
du := dst.asPointerTo(tf).Elem()
|
||||
typ := su.Elem().Type()
|
||||
if du.IsNil() || du.Elem().Type() != typ {
|
||||
du.Set(reflect.New(typ.Elem())) // Initialize interface if empty
|
||||
}
|
||||
sv := su.Elem().Elem().Field(0)
|
||||
if sv.Kind() == reflect.Ptr && sv.IsNil() {
|
||||
return
|
||||
}
|
||||
dv := du.Elem().Elem().Field(0)
|
||||
if dv.Kind() == reflect.Ptr && dv.IsNil() {
|
||||
dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty
|
||||
}
|
||||
switch sv.Type().Kind() {
|
||||
case reflect.Ptr: // Proto struct (e.g., *T)
|
||||
Merge(dv.Interface().(Message), sv.Interface().(Message))
|
||||
case reflect.Slice: // E.g. Bytes type (e.g., []byte)
|
||||
dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...)))
|
||||
default: // Basic type (e.g., string)
|
||||
dv.Set(sv)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("merger not found for type:%s", tf))
|
||||
}
|
||||
mi.fields = append(mi.fields, mfi)
|
||||
}
|
||||
|
||||
mi.unrecognized = invalidField
|
||||
if f, ok := t.FieldByName("XXX_unrecognized"); ok {
|
||||
if f.Type != reflect.TypeOf([]byte{}) {
|
||||
panic("expected XXX_unrecognized to be of type []byte")
|
||||
}
|
||||
mi.unrecognized = toField(&f)
|
||||
}
|
||||
|
||||
atomic.StoreInt32(&mi.initialized, 1)
|
||||
}
|
2249
vendor/github.com/gogo/protobuf/proto/table_unmarshal.go
generated
vendored
Normal file
2249
vendor/github.com/gogo/protobuf/proto/table_unmarshal.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
385
vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go
generated
vendored
Normal file
385
vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go
generated
vendored
Normal file
@ -0,0 +1,385 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func makeUnmarshalMessage(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
// First read the message field to see if something is there.
|
||||
// The semantics of multiple submessages are weird. Instead of
|
||||
// the last one winning (as it is for all other fields), multiple
|
||||
// submessages are merged.
|
||||
v := f // gogo: changed from v := f.getPointer()
|
||||
if v.isNil() {
|
||||
v = valToPointer(reflect.New(sub.typ))
|
||||
f.setPointer(v)
|
||||
}
|
||||
err := sub.unmarshal(v, b[:x])
|
||||
if err != nil {
|
||||
if r, ok := err.(*RequiredNotSetError); ok {
|
||||
r.field = name + "." + r.field
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return b[x:], err
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalMessageSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
v := valToPointer(reflect.New(sub.typ))
|
||||
err := sub.unmarshal(v, b[:x])
|
||||
if err != nil {
|
||||
if r, ok := err.(*RequiredNotSetError); ok {
|
||||
r.field = name + "." + r.field
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
f.appendRef(v, sub.typ) // gogo: changed from f.appendPointer(v)
|
||||
return b[x:], err
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalCustomPtr(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
|
||||
s.Set(reflect.New(sub.typ))
|
||||
m := s.Interface().(custom)
|
||||
if err := m.Unmarshal(b[:x]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalCustomSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := reflect.New(sub.typ)
|
||||
c := m.Interface().(custom)
|
||||
if err := c.Unmarshal(b[:x]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v := valToPointer(m)
|
||||
f.appendRef(v, sub.typ)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalCustom(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
m := f.asPointerTo(sub.typ).Interface().(custom)
|
||||
if err := m.Unmarshal(b[:x]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalTime(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := ×tamp{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := timestampFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := f.asPointerTo(sub.typ).Elem()
|
||||
s.Set(reflect.ValueOf(t))
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalTimePtr(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := ×tamp{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := timestampFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
|
||||
s.Set(reflect.ValueOf(&t))
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalTimePtrSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := ×tamp{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := timestampFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slice := f.getSlice(reflect.PtrTo(sub.typ))
|
||||
newSlice := reflect.Append(slice, reflect.ValueOf(&t))
|
||||
slice.Set(newSlice)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalTimeSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := ×tamp{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := timestampFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slice := f.getSlice(sub.typ)
|
||||
newSlice := reflect.Append(slice, reflect.ValueOf(t))
|
||||
slice.Set(newSlice)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalDurationPtr(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := &duration{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d, err := durationFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
|
||||
s.Set(reflect.ValueOf(&d))
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalDuration(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := &duration{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d, err := durationFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := f.asPointerTo(sub.typ).Elem()
|
||||
s.Set(reflect.ValueOf(d))
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalDurationPtrSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := &duration{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d, err := durationFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slice := f.getSlice(reflect.PtrTo(sub.typ))
|
||||
newSlice := reflect.Append(slice, reflect.ValueOf(&d))
|
||||
slice.Set(newSlice)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
||||
|
||||
func makeUnmarshalDurationSlice(sub *unmarshalInfo, name string) unmarshaler {
|
||||
return func(b []byte, f pointer, w int) ([]byte, error) {
|
||||
if w != WireBytes {
|
||||
return nil, errInternalBadWireType
|
||||
}
|
||||
x, n := decodeVarint(b)
|
||||
if n == 0 {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b = b[n:]
|
||||
if x > uint64(len(b)) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
m := &duration{}
|
||||
if err := Unmarshal(b[:x], m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d, err := durationFromProto(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slice := f.getSlice(sub.typ)
|
||||
newSlice := reflect.Append(slice, reflect.ValueOf(d))
|
||||
slice.Set(newSlice)
|
||||
return b[x:], nil
|
||||
}
|
||||
}
|
930
vendor/github.com/gogo/protobuf/proto/text.go
generated
vendored
Normal file
930
vendor/github.com/gogo/protobuf/proto/text.go
generated
vendored
Normal file
@ -0,0 +1,930 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
// Functions for writing the text protocol buffer format.
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
newline = []byte("\n")
|
||||
spaces = []byte(" ")
|
||||
endBraceNewline = []byte("}\n")
|
||||
backslashN = []byte{'\\', 'n'}
|
||||
backslashR = []byte{'\\', 'r'}
|
||||
backslashT = []byte{'\\', 't'}
|
||||
backslashDQ = []byte{'\\', '"'}
|
||||
backslashBS = []byte{'\\', '\\'}
|
||||
posInf = []byte("inf")
|
||||
negInf = []byte("-inf")
|
||||
nan = []byte("nan")
|
||||
)
|
||||
|
||||
type writer interface {
|
||||
io.Writer
|
||||
WriteByte(byte) error
|
||||
}
|
||||
|
||||
// textWriter is an io.Writer that tracks its indentation level.
|
||||
type textWriter struct {
|
||||
ind int
|
||||
complete bool // if the current position is a complete line
|
||||
compact bool // whether to write out as a one-liner
|
||||
w writer
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteString(s string) (n int, err error) {
|
||||
if !strings.Contains(s, "\n") {
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
w.complete = false
|
||||
return io.WriteString(w.w, s)
|
||||
}
|
||||
// WriteString is typically called without newlines, so this
|
||||
// codepath and its copy are rare. We copy to avoid
|
||||
// duplicating all of Write's logic here.
|
||||
return w.Write([]byte(s))
|
||||
}
|
||||
|
||||
func (w *textWriter) Write(p []byte) (n int, err error) {
|
||||
newlines := bytes.Count(p, newline)
|
||||
if newlines == 0 {
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
n, err = w.w.Write(p)
|
||||
w.complete = false
|
||||
return n, err
|
||||
}
|
||||
|
||||
frags := bytes.SplitN(p, newline, newlines+1)
|
||||
if w.compact {
|
||||
for i, frag := range frags {
|
||||
if i > 0 {
|
||||
if err := w.w.WriteByte(' '); err != nil {
|
||||
return n, err
|
||||
}
|
||||
n++
|
||||
}
|
||||
nn, err := w.w.Write(frag)
|
||||
n += nn
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
for i, frag := range frags {
|
||||
if w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
nn, err := w.w.Write(frag)
|
||||
n += nn
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
if i+1 < len(frags) {
|
||||
if err := w.w.WriteByte('\n'); err != nil {
|
||||
return n, err
|
||||
}
|
||||
n++
|
||||
}
|
||||
}
|
||||
w.complete = len(frags[len(frags)-1]) == 0
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteByte(c byte) error {
|
||||
if w.compact && c == '\n' {
|
||||
c = ' '
|
||||
}
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
err := w.w.WriteByte(c)
|
||||
w.complete = c == '\n'
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *textWriter) indent() { w.ind++ }
|
||||
|
||||
func (w *textWriter) unindent() {
|
||||
if w.ind == 0 {
|
||||
log.Print("proto: textWriter unindented too far")
|
||||
return
|
||||
}
|
||||
w.ind--
|
||||
}
|
||||
|
||||
func writeName(w *textWriter, props *Properties) error {
|
||||
if _, err := w.WriteString(props.OrigName); err != nil {
|
||||
return err
|
||||
}
|
||||
if props.Wire != "group" {
|
||||
return w.WriteByte(':')
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func requiresQuotes(u string) bool {
|
||||
// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
|
||||
for _, ch := range u {
|
||||
switch {
|
||||
case ch == '.' || ch == '/' || ch == '_':
|
||||
continue
|
||||
case '0' <= ch && ch <= '9':
|
||||
continue
|
||||
case 'A' <= ch && ch <= 'Z':
|
||||
continue
|
||||
case 'a' <= ch && ch <= 'z':
|
||||
continue
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isAny reports whether sv is a google.protobuf.Any message
|
||||
func isAny(sv reflect.Value) bool {
|
||||
type wkt interface {
|
||||
XXX_WellKnownType() string
|
||||
}
|
||||
t, ok := sv.Addr().Interface().(wkt)
|
||||
return ok && t.XXX_WellKnownType() == "Any"
|
||||
}
|
||||
|
||||
// writeProto3Any writes an expanded google.protobuf.Any message.
|
||||
//
|
||||
// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
|
||||
// required messages are not linked in).
|
||||
//
|
||||
// It returns (true, error) when sv was written in expanded format or an error
|
||||
// was encountered.
|
||||
func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
|
||||
turl := sv.FieldByName("TypeUrl")
|
||||
val := sv.FieldByName("Value")
|
||||
if !turl.IsValid() || !val.IsValid() {
|
||||
return true, errors.New("proto: invalid google.protobuf.Any message")
|
||||
}
|
||||
|
||||
b, ok := val.Interface().([]byte)
|
||||
if !ok {
|
||||
return true, errors.New("proto: invalid google.protobuf.Any message")
|
||||
}
|
||||
|
||||
parts := strings.Split(turl.String(), "/")
|
||||
mt := MessageType(parts[len(parts)-1])
|
||||
if mt == nil {
|
||||
return false, nil
|
||||
}
|
||||
m := reflect.New(mt.Elem())
|
||||
if err := Unmarshal(b, m.Interface().(Message)); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
w.Write([]byte("["))
|
||||
u := turl.String()
|
||||
if requiresQuotes(u) {
|
||||
writeString(w, u)
|
||||
} else {
|
||||
w.Write([]byte(u))
|
||||
}
|
||||
if w.compact {
|
||||
w.Write([]byte("]:<"))
|
||||
} else {
|
||||
w.Write([]byte("]: <\n"))
|
||||
w.ind++
|
||||
}
|
||||
if err := tm.writeStruct(w, m.Elem()); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if w.compact {
|
||||
w.Write([]byte("> "))
|
||||
} else {
|
||||
w.ind--
|
||||
w.Write([]byte(">\n"))
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
|
||||
if tm.ExpandAny && isAny(sv) {
|
||||
if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
|
||||
return err
|
||||
}
|
||||
}
|
||||
st := sv.Type()
|
||||
sprops := GetProperties(st)
|
||||
for i := 0; i < sv.NumField(); i++ {
|
||||
fv := sv.Field(i)
|
||||
props := sprops.Prop[i]
|
||||
name := st.Field(i).Name
|
||||
|
||||
if name == "XXX_NoUnkeyedLiteral" {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(name, "XXX_") {
|
||||
// There are two XXX_ fields:
|
||||
// XXX_unrecognized []byte
|
||||
// XXX_extensions map[int32]proto.Extension
|
||||
// The first is handled here;
|
||||
// the second is handled at the bottom of this function.
|
||||
if name == "XXX_unrecognized" && !fv.IsNil() {
|
||||
if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||
// Field not filled in. This could be an optional field or
|
||||
// a required field that wasn't filled in. Either way, there
|
||||
// isn't anything we can show for it.
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Slice && fv.IsNil() {
|
||||
// Repeated field that is empty, or a bytes field that is unused.
|
||||
continue
|
||||
}
|
||||
|
||||
if props.Repeated && fv.Kind() == reflect.Slice {
|
||||
// Repeated field.
|
||||
for j := 0; j < fv.Len(); j++ {
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
v := fv.Index(j)
|
||||
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
// A nil message in a repeated field is not valid,
|
||||
// but we can handle that more gracefully than panicking.
|
||||
if _, err := w.Write([]byte("<nil>\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if len(props.Enum) > 0 {
|
||||
if err := tm.writeEnum(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := tm.writeAny(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Map {
|
||||
// Map fields are rendered as a repeated struct with key/value fields.
|
||||
keys := fv.MapKeys()
|
||||
sort.Sort(mapKeys(keys))
|
||||
for _, key := range keys {
|
||||
val := fv.MapIndex(key)
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// open struct
|
||||
if err := w.WriteByte('<'); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.indent()
|
||||
// key
|
||||
if _, err := w.WriteString("key:"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
// nil values aren't legal, but we can avoid panicking because of them.
|
||||
if val.Kind() != reflect.Ptr || !val.IsNil() {
|
||||
// value
|
||||
if _, err := w.WriteString("value:"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, val, props.MapValProp); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// close struct
|
||||
w.unindent()
|
||||
if err := w.WriteByte('>'); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
|
||||
// empty bytes field
|
||||
continue
|
||||
}
|
||||
if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
|
||||
// proto3 non-repeated scalar field; skip if zero value
|
||||
if isProto3Zero(fv) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if fv.Kind() == reflect.Interface {
|
||||
// Check if it is a oneof.
|
||||
if st.Field(i).Tag.Get("protobuf_oneof") != "" {
|
||||
// fv is nil, or holds a pointer to generated struct.
|
||||
// That generated struct has exactly one field,
|
||||
// which has a protobuf struct tag.
|
||||
if fv.IsNil() {
|
||||
continue
|
||||
}
|
||||
inner := fv.Elem().Elem() // interface -> *T -> T
|
||||
tag := inner.Type().Field(0).Tag.Get("protobuf")
|
||||
props = new(Properties) // Overwrite the outer props var, but not its pointee.
|
||||
props.Parse(tag)
|
||||
// Write the value in the oneof, not the oneof itself.
|
||||
fv = inner.Field(0)
|
||||
|
||||
// Special case to cope with malformed messages gracefully:
|
||||
// If the value in the oneof is a nil pointer, don't panic
|
||||
// in writeAny.
|
||||
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||
// Use errors.New so writeAny won't render quotes.
|
||||
msg := errors.New("/* nil */")
|
||||
fv = reflect.ValueOf(&msg).Elem()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(props.Enum) > 0 {
|
||||
if err := tm.writeEnum(w, fv, props); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := tm.writeAny(w, fv, props); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Extensions (the XXX_extensions field).
|
||||
pv := sv
|
||||
if pv.CanAddr() {
|
||||
pv = sv.Addr()
|
||||
} else {
|
||||
pv = reflect.New(sv.Type())
|
||||
pv.Elem().Set(sv)
|
||||
}
|
||||
if _, err := extendable(pv.Interface()); err == nil {
|
||||
if err := tm.writeExtensions(w, pv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
|
||||
|
||||
// writeAny writes an arbitrary field.
|
||||
func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
||||
v = reflect.Indirect(v)
|
||||
|
||||
if props != nil {
|
||||
if len(props.CustomType) > 0 {
|
||||
custom, ok := v.Interface().(Marshaler)
|
||||
if ok {
|
||||
data, err := custom.Marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeString(w, string(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
} else if len(props.CastType) > 0 {
|
||||
if _, ok := v.Interface().(interface {
|
||||
String() string
|
||||
}); ok {
|
||||
switch v.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
_, err := fmt.Fprintf(w, "%d", v.Interface())
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if props.StdTime {
|
||||
t, ok := v.Interface().(time.Time)
|
||||
if !ok {
|
||||
return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface())
|
||||
}
|
||||
tproto, err := timestampProto(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
propsCopy := *props // Make a copy so that this is goroutine-safe
|
||||
propsCopy.StdTime = false
|
||||
err = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy)
|
||||
return err
|
||||
} else if props.StdDuration {
|
||||
d, ok := v.Interface().(time.Duration)
|
||||
if !ok {
|
||||
return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface())
|
||||
}
|
||||
dproto := durationProto(d)
|
||||
propsCopy := *props // Make a copy so that this is goroutine-safe
|
||||
propsCopy.StdDuration = false
|
||||
err := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Floats have special cases.
|
||||
if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
|
||||
x := v.Float()
|
||||
var b []byte
|
||||
switch {
|
||||
case math.IsInf(x, 1):
|
||||
b = posInf
|
||||
case math.IsInf(x, -1):
|
||||
b = negInf
|
||||
case math.IsNaN(x):
|
||||
b = nan
|
||||
}
|
||||
if b != nil {
|
||||
_, err := w.Write(b)
|
||||
return err
|
||||
}
|
||||
// Other values are handled below.
|
||||
}
|
||||
|
||||
// We don't attempt to serialise every possible value type; only those
|
||||
// that can occur in protocol buffers.
|
||||
switch v.Kind() {
|
||||
case reflect.Slice:
|
||||
// Should only be a []byte; repeated fields are handled in writeStruct.
|
||||
if err := writeString(w, string(v.Bytes())); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.String:
|
||||
if err := writeString(w, v.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.Struct:
|
||||
// Required/optional group/message.
|
||||
var bra, ket byte = '<', '>'
|
||||
if props != nil && props.Wire == "group" {
|
||||
bra, ket = '{', '}'
|
||||
}
|
||||
if err := w.WriteByte(bra); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.indent()
|
||||
if v.CanAddr() {
|
||||
// Calling v.Interface on a struct causes the reflect package to
|
||||
// copy the entire struct. This is racy with the new Marshaler
|
||||
// since we atomically update the XXX_sizecache.
|
||||
//
|
||||
// Thus, we retrieve a pointer to the struct if possible to avoid
|
||||
// a race since v.Interface on the pointer doesn't copy the struct.
|
||||
//
|
||||
// If v is not addressable, then we are not worried about a race
|
||||
// since it implies that the binary Marshaler cannot possibly be
|
||||
// mutating this value.
|
||||
v = v.Addr()
|
||||
}
|
||||
if v.Type().Implements(textMarshalerType) {
|
||||
text, err := v.Interface().(encoding.TextMarshaler).MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = w.Write(text); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
if err := tm.writeStruct(w, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.unindent()
|
||||
if err := w.WriteByte(ket); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
_, err := fmt.Fprint(w, v.Interface())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// equivalent to C's isprint.
|
||||
func isprint(c byte) bool {
|
||||
return c >= 0x20 && c < 0x7f
|
||||
}
|
||||
|
||||
// writeString writes a string in the protocol buffer text format.
|
||||
// It is similar to strconv.Quote except we don't use Go escape sequences,
|
||||
// we treat the string as a byte sequence, and we use octal escapes.
|
||||
// These differences are to maintain interoperability with the other
|
||||
// languages' implementations of the text format.
|
||||
func writeString(w *textWriter, s string) error {
|
||||
// use WriteByte here to get any needed indent
|
||||
if err := w.WriteByte('"'); err != nil {
|
||||
return err
|
||||
}
|
||||
// Loop over the bytes, not the runes.
|
||||
for i := 0; i < len(s); i++ {
|
||||
var err error
|
||||
// Divergence from C++: we don't escape apostrophes.
|
||||
// There's no need to escape them, and the C++ parser
|
||||
// copes with a naked apostrophe.
|
||||
switch c := s[i]; c {
|
||||
case '\n':
|
||||
_, err = w.w.Write(backslashN)
|
||||
case '\r':
|
||||
_, err = w.w.Write(backslashR)
|
||||
case '\t':
|
||||
_, err = w.w.Write(backslashT)
|
||||
case '"':
|
||||
_, err = w.w.Write(backslashDQ)
|
||||
case '\\':
|
||||
_, err = w.w.Write(backslashBS)
|
||||
default:
|
||||
if isprint(c) {
|
||||
err = w.w.WriteByte(c)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w.w, "\\%03o", c)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return w.WriteByte('"')
|
||||
}
|
||||
|
||||
func writeUnknownStruct(w *textWriter, data []byte) (err error) {
|
||||
if !w.compact {
|
||||
if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
b := NewBuffer(data)
|
||||
for b.index < len(b.buf) {
|
||||
x, err := b.DecodeVarint()
|
||||
if err != nil {
|
||||
_, ferr := fmt.Fprintf(w, "/* %v */\n", err)
|
||||
return ferr
|
||||
}
|
||||
wire, tag := x&7, x>>3
|
||||
if wire == WireEndGroup {
|
||||
w.unindent()
|
||||
if _, werr := w.Write(endBraceNewline); werr != nil {
|
||||
return werr
|
||||
}
|
||||
continue
|
||||
}
|
||||
if _, ferr := fmt.Fprint(w, tag); ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
if wire != WireStartGroup {
|
||||
if err = w.WriteByte(':'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !w.compact || wire == WireStartGroup {
|
||||
if err = w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
switch wire {
|
||||
case WireBytes:
|
||||
buf, e := b.DecodeRawBytes(false)
|
||||
if e == nil {
|
||||
_, err = fmt.Fprintf(w, "%q", buf)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w, "/* %v */", e)
|
||||
}
|
||||
case WireFixed32:
|
||||
x, err = b.DecodeFixed32()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
case WireFixed64:
|
||||
x, err = b.DecodeFixed64()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
case WireStartGroup:
|
||||
err = w.WriteByte('{')
|
||||
w.indent()
|
||||
case WireVarint:
|
||||
x, err = b.DecodeVarint()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
default:
|
||||
_, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeUnknownInt(w *textWriter, x uint64, err error) error {
|
||||
if err == nil {
|
||||
_, err = fmt.Fprint(w, x)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w, "/* %v */", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
type int32Slice []int32
|
||||
|
||||
func (s int32Slice) Len() int { return len(s) }
|
||||
func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
|
||||
func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// writeExtensions writes all the extensions in pv.
|
||||
// pv is assumed to be a pointer to a protocol message struct that is extendable.
|
||||
func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
|
||||
emap := extensionMaps[pv.Type().Elem()]
|
||||
e := pv.Interface().(Message)
|
||||
|
||||
var m map[int32]Extension
|
||||
var mu sync.Locker
|
||||
if em, ok := e.(extensionsBytes); ok {
|
||||
eb := em.GetExtensions()
|
||||
var err error
|
||||
m, err = BytesToExtensionsMap(*eb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mu = notLocker{}
|
||||
} else if _, ok := e.(extendableProto); ok {
|
||||
ep, _ := extendable(e)
|
||||
m, mu = ep.extensionsRead()
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Order the extensions by ID.
|
||||
// This isn't strictly necessary, but it will give us
|
||||
// canonical output, which will also make testing easier.
|
||||
|
||||
mu.Lock()
|
||||
ids := make([]int32, 0, len(m))
|
||||
for id := range m {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
sort.Sort(int32Slice(ids))
|
||||
mu.Unlock()
|
||||
|
||||
for _, extNum := range ids {
|
||||
ext := m[extNum]
|
||||
var desc *ExtensionDesc
|
||||
if emap != nil {
|
||||
desc = emap[extNum]
|
||||
}
|
||||
if desc == nil {
|
||||
// Unknown extension.
|
||||
if err := writeUnknownStruct(w, ext.enc); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
pb, err := GetExtension(e, desc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed getting extension: %v", err)
|
||||
}
|
||||
|
||||
// Repeated extensions will appear as a slice.
|
||||
if !desc.repeated() {
|
||||
if err := tm.writeExtension(w, desc.Name, pb); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
v := reflect.ValueOf(pb)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
|
||||
if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *textWriter) writeIndent() {
|
||||
if !w.complete {
|
||||
return
|
||||
}
|
||||
remain := w.ind * 2
|
||||
for remain > 0 {
|
||||
n := remain
|
||||
if n > len(spaces) {
|
||||
n = len(spaces)
|
||||
}
|
||||
w.w.Write(spaces[:n])
|
||||
remain -= n
|
||||
}
|
||||
w.complete = false
|
||||
}
|
||||
|
||||
// TextMarshaler is a configurable text format marshaler.
|
||||
type TextMarshaler struct {
|
||||
Compact bool // use compact text format (one line).
|
||||
ExpandAny bool // expand google.protobuf.Any messages of known types
|
||||
}
|
||||
|
||||
// Marshal writes a given protocol buffer in text format.
|
||||
// The only errors returned are from w.
|
||||
func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
||||
val := reflect.ValueOf(pb)
|
||||
if pb == nil || val.IsNil() {
|
||||
w.Write([]byte("<nil>"))
|
||||
return nil
|
||||
}
|
||||
var bw *bufio.Writer
|
||||
ww, ok := w.(writer)
|
||||
if !ok {
|
||||
bw = bufio.NewWriter(w)
|
||||
ww = bw
|
||||
}
|
||||
aw := &textWriter{
|
||||
w: ww,
|
||||
complete: true,
|
||||
compact: tm.Compact,
|
||||
}
|
||||
|
||||
if etm, ok := pb.(encoding.TextMarshaler); ok {
|
||||
text, err := etm.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = aw.Write(text); err != nil {
|
||||
return err
|
||||
}
|
||||
if bw != nil {
|
||||
return bw.Flush()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// Dereference the received pointer so we don't have outer < and >.
|
||||
v := reflect.Indirect(val)
|
||||
if err := tm.writeStruct(aw, v); err != nil {
|
||||
return err
|
||||
}
|
||||
if bw != nil {
|
||||
return bw.Flush()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Text is the same as Marshal, but returns the string directly.
|
||||
func (tm *TextMarshaler) Text(pb Message) string {
|
||||
var buf bytes.Buffer
|
||||
tm.Marshal(&buf, pb)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
var (
|
||||
defaultTextMarshaler = TextMarshaler{}
|
||||
compactTextMarshaler = TextMarshaler{Compact: true}
|
||||
)
|
||||
|
||||
// TODO: consider removing some of the Marshal functions below.
|
||||
|
||||
// MarshalText writes a given protocol buffer in text format.
|
||||
// The only errors returned are from w.
|
||||
func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
|
||||
|
||||
// MarshalTextString is the same as MarshalText, but returns the string directly.
|
||||
func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
|
||||
|
||||
// CompactText writes a given protocol buffer in compact text format (one line).
|
||||
func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
|
||||
|
||||
// CompactTextString is the same as CompactText, but returns the string directly.
|
||||
func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }
|
57
vendor/github.com/gogo/protobuf/proto/text_gogo.go
generated
vendored
Normal file
57
vendor/github.com/gogo/protobuf/proto/text_gogo.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error {
|
||||
m, ok := enumStringMaps[props.Enum]
|
||||
if !ok {
|
||||
if err := tm.writeAny(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
key := int32(0)
|
||||
if v.Kind() == reflect.Ptr {
|
||||
key = int32(v.Elem().Int())
|
||||
} else {
|
||||
key = int32(v.Int())
|
||||
}
|
||||
s, ok := m[key]
|
||||
if !ok {
|
||||
if err := tm.writeAny(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err := fmt.Fprint(w, s)
|
||||
return err
|
||||
}
|
1018
vendor/github.com/gogo/protobuf/proto/text_parser.go
generated
vendored
Normal file
1018
vendor/github.com/gogo/protobuf/proto/text_parser.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
113
vendor/github.com/gogo/protobuf/proto/timestamp.go
generated
vendored
Normal file
113
vendor/github.com/gogo/protobuf/proto/timestamp.go
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
// This file implements operations on google.protobuf.Timestamp.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// Seconds field of the earliest valid Timestamp.
|
||||
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
minValidSeconds = -62135596800
|
||||
// Seconds field just after the latest valid Timestamp.
|
||||
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
maxValidSeconds = 253402300800
|
||||
)
|
||||
|
||||
// validateTimestamp determines whether a Timestamp is valid.
|
||||
// A valid timestamp represents a time in the range
|
||||
// [0001-01-01, 10000-01-01) and has a Nanos field
|
||||
// in the range [0, 1e9).
|
||||
//
|
||||
// If the Timestamp is valid, validateTimestamp returns nil.
|
||||
// Otherwise, it returns an error that describes
|
||||
// the problem.
|
||||
//
|
||||
// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
|
||||
func validateTimestamp(ts *timestamp) error {
|
||||
if ts == nil {
|
||||
return errors.New("timestamp: nil Timestamp")
|
||||
}
|
||||
if ts.Seconds < minValidSeconds {
|
||||
return fmt.Errorf("timestamp: %#v before 0001-01-01", ts)
|
||||
}
|
||||
if ts.Seconds >= maxValidSeconds {
|
||||
return fmt.Errorf("timestamp: %#v after 10000-01-01", ts)
|
||||
}
|
||||
if ts.Nanos < 0 || ts.Nanos >= 1e9 {
|
||||
return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time.
|
||||
// It returns an error if the argument is invalid.
|
||||
//
|
||||
// Unlike most Go functions, if Timestamp returns an error, the first return value
|
||||
// is not the zero time.Time. Instead, it is the value obtained from the
|
||||
// time.Unix function when passed the contents of the Timestamp, in the UTC
|
||||
// locale. This may or may not be a meaningful time; many invalid Timestamps
|
||||
// do map to valid time.Times.
|
||||
//
|
||||
// A nil Timestamp returns an error. The first return value in that case is
|
||||
// undefined.
|
||||
func timestampFromProto(ts *timestamp) (time.Time, error) {
|
||||
// Don't return the zero value on error, because corresponds to a valid
|
||||
// timestamp. Instead return whatever time.Unix gives us.
|
||||
var t time.Time
|
||||
if ts == nil {
|
||||
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
|
||||
} else {
|
||||
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
|
||||
}
|
||||
return t, validateTimestamp(ts)
|
||||
}
|
||||
|
||||
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
|
||||
// It returns an error if the resulting Timestamp is invalid.
|
||||
func timestampProto(t time.Time) (*timestamp, error) {
|
||||
seconds := t.Unix()
|
||||
nanos := int32(t.Sub(time.Unix(seconds, 0)))
|
||||
ts := ×tamp{
|
||||
Seconds: seconds,
|
||||
Nanos: nanos,
|
||||
}
|
||||
if err := validateTimestamp(ts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ts, nil
|
||||
}
|
49
vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go
generated
vendored
Normal file
49
vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
var timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
||||
|
||||
type timestamp struct {
|
||||
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
|
||||
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
|
||||
}
|
||||
|
||||
func (m *timestamp) Reset() { *m = timestamp{} }
|
||||
func (*timestamp) ProtoMessage() {}
|
||||
func (*timestamp) String() string { return "timestamp<string>" }
|
||||
|
||||
func init() {
|
||||
RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp")
|
||||
}
|
1888
vendor/github.com/gogo/protobuf/proto/wrappers.go
generated
vendored
Normal file
1888
vendor/github.com/gogo/protobuf/proto/wrappers.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
113
vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go
generated
vendored
Normal file
113
vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
type float64Value struct {
|
||||
Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *float64Value) Reset() { *m = float64Value{} }
|
||||
func (*float64Value) ProtoMessage() {}
|
||||
func (*float64Value) String() string { return "float64<string>" }
|
||||
|
||||
type float32Value struct {
|
||||
Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *float32Value) Reset() { *m = float32Value{} }
|
||||
func (*float32Value) ProtoMessage() {}
|
||||
func (*float32Value) String() string { return "float32<string>" }
|
||||
|
||||
type int64Value struct {
|
||||
Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *int64Value) Reset() { *m = int64Value{} }
|
||||
func (*int64Value) ProtoMessage() {}
|
||||
func (*int64Value) String() string { return "int64<string>" }
|
||||
|
||||
type uint64Value struct {
|
||||
Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *uint64Value) Reset() { *m = uint64Value{} }
|
||||
func (*uint64Value) ProtoMessage() {}
|
||||
func (*uint64Value) String() string { return "uint64<string>" }
|
||||
|
||||
type int32Value struct {
|
||||
Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *int32Value) Reset() { *m = int32Value{} }
|
||||
func (*int32Value) ProtoMessage() {}
|
||||
func (*int32Value) String() string { return "int32<string>" }
|
||||
|
||||
type uint32Value struct {
|
||||
Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *uint32Value) Reset() { *m = uint32Value{} }
|
||||
func (*uint32Value) ProtoMessage() {}
|
||||
func (*uint32Value) String() string { return "uint32<string>" }
|
||||
|
||||
type boolValue struct {
|
||||
Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *boolValue) Reset() { *m = boolValue{} }
|
||||
func (*boolValue) ProtoMessage() {}
|
||||
func (*boolValue) String() string { return "bool<string>" }
|
||||
|
||||
type stringValue struct {
|
||||
Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *stringValue) Reset() { *m = stringValue{} }
|
||||
func (*stringValue) ProtoMessage() {}
|
||||
func (*stringValue) String() string { return "string<string>" }
|
||||
|
||||
type bytesValue struct {
|
||||
Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *bytesValue) Reset() { *m = bytesValue{} }
|
||||
func (*bytesValue) ProtoMessage() {}
|
||||
func (*bytesValue) String() string { return "[]byte<string>" }
|
||||
|
||||
func init() {
|
||||
RegisterType((*float64Value)(nil), "gogo.protobuf.proto.DoubleValue")
|
||||
RegisterType((*float32Value)(nil), "gogo.protobuf.proto.FloatValue")
|
||||
RegisterType((*int64Value)(nil), "gogo.protobuf.proto.Int64Value")
|
||||
RegisterType((*uint64Value)(nil), "gogo.protobuf.proto.UInt64Value")
|
||||
RegisterType((*int32Value)(nil), "gogo.protobuf.proto.Int32Value")
|
||||
RegisterType((*uint32Value)(nil), "gogo.protobuf.proto.UInt32Value")
|
||||
RegisterType((*boolValue)(nil), "gogo.protobuf.proto.BoolValue")
|
||||
RegisterType((*stringValue)(nil), "gogo.protobuf.proto.StringValue")
|
||||
RegisterType((*bytesValue)(nil), "gogo.protobuf.proto.BytesValue")
|
||||
}
|
1
vendor/github.com/ipfs/go-cid/.gitignore
generated
vendored
Normal file
1
vendor/github.com/ipfs/go-cid/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
cid-fuzz.zip
|
30
vendor/github.com/ipfs/go-cid/.travis.yml
generated
vendored
Normal file
30
vendor/github.com/ipfs/go-cid/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
os:
|
||||
- linux
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.11.x
|
||||
|
||||
env:
|
||||
global:
|
||||
- GOTFLAGS="-race"
|
||||
matrix:
|
||||
- BUILD_DEPTYPE=gomod
|
||||
|
||||
|
||||
# disable travis install
|
||||
install:
|
||||
- true
|
||||
|
||||
script:
|
||||
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)
|
||||
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $GOPATH/pkg/mod
|
||||
- $HOME/.cache/go-build
|
||||
|
||||
notifications:
|
||||
email: false
|
21
vendor/github.com/ipfs/go-cid/LICENSE
generated
vendored
Normal file
21
vendor/github.com/ipfs/go-cid/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Protocol Labs, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
5
vendor/github.com/ipfs/go-cid/Makefile
generated
vendored
Normal file
5
vendor/github.com/ipfs/go-cid/Makefile
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
all: deps
|
||||
|
||||
deps:
|
||||
go get github.com/mattn/goveralls
|
||||
go get golang.org/x/tools/cmd/cover
|
108
vendor/github.com/ipfs/go-cid/README.md
generated
vendored
Normal file
108
vendor/github.com/ipfs/go-cid/README.md
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
go-cid
|
||||
==================
|
||||
|
||||
[](http://ipn.io)
|
||||
[](http://ipfs.io/)
|
||||
[](http://webchat.freenode.net/?channels=%23ipfs)
|
||||
[](https://github.com/RichardLitt/standard-readme)
|
||||
[](https://godoc.org/github.com/ipfs/go-cid)
|
||||
[](https://coveralls.io/github/ipfs/go-cid?branch=master)
|
||||
[](https://travis-ci.org/ipfs/go-cid)
|
||||
|
||||
> A package to handle content IDs in Go.
|
||||
|
||||
This is an implementation in Go of the [CID spec](https://github.com/ipld/cid).
|
||||
It is used in `go-ipfs` and related packages to refer to a typed hunk of data.
|
||||
|
||||
## Lead Maintainer
|
||||
|
||||
[Eric Myhre](https://github.com/warpfork)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Install](#install)
|
||||
- [Usage](#usage)
|
||||
- [API](#api)
|
||||
- [Contribute](#contribute)
|
||||
- [License](#license)
|
||||
|
||||
## Install
|
||||
|
||||
`go-cid` is a standard Go module which can be installed with:
|
||||
|
||||
```sh
|
||||
go get github.com/ipfs/go-cid
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Running tests
|
||||
|
||||
Run tests with `go test` from the directory root
|
||||
|
||||
```sh
|
||||
go test
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
#### Parsing string input from users
|
||||
|
||||
```go
|
||||
// Create a cid from a marshaled string
|
||||
c, err := cid.Decode("bafzbeigai3eoy2ccc7ybwjfz5r3rdxqrinwi4rwytly24tdbh6yk7zslrm")
|
||||
if err != nil {...}
|
||||
|
||||
fmt.Println("Got CID: ", c)
|
||||
```
|
||||
|
||||
#### Creating a CID from scratch
|
||||
|
||||
```go
|
||||
// Create a cid manually by specifying the 'prefix' parameters
|
||||
pref := cid.Prefix{
|
||||
Version: 1,
|
||||
Codec: cid.Raw,
|
||||
MhType: mh.SHA2_256,
|
||||
MhLength: -1, // default length
|
||||
}
|
||||
|
||||
// And then feed it some data
|
||||
c, err := pref.Sum([]byte("Hello World!"))
|
||||
if err != nil {...}
|
||||
|
||||
fmt.Println("Created CID: ", c)
|
||||
```
|
||||
|
||||
#### Check if two CIDs match
|
||||
|
||||
```go
|
||||
// To test if two cid's are equivalent, be sure to use the 'Equals' method:
|
||||
if c1.Equals(c2) {
|
||||
fmt.Println("These two refer to the same exact data!")
|
||||
}
|
||||
```
|
||||
|
||||
#### Check if some data matches a given CID
|
||||
|
||||
```go
|
||||
// To check if some data matches a given cid,
|
||||
// Get your CIDs prefix, and use that to sum the data in question:
|
||||
other, err := c.Prefix().Sum(mydata)
|
||||
if err != nil {...}
|
||||
|
||||
if !c.Equals(other) {
|
||||
fmt.Println("This data is different.")
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Contribute
|
||||
|
||||
PRs are welcome!
|
||||
|
||||
Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
|
||||
|
||||
## License
|
||||
|
||||
MIT © Jeromy Johnson
|
74
vendor/github.com/ipfs/go-cid/builder.go
generated
vendored
Normal file
74
vendor/github.com/ipfs/go-cid/builder.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
package cid
|
||||
|
||||
import (
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
type Builder interface {
|
||||
Sum(data []byte) (Cid, error)
|
||||
GetCodec() uint64
|
||||
WithCodec(uint64) Builder
|
||||
}
|
||||
|
||||
type V0Builder struct{}
|
||||
|
||||
type V1Builder struct {
|
||||
Codec uint64
|
||||
MhType uint64
|
||||
MhLength int // MhLength <= 0 means the default length
|
||||
}
|
||||
|
||||
func (p Prefix) GetCodec() uint64 {
|
||||
return p.Codec
|
||||
}
|
||||
|
||||
func (p Prefix) WithCodec(c uint64) Builder {
|
||||
if c == p.Codec {
|
||||
return p
|
||||
}
|
||||
p.Codec = c
|
||||
if c != DagProtobuf {
|
||||
p.Version = 1
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p V0Builder) Sum(data []byte) (Cid, error) {
|
||||
hash, err := mh.Sum(data, mh.SHA2_256, -1)
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
return Cid{string(hash)}, nil
|
||||
}
|
||||
|
||||
func (p V0Builder) GetCodec() uint64 {
|
||||
return DagProtobuf
|
||||
}
|
||||
|
||||
func (p V0Builder) WithCodec(c uint64) Builder {
|
||||
if c == DagProtobuf {
|
||||
return p
|
||||
}
|
||||
return V1Builder{Codec: c, MhType: mh.SHA2_256}
|
||||
}
|
||||
|
||||
func (p V1Builder) Sum(data []byte) (Cid, error) {
|
||||
mhLen := p.MhLength
|
||||
if mhLen <= 0 {
|
||||
mhLen = -1
|
||||
}
|
||||
hash, err := mh.Sum(data, p.MhType, mhLen)
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
return NewCidV1(p.Codec, hash), nil
|
||||
}
|
||||
|
||||
func (p V1Builder) GetCodec() uint64 {
|
||||
return p.Codec
|
||||
}
|
||||
|
||||
func (p V1Builder) WithCodec(c uint64) Builder {
|
||||
p.Codec = c
|
||||
return p
|
||||
}
|
677
vendor/github.com/ipfs/go-cid/cid.go
generated
vendored
Normal file
677
vendor/github.com/ipfs/go-cid/cid.go
generated
vendored
Normal file
@ -0,0 +1,677 @@
|
||||
// Package cid implements the Content-IDentifiers specification
|
||||
// (https://github.com/ipld/cid) in Go. CIDs are
|
||||
// self-describing content-addressed identifiers useful for
|
||||
// distributed information systems. CIDs are used in the IPFS
|
||||
// (https://ipfs.io) project ecosystem.
|
||||
//
|
||||
// CIDs have two major versions. A CIDv0 corresponds to a multihash of type
|
||||
// DagProtobuf, is deprecated and exists for compatibility reasons. Usually,
|
||||
// CIDv1 should be used.
|
||||
//
|
||||
// A CIDv1 has four parts:
|
||||
//
|
||||
// <cidv1> ::= <multibase-prefix><cid-version><multicodec-packed-content-type><multihash-content-address>
|
||||
//
|
||||
// As shown above, the CID implementation relies heavily on Multiformats,
|
||||
// particularly Multibase
|
||||
// (https://github.com/multiformats/go-multibase), Multicodec
|
||||
// (https://github.com/multiformats/multicodec) and Multihash
|
||||
// implementations (https://github.com/multiformats/go-multihash).
|
||||
package cid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
mbase "github.com/multiformats/go-multibase"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
varint "github.com/multiformats/go-varint"
|
||||
)
|
||||
|
||||
// UnsupportedVersionString just holds an error message
|
||||
const UnsupportedVersionString = "<unsupported cid version>"
|
||||
|
||||
var (
|
||||
// ErrCidTooShort means that the cid passed to decode was not long
|
||||
// enough to be a valid Cid
|
||||
ErrCidTooShort = errors.New("cid too short")
|
||||
|
||||
// ErrInvalidEncoding means that selected encoding is not supported
|
||||
// by this Cid version
|
||||
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
|
||||
const (
|
||||
Raw = 0x55
|
||||
|
||||
DagProtobuf = 0x70
|
||||
DagCBOR = 0x71
|
||||
Libp2pKey = 0x72
|
||||
|
||||
GitRaw = 0x78
|
||||
|
||||
EthBlock = 0x90
|
||||
EthBlockList = 0x91
|
||||
EthTxTrie = 0x92
|
||||
EthTx = 0x93
|
||||
EthTxReceiptTrie = 0x94
|
||||
EthTxReceipt = 0x95
|
||||
EthStateTrie = 0x96
|
||||
EthAccountSnapshot = 0x97
|
||||
EthStorageTrie = 0x98
|
||||
BitcoinBlock = 0xb0
|
||||
BitcoinTx = 0xb1
|
||||
ZcashBlock = 0xc0
|
||||
ZcashTx = 0xc1
|
||||
DecredBlock = 0xe0
|
||||
DecredTx = 0xe1
|
||||
DashBlock = 0xf0
|
||||
DashTx = 0xf1
|
||||
FilCommitmentUnsealed = 0xf101
|
||||
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,
|
||||
}
|
||||
|
||||
// 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",
|
||||
}
|
||||
|
||||
// tryNewCidV0 tries to convert a multihash into a CIDv0 CID and returns an
|
||||
// error on failure.
|
||||
func tryNewCidV0(mhash mh.Multihash) (Cid, error) {
|
||||
// Need to make sure hash is valid for CidV0 otherwise we will
|
||||
// incorrectly detect it as CidV1 in the Version() method
|
||||
dec, err := mh.Decode(mhash)
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
if dec.Code != mh.SHA2_256 || dec.Length != 32 {
|
||||
return Undef, fmt.Errorf("invalid hash for cidv0 %d-%d", dec.Code, dec.Length)
|
||||
}
|
||||
return Cid{string(mhash)}, nil
|
||||
}
|
||||
|
||||
// NewCidV0 returns a Cid-wrapped multihash.
|
||||
// They exist to allow IPFS to work with Cids while keeping
|
||||
// compatibility with the plain-multihash format used used in IPFS.
|
||||
// NewCidV1 should be used preferentially.
|
||||
//
|
||||
// Panics if the multihash isn't sha2-256.
|
||||
func NewCidV0(mhash mh.Multihash) Cid {
|
||||
c, err := tryNewCidV0(mhash)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// NewCidV1 returns a new Cid using the given multicodec-packed
|
||||
// content type.
|
||||
//
|
||||
// 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)
|
||||
if cn != hashlen {
|
||||
panic("copy hash length is inconsistent")
|
||||
}
|
||||
|
||||
return Cid{string(buf[:n+hashlen])}
|
||||
}
|
||||
|
||||
var _ encoding.BinaryMarshaler = Cid{}
|
||||
var _ encoding.BinaryUnmarshaler = (*Cid)(nil)
|
||||
var _ encoding.TextMarshaler = Cid{}
|
||||
var _ encoding.TextUnmarshaler = (*Cid)(nil)
|
||||
|
||||
// Cid represents a self-describing content addressed
|
||||
// identifier. It is formed by a Version, a Codec (which indicates
|
||||
// a multicodec-packed content type) and a Multihash.
|
||||
type Cid struct{ str string }
|
||||
|
||||
// Undef can be used to represent a nil or undefined Cid, using Cid{}
|
||||
// directly is also acceptable.
|
||||
var Undef = Cid{}
|
||||
|
||||
// Defined returns true if a Cid is defined
|
||||
// Calling any other methods on an undefined Cid will result in
|
||||
// undefined behavior.
|
||||
func (c Cid) Defined() bool {
|
||||
return c.str != ""
|
||||
}
|
||||
|
||||
// Parse is a short-hand function to perform Decode, Cast etc... on
|
||||
// a generic interface{} type.
|
||||
func Parse(v interface{}) (Cid, error) {
|
||||
switch v2 := v.(type) {
|
||||
case string:
|
||||
if strings.Contains(v2, "/ipfs/") {
|
||||
return Decode(strings.Split(v2, "/ipfs/")[1])
|
||||
}
|
||||
return Decode(v2)
|
||||
case []byte:
|
||||
return Cast(v2)
|
||||
case mh.Multihash:
|
||||
return tryNewCidV0(v2)
|
||||
case Cid:
|
||||
return v2, nil
|
||||
default:
|
||||
return Undef, fmt.Errorf("can't parse %+v as Cid", v2)
|
||||
}
|
||||
}
|
||||
|
||||
// Decode parses a Cid-encoded string and returns a Cid object.
|
||||
// For CidV1, a Cid-encoded string is primarily a multibase string:
|
||||
//
|
||||
// <multibase-type-code><base-encoded-string>
|
||||
//
|
||||
// The base-encoded string represents a:
|
||||
//
|
||||
// <version><codec-type><multihash>
|
||||
//
|
||||
// Decode will also detect and parse CidV0 strings. Strings
|
||||
// starting with "Qm" are considered CidV0 and treated directly
|
||||
// as B58-encoded multihashes.
|
||||
func Decode(v string) (Cid, error) {
|
||||
if len(v) < 2 {
|
||||
return Undef, ErrCidTooShort
|
||||
}
|
||||
|
||||
if len(v) == 46 && v[:2] == "Qm" {
|
||||
hash, err := mh.FromB58String(v)
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
|
||||
return tryNewCidV0(hash)
|
||||
}
|
||||
|
||||
_, data, err := mbase.Decode(v)
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
|
||||
return Cast(data)
|
||||
}
|
||||
|
||||
// Extract the encoding from a Cid. If Decode on the same string did
|
||||
// not return an error neither will this function.
|
||||
func ExtractEncoding(v string) (mbase.Encoding, error) {
|
||||
if len(v) < 2 {
|
||||
return -1, ErrCidTooShort
|
||||
}
|
||||
|
||||
if len(v) == 46 && v[:2] == "Qm" {
|
||||
return mbase.Base58BTC, nil
|
||||
}
|
||||
|
||||
encoding := mbase.Encoding(v[0])
|
||||
|
||||
// check encoding is valid
|
||||
_, err := mbase.NewEncoder(encoding)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return encoding, nil
|
||||
}
|
||||
|
||||
// Cast takes a Cid data slice, parses it and returns a Cid.
|
||||
// For CidV1, the data buffer is in the form:
|
||||
//
|
||||
// <version><codec-type><multihash>
|
||||
//
|
||||
// CidV0 are also supported. In particular, data buffers starting
|
||||
// with length 34 bytes, which starts with bytes [18,32...] are considered
|
||||
// binary multihashes.
|
||||
//
|
||||
// Please use decode when parsing a regular Cid string, as Cast does not
|
||||
// expect multibase-encoded data. Cast accepts the output of Cid.Bytes().
|
||||
func Cast(data []byte) (Cid, error) {
|
||||
nr, c, err := CidFromBytes(data)
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
|
||||
if nr != len(data) {
|
||||
return Undef, fmt.Errorf("trailing bytes in data buffer passed to cid Cast")
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary is equivalent to Cast(). It implements the
|
||||
// encoding.BinaryUnmarshaler interface.
|
||||
func (c *Cid) UnmarshalBinary(data []byte) error {
|
||||
casted, err := Cast(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.str = casted.str
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText is equivalent to Decode(). It implements the
|
||||
// encoding.TextUnmarshaler interface.
|
||||
func (c *Cid) UnmarshalText(text []byte) error {
|
||||
decodedCid, err := Decode(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.str = decodedCid.str
|
||||
return nil
|
||||
}
|
||||
|
||||
// Version returns the Cid version.
|
||||
func (c Cid) Version() uint64 {
|
||||
if len(c.str) == 34 && c.str[0] == 18 && c.str[1] == 32 {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// Type returns the multicodec-packed content type of a Cid.
|
||||
func (c Cid) Type() uint64 {
|
||||
if c.Version() == 0 {
|
||||
return DagProtobuf
|
||||
}
|
||||
_, n, _ := uvarint(c.str)
|
||||
codec, _, _ := uvarint(c.str[n:])
|
||||
return codec
|
||||
}
|
||||
|
||||
// String returns the default string representation of a
|
||||
// Cid. Currently, Base32 is used for CIDV1 as the encoding for the
|
||||
// multibase string, Base58 is used for CIDV0.
|
||||
func (c Cid) String() string {
|
||||
switch c.Version() {
|
||||
case 0:
|
||||
return c.Hash().B58String()
|
||||
case 1:
|
||||
mbstr, err := mbase.Encode(mbase.Base32, c.Bytes())
|
||||
if err != nil {
|
||||
panic("should not error with hardcoded mbase: " + err.Error())
|
||||
}
|
||||
|
||||
return mbstr
|
||||
default:
|
||||
panic("not possible to reach this point")
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the string representation of a Cid
|
||||
// encoded is selected base
|
||||
func (c Cid) StringOfBase(base mbase.Encoding) (string, error) {
|
||||
switch c.Version() {
|
||||
case 0:
|
||||
if base != mbase.Base58BTC {
|
||||
return "", ErrInvalidEncoding
|
||||
}
|
||||
return c.Hash().B58String(), nil
|
||||
case 1:
|
||||
return mbase.Encode(base, c.Bytes())
|
||||
default:
|
||||
panic("not possible to reach this point")
|
||||
}
|
||||
}
|
||||
|
||||
// Encode return the string representation of a Cid in a given base
|
||||
// when applicable. Version 0 Cid's are always in Base58 as they do
|
||||
// not take a multibase prefix.
|
||||
func (c Cid) Encode(base mbase.Encoder) string {
|
||||
switch c.Version() {
|
||||
case 0:
|
||||
return c.Hash().B58String()
|
||||
case 1:
|
||||
return base.Encode(c.Bytes())
|
||||
default:
|
||||
panic("not possible to reach this point")
|
||||
}
|
||||
}
|
||||
|
||||
// Hash returns the multihash contained by a Cid.
|
||||
func (c Cid) Hash() mh.Multihash {
|
||||
bytes := c.Bytes()
|
||||
|
||||
if c.Version() == 0 {
|
||||
return mh.Multihash(bytes)
|
||||
}
|
||||
|
||||
// skip version length
|
||||
_, n1, _ := varint.FromUvarint(bytes)
|
||||
// skip codec length
|
||||
_, n2, _ := varint.FromUvarint(bytes[n1:])
|
||||
|
||||
return mh.Multihash(bytes[n1+n2:])
|
||||
}
|
||||
|
||||
// Bytes returns the byte representation of a Cid.
|
||||
// The output of bytes can be parsed back into a Cid
|
||||
// with Cast().
|
||||
func (c Cid) Bytes() []byte {
|
||||
return []byte(c.str)
|
||||
}
|
||||
|
||||
// ByteLen returns the length of the CID in bytes.
|
||||
// It's equivalent to `len(c.Bytes())`, but works without an allocation,
|
||||
// and should therefore be preferred.
|
||||
//
|
||||
// (See also the WriteTo method for other important operations that work without allocation.)
|
||||
func (c Cid) ByteLen() int {
|
||||
return len(c.str)
|
||||
}
|
||||
|
||||
// WriteBytes writes the CID bytes to the given writer.
|
||||
// This method works without incurring any allocation.
|
||||
//
|
||||
// (See also the ByteLen method for other important operations that work without allocation.)
|
||||
func (c Cid) WriteBytes(w io.Writer) (int, error) {
|
||||
n, err := io.WriteString(w, c.str)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
if n != len(c.str) {
|
||||
return n, fmt.Errorf("failed to write entire cid string")
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// MarshalBinary is equivalent to Bytes(). It implements the
|
||||
// encoding.BinaryMarshaler interface.
|
||||
func (c Cid) MarshalBinary() ([]byte, error) {
|
||||
return c.Bytes(), nil
|
||||
}
|
||||
|
||||
// MarshalText is equivalent to String(). It implements the
|
||||
// encoding.TextMarshaler interface.
|
||||
func (c Cid) MarshalText() ([]byte, error) {
|
||||
return []byte(c.String()), nil
|
||||
}
|
||||
|
||||
// Equals checks that two Cids are the same.
|
||||
// In order for two Cids to be considered equal, the
|
||||
// Version, the Codec and the Multihash must match.
|
||||
func (c Cid) Equals(o Cid) bool {
|
||||
return c == o
|
||||
}
|
||||
|
||||
// UnmarshalJSON parses the JSON representation of a Cid.
|
||||
func (c *Cid) UnmarshalJSON(b []byte) error {
|
||||
if len(b) < 2 {
|
||||
return fmt.Errorf("invalid cid json blob")
|
||||
}
|
||||
obj := struct {
|
||||
CidTarget string `json:"/"`
|
||||
}{}
|
||||
objptr := &obj
|
||||
err := json.Unmarshal(b, &objptr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if objptr == nil {
|
||||
*c = Cid{}
|
||||
return nil
|
||||
}
|
||||
|
||||
if obj.CidTarget == "" {
|
||||
return fmt.Errorf("cid was incorrectly formatted")
|
||||
}
|
||||
|
||||
out, err := Decode(obj.CidTarget)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*c = out
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON procudes a JSON representation of a Cid, which looks as follows:
|
||||
//
|
||||
// { "/": "<cid-string>" }
|
||||
//
|
||||
// Note that this formatting comes from the IPLD specification
|
||||
// (https://github.com/ipld/specs/tree/master/ipld)
|
||||
func (c Cid) MarshalJSON() ([]byte, error) {
|
||||
if !c.Defined() {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return []byte(fmt.Sprintf("{\"/\":\"%s\"}", c.String())), nil
|
||||
}
|
||||
|
||||
// KeyString returns the binary representation of the Cid as a string
|
||||
func (c Cid) KeyString() string {
|
||||
return c.str
|
||||
}
|
||||
|
||||
// Loggable returns a Loggable (as defined by
|
||||
// https://godoc.org/github.com/ipfs/go-log).
|
||||
func (c Cid) Loggable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"cid": c,
|
||||
}
|
||||
}
|
||||
|
||||
// Prefix builds and returns a Prefix out of a Cid.
|
||||
func (c Cid) Prefix() Prefix {
|
||||
if c.Version() == 0 {
|
||||
return Prefix{
|
||||
MhType: mh.SHA2_256,
|
||||
MhLength: 32,
|
||||
Version: 0,
|
||||
Codec: DagProtobuf,
|
||||
}
|
||||
}
|
||||
|
||||
offset := 0
|
||||
version, n, _ := uvarint(c.str[offset:])
|
||||
offset += n
|
||||
codec, n, _ := uvarint(c.str[offset:])
|
||||
offset += n
|
||||
mhtype, n, _ := uvarint(c.str[offset:])
|
||||
offset += n
|
||||
mhlen, _, _ := uvarint(c.str[offset:])
|
||||
|
||||
return Prefix{
|
||||
MhType: mhtype,
|
||||
MhLength: int(mhlen),
|
||||
Version: version,
|
||||
Codec: codec,
|
||||
}
|
||||
}
|
||||
|
||||
// Prefix represents all the metadata of a Cid,
|
||||
// that is, the Version, the Codec, the Multihash type
|
||||
// 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
|
||||
type Prefix struct {
|
||||
Version uint64
|
||||
Codec uint64
|
||||
MhType uint64
|
||||
MhLength int
|
||||
}
|
||||
|
||||
// Sum uses the information in a prefix to perform a multihash.Sum()
|
||||
// and return a newly constructed Cid with the resulting multihash.
|
||||
func (p Prefix) Sum(data []byte) (Cid, error) {
|
||||
length := p.MhLength
|
||||
if p.MhType == mh.ID {
|
||||
length = -1
|
||||
}
|
||||
|
||||
if p.Version == 0 && (p.MhType != mh.SHA2_256 ||
|
||||
(p.MhLength != 32 && p.MhLength != -1)) {
|
||||
|
||||
return Undef, fmt.Errorf("invalid v0 prefix")
|
||||
}
|
||||
|
||||
hash, err := mh.Sum(data, p.MhType, length)
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
|
||||
switch p.Version {
|
||||
case 0:
|
||||
return NewCidV0(hash), nil
|
||||
case 1:
|
||||
return NewCidV1(p.Codec, hash), nil
|
||||
default:
|
||||
return Undef, fmt.Errorf("invalid cid version")
|
||||
}
|
||||
}
|
||||
|
||||
// Bytes returns a byte representation of a Prefix. It looks like:
|
||||
//
|
||||
// <version><codec><mh-type><mh-length>
|
||||
func (p Prefix) Bytes() []byte {
|
||||
size := varint.UvarintSize(p.Version)
|
||||
size += varint.UvarintSize(p.Codec)
|
||||
size += varint.UvarintSize(p.MhType)
|
||||
size += varint.UvarintSize(uint64(p.MhLength))
|
||||
|
||||
buf := make([]byte, size)
|
||||
n := varint.PutUvarint(buf, p.Version)
|
||||
n += varint.PutUvarint(buf[n:], p.Codec)
|
||||
n += varint.PutUvarint(buf[n:], p.MhType)
|
||||
n += varint.PutUvarint(buf[n:], uint64(p.MhLength))
|
||||
if n != size {
|
||||
panic("size mismatch")
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
// PrefixFromBytes parses a Prefix-byte representation onto a
|
||||
// Prefix.
|
||||
func PrefixFromBytes(buf []byte) (Prefix, error) {
|
||||
r := bytes.NewReader(buf)
|
||||
vers, err := varint.ReadUvarint(r)
|
||||
if err != nil {
|
||||
return Prefix{}, err
|
||||
}
|
||||
|
||||
codec, err := varint.ReadUvarint(r)
|
||||
if err != nil {
|
||||
return Prefix{}, err
|
||||
}
|
||||
|
||||
mhtype, err := varint.ReadUvarint(r)
|
||||
if err != nil {
|
||||
return Prefix{}, err
|
||||
}
|
||||
|
||||
mhlen, err := varint.ReadUvarint(r)
|
||||
if err != nil {
|
||||
return Prefix{}, err
|
||||
}
|
||||
|
||||
return Prefix{
|
||||
Version: vers,
|
||||
Codec: codec,
|
||||
MhType: mhtype,
|
||||
MhLength: int(mhlen),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func CidFromBytes(data []byte) (int, Cid, error) {
|
||||
if len(data) > 2 && data[0] == mh.SHA2_256 && data[1] == 32 {
|
||||
if len(data) < 34 {
|
||||
return 0, Undef, fmt.Errorf("not enough bytes for cid v0")
|
||||
}
|
||||
|
||||
h, err := mh.Cast(data[:34])
|
||||
if err != nil {
|
||||
return 0, Undef, err
|
||||
}
|
||||
|
||||
return 34, Cid{string(h)}, nil
|
||||
}
|
||||
|
||||
vers, n, err := varint.FromUvarint(data)
|
||||
if err != nil {
|
||||
return 0, Undef, err
|
||||
}
|
||||
|
||||
if vers != 1 {
|
||||
return 0, Undef, fmt.Errorf("expected 1 as the cid version number, got: %d", vers)
|
||||
}
|
||||
|
||||
_, cn, err := varint.FromUvarint(data[n:])
|
||||
if err != nil {
|
||||
return 0, Undef, err
|
||||
}
|
||||
|
||||
mhnr, _, err := mh.MHFromBytes(data[n+cn:])
|
||||
if err != nil {
|
||||
return 0, Undef, err
|
||||
}
|
||||
|
||||
l := n + cn + mhnr
|
||||
|
||||
return l, Cid{string(data[0:l])}, nil
|
||||
}
|
37
vendor/github.com/ipfs/go-cid/cid_fuzz.go
generated
vendored
Normal file
37
vendor/github.com/ipfs/go-cid/cid_fuzz.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
// +build gofuzz
|
||||
|
||||
package cid
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
cid, err := Cast(data)
|
||||
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
_ = cid.Bytes()
|
||||
_ = cid.String()
|
||||
p := cid.Prefix()
|
||||
_ = p.Bytes()
|
||||
|
||||
if !cid.Equals(cid) {
|
||||
panic("inequality")
|
||||
}
|
||||
|
||||
// json loop
|
||||
json, err := cid.MarshalJSON()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
cid2 := Cid{}
|
||||
err = cid2.UnmarshalJSON(json)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
if !cid.Equals(cid2) {
|
||||
panic("json loop not equal")
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
3
vendor/github.com/ipfs/go-cid/codecov.yml
generated
vendored
Normal file
3
vendor/github.com/ipfs/go-cid/codecov.yml
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
coverage:
|
||||
range: "50...100"
|
||||
comment: off
|
28
vendor/github.com/ipfs/go-cid/deprecated.go
generated
vendored
Normal file
28
vendor/github.com/ipfs/go-cid/deprecated.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
package cid
|
||||
|
||||
import (
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
// NewPrefixV0 returns a CIDv0 prefix with the specified multihash type.
|
||||
// DEPRECATED: Use V0Builder
|
||||
func NewPrefixV0(mhType uint64) Prefix {
|
||||
return Prefix{
|
||||
MhType: mhType,
|
||||
MhLength: mh.DefaultLengths[mhType],
|
||||
Version: 0,
|
||||
Codec: DagProtobuf,
|
||||
}
|
||||
}
|
||||
|
||||
// NewPrefixV1 returns a CIDv1 prefix with the specified codec and multihash
|
||||
// type.
|
||||
// DEPRECATED: Use V1Builder
|
||||
func NewPrefixV1(codecType uint64, mhType uint64) Prefix {
|
||||
return Prefix{
|
||||
MhType: mhType,
|
||||
MhLength: mh.DefaultLengths[mhType],
|
||||
Version: 1,
|
||||
Codec: codecType,
|
||||
}
|
||||
}
|
9
vendor/github.com/ipfs/go-cid/go.mod
generated
vendored
Normal file
9
vendor/github.com/ipfs/go-cid/go.mod
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
module github.com/ipfs/go-cid
|
||||
|
||||
require (
|
||||
github.com/multiformats/go-multibase v0.0.3
|
||||
github.com/multiformats/go-multihash v0.0.13
|
||||
github.com/multiformats/go-varint v0.0.5
|
||||
)
|
||||
|
||||
go 1.13
|
28
vendor/github.com/ipfs/go-cid/go.sum
generated
vendored
Normal file
28
vendor/github.com/ipfs/go-cid/go.sum
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
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.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo=
|
||||
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ=
|
||||
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
|
||||
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
|
||||
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
|
||||
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
|
||||
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
|
||||
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
|
||||
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-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
|
||||
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
|
||||
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
|
||||
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
65
vendor/github.com/ipfs/go-cid/set.go
generated
vendored
Normal file
65
vendor/github.com/ipfs/go-cid/set.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
package cid
|
||||
|
||||
// Set is a implementation of a set of Cids, that is, a structure
|
||||
// to which holds a single copy of every Cids that is added to it.
|
||||
type Set struct {
|
||||
set map[Cid]struct{}
|
||||
}
|
||||
|
||||
// NewSet initializes and returns a new Set.
|
||||
func NewSet() *Set {
|
||||
return &Set{set: make(map[Cid]struct{})}
|
||||
}
|
||||
|
||||
// Add puts a Cid in the Set.
|
||||
func (s *Set) Add(c Cid) {
|
||||
s.set[c] = struct{}{}
|
||||
}
|
||||
|
||||
// Has returns if the Set contains a given Cid.
|
||||
func (s *Set) Has(c Cid) bool {
|
||||
_, ok := s.set[c]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Remove deletes a Cid from the Set.
|
||||
func (s *Set) Remove(c Cid) {
|
||||
delete(s.set, c)
|
||||
}
|
||||
|
||||
// Len returns how many elements the Set has.
|
||||
func (s *Set) Len() int {
|
||||
return len(s.set)
|
||||
}
|
||||
|
||||
// Keys returns the Cids in the set.
|
||||
func (s *Set) Keys() []Cid {
|
||||
out := make([]Cid, 0, len(s.set))
|
||||
for k := range s.set {
|
||||
out = append(out, k)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Visit adds a Cid to the set only if it is
|
||||
// not in it already.
|
||||
func (s *Set) Visit(c Cid) bool {
|
||||
if !s.Has(c) {
|
||||
s.Add(c)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ForEach allows to run a custom function on each
|
||||
// Cid in the set.
|
||||
func (s *Set) ForEach(f func(c Cid) error) error {
|
||||
for c := range s.set {
|
||||
err := f(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
40
vendor/github.com/ipfs/go-cid/varint.go
generated
vendored
Normal file
40
vendor/github.com/ipfs/go-cid/varint.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package cid
|
||||
|
||||
import (
|
||||
"github.com/multiformats/go-varint"
|
||||
)
|
||||
|
||||
// Version of varint function that work with a string rather than
|
||||
// []byte to avoid unnecessary allocation
|
||||
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license as given at https://golang.org/LICENSE
|
||||
|
||||
// uvarint decodes a uint64 from buf and returns that value and the
|
||||
// number of characters read (> 0). If an error occurred, the value is 0
|
||||
// and the number of bytes n is <= 0 meaning:
|
||||
//
|
||||
// n == 0: buf too small
|
||||
// n < 0: value larger than 64 bits (overflow)
|
||||
// and -n is the number of bytes read
|
||||
//
|
||||
func uvarint(buf string) (uint64, int, error) {
|
||||
var x uint64
|
||||
var s uint
|
||||
// we have a binary string so we can't use a range loope
|
||||
for i := 0; i < len(buf); i++ {
|
||||
b := buf[i]
|
||||
if b < 0x80 {
|
||||
if i > 9 || i == 9 && b > 1 {
|
||||
return 0, 0, varint.ErrOverflow
|
||||
} else if b == 0 && i > 0 {
|
||||
return 0, 0, varint.ErrNotMinimal
|
||||
}
|
||||
return x | uint64(b)<<s, i + 1, nil
|
||||
}
|
||||
x |= uint64(b&0x7f) << s
|
||||
s += 7
|
||||
}
|
||||
return 0, 0, varint.ErrUnderflow
|
||||
}
|
43
vendor/github.com/ipfs/go-ipfs-api/.travis.yml
generated
vendored
Normal file
43
vendor/github.com/ipfs/go-ipfs-api/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
os:
|
||||
- linux
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.13.x
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
env:
|
||||
global:
|
||||
- GO111MODULE=on
|
||||
- GOTFLAGS="-race"
|
||||
- IPFS_PATH=/tmp/ipfs
|
||||
matrix:
|
||||
- BUILD_DEPTYPE=gomod
|
||||
|
||||
before_install:
|
||||
- docker pull ipfs/go-ipfs:master
|
||||
- mkdir /tmp/ipfs && chmod 0777 /tmp/ipfs
|
||||
- docker run -d -v /tmp/ipfs:/data/ipfs -p 8080:8080 -p 4001:4001 -p 5001:5001 ipfs/go-ipfs:master "daemon" "--enable-namesys-pubsub"
|
||||
|
||||
install:
|
||||
- go mod download
|
||||
|
||||
before_script:
|
||||
- go vet ./...
|
||||
|
||||
script:
|
||||
- go get -d github.com/cheekybits/is/... # remove with gx
|
||||
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)
|
||||
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $GOPATH/src/gx
|
||||
- $GOPATH/pkg/mod
|
||||
- $HOME/.cache/go-build
|
||||
|
||||
notifications:
|
||||
email: false
|
21
vendor/github.com/ipfs/go-ipfs-api/LICENSE
generated
vendored
Normal file
21
vendor/github.com/ipfs/go-ipfs-api/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Jeromy Johnson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
65
vendor/github.com/ipfs/go-ipfs-api/README.md
generated
vendored
Normal file
65
vendor/github.com/ipfs/go-ipfs-api/README.md
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
# go-ipfs-api
|
||||
|
||||
[](http://ipn.io)
|
||||
[](http://ipfs.io/)
|
||||
[](http://webchat.freenode.net/?channels=%23ipfs)
|
||||
[](https://github.com/RichardLitt/standard-readme)
|
||||
[](https://godoc.org/github.com/ipfs/go-ipfs-api)
|
||||
[](https://travis-ci.org/ipfs/go-ipfs-api)
|
||||
|
||||

|
||||
|
||||
> The go interface to ipfs's HTTP API
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
go get -u github.com/ipfs/go-ipfs-api
|
||||
```
|
||||
|
||||
This will download the source into `$GOPATH/src/github.com/ipfs/go-ipfs-api`.
|
||||
|
||||
## Usage
|
||||
|
||||
See [the godocs](https://godoc.org/github.com/ipfs/go-ipfs-api) for details on available methods. This should match the specs at [ipfs/specs](https://github.com/ipfs/specs/tree/master/public-api); however, there are still some methods which are not accounted for. If you would like to add any of them, see the contribute section below.
|
||||
|
||||
### Example
|
||||
|
||||
Add a file with the contents "hello world!":
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"os"
|
||||
|
||||
shell "github.com/ipfs/go-ipfs-api"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Where your local node is running on localhost:5001
|
||||
sh := shell.NewShell("localhost:5001")
|
||||
cid, err := sh.Add(strings.NewReader("hello world!"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("added %s", cid)
|
||||
}
|
||||
```
|
||||
|
||||
For a more complete example, please see: https://github.com/ipfs/go-ipfs-api/blob/master/tests/main.go
|
||||
|
||||
## Contribute
|
||||
|
||||
Contributions are welcome! Please check out the [issues](https://github.com/ipfs/go-ipfs-api/issues).
|
||||
|
||||
### Want to hack on IPFS?
|
||||
|
||||
[](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
145
vendor/github.com/ipfs/go-ipfs-api/add.go
generated
vendored
Normal file
145
vendor/github.com/ipfs/go-ipfs-api/add.go
generated
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
)
|
||||
|
||||
type object struct {
|
||||
Hash string
|
||||
}
|
||||
|
||||
type AddOpts = func(*RequestBuilder) error
|
||||
|
||||
func OnlyHash(enabled bool) AddOpts {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("only-hash", enabled)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func Pin(enabled bool) AddOpts {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("pin", enabled)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func Progress(enabled bool) AddOpts {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("progress", enabled)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func RawLeaves(enabled bool) AddOpts {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("raw-leaves", enabled)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Hash allows for selecting the multihash type
|
||||
func Hash(hash string) AddOpts {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("hash", hash)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CidVersion allows for selecting the CID version that ipfs should use.
|
||||
func CidVersion(version int) AddOpts {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("cid-version", version)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Shell) Add(r io.Reader, options ...AddOpts) (string, error) {
|
||||
fr := files.NewReaderFile(r)
|
||||
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)})
|
||||
fileReader := files.NewMultiFileReader(slf, true)
|
||||
|
||||
var out object
|
||||
rb := s.Request("add")
|
||||
for _, option := range options {
|
||||
option(rb)
|
||||
}
|
||||
return out.Hash, rb.Body(fileReader).Exec(context.Background(), &out)
|
||||
}
|
||||
|
||||
// AddNoPin adds a file to ipfs without pinning it
|
||||
// Deprecated: Use Add() with option functions instead
|
||||
func (s *Shell) AddNoPin(r io.Reader) (string, error) {
|
||||
return s.Add(r, Pin(false))
|
||||
}
|
||||
|
||||
// AddWithOpts adds a file to ipfs with some additional options
|
||||
// Deprecated: Use Add() with option functions instead
|
||||
func (s *Shell) AddWithOpts(r io.Reader, pin bool, rawLeaves bool) (string, error) {
|
||||
return s.Add(r, Pin(pin), RawLeaves(rawLeaves))
|
||||
}
|
||||
|
||||
func (s *Shell) AddLink(target string) (string, error) {
|
||||
link := files.NewLinkFile(target, nil)
|
||||
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", link)})
|
||||
reader := files.NewMultiFileReader(slf, true)
|
||||
|
||||
var out object
|
||||
return out.Hash, s.Request("add").Body(reader).Exec(context.Background(), &out)
|
||||
}
|
||||
|
||||
// AddDir adds a directory recursively with all of the files under it
|
||||
func (s *Shell) AddDir(dir string) (string, error) {
|
||||
stat, err := os.Lstat(dir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sf, err := files.NewSerialFile(dir, false, stat)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry(filepath.Base(dir), sf)})
|
||||
reader := files.NewMultiFileReader(slf, true)
|
||||
|
||||
resp, err := s.Request("add").
|
||||
Option("recursive", true).
|
||||
Body(reader).
|
||||
Send(context.Background())
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
defer resp.Close()
|
||||
|
||||
if resp.Error != nil {
|
||||
return "", resp.Error
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(resp.Output)
|
||||
var final string
|
||||
for {
|
||||
var out object
|
||||
err = dec.Decode(&out)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
final = out.Hash
|
||||
}
|
||||
|
||||
if final == "" {
|
||||
return "", errors.New("no results received")
|
||||
}
|
||||
|
||||
return final, nil
|
||||
}
|
27
vendor/github.com/ipfs/go-ipfs-api/bootstrap.go
generated
vendored
Normal file
27
vendor/github.com/ipfs/go-ipfs-api/bootstrap.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type PeersList struct {
|
||||
Peers []string
|
||||
}
|
||||
|
||||
func (s *Shell) BootstrapAdd(peers []string) ([]string, error) {
|
||||
var addOutput PeersList
|
||||
err := s.Request("bootstrap/add", peers...).Exec(context.Background(), &addOutput)
|
||||
return addOutput.Peers, err
|
||||
}
|
||||
|
||||
func (s *Shell) BootstrapAddDefault() ([]string, error) {
|
||||
var addOutput PeersList
|
||||
err := s.Request("bootstrap/add/default").Exec(context.Background(), &addOutput)
|
||||
return addOutput.Peers, err
|
||||
}
|
||||
|
||||
func (s *Shell) BootstrapRmAll() ([]string, error) {
|
||||
var rmAllOutput PeersList
|
||||
err := s.Request("bootstrap/rm/all").Exec(context.Background(), &rmAllOutput)
|
||||
return rmAllOutput.Peers, err
|
||||
}
|
58
vendor/github.com/ipfs/go-ipfs-api/dag.go
generated
vendored
Normal file
58
vendor/github.com/ipfs/go-ipfs-api/dag.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/ipfs/go-ipfs-api/options"
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
)
|
||||
|
||||
func (s *Shell) DagGet(ref string, out interface{}) error {
|
||||
return s.Request("dag/get", ref).Exec(context.Background(), out)
|
||||
}
|
||||
|
||||
func (s *Shell) DagPut(data interface{}, ienc, kind string) (string, error) {
|
||||
return s.DagPutWithOpts(data, options.Dag.InputEnc(ienc), options.Dag.Kind(kind))
|
||||
}
|
||||
|
||||
func (s *Shell) DagPutWithOpts(data interface{}, opts ...options.DagPutOption) (string, error) {
|
||||
cfg, err := options.DagPutOptions(opts...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var r io.Reader
|
||||
switch data := data.(type) {
|
||||
case string:
|
||||
r = strings.NewReader(data)
|
||||
case []byte:
|
||||
r = bytes.NewReader(data)
|
||||
case io.Reader:
|
||||
r = data
|
||||
default:
|
||||
return "", fmt.Errorf("cannot current handle putting values of type %T", data)
|
||||
}
|
||||
|
||||
fr := files.NewReaderFile(r)
|
||||
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)})
|
||||
fileReader := files.NewMultiFileReader(slf, true)
|
||||
|
||||
var out struct {
|
||||
Cid struct {
|
||||
Target string `json:"/"`
|
||||
}
|
||||
}
|
||||
|
||||
return out.Cid.Target, s.
|
||||
Request("dag/put").
|
||||
Option("input-enc", cfg.InputEnc).
|
||||
Option("format", cfg.Kind).
|
||||
Option("pin", cfg.Pin).
|
||||
Option("hash", cfg.Hash).
|
||||
Body(fileReader).
|
||||
Exec(context.Background(), &out)
|
||||
}
|
14
vendor/github.com/ipfs/go-ipfs-api/go.mod
generated
vendored
Normal file
14
vendor/github.com/ipfs/go-ipfs-api/go.mod
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
go 1.13
|
||||
|
||||
module github.com/ipfs/go-ipfs-api
|
||||
|
||||
require (
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927
|
||||
github.com/ipfs/go-ipfs-files v0.0.8
|
||||
github.com/ipfs/go-ipfs-util v0.0.2
|
||||
github.com/libp2p/go-libp2p-core v0.6.1
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/multiformats/go-multiaddr v0.3.0
|
||||
github.com/multiformats/go-multiaddr-net v0.2.0
|
||||
github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c
|
||||
)
|
157
vendor/github.com/ipfs/go-ipfs-api/go.sum
generated
vendored
Normal file
157
vendor/github.com/ipfs/go-ipfs-api/go.sum
generated
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 h1:SKI1/fuSdodxmNNyVBR8d7X/HuLnRpvvFO0AgyQk764=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg=
|
||||
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY=
|
||||
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
||||
github.com/ipfs/go-ipfs-files v0.0.8 h1:8o0oFJkJ8UkO/ABl8T6ac6tKF3+NIpj67aAB6ZpusRg=
|
||||
github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs=
|
||||
github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8=
|
||||
github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ=
|
||||
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
||||
github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o=
|
||||
github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
|
||||
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
|
||||
github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM=
|
||||
github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs=
|
||||
github.com/libp2p/go-libp2p-core v0.6.1 h1:XS+Goh+QegCDojUZp00CaPMfiEADCrLjNZskWE7pvqs=
|
||||
github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8=
|
||||
github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA=
|
||||
github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw=
|
||||
github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
|
||||
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.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo=
|
||||
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ=
|
||||
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
|
||||
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
|
||||
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
|
||||
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
|
||||
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
|
||||
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
|
||||
github.com/multiformats/go-multiaddr v0.2.2 h1:XZLDTszBIJe6m0zF6ITBrEcZR73OPUhCBBS9rYAuUzI=
|
||||
github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y=
|
||||
github.com/multiformats/go-multiaddr v0.3.0 h1:z1Old9IYcUyMEtSbvwCOJ1jcrmJdU0LYH8aFBvZKzcQ=
|
||||
github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI=
|
||||
github.com/multiformats/go-multiaddr-net v0.2.0 h1:MSXRGN0mFymt6B1yo/6BPnIRpLPEnKgQNvVfCX5VDJk=
|
||||
github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA=
|
||||
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-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
|
||||
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
|
||||
github.com/multiformats/go-multihash v0.0.14 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I=
|
||||
github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
|
||||
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
|
||||
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY=
|
||||
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
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/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
|
||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c h1:GGsyl0dZ2jJgVT+VvWBf/cNijrHRhkrTjkmp5wg7li0=
|
||||
github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c/go.mod h1:xxcJeBb7SIUl/Wzkz1eVKJE/CB34YNrqX2TQI6jY9zs=
|
||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ=
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
55
vendor/github.com/ipfs/go-ipfs-api/ipns.go
generated
vendored
Normal file
55
vendor/github.com/ipfs/go-ipfs-api/ipns.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PublishResponse struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Publish updates a mutable name to point to a given value
|
||||
func (s *Shell) Publish(node string, value string) error {
|
||||
var pubResp PublishResponse
|
||||
req := s.Request("name/publish")
|
||||
if node != "" {
|
||||
req.Arguments(node)
|
||||
}
|
||||
req.Arguments(value)
|
||||
|
||||
return req.Exec(context.Background(), &pubResp)
|
||||
}
|
||||
|
||||
// PublishWithDetails is used for fine grained control over record publishing
|
||||
func (s *Shell) PublishWithDetails(contentHash, key string, lifetime, ttl time.Duration, resolve bool) (*PublishResponse, error) {
|
||||
var pubResp PublishResponse
|
||||
req := s.Request("name/publish", contentHash).Option("resolve", resolve)
|
||||
if key != "" {
|
||||
req.Option("key", key)
|
||||
}
|
||||
if lifetime != 0 {
|
||||
req.Option("lifetime", lifetime)
|
||||
}
|
||||
if ttl.Seconds() > 0 {
|
||||
req.Option("ttl", ttl)
|
||||
}
|
||||
err := req.Exec(context.Background(), &pubResp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pubResp, nil
|
||||
}
|
||||
|
||||
// Resolve gets resolves the string provided to an /ipns/[name]. If asked to
|
||||
// resolve an empty string, resolve instead resolves the node's own /ipns value.
|
||||
func (s *Shell) Resolve(id string) (string, error) {
|
||||
req := s.Request("name/resolve")
|
||||
if id != "" {
|
||||
req.Arguments(id)
|
||||
}
|
||||
var out struct{ Path string }
|
||||
err := req.Exec(context.Background(), &out)
|
||||
return out.Path, err
|
||||
}
|
84
vendor/github.com/ipfs/go-ipfs-api/key.go
generated
vendored
Normal file
84
vendor/github.com/ipfs/go-ipfs-api/key.go
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
package shell
|
||||
|
||||
import "context"
|
||||
|
||||
type Key struct {
|
||||
Id string
|
||||
Name string
|
||||
}
|
||||
|
||||
type KeyRenameObject struct {
|
||||
Id string
|
||||
Now string
|
||||
Overwrite bool
|
||||
Was string
|
||||
}
|
||||
|
||||
type keyListOutput struct {
|
||||
Keys []*Key
|
||||
}
|
||||
|
||||
type KeyOpt func(*RequestBuilder) error
|
||||
type keyGen struct{}
|
||||
|
||||
var KeyGen keyGen
|
||||
|
||||
func (keyGen) Type(alg string) KeyOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("type", alg)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (keyGen) Size(size int) KeyOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("size", size)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// KeyGen Create a new keypair
|
||||
func (s *Shell) KeyGen(ctx context.Context, name string, options ...KeyOpt) (*Key, error) {
|
||||
rb := s.Request("key/gen", name)
|
||||
for _, opt := range options {
|
||||
if err := opt(rb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var out Key
|
||||
if err := rb.Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
// KeyList List all local keypairs
|
||||
func (s *Shell) KeyList(ctx context.Context) ([]*Key, error) {
|
||||
var out keyListOutput
|
||||
if err := s.Request("key/list").Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out.Keys, nil
|
||||
}
|
||||
|
||||
// KeyRename Rename a keypair
|
||||
func (s *Shell) KeyRename(ctx context.Context, old string, new string, force bool) (*KeyRenameObject, error) {
|
||||
var out KeyRenameObject
|
||||
if err := s.Request("key/rename", old, new).
|
||||
Option("force", force).
|
||||
Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
// KeyRm remove a keypair
|
||||
func (s *Shell) KeyRm(ctx context.Context, name string) ([]*Key, error) {
|
||||
var out keyListOutput
|
||||
if err := s.Request("key/rm", name).
|
||||
Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out.Keys, nil
|
||||
}
|
41
vendor/github.com/ipfs/go-ipfs-api/logger.go
generated
vendored
Normal file
41
vendor/github.com/ipfs/go-ipfs-api/logger.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Logger is used to handle incoming logs from the ipfs node
|
||||
type Logger struct {
|
||||
resp io.ReadCloser
|
||||
dec *json.Decoder
|
||||
}
|
||||
|
||||
// Next is used to retrieve the next event from the logging system
|
||||
func (l Logger) Next() (map[string]interface{}, error) {
|
||||
var out map[string]interface{}
|
||||
return out, l.dec.Decode(&out)
|
||||
}
|
||||
|
||||
// Close is used to close our reader
|
||||
func (l Logger) Close() error {
|
||||
return l.resp.Close()
|
||||
}
|
||||
|
||||
// GetLogs is used to retrieve a parsable logger object
|
||||
func (s *Shell) GetLogs(ctx context.Context) (Logger, error) {
|
||||
resp, err := s.Request("log/tail").Send(ctx)
|
||||
if err != nil {
|
||||
return Logger{}, err
|
||||
}
|
||||
if resp.Error != nil {
|
||||
resp.Output.Close()
|
||||
return Logger{}, resp.Error
|
||||
}
|
||||
return newLogger(resp.Output), nil
|
||||
}
|
||||
|
||||
func newLogger(resp io.ReadCloser) Logger {
|
||||
return Logger{resp, json.NewDecoder(resp)}
|
||||
}
|
335
vendor/github.com/ipfs/go-ipfs-api/mfs.go
generated
vendored
Normal file
335
vendor/github.com/ipfs/go-ipfs-api/mfs.go
generated
vendored
Normal file
@ -0,0 +1,335 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
)
|
||||
|
||||
type FilesOpt func(*RequestBuilder) error
|
||||
|
||||
type MfsLsEntry struct {
|
||||
Name string
|
||||
Type uint8
|
||||
Size uint64
|
||||
Hash string
|
||||
}
|
||||
|
||||
type FilesStatObject struct {
|
||||
Blocks int
|
||||
CumulativeSize uint64
|
||||
Hash string
|
||||
Local bool
|
||||
Size uint64
|
||||
SizeLocal uint64
|
||||
Type string
|
||||
WithLocality bool
|
||||
}
|
||||
|
||||
type filesLsOutput struct {
|
||||
Entries []*MfsLsEntry
|
||||
}
|
||||
|
||||
type filesFlushOutput struct {
|
||||
Cid string
|
||||
}
|
||||
|
||||
type filesLs struct{}
|
||||
type filesChcid struct{}
|
||||
type filesMkdir struct{}
|
||||
type filesRead struct{}
|
||||
type filesWrite struct{}
|
||||
type filesStat struct{}
|
||||
|
||||
var (
|
||||
FilesLs filesLs
|
||||
FilesChcid filesChcid
|
||||
FilesMkdir filesMkdir
|
||||
FilesRead filesRead
|
||||
FilesWrite filesWrite
|
||||
FilesStat filesStat
|
||||
)
|
||||
|
||||
// Stat use long listing format
|
||||
func (filesLs) Stat(long bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("long", long)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CidVersion cid version to use. (experimental)
|
||||
func (filesChcid) CidVersion(version int) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("cid-version", version)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Hash hash function to use. Will set Cid version to 1 if used. (experimental)
|
||||
func (filesChcid) Hash(hash string) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("hash", hash)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Parents no error if existing, make parent directories as needed
|
||||
func (filesMkdir) Parents(parents bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("parents", parents)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CidVersion cid version to use. (experimental)
|
||||
func (filesMkdir) CidVersion(version int) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("cid-version", version)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Hash hash function to use. Will set Cid version to 1 if used. (experimental)
|
||||
func (filesMkdir) Hash(hash string) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("hash", hash)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Offset byte offset to begin reading from
|
||||
func (filesRead) Offset(offset int64) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("offset", offset)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Count maximum number of bytes to read
|
||||
func (filesRead) Count(count int64) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("count", count)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Hash print only hash. Implies '--format=<hash>'. Conflicts with other format options.
|
||||
func (filesStat) Hash(hash bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("hash", hash)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Size print only size. Implies '--format=<cumulsize>'. Conflicts with other format options.
|
||||
func (filesStat) Size(size bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("size", size)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithLocal compute the amount of the dag that is local, and if possible the total size.
|
||||
func (filesStat) WithLocal(withLocal bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("with-local", withLocal)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Offset byte offset to begin writing at
|
||||
func (filesWrite) Offset(offset int64) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("offset", offset)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Create create the file if it does not exist
|
||||
func (filesWrite) Create(create bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("create", create)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Parents make parent directories as needed
|
||||
func (filesWrite) Parents(parents bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("parents", parents)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Truncate truncate the file to size zero before writing
|
||||
func (filesWrite) Truncate(truncate bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("truncate", truncate)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Count maximum number of bytes to write
|
||||
func (filesWrite) Count(count int64) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("count", count)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// RawLeaves use raw blocks for newly created leaf nodes. (experimental)
|
||||
func (filesWrite) RawLeaves(rawLeaves bool) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("raw-leaves", rawLeaves)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// CidVersion cid version to use. (experimental)
|
||||
func (filesWrite) CidVersion(version int) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("cid-version", version)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Hash hash function to use. Will set Cid version to 1 if used. (experimental)
|
||||
func (filesWrite) Hash(hash string) FilesOpt {
|
||||
return func(rb *RequestBuilder) error {
|
||||
rb.Option("hash", hash)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// FilesChcid change the cid version or hash function of the root node of a given path
|
||||
func (s *Shell) FilesChcid(ctx context.Context, path string, options ...FilesOpt) error {
|
||||
if len(path) == 0 {
|
||||
path = "/"
|
||||
}
|
||||
|
||||
rb := s.Request("files/chcid", path)
|
||||
for _, opt := range options {
|
||||
if err := opt(rb); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return rb.Exec(ctx, nil)
|
||||
}
|
||||
|
||||
// FilesCp copy any IPFS files and directories into MFS (or copy within MFS)
|
||||
func (s *Shell) FilesCp(ctx context.Context, src string, dest string) error {
|
||||
return s.Request("files/cp", src, dest).Exec(ctx, nil)
|
||||
}
|
||||
|
||||
// FilesFlush flush a given path's data to disk
|
||||
func (s *Shell) FilesFlush(ctx context.Context, path string) (string, error) {
|
||||
if len(path) == 0 {
|
||||
path = "/"
|
||||
}
|
||||
out := &filesFlushOutput{}
|
||||
if err := s.Request("files/flush", path).
|
||||
Exec(ctx, out); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return out.Cid, nil
|
||||
}
|
||||
|
||||
// FilesLs list directories in the local mutable namespace
|
||||
func (s *Shell) FilesLs(ctx context.Context, path string, options ...FilesOpt) ([]*MfsLsEntry, error) {
|
||||
if len(path) == 0 {
|
||||
path = "/"
|
||||
}
|
||||
|
||||
var out filesLsOutput
|
||||
rb := s.Request("files/ls", path)
|
||||
for _, opt := range options {
|
||||
if err := opt(rb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := rb.Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out.Entries, nil
|
||||
}
|
||||
|
||||
// FilesMkdir make directories
|
||||
func (s *Shell) FilesMkdir(ctx context.Context, path string, options ...FilesOpt) error {
|
||||
rb := s.Request("files/mkdir", path)
|
||||
for _, opt := range options {
|
||||
if err := opt(rb); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return rb.Exec(ctx, nil)
|
||||
}
|
||||
|
||||
// FilesMv move files
|
||||
func (s *Shell) FilesMv(ctx context.Context, src string, dest string) error {
|
||||
return s.Request("files/mv", src, dest).Exec(ctx, nil)
|
||||
}
|
||||
|
||||
// FilesRead read a file in a given MFS
|
||||
func (s *Shell) FilesRead(ctx context.Context, path string, options ...FilesOpt) (io.ReadCloser, error) {
|
||||
rb := s.Request("files/read", path)
|
||||
for _, opt := range options {
|
||||
if err := opt(rb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := rb.Send(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Error != nil {
|
||||
return nil, resp.Error
|
||||
}
|
||||
|
||||
return resp.Output, nil
|
||||
}
|
||||
|
||||
// FilesRm remove a file
|
||||
func (s *Shell) FilesRm(ctx context.Context, path string, force bool) error {
|
||||
return s.Request("files/rm", path).
|
||||
Option("force", force).
|
||||
Exec(ctx, nil)
|
||||
}
|
||||
|
||||
// FilesStat display file status
|
||||
func (s *Shell) FilesStat(ctx context.Context, path string, options ...FilesOpt) (*FilesStatObject, error) {
|
||||
out := &FilesStatObject{}
|
||||
|
||||
rb := s.Request("files/stat", path)
|
||||
for _, opt := range options {
|
||||
if err := opt(rb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := rb.Exec(ctx, out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// FilesWrite write to a mutable file in a given filesystem
|
||||
func (s *Shell) FilesWrite(ctx context.Context, path string, data io.Reader, options ...FilesOpt) error {
|
||||
fr := files.NewReaderFile(data)
|
||||
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)})
|
||||
fileReader := files.NewMultiFileReader(slf, true)
|
||||
|
||||
rb := s.Request("files/write", path)
|
||||
for _, opt := range options {
|
||||
if err := opt(rb); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return rb.Body(fileReader).Exec(ctx, nil)
|
||||
}
|
69
vendor/github.com/ipfs/go-ipfs-api/options/dag.go
generated
vendored
Normal file
69
vendor/github.com/ipfs/go-ipfs-api/options/dag.go
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
package options
|
||||
|
||||
// DagPutSettings is a set of DagPut options.
|
||||
type DagPutSettings struct {
|
||||
InputEnc string
|
||||
Kind string
|
||||
Pin string
|
||||
Hash string
|
||||
}
|
||||
|
||||
// DagPutOption is a single DagPut option.
|
||||
type DagPutOption func(opts *DagPutSettings) error
|
||||
|
||||
// DagPutOptions applies the given options to a DagPutSettings instance.
|
||||
func DagPutOptions(opts ...DagPutOption) (*DagPutSettings, error) {
|
||||
options := &DagPutSettings{
|
||||
InputEnc: "json",
|
||||
Kind: "cbor",
|
||||
Pin: "false",
|
||||
Hash: "sha2-256",
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
err := opt(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return options, nil
|
||||
}
|
||||
|
||||
type dagOpts struct{}
|
||||
|
||||
var Dag dagOpts
|
||||
|
||||
// Pin is an option for Dag.Put which specifies whether to pin the added
|
||||
// dags. Default is "false".
|
||||
func (dagOpts) Pin(pin string) DagPutOption {
|
||||
return func(opts *DagPutSettings) error {
|
||||
opts.Pin = pin
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// InputEnc is an option for Dag.Put which specifies the input encoding of the
|
||||
// data. Default is "json", most formats/codecs support "raw".
|
||||
func (dagOpts) InputEnc(enc string) DagPutOption {
|
||||
return func(opts *DagPutSettings) error {
|
||||
opts.InputEnc = enc
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Kind is an option for Dag.Put which specifies the format that the dag
|
||||
// will be added as. Default is "cbor".
|
||||
func (dagOpts) Kind(kind string) DagPutOption {
|
||||
return func(opts *DagPutSettings) error {
|
||||
opts.Kind = kind
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Hash is an option for Dag.Put which specifies the hash function to use
|
||||
func (dagOpts) Hash(hash string) DagPutOption {
|
||||
return func(opts *DagPutSettings) error {
|
||||
opts.Hash = hash
|
||||
return nil
|
||||
}
|
||||
}
|
60
vendor/github.com/ipfs/go-ipfs-api/pubsub.go
generated
vendored
Normal file
60
vendor/github.com/ipfs/go-ipfs-api/pubsub.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
)
|
||||
|
||||
// Message is a pubsub message.
|
||||
type Message struct {
|
||||
From peer.ID
|
||||
Data []byte
|
||||
Seqno []byte
|
||||
TopicIDs []string
|
||||
}
|
||||
|
||||
// PubSubSubscription allow you to receive pubsub records that where published on the network.
|
||||
type PubSubSubscription struct {
|
||||
resp io.Closer
|
||||
dec *json.Decoder
|
||||
}
|
||||
|
||||
func newPubSubSubscription(resp io.ReadCloser) *PubSubSubscription {
|
||||
return &PubSubSubscription{
|
||||
resp: resp,
|
||||
dec: json.NewDecoder(resp),
|
||||
}
|
||||
}
|
||||
|
||||
// Next waits for the next record and returns that.
|
||||
func (s *PubSubSubscription) Next() (*Message, error) {
|
||||
var r struct {
|
||||
From []byte `json:"from,omitempty"`
|
||||
Data []byte `json:"data,omitempty"`
|
||||
Seqno []byte `json:"seqno,omitempty"`
|
||||
TopicIDs []string `json:"topicIDs,omitempty"`
|
||||
}
|
||||
|
||||
err := s.dec.Decode(&r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
from, err := peer.IDFromBytes(r.From)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Message{
|
||||
From: from,
|
||||
Data: r.Data,
|
||||
Seqno: r.Seqno,
|
||||
TopicIDs: r.TopicIDs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Cancel cancels the given subscription.
|
||||
func (s *PubSubSubscription) Cancel() error {
|
||||
return s.resp.Close()
|
||||
}
|
189
vendor/github.com/ipfs/go-ipfs-api/request.go
generated
vendored
Normal file
189
vendor/github.com/ipfs/go-ipfs-api/request.go
generated
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
Ctx context.Context
|
||||
ApiBase string
|
||||
Command string
|
||||
Args []string
|
||||
Opts map[string]string
|
||||
Body io.Reader
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
func NewRequest(ctx context.Context, url, command string, args ...string) *Request {
|
||||
if !strings.HasPrefix(url, "http") {
|
||||
url = "http://" + url
|
||||
}
|
||||
|
||||
opts := map[string]string{
|
||||
"encoding": "json",
|
||||
"stream-channels": "true",
|
||||
}
|
||||
return &Request{
|
||||
Ctx: ctx,
|
||||
ApiBase: url + "/api/v0",
|
||||
Command: command,
|
||||
Args: args,
|
||||
Opts: opts,
|
||||
Headers: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
type trailerReader struct {
|
||||
resp *http.Response
|
||||
}
|
||||
|
||||
func (r *trailerReader) Read(b []byte) (int, error) {
|
||||
n, err := r.resp.Body.Read(b)
|
||||
if err != nil {
|
||||
if e := r.resp.Trailer.Get("X-Stream-Error"); e != "" {
|
||||
err = errors.New(e)
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *trailerReader) Close() error {
|
||||
return r.resp.Body.Close()
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Output io.ReadCloser
|
||||
Error *Error
|
||||
}
|
||||
|
||||
func (r *Response) Close() error {
|
||||
if r.Output != nil {
|
||||
// always drain output (response body)
|
||||
_, err1 := io.Copy(ioutil.Discard, r.Output)
|
||||
err2 := r.Output.Close()
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Response) Decode(dec interface{}) error {
|
||||
defer r.Close()
|
||||
if r.Error != nil {
|
||||
return r.Error
|
||||
}
|
||||
|
||||
return json.NewDecoder(r.Output).Decode(dec)
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Command string
|
||||
Message string
|
||||
Code int
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
var out string
|
||||
if e.Command != "" {
|
||||
out = e.Command + ": "
|
||||
}
|
||||
if e.Code != 0 {
|
||||
out = fmt.Sprintf("%s%d: ", out, e.Code)
|
||||
}
|
||||
return out + e.Message
|
||||
}
|
||||
|
||||
func (r *Request) Send(c *http.Client) (*Response, error) {
|
||||
url := r.getURL()
|
||||
req, err := http.NewRequest("POST", url, r.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req = req.WithContext(r.Ctx)
|
||||
|
||||
// Add any headers that were supplied via the RequestBuilder.
|
||||
for k, v := range r.Headers {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
|
||||
if fr, ok := r.Body.(*files.MultiFileReader); ok {
|
||||
req.Header.Set("Content-Type", "multipart/form-data; boundary="+fr.Boundary())
|
||||
req.Header.Set("Content-Disposition", "form-data; name=\"files\"")
|
||||
}
|
||||
|
||||
resp, err := c.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
parts := strings.Split(contentType, ";")
|
||||
contentType = parts[0]
|
||||
|
||||
nresp := new(Response)
|
||||
|
||||
nresp.Output = &trailerReader{resp}
|
||||
if resp.StatusCode >= http.StatusBadRequest {
|
||||
e := &Error{
|
||||
Command: r.Command,
|
||||
}
|
||||
switch {
|
||||
case resp.StatusCode == http.StatusNotFound:
|
||||
e.Message = "command not found"
|
||||
case contentType == "text/plain":
|
||||
out, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) read error: %s\n", resp.StatusCode, err)
|
||||
}
|
||||
e.Message = string(out)
|
||||
case contentType == "application/json":
|
||||
if err = json.NewDecoder(resp.Body).Decode(e); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "ipfs-shell: warning! response (%d) unmarshall error: %s\n", resp.StatusCode, err)
|
||||
}
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "ipfs-shell: warning! unhandled response (%d) encoding: %s", resp.StatusCode, contentType)
|
||||
out, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "ipfs-shell: response (%d) read error: %s\n", resp.StatusCode, err)
|
||||
}
|
||||
e.Message = fmt.Sprintf("unknown ipfs-shell error encoding: %q - %q", contentType, out)
|
||||
}
|
||||
nresp.Error = e
|
||||
nresp.Output = nil
|
||||
|
||||
// drain body and close
|
||||
io.Copy(ioutil.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
||||
return nresp, nil
|
||||
}
|
||||
|
||||
func (r *Request) getURL() string {
|
||||
|
||||
values := make(url.Values)
|
||||
for _, arg := range r.Args {
|
||||
values.Add("arg", arg)
|
||||
}
|
||||
for k, v := range r.Opts {
|
||||
values.Add(k, v)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s?%s", r.ApiBase, r.Command, values.Encode())
|
||||
}
|
100
vendor/github.com/ipfs/go-ipfs-api/requestbuilder.go
generated
vendored
Normal file
100
vendor/github.com/ipfs/go-ipfs-api/requestbuilder.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RequestBuilder is an IPFS commands request builder.
|
||||
type RequestBuilder struct {
|
||||
command string
|
||||
args []string
|
||||
opts map[string]string
|
||||
headers map[string]string
|
||||
body io.Reader
|
||||
|
||||
shell *Shell
|
||||
}
|
||||
|
||||
// Arguments adds the arguments to the args.
|
||||
func (r *RequestBuilder) Arguments(args ...string) *RequestBuilder {
|
||||
r.args = append(r.args, args...)
|
||||
return r
|
||||
}
|
||||
|
||||
// BodyString sets the request body to the given string.
|
||||
func (r *RequestBuilder) BodyString(body string) *RequestBuilder {
|
||||
return r.Body(strings.NewReader(body))
|
||||
}
|
||||
|
||||
// BodyBytes sets the request body to the given buffer.
|
||||
func (r *RequestBuilder) BodyBytes(body []byte) *RequestBuilder {
|
||||
return r.Body(bytes.NewReader(body))
|
||||
}
|
||||
|
||||
// Body sets the request body to the given reader.
|
||||
func (r *RequestBuilder) Body(body io.Reader) *RequestBuilder {
|
||||
r.body = body
|
||||
return r
|
||||
}
|
||||
|
||||
// Option sets the given option.
|
||||
func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder {
|
||||
var s string
|
||||
switch v := value.(type) {
|
||||
case bool:
|
||||
s = strconv.FormatBool(v)
|
||||
case string:
|
||||
s = v
|
||||
case []byte:
|
||||
s = string(v)
|
||||
default:
|
||||
// slow case.
|
||||
s = fmt.Sprint(value)
|
||||
}
|
||||
if r.opts == nil {
|
||||
r.opts = make(map[string]string, 1)
|
||||
}
|
||||
r.opts[key] = s
|
||||
return r
|
||||
}
|
||||
|
||||
// Header sets the given header.
|
||||
func (r *RequestBuilder) Header(name, value string) *RequestBuilder {
|
||||
if r.headers == nil {
|
||||
r.headers = make(map[string]string, 1)
|
||||
}
|
||||
r.headers[name] = value
|
||||
return r
|
||||
}
|
||||
|
||||
// Send sends the request and return the response.
|
||||
func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) {
|
||||
req := NewRequest(ctx, r.shell.url, r.command, r.args...)
|
||||
req.Opts = r.opts
|
||||
req.Headers = r.headers
|
||||
req.Body = r.body
|
||||
return req.Send(&r.shell.httpcli)
|
||||
}
|
||||
|
||||
// Exec sends the request a request and decodes the response.
|
||||
func (r *RequestBuilder) Exec(ctx context.Context, res interface{}) error {
|
||||
httpRes, err := r.Send(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if res == nil {
|
||||
lateErr := httpRes.Close()
|
||||
if httpRes.Error != nil {
|
||||
return httpRes.Error
|
||||
}
|
||||
return lateErr
|
||||
}
|
||||
|
||||
return httpRes.Decode(res)
|
||||
}
|
596
vendor/github.com/ipfs/go-ipfs-api/shell.go
generated
vendored
Normal file
596
vendor/github.com/ipfs/go-ipfs-api/shell.go
generated
vendored
Normal file
@ -0,0 +1,596 @@
|
||||
// package shell implements a remote API interface for a running ipfs daemon
|
||||
package shell
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
gohttp "net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
tar "github.com/whyrusleeping/tar-utils"
|
||||
|
||||
p2pmetrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultPathName = ".ipfs"
|
||||
DefaultPathRoot = "~/" + DefaultPathName
|
||||
DefaultApiFile = "api"
|
||||
EnvDir = "IPFS_PATH"
|
||||
)
|
||||
|
||||
type Shell struct {
|
||||
url string
|
||||
httpcli gohttp.Client
|
||||
}
|
||||
|
||||
func NewLocalShell() *Shell {
|
||||
baseDir := os.Getenv(EnvDir)
|
||||
if baseDir == "" {
|
||||
baseDir = DefaultPathRoot
|
||||
}
|
||||
|
||||
baseDir, err := homedir.Expand(baseDir)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
apiFile := path.Join(baseDir, DefaultApiFile)
|
||||
|
||||
if _, err := os.Stat(apiFile); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
api, err := ioutil.ReadFile(apiFile)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return NewShell(strings.TrimSpace(string(api)))
|
||||
}
|
||||
|
||||
func NewShell(url string) *Shell {
|
||||
c := &gohttp.Client{
|
||||
Transport: &gohttp.Transport{
|
||||
Proxy: gohttp.ProxyFromEnvironment,
|
||||
DisableKeepAlives: true,
|
||||
},
|
||||
}
|
||||
|
||||
return NewShellWithClient(url, c)
|
||||
}
|
||||
|
||||
func NewShellWithClient(url string, client *gohttp.Client) *Shell {
|
||||
var sh Shell
|
||||
|
||||
sh.url = url
|
||||
sh.httpcli = *client
|
||||
// We don't support redirects.
|
||||
sh.httpcli.CheckRedirect = func(_ *gohttp.Request, _ []*gohttp.Request) error {
|
||||
return fmt.Errorf("unexpected redirect")
|
||||
}
|
||||
|
||||
maddr, err := ma.NewMultiaddr(url)
|
||||
if err != nil {
|
||||
return &sh
|
||||
}
|
||||
|
||||
network, host, err := manet.DialArgs(maddr)
|
||||
if err != nil {
|
||||
return &sh
|
||||
}
|
||||
|
||||
if network == "unix" {
|
||||
sh.url = network
|
||||
|
||||
var tptCopy *gohttp.Transport
|
||||
if tpt, ok := sh.httpcli.Transport.(*gohttp.Transport); ok && tpt.DialContext == nil {
|
||||
tptCopy = tpt.Clone()
|
||||
} else if sh.httpcli.Transport == nil {
|
||||
tptCopy = &gohttp.Transport{
|
||||
Proxy: gohttp.ProxyFromEnvironment,
|
||||
DisableKeepAlives: true,
|
||||
}
|
||||
} else {
|
||||
// custom Transport or custom Dialer, we are done here
|
||||
return &sh
|
||||
}
|
||||
|
||||
tptCopy.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
|
||||
return net.Dial("unix", host)
|
||||
}
|
||||
|
||||
sh.httpcli.Transport = tptCopy
|
||||
} else {
|
||||
sh.url = host
|
||||
}
|
||||
|
||||
return &sh
|
||||
}
|
||||
|
||||
func (s *Shell) SetTimeout(d time.Duration) {
|
||||
s.httpcli.Timeout = d
|
||||
}
|
||||
|
||||
func (s *Shell) Request(command string, args ...string) *RequestBuilder {
|
||||
return &RequestBuilder{
|
||||
command: command,
|
||||
args: args,
|
||||
shell: s,
|
||||
}
|
||||
}
|
||||
|
||||
type IdOutput struct {
|
||||
ID string
|
||||
PublicKey string
|
||||
Addresses []string
|
||||
AgentVersion string
|
||||
ProtocolVersion string
|
||||
}
|
||||
|
||||
// ID gets information about a given peer. Arguments:
|
||||
//
|
||||
// peer: peer.ID of the node to look up. If no peer is specified,
|
||||
// return information about the local peer.
|
||||
func (s *Shell) ID(peer ...string) (*IdOutput, error) {
|
||||
if len(peer) > 1 {
|
||||
return nil, fmt.Errorf("Too many peer arguments")
|
||||
}
|
||||
|
||||
var out IdOutput
|
||||
if err := s.Request("id", peer...).Exec(context.Background(), &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
// Cat the content at the given path. Callers need to drain and close the returned reader after usage.
|
||||
func (s *Shell) Cat(path string) (io.ReadCloser, error) {
|
||||
resp, err := s.Request("cat", path).Send(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Error != nil {
|
||||
return nil, resp.Error
|
||||
}
|
||||
|
||||
return resp.Output, nil
|
||||
}
|
||||
|
||||
const (
|
||||
TRaw = iota
|
||||
TDirectory
|
||||
TFile
|
||||
TMetadata
|
||||
TSymlink
|
||||
)
|
||||
|
||||
// List entries at the given path
|
||||
func (s *Shell) List(path string) ([]*LsLink, error) {
|
||||
var out struct{ Objects []LsObject }
|
||||
err := s.Request("ls", path).Exec(context.Background(), &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(out.Objects) != 1 {
|
||||
return nil, errors.New("bad response from server")
|
||||
}
|
||||
return out.Objects[0].Links, nil
|
||||
}
|
||||
|
||||
type LsLink struct {
|
||||
Hash string
|
||||
Name string
|
||||
Size uint64
|
||||
Type int
|
||||
}
|
||||
|
||||
type LsObject struct {
|
||||
Links []*LsLink
|
||||
LsLink
|
||||
}
|
||||
|
||||
// Pin the given path
|
||||
func (s *Shell) Pin(path string) error {
|
||||
return s.Request("pin/add", path).
|
||||
Option("recursive", true).
|
||||
Exec(context.Background(), nil)
|
||||
}
|
||||
|
||||
// Unpin the given path
|
||||
func (s *Shell) Unpin(path string) error {
|
||||
return s.Request("pin/rm", path).
|
||||
Option("recursive", true).
|
||||
Exec(context.Background(), nil)
|
||||
}
|
||||
|
||||
const (
|
||||
DirectPin = "direct"
|
||||
RecursivePin = "recursive"
|
||||
IndirectPin = "indirect"
|
||||
)
|
||||
|
||||
type PinInfo struct {
|
||||
Type string
|
||||
}
|
||||
|
||||
// Pins returns a map of the pin hashes to their info (currently just the
|
||||
// pin type, one of DirectPin, RecursivePin, or IndirectPin). A map is returned
|
||||
// instead of a slice because it is easier to do existence lookup by map key
|
||||
// than unordered array searching. The map is likely to be more useful to a
|
||||
// client than a flat list.
|
||||
func (s *Shell) Pins() (map[string]PinInfo, error) {
|
||||
var raw struct{ Keys map[string]PinInfo }
|
||||
return raw.Keys, s.Request("pin/ls").Exec(context.Background(), &raw)
|
||||
}
|
||||
|
||||
// PinStreamInfo is the output type for PinsStream
|
||||
type PinStreamInfo struct {
|
||||
Cid string
|
||||
Type string
|
||||
}
|
||||
|
||||
// PinsStream is a streamed version of Pins. It returns a channel of the pins
|
||||
// with their type, one of DirectPin, RecursivePin, or IndirectPin.
|
||||
func (s *Shell) PinsStream(ctx context.Context) (<-chan PinStreamInfo, error) {
|
||||
resp, err := s.Request("pin/ls").
|
||||
Option("stream", true).
|
||||
Send(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.Error != nil {
|
||||
resp.Close()
|
||||
return nil, resp.Error
|
||||
}
|
||||
|
||||
out := make(chan PinStreamInfo)
|
||||
go func() {
|
||||
defer resp.Close()
|
||||
var pin PinStreamInfo
|
||||
defer close(out)
|
||||
dec := json.NewDecoder(resp.Output)
|
||||
for {
|
||||
err := dec.Decode(&pin)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case out <- pin:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type PeerInfo struct {
|
||||
Addrs []string
|
||||
ID string
|
||||
}
|
||||
|
||||
func (s *Shell) FindPeer(peer string) (*PeerInfo, error) {
|
||||
var peers struct{ Responses []PeerInfo }
|
||||
err := s.Request("dht/findpeer", peer).Exec(context.Background(), &peers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(peers.Responses) == 0 {
|
||||
return nil, errors.New("peer not found")
|
||||
}
|
||||
return &peers.Responses[0], nil
|
||||
}
|
||||
|
||||
func (s *Shell) Refs(hash string, recursive bool) (<-chan string, error) {
|
||||
resp, err := s.Request("refs", hash).
|
||||
Option("recursive", recursive).
|
||||
Send(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.Error != nil {
|
||||
resp.Close()
|
||||
return nil, resp.Error
|
||||
}
|
||||
|
||||
out := make(chan string)
|
||||
go func() {
|
||||
defer resp.Close()
|
||||
var ref struct {
|
||||
Ref string
|
||||
}
|
||||
defer close(out)
|
||||
dec := json.NewDecoder(resp.Output)
|
||||
for {
|
||||
err := dec.Decode(&ref)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(ref.Ref) > 0 {
|
||||
out <- ref.Ref
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (s *Shell) Patch(root, action string, args ...string) (string, error) {
|
||||
var out object
|
||||
return out.Hash, s.Request("object/patch/"+action, root).
|
||||
Arguments(args...).
|
||||
Exec(context.Background(), &out)
|
||||
}
|
||||
|
||||
func (s *Shell) PatchData(root string, set bool, data interface{}) (string, error) {
|
||||
var read io.Reader
|
||||
switch d := data.(type) {
|
||||
case io.Reader:
|
||||
read = d
|
||||
case []byte:
|
||||
read = bytes.NewReader(d)
|
||||
case string:
|
||||
read = strings.NewReader(d)
|
||||
default:
|
||||
return "", fmt.Errorf("unrecognized type: %#v", data)
|
||||
}
|
||||
|
||||
cmd := "append-data"
|
||||
if set {
|
||||
cmd = "set-data"
|
||||
}
|
||||
|
||||
fr := files.NewReaderFile(read)
|
||||
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)})
|
||||
fileReader := files.NewMultiFileReader(slf, true)
|
||||
|
||||
var out object
|
||||
return out.Hash, s.Request("object/patch/"+cmd, root).
|
||||
Body(fileReader).
|
||||
Exec(context.Background(), &out)
|
||||
}
|
||||
|
||||
func (s *Shell) PatchLink(root, path, childhash string, create bool) (string, error) {
|
||||
var out object
|
||||
return out.Hash, s.Request("object/patch/add-link", root, path, childhash).
|
||||
Option("create", create).
|
||||
Exec(context.Background(), &out)
|
||||
}
|
||||
|
||||
func (s *Shell) Get(hash, outdir string) error {
|
||||
resp, err := s.Request("get", hash).Option("create", true).Send(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Close()
|
||||
|
||||
if resp.Error != nil {
|
||||
return resp.Error
|
||||
}
|
||||
|
||||
extractor := &tar.Extractor{Path: outdir}
|
||||
return extractor.Extract(resp.Output)
|
||||
}
|
||||
|
||||
func (s *Shell) NewObject(template string) (string, error) {
|
||||
var out object
|
||||
req := s.Request("object/new")
|
||||
if template != "" {
|
||||
req.Arguments(template)
|
||||
}
|
||||
return out.Hash, req.Exec(context.Background(), &out)
|
||||
}
|
||||
|
||||
func (s *Shell) ResolvePath(path string) (string, error) {
|
||||
var out struct {
|
||||
Path string
|
||||
}
|
||||
err := s.Request("resolve", path).Exec(context.Background(), &out)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return strings.TrimPrefix(out.Path, "/ipfs/"), nil
|
||||
}
|
||||
|
||||
// returns ipfs version and commit sha
|
||||
func (s *Shell) Version() (string, string, error) {
|
||||
ver := struct {
|
||||
Version string
|
||||
Commit string
|
||||
}{}
|
||||
|
||||
if err := s.Request("version").Exec(context.Background(), &ver); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return ver.Version, ver.Commit, nil
|
||||
}
|
||||
|
||||
func (s *Shell) IsUp() bool {
|
||||
_, _, err := s.Version()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (s *Shell) BlockStat(path string) (string, int, error) {
|
||||
var inf struct {
|
||||
Key string
|
||||
Size int
|
||||
}
|
||||
|
||||
if err := s.Request("block/stat", path).Exec(context.Background(), &inf); err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
return inf.Key, inf.Size, nil
|
||||
}
|
||||
|
||||
func (s *Shell) BlockGet(path string) ([]byte, error) {
|
||||
resp, err := s.Request("block/get", path).Send(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Close()
|
||||
|
||||
if resp.Error != nil {
|
||||
return nil, resp.Error
|
||||
}
|
||||
|
||||
return ioutil.ReadAll(resp.Output)
|
||||
}
|
||||
|
||||
func (s *Shell) BlockPut(block []byte, format, mhtype string, mhlen int) (string, error) {
|
||||
var out struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
fr := files.NewBytesFile(block)
|
||||
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)})
|
||||
fileReader := files.NewMultiFileReader(slf, true)
|
||||
|
||||
return out.Key, s.Request("block/put").
|
||||
Option("mhtype", mhtype).
|
||||
Option("format", format).
|
||||
Option("mhlen", mhlen).
|
||||
Body(fileReader).
|
||||
Exec(context.Background(), &out)
|
||||
}
|
||||
|
||||
type IpfsObject struct {
|
||||
Links []ObjectLink
|
||||
Data string
|
||||
}
|
||||
|
||||
type ObjectLink struct {
|
||||
Name, Hash string
|
||||
Size uint64
|
||||
}
|
||||
|
||||
func (s *Shell) ObjectGet(path string) (*IpfsObject, error) {
|
||||
var obj IpfsObject
|
||||
if err := s.Request("object/get", path).Exec(context.Background(), &obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &obj, nil
|
||||
}
|
||||
|
||||
func (s *Shell) ObjectPut(obj *IpfsObject) (string, error) {
|
||||
var data bytes.Buffer
|
||||
err := json.NewEncoder(&data).Encode(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
fr := files.NewReaderFile(&data)
|
||||
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)})
|
||||
fileReader := files.NewMultiFileReader(slf, true)
|
||||
|
||||
var out object
|
||||
return out.Hash, s.Request("object/put").
|
||||
Body(fileReader).
|
||||
Exec(context.Background(), &out)
|
||||
}
|
||||
|
||||
func (s *Shell) PubSubSubscribe(topic string) (*PubSubSubscription, error) {
|
||||
// connect
|
||||
resp, err := s.Request("pubsub/sub", topic).Send(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Error != nil {
|
||||
resp.Close()
|
||||
return nil, resp.Error
|
||||
}
|
||||
return newPubSubSubscription(resp.Output), nil
|
||||
}
|
||||
|
||||
func (s *Shell) PubSubPublish(topic, data string) (err error) {
|
||||
resp, err := s.Request("pubsub/pub", topic, data).Send(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Close()
|
||||
if resp.Error != nil {
|
||||
return resp.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ObjectStats struct {
|
||||
Hash string
|
||||
BlockSize int
|
||||
CumulativeSize int
|
||||
DataSize int
|
||||
LinksSize int
|
||||
NumLinks int
|
||||
}
|
||||
|
||||
// ObjectStat gets stats for the DAG object named by key. It returns
|
||||
// the stats of the requested Object or an error.
|
||||
func (s *Shell) ObjectStat(key string) (*ObjectStats, error) {
|
||||
var stat ObjectStats
|
||||
err := s.Request("object/stat", key).Exec(context.Background(), &stat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &stat, nil
|
||||
}
|
||||
|
||||
// ObjectStat gets stats for the DAG object named by key. It returns
|
||||
// the stats of the requested Object or an error.
|
||||
func (s *Shell) StatsBW(ctx context.Context) (*p2pmetrics.Stats, error) {
|
||||
v := &p2pmetrics.Stats{}
|
||||
err := s.Request("stats/bw").Exec(ctx, &v)
|
||||
return v, err
|
||||
}
|
||||
|
||||
type SwarmStreamInfo struct {
|
||||
Protocol string
|
||||
}
|
||||
|
||||
type SwarmConnInfo struct {
|
||||
Addr string
|
||||
Peer string
|
||||
Latency string
|
||||
Muxer string
|
||||
Streams []SwarmStreamInfo
|
||||
}
|
||||
|
||||
type SwarmConnInfos struct {
|
||||
Peers []SwarmConnInfo
|
||||
}
|
||||
|
||||
// SwarmPeers gets all the swarm peers
|
||||
func (s *Shell) SwarmPeers(ctx context.Context) (*SwarmConnInfos, error) {
|
||||
v := &SwarmConnInfos{}
|
||||
err := s.Request("swarm/peers").Exec(ctx, &v)
|
||||
return v, err
|
||||
}
|
||||
|
||||
type swarmConnection struct {
|
||||
Strings []string
|
||||
}
|
||||
|
||||
// SwarmConnect opens a swarm connection to a specific address.
|
||||
func (s *Shell) SwarmConnect(ctx context.Context, addr ...string) error {
|
||||
var conn *swarmConnection
|
||||
err := s.Request("swarm/connect").
|
||||
Arguments(addr...).
|
||||
Exec(ctx, &conn)
|
||||
return err
|
||||
}
|
38
vendor/github.com/ipfs/go-ipfs-api/unixfs.go
generated
vendored
Normal file
38
vendor/github.com/ipfs/go-ipfs-api/unixfs.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type UnixLsObject struct {
|
||||
Hash string
|
||||
Size uint64
|
||||
Type string
|
||||
Links []*UnixLsLink
|
||||
}
|
||||
|
||||
type UnixLsLink struct {
|
||||
Hash string
|
||||
Name string
|
||||
Size uint64
|
||||
Type string
|
||||
}
|
||||
|
||||
type lsOutput struct {
|
||||
Objects map[string]*UnixLsObject
|
||||
}
|
||||
|
||||
// FileList entries at the given path using the UnixFS commands
|
||||
func (s *Shell) FileList(path string) (*UnixLsObject, error) {
|
||||
var out lsOutput
|
||||
if err := s.Request("file/ls", path).Exec(context.Background(), &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, object := range out.Objects {
|
||||
return object, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no object in results")
|
||||
}
|
30
vendor/github.com/ipfs/go-ipfs-files/.travis.yml
generated
vendored
Normal file
30
vendor/github.com/ipfs/go-ipfs-files/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
os:
|
||||
- linux
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.14.x
|
||||
|
||||
env:
|
||||
global:
|
||||
- GOTFLAGS="-race"
|
||||
matrix:
|
||||
- BUILD_DEPTYPE=gomod
|
||||
|
||||
|
||||
# disable travis install
|
||||
install:
|
||||
- true
|
||||
|
||||
script:
|
||||
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)
|
||||
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $GOPATH/pkg/mod
|
||||
- $HOME/.cache/go-build
|
||||
|
||||
notifications:
|
||||
email: false
|
21
vendor/github.com/ipfs/go-ipfs-files/LICENSE
generated
vendored
Normal file
21
vendor/github.com/ipfs/go-ipfs-files/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Protocol Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
31
vendor/github.com/ipfs/go-ipfs-files/README.md
generated
vendored
Normal file
31
vendor/github.com/ipfs/go-ipfs-files/README.md
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
# go-ipfs-files
|
||||
|
||||
[](http://ipn.io)
|
||||
[](http://ipfs.io/)
|
||||
[](http://webchat.freenode.net/?channels=%23ipfs)
|
||||
[](https://github.com/RichardLitt/standard-readme)
|
||||
|
||||
> File interfaces and utils used in IPFS
|
||||
|
||||
## Lead Maintainer
|
||||
|
||||
[Steven Allen](https://github.com/Stebalien)
|
||||
|
||||
## Documentation
|
||||
|
||||
https://godoc.org/github.com/ipfs/go-ipfs-files
|
||||
|
||||
## Contribute
|
||||
|
||||
Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ipfs-files/issues)!
|
||||
|
||||
This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
|
||||
|
||||
### Want to hack on IPFS?
|
||||
|
||||
[](https://github.com/ipfs/community/blob/master/contributing.md)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
94
vendor/github.com/ipfs/go-ipfs-files/file.go
generated
vendored
Normal file
94
vendor/github.com/ipfs/go-ipfs-files/file.go
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotDirectory = errors.New("file isn't a directory")
|
||||
ErrNotReader = errors.New("file isn't a regular file")
|
||||
|
||||
ErrNotSupported = errors.New("operation not supported")
|
||||
)
|
||||
|
||||
// Node is a common interface for files, directories and other special files
|
||||
type Node interface {
|
||||
io.Closer
|
||||
|
||||
// Size returns size of this file (if this file is a directory, total size of
|
||||
// all files stored in the tree should be returned). Some implementations may
|
||||
// choose not to implement this
|
||||
Size() (int64, error)
|
||||
}
|
||||
|
||||
// Node represents a regular Unix file
|
||||
type File interface {
|
||||
Node
|
||||
|
||||
io.Reader
|
||||
io.Seeker
|
||||
}
|
||||
|
||||
// DirEntry exposes information about a directory entry
|
||||
type DirEntry interface {
|
||||
// Name returns base name of this entry, which is the base name of referenced
|
||||
// file
|
||||
Name() string
|
||||
|
||||
// Node returns the file referenced by this DirEntry
|
||||
Node() Node
|
||||
}
|
||||
|
||||
// DirIterator is a iterator over directory entries.
|
||||
// See Directory.Entries for more
|
||||
type DirIterator interface {
|
||||
// DirEntry holds information about current directory entry.
|
||||
// Note that after creating new iterator you MUST call Next() at least once
|
||||
// before accessing these methods. Calling these methods without prior calls
|
||||
// to Next() and after Next() returned false may result in undefined behavior
|
||||
DirEntry
|
||||
|
||||
// Next advances iterator to the next file.
|
||||
Next() bool
|
||||
|
||||
// Err may return an error after previous call to Next() returned `false`.
|
||||
// If previous call to Next() returned `true`, Err() is guaranteed to
|
||||
// return nil
|
||||
Err() error
|
||||
}
|
||||
|
||||
// Directory is a special file which can link to any number of files.
|
||||
type Directory interface {
|
||||
Node
|
||||
|
||||
// Entries returns a stateful iterator over directory entries.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// it := dir.Entries()
|
||||
// for it.Next() {
|
||||
// name := it.Name()
|
||||
// file := it.Node()
|
||||
// [...]
|
||||
// }
|
||||
// if it.Err() != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// Note that you can't store the result of it.Node() and use it after
|
||||
// advancing the iterator
|
||||
Entries() DirIterator
|
||||
}
|
||||
|
||||
// FileInfo exposes information on files in local filesystem
|
||||
type FileInfo interface {
|
||||
Node
|
||||
|
||||
// AbsPath returns full real file path.
|
||||
AbsPath() string
|
||||
|
||||
// Stat returns os.Stat of this file, may be nil for some files
|
||||
Stat() os.FileInfo
|
||||
}
|
43
vendor/github.com/ipfs/go-ipfs-files/filewriter.go
generated
vendored
Normal file
43
vendor/github.com/ipfs/go-ipfs-files/filewriter.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// WriteTo writes the given node to the local filesystem at fpath.
|
||||
func WriteTo(nd Node, fpath string) error {
|
||||
switch nd := nd.(type) {
|
||||
case *Symlink:
|
||||
return os.Symlink(nd.Target, fpath)
|
||||
case File:
|
||||
f, err := os.Create(fpath)
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(f, nd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case Directory:
|
||||
err := os.Mkdir(fpath, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
entries := nd.Entries()
|
||||
for entries.Next() {
|
||||
child := filepath.Join(fpath, entries.Name())
|
||||
if err := WriteTo(entries.Node(), child); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return entries.Err()
|
||||
default:
|
||||
return fmt.Errorf("file type %T at %q is not supported", nd, fpath)
|
||||
}
|
||||
}
|
49
vendor/github.com/ipfs/go-ipfs-files/filter.go
generated
vendored
Normal file
49
vendor/github.com/ipfs/go-ipfs-files/filter.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
ignore "github.com/crackcomm/go-gitignore"
|
||||
)
|
||||
|
||||
// Filter represents a set of rules for determining if a file should be included or excluded.
|
||||
// A rule follows the syntax for patterns used in .gitgnore files for specifying untracked files.
|
||||
// Examples:
|
||||
// foo.txt
|
||||
// *.app
|
||||
// bar/
|
||||
// **/baz
|
||||
// fizz/**
|
||||
type Filter struct {
|
||||
// IncludeHidden - Include hidden files
|
||||
IncludeHidden bool
|
||||
// Rules - File filter rules
|
||||
Rules *ignore.GitIgnore
|
||||
}
|
||||
|
||||
// NewFilter creates a new file filter from a .gitignore file and/or a list of ignore rules.
|
||||
// An ignoreFile is a path to a file with .gitignore-style patterns to exclude, one per line
|
||||
// rules is an array of strings representing .gitignore-style patterns
|
||||
// For reference on ignore rule syntax, see https://git-scm.com/docs/gitignore
|
||||
func NewFilter(ignoreFile string, rules []string, includeHidden bool) (*Filter, error) {
|
||||
var ignoreRules *ignore.GitIgnore
|
||||
var err error
|
||||
if ignoreFile == "" {
|
||||
ignoreRules, err = ignore.CompileIgnoreLines(rules...)
|
||||
} else {
|
||||
ignoreRules, err = ignore.CompileIgnoreFileAndLines(ignoreFile, rules...)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Filter{IncludeHidden: includeHidden, Rules: ignoreRules}, nil
|
||||
}
|
||||
|
||||
// ShouldExclude takes an os.FileInfo object and applies rules to determine if its target should be excluded.
|
||||
func (filter *Filter) ShouldExclude(fileInfo os.FileInfo) (result bool) {
|
||||
path := fileInfo.Name()
|
||||
if !filter.IncludeHidden && isHidden(fileInfo) {
|
||||
return true
|
||||
}
|
||||
return filter.Rules.MatchesPath(path)
|
||||
}
|
8
vendor/github.com/ipfs/go-ipfs-files/go.mod
generated
vendored
Normal file
8
vendor/github.com/ipfs/go-ipfs-files/go.mod
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
module github.com/ipfs/go-ipfs-files
|
||||
|
||||
require (
|
||||
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10
|
||||
)
|
||||
|
||||
go 1.12
|
4
vendor/github.com/ipfs/go-ipfs-files/go.sum
generated
vendored
Normal file
4
vendor/github.com/ipfs/go-ipfs-files/go.sum
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg=
|
||||
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE=
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ=
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
17
vendor/github.com/ipfs/go-ipfs-files/is_hidden.go
generated
vendored
Normal file
17
vendor/github.com/ipfs/go-ipfs-files/is_hidden.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
//+build !windows
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func isHidden(fi os.FileInfo) bool {
|
||||
fName := fi.Name()
|
||||
switch fName {
|
||||
case "", ".", "..":
|
||||
return false
|
||||
default:
|
||||
return fName[0] == '.'
|
||||
}
|
||||
}
|
28
vendor/github.com/ipfs/go-ipfs-files/is_hidden_windows.go
generated
vendored
Normal file
28
vendor/github.com/ipfs/go-ipfs-files/is_hidden_windows.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// +build windows
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
windows "golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func isHidden(fi os.FileInfo) bool {
|
||||
fName := fi.Name()
|
||||
switch fName {
|
||||
case "", ".", "..":
|
||||
return false
|
||||
}
|
||||
|
||||
if fName[0] == '.' {
|
||||
return true
|
||||
}
|
||||
|
||||
wi, ok := fi.Sys().(*windows.Win32FileAttributeData)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return wi.FileAttributes&windows.FILE_ATTRIBUTE_HIDDEN != 0
|
||||
}
|
42
vendor/github.com/ipfs/go-ipfs-files/linkfile.go
generated
vendored
Normal file
42
vendor/github.com/ipfs/go-ipfs-files/linkfile.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Symlink struct {
|
||||
Target string
|
||||
|
||||
stat os.FileInfo
|
||||
reader strings.Reader
|
||||
}
|
||||
|
||||
func NewLinkFile(target string, stat os.FileInfo) File {
|
||||
lf := &Symlink{Target: target, stat: stat}
|
||||
lf.reader.Reset(lf.Target)
|
||||
return lf
|
||||
}
|
||||
|
||||
func (lf *Symlink) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lf *Symlink) Read(b []byte) (int, error) {
|
||||
return lf.reader.Read(b)
|
||||
}
|
||||
|
||||
func (lf *Symlink) Seek(offset int64, whence int) (int64, error) {
|
||||
return lf.reader.Seek(offset, whence)
|
||||
}
|
||||
|
||||
func (lf *Symlink) Size() (int64, error) {
|
||||
return lf.reader.Size(), nil
|
||||
}
|
||||
|
||||
func ToSymlink(n Node) *Symlink {
|
||||
l, _ := n.(*Symlink)
|
||||
return l
|
||||
}
|
||||
|
||||
var _ File = &Symlink{}
|
152
vendor/github.com/ipfs/go-ipfs-files/multifilereader.go
generated
vendored
Normal file
152
vendor/github.com/ipfs/go-ipfs-files/multifilereader.go
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
"path"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// MultiFileReader reads from a `commands.Node` (which can be a directory of files
|
||||
// or a regular file) as HTTP multipart encoded data.
|
||||
type MultiFileReader struct {
|
||||
io.Reader
|
||||
|
||||
// directory stack for NextFile
|
||||
files []DirIterator
|
||||
path []string
|
||||
|
||||
currentFile Node
|
||||
buf bytes.Buffer
|
||||
mpWriter *multipart.Writer
|
||||
closed bool
|
||||
mutex *sync.Mutex
|
||||
|
||||
// if true, the content disposition will be "form-data"
|
||||
// if false, the content disposition will be "attachment"
|
||||
form bool
|
||||
}
|
||||
|
||||
// NewMultiFileReader constructs a MultiFileReader. `file` can be any `commands.Directory`.
|
||||
// If `form` is set to true, the Content-Disposition will be "form-data".
|
||||
// Otherwise, it will be "attachment".
|
||||
func NewMultiFileReader(file Directory, form bool) *MultiFileReader {
|
||||
it := file.Entries()
|
||||
|
||||
mfr := &MultiFileReader{
|
||||
files: []DirIterator{it},
|
||||
path: []string{""},
|
||||
form: form,
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
mfr.mpWriter = multipart.NewWriter(&mfr.buf)
|
||||
|
||||
return mfr
|
||||
}
|
||||
|
||||
func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) {
|
||||
mfr.mutex.Lock()
|
||||
defer mfr.mutex.Unlock()
|
||||
|
||||
// if we are closed and the buffer is flushed, end reading
|
||||
if mfr.closed && mfr.buf.Len() == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
// if the current file isn't set, advance to the next file
|
||||
if mfr.currentFile == nil {
|
||||
var entry DirEntry
|
||||
|
||||
for entry == nil {
|
||||
if len(mfr.files) == 0 {
|
||||
mfr.mpWriter.Close()
|
||||
mfr.closed = true
|
||||
return mfr.buf.Read(buf)
|
||||
}
|
||||
|
||||
if !mfr.files[len(mfr.files)-1].Next() {
|
||||
if mfr.files[len(mfr.files)-1].Err() != nil {
|
||||
return 0, mfr.files[len(mfr.files)-1].Err()
|
||||
}
|
||||
mfr.files = mfr.files[:len(mfr.files)-1]
|
||||
mfr.path = mfr.path[:len(mfr.path)-1]
|
||||
continue
|
||||
}
|
||||
|
||||
entry = mfr.files[len(mfr.files)-1]
|
||||
}
|
||||
|
||||
// handle starting a new file part
|
||||
if !mfr.closed {
|
||||
|
||||
mfr.currentFile = entry.Node()
|
||||
|
||||
// write the boundary and headers
|
||||
header := make(textproto.MIMEHeader)
|
||||
filename := url.QueryEscape(path.Join(path.Join(mfr.path...), entry.Name()))
|
||||
dispositionPrefix := "attachment"
|
||||
if mfr.form {
|
||||
dispositionPrefix = "form-data; name=\"file\""
|
||||
}
|
||||
|
||||
header.Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"", dispositionPrefix, filename))
|
||||
|
||||
var contentType string
|
||||
|
||||
switch f := entry.Node().(type) {
|
||||
case *Symlink:
|
||||
contentType = "application/symlink"
|
||||
case Directory:
|
||||
newIt := f.Entries()
|
||||
mfr.files = append(mfr.files, newIt)
|
||||
mfr.path = append(mfr.path, entry.Name())
|
||||
contentType = "application/x-directory"
|
||||
case File:
|
||||
// otherwise, use the file as a reader to read its contents
|
||||
contentType = "application/octet-stream"
|
||||
default:
|
||||
return 0, ErrNotSupported
|
||||
}
|
||||
|
||||
header.Set("Content-Type", contentType)
|
||||
if rf, ok := entry.Node().(FileInfo); ok {
|
||||
header.Set("abspath", rf.AbsPath())
|
||||
}
|
||||
|
||||
_, err := mfr.mpWriter.CreatePart(header)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the buffer has something in it, read from it
|
||||
if mfr.buf.Len() > 0 {
|
||||
return mfr.buf.Read(buf)
|
||||
}
|
||||
|
||||
// otherwise, read from file data
|
||||
switch f := mfr.currentFile.(type) {
|
||||
case File:
|
||||
written, err = f.Read(buf)
|
||||
if err != io.EOF {
|
||||
return written, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := mfr.currentFile.Close(); err != nil {
|
||||
return written, err
|
||||
}
|
||||
|
||||
mfr.currentFile = nil
|
||||
return written, nil
|
||||
}
|
||||
|
||||
// Boundary returns the boundary string to be used to separate files in the multipart data
|
||||
func (mfr *MultiFileReader) Boundary() string {
|
||||
return mfr.mpWriter.Boundary()
|
||||
}
|
228
vendor/github.com/ipfs/go-ipfs-files/multipartfile.go
generated
vendored
Normal file
228
vendor/github.com/ipfs/go-ipfs-files/multipartfile.go
generated
vendored
Normal file
@ -0,0 +1,228 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
multipartFormdataType = "multipart/form-data"
|
||||
multipartMixedType = "multipart/mixed"
|
||||
|
||||
applicationDirectory = "application/x-directory"
|
||||
applicationSymlink = "application/symlink"
|
||||
applicationFile = "application/octet-stream"
|
||||
|
||||
contentTypeHeader = "Content-Type"
|
||||
)
|
||||
|
||||
type multipartDirectory struct {
|
||||
path string
|
||||
walker *multipartWalker
|
||||
|
||||
// part is the part describing the directory. It's nil when implicit.
|
||||
part *multipart.Part
|
||||
}
|
||||
|
||||
type multipartWalker struct {
|
||||
part *multipart.Part
|
||||
reader *multipart.Reader
|
||||
}
|
||||
|
||||
func (m *multipartWalker) consumePart() {
|
||||
m.part = nil
|
||||
}
|
||||
|
||||
func (m *multipartWalker) getPart() (*multipart.Part, error) {
|
||||
if m.part != nil {
|
||||
return m.part, nil
|
||||
}
|
||||
if m.reader == nil {
|
||||
return nil, io.EOF
|
||||
}
|
||||
|
||||
var err error
|
||||
m.part, err = m.reader.NextPart()
|
||||
if err == io.EOF {
|
||||
m.reader = nil
|
||||
}
|
||||
return m.part, err
|
||||
}
|
||||
|
||||
// NewFileFromPartReader creates a Directory from a multipart reader.
|
||||
func NewFileFromPartReader(reader *multipart.Reader, mediatype string) (Directory, error) {
|
||||
switch mediatype {
|
||||
case applicationDirectory, multipartFormdataType:
|
||||
default:
|
||||
return nil, ErrNotDirectory
|
||||
}
|
||||
|
||||
return &multipartDirectory{
|
||||
path: "/",
|
||||
walker: &multipartWalker{
|
||||
reader: reader,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (w *multipartWalker) nextFile() (Node, error) {
|
||||
part, err := w.getPart()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w.consumePart()
|
||||
|
||||
contentType := part.Header.Get(contentTypeHeader)
|
||||
if contentType != "" {
|
||||
var err error
|
||||
contentType, _, err = mime.ParseMediaType(contentType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
switch contentType {
|
||||
case multipartFormdataType, applicationDirectory:
|
||||
return &multipartDirectory{
|
||||
part: part,
|
||||
path: fileName(part),
|
||||
walker: w,
|
||||
}, nil
|
||||
case applicationSymlink:
|
||||
out, err := ioutil.ReadAll(part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewLinkFile(string(out), nil), nil
|
||||
default:
|
||||
return &ReaderFile{
|
||||
reader: part,
|
||||
abspath: part.Header.Get("abspath"),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// fileName returns a normalized filename from a part.
|
||||
func fileName(part *multipart.Part) string {
|
||||
filename := part.FileName()
|
||||
if escaped, err := url.QueryUnescape(filename); err == nil {
|
||||
filename = escaped
|
||||
} // if there is a unescape error, just treat the name as unescaped
|
||||
|
||||
return path.Clean("/" + filename)
|
||||
}
|
||||
|
||||
// dirName appends a slash to the end of the filename, if not present.
|
||||
// expects a _cleaned_ path.
|
||||
func dirName(filename string) string {
|
||||
if !strings.HasSuffix(filename, "/") {
|
||||
filename += "/"
|
||||
}
|
||||
return filename
|
||||
}
|
||||
|
||||
// isChild checks if child is a child of parent directory.
|
||||
// expects a _cleaned_ path.
|
||||
func isChild(child, parent string) bool {
|
||||
return strings.HasPrefix(child, dirName(parent))
|
||||
}
|
||||
|
||||
// makeRelative makes the child path relative to the parent path.
|
||||
// expects a _cleaned_ path.
|
||||
func makeRelative(child, parent string) string {
|
||||
return strings.TrimPrefix(child, dirName(parent))
|
||||
}
|
||||
|
||||
type multipartIterator struct {
|
||||
f *multipartDirectory
|
||||
|
||||
curFile Node
|
||||
curName string
|
||||
err error
|
||||
}
|
||||
|
||||
func (it *multipartIterator) Name() string {
|
||||
return it.curName
|
||||
}
|
||||
|
||||
func (it *multipartIterator) Node() Node {
|
||||
return it.curFile
|
||||
}
|
||||
|
||||
func (it *multipartIterator) Next() bool {
|
||||
if it.f.walker.reader == nil || it.err != nil {
|
||||
return false
|
||||
}
|
||||
var part *multipart.Part
|
||||
for {
|
||||
part, it.err = it.f.walker.getPart()
|
||||
if it.err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
name := fileName(part)
|
||||
|
||||
// Is the file in a different directory?
|
||||
if !isChild(name, it.f.path) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Have we already entered this directory?
|
||||
if it.curName != "" && isChild(name, path.Join(it.f.path, it.curName)) {
|
||||
it.f.walker.consumePart()
|
||||
continue
|
||||
}
|
||||
|
||||
// Make the path relative to the current directory.
|
||||
name = makeRelative(name, it.f.path)
|
||||
|
||||
// Check if we need to create a fake directory (more than one
|
||||
// path component).
|
||||
if idx := strings.IndexByte(name, '/'); idx >= 0 {
|
||||
it.curName = name[:idx]
|
||||
it.curFile = &multipartDirectory{
|
||||
path: path.Join(it.f.path, it.curName),
|
||||
walker: it.f.walker,
|
||||
}
|
||||
return true
|
||||
}
|
||||
it.curName = name
|
||||
|
||||
// Finally, advance to the next file.
|
||||
it.curFile, it.err = it.f.walker.nextFile()
|
||||
|
||||
return it.err == nil
|
||||
}
|
||||
}
|
||||
|
||||
func (it *multipartIterator) Err() error {
|
||||
// We use EOF to signal that this iterator is done. That way, we don't
|
||||
// need to check every time `Next` is called.
|
||||
if it.err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return it.err
|
||||
}
|
||||
|
||||
func (f *multipartDirectory) Entries() DirIterator {
|
||||
return &multipartIterator{f: f}
|
||||
}
|
||||
|
||||
func (f *multipartDirectory) Close() error {
|
||||
if f.part != nil {
|
||||
return f.part.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *multipartDirectory) Size() (int64, error) {
|
||||
return 0, ErrNotSupported
|
||||
}
|
||||
|
||||
var _ Directory = &multipartDirectory{}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user