feature_reflect_optional.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package jsoniter
  2. import (
  3. "reflect"
  4. "unsafe"
  5. )
  6. func decoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  7. elemType := typ.Elem()
  8. decoder := decoderOfType(cfg, prefix, elemType)
  9. return &OptionalDecoder{elemType, decoder}
  10. }
  11. func encoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  12. elemType := typ.Elem()
  13. elemEncoder := encoderOfType(cfg, prefix, elemType)
  14. encoder := &OptionalEncoder{elemEncoder}
  15. if elemType.Kind() == reflect.Map {
  16. encoder = &OptionalEncoder{encoder}
  17. }
  18. return encoder
  19. }
  20. type OptionalDecoder struct {
  21. ValueType reflect.Type
  22. ValueDecoder ValDecoder
  23. }
  24. func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  25. if iter.ReadNil() {
  26. *((*unsafe.Pointer)(ptr)) = nil
  27. } else {
  28. if *((*unsafe.Pointer)(ptr)) == nil {
  29. //pointer to null, we have to allocate memory to hold the value
  30. value := reflect.New(decoder.ValueType)
  31. newPtr := extractInterface(value.Interface()).word
  32. decoder.ValueDecoder.Decode(newPtr, iter)
  33. *((*uintptr)(ptr)) = uintptr(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 reflect.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. value := reflect.New(decoder.valueType)
  49. newPtr := extractInterface(value.Interface()).word
  50. decoder.valueDecoder.Decode(newPtr, iter)
  51. *((*uintptr)(ptr)) = uintptr(newPtr)
  52. } else {
  53. //reuse existing instance
  54. decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
  55. }
  56. }
  57. type OptionalEncoder struct {
  58. ValueEncoder ValEncoder
  59. }
  60. func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  61. if *((*unsafe.Pointer)(ptr)) == nil {
  62. stream.WriteNil()
  63. } else {
  64. encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
  65. }
  66. }
  67. func (encoder *OptionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
  68. WriteToStream(val, stream, encoder)
  69. }
  70. func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  71. return *((*unsafe.Pointer)(ptr)) == nil
  72. }
  73. type dereferenceEncoder struct {
  74. ValueEncoder ValEncoder
  75. }
  76. func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  77. if *((*unsafe.Pointer)(ptr)) == nil {
  78. stream.WriteNil()
  79. } else {
  80. encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
  81. }
  82. }
  83. func (encoder *dereferenceEncoder) EncodeInterface(val interface{}, stream *Stream) {
  84. WriteToStream(val, stream, encoder)
  85. }
  86. func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  87. return encoder.ValueEncoder.IsEmpty(*((*unsafe.Pointer)(ptr)))
  88. }
  89. type optionalMapEncoder struct {
  90. valueEncoder ValEncoder
  91. }
  92. func (encoder *optionalMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  93. if *((*unsafe.Pointer)(ptr)) == nil {
  94. stream.WriteNil()
  95. } else {
  96. encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
  97. }
  98. }
  99. func (encoder *optionalMapEncoder) EncodeInterface(val interface{}, stream *Stream) {
  100. WriteToStream(val, stream, encoder)
  101. }
  102. func (encoder *optionalMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  103. p := *((*unsafe.Pointer)(ptr))
  104. return p == nil || encoder.valueEncoder.IsEmpty(p)
  105. }