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