blob: 8fcdc3b69bdf62b878cb9532a326f03c37d1207f [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
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}