feature_reflect_object.go 4.8 KB

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