libs/json: add proper support for decoding unicode escapes
This commit is contained in:
parent
e97596f42d
commit
297d368ecc
1 changed files with 82 additions and 48 deletions
|
@ -39,6 +39,7 @@ Encoder:
|
|||
luci.ltn12.pump.all(encoder:source(), luci.ltn12.sink.file(io.open("someFile", w)))
|
||||
]]--
|
||||
|
||||
local nixio = require "nixio"
|
||||
local util = require "luci.util"
|
||||
local table = require "table"
|
||||
local string = require "string"
|
||||
|
@ -54,6 +55,11 @@ local ipairs = ipairs
|
|||
local next = next
|
||||
local pcall = pcall
|
||||
|
||||
local band = nixio.bit.band
|
||||
local bor = nixio.bit.bor
|
||||
local rshift = nixio.bit.rshift
|
||||
local char = string.char
|
||||
|
||||
local getmetatable = getmetatable
|
||||
|
||||
--- LuCI JSON-Library
|
||||
|
@ -412,6 +418,35 @@ function Decoder.parse_string(self, chunk)
|
|||
end
|
||||
|
||||
|
||||
function Decoder.utf8_encode(self, s1, s2)
|
||||
local n = s1 * 256 + s2
|
||||
|
||||
if n >= 0 and n <= 0x7F then
|
||||
return char(n)
|
||||
elseif n >= 0 and n <= 0x7FF then
|
||||
return char(
|
||||
bor(band(rshift(n, 6), 0x1F), 0xC0),
|
||||
bor(band(n, 0x3F), 0x80)
|
||||
)
|
||||
elseif n >= 0 and n <= 0xFFFF then
|
||||
return char(
|
||||
bor(band(rshift(n, 12), 0x0F), 0xE0),
|
||||
bor(band(rshift(n, 6), 0x3F), 0x80),
|
||||
bor(band(n, 0x3F), 0x80)
|
||||
)
|
||||
elseif n >= 0 and n <= 0x10FFFF then
|
||||
return char(
|
||||
bor(band(rshift(n, 18), 0x07), 0xF0),
|
||||
bor(band(rshift(n, 12), 0x3F), 0x80),
|
||||
bor(band(rshift(n, 6), 0x3F), 0x80),
|
||||
bor(band(n, 0x3F), 0x80)
|
||||
)
|
||||
else
|
||||
return "?"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Decoder.parse_escape(self, chunk)
|
||||
local str = ""
|
||||
chunk = self:fetch_atleast(chunk:sub(2), 1)
|
||||
|
@ -428,8 +463,7 @@ function Decoder.parse_escape(self, chunk)
|
|||
s1, s2 = tonumber(s1, 16), tonumber(s2, 16)
|
||||
assert(s1 and s2, "Invalid Unicode character")
|
||||
|
||||
-- ToDo: Unicode support
|
||||
return chunk:sub(5), s1 == 0 and string.char(s2) or ""
|
||||
return chunk:sub(5), self:utf8_encode(s1, s2)
|
||||
elseif char == "/" then
|
||||
return chunk, "/"
|
||||
elseif char == "b" then
|
||||
|
|
Loading…
Reference in a new issue