Comparison

util/stanza.lua @ 7253:f4e71242556a

util.stanza: Some code cleanup [luacheck]
author Matthew Wild <mwild1@gmail.com>
date Wed, 09 Mar 2016 12:37:56 +0000
parent 6821:5de30376bf98
child 7256:9fbb9fbf7e52
child 7750:e58524240b30
comparison
equal deleted inserted replaced
7252:fa0169cc8511 7253:f4e71242556a
38 local _ENV = nil; 38 local _ENV = nil;
39 39
40 local stanza_mt = { __type = "stanza" }; 40 local stanza_mt = { __type = "stanza" };
41 stanza_mt.__index = stanza_mt; 41 stanza_mt.__index = stanza_mt;
42 42
43 local function stanza(name, attr) 43 local function new_stanza(name, attr)
44 local stanza = { name = name, attr = attr or {}, tags = {} }; 44 local stanza = { name = name, attr = attr or {}, tags = {} };
45 return setmetatable(stanza, stanza_mt); 45 return setmetatable(stanza, stanza_mt);
46 end 46 end
47 local stanza = stanza;
48 47
49 function stanza_mt:query(xmlns) 48 function stanza_mt:query(xmlns)
50 return self:tag("query", { xmlns = xmlns }); 49 return self:tag("query", { xmlns = xmlns });
51 end 50 end
52 51
53 function stanza_mt:body(text, attr) 52 function stanza_mt:body(text, attr)
54 return self:tag("body", attr):text(text); 53 return self:tag("body", attr):text(text);
55 end 54 end
56 55
57 function stanza_mt:tag(name, attrs) 56 function stanza_mt:tag(name, attrs)
58 local s = stanza(name, attrs); 57 local s = new_stanza(name, attrs);
59 local last_add = self.last_add; 58 local last_add = self.last_add;
60 if not last_add then last_add = {}; self.last_add = last_add; end 59 if not last_add then last_add = {}; self.last_add = last_add; end
61 (last_add[#last_add] or self):add_direct_child(s); 60 (last_add[#last_add] or self):add_direct_child(s);
62 t_insert(last_add, s); 61 t_insert(last_add, s);
63 return self; 62 return self;
200 199
201 200
202 local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" }; 201 local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" };
203 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end 202 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end
204 203
205 local function _dostring(t, buf, self, xml_escape, parentns) 204 local function _dostring(t, buf, self, _xml_escape, parentns)
206 local nsid = 0; 205 local nsid = 0;
207 local name = t.name 206 local name = t.name
208 t_insert(buf, "<"..name); 207 t_insert(buf, "<"..name);
209 for k, v in pairs(t.attr) do 208 for k, v in pairs(t.attr) do
210 if s_find(k, "\1", 1, true) then 209 if s_find(k, "\1", 1, true) then
211 local ns, attrk = s_match(k, "^([^\1]*)\1?(.*)$"); 210 local ns, attrk = s_match(k, "^([^\1]*)\1?(.*)$");
212 nsid = nsid + 1; 211 nsid = nsid + 1;
213 t_insert(buf, " xmlns:ns"..nsid.."='"..xml_escape(ns).."' ".."ns"..nsid..":"..attrk.."='"..xml_escape(v).."'"); 212 t_insert(buf, " xmlns:ns"..nsid.."='".._xml_escape(ns).."' ".."ns"..nsid..":"..attrk.."='".._xml_escape(v).."'");
214 elseif not(k == "xmlns" and v == parentns) then 213 elseif not(k == "xmlns" and v == parentns) then
215 t_insert(buf, " "..k.."='"..xml_escape(v).."'"); 214 t_insert(buf, " "..k.."='".._xml_escape(v).."'");
216 end 215 end
217 end 216 end
218 local len = #t; 217 local len = #t;
219 if len == 0 then 218 if len == 0 then
220 t_insert(buf, "/>"); 219 t_insert(buf, "/>");
221 else 220 else
222 t_insert(buf, ">"); 221 t_insert(buf, ">");
223 for n=1,len do 222 for n=1,len do
224 local child = t[n]; 223 local child = t[n];
225 if child.name then 224 if child.name then
226 self(child, buf, self, xml_escape, t.attr.xmlns); 225 self(child, buf, self, _xml_escape, t.attr.xmlns);
227 else 226 else
228 t_insert(buf, xml_escape(child)); 227 t_insert(buf, _xml_escape(child));
229 end 228 end
230 end 229 end
231 t_insert(buf, "</"..name..">"); 230 t_insert(buf, "</"..name..">");
232 end 231 end
233 end 232 end
250 return t_concat(t); 249 return t_concat(t);
251 end 250 end
252 end 251 end
253 252
254 function stanza_mt.get_error(stanza) 253 function stanza_mt.get_error(stanza)
255 local type, condition, text; 254 local error_type, condition, text;
256 255
257 local error_tag = stanza:get_child("error"); 256 local error_tag = stanza:get_child("error");
258 if not error_tag then 257 if not error_tag then
259 return nil, nil, nil; 258 return nil, nil, nil;
260 end 259 end
261 type = error_tag.attr.type; 260 error_type = error_tag.attr.type;
262 261
263 for _, child in ipairs(error_tag.tags) do 262 for _, child in ipairs(error_tag.tags) do
264 if child.attr.xmlns == xmlns_stanzas then 263 if child.attr.xmlns == xmlns_stanzas then
265 if not text and child.name == "text" then 264 if not text and child.name == "text" then
266 text = child:get_text(); 265 text = child:get_text();
270 if condition and text then 269 if condition and text then
271 break; 270 break;
272 end 271 end
273 end 272 end
274 end 273 end
275 return type, condition or "undefined-condition", text; 274 return error_type, condition or "undefined-condition", text;
276 end 275 end
277 276
278 local id = 0; 277 local id = 0;
279 local function new_id() 278 local function new_id()
280 id = id + 1; 279 id = id + 1;
345 return setmetatable(new, stanza_mt); 344 return setmetatable(new, stanza_mt);
346 end 345 end
347 346
348 local function message(attr, body) 347 local function message(attr, body)
349 if not body then 348 if not body then
350 return stanza("message", attr); 349 return new_stanza("message", attr);
351 else 350 else
352 return stanza("message", attr):tag("body"):text(body):up(); 351 return new_stanza("message", attr):tag("body"):text(body):up();
353 end 352 end
354 end 353 end
355 local function iq(attr) 354 local function iq(attr)
356 if attr and not attr.id then attr.id = new_id(); end 355 if attr and not attr.id then attr.id = new_id(); end
357 return stanza("iq", attr or { id = new_id() }); 356 return new_stanza("iq", attr or { id = new_id() });
358 end 357 end
359 358
360 local function reply(orig) 359 local function reply(orig)
361 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 orig.attr.type) }); 360 return new_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 orig.attr.type) });
362 end 361 end
363 362
364 local xmpp_stanzas_attr = { xmlns = xmlns_stanzas }; 363 local xmpp_stanzas_attr = { xmlns = xmlns_stanzas };
365 local function error_reply(orig, type, condition, message) 364 local function error_reply(orig, error_type, condition, error_message)
366 local t = reply(orig); 365 local t = reply(orig);
367 t.attr.type = "error"; 366 t.attr.type = "error";
368 t:tag("error", {type = type}) --COMPAT: Some day xmlns:stanzas goes here 367 t:tag("error", {type = error_type}) --COMPAT: Some day xmlns:stanzas goes here
369 :tag(condition, xmpp_stanzas_attr):up(); 368 :tag(condition, xmpp_stanzas_attr):up();
370 if (message) then t:tag("text", xmpp_stanzas_attr):text(message):up(); end 369 if error_message then t:tag("text", xmpp_stanzas_attr):text(error_message):up(); end
371 return t; -- stanza ready for adding app-specific errors 370 return t; -- stanza ready for adding app-specific errors
372 end 371 end
373 372
374 local function presence(attr) 373 local function presence(attr)
375 return stanza("presence", attr); 374 return new_stanza("presence", attr);
376 end 375 end
377 376
378 if do_pretty_printing then 377 if do_pretty_printing then
379 local style_attrk = getstyle("yellow"); 378 local style_attrk = getstyle("yellow");
380 local style_attrv = getstyle("red"); 379 local style_attrv = getstyle("red");
385 local top_tag_format = getstring(style_punc, "<")..getstring(style_tagname, "%s").."%s"..getstring(style_punc, ">"); 384 local top_tag_format = getstring(style_punc, "<")..getstring(style_tagname, "%s").."%s"..getstring(style_punc, ">");
386 --local tag_format = getstring(style_punc, "<")..getstring(style_tagname, "%s").."%s"..getstring(style_punc, ">").."%s"..getstring(style_punc, "</")..getstring(style_tagname, "%s")..getstring(style_punc, ">"); 385 --local tag_format = getstring(style_punc, "<")..getstring(style_tagname, "%s").."%s"..getstring(style_punc, ">").."%s"..getstring(style_punc, "</")..getstring(style_tagname, "%s")..getstring(style_punc, ">");
387 local tag_format = top_tag_format.."%s"..getstring(style_punc, "</")..getstring(style_tagname, "%s")..getstring(style_punc, ">"); 386 local tag_format = top_tag_format.."%s"..getstring(style_punc, "</")..getstring(style_tagname, "%s")..getstring(style_punc, ">");
388 function stanza_mt.pretty_print(t) 387 function stanza_mt.pretty_print(t)
389 local children_text = ""; 388 local children_text = "";
390 for n, child in ipairs(t) do 389 for _, child in ipairs(t) do
391 if type(child) == "string" then 390 if type(child) == "string" then
392 children_text = children_text .. xml_escape(child); 391 children_text = children_text .. xml_escape(child);
393 else 392 else
394 children_text = children_text .. child:pretty_print(); 393 children_text = children_text .. child:pretty_print();
395 end 394 end
415 stanza_mt.pretty_top_tag = stanza_mt.top_tag; 414 stanza_mt.pretty_top_tag = stanza_mt.top_tag;
416 end 415 end
417 416
418 return { 417 return {
419 stanza_mt = stanza_mt; 418 stanza_mt = stanza_mt;
420 stanza = stanza; 419 stanza = new_stanza;
421 new_id = new_id; 420 new_id = new_id;
422 preserialize = preserialize; 421 preserialize = preserialize;
423 deserialize = deserialize; 422 deserialize = deserialize;
424 clone = clone; 423 clone = clone;
425 message = message; 424 message = message;