-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
77 lines (63 loc) · 1.52 KB
/
util.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
package schemer
import (
"encoding/binary"
"errors"
"fmt"
"io"
)
// byter wraps an io.Reader and provides a ReadByte() function
// Caution: ReadByte() usually implies that reading a single byte is fast, so
// please ensure that the underlying Reader can read individual bytes in
// sequence without major performance issues.
type byter struct {
io.Reader
}
func (r byter) ReadByte() (byte, error) {
var buf [1]byte
n, err := r.Reader.Read(buf[:])
if err != nil {
return 0, err
}
if n == 0 {
return 0, io.ErrNoProgress
}
return buf[0], nil
}
func (r byter) ReadVarint() (int64, error) {
return binary.ReadVarint(r)
}
// ReadUvarint reads an Uvarint from r one byte at a time
func ReadUvarint(r io.Reader) (uint64, error) {
rb := byter{r}
buf := make([]byte, binary.MaxVarintLen64)
// Read first byte into `buf`
b, err := rb.ReadByte()
if err != nil {
return 0, err
}
buf[0] = b
// Read subsequent bytes into `buf`
i := 1
for ; b&0x80 > 0; i++ {
b, err = rb.ReadByte()
if err != nil {
return 0, err
}
buf[i] = b
}
decodedUInt, n := binary.Uvarint(buf)
if n != i {
return 0, fmt.Errorf("uvarint did not consume expected number of bytes")
}
return decodedUInt, nil
}
// WriteUvarint writes v to w as an Uvarint
func WriteUvarint(w io.Writer, v uint64) error {
buf := make([]byte, binary.MaxVarintLen64)
varIntBytes := binary.PutUvarint(buf, v)
n, err := w.Write(buf[0:varIntBytes])
if err == nil && n != varIntBytes {
err = errors.New("unexpected number of bytes written")
}
return err
}