X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=util%2Fstanza.lua;h=7c21421083d57daafbcf2ad807c3d7b7166c36a5;hb=5708de632055001445a24f1473895a26b1beefb4;hp=bf94411556b158c4eab8597cfaaf33d1350cee9b;hpb=0ba1be1015d883c8dc6d1eed2ec84114af09ef6f;p=prosody.git diff --git a/util/stanza.lua b/util/stanza.lua index bf944115..7c214210 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -8,22 +8,17 @@ local t_insert = table.insert; -local t_concat = table.concat; local t_remove = table.remove; local t_concat = table.concat; local s_format = string.format; local s_match = string.match; local tostring = tostring; local setmetatable = setmetatable; -local getmetatable = getmetatable; local pairs = pairs; local ipairs = ipairs; local type = type; -local next = next; -local print = print; -local unpack = unpack; local s_gsub = string.gsub; -local s_char = string.char; +local s_sub = string.sub; local s_find = string.find; local os = os; @@ -138,29 +133,20 @@ function stanza_mt:children() end, self, i; end -function stanza_mt:matching_tags(name, xmlns) - xmlns = xmlns or self.attr.xmlns; +function stanza_mt:childtags(name, xmlns) local tags = self.tags; local start_i, max_i = 1, #tags; return function () - for i=start_i,max_i do - v = tags[i]; - if (not name or v.name == name) - and (not xmlns or xmlns == v.attr.xmlns) then - start_i = i+1; - return v; - end + for i = start_i, max_i do + local v = tags[i]; + if (not name or v.name == name) + and ((not xmlns and self.attr.xmlns == v.attr.xmlns) + or v.attr.xmlns == xmlns) then + start_i = i+1; + return v; end - end, tags, i; -end - -function stanza_mt:childtags() - local i = 0; - return function (a) - i = i + 1 - local v = self.tags[i] - if v then return v; end - end, self.tags[1], i; + end + end; end function stanza_mt:maptags(callback) @@ -168,7 +154,7 @@ function stanza_mt:maptags(callback) local n_children, n_tags = #self, #tags; local i = 1; - while curr_tag <= n_tags do + while curr_tag <= n_tags and n_tags > 0 do if self[i] == tags[curr_tag] then local ret = callback(self[i]); if ret == nil then @@ -176,17 +162,44 @@ function stanza_mt:maptags(callback) t_remove(tags, curr_tag); n_children = n_children - 1; n_tags = n_tags - 1; + i = i - 1; + curr_tag = curr_tag - 1; else self[i] = ret; - tags[i] = ret; + tags[curr_tag] = ret; end - i = i + 1; curr_tag = curr_tag + 1; end + i = i + 1; end return self; end +function stanza_mt:find(path) + local pos = 1; + local len = #path + 1; + + repeat + local xmlns, name, text; + local char = s_sub(path, pos, pos); + if char == "@" then + return self.attr[s_sub(path, pos + 1)]; + elseif char == "{" then + xmlns, pos = s_match(path, "^([^}]+)}()", pos + 1); + end + name, text, pos = s_match(path, "^([^@/#]*)([/#]?)()", pos); + name = name ~= "" and name or nil; + if pos == len then + if text == "#" then + return self:get_child_text(name, xmlns); + end + return self:get_child(name, xmlns); + end + self = self:get_child(name, xmlns); + until not self +end + + local xml_escape do local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; @@ -252,7 +265,7 @@ function stanza_mt.get_error(stanza) end type = error_tag.attr.type; - for child in error_tag:childtags() do + for _, child in ipairs(error_tag.tags) do if child.attr.xmlns == xmlns_stanzas then if not text and child.name == "text" then text = child:get_text(); @@ -267,11 +280,6 @@ function stanza_mt.get_error(stanza) return type, condition or "undefined-condition", text; end -function stanza_mt.__add(s1, s2) - return s1:add_direct_child(s2); -end - - do local id = 0; function new_id()