blob: 9c323b29e16fb20d823c83383667ebdba62c4388 [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
48// all been initialized.
49var ErrRequiredNotSet = os.NewError("required fields not set")
50
51// ErrRepeatedHasNil is the error returned if Marshal is called with
52// a protocol buffer struct with a repeated field containing a nil element.
53var ErrRepeatedHasNil = os.NewError("repeated field has nil")
54
55// ErrNil is the error returned if Marshal is called with nil.
56var ErrNil = os.NewError("marshal called with nil")
57
58// The fundamental encoders that put bytes on the wire.
59// Those that take integer types all accept uint64 and are
60// therefore of type valueEncoder.
61
62// EncodeVarint returns the varint encoding of x.
63// This is the format for the
64// int32, int64, uint32, uint64, bool, and enum
65// protocol buffer types.
66// Not used by the package itself, but helpful to clients
67// wishing to use the same encoding.
68func EncodeVarint(x uint64) []byte {
69 var buf [16]byte
70 var n int
71 for n = 0; x > 127; n++ {
72 buf[n] = 0x80 | uint8(x&0x7F)
73 x >>= 7
74 }
75 buf[n] = uint8(x)
76 n++
77 return buf[0:n]
78}
79
80// EncodeVarint writes a varint-encoded integer to the Buffer.
81// This is the format for the
82// int32, int64, uint32, uint64, bool, and enum
83// protocol buffer types.
84func (p *Buffer) EncodeVarint(x uint64) os.Error {
85 l := len(p.buf)
86 c := cap(p.buf)
87 if l+10 > c {
88 c += c/2 + 10
89 obuf := make([]byte, c)
90 copy(obuf, p.buf)
91 p.buf = obuf
92 }
93 p.buf = p.buf[0:c]
94
95 for {
96 if x < 1<<7 {
97 break
98 }
99 p.buf[l] = uint8(x&0x7f | 0x80)
100 l++
101 x >>= 7
102 }
103 p.buf[l] = uint8(x)
104 p.buf = p.buf[0 : l+1]
105 return nil
106}
107
108// EncodeFixed64 writes a 64-bit integer to the Buffer.
109// This is the format for the
110// fixed64, sfixed64, and double protocol buffer types.
111func (p *Buffer) EncodeFixed64(x uint64) os.Error {
112 l := len(p.buf)
113 c := cap(p.buf)
114 if l+8 > c {
115 c += c/2 + 8
116 obuf := make([]byte, c)
117 copy(obuf, p.buf)
118 p.buf = obuf
119 }
120 p.buf = p.buf[0 : l+8]
121
122 p.buf[l] = uint8(x)
123 p.buf[l+1] = uint8(x >> 8)
124 p.buf[l+2] = uint8(x >> 16)
125 p.buf[l+3] = uint8(x >> 24)
126 p.buf[l+4] = uint8(x >> 32)
127 p.buf[l+5] = uint8(x >> 40)
128 p.buf[l+6] = uint8(x >> 48)
129 p.buf[l+7] = uint8(x >> 56)
130 return nil
131}
132
133// EncodeFixed32 writes a 32-bit integer to the Buffer.
134// This is the format for the
135// fixed32, sfixed32, and float protocol buffer types.
136func (p *Buffer) EncodeFixed32(x uint64) os.Error {
137 l := len(p.buf)
138 c := cap(p.buf)
139 if l+4 > c {
140 c += c/2 + 4
141 obuf := make([]byte, c)
142 copy(obuf, p.buf)
143 p.buf = obuf
144 }
145 p.buf = p.buf[0 : l+4]
146
147 p.buf[l] = uint8(x)
148 p.buf[l+1] = uint8(x >> 8)
149 p.buf[l+2] = uint8(x >> 16)
150 p.buf[l+3] = uint8(x >> 24)
151 return nil
152}
153
154// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
155// to the Buffer.
156// This is the format used for the sint64 protocol buffer type.
157func (p *Buffer) EncodeZigzag64(x uint64) os.Error {
158 // use signed number to get arithmetic right shift.
159 return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
160}
161
162// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
163// to the Buffer.
164// This is the format used for the sint32 protocol buffer type.
165func (p *Buffer) EncodeZigzag32(x uint64) os.Error {
166 // use signed number to get arithmetic right shift.
167 return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
168}
169
170// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
171// This is the format used for the bytes protocol buffer
172// type and for embedded messages.
173func (p *Buffer) EncodeRawBytes(b []byte) os.Error {
174 lb := len(b)
175 p.EncodeVarint(uint64(lb))
176 p.buf = bytes.Add(p.buf, b)
177 return nil
178}
179
180// EncodeStringBytes writes an encoded string to the Buffer.
181// This is the format used for the proto2 string type.
182func (p *Buffer) EncodeStringBytes(s string) os.Error {
183
184 // this works because strings and slices are the same.
185 y := *(*[]byte)(unsafe.Pointer(&s))
186 p.EncodeRawBytes(y)
187 return nil
188}
189
190// Marshaler is the interface representing objects that can marshal themselves.
191type Marshaler interface {
192 Marshal() ([]byte, os.Error)
193}
194
195// Marshal takes the protocol buffer struct represented by pb
196// and encodes it into the wire format, returning the data.
197func Marshal(pb interface{}) ([]byte, os.Error) {
198 // Can the object marshal itself?
199 if m, ok := pb.(Marshaler); ok {
200 return m.Marshal()
201 }
202 p := NewBuffer(nil)
203 err := p.Marshal(pb)
204 if err != nil {
205 return nil, err
206 }
207 return p.buf, err
208}
209
210// Marshal takes the protocol buffer struct represented by pb
211// and encodes it into the wire format, writing the result to the
212// Buffer.
213func (p *Buffer) Marshal(pb interface{}) os.Error {
214 // Can the object marshal itself?
215 if m, ok := pb.(Marshaler); ok {
216 data, err := m.Marshal()
217 if err != nil {
218 return err
219 }
220 p.buf = bytes.Add(p.buf, data)
221 return nil
222 }
223
224 mstat := runtime.MemStats.Mallocs
225
226 t, b, err := getbase(pb)
227 if err == nil {
228 err = p.enc_struct(t.Elem().(*reflect.StructType), b)
229 }
230
231 mstat = runtime.MemStats.Mallocs - mstat
232 stats.Emalloc += mstat
233 stats.Encode++
234
235 return err
236}
237
238// Individual type encoders.
239
240// Encode a bool.
241func (o *Buffer) enc_bool(p *Properties, base uintptr) os.Error {
242 v := *(**uint8)(unsafe.Pointer(base + p.offset))
243 if v == nil {
244 return ErrNil
245 }
246 x := *v
247 if x != 0 {
248 x = 1
249 }
250 o.buf = bytes.Add(o.buf, p.tagcode)
251 p.valEnc(o, uint64(x))
252 return nil
253}
254
255// Encode an int32.
256func (o *Buffer) enc_int32(p *Properties, base uintptr) os.Error {
257 v := *(**uint32)(unsafe.Pointer(base + p.offset))
258 if v == nil {
259 return ErrNil
260 }
261 x := *v
262 o.buf = bytes.Add(o.buf, p.tagcode)
263 p.valEnc(o, uint64(x))
264 return nil
265}
266
267// Encode an int64.
268func (o *Buffer) enc_int64(p *Properties, base uintptr) os.Error {
269 v := *(**uint64)(unsafe.Pointer(base + p.offset))
270 if v == nil {
271 return ErrNil
272 }
273 x := *v
274 o.buf = bytes.Add(o.buf, p.tagcode)
275 p.valEnc(o, uint64(x))
276 return nil
277}
278
279// Encode a string.
280func (o *Buffer) enc_string(p *Properties, base uintptr) os.Error {
281 v := *(**string)(unsafe.Pointer(base + p.offset))
282 if v == nil {
283 return ErrNil
284 }
285 x := *v
286 o.buf = bytes.Add(o.buf, p.tagcode)
287 o.EncodeStringBytes(x)
288 return nil
289}
290
291// Encode a message struct.
292func (o *Buffer) enc_struct_message(p *Properties, base uintptr) os.Error {
293 // Can the object marshal itself?
294 iv := unsafe.Unreflect(p.stype, unsafe.Pointer(base+p.offset))
295 if m, ok := iv.(Marshaler); ok {
296 data, err := m.Marshal()
297 if err != nil {
298 return err
299 }
300 o.buf = bytes.Add(o.buf, p.tagcode)
301 o.EncodeRawBytes(data)
302 return nil
303 }
304 v := *(**struct{})(unsafe.Pointer(base + p.offset))
305 if v == nil {
306 return ErrNil
307 }
308
309 // need the length before we can write out the message itself,
310 // so marshal into a separate byte buffer first.
311 obuf := o.buf
312 o.buf = o.bufalloc()
313
314 b := uintptr(unsafe.Pointer(v))
315 typ := p.stype.Elem().(*reflect.StructType)
316 err := o.enc_struct(typ, b)
317
318 nbuf := o.buf
319 o.buf = obuf
320 if err != nil {
321 o.buffree(nbuf)
322 return err
323 }
324 o.buf = bytes.Add(o.buf, p.tagcode)
325 o.EncodeRawBytes(nbuf)
326 o.buffree(nbuf)
327 return nil
328}
329
330// Encode a group struct.
331func (o *Buffer) enc_struct_group(p *Properties, base uintptr) os.Error {
332 v := *(**struct{})(unsafe.Pointer(base + p.offset))
333 if v == nil {
334 return ErrNil
335 }
336
337 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
338 b := uintptr(unsafe.Pointer(v))
339 typ := p.stype.Elem().(*reflect.StructType)
340 err := o.enc_struct(typ, b)
341 if err != nil {
342 return err
343 }
344 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
345 return nil
346}
347
348// Encode a slice of bools ([]bool).
349func (o *Buffer) enc_slice_bool(p *Properties, base uintptr) os.Error {
350 s := *(*[]uint8)(unsafe.Pointer(base + p.offset))
351 l := len(s)
352 if l == 0 {
353 return ErrNil
354 }
355 for _, x := range s {
356 o.buf = bytes.Add(o.buf, p.tagcode)
357 if x != 0 {
358 x = 1
359 }
360 p.valEnc(o, uint64(x))
361 }
362 return nil
363}
364
365// Encode a slice of bytes ([]byte).
366func (o *Buffer) enc_slice_byte(p *Properties, base uintptr) os.Error {
367 s := *(*[]uint8)(unsafe.Pointer(base + p.offset))
368 // if the field is required, we must send something, even if it's an empty array.
369 if !p.Required {
370 l := len(s)
371 if l == 0 {
372 return ErrNil
373 }
374 // check default
375 if l == len(p.Default) {
376 same := true
377 for i := 0; i < len(p.Default); i++ {
378 if p.Default[i] != s[i] {
379 same = false
380 break
381 }
382 }
383 if same {
384 return ErrNil
385 }
386 }
387 }
388 o.buf = bytes.Add(o.buf, p.tagcode)
389 o.EncodeRawBytes(s)
390 return nil
391}
392
393// Encode a slice of int32s ([]int32).
394func (o *Buffer) enc_slice_int32(p *Properties, base uintptr) os.Error {
395 s := *(*[]uint32)(unsafe.Pointer(base + p.offset))
396 l := len(s)
397 if l == 0 {
398 return ErrNil
399 }
400 for i := 0; i < l; i++ {
401 o.buf = bytes.Add(o.buf, p.tagcode)
402 x := s[i]
403 p.valEnc(o, uint64(x))
404 }
405 return nil
406}
407
408// Encode a slice of int64s ([]int64).
409func (o *Buffer) enc_slice_int64(p *Properties, base uintptr) os.Error {
410 s := *(*[]uint64)(unsafe.Pointer(base + p.offset))
411 l := len(s)
412 if l == 0 {
413 return ErrNil
414 }
415 for i := 0; i < l; i++ {
416 o.buf = bytes.Add(o.buf, p.tagcode)
417 x := s[i]
418 p.valEnc(o, uint64(x))
419 }
420 return nil
421}
422
423// Encode a slice of slice of bytes ([][]byte).
424func (o *Buffer) enc_slice_slice_byte(p *Properties, base uintptr) os.Error {
425 ss := *(*[][]uint8)(unsafe.Pointer(base + p.offset))
426 l := len(ss)
427 if l == 0 {
428 return ErrNil
429 }
430 for i := 0; i < l; i++ {
431 o.buf = bytes.Add(o.buf, p.tagcode)
432 s := ss[i]
433 o.EncodeRawBytes(s)
434 }
435 return nil
436}
437
438// Encode a slice of strings ([]string).
439func (o *Buffer) enc_slice_string(p *Properties, base uintptr) os.Error {
440 ss := *(*[]string)(unsafe.Pointer(base + p.offset))
441 l := len(ss)
442 for i := 0; i < l; i++ {
443 o.buf = bytes.Add(o.buf, p.tagcode)
444 s := ss[i]
445 o.EncodeStringBytes(s)
446 }
447 return nil
448}
449
450// Encode a slice of message structs ([]*struct).
451func (o *Buffer) enc_slice_struct_message(p *Properties, base uintptr) os.Error {
452 s := *(*[]*struct{})(unsafe.Pointer(base + p.offset))
453 l := len(s)
454 typ := p.stype.Elem().(*reflect.StructType)
455
456 for i := 0; i < l; i++ {
457 v := s[i]
458 if v == nil {
459 return ErrRepeatedHasNil
460 }
461
462 // Can the object marshal itself?
463 iv := unsafe.Unreflect(p.stype, unsafe.Pointer(&s[i]))
464 if m, ok := iv.(Marshaler); ok {
465 data, err := m.Marshal()
466 if err != nil {
467 return err
468 }
469 o.buf = bytes.Add(o.buf, p.tagcode)
470 o.EncodeRawBytes(data)
471 continue
472 }
473
474 obuf := o.buf
475 o.buf = o.bufalloc()
476
477 b := uintptr(unsafe.Pointer(v))
478 err := o.enc_struct(typ, b)
479
480 nbuf := o.buf
481 o.buf = obuf
482 if err != nil {
483 o.buffree(nbuf)
484 if err == ErrNil {
485 return ErrRepeatedHasNil
486 }
487 return err
488 }
489 o.buf = bytes.Add(o.buf, p.tagcode)
490 o.EncodeRawBytes(nbuf)
491
492 o.buffree(nbuf)
493 }
494 return nil
495}
496
497// Encode a slice of group structs ([]*struct).
498func (o *Buffer) enc_slice_struct_group(p *Properties, base uintptr) os.Error {
499 s := *(*[]*struct{})(unsafe.Pointer(base + p.offset))
500 l := len(s)
501 typ := p.stype.Elem().(*reflect.StructType)
502
503 for i := 0; i < l; i++ {
504 v := s[i]
505 if v == nil {
506 return ErrRepeatedHasNil
507 }
508
509 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
510
511 b := uintptr(unsafe.Pointer(v))
512 err := o.enc_struct(typ, b)
513
514 if err != nil {
515 if err == ErrNil {
516 return ErrRepeatedHasNil
517 }
518 return err
519 }
520
521 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
522 }
523 return nil
524}
525
526// Encode an extension map.
527func (o *Buffer) enc_map(p *Properties, base uintptr) os.Error {
528 v := *(*map[int32][]byte)(unsafe.Pointer(base + p.offset))
529 for _, b := range v {
530 o.buf = bytes.Add(o.buf, b)
531 }
532 return nil
533}
534
535// Encode a struct.
536func (o *Buffer) enc_struct(t *reflect.StructType, base uintptr) os.Error {
537 prop := GetProperties(t)
538 required := prop.reqCount
539 for _, p := range prop.Prop {
540 if p.enc != nil {
541 err := p.enc(o, p, base)
542 if err != nil {
543 if err != ErrNil {
544 return err
545 }
546 } else if p.Required {
547 required--
548 }
549 }
550 }
551 // See if we encoded all required fields.
552 if required > 0 {
553 return ErrRequiredNotSet
554 }
555
556 return nil
557}