...
1 package base64vlq
2
3 import "io"
4
5 const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
6
7 const (
8 vlqBaseShift = 5
9 vlqBase = 1 << vlqBaseShift
10 vlqBaseMask = vlqBase - 1
11 vlqSignBit = 1
12 vlqContinuationBit = vlqBase
13 )
14
15 var decodeMap [256]byte
16
17 func init() {
18 for i := 0; i < len(encodeStd); i++ {
19 decodeMap[encodeStd[i]] = byte(i)
20 }
21 }
22
23 func toVLQSigned(n int32) int32 {
24 if n < 0 {
25 return -n<<1 + 1
26 }
27 return n << 1
28 }
29
30 func fromVLQSigned(n int32) int32 {
31 isNeg := n&vlqSignBit != 0
32 n >>= 1
33 if isNeg {
34 return -n
35 }
36 return n
37 }
38
39 type Encoder struct {
40 w io.ByteWriter
41 }
42
43 func NewEncoder(w io.ByteWriter) *Encoder {
44 return &Encoder{
45 w: w,
46 }
47 }
48
49 func (enc Encoder) Encode(n int32) error {
50 n = toVLQSigned(n)
51 for digit := int32(vlqContinuationBit); digit&vlqContinuationBit != 0; {
52 digit = n & vlqBaseMask
53 n >>= vlqBaseShift
54 if n > 0 {
55 digit |= vlqContinuationBit
56 }
57
58 err := enc.w.WriteByte(encodeStd[digit])
59 if err != nil {
60 return err
61 }
62 }
63 return nil
64 }
65
66 type Decoder struct {
67 r io.ByteReader
68 }
69
70 func NewDecoder(r io.ByteReader) Decoder {
71 return Decoder{
72 r: r,
73 }
74 }
75
76 func (dec Decoder) Decode() (n int32, err error) {
77 shift := uint(0)
78 for continuation := true; continuation; {
79 c, err := dec.r.ReadByte()
80 if err != nil {
81 return 0, err
82 }
83
84 c = decodeMap[c]
85 continuation = c&vlqContinuationBit != 0
86 n += int32(c&vlqBaseMask) << shift
87 shift += vlqBaseShift
88 }
89 return fromVLQSigned(n), nil
90 }
91
View as plain text