- --[[
- file name : table序列化和反序列化的问题.lua
- author : Clark/陈泽丹
- created : 2011-12-22
- 备注:
- 支持table的递归结构,但数据类型不支持function属性(因为function只是记录地址,在不同机器上序列化和反序列化后的地址相同没什么意义)
- 后记:
- 郁闷, 写完到网上一搜, 才发现原来Lua有提供一些现成的函数可用来做序列化和反序列化操作。。。
- 其中loadstring可以执行字符串。
- 通过
- lua = "return " .. lua
- local func = loadstring(lua)
- 即实现了反序列化。。。
- --]]
- ----------- 个人编写 -----------------
- --table转字符串(只取标准写法,以防止因系统的遍历次序导致ID乱序)
- function sz_T2S(_t)
- local szRet = "{"
- function doT2S(_i, _v)
- if "number" == type(_i) then
- szRet = szRet .. "[" .. _i .. "] = "
- if "number" == type(_v) then
- szRet = szRet .. _v .. ","
- elseif "string" == type(_v) then
- szRet = szRet .. '"' .. _v .. '"' .. ","
- elseif "table" == type(_v) then
- szRet = szRet .. sz_T2S(_v) .. ","
- else
- szRet = szRet .. "nil,"
- end
- elseif "string" == type(_i) then
- szRet = szRet .. '["' .. _i .. '"] = '
- if "number" == type(_v) then
- szRet = szRet .. _v .. ","
- elseif "string" == type(_v) then
- szRet = szRet .. '"' .. _v .. '"' .. ","
- elseif "table" == type(_v) then
- szRet = szRet .. sz_T2S(_v) .. ","
- else
- szRet = szRet .. "nil,"
- end
- end
- end
- table.foreach(_t, doT2S)
- szRet = szRet .. "}"
- return szRet
- end
- --字符串转table(反序列化,异常数据直接返回nil)
- function t_S2T(_szText)
- --栈
- function stack_newStack()
- local first = 1
- local last = 0
- local stack = {}
- local m_public = {}
- function m_public.pushBack(_tempObj)
- last = last + 1
- stack[last] = _tempObj
- end
- function m_public.temp_getBack()
- if m_public.bool_isEmpty() then
- return nil
- else
- local val = stack[last]
- return val
- end
- end
- function m_public.popBack()
- stack[last] = nil
- last = last - 1
- end
- function m_public.bool_isEmpty()
- if first > last then
- first = 1
- last = 0
- return true
- else
- return false
- end
- end
- function m_public.clear()
- while false == m_public.bool_isEmpty() do
- stack.popFront()
- end
- end
- return m_public
- end
- function getVal(_szVal)
- local s, e = string.find(_szVal,'"',1,string.len(_szVal))
- if nil ~= s and nil ~= e then
- --return _szVal
- return string.sub(_szVal,2,string.len(_szVal)-1)
- else
- return tonumber(_szVal)
- end
- end
- local m_szText = _szText
- local charTemp = string.sub(m_szText,1,1)
- if "{" == charTemp then
- m_szText = string.sub(m_szText,2,string.len(m_szText))
- end
- function doS2T()
- local tRet = {}
- local tTemp = nil
- local stackOperator = stack_newStack()
- local stackItem = stack_newStack()
- local val = ""
- while true do
- local dLen = string.len(m_szText)
- if dLen <= 0 then
- break
- end
- charTemp = string.sub(m_szText,1,1)
- if "[" == charTemp or "=" == charTemp then
- stackOperator.pushBack(charTemp)
- m_szText = string.sub(m_szText,2,dLen)
- elseif '"' == charTemp then
- local s, e = string.find(m_szText, '"', 2, dLen)
- if nil ~= s and nil ~= e then
- val = val .. string.sub(m_szText,1,s)
- m_szText = string.sub(m_szText,s+1,dLen)
- else
- return nil
- end
- elseif "]" == charTemp then
- if "[" == stackOperator.temp_getBack() then
- stackOperator.popBack()
- stackItem.pushBack(val)
- val = ""
- m_szText = string.sub(m_szText,2,dLen)
- else
- return nil
- end
- elseif "," == charTemp then
- if "=" == stackOperator.temp_getBack() then
- stackOperator.popBack()
- local Item = stackItem.temp_getBack()
- Item = getVal(Item)
- stackItem.popBack()
- if nil ~= tTemp then
- tRet[Item] = tTemp
- tTemp = nil
- else
- tRet[Item] = getVal(val)
- end
- val = ""
- m_szText = string.sub(m_szText,2,dLen)
- else
- return nil
- end
- elseif "{" == charTemp then
- m_szText = string.sub(m_szText,2,string.len(m_szText))
- local t = doS2T()
- if nil ~= t then
- szText = sz_T2S(t)
- tTemp = t
- --val = val .. szText
- else
- return nil
- end
- elseif "}" == charTemp then
- m_szText = string.sub(m_szText,2,string.len(m_szText))
- return tRet
- elseif " " ~= charTemp then
- val = val .. charTemp
- m_szText = string.sub(m_szText,2,dLen)
- else
- m_szText = string.sub(m_szText,2,dLen)
- end
- end
- return tRet
- end
- local t = doS2T()
- return t
- end
- --[[
- t = {1,2,3,"sdf", a = "df", qe = 3, {7}, qq = {{2,3,a={}}}, }
- t.f = {1,2,3}
- t.m = {3,4,5}
- szT = sz_T2S(t)
- print(szT)
- print("-----------")
- tq = t_S2T(szT)
- szT = sz_T2S(tq)
- print(szT)
- --]]
- -------- 网上资料 -------------------
- function serialize(obj)
- local lua = ""
- local t = type(obj)
- if t == "number" then
- lua = lua .. obj
- elseif t == "boolean" then
- lua = lua .. tostring(obj)
- elseif t == "string" then
- lua = lua .. string.format("%q", obj)
- elseif t == "table" then
- lua = lua .. "{\n"
- for k, v in pairs(obj) do
- lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
- end
- local metatable = getmetatable(obj)
- if metatable ~= nil and type(metatable.__index) == "table" then
- for k, v in pairs(metatable.__index) do
- lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
- end
- end
- lua = lua .. "}"
- elseif t == "nil" then
- return nil
- else
- error("can not serialize a " .. t .. " type.")
- end
- return lua
- end
- function unserialize(lua)
- local t = type(lua)
- if t == "nil" or lua == "" then
- return nil
- elseif t == "number" or t == "string" or t == "boolean" then
- lua = tostring(lua)
- else
- error("can not unserialize a " .. t .. " type.")
- end
- lua = "return " .. lua
- local func = loadstring(lua)
- if func == nil then
- return nil
- end
- return func()
- end
- data = {["a"] = "a", ["b"] = "b", [1] = 1, [2] = 2, ["t"] = {1, 2, 3}}
- local sz = serialize(data)
- print(sz)
- print("---------")
- print(serialize(unserialize(sz)))
http://blog.youkuaiyun.com/xiaodan007/article/details/7096718