12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)"""JSON token scanner
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def _import_c_make_scanner():
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    try:
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        from simplejson._speedups import make_scanner
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return make_scanner
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    except ImportError:
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return None
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)c_make_scanner = _import_c_make_scanner()
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)__all__ = ['make_scanner']
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NUMBER_RE = re.compile(
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (re.VERBOSE | re.MULTILINE | re.DOTALL))
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def py_make_scanner(context):
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parse_object = context.parse_object
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parse_array = context.parse_array
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parse_string = context.parse_string
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    match_number = NUMBER_RE.match
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encoding = context.encoding
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    strict = context.strict
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parse_float = context.parse_float
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parse_int = context.parse_int
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parse_constant = context.parse_constant
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object_hook = context.object_hook
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object_pairs_hook = context.object_pairs_hook
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memo = context.memo
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def _scan_once(string, idx):
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        try:
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            nextchar = string[idx]
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        except IndexError:
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raise StopIteration
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if nextchar == '"':
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return parse_string(string, idx + 1, encoding, strict)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        elif nextchar == '{':
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return parse_object((string, idx + 1), encoding, strict,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                _scan_once, object_hook, object_pairs_hook, memo)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        elif nextchar == '[':
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return parse_array((string, idx + 1), _scan_once)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        elif nextchar == 'n' and string[idx:idx + 4] == 'null':
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return None, idx + 4
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        elif nextchar == 't' and string[idx:idx + 4] == 'true':
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return True, idx + 4
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        elif nextchar == 'f' and string[idx:idx + 5] == 'false':
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return False, idx + 5
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        m = match_number(string, idx)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if m is not None:
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            integer, frac, exp = m.groups()
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if frac or exp:
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                res = parse_float(integer + (frac or '') + (exp or ''))
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            else:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                res = parse_int(integer)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return res, m.end()
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return parse_constant('NaN'), idx + 3
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return parse_constant('Infinity'), idx + 8
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return parse_constant('-Infinity'), idx + 9
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        else:
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raise StopIteration
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    def scan_once(string, idx):
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        try:
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return _scan_once(string, idx)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        finally:
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            memo.clear()
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scan_once
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)make_scanner = c_make_scanner or py_make_scanner
78