github.com/gogo/protobuf@v1.3.2/proto/table_marshal_gogo.go (about) 1 // Protocol Buffers for Go with Gadgets 2 // 3 // Copyright (c) 2018, The GoGo Authors. All rights reserved. 4 // http://github.com/gogo/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 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 package proto 30 31 import ( 32 "reflect" 33 "time" 34 ) 35 36 // makeMessageRefMarshaler differs a bit from makeMessageMarshaler 37 // It marshal a message T instead of a *T 38 func makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) { 39 return func(ptr pointer, tagsize int) int { 40 siz := u.size(ptr) 41 return siz + SizeVarint(uint64(siz)) + tagsize 42 }, 43 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 44 b = appendVarint(b, wiretag) 45 siz := u.cachedsize(ptr) 46 b = appendVarint(b, uint64(siz)) 47 return u.marshal(b, ptr, deterministic) 48 } 49 } 50 51 // makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler 52 // It marshals a slice of messages []T instead of []*T 53 func makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) { 54 return func(ptr pointer, tagsize int) int { 55 s := ptr.getSlice(u.typ) 56 n := 0 57 for i := 0; i < s.Len(); i++ { 58 elem := s.Index(i) 59 e := elem.Interface() 60 v := toAddrPointer(&e, false) 61 siz := u.size(v) 62 n += siz + SizeVarint(uint64(siz)) + tagsize 63 } 64 return n 65 }, 66 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 67 s := ptr.getSlice(u.typ) 68 var err, errreq error 69 for i := 0; i < s.Len(); i++ { 70 elem := s.Index(i) 71 e := elem.Interface() 72 v := toAddrPointer(&e, false) 73 b = appendVarint(b, wiretag) 74 siz := u.size(v) 75 b = appendVarint(b, uint64(siz)) 76 b, err = u.marshal(b, v, deterministic) 77 78 if err != nil { 79 if _, ok := err.(*RequiredNotSetError); ok { 80 // Required field in submessage is not set. 81 // We record the error but keep going, to give a complete marshaling. 82 if errreq == nil { 83 errreq = err 84 } 85 continue 86 } 87 if err == ErrNil { 88 err = errRepeatedHasNil 89 } 90 return b, err 91 } 92 } 93 94 return b, errreq 95 } 96 } 97 98 func makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) { 99 return func(ptr pointer, tagsize int) int { 100 if ptr.isNil() { 101 return 0 102 } 103 m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom) 104 siz := m.Size() 105 return tagsize + SizeVarint(uint64(siz)) + siz 106 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 107 if ptr.isNil() { 108 return b, nil 109 } 110 m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom) 111 siz := m.Size() 112 buf, err := m.Marshal() 113 if err != nil { 114 return nil, err 115 } 116 b = appendVarint(b, wiretag) 117 b = appendVarint(b, uint64(siz)) 118 b = append(b, buf...) 119 return b, nil 120 } 121 } 122 123 func makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) { 124 return func(ptr pointer, tagsize int) int { 125 m := ptr.asPointerTo(u.typ).Interface().(custom) 126 siz := m.Size() 127 return tagsize + SizeVarint(uint64(siz)) + siz 128 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 129 m := ptr.asPointerTo(u.typ).Interface().(custom) 130 siz := m.Size() 131 buf, err := m.Marshal() 132 if err != nil { 133 return nil, err 134 } 135 b = appendVarint(b, wiretag) 136 b = appendVarint(b, uint64(siz)) 137 b = append(b, buf...) 138 return b, nil 139 } 140 } 141 142 func makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) { 143 return func(ptr pointer, tagsize int) int { 144 t := ptr.asPointerTo(u.typ).Interface().(*time.Time) 145 ts, err := timestampProto(*t) 146 if err != nil { 147 return 0 148 } 149 siz := Size(ts) 150 return tagsize + SizeVarint(uint64(siz)) + siz 151 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 152 t := ptr.asPointerTo(u.typ).Interface().(*time.Time) 153 ts, err := timestampProto(*t) 154 if err != nil { 155 return nil, err 156 } 157 buf, err := Marshal(ts) 158 if err != nil { 159 return nil, err 160 } 161 b = appendVarint(b, wiretag) 162 b = appendVarint(b, uint64(len(buf))) 163 b = append(b, buf...) 164 return b, nil 165 } 166 } 167 168 func makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) { 169 return func(ptr pointer, tagsize int) int { 170 if ptr.isNil() { 171 return 0 172 } 173 t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time) 174 ts, err := timestampProto(*t) 175 if err != nil { 176 return 0 177 } 178 siz := Size(ts) 179 return tagsize + SizeVarint(uint64(siz)) + siz 180 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 181 if ptr.isNil() { 182 return b, nil 183 } 184 t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time) 185 ts, err := timestampProto(*t) 186 if err != nil { 187 return nil, err 188 } 189 buf, err := Marshal(ts) 190 if err != nil { 191 return nil, err 192 } 193 b = appendVarint(b, wiretag) 194 b = appendVarint(b, uint64(len(buf))) 195 b = append(b, buf...) 196 return b, nil 197 } 198 } 199 200 func makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) { 201 return func(ptr pointer, tagsize int) int { 202 s := ptr.getSlice(u.typ) 203 n := 0 204 for i := 0; i < s.Len(); i++ { 205 elem := s.Index(i) 206 t := elem.Interface().(time.Time) 207 ts, err := timestampProto(t) 208 if err != nil { 209 return 0 210 } 211 siz := Size(ts) 212 n += siz + SizeVarint(uint64(siz)) + tagsize 213 } 214 return n 215 }, 216 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 217 s := ptr.getSlice(u.typ) 218 for i := 0; i < s.Len(); i++ { 219 elem := s.Index(i) 220 t := elem.Interface().(time.Time) 221 ts, err := timestampProto(t) 222 if err != nil { 223 return nil, err 224 } 225 siz := Size(ts) 226 buf, err := Marshal(ts) 227 if err != nil { 228 return nil, err 229 } 230 b = appendVarint(b, wiretag) 231 b = appendVarint(b, uint64(siz)) 232 b = append(b, buf...) 233 } 234 235 return b, nil 236 } 237 } 238 239 func makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { 240 return func(ptr pointer, tagsize int) int { 241 s := ptr.getSlice(reflect.PtrTo(u.typ)) 242 n := 0 243 for i := 0; i < s.Len(); i++ { 244 elem := s.Index(i) 245 t := elem.Interface().(*time.Time) 246 ts, err := timestampProto(*t) 247 if err != nil { 248 return 0 249 } 250 siz := Size(ts) 251 n += siz + SizeVarint(uint64(siz)) + tagsize 252 } 253 return n 254 }, 255 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 256 s := ptr.getSlice(reflect.PtrTo(u.typ)) 257 for i := 0; i < s.Len(); i++ { 258 elem := s.Index(i) 259 t := elem.Interface().(*time.Time) 260 ts, err := timestampProto(*t) 261 if err != nil { 262 return nil, err 263 } 264 siz := Size(ts) 265 buf, err := Marshal(ts) 266 if err != nil { 267 return nil, err 268 } 269 b = appendVarint(b, wiretag) 270 b = appendVarint(b, uint64(siz)) 271 b = append(b, buf...) 272 } 273 274 return b, nil 275 } 276 } 277 278 func makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) { 279 return func(ptr pointer, tagsize int) int { 280 d := ptr.asPointerTo(u.typ).Interface().(*time.Duration) 281 dur := durationProto(*d) 282 siz := Size(dur) 283 return tagsize + SizeVarint(uint64(siz)) + siz 284 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 285 d := ptr.asPointerTo(u.typ).Interface().(*time.Duration) 286 dur := durationProto(*d) 287 buf, err := Marshal(dur) 288 if err != nil { 289 return nil, err 290 } 291 b = appendVarint(b, wiretag) 292 b = appendVarint(b, uint64(len(buf))) 293 b = append(b, buf...) 294 return b, nil 295 } 296 } 297 298 func makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) { 299 return func(ptr pointer, tagsize int) int { 300 if ptr.isNil() { 301 return 0 302 } 303 d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration) 304 dur := durationProto(*d) 305 siz := Size(dur) 306 return tagsize + SizeVarint(uint64(siz)) + siz 307 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 308 if ptr.isNil() { 309 return b, nil 310 } 311 d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration) 312 dur := durationProto(*d) 313 buf, err := Marshal(dur) 314 if err != nil { 315 return nil, err 316 } 317 b = appendVarint(b, wiretag) 318 b = appendVarint(b, uint64(len(buf))) 319 b = append(b, buf...) 320 return b, nil 321 } 322 } 323 324 func makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) { 325 return func(ptr pointer, tagsize int) int { 326 s := ptr.getSlice(u.typ) 327 n := 0 328 for i := 0; i < s.Len(); i++ { 329 elem := s.Index(i) 330 d := elem.Interface().(time.Duration) 331 dur := durationProto(d) 332 siz := Size(dur) 333 n += siz + SizeVarint(uint64(siz)) + tagsize 334 } 335 return n 336 }, 337 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 338 s := ptr.getSlice(u.typ) 339 for i := 0; i < s.Len(); i++ { 340 elem := s.Index(i) 341 d := elem.Interface().(time.Duration) 342 dur := durationProto(d) 343 siz := Size(dur) 344 buf, err := Marshal(dur) 345 if err != nil { 346 return nil, err 347 } 348 b = appendVarint(b, wiretag) 349 b = appendVarint(b, uint64(siz)) 350 b = append(b, buf...) 351 } 352 353 return b, nil 354 } 355 } 356 357 func makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { 358 return func(ptr pointer, tagsize int) int { 359 s := ptr.getSlice(reflect.PtrTo(u.typ)) 360 n := 0 361 for i := 0; i < s.Len(); i++ { 362 elem := s.Index(i) 363 d := elem.Interface().(*time.Duration) 364 dur := durationProto(*d) 365 siz := Size(dur) 366 n += siz + SizeVarint(uint64(siz)) + tagsize 367 } 368 return n 369 }, 370 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { 371 s := ptr.getSlice(reflect.PtrTo(u.typ)) 372 for i := 0; i < s.Len(); i++ { 373 elem := s.Index(i) 374 d := elem.Interface().(*time.Duration) 375 dur := durationProto(*d) 376 siz := Size(dur) 377 buf, err := Marshal(dur) 378 if err != nil { 379 return nil, err 380 } 381 b = appendVarint(b, wiretag) 382 b = appendVarint(b, uint64(siz)) 383 b = append(b, buf...) 384 } 385 386 return b, nil 387 } 388 }