Home | History | Annotate | Download | only in profile
      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