codec_reflect.go 5.3 KB

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