diff --git a/varint.go b/varint.go index 79ebe2f..b8b1507 100644 --- a/varint.go +++ b/varint.go @@ -8,12 +8,18 @@ import ( // VarintSize returns the size (in bytes) of `num` encoded as a varint. func VarintSize(num int) int { - return bits.Len(uint(num))/7 + 1 + bits := bits.Len(uint(num)) + q, r := bits/7, bits%7 + size := q + if r > 0 || size == 0 { + size++ + } + return size } // CodeToVarint converts an integer to a varint-encoded []byte func CodeToVarint(num int) []byte { - buf := make([]byte, bits.Len(uint(num))/7+1) + buf := make([]byte, VarintSize(num)) n := binary.PutUvarint(buf, uint64(num)) return buf[:n] } diff --git a/varint_test.go b/varint_test.go new file mode 100644 index 0000000..817b3dd --- /dev/null +++ b/varint_test.go @@ -0,0 +1,23 @@ +package multiaddr + +import ( + "encoding/binary" + "testing" +) + +func checkVarint(t *testing.T, x int) { + buf := make([]byte, binary.MaxVarintLen64) + expected := binary.PutUvarint(buf, uint64(x)) + + size := VarintSize(x) + if size != expected { + t.Fatalf("expected varintsize of %d to be %d, got %d", x, expected, size) + } +} + +func TestVarintSize(t *testing.T) { + max := 1 << 16 + for x := 0; x < max; x++ { + checkVarint(t, x) + } +}