Mercurial > prosody-hg
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 |
| parents | c85f9a4ae1c4 |
| children | 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' }); |
