|
1 local t_insert = table.insert; |
|
2 local t_remove = table.remove; |
|
3 local format = string.format; |
|
4 local tostring = tostring; |
|
5 local setmetatable= setmetatable; |
|
6 local pairs = pairs; |
|
7 local ipairs = ipairs; |
|
8 |
|
9 module "stanza" |
|
10 |
|
11 stanza_mt = {}; |
|
12 stanza_mt.__index = stanza_mt; |
|
13 |
|
14 function stanza(name, attr) |
|
15 local stanza = { name = name, attr = attr or {}, last_add = {}}; |
|
16 return setmetatable(stanza, stanza_mt); |
|
17 end |
|
18 |
|
19 function stanza_mt:iq(attrs) |
|
20 return self + stanza("iq", attrs) |
|
21 end |
|
22 function stanza_mt:message(attrs) |
|
23 return self + stanza("message", attrs) |
|
24 end |
|
25 function stanza_mt:presence(attrs) |
|
26 return self + stanza("presence", attrs) |
|
27 end |
|
28 function stanza_mt:query(xmlns) |
|
29 return self:tag("query", { xmlns = xmlns }); |
|
30 end |
|
31 function stanza_mt:tag(name, attrs) |
|
32 local s = stanza(name, attrs); |
|
33 (self.last_add[#self.last_add] or self):add_child(s); |
|
34 t_insert(self.last_add, s); |
|
35 return self; |
|
36 end |
|
37 |
|
38 function stanza_mt:text(text) |
|
39 (self.last_add[#self.last_add] or self):add_child(text); |
|
40 return self; |
|
41 end |
|
42 |
|
43 function stanza_mt:up() |
|
44 t_remove(self.last_add); |
|
45 return self; |
|
46 end |
|
47 |
|
48 function stanza_mt:add_child(child) |
|
49 t_insert(self, child); |
|
50 end |
|
51 |
|
52 function stanza_mt:child_with_name(name) |
|
53 for _, child in ipairs(self) do |
|
54 if child.name == name then return child; end |
|
55 end |
|
56 end |
|
57 |
|
58 function stanza_mt.__tostring(t) |
|
59 local children_text = ""; |
|
60 for n, child in ipairs(t) do |
|
61 children_text = children_text .. tostring(child); |
|
62 end |
|
63 |
|
64 local attr_string = ""; |
|
65 if t.attr then |
|
66 for k, v in pairs(t.attr) do attr_string = attr_string .. format(" %s='%s'", k, tostring(v)); end |
|
67 end |
|
68 |
|
69 return format("<%s%s>%s</%s>", t.name, attr_string, children_text, t.name); |
|
70 end |
|
71 |
|
72 function stanza_mt.__add(s1, s2) |
|
73 return s:add_child(s2); |
|
74 end |
|
75 |
|
76 |
|
77 do |
|
78 local id = 0; |
|
79 function new_id() |
|
80 id = id + 1; |
|
81 return "lx"..id; |
|
82 end |
|
83 end |
|
84 |
|
85 function message(attr, body) |
|
86 if not body then |
|
87 return stanza("message", attr); |
|
88 else |
|
89 return stanza("message", attr):tag("body"):text(body); |
|
90 end |
|
91 end |
|
92 function iq(attr) |
|
93 if attr and not attr.id then attr.id = new_id(); end |
|
94 return stanza("iq", attr or { id = new_id() }); |
|
95 end |
|
96 |
|
97 function reply(orig) |
|
98 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) }); |
|
99 end |
|
100 |
|
101 function presence(attr) |
|
102 return stanza("presence", attr); |
|
103 end |
|
104 |