diff options
Diffstat (limited to 'vendor/github.com/json-iterator/go/iter_object.go')
-rw-r--r-- | vendor/github.com/json-iterator/go/iter_object.go | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/vendor/github.com/json-iterator/go/iter_object.go b/vendor/github.com/json-iterator/go/iter_object.go new file mode 100644 index 0000000..58ee89c --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_object.go | |||
@@ -0,0 +1,267 @@ | |||
1 | package jsoniter | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "strings" | ||
6 | ) | ||
7 | |||
8 | // ReadObject read one field from object. | ||
9 | // If object ended, returns empty string. | ||
10 | // Otherwise, returns the field name. | ||
11 | func (iter *Iterator) ReadObject() (ret string) { | ||
12 | c := iter.nextToken() | ||
13 | switch c { | ||
14 | case 'n': | ||
15 | iter.skipThreeBytes('u', 'l', 'l') | ||
16 | return "" // null | ||
17 | case '{': | ||
18 | c = iter.nextToken() | ||
19 | if c == '"' { | ||
20 | iter.unreadByte() | ||
21 | field := iter.ReadString() | ||
22 | c = iter.nextToken() | ||
23 | if c != ':' { | ||
24 | iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) | ||
25 | } | ||
26 | return field | ||
27 | } | ||
28 | if c == '}' { | ||
29 | return "" // end of object | ||
30 | } | ||
31 | iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) | ||
32 | return | ||
33 | case ',': | ||
34 | field := iter.ReadString() | ||
35 | c = iter.nextToken() | ||
36 | if c != ':' { | ||
37 | iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) | ||
38 | } | ||
39 | return field | ||
40 | case '}': | ||
41 | return "" // end of object | ||
42 | default: | ||
43 | iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) | ||
44 | return | ||
45 | } | ||
46 | } | ||
47 | |||
48 | // CaseInsensitive | ||
49 | func (iter *Iterator) readFieldHash() int64 { | ||
50 | hash := int64(0x811c9dc5) | ||
51 | c := iter.nextToken() | ||
52 | if c != '"' { | ||
53 | iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) | ||
54 | return 0 | ||
55 | } | ||
56 | for { | ||
57 | for i := iter.head; i < iter.tail; i++ { | ||
58 | // require ascii string and no escape | ||
59 | b := iter.buf[i] | ||
60 | if b == '\\' { | ||
61 | iter.head = i | ||
62 | for _, b := range iter.readStringSlowPath() { | ||
63 | if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { | ||
64 | b += 'a' - 'A' | ||
65 | } | ||
66 | hash ^= int64(b) | ||
67 | hash *= 0x1000193 | ||
68 | } | ||
69 | c = iter.nextToken() | ||
70 | if c != ':' { | ||
71 | iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) | ||
72 | return 0 | ||
73 | } | ||
74 | return hash | ||
75 | } | ||
76 | if b == '"' { | ||
77 | iter.head = i + 1 | ||
78 | c = iter.nextToken() | ||
79 | if c != ':' { | ||
80 | iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) | ||
81 | return 0 | ||
82 | } | ||
83 | return hash | ||
84 | } | ||
85 | if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { | ||
86 | b += 'a' - 'A' | ||
87 | } | ||
88 | hash ^= int64(b) | ||
89 | hash *= 0x1000193 | ||
90 | } | ||
91 | if !iter.loadMore() { | ||
92 | iter.ReportError("readFieldHash", `incomplete field name`) | ||
93 | return 0 | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | func calcHash(str string, caseSensitive bool) int64 { | ||
99 | if !caseSensitive { | ||
100 | str = strings.ToLower(str) | ||
101 | } | ||
102 | hash := int64(0x811c9dc5) | ||
103 | for _, b := range []byte(str) { | ||
104 | hash ^= int64(b) | ||
105 | hash *= 0x1000193 | ||
106 | } | ||
107 | return int64(hash) | ||
108 | } | ||
109 | |||
110 | // ReadObjectCB read object with callback, the key is ascii only and field name not copied | ||
111 | func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { | ||
112 | c := iter.nextToken() | ||
113 | var field string | ||
114 | if c == '{' { | ||
115 | if !iter.incrementDepth() { | ||
116 | return false | ||
117 | } | ||
118 | c = iter.nextToken() | ||
119 | if c == '"' { | ||
120 | iter.unreadByte() | ||
121 | field = iter.ReadString() | ||
122 | c = iter.nextToken() | ||
123 | if c != ':' { | ||
124 | iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) | ||
125 | } | ||
126 | if !callback(iter, field) { | ||
127 | iter.decrementDepth() | ||
128 | return false | ||
129 | } | ||
130 | c = iter.nextToken() | ||
131 | for c == ',' { | ||
132 | field = iter.ReadString() | ||
133 | c = iter.nextToken() | ||
134 | if c != ':' { | ||
135 | iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) | ||
136 | } | ||
137 | if !callback(iter, field) { | ||
138 | iter.decrementDepth() | ||
139 | return false | ||
140 | } | ||
141 | c = iter.nextToken() | ||
142 | } | ||
143 | if c != '}' { | ||
144 | iter.ReportError("ReadObjectCB", `object not ended with }`) | ||
145 | iter.decrementDepth() | ||
146 | return false | ||
147 | } | ||
148 | return iter.decrementDepth() | ||
149 | } | ||
150 | if c == '}' { | ||
151 | return iter.decrementDepth() | ||
152 | } | ||
153 | iter.ReportError("ReadObjectCB", `expect " after {, but found `+string([]byte{c})) | ||
154 | iter.decrementDepth() | ||
155 | return false | ||
156 | } | ||
157 | if c == 'n' { | ||
158 | iter.skipThreeBytes('u', 'l', 'l') | ||
159 | return true // null | ||
160 | } | ||
161 | iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) | ||
162 | return false | ||
163 | } | ||
164 | |||
165 | // ReadMapCB read map with callback, the key can be any string | ||
166 | func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { | ||
167 | c := iter.nextToken() | ||
168 | if c == '{' { | ||
169 | if !iter.incrementDepth() { | ||
170 | return false | ||
171 | } | ||
172 | c = iter.nextToken() | ||
173 | if c == '"' { | ||
174 | iter.unreadByte() | ||
175 | field := iter.ReadString() | ||
176 | if iter.nextToken() != ':' { | ||
177 | iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) | ||
178 | iter.decrementDepth() | ||
179 | return false | ||
180 | } | ||
181 | if !callback(iter, field) { | ||
182 | iter.decrementDepth() | ||
183 | return false | ||
184 | } | ||
185 | c = iter.nextToken() | ||
186 | for c == ',' { | ||
187 | field = iter.ReadString() | ||
188 | if iter.nextToken() != ':' { | ||
189 | iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) | ||
190 | iter.decrementDepth() | ||
191 | return false | ||
192 | } | ||
193 | if !callback(iter, field) { | ||
194 | iter.decrementDepth() | ||
195 | return false | ||
196 | } | ||
197 | c = iter.nextToken() | ||
198 | } | ||
199 | if c != '}' { | ||
200 | iter.ReportError("ReadMapCB", `object not ended with }`) | ||
201 | iter.decrementDepth() | ||
202 | return false | ||
203 | } | ||
204 | return iter.decrementDepth() | ||
205 | } | ||
206 | if c == '}' { | ||
207 | return iter.decrementDepth() | ||
208 | } | ||
209 | iter.ReportError("ReadMapCB", `expect " after {, but found `+string([]byte{c})) | ||
210 | iter.decrementDepth() | ||
211 | return false | ||
212 | } | ||
213 | if c == 'n' { | ||
214 | iter.skipThreeBytes('u', 'l', 'l') | ||
215 | return true // null | ||
216 | } | ||
217 | iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) | ||
218 | return false | ||
219 | } | ||
220 | |||
221 | func (iter *Iterator) readObjectStart() bool { | ||
222 | c := iter.nextToken() | ||
223 | if c == '{' { | ||
224 | c = iter.nextToken() | ||
225 | if c == '}' { | ||
226 | return false | ||
227 | } | ||
228 | iter.unreadByte() | ||
229 | return true | ||
230 | } else if c == 'n' { | ||
231 | iter.skipThreeBytes('u', 'l', 'l') | ||
232 | return false | ||
233 | } | ||
234 | iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) | ||
235 | return false | ||
236 | } | ||
237 | |||
238 | func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { | ||
239 | str := iter.ReadStringAsSlice() | ||
240 | if iter.skipWhitespacesWithoutLoadMore() { | ||
241 | if ret == nil { | ||
242 | ret = make([]byte, len(str)) | ||
243 | copy(ret, str) | ||
244 | } | ||
245 | if !iter.loadMore() { | ||
246 | return | ||
247 | } | ||
248 | } | ||
249 | if iter.buf[iter.head] != ':' { | ||
250 | iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) | ||
251 | return | ||
252 | } | ||
253 | iter.head++ | ||
254 | if iter.skipWhitespacesWithoutLoadMore() { | ||
255 | if ret == nil { | ||
256 | ret = make([]byte, len(str)) | ||
257 | copy(ret, str) | ||
258 | } | ||
259 | if !iter.loadMore() { | ||
260 | return | ||
261 | } | ||
262 | } | ||
263 | if ret == nil { | ||
264 | return str | ||
265 | } | ||
266 | return ret | ||
267 | } | ||