1package jsoniter
2
3import (
4	"reflect"
5	"unsafe"
6)
7
8type arrayLazyAny struct {
9	baseAny
10	cfg *frozenConfig
11	buf []byte
12	err error
13}
14
15func (any *arrayLazyAny) ValueType() ValueType {
16	return ArrayValue
17}
18
19func (any *arrayLazyAny) MustBeValid() Any {
20	return any
21}
22
23func (any *arrayLazyAny) LastError() error {
24	return any.err
25}
26
27func (any *arrayLazyAny) ToBool() bool {
28	iter := any.cfg.BorrowIterator(any.buf)
29	defer any.cfg.ReturnIterator(iter)
30	return iter.ReadArray()
31}
32
33func (any *arrayLazyAny) ToInt() int {
34	if any.ToBool() {
35		return 1
36	}
37	return 0
38}
39
40func (any *arrayLazyAny) ToInt32() int32 {
41	if any.ToBool() {
42		return 1
43	}
44	return 0
45}
46
47func (any *arrayLazyAny) ToInt64() int64 {
48	if any.ToBool() {
49		return 1
50	}
51	return 0
52}
53
54func (any *arrayLazyAny) ToUint() uint {
55	if any.ToBool() {
56		return 1
57	}
58	return 0
59}
60
61func (any *arrayLazyAny) ToUint32() uint32 {
62	if any.ToBool() {
63		return 1
64	}
65	return 0
66}
67
68func (any *arrayLazyAny) ToUint64() uint64 {
69	if any.ToBool() {
70		return 1
71	}
72	return 0
73}
74
75func (any *arrayLazyAny) ToFloat32() float32 {
76	if any.ToBool() {
77		return 1
78	}
79	return 0
80}
81
82func (any *arrayLazyAny) ToFloat64() float64 {
83	if any.ToBool() {
84		return 1
85	}
86	return 0
87}
88
89func (any *arrayLazyAny) ToString() string {
90	return *(*string)(unsafe.Pointer(&any.buf))
91}
92
93func (any *arrayLazyAny) ToVal(val interface{}) {
94	iter := any.cfg.BorrowIterator(any.buf)
95	defer any.cfg.ReturnIterator(iter)
96	iter.ReadVal(val)
97}
98
99func (any *arrayLazyAny) Get(path ...interface{}) Any {
100	if len(path) == 0 {
101		return any
102	}
103	switch firstPath := path[0].(type) {
104	case int:
105		iter := any.cfg.BorrowIterator(any.buf)
106		defer any.cfg.ReturnIterator(iter)
107		valueBytes := locateArrayElement(iter, firstPath)
108		if valueBytes == nil {
109			return newInvalidAny(path)
110		}
111		iter.ResetBytes(valueBytes)
112		return locatePath(iter, path[1:])
113	case int32:
114		if '*' == firstPath {
115			iter := any.cfg.BorrowIterator(any.buf)
116			defer any.cfg.ReturnIterator(iter)
117			arr := make([]Any, 0)
118			iter.ReadArrayCB(func(iter *Iterator) bool {
119				found := iter.readAny().Get(path[1:]...)
120				if found.ValueType() != InvalidValue {
121					arr = append(arr, found)
122				}
123				return true
124			})
125			return wrapArray(arr)
126		}
127		return newInvalidAny(path)
128	default:
129		return newInvalidAny(path)
130	}
131}
132
133func (any *arrayLazyAny) Size() int {
134	size := 0
135	iter := any.cfg.BorrowIterator(any.buf)
136	defer any.cfg.ReturnIterator(iter)
137	iter.ReadArrayCB(func(iter *Iterator) bool {
138		size++
139		iter.Skip()
140		return true
141	})
142	return size
143}
144
145func (any *arrayLazyAny) WriteTo(stream *Stream) {
146	stream.Write(any.buf)
147}
148
149func (any *arrayLazyAny) GetInterface() interface{} {
150	iter := any.cfg.BorrowIterator(any.buf)
151	defer any.cfg.ReturnIterator(iter)
152	return iter.Read()
153}
154
155type arrayAny struct {
156	baseAny
157	val reflect.Value
158}
159
160func wrapArray(val interface{}) *arrayAny {
161	return &arrayAny{baseAny{}, reflect.ValueOf(val)}
162}
163
164func (any *arrayAny) ValueType() ValueType {
165	return ArrayValue
166}
167
168func (any *arrayAny) MustBeValid() Any {
169	return any
170}
171
172func (any *arrayAny) LastError() error {
173	return nil
174}
175
176func (any *arrayAny) ToBool() bool {
177	return any.val.Len() != 0
178}
179
180func (any *arrayAny) ToInt() int {
181	if any.val.Len() == 0 {
182		return 0
183	}
184	return 1
185}
186
187func (any *arrayAny) ToInt32() int32 {
188	if any.val.Len() == 0 {
189		return 0
190	}
191	return 1
192}
193
194func (any *arrayAny) ToInt64() int64 {
195	if any.val.Len() == 0 {
196		return 0
197	}
198	return 1
199}
200
201func (any *arrayAny) ToUint() uint {
202	if any.val.Len() == 0 {
203		return 0
204	}
205	return 1
206}
207
208func (any *arrayAny) ToUint32() uint32 {
209	if any.val.Len() == 0 {
210		return 0
211	}
212	return 1
213}
214
215func (any *arrayAny) ToUint64() uint64 {
216	if any.val.Len() == 0 {
217		return 0
218	}
219	return 1
220}
221
222func (any *arrayAny) ToFloat32() float32 {
223	if any.val.Len() == 0 {
224		return 0
225	}
226	return 1
227}
228
229func (any *arrayAny) ToFloat64() float64 {
230	if any.val.Len() == 0 {
231		return 0
232	}
233	return 1
234}
235
236func (any *arrayAny) ToString() string {
237	str, _ := MarshalToString(any.val.Interface())
238	return str
239}
240
241func (any *arrayAny) Get(path ...interface{}) Any {
242	if len(path) == 0 {
243		return any
244	}
245	switch firstPath := path[0].(type) {
246	case int:
247		if firstPath < 0 || firstPath >= any.val.Len() {
248			return newInvalidAny(path)
249		}
250		return Wrap(any.val.Index(firstPath).Interface())
251	case int32:
252		if '*' == firstPath {
253			mappedAll := make([]Any, 0)
254			for i := 0; i < any.val.Len(); i++ {
255				mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...)
256				if mapped.ValueType() != InvalidValue {
257					mappedAll = append(mappedAll, mapped)
258				}
259			}
260			return wrapArray(mappedAll)
261		}
262		return newInvalidAny(path)
263	default:
264		return newInvalidAny(path)
265	}
266}
267
268func (any *arrayAny) Size() int {
269	return any.val.Len()
270}
271
272func (any *arrayAny) WriteTo(stream *Stream) {
273	stream.WriteVal(any.val)
274}
275
276func (any *arrayAny) GetInterface() interface{} {
277	return any.val.Interface()
278}
279