reflect_optional.go 3.3 KB

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