blob: 6c7f53af4ad393a2f00b93ebe7d70e5385345c23 [file] [log] [blame]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001// Go support for Protocol Buffers - Google's data interchange format
2//
3// Copyright 2010 Google Inc. All rights reserved.
4// 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 "unsafe"
45)
46
47// ErrWrongType occurs when the wire encoding for the field disagrees with
48// that specified in the type being decoded. This is usually caused by attempting
49// to convert an encoded protocol buffer into a struct of the wrong type.
Rob Pikea17fdd92011-11-02 12:43:05 -070050var ErrWrongType = errors.New("field/encoding mismatch: wrong type for field")
Rob Pikeaaa3a622010-03-20 22:32:34 -070051
52// The fundamental decoders that interpret bytes on the wire.
53// Those that take integer types all return uint64 and are
54// therefore of type valueDecoder.
55
56// DecodeVarint reads a varint-encoded integer from the slice.
57// It returns the integer and the number of bytes consumed, or
58// zero if there is not enough.
59// This is the format for the
60// int32, int64, uint32, uint64, bool, and enum
61// protocol buffer types.
62func DecodeVarint(buf []byte) (x uint64, n int) {
63 // x, n already 0
64 for shift := uint(0); ; shift += 7 {
65 if n >= len(buf) {
66 return 0, 0
67 }
68 b := uint64(buf[n])
69 n++
70 x |= (b & 0x7F) << shift
71 if (b & 0x80) == 0 {
72 break
73 }
74 }
75 return x, n
76}
77
78// DecodeVarint reads a varint-encoded integer from the Buffer.
79// This is the format for the
80// int32, int64, uint32, uint64, bool, and enum
81// protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -070082func (p *Buffer) DecodeVarint() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -070083 // x, err already 0
84
85 i := p.index
86 l := len(p.buf)
87
88 for shift := uint(0); ; shift += 7 {
89 if i >= l {
90 err = io.ErrUnexpectedEOF
91 return
92 }
93 b := p.buf[i]
94 i++
95 x |= (uint64(b) & 0x7F) << shift
96 if b < 0x80 {
97 break
98 }
99 }
100 p.index = i
101 return
102}
103
104// DecodeFixed64 reads a 64-bit integer from the Buffer.
105// This is the format for the
106// fixed64, sfixed64, and double protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700107func (p *Buffer) DecodeFixed64() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700108 // x, err already 0
109 i := p.index + 8
110 if i > len(p.buf) {
111 err = io.ErrUnexpectedEOF
112 return
113 }
114 p.index = i
115
116 x = uint64(p.buf[i-8])
117 x |= uint64(p.buf[i-7]) << 8
118 x |= uint64(p.buf[i-6]) << 16
119 x |= uint64(p.buf[i-5]) << 24
120 x |= uint64(p.buf[i-4]) << 32
121 x |= uint64(p.buf[i-3]) << 40
122 x |= uint64(p.buf[i-2]) << 48
123 x |= uint64(p.buf[i-1]) << 56
124 return
125}
126
127// DecodeFixed32 reads a 32-bit integer from the Buffer.
128// This is the format for the
129// fixed32, sfixed32, and float protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700130func (p *Buffer) DecodeFixed32() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700131 // x, err already 0
132 i := p.index + 4
133 if i > len(p.buf) {
134 err = io.ErrUnexpectedEOF
135 return
136 }
137 p.index = i
138
139 x = uint64(p.buf[i-4])
140 x |= uint64(p.buf[i-3]) << 8
141 x |= uint64(p.buf[i-2]) << 16
142 x |= uint64(p.buf[i-1]) << 24
143 return
144}
145
146// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
147// from the Buffer.
148// This is the format used for the sint64 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700149func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700150 x, err = p.DecodeVarint()
151 if err != nil {
152 return
153 }
154 x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
155 return
156}
157
158// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
159// from the Buffer.
160// This is the format used for the sint32 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700161func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700162 x, err = p.DecodeVarint()
163 if err != nil {
164 return
165 }
166 x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
167 return
168}
169
170// These are not ValueDecoders: they produce an array of bytes or a string.
171// bytes, embedded messages
172
173// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
174// This is the format used for the bytes protocol buffer
175// type and for embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700176func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700177 n, err := p.DecodeVarint()
178 if err != nil {
179 return
180 }
181
182 nb := int(n)
David Symonds22ac1502012-01-18 12:37:12 +1100183 if nb < 0 {
184 return nil, fmt.Errorf("proto: bad byte length %d", nb)
185 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700186 if p.index+nb > len(p.buf) {
David Symonds22ac1502012-01-18 12:37:12 +1100187 return nil, io.ErrUnexpectedEOF
Rob Pikeaaa3a622010-03-20 22:32:34 -0700188 }
189
190 if !alloc {
191 // todo: check if can get more uses of alloc=false
192 buf = p.buf[p.index : p.index+nb]
193 p.index += nb
194 return
195 }
196
197 buf = make([]byte, nb)
198 copy(buf, p.buf[p.index:])
199 p.index += nb
200 return
201}
202
203// DecodeStringBytes reads an encoded string from the Buffer.
204// This is the format used for the proto2 string type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700205func (p *Buffer) DecodeStringBytes() (s string, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700206 buf, err := p.DecodeRawBytes(false)
207 if err != nil {
208 return
209 }
210 return string(buf), nil
211}
212
213// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
214// If the protocol buffer has extensions, and the field matches, add it as an extension.
215// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
David Symondsc0287172012-08-15 11:10:30 +1000216func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base, unrecOffset uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700217
218 oi := o.index
219
220 err := o.skip(t, tag, wire)
221 if err != nil {
222 return err
223 }
224
David Symondsc0287172012-08-15 11:10:30 +1000225 if unrecOffset == 0 {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700226 return nil
227 }
228
David Symondsc0287172012-08-15 11:10:30 +1000229 ptr := (*[]byte)(unsafe.Pointer(base + unrecOffset))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700230
231 if *ptr == nil {
232 // This is the first skipped element,
233 // allocate a new buffer.
234 *ptr = o.bufalloc()
235 }
236
237 // Add the skipped field to struct field
238 obuf := o.buf
239
240 o.buf = *ptr
241 o.EncodeVarint(uint64(tag<<3 | wire))
Rob Pike99fa2b62010-12-02 10:39:42 -0800242 *ptr = append(o.buf, obuf[oi:o.index]...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700243
244 o.buf = obuf
245
246 return nil
247}
248
249// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
Rob Pikea17fdd92011-11-02 12:43:05 -0700250func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700251
252 var u uint64
Rob Pikea17fdd92011-11-02 12:43:05 -0700253 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700254
255 switch wire {
256 case WireVarint:
257 _, err = o.DecodeVarint()
258 case WireFixed64:
259 _, err = o.DecodeFixed64()
260 case WireBytes:
261 _, err = o.DecodeRawBytes(false)
262 case WireFixed32:
263 _, err = o.DecodeFixed32()
264 case WireStartGroup:
265 for {
266 u, err = o.DecodeVarint()
267 if err != nil {
268 break
269 }
270 fwire := int(u & 0x7)
271 if fwire == WireEndGroup {
272 break
273 }
274 ftag := int(u >> 3)
275 err = o.skip(t, ftag, fwire)
276 if err != nil {
277 break
278 }
279 }
280 default:
David Symonds22ac1502012-01-18 12:37:12 +1100281 err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700282 }
283 return err
284}
285
286// Unmarshaler is the interface representing objects that can unmarshal themselves.
David Symondsc0287172012-08-15 11:10:30 +1000287// The argument points to data that may be overwritten, so implementations should
288// not keep references to the buffer.
Rob Pikeaaa3a622010-03-20 22:32:34 -0700289type Unmarshaler interface {
Rob Pikea17fdd92011-11-02 12:43:05 -0700290 Unmarshal([]byte) error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700291}
292
293// Unmarshal parses the protocol buffer representation in buf and places the
294// decoded result in pb. If the struct underlying pb does not match
295// the data in buf, the results can be unpredictable.
David Symonds19285602012-07-02 16:04:28 -0700296//
David Symonds525838c2012-07-20 15:42:49 +1000297// Unmarshal resets pb before starting to unmarshal, so any
298// existing data in pb is always removed. Use UnmarshalAppend
299// to preserve and append to existing data.
David Symonds9f60f432012-06-14 09:45:25 +1000300func Unmarshal(buf []byte, pb Message) error {
David Symonds525838c2012-07-20 15:42:49 +1000301 pb.Reset()
David Symonds19285602012-07-02 16:04:28 -0700302 return UnmarshalAppend(buf, pb)
303}
304
305// UnmarshalAppend parses the protocol buffer representation in buf and
306// writes the decoded result to pb. If the struct underlying pb does not match
307// the data in buf, the results can be unpredictable.
308//
David Symonds525838c2012-07-20 15:42:49 +1000309// UnmarshalAppend preserves and appends to existing data in pb.
310// Most code should use Unmarshal instead.
David Symonds19285602012-07-02 16:04:28 -0700311func UnmarshalAppend(buf []byte, pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700312 // If the object can unmarshal itself, let it.
313 if u, ok := pb.(Unmarshaler); ok {
314 return u.Unmarshal(buf)
315 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700316 return NewBuffer(buf).Unmarshal(pb)
317}
318
319// Unmarshal parses the protocol buffer representation in the
320// Buffer and places the decoded result in pb. If the struct
321// underlying pb does not match the data in the buffer, the results can be
322// unpredictable.
David Symonds9f60f432012-06-14 09:45:25 +1000323func (p *Buffer) Unmarshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700324 // If the object can unmarshal itself, let it.
325 if u, ok := pb.(Unmarshaler); ok {
326 err := u.Unmarshal(p.buf[p.index:])
327 p.index = len(p.buf)
328 return err
329 }
330
Rob Pikeaaa3a622010-03-20 22:32:34 -0700331 typ, base, err := getbase(pb)
332 if err != nil {
333 return err
334 }
335
David Symonds6a6f82c2012-08-22 09:18:54 +1000336 err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700337
David Symonds9f60f432012-06-14 09:45:25 +1000338 if collectStats {
339 stats.Decode++
340 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700341
342 return err
343}
344
345// unmarshalType does the work of unmarshaling a structure.
David Symonds6a6f82c2012-08-22 09:18:54 +1000346func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base uintptr) error {
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700347 required, reqFields := prop.reqCount, uint64(0)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700348
Rob Pikea17fdd92011-11-02 12:43:05 -0700349 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700350 for err == nil && o.index < len(o.buf) {
351 oi := o.index
352 var u uint64
353 u, err = o.DecodeVarint()
354 if err != nil {
355 break
356 }
357 wire := int(u & 0x7)
358 if wire == WireEndGroup {
359 if is_group {
360 return nil // input is satisfied
361 }
362 return ErrWrongType
363 }
364 tag := int(u >> 3)
David Symonds6e50db52012-02-11 15:56:22 +1100365 if tag <= 0 {
366 return fmt.Errorf("proto: illegal tag %d", tag)
367 }
David Symonds6a6f82c2012-08-22 09:18:54 +1000368 fieldnum, ok := prop.tags.get(tag)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700369 if !ok {
370 // Maybe it's an extension?
David Symondsa80b2822012-03-14 14:31:25 +1100371 iv := reflect.NewAt(st, unsafe.Pointer(base)).Interface()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700372 if e, ok := iv.(extendableProto); ok && isExtensionField(e, int32(tag)) {
373 if err = o.skip(st, tag, wire); err == nil {
David Symonds61826da2012-05-05 09:31:28 +1000374 ext := e.ExtensionMap()[int32(tag)] // may be missing
375 ext.enc = append(ext.enc, o.buf[oi:o.index]...)
376 e.ExtensionMap()[int32(tag)] = ext
Rob Pikeaaa3a622010-03-20 22:32:34 -0700377 }
378 continue
379 }
David Symondsc0287172012-08-15 11:10:30 +1000380 err = o.skipAndSave(st, tag, wire, base, prop.unrecOffset)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700381 continue
382 }
383 p := prop.Prop[fieldnum]
384
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700385 if p.dec == nil {
David Symonds6a6f82c2012-08-22 09:18:54 +1000386 fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700387 continue
388 }
David Symonds5b7775e2010-12-01 10:09:04 +1100389 dec := p.dec
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700390 if wire != WireStartGroup && wire != p.WireType {
David Symonds5b7775e2010-12-01 10:09:04 +1100391 if wire == WireBytes && p.packedDec != nil {
392 // a packable field
393 dec = p.packedDec
394 } else {
395 err = ErrWrongType
396 continue
397 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700398 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700399 err = dec(o, p, base)
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700400 if err == nil && p.Required {
401 // Successfully decoded a required field.
402 if tag <= 64 {
403 // use bitmap for fields 1-64 to catch field reuse.
404 var mask uint64 = 1 << uint64(tag-1)
405 if reqFields&mask == 0 {
406 // new required field
407 reqFields |= mask
408 required--
409 }
410 } else {
411 // This is imprecise. It can be fooled by a required field
412 // with a tag > 64 that is encoded twice; that's very rare.
413 // A fully correct implementation would require allocating
414 // a data structure, which we would like to avoid.
415 required--
416 }
417 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700418 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700419 if err == nil {
420 if is_group {
421 return io.ErrUnexpectedEOF
422 }
423 if required > 0 {
David Symonds5b7775e2010-12-01 10:09:04 +1100424 return &ErrRequiredNotSet{st}
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700425 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700426 }
427 return err
428}
429
Rob Pikeaaa3a622010-03-20 22:32:34 -0700430// Individual type decoders
431// For each,
432// u is the decoded value,
433// v is a pointer to the field (pointer) in the struct
Rob Pike76f6ee52011-10-20 12:58:28 -0700434
435// Sizes of the pools to allocate inside the Buffer.
Rob Pike97edc7e2011-10-20 15:53:19 -0700436// The goal is modest amortization and allocation
437// on at least 16-byte boundaries.
Rob Pike76f6ee52011-10-20 12:58:28 -0700438const (
David Symonds049646b2011-10-21 11:13:45 +1100439 boolPoolSize = 16
Rob Pike76f6ee52011-10-20 12:58:28 -0700440 int32PoolSize = 8
441 int64PoolSize = 4
442)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700443
444// Decode a bool.
Rob Pikea17fdd92011-11-02 12:43:05 -0700445func (o *Buffer) dec_bool(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700446 u, err := p.valDec(o)
447 if err != nil {
448 return err
449 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700450 if len(o.bools) == 0 {
451 o.bools = make([]bool, boolPoolSize)
452 }
453 o.bools[0] = u != 0
454 v := (**bool)(unsafe.Pointer(base + p.offset))
455 *v = &o.bools[0]
456 o.bools = o.bools[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700457 return nil
458}
459
460// Decode an int32.
Rob Pikea17fdd92011-11-02 12:43:05 -0700461func (o *Buffer) dec_int32(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700462 u, err := p.valDec(o)
463 if err != nil {
464 return err
465 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700466 if len(o.int32s) == 0 {
467 o.int32s = make([]int32, int32PoolSize)
468 }
469 o.int32s[0] = int32(u)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700470 v := (**int32)(unsafe.Pointer(base + p.offset))
Rob Pike76f6ee52011-10-20 12:58:28 -0700471 *v = &o.int32s[0]
472 o.int32s = o.int32s[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700473 return nil
474}
475
476// Decode an int64.
Rob Pikea17fdd92011-11-02 12:43:05 -0700477func (o *Buffer) dec_int64(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700478 u, err := p.valDec(o)
479 if err != nil {
480 return err
481 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700482 if len(o.int64s) == 0 {
483 o.int64s = make([]int64, int64PoolSize)
484 }
485 o.int64s[0] = int64(u)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700486 v := (**int64)(unsafe.Pointer(base + p.offset))
Rob Pike76f6ee52011-10-20 12:58:28 -0700487 *v = &o.int64s[0]
488 o.int64s = o.int64s[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700489 return nil
490}
491
492// Decode a string.
Rob Pikea17fdd92011-11-02 12:43:05 -0700493func (o *Buffer) dec_string(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700494 s, err := o.DecodeStringBytes()
495 if err != nil {
496 return err
497 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700498 sp := new(string)
499 *sp = s
Rob Pikeaaa3a622010-03-20 22:32:34 -0700500 v := (**string)(unsafe.Pointer(base + p.offset))
Rob Pike76f6ee52011-10-20 12:58:28 -0700501 *v = sp
Rob Pikeaaa3a622010-03-20 22:32:34 -0700502 return nil
503}
504
505// Decode a slice of bytes ([]byte).
Rob Pikea17fdd92011-11-02 12:43:05 -0700506func (o *Buffer) dec_slice_byte(p *Properties, base uintptr) 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 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700511 v := (*[]byte)(unsafe.Pointer(base + p.offset))
512 *v = b
Rob Pikeaaa3a622010-03-20 22:32:34 -0700513 return nil
514}
515
516// Decode a slice of bools ([]bool).
Rob Pikea17fdd92011-11-02 12:43:05 -0700517func (o *Buffer) dec_slice_bool(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700518 u, err := p.valDec(o)
519 if err != nil {
520 return err
521 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700522 v := (*[]bool)(unsafe.Pointer(base + p.offset))
523 *v = append(*v, u != 0)
David Symonds5b7775e2010-12-01 10:09:04 +1100524 return nil
525}
526
527// Decode a slice of bools ([]bool) in packed format.
Rob Pikea17fdd92011-11-02 12:43:05 -0700528func (o *Buffer) dec_slice_packed_bool(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700529 v := (*[]bool)(unsafe.Pointer(base + p.offset))
David Symonds5b7775e2010-12-01 10:09:04 +1100530
531 nn, err := o.DecodeVarint()
532 if err != nil {
533 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700534 }
David Symonds5b7775e2010-12-01 10:09:04 +1100535 nb := int(nn) // number of bytes of encoded bools
536
Rob Pike76f6ee52011-10-20 12:58:28 -0700537 y := *v
David Symonds5b7775e2010-12-01 10:09:04 +1100538 for i := 0; i < nb; i++ {
539 u, err := p.valDec(o)
540 if err != nil {
541 return err
542 }
543 y = append(y, u != 0)
544 }
545
Rob Pike76f6ee52011-10-20 12:58:28 -0700546 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700547 return nil
548}
549
550// Decode a slice of int32s ([]int32).
Rob Pikea17fdd92011-11-02 12:43:05 -0700551func (o *Buffer) dec_slice_int32(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700552 u, err := p.valDec(o)
553 if err != nil {
554 return err
555 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700556 v := (*[]int32)(unsafe.Pointer(base + p.offset))
557 *v = append(*v, int32(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100558 return nil
559}
560
561// Decode a slice of int32s ([]int32) in packed format.
Rob Pikea17fdd92011-11-02 12:43:05 -0700562func (o *Buffer) dec_slice_packed_int32(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700563 v := (*[]int32)(unsafe.Pointer(base + p.offset))
David Symonds5b7775e2010-12-01 10:09:04 +1100564
565 nn, err := o.DecodeVarint()
566 if err != nil {
567 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700568 }
David Symonds5b7775e2010-12-01 10:09:04 +1100569 nb := int(nn) // number of bytes of encoded int32s
570
Rob Pike76f6ee52011-10-20 12:58:28 -0700571 y := *v
David Symonds5b7775e2010-12-01 10:09:04 +1100572
573 fin := o.index + nb
574 for o.index < fin {
575 u, err := p.valDec(o)
576 if err != nil {
577 return err
578 }
579 y = append(y, int32(u))
580 }
581
Rob Pike76f6ee52011-10-20 12:58:28 -0700582 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700583 return nil
584}
585
586// Decode a slice of int64s ([]int64).
Rob Pikea17fdd92011-11-02 12:43:05 -0700587func (o *Buffer) dec_slice_int64(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700588 u, err := p.valDec(o)
589 if err != nil {
590 return err
591 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700592 v := (*[]int64)(unsafe.Pointer(base + p.offset))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700593
Rob Pike76f6ee52011-10-20 12:58:28 -0700594 y := *v
595 *v = append(y, int64(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100596 return nil
597}
598
599// Decode a slice of int64s ([]int64) in packed format.
Rob Pikea17fdd92011-11-02 12:43:05 -0700600func (o *Buffer) dec_slice_packed_int64(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700601 v := (*[]int64)(unsafe.Pointer(base + p.offset))
David Symonds5b7775e2010-12-01 10:09:04 +1100602
603 nn, err := o.DecodeVarint()
604 if err != nil {
605 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700606 }
David Symonds5b7775e2010-12-01 10:09:04 +1100607 nb := int(nn) // number of bytes of encoded int64s
608
Rob Pike76f6ee52011-10-20 12:58:28 -0700609 y := *v
David Symonds5b7775e2010-12-01 10:09:04 +1100610 fin := o.index + nb
611 for o.index < fin {
612 u, err := p.valDec(o)
613 if err != nil {
614 return err
615 }
616 y = append(y, int64(u))
617 }
618
Rob Pike76f6ee52011-10-20 12:58:28 -0700619 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700620 return nil
621}
622
623// Decode a slice of strings ([]string).
Rob Pikea17fdd92011-11-02 12:43:05 -0700624func (o *Buffer) dec_slice_string(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700625 s, err := o.DecodeStringBytes()
626 if err != nil {
627 return err
628 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700629 v := (*[]string)(unsafe.Pointer(base + p.offset))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700630
Rob Pike76f6ee52011-10-20 12:58:28 -0700631 y := *v
632 *v = append(y, s)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700633 return nil
634}
635
636// Decode a slice of slice of bytes ([][]byte).
Rob Pikea17fdd92011-11-02 12:43:05 -0700637func (o *Buffer) dec_slice_slice_byte(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700638 b, err := o.DecodeRawBytes(true)
639 if err != nil {
640 return err
641 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700642 v := (*[][]byte)(unsafe.Pointer(base + p.offset))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700643
Rob Pike76f6ee52011-10-20 12:58:28 -0700644 y := *v
645 *v = append(y, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700646 return nil
647}
648
649// Decode a group.
Rob Pikea17fdd92011-11-02 12:43:05 -0700650func (o *Buffer) dec_struct_group(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700651 ptr := (**struct{})(unsafe.Pointer(base + p.offset))
David Symonds6a6f82c2012-08-22 09:18:54 +1000652 bas := reflect.New(p.stype).Pointer()
Rob Pike7a788132012-02-14 08:14:14 +1100653 structv := unsafe.Pointer(bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700654 *ptr = (*struct{})(structv)
655
David Symondsc0287172012-08-15 11:10:30 +1000656 err := o.unmarshalType(p.stype, p.sprop, true, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700657
658 return err
659}
660
661// Decode an embedded message.
Rob Pikea17fdd92011-11-02 12:43:05 -0700662func (o *Buffer) dec_struct_message(p *Properties, base uintptr) (err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700663 raw, e := o.DecodeRawBytes(false)
664 if e != nil {
665 return e
666 }
667
668 ptr := (**struct{})(unsafe.Pointer(base + p.offset))
David Symonds6a6f82c2012-08-22 09:18:54 +1000669 bas := reflect.New(p.stype).Pointer()
David Symondsa80b2822012-03-14 14:31:25 +1100670 structp := unsafe.Pointer(bas)
671 *ptr = (*struct{})(structp)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700672
673 // If the object can unmarshal itself, let it.
David Symondsa80b2822012-03-14 14:31:25 +1100674 if p.isMarshaler {
David Symonds6a6f82c2012-08-22 09:18:54 +1000675 iv := reflect.NewAt(p.stype, structp).Interface()
David Symondsa80b2822012-03-14 14:31:25 +1100676 return iv.(Unmarshaler).Unmarshal(raw)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700677 }
678
679 obuf := o.buf
680 oi := o.index
681 o.buf = raw
682 o.index = 0
683
David Symondsc0287172012-08-15 11:10:30 +1000684 err = o.unmarshalType(p.stype, p.sprop, false, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700685 o.buf = obuf
686 o.index = oi
687
688 return err
689}
690
691// Decode a slice of embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700692func (o *Buffer) dec_slice_struct_message(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700693 return o.dec_slice_struct(p, false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700694}
695
696// Decode a slice of embedded groups.
Rob Pikea17fdd92011-11-02 12:43:05 -0700697func (o *Buffer) dec_slice_struct_group(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700698 return o.dec_slice_struct(p, true, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700699}
700
701// Decode a slice of structs ([]*struct).
Rob Pikea17fdd92011-11-02 12:43:05 -0700702func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700703
Rob Pike76f6ee52011-10-20 12:58:28 -0700704 v := (*[]*struct{})(unsafe.Pointer(base + p.offset))
705 y := *v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700706
David Symonds6a6f82c2012-08-22 09:18:54 +1000707 bas := reflect.New(p.stype).Pointer()
David Symondsa80b2822012-03-14 14:31:25 +1100708 structp := unsafe.Pointer(bas)
709 y = append(y, (*struct{})(structp))
Rob Pike76f6ee52011-10-20 12:58:28 -0700710 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700711
712 if is_group {
David Symondsc0287172012-08-15 11:10:30 +1000713 err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700714 return err
715 }
716
David Symondsc0287172012-08-15 11:10:30 +1000717 raw, err := o.DecodeRawBytes(false)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700718 if err != nil {
719 return err
720 }
721
722 // If the object can unmarshal itself, let it.
David Symondsa80b2822012-03-14 14:31:25 +1100723 if p.isUnmarshaler {
David Symonds6a6f82c2012-08-22 09:18:54 +1000724 iv := reflect.NewAt(p.stype, structp).Interface()
David Symondsa80b2822012-03-14 14:31:25 +1100725 return iv.(Unmarshaler).Unmarshal(raw)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700726 }
727
728 obuf := o.buf
729 oi := o.index
730 o.buf = raw
731 o.index = 0
732
David Symondsc0287172012-08-15 11:10:30 +1000733 err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700734
735 o.buf = obuf
736 o.index = oi
737
738 return err
739}