blob: 9d592cd5e1e33a1ddd9b9aca87374d09087f0fa6 [file] [log] [blame]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001// Go support for Protocol Buffers - Google's data interchange format
2//
David Symondsee6e9c52012-11-29 08:51:07 +11003// Copyright 2010 The Go Authors. All rights reserved.
Rob Pikeaaa3a622010-03-20 22:32:34 -07004// http://code.google.com/p/goprotobuf/
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 (
Rob Pikea17fdd92011-11-02 12:43:05 -070039 "errors"
Rob Pikeaaa3a622010-03-20 22:32:34 -070040 "reflect"
David Symondsdf583ae2012-12-06 14:06:53 +110041 "sort"
Rob Pikeaaa3a622010-03-20 22:32:34 -070042)
43
44// ErrRequiredNotSet is the error returned if Marshal is called with
45// a protocol buffer struct whose required fields have not
Rob Pikec6d8e4a2010-07-28 15:34:32 -070046// 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.
David Symonds5b7775e2010-12-01 10:09:04 +110049type ErrRequiredNotSet struct {
50 t reflect.Type
51}
52
Rob Pikea17fdd92011-11-02 12:43:05 -070053func (e *ErrRequiredNotSet) Error() string {
David Symonds7656e742011-07-22 14:54:17 +100054 return "proto: required fields not set in " + e.t.String()
David Symonds5b7775e2010-12-01 10:09:04 +110055}
Rob Pikeaaa3a622010-03-20 22:32:34 -070056
David Symonds7656e742011-07-22 14:54:17 +100057var (
58 // ErrRepeatedHasNil is the error returned if Marshal is called with
59 // a struct with a repeated field containing a nil element.
David Symonds381349d2012-09-18 15:11:46 +100060 ErrRepeatedHasNil = errors.New("proto: repeated field has nil element")
Rob Pikeaaa3a622010-03-20 22:32:34 -070061
David Symonds7656e742011-07-22 14:54:17 +100062 // ErrNil is the error returned if Marshal is called with nil.
Rob Pikea17fdd92011-11-02 12:43:05 -070063 ErrNil = errors.New("proto: Marshal called with nil")
David Symonds7656e742011-07-22 14:54:17 +100064)
Rob Pikeaaa3a622010-03-20 22:32:34 -070065
66// The fundamental encoders that put bytes on the wire.
67// Those that take integer types all accept uint64 and are
68// therefore of type valueEncoder.
69
David Symonds4fee3b12010-11-11 10:00:13 +110070const maxVarintBytes = 10 // maximum length of a varint
71
Rob Pikeaaa3a622010-03-20 22:32:34 -070072// EncodeVarint returns the varint encoding of x.
73// This is the format for the
74// int32, int64, uint32, uint64, bool, and enum
75// protocol buffer types.
76// Not used by the package itself, but helpful to clients
77// wishing to use the same encoding.
78func EncodeVarint(x uint64) []byte {
David Symonds4fee3b12010-11-11 10:00:13 +110079 var buf [maxVarintBytes]byte
Rob Pikeaaa3a622010-03-20 22:32:34 -070080 var n int
81 for n = 0; x > 127; n++ {
82 buf[n] = 0x80 | uint8(x&0x7F)
83 x >>= 7
84 }
85 buf[n] = uint8(x)
86 n++
87 return buf[0:n]
88}
89
90// EncodeVarint writes a varint-encoded integer to the Buffer.
91// This is the format for the
92// int32, int64, uint32, uint64, bool, and enum
93// protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -070094func (p *Buffer) EncodeVarint(x uint64) error {
David Symonds4fee3b12010-11-11 10:00:13 +110095 for x >= 1<<7 {
David Symondsd9da6ba2011-08-30 14:41:30 +100096 p.buf = append(p.buf, uint8(x&0x7f|0x80))
Rob Pikeaaa3a622010-03-20 22:32:34 -070097 x >>= 7
98 }
David Symondsd9da6ba2011-08-30 14:41:30 +100099 p.buf = append(p.buf, uint8(x))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700100 return nil
101}
102
103// EncodeFixed64 writes a 64-bit integer to the Buffer.
104// This is the format for the
105// fixed64, sfixed64, and double protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700106func (p *Buffer) EncodeFixed64(x uint64) error {
David Symondsd9da6ba2011-08-30 14:41:30 +1000107 p.buf = append(p.buf,
108 uint8(x),
109 uint8(x>>8),
110 uint8(x>>16),
111 uint8(x>>24),
112 uint8(x>>32),
113 uint8(x>>40),
114 uint8(x>>48),
115 uint8(x>>56))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700116 return nil
117}
118
119// EncodeFixed32 writes a 32-bit integer to the Buffer.
120// This is the format for the
121// fixed32, sfixed32, and float protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700122func (p *Buffer) EncodeFixed32(x uint64) error {
David Symondsd9da6ba2011-08-30 14:41:30 +1000123 p.buf = append(p.buf,
124 uint8(x),
125 uint8(x>>8),
126 uint8(x>>16),
127 uint8(x>>24))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700128 return nil
129}
130
131// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
132// to the Buffer.
133// This is the format used for the sint64 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700134func (p *Buffer) EncodeZigzag64(x uint64) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700135 // use signed number to get arithmetic right shift.
136 return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
137}
138
139// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
140// to the Buffer.
141// This is the format used for the sint32 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700142func (p *Buffer) EncodeZigzag32(x uint64) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700143 // use signed number to get arithmetic right shift.
144 return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
145}
146
147// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
148// This is the format used for the bytes protocol buffer
149// type and for embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700150func (p *Buffer) EncodeRawBytes(b []byte) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700151 p.EncodeVarint(uint64(len(b)))
Rob Pike99fa2b62010-12-02 10:39:42 -0800152 p.buf = append(p.buf, b...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700153 return nil
154}
155
156// EncodeStringBytes writes an encoded string to the Buffer.
157// This is the format used for the proto2 string type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700158func (p *Buffer) EncodeStringBytes(s string) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700159 p.EncodeVarint(uint64(len(s)))
160 p.buf = append(p.buf, s...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700161 return nil
162}
163
164// Marshaler is the interface representing objects that can marshal themselves.
165type Marshaler interface {
Rob Pikea17fdd92011-11-02 12:43:05 -0700166 Marshal() ([]byte, error)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700167}
168
David Symonds9f60f432012-06-14 09:45:25 +1000169// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700170// and encodes it into the wire format, returning the data.
David Symonds9f60f432012-06-14 09:45:25 +1000171func Marshal(pb Message) ([]byte, error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700172 // Can the object marshal itself?
173 if m, ok := pb.(Marshaler); ok {
174 return m.Marshal()
175 }
176 p := NewBuffer(nil)
177 err := p.Marshal(pb)
178 if err != nil {
179 return nil, err
180 }
181 return p.buf, err
182}
183
David Symonds9f60f432012-06-14 09:45:25 +1000184// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700185// and encodes it into the wire format, writing the result to the
186// Buffer.
David Symonds9f60f432012-06-14 09:45:25 +1000187func (p *Buffer) Marshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700188 // Can the object marshal itself?
189 if m, ok := pb.(Marshaler); ok {
190 data, err := m.Marshal()
191 if err != nil {
192 return err
193 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800194 p.buf = append(p.buf, data...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700195 return nil
196 }
197
Russ Coxd4ce3f12012-09-12 10:36:26 +1000198 t, base, err := getbase(pb)
199 if structPointer_IsNil(base) {
David Symondsd4661c52012-08-30 15:17:53 +1000200 return ErrNil
201 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700202 if err == nil {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000203 err = p.enc_struct(t.Elem(), GetProperties(t.Elem()), base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700204 }
205
David Symonds9f60f432012-06-14 09:45:25 +1000206 if collectStats {
207 stats.Encode++
208 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700209
210 return err
211}
212
213// Individual type encoders.
214
215// Encode a bool.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000216func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
217 v := *structPointer_Bool(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700218 if v == nil {
219 return ErrNil
220 }
Rob Pike0f42a272011-10-20 16:03:11 -0700221 x := 0
222 if *v {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700223 x = 1
224 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800225 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700226 p.valEnc(o, uint64(x))
227 return nil
228}
229
230// Encode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000231func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
232 v := structPointer_Word32(base, p.field)
233 if word32_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700234 return ErrNil
235 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000236 x := word32_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800237 o.buf = append(o.buf, p.tagcode...)
David Symondsc31645c2013-06-22 17:57:36 +1000238 p.valEnc(o, uint64(x))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700239 return nil
240}
241
242// Encode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000243func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
244 v := structPointer_Word64(base, p.field)
245 if word64_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700246 return ErrNil
247 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000248 x := word64_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800249 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000250 p.valEnc(o, x)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700251 return nil
252}
253
254// Encode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000255func (o *Buffer) enc_string(p *Properties, base structPointer) error {
256 v := *structPointer_String(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700257 if v == nil {
258 return ErrNil
259 }
260 x := *v
Rob Pike99fa2b62010-12-02 10:39:42 -0800261 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700262 o.EncodeStringBytes(x)
263 return nil
264}
265
Rob Pike97e934d2011-04-11 12:52:49 -0700266// All protocol buffer fields are nillable, but be careful.
267func isNil(v reflect.Value) bool {
268 switch v.Kind() {
David Symonds007ed9d2012-07-24 10:59:36 +1000269 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
Rob Pike97e934d2011-04-11 12:52:49 -0700270 return v.IsNil()
271 }
272 return false
273}
274
Rob Pikeaaa3a622010-03-20 22:32:34 -0700275// Encode a message struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000276func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
277 structp := structPointer_GetStructPointer(base, p.field)
278 if structPointer_IsNil(structp) {
David Symondsa80b2822012-03-14 14:31:25 +1100279 return ErrNil
280 }
281
Rob Pikeaaa3a622010-03-20 22:32:34 -0700282 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100283 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000284 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700285 data, err := m.Marshal()
286 if err != nil {
287 return err
288 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800289 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700290 o.EncodeRawBytes(data)
291 return nil
292 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700293
294 // need the length before we can write out the message itself,
295 // so marshal into a separate byte buffer first.
296 obuf := o.buf
297 o.buf = o.bufalloc()
298
Russ Coxd4ce3f12012-09-12 10:36:26 +1000299 err := o.enc_struct(p.stype, p.sprop, structp)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700300
301 nbuf := o.buf
302 o.buf = obuf
303 if err != nil {
304 o.buffree(nbuf)
305 return err
306 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800307 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700308 o.EncodeRawBytes(nbuf)
309 o.buffree(nbuf)
310 return nil
311}
312
313// Encode a group struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000314func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
315 b := structPointer_GetStructPointer(base, p.field)
316 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700317 return ErrNil
318 }
319
320 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symonds6a6f82c2012-08-22 09:18:54 +1000321 err := o.enc_struct(p.stype, p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700322 if err != nil {
323 return err
324 }
325 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
326 return nil
327}
328
329// Encode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000330func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
331 s := *structPointer_BoolSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700332 l := len(s)
333 if l == 0 {
334 return ErrNil
335 }
336 for _, x := range s {
Rob Pike99fa2b62010-12-02 10:39:42 -0800337 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000338 v := uint64(0)
339 if x {
340 v = 1
Rob Pikeaaa3a622010-03-20 22:32:34 -0700341 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000342 p.valEnc(o, v)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700343 }
344 return nil
345}
346
David Symonds5b7775e2010-12-01 10:09:04 +1100347// Encode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000348func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
349 s := *structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100350 l := len(s)
351 if l == 0 {
352 return ErrNil
353 }
354 o.buf = append(o.buf, p.tagcode...)
355 o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
356 for _, x := range s {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000357 v := uint64(0)
358 if x {
359 v = 1
David Symonds5b7775e2010-12-01 10:09:04 +1100360 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000361 p.valEnc(o, v)
David Symonds5b7775e2010-12-01 10:09:04 +1100362 }
363 return nil
364}
365
Rob Pikeaaa3a622010-03-20 22:32:34 -0700366// Encode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000367func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
368 s := *structPointer_Bytes(base, p.field)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800369 if s == nil {
370 return ErrNil
371 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800372 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700373 o.EncodeRawBytes(s)
374 return nil
375}
376
377// Encode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000378func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
379 s := structPointer_Word32Slice(base, p.field)
380 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700381 if l == 0 {
382 return ErrNil
383 }
384 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800385 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000386 x := s.Index(i)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700387 p.valEnc(o, uint64(x))
388 }
389 return nil
390}
391
David Symonds5b7775e2010-12-01 10:09:04 +1100392// Encode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000393func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
394 s := structPointer_Word32Slice(base, p.field)
395 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100396 if l == 0 {
397 return ErrNil
398 }
399 // TODO: Reuse a Buffer.
400 buf := NewBuffer(nil)
401 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000402 p.valEnc(buf, uint64(s.Index(i)))
David Symonds5b7775e2010-12-01 10:09:04 +1100403 }
404
405 o.buf = append(o.buf, p.tagcode...)
406 o.EncodeVarint(uint64(len(buf.buf)))
407 o.buf = append(o.buf, buf.buf...)
408 return nil
409}
410
Rob Pikeaaa3a622010-03-20 22:32:34 -0700411// Encode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000412func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
413 s := structPointer_Word64Slice(base, p.field)
414 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700415 if l == 0 {
416 return ErrNil
417 }
418 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800419 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000420 p.valEnc(o, s.Index(i))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700421 }
422 return nil
423}
424
David Symonds5b7775e2010-12-01 10:09:04 +1100425// Encode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000426func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
427 s := structPointer_Word64Slice(base, p.field)
428 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100429 if l == 0 {
430 return ErrNil
431 }
432 // TODO: Reuse a Buffer.
433 buf := NewBuffer(nil)
434 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000435 p.valEnc(buf, s.Index(i))
David Symonds5b7775e2010-12-01 10:09:04 +1100436 }
437
438 o.buf = append(o.buf, p.tagcode...)
439 o.EncodeVarint(uint64(len(buf.buf)))
440 o.buf = append(o.buf, buf.buf...)
441 return nil
442}
443
Rob Pikeaaa3a622010-03-20 22:32:34 -0700444// Encode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000445func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
446 ss := *structPointer_BytesSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700447 l := len(ss)
448 if l == 0 {
449 return ErrNil
450 }
451 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800452 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700453 s := ss[i]
454 o.EncodeRawBytes(s)
455 }
456 return nil
457}
458
459// Encode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000460func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
461 ss := *structPointer_StringSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700462 l := len(ss)
463 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800464 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700465 s := ss[i]
466 o.EncodeStringBytes(s)
467 }
468 return nil
469}
470
471// Encode a slice of message structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000472func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
473 s := structPointer_StructPointerSlice(base, p.field)
474 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700475
476 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000477 structp := s.Index(i)
478 if structPointer_IsNil(structp) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700479 return ErrRepeatedHasNil
480 }
481
482 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100483 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000484 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700485 data, err := m.Marshal()
486 if err != nil {
487 return err
488 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800489 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700490 o.EncodeRawBytes(data)
491 continue
492 }
493
494 obuf := o.buf
495 o.buf = o.bufalloc()
496
Russ Coxd4ce3f12012-09-12 10:36:26 +1000497 err := o.enc_struct(p.stype, p.sprop, structp)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700498
499 nbuf := o.buf
500 o.buf = obuf
501 if err != nil {
502 o.buffree(nbuf)
503 if err == ErrNil {
504 return ErrRepeatedHasNil
505 }
506 return err
507 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800508 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700509 o.EncodeRawBytes(nbuf)
510
511 o.buffree(nbuf)
512 }
513 return nil
514}
515
516// Encode a slice of group structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000517func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
518 s := structPointer_StructPointerSlice(base, p.field)
519 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700520
521 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000522 b := s.Index(i)
523 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700524 return ErrRepeatedHasNil
525 }
526
527 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
528
David Symonds6a6f82c2012-08-22 09:18:54 +1000529 err := o.enc_struct(p.stype, p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700530
531 if err != nil {
532 if err == ErrNil {
533 return ErrRepeatedHasNil
534 }
535 return err
536 }
537
538 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
539 }
540 return nil
541}
542
543// Encode an extension map.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000544func (o *Buffer) enc_map(p *Properties, base structPointer) error {
545 v := *structPointer_ExtMap(base, p.field)
David Symonds1d72f7a2011-08-19 18:28:52 +1000546 if err := encodeExtensionMap(v); err != nil {
547 return err
548 }
David Symondsdf583ae2012-12-06 14:06:53 +1100549 // Fast-path for common cases: zero or one extensions.
550 if len(v) <= 1 {
551 for _, e := range v {
552 o.buf = append(o.buf, e.enc...)
553 }
554 return nil
555 }
556
557 // Sort keys to provide a deterministic encoding.
558 keys := make([]int, 0, len(v))
559 for k := range v {
560 keys = append(keys, int(k))
561 }
562 sort.Ints(keys)
563
564 for _, k := range keys {
565 o.buf = append(o.buf, v[int32(k)].enc...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700566 }
567 return nil
568}
569
570// Encode a struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000571func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700572 required := prop.reqCount
David Symondsd15e81b2011-10-03 14:31:12 -0700573 // Encode fields in tag order so that decoders may use optimizations
574 // that depend on the ordering.
575 // http://code.google.com/apis/protocolbuffers/docs/encoding.html#order
576 for _, i := range prop.order {
577 p := prop.Prop[i]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700578 if p.enc != nil {
579 err := p.enc(o, p, base)
580 if err != nil {
581 if err != ErrNil {
582 return err
583 }
584 } else if p.Required {
585 required--
586 }
587 }
588 }
589 // See if we encoded all required fields.
590 if required > 0 {
David Symonds5b7775e2010-12-01 10:09:04 +1100591 return &ErrRequiredNotSet{t}
Rob Pikeaaa3a622010-03-20 22:32:34 -0700592 }
593
David Symonds10c93ba2012-08-04 16:38:08 +1000594 // Add unrecognized fields at the end.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000595 if prop.unrecField.IsValid() {
596 v := *structPointer_Bytes(base, prop.unrecField)
597 if len(v) > 0 {
598 o.buf = append(o.buf, v...)
599 }
David Symonds10c93ba2012-08-04 16:38:08 +1000600 }
601
Rob Pikeaaa3a622010-03-20 22:32:34 -0700602 return nil
603}