podman

Форк
0
/
reflect_optional.go 
129 строк · 3.3 Кб
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
			//pointer to null, we have to allocate memory to hold the value
34
			newPtr := decoder.ValueType.UnsafeNew()
35
			decoder.ValueDecoder.Decode(newPtr, iter)
36
			*((*unsafe.Pointer)(ptr)) = newPtr
37
		} else {
38
			//reuse existing instance
39
			decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
40
		}
41
	}
42
}
43

44
type dereferenceDecoder struct {
45
	// only to deference a pointer
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
		//pointer to null, we have to allocate memory to hold the value
53
		newPtr := decoder.valueType.UnsafeNew()
54
		decoder.valueDecoder.Decode(newPtr, iter)
55
		*((*unsafe.Pointer)(ptr)) = newPtr
56
	} else {
57
		//reuse existing instance
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.