1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
----------------------------------------------
-- Pickle.lua
-- An table serialization utility for lua 5
-- Steve Dekorte, http://www.dekorte.com, April 2000
-- Public Domain
-- Lua 5.0 update by Daan Nusman July 2003
----------------------------------------------
function pickle(t)
return Pickle:clone():pickle_(t)
end
Pickle = {
clone = function (t) local nt={}; for i, v in pairs(t) do nt[i]=v end return nt end
}
function Pickle:pickle_(root)
if type(root) ~= "table" then
error("can only pickle tables, not ".. type(root).."s")
end
self._tableToRef = {}
self._refToTable = {}
local savecount = 0
self:ref_(root)
local s = ""
while table.getn(self._refToTable) > savecount do
savecount = savecount + 1
local t = self._refToTable[savecount]
s = s.."{\n"
for i, v in pairs(t) do
if type(v) ~= "function" then
s = string.format("%s[%s]=%s,\n", s, self:value_(i), self:value_(v))
end
end
s = s.."},\n"
end
return string.format("{%s}", s)
end
function Pickle:value_(v)
local vtype = type(v)
if vtype == "string" then return string.format("%q", v)
elseif vtype == "number" then return v
elseif vtype == "boolean" then return tostring(v)
elseif vtype == "table" then return "{"..self:ref_(v).."}"
else error("pickle a "..type(v).." is not supported")
end
end
function Pickle:ref_(t)
local ref = self._tableToRef[t]
if not ref then
if t == self then error("can't pickle the pickle class") end
table.insert(self._refToTable, t)
ref = table.getn(self._refToTable)
self._tableToRef[t] = ref
end
return ref
end
----------------------------------------------
-- unpickle
----------------------------------------------
function unpickle_string(s)
if type(s) ~= "string" then
error("can't unpickle a "..type(s)..", only strings")
end
local tables = loadstring("return "..s)()
return unpickle_table(tables)
end
function unpickle_table(tables)
if type(tables) ~= "table" then
error("can't unpickle a "..type(tables)..", only tables")
end
for tnum = 1, table.getn(tables) do
local t = tables[tnum]
local tcopy = {}; for i, v in t do tcopy[i] = v end
for i, v in pairs(tcopy) do
local ni, nv
if type(i) == "table" then ni = tables[i[1]] else ni = i end
if type(v) == "table" then nv = tables[v[1]] else nv = v end
t[ni] = nv
end
end
return tables[1]
end
|