data_struct.lua 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. --[[
  2. SaferLua [safer_lua]
  3. ====================
  4. Copyright (C) 2017-2020 Joachim Stolberg
  5. AGPL v3
  6. See LICENSE.txt for more information
  7. data_struct.lua:
  8. see https://github.com/joe7575/techpack/wiki/Data-Structures
  9. ]]--
  10. safer_lua.DataStructHelp = [[
  11. Data structures as a secure shell over the LUA table type.
  12. see https://github.com/joe7575/techpack/wiki/Data-Structures
  13. 'Arrays' are lists of elements, which can be addressed
  14. by means of an index:
  15. a = Array(1,2,3,4) --> {1,2,3,4}
  16. a.add(6) --> {1,2,3,4,6}
  17. a.set(2, 8) --> {1,8,3,4,6}
  18. a.insert(5,7) --> {1,8,3,4,7,6}
  19. a.remove(3) --> {1,8,4,7,6}
  20. a.insert(1, "hello") --> {"hello",1,8,4,7,6}
  21. a.size() --> function returns 6
  22. a.memsize() --> return returns 10
  23. a.next() --> for loop iterator function
  24. a.sort(reverse) --> sort the array elements in place
  25. Unlike arrays, which are indexed by a range of numbers,
  26. 'stores' are indexed by keys:
  27. s = Store("a",4,"b",5) --> {a = 4, b = 5}
  28. s.set("val", 12) --> {a = 4, b = 5, val = 12}
  29. s.get("val") --> returns 12
  30. s.set(0, "hello") --> {a = 4, b = 5, val = 12, [0] = "hello"}
  31. s.del("val") --> {[0] = "hello"}
  32. s.size() --> function returns 4
  33. s.memsize() --> function returns 8
  34. s.next() --> for loop iterator function
  35. s.keys(order) --> return an array with the keys
  36. A 'set' is an unordered collection with no duplicate
  37. elements.
  38. s = Set("Tom", "Lucy")
  39. --> {Tom = true, Lucy = true}
  40. s.del("Tom") --> {Lucy = true}
  41. s.add("Susi") --> {Lucy = true, Susi = true}
  42. s.has("Susi") --> function returns `true`
  43. s.has("Mike") --> function returns `false`
  44. s.size() --> function returns 2
  45. s.memsize() --> function returns 8
  46. s.next() --> for loop iterator function
  47. ]]
  48. local function var_count(v)
  49. if type(v) == "number" then
  50. return 1
  51. elseif type(v) == "boolean" then
  52. return 1
  53. elseif v == nil then
  54. return 0
  55. elseif type(v) == "string" then
  56. return #v
  57. elseif type(v) == "table" then
  58. return v.memsize()
  59. else
  60. return nil
  61. end
  62. end
  63. function safer_lua.Store(...)
  64. local new_t = {}
  65. local mt = {}
  66. local MemSize = 0
  67. local Size = 0
  68. local Data = {}
  69. mt.__newindex = function(t, k, v) return end
  70. mt.count = var_count
  71. new_t.set = function(k,v)
  72. if type(k) == "number" then
  73. if rawget(Data, k) then -- has entry?
  74. MemSize = MemSize - mt.count(rawget(Data, k))
  75. else
  76. Size = Size + 1
  77. end
  78. MemSize = MemSize + mt.count(v)
  79. rawset(Data, k, v)
  80. elseif type(k) == "string" then
  81. if rawget(Data, k) then -- has entry?
  82. MemSize = MemSize - mt.count(rawget(Data, k))
  83. else
  84. MemSize = MemSize + mt.count(k)
  85. Size = Size + 1
  86. end
  87. MemSize = MemSize + mt.count(v)
  88. rawset(Data, k, v)
  89. end
  90. end
  91. new_t.get = function(k)
  92. return rawget(Data, k)
  93. end
  94. new_t.del = function(k)
  95. if rawget(Data, k) then -- has entry?
  96. MemSize = MemSize - mt.count(k)
  97. MemSize = MemSize - mt.count(rawget(Data, k))
  98. rawset(Data, k, nil)
  99. Size = Size - 1
  100. end
  101. end
  102. new_t.memsize = function(t)
  103. return MemSize
  104. end
  105. new_t.size = function(t)
  106. return Size
  107. end
  108. new_t.next = function(t)
  109. local n = nil
  110. return function ()
  111. n = next(Data, n)
  112. if n then return n, Data[n] end
  113. end
  114. end
  115. new_t.keys = function(order)
  116. local keyset = {}
  117. local n = 0
  118. local size = 0
  119. for k,v in pairs(Data) do
  120. n = n + 1
  121. keyset[n] = k
  122. size = size + var_count(k)
  123. end
  124. if order == "up" then
  125. table.sort(keyset, function(a,b) return a > b end)
  126. elseif order == "down" then
  127. table.sort(keyset)
  128. end
  129. local a = safer_lua.Array()
  130. a.__load(size, keyset)
  131. return a
  132. end
  133. new_t.__dump = function()
  134. -- remove the not serializable meta data
  135. return {Type = "Store", Size = Size, MemSize = MemSize, Data = Data}
  136. end
  137. new_t.__load = function(size, memsize, data)
  138. Size = size
  139. MemSize = memsize
  140. Data = data
  141. end
  142. for idx = 1,select('#',...),2 do
  143. local k,v = select(idx,...),select(idx+1,...)
  144. new_t.set(k,v)
  145. end
  146. return setmetatable(new_t, mt)
  147. end
  148. function safer_lua.Array(...)
  149. local new_t = {}
  150. local mt = {}
  151. local MemSize = 0
  152. local Data = {}
  153. mt.__newindex = function(t, k, v) return end
  154. mt.count = var_count
  155. for idx = 1,select('#',...) do
  156. local v = select(idx,...)
  157. local cnt = mt.count(v)
  158. if cnt then
  159. MemSize = MemSize + cnt
  160. rawset(Data, idx, v)
  161. end
  162. end
  163. new_t.add = function(v)
  164. MemSize = MemSize + mt.count(v)
  165. local i = #Data + 1
  166. table.insert(Data, i, v)
  167. end
  168. new_t.set = function(i,v)
  169. i = math.min(#Data, i)
  170. MemSize = MemSize - mt.count(rawget(Data, i))
  171. MemSize = MemSize + mt.count(v)
  172. rawset(Data, i, v)
  173. end
  174. new_t.get = function(i)
  175. return Data[i]
  176. end
  177. new_t.insert = function(i, v)
  178. MemSize = MemSize + mt.count(v)
  179. i = math.min(#Data, i)
  180. table.insert(Data, i, v)
  181. end
  182. new_t.remove = function(i)
  183. local v = table.remove(Data, i)
  184. MemSize = MemSize - mt.count(v)
  185. return v
  186. end
  187. new_t.sort = function(reverse)
  188. if reverse then
  189. table.sort(Data, function(a,b) return a > b end)
  190. else
  191. table.sort(Data)
  192. end
  193. end
  194. new_t.memsize = function(t)
  195. return MemSize
  196. end
  197. new_t.size = function(t)
  198. return #Data
  199. end
  200. new_t.next = function(t)
  201. local i = 0
  202. local n = #Data
  203. return function ()
  204. i = i + 1
  205. if i <= n then return i, Data[i] end
  206. end
  207. end
  208. new_t.__dump = function()
  209. -- remove the not serializable meta data
  210. return {Type = "Array", MemSize = MemSize, Data = Data}
  211. end
  212. new_t.__load = function(memsize, data)
  213. MemSize = memsize
  214. Data = data
  215. end
  216. return setmetatable(new_t, mt)
  217. end
  218. function safer_lua.Set(...)
  219. local new_t = {}
  220. local mt = {}
  221. local MemSize = 0
  222. local Size = 0
  223. local Data = {}
  224. mt.__newindex = function(t, k, v) return end
  225. mt.count = var_count
  226. for idx = 1,select('#',...) do
  227. local v = select(idx,...)
  228. local cnt = mt.count(v)
  229. if cnt then
  230. MemSize = MemSize + cnt
  231. Size = Size + 1
  232. rawset(Data, v, true)
  233. end
  234. end
  235. new_t.add = function(k)
  236. MemSize = MemSize + mt.count(k)
  237. rawset(Data, k, true)
  238. Size = Size + 1
  239. end
  240. new_t.del = function(k)
  241. MemSize = MemSize - mt.count(k)
  242. rawset(Data, k, nil)
  243. Size = Size - 1
  244. end
  245. new_t.has = function(k)
  246. return rawget(Data, k) == true
  247. end
  248. new_t.memsize = function(t)
  249. return MemSize
  250. end
  251. new_t.size = function(t)
  252. return Size
  253. end
  254. new_t.next = function(t)
  255. local i = 0
  256. local n = nil
  257. return function ()
  258. i = i + 1
  259. n = next(Data, n)
  260. if n then return i, n end
  261. end
  262. end
  263. new_t.__dump = function()
  264. -- remove the not serializable meta data
  265. return {Type = "Set", Size = Size, MemSize = MemSize, Data = Data}
  266. end
  267. new_t.__load = function(size, memsize, data)
  268. Size = size
  269. MemSize = memsize
  270. Data = data
  271. end
  272. return setmetatable(new_t, mt)
  273. end
  274. -- remove the not serializable meta data
  275. function safer_lua.datastruct_to_table(ds)
  276. return ds.__dump()
  277. end
  278. -- add the not serializable meta data again
  279. function safer_lua.table_to_datastruct(tbl)
  280. if tbl.Type == "Store" then
  281. local s = safer_lua.Store()
  282. s.__load(tbl.Size, tbl.MemSize, tbl.Data)
  283. return s
  284. elseif tbl.Type == "Set" then
  285. local s = safer_lua.Set()
  286. s.__load(tbl.Size, tbl.MemSize, tbl.Data)
  287. return s
  288. elseif tbl.Type == "Array" then
  289. local a = safer_lua.Array()
  290. a.__load(tbl.MemSize, tbl.Data)
  291. return a
  292. end
  293. end