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