1package jsoniter
2
3import (
4	"reflect"
5	"unsafe"
6)
7
8type objectLazyAny struct {
9	baseAny
10	cfg *frozenConfig
11	buf []byte
12	err error
13}
14
15func (any *objectLazyAny) ValueType() ValueType {
16	return ObjectValue
17}
18
19func (any *objectLazyAny) MustBeValid() Any {
20	return any
21}
22
23func (any *objectLazyAny) LastError() error {
24	return any.err
25}
26
27func (any *objectLazyAny) ToBool() bool {
28	return true
29}
30
31func (any *objectLazyAny) ToInt() int {
32	return 0
33}
34
35func (any *objectLazyAny) ToInt32() int32 {
36	return 0
37}
38
39func (any *objectLazyAny) ToInt64() int64 {
40	return 0
41}
42
43func (any *objectLazyAny) ToUint() uint {
44	return 0
45}
46
47func (any *objectLazyAny) ToUint32() uint32 {
48	return 0
49}
50
51func (any *objectLazyAny) ToUint64() uint64 {
52	return 0
53}
54
55func (any *objectLazyAny) ToFloat32() float32 {
56	return 0
57}
58
59func (any *objectLazyAny) ToFloat64() float64 {
60	return 0
61}
62
63func (any *objectLazyAny) ToString() string {
64	return *(*string)(unsafe.Pointer(&any.buf))
65}
66
67func (any *objectLazyAny) ToVal(obj interface{}) {
68	iter := any.cfg.BorrowIterator(any.buf)
69	defer any.cfg.ReturnIterator(iter)
70	iter.ReadVal(obj)
71}
72
73func (any *objectLazyAny) Get(path ...interface{}) Any {
74	if len(path) == 0 {
75		return any
76	}
77	switch firstPath := path[0].(type) {
78	case string:
79		iter := any.cfg.BorrowIterator(any.buf)
80		defer any.cfg.ReturnIterator(iter)
81		valueBytes := locateObjectField(iter, firstPath)
82		if valueBytes == nil {
83			return newInvalidAny(path)
84		}
85		iter.ResetBytes(valueBytes)
86		return locatePath(iter, path[1:])
87	case int32:
88		if '*' == firstPath {
89			mappedAll := map[string]Any{}
90			iter := any.cfg.BorrowIterator(any.buf)
91			defer any.cfg.ReturnIterator(iter)
92			iter.ReadMapCB(func(iter *Iterator, field string) bool {
93				mapped := locatePath(iter, path[1:])
94				if mapped.ValueType() != InvalidValue {
95					mappedAll[field] = mapped
96				}
97				return true
98			})
99			return wrapMap(mappedAll)
100		}
101		return newInvalidAny(path)
102	default:
103		return newInvalidAny(path)
104	}
105}
106
107func (any *objectLazyAny) Keys() []string {
108	keys := []string{}
109	iter := any.cfg.BorrowIterator(any.buf)
110	defer any.cfg.ReturnIterator(iter)
111	iter.ReadMapCB(func(iter *Iterator, field string) bool {
112		iter.Skip()
113		keys = append(keys, field)
114		return true
115	})
116	return keys
117}
118
119func (any *objectLazyAny) Size() int {
120	size := 0
121	iter := any.cfg.BorrowIterator(any.buf)
122	defer any.cfg.ReturnIterator(iter)
123	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
124		iter.Skip()
125		size++
126		return true
127	})
128	return size
129}
130
131func (any *objectLazyAny) WriteTo(stream *Stream) {
132	stream.Write(any.buf)
133}
134
135func (any *objectLazyAny) GetInterface() interface{} {
136	iter := any.cfg.BorrowIterator(any.buf)
137	defer any.cfg.ReturnIterator(iter)
138	return iter.Read()
139}
140
141type objectAny struct {
142	baseAny
143	err error
144	val reflect.Value
145}
146
147func wrapStruct(val interface{}) *objectAny {
148	return &objectAny{baseAny{}, nil, reflect.ValueOf(val)}
149}
150
151func (any *objectAny) ValueType() ValueType {
152	return ObjectValue
153}
154
155func (any *objectAny) MustBeValid() Any {
156	return any
157}
158
159func (any *objectAny) Parse() *Iterator {
160	return nil
161}
162
163func (any *objectAny) LastError() error {
164	return any.err
165}
166
167func (any *objectAny) ToBool() bool {
168	return any.val.NumField() != 0
169}
170
171func (any *objectAny) ToInt() int {
172	return 0
173}
174
175func (any *objectAny) ToInt32() int32 {
176	return 0
177}
178
179func (any *objectAny) ToInt64() int64 {
180	return 0
181}
182
183func (any *objectAny) ToUint() uint {
184	return 0
185}
186
187func (any *objectAny) ToUint32() uint32 {
188	return 0
189}
190
191func (any *objectAny) ToUint64() uint64 {
192	return 0
193}
194
195func (any *objectAny) ToFloat32() float32 {
196	return 0
197}
198
199func (any *objectAny) ToFloat64() float64 {
200	return 0
201}
202
203func (any *objectAny) ToString() string {
204	str, err := MarshalToString(any.val.Interface())
205	any.err = err
206	return str
207}
208
209func (any *objectAny) Get(path ...interface{}) Any {
210	if len(path) == 0 {
211		return any
212	}
213	switch firstPath := path[0].(type) {
214	case string:
215		field := any.val.FieldByName(firstPath)
216		if !field.IsValid() {
217			return newInvalidAny(path)
218		}
219		return Wrap(field.Interface())
220	case int32:
221		if '*' == firstPath {
222			mappedAll := map[string]Any{}
223			for i := 0; i < any.val.NumField(); i++ {
224				field := any.val.Field(i)
225				if field.CanInterface() {
226					mapped := Wrap(field.Interface()).Get(path[1:]...)
227					if mapped.ValueType() != InvalidValue {
228						mappedAll[any.val.Type().Field(i).Name] = mapped
229					}
230				}
231			}
232			return wrapMap(mappedAll)
233		}
234		return newInvalidAny(path)
235	default:
236		return newInvalidAny(path)
237	}
238}
239
240func (any *objectAny) Keys() []string {
241	keys := make([]string, 0, any.val.NumField())
242	for i := 0; i < any.val.NumField(); i++ {
243		keys = append(keys, any.val.Type().Field(i).Name)
244	}
245	return keys
246}
247
248func (any *objectAny) Size() int {
249	return any.val.NumField()
250}
251
252func (any *objectAny) WriteTo(stream *Stream) {
253	stream.WriteVal(any.val)
254}
255
256func (any *objectAny) GetInterface() interface{} {
257	return any.val.Interface()
258}
259
260type mapAny struct {
261	baseAny
262	err error
263	val reflect.Value
264}
265
266func wrapMap(val interface{}) *mapAny {
267	return &mapAny{baseAny{}, nil, reflect.ValueOf(val)}
268}
269
270func (any *mapAny) ValueType() ValueType {
271	return ObjectValue
272}
273
274func (any *mapAny) MustBeValid() Any {
275	return any
276}
277
278func (any *mapAny) Parse() *Iterator {
279	return nil
280}
281
282func (any *mapAny) LastError() error {
283	return any.err
284}
285
286func (any *mapAny) ToBool() bool {
287	return true
288}
289
290func (any *mapAny) ToInt() int {
291	return 0
292}
293
294func (any *mapAny) ToInt32() int32 {
295	return 0
296}
297
298func (any *mapAny) ToInt64() int64 {
299	return 0
300}
301
302func (any *mapAny) ToUint() uint {
303	return 0
304}
305
306func (any *mapAny) ToUint32() uint32 {
307	return 0
308}
309
310func (any *mapAny) ToUint64() uint64 {
311	return 0
312}
313
314func (any *mapAny) ToFloat32() float32 {
315	return 0
316}
317
318func (any *mapAny) ToFloat64() float64 {
319	return 0
320}
321
322func (any *mapAny) ToString() string {
323	str, err := MarshalToString(any.val.Interface())
324	any.err = err
325	return str
326}
327
328func (any *mapAny) Get(path ...interface{}) Any {
329	if len(path) == 0 {
330		return any
331	}
332	switch firstPath := path[0].(type) {
333	case int32:
334		if '*' == firstPath {
335			mappedAll := map[string]Any{}
336			for _, key := range any.val.MapKeys() {
337				keyAsStr := key.String()
338				element := Wrap(any.val.MapIndex(key).Interface())
339				mapped := element.Get(path[1:]...)
340				if mapped.ValueType() != InvalidValue {
341					mappedAll[keyAsStr] = mapped
342				}
343			}
344			return wrapMap(mappedAll)
345		}
346		return newInvalidAny(path)
347	default:
348		value := any.val.MapIndex(reflect.ValueOf(firstPath))
349		if !value.IsValid() {
350			return newInvalidAny(path)
351		}
352		return Wrap(value.Interface())
353	}
354}
355
356func (any *mapAny) Keys() []string {
357	keys := make([]string, 0, any.val.Len())
358	for _, key := range any.val.MapKeys() {
359		keys = append(keys, key.String())
360	}
361	return keys
362}
363
364func (any *mapAny) Size() int {
365	return any.val.Len()
366}
367
368func (any *mapAny) WriteTo(stream *Stream) {
369	stream.WriteVal(any.val)
370}
371
372func (any *mapAny) GetInterface() interface{} {
373	return any.val.Interface()
374}
375