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