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
|
local t_insert = table.insert;
local t_remove = table.remove;
local format = string.format;
local tostring = tostring;
local setmetatable= setmetatable;
local pairs = pairs;
local ipairs = ipairs;
module "stanza"
stanza_mt = {};
stanza_mt.__index = stanza_mt;
function stanza(name, attr)
local stanza = { name = name, attr = attr or {}, last_add = {}};
return setmetatable(stanza, stanza_mt);
end
function stanza_mt:iq(attrs)
return self + stanza("iq", attrs)
end
function stanza_mt:message(attrs)
return self + stanza("message", attrs)
end
function stanza_mt:presence(attrs)
return self + stanza("presence", attrs)
end
function stanza_mt:query(xmlns)
return self:tag("query", { xmlns = xmlns });
end
function stanza_mt:tag(name, attrs)
local s = stanza(name, attrs);
(self.last_add[#self.last_add] or self):add_child(s);
t_insert(self.last_add, s);
return self;
end
function stanza_mt:text(text)
(self.last_add[#self.last_add] or self):add_child(text);
return self;
end
function stanza_mt:up()
t_remove(self.last_add);
return self;
end
function stanza_mt:add_child(child)
t_insert(self, child);
end
function stanza_mt:child_with_name(name)
for _, child in ipairs(self) do
if child.name == name then return child; end
end
end
function stanza_mt.__tostring(t)
local children_text = "";
for n, child in ipairs(t) do
children_text = children_text .. tostring(child);
end
local attr_string = "";
if t.attr then
for k, v in pairs(t.attr) do attr_string = attr_string .. format(" %s='%s'", k, tostring(v)); end
end
return format("<%s%s>%s</%s>", t.name, attr_string, children_text, t.name);
end
function stanza_mt.__add(s1, s2)
return s:add_child(s2);
end
do
local id = 0;
function new_id()
id = id + 1;
return "lx"..id;
end
end
function message(attr, body)
if not body then
return stanza("message", attr);
else
return stanza("message", attr):tag("body"):text(body);
end
end
function iq(attr)
if attr and not attr.id then attr.id = new_id(); end
return stanza("iq", attr or { id = new_id() });
end
function reply(orig)
return stanza(orig.name, orig.attr and { to = orig.attr.from, from = orig.attr.to, id = orig.attr.id, type = ((orig.name == "iq" and "result") or nil) });
end
function presence(attr)
return stanza("presence", attr);
end
|