1package jsoniter
2
3import (
4	"fmt"
5	"io"
6	"reflect"
7)
8
9// Any generic object representation.
10// The lazy json implementation holds []byte and parse lazily.
11type Any interface {
12	LastError() error
13	ValueType() ValueType
14	MustBeValid() Any
15	ToBool() bool
16	ToInt() int
17	ToInt32() int32
18	ToInt64() int64
19	ToUint() uint
20	ToUint32() uint32
21	ToUint64() uint64
22	ToFloat32() float32
23	ToFloat64() float64
24	ToString() string
25	ToVal(val interface{})
26	Get(path ...interface{}) Any
27	// TODO: add Set
28	Size() int
29	Keys() []string
30	GetInterface() interface{}
31	WriteTo(stream *Stream)
32}
33
34type baseAny struct{}
35
36func (any *baseAny) Get(path ...interface{}) Any {
37	return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)}
38}
39
40func (any *baseAny) Size() int {
41	return 0
42}
43
44func (any *baseAny) Keys() []string {
45	return []string{}
46}
47
48func (any *baseAny) ToVal(obj interface{}) {
49	panic("not implemented")
50}
51
52// WrapInt32 turn int32 into Any interface
53func WrapInt32(val int32) Any {
54	return &int32Any{baseAny{}, val}
55}
56
57// WrapInt64 turn int64 into Any interface
58func WrapInt64(val int64) Any {
59	return &int64Any{baseAny{}, val}
60}
61
62// WrapUint32 turn uint32 into Any interface
63func WrapUint32(val uint32) Any {
64	return &uint32Any{baseAny{}, val}
65}
66
67// WrapUint64 turn uint64 into Any interface
68func WrapUint64(val uint64) Any {
69	return &uint64Any{baseAny{}, val}
70}
71
72// WrapFloat64 turn float64 into Any interface
73func WrapFloat64(val float64) Any {
74	return &floatAny{baseAny{}, val}
75}
76
77// WrapString turn string into Any interface
78func WrapString(val string) Any {
79	return &stringAny{baseAny{}, val}
80}
81
82// Wrap turn a go object into Any interface
83func Wrap(val interface{}) Any {
84	if val == nil {
85		return &nilAny{}
86	}
87	asAny, isAny := val.(Any)
88	if isAny {
89		return asAny
90	}
91	typ := reflect.TypeOf(val)
92	switch typ.Kind() {
93	case reflect.Slice:
94		return wrapArray(val)
95	case reflect.Struct:
96		return wrapStruct(val)
97	case reflect.Map:
98		return wrapMap(val)
99	case reflect.String:
100		return WrapString(val.(string))
101	case reflect.Int:
102		return WrapInt64(int64(val.(int)))
103	case reflect.Int8:
104		return WrapInt32(int32(val.(int8)))
105	case reflect.Int16:
106		return WrapInt32(int32(val.(int16)))
107	case reflect.Int32:
108		return WrapInt32(val.(int32))
109	case reflect.Int64:
110		return WrapInt64(val.(int64))
111	case reflect.Uint:
112		return WrapUint64(uint64(val.(uint)))
113	case reflect.Uint8:
114		return WrapUint32(uint32(val.(uint8)))
115	case reflect.Uint16:
116		return WrapUint32(uint32(val.(uint16)))
117	case reflect.Uint32:
118		return WrapUint32(uint32(val.(uint32)))
119	case reflect.Uint64:
120		return WrapUint64(val.(uint64))
121	case reflect.Float32:
122		return WrapFloat64(float64(val.(float32)))
123	case reflect.Float64:
124		return WrapFloat64(val.(float64))
125	case reflect.Bool:
126		if val.(bool) == true {
127			return &trueAny{}
128		}
129		return &falseAny{}
130	}
131	return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)}
132}
133
134// ReadAny read next JSON element as an Any object. It is a better json.RawMessage.
135func (iter *Iterator) ReadAny() Any {
136	return iter.readAny()
137}
138
139func (iter *Iterator) readAny() Any {
140	c := iter.nextToken()
141	switch c {
142	case '"':
143		iter.unreadByte()
144		return &stringAny{baseAny{}, iter.ReadString()}
145	case 'n':
146		iter.skipThreeBytes('u', 'l', 'l') // null
147		return &nilAny{}
148	case 't':
149		iter.skipThreeBytes('r', 'u', 'e') // true
150		return &trueAny{}
151	case 'f':
152		iter.skipFourBytes('a', 'l', 's', 'e') // false
153		return &falseAny{}
154	case '{':
155		return iter.readObjectAny()
156	case '[':
157		return iter.readArrayAny()
158	case '-':
159		return iter.readNumberAny(false)
160	default:
161		return iter.readNumberAny(true)
162	}
163}
164
165func (iter *Iterator) readNumberAny(positive bool) Any {
166	iter.startCapture(iter.head - 1)
167	iter.skipNumber()
168	lazyBuf := iter.stopCapture()
169	return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
170}
171
172func (iter *Iterator) readObjectAny() Any {
173	iter.startCapture(iter.head - 1)
174	iter.skipObject()
175	lazyBuf := iter.stopCapture()
176	return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
177}
178
179func (iter *Iterator) readArrayAny() Any {
180	iter.startCapture(iter.head - 1)
181	iter.skipArray()
182	lazyBuf := iter.stopCapture()
183	return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
184}
185
186func locateObjectField(iter *Iterator, target string) []byte {
187	var found []byte
188	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
189		if field == target {
190			found = iter.SkipAndReturnBytes()
191			return false
192		}
193		iter.Skip()
194		return true
195	})
196	return found
197}
198
199func locateArrayElement(iter *Iterator, target int) []byte {
200	var found []byte
201	n := 0
202	iter.ReadArrayCB(func(iter *Iterator) bool {
203		if n == target {
204			found = iter.SkipAndReturnBytes()
205			return false
206		}
207		iter.Skip()
208		n++
209		return true
210	})
211	return found
212}
213
214func locatePath(iter *Iterator, path []interface{}) Any {
215	for i, pathKeyObj := range path {
216		switch pathKey := pathKeyObj.(type) {
217		case string:
218			valueBytes := locateObjectField(iter, pathKey)
219			if valueBytes == nil {
220				return newInvalidAny(path[i:])
221			}
222			iter.ResetBytes(valueBytes)
223		case int:
224			valueBytes := locateArrayElement(iter, pathKey)
225			if valueBytes == nil {
226				return newInvalidAny(path[i:])
227			}
228			iter.ResetBytes(valueBytes)
229		case int32:
230			if '*' == pathKey {
231				return iter.readAny().Get(path[i:]...)
232			}
233			return newInvalidAny(path[i:])
234		default:
235			return newInvalidAny(path[i:])
236		}
237	}
238	if iter.Error != nil && iter.Error != io.EOF {
239		return &invalidAny{baseAny{}, iter.Error}
240	}
241	return iter.readAny()
242}
243