aboutsummaryrefslogblamecommitdiffstats
path: root/vendor/github.com/golang/protobuf/proto/encode.go
blob: 3abfed2cff04bdf3bb72517b6f1807b82a151570 (plain) (tree)






































                                                                         
                 

 






















                                                                               
































                                                              




















                        

















                                                       











                                                       




                                                               
                                                                          









                                                                                  








                                                                     







                                                            




                                                                               


                                                          


                                   









                                                                        
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 The Go Authors.  All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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
}