Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / json-iterator / go / iter.go
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         captureStartedAt int
78         captured         []byte
79         Error            error
80         Attachment       interface{} // open for customized decoder
81 }
82
83 // NewIterator creates an empty Iterator instance
84 func NewIterator(cfg API) *Iterator {
85         return &Iterator{
86                 cfg:    cfg.(*frozenConfig),
87                 reader: nil,
88                 buf:    nil,
89                 head:   0,
90                 tail:   0,
91         }
92 }
93
94 // Parse creates an Iterator instance from io.Reader
95 func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
96         return &Iterator{
97                 cfg:    cfg.(*frozenConfig),
98                 reader: reader,
99                 buf:    make([]byte, bufSize),
100                 head:   0,
101                 tail:   0,
102         }
103 }
104
105 // ParseBytes creates an Iterator instance from byte array
106 func ParseBytes(cfg API, input []byte) *Iterator {
107         return &Iterator{
108                 cfg:    cfg.(*frozenConfig),
109                 reader: nil,
110                 buf:    input,
111                 head:   0,
112                 tail:   len(input),
113         }
114 }
115
116 // ParseString creates an Iterator instance from string
117 func ParseString(cfg API, input string) *Iterator {
118         return ParseBytes(cfg, []byte(input))
119 }
120
121 // Pool returns a pool can provide more iterator with same configuration
122 func (iter *Iterator) Pool() IteratorPool {
123         return iter.cfg
124 }
125
126 // Reset reuse iterator instance by specifying another reader
127 func (iter *Iterator) Reset(reader io.Reader) *Iterator {
128         iter.reader = reader
129         iter.head = 0
130         iter.tail = 0
131         return iter
132 }
133
134 // ResetBytes reuse iterator instance by specifying another byte array as input
135 func (iter *Iterator) ResetBytes(input []byte) *Iterator {
136         iter.reader = nil
137         iter.buf = input
138         iter.head = 0
139         iter.tail = len(input)
140         return iter
141 }
142
143 // WhatIsNext gets ValueType of relatively next json element
144 func (iter *Iterator) WhatIsNext() ValueType {
145         valueType := valueTypes[iter.nextToken()]
146         iter.unreadByte()
147         return valueType
148 }
149
150 func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
151         for i := iter.head; i < iter.tail; i++ {
152                 c := iter.buf[i]
153                 switch c {
154                 case ' ', '\n', '\t', '\r':
155                         continue
156                 }
157                 iter.head = i
158                 return false
159         }
160         return true
161 }
162
163 func (iter *Iterator) isObjectEnd() bool {
164         c := iter.nextToken()
165         if c == ',' {
166                 return false
167         }
168         if c == '}' {
169                 return true
170         }
171         iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
172         return true
173 }
174
175 func (iter *Iterator) nextToken() byte {
176         // a variation of skip whitespaces, returning the next non-whitespace token
177         for {
178                 for i := iter.head; i < iter.tail; i++ {
179                         c := iter.buf[i]
180                         switch c {
181                         case ' ', '\n', '\t', '\r':
182                                 continue
183                         }
184                         iter.head = i + 1
185                         return c
186                 }
187                 if !iter.loadMore() {
188                         return 0
189                 }
190         }
191 }
192
193 // ReportError record a error in iterator instance with current position.
194 func (iter *Iterator) ReportError(operation string, msg string) {
195         if iter.Error != nil {
196                 if iter.Error != io.EOF {
197                         return
198                 }
199         }
200         peekStart := iter.head - 10
201         if peekStart < 0 {
202                 peekStart = 0
203         }
204         peekEnd := iter.head + 10
205         if peekEnd > iter.tail {
206                 peekEnd = iter.tail
207         }
208         parsing := string(iter.buf[peekStart:peekEnd])
209         contextStart := iter.head - 50
210         if contextStart < 0 {
211                 contextStart = 0
212         }
213         contextEnd := iter.head + 50
214         if contextEnd > iter.tail {
215                 contextEnd = iter.tail
216         }
217         context := string(iter.buf[contextStart:contextEnd])
218         iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
219                 operation, msg, iter.head-peekStart, parsing, context)
220 }
221
222 // CurrentBuffer gets current buffer as string for debugging purpose
223 func (iter *Iterator) CurrentBuffer() string {
224         peekStart := iter.head - 10
225         if peekStart < 0 {
226                 peekStart = 0
227         }
228         return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
229                 string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
230 }
231
232 func (iter *Iterator) readByte() (ret byte) {
233         if iter.head == iter.tail {
234                 if iter.loadMore() {
235                         ret = iter.buf[iter.head]
236                         iter.head++
237                         return ret
238                 }
239                 return 0
240         }
241         ret = iter.buf[iter.head]
242         iter.head++
243         return ret
244 }
245
246 func (iter *Iterator) loadMore() bool {
247         if iter.reader == nil {
248                 if iter.Error == nil {
249                         iter.head = iter.tail
250                         iter.Error = io.EOF
251                 }
252                 return false
253         }
254         if iter.captured != nil {
255                 iter.captured = append(iter.captured,
256                         iter.buf[iter.captureStartedAt:iter.tail]...)
257                 iter.captureStartedAt = 0
258         }
259         for {
260                 n, err := iter.reader.Read(iter.buf)
261                 if n == 0 {
262                         if err != nil {
263                                 if iter.Error == nil {
264                                         iter.Error = err
265                                 }
266                                 return false
267                         }
268                 } else {
269                         iter.head = 0
270                         iter.tail = n
271                         return true
272                 }
273         }
274 }
275
276 func (iter *Iterator) unreadByte() {
277         if iter.Error != nil {
278                 return
279         }
280         iter.head--
281         return
282 }
283
284 // Read read the next JSON element as generic interface{}.
285 func (iter *Iterator) Read() interface{} {
286         valueType := iter.WhatIsNext()
287         switch valueType {
288         case StringValue:
289                 return iter.ReadString()
290         case NumberValue:
291                 if iter.cfg.configBeforeFrozen.UseNumber {
292                         return json.Number(iter.readNumberAsString())
293                 }
294                 return iter.ReadFloat64()
295         case NilValue:
296                 iter.skipFourBytes('n', 'u', 'l', 'l')
297                 return nil
298         case BoolValue:
299                 return iter.ReadBool()
300         case ArrayValue:
301                 arr := []interface{}{}
302                 iter.ReadArrayCB(func(iter *Iterator) bool {
303                         var elem interface{}
304                         iter.ReadVal(&elem)
305                         arr = append(arr, elem)
306                         return true
307                 })
308                 return arr
309         case ObjectValue:
310                 obj := map[string]interface{}{}
311                 iter.ReadMapCB(func(Iter *Iterator, field string) bool {
312                         var elem interface{}
313                         iter.ReadVal(&elem)
314                         obj[field] = elem
315                         return true
316                 })
317                 return obj
318         default:
319                 iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
320                 return nil
321         }
322 }