reflect_marshaler.go 5.8 KB

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