# HG changeset patch # User Waqas Hussain # Date 1287914902 -18000 # Node ID cb1600dea3ad90d05d1a23ec8e50d7644d867034 # Parent c85f9a4ae1c45483e61891b23a51d2eca818513a util.template: Optimized to be almost as fast as manual stanza building. diff -r c85f9a4ae1c4 -r cb1600dea3ad util/template.lua --- a/util/template.lua Sun Oct 24 15:06:13 2010 +0500 +++ b/util/template.lua Sun Oct 24 15:08:22 2010 +0500 @@ -24,6 +24,8 @@ local child = stanza[i]; if child.name then process_stanza(child, ops); + elseif child:match("^{[^}]*}$") then -- text + t_insert(ops, {stanza, i, child:match("^{([^}]*)}$"), true}); elseif child:match("{[^}]*}") then -- text t_insert(ops, {stanza, i, child}); end @@ -81,22 +83,47 @@ end; end)(); +local stanza_mt = st.stanza_mt; +local function fast_st_clone(stanza, lookup) + local stanza_attr = stanza.attr; + local stanza_tags = stanza.tags; + local tags, attr = {}, {}; + local clone = { name = stanza.name, attr = attr, tags = tags, last_add = {} }; + for k,v in pairs(stanza_attr) do attr[k] = v; end + lookup[stanza_attr] = attr; + for i=1,#stanza_tags do + local child = stanza_tags[i]; + local new = fast_st_clone(child, lookup); + tags[i] = new; + lookup[child] = new; + end + for i=1,#stanza do + local child = stanza[i]; + clone[i] = lookup[child] or child; + end + return setmetatable(clone, stanza_mt); +end + local function create_template(text) local stanza, err = parse_xml(text); if not stanza then error(err); end local ops = {}; process_stanza(stanza, ops); - ops.stanza = stanza; local template = {}; + local lookup = {}; function template.apply(data) - local newops = st.clone(ops); - for i=1,#newops do - local op = newops[i]; - local t, k, v = op[1], op[2], op[3]; - t[k] = s_gsub(v, "{([^}]*)}", data); + local newstanza = fast_st_clone(stanza, lookup); + for i=1,#ops do + local op = ops[i]; + local t, k, v, g = op[1], op[2], op[3], op[4]; + if g then + lookup[t][k] = data[v]; + else + lookup[t][k] = s_gsub(v, "{([^}]*)}", data); + end end - return newops.stanza; + return newstanza; end return template; end