OSDN Git Service

add package
[bytom/vapor.git] / vendor / github.com / gogo / protobuf / proto / encode.go
1 // Go support for Protocol Buffers - Google's data interchange format
2 //
3 // Copyright 2010 The Go Authors.  All rights reserved.
4 // https://github.com/golang/protobuf
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 //     * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 package proto
33
34 /*
35  * Routines for encoding data into the wire format for protocol buffers.
36  */
37
38 import (
39         "errors"
40         "reflect"
41 )
42
43 var (
44         // errRepeatedHasNil is the error returned if Marshal is called with
45         // a struct with a repeated field containing a nil element.
46         errRepeatedHasNil = errors.New("proto: repeated field has nil element")
47
48         // errOneofHasNil is the error returned if Marshal is called with
49         // a struct with a oneof field containing a nil element.
50         errOneofHasNil = errors.New("proto: oneof field has nil value")
51
52         // ErrNil is the error returned if Marshal is called with nil.
53         ErrNil = errors.New("proto: Marshal called with nil")
54
55         // ErrTooLarge is the error returned if Marshal is called with a
56         // message that encodes to >2GB.
57         ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
58 )
59
60 // The fundamental encoders that put bytes on the wire.
61 // Those that take integer types all accept uint64 and are
62 // therefore of type valueEncoder.
63
64 const maxVarintBytes = 10 // maximum length of a varint
65
66 // EncodeVarint returns the varint encoding of x.
67 // This is the format for the
68 // int32, int64, uint32, uint64, bool, and enum
69 // protocol buffer types.
70 // Not used by the package itself, but helpful to clients
71 // wishing to use the same encoding.
72 func EncodeVarint(x uint64) []byte {
73         var buf [maxVarintBytes]byte
74         var n int
75         for n = 0; x > 127; n++ {
76                 buf[n] = 0x80 | uint8(x&0x7F)
77                 x >>= 7
78         }
79         buf[n] = uint8(x)
80         n++
81         return buf[0:n]
82 }
83
84 // EncodeVarint writes a varint-encoded integer to the Buffer.
85 // This is the format for the
86 // int32, int64, uint32, uint64, bool, and enum
87 // protocol buffer types.
88 func (p *Buffer) EncodeVarint(x uint64) error {
89         for x >= 1<<7 {
90                 p.buf = append(p.buf, uint8(x&0x7f|0x80))
91                 x >>= 7
92         }
93         p.buf = append(p.buf, uint8(x))
94         return nil
95 }
96
97 // SizeVarint returns the varint encoding size of an integer.
98 func SizeVarint(x uint64) int {
99         switch {
100         case x < 1<<7:
101                 return 1
102         case x < 1<<14:
103                 return 2
104         case x < 1<<21:
105                 return 3
106         case x < 1<<28:
107                 return 4
108         case x < 1<<35:
109                 return 5
110         case x < 1<<42:
111                 return 6
112         case x < 1<<49:
113                 return 7
114         case x < 1<<56:
115                 return 8
116         case x < 1<<63:
117                 return 9
118         }
119         return 10
120 }
121
122 // EncodeFixed64 writes a 64-bit integer to the Buffer.
123 // This is the format for the
124 // fixed64, sfixed64, and double protocol buffer types.
125 func (p *Buffer) EncodeFixed64(x uint64) error {
126         p.buf = append(p.buf,
127                 uint8(x),
128                 uint8(x>>8),
129                 uint8(x>>16),
130                 uint8(x>>24),
131                 uint8(x>>32),
132                 uint8(x>>40),
133                 uint8(x>>48),
134                 uint8(x>>56))
135         return nil
136 }
137
138 // EncodeFixed32 writes a 32-bit integer to the Buffer.
139 // This is the format for the
140 // fixed32, sfixed32, and float protocol buffer types.
141 func (p *Buffer) EncodeFixed32(x uint64) error {
142         p.buf = append(p.buf,
143                 uint8(x),
144                 uint8(x>>8),
145                 uint8(x>>16),
146                 uint8(x>>24))
147         return nil
148 }
149
150 // EncodeZigzag64 writes a zigzag-encoded 64-bit integer
151 // to the Buffer.
152 // This is the format used for the sint64 protocol buffer type.
153 func (p *Buffer) EncodeZigzag64(x uint64) error {
154         // use signed number to get arithmetic right shift.
155         return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
156 }
157
158 // EncodeZigzag32 writes a zigzag-encoded 32-bit integer
159 // to the Buffer.
160 // This is the format used for the sint32 protocol buffer type.
161 func (p *Buffer) EncodeZigzag32(x uint64) error {
162         // use signed number to get arithmetic right shift.
163         return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
164 }
165
166 // EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
167 // This is the format used for the bytes protocol buffer
168 // type and for embedded messages.
169 func (p *Buffer) EncodeRawBytes(b []byte) error {
170         p.EncodeVarint(uint64(len(b)))
171         p.buf = append(p.buf, b...)
172         return nil
173 }
174
175 // EncodeStringBytes writes an encoded string to the Buffer.
176 // This is the format used for the proto2 string type.
177 func (p *Buffer) EncodeStringBytes(s string) error {
178         p.EncodeVarint(uint64(len(s)))
179         p.buf = append(p.buf, s...)
180         return nil
181 }
182
183 // Marshaler is the interface representing objects that can marshal themselves.
184 type Marshaler interface {
185         Marshal() ([]byte, error)
186 }
187
188 // EncodeMessage writes the protocol buffer to the Buffer,
189 // prefixed by a varint-encoded length.
190 func (p *Buffer) EncodeMessage(pb Message) error {
191         siz := Size(pb)
192         p.EncodeVarint(uint64(siz))
193         return p.Marshal(pb)
194 }
195
196 // All protocol buffer fields are nillable, but be careful.
197 func isNil(v reflect.Value) bool {
198         switch v.Kind() {
199         case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
200                 return v.IsNil()
201         }
202         return false
203 }