| // Copyright 2010 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package proto |
| |
| /* |
| * Routines for encoding data into the wire format for protocol buffers. |
| */ |
| |
| import ( |
| "errors" |
| "reflect" |
| ) |
| |
| var ( |
| // errRepeatedHasNil is the error returned if Marshal is called with |
| // a struct with a repeated field containing a nil element. |
| errRepeatedHasNil = errors.New("proto: repeated field has nil element") |
| |
| // errOneofHasNil is the error returned if Marshal is called with |
| // a struct with a oneof field containing a nil element. |
| errOneofHasNil = errors.New("proto: oneof field has nil value") |
| |
| // ErrNil is the error returned if Marshal is called with nil. |
| ErrNil = errors.New("proto: Marshal called with nil") |
| |
| // ErrTooLarge is the error returned if Marshal is called with a |
| // message that encodes to >2GB. |
| ErrTooLarge = errors.New("proto: message encodes to over 2 GB") |
| ) |
| |
| // The fundamental encoders that put bytes on the wire. |
| // Those that take integer types all accept uint64 and are |
| // therefore of type valueEncoder. |
| |
| const maxVarintBytes = 10 // maximum length of a varint |
| |
| // EncodeVarint returns the varint encoding of x. |
| // This is the format for the |
| // int32, int64, uint32, uint64, bool, and enum |
| // protocol buffer types. |
| // Not used by the package itself, but helpful to clients |
| // wishing to use the same encoding. |
| func EncodeVarint(x uint64) []byte { |
| var buf [maxVarintBytes]byte |
| var n int |
| for n = 0; x > 127; n++ { |
| buf[n] = 0x80 | uint8(x&0x7F) |
| x >>= 7 |
| } |
| buf[n] = uint8(x) |
| n++ |
| return buf[0:n] |
| } |
| |
| // EncodeVarint writes a varint-encoded integer to the Buffer. |
| // This is the format for the |
| // int32, int64, uint32, uint64, bool, and enum |
| // protocol buffer types. |
| func (p *Buffer) EncodeVarint(x uint64) error { |
| for x >= 1<<7 { |
| p.buf = append(p.buf, uint8(x&0x7f|0x80)) |
| x >>= 7 |
| } |
| p.buf = append(p.buf, uint8(x)) |
| return nil |
| } |
| |
| // SizeVarint returns the varint encoding size of an integer. |
| func SizeVarint(x uint64) int { |
| switch { |
| case x < 1<<7: |
| return 1 |
| case x < 1<<14: |
| return 2 |
| case x < 1<<21: |
| return 3 |
| case x < 1<<28: |
| return 4 |
| case x < 1<<35: |
| return 5 |
| case x < 1<<42: |
| return 6 |
| case x < 1<<49: |
| return 7 |
| case x < 1<<56: |
| return 8 |
| case x < 1<<63: |
| return 9 |
| } |
| return 10 |
| } |
| |
| // EncodeFixed64 writes a 64-bit integer to the Buffer. |
| // This is the format for the |
| // fixed64, sfixed64, and double protocol buffer types. |
| func (p *Buffer) EncodeFixed64(x uint64) error { |
| p.buf = append(p.buf, |
| uint8(x), |
| uint8(x>>8), |
| uint8(x>>16), |
| uint8(x>>24), |
| uint8(x>>32), |
| uint8(x>>40), |
| uint8(x>>48), |
| uint8(x>>56)) |
| return nil |
| } |
| |
| // EncodeFixed32 writes a 32-bit integer to the Buffer. |
| // This is the format for the |
| // fixed32, sfixed32, and float protocol buffer types. |
| func (p *Buffer) EncodeFixed32(x uint64) error { |
| p.buf = append(p.buf, |
| uint8(x), |
| uint8(x>>8), |
| uint8(x>>16), |
| uint8(x>>24)) |
| return nil |
| } |
| |
| // EncodeZigzag64 writes a zigzag-encoded 64-bit integer |
| // to the Buffer. |
| // This is the format used for the sint64 protocol buffer type. |
| func (p *Buffer) EncodeZigzag64(x uint64) error { |
| // use signed number to get arithmetic right shift. |
| return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) |
| } |
| |
| // EncodeZigzag32 writes a zigzag-encoded 32-bit integer |
| // to the Buffer. |
| // This is the format used for the sint32 protocol buffer type. |
| func (p *Buffer) EncodeZigzag32(x uint64) error { |
| // use signed number to get arithmetic right shift. |
| return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) |
| } |
| |
| // EncodeRawBytes writes a count-delimited byte buffer to the Buffer. |
| // This is the format used for the bytes protocol buffer |
| // type and for embedded messages. |
| func (p *Buffer) EncodeRawBytes(b []byte) error { |
| p.EncodeVarint(uint64(len(b))) |
| p.buf = append(p.buf, b...) |
| return nil |
| } |
| |
| // EncodeStringBytes writes an encoded string to the Buffer. |
| // This is the format used for the proto2 string type. |
| func (p *Buffer) EncodeStringBytes(s string) error { |
| p.EncodeVarint(uint64(len(s))) |
| p.buf = append(p.buf, s...) |
| return nil |
| } |
| |
| // Marshaler is the interface representing objects that can marshal themselves. |
| type Marshaler interface { |
| Marshal() ([]byte, error) |
| } |
| |
| // EncodeMessage writes the protocol buffer to the Buffer, |
| // prefixed by a varint-encoded length. |
| func (p *Buffer) EncodeMessage(pb Message) error { |
| siz := Size(pb) |
| p.EncodeVarint(uint64(siz)) |
| return p.Marshal(pb) |
| } |
| |
| // All protocol buffer fields are nillable, but be careful. |
| func isNil(v reflect.Value) bool { |
| switch v.Kind() { |
| case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: |
| return v.IsNil() |
| } |
| return false |
| } |