...

Source file src/github.com/gogo/protobuf/proto/table_marshal_gogo.go

Documentation: github.com/gogo/protobuf/proto

     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  }
   389  

View as plain text