1 import string
2 import types
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
25 self.string = string
26 self.index = -1
28 i = self.index + 1
29 if i < len(self.string):
30 return self.string[i]
31 else:
32 return None
34 self.index += 1
35 if self.index < len(self.string):
36 return self.string[self.index]
37 else:
38 raise StopIteration
41
44
47
49 hex_digits = {'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F':15}
50 escapes = {'t':'\t','n':'\n','f':'\f','r':'\r','b':'\b'}
51
56
81
88
96
103
105 if self._next() != ch:
106 raise ReadException, "Trying to read %s: '%s'" % (target, self._generator.all())
107
109 isfloat = False
110 result = self._next()
111 peek = self._peek()
112 while peek is not None and (peek.isdigit() or peek == "."):
113 isfloat = isfloat or peek == "."
114 result = result + self._next()
115 peek = self._peek()
116 try:
117 if isfloat:
118 return float(result)
119 else:
120 return int(result)
121 except ValueError:
122 raise ReadException, "Not a valid JSON number: '%s'" % result
123
125 result = ""
126 assert self._next() == '"'
127 try:
128 while self._peek() != '"':
129 ch = self._next()
130 if ch == "\\":
131 ch = self._next()
132 if ch in 'brnft':
133 ch = self.escapes[ch]
134 elif ch == "u":
135 ch4096 = self._next()
136 ch256 = self._next()
137 ch16 = self._next()
138 ch1 = self._next()
139 n = 4096 * self._hexDigitToInt(ch4096)
140 n += 256 * self._hexDigitToInt(ch256)
141 n += 16 * self._hexDigitToInt(ch16)
142 n += self._hexDigitToInt(ch1)
143 ch = unichr(n)
144 elif ch not in '"/\\':
145 raise ReadException, "Not a valid escaped JSON character: '%s' in %s" % (ch, self._generator.all())
146 result = result + ch
147 except StopIteration:
148 raise ReadException, "Not a valid JSON string: '%s'" % self._generator.all()
149 assert self._next() == '"'
150 return result
151
153 try:
154 result = self.hex_digits[ch.upper()]
155 except KeyError:
156 try:
157 result = int(ch)
158 except ValueError:
159 raise ReadException, "The character %s is not a hex digit." % ch
160 return result
161
171
183
191
193 result = []
194 assert self._next() == '['
195 done = self._peek() == ']'
196 while not done:
197 item = self._read()
198 result.append(item)
199 self._eatWhitespace()
200 done = self._peek() == ']'
201 if not done:
202 ch = self._next()
203 if ch != ",":
204 raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch)
205 assert ']' == self._next()
206 return result
207
209 result = {}
210 assert self._next() == '{'
211 done = self._peek() == '}'
212 while not done:
213 key = self._read()
214 if type(key) is not types.StringType:
215 raise ReadException, "Not a valid JSON object key (should be a string): %s" % key
216 self._eatWhitespace()
217 ch = self._next()
218 if ch != ":":
219 raise ReadException, "Not a valid JSON object: '%s' due to: '%s'" % (self._generator.all(), ch)
220 self._eatWhitespace()
221 val = self._read()
222 result[key] = val
223 self._eatWhitespace()
224 done = self._peek() == '}'
225 if not done:
226 ch = self._next()
227 if ch != ",":
228 raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch)
229 assert self._next() == "}"
230 return result
231
233 p = self._peek()
234 while p is not None and p in string.whitespace or p == '/':
235 if p == '/':
236 self._readComment()
237 else:
238 self._next()
239 p = self._peek()
240
242 return self._generator.peek()
243
245 return self._generator.next()
246
248
250 self._results.append(s)
251
252 - def write(self, obj, escaped_forward_slash=False):
253 self._escaped_forward_slash = escaped_forward_slash
254 self._results = []
255 self._write(obj)
256 return "".join(self._results)
257
259 ty = type(obj)
260 if ty is types.DictType:
261 n = len(obj)
262 self._append("{")
263 for k, v in obj.items():
264 self._write(k)
265 self._append(":")
266 self._write(v)
267 n = n - 1
268 if n > 0:
269 self._append(",")
270 self._append("}")
271 elif ty is types.ListType or ty is types.TupleType:
272 n = len(obj)
273 self._append("[")
274 for item in obj:
275 self._write(item)
276 n = n - 1
277 if n > 0:
278 self._append(",")
279 self._append("]")
280 elif ty is types.StringType or ty is types.UnicodeType:
281 self._append('"')
282 obj = obj.replace('\\', r'\\')
283 if self._escaped_forward_slash:
284 obj = obj.replace('/', r'\/')
285 obj = obj.replace('"', r'\"')
286 obj = obj.replace('\b', r'\b')
287 obj = obj.replace('\f', r'\f')
288 obj = obj.replace('\n', r'\n')
289 obj = obj.replace('\r', r'\r')
290 obj = obj.replace('\t', r'\t')
291 self._append(obj)
292 self._append('"')
293 elif ty is types.IntType or ty is types.LongType:
294 self._append(str(obj))
295 elif ty is types.FloatType:
296 self._append("%f" % obj)
297 elif obj is True:
298 self._append("true")
299 elif obj is False:
300 self._append("false")
301 elif obj is None:
302 self._append("null")
303 else:
304 raise WriteException, "Cannot write in JSON: %s" % repr(obj)
305
306 -def write(obj, escaped_forward_slash=False):
308
311