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