reflect_struct_encoder.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. type structFieldEncoder struct {
  74. field *reflect.StructField
  75. fieldEncoder ValEncoder
  76. omitempty bool
  77. }
  78. func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  79. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  80. encoder.fieldEncoder.Encode(fieldPtr, stream)
  81. if stream.Error != nil && stream.Error != io.EOF {
  82. stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
  83. }
  84. }
  85. func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  86. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  87. return encoder.fieldEncoder.IsEmpty(fieldPtr)
  88. }
  89. func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
  90. isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil)
  91. if !converted {
  92. return false
  93. }
  94. fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
  95. return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
  96. }
  97. type IsEmbeddedPtrNil interface {
  98. IsEmbeddedPtrNil(ptr unsafe.Pointer) bool
  99. }
  100. type structEncoder struct {
  101. typ reflect.Type
  102. fields []structFieldTo
  103. }
  104. type structFieldTo struct {
  105. encoder *structFieldEncoder
  106. toName string
  107. }
  108. func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  109. stream.WriteObjectStart()
  110. isNotFirst := false
  111. for _, field := range encoder.fields {
  112. if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
  113. continue
  114. }
  115. if field.encoder.IsEmbeddedPtrNil(ptr) {
  116. continue
  117. }
  118. if isNotFirst {
  119. stream.WriteMore()
  120. }
  121. stream.WriteObjectField(field.toName)
  122. field.encoder.Encode(ptr, stream)
  123. isNotFirst = true
  124. }
  125. stream.WriteObjectEnd()
  126. if stream.Error != nil && stream.Error != io.EOF {
  127. stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
  128. }
  129. }
  130. func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  131. return false
  132. }
  133. type emptyStructEncoder struct {
  134. }
  135. func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  136. stream.WriteEmptyObject()
  137. }
  138. func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  139. return false
  140. }
  141. type stringModeNumberEncoder struct {
  142. elemEncoder ValEncoder
  143. }
  144. func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  145. stream.writeByte('"')
  146. encoder.elemEncoder.Encode(ptr, stream)
  147. stream.writeByte('"')
  148. }
  149. func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  150. return encoder.elemEncoder.IsEmpty(ptr)
  151. }
  152. type stringModeStringEncoder struct {
  153. elemEncoder ValEncoder
  154. cfg *frozenConfig
  155. }
  156. func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  157. tempStream := encoder.cfg.BorrowStream(nil)
  158. defer encoder.cfg.ReturnStream(tempStream)
  159. encoder.elemEncoder.Encode(ptr, tempStream)
  160. stream.WriteString(string(tempStream.Buffer()))
  161. }
  162. func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  163. return encoder.elemEncoder.IsEmpty(ptr)
  164. }