podman
104 строки · 2.6 Кб
1package jsoniter
2
3import (
4"fmt"
5"github.com/modern-go/reflect2"
6"io"
7"unsafe"
8)
9
10func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
11arrayType := typ.(*reflect2.UnsafeArrayType)
12decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
13return &arrayDecoder{arrayType, decoder}
14}
15
16func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
17arrayType := typ.(*reflect2.UnsafeArrayType)
18if arrayType.Len() == 0 {
19return emptyArrayEncoder{}
20}
21encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
22return &arrayEncoder{arrayType, encoder}
23}
24
25type emptyArrayEncoder struct{}
26
27func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
28stream.WriteEmptyArray()
29}
30
31func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
32return true
33}
34
35type arrayEncoder struct {
36arrayType *reflect2.UnsafeArrayType
37elemEncoder ValEncoder
38}
39
40func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
41stream.WriteArrayStart()
42elemPtr := unsafe.Pointer(ptr)
43encoder.elemEncoder.Encode(elemPtr, stream)
44for i := 1; i < encoder.arrayType.Len(); i++ {
45stream.WriteMore()
46elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
47encoder.elemEncoder.Encode(elemPtr, stream)
48}
49stream.WriteArrayEnd()
50if stream.Error != nil && stream.Error != io.EOF {
51stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
52}
53}
54
55func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
56return false
57}
58
59type arrayDecoder struct {
60arrayType *reflect2.UnsafeArrayType
61elemDecoder ValDecoder
62}
63
64func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
65decoder.doDecode(ptr, iter)
66if iter.Error != nil && iter.Error != io.EOF {
67iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
68}
69}
70
71func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
72c := iter.nextToken()
73arrayType := decoder.arrayType
74if c == 'n' {
75iter.skipThreeBytes('u', 'l', 'l')
76return
77}
78if c != '[' {
79iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
80return
81}
82c = iter.nextToken()
83if c == ']' {
84return
85}
86iter.unreadByte()
87elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
88decoder.elemDecoder.Decode(elemPtr, iter)
89length := 1
90for c = iter.nextToken(); c == ','; c = iter.nextToken() {
91if length >= arrayType.Len() {
92iter.Skip()
93continue
94}
95idx := length
96length += 1
97elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
98decoder.elemDecoder.Decode(elemPtr, iter)
99}
100if c != ']' {
101iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
102return
103}
104}
105