The following little snippet allows you to ‘pickle’ Lua objects directly into Lua code (with the exception of functions, which are serialized as raw bytecode). Metatable support is on the way, but for now, it should be useful enough.
Example code:
01.
dofile
"pickle.lua"
02.
03.
users
=
{
04.
user1
=
{
pass
=
"abcdef"
,
start
=
10230
}
,
05.
user2
=
{
pass
=
"cdefba"
,
start
=
12032
}
06.
}
07.
08.
userdump
=
pickle
.
dumps
(
users
)
09.
print
(
userdump
)
Outputs
01.
return
{
02.
[
"user1"
]
=
{
03.
[
"pass"
]
=
"abcdef"
,
04.
[
"start"
]
=
10230
,
05.
}
,
06.
[
"user2"
]
=
{
07.
[
"pass"
]
=
"cdefba"
,
08.
[
"start"
]
=
12032
,
09.
}
,
10.
}
Pickle API:
- pickle.dumps(object) -> String
Pickles an object and returns it.
- pickle.dump(object, filename) -> String
Pickles an object and saves it as :filename, afterwards, returns the dump.
- pickle.loads(object) -> Lua Object
Loads a string dump of lua object and returns the object. The returned object will not injected into the global table.
- pickle.load(filename) -> Lua Object
Loads a pickled object from a file and returns it. The returned object will not be injected into the global table.
Full Source:
01.
local
objects
=
{
}
02.
setmetatable
(
objects
,
{
__index
=
{
[
"subset"
]
=
function
(
object
,
proxies
)
03.
for
_
,
o in
ipairs
(
proxies
)
do
04.
if
object
=
=
o
then
return
true
end
05.
end
06.
end
}
}
)
07.
08.
function
_pickle
(
object
,
seen
,
indent
)
09.
-
--if not seen then seen = {} end
10.
if
not
indent
then
indent
=
""
end
11.
12.
local
serialize_key
=
function
(
key
)
13.
if
type
(
key
)
=
=
"string"
then
14.
return
"[\""
..
key
..
"\"]"
15.
elseif
type
(
key
)
=
=
"table"
then
16.
return
"["
..
_pickle
(
key
)
:gsub
(
"\n"
,
" "
)
..
"]"
17.
else
18.
return
"["
..
key
..
"]"
19.
end
20.
return
key
21.
end
22.
23.
local
escape
=
function
(
o
)
24.
return
o:gsub
(
"\\","
\\\\
"):gsub("
'","\\'"):gsub('
"
','
\\"'
)
25.
end
26.
27.
-
--Switch Object type:
28.
if
type
(
object
)
=
=
"table"
then
29.
local
serialize
=
"{\n"
30.
for
key
,
value in pairs
(
object
)
do
31.
serialize
=
serialize
..
indent
..
"\t"
..
serialize_key
(
key
)
..
" = "
..
tostring
(
_pickle
(
value
,
seen
,
indent
..
"\t"
)
)
..
",\n"
32.
end
33.
serialize
=
serialize
..
indent
..
"}"
34.
35.
return
serialize
36.
elseif
type
(
object
)
=
=
"string"
then
37.
return
'"'
..
escape
(
object
)
..
'"'
38.
elseif
type
(
object
)
=
=
"function"
then
39.
return
"loadstring([["
..
string.dump
(
object
)
..
"]])"
40.
elseif
objects
.
subset
(
object
,
{
"userdata"
}
)
then
41.
return
nil
42.
end
43.
return
tostring
(
object
)
44.
end
45.
46.
pickle
=
{
}
47.
48.
function
pickle
.
dumps
(
object
)
49.
return
"return "
..
_pickle
(
object
)
50.
end
51.
52.
function
pickle
.
dump
(
object
,
filename
)
53.
local
dump
=
pickle
.
dumps
(
object
)
54.
local
_file
=
io.open
(
filename
,
"wb"
)
55.
_file:write
(
dump
)
56.
_file:close
(
)
57.
return
dump
58.
end
59.
60.
function
pickle
.
loads
(
object
)
61.
local
fn
=
loadstring
(
object
)
62.
if
fn
then
63.
return
fn
(
)
64.
end
65.
end
66.
67.
function
pickle
.
load
(
filename
)
68.
local
_file
=
io.open
(
filename
,
"rb"
)
69.
local
dump
=
_file:read
(
"*all"
)
70.
local
object
=
pickle
.
loads
(
dump
)
71.
_file:close
(
)
72.
return
object
73.
end