blob: b2a27b9877170e823d951a31ba18fbc869b26875 [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"
44 "runtime"
45 "unsafe"
46)
47
48// ErrWrongType occurs when the wire encoding for the field disagrees with
49// that specified in the type being decoded. This is usually caused by attempting
50// to convert an encoded protocol buffer into a struct of the wrong type.
Rob Pikea17fdd92011-11-02 12:43:05 -070051var ErrWrongType = errors.New("field/encoding mismatch: wrong type for field")
Rob Pikeaaa3a622010-03-20 22:32:34 -070052
53// The fundamental decoders that interpret bytes on the wire.
54// Those that take integer types all return uint64 and are
55// therefore of type valueDecoder.
56
57// DecodeVarint reads a varint-encoded integer from the slice.
58// It returns the integer and the number of bytes consumed, or
59// zero if there is not enough.
60// This is the format for the
61// int32, int64, uint32, uint64, bool, and enum
62// protocol buffer types.
63func DecodeVarint(buf []byte) (x uint64, n int) {
64 // x, n already 0
65 for shift := uint(0); ; shift += 7 {
66 if n >= len(buf) {
67 return 0, 0
68 }
69 b := uint64(buf[n])
70 n++
71 x |= (b & 0x7F) << shift
72 if (b & 0x80) == 0 {
73 break
74 }
75 }
76 return x, n
77}
78
79// DecodeVarint reads a varint-encoded integer from the Buffer.
80// This is the format for the
81// int32, int64, uint32, uint64, bool, and enum
82// protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -070083func (p *Buffer) DecodeVarint() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -070084 // x, err already 0
85
86 i := p.index
87 l := len(p.buf)
88
89 for shift := uint(0); ; shift += 7 {
90 if i >= l {
91 err = io.ErrUnexpectedEOF
92 return
93 }
94 b := p.buf[i]
95 i++
96 x |= (uint64(b) & 0x7F) << shift
97 if b < 0x80 {
98 break
99 }
100 }
101 p.index = i
102 return
103}
104
105// DecodeFixed64 reads a 64-bit integer from the Buffer.
106// This is the format for the
107// fixed64, sfixed64, and double protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700108func (p *Buffer) DecodeFixed64() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700109 // x, err already 0
110 i := p.index + 8
111 if i > len(p.buf) {
112 err = io.ErrUnexpectedEOF
113 return
114 }
115 p.index = i
116
117 x = uint64(p.buf[i-8])
118 x |= uint64(p.buf[i-7]) << 8
119 x |= uint64(p.buf[i-6]) << 16
120 x |= uint64(p.buf[i-5]) << 24
121 x |= uint64(p.buf[i-4]) << 32
122 x |= uint64(p.buf[i-3]) << 40
123 x |= uint64(p.buf[i-2]) << 48
124 x |= uint64(p.buf[i-1]) << 56
125 return
126}
127
128// DecodeFixed32 reads a 32-bit integer from the Buffer.
129// This is the format for the
130// fixed32, sfixed32, and float protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700131func (p *Buffer) DecodeFixed32() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700132 // x, err already 0
133 i := p.index + 4
134 if i > len(p.buf) {
135 err = io.ErrUnexpectedEOF
136 return
137 }
138 p.index = i
139
140 x = uint64(p.buf[i-4])
141 x |= uint64(p.buf[i-3]) << 8
142 x |= uint64(p.buf[i-2]) << 16
143 x |= uint64(p.buf[i-1]) << 24
144 return
145}
146
147// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
148// from the Buffer.
149// This is the format used for the sint64 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700150func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700151 x, err = p.DecodeVarint()
152 if err != nil {
153 return
154 }
155 x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
156 return
157}
158
159// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
160// from the Buffer.
161// This is the format used for the sint32 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700162func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700163 x, err = p.DecodeVarint()
164 if err != nil {
165 return
166 }
167 x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
168 return
169}
170
171// These are not ValueDecoders: they produce an array of bytes or a string.
172// bytes, embedded messages
173
174// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
175// This is the format used for the bytes protocol buffer
176// type and for embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700177func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700178 n, err := p.DecodeVarint()
179 if err != nil {
180 return
181 }
182
183 nb := int(n)
David Symonds22ac1502012-01-18 12:37:12 +1100184 if nb < 0 {
185 return nil, fmt.Errorf("proto: bad byte length %d", nb)
186 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700187 if p.index+nb > len(p.buf) {
David Symonds22ac1502012-01-18 12:37:12 +1100188 return nil, io.ErrUnexpectedEOF
Rob Pikeaaa3a622010-03-20 22:32:34 -0700189 }
190
191 if !alloc {
192 // todo: check if can get more uses of alloc=false
193 buf = p.buf[p.index : p.index+nb]
194 p.index += nb
195 return
196 }
197
198 buf = make([]byte, nb)
199 copy(buf, p.buf[p.index:])
200 p.index += nb
201 return
202}
203
204// DecodeStringBytes reads an encoded string from the Buffer.
205// This is the format used for the proto2 string type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700206func (p *Buffer) DecodeStringBytes() (s string, err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700207 buf, err := p.DecodeRawBytes(false)
208 if err != nil {
209 return
210 }
211 return string(buf), nil
212}
213
214// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
215// If the protocol buffer has extensions, and the field matches, add it as an extension.
216// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
Rob Pikea17fdd92011-11-02 12:43:05 -0700217func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700218
219 oi := o.index
220
221 err := o.skip(t, tag, wire)
222 if err != nil {
223 return err
224 }
225
226 x := fieldIndex(t, "XXX_unrecognized")
227 if x == nil {
228 return nil
229 }
230
231 p := propByIndex(t, x)
232 ptr := (*[]byte)(unsafe.Pointer(base + p.offset))
233
234 if *ptr == nil {
235 // This is the first skipped element,
236 // allocate a new buffer.
237 *ptr = o.bufalloc()
238 }
239
240 // Add the skipped field to struct field
241 obuf := o.buf
242
243 o.buf = *ptr
244 o.EncodeVarint(uint64(tag<<3 | wire))
Rob Pike99fa2b62010-12-02 10:39:42 -0800245 *ptr = append(o.buf, obuf[oi:o.index]...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700246
247 o.buf = obuf
248
249 return nil
250}
251
252// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
Rob Pikea17fdd92011-11-02 12:43:05 -0700253func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700254
255 var u uint64
Rob Pikea17fdd92011-11-02 12:43:05 -0700256 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700257
258 switch wire {
259 case WireVarint:
260 _, err = o.DecodeVarint()
261 case WireFixed64:
262 _, err = o.DecodeFixed64()
263 case WireBytes:
264 _, err = o.DecodeRawBytes(false)
265 case WireFixed32:
266 _, err = o.DecodeFixed32()
267 case WireStartGroup:
268 for {
269 u, err = o.DecodeVarint()
270 if err != nil {
271 break
272 }
273 fwire := int(u & 0x7)
274 if fwire == WireEndGroup {
275 break
276 }
277 ftag := int(u >> 3)
278 err = o.skip(t, ftag, fwire)
279 if err != nil {
280 break
281 }
282 }
283 default:
David Symonds22ac1502012-01-18 12:37:12 +1100284 err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700285 }
286 return err
287}
288
289// Unmarshaler is the interface representing objects that can unmarshal themselves.
290type 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.
Rob Pikea17fdd92011-11-02 12:43:05 -0700297func Unmarshal(buf []byte, pb interface{}) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700298 // If the object can unmarshal itself, let it.
299 if u, ok := pb.(Unmarshaler); ok {
300 return u.Unmarshal(buf)
301 }
302
303 return NewBuffer(buf).Unmarshal(pb)
304}
305
306// Unmarshal parses the protocol buffer representation in the
307// Buffer and places the decoded result in pb. If the struct
308// underlying pb does not match the data in the buffer, the results can be
309// unpredictable.
Rob Pikea17fdd92011-11-02 12:43:05 -0700310func (p *Buffer) Unmarshal(pb interface{}) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700311 // If the object can unmarshal itself, let it.
312 if u, ok := pb.(Unmarshaler); ok {
313 err := u.Unmarshal(p.buf[p.index:])
314 p.index = len(p.buf)
315 return err
316 }
317
318 mstat := runtime.MemStats.Mallocs
319
320 typ, base, err := getbase(pb)
321 if err != nil {
322 return err
323 }
324
325 err = p.unmarshalType(typ, false, base)
326
327 mstat = runtime.MemStats.Mallocs - mstat
328 stats.Dmalloc += mstat
329 stats.Decode++
330
331 return err
332}
333
334// unmarshalType does the work of unmarshaling a structure.
Rob Pikea17fdd92011-11-02 12:43:05 -0700335func (o *Buffer) unmarshalType(t reflect.Type, is_group bool, base uintptr) error {
Rob Pike97e934d2011-04-11 12:52:49 -0700336 st := t.Elem()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700337 prop := GetProperties(st)
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700338 required, reqFields := prop.reqCount, uint64(0)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700339
Rob Pikea17fdd92011-11-02 12:43:05 -0700340 var err error
Rob Pikeaaa3a622010-03-20 22:32:34 -0700341 for err == nil && o.index < len(o.buf) {
342 oi := o.index
343 var u uint64
344 u, err = o.DecodeVarint()
345 if err != nil {
346 break
347 }
348 wire := int(u & 0x7)
349 if wire == WireEndGroup {
350 if is_group {
351 return nil // input is satisfied
352 }
353 return ErrWrongType
354 }
355 tag := int(u >> 3)
356 fieldnum, ok := prop.tags[tag]
357 if !ok {
358 // Maybe it's an extension?
Rob Pike76f6ee52011-10-20 12:58:28 -0700359 o.ptr = base // copy the address here to avoid a heap allocation.
Rob Pikeaaa3a622010-03-20 22:32:34 -0700360 iv := unsafe.Unreflect(t, unsafe.Pointer(&o.ptr))
361 if e, ok := iv.(extendableProto); ok && isExtensionField(e, int32(tag)) {
362 if err = o.skip(st, tag, wire); err == nil {
David Symonds1d72f7a2011-08-19 18:28:52 +1000363 e.ExtensionMap()[int32(tag)] = Extension{enc: append([]byte(nil), o.buf[oi:o.index]...)}
Rob Pikeaaa3a622010-03-20 22:32:34 -0700364 }
365 continue
366 }
367 err = o.skipAndSave(st, tag, wire, base)
368 continue
369 }
370 p := prop.Prop[fieldnum]
371
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700372 if p.dec == nil {
373 fmt.Fprintf(os.Stderr, "no protobuf decoder for %s.%s\n", t, st.Field(fieldnum).Name)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700374 continue
375 }
David Symonds5b7775e2010-12-01 10:09:04 +1100376 dec := p.dec
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700377 if wire != WireStartGroup && wire != p.WireType {
David Symonds5b7775e2010-12-01 10:09:04 +1100378 if wire == WireBytes && p.packedDec != nil {
379 // a packable field
380 dec = p.packedDec
381 } else {
382 err = ErrWrongType
383 continue
384 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700385 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700386 err = dec(o, p, base)
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700387 if err == nil && p.Required {
388 // Successfully decoded a required field.
389 if tag <= 64 {
390 // use bitmap for fields 1-64 to catch field reuse.
391 var mask uint64 = 1 << uint64(tag-1)
392 if reqFields&mask == 0 {
393 // new required field
394 reqFields |= mask
395 required--
396 }
397 } else {
398 // This is imprecise. It can be fooled by a required field
399 // with a tag > 64 that is encoded twice; that's very rare.
400 // A fully correct implementation would require allocating
401 // a data structure, which we would like to avoid.
402 required--
403 }
404 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700405 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700406 if err == nil {
407 if is_group {
408 return io.ErrUnexpectedEOF
409 }
410 if required > 0 {
David Symonds5b7775e2010-12-01 10:09:04 +1100411 return &ErrRequiredNotSet{st}
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700412 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700413 }
414 return err
415}
416
Rob Pikeaaa3a622010-03-20 22:32:34 -0700417// Individual type decoders
418// For each,
419// u is the decoded value,
420// v is a pointer to the field (pointer) in the struct
Rob Pike76f6ee52011-10-20 12:58:28 -0700421
422// Sizes of the pools to allocate inside the Buffer.
Rob Pike97edc7e2011-10-20 15:53:19 -0700423// The goal is modest amortization and allocation
424// on at least 16-byte boundaries.
Rob Pike76f6ee52011-10-20 12:58:28 -0700425const (
David Symonds049646b2011-10-21 11:13:45 +1100426 boolPoolSize = 16
Rob Pike76f6ee52011-10-20 12:58:28 -0700427 int32PoolSize = 8
428 int64PoolSize = 4
429)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700430
431// Decode a bool.
Rob Pikea17fdd92011-11-02 12:43:05 -0700432func (o *Buffer) dec_bool(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700433 u, err := p.valDec(o)
434 if err != nil {
435 return err
436 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700437 if len(o.bools) == 0 {
438 o.bools = make([]bool, boolPoolSize)
439 }
440 o.bools[0] = u != 0
441 v := (**bool)(unsafe.Pointer(base + p.offset))
442 *v = &o.bools[0]
443 o.bools = o.bools[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700444 return nil
445}
446
447// Decode an int32.
Rob Pikea17fdd92011-11-02 12:43:05 -0700448func (o *Buffer) dec_int32(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700449 u, err := p.valDec(o)
450 if err != nil {
451 return err
452 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700453 if len(o.int32s) == 0 {
454 o.int32s = make([]int32, int32PoolSize)
455 }
456 o.int32s[0] = int32(u)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700457 v := (**int32)(unsafe.Pointer(base + p.offset))
Rob Pike76f6ee52011-10-20 12:58:28 -0700458 *v = &o.int32s[0]
459 o.int32s = o.int32s[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700460 return nil
461}
462
463// Decode an int64.
Rob Pikea17fdd92011-11-02 12:43:05 -0700464func (o *Buffer) dec_int64(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700465 u, err := p.valDec(o)
466 if err != nil {
467 return err
468 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700469 if len(o.int64s) == 0 {
470 o.int64s = make([]int64, int64PoolSize)
471 }
472 o.int64s[0] = int64(u)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700473 v := (**int64)(unsafe.Pointer(base + p.offset))
Rob Pike76f6ee52011-10-20 12:58:28 -0700474 *v = &o.int64s[0]
475 o.int64s = o.int64s[1:]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700476 return nil
477}
478
479// Decode a string.
Rob Pikea17fdd92011-11-02 12:43:05 -0700480func (o *Buffer) dec_string(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700481 s, err := o.DecodeStringBytes()
482 if err != nil {
483 return err
484 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700485 sp := new(string)
486 *sp = s
Rob Pikeaaa3a622010-03-20 22:32:34 -0700487 v := (**string)(unsafe.Pointer(base + p.offset))
Rob Pike76f6ee52011-10-20 12:58:28 -0700488 *v = sp
Rob Pikeaaa3a622010-03-20 22:32:34 -0700489 return nil
490}
491
492// Decode a slice of bytes ([]byte).
Rob Pikea17fdd92011-11-02 12:43:05 -0700493func (o *Buffer) dec_slice_byte(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700494 b, err := o.DecodeRawBytes(true)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700495 if err != nil {
496 return err
497 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700498 v := (*[]byte)(unsafe.Pointer(base + p.offset))
499 *v = b
Rob Pikeaaa3a622010-03-20 22:32:34 -0700500 return nil
501}
502
503// Decode a slice of bools ([]bool).
Rob Pikea17fdd92011-11-02 12:43:05 -0700504func (o *Buffer) dec_slice_bool(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700505 u, err := p.valDec(o)
506 if err != nil {
507 return err
508 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700509 v := (*[]bool)(unsafe.Pointer(base + p.offset))
510 *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.
Rob Pikea17fdd92011-11-02 12:43:05 -0700515func (o *Buffer) dec_slice_packed_bool(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700516 v := (*[]bool)(unsafe.Pointer(base + p.offset))
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).
Rob Pikea17fdd92011-11-02 12:43:05 -0700538func (o *Buffer) dec_slice_int32(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700539 u, err := p.valDec(o)
540 if err != nil {
541 return err
542 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700543 v := (*[]int32)(unsafe.Pointer(base + p.offset))
544 *v = append(*v, int32(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100545 return nil
546}
547
548// Decode a slice of int32s ([]int32) in packed format.
Rob Pikea17fdd92011-11-02 12:43:05 -0700549func (o *Buffer) dec_slice_packed_int32(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700550 v := (*[]int32)(unsafe.Pointer(base + p.offset))
David Symonds5b7775e2010-12-01 10:09:04 +1100551
552 nn, err := o.DecodeVarint()
553 if err != nil {
554 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700555 }
David Symonds5b7775e2010-12-01 10:09:04 +1100556 nb := int(nn) // number of bytes of encoded int32s
557
Rob Pike76f6ee52011-10-20 12:58:28 -0700558 y := *v
David Symonds5b7775e2010-12-01 10:09:04 +1100559
560 fin := o.index + nb
561 for o.index < fin {
562 u, err := p.valDec(o)
563 if err != nil {
564 return err
565 }
566 y = append(y, int32(u))
567 }
568
Rob Pike76f6ee52011-10-20 12:58:28 -0700569 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700570 return nil
571}
572
573// Decode a slice of int64s ([]int64).
Rob Pikea17fdd92011-11-02 12:43:05 -0700574func (o *Buffer) dec_slice_int64(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700575 u, err := p.valDec(o)
576 if err != nil {
577 return err
578 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700579 v := (*[]int64)(unsafe.Pointer(base + p.offset))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700580
Rob Pike76f6ee52011-10-20 12:58:28 -0700581 y := *v
582 *v = append(y, int64(u))
David Symonds5b7775e2010-12-01 10:09:04 +1100583 return nil
584}
585
586// Decode a slice of int64s ([]int64) in packed format.
Rob Pikea17fdd92011-11-02 12:43:05 -0700587func (o *Buffer) dec_slice_packed_int64(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700588 v := (*[]int64)(unsafe.Pointer(base + p.offset))
David Symonds5b7775e2010-12-01 10:09:04 +1100589
590 nn, err := o.DecodeVarint()
591 if err != nil {
592 return err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700593 }
David Symonds5b7775e2010-12-01 10:09:04 +1100594 nb := int(nn) // number of bytes of encoded int64s
595
Rob Pike76f6ee52011-10-20 12:58:28 -0700596 y := *v
David Symonds5b7775e2010-12-01 10:09:04 +1100597 fin := o.index + nb
598 for o.index < fin {
599 u, err := p.valDec(o)
600 if err != nil {
601 return err
602 }
603 y = append(y, int64(u))
604 }
605
Rob Pike76f6ee52011-10-20 12:58:28 -0700606 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700607 return nil
608}
609
610// Decode a slice of strings ([]string).
Rob Pikea17fdd92011-11-02 12:43:05 -0700611func (o *Buffer) dec_slice_string(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700612 s, err := o.DecodeStringBytes()
613 if err != nil {
614 return err
615 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700616 v := (*[]string)(unsafe.Pointer(base + p.offset))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700617
Rob Pike76f6ee52011-10-20 12:58:28 -0700618 y := *v
619 *v = append(y, s)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700620 return nil
621}
622
623// Decode a slice of slice of bytes ([][]byte).
Rob Pikea17fdd92011-11-02 12:43:05 -0700624func (o *Buffer) dec_slice_slice_byte(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700625 b, err := o.DecodeRawBytes(true)
626 if err != nil {
627 return err
628 }
Rob Pike76f6ee52011-10-20 12:58:28 -0700629 v := (*[][]byte)(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, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700633 return nil
634}
635
636// Decode a group.
Rob Pikea17fdd92011-11-02 12:43:05 -0700637func (o *Buffer) dec_struct_group(p *Properties, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700638 ptr := (**struct{})(unsafe.Pointer(base + p.offset))
Rob Pike97e934d2011-04-11 12:52:49 -0700639 typ := p.stype.Elem()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700640 structv := unsafe.New(typ)
641 bas := uintptr(structv)
642 *ptr = (*struct{})(structv)
643
644 err := o.unmarshalType(p.stype, true, bas)
645
646 return err
647}
648
649// Decode an embedded message.
Rob Pikea17fdd92011-11-02 12:43:05 -0700650func (o *Buffer) dec_struct_message(p *Properties, base uintptr) (err error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700651 raw, e := o.DecodeRawBytes(false)
652 if e != nil {
653 return e
654 }
655
656 ptr := (**struct{})(unsafe.Pointer(base + p.offset))
Rob Pike97e934d2011-04-11 12:52:49 -0700657 typ := p.stype.Elem()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700658 structv := unsafe.New(typ)
659 bas := uintptr(structv)
660 *ptr = (*struct{})(structv)
661
662 // If the object can unmarshal itself, let it.
663 iv := unsafe.Unreflect(p.stype, unsafe.Pointer(ptr))
664 if u, ok := iv.(Unmarshaler); ok {
665 return u.Unmarshal(raw)
666 }
667
668 obuf := o.buf
669 oi := o.index
670 o.buf = raw
671 o.index = 0
672
673 err = o.unmarshalType(p.stype, false, bas)
674 o.buf = obuf
675 o.index = oi
676
677 return err
678}
679
680// Decode a slice of embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700681func (o *Buffer) dec_slice_struct_message(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700682 return o.dec_slice_struct(p, false, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700683}
684
685// Decode a slice of embedded groups.
Rob Pikea17fdd92011-11-02 12:43:05 -0700686func (o *Buffer) dec_slice_struct_group(p *Properties, base uintptr) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700687 return o.dec_slice_struct(p, true, base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700688}
689
690// Decode a slice of structs ([]*struct).
Rob Pikea17fdd92011-11-02 12:43:05 -0700691func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base uintptr) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700692
Rob Pike76f6ee52011-10-20 12:58:28 -0700693 v := (*[]*struct{})(unsafe.Pointer(base + p.offset))
694 y := *v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700695
Rob Pike97e934d2011-04-11 12:52:49 -0700696 typ := p.stype.Elem()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700697 structv := unsafe.New(typ)
698 bas := uintptr(structv)
David Symonds5b7775e2010-12-01 10:09:04 +1100699 y = append(y, (*struct{})(structv))
Rob Pike76f6ee52011-10-20 12:58:28 -0700700 *v = y
Rob Pikeaaa3a622010-03-20 22:32:34 -0700701
702 if is_group {
703 err := o.unmarshalType(p.stype, is_group, bas)
704 return err
705 }
706
707 raw, err := o.DecodeRawBytes(true)
708 if err != nil {
709 return err
710 }
711
712 // If the object can unmarshal itself, let it.
David Symonds5b7775e2010-12-01 10:09:04 +1100713 iv := unsafe.Unreflect(p.stype, unsafe.Pointer(&y[len(y)-1]))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700714 if u, ok := iv.(Unmarshaler); ok {
715 return u.Unmarshal(raw)
716 }
717
718 obuf := o.buf
719 oi := o.index
720 o.buf = raw
721 o.index = 0
722
723 err = o.unmarshalType(p.stype, is_group, bas)
724
725 o.buf = obuf
726 o.index = oi
727
728 return err
729}