aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/google.golang.org/grpc/codec.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/google.golang.org/grpc/codec.go')
-rw-r--r--vendor/google.golang.org/grpc/codec.go104
1 files changed, 104 insertions, 0 deletions
diff --git a/vendor/google.golang.org/grpc/codec.go b/vendor/google.golang.org/grpc/codec.go
new file mode 100644
index 0000000..905b048
--- /dev/null
+++ b/vendor/google.golang.org/grpc/codec.go
@@ -0,0 +1,104 @@
1/*
2 *
3 * Copyright 2014 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
19package grpc
20
21import (
22 "math"
23 "sync"
24
25 "github.com/golang/protobuf/proto"
26)
27
28// Codec defines the interface gRPC uses to encode and decode messages.
29// Note that implementations of this interface must be thread safe;
30// a Codec's methods can be called from concurrent goroutines.
31type Codec interface {
32 // Marshal returns the wire format of v.
33 Marshal(v interface{}) ([]byte, error)
34 // Unmarshal parses the wire format into v.
35 Unmarshal(data []byte, v interface{}) error
36 // String returns the name of the Codec implementation. The returned
37 // string will be used as part of content type in transmission.
38 String() string
39}
40
41// protoCodec is a Codec implementation with protobuf. It is the default codec for gRPC.
42type protoCodec struct {
43}
44
45type cachedProtoBuffer struct {
46 lastMarshaledSize uint32
47 proto.Buffer
48}
49
50func capToMaxInt32(val int) uint32 {
51 if val > math.MaxInt32 {
52 return uint32(math.MaxInt32)
53 }
54 return uint32(val)
55}
56
57func (p protoCodec) marshal(v interface{}, cb *cachedProtoBuffer) ([]byte, error) {
58 protoMsg := v.(proto.Message)
59 newSlice := make([]byte, 0, cb.lastMarshaledSize)
60
61 cb.SetBuf(newSlice)
62 cb.Reset()
63 if err := cb.Marshal(protoMsg); err != nil {
64 return nil, err
65 }
66 out := cb.Bytes()
67 cb.lastMarshaledSize = capToMaxInt32(len(out))
68 return out, nil
69}
70
71func (p protoCodec) Marshal(v interface{}) ([]byte, error) {
72 cb := protoBufferPool.Get().(*cachedProtoBuffer)
73 out, err := p.marshal(v, cb)
74
75 // put back buffer and lose the ref to the slice
76 cb.SetBuf(nil)
77 protoBufferPool.Put(cb)
78 return out, err
79}
80
81func (p protoCodec) Unmarshal(data []byte, v interface{}) error {
82 cb := protoBufferPool.Get().(*cachedProtoBuffer)
83 cb.SetBuf(data)
84 v.(proto.Message).Reset()
85 err := cb.Unmarshal(v.(proto.Message))
86 cb.SetBuf(nil)
87 protoBufferPool.Put(cb)
88 return err
89}
90
91func (protoCodec) String() string {
92 return "proto"
93}
94
95var (
96 protoBufferPool = &sync.Pool{
97 New: func() interface{} {
98 return &cachedProtoBuffer{
99 Buffer: proto.Buffer{},
100 lastMarshaledSize: 16,
101 }
102 },
103 }
104)