Skip to content

Instantly share code, notes, and snippets.

@bseibold
Created February 27, 2013 13:18
Show Gist options
  • Save bseibold/5047825 to your computer and use it in GitHub Desktop.
Save bseibold/5047825 to your computer and use it in GitHub Desktop.
Minimized stanza.lua from Prosody, containing a fix/workaround, for use with prosody_to_xep227.lua https://gist.github.com/bseibold/5041603
-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
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_find = string.find;
local os = os;
local getstyle, getstring;
local xmlns_stanzas = "urn:ietf:params:xml:ns:xmpp-stanzas";
module "mystanza"
stanza_mt = { __type = "stanza" };
stanza_mt.__index = stanza_mt;
local stanza_mt = stanza_mt;
function stanza_mt:add_direct_child(child)
if type(child) == "table" then
t_insert(self.tags, child);
end
t_insert(self, child);
end
function stanza_mt:add_child(child)
local last_add = self.last_add;
(last_add and last_add[#last_add] or self):add_direct_child(child);
return self;
end
local xml_escape
do
local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" };
function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end
_M.xml_escape = xml_escape;
end
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", 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).."'");
elseif not(k == "xmlns" and v == parentns) then
if type(v) == "table" and #v == 0 then
t_insert(buf, " "..k.."=''");
else
t_insert(buf, " "..k.."='"..xml_escape(v).."'");
end
end
end
local len = #t;
if len == 0 then
t_insert(buf, "/>");
else
t_insert(buf, ">");
for n=1,len do
local child = t[n];
if child.name then
self(child, buf, self, xml_escape, t.attr.xmlns);
else
t_insert(buf, xml_escape(child));
end
end
t_insert(buf, "</"..name..">");
end
end
function stanza_mt.__tostring(t)
local buf = {};
_dostring(t, buf, _dostring, xml_escape, nil);
return t_concat(buf);
end
function deserialize(stanza)
-- Set metatable
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(att, "\1", 1, true) then
local ns,na = s_match(att, "^([^|]+)|(.+)$");
attrx[ns.."\1"..na] = attr[att];
attr[att] = nil;
end
end
for a,v in pairs(attrx) do
attr[a] = v;
end
setmetatable(stanza, stanza_mt);
for _, child in ipairs(stanza) do
if type(child) == "table" then
deserialize(child);
end
end
if not stanza.tags then
-- Rebuild tags
local tags = {};
for _, child in ipairs(stanza) do
if type(child) == "table" then
t_insert(tags, child);
end
end
stanza.tags = tags;
end
end
return stanza;
end
return _M;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment