...
Run Format

Source file src/runtime/pprof/protobuf.go

Documentation: runtime/pprof

  // Copyright 2014 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package pprof
  
  // A protobuf is a simple protocol buffer encoder.
  type protobuf struct {
  	data []byte
  	tmp  [16]byte
  	nest int
  }
  
  func (b *protobuf) varint(x uint64) {
  	for x >= 128 {
  		b.data = append(b.data, byte(x)|0x80)
  		x >>= 7
  	}
  	b.data = append(b.data, byte(x))
  }
  
  func (b *protobuf) length(tag int, len int) {
  	b.varint(uint64(tag)<<3 | 2)
  	b.varint(uint64(len))
  }
  
  func (b *protobuf) uint64(tag int, x uint64) {
  	// append varint to b.data
  	b.varint(uint64(tag)<<3 | 0)
  	b.varint(x)
  }
  
  func (b *protobuf) uint64s(tag int, x []uint64) {
  	if len(x) > 2 {
  		// Use packed encoding
  		n1 := len(b.data)
  		for _, u := range x {
  			b.varint(u)
  		}
  		n2 := len(b.data)
  		b.length(tag, n2-n1)
  		n3 := len(b.data)
  		copy(b.tmp[:], b.data[n2:n3])
  		copy(b.data[n1+(n3-n2):], b.data[n1:n2])
  		copy(b.data[n1:], b.tmp[:n3-n2])
  		return
  	}
  	for _, u := range x {
  		b.uint64(tag, u)
  	}
  }
  
  func (b *protobuf) uint64Opt(tag int, x uint64) {
  	if x == 0 {
  		return
  	}
  	b.uint64(tag, x)
  }
  
  func (b *protobuf) int64(tag int, x int64) {
  	u := uint64(x)
  	b.uint64(tag, u)
  }
  
  func (b *protobuf) int64Opt(tag int, x int64) {
  	if x == 0 {
  		return
  	}
  	b.int64(tag, x)
  }
  
  func (b *protobuf) int64s(tag int, x []int64) {
  	if len(x) > 2 {
  		// Use packed encoding
  		n1 := len(b.data)
  		for _, u := range x {
  			b.varint(uint64(u))
  		}
  		n2 := len(b.data)
  		b.length(tag, n2-n1)
  		n3 := len(b.data)
  		copy(b.tmp[:], b.data[n2:n3])
  		copy(b.data[n1+(n3-n2):], b.data[n1:n2])
  		copy(b.data[n1:], b.tmp[:n3-n2])
  		return
  	}
  	for _, u := range x {
  		b.int64(tag, u)
  	}
  }
  
  func (b *protobuf) string(tag int, x string) {
  	b.length(tag, len(x))
  	b.data = append(b.data, x...)
  }
  
  func (b *protobuf) strings(tag int, x []string) {
  	for _, s := range x {
  		b.string(tag, s)
  	}
  }
  
  func (b *protobuf) stringOpt(tag int, x string) {
  	if x == "" {
  		return
  	}
  	b.string(tag, x)
  }
  
  func (b *protobuf) bool(tag int, x bool) {
  	if x {
  		b.uint64(tag, 1)
  	} else {
  		b.uint64(tag, 0)
  	}
  }
  
  func (b *protobuf) boolOpt(tag int, x bool) {
  	if x == false {
  		return
  	}
  	b.bool(tag, x)
  }
  
  type msgOffset int
  
  func (b *protobuf) startMessage() msgOffset {
  	b.nest++
  	return msgOffset(len(b.data))
  }
  
  func (b *protobuf) endMessage(tag int, start msgOffset) {
  	n1 := int(start)
  	n2 := len(b.data)
  	b.length(tag, n2-n1)
  	n3 := len(b.data)
  	copy(b.tmp[:], b.data[n2:n3])
  	copy(b.data[n1+(n3-n2):], b.data[n1:n2])
  	copy(b.data[n1:], b.tmp[:n3-n2])
  	b.nest--
  }
  

View as plain text