libgo: update to go1.9
[official-gcc.git] / libgo / go / runtime / pprof / protobuf.go
blob7b99095a13a62ee2eba53779934d1880c6c87e95
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package pprof
7 // A protobuf is a simple protocol buffer encoder.
8 type protobuf struct {
9 data []byte
10 tmp [16]byte
11 nest int
14 func (b *protobuf) varint(x uint64) {
15 for x >= 128 {
16 b.data = append(b.data, byte(x)|0x80)
17 x >>= 7
19 b.data = append(b.data, byte(x))
22 func (b *protobuf) length(tag int, len int) {
23 b.varint(uint64(tag)<<3 | 2)
24 b.varint(uint64(len))
27 func (b *protobuf) uint64(tag int, x uint64) {
28 // append varint to b.data
29 b.varint(uint64(tag)<<3 | 0)
30 b.varint(x)
33 func (b *protobuf) uint64s(tag int, x []uint64) {
34 if len(x) > 2 {
35 // Use packed encoding
36 n1 := len(b.data)
37 for _, u := range x {
38 b.varint(u)
40 n2 := len(b.data)
41 b.length(tag, n2-n1)
42 n3 := len(b.data)
43 copy(b.tmp[:], b.data[n2:n3])
44 copy(b.data[n1+(n3-n2):], b.data[n1:n2])
45 copy(b.data[n1:], b.tmp[:n3-n2])
46 return
48 for _, u := range x {
49 b.uint64(tag, u)
53 func (b *protobuf) uint64Opt(tag int, x uint64) {
54 if x == 0 {
55 return
57 b.uint64(tag, x)
60 func (b *protobuf) int64(tag int, x int64) {
61 u := uint64(x)
62 b.uint64(tag, u)
65 func (b *protobuf) int64Opt(tag int, x int64) {
66 if x == 0 {
67 return
69 b.int64(tag, x)
72 func (b *protobuf) int64s(tag int, x []int64) {
73 if len(x) > 2 {
74 // Use packed encoding
75 n1 := len(b.data)
76 for _, u := range x {
77 b.varint(uint64(u))
79 n2 := len(b.data)
80 b.length(tag, n2-n1)
81 n3 := len(b.data)
82 copy(b.tmp[:], b.data[n2:n3])
83 copy(b.data[n1+(n3-n2):], b.data[n1:n2])
84 copy(b.data[n1:], b.tmp[:n3-n2])
85 return
87 for _, u := range x {
88 b.int64(tag, u)
92 func (b *protobuf) string(tag int, x string) {
93 b.length(tag, len(x))
94 b.data = append(b.data, x...)
97 func (b *protobuf) strings(tag int, x []string) {
98 for _, s := range x {
99 b.string(tag, s)
103 func (b *protobuf) stringOpt(tag int, x string) {
104 if x == "" {
105 return
107 b.string(tag, x)
110 func (b *protobuf) bool(tag int, x bool) {
111 if x {
112 b.uint64(tag, 1)
113 } else {
114 b.uint64(tag, 0)
118 func (b *protobuf) boolOpt(tag int, x bool) {
119 if x == false {
120 return
122 b.bool(tag, x)
125 type msgOffset int
127 func (b *protobuf) startMessage() msgOffset {
128 b.nest++
129 return msgOffset(len(b.data))
132 func (b *protobuf) endMessage(tag int, start msgOffset) {
133 n1 := int(start)
134 n2 := len(b.data)
135 b.length(tag, n2-n1)
136 n3 := len(b.data)
137 copy(b.tmp[:], b.data[n2:n3])
138 copy(b.data[n1+(n3-n2):], b.data[n1:n2])
139 copy(b.data[n1:], b.tmp[:n3-n2])
140 b.nest--