Comparison

util/stanza.lua @ 10061:5c71693c8345

Merge 0.11->trunk
author Kim Alvefur <zash@zash.se>
date Mon, 08 Jul 2019 02:44:32 +0200
parent 9924:5a2e53bef031
child 10116:4807535b8673
comparison
equal deleted inserted replaced
10060:7a36b7ac309b 10061:5c71693c8345
268 end 268 end
269 self = self:get_child(name, xmlns); 269 self = self:get_child(name, xmlns);
270 until not self 270 until not self
271 end 271 end
272 272
273 local function _clone(stanza, only_top)
274 local attr, tags = {}, {};
275 for k,v in pairs(stanza.attr) do attr[k] = v; end
276 local old_namespaces, namespaces = stanza.namespaces;
277 if old_namespaces then
278 namespaces = {};
279 for k,v in pairs(old_namespaces) do namespaces[k] = v; end
280 end
281 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags };
282 if not only_top then
283 for i=1,#stanza do
284 local child = stanza[i];
285 if child.name then
286 child = _clone(child);
287 t_insert(tags, child);
288 end
289 t_insert(new, child);
290 end
291 end
292 return setmetatable(new, stanza_mt);
293 end
294
295 local function clone(stanza, only_top)
296 if not is_stanza(stanza) then
297 error("bad argument to clone: expected stanza, got "..type(stanza));
298 end
299 return _clone(stanza, only_top);
300 end
273 301
274 local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" }; 302 local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" };
275 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end 303 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end
276 304
277 local function _dostring(t, buf, self, _xml_escape, parentns) 305 local function _dostring(t, buf, self, _xml_escape, parentns)
308 _dostring(t, buf, _dostring, xml_escape, nil); 336 _dostring(t, buf, _dostring, xml_escape, nil);
309 return t_concat(buf); 337 return t_concat(buf);
310 end 338 end
311 339
312 function stanza_mt.top_tag(t) 340 function stanza_mt.top_tag(t)
313 local attr_string = ""; 341 local top_tag_clone = clone(t, true);
314 if t.attr then 342 return tostring(top_tag_clone):sub(1,-3)..">";
315 for k, v in pairs(t.attr) do if type(k) == "string" then attr_string = attr_string .. s_format(" %s='%s'", k, xml_escape(tostring(v))); end end
316 end
317 return s_format("<%s%s>", t.name, attr_string);
318 end 343 end
319 344
320 function stanza_mt.get_text(t) 345 function stanza_mt.get_text(t)
321 if #t.tags == 0 then 346 if #t.tags == 0 then
322 return t_concat(t); 347 return t_concat(t);
386 end 411 end
387 return stanza; 412 return stanza;
388 end 413 end
389 end 414 end
390 415
391 local function _clone(stanza)
392 local attr, tags = {}, {};
393 for k,v in pairs(stanza.attr) do attr[k] = v; end
394 local old_namespaces, namespaces = stanza.namespaces;
395 if old_namespaces then
396 namespaces = {};
397 for k,v in pairs(old_namespaces) do namespaces[k] = v; end
398 end
399 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags };
400 for i=1,#stanza do
401 local child = stanza[i];
402 if child.name then
403 child = _clone(child);
404 t_insert(tags, child);
405 end
406 t_insert(new, child);
407 end
408 return setmetatable(new, stanza_mt);
409 end
410
411 local function clone(stanza)
412 if not is_stanza(stanza) then
413 error("bad argument to clone: expected stanza, got "..type(stanza));
414 end
415 return _clone(stanza);
416 end
417
418 local function message(attr, body) 416 local function message(attr, body)
419 if not body then 417 if not body then
420 return new_stanza("message", attr); 418 return new_stanza("message", attr);
421 else 419 else
422 return new_stanza("message", attr):tag("body"):text(body):up(); 420 return new_stanza("message", attr):tag("body"):text(body):up();
423 end 421 end
424 end 422 end
425 local function iq(attr) 423 local function iq(attr)
426 if not (attr and attr.id) then 424 if not attr then
425 error("iq stanzas require id and type attributes");
426 end
427 if not attr.id then
427 error("iq stanzas require an id attribute"); 428 error("iq stanzas require an id attribute");
429 end
430 if not attr.type then
431 error("iq stanzas require a type attribute");
428 end 432 end
429 return new_stanza("iq", attr); 433 return new_stanza("iq", attr);
430 end 434 end
431 435
432 local function reply(orig) 436 local function reply(orig)