podman

Форк
0
104 строки · 2.6 Кб
1
package jsoniter
2

3
import (
4
	"fmt"
5
	"github.com/modern-go/reflect2"
6
	"io"
7
	"unsafe"
8
)
9

10
func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
11
	arrayType := typ.(*reflect2.UnsafeArrayType)
12
	decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
13
	return &arrayDecoder{arrayType, decoder}
14
}
15

16
func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
17
	arrayType := typ.(*reflect2.UnsafeArrayType)
18
	if arrayType.Len() == 0 {
19
		return emptyArrayEncoder{}
20
	}
21
	encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
22
	return &arrayEncoder{arrayType, encoder}
23
}
24

25
type emptyArrayEncoder struct{}
26

27
func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
28
	stream.WriteEmptyArray()
29
}
30

31
func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
32
	return true
33
}
34

35
type arrayEncoder struct {
36
	arrayType   *reflect2.UnsafeArrayType
37
	elemEncoder ValEncoder
38
}
39

40
func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
41
	stream.WriteArrayStart()
42
	elemPtr := unsafe.Pointer(ptr)
43
	encoder.elemEncoder.Encode(elemPtr, stream)
44
	for i := 1; i < encoder.arrayType.Len(); i++ {
45
		stream.WriteMore()
46
		elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
47
		encoder.elemEncoder.Encode(elemPtr, stream)
48
	}
49
	stream.WriteArrayEnd()
50
	if stream.Error != nil && stream.Error != io.EOF {
51
		stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
52
	}
53
}
54

55
func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
56
	return false
57
}
58

59
type arrayDecoder struct {
60
	arrayType   *reflect2.UnsafeArrayType
61
	elemDecoder ValDecoder
62
}
63

64
func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
65
	decoder.doDecode(ptr, iter)
66
	if iter.Error != nil && iter.Error != io.EOF {
67
		iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
68
	}
69
}
70

71
func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
72
	c := iter.nextToken()
73
	arrayType := decoder.arrayType
74
	if c == 'n' {
75
		iter.skipThreeBytes('u', 'l', 'l')
76
		return
77
	}
78
	if c != '[' {
79
		iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
80
		return
81
	}
82
	c = iter.nextToken()
83
	if c == ']' {
84
		return
85
	}
86
	iter.unreadByte()
87
	elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
88
	decoder.elemDecoder.Decode(elemPtr, iter)
89
	length := 1
90
	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
91
		if length >= arrayType.Len() {
92
			iter.Skip()
93
			continue
94
		}
95
		idx := length
96
		length += 1
97
		elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
98
		decoder.elemDecoder.Decode(elemPtr, iter)
99
	}
100
	if c != ']' {
101
		iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
102
		return
103
	}
104
}
105

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

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

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

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