1// Go support for Protocol Buffers - Google's data interchange format 2// 3// Copyright 2010 The Go Authors. All rights reserved. 4// https://github.com/golang/protobuf 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 "errors" 40 "reflect" 41) 42 43var ( 44 // errRepeatedHasNil is the error returned if Marshal is called with 45 // a struct with a repeated field containing a nil element. 46 errRepeatedHasNil = errors.New("proto: repeated field has nil element") 47 48 // errOneofHasNil is the error returned if Marshal is called with 49 // a struct with a oneof field containing a nil element. 50 errOneofHasNil = errors.New("proto: oneof field has nil value") 51 52 // ErrNil is the error returned if Marshal is called with nil. 53 ErrNil = errors.New("proto: Marshal called with nil") 54 55 // ErrTooLarge is the error returned if Marshal is called with a 56 // message that encodes to >2GB. 57 ErrTooLarge = errors.New("proto: message encodes to over 2 GB") 58) 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 64const maxVarintBytes = 10 // maximum length of a varint 65 66// EncodeVarint returns the varint encoding of x. 67// This is the format for the 68// int32, int64, uint32, uint64, bool, and enum 69// protocol buffer types. 70// Not used by the package itself, but helpful to clients 71// wishing to use the same encoding. 72func EncodeVarint(x uint64) []byte { 73 var buf [maxVarintBytes]byte 74 var n int 75 for n = 0; x > 127; n++ { 76 buf[n] = 0x80 | uint8(x&0x7F) 77 x >>= 7 78 } 79 buf[n] = uint8(x) 80 n++ 81 return buf[0:n] 82} 83 84// EncodeVarint writes a varint-encoded integer to the Buffer. 85// This is the format for the 86// int32, int64, uint32, uint64, bool, and enum 87// protocol buffer types. 88func (p *Buffer) EncodeVarint(x uint64) error { 89 for x >= 1<<7 { 90 p.buf = append(p.buf, uint8(x&0x7f|0x80)) 91 x >>= 7 92 } 93 p.buf = append(p.buf, uint8(x)) 94 return nil 95} 96 97// SizeVarint returns the varint encoding size of an integer. 98func SizeVarint(x uint64) int { 99 switch { 100 case x < 1<<7: 101 return 1 102 case x < 1<<14: 103 return 2 104 case x < 1<<21: 105 return 3 106 case x < 1<<28: 107 return 4 108 case x < 1<<35: 109 return 5 110 case x < 1<<42: 111 return 6 112 case x < 1<<49: 113 return 7 114 case x < 1<<56: 115 return 8 116 case x < 1<<63: 117 return 9 118 } 119 return 10 120} 121 122// EncodeFixed64 writes a 64-bit integer to the Buffer. 123// This is the format for the 124// fixed64, sfixed64, and double protocol buffer types. 125func (p *Buffer) EncodeFixed64(x uint64) error { 126 p.buf = append(p.buf, 127 uint8(x), 128 uint8(x>>8), 129 uint8(x>>16), 130 uint8(x>>24), 131 uint8(x>>32), 132 uint8(x>>40), 133 uint8(x>>48), 134 uint8(x>>56)) 135 return nil 136} 137 138// EncodeFixed32 writes a 32-bit integer to the Buffer. 139// This is the format for the 140// fixed32, sfixed32, and float protocol buffer types. 141func (p *Buffer) EncodeFixed32(x uint64) error { 142 p.buf = append(p.buf, 143 uint8(x), 144 uint8(x>>8), 145 uint8(x>>16), 146 uint8(x>>24)) 147 return nil 148} 149 150// EncodeZigzag64 writes a zigzag-encoded 64-bit integer 151// to the Buffer. 152// This is the format used for the sint64 protocol buffer type. 153func (p *Buffer) EncodeZigzag64(x uint64) error { 154 // use signed number to get arithmetic right shift. 155 return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) 156} 157 158// EncodeZigzag32 writes a zigzag-encoded 32-bit integer 159// to the Buffer. 160// This is the format used for the sint32 protocol buffer type. 161func (p *Buffer) EncodeZigzag32(x uint64) error { 162 // use signed number to get arithmetic right shift. 163 return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) 164} 165 166// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. 167// This is the format used for the bytes protocol buffer 168// type and for embedded messages. 169func (p *Buffer) EncodeRawBytes(b []byte) error { 170 p.EncodeVarint(uint64(len(b))) 171 p.buf = append(p.buf, b...) 172 return nil 173} 174 175// EncodeStringBytes writes an encoded string to the Buffer. 176// This is the format used for the proto2 string type. 177func (p *Buffer) EncodeStringBytes(s string) error { 178 p.EncodeVarint(uint64(len(s))) 179 p.buf = append(p.buf, s...) 180 return nil 181} 182 183// Marshaler is the interface representing objects that can marshal themselves. 184type Marshaler interface { 185 Marshal() ([]byte, error) 186} 187 188// EncodeMessage writes the protocol buffer to the Buffer, 189// prefixed by a varint-encoded length. 190func (p *Buffer) EncodeMessage(pb Message) error { 191 siz := Size(pb) 192 p.EncodeVarint(uint64(siz)) 193 return p.Marshal(pb) 194} 195 196// All protocol buffer fields are nillable, but be careful. 197func isNil(v reflect.Value) bool { 198 switch v.Kind() { 199 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: 200 return v.IsNil() 201 } 202 return false 203} 204