diff options
Diffstat (limited to 'vendor/github.com/json-iterator/go/reflect_array.go')
-rw-r--r-- | vendor/github.com/json-iterator/go/reflect_array.go | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go new file mode 100644 index 0000000..13a0b7b --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_array.go | |||
@@ -0,0 +1,104 @@ | |||
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 | } | ||