Software /
code /
prosody
Annotate
util/json.lua @ 7567:495de404a8ae
ejabberdsql2prosody: rename variable 'host' to prevent shadowing upvalue [luacheck]
Functions roster(), roster_pending(), roster_group(), private_storage() and
offline_msg() have argument named "host", which used to shadow upvalue of this
variable before this change. Instead of renaming this argument, let's rename
the variable to match what the script says in usage:
Usage: ejabberdsql2prosody.lua filename.txt hostname
author | Anton Shestakov <av6@dwimlabs.net> |
---|---|
date | Fri, 12 Aug 2016 13:44:47 +0800 |
parent | 7261:925f848c706d |
child | 8382:e5d00bf4a4d5 |
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; | |
4474
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
10 local t_insert, t_concat, t_remove, t_sort = table.insert, table.concat, table.remove, table.sort; |
3979 | 11 local s_char = string.char; |
12 local tostring, tonumber = tostring, tonumber; | |
13 local pairs, ipairs = pairs, ipairs; | |
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 | |
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") |
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 local unescapes = { | |
31 ["\""] = "\"", ["\\"] = "\\", ["/"] = "/", | |
32 b = "\b", f = "\f", n = "\n", r = "\r", t = "\t"}; | |
33 for i=0,31 do | |
34 local ch = s_char(i); | |
35 if not escapes[ch] then escapes[ch] = ("\\u%.4X"):format(i); end | |
36 end | |
37 | |
5517
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
38 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
|
39 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
|
40 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
|
41 if code < 0x800 then |
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
42 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
|
43 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
|
44 end |
5517
9d7349bbe4d2
util.json: New, improved, fixed codepoint to UTF-8 conversion.
Waqas Hussain <waqas20@gmail.com>
parents:
5516
diff
changeset
|
45 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
|
46 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
|
47 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
|
48 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
|
49 end |
a4ba5819bf50
util.json: Convert \uXXXX to UTF-8 when decoding
Matthew Wild <mwild1@gmail.com>
parents:
5395
diff
changeset
|
50 |
3979 | 51 local valid_types = { |
52 number = true, | |
53 string = true, | |
54 table = true, | |
55 boolean = true | |
56 }; | |
57 local special_keys = { | |
58 __array = true; | |
59 __hash = true; | |
60 }; | |
61 | |
62 local simplesave, tablesave, arraysave, stringsave; | |
63 | |
64 function stringsave(o, buffer) | |
65 -- FIXME do proper utf-8 and binary data detection | |
66 t_insert(buffer, "\""..(o:gsub(".", escapes)).."\""); | |
67 end | |
68 | |
69 function arraysave(o, buffer) | |
70 t_insert(buffer, "["); | |
71 if next(o) then | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
72 for _, v in ipairs(o) do |
3979 | 73 simplesave(v, buffer); |
74 t_insert(buffer, ","); | |
75 end | |
76 t_remove(buffer); | |
77 end | |
78 t_insert(buffer, "]"); | |
79 end | |
80 | |
81 function tablesave(o, buffer) | |
82 local __array = {}; | |
83 local __hash = {}; | |
84 local hash = {}; | |
85 for i,v in ipairs(o) do | |
86 __array[i] = v; | |
87 end | |
88 for k,v in pairs(o) do | |
89 local ktype, vtype = type(k), type(v); | |
90 if valid_types[vtype] or v == null then | |
91 if ktype == "string" and not special_keys[k] then | |
92 hash[k] = v; | |
93 elseif (valid_types[ktype] or k == null) and __array[k] == nil then | |
94 __hash[k] = v; | |
95 end | |
96 end | |
97 end | |
98 if next(__hash) ~= nil or next(hash) ~= nil or next(__array) == nil then | |
99 t_insert(buffer, "{"); | |
100 local mark = #buffer; | |
4474
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
101 if buffer.ordered then |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
102 local keys = {}; |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
103 for k in pairs(hash) do |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
104 t_insert(keys, k); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
105 end |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
106 t_sort(keys); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
107 for _,k in ipairs(keys) do |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
108 stringsave(k, buffer); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
109 t_insert(buffer, ":"); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
110 simplesave(hash[k], buffer); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
111 t_insert(buffer, ","); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
112 end |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
113 else |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
114 for k,v in pairs(hash) do |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
115 stringsave(k, buffer); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
116 t_insert(buffer, ":"); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
117 simplesave(v, buffer); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
118 t_insert(buffer, ","); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
119 end |
3979 | 120 end |
121 if next(__hash) ~= nil then | |
122 t_insert(buffer, "\"__hash\":["); | |
123 for k,v in pairs(__hash) do | |
124 simplesave(k, buffer); | |
125 t_insert(buffer, ","); | |
126 simplesave(v, buffer); | |
127 t_insert(buffer, ","); | |
128 end | |
129 t_remove(buffer); | |
130 t_insert(buffer, "]"); | |
131 t_insert(buffer, ","); | |
132 end | |
133 if next(__array) then | |
134 t_insert(buffer, "\"__array\":"); | |
135 arraysave(__array, buffer); | |
136 t_insert(buffer, ","); | |
137 end | |
138 if mark ~= #buffer then t_remove(buffer); end | |
139 t_insert(buffer, "}"); | |
140 else | |
141 arraysave(__array, buffer); | |
142 end | |
143 end | |
144 | |
145 function simplesave(o, buffer) | |
146 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
|
147 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
|
148 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
|
149 elseif t == "number" then |
3979 | 150 t_insert(buffer, tostring(o)); |
151 elseif t == "string" then | |
152 stringsave(o, buffer); | |
153 elseif t == "table" then | |
5516
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
154 local mt = getmetatable(o); |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
155 if mt == array_mt then |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
156 arraysave(o, buffer); |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
157 else |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
158 tablesave(o, buffer); |
9733836629f9
util.json: Make encode(decode("[]"))=="[]".
Waqas Hussain <waqas20@gmail.com>
parents:
5436
diff
changeset
|
159 end |
3979 | 160 elseif t == "boolean" then |
161 t_insert(buffer, (o and "true" or "false")); | |
162 else | |
163 t_insert(buffer, "null"); | |
164 end | |
165 end | |
166 | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
167 function module.encode(obj) |
3979 | 168 local t = {}; |
169 simplesave(obj, t); | |
170 return t_concat(t); | |
171 end | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
172 function module.encode_ordered(obj) |
4474
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
173 local t = { ordered = true }; |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
174 simplesave(obj, t); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
175 return t_concat(t); |
b08a46cf06e6
util.json: Added function encode_ordered(object).
Waqas Hussain <waqas20@gmail.com>
parents:
4404
diff
changeset
|
176 end |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
177 function module.encode_array(obj) |
5395
ec33d72a08b6
util.json: Add json.encode_array() (thanks B)
Matthew Wild <mwild1@gmail.com>
parents:
4474
diff
changeset
|
178 local t = {}; |
ec33d72a08b6
util.json: Add json.encode_array() (thanks B)
Matthew Wild <mwild1@gmail.com>
parents:
4474
diff
changeset
|
179 arraysave(obj, t); |
ec33d72a08b6
util.json: Add json.encode_array() (thanks B)
Matthew Wild <mwild1@gmail.com>
parents:
4474
diff
changeset
|
180 return t_concat(t); |
ec33d72a08b6
util.json: Add json.encode_array() (thanks B)
Matthew Wild <mwild1@gmail.com>
parents:
4474
diff
changeset
|
181 end |
3979 | 182 |
183 ----------------------------------- | |
184 | |
185 | |
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 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
|
187 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
|
188 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
|
189 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
|
190 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
|
191 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
|
192 obj.__array = nil; |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
193 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
|
194 t_insert(obj, v); |
3979 | 195 end |
196 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
|
197 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
|
198 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
|
199 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
|
200 local k; |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
201 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
|
202 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
|
203 obj[k] = v; k = nil; |
3979 | 204 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
|
205 k = v; |
3979 | 206 end |
207 end | |
208 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
|
209 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
|
210 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 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
|
212 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
|
213 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
|
214 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
|
215 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
|
216 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
|
217 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
|
218 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
|
219 return nil, "key expected"; |
3979 | 220 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
|
221 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
|
222 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
|
223 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
|
224 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
|
225 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
|
226 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
|
227 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
|
228 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
|
229 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
|
230 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
|
231 if b ~= 0x2c then return nil, "object eof"; end -- "," |
3979 | 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 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 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
|
235 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
|
236 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
|
237 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
|
238 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
|
239 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
|
240 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
|
241 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
|
242 return val, index; |
3979 | 243 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
|
244 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
|
245 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
|
246 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
|
247 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
|
248 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
|
249 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
|
250 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
|
251 local _unescape_error; |
6dd806829226
util.json: New, faster, stricter, 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 local function _unescape_surrogate_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
|
253 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
|
254 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
|
255 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
|
256 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
|
257 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
|
258 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
|
259 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
|
260 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
|
261 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
|
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 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
|
264 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
|
265 if x 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
|
266 --if x >= 0xD800 and x <= 0xDFFF then _unescape_error = true; end -- bad surrogate pair |
6dd806829226
util.json: New, faster, stricter, 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 return codepoint_to_utf8(tonumber(x, 16)); |
3979 | 268 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
|
269 _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
|
270 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
|
271 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
|
272 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
|
273 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
|
274 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
|
275 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
|
276 --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
|
277 -- 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
|
278 _unescape_error = 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
|
279 --s = s:gsub("\\u[dD][89abAB]%x%x\\u[dD][cdefCDEF]%x%x", _unescape_surrogate_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
|
280 -- 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
|
281 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
|
282 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
|
283 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
|
284 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
|
285 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
|
286 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
|
287 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
|
288 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
|
289 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
|
290 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
|
291 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
|
292 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
|
293 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
|
294 return null, index + 4; |
3979 | 295 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
|
296 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
|
297 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
|
298 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
|
299 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
|
300 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
|
301 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
|
302 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
|
303 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
|
304 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
|
305 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
|
306 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
|
307 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
|
308 return false, index + 5; |
3979 | 309 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
|
310 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
|
311 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
|
312 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
|
313 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
|
314 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
|
315 -- 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
|
316 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
|
317 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
|
318 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
|
319 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
|
320 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
|
321 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
|
322 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
|
323 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
|
324 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
|
325 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
|
326 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
|
327 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
|
328 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
|
329 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
|
330 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
|
331 return nil, "value expected"; |
3979 | 332 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
|
333 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
|
334 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
|
335 ["\\\""] = "\\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
|
336 ["\\\\"] = "\\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
|
337 ["\\/" ] = "\\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
|
338 ["\\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
|
339 ["\\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
|
340 ["\\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
|
341 ["\\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
|
342 ["\\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
|
343 ["\\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
|
344 }; |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
345 |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
346 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
|
347 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
|
348 --: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
|
349 |
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
|
350 -- TODO do encoding verification |
5776
bd0ff8ae98a8
Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
5565
diff
changeset
|
351 |
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
|
352 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
|
353 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
|
354 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
|
355 |
6dd806829226
util.json: New, faster, stricter, more compliant JSON decoder. Now returns nil,err instead of throwing errors on invalid input.
Waqas Hussain <waqas20@gmail.com>
parents:
5563
diff
changeset
|
356 return val; |
3979 | 357 end |
358 | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
359 function module.test(object) |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
360 local encoded = module.encode(object); |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
361 local decoded = module.decode(encoded); |
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
362 local recoded = module.encode(decoded); |
3979 | 363 if encoded ~= recoded then |
364 print("FAILED"); | |
365 print("encoded:", encoded); | |
366 print("recoded:", recoded); | |
367 else | |
368 print(encoded); | |
369 end | |
370 return encoded == recoded; | |
371 end | |
372 | |
7261
925f848c706d
util.json: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
7259
diff
changeset
|
373 return module; |