Add a command to read a cid from an array of bytes

This commit is contained in:
whyrusleeping
2019-11-10 22:17:41 -08:00
parent 64acce09e1
commit 16bbe1cf14

71
cid.go
View File

@@ -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 {
return Undef, err
}
rest := data[n+cn:]
h, err := mh.Cast(rest)
nr, c, err := CidFromBytes(data)
if err != nil {
return Undef, err
}
return Cid{string(data[0 : n+cn+len(h)])}, nil
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
@@ -601,3 +581,42 @@ 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
}
mhr := mh.NewReader(bytes.NewReader(data[n+cn:]))
h, err := mhr.ReadMultihash()
if err != nil {
return 0, Undef, err
}
l := n + cn + len(h)
return l, Cid{string(data[0:l])}, nil
}