Mercurial > hg > ooxml
view eDecoder.py @ 74:7827e686be75 default tip
refactoring again...
author | Henry S. Thompson <ht@markup.co.uk> |
---|---|
date | Wed, 05 Jul 2017 18:26:27 +0100 |
parents | 0654e37583b5 |
children |
line wrap: on
line source
'''Extend JSON to support atoms as properties and class names''' from json import decoder from json.decoder import JSONDecoder, JSONObject, JSONArray,\ _CONSTANTS, WHITESPACE, WHITESPACE_STR, FLAGS, errmsg import json, re JSONObject_orig=JSONObject JSONArray_orig=JSONArray class eDecoder(JSONDecoder): def __init__(self, encoding=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None): self.parse_object = eJSONObject super(eDecoder,self).__init__(encoding, object_hook, parse_float, parse_int, e_parse_constant, strict, object_pairs_hook) def e_parse_constant(istr): print('constant: %s'%istr) return _CONSTANTS[istr] IDENT=re.compile(r'[$]?[A-Z]+[$]?[0-9]+([:][$]?[A-Z]+[$]?[0-9]+)|[a-zA-Z0-9_.-]+', FLAGS) def eJSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): s, end = s_and_end values = [] nextchar = s[end:end + 1] if nextchar in _ws: end = _w(s, end + 1).end() nextchar = s[end:end + 1] # Look-ahead for trivial empty array if nextchar == ']': return values, end + 1 _append = values.append while True: try: value, end = scan_once(s, end) except StopIteration: # Two possible causes: string empty, or no ident here # Either way, the match will fail and the (original) value error is correct isId = IDENT.match(s,end) if isId: value=isId.group() end=isId.end() else: raise ValueError(errmsg("Expecting object", s, end)) _append(value) nextchar = s[end:end + 1] if nextchar in _ws: end = _w(s, end + 1).end() nextchar = s[end:end + 1] end += 1 if nextchar == ']': break elif nextchar != ',': raise ValueError(errmsg("Expecting ',' delimiter", s, end)) try: if s[end] in _ws: end += 1 if s[end] in _ws: end = _w(s, end + 1).end() except IndexError: pass return values, end def eJSONObject(s_and_end, encoding, strict, scan_once, object_hook, object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): s, end = s_and_end pairs = [] pairs_append = pairs.append # Use a slice to prevent IndexError from being raised, the following # check will raise a more specific ValueError if the string is empty nextchar = s[end:end + 1] # Normally we expect nextchar == '"' if nextchar != '"': if nextchar in _ws: end = _w(s, end).end() nextchar = s[end:end + 1] # Trivial empty object if nextchar == '}': if object_pairs_hook is not None: result = object_pairs_hook(pairs) return result, end + 1 pairs = {} if object_hook is not None: pairs = object_hook(pairs) return pairs, end + 1 while True: if nextchar=='"': key, end = scanstring(s, end, encoding, strict) else: isId = IDENT.match(s,end) if isId: key=isId.group() end=isId.end() else: raise ValueError(errmsg( "Expecting property name with or w/o double quotes", s, end)) # To skip some function call overhead we optimize the fast paths where # the JSON key separator is ": " or just ":". if s[end:end + 1] != ':': end = _w(s, end).end() if s[end:end + 1] != ':': raise ValueError(errmsg("Expecting ':' delimiter", s, end)) end += 1 try: if s[end] in _ws: end += 1 if s[end] in _ws: end = _w(s, end + 1).end() except IndexError: pass try: value, end = scan_once(s, end) except StopIteration: # Two possible causes: string empty, or no ident here # Either way, the match will fail and the (original) value error is correct isId = IDENT.match(s,end) if isId: value=isId.group() end=isId.end() else: raise ValueError(errmsg("Expecting object", s, end)) pairs_append((key, value)) try: nextchar = s[end] if nextchar in _ws: end = _w(s, end + 1).end() nextchar = s[end] except IndexError: nextchar = '' end += 1 if nextchar == '}': break elif nextchar != ',': raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1)) try: nextchar = s[end] if nextchar in _ws: end += 1 nextchar = s[end] if nextchar in _ws: end = _w(s, end + 1).end() nextchar = s[end] except IndexError: nextchar = '' if nextchar=='"': end += 1 if object_pairs_hook is not None: result = object_pairs_hook(pairs) return result, end pairs = dict(pairs) if object_hook is not None: pairs = object_hook(pairs) return pairs, end json.scanner.make_scanner=json.scanner.py_make_scanner json.decoder.JSONObject=eJSONObject json.decoder.JSONArray=eJSONArray