blob: 6281da3005921baeedf58fa20d61ebd34d0014da [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.
David Symondsa7f3a0f2013-09-09 13:32:33 +100049var ErrWrongType = errors.New("proto: field/encoding mismatch: wrong type for field")
Rob Pikeaaa3a622010-03-20 22:32:34 -070050
Adam Langley28c83cb2013-07-13 14:54:54 +100051// errOverflow is returned when an integer is too large to be represented.
52var errOverflow = errors.New("proto: integer overflow")
53
Rob Pikeaaa3a622010-03-20 22:32:34 -070054// The fundamental decoders that interpret bytes on the wire.
55// Those that take integer types all return uint64 and are
56// therefore of type valueDecoder.
57
58// DecodeVarint reads a varint-encoded integer from the slice.
59// It returns the integer and the number of bytes consumed, or
60// zero if there is not enough.
61// This is the format for the
62// int32, int64, uint32, uint64, bool, and enum
63// protocol buffer types.
64func DecodeVarint(buf []byte) (x uint64, n int) {
65 // x, n already 0
Adam Langley28c83cb2013-07-13 14:54:54 +100066 for shift := uint(0); shift < 64; shift += 7 {
Rob Pikeaaa3a622010-03-20 22:32:34 -070067 if n >= len(buf) {
68 return 0, 0
69 }
70 b := uint64(buf[n])
71 n++
72 x |= (b & 0x7F) << shift
73 if (b & 0x80) == 0 {
Adam Langley28c83cb2013-07-13 14:54:54 +100074 return x, n
Rob Pikeaaa3a622010-03-20 22:32:34 -070075 }
76 }
Adam Langley28c83cb2013-07-13 14:54:54 +100077
78 // The number is too large to represent in a 64-bit value.
79 return 0, 0
Rob Pikeaaa3a622010-03-20 22:32:34 -070080}
81
82// DecodeVarint reads a varint-encoded integer from the Buffer.
83// This is the format for the
84// int32, int64, uint32, uint64, bool, and enum
85// protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -070086func (p *Buffer) DecodeVarint() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -070087 // x, err already 0
88
89 i := p.index
90 l := len(p.buf)
91
Adam Langley28c83cb2013-07-13 14:54:54 +100092 for shift := uint(0); shift < 64; shift += 7 {
Rob Pikeaaa3a622010-03-20 22:32:34 -070093 if i >= l {
94 err = io.ErrUnexpectedEOF
95 return
96 }
97 b := p.buf[i]
98 i++
99 x |= (uint64(b) & 0x7F) << shift
100 if b < 0x80 {
Adam Langley28c83cb2013-07-13 14:54:54 +1000101 p.index = i
102 return
Rob Pikeaaa3a622010-03-20 22:32:34 -0700103 }
104 }
Adam Langley28c83cb2013-07-13 14:54:54 +1000105
106 // The number is too large to represent in a 64-bit value.
107 err = errOverflow
Rob Pikeaaa3a622010-03-20 22:32:34 -0700108 return
109}
110
111// DecodeFixed64 reads a 64-bit integer from the Buffer.
112// This is the format for the
113// fixed64, sfixed64, and double protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700114func (p *Buffer) DecodeFixed64() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700115 // x, err already 0
116 i := p.index + 8
Adam Langley28c83cb2013-07-13 14:54:54 +1000117 if i < 0 || i > len(p.buf) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700118 err = io.ErrUnexpectedEOF
119 return
120 }
121 p.index = i
122
123 x = uint64(p.buf[i-8])
124 x |= uint64(p.buf[i-7]) << 8
125 x |= uint64(p.buf[i-6]) << 16
126 x |= uint64(p.buf[i-5]) << 24
127 x |= uint64(p.buf[i-4]) << 32
128 x |= uint64(p.buf[i-3]) << 40
129 x |= uint64(p.buf[i-2]) << 48
130 x |= uint64(p.buf[i-1]) << 56
131 return
132}
133
134// DecodeFixed32 reads a 32-bit integer from the Buffer.
135// This is the format for the
136// fixed32, sfixed32, and float protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700137func (p *Buffer) DecodeFixed32() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700138 // x, err already 0
139 i := p.index + 4
Adam Langley28c83cb2013-07-13 14:54:54 +1000140 if i < 0 || i > len(p.buf) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700141 err = io.ErrUnexpectedEOF
142 return
143 }
144 p.index = i
145
146 x = uint64(p.buf[i-4])
147 x |= uint64(p.buf[i-3]) << 8
148 x |= uint64(p.buf[i-2]) << 16
149 x |= uint64(p.buf[i-1]) << 24
150 return
151}
152
153// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
154// from the Buffer.
155// This is the format used for the sint64 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700156func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700157 x, err = p.DecodeVarint()
158 if err != nil {
159 return
160 }
161 x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
162 return
163}
164
165// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
166// from the Buffer.
167// This is the format used for the sint32 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700168func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700169 x, err = p.DecodeVarint()
170 if err != nil {
171 return
172 }
173 x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
174 return
175}
176
177// These are not ValueDecoders: they produce an array of bytes or a string.
178// bytes, embedded messages
179
180// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
181// This is the format used for the bytes protocol buffer
182// type and for embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700183func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700184 n, err := p.DecodeVarint()
185 if err != nil {
186 return
187 }
188
189 nb := int(n)
David Symonds22ac1502012-01-18 12:37:12 +1100190 if nb < 0 {
191 return nil, fmt.Errorf("proto: bad byte length %d", nb)
192 }
Adam Langley28c83cb2013-07-13 14:54:54 +1000193 end := p.index + nb
194 if end < p.index || end > len(p.buf) {
David Symonds22ac1502012-01-18 12:37:12 +1100195 return nil, io.ErrUnexpectedEOF
Rob Pikeaaa3a622010-03-20 22:32:34 -0700196 }
197
198 if !alloc {
199 // todo: check if can get more uses of alloc=false
Adam Langley28c83cb2013-07-13 14:54:54 +1000200 buf = p.buf[p.index:end]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700201 p.index += nb
202 return
203 }
204
205 buf = make([]byte, nb)
206 copy(buf, p.buf[p.index:])
207 p.index += nb
208 return
209}
210
211// DecodeStringBytes reads an encoded string from the Buffer.
212// This is the format used for the proto2 string type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700213func (p *Buffer) DecodeStringBytes() (s string, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700214 buf, err := p.DecodeRawBytes(false)
215 if err != nil {
216 return
217 }
218 return string(buf), nil
219}
220
221// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
222// If the protocol buffer has extensions, and the field matches, add it as an extension.
223// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000224func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700225 oi := o.index
226
227 err := o.skip(t, tag, wire)
228 if err != nil {
229 return err
230 }
231
Russ Coxd4ce3f12012-09-12 10:36:26 +1000232 if !unrecField.IsValid() {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700233 return nil
234 }
235
Russ Coxd4ce3f12012-09-12 10:36:26 +1000236 ptr := structPointer_Bytes(base, unrecField)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700237
Rob Pikeaaa3a622010-03-20 22:32:34 -0700238 // Add the skipped field to struct field
239 obuf := o.buf
240
241 o.buf = *ptr
242 o.EncodeVarint(uint64(tag<<3 | wire))
Rob Pike99fa2b62010-12-02 10:39:42 -0800243 *ptr = append(o.buf, obuf[oi:o.index]...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700244
245 o.buf = obuf
246
247 return nil
248}
249
250// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
Rob Pikea17fdd92011-11-02 12:43:05 -0700251func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700252
253 var u uint64
Rob Pikea17fdd92011-11-02 12:43:05 -0700254 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700255
256 switch wire {
257 case WireVarint:
258 _, err = o.DecodeVarint()
259 case WireFixed64:
260 _, err = o.DecodeFixed64()
261 case WireBytes:
262 _, err = o.DecodeRawBytes(false)
263 case WireFixed32:
264 _, err = o.DecodeFixed32()
265 case WireStartGroup:
266 for {
267 u, err = o.DecodeVarint()
268 if err != nil {
269 break
270 }
271 fwire := int(u & 0x7)
272 if fwire == WireEndGroup {
273 break
274 }
275 ftag := int(u >> 3)
276 err = o.skip(t, ftag, fwire)
277 if err != nil {
278 break
279 }
280 }
281 default:
David Symonds22ac1502012-01-18 12:37:12 +1100282 err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700283 }
284 return err
285}
286
David Symonds7d3c6802012-11-08 08:20:18 +1100287// Unmarshaler is the interface representing objects that can
288// unmarshal themselves. The method should reset the receiver before
289// decoding starts. The argument points to data that may be
290// overwritten, so implementations should not keep references to the
291// buffer.
Rob Pikeaaa3a622010-03-20 22:32:34 -0700292type Unmarshaler interface {
Rob Pikea17fdd92011-11-02 12:43:05 -0700293 Unmarshal([]byte) error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700294}
295
296// Unmarshal parses the protocol buffer representation in buf and places the
297// decoded result in pb. If the struct underlying pb does not match
298// the data in buf, the results can be unpredictable.
David Symonds19285602012-07-02 16:04:28 -0700299//
David Symonds525838c2012-07-20 15:42:49 +1000300// Unmarshal resets pb before starting to unmarshal, so any
David Symondsd4b52d02013-01-15 14:30:26 +1100301// existing data in pb is always removed. Use UnmarshalMerge
David Symonds525838c2012-07-20 15:42:49 +1000302// to preserve and append to existing data.
David Symonds9f60f432012-06-14 09:45:25 +1000303func Unmarshal(buf []byte, pb Message) error {
David Symonds525838c2012-07-20 15:42:49 +1000304 pb.Reset()
David Symondsd4b52d02013-01-15 14:30:26 +1100305 return UnmarshalMerge(buf, pb)
David Symonds19285602012-07-02 16:04:28 -0700306}
307
David Symondsd4b52d02013-01-15 14:30:26 +1100308// UnmarshalMerge parses the protocol buffer representation in buf and
David Symonds19285602012-07-02 16:04:28 -0700309// writes the decoded result to pb. If the struct underlying pb does not match
310// the data in buf, the results can be unpredictable.
311//
David Symondsd4b52d02013-01-15 14:30:26 +1100312// UnmarshalMerge merges into existing data in pb.
David Symonds525838c2012-07-20 15:42:49 +1000313// Most code should use Unmarshal instead.
David Symondsd4b52d02013-01-15 14:30:26 +1100314func UnmarshalMerge(buf []byte, pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700315 // If the object can unmarshal itself, let it.
316 if u, ok := pb.(Unmarshaler); ok {
317 return u.Unmarshal(buf)
318 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700319 return NewBuffer(buf).Unmarshal(pb)
320}
321
322// Unmarshal parses the protocol buffer representation in the
323// Buffer and places the decoded result in pb. If the struct
324// underlying pb does not match the data in the buffer, the results can be
325// unpredictable.
David Symonds9f60f432012-06-14 09:45:25 +1000326func (p *Buffer) Unmarshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700327 // If the object can unmarshal itself, let it.
328 if u, ok := pb.(Unmarshaler); ok {
329 err := u.Unmarshal(p.buf[p.index:])
330 p.index = len(p.buf)
331 return err
332 }
333
Rob Pikeaaa3a622010-03-20 22:32:34 -0700334 typ, base, err := getbase(pb)
335 if err != nil {
336 return err
337 }
338
David Symonds6a6f82c2012-08-22 09:18:54 +1000339 err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700340
David Symonds9f60f432012-06-14 09:45:25 +1000341 if collectStats {
342 stats.Decode++
343 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700344
345 return err
346}
347
348// unmarshalType does the work of unmarshaling a structure.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000349func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000350 var state errorState
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700351 required, reqFields := prop.reqCount, uint64(0)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700352
Rob Pikea17fdd92011-11-02 12:43:05 -0700353 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700354 for err == nil && o.index < len(o.buf) {
355 oi := o.index
356 var u uint64
357 u, err = o.DecodeVarint()
358 if err != nil {
359 break
360 }
361 wire := int(u & 0x7)
362 if wire == WireEndGroup {
363 if is_group {
364 return nil // input is satisfied
365 }
366 return ErrWrongType
367 }
368 tag := int(u >> 3)
David Symonds6e50db52012-02-11 15:56:22 +1100369 if tag <= 0 {
370 return fmt.Errorf("proto: illegal tag %d", tag)
371 }
David Symonds2bba1b22012-09-26 14:53:08 +1000372 fieldnum, ok := prop.decoderTags.get(tag)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700373 if !ok {
374 // Maybe it's an extension?
Russ Coxd4ce3f12012-09-12 10:36:26 +1000375 if prop.extendable {
376 if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
377 if err = o.skip(st, tag, wire); err == nil {
378 ext := e.ExtensionMap()[int32(tag)] // may be missing
379 ext.enc = append(ext.enc, o.buf[oi:o.index]...)
380 e.ExtensionMap()[int32(tag)] = ext
381 }
382 continue
Rob Pikeaaa3a622010-03-20 22:32:34 -0700383 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700384 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000385 err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700386 continue
387 }
388 p := prop.Prop[fieldnum]
389
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700390 if p.dec == nil {
David Symonds6a6f82c2012-08-22 09:18:54 +1000391 fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700392 continue
393 }
David Symonds5b7775e2010-12-01 10:09:04 +1100394 dec := p.dec
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700395 if wire != WireStartGroup && wire != p.WireType {
David Symonds5b7775e2010-12-01 10:09:04 +1100396 if wire == WireBytes && p.packedDec != nil {
397 // a packable field
398 dec = p.packedDec
399 } else {
400 err = ErrWrongType
401 continue
402 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700403 }
David Symonds4646c372013-09-09 13:18:58 +1000404 decErr := dec(o, p, base)
405 if decErr != nil && !state.shouldContinue(decErr, p) {
406 err = decErr
407 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700408 if err == nil && p.Required {
409 // Successfully decoded a required field.
410 if tag <= 64 {
411 // use bitmap for fields 1-64 to catch field reuse.
412 var mask uint64 = 1 << uint64(tag-1)
413 if reqFields&mask == 0 {
414 // new required field
415 reqFields |= mask
416 required--
417 }
418 } else {
419 // This is imprecise. It can be fooled by a required field
420 // with a tag > 64 that is encoded twice; that's very rare.
421 // A fully correct implementation would require allocating
422 // a data structure, which we would like to avoid.
423 required--
424 }
425 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700426 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700427 if err == nil {
428 if is_group {
429 return io.ErrUnexpectedEOF
430 }
David Symonds4646c372013-09-09 13:18:58 +1000431 if state.err != nil {
432 return state.err
433 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700434 if required > 0 {
David Symonds4646c372013-09-09 13:18:58 +1000435 // Not enough information to determine the exact field. If we use extra
436 // CPU, we could determine the field only if the missing required field
437 // has a tag <= 64 and we check reqFields.
David Symondse583a5f2013-09-27 10:02:37 +1000438 return &RequiredNotSetError{"{Unknown}"}
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700439 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700440 }
441 return err
442}
443
Rob Pikeaaa3a622010-03-20 22:32:34 -0700444// Individual type decoders
445// For each,
446// u is the decoded value,
447// v is a pointer to the field (pointer) in the struct
Rob Pike76f6ee52011-10-20 12:58:28 -0700448
449// Sizes of the pools to allocate inside the Buffer.
Rob Pike97edc7e2011-10-20 15:53:19 -0700450// The goal is modest amortization and allocation
451// on at least 16-byte boundaries.
Rob Pike76f6ee52011-10-20 12:58:28 -0700452const (
Russ Coxd4ce3f12012-09-12 10:36:26 +1000453 boolPoolSize = 16
454 uint32PoolSize = 8
455 uint64PoolSize = 4
Rob Pike76f6ee52011-10-20 12:58:28 -0700456)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700457
458// Decode a bool.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000459func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700460 u, err := p.valDec(o)
461 if err != nil {
462 return err
463 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700464 if len(o.bools) == 0 {
465 o.bools = make([]bool, boolPoolSize)
466 }
467 o.bools[0] = u != 0
Russ Coxd4ce3f12012-09-12 10:36:26 +1000468 *structPointer_Bool(base, p.field) = &o.bools[0]
Rob Pike76f6ee52011-10-20 12:58:28 -0700469 o.bools = o.bools[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700470 return nil
471}
472
473// Decode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000474func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700475 u, err := p.valDec(o)
476 if err != nil {
477 return err
478 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000479 word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700480 return nil
481}
482
483// Decode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000484func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700485 u, err := p.valDec(o)
486 if err != nil {
487 return err
488 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000489 word64_Set(structPointer_Word64(base, p.field), o, u)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700490 return nil
491}
492
493// Decode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000494func (o *Buffer) dec_string(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700495 s, err := o.DecodeStringBytes()
496 if err != nil {
497 return err
498 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700499 sp := new(string)
500 *sp = s
Russ Coxd4ce3f12012-09-12 10:36:26 +1000501 *structPointer_String(base, p.field) = sp
Rob Pikeaaa3a622010-03-20 22:32:34 -0700502 return nil
503}
504
505// Decode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000506func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700507 b, err := o.DecodeRawBytes(true)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700508 if err != nil {
509 return err
510 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000511 *structPointer_Bytes(base, p.field) = b
Rob Pikeaaa3a622010-03-20 22:32:34 -0700512 return nil
513}
514
515// Decode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000516func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700517 u, err := p.valDec(o)
518 if err != nil {
519 return err
520 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000521 v := structPointer_BoolSlice(base, p.field)
Rob Pike76f6ee52011-10-20 12:58:28 -0700522 *v = append(*v, u != 0)
David Symonds5b7775e2010-12-01 10:09:04 +1100523 return nil
524}
525
526// Decode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000527func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
528 v := structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100529
530 nn, err := o.DecodeVarint()
531 if err != nil {
532 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700533 }
David Symonds5b7775e2010-12-01 10:09:04 +1100534 nb := int(nn) // number of bytes of encoded bools
535
Rob Pike76f6ee52011-10-20 12:58:28 -0700536 y := *v
David Symonds5b7775e2010-12-01 10:09:04 +1100537 for i := 0; i < nb; i++ {
538 u, err := p.valDec(o)
539 if err != nil {
540 return err
541 }
542 y = append(y, u != 0)
543 }
544
Rob Pike76f6ee52011-10-20 12:58:28 -0700545 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700546 return nil
547}
548
549// Decode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000550func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700551 u, err := p.valDec(o)
552 if err != nil {
553 return err
554 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000555 structPointer_Word32Slice(base, p.field).Append(uint32(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100556 return nil
557}
558
559// Decode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000560func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
561 v := structPointer_Word32Slice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100562
563 nn, err := o.DecodeVarint()
564 if err != nil {
565 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700566 }
David Symonds5b7775e2010-12-01 10:09:04 +1100567 nb := int(nn) // number of bytes of encoded int32s
568
David Symonds5b7775e2010-12-01 10:09:04 +1100569 fin := o.index + nb
Adam Langley28c83cb2013-07-13 14:54:54 +1000570 if fin < o.index {
571 return errOverflow
572 }
David Symonds5b7775e2010-12-01 10:09:04 +1100573 for o.index < fin {
574 u, err := p.valDec(o)
575 if err != nil {
576 return err
577 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000578 v.Append(uint32(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100579 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700580 return nil
581}
582
583// Decode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000584func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700585 u, err := p.valDec(o)
586 if err != nil {
587 return err
588 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700589
Russ Coxd4ce3f12012-09-12 10:36:26 +1000590 structPointer_Word64Slice(base, p.field).Append(u)
David Symonds5b7775e2010-12-01 10:09:04 +1100591 return nil
592}
593
594// Decode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000595func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
596 v := structPointer_Word64Slice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100597
598 nn, err := o.DecodeVarint()
599 if err != nil {
600 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700601 }
David Symonds5b7775e2010-12-01 10:09:04 +1100602 nb := int(nn) // number of bytes of encoded int64s
603
David Symonds5b7775e2010-12-01 10:09:04 +1100604 fin := o.index + nb
Adam Langley28c83cb2013-07-13 14:54:54 +1000605 if fin < o.index {
606 return errOverflow
607 }
David Symonds5b7775e2010-12-01 10:09:04 +1100608 for o.index < fin {
609 u, err := p.valDec(o)
610 if err != nil {
611 return err
612 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000613 v.Append(u)
David Symonds5b7775e2010-12-01 10:09:04 +1100614 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700615 return nil
616}
617
618// Decode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000619func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700620 s, err := o.DecodeStringBytes()
621 if err != nil {
622 return err
623 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000624 v := structPointer_StringSlice(base, p.field)
625 *v = append(*v, s)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700626 return nil
627}
628
629// Decode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000630func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700631 b, err := o.DecodeRawBytes(true)
632 if err != nil {
633 return err
634 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000635 v := structPointer_BytesSlice(base, p.field)
636 *v = append(*v, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700637 return nil
638}
639
640// Decode a group.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000641func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
David Symonds2ce8ed42013-06-20 13:22:17 +1000642 bas := structPointer_GetStructPointer(base, p.field)
643 if structPointer_IsNil(bas) {
644 // allocate new nested message
645 bas = toStructPointer(reflect.New(p.stype))
646 structPointer_SetStructPointer(base, p.field, bas)
647 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000648 return o.unmarshalType(p.stype, p.sprop, true, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700649}
650
651// Decode an embedded message.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000652func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700653 raw, e := o.DecodeRawBytes(false)
654 if e != nil {
655 return e
656 }
657
David Symonds2ce8ed42013-06-20 13:22:17 +1000658 bas := structPointer_GetStructPointer(base, p.field)
659 if structPointer_IsNil(bas) {
660 // allocate new nested message
661 bas = toStructPointer(reflect.New(p.stype))
662 structPointer_SetStructPointer(base, p.field, bas)
663 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700664
665 // If the object can unmarshal itself, let it.
David Symonds4f8da862013-06-24 10:57:29 +1000666 if p.isUnmarshaler {
David Symonds2ce8ed42013-06-20 13:22:17 +1000667 iv := structPointer_Interface(bas, p.stype)
David Symondsa80b2822012-03-14 14:31:25 +1100668 return iv.(Unmarshaler).Unmarshal(raw)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700669 }
670
671 obuf := o.buf
672 oi := o.index
673 o.buf = raw
674 o.index = 0
675
David Symondsc0287172012-08-15 11:10:30 +1000676 err = o.unmarshalType(p.stype, p.sprop, false, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700677 o.buf = obuf
678 o.index = oi
679
680 return err
681}
682
683// Decode a slice of embedded messages.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000684func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700685 return o.dec_slice_struct(p, false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700686}
687
688// Decode a slice of embedded groups.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000689func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700690 return o.dec_slice_struct(p, true, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700691}
692
693// Decode a slice of structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000694func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
695 v := reflect.New(p.stype)
696 bas := toStructPointer(v)
697 structPointer_StructPointerSlice(base, p.field).Append(bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700698
699 if is_group {
David Symondsc0287172012-08-15 11:10:30 +1000700 err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700701 return err
702 }
703
David Symondsc0287172012-08-15 11:10:30 +1000704 raw, err := o.DecodeRawBytes(false)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700705 if err != nil {
706 return err
707 }
708
709 // If the object can unmarshal itself, let it.
David Symondsa80b2822012-03-14 14:31:25 +1100710 if p.isUnmarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000711 iv := v.Interface()
David Symondsa80b2822012-03-14 14:31:25 +1100712 return iv.(Unmarshaler).Unmarshal(raw)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700713 }
714
715 obuf := o.buf
716 oi := o.index
717 o.buf = raw
718 o.index = 0
719
David Symondsc0287172012-08-15 11:10:30 +1000720 err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700721
722 o.buf = obuf
723 o.index = oi
724
725 return err
726}