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