blob: 9f2eb0f59ce5735ec24ca1de1df90ff8cc5820ee [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 decoding protocol buffer data to construct in-memory representations.
36 */
37
38import (
Rob Pikea17fdd92011-11-02 12:43:05 -070039 "errors"
Rob Pikeaaa3a622010-03-20 22:32:34 -070040 "fmt"
41 "io"
42 "os"
43 "reflect"
Rob Pikeaaa3a622010-03-20 22:32:34 -070044)
45
46// ErrWrongType occurs when the wire encoding for the field disagrees with
47// that specified in the type being decoded. This is usually caused by attempting
48// to convert an encoded protocol buffer into a struct of the wrong type.
Rob Pikea17fdd92011-11-02 12:43:05 -070049var ErrWrongType = errors.New("field/encoding mismatch: wrong type for field")
Rob Pikeaaa3a622010-03-20 22:32:34 -070050
51// The fundamental decoders that interpret bytes on the wire.
52// Those that take integer types all return uint64 and are
53// therefore of type valueDecoder.
54
55// DecodeVarint reads a varint-encoded integer from the slice.
56// It returns the integer and the number of bytes consumed, or
57// zero if there is not enough.
58// This is the format for the
59// int32, int64, uint32, uint64, bool, and enum
60// protocol buffer types.
61func DecodeVarint(buf []byte) (x uint64, n int) {
62 // x, n already 0
63 for shift := uint(0); ; shift += 7 {
64 if n >= len(buf) {
65 return 0, 0
66 }
67 b := uint64(buf[n])
68 n++
69 x |= (b & 0x7F) << shift
70 if (b & 0x80) == 0 {
71 break
72 }
73 }
74 return x, n
75}
76
77// DecodeVarint reads a varint-encoded integer from the Buffer.
78// This is the format for the
79// int32, int64, uint32, uint64, bool, and enum
80// protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -070081func (p *Buffer) DecodeVarint() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -070082 // x, err already 0
83
84 i := p.index
85 l := len(p.buf)
86
87 for shift := uint(0); ; shift += 7 {
88 if i >= l {
89 err = io.ErrUnexpectedEOF
90 return
91 }
92 b := p.buf[i]
93 i++
94 x |= (uint64(b) & 0x7F) << shift
95 if b < 0x80 {
96 break
97 }
98 }
99 p.index = i
100 return
101}
102
103// DecodeFixed64 reads a 64-bit integer from 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) DecodeFixed64() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700107 // x, err already 0
108 i := p.index + 8
109 if i > len(p.buf) {
110 err = io.ErrUnexpectedEOF
111 return
112 }
113 p.index = i
114
115 x = uint64(p.buf[i-8])
116 x |= uint64(p.buf[i-7]) << 8
117 x |= uint64(p.buf[i-6]) << 16
118 x |= uint64(p.buf[i-5]) << 24
119 x |= uint64(p.buf[i-4]) << 32
120 x |= uint64(p.buf[i-3]) << 40
121 x |= uint64(p.buf[i-2]) << 48
122 x |= uint64(p.buf[i-1]) << 56
123 return
124}
125
126// DecodeFixed32 reads a 32-bit integer from the Buffer.
127// This is the format for the
128// fixed32, sfixed32, and float protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700129func (p *Buffer) DecodeFixed32() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700130 // x, err already 0
131 i := p.index + 4
132 if i > len(p.buf) {
133 err = io.ErrUnexpectedEOF
134 return
135 }
136 p.index = i
137
138 x = uint64(p.buf[i-4])
139 x |= uint64(p.buf[i-3]) << 8
140 x |= uint64(p.buf[i-2]) << 16
141 x |= uint64(p.buf[i-1]) << 24
142 return
143}
144
145// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
146// from the Buffer.
147// This is the format used for the sint64 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700148func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700149 x, err = p.DecodeVarint()
150 if err != nil {
151 return
152 }
153 x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
154 return
155}
156
157// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
158// from the Buffer.
159// This is the format used for the sint32 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700160func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700161 x, err = p.DecodeVarint()
162 if err != nil {
163 return
164 }
165 x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
166 return
167}
168
169// These are not ValueDecoders: they produce an array of bytes or a string.
170// bytes, embedded messages
171
172// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
173// This is the format used for the bytes protocol buffer
174// type and for embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700175func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700176 n, err := p.DecodeVarint()
177 if err != nil {
178 return
179 }
180
181 nb := int(n)
David Symonds22ac1502012-01-18 12:37:12 +1100182 if nb < 0 {
183 return nil, fmt.Errorf("proto: bad byte length %d", nb)
184 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700185 if p.index+nb > len(p.buf) {
David Symonds22ac1502012-01-18 12:37:12 +1100186 return nil, io.ErrUnexpectedEOF
Rob Pikeaaa3a622010-03-20 22:32:34 -0700187 }
188
189 if !alloc {
190 // todo: check if can get more uses of alloc=false
191 buf = p.buf[p.index : p.index+nb]
192 p.index += nb
193 return
194 }
195
196 buf = make([]byte, nb)
197 copy(buf, p.buf[p.index:])
198 p.index += nb
199 return
200}
201
202// DecodeStringBytes reads an encoded string from the Buffer.
203// This is the format used for the proto2 string type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700204func (p *Buffer) DecodeStringBytes() (s string, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700205 buf, err := p.DecodeRawBytes(false)
206 if err != nil {
207 return
208 }
209 return string(buf), nil
210}
211
212// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
213// If the protocol buffer has extensions, and the field matches, add it as an extension.
214// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000215func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700216
217 oi := o.index
218
219 err := o.skip(t, tag, wire)
220 if err != nil {
221 return err
222 }
223
Russ Coxd4ce3f12012-09-12 10:36:26 +1000224 if !unrecField.IsValid() {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700225 return nil
226 }
227
Russ Coxd4ce3f12012-09-12 10:36:26 +1000228 ptr := structPointer_Bytes(base, unrecField)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700229
230 if *ptr == nil {
231 // This is the first skipped element,
232 // allocate a new buffer.
233 *ptr = o.bufalloc()
234 }
235
236 // Add the skipped field to struct field
237 obuf := o.buf
238
239 o.buf = *ptr
240 o.EncodeVarint(uint64(tag<<3 | wire))
Rob Pike99fa2b62010-12-02 10:39:42 -0800241 *ptr = append(o.buf, obuf[oi:o.index]...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700242
243 o.buf = obuf
244
245 return nil
246}
247
248// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
Rob Pikea17fdd92011-11-02 12:43:05 -0700249func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700250
251 var u uint64
Rob Pikea17fdd92011-11-02 12:43:05 -0700252 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700253
254 switch wire {
255 case WireVarint:
256 _, err = o.DecodeVarint()
257 case WireFixed64:
258 _, err = o.DecodeFixed64()
259 case WireBytes:
260 _, err = o.DecodeRawBytes(false)
261 case WireFixed32:
262 _, err = o.DecodeFixed32()
263 case WireStartGroup:
264 for {
265 u, err = o.DecodeVarint()
266 if err != nil {
267 break
268 }
269 fwire := int(u & 0x7)
270 if fwire == WireEndGroup {
271 break
272 }
273 ftag := int(u >> 3)
274 err = o.skip(t, ftag, fwire)
275 if err != nil {
276 break
277 }
278 }
279 default:
David Symonds22ac1502012-01-18 12:37:12 +1100280 err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700281 }
282 return err
283}
284
David Symonds7d3c6802012-11-08 08:20:18 +1100285// Unmarshaler is the interface representing objects that can
286// unmarshal themselves. The method should reset the receiver before
287// decoding starts. The argument points to data that may be
288// overwritten, so implementations should not keep references to the
289// buffer.
Rob Pikeaaa3a622010-03-20 22:32:34 -0700290type Unmarshaler interface {
Rob Pikea17fdd92011-11-02 12:43:05 -0700291 Unmarshal([]byte) error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700292}
293
294// Unmarshal parses the protocol buffer representation in buf and places the
295// decoded result in pb. If the struct underlying pb does not match
296// the data in buf, the results can be unpredictable.
David Symonds19285602012-07-02 16:04:28 -0700297//
David Symonds525838c2012-07-20 15:42:49 +1000298// Unmarshal resets pb before starting to unmarshal, so any
David Symondsd4b52d02013-01-15 14:30:26 +1100299// existing data in pb is always removed. Use UnmarshalMerge
David Symonds525838c2012-07-20 15:42:49 +1000300// to preserve and append to existing data.
David Symonds9f60f432012-06-14 09:45:25 +1000301func Unmarshal(buf []byte, pb Message) error {
David Symonds525838c2012-07-20 15:42:49 +1000302 pb.Reset()
David Symondsd4b52d02013-01-15 14:30:26 +1100303 return UnmarshalMerge(buf, pb)
David Symonds19285602012-07-02 16:04:28 -0700304}
305
David Symondsd4b52d02013-01-15 14:30:26 +1100306// UnmarshalMerge parses the protocol buffer representation in buf and
David Symonds19285602012-07-02 16:04:28 -0700307// writes the decoded result to pb. If the struct underlying pb does not match
308// the data in buf, the results can be unpredictable.
309//
David Symondsd4b52d02013-01-15 14:30:26 +1100310// UnmarshalMerge merges into existing data in pb.
David Symonds525838c2012-07-20 15:42:49 +1000311// Most code should use Unmarshal instead.
David Symondsd4b52d02013-01-15 14:30:26 +1100312func UnmarshalMerge(buf []byte, pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700313 // If the object can unmarshal itself, let it.
314 if u, ok := pb.(Unmarshaler); ok {
315 return u.Unmarshal(buf)
316 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700317 return NewBuffer(buf).Unmarshal(pb)
318}
319
320// Unmarshal parses the protocol buffer representation in the
321// Buffer and places the decoded result in pb. If the struct
322// underlying pb does not match the data in the buffer, the results can be
323// unpredictable.
David Symonds9f60f432012-06-14 09:45:25 +1000324func (p *Buffer) Unmarshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700325 // If the object can unmarshal itself, let it.
326 if u, ok := pb.(Unmarshaler); ok {
327 err := u.Unmarshal(p.buf[p.index:])
328 p.index = len(p.buf)
329 return err
330 }
331
Rob Pikeaaa3a622010-03-20 22:32:34 -0700332 typ, base, err := getbase(pb)
333 if err != nil {
334 return err
335 }
336
David Symonds6a6f82c2012-08-22 09:18:54 +1000337 err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700338
David Symonds9f60f432012-06-14 09:45:25 +1000339 if collectStats {
340 stats.Decode++
341 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700342
343 return err
344}
345
346// unmarshalType does the work of unmarshaling a structure.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000347func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700348 required, reqFields := prop.reqCount, uint64(0)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700349
Rob Pikea17fdd92011-11-02 12:43:05 -0700350 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700351 for err == nil && o.index < len(o.buf) {
352 oi := o.index
353 var u uint64
354 u, err = o.DecodeVarint()
355 if err != nil {
356 break
357 }
358 wire := int(u & 0x7)
359 if wire == WireEndGroup {
360 if is_group {
361 return nil // input is satisfied
362 }
363 return ErrWrongType
364 }
365 tag := int(u >> 3)
David Symonds6e50db52012-02-11 15:56:22 +1100366 if tag <= 0 {
367 return fmt.Errorf("proto: illegal tag %d", tag)
368 }
David Symonds2bba1b22012-09-26 14:53:08 +1000369 fieldnum, ok := prop.decoderTags.get(tag)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700370 if !ok {
371 // Maybe it's an extension?
Russ Coxd4ce3f12012-09-12 10:36:26 +1000372 if prop.extendable {
373 if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
374 if err = o.skip(st, tag, wire); err == nil {
375 ext := e.ExtensionMap()[int32(tag)] // may be missing
376 ext.enc = append(ext.enc, o.buf[oi:o.index]...)
377 e.ExtensionMap()[int32(tag)] = ext
378 }
379 continue
Rob Pikeaaa3a622010-03-20 22:32:34 -0700380 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700381 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000382 err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700383 continue
384 }
385 p := prop.Prop[fieldnum]
386
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700387 if p.dec == nil {
David Symonds6a6f82c2012-08-22 09:18:54 +1000388 fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700389 continue
390 }
David Symonds5b7775e2010-12-01 10:09:04 +1100391 dec := p.dec
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700392 if wire != WireStartGroup && wire != p.WireType {
David Symonds5b7775e2010-12-01 10:09:04 +1100393 if wire == WireBytes && p.packedDec != nil {
394 // a packable field
395 dec = p.packedDec
396 } else {
397 err = ErrWrongType
398 continue
399 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700400 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700401 err = dec(o, p, base)
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700402 if err == nil && p.Required {
403 // Successfully decoded a required field.
404 if tag <= 64 {
405 // use bitmap for fields 1-64 to catch field reuse.
406 var mask uint64 = 1 << uint64(tag-1)
407 if reqFields&mask == 0 {
408 // new required field
409 reqFields |= mask
410 required--
411 }
412 } else {
413 // This is imprecise. It can be fooled by a required field
414 // with a tag > 64 that is encoded twice; that's very rare.
415 // A fully correct implementation would require allocating
416 // a data structure, which we would like to avoid.
417 required--
418 }
419 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700420 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700421 if err == nil {
422 if is_group {
423 return io.ErrUnexpectedEOF
424 }
425 if required > 0 {
David Symonds5b7775e2010-12-01 10:09:04 +1100426 return &ErrRequiredNotSet{st}
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700427 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700428 }
429 return err
430}
431
Rob Pikeaaa3a622010-03-20 22:32:34 -0700432// Individual type decoders
433// For each,
434// u is the decoded value,
435// v is a pointer to the field (pointer) in the struct
Rob Pike76f6ee52011-10-20 12:58:28 -0700436
437// Sizes of the pools to allocate inside the Buffer.
Rob Pike97edc7e2011-10-20 15:53:19 -0700438// The goal is modest amortization and allocation
439// on at least 16-byte boundaries.
Rob Pike76f6ee52011-10-20 12:58:28 -0700440const (
Russ Coxd4ce3f12012-09-12 10:36:26 +1000441 boolPoolSize = 16
442 uint32PoolSize = 8
443 uint64PoolSize = 4
Rob Pike76f6ee52011-10-20 12:58:28 -0700444)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700445
446// Decode a bool.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000447func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700448 u, err := p.valDec(o)
449 if err != nil {
450 return err
451 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700452 if len(o.bools) == 0 {
453 o.bools = make([]bool, boolPoolSize)
454 }
455 o.bools[0] = u != 0
Russ Coxd4ce3f12012-09-12 10:36:26 +1000456 *structPointer_Bool(base, p.field) = &o.bools[0]
Rob Pike76f6ee52011-10-20 12:58:28 -0700457 o.bools = o.bools[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700458 return nil
459}
460
461// Decode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000462func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700463 u, err := p.valDec(o)
464 if err != nil {
465 return err
466 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000467 word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700468 return nil
469}
470
471// Decode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000472func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700473 u, err := p.valDec(o)
474 if err != nil {
475 return err
476 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000477 word64_Set(structPointer_Word64(base, p.field), o, u)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700478 return nil
479}
480
481// Decode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000482func (o *Buffer) dec_string(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700483 s, err := o.DecodeStringBytes()
484 if err != nil {
485 return err
486 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700487 sp := new(string)
488 *sp = s
Russ Coxd4ce3f12012-09-12 10:36:26 +1000489 *structPointer_String(base, p.field) = sp
Rob Pikeaaa3a622010-03-20 22:32:34 -0700490 return nil
491}
492
493// Decode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000494func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700495 b, err := o.DecodeRawBytes(true)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700496 if err != nil {
497 return err
498 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000499 *structPointer_Bytes(base, p.field) = b
Rob Pikeaaa3a622010-03-20 22:32:34 -0700500 return nil
501}
502
503// Decode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000504func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700505 u, err := p.valDec(o)
506 if err != nil {
507 return err
508 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000509 v := structPointer_BoolSlice(base, p.field)
Rob Pike76f6ee52011-10-20 12:58:28 -0700510 *v = append(*v, u != 0)
David Symonds5b7775e2010-12-01 10:09:04 +1100511 return nil
512}
513
514// Decode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000515func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
516 v := structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100517
518 nn, err := o.DecodeVarint()
519 if err != nil {
520 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700521 }
David Symonds5b7775e2010-12-01 10:09:04 +1100522 nb := int(nn) // number of bytes of encoded bools
523
Rob Pike76f6ee52011-10-20 12:58:28 -0700524 y := *v
David Symonds5b7775e2010-12-01 10:09:04 +1100525 for i := 0; i < nb; i++ {
526 u, err := p.valDec(o)
527 if err != nil {
528 return err
529 }
530 y = append(y, u != 0)
531 }
532
Rob Pike76f6ee52011-10-20 12:58:28 -0700533 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700534 return nil
535}
536
537// Decode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000538func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700539 u, err := p.valDec(o)
540 if err != nil {
541 return err
542 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000543 structPointer_Word32Slice(base, p.field).Append(uint32(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100544 return nil
545}
546
547// Decode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000548func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
549 v := structPointer_Word32Slice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100550
551 nn, err := o.DecodeVarint()
552 if err != nil {
553 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700554 }
David Symonds5b7775e2010-12-01 10:09:04 +1100555 nb := int(nn) // number of bytes of encoded int32s
556
David Symonds5b7775e2010-12-01 10:09:04 +1100557 fin := o.index + nb
558 for o.index < fin {
559 u, err := p.valDec(o)
560 if err != nil {
561 return err
562 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000563 v.Append(uint32(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100564 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700565 return nil
566}
567
568// Decode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000569func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700570 u, err := p.valDec(o)
571 if err != nil {
572 return err
573 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700574
Russ Coxd4ce3f12012-09-12 10:36:26 +1000575 structPointer_Word64Slice(base, p.field).Append(u)
David Symonds5b7775e2010-12-01 10:09:04 +1100576 return nil
577}
578
579// Decode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000580func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
581 v := structPointer_Word64Slice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100582
583 nn, err := o.DecodeVarint()
584 if err != nil {
585 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700586 }
David Symonds5b7775e2010-12-01 10:09:04 +1100587 nb := int(nn) // number of bytes of encoded int64s
588
David Symonds5b7775e2010-12-01 10:09:04 +1100589 fin := o.index + nb
590 for o.index < fin {
591 u, err := p.valDec(o)
592 if err != nil {
593 return err
594 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000595 v.Append(u)
David Symonds5b7775e2010-12-01 10:09:04 +1100596 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700597 return nil
598}
599
600// Decode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000601func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700602 s, err := o.DecodeStringBytes()
603 if err != nil {
604 return err
605 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000606 v := structPointer_StringSlice(base, p.field)
607 *v = append(*v, s)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700608 return nil
609}
610
611// Decode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000612func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700613 b, err := o.DecodeRawBytes(true)
614 if err != nil {
615 return err
616 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000617 v := structPointer_BytesSlice(base, p.field)
618 *v = append(*v, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700619 return nil
620}
621
622// Decode a group.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000623func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
624 bas := toStructPointer(reflect.New(p.stype))
625 structPointer_SetStructPointer(base, p.field, bas)
626 return o.unmarshalType(p.stype, p.sprop, true, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700627}
628
629// Decode an embedded message.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000630func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700631 raw, e := o.DecodeRawBytes(false)
632 if e != nil {
633 return e
634 }
635
Russ Coxd4ce3f12012-09-12 10:36:26 +1000636 v := reflect.New(p.stype)
637 bas := toStructPointer(v)
638 structPointer_SetStructPointer(base, p.field, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700639
640 // If the object can unmarshal itself, let it.
David Symondsa80b2822012-03-14 14:31:25 +1100641 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000642 iv := v.Interface()
David Symondsa80b2822012-03-14 14:31:25 +1100643 return iv.(Unmarshaler).Unmarshal(raw)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700644 }
645
646 obuf := o.buf
647 oi := o.index
648 o.buf = raw
649 o.index = 0
650
David Symondsc0287172012-08-15 11:10:30 +1000651 err = o.unmarshalType(p.stype, p.sprop, false, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700652 o.buf = obuf
653 o.index = oi
654
655 return err
656}
657
658// Decode a slice of embedded messages.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000659func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700660 return o.dec_slice_struct(p, false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700661}
662
663// Decode a slice of embedded groups.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000664func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700665 return o.dec_slice_struct(p, true, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700666}
667
668// Decode a slice of structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000669func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
670 v := reflect.New(p.stype)
671 bas := toStructPointer(v)
672 structPointer_StructPointerSlice(base, p.field).Append(bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700673
674 if is_group {
David Symondsc0287172012-08-15 11:10:30 +1000675 err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700676 return err
677 }
678
David Symondsc0287172012-08-15 11:10:30 +1000679 raw, err := o.DecodeRawBytes(false)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700680 if err != nil {
681 return err
682 }
683
684 // If the object can unmarshal itself, let it.
David Symondsa80b2822012-03-14 14:31:25 +1100685 if p.isUnmarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000686 iv := v.Interface()
David Symondsa80b2822012-03-14 14:31:25 +1100687 return iv.(Unmarshaler).Unmarshal(raw)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700688 }
689
690 obuf := o.buf
691 oi := o.index
692 o.buf = raw
693 o.index = 0
694
David Symondsc0287172012-08-15 11:10:30 +1000695 err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700696
697 o.buf = obuf
698 o.index = oi
699
700 return err
701}