mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-04 03:48:46 -05:00
* Added scripts dependencies * Added script to generate scripts package automatically * Added integration with PureOS CMake * [MOS-804] Created factory reset script
186 lines
3.4 KiB
Lua
186 lines
3.4 KiB
Lua
local error = error
|
|
local byte, find, format, gsub, match = string.byte, string.find, string.format, string.gsub, string.match
|
|
local concat = table.concat
|
|
local tostring = tostring
|
|
local pairs, type = pairs, type
|
|
local setmetatable = setmetatable
|
|
local huge, tiny = 1/0, -1/0
|
|
|
|
local f_string_esc_pat
|
|
if _VERSION == "Lua 5.1" then
|
|
-- use the cluttered pattern because lua 5.1 does not handle \0 in a pattern correctly
|
|
f_string_esc_pat = '[^ -!#-[%]^-\255]'
|
|
else
|
|
f_string_esc_pat = '[\0-\31"\\]'
|
|
end
|
|
|
|
local _ENV = nil
|
|
|
|
|
|
local function newencoder()
|
|
local v, nullv
|
|
local i, builder, visited
|
|
|
|
local function f_tostring(v)
|
|
builder[i] = tostring(v)
|
|
i = i+1
|
|
end
|
|
|
|
local radixmark = match(tostring(0.5), '[^0-9]')
|
|
local delimmark = match(tostring(12345.12345), '[^0-9' .. radixmark .. ']')
|
|
if radixmark == '.' then
|
|
radixmark = nil
|
|
end
|
|
|
|
local radixordelim
|
|
if radixmark or delimmark then
|
|
radixordelim = true
|
|
if radixmark and find(radixmark, '%W') then
|
|
radixmark = '%' .. radixmark
|
|
end
|
|
if delimmark and find(delimmark, '%W') then
|
|
delimmark = '%' .. delimmark
|
|
end
|
|
end
|
|
|
|
local f_number = function(n)
|
|
if tiny < n and n < huge then
|
|
local s = format("%.17g", n)
|
|
if radixordelim then
|
|
if delimmark then
|
|
s = gsub(s, delimmark, '')
|
|
end
|
|
if radixmark then
|
|
s = gsub(s, radixmark, '.')
|
|
end
|
|
end
|
|
builder[i] = s
|
|
i = i+1
|
|
return
|
|
end
|
|
error('invalid number')
|
|
end
|
|
|
|
local doencode
|
|
|
|
local f_string_subst = {
|
|
['"'] = '\\"',
|
|
['\\'] = '\\\\',
|
|
['\b'] = '\\b',
|
|
['\f'] = '\\f',
|
|
['\n'] = '\\n',
|
|
['\r'] = '\\r',
|
|
['\t'] = '\\t',
|
|
__index = function(_, c)
|
|
return format('\\u00%02X', byte(c))
|
|
end
|
|
}
|
|
setmetatable(f_string_subst, f_string_subst)
|
|
|
|
local function f_string(s)
|
|
builder[i] = '"'
|
|
if find(s, f_string_esc_pat) then
|
|
s = gsub(s, f_string_esc_pat, f_string_subst)
|
|
end
|
|
builder[i+1] = s
|
|
builder[i+2] = '"'
|
|
i = i+3
|
|
end
|
|
|
|
local function f_table(o)
|
|
if visited[o] then
|
|
error("loop detected")
|
|
end
|
|
visited[o] = true
|
|
|
|
local tmp = o[0]
|
|
if type(tmp) == 'number' then -- arraylen available
|
|
builder[i] = '['
|
|
i = i+1
|
|
for j = 1, tmp do
|
|
doencode(o[j])
|
|
builder[i] = ','
|
|
i = i+1
|
|
end
|
|
if tmp > 0 then
|
|
i = i-1
|
|
end
|
|
builder[i] = ']'
|
|
|
|
else
|
|
tmp = o[1]
|
|
if tmp ~= nil then -- detected as array
|
|
builder[i] = '['
|
|
i = i+1
|
|
local j = 2
|
|
repeat
|
|
doencode(tmp)
|
|
tmp = o[j]
|
|
if tmp == nil then
|
|
break
|
|
end
|
|
j = j+1
|
|
builder[i] = ','
|
|
i = i+1
|
|
until false
|
|
builder[i] = ']'
|
|
|
|
else -- detected as object
|
|
builder[i] = '{'
|
|
i = i+1
|
|
local tmp = i
|
|
for k, v in pairs(o) do
|
|
if type(k) ~= 'string' then
|
|
error("non-string key")
|
|
end
|
|
f_string(k)
|
|
builder[i] = ':'
|
|
i = i+1
|
|
doencode(v)
|
|
builder[i] = ','
|
|
i = i+1
|
|
end
|
|
if i > tmp then
|
|
i = i-1
|
|
end
|
|
builder[i] = '}'
|
|
end
|
|
end
|
|
|
|
i = i+1
|
|
visited[o] = nil
|
|
end
|
|
|
|
local dispatcher = {
|
|
boolean = f_tostring,
|
|
number = f_number,
|
|
string = f_string,
|
|
table = f_table,
|
|
__index = function()
|
|
error("invalid type value")
|
|
end
|
|
}
|
|
setmetatable(dispatcher, dispatcher)
|
|
|
|
function doencode(v)
|
|
if v == nullv then
|
|
builder[i] = 'null'
|
|
i = i+1
|
|
return
|
|
end
|
|
return dispatcher[type(v)](v)
|
|
end
|
|
|
|
local function encode(v_, nullv_)
|
|
v, nullv = v_, nullv_
|
|
i, builder, visited = 1, {}, {}
|
|
|
|
doencode(v)
|
|
return concat(builder)
|
|
end
|
|
|
|
return encode
|
|
end
|
|
|
|
return newencoder
|