Skip to content

Commit 35a92f9

Browse files
committed
encoding/binary: add AppendVarint AppendUvarint
This adds a straight-forward implementation of the functionality. A more performant version could be added that unrolls the loop as is done in google.golang.org/protobuf/encoding/protowire, but usages that demand high performance can use that package instead. Fixes #51644 Change-Id: I9d3b615a60cdff47e5200e7e5d2276adf4c93783 Reviewed-on: https://go-review.googlesource.com/c/go/+/400176 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Run-TryBot: Joseph Tsai <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 5a4f0b6 commit 35a92f9

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

api/next/51644.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pkg encoding/binary, func AppendUvarint([]uint8, uint64) []uint8 #51644
2+
pkg encoding/binary, func AppendVarint([]uint8, int64) []uint8 #51644

src/encoding/binary/varint.go

+20
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ const (
3636
MaxVarintLen64 = 10
3737
)
3838

39+
// AppendUvarint appends the varint-encoded form of x,
40+
// as generated by PutUvarint, to buf and returns the extended buffer.
41+
func AppendUvarint(buf []byte, x uint64) []byte {
42+
for x >= 0x80 {
43+
buf = append(buf, byte(x)|0x80)
44+
x >>= 7
45+
}
46+
return append(buf, byte(x))
47+
}
48+
3949
// PutUvarint encodes a uint64 into buf and returns the number of bytes written.
4050
// If the buffer is too small, PutUvarint will panic.
4151
func PutUvarint(buf []byte, x uint64) int {
@@ -77,6 +87,16 @@ func Uvarint(buf []byte) (uint64, int) {
7787
return 0, 0
7888
}
7989

90+
// AppendVarint appends the varint-encoded form of x,
91+
// as generated by PutVarint, to buf and returns the extended buffer.
92+
func AppendVarint(buf []byte, x int64) []byte {
93+
ux := uint64(x) << 1
94+
if x < 0 {
95+
ux = ^ux
96+
}
97+
return AppendUvarint(buf, ux)
98+
}
99+
80100
// PutVarint encodes an int64 into buf and returns the number of bytes written.
81101
// If the buffer is too small, PutVarint will panic.
82102
func PutVarint(buf []byte, x int64) int {

src/encoding/binary/varint_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ func testVarint(t *testing.T, x int64) {
3636
t.Errorf("Varint(%d): got n = %d; want %d", x, m, n)
3737
}
3838

39+
buf2 := []byte("prefix")
40+
buf2 = AppendVarint(buf2, x)
41+
if string(buf2) != "prefix"+string(buf[:n]) {
42+
t.Errorf("AppendVarint(%d): got %q, want %q", x, buf2, "prefix"+string(buf[:n]))
43+
}
44+
3945
y, err := ReadVarint(bytes.NewReader(buf))
4046
if err != nil {
4147
t.Errorf("ReadVarint(%d): %s", x, err)
@@ -56,6 +62,12 @@ func testUvarint(t *testing.T, x uint64) {
5662
t.Errorf("Uvarint(%d): got n = %d; want %d", x, m, n)
5763
}
5864

65+
buf2 := []byte("prefix")
66+
buf2 = AppendUvarint(buf2, x)
67+
if string(buf2) != "prefix"+string(buf[:n]) {
68+
t.Errorf("AppendUvarint(%d): got %q, want %q", x, buf2, "prefix"+string(buf[:n]))
69+
}
70+
5971
y, err := ReadUvarint(bytes.NewReader(buf))
6072
if err != nil {
6173
t.Errorf("ReadUvarint(%d): %s", x, err)

0 commit comments

Comments
 (0)