reflect_struct_encoder.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. package jsoniter
  2. import (
  3. "fmt"
  4. "io"
  5. "reflect"
  6. "unsafe"
  7. "github.com/v2pro/plz/reflect2"
  8. )
  9. func encoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  10. type bindingTo struct {
  11. binding *Binding
  12. toName string
  13. ignored bool
  14. }
  15. orderedBindings := []*bindingTo{}
  16. structDescriptor := describeStruct(cfg, prefix, typ)
  17. for _, binding := range structDescriptor.Fields {
  18. for _, toName := range binding.ToNames {
  19. new := &bindingTo{
  20. binding: binding,
  21. toName: toName,
  22. }
  23. for _, old := range orderedBindings {
  24. if old.toName != toName {
  25. continue
  26. }
  27. old.ignored, new.ignored = resolveConflictBinding(cfg, old.binding, new.binding)
  28. }
  29. orderedBindings = append(orderedBindings, new)
  30. }
  31. }
  32. if len(orderedBindings) == 0 {
  33. return &emptyStructEncoder{}
  34. }
  35. finalOrderedFields := []structFieldTo{}
  36. for _, bindingTo := range orderedBindings {
  37. if !bindingTo.ignored {
  38. finalOrderedFields = append(finalOrderedFields, structFieldTo{
  39. encoder: bindingTo.binding.Encoder.(*structFieldEncoder),
  40. toName: bindingTo.toName,
  41. })
  42. }
  43. }
  44. return &structEncoder{typ, finalOrderedFields}
  45. }
  46. func createCheckIsEmpty(cfg *frozenConfig, typ reflect.Type) checkIsEmpty {
  47. kind := typ.Kind()
  48. switch kind {
  49. case reflect.String:
  50. return &stringCodec{}
  51. case reflect.Int:
  52. return &intCodec{}
  53. case reflect.Int8:
  54. return &int8Codec{}
  55. case reflect.Int16:
  56. return &int16Codec{}
  57. case reflect.Int32:
  58. return &int32Codec{}
  59. case reflect.Int64:
  60. return &int64Codec{}
  61. case reflect.Uint:
  62. return &uintCodec{}
  63. case reflect.Uint8:
  64. return &uint8Codec{}
  65. case reflect.Uint16:
  66. return &uint16Codec{}
  67. case reflect.Uint32:
  68. return &uint32Codec{}
  69. case reflect.Uintptr:
  70. return &uintptrCodec{}
  71. case reflect.Uint64:
  72. return &uint64Codec{}
  73. case reflect.Float32:
  74. return &float32Codec{}
  75. case reflect.Float64:
  76. return &float64Codec{}
  77. case reflect.Bool:
  78. return &boolCodec{}
  79. case reflect.Interface:
  80. return &dynamicEncoder{reflect2.Type2(typ)}
  81. case reflect.Struct:
  82. return &structEncoder{typ: typ}
  83. case reflect.Array:
  84. return &arrayEncoder{}
  85. case reflect.Slice:
  86. return &sliceEncoder{}
  87. case reflect.Map:
  88. return encoderOfMap(cfg, "", typ)
  89. case reflect.Ptr:
  90. return &OptionalEncoder{}
  91. default:
  92. return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)}
  93. }
  94. }
  95. func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
  96. newTagged := new.Field.Tag.Get(cfg.getTagKey()) != ""
  97. oldTagged := old.Field.Tag.Get(cfg.getTagKey()) != ""
  98. if newTagged {
  99. if oldTagged {
  100. if len(old.levels) > len(new.levels) {
  101. return true, false
  102. } else if len(new.levels) > len(old.levels) {
  103. return false, true
  104. } else {
  105. return true, true
  106. }
  107. } else {
  108. return true, false
  109. }
  110. } else {
  111. if oldTagged {
  112. return true, false
  113. }
  114. if len(old.levels) > len(new.levels) {
  115. return true, false
  116. } else if len(new.levels) > len(old.levels) {
  117. return false, true
  118. } else {
  119. return true, true
  120. }
  121. }
  122. }
  123. type structFieldEncoder struct {
  124. field *reflect.StructField
  125. fieldEncoder ValEncoder
  126. omitempty bool
  127. }
  128. func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  129. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  130. encoder.fieldEncoder.Encode(fieldPtr, stream)
  131. if stream.Error != nil && stream.Error != io.EOF {
  132. stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
  133. }
  134. }
  135. func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  136. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  137. return encoder.fieldEncoder.IsEmpty(fieldPtr)
  138. }
  139. func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
  140. isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil)
  141. if !converted {
  142. return false
  143. }
  144. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  145. return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
  146. }
  147. type IsEmbeddedPtrNil interface {
  148. IsEmbeddedPtrNil(ptr unsafe.Pointer) bool
  149. }
  150. type structEncoder struct {
  151. typ reflect.Type
  152. fields []structFieldTo
  153. }
  154. type structFieldTo struct {
  155. encoder *structFieldEncoder
  156. toName string
  157. }
  158. func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  159. stream.WriteObjectStart()
  160. isNotFirst := false
  161. for _, field := range encoder.fields {
  162. if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
  163. continue
  164. }
  165. if field.encoder.IsEmbeddedPtrNil(ptr) {
  166. continue
  167. }
  168. if isNotFirst {
  169. stream.WriteMore()
  170. }
  171. stream.WriteObjectField(field.toName)
  172. field.encoder.Encode(ptr, stream)
  173. isNotFirst = true
  174. }
  175. stream.WriteObjectEnd()
  176. if stream.Error != nil && stream.Error != io.EOF {
  177. stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
  178. }
  179. }
  180. func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  181. return false
  182. }
  183. type emptyStructEncoder struct {
  184. }
  185. func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  186. stream.WriteEmptyObject()
  187. }
  188. func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  189. return false
  190. }
  191. type stringModeNumberEncoder struct {
  192. elemEncoder ValEncoder
  193. }
  194. func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  195. stream.writeByte('"')
  196. encoder.elemEncoder.Encode(ptr, stream)
  197. stream.writeByte('"')
  198. }
  199. func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  200. return encoder.elemEncoder.IsEmpty(ptr)
  201. }
  202. type stringModeStringEncoder struct {
  203. elemEncoder ValEncoder
  204. cfg *frozenConfig
  205. }
  206. func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  207. tempStream := encoder.cfg.BorrowStream(nil)
  208. defer encoder.cfg.ReturnStream(tempStream)
  209. encoder.elemEncoder.Encode(ptr, tempStream)
  210. stream.WriteString(string(tempStream.Buffer()))
  211. }
  212. func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  213. return encoder.elemEncoder.IsEmpty(ptr)
  214. }