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