9 // ValueType the type for JSON element
13 // InvalidValue invalid JSON element
14 InvalidValue ValueType = iota
15 // StringValue JSON element "string"
17 // NumberValue JSON element 100 or 0.10
19 // NilValue JSON element null
21 // BoolValue JSON element true or false
23 // ArrayValue JSON element []
25 // ObjectValue JSON element {}
30 var valueTypes []ValueType
33 hexDigits = make([]byte, 256)
34 for i := 0; i < len(hexDigits); i++ {
37 for i := '0'; i <= '9'; i++ {
38 hexDigits[i] = byte(i - '0')
40 for i := 'a'; i <= 'f'; i++ {
41 hexDigits[i] = byte((i - 'a') + 10)
43 for i := 'A'; i <= 'F'; i++ {
44 hexDigits[i] = byte((i - 'A') + 10)
46 valueTypes = make([]ValueType, 256)
47 for i := 0; i < len(valueTypes); i++ {
48 valueTypes[i] = InvalidValue
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
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 {
80 Attachment interface{} // open for customized decoder
83 // NewIterator creates an empty Iterator instance
84 func NewIterator(cfg API) *Iterator {
86 cfg: cfg.(*frozenConfig),
94 // Parse creates an Iterator instance from io.Reader
95 func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
97 cfg: cfg.(*frozenConfig),
99 buf: make([]byte, bufSize),
105 // ParseBytes creates an Iterator instance from byte array
106 func ParseBytes(cfg API, input []byte) *Iterator {
108 cfg: cfg.(*frozenConfig),
116 // ParseString creates an Iterator instance from string
117 func ParseString(cfg API, input string) *Iterator {
118 return ParseBytes(cfg, []byte(input))
121 // Pool returns a pool can provide more iterator with same configuration
122 func (iter *Iterator) Pool() IteratorPool {
126 // Reset reuse iterator instance by specifying another reader
127 func (iter *Iterator) Reset(reader io.Reader) *Iterator {
134 // ResetBytes reuse iterator instance by specifying another byte array as input
135 func (iter *Iterator) ResetBytes(input []byte) *Iterator {
139 iter.tail = len(input)
143 // WhatIsNext gets ValueType of relatively next json element
144 func (iter *Iterator) WhatIsNext() ValueType {
145 valueType := valueTypes[iter.nextToken()]
150 func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
151 for i := iter.head; i < iter.tail; i++ {
154 case ' ', '\n', '\t', '\r':
163 func (iter *Iterator) isObjectEnd() bool {
164 c := iter.nextToken()
171 iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
175 func (iter *Iterator) nextToken() byte {
176 // a variation of skip whitespaces, returning the next non-whitespace token
178 for i := iter.head; i < iter.tail; i++ {
181 case ' ', '\n', '\t', '\r':
187 if !iter.loadMore() {
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 {
200 peekStart := iter.head - 10
204 peekEnd := iter.head + 10
205 if peekEnd > iter.tail {
208 parsing := string(iter.buf[peekStart:peekEnd])
209 contextStart := iter.head - 50
210 if contextStart < 0 {
213 contextEnd := iter.head + 50
214 if contextEnd > iter.tail {
215 contextEnd = iter.tail
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)
222 // CurrentBuffer gets current buffer as string for debugging purpose
223 func (iter *Iterator) CurrentBuffer() string {
224 peekStart := iter.head - 10
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]))
232 func (iter *Iterator) readByte() (ret byte) {
233 if iter.head == iter.tail {
235 ret = iter.buf[iter.head]
241 ret = iter.buf[iter.head]
246 func (iter *Iterator) loadMore() bool {
247 if iter.reader == nil {
248 if iter.Error == nil {
249 iter.head = iter.tail
254 if iter.captured != nil {
255 iter.captured = append(iter.captured,
256 iter.buf[iter.captureStartedAt:iter.tail]...)
257 iter.captureStartedAt = 0
260 n, err := iter.reader.Read(iter.buf)
263 if iter.Error == nil {
276 func (iter *Iterator) unreadByte() {
277 if iter.Error != nil {
284 // Read read the next JSON element as generic interface{}.
285 func (iter *Iterator) Read() interface{} {
286 valueType := iter.WhatIsNext()
289 return iter.ReadString()
291 if iter.cfg.configBeforeFrozen.UseNumber {
292 return json.Number(iter.readNumberAsString())
294 return iter.ReadFloat64()
296 iter.skipFourBytes('n', 'u', 'l', 'l')
299 return iter.ReadBool()
301 arr := []interface{}{}
302 iter.ReadArrayCB(func(iter *Iterator) bool {
305 arr = append(arr, elem)
310 obj := map[string]interface{}{}
311 iter.ReadMapCB(func(Iter *Iterator, field string) bool {
319 iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))