podman
1// Copyright 2014 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// This file is a simple protocol buffer encoder and decoder.
16// The format is described at
17// https://developers.google.com/protocol-buffers/docs/encoding
18//
19// A protocol message must implement the message interface:
20// decoder() []decoder
21// encode(*buffer)
22//
23// The decode method returns a slice indexed by field number that gives the
24// function to decode that field.
25// The encode method encodes its receiver into the given buffer.
26//
27// The two methods are simple enough to be implemented by hand rather than
28// by using a protocol compiler.
29//
30// See profile.go for examples of messages implementing this interface.
31//
32// There is no support for groups, message sets, or "has" bits.
33
34package profile35
36import (37"errors"38"fmt"39)
40
41type buffer struct {42field int // field tag43typ int // proto wire type code for field44u64 uint6445data []byte46tmp [16]byte47}
48
49type decoder func(*buffer, message) error50
51type message interface {52decoder() []decoder53encode(*buffer)54}
55
56func marshal(m message) []byte {57var b buffer58m.encode(&b)59return b.data60}
61
62func encodeVarint(b *buffer, x uint64) {63for x >= 128 {64b.data = append(b.data, byte(x)|0x80)65x >>= 766}67b.data = append(b.data, byte(x))68}
69
70func encodeLength(b *buffer, tag int, len int) {71encodeVarint(b, uint64(tag)<<3|2)72encodeVarint(b, uint64(len))73}
74
75func encodeUint64(b *buffer, tag int, x uint64) {76// append varint to b.data77encodeVarint(b, uint64(tag)<<3)78encodeVarint(b, x)79}
80
81func encodeUint64s(b *buffer, tag int, x []uint64) {82if len(x) > 2 {83// Use packed encoding84n1 := len(b.data)85for _, u := range x {86encodeVarint(b, u)87}88n2 := len(b.data)89encodeLength(b, tag, n2-n1)90n3 := len(b.data)91copy(b.tmp[:], b.data[n2:n3])92copy(b.data[n1+(n3-n2):], b.data[n1:n2])93copy(b.data[n1:], b.tmp[:n3-n2])94return95}96for _, u := range x {97encodeUint64(b, tag, u)98}99}
100
101func encodeUint64Opt(b *buffer, tag int, x uint64) {102if x == 0 {103return104}105encodeUint64(b, tag, x)106}
107
108func encodeInt64(b *buffer, tag int, x int64) {109u := uint64(x)110encodeUint64(b, tag, u)111}
112
113func encodeInt64s(b *buffer, tag int, x []int64) {114if len(x) > 2 {115// Use packed encoding116n1 := len(b.data)117for _, u := range x {118encodeVarint(b, uint64(u))119}120n2 := len(b.data)121encodeLength(b, tag, n2-n1)122n3 := len(b.data)123copy(b.tmp[:], b.data[n2:n3])124copy(b.data[n1+(n3-n2):], b.data[n1:n2])125copy(b.data[n1:], b.tmp[:n3-n2])126return127}128for _, u := range x {129encodeInt64(b, tag, u)130}131}
132
133func encodeInt64Opt(b *buffer, tag int, x int64) {134if x == 0 {135return136}137encodeInt64(b, tag, x)138}
139
140func encodeString(b *buffer, tag int, x string) {141encodeLength(b, tag, len(x))142b.data = append(b.data, x...)143}
144
145func encodeStrings(b *buffer, tag int, x []string) {146for _, s := range x {147encodeString(b, tag, s)148}149}
150
151func encodeBool(b *buffer, tag int, x bool) {152if x {153encodeUint64(b, tag, 1)154} else {155encodeUint64(b, tag, 0)156}157}
158
159func encodeBoolOpt(b *buffer, tag int, x bool) {160if x {161encodeBool(b, tag, x)162}163}
164
165func encodeMessage(b *buffer, tag int, m message) {166n1 := len(b.data)167m.encode(b)168n2 := len(b.data)169encodeLength(b, tag, n2-n1)170n3 := len(b.data)171copy(b.tmp[:], b.data[n2:n3])172copy(b.data[n1+(n3-n2):], b.data[n1:n2])173copy(b.data[n1:], b.tmp[:n3-n2])174}
175
176func unmarshal(data []byte, m message) (err error) {177b := buffer{data: data, typ: 2}178return decodeMessage(&b, m)179}
180
181func le64(p []byte) uint64 {182return 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])<<56183}
184
185func le32(p []byte) uint32 {186return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24187}
188
189func decodeVarint(data []byte) (uint64, []byte, error) {190var u uint64191for i := 0; ; i++ {192if i >= 10 || i >= len(data) {193return 0, nil, errors.New("bad varint")194}195u |= uint64(data[i]&0x7F) << uint(7*i)196if data[i]&0x80 == 0 {197return u, data[i+1:], nil198}199}200}
201
202func decodeField(b *buffer, data []byte) ([]byte, error) {203x, data, err := decodeVarint(data)204if err != nil {205return nil, err206}207b.field = int(x >> 3)208b.typ = int(x & 7)209b.data = nil210b.u64 = 0211switch b.typ {212case 0:213b.u64, data, err = decodeVarint(data)214if err != nil {215return nil, err216}217case 1:218if len(data) < 8 {219return nil, errors.New("not enough data")220}221b.u64 = le64(data[:8])222data = data[8:]223case 2:224var n uint64225n, data, err = decodeVarint(data)226if err != nil {227return nil, err228}229if n > uint64(len(data)) {230return nil, errors.New("too much data")231}232b.data = data[:n]233data = data[n:]234case 5:235if len(data) < 4 {236return nil, errors.New("not enough data")237}238b.u64 = uint64(le32(data[:4]))239data = data[4:]240default:241return nil, fmt.Errorf("unknown wire type: %d", b.typ)242}243
244return data, nil245}
246
247func checkType(b *buffer, typ int) error {248if b.typ != typ {249return errors.New("type mismatch")250}251return nil252}
253
254func decodeMessage(b *buffer, m message) error {255if err := checkType(b, 2); err != nil {256return err257}258dec := m.decoder()259data := b.data260for len(data) > 0 {261// pull varint field# + type262var err error263data, err = decodeField(b, data)264if err != nil {265return err266}267if b.field >= len(dec) || dec[b.field] == nil {268continue269}270if err := dec[b.field](b, m); err != nil {271return err272}273}274return nil275}
276
277func decodeInt64(b *buffer, x *int64) error {278if err := checkType(b, 0); err != nil {279return err280}281*x = int64(b.u64)282return nil283}
284
285func decodeInt64s(b *buffer, x *[]int64) error {286if b.typ == 2 {287// Packed encoding288data := b.data289tmp := make([]int64, 0, len(data)) // Maximally sized290for len(data) > 0 {291var u uint64292var err error293
294if u, data, err = decodeVarint(data); err != nil {295return err296}297tmp = append(tmp, int64(u))298}299*x = append(*x, tmp...)300return nil301}302var i int64303if err := decodeInt64(b, &i); err != nil {304return err305}306*x = append(*x, i)307return nil308}
309
310func decodeUint64(b *buffer, x *uint64) error {311if err := checkType(b, 0); err != nil {312return err313}314*x = b.u64315return nil316}
317
318func decodeUint64s(b *buffer, x *[]uint64) error {319if b.typ == 2 {320data := b.data321// Packed encoding322tmp := make([]uint64, 0, len(data)) // Maximally sized323for len(data) > 0 {324var u uint64325var err error326
327if u, data, err = decodeVarint(data); err != nil {328return err329}330tmp = append(tmp, u)331}332*x = append(*x, tmp...)333return nil334}335var u uint64336if err := decodeUint64(b, &u); err != nil {337return err338}339*x = append(*x, u)340return nil341}
342
343func decodeString(b *buffer, x *string) error {344if err := checkType(b, 2); err != nil {345return err346}347*x = string(b.data)348return nil349}
350
351func decodeStrings(b *buffer, x *[]string) error {352var s string353if err := decodeString(b, &s); err != nil {354return err355}356*x = append(*x, s)357return nil358}
359
360func decodeBool(b *buffer, x *bool) error {361if err := checkType(b, 0); err != nil {362return err363}364if int64(b.u64) == 0 {365*x = false366} else {367*x = true368}369return nil370}
371