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