/serialize.lua

http://timprojectenchanter.googlecode.com/ · Lua · 113 lines · 82 code · 7 blank · 24 comment · 33 complexity · 4640ea608df9e55ae90ff0fee25846a9 MD5 · raw file

  1. ----------------------------------------------------------------------------
  2. -- Serialize tables.
  3. -- It works only for tables without cycles and without functions or
  4. -- userdata inside it.
  5. -- @release $Id: serialize.lua 34 2010-04-19 21:18:00Z rpusztai $
  6. ----------------------------------------------------------------------------
  7. local ipairs, pairs, type = ipairs, pairs, type
  8. local format = string.format
  9. local sort, tinsert = table.sort, table.insert
  10. --
  11. local value = nil
  12. ----------------------------------------------------------------------------
  13. -- Serializes a table.
  14. -- @param tab Table representing the session.
  15. -- @param outf Function used to generate the output.
  16. -- @param ind String with indentation pattern (default = "").
  17. -- @param pre String with indentation prefix (default = "").
  18. ----------------------------------------------------------------------------
  19. local function tabledump (tab, outf, ind, pre)
  20. local sep_n, sep, _n = ",\n", ", ", "\n"
  21. if (not ind) or (ind == "") then ind = ""; sep_n = ", "; _n = "" end
  22. if not pre then pre = "" end
  23. outf ("{")
  24. local p = pre..ind
  25. -- prepare list of keys
  26. local keys = { boolean = {}, number = {}, string = {} }
  27. local total = 0
  28. for key in pairs (tab) do
  29. total = total + 1
  30. local t = type(key)
  31. if t == "string" then
  32. tinsert (keys.string, key)
  33. else
  34. keys[t][key] = true
  35. end
  36. end
  37. local many = total > 5
  38. if not many then sep_n = sep; _n = " " end
  39. outf (_n)
  40. -- serialize entries with numeric keys
  41. if many then
  42. local _f,_s,_v = ipairs(tab)
  43. if _f(_s,_v) then outf (p) end
  44. end
  45. local num = keys.number
  46. local ok = false
  47. -- entries with automatic index
  48. for key, val in ipairs (tab) do
  49. value (val, outf, ind, p)
  50. outf (sep)
  51. num[key] = nil
  52. ok = true
  53. end
  54. if ok and many then outf (_n) end
  55. -- entries with explicit index
  56. for key in pairs (num) do
  57. if many then outf (p) end
  58. outf ("[")
  59. outf (key)
  60. outf ("] = ")
  61. value (tab[key], outf, ind, p)
  62. outf (sep_n)
  63. end
  64. -- serialize entries with boolean keys
  65. local tr = keys.boolean[true]
  66. if tr then
  67. outf (format ("%s[true] = ", many and p or ''))
  68. value (tab[true], outf, ind, p)
  69. outf (sep_n)
  70. end
  71. local fa = keys.boolean[false]
  72. if fa then
  73. outf (format ("%s[false] = ", many and p or ''))
  74. value (tab[false], outf, ind, p)
  75. outf (sep_n)
  76. end
  77. -- serialize entries with string keys
  78. sort (keys.string)
  79. for _, key in ipairs (keys.string) do
  80. outf (format ("%s[%q] = ", many and p or '', key))
  81. value (tab[key], outf, ind, p)
  82. outf (sep_n)
  83. end
  84. if many then outf (pre) end
  85. outf ("}")
  86. end
  87. --
  88. -- Serializes a value.
  89. --
  90. value = function (v, outf, ind, pre)
  91. local t = type (v)
  92. if t == "string" then
  93. outf (format ("%q", v))
  94. elseif t == "number" then
  95. outf (tostring(v))
  96. elseif t == "boolean" then
  97. outf (tostring(v))
  98. elseif t == "table" then
  99. tabledump (v, outf, ind, pre)
  100. else
  101. outf (format ("%q", tostring(v)))
  102. end
  103. end
  104. ----------------------------------------------------------------------------
  105. serialize = tabledump
  106. return tabledump