Skip to content
Snippets Groups Projects
Commit 1815b38f5e19 authored by Bob Ippolito's avatar Bob Ippolito
Browse files

even more decoder optimizations

git-svn-id: http://simplejson.googlecode.com/svn/trunk@104 a4795897-2c25-0410-b006-0d3caba88fa1
parent c395c5127e83
No related branches found
No related tags found
No related merge requests found
......@@ -125,7 +125,7 @@
WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
WHITESPACE_STR = ' \t\n\r'
def JSONObject((s, end), context, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
def JSONObject((s, end), encoding, strict, scan_once, object_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
pairs = {}
nextchar = s[end:end + 1]
# Normally we expect nextchar == '"'
......@@ -139,9 +139,6 @@
elif nextchar != '"':
raise ValueError(errmsg("Expecting property name", s, end))
end += 1
encoding = context.encoding
strict = context.strict
scan_once = context.scan_once
while True:
key, end = scanstring(s, end, encoding, strict)
......@@ -163,7 +160,7 @@
pass
try:
value, end = scan_once(s, end, context)
value, end = scan_once(s, end)
except StopIteration:
raise ValueError(errmsg("Expecting object", s, end))
pairs[key] = value
......@@ -197,8 +194,7 @@
if nextchar != '"':
raise ValueError(errmsg("Expecting property name", s, end - 1))
object_hook = context.object_hook
if object_hook is not None:
pairs = object_hook(pairs)
return pairs, end
......@@ -201,8 +197,8 @@
if object_hook is not None:
pairs = object_hook(pairs)
return pairs, end
def JSONArray((s, end), context, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
def JSONArray((s, end), scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
values = []
nextchar = s[end:end + 1]
if nextchar in _ws:
......@@ -211,7 +207,6 @@
# Look-ahead for trivial empty array
if nextchar == ']':
return values, end + 1
scan_once = context.scan_once
_append = values.append
while True:
try:
......@@ -215,7 +210,7 @@
_append = values.append
while True:
try:
value, end = scan_once(s, end, context)
value, end = scan_once(s, end)
except StopIteration:
raise ValueError(errmsg("Expecting object", s, end))
_append(value)
......@@ -313,7 +308,7 @@
self.parse_int = parse_int or int
self.parse_constant = parse_constant or _CONSTANTS.__getitem__
self.strict = strict
self.scan_once = make_scanner(_LEXICON)
self.scan_once = make_scanner(_LEXICON, self)
def decode(self, s, _w=WHITESPACE.match):
"""
......@@ -326,7 +321,7 @@
raise ValueError(errmsg("Extra data", s, end, len(s)))
return obj
def raw_decode(self, s, **kw):
def raw_decode(self, s, idx=0):
"""
Decode a JSON document from ``s`` (a ``str`` or ``unicode`` beginning
with a JSON document) and return a 2-tuple of the Python
......@@ -335,6 +330,4 @@
This can be used to decode a JSON document from a string that may
have extraneous data at the end.
"""
idx = kw.get('idx', 0)
context = kw.get('context', self)
try:
......@@ -340,5 +333,5 @@
try:
obj, end = self.scan_once(s, idx, context)
obj, end = self.scan_once(s, idx)
except StopIteration:
raise ValueError("No JSON object could be decoded")
return obj, end
......
......@@ -11,8 +11,8 @@
NUMBER_PATTERN = r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?'
def make_scanner(lexicon):
def make_scanner(lexicon, context):
parse_object = lexicon['object']
parse_array = lexicon['array']
parse_string = lexicon['string']
match_number = re.compile(NUMBER_PATTERN, FLAGS).match
......@@ -15,5 +15,11 @@
parse_object = lexicon['object']
parse_array = lexicon['array']
parse_string = lexicon['string']
match_number = re.compile(NUMBER_PATTERN, FLAGS).match
encoding = context.encoding
strict = context.strict
parse_float = context.parse_float
parse_int = context.parse_int
parse_constant = context.parse_constant
object_hook = context.object_hook
......@@ -19,8 +25,8 @@
def _scan_once(string, idx, context):
def _scan_once(string, idx):
try:
nextchar = string[idx]
except IndexError:
raise StopIteration
if nextchar == '"':
......@@ -21,8 +27,8 @@
try:
nextchar = string[idx]
except IndexError:
raise StopIteration
if nextchar == '"':
return parse_string(string, idx + 1, context.encoding, context.strict)
return parse_string(string, idx + 1, encoding, strict)
elif nextchar == '{':
......@@ -28,3 +34,3 @@
elif nextchar == '{':
return parse_object((string, idx + 1), context)
return parse_object((string, idx + 1), encoding, strict, _scan_once, object_hook)
elif nextchar == '[':
......@@ -30,5 +36,5 @@
elif nextchar == '[':
return parse_array((string, idx + 1), context)
return parse_array((string, idx + 1), _scan_once)
elif nextchar == 'n' and string[idx:idx + 4] == 'null':
return None, idx + 4
elif nextchar == 't' and string[idx:idx + 4] == 'true':
......@@ -40,5 +46,5 @@
if m is not None:
integer, frac, exp = m.groups()
if frac or exp:
res = context.parse_float(integer + (frac or '') + (exp or ''))
res = parse_float(integer + (frac or '') + (exp or ''))
else:
......@@ -44,4 +50,4 @@
else:
res = context.parse_int(integer)
res = parse_int(integer)
return res, m.end()
elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
......@@ -46,4 +52,4 @@
return res, m.end()
elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
return context.parse_constant('NaN'), idx + 3
return parse_constant('NaN'), idx + 3
elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
......@@ -49,3 +55,3 @@
elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
return context.parse_constant('Infinity'), idx + 8
return parse_constant('Infinity'), idx + 8
elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
......@@ -51,5 +57,5 @@
elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
return context.parse_constant('-Infinity'), idx + 9
return parse_constant('-Infinity'), idx + 9
else:
raise StopIteration
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment