blob: c27d35f866bb0b6a72bc895de19461146ae44b21 [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001// 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 "fmt"
41 "reflect"
42)
43
44// RequiredNotSetError is the error returned if Marshal is called with
45// a protocol buffer struct whose required fields have not
46// all been initialized. It is also the error returned if Unmarshal is
47// called with an encoded protocol buffer that does not include all the
48// required fields.
49//
50// When printed, RequiredNotSetError reports the first unset required field in a
51// message. If the field cannot be precisely determined, it is reported as
52// "{Unknown}".
53type RequiredNotSetError struct {
54 field string
55}
56
57func (e *RequiredNotSetError) Error() string {
58 return fmt.Sprintf("proto: required field %q not set", e.field)
59}
60
61var (
62 // errRepeatedHasNil is the error returned if Marshal is called with
63 // a struct with a repeated field containing a nil element.
64 errRepeatedHasNil = errors.New("proto: repeated field has nil element")
65
66 // errOneofHasNil is the error returned if Marshal is called with
67 // a struct with a oneof field containing a nil element.
68 errOneofHasNil = errors.New("proto: oneof field has nil value")
69
70 // ErrNil is the error returned if Marshal is called with nil.
71 ErrNil = errors.New("proto: Marshal called with nil")
72
73 // ErrTooLarge is the error returned if Marshal is called with a
74 // message that encodes to >2GB.
75 ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
76)
77
78// The fundamental encoders that put bytes on the wire.
79// Those that take integer types all accept uint64 and are
80// therefore of type valueEncoder.
81
82const maxVarintBytes = 10 // maximum length of a varint
83
84// EncodeVarint returns the varint encoding of x.
85// This is the format for the
86// int32, int64, uint32, uint64, bool, and enum
87// protocol buffer types.
88// Not used by the package itself, but helpful to clients
89// wishing to use the same encoding.
90func EncodeVarint(x uint64) []byte {
91 var buf [maxVarintBytes]byte
92 var n int
93 for n = 0; x > 127; n++ {
94 buf[n] = 0x80 | uint8(x&0x7F)
95 x >>= 7
96 }
97 buf[n] = uint8(x)
98 n++
99 return buf[0:n]
100}
101
102// EncodeVarint writes a varint-encoded integer to the Buffer.
103// This is the format for the
104// int32, int64, uint32, uint64, bool, and enum
105// protocol buffer types.
106func (p *Buffer) EncodeVarint(x uint64) error {
107 for x >= 1<<7 {
108 p.buf = append(p.buf, uint8(x&0x7f|0x80))
109 x >>= 7
110 }
111 p.buf = append(p.buf, uint8(x))
112 return nil
113}
114
115// SizeVarint returns the varint encoding size of an integer.
116func SizeVarint(x uint64) int {
117 switch {
118 case x < 1<<7:
119 return 1
120 case x < 1<<14:
121 return 2
122 case x < 1<<21:
123 return 3
124 case x < 1<<28:
125 return 4
126 case x < 1<<35:
127 return 5
128 case x < 1<<42:
129 return 6
130 case x < 1<<49:
131 return 7
132 case x < 1<<56:
133 return 8
134 case x < 1<<63:
135 return 9
136 }
137 return 10
138}
139
140// EncodeFixed64 writes a 64-bit integer to the Buffer.
141// This is the format for the
142// fixed64, sfixed64, and double protocol buffer types.
143func (p *Buffer) EncodeFixed64(x uint64) error {
144 p.buf = append(p.buf,
145 uint8(x),
146 uint8(x>>8),
147 uint8(x>>16),
148 uint8(x>>24),
149 uint8(x>>32),
150 uint8(x>>40),
151 uint8(x>>48),
152 uint8(x>>56))
153 return nil
154}
155
156// EncodeFixed32 writes a 32-bit integer to the Buffer.
157// This is the format for the
158// fixed32, sfixed32, and float protocol buffer types.
159func (p *Buffer) EncodeFixed32(x uint64) error {
160 p.buf = append(p.buf,
161 uint8(x),
162 uint8(x>>8),
163 uint8(x>>16),
164 uint8(x>>24))
165 return nil
166}
167
168// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
169// to the Buffer.
170// This is the format used for the sint64 protocol buffer type.
171func (p *Buffer) EncodeZigzag64(x uint64) error {
172 // use signed number to get arithmetic right shift.
173 return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
174}
175
176// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
177// to the Buffer.
178// This is the format used for the sint32 protocol buffer type.
179func (p *Buffer) EncodeZigzag32(x uint64) error {
180 // use signed number to get arithmetic right shift.
181 return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
182}
183
184// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
185// This is the format used for the bytes protocol buffer
186// type and for embedded messages.
187func (p *Buffer) EncodeRawBytes(b []byte) error {
188 p.EncodeVarint(uint64(len(b)))
189 p.buf = append(p.buf, b...)
190 return nil
191}
192
193// EncodeStringBytes writes an encoded string to the Buffer.
194// This is the format used for the proto2 string type.
195func (p *Buffer) EncodeStringBytes(s string) error {
196 p.EncodeVarint(uint64(len(s)))
197 p.buf = append(p.buf, s...)
198 return nil
199}
200
201// Marshaler is the interface representing objects that can marshal themselves.
202type Marshaler interface {
203 Marshal() ([]byte, error)
204}
205
206// EncodeMessage writes the protocol buffer to the Buffer,
207// prefixed by a varint-encoded length.
208func (p *Buffer) EncodeMessage(pb Message) error {
209 siz := Size(pb)
210 p.EncodeVarint(uint64(siz))
211 return p.Marshal(pb)
212}
213
214// All protocol buffer fields are nillable, but be careful.
215func isNil(v reflect.Value) bool {
216 switch v.Kind() {
217 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
218 return v.IsNil()
219 }
220 return false
221}