1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
local json = {}
local escapes = {
['"'] = '\\"',
['\\'] = '\\\\',
['\b'] = '\\b',
['\f'] = '\\f',
['\n'] = '\\n',
['\r'] = '\\r',
['\t'] = '\\t',
}
local function is_array(t)
local max = 0
local count = 0
for k, _ in pairs(t) do
if type(k) ~= "number" or k < 1 or k % 1 ~= 0 then
return false
end
if k > max then max = k end
count = count + 1
end
return max == count
end
local function encode_string(s)
return '"' .. tostring(s):gsub('[%z\1-\31\\"]', function(c)
return escapes[c] or string.format("\\u%04x", c:byte())
end) .. '"'
end
local function encode_value(v)
local tv = type(v)
if tv == "nil" then
return "null"
elseif tv == "boolean" then
return v and "true" or "false"
elseif tv == "number" then
return tostring(v)
elseif tv == "string" then
return encode_string(v)
elseif tv == "table" then
local out = {}
if is_array(v) then
for i = 1, #v do
out[#out + 1] = encode_value(v[i])
end
return "[" .. table.concat(out, ",") .. "]"
end
local keys = {}
for k, _ in pairs(v) do keys[#keys + 1] = k end
table.sort(keys, function(a, b) return tostring(a) < tostring(b) end)
for _, k in ipairs(keys) do
out[#out + 1] = encode_string(k) .. ":" .. encode_value(v[k])
end
return "{" .. table.concat(out, ",") .. "}"
end
error("cannot JSON encode " .. tv)
end
function json.encode(v)
return encode_value(v)
end
return json