diff --git a/merkledag/coding.go b/merkledag/coding.go index e538e519c..e76af12c7 100644 --- a/merkledag/coding.go +++ b/merkledag/coding.go @@ -60,7 +60,9 @@ func (n *ProtoNode) getPBNode() *pb.PBNode { pbn.Links[i] = &pb.PBLink{} pbn.Links[i].Name = &l.Name pbn.Links[i].Tsize = &l.Size - pbn.Links[i].Hash = l.Cid.Bytes() + if l.Cid != nil { + pbn.Links[i].Hash = l.Cid.Bytes() + } } if len(n.data) > 0 { diff --git a/merkledag/node.go b/merkledag/node.go index 38a47382b..4f0d72bc9 100644 --- a/merkledag/node.go +++ b/merkledag/node.go @@ -2,6 +2,7 @@ package merkledag import ( "context" + "encoding/json" "fmt" node "gx/ipfs/QmRSU5EqqWVZSNdbU51yXmVoF1uNw3JgTNB6RaiL7DZM16/go-ipld-node" @@ -228,6 +229,31 @@ func (n *ProtoNode) Loggable() map[string]interface{} { } } +func (n *ProtoNode) UnmarshalJSON(b []byte) error { + s := struct { + Data []byte `json:"data"` + Links []*node.Link `json:"links"` + }{} + + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + n.data = s.Data + n.links = s.Links + return nil +} + +func (n *ProtoNode) MarshalJSON() ([]byte, error) { + out := map[string]interface{}{ + "data": n.data, + "links": n.links, + } + + return json.Marshal(out) +} + func (n *ProtoNode) Cid() *cid.Cid { if n.encoded != nil && n.cached != nil { return n.cached diff --git a/merkledag/node_test.go b/merkledag/node_test.go index beec7ba65..63f0473ba 100644 --- a/merkledag/node_test.go +++ b/merkledag/node_test.go @@ -1,6 +1,7 @@ package merkledag_test import ( + "bytes" "context" "testing" @@ -128,3 +129,32 @@ func TestNodeCopy(t *testing.T) { t.Fatal("should be different objects") } } + +func TestJsonRoundtrip(t *testing.T) { + nd := new(ProtoNode) + nd.SetLinks([]*node.Link{ + {Name: "a"}, + {Name: "c"}, + {Name: "b"}, + }) + nd.SetData([]byte("testing")) + + jb, err := nd.MarshalJSON() + if err != nil { + t.Fatal(err) + } + + nn := new(ProtoNode) + err = nn.UnmarshalJSON(jb) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(nn.Data(), nd.Data()) { + t.Fatal("data wasnt the same") + } + + if !nn.Cid().Equals(nd.Cid()) { + t.Fatal("objects differed after marshaling") + } +} diff --git a/test/sharness/t0053-dag.sh b/test/sharness/t0053-dag.sh index bce877893..e7ae42c3e 100755 --- a/test/sharness/t0053-dag.sh +++ b/test/sharness/t0053-dag.sh @@ -46,6 +46,19 @@ test_dag_cmd() { test_cmp file2 out2 && test_cmp file3 out3 ' + + test_expect_success "add a normal file" ' + HASH=$(echo "foobar" | ipfs add -q) + ' + + test_expect_success "can view protobuf object with dag get" ' + ipfs dag get $HASH > dag_get_pb_out + ' + + test_expect_success "output looks correct" ' + echo "{\"data\":\"CAISB2Zvb2JhcgoYBw==\",\"links\":[]}" > dag_get_pb_exp && + test_cmp dag_get_pb_exp dag_get_pb_out + ' } # should work offline