1package jsoniter
2
3import (
4	"encoding/json"
5	"fmt"
6	"io"
7)
8
9// ValueType the type for JSON element
10type ValueType int
11
12const (
13	// InvalidValue invalid JSON element
14	InvalidValue ValueType = iota
15	// StringValue JSON element "string"
16	StringValue
17	// NumberValue JSON element 100 or 0.10
18	NumberValue
19	// NilValue JSON element null
20	NilValue
21	// BoolValue JSON element true or false
22	BoolValue
23	// ArrayValue JSON element []
24	ArrayValue
25	// ObjectValue JSON element {}
26	ObjectValue
27)
28
29var hexDigits []byte
30var valueTypes []ValueType
31
32func init() {
33	hexDigits = make([]byte, 256)
34	for i := 0; i < len(hexDigits); i++ {
35		hexDigits[i] = 255
36	}
37	for i := '0'; i <= '9'; i++ {
38		hexDigits[i] = byte(i - '0')
39	}
40	for i := 'a'; i <= 'f'; i++ {
41		hexDigits[i] = byte((i - 'a') + 10)
42	}
43	for i := 'A'; i <= 'F'; i++ {
44		hexDigits[i] = byte((i - 'A') + 10)
45	}
46	valueTypes = make([]ValueType, 256)
47	for i := 0; i < len(valueTypes); i++ {
48		valueTypes[i] = InvalidValue
49	}
50	valueTypes['"'] = StringValue
51	valueTypes['-'] = NumberValue
52	valueTypes['0'] = NumberValue
53	valueTypes['1'] = NumberValue
54	valueTypes['2'] = NumberValue
55	valueTypes['3'] = NumberValue
56	valueTypes['4'] = NumberValue
57	valueTypes['5'] = NumberValue
58	valueTypes['6'] = NumberValue
59	valueTypes['7'] = NumberValue
60	valueTypes['8'] = NumberValue
61	valueTypes['9'] = NumberValue
62	valueTypes['t'] = BoolValue
63	valueTypes['f'] = BoolValue
64	valueTypes['n'] = NilValue
65	valueTypes['['] = ArrayValue
66	valueTypes['{'] = ObjectValue
67}
68
69// Iterator is a io.Reader like object, with JSON specific read functions.
70// Error is not returned as return value, but stored as Error member on this iterator instance.
71type Iterator struct {
72	cfg              *frozenConfig
73	reader           io.Reader
74	buf              []byte
75	head             int
76	tail             int
77	depth            int
78	captureStartedAt int
79	captured         []byte
80	Error            error
81	Attachment       interface{} // open for customized decoder
82}
83
84// NewIterator creates an empty Iterator instance
85func NewIterator(cfg API) *Iterator {
86	return &Iterator{
87		cfg:    cfg.(*frozenConfig),
88		reader: nil,
89		buf:    nil,
90		head:   0,
91		tail:   0,
92		depth:  0,
93	}
94}
95
96// Parse creates an Iterator instance from io.Reader
97func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
98	return &Iterator{
99		cfg:    cfg.(*frozenConfig),
100		reader: reader,
101		buf:    make([]byte, bufSize),
102		head:   0,
103		tail:   0,
104		depth:  0,
105	}
106}
107
108// ParseBytes creates an Iterator instance from byte array
109func ParseBytes(cfg API, input []byte) *Iterator {
110	return &Iterator{
111		cfg:    cfg.(*frozenConfig),
112		reader: nil,
113		buf:    input,
114		head:   0,
115		tail:   len(input),
116		depth:  0,
117	}
118}
119
120// ParseString creates an Iterator instance from string
121func ParseString(cfg API, input string) *Iterator {
122	return ParseBytes(cfg, []byte(input))
123}
124
125// Pool returns a pool can provide more iterator with same configuration
126func (iter *Iterator) Pool() IteratorPool {
127	return iter.cfg
128}
129
130// Reset reuse iterator instance by specifying another reader
131func (iter *Iterator) Reset(reader io.Reader) *Iterator {
132	iter.reader = reader
133	iter.head = 0
134	iter.tail = 0
135	iter.depth = 0
136	return iter
137}
138
139// ResetBytes reuse iterator instance by specifying another byte array as input
140func (iter *Iterator) ResetBytes(input []byte) *Iterator {
141	iter.reader = nil
142	iter.buf = input
143	iter.head = 0
144	iter.tail = len(input)
145	iter.depth = 0
146	return iter
147}
148
149// WhatIsNext gets ValueType of relatively next json element
150func (iter *Iterator) WhatIsNext() ValueType {
151	valueType := valueTypes[iter.nextToken()]
152	iter.unreadByte()
153	return valueType
154}
155
156func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
157	for i := iter.head; i < iter.tail; i++ {
158		c := iter.buf[i]
159		switch c {
160		case ' ', '\n', '\t', '\r':
161			continue
162		}
163		iter.head = i
164		return false
165	}
166	return true
167}
168
169func (iter *Iterator) isObjectEnd() bool {
170	c := iter.nextToken()
171	if c == ',' {
172		return false
173	}
174	if c == '}' {
175		return true
176	}
177	iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
178	return true
179}
180
181func (iter *Iterator) nextToken() byte {
182	// a variation of skip whitespaces, returning the next non-whitespace token
183	for {
184		for i := iter.head; i < iter.tail; i++ {
185			c := iter.buf[i]
186			switch c {
187			case ' ', '\n', '\t', '\r':
188				continue
189			}
190			iter.head = i + 1
191			return c
192		}
193		if !iter.loadMore() {
194			return 0
195		}
196	}
197}
198
199// ReportError record a error in iterator instance with current position.
200func (iter *Iterator) ReportError(operation string, msg string) {
201	if iter.Error != nil {
202		if iter.Error != io.EOF {
203			return
204		}
205	}
206	peekStart := iter.head - 10
207	if peekStart < 0 {
208		peekStart = 0
209	}
210	peekEnd := iter.head + 10
211	if peekEnd > iter.tail {
212		peekEnd = iter.tail
213	}
214	parsing := string(iter.buf[peekStart:peekEnd])
215	contextStart := iter.head - 50
216	if contextStart < 0 {
217		contextStart = 0
218	}
219	contextEnd := iter.head + 50
220	if contextEnd > iter.tail {
221		contextEnd = iter.tail
222	}
223	context := string(iter.buf[contextStart:contextEnd])
224	iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
225		operation, msg, iter.head-peekStart, parsing, context)
226}
227
228// CurrentBuffer gets current buffer as string for debugging purpose
229func (iter *Iterator) CurrentBuffer() string {
230	peekStart := iter.head - 10
231	if peekStart < 0 {
232		peekStart = 0
233	}
234	return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
235		string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
236}
237
238func (iter *Iterator) readByte() (ret byte) {
239	if iter.head == iter.tail {
240		if iter.loadMore() {
241			ret = iter.buf[iter.head]
242			iter.head++
243			return ret
244		}
245		return 0
246	}
247	ret = iter.buf[iter.head]
248	iter.head++
249	return ret
250}
251
252func (iter *Iterator) loadMore() bool {
253	if iter.reader == nil {
254		if iter.Error == nil {
255			iter.head = iter.tail
256			iter.Error = io.EOF
257		}
258		return false
259	}
260	if iter.captured != nil {
261		iter.captured = append(iter.captured,
262			iter.buf[iter.captureStartedAt:iter.tail]...)
263		iter.captureStartedAt = 0
264	}
265	for {
266		n, err := iter.reader.Read(iter.buf)
267		if n == 0 {
268			if err != nil {
269				if iter.Error == nil {
270					iter.Error = err
271				}
272				return false
273			}
274		} else {
275			iter.head = 0
276			iter.tail = n
277			return true
278		}
279	}
280}
281
282func (iter *Iterator) unreadByte() {
283	if iter.Error != nil {
284		return
285	}
286	iter.head--
287	return
288}
289
290// Read read the next JSON element as generic interface{}.
291func (iter *Iterator) Read() interface{} {
292	valueType := iter.WhatIsNext()
293	switch valueType {
294	case StringValue:
295		return iter.ReadString()
296	case NumberValue:
297		if iter.cfg.configBeforeFrozen.UseNumber {
298			return json.Number(iter.readNumberAsString())
299		}
300		return iter.ReadFloat64()
301	case NilValue:
302		iter.skipFourBytes('n', 'u', 'l', 'l')
303		return nil
304	case BoolValue:
305		return iter.ReadBool()
306	case ArrayValue:
307		arr := []interface{}{}
308		iter.ReadArrayCB(func(iter *Iterator) bool {
309			var elem interface{}
310			iter.ReadVal(&elem)
311			arr = append(arr, elem)
312			return true
313		})
314		return arr
315	case ObjectValue:
316		obj := map[string]interface{}{}
317		iter.ReadMapCB(func(Iter *Iterator, field string) bool {
318			var elem interface{}
319			iter.ReadVal(&elem)
320			obj[field] = elem
321			return true
322		})
323		return obj
324	default:
325		iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
326		return nil
327	}
328}
329
330// limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9
331const maxDepth = 10000
332
333func (iter *Iterator) incrementDepth() (success bool) {
334	iter.depth++
335	if iter.depth <= maxDepth {
336		return true
337	}
338	iter.ReportError("incrementDepth", "exceeded max depth")
339	return false
340}
341
342func (iter *Iterator) decrementDepth() (success bool) {
343	iter.depth--
344	if iter.depth >= 0 {
345		return true
346	}
347	iter.ReportError("decrementDepth", "unexpected negative nesting")
348	return false
349}
350