1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package tag
17
18 import (
19 "encoding/binary"
20 "fmt"
21 )
22
23
24
25 type keyType byte
26
27 const (
28 keyTypeString keyType = iota
29 keyTypeInt64
30 keyTypeTrue
31 keyTypeFalse
32
33 tagsVersionID = byte(0)
34 )
35
36 type encoderGRPC struct {
37 buf []byte
38 writeIdx, readIdx int
39 }
40
41
42
43 func (eg *encoderGRPC) writeTagString(k, v string) {
44 eg.writeByte(byte(keyTypeString))
45 eg.writeStringWithVarintLen(k)
46 eg.writeStringWithVarintLen(v)
47 }
48
49 func (eg *encoderGRPC) writeTagUint64(k string, i uint64) {
50 eg.writeByte(byte(keyTypeInt64))
51 eg.writeStringWithVarintLen(k)
52 eg.writeUint64(i)
53 }
54
55 func (eg *encoderGRPC) writeTagTrue(k string) {
56 eg.writeByte(byte(keyTypeTrue))
57 eg.writeStringWithVarintLen(k)
58 }
59
60 func (eg *encoderGRPC) writeTagFalse(k string) {
61 eg.writeByte(byte(keyTypeFalse))
62 eg.writeStringWithVarintLen(k)
63 }
64
65 func (eg *encoderGRPC) writeBytesWithVarintLen(bytes []byte) {
66 length := len(bytes)
67
68 eg.growIfRequired(binary.MaxVarintLen64 + length)
69 eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length))
70 copy(eg.buf[eg.writeIdx:], bytes)
71 eg.writeIdx += length
72 }
73
74 func (eg *encoderGRPC) writeStringWithVarintLen(s string) {
75 length := len(s)
76
77 eg.growIfRequired(binary.MaxVarintLen64 + length)
78 eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length))
79 copy(eg.buf[eg.writeIdx:], s)
80 eg.writeIdx += length
81 }
82
83 func (eg *encoderGRPC) writeByte(v byte) {
84 eg.growIfRequired(1)
85 eg.buf[eg.writeIdx] = v
86 eg.writeIdx++
87 }
88
89 func (eg *encoderGRPC) writeUint32(i uint32) {
90 eg.growIfRequired(4)
91 binary.LittleEndian.PutUint32(eg.buf[eg.writeIdx:], i)
92 eg.writeIdx += 4
93 }
94
95 func (eg *encoderGRPC) writeUint64(i uint64) {
96 eg.growIfRequired(8)
97 binary.LittleEndian.PutUint64(eg.buf[eg.writeIdx:], i)
98 eg.writeIdx += 8
99 }
100
101 func (eg *encoderGRPC) readByte() byte {
102 b := eg.buf[eg.readIdx]
103 eg.readIdx++
104 return b
105 }
106
107 func (eg *encoderGRPC) readUint32() uint32 {
108 i := binary.LittleEndian.Uint32(eg.buf[eg.readIdx:])
109 eg.readIdx += 4
110 return i
111 }
112
113 func (eg *encoderGRPC) readUint64() uint64 {
114 i := binary.LittleEndian.Uint64(eg.buf[eg.readIdx:])
115 eg.readIdx += 8
116 return i
117 }
118
119 func (eg *encoderGRPC) readBytesWithVarintLen() ([]byte, error) {
120 if eg.readEnded() {
121 return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx)
122 }
123 length, valueStart := binary.Uvarint(eg.buf[eg.readIdx:])
124 if valueStart <= 0 {
125 return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx)
126 }
127
128 valueStart += eg.readIdx
129 valueEnd := valueStart + int(length)
130 if valueEnd > len(eg.buf) {
131 return nil, fmt.Errorf("malformed encoding: length:%v, upper:%v, maxLength:%v", length, valueEnd, len(eg.buf))
132 }
133
134 eg.readIdx = valueEnd
135 return eg.buf[valueStart:valueEnd], nil
136 }
137
138 func (eg *encoderGRPC) readStringWithVarintLen() (string, error) {
139 bytes, err := eg.readBytesWithVarintLen()
140 if err != nil {
141 return "", err
142 }
143 return string(bytes), nil
144 }
145
146 func (eg *encoderGRPC) growIfRequired(expected int) {
147 if len(eg.buf)-eg.writeIdx < expected {
148 tmp := make([]byte, 2*(len(eg.buf)+1)+expected)
149 copy(tmp, eg.buf)
150 eg.buf = tmp
151 }
152 }
153
154 func (eg *encoderGRPC) readEnded() bool {
155 return eg.readIdx >= len(eg.buf)
156 }
157
158 func (eg *encoderGRPC) bytes() []byte {
159 return eg.buf[:eg.writeIdx]
160 }
161
162
163
164 func Encode(m *Map) []byte {
165 if m == nil {
166 return nil
167 }
168 eg := &encoderGRPC{
169 buf: make([]byte, len(m.m)),
170 }
171 eg.writeByte(tagsVersionID)
172 for k, v := range m.m {
173 if v.m.ttl.ttl == valueTTLUnlimitedPropagation {
174 eg.writeByte(byte(keyTypeString))
175 eg.writeStringWithVarintLen(k.name)
176 eg.writeBytesWithVarintLen([]byte(v.value))
177 }
178 }
179 return eg.bytes()
180 }
181
182
183 func Decode(bytes []byte) (*Map, error) {
184 ts := newMap()
185 err := DecodeEach(bytes, ts.upsert)
186 if err != nil {
187
188 return nil, err
189 }
190 return ts, nil
191 }
192
193
194
195 func DecodeEach(bytes []byte, fn func(key Key, val string, md metadatas)) error {
196 eg := &encoderGRPC{
197 buf: bytes,
198 }
199 if len(eg.buf) == 0 {
200 return nil
201 }
202
203 version := eg.readByte()
204 if version > tagsVersionID {
205 return fmt.Errorf("cannot decode: unsupported version: %q; supports only up to: %q", version, tagsVersionID)
206 }
207
208 for !eg.readEnded() {
209 typ := keyType(eg.readByte())
210
211 if typ != keyTypeString {
212 return fmt.Errorf("cannot decode: invalid key type: %q", typ)
213 }
214
215 k, err := eg.readBytesWithVarintLen()
216 if err != nil {
217 return err
218 }
219
220 v, err := eg.readBytesWithVarintLen()
221 if err != nil {
222 return err
223 }
224
225 key, err := NewKey(string(k))
226 if err != nil {
227 return err
228 }
229 val := string(v)
230 if !checkValue(val) {
231 return errInvalidValue
232 }
233 fn(key, val, createMetadatas(WithTTL(TTLUnlimitedPropagation)))
234 if err != nil {
235 return err
236 }
237 }
238 return nil
239 }
240
View as plain text