summaryrefslogtreecommitdiff
path: root/src/bindings/lua/eina/xattr.lua
blob: bac2d85bd85c35fc0c3242ff1c80f89658d26012 (plain) (blame)
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
-- EFL LuaJIT bindings: Eina (xattr module)
-- For use with Elua

local ffi = require("ffi")
local C = ffi.C

local tonum = ffi.tonumber or tonumber

local iterator = require("eina.iterator")

ffi.cdef [[
    typedef unsigned char Eina_Bool;
    typedef ptrdiff_t ssize_t;

    typedef enum {
        EINA_XATTR_INSERT,
        EINA_XATTR_REPLACE,
        EINA_XATTR_CREATED
    } Eina_Xattr_Flags;

    typedef struct _Eina_Xattr Eina_Xattr;
    struct _Eina_Xattr {
        const char *name;
        const char *value;
        size_t length;
    };

    Eina_Iterator *eina_xattr_ls(const char *file);
    Eina_Iterator *eina_xattr_value_ls(const char *file);
    Eina_Iterator *eina_xattr_fd_ls(int fd);
    Eina_Iterator *eina_xattr_value_fd_ls(int fd);
    Eina_Bool eina_xattr_copy(const char *src, const char *dst);
    Eina_Bool eina_xattr_fd_copy(int src, int dst);
    void *eina_xattr_get(const char *file, const char *attribute, ssize_t *size);
    void *eina_xattr_fd_get(int fd, const char *attribute, ssize_t *size);
    Eina_Bool eina_xattr_set(const char *file, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags);
    Eina_Bool eina_xattr_fd_set(int fd, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags);
    Eina_Bool eina_xattr_del(const char *file, const char *attribute);
    Eina_Bool eina_xattr_fd_del(int fd, const char *attribute);
    Eina_Bool eina_xattr_string_set(const char *file, const char *attribute, const char *data, Eina_Xattr_Flags flags);
    char *eina_xattr_string_get(const char *file, const char *attribute);
    Eina_Bool eina_xattr_double_set(const char *file, const char *attribute, double value, Eina_Xattr_Flags flags);
    Eina_Bool eina_xattr_double_get(const char *file, const char *attribute, double *value);
    Eina_Bool eina_xattr_int_set(const char *file, const char *attribute, int value, Eina_Xattr_Flags flags);
    Eina_Bool eina_xattr_int_get(const char *file, const char *attribute, int *value);

    void free(void*);
]]

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

cutil.init_module(init, shutdown)

local Iterator = iterator.Iterator

local Name_Iterator = Iterator:clone {
    __ctor = function(self, selfmt, file)
        return Iterator.__ctor(self, selfmt, eina.eina_xattr_ls(file))
    end,
    next = function(self)
        local  v = Iterator.next(self)
        if not v then return nil end
        return ffi.string(v)
    end
}

M.ls = function(file) return Name_Iterator(file) end

local Value_Iterator = Iterator:clone {
    __ctor = function(self, selfmt, file)
        return Iterator.__ctor(self, selfmt, eina.eina_xattr_value_ls(file))
    end,
    next = function(self)
        local  v = Iterator.next(self)
        if not v then return nil end
        v = ffi.cast(v, "Eina_Xattr*")
        return ffi.string(v.name), ffi.string(v.value, v.length)
    end
}

M.value_ls = function(file) return Value_Iterator(file) end

M.copy = function(src, dst)
    return eina.eina_xatr_copy(src, dst) ~= 0
end

M.get = function(file, attribute)
    local size = ffi.new("size_t[1]")
    local v = eina.eina_xattr_get(file, attribute, size)
    if v == ffi.nullptr then return nil end
    local r = ffi.string(v, size[0])
    C.free(v)
    return r
end

M.flags = {
    INSERT  = 0,
    REPLACE = 1,
    CREATED = 2
}

M.set = function(file, attribute, data, flags)
    if not data then return false end
    return eina.eina_xattr_set(file, attribute, data, #data, flags or 0) ~= 0
end

M.del = function(file, attribute)
    return eina.eina_xattr_del(file, attribute) ~= 0
end

M.string_set = function(file, attribute, data, flags)
    return eina.eina_xattr_set(file, attribute, data, #data + 1,
        flags or 0) ~= 0
end

M.string_get = function(file, attribute)
    local v = eina.eina_xattr_string_get(file, attribute)
    if v == ffi.nullptr then return nil end
    local r = ffi.string(v)
    C.free(v)
    return r
end

M.double_set = function(file, attribute, value, flags)
    return eina.eina_xattr_double_set(file, attribute, value, flags) ~= 0
end

M.double_get = function(file, attribute)
    local v = ffi.new("double[1]")
    local r = eina.eina_xattr_double_get(file, attribute, v)
    if r == 0 then return false end
    return true, tonum(v[0])
end

M.int_set = function(file, attribute, value, flags)
    return eina.eina_xattr_int_set(file, attribute, value, flags) ~= 0
end

M.int_get = function(file, attribute)
    local v = ffi.new("int[1]")
    local r = eina.eina_xattr_int_get(file, attribute, v)
    if r == 0 then return false end
    return true, tonum(v[0])
end

return M