blob: 13fd835d28e540fca3b2e2f011d33ca8effc74e0 [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 encoding data into the wire format for protocol buffers.
36 */
37
38import (
39 "bytes"
40 "os"
41 "reflect"
42 "runtime"
43 "unsafe"
44)
45
46// ErrRequiredNotSet is the error returned if Marshal is called with
47// a protocol buffer struct whose required fields have not
Rob Pikec6d8e4a2010-07-28 15:34:32 -070048// all been initialized. It is also the error returned if Unmarshal is
49// called with an encoded protocol buffer that does not include all the
50// required fields.
David Symonds5b7775e2010-12-01 10:09:04 +110051type ErrRequiredNotSet struct {
52 t reflect.Type
53}
54
55func (e *ErrRequiredNotSet) String() string {
56 return "required fields not set in " + e.t.String()
57}
Rob Pikeaaa3a622010-03-20 22:32:34 -070058
59// ErrRepeatedHasNil is the error returned if Marshal is called with
60// a protocol buffer struct with a repeated field containing a nil element.
61var ErrRepeatedHasNil = os.NewError("repeated field has nil")
62
63// ErrNil is the error returned if Marshal is called with nil.
64var ErrNil = os.NewError("marshal called with nil")
65
66// The fundamental encoders that put bytes on the wire.
67// Those that take integer types all accept uint64 and are
68// therefore of type valueEncoder.
69
David Symonds4fee3b12010-11-11 10:00:13 +110070const maxVarintBytes = 10 // maximum length of a varint
71
Rob Pikeaaa3a622010-03-20 22:32:34 -070072// EncodeVarint returns the varint encoding of x.
73// This is the format for the
74// int32, int64, uint32, uint64, bool, and enum
75// protocol buffer types.
76// Not used by the package itself, but helpful to clients
77// wishing to use the same encoding.
78func EncodeVarint(x uint64) []byte {
David Symonds4fee3b12010-11-11 10:00:13 +110079 var buf [maxVarintBytes]byte
Rob Pikeaaa3a622010-03-20 22:32:34 -070080 var n int
81 for n = 0; x > 127; n++ {
82 buf[n] = 0x80 | uint8(x&0x7F)
83 x >>= 7
84 }
85 buf[n] = uint8(x)
86 n++
87 return buf[0:n]
88}
89
David Symonds4fee3b12010-11-11 10:00:13 +110090var emptyBytes [maxVarintBytes]byte
91
Rob Pikeaaa3a622010-03-20 22:32:34 -070092// EncodeVarint writes a varint-encoded integer to the Buffer.
93// This is the format for the
94// int32, int64, uint32, uint64, bool, and enum
95// protocol buffer types.
96func (p *Buffer) EncodeVarint(x uint64) os.Error {
97 l := len(p.buf)
David Symonds4fee3b12010-11-11 10:00:13 +110098 if l+maxVarintBytes > cap(p.buf) { // not necessary except for performance
99 p.buf = append(p.buf, emptyBytes[:]...)
100 } else {
101 p.buf = p.buf[:l+maxVarintBytes]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700102 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700103
David Symonds4fee3b12010-11-11 10:00:13 +1100104 for x >= 1<<7 {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700105 p.buf[l] = uint8(x&0x7f | 0x80)
106 l++
107 x >>= 7
108 }
109 p.buf[l] = uint8(x)
David Symonds4fee3b12010-11-11 10:00:13 +1100110 p.buf = p.buf[:l+1]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700111 return nil
112}
113
114// EncodeFixed64 writes a 64-bit integer to the Buffer.
115// This is the format for the
116// fixed64, sfixed64, and double protocol buffer types.
117func (p *Buffer) EncodeFixed64(x uint64) os.Error {
David Symonds4fee3b12010-11-11 10:00:13 +1100118 const fixed64Bytes = 8
Rob Pikeaaa3a622010-03-20 22:32:34 -0700119 l := len(p.buf)
David Symonds4fee3b12010-11-11 10:00:13 +1100120 if l+fixed64Bytes > cap(p.buf) { // not necessary except for performance
121 p.buf = append(p.buf, emptyBytes[:fixed64Bytes]...)
122 } else {
123 p.buf = p.buf[:l+fixed64Bytes]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700124 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700125
126 p.buf[l] = uint8(x)
127 p.buf[l+1] = uint8(x >> 8)
128 p.buf[l+2] = uint8(x >> 16)
129 p.buf[l+3] = uint8(x >> 24)
130 p.buf[l+4] = uint8(x >> 32)
131 p.buf[l+5] = uint8(x >> 40)
132 p.buf[l+6] = uint8(x >> 48)
133 p.buf[l+7] = uint8(x >> 56)
134 return nil
135}
136
137// EncodeFixed32 writes a 32-bit integer to the Buffer.
138// This is the format for the
139// fixed32, sfixed32, and float protocol buffer types.
140func (p *Buffer) EncodeFixed32(x uint64) os.Error {
David Symonds4fee3b12010-11-11 10:00:13 +1100141 const fixed32Bytes = 4
Rob Pikeaaa3a622010-03-20 22:32:34 -0700142 l := len(p.buf)
David Symonds4fee3b12010-11-11 10:00:13 +1100143 if l+fixed32Bytes > cap(p.buf) { // not necessary except for performance
144 p.buf = append(p.buf, emptyBytes[:fixed32Bytes]...)
145 } else {
146 p.buf = p.buf[:l+fixed32Bytes]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700147 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700148
149 p.buf[l] = uint8(x)
150 p.buf[l+1] = uint8(x >> 8)
151 p.buf[l+2] = uint8(x >> 16)
152 p.buf[l+3] = uint8(x >> 24)
153 return nil
154}
155
156// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
157// to the Buffer.
158// This is the format used for the sint64 protocol buffer type.
159func (p *Buffer) EncodeZigzag64(x uint64) os.Error {
160 // use signed number to get arithmetic right shift.
161 return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
162}
163
164// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
165// to the Buffer.
166// This is the format used for the sint32 protocol buffer type.
167func (p *Buffer) EncodeZigzag32(x uint64) os.Error {
168 // use signed number to get arithmetic right shift.
169 return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
170}
171
172// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
173// This is the format used for the bytes protocol buffer
174// type and for embedded messages.
175func (p *Buffer) EncodeRawBytes(b []byte) os.Error {
176 lb := len(b)
177 p.EncodeVarint(uint64(lb))
178 p.buf = bytes.Add(p.buf, b)
179 return nil
180}
181
182// EncodeStringBytes writes an encoded string to the Buffer.
183// This is the format used for the proto2 string type.
184func (p *Buffer) EncodeStringBytes(s string) os.Error {
185
186 // this works because strings and slices are the same.
187 y := *(*[]byte)(unsafe.Pointer(&s))
188 p.EncodeRawBytes(y)
189 return nil
190}
191
192// Marshaler is the interface representing objects that can marshal themselves.
193type Marshaler interface {
194 Marshal() ([]byte, os.Error)
195}
196
197// Marshal takes the protocol buffer struct represented by pb
198// and encodes it into the wire format, returning the data.
199func Marshal(pb interface{}) ([]byte, os.Error) {
200 // Can the object marshal itself?
201 if m, ok := pb.(Marshaler); ok {
202 return m.Marshal()
203 }
204 p := NewBuffer(nil)
205 err := p.Marshal(pb)
206 if err != nil {
207 return nil, err
208 }
209 return p.buf, err
210}
211
212// Marshal takes the protocol buffer struct represented by pb
213// and encodes it into the wire format, writing the result to the
214// Buffer.
215func (p *Buffer) Marshal(pb interface{}) os.Error {
216 // Can the object marshal itself?
217 if m, ok := pb.(Marshaler); ok {
218 data, err := m.Marshal()
219 if err != nil {
220 return err
221 }
222 p.buf = bytes.Add(p.buf, data)
223 return nil
224 }
225
226 mstat := runtime.MemStats.Mallocs
227
228 t, b, err := getbase(pb)
229 if err == nil {
230 err = p.enc_struct(t.Elem().(*reflect.StructType), b)
231 }
232
233 mstat = runtime.MemStats.Mallocs - mstat
234 stats.Emalloc += mstat
235 stats.Encode++
236
237 return err
238}
239
240// Individual type encoders.
241
242// Encode a bool.
243func (o *Buffer) enc_bool(p *Properties, base uintptr) os.Error {
244 v := *(**uint8)(unsafe.Pointer(base + p.offset))
245 if v == nil {
246 return ErrNil
247 }
248 x := *v
249 if x != 0 {
250 x = 1
251 }
252 o.buf = bytes.Add(o.buf, p.tagcode)
253 p.valEnc(o, uint64(x))
254 return nil
255}
256
257// Encode an int32.
258func (o *Buffer) enc_int32(p *Properties, base uintptr) os.Error {
259 v := *(**uint32)(unsafe.Pointer(base + p.offset))
260 if v == nil {
261 return ErrNil
262 }
263 x := *v
264 o.buf = bytes.Add(o.buf, p.tagcode)
265 p.valEnc(o, uint64(x))
266 return nil
267}
268
269// Encode an int64.
270func (o *Buffer) enc_int64(p *Properties, base uintptr) os.Error {
271 v := *(**uint64)(unsafe.Pointer(base + p.offset))
272 if v == nil {
273 return ErrNil
274 }
275 x := *v
276 o.buf = bytes.Add(o.buf, p.tagcode)
277 p.valEnc(o, uint64(x))
278 return nil
279}
280
281// Encode a string.
282func (o *Buffer) enc_string(p *Properties, base uintptr) os.Error {
283 v := *(**string)(unsafe.Pointer(base + p.offset))
284 if v == nil {
285 return ErrNil
286 }
287 x := *v
288 o.buf = bytes.Add(o.buf, p.tagcode)
289 o.EncodeStringBytes(x)
290 return nil
291}
292
293// Encode a message struct.
294func (o *Buffer) enc_struct_message(p *Properties, base uintptr) os.Error {
295 // Can the object marshal itself?
296 iv := unsafe.Unreflect(p.stype, unsafe.Pointer(base+p.offset))
297 if m, ok := iv.(Marshaler); ok {
David Symonds03c9d412010-08-26 14:23:18 +1000298 if n, ok := reflect.NewValue(iv).(nillable); ok && n.IsNil() {
299 return ErrNil
300 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700301 data, err := m.Marshal()
302 if err != nil {
303 return err
304 }
305 o.buf = bytes.Add(o.buf, p.tagcode)
306 o.EncodeRawBytes(data)
307 return nil
308 }
309 v := *(**struct{})(unsafe.Pointer(base + p.offset))
310 if v == nil {
311 return ErrNil
312 }
313
314 // need the length before we can write out the message itself,
315 // so marshal into a separate byte buffer first.
316 obuf := o.buf
317 o.buf = o.bufalloc()
318
319 b := uintptr(unsafe.Pointer(v))
320 typ := p.stype.Elem().(*reflect.StructType)
321 err := o.enc_struct(typ, b)
322
323 nbuf := o.buf
324 o.buf = obuf
325 if err != nil {
326 o.buffree(nbuf)
327 return err
328 }
329 o.buf = bytes.Add(o.buf, p.tagcode)
330 o.EncodeRawBytes(nbuf)
331 o.buffree(nbuf)
332 return nil
333}
334
335// Encode a group struct.
336func (o *Buffer) enc_struct_group(p *Properties, base uintptr) os.Error {
337 v := *(**struct{})(unsafe.Pointer(base + p.offset))
338 if v == nil {
339 return ErrNil
340 }
341
342 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
343 b := uintptr(unsafe.Pointer(v))
344 typ := p.stype.Elem().(*reflect.StructType)
345 err := o.enc_struct(typ, b)
346 if err != nil {
347 return err
348 }
349 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
350 return nil
351}
352
353// Encode a slice of bools ([]bool).
354func (o *Buffer) enc_slice_bool(p *Properties, base uintptr) os.Error {
355 s := *(*[]uint8)(unsafe.Pointer(base + p.offset))
356 l := len(s)
357 if l == 0 {
358 return ErrNil
359 }
360 for _, x := range s {
361 o.buf = bytes.Add(o.buf, p.tagcode)
362 if x != 0 {
363 x = 1
364 }
365 p.valEnc(o, uint64(x))
366 }
367 return nil
368}
369
David Symonds5b7775e2010-12-01 10:09:04 +1100370// Encode a slice of bools ([]bool) in packed format.
371func (o *Buffer) enc_slice_packed_bool(p *Properties, base uintptr) os.Error {
372 s := *(*[]uint8)(unsafe.Pointer(base + p.offset))
373 l := len(s)
374 if l == 0 {
375 return ErrNil
376 }
377 o.buf = append(o.buf, p.tagcode...)
378 o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
379 for _, x := range s {
380 if x != 0 {
381 x = 1
382 }
383 p.valEnc(o, uint64(x))
384 }
385 return nil
386}
387
Rob Pikeaaa3a622010-03-20 22:32:34 -0700388// Encode a slice of bytes ([]byte).
389func (o *Buffer) enc_slice_byte(p *Properties, base uintptr) os.Error {
390 s := *(*[]uint8)(unsafe.Pointer(base + p.offset))
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800391 if s == nil {
392 return ErrNil
393 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700394 o.buf = bytes.Add(o.buf, p.tagcode)
395 o.EncodeRawBytes(s)
396 return nil
397}
398
399// Encode a slice of int32s ([]int32).
400func (o *Buffer) enc_slice_int32(p *Properties, base uintptr) os.Error {
401 s := *(*[]uint32)(unsafe.Pointer(base + p.offset))
402 l := len(s)
403 if l == 0 {
404 return ErrNil
405 }
406 for i := 0; i < l; i++ {
407 o.buf = bytes.Add(o.buf, p.tagcode)
408 x := s[i]
409 p.valEnc(o, uint64(x))
410 }
411 return nil
412}
413
David Symonds5b7775e2010-12-01 10:09:04 +1100414// Encode a slice of int32s ([]int32) in packed format.
415func (o *Buffer) enc_slice_packed_int32(p *Properties, base uintptr) os.Error {
416 s := *(*[]uint32)(unsafe.Pointer(base + p.offset))
417 l := len(s)
418 if l == 0 {
419 return ErrNil
420 }
421 // TODO: Reuse a Buffer.
422 buf := NewBuffer(nil)
423 for i := 0; i < l; i++ {
424 p.valEnc(buf, uint64(s[i]))
425 }
426
427 o.buf = append(o.buf, p.tagcode...)
428 o.EncodeVarint(uint64(len(buf.buf)))
429 o.buf = append(o.buf, buf.buf...)
430 return nil
431}
432
Rob Pikeaaa3a622010-03-20 22:32:34 -0700433// Encode a slice of int64s ([]int64).
434func (o *Buffer) enc_slice_int64(p *Properties, base uintptr) os.Error {
435 s := *(*[]uint64)(unsafe.Pointer(base + p.offset))
436 l := len(s)
437 if l == 0 {
438 return ErrNil
439 }
440 for i := 0; i < l; i++ {
441 o.buf = bytes.Add(o.buf, p.tagcode)
442 x := s[i]
443 p.valEnc(o, uint64(x))
444 }
445 return nil
446}
447
David Symonds5b7775e2010-12-01 10:09:04 +1100448// Encode a slice of int64s ([]int64) in packed format.
449func (o *Buffer) enc_slice_packed_int64(p *Properties, base uintptr) os.Error {
450 s := *(*[]uint64)(unsafe.Pointer(base + p.offset))
451 l := len(s)
452 if l == 0 {
453 return ErrNil
454 }
455 // TODO: Reuse a Buffer.
456 buf := NewBuffer(nil)
457 for i := 0; i < l; i++ {
458 p.valEnc(buf, s[i])
459 }
460
461 o.buf = append(o.buf, p.tagcode...)
462 o.EncodeVarint(uint64(len(buf.buf)))
463 o.buf = append(o.buf, buf.buf...)
464 return nil
465}
466
Rob Pikeaaa3a622010-03-20 22:32:34 -0700467// Encode a slice of slice of bytes ([][]byte).
468func (o *Buffer) enc_slice_slice_byte(p *Properties, base uintptr) os.Error {
469 ss := *(*[][]uint8)(unsafe.Pointer(base + p.offset))
470 l := len(ss)
471 if l == 0 {
472 return ErrNil
473 }
474 for i := 0; i < l; i++ {
475 o.buf = bytes.Add(o.buf, p.tagcode)
476 s := ss[i]
477 o.EncodeRawBytes(s)
478 }
479 return nil
480}
481
482// Encode a slice of strings ([]string).
483func (o *Buffer) enc_slice_string(p *Properties, base uintptr) os.Error {
484 ss := *(*[]string)(unsafe.Pointer(base + p.offset))
485 l := len(ss)
486 for i := 0; i < l; i++ {
487 o.buf = bytes.Add(o.buf, p.tagcode)
488 s := ss[i]
489 o.EncodeStringBytes(s)
490 }
491 return nil
492}
493
494// Encode a slice of message structs ([]*struct).
495func (o *Buffer) enc_slice_struct_message(p *Properties, base uintptr) os.Error {
496 s := *(*[]*struct{})(unsafe.Pointer(base + p.offset))
497 l := len(s)
498 typ := p.stype.Elem().(*reflect.StructType)
499
500 for i := 0; i < l; i++ {
501 v := s[i]
502 if v == nil {
503 return ErrRepeatedHasNil
504 }
505
506 // Can the object marshal itself?
507 iv := unsafe.Unreflect(p.stype, unsafe.Pointer(&s[i]))
508 if m, ok := iv.(Marshaler); ok {
David Symonds03c9d412010-08-26 14:23:18 +1000509 if n, ok := reflect.NewValue(iv).(nillable); ok && n.IsNil() {
510 return ErrNil
511 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700512 data, err := m.Marshal()
513 if err != nil {
514 return err
515 }
516 o.buf = bytes.Add(o.buf, p.tagcode)
517 o.EncodeRawBytes(data)
518 continue
519 }
520
521 obuf := o.buf
522 o.buf = o.bufalloc()
523
524 b := uintptr(unsafe.Pointer(v))
525 err := o.enc_struct(typ, b)
526
527 nbuf := o.buf
528 o.buf = obuf
529 if err != nil {
530 o.buffree(nbuf)
531 if err == ErrNil {
532 return ErrRepeatedHasNil
533 }
534 return err
535 }
536 o.buf = bytes.Add(o.buf, p.tagcode)
537 o.EncodeRawBytes(nbuf)
538
539 o.buffree(nbuf)
540 }
541 return nil
542}
543
544// Encode a slice of group structs ([]*struct).
545func (o *Buffer) enc_slice_struct_group(p *Properties, base uintptr) os.Error {
546 s := *(*[]*struct{})(unsafe.Pointer(base + p.offset))
547 l := len(s)
548 typ := p.stype.Elem().(*reflect.StructType)
549
550 for i := 0; i < l; i++ {
551 v := s[i]
552 if v == nil {
553 return ErrRepeatedHasNil
554 }
555
556 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
557
558 b := uintptr(unsafe.Pointer(v))
559 err := o.enc_struct(typ, b)
560
561 if err != nil {
562 if err == ErrNil {
563 return ErrRepeatedHasNil
564 }
565 return err
566 }
567
568 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
569 }
570 return nil
571}
572
573// Encode an extension map.
574func (o *Buffer) enc_map(p *Properties, base uintptr) os.Error {
575 v := *(*map[int32][]byte)(unsafe.Pointer(base + p.offset))
576 for _, b := range v {
577 o.buf = bytes.Add(o.buf, b)
578 }
579 return nil
580}
581
582// Encode a struct.
583func (o *Buffer) enc_struct(t *reflect.StructType, base uintptr) os.Error {
584 prop := GetProperties(t)
585 required := prop.reqCount
586 for _, p := range prop.Prop {
587 if p.enc != nil {
588 err := p.enc(o, p, base)
589 if err != nil {
590 if err != ErrNil {
591 return err
592 }
593 } else if p.Required {
594 required--
595 }
596 }
597 }
598 // See if we encoded all required fields.
599 if required > 0 {
David Symonds5b7775e2010-12-01 10:09:04 +1100600 return &ErrRequiredNotSet{t}
Rob Pikeaaa3a622010-03-20 22:32:34 -0700601 }
602
603 return nil
604}