reflect_optional.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package jsoniter
  2. import (
  3. "reflect"
  4. "unsafe"
  5. "github.com/v2pro/plz/reflect2"
  6. )
  7. func decoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  8. elemType := typ.Elem()
  9. decoder := decoderOfType(cfg, prefix, elemType)
  10. if prefix == "" && elemType.Kind() == reflect.Ptr {
  11. return &dereferenceDecoder{reflect2.Type2(elemType), decoder}
  12. }
  13. return &OptionalDecoder{reflect2.Type2(elemType), decoder}
  14. }
  15. func encoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  16. elemType := typ.Elem()
  17. elemEncoder := encoderOfType(cfg, prefix, elemType)
  18. encoder := &OptionalEncoder{elemEncoder}
  19. return encoder
  20. }
  21. type OptionalDecoder struct {
  22. ValueType reflect2.Type
  23. ValueDecoder ValDecoder
  24. }
  25. func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  26. if iter.ReadNil() {
  27. *((*unsafe.Pointer)(ptr)) = nil
  28. } else {
  29. if *((*unsafe.Pointer)(ptr)) == nil {
  30. //pointer to null, we have to allocate memory to hold the value
  31. newPtr := decoder.ValueType.UnsafeNew()
  32. decoder.ValueDecoder.Decode(newPtr, iter)
  33. *((*unsafe.Pointer)(ptr)) = newPtr
  34. } else {
  35. //reuse existing instance
  36. decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
  37. }
  38. }
  39. }
  40. type dereferenceDecoder struct {
  41. // only to deference a pointer
  42. valueType reflect2.Type
  43. valueDecoder ValDecoder
  44. }
  45. func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  46. if *((*unsafe.Pointer)(ptr)) == nil {
  47. //pointer to null, we have to allocate memory to hold the value
  48. newPtr := decoder.valueType.UnsafeNew()
  49. decoder.valueDecoder.Decode(newPtr, iter)
  50. *((*unsafe.Pointer)(ptr)) = newPtr
  51. } else {
  52. //reuse existing instance
  53. decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
  54. }
  55. }
  56. type OptionalEncoder struct {
  57. ValueEncoder ValEncoder
  58. }
  59. func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  60. if *((*unsafe.Pointer)(ptr)) == nil {
  61. stream.WriteNil()
  62. } else {
  63. encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
  64. }
  65. }
  66. func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  67. return *((*unsafe.Pointer)(ptr)) == nil
  68. }
  69. type dereferenceEncoder struct {
  70. ValueEncoder ValEncoder
  71. }
  72. func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  73. if *((*unsafe.Pointer)(ptr)) == nil {
  74. stream.WriteNil()
  75. } else {
  76. encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
  77. }
  78. }
  79. func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  80. dePtr := *((*unsafe.Pointer)(ptr))
  81. if dePtr == nil {
  82. return true
  83. }
  84. return encoder.ValueEncoder.IsEmpty(dePtr)
  85. }
  86. func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
  87. deReferenced := *((*unsafe.Pointer)(ptr))
  88. if deReferenced == nil {
  89. return true
  90. }
  91. isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil)
  92. if !converted {
  93. return false
  94. }
  95. fieldPtr := unsafe.Pointer(deReferenced)
  96. return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
  97. }
  98. type referenceEncoder struct {
  99. encoder ValEncoder
  100. }
  101. func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  102. encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
  103. }
  104. func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  105. return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
  106. }
  107. type referenceDecoder struct {
  108. decoder ValDecoder
  109. }
  110. func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  111. decoder.decoder.Decode(unsafe.Pointer(&ptr), iter)
  112. }