feature_reflect_object.go 4.9 KB

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