-
Notifications
You must be signed in to change notification settings - Fork 96
/
varint.go
106 lines (97 loc) · 2.46 KB
/
varint.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package protocol
import (
"bytes"
"errors"
)
// Varint64 reads up to 10 bytes from the source buffer passed and sets the integer produced to a pointer.
func Varint64(src *bytes.Buffer, x *int64) error {
var ux uint64
if err := Varuint64(src, &ux); err != nil {
return err
}
*x = int64(ux >> 1)
if ux&1 != 0 {
*x = ^*x
}
return nil
}
// Varuint64 reads up to 10 bytes from the source buffer passed and sets the integer produced to a pointer.
func Varuint64(src *bytes.Buffer, x *uint64) error {
var v uint64
for i := uint(0); i < 70; i += 7 {
b, err := src.ReadByte()
if err != nil {
return err
}
v |= uint64(b&0x7f) << i
if b&0x80 == 0 {
*x = v
return nil
}
}
return errors.New("varuint64 did not terminate after 10 bytes")
}
// Varint32 reads up to 5 bytes from the source buffer passed and sets the integer produced to a pointer.
func Varint32(src *bytes.Buffer, x *int32) error {
var ux uint32
if err := Varuint32(src, &ux); err != nil {
return err
}
*x = int32(ux >> 1)
if ux&1 != 0 {
*x = ^*x
}
return nil
}
// Varuint32 reads up to 5 bytes from the source buffer passed and sets the integer produced to a pointer.
func Varuint32(src *bytes.Buffer, x *uint32) error {
var v uint32
for i := uint(0); i < 35; i += 7 {
b, err := src.ReadByte()
if err != nil {
return err
}
v |= uint32(b&0x7f) << i
if b&0x80 == 0 {
*x = v
return nil
}
}
return errors.New("varuint32 did not terminate after 5 bytes")
}
// WriteVarint64 writes an int64 to the destination buffer passed with a size of 1-10 bytes.
func WriteVarint64(dst *bytes.Buffer, x int64) error {
ux := uint64(x) << 1
if x < 0 {
ux = ^ux
}
return WriteVaruint64(dst, ux)
}
// WriteVaruint64 writes a uint64 to the destination buffer passed with a size of 1-10 bytes.
func WriteVaruint64(dst *bytes.Buffer, x uint64) error {
for x >= 0x80 {
if err := dst.WriteByte(byte(x) | 0x80); err != nil {
return err
}
x >>= 7
}
return dst.WriteByte(byte(x))
}
// WriteVarint32 writes an int32 to the destination buffer passed with a size of 1-5 bytes.
func WriteVarint32(dst *bytes.Buffer, x int32) error {
ux := uint32(x) << 1
if x < 0 {
ux = ^ux
}
return WriteVaruint32(dst, ux)
}
// WriteVaruint32 writes a uint32 to the destination buffer passed with a size of 1-5 bytes.
func WriteVaruint32(dst *bytes.Buffer, x uint32) error {
for x >= 0x80 {
if err := dst.WriteByte(byte(x) | 0x80); err != nil {
return err
}
x >>= 7
}
return dst.WriteByte(byte(x))
}