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 32 package proto 33 34 /* 35 * Routines for encoding data into the wire format for protocol buffers. 36 */ 37 38 import ( 39 "errors" 40 "reflect" 41 ) 42 43 var ( 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 64 const 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. 72 func 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. 88 func (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. 98 func 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. 125 func (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. 141 func (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. 153 func (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. 161 func (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. 169 func (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. 177 func (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. 184 type Marshaler interface { 185 Marshal() ([]byte, error) 186 } 187 188 // EncodeMessage writes the protocol buffer to the Buffer, 189 // prefixed by a varint-encoded length. 190 func (p *Buffer) EncodeMessage(pb Message) error { 191 siz := Size(pb) 192 sizVar := SizeVarint(uint64(siz)) 193 p.grow(siz + sizVar) 194 p.EncodeVarint(uint64(siz)) 195 return p.Marshal(pb) 196 } 197 198 // All protocol buffer fields are nillable, but be careful. 199 func isNil(v reflect.Value) bool { 200 switch v.Kind() { 201 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: 202 return v.IsNil() 203 } 204 return false 205 } 206