diff options
Diffstat (limited to 'vendor/github.com/json-iterator/go/iter.go')
-rw-r--r-- | vendor/github.com/json-iterator/go/iter.go | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/vendor/github.com/json-iterator/go/iter.go b/vendor/github.com/json-iterator/go/iter.go new file mode 100644 index 0000000..29b31cf --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter.go | |||
@@ -0,0 +1,349 @@ | |||
1 | package jsoniter | ||
2 | |||
3 | import ( | ||
4 | "encoding/json" | ||
5 | "fmt" | ||
6 | "io" | ||
7 | ) | ||
8 | |||
9 | // ValueType the type for JSON element | ||
10 | type ValueType int | ||
11 | |||
12 | const ( | ||
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 | |||
29 | var hexDigits []byte | ||
30 | var valueTypes []ValueType | ||
31 | |||
32 | func 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. | ||
71 | type 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 | ||
85 | func 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 | ||
97 | func 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 | ||
109 | func 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 | ||
121 | func 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 | ||
126 | func (iter *Iterator) Pool() IteratorPool { | ||
127 | return iter.cfg | ||
128 | } | ||
129 | |||
130 | // Reset reuse iterator instance by specifying another reader | ||
131 | func (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 | ||
140 | func (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 | ||
150 | func (iter *Iterator) WhatIsNext() ValueType { | ||
151 | valueType := valueTypes[iter.nextToken()] | ||
152 | iter.unreadByte() | ||
153 | return valueType | ||
154 | } | ||
155 | |||
156 | func (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 | |||
169 | func (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 | |||
181 | func (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. | ||
200 | func (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 | ||
229 | func (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 | |||
238 | func (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 | |||
252 | func (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 | |||
282 | func (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{}. | ||
291 | func (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 | ||
331 | const maxDepth = 10000 | ||
332 | |||
333 | func (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 | |||
342 | func (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 | } | ||