github.com/matm/etcd@v0.3.1-0.20140328024009-5b4a473f1453/third_party/code.google.com/p/gogoprotobuf/proto/encode_gogo.go (about) 1 // Extensions for Protocol Buffers to create more go like structures. 2 // 3 // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 4 // http://code.google.com/p/gogoprotobuf/gogoproto 5 // 6 // Go support for Protocol Buffers - Google's data interchange format 7 // 8 // Copyright 2010 The Go Authors. All rights reserved. 9 // http://code.google.com/p/goprotobuf/ 10 // 11 // Redistribution and use in source and binary forms, with or without 12 // modification, are permitted provided that the following conditions are 13 // met: 14 // 15 // * Redistributions of source code must retain the above copyright 16 // notice, this list of conditions and the following disclaimer. 17 // * Redistributions in binary form must reproduce the above 18 // copyright notice, this list of conditions and the following disclaimer 19 // in the documentation and/or other materials provided with the 20 // distribution. 21 // * Neither the name of Google Inc. nor the names of its 22 // contributors may be used to endorse or promote products derived from 23 // this software without specific prior written permission. 24 // 25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 37 package proto 38 39 import ( 40 "reflect" 41 ) 42 43 type Sizer interface { 44 Size() int 45 } 46 47 // Encode a reference to bool pointer. 48 func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error { 49 v := structPointer_RefBool(base, p.field) 50 if v == nil { 51 return ErrNil 52 } 53 x := 0 54 if *v { 55 x = 1 56 } 57 o.buf = append(o.buf, p.tagcode...) 58 p.valEnc(o, uint64(x)) 59 return nil 60 } 61 62 func size_ref_bool(p *Properties, base structPointer) int { 63 v := structPointer_RefBool(base, p.field) 64 if v == nil { 65 return 0 66 } 67 return len(p.tagcode) + 1 // each bool takes exactly one byte 68 } 69 70 // Encode a reference to int32 pointer. 71 func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error { 72 v := structPointer_RefWord32(base, p.field) 73 if refWord32_IsNil(v) { 74 return ErrNil 75 } 76 x := refWord32_Get(v) 77 o.buf = append(o.buf, p.tagcode...) 78 p.valEnc(o, uint64(x)) 79 return nil 80 } 81 82 func size_ref_int32(p *Properties, base structPointer) (n int) { 83 v := structPointer_RefWord32(base, p.field) 84 if refWord32_IsNil(v) { 85 return 0 86 } 87 x := refWord32_Get(v) 88 n += len(p.tagcode) 89 n += p.valSize(uint64(x)) 90 return 91 } 92 93 // Encode a reference to an int64 pointer. 94 func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error { 95 v := structPointer_RefWord64(base, p.field) 96 if refWord64_IsNil(v) { 97 return ErrNil 98 } 99 x := refWord64_Get(v) 100 o.buf = append(o.buf, p.tagcode...) 101 p.valEnc(o, x) 102 return nil 103 } 104 105 func size_ref_int64(p *Properties, base structPointer) (n int) { 106 v := structPointer_RefWord64(base, p.field) 107 if refWord64_IsNil(v) { 108 return 0 109 } 110 x := refWord64_Get(v) 111 n += len(p.tagcode) 112 n += p.valSize(x) 113 return 114 } 115 116 // Encode a reference to a string pointer. 117 func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error { 118 v := structPointer_RefString(base, p.field) 119 if v == nil { 120 return ErrNil 121 } 122 x := *v 123 o.buf = append(o.buf, p.tagcode...) 124 o.EncodeStringBytes(x) 125 return nil 126 } 127 128 func size_ref_string(p *Properties, base structPointer) (n int) { 129 v := structPointer_RefString(base, p.field) 130 if v == nil { 131 return 0 132 } 133 x := *v 134 n += len(p.tagcode) 135 n += sizeStringBytes(x) 136 return 137 } 138 139 // Encode a reference to a message struct. 140 func (o *Buffer) enc_ref_struct_message(p *Properties, base structPointer) error { 141 var state errorState 142 structp := structPointer_GetRefStructPointer(base, p.field) 143 if structPointer_IsNil(structp) { 144 return ErrNil 145 } 146 147 // Can the object marshal itself? 148 if p.isMarshaler { 149 m := structPointer_Interface(structp, p.stype).(Marshaler) 150 data, err := m.Marshal() 151 if err != nil && !state.shouldContinue(err, nil) { 152 return err 153 } 154 o.buf = append(o.buf, p.tagcode...) 155 o.EncodeRawBytes(data) 156 return nil 157 } 158 159 // need the length before we can write out the message itself, 160 // so marshal into a separate byte buffer first. 161 obuf := o.buf 162 o.buf = o.bufalloc() 163 164 err := o.enc_struct(p.stype, p.sprop, structp) 165 166 nbuf := o.buf 167 o.buf = obuf 168 if err != nil && !state.shouldContinue(err, nil) { 169 o.buffree(nbuf) 170 return err 171 } 172 o.buf = append(o.buf, p.tagcode...) 173 o.EncodeRawBytes(nbuf) 174 o.buffree(nbuf) 175 return nil 176 } 177 178 //TODO this is only copied, please fix this 179 func size_ref_struct_message(p *Properties, base structPointer) int { 180 structp := structPointer_GetRefStructPointer(base, p.field) 181 if structPointer_IsNil(structp) { 182 return 0 183 } 184 185 // Can the object marshal itself? 186 if p.isMarshaler { 187 m := structPointer_Interface(structp, p.stype).(Marshaler) 188 data, _ := m.Marshal() 189 n0 := len(p.tagcode) 190 n1 := sizeRawBytes(data) 191 return n0 + n1 192 } 193 194 n0 := len(p.tagcode) 195 n1 := size_struct(p.stype, p.sprop, structp) 196 n2 := sizeVarint(uint64(n1)) // size of encoded length 197 return n0 + n1 + n2 198 } 199 200 // Encode a slice of references to message struct pointers ([]struct). 201 func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error { 202 var state errorState 203 ss := structPointer_GetStructPointer(base, p.field) 204 ss1 := structPointer_GetRefStructPointer(ss, field(0)) 205 size := p.stype.Size() 206 l := structPointer_Len(base, p.field) 207 for i := 0; i < l; i++ { 208 structp := structPointer_Add(ss1, field(uintptr(i)*size)) 209 if structPointer_IsNil(structp) { 210 return ErrRepeatedHasNil 211 } 212 213 // Can the object marshal itself? 214 if p.isMarshaler { 215 m := structPointer_Interface(structp, p.stype).(Marshaler) 216 data, err := m.Marshal() 217 if err != nil && !state.shouldContinue(err, nil) { 218 return err 219 } 220 o.buf = append(o.buf, p.tagcode...) 221 o.EncodeRawBytes(data) 222 continue 223 } 224 225 obuf := o.buf 226 o.buf = o.bufalloc() 227 228 err := o.enc_struct(p.stype, p.sprop, structp) 229 230 nbuf := o.buf 231 o.buf = obuf 232 if err != nil && !state.shouldContinue(err, nil) { 233 o.buffree(nbuf) 234 if err == ErrNil { 235 return ErrRepeatedHasNil 236 } 237 return err 238 } 239 o.buf = append(o.buf, p.tagcode...) 240 o.EncodeRawBytes(nbuf) 241 242 o.buffree(nbuf) 243 } 244 return nil 245 } 246 247 //TODO this is only copied, please fix this 248 func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) { 249 ss := structPointer_GetStructPointer(base, p.field) 250 ss1 := structPointer_GetRefStructPointer(ss, field(0)) 251 size := p.stype.Size() 252 l := structPointer_Len(base, p.field) 253 n += l * len(p.tagcode) 254 for i := 0; i < l; i++ { 255 structp := structPointer_Add(ss1, field(uintptr(i)*size)) 256 if structPointer_IsNil(structp) { 257 return // return the size up to this point 258 } 259 260 // Can the object marshal itself? 261 if p.isMarshaler { 262 m := structPointer_Interface(structp, p.stype).(Marshaler) 263 data, _ := m.Marshal() 264 n += len(p.tagcode) 265 n += sizeRawBytes(data) 266 continue 267 } 268 269 n0 := size_struct(p.stype, p.sprop, structp) 270 n1 := sizeVarint(uint64(n0)) // size of encoded length 271 n += n0 + n1 272 } 273 return 274 } 275 276 func (o *Buffer) enc_custom_bytes(p *Properties, base structPointer) error { 277 i := structPointer_InterfaceRef(base, p.field, p.ctype) 278 if i == nil { 279 return ErrNil 280 } 281 custom := i.(Marshaler) 282 data, err := custom.Marshal() 283 if err != nil { 284 return err 285 } 286 if data == nil { 287 return ErrNil 288 } 289 o.buf = append(o.buf, p.tagcode...) 290 o.EncodeRawBytes(data) 291 return nil 292 } 293 294 func size_custom_bytes(p *Properties, base structPointer) (n int) { 295 n += len(p.tagcode) 296 i := structPointer_InterfaceRef(base, p.field, p.ctype) 297 if i == nil { 298 return 0 299 } 300 custom := i.(Marshaler) 301 data, _ := custom.Marshal() 302 n += sizeRawBytes(data) 303 return 304 } 305 306 func (o *Buffer) enc_custom_ref_bytes(p *Properties, base structPointer) error { 307 custom := structPointer_InterfaceAt(base, p.field, p.ctype).(Marshaler) 308 data, err := custom.Marshal() 309 if err != nil { 310 return err 311 } 312 if data == nil { 313 return ErrNil 314 } 315 o.buf = append(o.buf, p.tagcode...) 316 o.EncodeRawBytes(data) 317 return nil 318 } 319 320 func size_custom_ref_bytes(p *Properties, base structPointer) (n int) { 321 n += len(p.tagcode) 322 i := structPointer_InterfaceAt(base, p.field, p.ctype) 323 if i == nil { 324 return 0 325 } 326 custom := i.(Marshaler) 327 data, _ := custom.Marshal() 328 n += sizeRawBytes(data) 329 return 330 } 331 332 func (o *Buffer) enc_custom_slice_bytes(p *Properties, base structPointer) error { 333 inter := structPointer_InterfaceRef(base, p.field, p.ctype) 334 if inter == nil { 335 return ErrNil 336 } 337 slice := reflect.ValueOf(inter) 338 l := slice.Len() 339 for i := 0; i < l; i++ { 340 v := slice.Index(i) 341 custom := v.Interface().(Marshaler) 342 data, err := custom.Marshal() 343 if err != nil { 344 return err 345 } 346 o.buf = append(o.buf, p.tagcode...) 347 o.EncodeRawBytes(data) 348 } 349 return nil 350 } 351 352 func size_custom_slice_bytes(p *Properties, base structPointer) (n int) { 353 inter := structPointer_InterfaceRef(base, p.field, p.ctype) 354 if inter == nil { 355 return 0 356 } 357 slice := reflect.ValueOf(inter) 358 l := slice.Len() 359 n += l * len(p.tagcode) 360 for i := 0; i < l; i++ { 361 v := slice.Index(i) 362 custom := v.Interface().(Marshaler) 363 data, _ := custom.Marshal() 364 n += sizeRawBytes(data) 365 } 366 return 367 }