Skip to content

Commit 43efcf7

Browse files
Merge pull request #3 from aryajur/master
@aryajur Improved table encoding code to handle sparse arrays.
2 parents 17b308b + f521e4a commit 43efcf7

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

json.lua

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,32 +64,43 @@ local function encode_table(val, stack)
6464
if stack[val] then error("circular reference") end
6565

6666
stack[val] = true
67+
-- Check whether to treat as a array or object
68+
local array = true
69+
local length = 0
70+
local nLen = 0
71+
for k,v in pairs(val) do
72+
if (type(k) ~= "number" or k<=0) and not (k == "n" and type(v) == "number") then
73+
array = nil
74+
break -- Treat as object
75+
else
76+
if k > length then
77+
length = k
78+
end
79+
if k == "n" and type(v) == "number" then
80+
nLen = v
81+
end
82+
end
83+
end
6784

68-
if rawget(val, 1) ~= nil or next(val) == nil then
69-
-- Treat as array -- check keys are valid and it is not sparse
70-
local n = 0
71-
for k in pairs(val) do
72-
if type(k) ~= "number" then
73-
error("invalid table: mixed or invalid key types")
74-
end
75-
n = n + 1
76-
end
77-
if n ~= #val then
78-
error("invalid table: sparse array")
79-
end
85+
if array then
86+
if nLen > length then
87+
length = nLen
88+
end
8089
-- Encode
81-
for i, v in ipairs(val) do
82-
table.insert(res, encode(v, stack))
90+
for i=1,length do
91+
table.insert(res, encode(val[i], stack))
8392
end
8493
stack[val] = nil
8594
return "[" .. table.concat(res, ",") .. "]"
8695

8796
else
8897
-- Treat as an object
8998
for k, v in pairs(val) do
99+
--[[
90100
if type(k) ~= "string" then
91101
error("invalid table: mixed or invalid key types")
92102
end
103+
]]
93104
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
94105
end
95106
stack[val] = nil
@@ -108,7 +119,7 @@ local function encode_number(val)
108119
if val ~= val or val <= -math.huge or val >= math.huge then
109120
error("unexpected number value '" .. tostring(val) .. "'")
110121
end
111-
return string.format("%.14g", val)
122+
return tostring(val)
112123
end
113124

114125

0 commit comments

Comments
 (0)