Mercurial > hg > ooxml
comparison eDecoder.py @ 72:0654e37583b5
appears to read kdir.js correctly
author | Henry S. Thompson <ht@markup.co.uk> |
---|---|
date | Thu, 29 Jun 2017 17:58:06 +0100 |
parents | 54bb53434887 |
children |
comparison
equal
deleted
inserted
replaced
71:54bb53434887 | 72:0654e37583b5 |
---|---|
1 '''Extend JSON to support atoms as properties and class names''' | 1 '''Extend JSON to support atoms as properties and class names''' |
2 from json import decoder | 2 from json import decoder |
3 from json.decoder import JSONDecoder, JSONObject, _CONSTANTS, WHITESPACE, WHITESPACE_STR, FLAGS, errmsg | 3 from json.decoder import JSONDecoder, JSONObject, JSONArray,\ |
4 _CONSTANTS, WHITESPACE, WHITESPACE_STR, FLAGS, errmsg | |
4 | 5 |
5 import json, re | 6 import json, re |
6 | 7 |
7 JSONObject_orig=JSONObject | 8 JSONObject_orig=JSONObject |
9 JSONArray_orig=JSONArray | |
8 | 10 |
9 class eDecoder(JSONDecoder): | 11 class eDecoder(JSONDecoder): |
10 def __init__(self, encoding=None, object_hook=None, parse_float=None, | 12 def __init__(self, encoding=None, object_hook=None, parse_float=None, |
11 parse_int=None, parse_constant=None, strict=True, | 13 parse_int=None, parse_constant=None, strict=True, |
12 object_pairs_hook=None): | 14 object_pairs_hook=None): |
18 | 20 |
19 def e_parse_constant(istr): | 21 def e_parse_constant(istr): |
20 print('constant: %s'%istr) | 22 print('constant: %s'%istr) |
21 return _CONSTANTS[istr] | 23 return _CONSTANTS[istr] |
22 | 24 |
23 IDENT=re.compile(r'[a-zA-Z0-9_.-]+', FLAGS) | 25 IDENT=re.compile(r'[$]?[A-Z]+[$]?[0-9]+([:][$]?[A-Z]+[$]?[0-9]+)|[a-zA-Z0-9_.-]+', FLAGS) |
26 | |
27 def eJSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): | |
28 s, end = s_and_end | |
29 values = [] | |
30 nextchar = s[end:end + 1] | |
31 if nextchar in _ws: | |
32 end = _w(s, end + 1).end() | |
33 nextchar = s[end:end + 1] | |
34 # Look-ahead for trivial empty array | |
35 if nextchar == ']': | |
36 return values, end + 1 | |
37 _append = values.append | |
38 while True: | |
39 try: | |
40 value, end = scan_once(s, end) | |
41 except StopIteration: | |
42 # Two possible causes: string empty, or no ident here | |
43 # Either way, the match will fail and the (original) value error is correct | |
44 isId = IDENT.match(s,end) | |
45 if isId: | |
46 value=isId.group() | |
47 end=isId.end() | |
48 else: | |
49 raise ValueError(errmsg("Expecting object", s, end)) | |
50 _append(value) | |
51 nextchar = s[end:end + 1] | |
52 if nextchar in _ws: | |
53 end = _w(s, end + 1).end() | |
54 nextchar = s[end:end + 1] | |
55 end += 1 | |
56 if nextchar == ']': | |
57 break | |
58 elif nextchar != ',': | |
59 raise ValueError(errmsg("Expecting ',' delimiter", s, end)) | |
60 try: | |
61 if s[end] in _ws: | |
62 end += 1 | |
63 if s[end] in _ws: | |
64 end = _w(s, end + 1).end() | |
65 except IndexError: | |
66 pass | |
67 | |
68 return values, end | |
24 | 69 |
25 def eJSONObject(s_and_end, encoding, strict, scan_once, object_hook, | 70 def eJSONObject(s_and_end, encoding, strict, scan_once, object_hook, |
26 object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): | 71 object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): |
27 s, end = s_and_end | 72 s, end = s_and_end |
28 if (s[end] in ('"','}') or | 73 pairs = [] |
29 (s[end] in _ws and | 74 pairs_append = pairs.append |
30 s[_w(s,end).end()] in ('"','}'))): | 75 # Use a slice to prevent IndexError from being raised, the following |
31 return JSONObject_orig(s_and_end, encoding, strict, scan_once, object_hook, | 76 # check will raise a more specific ValueError if the string is empty |
32 object_pairs_hook, _w, _ws) | 77 nextchar = s[end:end + 1] |
78 # Normally we expect nextchar == '"' | |
79 if nextchar != '"': | |
80 if nextchar in _ws: | |
81 end = _w(s, end).end() | |
82 nextchar = s[end:end + 1] | |
83 # Trivial empty object | |
84 if nextchar == '}': | |
85 if object_pairs_hook is not None: | |
86 result = object_pairs_hook(pairs) | |
87 return result, end + 1 | |
88 pairs = {} | |
89 if object_hook is not None: | |
90 pairs = object_hook(pairs) | |
91 return pairs, end + 1 | |
33 while True: | 92 while True: |
34 #key, end = scanstring(s, end, encoding, strict) | 93 if nextchar=='"': |
35 isId = IDENT.match(s,end) | 94 key, end = scanstring(s, end, encoding, strict) |
36 if isId: | |
37 key=isId.group() | |
38 end=isId.end() | |
39 else: | 95 else: |
40 raise ValueError(errmsg( | 96 isId = IDENT.match(s,end) |
41 "Expecting property name with or w/o in double quotes", s, end)) | 97 if isId: |
42 | 98 key=isId.group() |
99 end=isId.end() | |
100 else: | |
101 raise ValueError(errmsg( | |
102 "Expecting property name with or w/o double quotes", s, end)) | |
43 # To skip some function call overhead we optimize the fast paths where | 103 # To skip some function call overhead we optimize the fast paths where |
44 # the JSON key separator is ": " or just ":". | 104 # the JSON key separator is ": " or just ":". |
45 if s[end:end + 1] != ':': | 105 if s[end:end + 1] != ':': |
46 end = _w(s, end).end() | 106 end = _w(s, end).end() |
47 if s[end:end + 1] != ':': | 107 if s[end:end + 1] != ':': |
57 pass | 117 pass |
58 | 118 |
59 try: | 119 try: |
60 value, end = scan_once(s, end) | 120 value, end = scan_once(s, end) |
61 except StopIteration: | 121 except StopIteration: |
62 raise ValueError(errmsg("Expecting object", s, end)) | 122 # Two possible causes: string empty, or no ident here |
123 # Either way, the match will fail and the (original) value error is correct | |
124 isId = IDENT.match(s,end) | |
125 if isId: | |
126 value=isId.group() | |
127 end=isId.end() | |
128 else: | |
129 raise ValueError(errmsg("Expecting object", s, end)) | |
63 pairs_append((key, value)) | 130 pairs_append((key, value)) |
64 | 131 |
65 try: | 132 try: |
66 nextchar = s[end] | 133 nextchar = s[end] |
67 if nextchar in _ws: | 134 if nextchar in _ws: |
85 end = _w(s, end + 1).end() | 152 end = _w(s, end + 1).end() |
86 nextchar = s[end] | 153 nextchar = s[end] |
87 except IndexError: | 154 except IndexError: |
88 nextchar = '' | 155 nextchar = '' |
89 | 156 |
90 end += 1 | 157 if nextchar=='"': |
91 if nextchar != '"': | 158 end += 1 |
92 raise ValueError(errmsg( | |
93 "Expecting property name enclosed in double quotes", s, end - 1)) | |
94 if object_pairs_hook is not None: | 159 if object_pairs_hook is not None: |
95 result = object_pairs_hook(pairs) | 160 result = object_pairs_hook(pairs) |
96 return result, end | 161 return result, end |
97 pairs = dict(pairs) | 162 pairs = dict(pairs) |
98 if object_hook is not None: | 163 if object_hook is not None: |
100 return pairs, end | 165 return pairs, end |
101 | 166 |
102 | 167 |
103 json.scanner.make_scanner=json.scanner.py_make_scanner | 168 json.scanner.make_scanner=json.scanner.py_make_scanner |
104 json.decoder.JSONObject=eJSONObject | 169 json.decoder.JSONObject=eJSONObject |
170 json.decoder.JSONArray=eJSONArray |