blob: f951c01a713e74428fcfafa0233e1fc4f160ebde [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
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
238 if *ptr == nil {
239 // This is the first skipped element,
240 // allocate a new buffer.
241 *ptr = o.bufalloc()
242 }
243
244 // Add the skipped field to struct field
245 obuf := o.buf
246
247 o.buf = *ptr
248 o.EncodeVarint(uint64(tag<<3 | wire))
Rob Pike99fa2b62010-12-02 10:39:42 -0800249 *ptr = append(o.buf, obuf[oi:o.index]...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700250
251 o.buf = obuf
252
253 return nil
254}
255
256// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
Rob Pikea17fdd92011-11-02 12:43:05 -0700257func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700258
259 var u uint64
Rob Pikea17fdd92011-11-02 12:43:05 -0700260 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700261
262 switch wire {
263 case WireVarint:
264 _, err = o.DecodeVarint()
265 case WireFixed64:
266 _, err = o.DecodeFixed64()
267 case WireBytes:
268 _, err = o.DecodeRawBytes(false)
269 case WireFixed32:
270 _, err = o.DecodeFixed32()
271 case WireStartGroup:
272 for {
273 u, err = o.DecodeVarint()
274 if err != nil {
275 break
276 }
277 fwire := int(u & 0x7)
278 if fwire == WireEndGroup {
279 break
280 }
281 ftag := int(u >> 3)
282 err = o.skip(t, ftag, fwire)
283 if err != nil {
284 break
285 }
286 }
287 default:
David Symonds22ac1502012-01-18 12:37:12 +1100288 err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700289 }
290 return err
291}
292
David Symonds7d3c6802012-11-08 08:20:18 +1100293// Unmarshaler is the interface representing objects that can
294// unmarshal themselves. The method should reset the receiver before
295// decoding starts. The argument points to data that may be
296// overwritten, so implementations should not keep references to the
297// buffer.
Rob Pikeaaa3a622010-03-20 22:32:34 -0700298type Unmarshaler interface {
Rob Pikea17fdd92011-11-02 12:43:05 -0700299 Unmarshal([]byte) error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700300}
301
302// Unmarshal parses the protocol buffer representation in buf and places the
303// decoded result in pb. If the struct underlying pb does not match
304// the data in buf, the results can be unpredictable.
David Symonds19285602012-07-02 16:04:28 -0700305//
David Symonds525838c2012-07-20 15:42:49 +1000306// Unmarshal resets pb before starting to unmarshal, so any
David Symondsd4b52d02013-01-15 14:30:26 +1100307// existing data in pb is always removed. Use UnmarshalMerge
David Symonds525838c2012-07-20 15:42:49 +1000308// to preserve and append to existing data.
David Symonds9f60f432012-06-14 09:45:25 +1000309func Unmarshal(buf []byte, pb Message) error {
David Symonds525838c2012-07-20 15:42:49 +1000310 pb.Reset()
David Symondsd4b52d02013-01-15 14:30:26 +1100311 return UnmarshalMerge(buf, pb)
David Symonds19285602012-07-02 16:04:28 -0700312}
313
David Symondsd4b52d02013-01-15 14:30:26 +1100314// UnmarshalMerge parses the protocol buffer representation in buf and
David Symonds19285602012-07-02 16:04:28 -0700315// writes the decoded result to pb. If the struct underlying pb does not match
316// the data in buf, the results can be unpredictable.
317//
David Symondsd4b52d02013-01-15 14:30:26 +1100318// UnmarshalMerge merges into existing data in pb.
David Symonds525838c2012-07-20 15:42:49 +1000319// Most code should use Unmarshal instead.
David Symondsd4b52d02013-01-15 14:30:26 +1100320func UnmarshalMerge(buf []byte, pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700321 // If the object can unmarshal itself, let it.
322 if u, ok := pb.(Unmarshaler); ok {
323 return u.Unmarshal(buf)
324 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700325 return NewBuffer(buf).Unmarshal(pb)
326}
327
328// Unmarshal parses the protocol buffer representation in the
329// Buffer and places the decoded result in pb. If the struct
330// underlying pb does not match the data in the buffer, the results can be
331// unpredictable.
David Symonds9f60f432012-06-14 09:45:25 +1000332func (p *Buffer) Unmarshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700333 // If the object can unmarshal itself, let it.
334 if u, ok := pb.(Unmarshaler); ok {
335 err := u.Unmarshal(p.buf[p.index:])
336 p.index = len(p.buf)
337 return err
338 }
339
Rob Pikeaaa3a622010-03-20 22:32:34 -0700340 typ, base, err := getbase(pb)
341 if err != nil {
342 return err
343 }
344
David Symonds6a6f82c2012-08-22 09:18:54 +1000345 err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700346
David Symonds9f60f432012-06-14 09:45:25 +1000347 if collectStats {
348 stats.Decode++
349 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700350
351 return err
352}
353
354// unmarshalType does the work of unmarshaling a structure.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000355func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700356 required, reqFields := prop.reqCount, uint64(0)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700357
Rob Pikea17fdd92011-11-02 12:43:05 -0700358 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700359 for err == nil && o.index < len(o.buf) {
360 oi := o.index
361 var u uint64
362 u, err = o.DecodeVarint()
363 if err != nil {
364 break
365 }
366 wire := int(u & 0x7)
367 if wire == WireEndGroup {
368 if is_group {
369 return nil // input is satisfied
370 }
371 return ErrWrongType
372 }
373 tag := int(u >> 3)
David Symonds6e50db52012-02-11 15:56:22 +1100374 if tag <= 0 {
375 return fmt.Errorf("proto: illegal tag %d", tag)
376 }
David Symonds2bba1b22012-09-26 14:53:08 +1000377 fieldnum, ok := prop.decoderTags.get(tag)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700378 if !ok {
379 // Maybe it's an extension?
Russ Coxd4ce3f12012-09-12 10:36:26 +1000380 if prop.extendable {
381 if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
382 if err = o.skip(st, tag, wire); err == nil {
383 ext := e.ExtensionMap()[int32(tag)] // may be missing
384 ext.enc = append(ext.enc, o.buf[oi:o.index]...)
385 e.ExtensionMap()[int32(tag)] = ext
386 }
387 continue
Rob Pikeaaa3a622010-03-20 22:32:34 -0700388 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700389 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000390 err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700391 continue
392 }
393 p := prop.Prop[fieldnum]
394
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700395 if p.dec == nil {
David Symonds6a6f82c2012-08-22 09:18:54 +1000396 fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700397 continue
398 }
David Symonds5b7775e2010-12-01 10:09:04 +1100399 dec := p.dec
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700400 if wire != WireStartGroup && wire != p.WireType {
David Symonds5b7775e2010-12-01 10:09:04 +1100401 if wire == WireBytes && p.packedDec != nil {
402 // a packable field
403 dec = p.packedDec
404 } else {
405 err = ErrWrongType
406 continue
407 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700408 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700409 err = dec(o, p, base)
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700410 if err == nil && p.Required {
411 // Successfully decoded a required field.
412 if tag <= 64 {
413 // use bitmap for fields 1-64 to catch field reuse.
414 var mask uint64 = 1 << uint64(tag-1)
415 if reqFields&mask == 0 {
416 // new required field
417 reqFields |= mask
418 required--
419 }
420 } else {
421 // This is imprecise. It can be fooled by a required field
422 // with a tag > 64 that is encoded twice; that's very rare.
423 // A fully correct implementation would require allocating
424 // a data structure, which we would like to avoid.
425 required--
426 }
427 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700428 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700429 if err == nil {
430 if is_group {
431 return io.ErrUnexpectedEOF
432 }
433 if required > 0 {
David Symonds5b7775e2010-12-01 10:09:04 +1100434 return &ErrRequiredNotSet{st}
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700435 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700436 }
437 return err
438}
439
Rob Pikeaaa3a622010-03-20 22:32:34 -0700440// Individual type decoders
441// For each,
442// u is the decoded value,
443// v is a pointer to the field (pointer) in the struct
Rob Pike76f6ee52011-10-20 12:58:28 -0700444
445// Sizes of the pools to allocate inside the Buffer.
Rob Pike97edc7e2011-10-20 15:53:19 -0700446// The goal is modest amortization and allocation
447// on at least 16-byte boundaries.
Rob Pike76f6ee52011-10-20 12:58:28 -0700448const (
Russ Coxd4ce3f12012-09-12 10:36:26 +1000449 boolPoolSize = 16
450 uint32PoolSize = 8
451 uint64PoolSize = 4
Rob Pike76f6ee52011-10-20 12:58:28 -0700452)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700453
454// Decode a bool.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000455func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700456 u, err := p.valDec(o)
457 if err != nil {
458 return err
459 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700460 if len(o.bools) == 0 {
461 o.bools = make([]bool, boolPoolSize)
462 }
463 o.bools[0] = u != 0
Russ Coxd4ce3f12012-09-12 10:36:26 +1000464 *structPointer_Bool(base, p.field) = &o.bools[0]
Rob Pike76f6ee52011-10-20 12:58:28 -0700465 o.bools = o.bools[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700466 return nil
467}
468
469// Decode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000470func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700471 u, err := p.valDec(o)
472 if err != nil {
473 return err
474 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000475 word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700476 return nil
477}
478
479// Decode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000480func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700481 u, err := p.valDec(o)
482 if err != nil {
483 return err
484 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000485 word64_Set(structPointer_Word64(base, p.field), o, u)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700486 return nil
487}
488
489// Decode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000490func (o *Buffer) dec_string(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700491 s, err := o.DecodeStringBytes()
492 if err != nil {
493 return err
494 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700495 sp := new(string)
496 *sp = s
Russ Coxd4ce3f12012-09-12 10:36:26 +1000497 *structPointer_String(base, p.field) = sp
Rob Pikeaaa3a622010-03-20 22:32:34 -0700498 return nil
499}
500
501// Decode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000502func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700503 b, err := o.DecodeRawBytes(true)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700504 if err != nil {
505 return err
506 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000507 *structPointer_Bytes(base, p.field) = b
Rob Pikeaaa3a622010-03-20 22:32:34 -0700508 return nil
509}
510
511// Decode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000512func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700513 u, err := p.valDec(o)
514 if err != nil {
515 return err
516 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000517 v := structPointer_BoolSlice(base, p.field)
Rob Pike76f6ee52011-10-20 12:58:28 -0700518 *v = append(*v, u != 0)
David Symonds5b7775e2010-12-01 10:09:04 +1100519 return nil
520}
521
522// Decode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000523func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
524 v := structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100525
526 nn, err := o.DecodeVarint()
527 if err != nil {
528 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700529 }
David Symonds5b7775e2010-12-01 10:09:04 +1100530 nb := int(nn) // number of bytes of encoded bools
531
Rob Pike76f6ee52011-10-20 12:58:28 -0700532 y := *v
David Symonds5b7775e2010-12-01 10:09:04 +1100533 for i := 0; i < nb; i++ {
534 u, err := p.valDec(o)
535 if err != nil {
536 return err
537 }
538 y = append(y, u != 0)
539 }
540
Rob Pike76f6ee52011-10-20 12:58:28 -0700541 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700542 return nil
543}
544
545// Decode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000546func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700547 u, err := p.valDec(o)
548 if err != nil {
549 return err
550 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000551 structPointer_Word32Slice(base, p.field).Append(uint32(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100552 return nil
553}
554
555// Decode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000556func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
557 v := structPointer_Word32Slice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100558
559 nn, err := o.DecodeVarint()
560 if err != nil {
561 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700562 }
David Symonds5b7775e2010-12-01 10:09:04 +1100563 nb := int(nn) // number of bytes of encoded int32s
564
David Symonds5b7775e2010-12-01 10:09:04 +1100565 fin := o.index + nb
Adam Langley28c83cb2013-07-13 14:54:54 +1000566 if fin < o.index {
567 return errOverflow
568 }
David Symonds5b7775e2010-12-01 10:09:04 +1100569 for o.index < fin {
570 u, err := p.valDec(o)
571 if err != nil {
572 return err
573 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000574 v.Append(uint32(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100575 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700576 return nil
577}
578
579// Decode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000580func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700581 u, err := p.valDec(o)
582 if err != nil {
583 return err
584 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700585
Russ Coxd4ce3f12012-09-12 10:36:26 +1000586 structPointer_Word64Slice(base, p.field).Append(u)
David Symonds5b7775e2010-12-01 10:09:04 +1100587 return nil
588}
589
590// Decode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000591func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
592 v := structPointer_Word64Slice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100593
594 nn, err := o.DecodeVarint()
595 if err != nil {
596 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700597 }
David Symonds5b7775e2010-12-01 10:09:04 +1100598 nb := int(nn) // number of bytes of encoded int64s
599
David Symonds5b7775e2010-12-01 10:09:04 +1100600 fin := o.index + nb
Adam Langley28c83cb2013-07-13 14:54:54 +1000601 if fin < o.index {
602 return errOverflow
603 }
David Symonds5b7775e2010-12-01 10:09:04 +1100604 for o.index < fin {
605 u, err := p.valDec(o)
606 if err != nil {
607 return err
608 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000609 v.Append(u)
David Symonds5b7775e2010-12-01 10:09:04 +1100610 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700611 return nil
612}
613
614// Decode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000615func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700616 s, err := o.DecodeStringBytes()
617 if err != nil {
618 return err
619 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000620 v := structPointer_StringSlice(base, p.field)
621 *v = append(*v, s)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700622 return nil
623}
624
625// Decode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000626func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700627 b, err := o.DecodeRawBytes(true)
628 if err != nil {
629 return err
630 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000631 v := structPointer_BytesSlice(base, p.field)
632 *v = append(*v, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700633 return nil
634}
635
636// Decode a group.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000637func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
David Symonds2ce8ed42013-06-20 13:22:17 +1000638 bas := structPointer_GetStructPointer(base, p.field)
639 if structPointer_IsNil(bas) {
640 // allocate new nested message
641 bas = toStructPointer(reflect.New(p.stype))
642 structPointer_SetStructPointer(base, p.field, bas)
643 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000644 return o.unmarshalType(p.stype, p.sprop, true, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700645}
646
647// Decode an embedded message.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000648func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700649 raw, e := o.DecodeRawBytes(false)
650 if e != nil {
651 return e
652 }
653
David Symonds2ce8ed42013-06-20 13:22:17 +1000654 bas := structPointer_GetStructPointer(base, p.field)
655 if structPointer_IsNil(bas) {
656 // allocate new nested message
657 bas = toStructPointer(reflect.New(p.stype))
658 structPointer_SetStructPointer(base, p.field, bas)
659 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700660
661 // If the object can unmarshal itself, let it.
David Symonds4f8da862013-06-24 10:57:29 +1000662 if p.isUnmarshaler {
David Symonds2ce8ed42013-06-20 13:22:17 +1000663 iv := structPointer_Interface(bas, p.stype)
David Symondsa80b2822012-03-14 14:31:25 +1100664 return iv.(Unmarshaler).Unmarshal(raw)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700665 }
666
667 obuf := o.buf
668 oi := o.index
669 o.buf = raw
670 o.index = 0
671
David Symondsc0287172012-08-15 11:10:30 +1000672 err = o.unmarshalType(p.stype, p.sprop, false, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700673 o.buf = obuf
674 o.index = oi
675
676 return err
677}
678
679// Decode a slice of embedded messages.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000680func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700681 return o.dec_slice_struct(p, false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700682}
683
684// Decode a slice of embedded groups.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000685func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700686 return o.dec_slice_struct(p, true, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700687}
688
689// Decode a slice of structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000690func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
691 v := reflect.New(p.stype)
692 bas := toStructPointer(v)
693 structPointer_StructPointerSlice(base, p.field).Append(bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700694
695 if is_group {
David Symondsc0287172012-08-15 11:10:30 +1000696 err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700697 return err
698 }
699
David Symondsc0287172012-08-15 11:10:30 +1000700 raw, err := o.DecodeRawBytes(false)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700701 if err != nil {
702 return err
703 }
704
705 // If the object can unmarshal itself, let it.
David Symondsa80b2822012-03-14 14:31:25 +1100706 if p.isUnmarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000707 iv := v.Interface()
David Symondsa80b2822012-03-14 14:31:25 +1100708 return iv.(Unmarshaler).Unmarshal(raw)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700709 }
710
711 obuf := o.buf
712 oi := o.index
713 o.buf = raw
714 o.index = 0
715
David Symondsc0287172012-08-15 11:10:30 +1000716 err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700717
718 o.buf = obuf
719 o.index = oi
720
721 return err
722}