blob: 3abfed2cff04bdf3bb72517b6f1807b82a151570 [file] [log] [blame]
Scott Bakereee8dd82019-09-24 12:52:34 -07001// 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
32package proto
33
34/*
35 * Routines for encoding data into the wire format for protocol buffers.
36 */
37
38import (
39 "errors"
40 "reflect"
41)
42
43var (
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
64const 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.
72func 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.
88func (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.
98func 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.
125func (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.
141func (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.
153func (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.
161func (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.
169func (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.
177func (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.
184type Marshaler interface {
185 Marshal() ([]byte, error)
186}
187
188// EncodeMessage writes the protocol buffer to the Buffer,
189// prefixed by a varint-encoded length.
190func (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.
197func 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}