Unverified Commit 8ec0ca07 authored by Rod Vagg's avatar Rod Vagg

add wrapping utilities, more tests ported from JS

parent e34a566d
coverage.out
package dagpb
import (
"encoding/hex"
"reflect"
"strings"
"testing"
cid "github.com/ipfs/go-cid"
)
func mkcid(t *testing.T, cidStr string) cid.Cid {
c, err := cid.Decode(cidStr)
if err != nil {
t.Fatal(err)
}
return c
}
func TestEmptyNode(t *testing.T) {
n := NewPBNode()
byts, err := n.Marshal()
if err != nil {
t.Fatal(err)
}
rn, err := UnmarshalPBNode(byts)
if err != nil {
t.Fatal(err)
}
if rn.Data != nil {
t.Errorf("Expected nil PBNode#Data")
}
if rn.Links == nil || len(rn.Links) != 0 {
t.Errorf("Expected zero-length PBNode#Links")
}
}
func TestNodeWithData(t *testing.T) {
n := NewPBNode()
n.Data = []byte{0, 1, 2, 3, 4}
byts, err := n.Marshal()
if err != nil {
t.Fatal(err)
}
rn, err := UnmarshalPBNode(byts)
if err != nil {
t.Fatal(err)
}
if rn.Data == nil {
t.Errorf("Expected non-nil PBNode#Data")
}
if !reflect.DeepEqual(rn.Data, []byte{0, 1, 2, 3, 4}) {
t.Errorf("Didn't get expected bytes")
}
if rn.Links == nil || len(rn.Links) != 0 {
t.Errorf("Expected zero-length PBNode#Links")
}
}
func TestNodeWithLink(t *testing.T) {
n := NewPBNode()
n.Links = append(n.Links, NewPBLinkFromCid(mkcid(t, "QmWDtUQj38YLW8v3q4A6LwPn4vYKEbuKWpgSm6bjKW6Xfe")))
byts, err := n.Marshal()
if err != nil {
t.Fatal(err)
}
rn, err := UnmarshalPBNode(byts)
if err != nil {
t.Fatal(err)
}
if rn.Data != nil {
t.Errorf("Expected nil PBNode#Data")
}
if rn.Links == nil || len(rn.Links) != 1 {
t.Errorf("Expected one PBNode#Links element")
}
if rn.Links[0].Tsize != nil || rn.Links[0].Name != nil {
t.Errorf("Expected Tsize and Name to be nil")
}
if rn.Links[0].Hash.String() != "QmWDtUQj38YLW8v3q4A6LwPn4vYKEbuKWpgSm6bjKW6Xfe" {
t.Errorf("Got unexpected Hash")
}
}
func TestNodeWithTwoUnsortedLinks(t *testing.T) {
n := NewPBNodeFromData([]byte("some data"))
n.Links = append(n.Links, NewPBLink("some other link", mkcid(t, "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V"), 8))
n.Links = append(n.Links, NewPBLink("some link", mkcid(t, "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39U"), 100000000))
byts, err := n.Marshal()
if err == nil || !strings.Contains(err.Error(), "links must be sorted") || byts != nil {
t.Fatal("Expected to error from unsorted links")
}
n.SortLinks()
if byts, err = n.Marshal(); err != nil {
t.Fatal(err)
}
expectedBytes := "12340a2212208ab7a6c5e74737878ac73863cb76739d15d4666de44e5756bf55a2f9e9ab5f431209736f6d65206c696e6b1880c2d72f12370a2212208ab7a6c5e74737878ac73863cb76739d15d4666de44e5756bf55a2f9e9ab5f44120f736f6d65206f74686572206c696e6b18080a09736f6d652064617461"
if hex.EncodeToString(byts) != expectedBytes {
t.Fatal("Did not get expected bytes")
}
rn, err := UnmarshalPBNode(byts)
if err != nil {
t.Fatal(err)
}
if rn.Data == nil || !reflect.DeepEqual(rn.Data, []byte("some data")) {
t.Errorf("Did not match expected PBNode#Data")
}
if rn.Links == nil || len(rn.Links) != 2 {
t.Errorf("Expected two PBNode#Links elements")
}
if rn.Links[0].Tsize == nil || rn.Links[0].Name == nil || rn.Links[1].Tsize == nil || rn.Links[1].Name == nil {
t.Errorf("Expected Tsize and Name to not be nil")
}
if rn.Links[0].Hash.String() != "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39U" {
t.Errorf("Got unexpected Hash 0")
}
if rn.Links[1].Hash.String() != "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V" {
t.Errorf("Got unexpected Hash 1")
}
if *rn.Links[0].Name != "some link" {
t.Errorf("Got unexpected Name 0")
}
if *rn.Links[1].Name != "some other link" {
t.Errorf("Got unexpected Name 1")
}
if *rn.Links[0].Tsize != 100000000 {
t.Errorf("Got unexpected Tsize 0")
}
if *rn.Links[1].Tsize != 8 {
t.Errorf("Got unexpected Tsize 1")
}
}
func TestNodeWithStableSortedLinks(t *testing.T) {
n := NewPBNodeFromData([]byte("some data"))
cids := []string{
"QmUGhP2X8xo9dsj45vqx1H6i5WqPqLqmLQsHTTxd3ke8mp",
"QmP7SrR76KHK9A916RbHG1ufy2TzNABZgiE23PjZDMzZXy",
"QmQg1v4o9xdT3Q14wh4S7dxZkDjyZ9ssFzFzyep1YrVJBY",
"QmdP6fartWRrydZCUjHgrJ4XpxSE4SAoRsWJZ1zJ4MWiuf",
"QmNNjUStxtMC1WaSZYiDW6CmAUrvd5Q2e17qnxPgVdwrwW",
"QmWJwqZBJWerHsN1b7g4pRDYmzGNnaMYuD3KSbnpaxsB2h",
"QmRXPSdysBS3dbUXe6w8oXevZWHdPQWaR2d3fggNsjvieL",
"QmTUZAXfws6zrhEksnMqLxsbhXZBQs4FNiarjXSYQqVrjC",
"QmNNk7dTdh8UofwgqLNauq6N78DPc6LKK2yBs1MFdx7Mbg",
"QmW5mrJfyqh7B4ywSvraZgnWjS3q9CLiYURiJpCX3aro5i",
"QmTFHZL5CkgNz19MdPnSuyLAi6AVq9fFp81zmPpaL2amED",
}
// name is the same for all, they should remain unsorted
for _, c := range cids {
n.Links = append(n.Links, NewPBLink("", mkcid(t, c), 262158))
}
byts, err := n.Marshal()
if err != nil {
t.Fatal(err)
}
n.SortLinks()
byts2, err := n.Marshal()
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(byts2, byts) {
t.Errorf("Sort was not stable for unnamed links")
}
rn, err := UnmarshalPBNode(byts)
if err != nil {
t.Fatal(err)
}
for i, link := range rn.Links {
if link.Hash.String() != cids[i] {
t.Errorf("Link #%d does not match expected (%v)", i, cids[i])
}
}
}
func TestNodeWithUnnamedLinksFixture(t *testing.T) {
fixture := "122b0a2212203f29086b59b9e046b362b4b19c9371e834a9f5a80597af83be6d8b7d1a5ad33b120018aed4e015122b0a221220ae1a5afd7c770507dddf17f92bba7a326974af8ae5277c198cf13206373f7263120018aed4e015122b0a22122022ab2ebf9c3523077bd6a171d516ea0e1be1beb132d853778bcc62cd208e77f1120018aed4e015122b0a22122040a77fe7bc69bbef2491f7633b7c462d0bce968868f88e2cbcaae9d0996997e8120018aed4e015122b0a2212206ae1979b14dd43966b0241ebe80ac2a04ad48959078dc5affa12860648356ef6120018aed4e015122b0a221220a957d1f89eb9a861593bfcd19e0637b5c957699417e2b7f23c88653a240836c4120018aed4e015122b0a221220345f9c2137a2cd76d7b876af4bfecd01f80b7dd125f375cb0d56f8a2f96de2c31200189bfec10f0a2b080218cbc1819201208080e015208080e015208080e015208080e015208080e015208080e01520cbc1c10f"
expectedLinks := []*PBLink{
NewPBLink("", mkcid(t, "QmSbCgdsX12C4KDw3PDmpBN9iCzS87a5DjgSCoW9esqzXk"), 45623854),
NewPBLink("", mkcid(t, "Qma4GxWNhywSvWFzPKtEswPGqeZ9mLs2Kt76JuBq9g3fi2"), 45623854),
NewPBLink("", mkcid(t, "QmQfyxyys7a1e3mpz9XsntSsTGc8VgpjPj5BF1a1CGdGNc"), 45623854),
NewPBLink("", mkcid(t, "QmSh2wTTZT4N8fuSeCFw7wterzdqbE93j1XDhfN3vQHzDV"), 45623854),
NewPBLink("", mkcid(t, "QmVXsSVjwxMsCwKRCUxEkGb4f4B98gXVy3ih3v4otvcURK"), 45623854),
NewPBLink("", mkcid(t, "QmZjhH97MEYwQXzCqSQbdjGDhXWuwW4RyikR24pNqytWLj"), 45623854),
NewPBLink("", mkcid(t, "QmRs6U5YirCqC7taTynz3x2GNaHJZ3jDvMVAzaiXppwmNJ"), 32538395),
}
byts, err := hex.DecodeString(fixture)
rn, err := UnmarshalPBNode(byts)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rn.Links, expectedLinks) {
t.Errorf("Didn't get expected Links array")
}
}
func TestNodeWithNamedLinksFixture(t *testing.T) {
fixture := "12390a221220b4397c02da5513563d33eef894bf68f2ccdf1bdfc14a976956ab3d1c72f735a0120e617564696f5f6f6e6c792e6d346118cda88f0b12310a221220025c13fcd1a885df444f64a4a82a26aea867b1148c68cb671e83589f971149321208636861742e74787418e40712340a2212205d44a305b9b328ab80451d0daa72a12a7bf2763c5f8bbe327597a31ee40d1e48120c706c61796261636b2e6d3375187412360a2212202539ed6e85f2a6f9097db9d76cffd49bf3042eb2e3e8e9af4a3ce842d49dea22120a7a6f6f6d5f302e6d70341897fb8592010a020801"
expectedLinks := []*PBLink{
NewPBLink("audio_only.m4a", mkcid(t, "QmaUAwAQJNtvUdJB42qNbTTgDpzPYD1qdsKNtctM5i7DGB"), 23319629),
NewPBLink("chat.txt", mkcid(t, "QmNVrxbB25cKTRuKg2DuhUmBVEK9NmCwWEHtsHPV6YutHw"), 996),
NewPBLink("playback.m3u", mkcid(t, "QmUcjKzDLXBPmB6BKHeKSh6ZoFZjss4XDhMRdLYRVuvVfu"), 116),
NewPBLink("zoom_0.mp4", mkcid(t, "QmQqy2SiEkKgr2cw5UbQ93TtLKEMsD8TdcWggR8q9JabjX"), 306281879),
}
byts, err := hex.DecodeString(fixture)
rn, err := UnmarshalPBNode(byts)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(rn.Links, expectedLinks) {
t.Errorf("Didn't get expected Links array")
}
}
......@@ -5,12 +5,15 @@ package dagpb
import (
"encoding/hex"
"encoding/json"
"strings"
"testing"
cid "github.com/ipfs/go-cid"
)
var dataZero []byte = make([]byte, 0)
var dataSome []byte = []byte{0, 1, 2, 3, 4}
var cidBytes []byte = []byte{1, 85, 0, 5, 0, 1, 2, 3, 4}
var acid cid.Cid = _mkcid()
var zeroName string = ""
var someName string = "some name"
var zeroTsize uint64 = 0
......@@ -22,6 +25,8 @@ type testCase struct {
node *PBNode
expectedBytes string
expectedForm string
encodeError string
decodeError string
}
var testCases = []testCase{
......@@ -29,74 +34,70 @@ var testCases = []testCase{
name: "empty",
node: &PBNode{},
expectedBytes: "",
expectedForm: "{}",
expectedForm: `{
"Links": []
}`,
encodeError: "Links must be an array",
},
{
name: "Data zero",
node: &PBNode{Data: dataZero},
expectedBytes: "0a00",
expectedForm: `{
"Data": ""
"Data": "",
"Links": []
}`,
encodeError: "Links must be an array",
},
{
name: "Data some",
node: &PBNode{Data: dataSome},
expectedBytes: "0a050001020304",
expectedForm: `{
"Data": "0001020304"
"Data": "0001020304",
"Links": []
}`,
encodeError: "Links must be an array",
},
{
name: "Links zero",
node: &PBNode{Links: make([]*PBLink, 0)},
expectedBytes: "",
expectedForm: "{}",
expectedForm: `{
"Links": []
}`,
},
{
name: "Data some Links zero",
node: &PBNode{Data: dataSome, Links: make([]*PBLink, 0)},
expectedBytes: "0a050001020304",
expectedForm: `{
"Data": "0001020304"
"Data": "0001020304",
"Links": []
}`,
},
{
name: "Links empty",
node: &PBNode{Links: []*PBLink{{}}},
expectedBytes: "1200",
expectedForm: `{
"Links": [
{}
]
}`,
encodeError: "link must have a Hash",
decodeError: "expected CID",
},
{
name: "Data some Links empty",
node: &PBNode{Data: dataSome, Links: []*PBLink{{}}},
expectedBytes: "12000a050001020304",
expectedForm: `{
"Data": "0001020304",
"Links": [
{}
]
}`,
encodeError: "link must have a Hash",
decodeError: "expected CID",
},
{
name: "Links Hash zero",
node: &PBNode{Links: []*PBLink{{Hash: dataZero}}},
expectedBytes: "12020a00",
expectedForm: `{
"Links": [
{
"Hash": ""
}
]
}`,
decodeError: "expected CID", // error should come up from go-cid too
},
{
name: "Links Hash some",
node: &PBNode{Links: []*PBLink{{Hash: cidBytes}}},
node: &PBNode{Links: []*PBLink{{Hash: &acid}}},
expectedBytes: "120b0a09015500050001020304",
expectedForm: `{
"Links": [
......@@ -110,17 +111,12 @@ var testCases = []testCase{
name: "Links Name zero",
node: &PBNode{Links: []*PBLink{{Name: &zeroName}}},
expectedBytes: "12021200",
expectedForm: `{
"Links": [
{
"Name": ""
}
]
}`,
encodeError: "link must have a Hash",
decodeError: "expected CID",
},
{
name: "Links Hash some Name zero",
node: &PBNode{Links: []*PBLink{{Hash: cidBytes, Name: &zeroName}}},
node: &PBNode{Links: []*PBLink{{Hash: &acid, Name: &zeroName}}},
expectedBytes: "120d0a090155000500010203041200",
expectedForm: `{
"Links": [
......@@ -135,17 +131,12 @@ var testCases = []testCase{
name: "Links Name some",
node: &PBNode{Links: []*PBLink{{Name: &someName}}},
expectedBytes: "120b1209736f6d65206e616d65",
expectedForm: `{
"Links": [
{
"Name": "some name"
}
]
}`,
encodeError: "link must have a Hash",
decodeError: "expected CID",
},
{
name: "Links Hash some Name some",
node: &PBNode{Links: []*PBLink{{Hash: cidBytes, Name: &someName}}},
node: &PBNode{Links: []*PBLink{{Hash: &acid, Name: &someName}}},
expectedBytes: "12160a090155000500010203041209736f6d65206e616d65",
expectedForm: `{
"Links": [
......@@ -160,17 +151,12 @@ var testCases = []testCase{
name: "Links Tsize zero",
node: &PBNode{Links: []*PBLink{{Tsize: &zeroTsize}}},
expectedBytes: "12021800",
expectedForm: `{
"Links": [
{
"Tsize": 0
}
]
}`,
encodeError: "link must have a Hash",
decodeError: "expected CID",
},
{
name: "Links Hash some Tsize zero",
node: &PBNode{Links: []*PBLink{{Hash: cidBytes, Tsize: &zeroTsize}}},
node: &PBNode{Links: []*PBLink{{Hash: &acid, Tsize: &zeroTsize}}},
expectedBytes: "120d0a090155000500010203041800",
expectedForm: `{
"Links": [
......@@ -185,17 +171,12 @@ var testCases = []testCase{
name: "Links Tsize some",
node: &PBNode{Links: []*PBLink{{Tsize: &someTsize}}},
expectedBytes: "120318f207",
expectedForm: `{
"Links": [
{
"Tsize": 1010
}
]
}`,
encodeError: "link must have a Hash",
decodeError: "expected CID",
},
{
name: "Links Hash some Tsize some",
node: &PBNode{Links: []*PBLink{{Hash: cidBytes, Tsize: &largeTsize}}},
node: &PBNode{Links: []*PBLink{{Hash: &acid, Tsize: &largeTsize}}},
expectedBytes: "12140a0901550005000102030418ffffffffffffff0f",
expectedForm: `{
"Links": [
......@@ -217,43 +198,80 @@ func TestCompat(t *testing.T) {
}
func verifyRoundTrip(t *testing.T, tc testCase) {
actualBytes, actualForm, err := nodeRoundTripToString(t, tc.node)
if err != nil {
t.Fatal(err)
}
if actualBytes != tc.expectedBytes {
t.Logf(
"Expected bytes: [%v]\nGot: [%v]\n",
tc.expectedBytes,
actualBytes)
t.Error("Did not match")
var err error
var actualBytes string
var actualForm string
if tc.node != nil {
actualBytes, err = nodeToString(t, tc.node)
if tc.encodeError != "" {
if err != nil {
if !strings.Contains(err.Error(), tc.encodeError) {
t.Fatalf("got unexpeced encode error: [%v] (expected [%v])", err.Error(), tc.encodeError)
}
} else {
t.Fatalf("did not get expected encode error: %v", tc.encodeError)
}
} else {
if err != nil {
t.Fatal(err)
} else {
if actualBytes != tc.expectedBytes {
t.Logf(
"Expected bytes: [%v]\nGot: [%v]\n",
tc.expectedBytes,
actualBytes)
t.Error("Did not match")
}
}
}
}
if actualForm != tc.expectedForm {
t.Logf(
"Expected form: [%v]\nGot: [%v]\n",
tc.expectedForm,
actualForm)
t.Error("Did not match")
actualForm, err = bytesToFormString(t, tc.expectedBytes)
if tc.decodeError != "" {
if err != nil {
if !strings.Contains(err.Error(), tc.decodeError) {
t.Fatalf("got unexpeced decode error: [%v] (expected [%v])", err.Error(), tc.decodeError)
}
} else {
t.Fatalf("did not get expected decode error: %v", tc.decodeError)
}
} else {
if err != nil {
t.Fatal(err)
}
if actualForm != tc.expectedForm {
t.Logf(
"Expected form: [%v]\nGot: [%v]\n",
tc.expectedForm,
actualForm)
t.Error("Did not match")
}
}
}
func nodeRoundTripToString(t *testing.T, n *PBNode) (string, string, error) {
func nodeToString(t *testing.T, n *PBNode) (string, error) {
bytes, err := n.Marshal()
if err != nil {
return "", "", err
return "", err
}
t.Logf("[%v]\n", hex.EncodeToString(bytes))
rt := new(PBNode)
if err := rt.Unmarshal(bytes); err != nil {
return "", "", err
return hex.EncodeToString(bytes), nil
}
func bytesToFormString(t *testing.T, bytesHex string) (string, error) {
bytes, err := hex.DecodeString(bytesHex)
if err != nil {
return "", err
}
var rt *PBNode
if rt, err = UnmarshalPBNode(bytes); err != nil {
return "", err
}
str, err := json.MarshalIndent(cleanPBNode(t, rt), "", "\t")
if err != nil {
return "", "", err
return "", err
}
return hex.EncodeToString(bytes), string(str), nil
return string(str), nil
}
// convert a PBLink into a map for clean JSON marshalling
......@@ -263,7 +281,7 @@ func cleanPBLink(t *testing.T, link *PBLink) map[string]interface{} {
}
nl := make(map[string]interface{})
if link.Hash != nil {
nl["Hash"] = hex.EncodeToString(link.Hash)
nl["Hash"] = hex.EncodeToString(link.Hash.Bytes())
}
if link.Name != nil {
nl["Name"] = link.Name
......@@ -289,3 +307,8 @@ func cleanPBNode(t *testing.T, node *PBNode) map[string]interface{} {
}
return nn
}
func _mkcid() cid.Cid {
_, c, _ := cid.CidFromBytes([]byte{1, 85, 0, 5, 0, 1, 2, 3, 4})
return c
}
package dagpb
import (
"sort"
cid "github.com/ipfs/go-cid"
)
// PBLink ...
type PBLink struct {
Hash []byte
Hash *cid.Cid
Name *string
Tsize *uint64
}
......@@ -12,3 +18,45 @@ type PBNode struct {
Links []*PBLink
Data []byte
}
func NewPBNode() *PBNode {
n := &PBNode{Links: make([]*PBLink, 0)}
return n
}
func NewPBNodeFromData(data []byte) *PBNode {
n := &PBNode{Data: data, Links: make([]*PBLink, 0)}
return n
}
func UnmarshalPBNode(bytes []byte) (*PBNode, error) {
n := NewPBNode()
if err := n.Unmarshal(bytes); err != nil {
return nil, err
}
return n, nil
}
func NewPBLinkFromCid(c cid.Cid) *PBLink {
l := &PBLink{Hash: &c}
return l
}
func NewPBLink(name string, c cid.Cid, tsize uint64) *PBLink {
l := &PBLink{Name: &name, Hash: &c, Tsize: &tsize}
return l
}
func (node *PBNode) SortLinks() {
sort.Stable(pbLinkSlice(node.Links))
}
type pbLinkSlice []*PBLink
func (ls pbLinkSlice) Len() int { return len(ls) }
func (ls pbLinkSlice) Swap(a, b int) { ls[a], ls[b] = ls[b], ls[a] }
func (ls pbLinkSlice) Less(a, b int) bool { return pbLinkLess(ls[a], ls[b]) }
func pbLinkLess(a *PBLink, b *PBLink) bool {
return *a.Name < *b.Name
}
......@@ -3,24 +3,28 @@ package dagpb
// based on the original pb codegen
import (
"fmt"
math_bits "math/bits"
)
// Marshal TODO
func (m *PBNode) Marshal() (data []byte, err error) {
size := m.size()
func (node *PBNode) Marshal() (data []byte, err error) {
if err := node.validate(); err != nil {
return nil, err
}
size := node.size()
data = make([]byte, size)
i := len(data)
if m.Data != nil {
i -= len(m.Data)
copy(data[i:], m.Data)
i = encodeVarint(data, i, uint64(len(m.Data))) - 1
if node.Data != nil {
i -= len(node.Data)
copy(data[i:], node.Data)
i = encodeVarint(data, i, uint64(len(node.Data))) - 1
data[i] = 0xa
}
if len(m.Links) > 0 {
for iNdEx := len(m.Links) - 1; iNdEx >= 0; iNdEx-- {
size, err := m.Links[iNdEx].marshal(data[:i])
if len(node.Links) > 0 {
for iNdEx := len(node.Links) - 1; iNdEx >= 0; iNdEx-- {
size, err := node.Links[iNdEx].marshal(data[:i])
if err != nil {
return nil, err
}
......@@ -32,59 +36,82 @@ func (m *PBNode) Marshal() (data []byte, err error) {
return data[:size], nil
}
func (m *PBLink) marshal(data []byte) (int, error) {
func (link *PBLink) marshal(data []byte) (int, error) {
i := len(data)
if m.Tsize != nil {
i = encodeVarint(data, i, uint64(*m.Tsize)) - 1
if link.Tsize != nil {
i = encodeVarint(data, i, uint64(*link.Tsize)) - 1
data[i] = 0x18
}
if m.Name != nil {
i -= len(*m.Name)
copy(data[i:], *m.Name)
i = encodeVarint(data, i, uint64(len(*m.Name))) - 1
if link.Name != nil {
i -= len(*link.Name)
copy(data[i:], *link.Name)
i = encodeVarint(data, i, uint64(len(*link.Name))) - 1
data[i] = 0x12
}
if m.Hash != nil {
i -= len(m.Hash)
copy(data[i:], m.Hash)
i = encodeVarint(data, i, uint64(len(m.Hash))) - 1
if link.Hash != nil {
byts := link.Hash.Bytes()
i -= len(byts)
copy(data[i:], byts)
i = encodeVarint(data, i, uint64(len(byts))) - 1
data[i] = 0xa
} else {
return 0, fmt.Errorf("invalid DAG-PB form (link must have a Hash)")
}
return len(data) - i, nil
}
func (m *PBLink) size() (n int) {
if m == nil {
func (node *PBNode) validate() error {
if node == nil {
return fmt.Errorf("PBNode not defined")
}
if node.Links == nil {
return fmt.Errorf("invalid DAG-PB form (Links must be an array)")
}
for i, link := range node.Links {
if link.Hash == nil {
return fmt.Errorf("invalid DAG-PB form (link must have a Hash)")
}
if i > 0 && pbLinkLess(link, node.Links[i-1]) {
return fmt.Errorf("invalid DAG-PB form (links must be sorted by Name bytes)")
}
}
return nil
}
func (link *PBLink) size() (n int) {
if link == nil {
return 0
}
var l int
_ = l
if m.Hash != nil {
l = len(m.Hash)
if link.Hash != nil {
l = link.Hash.ByteLen()
n += 1 + l + sizeOfVarint(uint64(l))
}
if m.Name != nil {
l = len(*m.Name)
if link.Name != nil {
l = len(*link.Name)
n += 1 + l + sizeOfVarint(uint64(l))
}
if m.Tsize != nil {
n += 1 + sizeOfVarint(uint64(*m.Tsize))
if link.Tsize != nil {
n += 1 + sizeOfVarint(uint64(*link.Tsize))
}
return n
}
func (m *PBNode) size() (n int) {
if m == nil {
func (node *PBNode) size() (n int) {
if node == nil {
return 0
}
var l int
_ = l
if m.Data != nil {
l = len(m.Data)
if node.Data != nil {
l = len(node.Data)
n += 1 + l + sizeOfVarint(uint64(l))
}
if len(m.Links) > 0 {
for _, e := range m.Links {
if len(node.Links) > 0 {
for _, e := range node.Links {
l = e.size()
n += 1 + l + sizeOfVarint(uint64(l))
}
......
......@@ -3,6 +3,8 @@ package dagpb
import (
"fmt"
"io"
cid "github.com/ipfs/go-cid"
)
// Unmarshal TODO
......@@ -47,6 +49,10 @@ func (node *PBNode) Unmarshal(data []byte) error {
if index > l {
return io.ErrUnexpectedEOF
}
if node.Links == nil {
node.Links = make([]*PBLink, 0)
}
return nil
}
......@@ -74,9 +80,15 @@ func (link *PBLink) unmarshal(data []byte) error {
return fmt.Errorf("protobuf: (PBLink) wrong wireType (%d) for Hash", wireType)
}
if link.Hash, index, err = decodeBytes(data, index); err != nil {
var chunk []byte
if chunk, index, err = decodeBytes(data, index); err != nil {
return err
}
var c cid.Cid
if _, c, err = cid.CidFromBytes(chunk); err != nil {
return fmt.Errorf("invalid Hash field found in link, expected CID (%v)", err)
}
link.Hash = &c
} else if fieldNum == 2 {
if link.Name != nil {
return fmt.Errorf("protobuf: (PBLink) duplicate Name section")
......@@ -115,6 +127,10 @@ func (link *PBLink) unmarshal(data []byte) error {
if index > l {
return io.ErrUnexpectedEOF
}
if link.Hash == nil {
return fmt.Errorf("invalid Hash field found in link, expected CID")
}
return nil
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment