1
2
3
4
5
6
7 package quic
8
9 import "encoding/binary"
10
11 const (
12 maxVarintSize = 8
13 maxVarint = (1 << 62) - 1
14 )
15
16
17
18
19
20 func consumeVarint(b []byte) (v uint64, n int) {
21 if len(b) < 1 {
22 return 0, -1
23 }
24 b0 := b[0] & 0x3f
25 switch b[0] >> 6 {
26 case 0:
27 return uint64(b0), 1
28 case 1:
29 if len(b) < 2 {
30 return 0, -1
31 }
32 return uint64(b0)<<8 | uint64(b[1]), 2
33 case 2:
34 if len(b) < 4 {
35 return 0, -1
36 }
37 return uint64(b0)<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3]), 4
38 case 3:
39 if len(b) < 8 {
40 return 0, -1
41 }
42 return uint64(b0)<<56 | uint64(b[1])<<48 | uint64(b[2])<<40 | uint64(b[3])<<32 | uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7]), 8
43 }
44 return 0, -1
45 }
46
47
48 func consumeVarintInt64(b []byte) (v int64, n int) {
49 u, n := consumeVarint(b)
50
51 return int64(u), n
52 }
53
54
55
56
57 func appendVarint(b []byte, v uint64) []byte {
58 switch {
59 case v <= 63:
60 return append(b, byte(v))
61 case v <= 16383:
62 return append(b, (1<<6)|byte(v>>8), byte(v))
63 case v <= 1073741823:
64 return append(b, (2<<6)|byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
65 case v <= 4611686018427387903:
66 return append(b, (3<<6)|byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
67 default:
68 panic("varint too large")
69 }
70 }
71
72
73 func sizeVarint(v uint64) int {
74 switch {
75 case v <= 63:
76 return 1
77 case v <= 16383:
78 return 2
79 case v <= 1073741823:
80 return 4
81 case v <= 4611686018427387903:
82 return 8
83 default:
84 panic("varint too large")
85 }
86 }
87
88
89
90 func consumeUint32(b []byte) (uint32, int) {
91 if len(b) < 4 {
92 return 0, -1
93 }
94 return binary.BigEndian.Uint32(b), 4
95 }
96
97
98
99 func consumeUint64(b []byte) (uint64, int) {
100 if len(b) < 8 {
101 return 0, -1
102 }
103 return binary.BigEndian.Uint64(b), 8
104 }
105
106
107
108
109 func consumeUint8Bytes(b []byte) ([]byte, int) {
110 if len(b) < 1 {
111 return nil, -1
112 }
113 size := int(b[0])
114 const n = 1
115 if size > len(b[n:]) {
116 return nil, -1
117 }
118 return b[n:][:size], size + n
119 }
120
121
122 func appendUint8Bytes(b, v []byte) []byte {
123 if len(v) > 0xff {
124 panic("uint8-prefixed bytes too large")
125 }
126 b = append(b, uint8(len(v)))
127 b = append(b, v...)
128 return b
129 }
130
131
132
133
134 func consumeVarintBytes(b []byte) ([]byte, int) {
135 size, n := consumeVarint(b)
136 if n < 0 {
137 return nil, -1
138 }
139 if size > uint64(len(b[n:])) {
140 return nil, -1
141 }
142 return b[n:][:size], int(size) + n
143 }
144
145
146 func appendVarintBytes(b, v []byte) []byte {
147 b = appendVarint(b, uint64(len(v)))
148 b = append(b, v...)
149 return b
150 }
151
View as plain text