Merge 0.10->trunk
[prosody.git] / util / filters.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 --
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9 local t_insert, t_remove = table.insert, table.remove;
10
11 local _ENV = nil;
12
13 local new_filter_hooks = {};
14
15 local function initialize(session)
16         if not session.filters then
17                 local filters = {};
18                 session.filters = filters;
19
20                 function session.filter(type, data)
21                         local filter_list = filters[type];
22                         if filter_list then
23                                 for i = 1, #filter_list do
24                                         data = filter_list[i](data, session);
25                                         if data == nil then break; end
26                                 end
27                         end
28                         return data;
29                 end
30         end
31
32         for i=1,#new_filter_hooks do
33                 new_filter_hooks[i](session);
34         end
35
36         return session.filter;
37 end
38
39 local function add_filter(session, type, callback, priority)
40         if not session.filters then
41                 initialize(session);
42         end
43
44         local filter_list = session.filters[type];
45         if not filter_list then
46                 filter_list = {};
47                 session.filters[type] = filter_list;
48         elseif filter_list[callback] then
49                 return; -- Filter already added
50         end
51
52         priority = priority or 0;
53
54         local i = 0;
55         repeat
56                 i = i + 1;
57         until not filter_list[i] or filter_list[filter_list[i]] < priority;
58
59         t_insert(filter_list, i, callback);
60         filter_list[callback] = priority;
61 end
62
63 local function remove_filter(session, type, callback)
64         if not session.filters then return; end
65         local filter_list = session.filters[type];
66         if filter_list and filter_list[callback] then
67                 for i=1, #filter_list do
68                         if filter_list[i] == callback then
69                                 t_remove(filter_list, i);
70                                 filter_list[callback] = nil;
71                                 return true;
72                         end
73                 end
74         end
75 end
76
77 local function add_filter_hook(callback)
78         t_insert(new_filter_hooks, callback);
79 end
80
81 local function remove_filter_hook(callback)
82         for i=1,#new_filter_hooks do
83                 if new_filter_hooks[i] == callback then
84                         t_remove(new_filter_hooks, i);
85                 end
86         end
87 end
88
89 return {
90         initialize = initialize;
91         add_filter = add_filter;
92         remove_filter = remove_filter;
93         add_filter_hook = add_filter_hook;
94         remove_filter_hook = remove_filter_hook;
95 };