feature_reflect_struct_encoder.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package jsoniter
  2. import (
  3. "fmt"
  4. "io"
  5. "reflect"
  6. "unsafe"
  7. )
  8. func encoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  9. type bindingTo struct {
  10. binding *Binding
  11. toName string
  12. ignored bool
  13. }
  14. orderedBindings := []*bindingTo{}
  15. structDescriptor := describeStruct(cfg, prefix, typ)
  16. for _, binding := range structDescriptor.Fields {
  17. for _, toName := range binding.ToNames {
  18. new := &bindingTo{
  19. binding: binding,
  20. toName: toName,
  21. }
  22. for _, old := range orderedBindings {
  23. if old.toName != toName {
  24. continue
  25. }
  26. old.ignored, new.ignored = resolveConflictBinding(cfg, old.binding, new.binding)
  27. }
  28. orderedBindings = append(orderedBindings, new)
  29. }
  30. }
  31. if len(orderedBindings) == 0 {
  32. return &emptyStructEncoder{}
  33. }
  34. finalOrderedFields := []structFieldTo{}
  35. for _, bindingTo := range orderedBindings {
  36. if !bindingTo.ignored {
  37. finalOrderedFields = append(finalOrderedFields, structFieldTo{
  38. encoder: bindingTo.binding.Encoder.(*structFieldEncoder),
  39. toName: bindingTo.toName,
  40. })
  41. }
  42. }
  43. return &structEncoder{typ, finalOrderedFields}
  44. }
  45. func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
  46. newTagged := new.Field.Tag.Get(cfg.getTagKey()) != ""
  47. oldTagged := old.Field.Tag.Get(cfg.getTagKey()) != ""
  48. if newTagged {
  49. if oldTagged {
  50. if len(old.levels) > len(new.levels) {
  51. return true, false
  52. } else if len(new.levels) > len(old.levels) {
  53. return false, true
  54. } else {
  55. return true, true
  56. }
  57. } else {
  58. return true, false
  59. }
  60. } else {
  61. if oldTagged {
  62. return true, false
  63. }
  64. if len(old.levels) > len(new.levels) {
  65. return true, false
  66. } else if len(new.levels) > len(old.levels) {
  67. return false, true
  68. } else {
  69. return true, true
  70. }
  71. }
  72. }
  73. func decoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  74. bindings := map[string]*Binding{}
  75. structDescriptor := describeStruct(cfg, prefix, typ)
  76. for _, binding := range structDescriptor.Fields {
  77. for _, fromName := range binding.FromNames {
  78. old := bindings[fromName]
  79. if old == nil {
  80. bindings[fromName] = binding
  81. continue
  82. }
  83. ignoreOld, ignoreNew := resolveConflictBinding(cfg, old, binding)
  84. if ignoreOld {
  85. delete(bindings, fromName)
  86. }
  87. if !ignoreNew {
  88. bindings[fromName] = binding
  89. }
  90. }
  91. }
  92. fields := map[string]*structFieldDecoder{}
  93. for k, binding := range bindings {
  94. fields[k] = binding.Decoder.(*structFieldDecoder)
  95. }
  96. return createStructDecoder(cfg, typ, fields)
  97. }
  98. type structFieldEncoder struct {
  99. field *reflect.StructField
  100. fieldEncoder ValEncoder
  101. omitempty bool
  102. }
  103. func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  104. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  105. encoder.fieldEncoder.Encode(fieldPtr, stream)
  106. if stream.Error != nil && stream.Error != io.EOF {
  107. stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
  108. }
  109. }
  110. func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  111. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  112. return encoder.fieldEncoder.IsEmpty(fieldPtr)
  113. }
  114. func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
  115. isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil)
  116. if !converted {
  117. return false
  118. }
  119. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  120. return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
  121. }
  122. type IsEmbeddedPtrNil interface {
  123. IsEmbeddedPtrNil(ptr unsafe.Pointer) bool
  124. }
  125. type structEncoder struct {
  126. typ reflect.Type
  127. fields []structFieldTo
  128. }
  129. type structFieldTo struct {
  130. encoder *structFieldEncoder
  131. toName string
  132. }
  133. func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  134. stream.WriteObjectStart()
  135. isNotFirst := false
  136. for _, field := range encoder.fields {
  137. if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
  138. continue
  139. }
  140. if field.encoder.IsEmbeddedPtrNil(ptr) {
  141. continue
  142. }
  143. if isNotFirst {
  144. stream.WriteMore()
  145. }
  146. stream.WriteObjectField(field.toName)
  147. field.encoder.Encode(ptr, stream)
  148. isNotFirst = true
  149. }
  150. stream.WriteObjectEnd()
  151. if stream.Error != nil && stream.Error != io.EOF {
  152. stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
  153. }
  154. }
  155. func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  156. return false
  157. }
  158. type emptyStructEncoder struct {
  159. }
  160. func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  161. stream.WriteEmptyObject()
  162. }
  163. func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  164. return false
  165. }