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