Software /
code /
prosody
Comparison
util/template.lua @ 3546:cb1600dea3ad
util.template: Optimized to be almost as fast as manual stanza building.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Sun, 24 Oct 2010 15:08:22 +0500 |
parent | 3545:c85f9a4ae1c4 |
child | 3637:bd491def3efb |
comparison
equal
deleted
inserted
replaced
3545:c85f9a4ae1c4 | 3546:cb1600dea3ad |
---|---|
22 local i = 1; | 22 local i = 1; |
23 while i <= #stanza do | 23 while i <= #stanza do |
24 local child = stanza[i]; | 24 local child = stanza[i]; |
25 if child.name then | 25 if child.name then |
26 process_stanza(child, ops); | 26 process_stanza(child, ops); |
27 elseif child:match("^{[^}]*}$") then -- text | |
28 t_insert(ops, {stanza, i, child:match("^{([^}]*)}$"), true}); | |
27 elseif child:match("{[^}]*}") then -- text | 29 elseif child:match("{[^}]*}") then -- text |
28 t_insert(ops, {stanza, i, child}); | 30 t_insert(ops, {stanza, i, child}); |
29 end | 31 end |
30 i = i + 1; | 32 i = i + 1; |
31 end | 33 end |
79 return ok, err.." (line "..line..", col "..col..")"; | 81 return ok, err.." (line "..line..", col "..col..")"; |
80 end | 82 end |
81 end; | 83 end; |
82 end)(); | 84 end)(); |
83 | 85 |
86 local stanza_mt = st.stanza_mt; | |
87 local function fast_st_clone(stanza, lookup) | |
88 local stanza_attr = stanza.attr; | |
89 local stanza_tags = stanza.tags; | |
90 local tags, attr = {}, {}; | |
91 local clone = { name = stanza.name, attr = attr, tags = tags, last_add = {} }; | |
92 for k,v in pairs(stanza_attr) do attr[k] = v; end | |
93 lookup[stanza_attr] = attr; | |
94 for i=1,#stanza_tags do | |
95 local child = stanza_tags[i]; | |
96 local new = fast_st_clone(child, lookup); | |
97 tags[i] = new; | |
98 lookup[child] = new; | |
99 end | |
100 for i=1,#stanza do | |
101 local child = stanza[i]; | |
102 clone[i] = lookup[child] or child; | |
103 end | |
104 return setmetatable(clone, stanza_mt); | |
105 end | |
106 | |
84 local function create_template(text) | 107 local function create_template(text) |
85 local stanza, err = parse_xml(text); | 108 local stanza, err = parse_xml(text); |
86 if not stanza then error(err); end | 109 if not stanza then error(err); end |
87 local ops = {}; | 110 local ops = {}; |
88 process_stanza(stanza, ops); | 111 process_stanza(stanza, ops); |
89 ops.stanza = stanza; | |
90 | 112 |
91 local template = {}; | 113 local template = {}; |
114 local lookup = {}; | |
92 function template.apply(data) | 115 function template.apply(data) |
93 local newops = st.clone(ops); | 116 local newstanza = fast_st_clone(stanza, lookup); |
94 for i=1,#newops do | 117 for i=1,#ops do |
95 local op = newops[i]; | 118 local op = ops[i]; |
96 local t, k, v = op[1], op[2], op[3]; | 119 local t, k, v, g = op[1], op[2], op[3], op[4]; |
97 t[k] = s_gsub(v, "{([^}]*)}", data); | 120 if g then |
121 lookup[t][k] = data[v]; | |
122 else | |
123 lookup[t][k] = s_gsub(v, "{([^}]*)}", data); | |
124 end | |
98 end | 125 end |
99 return newops.stanza; | 126 return newstanza; |
100 end | 127 end |
101 return template; | 128 return template; |
102 end | 129 end |
103 | 130 |
104 local templates = setmetatable({}, { __mode = 'k' }); | 131 local templates = setmetatable({}, { __mode = 'k' }); |