]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/binary: add AppendVarint AppendUvarint
authorJoe Tsai <joetsai@digital-static.net>
Wed, 13 Apr 2022 20:21:30 +0000 (13:21 -0700)
committerJoseph Tsai <joetsai@digital-static.net>
Fri, 15 Apr 2022 01:19:37 +0000 (01:19 +0000)
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 <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>

api/next/51644.txt [new file with mode: 0644]
src/encoding/binary/varint.go
src/encoding/binary/varint_test.go

diff --git a/api/next/51644.txt b/api/next/51644.txt
new file mode 100644 (file)
index 0000000..d93dbbf
--- /dev/null
@@ -0,0 +1,2 @@
+pkg encoding/binary, func AppendUvarint([]uint8, uint64) []uint8 #51644
+pkg encoding/binary, func AppendVarint([]uint8, int64) []uint8 #51644
index 1b07e2541ddb50d3ea1372f4372295325dd337c2..c807d15f442e7811d9273dbc9e666f94f6031164 100644 (file)
@@ -36,6 +36,16 @@ const (
        MaxVarintLen64 = 10
 )
 
+// AppendUvarint appends the varint-encoded form of x,
+// as generated by PutUvarint, to buf and returns the extended buffer.
+func AppendUvarint(buf []byte, x uint64) []byte {
+       for x >= 0x80 {
+               buf = append(buf, byte(x)|0x80)
+               x >>= 7
+       }
+       return append(buf, byte(x))
+}
+
 // PutUvarint encodes a uint64 into buf and returns the number of bytes written.
 // If the buffer is too small, PutUvarint will panic.
 func PutUvarint(buf []byte, x uint64) int {
@@ -77,6 +87,16 @@ func Uvarint(buf []byte) (uint64, int) {
        return 0, 0
 }
 
+// AppendVarint appends the varint-encoded form of x,
+// as generated by PutVarint, to buf and returns the extended buffer.
+func AppendVarint(buf []byte, x int64) []byte {
+       ux := uint64(x) << 1
+       if x < 0 {
+               ux = ^ux
+       }
+       return AppendUvarint(buf, ux)
+}
+
 // PutVarint encodes an int64 into buf and returns the number of bytes written.
 // If the buffer is too small, PutVarint will panic.
 func PutVarint(buf []byte, x int64) int {
index d025a67538ccdb66e42834d9540437fbb87caa14..080a2148f0b4f8b51cd2862a1a2c9d8c9450a132 100644 (file)
@@ -36,6 +36,12 @@ func testVarint(t *testing.T, x int64) {
                t.Errorf("Varint(%d): got n = %d; want %d", x, m, n)
        }
 
+       buf2 := []byte("prefix")
+       buf2 = AppendVarint(buf2, x)
+       if string(buf2) != "prefix"+string(buf[:n]) {
+               t.Errorf("AppendVarint(%d): got %q, want %q", x, buf2, "prefix"+string(buf[:n]))
+       }
+
        y, err := ReadVarint(bytes.NewReader(buf))
        if err != nil {
                t.Errorf("ReadVarint(%d): %s", x, err)
@@ -56,6 +62,12 @@ func testUvarint(t *testing.T, x uint64) {
                t.Errorf("Uvarint(%d): got n = %d; want %d", x, m, n)
        }
 
+       buf2 := []byte("prefix")
+       buf2 = AppendUvarint(buf2, x)
+       if string(buf2) != "prefix"+string(buf[:n]) {
+               t.Errorf("AppendUvarint(%d): got %q, want %q", x, buf2, "prefix"+string(buf[:n]))
+       }
+
        y, err := ReadUvarint(bytes.NewReader(buf))
        if err != nil {
                t.Errorf("ReadUvarint(%d): %s", x, err)