1//+build jsoniter_sloppy
2
3package jsoniter
4
5// sloppy but faster implementation, do not validate the input json
6
7func (iter *Iterator) skipNumber() {
8	for {
9		for i := iter.head; i < iter.tail; i++ {
10			c := iter.buf[i]
11			switch c {
12			case ' ', '\n', '\r', '\t', ',', '}', ']':
13				iter.head = i
14				return
15			}
16		}
17		if !iter.loadMore() {
18			return
19		}
20	}
21}
22
23func (iter *Iterator) skipArray() {
24	level := 1
25	for {
26		for i := iter.head; i < iter.tail; i++ {
27			switch iter.buf[i] {
28			case '"': // If inside string, skip it
29				iter.head = i + 1
30				iter.skipString()
31				i = iter.head - 1 // it will be i++ soon
32			case '[': // If open symbol, increase level
33				level++
34			case ']': // If close symbol, increase level
35				level--
36
37				// If we have returned to the original level, we're done
38				if level == 0 {
39					iter.head = i + 1
40					return
41				}
42			}
43		}
44		if !iter.loadMore() {
45			iter.ReportError("skipObject", "incomplete array")
46			return
47		}
48	}
49}
50
51func (iter *Iterator) skipObject() {
52	level := 1
53	for {
54		for i := iter.head; i < iter.tail; i++ {
55			switch iter.buf[i] {
56			case '"': // If inside string, skip it
57				iter.head = i + 1
58				iter.skipString()
59				i = iter.head - 1 // it will be i++ soon
60			case '{': // If open symbol, increase level
61				level++
62			case '}': // If close symbol, increase level
63				level--
64
65				// If we have returned to the original level, we're done
66				if level == 0 {
67					iter.head = i + 1
68					return
69				}
70			}
71		}
72		if !iter.loadMore() {
73			iter.ReportError("skipObject", "incomplete object")
74			return
75		}
76	}
77}
78
79func (iter *Iterator) skipString() {
80	for {
81		end, escaped := iter.findStringEnd()
82		if end == -1 {
83			if !iter.loadMore() {
84				iter.ReportError("skipString", "incomplete string")
85				return
86			}
87			if escaped {
88				iter.head = 1 // skip the first char as last char read is \
89			}
90		} else {
91			iter.head = end
92			return
93		}
94	}
95}
96
97// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
98// Tries to find the end of string
99// Support if string contains escaped quote symbols.
100func (iter *Iterator) findStringEnd() (int, bool) {
101	escaped := false
102	for i := iter.head; i < iter.tail; i++ {
103		c := iter.buf[i]
104		if c == '"' {
105			if !escaped {
106				return i + 1, false
107			}
108			j := i - 1
109			for {
110				if j < iter.head || iter.buf[j] != '\\' {
111					// even number of backslashes
112					// either end of buffer, or " found
113					return i + 1, true
114				}
115				j--
116				if j < iter.head || iter.buf[j] != '\\' {
117					// odd number of backslashes
118					// it is \" or \\\"
119					break
120				}
121				j--
122			}
123		} else if c == '\\' {
124			escaped = true
125		}
126	}
127	j := iter.tail - 1
128	for {
129		if j < iter.head || iter.buf[j] != '\\' {
130			// even number of backslashes
131			// either end of buffer, or " found
132			return -1, false // do not end with \
133		}
134		j--
135		if j < iter.head || iter.buf[j] != '\\' {
136			// odd number of backslashes
137			// it is \" or \\\"
138			break
139		}
140		j--
141
142	}
143	return -1, true // end with \
144}
145