...

Source file src/runtime/pprof/internal/profile/proto.go

     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	// This file is a simple protocol buffer encoder and decoder.
     6	//
     7	// A protocol message must implement the message interface:
     8	//   decoder() []decoder
     9	//   encode(*buffer)
    10	//
    11	// The decode method returns a slice indexed by field number that gives the
    12	// function to decode that field.
    13	// The encode method encodes its receiver into the given buffer.
    14	//
    15	// The two methods are simple enough to be implemented by hand rather than
    16	// by using a protocol compiler.
    17	//
    18	// See profile.go for examples of messages implementing this interface.
    19	//
    20	// There is no support for groups, message sets, or "has" bits.
    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		// append varint to b.data
    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			// Use packed encoding
    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			// Use packed encoding
   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			// pull varint field# + type
   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			// Packed encoding
   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			// Packed encoding
   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