...

Source file src/runtime/pprof/protobuf.go

Documentation: runtime/pprof

		 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.
		 4  
		 5  package pprof
		 6  
		 7  // A protobuf is a simple protocol buffer encoder.
		 8  type protobuf struct {
		 9  	data []byte
		10  	tmp	[16]byte
		11  	nest int
		12  }
		13  
		14  func (b *protobuf) varint(x uint64) {
		15  	for x >= 128 {
		16  		b.data = append(b.data, byte(x)|0x80)
		17  		x >>= 7
		18  	}
		19  	b.data = append(b.data, byte(x))
		20  }
		21  
		22  func (b *protobuf) length(tag int, len int) {
		23  	b.varint(uint64(tag)<<3 | 2)
		24  	b.varint(uint64(len))
		25  }
		26  
		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)
		31  }
		32  
		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)
		39  		}
		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
		47  	}
		48  	for _, u := range x {
		49  		b.uint64(tag, u)
		50  	}
		51  }
		52  
		53  func (b *protobuf) uint64Opt(tag int, x uint64) {
		54  	if x == 0 {
		55  		return
		56  	}
		57  	b.uint64(tag, x)
		58  }
		59  
		60  func (b *protobuf) int64(tag int, x int64) {
		61  	u := uint64(x)
		62  	b.uint64(tag, u)
		63  }
		64  
		65  func (b *protobuf) int64Opt(tag int, x int64) {
		66  	if x == 0 {
		67  		return
		68  	}
		69  	b.int64(tag, x)
		70  }
		71  
		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))
		78  		}
		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
		86  	}
		87  	for _, u := range x {
		88  		b.int64(tag, u)
		89  	}
		90  }
		91  
		92  func (b *protobuf) string(tag int, x string) {
		93  	b.length(tag, len(x))
		94  	b.data = append(b.data, x...)
		95  }
		96  
		97  func (b *protobuf) strings(tag int, x []string) {
		98  	for _, s := range x {
		99  		b.string(tag, s)
	 100  	}
	 101  }
	 102  
	 103  func (b *protobuf) stringOpt(tag int, x string) {
	 104  	if x == "" {
	 105  		return
	 106  	}
	 107  	b.string(tag, x)
	 108  }
	 109  
	 110  func (b *protobuf) bool(tag int, x bool) {
	 111  	if x {
	 112  		b.uint64(tag, 1)
	 113  	} else {
	 114  		b.uint64(tag, 0)
	 115  	}
	 116  }
	 117  
	 118  func (b *protobuf) boolOpt(tag int, x bool) {
	 119  	if x == false {
	 120  		return
	 121  	}
	 122  	b.bool(tag, x)
	 123  }
	 124  
	 125  type msgOffset int
	 126  
	 127  func (b *protobuf) startMessage() msgOffset {
	 128  	b.nest++
	 129  	return msgOffset(len(b.data))
	 130  }
	 131  
	 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--
	 141  }
	 142  

View as plain text