1
2
3
4
5
6
7
8
9
10 package protowire
11
12 import (
13 "io"
14 "math"
15 "math/bits"
16
17 "google.golang.org/protobuf/internal/errors"
18 )
19
20
21 type Number int32
22
23 const (
24 MinValidNumber Number = 1
25 FirstReservedNumber Number = 19000
26 LastReservedNumber Number = 19999
27 MaxValidNumber Number = 1<<29 - 1
28 DefaultRecursionLimit = 10000
29 )
30
31
32 func (n Number) IsValid() bool {
33 return MinValidNumber <= n && n <= MaxValidNumber
34 }
35
36
37 type Type int8
38
39 const (
40 VarintType Type = 0
41 Fixed32Type Type = 5
42 Fixed64Type Type = 1
43 BytesType Type = 2
44 StartGroupType Type = 3
45 EndGroupType Type = 4
46 )
47
48 const (
49 _ = -iota
50 errCodeTruncated
51 errCodeFieldNumber
52 errCodeOverflow
53 errCodeReserved
54 errCodeEndGroup
55 errCodeRecursionDepth
56 )
57
58 var (
59 errFieldNumber = errors.New("invalid field number")
60 errOverflow = errors.New("variable length integer overflow")
61 errReserved = errors.New("cannot parse reserved wire type")
62 errEndGroup = errors.New("mismatching end group marker")
63 errParse = errors.New("parse error")
64 )
65
66
67
68 func ParseError(n int) error {
69 if n >= 0 {
70 return nil
71 }
72 switch n {
73 case errCodeTruncated:
74 return io.ErrUnexpectedEOF
75 case errCodeFieldNumber:
76 return errFieldNumber
77 case errCodeOverflow:
78 return errOverflow
79 case errCodeReserved:
80 return errReserved
81 case errCodeEndGroup:
82 return errEndGroup
83 default:
84 return errParse
85 }
86 }
87
88
89
90
91
92
93
94 func ConsumeField(b []byte) (Number, Type, int) {
95 num, typ, n := ConsumeTag(b)
96 if n < 0 {
97 return 0, 0, n
98 }
99 m := ConsumeFieldValue(num, typ, b[n:])
100 if m < 0 {
101 return 0, 0, m
102 }
103 return num, typ, n + m
104 }
105
106
107
108
109
110
111
112 func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
113 return consumeFieldValueD(num, typ, b, DefaultRecursionLimit)
114 }
115
116 func consumeFieldValueD(num Number, typ Type, b []byte, depth int) (n int) {
117 switch typ {
118 case VarintType:
119 _, n = ConsumeVarint(b)
120 return n
121 case Fixed32Type:
122 _, n = ConsumeFixed32(b)
123 return n
124 case Fixed64Type:
125 _, n = ConsumeFixed64(b)
126 return n
127 case BytesType:
128 _, n = ConsumeBytes(b)
129 return n
130 case StartGroupType:
131 if depth < 0 {
132 return errCodeRecursionDepth
133 }
134 n0 := len(b)
135 for {
136 num2, typ2, n := ConsumeTag(b)
137 if n < 0 {
138 return n
139 }
140 b = b[n:]
141 if typ2 == EndGroupType {
142 if num != num2 {
143 return errCodeEndGroup
144 }
145 return n0 - len(b)
146 }
147
148 n = consumeFieldValueD(num2, typ2, b, depth-1)
149 if n < 0 {
150 return n
151 }
152 b = b[n:]
153 }
154 case EndGroupType:
155 return errCodeEndGroup
156 default:
157 return errCodeReserved
158 }
159 }
160
161
162 func AppendTag(b []byte, num Number, typ Type) []byte {
163 return AppendVarint(b, EncodeTag(num, typ))
164 }
165
166
167
168 func ConsumeTag(b []byte) (Number, Type, int) {
169 v, n := ConsumeVarint(b)
170 if n < 0 {
171 return 0, 0, n
172 }
173 num, typ := DecodeTag(v)
174 if num < MinValidNumber {
175 return 0, 0, errCodeFieldNumber
176 }
177 return num, typ, n
178 }
179
180 func SizeTag(num Number) int {
181 return SizeVarint(EncodeTag(num, 0))
182 }
183
184
185 func AppendVarint(b []byte, v uint64) []byte {
186 switch {
187 case v < 1<<7:
188 b = append(b, byte(v))
189 case v < 1<<14:
190 b = append(b,
191 byte((v>>0)&0x7f|0x80),
192 byte(v>>7))
193 case v < 1<<21:
194 b = append(b,
195 byte((v>>0)&0x7f|0x80),
196 byte((v>>7)&0x7f|0x80),
197 byte(v>>14))
198 case v < 1<<28:
199 b = append(b,
200 byte((v>>0)&0x7f|0x80),
201 byte((v>>7)&0x7f|0x80),
202 byte((v>>14)&0x7f|0x80),
203 byte(v>>21))
204 case v < 1<<35:
205 b = append(b,
206 byte((v>>0)&0x7f|0x80),
207 byte((v>>7)&0x7f|0x80),
208 byte((v>>14)&0x7f|0x80),
209 byte((v>>21)&0x7f|0x80),
210 byte(v>>28))
211 case v < 1<<42:
212 b = append(b,
213 byte((v>>0)&0x7f|0x80),
214 byte((v>>7)&0x7f|0x80),
215 byte((v>>14)&0x7f|0x80),
216 byte((v>>21)&0x7f|0x80),
217 byte((v>>28)&0x7f|0x80),
218 byte(v>>35))
219 case v < 1<<49:
220 b = append(b,
221 byte((v>>0)&0x7f|0x80),
222 byte((v>>7)&0x7f|0x80),
223 byte((v>>14)&0x7f|0x80),
224 byte((v>>21)&0x7f|0x80),
225 byte((v>>28)&0x7f|0x80),
226 byte((v>>35)&0x7f|0x80),
227 byte(v>>42))
228 case v < 1<<56:
229 b = append(b,
230 byte((v>>0)&0x7f|0x80),
231 byte((v>>7)&0x7f|0x80),
232 byte((v>>14)&0x7f|0x80),
233 byte((v>>21)&0x7f|0x80),
234 byte((v>>28)&0x7f|0x80),
235 byte((v>>35)&0x7f|0x80),
236 byte((v>>42)&0x7f|0x80),
237 byte(v>>49))
238 case v < 1<<63:
239 b = append(b,
240 byte((v>>0)&0x7f|0x80),
241 byte((v>>7)&0x7f|0x80),
242 byte((v>>14)&0x7f|0x80),
243 byte((v>>21)&0x7f|0x80),
244 byte((v>>28)&0x7f|0x80),
245 byte((v>>35)&0x7f|0x80),
246 byte((v>>42)&0x7f|0x80),
247 byte((v>>49)&0x7f|0x80),
248 byte(v>>56))
249 default:
250 b = append(b,
251 byte((v>>0)&0x7f|0x80),
252 byte((v>>7)&0x7f|0x80),
253 byte((v>>14)&0x7f|0x80),
254 byte((v>>21)&0x7f|0x80),
255 byte((v>>28)&0x7f|0x80),
256 byte((v>>35)&0x7f|0x80),
257 byte((v>>42)&0x7f|0x80),
258 byte((v>>49)&0x7f|0x80),
259 byte((v>>56)&0x7f|0x80),
260 1)
261 }
262 return b
263 }
264
265
266
267 func ConsumeVarint(b []byte) (v uint64, n int) {
268 var y uint64
269 if len(b) <= 0 {
270 return 0, errCodeTruncated
271 }
272 v = uint64(b[0])
273 if v < 0x80 {
274 return v, 1
275 }
276 v -= 0x80
277
278 if len(b) <= 1 {
279 return 0, errCodeTruncated
280 }
281 y = uint64(b[1])
282 v += y << 7
283 if y < 0x80 {
284 return v, 2
285 }
286 v -= 0x80 << 7
287
288 if len(b) <= 2 {
289 return 0, errCodeTruncated
290 }
291 y = uint64(b[2])
292 v += y << 14
293 if y < 0x80 {
294 return v, 3
295 }
296 v -= 0x80 << 14
297
298 if len(b) <= 3 {
299 return 0, errCodeTruncated
300 }
301 y = uint64(b[3])
302 v += y << 21
303 if y < 0x80 {
304 return v, 4
305 }
306 v -= 0x80 << 21
307
308 if len(b) <= 4 {
309 return 0, errCodeTruncated
310 }
311 y = uint64(b[4])
312 v += y << 28
313 if y < 0x80 {
314 return v, 5
315 }
316 v -= 0x80 << 28
317
318 if len(b) <= 5 {
319 return 0, errCodeTruncated
320 }
321 y = uint64(b[5])
322 v += y << 35
323 if y < 0x80 {
324 return v, 6
325 }
326 v -= 0x80 << 35
327
328 if len(b) <= 6 {
329 return 0, errCodeTruncated
330 }
331 y = uint64(b[6])
332 v += y << 42
333 if y < 0x80 {
334 return v, 7
335 }
336 v -= 0x80 << 42
337
338 if len(b) <= 7 {
339 return 0, errCodeTruncated
340 }
341 y = uint64(b[7])
342 v += y << 49
343 if y < 0x80 {
344 return v, 8
345 }
346 v -= 0x80 << 49
347
348 if len(b) <= 8 {
349 return 0, errCodeTruncated
350 }
351 y = uint64(b[8])
352 v += y << 56
353 if y < 0x80 {
354 return v, 9
355 }
356 v -= 0x80 << 56
357
358 if len(b) <= 9 {
359 return 0, errCodeTruncated
360 }
361 y = uint64(b[9])
362 v += y << 63
363 if y < 2 {
364 return v, 10
365 }
366 return 0, errCodeOverflow
367 }
368
369
370
371 func SizeVarint(v uint64) int {
372
373
374 return int(9*uint32(bits.Len64(v))+64) / 64
375 }
376
377
378 func AppendFixed32(b []byte, v uint32) []byte {
379 return append(b,
380 byte(v>>0),
381 byte(v>>8),
382 byte(v>>16),
383 byte(v>>24))
384 }
385
386
387
388 func ConsumeFixed32(b []byte) (v uint32, n int) {
389 if len(b) < 4 {
390 return 0, errCodeTruncated
391 }
392 v = uint32(b[0])<<0 | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
393 return v, 4
394 }
395
396
397 func SizeFixed32() int {
398 return 4
399 }
400
401
402 func AppendFixed64(b []byte, v uint64) []byte {
403 return append(b,
404 byte(v>>0),
405 byte(v>>8),
406 byte(v>>16),
407 byte(v>>24),
408 byte(v>>32),
409 byte(v>>40),
410 byte(v>>48),
411 byte(v>>56))
412 }
413
414
415
416 func ConsumeFixed64(b []byte) (v uint64, n int) {
417 if len(b) < 8 {
418 return 0, errCodeTruncated
419 }
420 v = uint64(b[0])<<0 | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
421 return v, 8
422 }
423
424
425 func SizeFixed64() int {
426 return 8
427 }
428
429
430 func AppendBytes(b []byte, v []byte) []byte {
431 return append(AppendVarint(b, uint64(len(v))), v...)
432 }
433
434
435
436 func ConsumeBytes(b []byte) (v []byte, n int) {
437 m, n := ConsumeVarint(b)
438 if n < 0 {
439 return nil, n
440 }
441 if m > uint64(len(b[n:])) {
442 return nil, errCodeTruncated
443 }
444 return b[n:][:m], n + int(m)
445 }
446
447
448
449 func SizeBytes(n int) int {
450 return SizeVarint(uint64(n)) + n
451 }
452
453
454 func AppendString(b []byte, v string) []byte {
455 return append(AppendVarint(b, uint64(len(v))), v...)
456 }
457
458
459
460 func ConsumeString(b []byte) (v string, n int) {
461 bb, n := ConsumeBytes(b)
462 return string(bb), n
463 }
464
465
466
467 func AppendGroup(b []byte, num Number, v []byte) []byte {
468 return AppendVarint(append(b, v...), EncodeTag(num, EndGroupType))
469 }
470
471
472
473
474
475 func ConsumeGroup(num Number, b []byte) (v []byte, n int) {
476 n = ConsumeFieldValue(num, StartGroupType, b)
477 if n < 0 {
478 return nil, n
479 }
480 b = b[:n]
481
482
483
484
485
486 for len(b) > 0 && b[len(b)-1]&0x7f == 0 {
487 b = b[:len(b)-1]
488 }
489 b = b[:len(b)-SizeTag(num)]
490 return b, n
491 }
492
493
494 func SizeGroup(num Number, n int) int {
495 return n + SizeTag(num)
496 }
497
498
499
500
501 func DecodeTag(x uint64) (Number, Type) {
502
503 if x>>3 > uint64(math.MaxInt32) {
504 return -1, 0
505 }
506 return Number(x >> 3), Type(x & 7)
507 }
508
509
510 func EncodeTag(num Number, typ Type) uint64 {
511 return uint64(num)<<3 | uint64(typ&7)
512 }
513
514
515
516
517
518 func DecodeZigZag(x uint64) int64 {
519 return int64(x>>1) ^ int64(x)<<63>>63
520 }
521
522
523
524
525
526 func EncodeZigZag(x int64) uint64 {
527 return uint64(x<<1) ^ uint64(x>>63)
528 }
529
530
531
532
533
534 func DecodeBool(x uint64) bool {
535 return x != 0
536 }
537
538
539
540
541
542 func EncodeBool(x bool) uint64 {
543 if x {
544 return 1
545 }
546 return 0
547 }
548
View as plain text