package profile
import (
)
type buffer struct {
field int
typ int
u64 uint64
data []byte
tmp [16]byte
}
type decoder func(*buffer, message) error
type message interface {
decoder() []decoder
encode(*buffer)
}
func ( message) []byte {
var buffer
.encode(&)
return .data
}
func ( *buffer, uint64) {
for >= 128 {
.data = append(.data, byte()|0x80)
>>= 7
}
.data = append(.data, byte())
}
func ( *buffer, int, int) {
encodeVarint(, uint64()<<3|2)
encodeVarint(, uint64())
}
func ( *buffer, int, uint64) {
encodeVarint(, uint64()<<3|0)
encodeVarint(, )
}
func ( *buffer, int, []uint64) {
if len() > 2 {
:= len(.data)
for , := range {
encodeVarint(, )
}
:= len(.data)
encodeLength(, , -)
:= len(.data)
copy(.tmp[:], .data[:])
copy(.data[+(-):], .data[:])
copy(.data[:], .tmp[:-])
return
}
for , := range {
encodeUint64(, , )
}
}
func ( *buffer, int, uint64) {
if == 0 {
return
}
encodeUint64(, , )
}
func ( *buffer, int, int64) {
:= uint64()
encodeUint64(, , )
}
func ( *buffer, int, int64) {
if == 0 {
return
}
encodeInt64(, , )
}
func ( *buffer, int, []int64) {
if len() > 2 {
:= len(.data)
for , := range {
encodeVarint(, uint64())
}
:= len(.data)
encodeLength(, , -)
:= len(.data)
copy(.tmp[:], .data[:])
copy(.data[+(-):], .data[:])
copy(.data[:], .tmp[:-])
return
}
for , := range {
encodeInt64(, , )
}
}
func ( *buffer, int, string) {
encodeLength(, , len())
.data = append(.data, ...)
}
func ( *buffer, int, []string) {
for , := range {
encodeString(, , )
}
}
func ( *buffer, int, string) {
if == "" {
return
}
encodeString(, , )
}
func ( *buffer, int, bool) {
if {
encodeUint64(, , 1)
} else {
encodeUint64(, , 0)
}
}
func ( *buffer, int, bool) {
if == false {
return
}
encodeBool(, , )
}
func ( *buffer, int, message) {
:= len(.data)
.encode()
:= len(.data)
encodeLength(, , -)
:= len(.data)
copy(.tmp[:], .data[:])
copy(.data[+(-):], .data[:])
copy(.data[:], .tmp[:-])
}
func ( []byte, message) ( error) {
:= buffer{data: , typ: 2}
return decodeMessage(&, )
}
func ( []byte) uint64 {
return uint64([0]) | uint64([1])<<8 | uint64([2])<<16 | uint64([3])<<24 | uint64([4])<<32 | uint64([5])<<40 | uint64([6])<<48 | uint64([7])<<56
}
func ( []byte) uint32 {
return uint32([0]) | uint32([1])<<8 | uint32([2])<<16 | uint32([3])<<24
}
func ( []byte) (uint64, []byte, error) {
var int
var uint64
for = 0; ; ++ {
if >= 10 || >= len() {
return 0, nil, errors.New("bad varint")
}
|= uint64([]&0x7F) << uint(7*)
if []&0x80 == 0 {
return , [+1:], nil
}
}
}
func ( *buffer, []byte) ([]byte, error) {
, , := decodeVarint()
if != nil {
return nil,
}
.field = int( >> 3)
.typ = int( & 7)
.data = nil
.u64 = 0
switch .typ {
case 0:
.u64, , = decodeVarint()
if != nil {
return nil,
}
case 1:
if len() < 8 {
return nil, errors.New("not enough data")
}
.u64 = le64([:8])
= [8:]
case 2:
var uint64
, , = decodeVarint()
if != nil {
return nil,
}
if > uint64(len()) {
return nil, errors.New("too much data")
}
.data = [:]
= [:]
case 5:
if len() < 4 {
return nil, errors.New("not enough data")
}
.u64 = uint64(le32([:4]))
= [4:]
default:
return nil, fmt.Errorf("unknown wire type: %d", .typ)
}
return , nil
}
func ( *buffer, int) error {
if .typ != {
return errors.New("type mismatch")
}
return nil
}
func ( *buffer, message) error {
if := checkType(, 2); != nil {
return
}
:= .decoder()
:= .data
for len() > 0 {
var error
, = decodeField(, )
if != nil {
return
}
if .field >= len() || [.field] == nil {
continue
}
if := [.field](, ); != nil {
return
}
}
return nil
}
func ( *buffer, *int64) error {
if := checkType(, 0); != nil {
return
}
* = int64(.u64)
return nil
}
func ( *buffer, *[]int64) error {
if .typ == 2 {
:= .data
for len() > 0 {
var uint64
var error
if , , = decodeVarint(); != nil {
return
}
* = append(*, int64())
}
return nil
}
var int64
if := decodeInt64(, &); != nil {
return
}
* = append(*, )
return nil
}
func ( *buffer, *uint64) error {
if := checkType(, 0); != nil {
return
}
* = .u64
return nil
}
func ( *buffer, *[]uint64) error {
if .typ == 2 {
:= .data
for len() > 0 {
var uint64
var error
if , , = decodeVarint(); != nil {
return
}
* = append(*, )
}
return nil
}
var uint64
if := decodeUint64(, &); != nil {
return
}
* = append(*, )
return nil
}
func ( *buffer, *string) error {
if := checkType(, 2); != nil {
return
}
* = string(.data)
return nil
}
func ( *buffer, *[]string) error {
var string
if := decodeString(, &); != nil {
return
}
* = append(*, )
return nil
}
func ( *buffer, *bool) error {
if := checkType(, 0); != nil {
return
}
if int64(.u64) == 0 {
* = false
} else {
* = true
}
return nil
}