When reading from an io.Reader that has no data, the io.EOF error should not be wrapped in ErrInvalidCid. This is not an invalid CID, and is not the same as a partial read which is indicated by io.ErrUnexpectedEOF.
This fix is needed because existing code that uses CidFromReader may check for the end of an input stream by `if err == io.EOF` instead of the preferred `if errors.Is(err, io.EOF)`, and that code break at runtime after upgrading to go-cid v0.4.0.
* refactor: remove Codecs table
* chore: go-cid 0.2.0
Codec table was missing dag-json and it had invalid code for dag-cbor.
It also had invalid string representation of dag-pb -- it was using
'protobuf' which is a totally different code.
This removes invalid mappings entirely.
https://github.com/multiformats/go-multicodec should be used instead.
We allocate once via "make([]byte, len)",
and again when that buffer is converted to a string.
Thankfully, since Go 1.10 we have strings.Builder,
designed specifically for this use case.
In a downstream benchmark in go-car,
which needs to reconstruct many CID values,
we see small but nice gains:
name old time/op new time/op delta
ReadBlocks-16 1.09ms ± 4% 1.06ms ± 5% -3.33% (p=0.007 n=11+11)
name old speed new speed delta
ReadBlocks-16 478MB/s ± 4% 494MB/s ± 5% +3.46% (p=0.007 n=11+11)
name old alloc/op new alloc/op delta
ReadBlocks-16 1.30MB ± 0% 1.25MB ± 0% -3.86% (p=0.000 n=12+12)
name old allocs/op new allocs/op delta
ReadBlocks-16 9.50k ± 0% 8.45k ± 0% -11.05% (p=0.000 n=12+12)
The append+make slice extension idiom works, but note that append uses
the slice's length as its base. We need to append the number of bytes
required for length to reach cidLength, not the capacity.
The added test case panicked before this change, and works now:
--- FAIL: TestReadCidsFromBuffer (0.00s)
panic: runtime error: slice bounds out of range [:73] with capacity 64 [recovered]
panic: runtime error: slice bounds out of range [:73] with capacity 64
goroutine 37 [running]:
testing.tRunner.func1.2({0x570d60, 0xc000016438})
testing/testing.go:1203 +0x24e
testing.tRunner.func1()
testing/testing.go:1206 +0x218
panic({0x570d60, 0xc000016438})
runtime/panic.go:1038 +0x215
github.com/ipfs/go-cid.CidFromReader({0x5b0e20, 0xc000010900})
github.com/ipfs/go-cid/cid.go:803 +0x75f
github.com/ipfs/go-cid.TestReadCidsFromBuffer(0xc00014ba00)
github.com/ipfs/go-cid/cid_test.go:710 +0x625
testing.tRunner(0xc00014ba00, 0x58af38)
testing/testing.go:1253 +0x102
created by testing.(*T).Run
testing/testing.go:1300 +0x35a
exit status 2
FAIL github.com/ipfs/go-cid 0.004s
This makes Cid implement https://golang.org/pkg/encoding/#BinaryMarshaler
which is used by go-codec to decide if things know how to serialize themselves
(currently we need do manual wrapping for anything containing a CID).
Since I was at it, I did the TextMarshaling one too.