Skip to content

Commit

Permalink
Merge pull request #95 from ipfs/feat/cid-from-bytes
Browse files Browse the repository at this point in the history
Add a function to read a cid from an array of bytes
  • Loading branch information
whyrusleeping authored Nov 12, 2019
2 parents aa8072e + d93d4ba commit 79e75df
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 26 deletions.
68 changes: 43 additions & 25 deletions cid.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,36 +290,16 @@ func uvError(read int) error {
// 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) {
if len(data) == 34 && data[0] == 18 && data[1] == 32 {
h, err := mh.Cast(data)
if err != nil {
return Undef, err
}

return NewCidV0(h), nil
}

vers, n := binary.Uvarint(data)
if err := uvError(n); err != nil {
return Undef, err
}

if vers != 1 {
return Undef, fmt.Errorf("expected 1 as the cid version number, got: %d", vers)
}

_, cn := binary.Uvarint(data[n:])
if err := uvError(cn); err != nil {
nr, c, err := CidFromBytes(data)
if err != nil {
return Undef, err
}

rest := data[n+cn:]
h, err := mh.Cast(rest)
if err != nil {
return Undef, err
if nr != len(data) {
return Undef, fmt.Errorf("trailing bytes in data buffer passed to cid Cast")
}

return Cid{string(data[0 : n+cn+len(h)])}, nil
return c, nil
}

// UnmarshalBinary is equivalent to Cast(). It implements the
Expand Down Expand Up @@ -607,3 +587,41 @@ func PrefixFromBytes(buf []byte) (Prefix, error) {
MhLength: int(mhlen),
}, nil
}

func CidFromBytes(data []byte) (int, Cid, error) {
if len(data) > 2 && data[0] == 18 && 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, NewCidV0(h), nil
}

vers, n := binary.Uvarint(data)
if err := uvError(n); 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 := binary.Uvarint(data[n:])
if err := uvError(cn); 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
}
34 changes: 34 additions & 0 deletions cid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,3 +550,37 @@ func BenchmarkStringV1(b *testing.B) {
b.FailNow()
}
}

func TestReadCidsFromBuffer(t *testing.T) {
cidstr := []string{
"bafkreie5qrjvaw64n4tjm6hbnm7fnqvcssfed4whsjqxzslbd3jwhsk3mm",
"Qmf5Qzp6nGBku7CEn2UQx4mgN8TW69YUok36DrGa6NN893",
"zb2rhZi1JR4eNc2jBGaRYJKYM8JEB4ovenym8L1CmFsRAytkz",
}

var cids []Cid
var buf []byte
for _, cs := range cidstr {
c, err := Decode(cs)
if err != nil {
t.Fatal(err)
}
cids = append(cids, c)
buf = append(buf, c.Bytes()...)
}

var cur int
for _, expc := range cids {
n, c, err := CidFromBytes(buf[cur:])
if err != nil {
t.Fatal(err)
}
if c != expc {
t.Fatal("cids mismatched")
}
cur += n
}
if cur != len(buf) {
t.Fatal("had trailing bytes")
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/ipfs/go-cid

require (
github.com/multiformats/go-multibase v0.0.1
github.com/multiformats/go-multihash v0.0.8
github.com/multiformats/go-multihash v0.0.9
)

go 1.13
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmr
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg=
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.0.9 h1:aoijQXYYl7Xtb2pUUP68R+ys1TlnlR3eX6wmozr0Hp4=
github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
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=
Expand Down

0 comments on commit 79e75df

Please # to comment.