Software /
code /
prosody
Annotate
util/json.lua @ 13182:c48ae06e24d6
util.datamanager: Fix indexing first item if not at the very start
If the first item does not start at position 0 then the index function
produces a phantom first entry covering position zero until where the
real first item starts. When using the index, this would make it either
appear as the first item was missing or cause an off-by-one issue with
remaining items.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 10 Jul 2023 17:19:05 +0200 |
parent | 12975:d10957394a3c |
rev | line source |
---|---|
5436
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
1 -- Prosody IM |
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
2 -- Copyright (C) 2008-2010 Matthew Wild |
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
3 -- Copyright (C) 2008-2010 Waqas Hussain |
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
4 -- |
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
5 -- This project is MIT/X11 licensed. Please see the |
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
6 -- COPYING file in the source package for more information. |
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
7 -- |
3979 | 8 |
9 local type = type; | |
9329
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8697
diff
changeset
|
10 local t_insert, t_concat, t_remove = table.insert, table.concat, table.remove; |
3979 | 11 local s_char = string.char; |
12 local tostring, tonumber = tostring, tonumber; | |
12975
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12792
diff
changeset
|
13 local pairs, ipairs, spairs = pairs, ipairs, require "prosody.util.iterators".sorted_pairs; |
3979 | 14 local next = next; |
6785
bf1f09a5bcf7
util.json: Remove use of newproxy
Kim Alvefur <zash@zash.se>
parents:
5776
diff
changeset
|
15 local getmetatable, setmetatable = getmetatable, setmetatable; |
3979 | 16 local print = print; |
17 | |
12975
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12792
diff
changeset
|
18 local has_array, array = pcall(require, "prosody.util.array"); |
5562
a6b8fb827e2a
util.json: Fix variable name typo which broke util.json when util.array was missing.
Waqas Hussain <waqas20@gmail.com>
parents:
5561
diff
changeset
|
19 local array_mt = has_array and getmetatable(array()) or {}; |
5516
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
20 |
3979 | 21 --module("json") |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
22 local module = {}; |
3979 | 23 |
6785
bf1f09a5bcf7
util.json: Remove use of newproxy
Kim Alvefur <zash@zash.se>
parents:
5776
diff
changeset
|
24 local null = setmetatable({}, { __tostring = function() return "null"; end; }); |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
25 module.null = null; |
3979 | 26 |
27 local escapes = { | |
28 ["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", | |
29 ["\f"] = "\\f", ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"}; | |
30 for i=0,31 do | |
31 local ch = s_char(i); | |
32 if not escapes[ch] then escapes[ch] = ("\\u%.4X"):format(i); end | |
33 end | |
34 | |
5517
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
35 local function codepoint_to_utf8(code) |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
36 if code < 0x80 then return s_char(code); end |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
37 local bits0_6 = code % 64; |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
38 if code < 0x800 then |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
39 local bits6_5 = (code - bits0_6) / 64; |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
40 return s_char(0x80 + 0x40 + bits6_5, 0x80 + bits0_6); |
5436
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
41 end |
5517
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
42 local bits0_12 = code % 4096; |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
43 local bits6_6 = (bits0_12 - bits0_6) / 64; |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
44 local bits12_4 = (code - bits0_12) / 4096; |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
45 return s_char(0x80 + 0x40 + 0x20 + bits12_4, 0x80 + bits6_6, 0x80 + bits0_6); |
5436
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
46 end |
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
47 |
3979 | 48 local valid_types = { |
49 number = true, | |
50 string = true, | |
51 table = true, | |
52 boolean = true | |
53 }; | |
54 local special_keys = { | |
55 __array = true; | |
56 __hash = true; | |
57 }; | |
58 | |
59 local simplesave, tablesave, arraysave, stringsave; | |
60 | |
61 function stringsave(o, buffer) | |
62 -- FIXME do proper utf-8 and binary data detection | |
63 t_insert(buffer, "\""..(o:gsub(".", escapes)).."\""); | |
64 end | |
65 | |
66 function arraysave(o, buffer) | |
67 t_insert(buffer, "["); | |
68 if next(o) then | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
69 for _, v in ipairs(o) do |
3979 | 70 simplesave(v, buffer); |
71 t_insert(buffer, ","); | |
72 end | |
73 t_remove(buffer); | |
74 end | |
75 t_insert(buffer, "]"); | |
76 end | |
77 | |
78 function tablesave(o, buffer) | |
79 local __array = {}; | |
80 local __hash = {}; | |
81 local hash = {}; | |
82 for i,v in ipairs(o) do | |
83 __array[i] = v; | |
84 end | |
85 for k,v in pairs(o) do | |
86 local ktype, vtype = type(k), type(v); | |
87 if valid_types[vtype] or v == null then | |
88 if ktype == "string" and not special_keys[k] then | |
89 hash[k] = v; | |
90 elseif (valid_types[ktype] or k == null) and __array[k] == nil then | |
91 __hash[k] = v; | |
92 end | |
93 end | |
94 end | |
95 if next(__hash) ~= nil or next(hash) ~= nil or next(__array) == nil then | |
96 t_insert(buffer, "{"); | |
97 local mark = #buffer; | |
9329
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8697
diff
changeset
|
98 local _pairs = buffer.ordered and spairs or pairs; |
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8697
diff
changeset
|
99 for k,v in _pairs(hash) do |
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8697
diff
changeset
|
100 stringsave(k, buffer); |
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8697
diff
changeset
|
101 t_insert(buffer, ":"); |
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8697
diff
changeset
|
102 simplesave(v, buffer); |
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8697
diff
changeset
|
103 t_insert(buffer, ","); |
3979 | 104 end |
105 if next(__hash) ~= nil then | |
106 t_insert(buffer, "\"__hash\":["); | |
107 for k,v in pairs(__hash) do | |
108 simplesave(k, buffer); | |
109 t_insert(buffer, ","); | |
110 simplesave(v, buffer); | |
111 t_insert(buffer, ","); | |
112 end | |
113 t_remove(buffer); | |
114 t_insert(buffer, "]"); | |
115 t_insert(buffer, ","); | |
116 end | |
117 if next(__array) then | |
118 t_insert(buffer, "\"__array\":"); | |
119 arraysave(__array, buffer); | |
120 t_insert(buffer, ","); | |
121 end | |
122 if mark ~= #buffer then t_remove(buffer); end | |
123 t_insert(buffer, "}"); | |
124 else | |
125 arraysave(__array, buffer); | |
126 end | |
127 end | |
128 | |
129 function simplesave(o, buffer) | |
130 local t = type(o); | |
7235
ee1f7e1e548c
util.json: Fix encoding of json.null (bug introduced in bf1f09a5bcf7)
Matthew Wild <mwild1@gmail.com>
parents:
6785
diff
changeset
|
131 if o == null then |
ee1f7e1e548c
util.json: Fix encoding of json.null (bug introduced in bf1f09a5bcf7)
Matthew Wild <mwild1@gmail.com>
parents:
6785
diff
changeset
|
132 t_insert(buffer, "null"); |
ee1f7e1e548c
util.json: Fix encoding of json.null (bug introduced in bf1f09a5bcf7)
Matthew Wild <mwild1@gmail.com>
parents:
6785
diff
changeset
|
133 elseif t == "number" then |
3979 | 134 t_insert(buffer, tostring(o)); |
135 elseif t == "string" then | |
136 stringsave(o, buffer); | |
137 elseif t == "table" then | |
5516
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
138 local mt = getmetatable(o); |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
139 if mt == array_mt then |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
140 arraysave(o, buffer); |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
141 else |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
142 tablesave(o, buffer); |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
143 end |
3979 | 144 elseif t == "boolean" then |
145 t_insert(buffer, (o and "true" or "false")); | |
146 else | |
147 t_insert(buffer, "null"); | |
148 end | |
149 end | |
150 | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
151 function module.encode(obj) |
3979 | 152 local t = {}; |
153 simplesave(obj, t); | |
154 return t_concat(t); | |
155 end | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
156 function module.encode_ordered(obj) |
4474
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
157 local t = { ordered = true }; |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
158 simplesave(obj, t); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
159 return t_concat(t); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
160 end |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
161 function module.encode_array(obj) |
5395
ec33d72a08b6
util.json: Add json.encode_array() (thanks B)
Matthew Wild <mwild1@gmail.com>
parents:
4474
diff
changeset
|
162 local t = {}; |
ec33d72a08b6
util.json: Add json.encode_array() (thanks B)
Matthew Wild <mwild1@gmail.com>
parents:
4474
diff
changeset
|
163 arraysave(obj, t); |
ec33d72a08b6
util.json: Add json.encode_array() (thanks B)
Matthew Wild <mwild1@gmail.com>
parents:
4474
diff
changeset
|
164 return t_concat(t); |
ec33d72a08b6
util.json: Add json.encode_array() (thanks B)
Matthew Wild <mwild1@gmail.com>
parents:
4474
diff
changeset
|
165 end |
3979 | 166 |
167 ----------------------------------- | |
168 | |
169 | |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
170 local function _skip_whitespace(json, index) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
171 return json:find("[^ \t\r\n]", index) or index; -- no need to check \r\n, we converted those to \t |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
172 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
173 local function _fixobject(obj) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
174 local __array = obj.__array; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
175 if __array then |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
176 obj.__array = nil; |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
177 for _, v in ipairs(__array) do |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
178 t_insert(obj, v); |
3979 | 179 end |
180 end | |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
181 local __hash = obj.__hash; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
182 if __hash then |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
183 obj.__hash = nil; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
184 local k; |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
185 for _, v in ipairs(__hash) do |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
186 if k ~= nil then |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
187 obj[k] = v; k = nil; |
3979 | 188 else |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
189 k = v; |
3979 | 190 end |
191 end | |
192 end | |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
193 return obj; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
194 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
195 local _readvalue, _readstring; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
196 local function _readobject(json, index) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
197 local o = {}; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
198 while true do |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
199 local key, val; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
200 index = _skip_whitespace(json, index + 1); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
201 if json:byte(index) ~= 0x22 then -- "\"" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
202 if json:byte(index) == 0x7d then return o, index + 1; end -- "}" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
203 return nil, "key expected"; |
3979 | 204 end |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
205 key, index = _readstring(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
206 if key == nil then return nil, index; end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
207 index = _skip_whitespace(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
208 if json:byte(index) ~= 0x3a then return nil, "colon expected"; end -- ":" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
209 val, index = _readvalue(json, index + 1); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
210 if val == nil then return nil, index; end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
211 o[key] = val; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
212 index = _skip_whitespace(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
213 local b = json:byte(index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
214 if b == 0x7d then return _fixobject(o), index + 1; end -- "}" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
215 if b ~= 0x2c then return nil, "object eof"; end -- "," |
3979 | 216 end |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
217 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
218 local function _readarray(json, index) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
219 local a = {}; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
220 while true do |
12792
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
221 local val, terminated; |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
222 val, index, terminated = _readvalue(json, index + 1, 0x5d); |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
223 if val == nil then |
12792
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
224 if terminated then -- "]" found instead of value |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
225 if #a ~= 0 then |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
226 -- A non-empty array here means we processed a comma, |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
227 -- but it wasn't followed by a value. JSON doesn't allow |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
228 -- trailing commas. |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
229 return nil, "value expected"; |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
230 end |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
231 val, index = setmetatable(a, array_mt), index+1; |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
232 end |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
233 return val, index; |
3979 | 234 end |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
235 t_insert(a, val); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
236 index = _skip_whitespace(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
237 local b = json:byte(index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
238 if b == 0x5d then return setmetatable(a, array_mt), index + 1; end -- "]" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
239 if b ~= 0x2c then return nil, "array eof"; end -- "," |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
240 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
241 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
242 local _unescape_error; |
8697
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8382
diff
changeset
|
243 local function _unescape_surrogate_func(x) |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
244 local lead, trail = tonumber(x:sub(3, 6), 16), tonumber(x:sub(9, 12), 16); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
245 local codepoint = lead * 0x400 + trail - 0x35FDC00; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
246 local a = codepoint % 64; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
247 codepoint = (codepoint - a) / 64; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
248 local b = codepoint % 64; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
249 codepoint = (codepoint - b) / 64; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
250 local c = codepoint % 64; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
251 codepoint = (codepoint - c) / 64; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
252 return s_char(0xF0 + codepoint, 0x80 + c, 0x80 + b, 0x80 + a); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
253 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
254 local function _unescape_func(x) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
255 x = x:match("%x%x%x%x", 3); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
256 if x then |
8697
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8382
diff
changeset
|
257 local codepoint = tonumber(x, 16) |
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8382
diff
changeset
|
258 if codepoint >= 0xD800 and codepoint <= 0xDFFF then _unescape_error = true; end -- bad surrogate pair |
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8382
diff
changeset
|
259 return codepoint_to_utf8(codepoint); |
3979 | 260 end |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
261 _unescape_error = true; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
262 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
263 function _readstring(json, index) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
264 index = index + 1; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
265 local endindex = json:find("\"", index, true); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
266 if endindex then |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
267 local s = json:sub(index, endindex - 1); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
268 --if s:find("[%z-\31]") then return nil, "control char in string"; end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
269 -- FIXME handle control characters |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
270 _unescape_error = nil; |
8697
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8382
diff
changeset
|
271 s = s:gsub("\\u[dD][89abAB]%x%x\\u[dD][cdefCDEF]%x%x", _unescape_surrogate_func); |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
272 -- FIXME handle escapes beyond BMP |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
273 s = s:gsub("\\u.?.?.?.?", _unescape_func); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
274 if _unescape_error then return nil, "invalid escape"; end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
275 return s, endindex + 1; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
276 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
277 return nil, "string eof"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
278 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
279 local function _readnumber(json, index) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
280 local m = json:match("[0-9%.%-eE%+]+", index); -- FIXME do strict checking |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
281 return tonumber(m), index + #m; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
282 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
283 local function _readnull(json, index) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
284 local a, b, c = json:byte(index + 1, index + 3); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
285 if a == 0x75 and b == 0x6c and c == 0x6c then |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
286 return null, index + 4; |
3979 | 287 end |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
288 return nil, "null parse failed"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
289 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
290 local function _readtrue(json, index) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
291 local a, b, c = json:byte(index + 1, index + 3); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
292 if a == 0x72 and b == 0x75 and c == 0x65 then |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
293 return true, index + 4; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
294 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
295 return nil, "true parse failed"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
296 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
297 local function _readfalse(json, index) |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
298 local a, b, c, d = json:byte(index + 1, index + 4); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
299 if a == 0x61 and b == 0x6c and c == 0x73 and d == 0x65 then |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
300 return false, index + 5; |
3979 | 301 end |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
302 return nil, "false parse failed"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
303 end |
12792
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
304 function _readvalue(json, index, terminator) |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
305 index = _skip_whitespace(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
306 local b = json:byte(index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
307 -- TODO try table lookup instead of if-else? |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
308 if b == 0x7B then -- "{" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
309 return _readobject(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
310 elseif b == 0x5B then -- "[" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
311 return _readarray(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
312 elseif b == 0x22 then -- "\"" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
313 return _readstring(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
314 elseif b ~= nil and b >= 0x30 and b <= 0x39 or b == 0x2d then -- "0"-"9" or "-" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
315 return _readnumber(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
316 elseif b == 0x6e then -- "n" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
317 return _readnull(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
318 elseif b == 0x74 then -- "t" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
319 return _readtrue(json, index); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
320 elseif b == 0x66 then -- "f" |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
321 return _readfalse(json, index); |
12792
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
322 elseif b == terminator then |
997f3ca90628
util.json: Accept empty arrays with whitespace (fixes #1782)
Matthew Wild <mwild1@gmail.com>
parents:
9329
diff
changeset
|
323 return nil, index, true; |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
324 else |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
325 return nil, "value expected"; |
3979 | 326 end |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
327 end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
328 local first_escape = { |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
329 ["\\\""] = "\\u0022"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
330 ["\\\\"] = "\\u005c"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
331 ["\\/" ] = "\\u002f"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
332 ["\\b" ] = "\\u0008"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
333 ["\\f" ] = "\\u000C"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
334 ["\\n" ] = "\\u000A"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
335 ["\\r" ] = "\\u000D"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
336 ["\\t" ] = "\\u0009"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
337 ["\\u" ] = "\\u"; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
338 }; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
339 |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
340 function module.decode(json) |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
341 json = json:gsub("\\.", first_escape) -- get rid of all escapes except \uXXXX, making string parsing much simpler |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
342 --:gsub("[\r\n]", "\t"); -- \r\n\t are equivalent, we care about none of them, and none of them can be in strings |
5776
bd0ff8ae98a8
Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
5565
diff
changeset
|
343 |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
344 -- TODO do encoding verification |
5776
bd0ff8ae98a8
Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
5565
diff
changeset
|
345 |
5565
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
346 local val, index = _readvalue(json, 1); |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
347 if val == nil then return val, index; end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
348 if json:find("[^ \t\r\n]", index) then return nil, "garbage at eof"; end |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
349 |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
350 return val; |
3979 | 351 end |
352 | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
353 function module.test(object) |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
354 local encoded = module.encode(object); |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
355 local decoded = module.decode(encoded); |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
356 local recoded = module.encode(decoded); |
3979 | 357 if encoded ~= recoded then |
358 print("FAILED"); | |
359 print("encoded:", encoded); | |
360 print("recoded:", recoded); | |
361 else | |
362 print(encoded); | |
363 end | |
364 return encoded == recoded; | |
365 end | |
366 | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
367 return module; |