mod_posix: Remove the lines added to work around the util.signal loop bug
[prosody.git] / util / stanza.lua
index ba864e0176d1b80ff3c9666c16f2d67ca1ca3425..8d3b7747b39dadb50ff73c98dc5bd250f34e7471 100644 (file)
@@ -6,6 +6,7 @@
 -- COPYING file in the source package for more information.
 --
 
+
 local t_insert      =  table.insert;
 local t_concat      =  table.concat;
 local t_remove      =  table.remove;
@@ -37,8 +38,6 @@ if do_pretty_printing then
        end
 end
 
-local log = require "util.logger".init("stanza");
-
 module "stanza"
 
 stanza_mt = { __type = "stanza" };
@@ -94,6 +93,17 @@ function stanza_mt:add_child(child)
        return self;
 end
 
+function stanza_mt:get_child(name, xmlns)
+       for _, child in ipairs(self.tags) do
+               if (not name or child.name == name) 
+                       and ((not xmlns and self.attr.xmlns == child.attr.xmlns)
+                               or child.attr.xmlns == xmlns) then
+                       
+                       return child;
+               end
+       end
+end
+
 function stanza_mt:child_with_name(name)
        for _, child in ipairs(self.tags) do    
                if child.name == name then return child; end
@@ -132,16 +142,16 @@ do
        _M.xml_escape = xml_escape;
 end
 
-local function _dostring(t, buf, self, xml_escape)
+local function _dostring(t, buf, self, xml_escape, parentns)
        local nsid = 0;
        local name = t.name
        t_insert(buf, "<"..name);
        for k, v in pairs(t.attr) do
-               if s_find(k, "|", 1, true) then
-                       local ns, attrk = s_match(k, "^([^|]+)|(.+)$");
+               if s_find(k, "\1", 1, true) then
+                       local ns, attrk = s_match(k, "^([^\1]*)\1?(.*)$");
                        nsid = nsid + 1;
                        t_insert(buf, " xmlns:ns"..nsid.."='"..xml_escape(ns).."' ".."ns"..nsid..":"..attrk.."='"..xml_escape(v).."'");
-               else
+               elseif not(k == "xmlns" and v == parentns) then
                        t_insert(buf, " "..k.."='"..xml_escape(v).."'");
                end
        end
@@ -153,7 +163,7 @@ local function _dostring(t, buf, self, xml_escape)
                for n=1,len do
                        local child = t[n];
                        if child.name then
-                               self(child, buf, self, xml_escape);
+                               self(child, buf, self, xml_escape, t.attr.xmlns);
                        else
                                t_insert(buf, xml_escape(child));
                        end
@@ -163,7 +173,7 @@ local function _dostring(t, buf, self, xml_escape)
 end
 function stanza_mt.__tostring(t)
        local buf = {};
-       _dostring(t, buf, _dostring, xml_escape);
+       _dostring(t, buf, _dostring, xml_escape, nil);
        return t_concat(buf);
 end
 
@@ -211,6 +221,17 @@ function deserialize(stanza)
        if stanza then
                local attr = stanza.attr;
                for i=1,#attr do attr[i] = nil; end
+               local attrx = {};
+               for att in pairs(attr) do
+                       if s_find(att, "|", 1, true) and not s_find(k, "\1", 1, true) then
+                               local ns,na = s_match(k, "^([^|]+)|(.+)$");
+                               attrx[ns.."\1"..na] = attr[att];
+                               attr[att] = nil;
+                       end
+               end
+               for a,v in pairs(attrx) do
+                       attr[x] = v;
+               end
                setmetatable(stanza, stanza_mt);
                for _, child in ipairs(stanza) do
                        if type(child) == "table" then