123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- // 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
- }
|