reflect_marshaler.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. package jsoniter
  2. import (
  3. "github.com/v2pro/plz/reflect2"
  4. "unsafe"
  5. "encoding"
  6. "encoding/json"
  7. "reflect"
  8. )
  9. func createDecoderOfMarshaler(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  10. ptrType := reflect.PtrTo(typ)
  11. if ptrType.Implements(unmarshalerType) {
  12. return &referenceDecoder{
  13. &unmarshalerDecoder{reflect2.Type2(ptrType)},
  14. }
  15. }
  16. if ptrType.Implements(textUnmarshalerType) {
  17. return &referenceDecoder{
  18. &textUnmarshalerDecoder{reflect2.Type2(ptrType)},
  19. }
  20. }
  21. return nil
  22. }
  23. func createEncoderOfMarshaler(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  24. if typ == marshalerType {
  25. checkIsEmpty := createCheckIsEmpty(cfg, typ)
  26. var encoder ValEncoder = &directMarshalerEncoder{
  27. checkIsEmpty: checkIsEmpty,
  28. }
  29. return encoder
  30. }
  31. if typ.Implements(marshalerType) {
  32. checkIsEmpty := createCheckIsEmpty(cfg, typ)
  33. var encoder ValEncoder = &marshalerEncoder{
  34. valType: reflect2.Type2(typ),
  35. checkIsEmpty: checkIsEmpty,
  36. }
  37. return encoder
  38. }
  39. ptrType := reflect.PtrTo(typ)
  40. if prefix != "" && ptrType.Implements(marshalerType) {
  41. checkIsEmpty := createCheckIsEmpty(cfg, ptrType)
  42. var encoder ValEncoder = &marshalerEncoder{
  43. valType: reflect2.Type2(ptrType),
  44. checkIsEmpty: checkIsEmpty,
  45. }
  46. return &referenceEncoder{encoder}
  47. }
  48. if typ == textMarshalerType {
  49. checkIsEmpty := createCheckIsEmpty(cfg, typ)
  50. var encoder ValEncoder = &directTextMarshalerEncoder{
  51. checkIsEmpty: checkIsEmpty,
  52. stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
  53. }
  54. return encoder
  55. }
  56. if typ.Implements(textMarshalerType) {
  57. checkIsEmpty := createCheckIsEmpty(cfg, typ)
  58. var encoder ValEncoder = &textMarshalerEncoder{
  59. valType: reflect2.Type2(typ),
  60. stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
  61. checkIsEmpty: checkIsEmpty,
  62. }
  63. return encoder
  64. }
  65. // if prefix is empty, the type is the root type
  66. if prefix != "" && ptrType.Implements(textMarshalerType) {
  67. checkIsEmpty := createCheckIsEmpty(cfg, ptrType)
  68. var encoder ValEncoder = &textMarshalerEncoder{
  69. valType: reflect2.Type2(ptrType),
  70. stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
  71. checkIsEmpty: checkIsEmpty,
  72. }
  73. return &referenceEncoder{encoder}
  74. }
  75. return nil
  76. }
  77. type marshalerEncoder struct {
  78. checkIsEmpty checkIsEmpty
  79. valType reflect2.Type
  80. }
  81. func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  82. obj := encoder.valType.UnsafeIndirect(ptr)
  83. if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
  84. stream.WriteNil()
  85. return
  86. }
  87. marshaler := obj.(json.Marshaler)
  88. bytes, err := marshaler.MarshalJSON()
  89. if err != nil {
  90. stream.Error = err
  91. } else {
  92. stream.Write(bytes)
  93. }
  94. }
  95. func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  96. return encoder.checkIsEmpty.IsEmpty(ptr)
  97. }
  98. type directMarshalerEncoder struct {
  99. checkIsEmpty checkIsEmpty
  100. }
  101. func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  102. marshaler := *(*json.Marshaler)(ptr)
  103. if marshaler == nil {
  104. stream.WriteNil()
  105. return
  106. }
  107. bytes, err := marshaler.MarshalJSON()
  108. if err != nil {
  109. stream.Error = err
  110. } else {
  111. stream.Write(bytes)
  112. }
  113. }
  114. func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  115. return encoder.checkIsEmpty.IsEmpty(ptr)
  116. }
  117. type textMarshalerEncoder struct {
  118. valType reflect2.Type
  119. stringEncoder ValEncoder
  120. checkIsEmpty checkIsEmpty
  121. }
  122. func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  123. obj := encoder.valType.UnsafeIndirect(ptr)
  124. if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
  125. stream.WriteNil()
  126. return
  127. }
  128. marshaler := (obj).(encoding.TextMarshaler)
  129. bytes, err := marshaler.MarshalText()
  130. if err != nil {
  131. stream.Error = err
  132. } else {
  133. str := string(bytes)
  134. encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream)
  135. }
  136. }
  137. func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  138. return encoder.checkIsEmpty.IsEmpty(ptr)
  139. }
  140. type directTextMarshalerEncoder struct {
  141. stringEncoder ValEncoder
  142. checkIsEmpty checkIsEmpty
  143. }
  144. func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  145. marshaler := *(*encoding.TextMarshaler)(ptr)
  146. if marshaler == nil {
  147. stream.WriteNil()
  148. return
  149. }
  150. bytes, err := marshaler.MarshalText()
  151. if err != nil {
  152. stream.Error = err
  153. } else {
  154. str := string(bytes)
  155. encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream)
  156. }
  157. }
  158. func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  159. return encoder.checkIsEmpty.IsEmpty(ptr)
  160. }
  161. type unmarshalerDecoder struct {
  162. valType reflect2.Type
  163. }
  164. func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  165. valType := decoder.valType
  166. obj := valType.UnsafeIndirect(ptr)
  167. unmarshaler := obj.(json.Unmarshaler)
  168. iter.nextToken()
  169. iter.unreadByte() // skip spaces
  170. bytes := iter.SkipAndReturnBytes()
  171. err := unmarshaler.UnmarshalJSON(bytes)
  172. if err != nil {
  173. iter.ReportError("unmarshalerDecoder", err.Error())
  174. }
  175. }
  176. type textUnmarshalerDecoder struct {
  177. valType reflect2.Type
  178. }
  179. func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  180. valType := decoder.valType
  181. obj := valType.UnsafeIndirect(ptr)
  182. if reflect2.IsNil(obj) {
  183. ptrType := valType.(*reflect2.UnsafePtrType)
  184. elemType := ptrType.Elem()
  185. elem := elemType.UnsafeNew()
  186. ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem))
  187. obj = valType.UnsafeIndirect(ptr)
  188. }
  189. unmarshaler := (obj).(encoding.TextUnmarshaler)
  190. str := iter.ReadString()
  191. err := unmarshaler.UnmarshalText([]byte(str))
  192. if err != nil {
  193. iter.ReportError("textUnmarshalerDecoder", err.Error())
  194. }
  195. }