Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / google.golang.org / grpc / encoding / proto / proto.go
1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 // Package proto defines the protobuf codec. Importing this package will
20 // register the codec.
21 package proto
22
23 import (
24         "math"
25         "sync"
26
27         "github.com/golang/protobuf/proto"
28         "google.golang.org/grpc/encoding"
29 )
30
31 // Name is the name registered for the proto compressor.
32 const Name = "proto"
33
34 func init() {
35         encoding.RegisterCodec(codec{})
36 }
37
38 // codec is a Codec implementation with protobuf. It is the default codec for gRPC.
39 type codec struct{}
40
41 type cachedProtoBuffer struct {
42         lastMarshaledSize uint32
43         proto.Buffer
44 }
45
46 func capToMaxInt32(val int) uint32 {
47         if val > math.MaxInt32 {
48                 return uint32(math.MaxInt32)
49         }
50         return uint32(val)
51 }
52
53 func marshal(v interface{}, cb *cachedProtoBuffer) ([]byte, error) {
54         protoMsg := v.(proto.Message)
55         newSlice := make([]byte, 0, cb.lastMarshaledSize)
56
57         cb.SetBuf(newSlice)
58         cb.Reset()
59         if err := cb.Marshal(protoMsg); err != nil {
60                 return nil, err
61         }
62         out := cb.Bytes()
63         cb.lastMarshaledSize = capToMaxInt32(len(out))
64         return out, nil
65 }
66
67 func (codec) Marshal(v interface{}) ([]byte, error) {
68         if pm, ok := v.(proto.Marshaler); ok {
69                 // object can marshal itself, no need for buffer
70                 return pm.Marshal()
71         }
72
73         cb := protoBufferPool.Get().(*cachedProtoBuffer)
74         out, err := marshal(v, cb)
75
76         // put back buffer and lose the ref to the slice
77         cb.SetBuf(nil)
78         protoBufferPool.Put(cb)
79         return out, err
80 }
81
82 func (codec) Unmarshal(data []byte, v interface{}) error {
83         protoMsg := v.(proto.Message)
84         protoMsg.Reset()
85
86         if pu, ok := protoMsg.(proto.Unmarshaler); ok {
87                 // object can unmarshal itself, no need for buffer
88                 return pu.Unmarshal(data)
89         }
90
91         cb := protoBufferPool.Get().(*cachedProtoBuffer)
92         cb.SetBuf(data)
93         err := cb.Unmarshal(protoMsg)
94         cb.SetBuf(nil)
95         protoBufferPool.Put(cb)
96         return err
97 }
98
99 func (codec) Name() string {
100         return Name
101 }
102
103 var protoBufferPool = &sync.Pool{
104         New: func() interface{} {
105                 return &cachedProtoBuffer{
106                         Buffer:            proto.Buffer{},
107                         lastMarshaledSize: 16,
108                 }
109         },
110 }