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 package profile
35
36 import (
37 "errors"
38 "fmt"
39 "slices"
40 )
41
42 type buffer struct {
43 field int
44 typ int
45 u64 uint64
46 data []byte
47 tmp [16]byte
48 tmpLines []Line
49 }
50
51 type decoder func(*buffer, message) error
52
53 type message interface {
54 decoder() []decoder
55 encode(*buffer)
56 }
57
58 func marshal(m message) []byte {
59 var b buffer
60 m.encode(&b)
61 return b.data
62 }
63
64 func encodeVarint(b *buffer, x uint64) {
65 for x >= 128 {
66 b.data = append(b.data, byte(x)|0x80)
67 x >>= 7
68 }
69 b.data = append(b.data, byte(x))
70 }
71
72 func encodeLength(b *buffer, tag int, len int) {
73 encodeVarint(b, uint64(tag)<<3|2)
74 encodeVarint(b, uint64(len))
75 }
76
77 func encodeUint64(b *buffer, tag int, x uint64) {
78
79 encodeVarint(b, uint64(tag)<<3)
80 encodeVarint(b, x)
81 }
82
83 func encodeUint64s(b *buffer, tag int, x []uint64) {
84 if len(x) > 2 {
85
86 n1 := len(b.data)
87 for _, u := range x {
88 encodeVarint(b, u)
89 }
90 n2 := len(b.data)
91 encodeLength(b, tag, n2-n1)
92 n3 := len(b.data)
93 copy(b.tmp[:], b.data[n2:n3])
94 copy(b.data[n1+(n3-n2):], b.data[n1:n2])
95 copy(b.data[n1:], b.tmp[:n3-n2])
96 return
97 }
98 for _, u := range x {
99 encodeUint64(b, tag, u)
100 }
101 }
102
103 func encodeUint64Opt(b *buffer, tag int, x uint64) {
104 if x == 0 {
105 return
106 }
107 encodeUint64(b, tag, x)
108 }
109
110 func encodeInt64(b *buffer, tag int, x int64) {
111 u := uint64(x)
112 encodeUint64(b, tag, u)
113 }
114
115 func encodeInt64s(b *buffer, tag int, x []int64) {
116 if len(x) > 2 {
117
118 n1 := len(b.data)
119 for _, u := range x {
120 encodeVarint(b, uint64(u))
121 }
122 n2 := len(b.data)
123 encodeLength(b, tag, n2-n1)
124 n3 := len(b.data)
125 copy(b.tmp[:], b.data[n2:n3])
126 copy(b.data[n1+(n3-n2):], b.data[n1:n2])
127 copy(b.data[n1:], b.tmp[:n3-n2])
128 return
129 }
130 for _, u := range x {
131 encodeInt64(b, tag, u)
132 }
133 }
134
135 func encodeInt64Opt(b *buffer, tag int, x int64) {
136 if x == 0 {
137 return
138 }
139 encodeInt64(b, tag, x)
140 }
141
142 func encodeString(b *buffer, tag int, x string) {
143 encodeLength(b, tag, len(x))
144 b.data = append(b.data, x...)
145 }
146
147 func encodeStrings(b *buffer, tag int, x []string) {
148 for _, s := range x {
149 encodeString(b, tag, s)
150 }
151 }
152
153 func encodeBool(b *buffer, tag int, x bool) {
154 if x {
155 encodeUint64(b, tag, 1)
156 } else {
157 encodeUint64(b, tag, 0)
158 }
159 }
160
161 func encodeBoolOpt(b *buffer, tag int, x bool) {
162 if x {
163 encodeBool(b, tag, x)
164 }
165 }
166
167 func encodeMessage(b *buffer, tag int, m message) {
168 n1 := len(b.data)
169 m.encode(b)
170 n2 := len(b.data)
171 encodeLength(b, tag, n2-n1)
172 n3 := len(b.data)
173 copy(b.tmp[:], b.data[n2:n3])
174 copy(b.data[n1+(n3-n2):], b.data[n1:n2])
175 copy(b.data[n1:], b.tmp[:n3-n2])
176 }
177
178 func unmarshal(data []byte, m message) (err error) {
179 b := buffer{data: data, typ: 2}
180 return decodeMessage(&b, m)
181 }
182
183 func le64(p []byte) uint64 {
184 return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
185 }
186
187 func le32(p []byte) uint32 {
188 return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
189 }
190
191 func peekNumVarints(data []byte) (numVarints int) {
192 for ; len(data) > 0; numVarints++ {
193 var err error
194 if _, data, err = decodeVarint(data); err != nil {
195 break
196 }
197 }
198 return numVarints
199 }
200
201 func decodeVarint(data []byte) (uint64, []byte, error) {
202 var u uint64
203 for i := 0; ; i++ {
204 if i >= 10 || i >= len(data) {
205 return 0, nil, errors.New("bad varint")
206 }
207 u |= uint64(data[i]&0x7F) << uint(7*i)
208 if data[i]&0x80 == 0 {
209 return u, data[i+1:], nil
210 }
211 }
212 }
213
214 func decodeField(b *buffer, data []byte) ([]byte, error) {
215 x, data, err := decodeVarint(data)
216 if err != nil {
217 return nil, err
218 }
219 b.field = int(x >> 3)
220 b.typ = int(x & 7)
221 b.data = nil
222 b.u64 = 0
223 switch b.typ {
224 case 0:
225 b.u64, data, err = decodeVarint(data)
226 if err != nil {
227 return nil, err
228 }
229 case 1:
230 if len(data) < 8 {
231 return nil, errors.New("not enough data")
232 }
233 b.u64 = le64(data[:8])
234 data = data[8:]
235 case 2:
236 var n uint64
237 n, data, err = decodeVarint(data)
238 if err != nil {
239 return nil, err
240 }
241 if n > uint64(len(data)) {
242 return nil, errors.New("too much data")
243 }
244 b.data = data[:n]
245 data = data[n:]
246 case 5:
247 if len(data) < 4 {
248 return nil, errors.New("not enough data")
249 }
250 b.u64 = uint64(le32(data[:4]))
251 data = data[4:]
252 default:
253 return nil, fmt.Errorf("unknown wire type: %d", b.typ)
254 }
255
256 return data, nil
257 }
258
259 func checkType(b *buffer, typ int) error {
260 if b.typ != typ {
261 return errors.New("type mismatch")
262 }
263 return nil
264 }
265
266 func decodeMessage(b *buffer, m message) error {
267 if err := checkType(b, 2); err != nil {
268 return err
269 }
270 dec := m.decoder()
271 data := b.data
272 for len(data) > 0 {
273
274 var err error
275 data, err = decodeField(b, data)
276 if err != nil {
277 return err
278 }
279 if b.field >= len(dec) || dec[b.field] == nil {
280 continue
281 }
282 if err := dec[b.field](b, m); err != nil {
283 return err
284 }
285 }
286 return nil
287 }
288
289 func decodeInt64(b *buffer, x *int64) error {
290 if err := checkType(b, 0); err != nil {
291 return err
292 }
293 *x = int64(b.u64)
294 return nil
295 }
296
297 func decodeInt64s(b *buffer, x *[]int64) error {
298 if b.typ == 2 {
299
300 dataLen := peekNumVarints(b.data)
301 *x = slices.Grow(*x, dataLen)
302
303 data := b.data
304 for len(data) > 0 {
305 var u uint64
306 var err error
307
308 if u, data, err = decodeVarint(data); err != nil {
309 return err
310 }
311 *x = append(*x, int64(u))
312 }
313 return nil
314 }
315 var i int64
316 if err := decodeInt64(b, &i); err != nil {
317 return err
318 }
319 *x = append(*x, i)
320 return nil
321 }
322
323 func decodeUint64(b *buffer, x *uint64) error {
324 if err := checkType(b, 0); err != nil {
325 return err
326 }
327 *x = b.u64
328 return nil
329 }
330
331 func decodeUint64s(b *buffer, x *[]uint64) error {
332 if b.typ == 2 {
333
334 dataLen := peekNumVarints(b.data)
335 *x = slices.Grow(*x, dataLen)
336
337 data := b.data
338 for len(data) > 0 {
339 var u uint64
340 var err error
341
342 if u, data, err = decodeVarint(data); err != nil {
343 return err
344 }
345 *x = append(*x, u)
346 }
347 return nil
348 }
349 var u uint64
350 if err := decodeUint64(b, &u); err != nil {
351 return err
352 }
353 *x = append(*x, u)
354 return nil
355 }
356
357 func decodeString(b *buffer, x *string) error {
358 if err := checkType(b, 2); err != nil {
359 return err
360 }
361 *x = string(b.data)
362 return nil
363 }
364
365 func decodeStrings(b *buffer, x *[]string) error {
366 var s string
367 if err := decodeString(b, &s); err != nil {
368 return err
369 }
370 *x = append(*x, s)
371 return nil
372 }
373
374 func decodeBool(b *buffer, x *bool) error {
375 if err := checkType(b, 0); err != nil {
376 return err
377 }
378 if int64(b.u64) == 0 {
379 *x = false
380 } else {
381 *x = true
382 }
383 return nil
384 }
385
View as plain text