gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

codec_reflect.go (5412B)


      1 // Copyright 2019 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 //go:build purego || appengine
      6 // +build purego appengine
      7 
      8 package impl
      9 
     10 import (
     11 	"reflect"
     12 
     13 	"google.golang.org/protobuf/encoding/protowire"
     14 )
     15 
     16 func sizeEnum(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
     17 	v := p.v.Elem().Int()
     18 	return f.tagsize + protowire.SizeVarint(uint64(v))
     19 }
     20 
     21 func appendEnum(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
     22 	v := p.v.Elem().Int()
     23 	b = protowire.AppendVarint(b, f.wiretag)
     24 	b = protowire.AppendVarint(b, uint64(v))
     25 	return b, nil
     26 }
     27 
     28 func consumeEnum(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
     29 	if wtyp != protowire.VarintType {
     30 		return out, errUnknown
     31 	}
     32 	v, n := protowire.ConsumeVarint(b)
     33 	if n < 0 {
     34 		return out, errDecode
     35 	}
     36 	p.v.Elem().SetInt(int64(v))
     37 	out.n = n
     38 	return out, nil
     39 }
     40 
     41 func mergeEnum(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
     42 	dst.v.Elem().Set(src.v.Elem())
     43 }
     44 
     45 var coderEnum = pointerCoderFuncs{
     46 	size:      sizeEnum,
     47 	marshal:   appendEnum,
     48 	unmarshal: consumeEnum,
     49 	merge:     mergeEnum,
     50 }
     51 
     52 func sizeEnumNoZero(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
     53 	if p.v.Elem().Int() == 0 {
     54 		return 0
     55 	}
     56 	return sizeEnum(p, f, opts)
     57 }
     58 
     59 func appendEnumNoZero(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
     60 	if p.v.Elem().Int() == 0 {
     61 		return b, nil
     62 	}
     63 	return appendEnum(b, p, f, opts)
     64 }
     65 
     66 func mergeEnumNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
     67 	if src.v.Elem().Int() != 0 {
     68 		dst.v.Elem().Set(src.v.Elem())
     69 	}
     70 }
     71 
     72 var coderEnumNoZero = pointerCoderFuncs{
     73 	size:      sizeEnumNoZero,
     74 	marshal:   appendEnumNoZero,
     75 	unmarshal: consumeEnum,
     76 	merge:     mergeEnumNoZero,
     77 }
     78 
     79 func sizeEnumPtr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
     80 	return sizeEnum(pointer{p.v.Elem()}, f, opts)
     81 }
     82 
     83 func appendEnumPtr(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
     84 	return appendEnum(b, pointer{p.v.Elem()}, f, opts)
     85 }
     86 
     87 func consumeEnumPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
     88 	if wtyp != protowire.VarintType {
     89 		return out, errUnknown
     90 	}
     91 	if p.v.Elem().IsNil() {
     92 		p.v.Elem().Set(reflect.New(p.v.Elem().Type().Elem()))
     93 	}
     94 	return consumeEnum(b, pointer{p.v.Elem()}, wtyp, f, opts)
     95 }
     96 
     97 func mergeEnumPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
     98 	if !src.v.Elem().IsNil() {
     99 		v := reflect.New(dst.v.Type().Elem().Elem())
    100 		v.Elem().Set(src.v.Elem().Elem())
    101 		dst.v.Elem().Set(v)
    102 	}
    103 }
    104 
    105 var coderEnumPtr = pointerCoderFuncs{
    106 	size:      sizeEnumPtr,
    107 	marshal:   appendEnumPtr,
    108 	unmarshal: consumeEnumPtr,
    109 	merge:     mergeEnumPtr,
    110 }
    111 
    112 func sizeEnumSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
    113 	s := p.v.Elem()
    114 	for i, llen := 0, s.Len(); i < llen; i++ {
    115 		size += protowire.SizeVarint(uint64(s.Index(i).Int())) + f.tagsize
    116 	}
    117 	return size
    118 }
    119 
    120 func appendEnumSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
    121 	s := p.v.Elem()
    122 	for i, llen := 0, s.Len(); i < llen; i++ {
    123 		b = protowire.AppendVarint(b, f.wiretag)
    124 		b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
    125 	}
    126 	return b, nil
    127 }
    128 
    129 func consumeEnumSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
    130 	s := p.v.Elem()
    131 	if wtyp == protowire.BytesType {
    132 		b, n := protowire.ConsumeBytes(b)
    133 		if n < 0 {
    134 			return out, errDecode
    135 		}
    136 		for len(b) > 0 {
    137 			v, n := protowire.ConsumeVarint(b)
    138 			if n < 0 {
    139 				return out, errDecode
    140 			}
    141 			rv := reflect.New(s.Type().Elem()).Elem()
    142 			rv.SetInt(int64(v))
    143 			s.Set(reflect.Append(s, rv))
    144 			b = b[n:]
    145 		}
    146 		out.n = n
    147 		return out, nil
    148 	}
    149 	if wtyp != protowire.VarintType {
    150 		return out, errUnknown
    151 	}
    152 	v, n := protowire.ConsumeVarint(b)
    153 	if n < 0 {
    154 		return out, errDecode
    155 	}
    156 	rv := reflect.New(s.Type().Elem()).Elem()
    157 	rv.SetInt(int64(v))
    158 	s.Set(reflect.Append(s, rv))
    159 	out.n = n
    160 	return out, nil
    161 }
    162 
    163 func mergeEnumSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
    164 	dst.v.Elem().Set(reflect.AppendSlice(dst.v.Elem(), src.v.Elem()))
    165 }
    166 
    167 var coderEnumSlice = pointerCoderFuncs{
    168 	size:      sizeEnumSlice,
    169 	marshal:   appendEnumSlice,
    170 	unmarshal: consumeEnumSlice,
    171 	merge:     mergeEnumSlice,
    172 }
    173 
    174 func sizeEnumPackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
    175 	s := p.v.Elem()
    176 	llen := s.Len()
    177 	if llen == 0 {
    178 		return 0
    179 	}
    180 	n := 0
    181 	for i := 0; i < llen; i++ {
    182 		n += protowire.SizeVarint(uint64(s.Index(i).Int()))
    183 	}
    184 	return f.tagsize + protowire.SizeBytes(n)
    185 }
    186 
    187 func appendEnumPackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
    188 	s := p.v.Elem()
    189 	llen := s.Len()
    190 	if llen == 0 {
    191 		return b, nil
    192 	}
    193 	b = protowire.AppendVarint(b, f.wiretag)
    194 	n := 0
    195 	for i := 0; i < llen; i++ {
    196 		n += protowire.SizeVarint(uint64(s.Index(i).Int()))
    197 	}
    198 	b = protowire.AppendVarint(b, uint64(n))
    199 	for i := 0; i < llen; i++ {
    200 		b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
    201 	}
    202 	return b, nil
    203 }
    204 
    205 var coderEnumPackedSlice = pointerCoderFuncs{
    206 	size:      sizeEnumPackedSlice,
    207 	marshal:   appendEnumPackedSlice,
    208 	unmarshal: consumeEnumSlice,
    209 	merge:     mergeEnumSlice,
    210 }