forked from izaya/OC-PsychOS2
corrected spelling in the serialization lib oops
This commit is contained in:
parent
80eea7142d
commit
37df78ffed
@ -1,145 +1,49 @@
|
|||||||
-- serialization lib borrowed from OpenOS
|
local serial = {}
|
||||||
local serialization = {}
|
local local_pairs=function(tbl)
|
||||||
|
local mt=getmetatable(tbl)
|
||||||
-- delay loaded tables fail to deserialize cross [C] boundaries (such as when having to read files that cause yields)
|
|
||||||
local local_pairs = function(tbl)
|
|
||||||
local mt = getmetatable(tbl)
|
|
||||||
return (mt and mt.__pairs or pairs)(tbl)
|
return (mt and mt.__pairs or pairs)(tbl)
|
||||||
end
|
end
|
||||||
|
function serial.serialize(value)
|
||||||
-- Important: pretty formatting will allow presenting non-serializable values
|
local kw={["and"]=true,["break"]=true,["do"]=true,["else"]=true,["elseif"]=true,["end"]=true,["false"]=true,["for"]=true,["function"]=true,["goto"]=true,["if"]=true,["in"]=true,["local"]=true,["nil"]=true,["not"]=true,["or"]=true,["repeat"]=true,["return"]=true,["then"]=true,["true"]=true,["until"]=true,["while"]=true}
|
||||||
-- but may generate output that cannot be unserialized back.
|
local id="^[%a_][%w_]*$"
|
||||||
function serialization.serialize(value, pretty) -- serialize *value* into a string, optionally in a nicely formatted manner when *pretty* is set
|
local ts={}
|
||||||
local kw = {["and"]=true, ["break"]=true, ["do"]=true, ["else"]=true,
|
local function s(v,l)
|
||||||
["elseif"]=true, ["end"]=true, ["false"]=true, ["for"]=true,
|
local t=type(v)
|
||||||
["function"]=true, ["goto"]=true, ["if"]=true, ["in"]=true,
|
if t=="nil" then return "nil"
|
||||||
["local"]=true, ["nil"]=true, ["not"]=true, ["or"]=true,
|
elseif t=="boolean" then return v and "true" or "false"
|
||||||
["repeat"]=true, ["return"]=true, ["then"]=true, ["true"]=true,
|
elseif t=="number" then
|
||||||
["until"]=true, ["while"]=true}
|
if v~=v then return "0/0"
|
||||||
local id = "^[%a_][%w_]*$"
|
elseif v==math.huge then return "math.huge"
|
||||||
local ts = {}
|
elseif v==-math.huge then return "-math.huge"
|
||||||
local result_pack = {}
|
else return tostring(v) end
|
||||||
local function recurse(current_value, depth)
|
elseif t=="string" then return string.format("%q",v):gsub("\\\n","\\n")
|
||||||
local t = type(current_value)
|
elseif t=="table" then
|
||||||
if t == "number" then
|
if ts[v] then error("tcyc") end
|
||||||
if current_value ~= current_value then
|
ts[v]=true
|
||||||
table.insert(result_pack, "0/0")
|
local i,r=1, nil
|
||||||
elseif current_value == math.huge then
|
local f=table.pack(local_pairs(v))
|
||||||
table.insert(result_pack, "math.huge")
|
for k,v in table.unpack(f) do
|
||||||
elseif current_value == -math.huge then
|
if r then r=r..","..(("\n"..string.rep(" ",l)) or "")
|
||||||
table.insert(result_pack, "-math.huge")
|
else r="{" end
|
||||||
|
local tk=type(k)
|
||||||
|
if tk=="number" and k==i then
|
||||||
|
i=i+1
|
||||||
|
r=r..s(v,l+1)
|
||||||
else
|
else
|
||||||
table.insert(result_pack, tostring(current_value))
|
if tk == "string" and not kw[k] and string.match(k,id) then r=r..k
|
||||||
end
|
else r=r.."["..s(k,l+1).."]" end
|
||||||
elseif t == "string" then
|
r=r.."="..s(v,l+1) end end
|
||||||
table.insert(result_pack, (string.format("%q", current_value):gsub("\\\n","\\n")))
|
ts[v]=nil
|
||||||
elseif
|
return (r or "{").."}"
|
||||||
t == "nil" or
|
else error("ut "..t) end end
|
||||||
t == "boolean" or
|
return s(value, 1)
|
||||||
pretty and (t ~= "table" or (getmetatable(current_value) or {}).__tostring) then
|
|
||||||
table.insert(result_pack, tostring(current_value))
|
|
||||||
elseif t == "table" then
|
|
||||||
if ts[current_value] then
|
|
||||||
if pretty then
|
|
||||||
table.insert(result_pack, "recursion")
|
|
||||||
return
|
|
||||||
else
|
|
||||||
error("tables with cycles are not supported")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ts[current_value] = true
|
|
||||||
local f
|
|
||||||
if pretty then
|
|
||||||
local ks, sks, oks = {}, {}, {}
|
|
||||||
for k in local_pairs(current_value) do
|
|
||||||
if type(k) == "number" then
|
|
||||||
table.insert(ks, k)
|
|
||||||
elseif type(k) == "string" then
|
|
||||||
table.insert(sks, k)
|
|
||||||
else
|
|
||||||
table.insert(oks, k)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.sort(ks)
|
|
||||||
table.sort(sks)
|
|
||||||
for _, k in ipairs(sks) do
|
|
||||||
table.insert(ks, k)
|
|
||||||
end
|
|
||||||
for _, k in ipairs(oks) do
|
|
||||||
table.insert(ks, k)
|
|
||||||
end
|
|
||||||
local n = 0
|
|
||||||
f = table.pack(function()
|
|
||||||
n = n + 1
|
|
||||||
local k = ks[n]
|
|
||||||
if k ~= nil then
|
|
||||||
return k, current_value[k]
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
f = table.pack(local_pairs(current_value))
|
|
||||||
end
|
|
||||||
local i = 1
|
|
||||||
local first = true
|
|
||||||
table.insert(result_pack, "{")
|
|
||||||
for k, v in table.unpack(f) do
|
|
||||||
if not first then
|
|
||||||
table.insert(result_pack, ",")
|
|
||||||
if pretty then
|
|
||||||
table.insert(result_pack, "\n" .. string.rep(" ", depth))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
first = nil
|
|
||||||
local tk = type(k)
|
|
||||||
if tk == "number" and k == i then
|
|
||||||
i = i + 1
|
|
||||||
recurse(v, depth + 1)
|
|
||||||
else
|
|
||||||
if tk == "string" and not kw[k] and string.match(k, id) then
|
|
||||||
table.insert(result_pack, k)
|
|
||||||
else
|
|
||||||
table.insert(result_pack, "[")
|
|
||||||
recurse(k, depth + 1)
|
|
||||||
table.insert(result_pack, "]")
|
|
||||||
end
|
|
||||||
table.insert(result_pack, "=")
|
|
||||||
recurse(v, depth + 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ts[current_value] = nil -- allow writing same table more than once
|
|
||||||
table.insert(result_pack, "}")
|
|
||||||
else
|
|
||||||
error("unsupported type: " .. t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
recurse(value, 1)
|
|
||||||
local result = table.concat(result_pack)
|
|
||||||
if pretty then
|
|
||||||
local limit = type(pretty) == "number" and pretty or 10
|
|
||||||
local truncate = 0
|
|
||||||
while limit > 0 and truncate do
|
|
||||||
truncate = string.find(result, "\n", truncate + 1, true)
|
|
||||||
limit = limit - 1
|
|
||||||
end
|
|
||||||
if truncate then
|
|
||||||
return result:sub(1, truncate) .. "..."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
function serial.unserialize(data)
|
||||||
function serialization.unserialize(data) -- returns the data contained in serialized string *data*
|
checkArg(1, data, "string")
|
||||||
local result, reason = load("return " .. data, "=data", nil, {math={huge=math.huge}})
|
local result, reason = load("return " .. data, "=data", _, {math={huge=math.huge}})
|
||||||
if not result then
|
if not result then return nil, reason end
|
||||||
return nil, reason
|
|
||||||
end
|
|
||||||
local ok, output = pcall(result)
|
local ok, output = pcall(result)
|
||||||
if not ok then
|
if not ok then return nil, output end
|
||||||
return nil, output
|
|
||||||
end
|
|
||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
|
return serial
|
||||||
return serialization
|
|
||||||
|
Loading…
Reference in New Issue
Block a user