@cryptotaxi247 / kubo / commits / e4ea7ce59

merkledag

Juan Batiz-Benet committed Jul 4, 2014 at 14:54 UTC e4ea7ce59ab62397577135181e7f9059b8c0aa5b
3 files changed +137
merkledag/coding.go new
+61
@@ -0,0 +1,61 @@
1 +package merkledag
2 +
3 +import (
4 + "fmt"
5 + mh "github.com/jbenet/go-multihash"
6 +)
7 +
8 +// for now, we use a PBNode intermediate thing.
9 +// because native go objects are nice.
10 +
11 +func (n *Node) Unmarshal(encoded []byte) error {
12 + var pbn PBNode
13 + if err := pbn.Unmarshal(encoded), err != nil {
14 + return fmt.Errorf("Unmarshal failed. %v", err)
15 + }
16 +
17 + pbnl := pbn.Links()
18 + n.Links = make([]*Link, len(pbnl))
19 + for i, l := range(pbnl) {
20 + n.Links[i] = &Link{Name: l.GetName(), Size: l.GetSize()}
21 + n.Links[i].Hash, err := mh.Cast(l.GetHash())
22 + if err != nil {
23 + return fmt.Errorf("Link hash is not valid multihash. %v", err)
24 + }
25 + }
26 +
27 + n.Data = pbn.GetData()
28 + return nil
29 +}
30 +
31 +func (n *Node) MarshalTo(encoded []byte) error {
32 + pbn := n.getPBNode()
33 + if err := pbn.MarshalTo(encoded), err != nil {
34 + return fmt.Errorf("Marshal failed. %v", err)
35 + }
36 + return nil
37 +}
38 +
39 +func (n *Node) Marshal() ([]byte, error) {
40 + pbn := n.getPBNode()
41 + data, err := pbn.Marshal()
42 + if err != nil {
43 + return data, fmt.Errorf("Marshal failed. %v", err)
44 + }
45 + return data, nil
46 +}
47 +
48 +func (n *Node) getPBNode() *PBNode {
49 + pbn := &PBNode{}
50 + pbn.Links = make([]*PBLink, len(n.Links))
51 + for i, l := range(n.Links) {
52 + pbn.Links[i] = &PBLink{}
53 + n.Links[i].Name = &l.Name
54 + n.Links[i].Size = l.Size
55 + n.Links[i].Hash = &[]byte(l.Hash)
56 + }
57 +
58 + pbn.Data = &n.Data
59 + return pbn, nil
60 +}
61 +
merkledag/merkledag.go new
+36
@@ -0,0 +1,36 @@
1 +package merkledag
2 +
3 +import (
4 + mh "github.com/jbenet/go-multihash"
5 +)
6 +
7 +// A node in the IPFS Merkle DAG.
8 +// nodes have opaque data and a set of navigable links.
9 +type Node {
10 + Links []*Link
11 + Data []byte
12 +}
13 +
14 +
15 +// An IPFS Merkle DAG Link
16 +type Link {
17 + // utf string name. should be unique per object
18 + Name string // utf8
19 +
20 + // cumulative size of target object
21 + Size uint64
22 +
23 + // multihash of the target object
24 + Hash mh.Multihash
25 +}
26 +
27 +
28 +type EncodedNode []byte
29 +
30 +
31 +func (n *Node) Size() uint64 {
32 + uint64 s = len(n.Encode())
33 + for _, l := range(n.Links) {
34 + s += l.Size
35 + }
36 +}
merkledag/merkledag.proto new
+40
@@ -0,0 +1,40 @@
1 +package merkledag
2 +
3 +import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
4 +
5 +option (gogoproto.gostring_all) = true;
6 +option (gogoproto.equal_all) = true;
7 +option (gogoproto.verbose_equal_all) = true;
8 +option (gogoproto.goproto_stringer_all) = false;
9 +option (gogoproto.stringer_all) = true;
10 +option (gogoproto.populate_all) = true;
11 +option (gogoproto.testgen_all) = true;
12 +option (gogoproto.benchgen_all) = true;
13 +option (gogoproto.marshaler_all) = true;
14 +option (gogoproto.sizer_all) = true;
15 +option (gogoproto.unmarshaler_all) = true;
16 +
17 +
18 +// An IPFS MerkleDAG Node
19 +message PBNode {
20 +
21 + // refs to other objects
22 + repeated Link Links = 2;
23 +
24 + // opaque user data
25 + optional bytes Data = 1;
26 +}
27 +
28 +
29 +// An IPFS MerkleDAG Link
30 +message PBLink {
31 +
32 + // multihash of the target object
33 + optional bytes Hash = 1;
34 +
35 + // utf string name. should be unique per object
36 + optional string Name = 2;
37 +
38 + // cumulative size of target object
39 + optional uint64 Size = 3;
40 +}