6
6
--
7
7
-- includes unreleased upstream changes: https://github.com/rxi/json.lua/blob/dbf4b2dd2eb7c23be2773c89eb059dadd6436f94/json.lua
8
8
-- includes unmerged upstream pull request: https://github.com/rxi/json.lua/pull/51
9
+ -- includes unmerged upstream pull request: https://github.com/rxi/json.lua/pull/52
9
10
--
10
11
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
11
12
-- this software and associated documentation files (the "Software"), to deal in
@@ -74,6 +75,9 @@ local function encode_nil(val)
74
75
return " null"
75
76
end
76
77
78
+ local function encode_string (val )
79
+ return ' "' .. val :gsub (' [%z\1 -\31 \\ "]' , escape_char ) .. ' "'
80
+ end
77
81
78
82
local function encode_table (val , stack )
79
83
local res = {}
@@ -84,44 +88,44 @@ local function encode_table(val, stack)
84
88
85
89
stack [val ] = true
86
90
87
- if rawget (val , 1 ) ~= nil or next (val ) == nil then
88
- -- Treat as array -- check keys are valid and it is not sparse
89
- local n = 0
91
+ local types = {}
92
+
93
+ for k in pairs (val ) do
94
+ types [type (k )] = true
95
+ end
96
+
97
+ if # types > 1 then
98
+ error (" invalid table: mixed or invalid key types" )
99
+ elseif types [" number" ] then
100
+ -- Treat as array
101
+ local max_key = 0
90
102
for k in pairs (val ) do
91
- if type ( k ) ~= " number " then
92
- error ( " invalid table: mixed or invalid key types " )
103
+ if k > max_key then
104
+ max_key = k
93
105
end
94
- n = n + 1
95
- end
96
- if n ~= # val then
97
- error (" invalid table: sparse array" )
98
106
end
99
- -- Encode
100
- for i , v in ipairs (val ) do
101
- table.insert (res , encode (v , stack ))
107
+ for i = 1 , max_key do
108
+ if val [i ] == nil then
109
+ table.insert (res , " null" )
110
+ else
111
+ local v = encode (val [i ], stack )
112
+ table.insert (res , v )
113
+ end
102
114
end
103
115
stack [val ] = nil
104
116
return " [" .. table.concat (res , " ," ) .. " ]"
105
-
106
- else
107
- -- Treat as an object
117
+ elseif types [" string" ] then
118
+ -- Treat as object
108
119
for k , v in pairsByKeys (val ) do
109
- if type (k ) ~= " string" then
110
- error (" invalid table: mixed or invalid key types" )
111
- end
112
- table.insert (res , encode (k , stack ) .. " :" .. encode (v , stack ))
120
+ table.insert (res , encode_string (k ) .. " :" .. encode (v , stack ))
113
121
end
114
122
stack [val ] = nil
115
123
return " {" .. table.concat (res , " ," ) .. " }"
124
+ else
125
+ error ( string.format (" invalid table: unsupported key type %s" , types [1 ]) )
116
126
end
117
127
end
118
128
119
-
120
- local function encode_string (val )
121
- return ' "' .. val :gsub (' [%z\1 -\31 \\ "]' , escape_char ) .. ' "'
122
- end
123
-
124
-
125
129
local function encode_number (val )
126
130
-- Check for NaN, -inf and inf
127
131
if val ~= val or val <= - math.huge or val >= math.huge then
0 commit comments