2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
10 local t_insert = table.insert;
11 local unpack, pairs, next, type = unpack, pairs, next, type;
15 local function get(self, ...)
17 for n = 1,select('#', ...) do
18 t = t[select(n, ...)];
19 if not t then break; end
24 local function add(self, ...)
26 local count = select('#', ...);
28 local key = select(n, ...);
30 if not tab then tab = {}; t[key] = tab; end
33 t_insert(t, (select(count, ...)));
36 local function set(self, ...)
38 local count = select('#', ...);
40 local key = select(n, ...);
42 if not tab then tab = {}; t[key] = tab; end
45 t[(select(count-1, ...))] = (select(count, ...));
48 local function r(t, n, _end, ...)
49 if t == nil then return; end
50 local k = select(n, ...);
64 for _,b in pairs(t) do
73 local function remove(self, ...)
74 local _end = select('#', ...);
76 if select(n, ...) then _end = n; break; end
78 r(self.data, 1, _end, ...);
82 local function s(t, n, results, _end, ...)
83 if t == nil then return; end
84 local k = select(n, ...);
87 for _, v in pairs(t) do
91 t_insert(results, t[k]);
98 s(v, n+1, results, _end, ...);
101 for _,b in pairs(t) do
102 s(b, n+1, results, _end, ...);
107 -- Search for keys, nil == wildcard
108 local function search(self, ...)
109 local _end = select('#', ...);
111 if select(n, ...) then _end = n; break; end
114 s(self.data, 1, results, _end, ...);
118 -- Append results to an existing list
119 local function search_add(self, results, ...)
120 if not results then results = {}; end
121 local _end = select('#', ...);
123 if select(n, ...) then _end = n; break; end
125 s(self.data, 1, results, _end, ...);
129 function iter(self, ...)
130 local query = { ... };
131 local maxdepth = select("#", ...);
132 local stack = { self.data };
134 local function it(self)
135 local depth = #stack;
136 local key = next(stack[depth], keys[depth]);
137 if key == nil then -- Go up the stack
138 stack[depth], keys[depth] = nil, nil;
146 local value = stack[depth][key];
147 if query[depth] == nil or key == query[depth] then
148 if depth == maxdepth then -- Result
149 local result = {}; -- Collect keys forming path to result
153 result[depth+1] = value;
154 return unpack(result, 1, depth+1);
155 elseif type(value) == "table" then
156 t_insert(stack, value); -- Descend
172 search_add = search_add;