1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
-- EFL LuaJIT bindings: Eina (iterator module)
-- For use with Elua
local ffi = require("ffi")
local C = ffi.C
ffi.cdef [[
typedef struct _Eina_Iterator Eina_Iterator;
typedef unsigned char Eina_Bool;
void eina_iterator_free (Eina_Iterator *iterator);
Eina_Bool eina_iterator_next (Eina_Iterator *iterator, void **data);
Eina_Bool eina_iterator_lock (Eina_Iterator *iterator);
Eina_Bool eina_iterator_unlock (Eina_Iterator *iterator);
void *eina_iterator_container_get(Eina_Iterator *iterator);
]]
local cutil = require("cutil")
local util = require("util")
local M = {}
local eina
local init = function()
eina = util.lib_load("eina")
end
local shutdown = function()
util.lib_unload("eina")
end
ffi.metatype("Eina_Iterator", {
__index = {
free = function(self) eina.eina_iterator_free(ffi.gc(self, nil)) end,
next = function(self)
local data = ffi.new("void*[1]")
local r = eina.eina_iterator_next(self, data)
if r == 0 then return nil end
return data[0]
end,
lock = function(self) return eina.eina_iterator_lock (self) ~= 0 end,
unlock = function(self) return eina.eina_iterator_unlock(self) ~= 0 end,
container_get = function(self)
local v = eina.eina_iterator_container_get(self)
if v == nil then return nil end
return v
end
}
})
cutil.init_module(init, shutdown)
local dgetmt = debug.getmetatable
M.Iterator = util.Readonly_Object:clone {
__ctor = function(self, selfmt, iter)
-- prevent null stuff
if iter == nil then iter = nil end
if iter then ffi.gc(iter, iter.free) end
selfmt.__eq = function(self, other)
return selfmt.__iterator == dgetmt(other).__iterator
end
selfmt.__call = function(self)
return self:next()
end
selfmt.__iterator = iter
end,
free = function(self)
self = dgetmt(self)
if not self.__iterator then return end
self.__iterator:free()
self.__iterator = nil
end,
next = function(self)
self = dgetmt(self)
if not self.__iterator then return nil end
return self.__iterator:next()
end,
lock = function(self)
self = dgetmt(self)
if not self.__iterator then return false end
return self.__iterator:lock()
end,
unlock = function(self)
self = dgetmt(self)
if not self.__iterator then return false end
return self.__iterator:unlock()
end,
container_get = function(self)
self = dgetmt(self)
if not self.__iterator then return nil end
return self.__iterator:container_get()
end,
to_array = function(self)
local ret = {}
for v in self do
ret[#ret + 1] = v
end
return ret
end
}
local Iterator = M.Iterator
M.Ptr_Iterator = Iterator:clone {
__ctor = function(self, selfmt, ptrtype, iter)
Iterator.__ctor(self, selfmt, iter)
selfmt.ptrtype = ptrtype
end,
next = function(self)
local v = Iterator.next(self)
if not v then return nil end
return ffi.cast(dgetmt(self).ptrtype, v)
end
}
M.String_Iterator = Iterator:clone {
next = function(self)
local v = Iterator.next(self)
if not v then return nil end
return ffi.string(v)
end
}
return M
|