util/stanza.lua
changeset 9928 5a2e53bef031
parent 9736 51583ea2b4fd
child 10120 4807535b8673
equal deleted inserted replaced
9927:e83dfcdeab59 9928:5a2e53bef031
   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);
   384 				stanza:add_direct_child(child);
   409 				stanza:add_direct_child(child);
   385 			end
   410 			end
   386 		end
   411 		end
   387 		return stanza;
   412 		return stanza;
   388 	end
   413 	end
   389 end
       
   390 
       
   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
   414 end
   417 
   415 
   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);