Operating system for OpenComputers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
2.0KB

  1. local serial = {}
  2. local local_pairs=function(tbl)
  3. local mt=getmetatable(tbl)
  4. return (mt and mt.__pairs or pairs)(tbl)
  5. end
  6. function serial.serialize(value,af) -- boolean -- string -- serialize *value* into a string. If *af* is true, allow functions. This breaks unserialization.
  7. 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}
  8. local id="^[%a_][%w_]*$"
  9. local ts={}
  10. local function s(v,l)
  11. local t=type(v)
  12. if t=="nil" then return "nil"
  13. elseif t=="boolean" then return v and "true" or "false"
  14. elseif t=="number" then
  15. if v~=v then return "0/0"
  16. elseif v==math.huge then return "math.huge"
  17. elseif v==-math.huge then return "-math.huge"
  18. else return tostring(v) end
  19. elseif t=="string" then return string.format("%q",v):gsub("\\\n","\\n")
  20. elseif t=="table" then
  21. if ts[v] then error("tcyc") end
  22. ts[v]=true
  23. local i,r=1, nil
  24. local f=table.pack(local_pairs(v))
  25. for k,v in table.unpack(f) do
  26. if r then r=r..","..(("\n"..string.rep(" ",l)) or "")
  27. else r="{" end
  28. local tk=type(k)
  29. if tk=="number" and k==i then
  30. i=i+1
  31. r=r..s(v,l+1)
  32. else
  33. if tk == "string" and not kw[k] and string.match(k,id) then r=r..k
  34. else r=r.."["..s(k,l+1).."]" end
  35. r=r.."="..s(v,l+1) end end
  36. ts[v]=nil
  37. return (r or "{").."}"
  38. elseif t=="function" and af then
  39. return tostring(v)
  40. else error("ut "..t) end end
  41. return s(value, 1)
  42. end
  43. function serial.unserialize(data) -- string -- -- return *data*, but unserialized
  44. checkArg(1, data, "string")
  45. local result, reason = load("return " .. data, "=data", _, {math={huge=math.huge}})
  46. if not result then return nil, reason end
  47. local ok, output = pcall(result)
  48. if not ok then return nil, output end
  49. return output
  50. end
  51. return serial