blob: fac4b5e64f19cb0a4a17cb7871fc5bf6067f7883 [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.
Rob Pikeaaa3a622010-03-20 22:32:34 -070051var ErrRequiredNotSet = os.NewError("required fields not set")
52
53// ErrRepeatedHasNil is the error returned if Marshal is called with
54// a protocol buffer struct with a repeated field containing a nil element.
55var ErrRepeatedHasNil = os.NewError("repeated field has nil")
56
57// ErrNil is the error returned if Marshal is called with nil.
58var ErrNil = os.NewError("marshal called with nil")
59
60// The fundamental encoders that put bytes on the wire.
61// Those that take integer types all accept uint64 and are
62// therefore of type valueEncoder.
63
64// EncodeVarint returns the varint encoding of x.
65// This is the format for the
66// int32, int64, uint32, uint64, bool, and enum
67// protocol buffer types.
68// Not used by the package itself, but helpful to clients
69// wishing to use the same encoding.
70func EncodeVarint(x uint64) []byte {
71 var buf [16]byte
72 var n int
73 for n = 0; x > 127; n++ {
74 buf[n] = 0x80 | uint8(x&0x7F)
75 x >>= 7
76 }
77 buf[n] = uint8(x)
78 n++
79 return buf[0:n]
80}
81
82// EncodeVarint writes a varint-encoded integer to the Buffer.
83// This is the format for the
84// int32, int64, uint32, uint64, bool, and enum
85// protocol buffer types.
86func (p *Buffer) EncodeVarint(x uint64) os.Error {
87 l := len(p.buf)
88 c := cap(p.buf)
89 if l+10 > c {
90 c += c/2 + 10
91 obuf := make([]byte, c)
92 copy(obuf, p.buf)
93 p.buf = obuf
94 }
95 p.buf = p.buf[0:c]
96
97 for {
98 if x < 1<<7 {
99 break
100 }
101 p.buf[l] = uint8(x&0x7f | 0x80)
102 l++
103 x >>= 7
104 }
105 p.buf[l] = uint8(x)
106 p.buf = p.buf[0 : l+1]
107 return nil
108}
109
110// EncodeFixed64 writes a 64-bit integer to the Buffer.
111// This is the format for the
112// fixed64, sfixed64, and double protocol buffer types.
113func (p *Buffer) EncodeFixed64(x uint64) os.Error {
114 l := len(p.buf)
115 c := cap(p.buf)
116 if l+8 > c {
117 c += c/2 + 8
118 obuf := make([]byte, c)
119 copy(obuf, p.buf)
120 p.buf = obuf
121 }
122 p.buf = p.buf[0 : l+8]
123
124 p.buf[l] = uint8(x)
125 p.buf[l+1] = uint8(x >> 8)
126 p.buf[l+2] = uint8(x >> 16)
127 p.buf[l+3] = uint8(x >> 24)
128 p.buf[l+4] = uint8(x >> 32)
129 p.buf[l+5] = uint8(x >> 40)
130 p.buf[l+6] = uint8(x >> 48)
131 p.buf[l+7] = uint8(x >> 56)
132 return nil
133}
134
135// EncodeFixed32 writes a 32-bit integer to the Buffer.
136// This is the format for the
137// fixed32, sfixed32, and float protocol buffer types.
138func (p *Buffer) EncodeFixed32(x uint64) os.Error {
139 l := len(p.buf)
140 c := cap(p.buf)
141 if l+4 > c {
142 c += c/2 + 4
143 obuf := make([]byte, c)
144 copy(obuf, p.buf)
145 p.buf = obuf
146 }
147 p.buf = p.buf[0 : l+4]
148
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 {
298 data, err := m.Marshal()
299 if err != nil {
300 return err
301 }
302 o.buf = bytes.Add(o.buf, p.tagcode)
303 o.EncodeRawBytes(data)
304 return nil
305 }
306 v := *(**struct{})(unsafe.Pointer(base + p.offset))
307 if v == nil {
308 return ErrNil
309 }
310
311 // need the length before we can write out the message itself,
312 // so marshal into a separate byte buffer first.
313 obuf := o.buf
314 o.buf = o.bufalloc()
315
316 b := uintptr(unsafe.Pointer(v))
317 typ := p.stype.Elem().(*reflect.StructType)
318 err := o.enc_struct(typ, b)
319
320 nbuf := o.buf
321 o.buf = obuf
322 if err != nil {
323 o.buffree(nbuf)
324 return err
325 }
326 o.buf = bytes.Add(o.buf, p.tagcode)
327 o.EncodeRawBytes(nbuf)
328 o.buffree(nbuf)
329 return nil
330}
331
332// Encode a group struct.
333func (o *Buffer) enc_struct_group(p *Properties, base uintptr) os.Error {
334 v := *(**struct{})(unsafe.Pointer(base + p.offset))
335 if v == nil {
336 return ErrNil
337 }
338
339 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
340 b := uintptr(unsafe.Pointer(v))
341 typ := p.stype.Elem().(*reflect.StructType)
342 err := o.enc_struct(typ, b)
343 if err != nil {
344 return err
345 }
346 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
347 return nil
348}
349
350// Encode a slice of bools ([]bool).
351func (o *Buffer) enc_slice_bool(p *Properties, base uintptr) os.Error {
352 s := *(*[]uint8)(unsafe.Pointer(base + p.offset))
353 l := len(s)
354 if l == 0 {
355 return ErrNil
356 }
357 for _, x := range s {
358 o.buf = bytes.Add(o.buf, p.tagcode)
359 if x != 0 {
360 x = 1
361 }
362 p.valEnc(o, uint64(x))
363 }
364 return nil
365}
366
367// Encode a slice of bytes ([]byte).
368func (o *Buffer) enc_slice_byte(p *Properties, base uintptr) os.Error {
369 s := *(*[]uint8)(unsafe.Pointer(base + p.offset))
370 // if the field is required, we must send something, even if it's an empty array.
371 if !p.Required {
372 l := len(s)
373 if l == 0 {
374 return ErrNil
375 }
376 // check default
377 if l == len(p.Default) {
378 same := true
379 for i := 0; i < len(p.Default); i++ {
380 if p.Default[i] != s[i] {
381 same = false
382 break
383 }
384 }
385 if same {
386 return ErrNil
387 }
388 }
389 }
390 o.buf = bytes.Add(o.buf, p.tagcode)
391 o.EncodeRawBytes(s)
392 return nil
393}
394
395// Encode a slice of int32s ([]int32).
396func (o *Buffer) enc_slice_int32(p *Properties, base uintptr) os.Error {
397 s := *(*[]uint32)(unsafe.Pointer(base + p.offset))
398 l := len(s)
399 if l == 0 {
400 return ErrNil
401 }
402 for i := 0; i < l; i++ {
403 o.buf = bytes.Add(o.buf, p.tagcode)
404 x := s[i]
405 p.valEnc(o, uint64(x))
406 }
407 return nil
408}
409
410// Encode a slice of int64s ([]int64).
411func (o *Buffer) enc_slice_int64(p *Properties, base uintptr) os.Error {
412 s := *(*[]uint64)(unsafe.Pointer(base + p.offset))
413 l := len(s)
414 if l == 0 {
415 return ErrNil
416 }
417 for i := 0; i < l; i++ {
418 o.buf = bytes.Add(o.buf, p.tagcode)
419 x := s[i]
420 p.valEnc(o, uint64(x))
421 }
422 return nil
423}
424
425// Encode a slice of slice of bytes ([][]byte).
426func (o *Buffer) enc_slice_slice_byte(p *Properties, base uintptr) os.Error {
427 ss := *(*[][]uint8)(unsafe.Pointer(base + p.offset))
428 l := len(ss)
429 if l == 0 {
430 return ErrNil
431 }
432 for i := 0; i < l; i++ {
433 o.buf = bytes.Add(o.buf, p.tagcode)
434 s := ss[i]
435 o.EncodeRawBytes(s)
436 }
437 return nil
438}
439
440// Encode a slice of strings ([]string).
441func (o *Buffer) enc_slice_string(p *Properties, base uintptr) os.Error {
442 ss := *(*[]string)(unsafe.Pointer(base + p.offset))
443 l := len(ss)
444 for i := 0; i < l; i++ {
445 o.buf = bytes.Add(o.buf, p.tagcode)
446 s := ss[i]
447 o.EncodeStringBytes(s)
448 }
449 return nil
450}
451
452// Encode a slice of message structs ([]*struct).
453func (o *Buffer) enc_slice_struct_message(p *Properties, base uintptr) os.Error {
454 s := *(*[]*struct{})(unsafe.Pointer(base + p.offset))
455 l := len(s)
456 typ := p.stype.Elem().(*reflect.StructType)
457
458 for i := 0; i < l; i++ {
459 v := s[i]
460 if v == nil {
461 return ErrRepeatedHasNil
462 }
463
464 // Can the object marshal itself?
465 iv := unsafe.Unreflect(p.stype, unsafe.Pointer(&s[i]))
466 if m, ok := iv.(Marshaler); ok {
467 data, err := m.Marshal()
468 if err != nil {
469 return err
470 }
471 o.buf = bytes.Add(o.buf, p.tagcode)
472 o.EncodeRawBytes(data)
473 continue
474 }
475
476 obuf := o.buf
477 o.buf = o.bufalloc()
478
479 b := uintptr(unsafe.Pointer(v))
480 err := o.enc_struct(typ, b)
481
482 nbuf := o.buf
483 o.buf = obuf
484 if err != nil {
485 o.buffree(nbuf)
486 if err == ErrNil {
487 return ErrRepeatedHasNil
488 }
489 return err
490 }
491 o.buf = bytes.Add(o.buf, p.tagcode)
492 o.EncodeRawBytes(nbuf)
493
494 o.buffree(nbuf)
495 }
496 return nil
497}
498
499// Encode a slice of group structs ([]*struct).
500func (o *Buffer) enc_slice_struct_group(p *Properties, base uintptr) os.Error {
501 s := *(*[]*struct{})(unsafe.Pointer(base + p.offset))
502 l := len(s)
503 typ := p.stype.Elem().(*reflect.StructType)
504
505 for i := 0; i < l; i++ {
506 v := s[i]
507 if v == nil {
508 return ErrRepeatedHasNil
509 }
510
511 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
512
513 b := uintptr(unsafe.Pointer(v))
514 err := o.enc_struct(typ, b)
515
516 if err != nil {
517 if err == ErrNil {
518 return ErrRepeatedHasNil
519 }
520 return err
521 }
522
523 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
524 }
525 return nil
526}
527
528// Encode an extension map.
529func (o *Buffer) enc_map(p *Properties, base uintptr) os.Error {
530 v := *(*map[int32][]byte)(unsafe.Pointer(base + p.offset))
531 for _, b := range v {
532 o.buf = bytes.Add(o.buf, b)
533 }
534 return nil
535}
536
537// Encode a struct.
538func (o *Buffer) enc_struct(t *reflect.StructType, base uintptr) os.Error {
539 prop := GetProperties(t)
540 required := prop.reqCount
541 for _, p := range prop.Prop {
542 if p.enc != nil {
543 err := p.enc(o, p, base)
544 if err != nil {
545 if err != ErrNil {
546 return err
547 }
548 } else if p.Required {
549 required--
550 }
551 }
552 }
553 // See if we encoded all required fields.
554 if required > 0 {
555 return ErrRequiredNotSet
556 }
557
558 return nil
559}