-
Notifications
You must be signed in to change notification settings - Fork 6
/
json.lua
154 lines (139 loc) · 3.49 KB
/
json.lua
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
--[==[
JSON encoding and decoding API.
Written by Cosmin Apreutesei. Public Domain.
[try_]json_decode(s[, null_val]) -> v decode JSON
json_encode(v[, indent]) -> s encode JSON
null value to encode/decode json `null`
json_asarray(t) -> t mark t to be encoded as a json array
json_pack(...) -> t like pack() but nils become null
json_unpack(t) -> ... like unpack() but nulls become nil
repl_nulls(t) -> t replace `null` values in `t` recursively
]==]
local cjson = require'cjson'.new()
local cjson_safe = require'cjson.safe'.new()
cjson.encode_sparse_array(false, 0, 0) --encode all sparse arrays.
cjson.encode_empty_table_as_object(false) --encode empty tables as arrays.
cjson_safe.encode_sparse_array(false, 0, 0) --encode all sparse arrays.
cjson_safe.encode_empty_table_as_object(false) --encode empty tables as arrays.
null = cjson.null
local
type, select, pairs, unpack =
type, select, pairs, unpack
function json_asarray(t)
return setmetatable(t or {}, cjson.array_mt)
end
function json_pack(...)
local t = json_asarray{...}
for i=1,select('#',...) do
if t[i] == nil then
t[i] = null
end
end
return t
end
function json_unpack(t)
local dt = {}
for i=1,#t do
if t[i] == null then
dt[i] = nil
else
dt[i] = t[i]
end
end
return unpack(dt, 1, #t)
end
local function repl_nulls_t(t, null_val)
if null_val == nil and t[1] ~= nil then --array
local n = #t
for i=1,n do
if t[i] == null then --sparse
t[i] = nil
t.n = n
elseif type(t[i]) == 'table' then
repl_nulls_t(t[i], nil)
end
end
else
for k,v in pairs(t) do
if v == null then
t[k] = null_val
elseif type(v) == 'table' then
repl_nulls_t(v, null_val)
end
end
end
return t
end
function repl_nulls(v, null_val)
if null_val == null then return v end
if type(v) == 'table' then
return repl_nulls_t(v)
elseif v == null then
return null_val
else
return v
end
end
local repl_nulls = repl_nulls
function json_decode(v, null_val)
if type(v) ~= 'string' then return v end
return repl_nulls(cjson.decode(v), null_val)
end
function try_json_decode(v, null_val)
if type(v) ~= 'string' then return v end
local v, err = cjson_safe.decode(v)
if v == nil then return nil, err end
return repl_nulls(v, null_val)
end
--prettycjson 1.5 from https://github.com/bungle/lua-resty-prettycjson.
--Copyright (c) 2015 — 2016, Aapo Talvensaari. BSD license.
local rep = string.rep
local cat = table.concat
local function pretty(s, lf, id, ac)
lf, id, ac = lf or '\n', id or '\t', ac or ' '
local i, j, k, n, r, p, q = 1, 0, 0, #s, {}, nil, nil
local al = ac:sub(-1) == '\n'
for x = 1, n do
local c = s:sub(x, x)
if not q and (c == '{' or c == '[') then
r[i] = p == ':' and c..lf or rep(id, j)..c..lf
j = j + 1
elseif not q and (c == '}' or c == ']') then
j = j - 1
if p == '{' or p == '[' then
i = i - 1
r[i] = rep(id, j)..p..c
else
r[i] = lf..rep(id, j)..c
end
elseif not q and c == ',' then
r[i] = c..lf
k = -1
elseif not q and c == ':' then
r[i] = c..ac
if al then
i = i + 1
r[i] = rep(id, j)
end
else
if c == '\'' and p ~= '\\' then
q = not q and true or nil
end
if j ~= k then
r[i] = rep(id, j)
i, k = i + 1, j
end
r[i] = c
end
p, i = c, i + 1
end
return cat(r)
end
function json_encode(v, indent)
local s = cjson.encode(v)
if indent and indent ~= '' then
return pretty(s, nil, indent)
else
return s
end
end