github.com/sandwichdev/go-internals@v0.0.0-20210605002614-12311ac6b2c5/profile/proto.go (about) 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 ( 25 "errors" 26 "fmt" 27 ) 28 29 type buffer struct { 30 field int 31 typ int 32 u64 uint64 33 data []byte 34 tmp [16]byte 35 } 36 37 type decoder func(*buffer, message) error 38 39 type message interface { 40 decoder() []decoder 41 encode(*buffer) 42 } 43 44 func marshal(m message) []byte { 45 var b buffer 46 m.encode(&b) 47 return b.data 48 } 49 50 func encodeVarint(b *buffer, x uint64) { 51 for x >= 128 { 52 b.data = append(b.data, byte(x)|0x80) 53 x >>= 7 54 } 55 b.data = append(b.data, byte(x)) 56 } 57 58 func encodeLength(b *buffer, tag int, len int) { 59 encodeVarint(b, uint64(tag)<<3|2) 60 encodeVarint(b, uint64(len)) 61 } 62 63 func encodeUint64(b *buffer, tag int, x uint64) { 64 // append varint to b.data 65 encodeVarint(b, uint64(tag)<<3|0) 66 encodeVarint(b, x) 67 } 68 69 func encodeUint64s(b *buffer, tag int, x []uint64) { 70 if len(x) > 2 { 71 // Use packed encoding 72 n1 := len(b.data) 73 for _, u := range x { 74 encodeVarint(b, u) 75 } 76 n2 := len(b.data) 77 encodeLength(b, tag, n2-n1) 78 n3 := len(b.data) 79 copy(b.tmp[:], b.data[n2:n3]) 80 copy(b.data[n1+(n3-n2):], b.data[n1:n2]) 81 copy(b.data[n1:], b.tmp[:n3-n2]) 82 return 83 } 84 for _, u := range x { 85 encodeUint64(b, tag, u) 86 } 87 } 88 89 func encodeUint64Opt(b *buffer, tag int, x uint64) { 90 if x == 0 { 91 return 92 } 93 encodeUint64(b, tag, x) 94 } 95 96 func encodeInt64(b *buffer, tag int, x int64) { 97 u := uint64(x) 98 encodeUint64(b, tag, u) 99 } 100 101 func encodeInt64Opt(b *buffer, tag int, x int64) { 102 if x == 0 { 103 return 104 } 105 encodeInt64(b, tag, x) 106 } 107 108 func encodeInt64s(b *buffer, tag int, x []int64) { 109 if len(x) > 2 { 110 // Use packed encoding 111 n1 := len(b.data) 112 for _, u := range x { 113 encodeVarint(b, uint64(u)) 114 } 115 n2 := len(b.data) 116 encodeLength(b, tag, n2-n1) 117 n3 := len(b.data) 118 copy(b.tmp[:], b.data[n2:n3]) 119 copy(b.data[n1+(n3-n2):], b.data[n1:n2]) 120 copy(b.data[n1:], b.tmp[:n3-n2]) 121 return 122 } 123 for _, u := range x { 124 encodeInt64(b, tag, u) 125 } 126 } 127 128 func encodeString(b *buffer, tag int, x string) { 129 encodeLength(b, tag, len(x)) 130 b.data = append(b.data, x...) 131 } 132 133 func encodeStrings(b *buffer, tag int, x []string) { 134 for _, s := range x { 135 encodeString(b, tag, s) 136 } 137 } 138 139 func encodeStringOpt(b *buffer, tag int, x string) { 140 if x == "" { 141 return 142 } 143 encodeString(b, tag, x) 144 } 145 146 func encodeBool(b *buffer, tag int, x bool) { 147 if x { 148 encodeUint64(b, tag, 1) 149 } else { 150 encodeUint64(b, tag, 0) 151 } 152 } 153 154 func encodeBoolOpt(b *buffer, tag int, x bool) { 155 if x == false { 156 return 157 } 158 encodeBool(b, tag, x) 159 } 160 161 func encodeMessage(b *buffer, tag int, m message) { 162 n1 := len(b.data) 163 m.encode(b) 164 n2 := len(b.data) 165 encodeLength(b, tag, n2-n1) 166 n3 := len(b.data) 167 copy(b.tmp[:], b.data[n2:n3]) 168 copy(b.data[n1+(n3-n2):], b.data[n1:n2]) 169 copy(b.data[n1:], b.tmp[:n3-n2]) 170 } 171 172 func unmarshal(data []byte, m message) (err error) { 173 b := buffer{data: data, typ: 2} 174 return decodeMessage(&b, m) 175 } 176 177 func le64(p []byte) uint64 { 178 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 179 } 180 181 func le32(p []byte) uint32 { 182 return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 183 } 184 185 func decodeVarint(data []byte) (uint64, []byte, error) { 186 var i int 187 var u uint64 188 for i = 0; ; i++ { 189 if i >= 10 || i >= len(data) { 190 return 0, nil, errors.New("bad varint") 191 } 192 u |= uint64(data[i]&0x7F) << uint(7*i) 193 if data[i]&0x80 == 0 { 194 return u, data[i+1:], nil 195 } 196 } 197 } 198 199 func decodeField(b *buffer, data []byte) ([]byte, error) { 200 x, data, err := decodeVarint(data) 201 if err != nil { 202 return nil, err 203 } 204 b.field = int(x >> 3) 205 b.typ = int(x & 7) 206 b.data = nil 207 b.u64 = 0 208 switch b.typ { 209 case 0: 210 b.u64, data, err = decodeVarint(data) 211 if err != nil { 212 return nil, err 213 } 214 case 1: 215 if len(data) < 8 { 216 return nil, errors.New("not enough data") 217 } 218 b.u64 = le64(data[:8]) 219 data = data[8:] 220 case 2: 221 var n uint64 222 n, data, err = decodeVarint(data) 223 if err != nil { 224 return nil, err 225 } 226 if n > uint64(len(data)) { 227 return nil, errors.New("too much data") 228 } 229 b.data = data[:n] 230 data = data[n:] 231 case 5: 232 if len(data) < 4 { 233 return nil, errors.New("not enough data") 234 } 235 b.u64 = uint64(le32(data[:4])) 236 data = data[4:] 237 default: 238 return nil, fmt.Errorf("unknown wire type: %d", b.typ) 239 } 240 241 return data, nil 242 } 243 244 func checkType(b *buffer, typ int) error { 245 if b.typ != typ { 246 return errors.New("type mismatch") 247 } 248 return nil 249 } 250 251 func decodeMessage(b *buffer, m message) error { 252 if err := checkType(b, 2); err != nil { 253 return err 254 } 255 dec := m.decoder() 256 data := b.data 257 for len(data) > 0 { 258 // pull varint field# + type 259 var err error 260 data, err = decodeField(b, data) 261 if err != nil { 262 return err 263 } 264 if b.field >= len(dec) || dec[b.field] == nil { 265 continue 266 } 267 if err := dec[b.field](b, m); err != nil { 268 return err 269 } 270 } 271 return nil 272 } 273 274 func decodeInt64(b *buffer, x *int64) error { 275 if err := checkType(b, 0); err != nil { 276 return err 277 } 278 *x = int64(b.u64) 279 return nil 280 } 281 282 func decodeInt64s(b *buffer, x *[]int64) error { 283 if b.typ == 2 { 284 // Packed encoding 285 data := b.data 286 for len(data) > 0 { 287 var u uint64 288 var err error 289 290 if u, data, err = decodeVarint(data); err != nil { 291 return err 292 } 293 *x = append(*x, int64(u)) 294 } 295 return nil 296 } 297 var i int64 298 if err := decodeInt64(b, &i); err != nil { 299 return err 300 } 301 *x = append(*x, i) 302 return nil 303 } 304 305 func decodeUint64(b *buffer, x *uint64) error { 306 if err := checkType(b, 0); err != nil { 307 return err 308 } 309 *x = b.u64 310 return nil 311 } 312 313 func decodeUint64s(b *buffer, x *[]uint64) error { 314 if b.typ == 2 { 315 data := b.data 316 // Packed encoding 317 for len(data) > 0 { 318 var u uint64 319 var err error 320 321 if u, data, err = decodeVarint(data); err != nil { 322 return err 323 } 324 *x = append(*x, u) 325 } 326 return nil 327 } 328 var u uint64 329 if err := decodeUint64(b, &u); err != nil { 330 return err 331 } 332 *x = append(*x, u) 333 return nil 334 } 335 336 func decodeString(b *buffer, x *string) error { 337 if err := checkType(b, 2); err != nil { 338 return err 339 } 340 *x = string(b.data) 341 return nil 342 } 343 344 func decodeStrings(b *buffer, x *[]string) error { 345 var s string 346 if err := decodeString(b, &s); err != nil { 347 return err 348 } 349 *x = append(*x, s) 350 return nil 351 } 352 353 func decodeBool(b *buffer, x *bool) error { 354 if err := checkType(b, 0); err != nil { 355 return err 356 } 357 if int64(b.u64) == 0 { 358 *x = false 359 } else { 360 *x = true 361 } 362 return nil 363 }