author | Kim Alvefur <zash@zash.se> |
Fri, 08 Jul 2022 19:36:07 +0200 | |
changeset 12585 | 6ee9071c0a1f |
parent 9332 | 19bc3ec13f07 |
child 12796 | 997f3ca90628 |
permissions | -rw-r--r-- |
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; |
|
9332
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8700
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; |
|
9332
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8700
diff
changeset
|
13 |
local pairs, ipairs, spairs = pairs, ipairs, require "util.iterators".sorted_pairs; |
3979 | 14 |
local next = next; |
6788
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 |
||
5516
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
18 |
local has_array, array = pcall(require, "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") |
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
diff
changeset
|
22 |
local module = {}; |
3979 | 23 |
|
6788
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; }); |
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
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 |
|
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
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; |
|
9332
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8700
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:
8700
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:
8700
diff
changeset
|
100 |
stringsave(k, buffer); |
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8700
diff
changeset
|
101 |
t_insert(buffer, ":"); |
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8700
diff
changeset
|
102 |
simplesave(v, buffer); |
19bc3ec13f07
util.json: Use util.iterators.sorted_pairs() in ordered mode
Matthew Wild <mwild1@gmail.com>
parents:
8700
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); |
|
7238
ee1f7e1e548c
util.json: Fix encoding of json.null (bug introduced in bf1f09a5bcf7)
Matthew Wild <mwild1@gmail.com>
parents:
6788
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:
6788
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:
6788
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 |
||
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
diff
changeset
|
151 |
function module.encode(obj) |
3979 | 152 |
local t = {}; |
153 |
simplesave(obj, t); |
|
154 |
return t_concat(t); |
|
155 |
end |
|
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
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 |
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
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; |
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
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; |
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
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 |
local oindex = 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
|
221 |
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
|
222 |
local 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
|
223 |
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
|
224 |
if val == 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
|
225 |
if json:byte(oindex + 1) == 0x5d then return setmetatable(a, array_mt), oindex + 2; 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
|
226 |
return val, index; |
3979 | 227 |
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
|
228 |
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
|
229 |
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
|
230 |
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
|
231 |
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
|
232 |
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
|
233 |
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
|
234 |
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
|
235 |
local _unescape_error; |
8700
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8385
diff
changeset
|
236 |
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
|
237 |
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
|
238 |
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
|
239 |
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
|
240 |
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
|
241 |
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
|
242 |
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
|
243 |
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
|
244 |
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
|
245 |
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
|
246 |
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
|
247 |
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
|
248 |
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
|
249 |
if x then |
8700
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8385
diff
changeset
|
250 |
local codepoint = tonumber(x, 16) |
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8385
diff
changeset
|
251 |
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:
8385
diff
changeset
|
252 |
return codepoint_to_utf8(codepoint); |
3979 | 253 |
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
|
254 |
_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
|
255 |
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
|
256 |
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
|
257 |
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
|
258 |
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
|
259 |
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
|
260 |
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
|
261 |
--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
|
262 |
-- 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
|
263 |
_unescape_error = nil; |
8700
c60fdf148118
util.json: Unescape surrogate pairs
Matthew Wild <mwild1@gmail.com>
parents:
8385
diff
changeset
|
264 |
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
|
265 |
-- 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
|
266 |
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
|
267 |
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
|
268 |
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
|
269 |
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
|
270 |
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
|
271 |
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
|
272 |
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
|
273 |
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
|
274 |
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
|
275 |
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
|
276 |
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
|
277 |
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
|
278 |
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
|
279 |
return null, index + 4; |
3979 | 280 |
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
|
281 |
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
|
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 _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
|
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 == 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
|
286 |
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
|
287 |
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
|
288 |
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
|
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 _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
|
291 |
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
|
292 |
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
|
293 |
return false, index + 5; |
3979 | 294 |
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
|
295 |
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
|
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 |
function _readvalue(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 |
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
|
299 |
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
|
300 |
-- 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
|
301 |
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
|
302 |
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
|
303 |
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
|
304 |
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
|
305 |
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
|
306 |
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
|
307 |
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
|
308 |
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
|
309 |
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
|
310 |
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
|
311 |
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
|
312 |
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
|
313 |
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
|
314 |
return _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
|
315 |
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
|
316 |
return nil, "value expected"; |
3979 | 317 |
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
|
318 |
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
|
319 |
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
|
320 |
["\\\""] = "\\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
|
321 |
["\\\\"] = "\\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
|
322 |
["\\/" ] = "\\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
|
323 |
["\\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
|
324 |
["\\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
|
325 |
["\\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
|
326 |
["\\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
|
327 |
["\\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
|
328 |
["\\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
|
329 |
}; |
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 |
|
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
diff
changeset
|
331 |
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
|
332 |
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
|
333 |
--: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
|
334 |
|
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
|
335 |
-- TODO do encoding verification |
5776
bd0ff8ae98a8
Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
5565
diff
changeset
|
336 |
|
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
|
337 |
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
|
338 |
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
|
339 |
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
|
340 |
|
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 |
return val; |
3979 | 342 |
end |
343 |
||
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
diff
changeset
|
344 |
function module.test(object) |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
diff
changeset
|
345 |
local encoded = module.encode(object); |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
diff
changeset
|
346 |
local decoded = module.decode(encoded); |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
diff
changeset
|
347 |
local recoded = module.encode(decoded); |
3979 | 348 |
if encoded ~= recoded then |
349 |
print("FAILED"); |
|
350 |
print("encoded:", encoded); |
|
351 |
print("recoded:", recoded); |
|
352 |
else |
|
353 |
print(encoded); |
|
354 |
end |
|
355 |
return encoded == recoded; |
|
356 |
end |
|
357 |
||
7264
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7262
diff
changeset
|
358 |
return module; |