From 7105263bfa4ccc56b1456e12bef92c9c2892cbd3 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 31 Aug 2016 19:47:09 -0700 Subject: [PATCH] some improvements from integrating into go-ipfs --- cid.go | 102 ++++++++++++++++++++++++++++++++++++++------------- cid_test.go | 38 +++++-------------- package.json | 8 ++++ set.go | 35 ++++++++++++++++++ 4 files changed, 130 insertions(+), 53 deletions(-) create mode 100644 set.go diff --git a/cid.go b/cid.go index ff2cc21..cf693a9 100644 --- a/cid.go +++ b/cid.go @@ -1,19 +1,43 @@ package cid import ( + "bytes" "encoding/binary" "fmt" - mh "github.com/jbenet/go-multihash" mbase "github.com/multiformats/go-multibase" + mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash" ) const UnsupportedVersionString = "" +const ( + Protobuf = iota + Raw + JSON + CBOR +) + +func NewCidV0(h mh.Multihash) *Cid { + return &Cid{ + version: 0, + codec: Protobuf, + hash: h, + } +} + +func NewCidV1(c uint64, h mh.Multihash) *Cid { + return &Cid{ + version: 1, + codec: c, + hash: h, + } +} + type Cid struct { - Version uint64 - Type uint64 - Hash mh.Multihash + version uint64 + codec uint64 + hash mh.Multihash } func Decode(v string) (*Cid, error) { @@ -23,10 +47,7 @@ func Decode(v string) (*Cid, error) { return nil, err } - return &Cid{ - Version: 0, - Hash: hash, - }, nil + return NewCidV0(hash), nil } _, data, err := mbase.Decode(v) @@ -38,7 +59,24 @@ func Decode(v string) (*Cid, error) { } 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 nil, err + } + + return &Cid{ + codec: Protobuf, + version: 0, + hash: h, + }, nil + } + vers, n := binary.Uvarint(data) + if vers != 0 && vers != 1 { + return nil, fmt.Errorf("invalid cid version number: %d", vers) + } + codec, cn := binary.Uvarint(data[n:]) rest := data[n+cn:] @@ -48,16 +86,20 @@ func Cast(data []byte) (*Cid, error) { } return &Cid{ - Version: vers, - Type: codec, - Hash: h, + version: vers, + codec: codec, + hash: h, }, nil } +func (c *Cid) Type() uint64 { + return c.codec +} + func (c *Cid) String() string { - switch c.Version { + switch c.version { case 0: - return c.Hash.B58String() + return c.hash.B58String() case 1: mbstr, err := mbase.Encode(mbase.Base58BTC, c.bytesV1()) if err != nil { @@ -66,30 +108,40 @@ func (c *Cid) String() string { return mbstr default: - return "" + panic("not possible to reach this point") } } -func (c *Cid) Bytes() ([]byte, error) { - switch c.Version { +func (c *Cid) Hash() mh.Multihash { + return c.hash +} + +func (c *Cid) Bytes() []byte { + switch c.version { case 0: - return c.bytesV0(), nil + return c.bytesV0() case 1: - return c.bytesV1(), nil + return c.bytesV1() default: - return nil, fmt.Errorf("unsupported cid version") + panic("not possible to reach this point") } } func (c *Cid) bytesV0() []byte { - return []byte(c.Hash) + return []byte(c.hash) } func (c *Cid) bytesV1() []byte { - buf := make([]byte, 8+len(c.Hash)) - n := binary.PutUvarint(buf, c.Version) - n += binary.PutUvarint(buf[n:], c.Type) - copy(buf[n:], c.Hash) + buf := make([]byte, 8+len(c.hash)) + n := binary.PutUvarint(buf, c.version) + n += binary.PutUvarint(buf[n:], c.codec) + copy(buf[n:], c.hash) - return buf[:n+len(c.Hash)] + return buf[:n+len(c.hash)] +} + +func (c *Cid) Equals(o *Cid) bool { + return c.codec == o.codec && + c.version == o.version && + bytes.Equal(c.hash, o.hash) } diff --git a/cid_test.go b/cid_test.go index 2a1890b..361f6e2 100644 --- a/cid_test.go +++ b/cid_test.go @@ -4,19 +4,19 @@ import ( "bytes" "testing" - mh "github.com/jbenet/go-multihash" + mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash" ) func assertEqual(t *testing.T, a, b *Cid) { - if a.Type != b.Type { + if a.codec != b.codec { t.Fatal("mismatch on type") } - if a.Version != b.Version { + if a.version != b.version { t.Fatal("mismatch on version") } - if !bytes.Equal(a.Hash, b.Hash) { + if !bytes.Equal(a.hash, b.hash) { t.Fatal("multihash mismatch") } } @@ -28,15 +28,12 @@ func TestBasicMarshaling(t *testing.T) { } cid := &Cid{ - Type: 7, - Version: 1, - Hash: h, + codec: 7, + version: 1, + hash: h, } - data, err := cid.Bytes() - if err != nil { - t.Fatal(err) - } + data := cid.Bytes() out, err := Cast(data) if err != nil { @@ -62,11 +59,11 @@ func TestV0Handling(t *testing.T) { t.Fatal(err) } - if cid.Version != 0 { + if cid.version != 0 { t.Fatal("should have gotten version 0 cid") } - if cid.Hash.B58String() != old { + if cid.hash.B58String() != old { t.Fatal("marshaling roundtrip failed") } @@ -82,18 +79,3 @@ func TestV0ErrorCases(t *testing.T) { t.Fatal("should have failed to decode that ref") } } - -func TestBadVersion(t *testing.T) { - c := &Cid{ - Version: 17, - } - - if c.String() != UnsupportedVersionString { - t.Fatal("expected unsup string") - } - - _, err := c.Bytes() - if err == nil { - t.Fatal("shouldnt have succeeded in calling bytes") - } -} diff --git a/package.json b/package.json index 073b9e5..5145e07 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,14 @@ "gx": { "dvcsimport": "github.com/multiformats/go-cid" }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku", + "name": "go-multihash", + "version": "0.0.0" + } + ], "gxVersion": "0.8.0", "language": "go", "license": "", diff --git a/set.go b/set.go new file mode 100644 index 0000000..ec97a1f --- /dev/null +++ b/set.go @@ -0,0 +1,35 @@ +package cid + +type Set struct { + set map[string]struct{} +} + +func NewSet() *Set { + return &Set{set: make(map[string]struct{})} +} + +func (s *Set) Add(c *Cid) { + s.set[string(c.Bytes())] = struct{}{} +} + +func (s *Set) Has(c *Cid) bool { + _, ok := s.set[string(c.Bytes())] + return ok +} + +func (s *Set) Remove(c *Cid) { + delete(s.set, string(c.Bytes())) +} + +func (s *Set) Len() int { + return len(s.set) +} + +func (s *Set) Keys() []*Cid { + var out []*Cid + for k, _ := range s.set { + c, _ := Cast([]byte(k)) + out = append(out, c) + } + return out +}