blob: 9303de41e40050de20fd5256bad35932e038b930 [file] [log] [blame]
khenaidooab1f7bd2019-11-14 14:00:27 -05001//+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
khenaidood948f772021-08-11 17:49:24 -040025 if !iter.incrementDepth() {
26 return
27 }
khenaidooab1f7bd2019-11-14 14:00:27 -050028 for {
29 for i := iter.head; i < iter.tail; i++ {
30 switch iter.buf[i] {
31 case '"': // If inside string, skip it
32 iter.head = i + 1
33 iter.skipString()
34 i = iter.head - 1 // it will be i++ soon
35 case '[': // If open symbol, increase level
36 level++
khenaidood948f772021-08-11 17:49:24 -040037 if !iter.incrementDepth() {
38 return
39 }
khenaidooab1f7bd2019-11-14 14:00:27 -050040 case ']': // If close symbol, increase level
41 level--
khenaidood948f772021-08-11 17:49:24 -040042 if !iter.decrementDepth() {
43 return
44 }
khenaidooab1f7bd2019-11-14 14:00:27 -050045
46 // If we have returned to the original level, we're done
47 if level == 0 {
48 iter.head = i + 1
49 return
50 }
51 }
52 }
53 if !iter.loadMore() {
54 iter.ReportError("skipObject", "incomplete array")
55 return
56 }
57 }
58}
59
60func (iter *Iterator) skipObject() {
61 level := 1
khenaidood948f772021-08-11 17:49:24 -040062 if !iter.incrementDepth() {
63 return
64 }
65
khenaidooab1f7bd2019-11-14 14:00:27 -050066 for {
67 for i := iter.head; i < iter.tail; i++ {
68 switch iter.buf[i] {
69 case '"': // If inside string, skip it
70 iter.head = i + 1
71 iter.skipString()
72 i = iter.head - 1 // it will be i++ soon
73 case '{': // If open symbol, increase level
74 level++
khenaidood948f772021-08-11 17:49:24 -040075 if !iter.incrementDepth() {
76 return
77 }
khenaidooab1f7bd2019-11-14 14:00:27 -050078 case '}': // If close symbol, increase level
79 level--
khenaidood948f772021-08-11 17:49:24 -040080 if !iter.decrementDepth() {
81 return
82 }
khenaidooab1f7bd2019-11-14 14:00:27 -050083
84 // If we have returned to the original level, we're done
85 if level == 0 {
86 iter.head = i + 1
87 return
88 }
89 }
90 }
91 if !iter.loadMore() {
92 iter.ReportError("skipObject", "incomplete object")
93 return
94 }
95 }
96}
97
98func (iter *Iterator) skipString() {
99 for {
100 end, escaped := iter.findStringEnd()
101 if end == -1 {
102 if !iter.loadMore() {
103 iter.ReportError("skipString", "incomplete string")
104 return
105 }
106 if escaped {
107 iter.head = 1 // skip the first char as last char read is \
108 }
109 } else {
110 iter.head = end
111 return
112 }
113 }
114}
115
116// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
117// Tries to find the end of string
118// Support if string contains escaped quote symbols.
119func (iter *Iterator) findStringEnd() (int, bool) {
120 escaped := false
121 for i := iter.head; i < iter.tail; i++ {
122 c := iter.buf[i]
123 if c == '"' {
124 if !escaped {
125 return i + 1, false
126 }
127 j := i - 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 i + 1, true
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 } else if c == '\\' {
143 escaped = true
144 }
145 }
146 j := iter.tail - 1
147 for {
148 if j < iter.head || iter.buf[j] != '\\' {
149 // even number of backslashes
150 // either end of buffer, or " found
151 return -1, false // do not end with \
152 }
153 j--
154 if j < iter.head || iter.buf[j] != '\\' {
155 // odd number of backslashes
156 // it is \" or \\\"
157 break
158 }
159 j--
160
161 }
162 return -1, true // end with \
163}