diff --git a/inline.go b/inline.go new file mode 100644 index 0000000..f623099 --- /dev/null +++ b/inline.go @@ -0,0 +1,26 @@ +package cidutil + +import ( + cid "github.com/ipfs/go-cid" + mhash "github.com/multiformats/go-multihash" +) + +// InlineBuilder is a cid.Builder that will use the id multihash when the +// size of the content is no more than limit +type InlineBuilder struct { + cid.Builder // Parent Builder + Limit int // Limit (inclusive) +} + +// WithCodec implements the cid.Builder interface +func (p InlineBuilder) WithCodec(c uint64) cid.Builder { + return InlineBuilder{p.Builder.WithCodec(c), p.Limit} +} + +// Sum implements the cid.Builder interface +func (p InlineBuilder) Sum(data []byte) (*cid.Cid, error) { + if len(data) > p.Limit { + return p.Builder.Sum(data) + } + return cid.V1Builder{Codec: p.GetCodec(), MhType: mhash.ID}.Sum(data) +} diff --git a/inline_test.go b/inline_test.go new file mode 100644 index 0000000..99bad7d --- /dev/null +++ b/inline_test.go @@ -0,0 +1,33 @@ +package cidutil + +import ( + "math/rand" + "testing" + + cid "github.com/ipfs/go-cid" + mhash "github.com/multiformats/go-multihash" +) + +func TestInlineBuilderSmallValue(t *testing.T) { + builder := InlineBuilder{cid.V0Builder{}, 64} + c, err := builder.Sum([]byte("Hello World")) + if err != nil { + t.Fatal(err) + } + if c.Prefix().MhType != mhash.ID { + t.Fatal("Inliner builder failed to use ID Multihash on small values") + } +} + +func TestInlinerBuilderLargeValue(t *testing.T) { + builder := InlineBuilder{cid.V0Builder{}, 64} + data := make([]byte, 512) + rand.Read(data) + c, err := builder.Sum(data) + if err != nil { + t.Fatal(err) + } + if c.Prefix().MhType == mhash.ID { + t.Fatal("Inliner builder used ID Multihash on large values") + } +}