2009-06-25
util.stanza: Rewrote stanza_mt.__tostring. 20-30% faster stanza serialization. - #optimization
| util/stanza.lua | file | annotate | diff | revisions |
1.1 --- a/util/stanza.lua Thu Jun 25 17:19:13 2009 +0500 1.2 +++ b/util/stanza.lua Thu Jun 25 17:22:53 2009 +0500 1.3 @@ -23,6 +23,7 @@ 1.4 local print = print; 1.5 local unpack = unpack; 1.6 local s_gsub = string.gsub; 1.7 +local s_char = string.char; 1.8 local os = os; 1.9 1.10 local do_pretty_printing = not os.getenv("WINDIR"); 1.11 @@ -116,54 +117,39 @@ 1.12 1.13 end 1.14 1.15 -do 1.16 - local xml_entities = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; 1.17 - function xml_escape(s) return s_gsub(s, "['&<>\"]", xml_entities); end 1.18 -end 1.19 - 1.20 -local xml_escape = xml_escape; 1.21 - 1.22 -local function dostring(t, buf, self, xml_escape) 1.23 +local xml_escape = (function() 1.24 + local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; 1.25 + return function(str) return (s_gsub(str, "['&<>\"]", escape_table)); end 1.26 +end)(); 1.27 +local function _dostring(t, buf, self, xml_escape) 1.28 local nsid, ns, attrk = 0; 1.29 - t_insert(buf, "<"); 1.30 - t_insert(buf, t.name); 1.31 - for k, v in pairs(t.attr) do if type(k) == "string" then 1.32 - t_insert(buf, " "); 1.33 + t_insert(buf, "<"..t.name); 1.34 + for k, v in pairs(t.attr) do 1.35 ns, attrk = s_match(k, "^([^|]+)|(.+)$"); 1.36 if ns then 1.37 - nsid = (nsid or -1) + 1; 1.38 - t_insert(buf, "xmlns:ns"..nsid); 1.39 - t_insert(buf, "='"); 1.40 - t_insert(buf, (xml_escape(tostring(ns)))); 1.41 - t_insert(buf, "' "); 1.42 - t_insert(buf, "ns"..nsid..":"..attrk); 1.43 + nsid = nsid + 1; 1.44 + t_insert(buf, " xmlns:ns"..nsid.."='"..xml_escape(ns).."' ".."ns"..nsid..":"..attrk.."='"..xml_escape(v).."'"); 1.45 else 1.46 - t_insert(buf, k); 1.47 + t_insert(buf, " "..k.."='"..xml_escape(v).."'"); 1.48 end 1.49 - t_insert(buf, "='"); 1.50 - t_insert(buf, (xml_escape(tostring(v)))); 1.51 - t_insert(buf, "'"); 1.52 - end end 1.53 + end 1.54 t_insert(buf, ">"); 1.55 - for n, child in ipairs(t) do 1.56 - if child.name then 1.57 + for n=1,#t do 1.58 + local child = t[n]; 1.59 + if child.name then 1.60 self(child, buf, self, xml_escape); 1.61 else 1.62 - t_insert(buf, (xml_escape(child))); 1.63 + t_insert(buf, xml_escape(child)); 1.64 end 1.65 end 1.66 - t_insert(buf, "</"); 1.67 - t_insert(buf, t.name); 1.68 - t_insert(buf, ">"); 1.69 + t_insert(buf, "</"..t.name..">"); 1.70 end 1.71 - 1.72 function stanza_mt.__tostring(t) 1.73 local buf = {}; 1.74 - dostring(t, buf, dostring, xml_escape); 1.75 + _dostring(t, buf, _dostring, xml_escape); 1.76 return t_concat(buf); 1.77 end 1.78 1.79 - 1.80 function stanza_mt.top_tag(t) 1.81 local attr_string = ""; 1.82 if t.attr then