1*cda5da8dSAndroid Build Coastguard Worker"""JSON token scanner 2*cda5da8dSAndroid Build Coastguard Worker""" 3*cda5da8dSAndroid Build Coastguard Workerimport re 4*cda5da8dSAndroid Build Coastguard Workertry: 5*cda5da8dSAndroid Build Coastguard Worker from _json import make_scanner as c_make_scanner 6*cda5da8dSAndroid Build Coastguard Workerexcept ImportError: 7*cda5da8dSAndroid Build Coastguard Worker c_make_scanner = None 8*cda5da8dSAndroid Build Coastguard Worker 9*cda5da8dSAndroid Build Coastguard Worker__all__ = ['make_scanner'] 10*cda5da8dSAndroid Build Coastguard Worker 11*cda5da8dSAndroid Build Coastguard WorkerNUMBER_RE = re.compile( 12*cda5da8dSAndroid Build Coastguard Worker r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', 13*cda5da8dSAndroid Build Coastguard Worker (re.VERBOSE | re.MULTILINE | re.DOTALL)) 14*cda5da8dSAndroid Build Coastguard Worker 15*cda5da8dSAndroid Build Coastguard Workerdef py_make_scanner(context): 16*cda5da8dSAndroid Build Coastguard Worker parse_object = context.parse_object 17*cda5da8dSAndroid Build Coastguard Worker parse_array = context.parse_array 18*cda5da8dSAndroid Build Coastguard Worker parse_string = context.parse_string 19*cda5da8dSAndroid Build Coastguard Worker match_number = NUMBER_RE.match 20*cda5da8dSAndroid Build Coastguard Worker strict = context.strict 21*cda5da8dSAndroid Build Coastguard Worker parse_float = context.parse_float 22*cda5da8dSAndroid Build Coastguard Worker parse_int = context.parse_int 23*cda5da8dSAndroid Build Coastguard Worker parse_constant = context.parse_constant 24*cda5da8dSAndroid Build Coastguard Worker object_hook = context.object_hook 25*cda5da8dSAndroid Build Coastguard Worker object_pairs_hook = context.object_pairs_hook 26*cda5da8dSAndroid Build Coastguard Worker memo = context.memo 27*cda5da8dSAndroid Build Coastguard Worker 28*cda5da8dSAndroid Build Coastguard Worker def _scan_once(string, idx): 29*cda5da8dSAndroid Build Coastguard Worker try: 30*cda5da8dSAndroid Build Coastguard Worker nextchar = string[idx] 31*cda5da8dSAndroid Build Coastguard Worker except IndexError: 32*cda5da8dSAndroid Build Coastguard Worker raise StopIteration(idx) from None 33*cda5da8dSAndroid Build Coastguard Worker 34*cda5da8dSAndroid Build Coastguard Worker if nextchar == '"': 35*cda5da8dSAndroid Build Coastguard Worker return parse_string(string, idx + 1, strict) 36*cda5da8dSAndroid Build Coastguard Worker elif nextchar == '{': 37*cda5da8dSAndroid Build Coastguard Worker return parse_object((string, idx + 1), strict, 38*cda5da8dSAndroid Build Coastguard Worker _scan_once, object_hook, object_pairs_hook, memo) 39*cda5da8dSAndroid Build Coastguard Worker elif nextchar == '[': 40*cda5da8dSAndroid Build Coastguard Worker return parse_array((string, idx + 1), _scan_once) 41*cda5da8dSAndroid Build Coastguard Worker elif nextchar == 'n' and string[idx:idx + 4] == 'null': 42*cda5da8dSAndroid Build Coastguard Worker return None, idx + 4 43*cda5da8dSAndroid Build Coastguard Worker elif nextchar == 't' and string[idx:idx + 4] == 'true': 44*cda5da8dSAndroid Build Coastguard Worker return True, idx + 4 45*cda5da8dSAndroid Build Coastguard Worker elif nextchar == 'f' and string[idx:idx + 5] == 'false': 46*cda5da8dSAndroid Build Coastguard Worker return False, idx + 5 47*cda5da8dSAndroid Build Coastguard Worker 48*cda5da8dSAndroid Build Coastguard Worker m = match_number(string, idx) 49*cda5da8dSAndroid Build Coastguard Worker if m is not None: 50*cda5da8dSAndroid Build Coastguard Worker integer, frac, exp = m.groups() 51*cda5da8dSAndroid Build Coastguard Worker if frac or exp: 52*cda5da8dSAndroid Build Coastguard Worker res = parse_float(integer + (frac or '') + (exp or '')) 53*cda5da8dSAndroid Build Coastguard Worker else: 54*cda5da8dSAndroid Build Coastguard Worker res = parse_int(integer) 55*cda5da8dSAndroid Build Coastguard Worker return res, m.end() 56*cda5da8dSAndroid Build Coastguard Worker elif nextchar == 'N' and string[idx:idx + 3] == 'NaN': 57*cda5da8dSAndroid Build Coastguard Worker return parse_constant('NaN'), idx + 3 58*cda5da8dSAndroid Build Coastguard Worker elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity': 59*cda5da8dSAndroid Build Coastguard Worker return parse_constant('Infinity'), idx + 8 60*cda5da8dSAndroid Build Coastguard Worker elif nextchar == '-' and string[idx:idx + 9] == '-Infinity': 61*cda5da8dSAndroid Build Coastguard Worker return parse_constant('-Infinity'), idx + 9 62*cda5da8dSAndroid Build Coastguard Worker else: 63*cda5da8dSAndroid Build Coastguard Worker raise StopIteration(idx) 64*cda5da8dSAndroid Build Coastguard Worker 65*cda5da8dSAndroid Build Coastguard Worker def scan_once(string, idx): 66*cda5da8dSAndroid Build Coastguard Worker try: 67*cda5da8dSAndroid Build Coastguard Worker return _scan_once(string, idx) 68*cda5da8dSAndroid Build Coastguard Worker finally: 69*cda5da8dSAndroid Build Coastguard Worker memo.clear() 70*cda5da8dSAndroid Build Coastguard Worker 71*cda5da8dSAndroid Build Coastguard Worker return scan_once 72*cda5da8dSAndroid Build Coastguard Worker 73*cda5da8dSAndroid Build Coastguard Workermake_scanner = c_make_scanner or py_make_scanner 74