feature_reflect_object.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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, structDescriptor.onePtrEmbedded,
  44. structDescriptor.onePtrOptimization, finalOrderedFields}
  45. }
  46. func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
  47. newTagged := new.Field.Tag.Get(cfg.getTagKey()) != ""
  48. oldTagged := old.Field.Tag.Get(cfg.getTagKey()) != ""
  49. if newTagged {
  50. if oldTagged {
  51. if len(old.levels) > len(new.levels) {
  52. return true, false
  53. } else if len(new.levels) > len(old.levels) {
  54. return false, true
  55. } else {
  56. return true, true
  57. }
  58. } else {
  59. return true, false
  60. }
  61. } else {
  62. if oldTagged {
  63. return true, false
  64. }
  65. if len(old.levels) > len(new.levels) {
  66. return true, false
  67. } else if len(new.levels) > len(old.levels) {
  68. return false, true
  69. } else {
  70. return true, true
  71. }
  72. }
  73. }
  74. func decoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  75. bindings := map[string]*Binding{}
  76. structDescriptor := describeStruct(cfg, prefix, typ)
  77. for _, binding := range structDescriptor.Fields {
  78. for _, fromName := range binding.FromNames {
  79. old := bindings[fromName]
  80. if old == nil {
  81. bindings[fromName] = binding
  82. continue
  83. }
  84. ignoreOld, ignoreNew := resolveConflictBinding(cfg, old, binding)
  85. if ignoreOld {
  86. delete(bindings, fromName)
  87. }
  88. if !ignoreNew {
  89. bindings[fromName] = binding
  90. }
  91. }
  92. }
  93. fields := map[string]*structFieldDecoder{}
  94. for k, binding := range bindings {
  95. fields[k] = binding.Decoder.(*structFieldDecoder)
  96. }
  97. return createStructDecoder(cfg, typ, fields)
  98. }
  99. type structFieldEncoder struct {
  100. field *reflect.StructField
  101. fieldEncoder ValEncoder
  102. omitempty bool
  103. }
  104. func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  105. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  106. encoder.fieldEncoder.Encode(fieldPtr, stream)
  107. if stream.Error != nil && stream.Error != io.EOF {
  108. stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
  109. }
  110. }
  111. func (encoder *structFieldEncoder) EncodeInterface(val interface{}, stream *Stream) {
  112. WriteToStream(val, stream, encoder)
  113. }
  114. func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  115. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  116. return encoder.fieldEncoder.IsEmpty(fieldPtr)
  117. }
  118. type structEncoder struct {
  119. typ reflect.Type
  120. onePtrEmbedded bool
  121. onePtrOptimization bool
  122. fields []structFieldTo
  123. }
  124. type structFieldTo struct {
  125. encoder *structFieldEncoder
  126. toName string
  127. }
  128. func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  129. stream.WriteObjectStart()
  130. isNotFirst := false
  131. for _, field := range encoder.fields {
  132. if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
  133. continue
  134. }
  135. if isNotFirst {
  136. stream.WriteMore()
  137. }
  138. stream.WriteObjectField(field.toName)
  139. field.encoder.Encode(ptr, stream)
  140. isNotFirst = true
  141. }
  142. stream.WriteObjectEnd()
  143. if stream.Error != nil && stream.Error != io.EOF {
  144. stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
  145. }
  146. }
  147. func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) {
  148. e := (*emptyInterface)(unsafe.Pointer(&val))
  149. if encoder.onePtrOptimization {
  150. if e.word == nil && encoder.onePtrEmbedded {
  151. stream.WriteObjectStart()
  152. stream.WriteObjectEnd()
  153. return
  154. }
  155. ptr := uintptr(e.word)
  156. e.word = unsafe.Pointer(&ptr)
  157. }
  158. if reflect.TypeOf(val).Kind() == reflect.Ptr {
  159. encoder.Encode(unsafe.Pointer(&e.word), stream)
  160. } else {
  161. encoder.Encode(e.word, stream)
  162. }
  163. }
  164. func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  165. return false
  166. }
  167. type emptyStructEncoder struct {
  168. }
  169. func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  170. stream.WriteEmptyObject()
  171. }
  172. func (encoder *emptyStructEncoder) EncodeInterface(val interface{}, stream *Stream) {
  173. WriteToStream(val, stream, encoder)
  174. }
  175. func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  176. return false
  177. }