Removed use of loadstring() in parse_string()

Significant performance boost
pull/6/head
rxi 2015-08-12 18:23:30 +01:00
parent 157fa12fae
commit f36b2f34b7
1 changed files with 14 additions and 3 deletions

View File

@ -13,7 +13,6 @@ local json = { _version = "0.0.0" }
-- Encode -- Encode
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
local loadstring = loadstring or load
local encode local encode
local escape_char_map = { local escape_char_map = {
@ -26,6 +25,12 @@ local escape_char_map = {
[ "\t" ] = "\\t", [ "\t" ] = "\\t",
} }
local escape_char_map_inv = {}
for k, v in pairs(escape_char_map) do
escape_char_map_inv[v] = k
end
local function escape_char(c) local function escape_char(c)
return escape_char_map[c] or string.format("\\u%04x", c:byte()) return escape_char_map[c] or string.format("\\u%04x", c:byte())
end end
@ -169,6 +174,7 @@ end
local function parse_string(str, i, chr) local function parse_string(str, i, chr)
local has_unicode_escape = false local has_unicode_escape = false
local has_escape = false
local last local last
for j = i + 1, #str do for j = i + 1, #str do
local x = str:sub(j, j) local x = str:sub(j, j)
@ -187,17 +193,22 @@ local function parse_string(str, i, chr)
decode_error(str, j, "unsupported utf-16 surrogate pair in string") decode_error(str, j, "unsupported utf-16 surrogate pair in string")
end end
has_unicode_escape = true has_unicode_escape = true
else
has_escape = true
end end
if not escape_chars[x] then if not escape_chars[x] then
decode_error(str, j, "invalid escape char '" .. x .. "' in string") decode_error(str, j, "invalid escape char '" .. x .. "' in string")
end end
elseif x == '"' then elseif x == '"' then
local s = str:sub(i, j) local s = str:sub(i + 1, j - 1)
if has_unicode_escape then if has_unicode_escape then
s = s:gsub("\\u....", parse_unicode_escape) s = s:gsub("\\u....", parse_unicode_escape)
end end
return loadstring( "return " .. s )(), j + 1 if has_escape then
s = s:gsub("\\.", escape_char_map_inv)
end
return s, j + 1
end end
last = x last = x
end end