Software /
code /
prosody
Annotate
util/template.lua @ 5689:832ea1e9ac9e
mod_disco: Allow ansering disco requests including nodes, and adding custom items to disco#items requests
author | Florian Zeitz <florob@babelmonkeys.de> |
---|---|
date | Tue, 04 Jun 2013 23:59:59 +0200 |
parent | 5214:1430c6f36621 |
child | 6777:5de6b93d0190 |
rev | line source |
---|---|
3545
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
1 |
5214
1430c6f36621
util.template: Use util.xml.
Waqas Hussain <waqas20@gmail.com>
parents:
4495
diff
changeset
|
2 local stanza_mt = require "util.stanza".stanza_mt; |
3545
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
3 local setmetatable = setmetatable; |
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
4 local pairs = pairs; |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
5 local ipairs = ipairs; |
3545
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
6 local error = error; |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
7 local loadstring = loadstring; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
8 local debug = debug; |
4495
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
9 local t_remove = table.remove; |
5214
1430c6f36621
util.template: Use util.xml.
Waqas Hussain <waqas20@gmail.com>
parents:
4495
diff
changeset
|
10 local parse_xml = require "util.xml".parse; |
3545
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
11 |
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
12 module("template") |
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
13 |
4495
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
14 local function trim_xml(stanza) |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
15 for i=#stanza,1,-1 do |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
16 local child = stanza[i]; |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
17 if child.name then |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
18 trim_xml(child); |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
19 else |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
20 child = child:gsub("^%s*", ""):gsub("%s*$", ""); |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
21 stanza[i] = child; |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
22 if child == "" then t_remove(stanza, i); end |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
23 end |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
24 end |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
25 end |
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
26 |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
27 local function create_string_string(str) |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
28 str = ("%q"):format(str); |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
29 str = str:gsub("{([^}]*)}", function(s) |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
30 return '"..(data["'..s..'"]or"").."'; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
31 end); |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
32 return str; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
33 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
34 local function create_attr_string(attr, xmlns) |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
35 local str = '{'; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
36 for name,value in pairs(attr) do |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
37 if name ~= "xmlns" or value ~= xmlns then |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
38 str = str..("[%q]=%s;"):format(name, create_string_string(value)); |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
39 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
40 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
41 return str..'}'; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
42 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
43 local function create_clone_string(stanza, lookup, xmlns) |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
44 if not lookup[stanza] then |
3640
4bc88bb748d1
util.template: Don't add stanza.last_add. 20% faster.
Waqas Hussain <waqas20@gmail.com>
parents:
3637
diff
changeset
|
45 local s = ('setmetatable({name=%q,attr=%s,tags={'):format(stanza.name, create_attr_string(stanza.attr, xmlns)); |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
46 -- add tags |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
47 for i,tag in ipairs(stanza.tags) do |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
48 s = s..create_clone_string(tag, lookup, stanza.attr.xmlns)..";"; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
49 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
50 s = s..'};'; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
51 -- add children |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
52 for i,child in ipairs(stanza) do |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
53 if child.name then |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
54 s = s..create_clone_string(child, lookup, stanza.attr.xmlns)..";"; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
55 else |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
56 s = s..create_string_string(child)..";" |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
57 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
58 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
59 s = s..'}, stanza_mt)'; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
60 s = s:gsub('%.%.""', ""):gsub('([=;])""%.%.', "%1"):gsub(';"";', ";"); -- strip empty strings |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
61 local n = #lookup + 1; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
62 lookup[n] = s; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
63 lookup[stanza] = "_"..n; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
64 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
65 return lookup[stanza]; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
66 end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
67 local function create_cloner(stanza, chunkname) |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
68 local lookup = {}; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
69 local name = create_clone_string(stanza, lookup, ""); |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
70 local f = "local setmetatable,stanza_mt=...;return function(data)"; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
71 for i=1,#lookup do |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
72 f = f.."local _"..i.."="..lookup[i]..";"; |
3546
cb1600dea3ad
util.template: Optimized to be almost as fast as manual stanza building.
Waqas Hussain <waqas20@gmail.com>
parents:
3545
diff
changeset
|
73 end |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
74 f = f.."return "..name..";end"; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
75 local f,err = loadstring(f, chunkname); |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
76 if not f then error(err); end |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
77 return f(setmetatable, stanza_mt); |
3546
cb1600dea3ad
util.template: Optimized to be almost as fast as manual stanza building.
Waqas Hussain <waqas20@gmail.com>
parents:
3545
diff
changeset
|
78 end |
cb1600dea3ad
util.template: Optimized to be almost as fast as manual stanza building.
Waqas Hussain <waqas20@gmail.com>
parents:
3545
diff
changeset
|
79 |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
80 local template_mt = { __tostring = function(t) return t.name end }; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
81 local function create_template(templates, text) |
3545
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
82 local stanza, err = parse_xml(text); |
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
83 if not stanza then error(err); end |
4495
c0f5c78cb817
util.template: Refactoring to make the string->stanza conversion code more generic.
Waqas Hussain <waqas20@gmail.com>
parents:
3640
diff
changeset
|
84 trim_xml(stanza); |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
85 |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
86 local info = debug.getinfo(3, "Sl"); |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
87 info = info and ("template(%s:%d)"):format(info.short_src:match("[^\\/]*$"), info.currentline) or "template(unknown)"; |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
88 |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
89 local template = setmetatable({ apply = create_cloner(stanza, info), name = info, text = text }, template_mt); |
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
90 templates[text] = template; |
3545
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
91 return template; |
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
92 end |
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
93 |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
94 local templates = setmetatable({}, { __mode = 'k', __index = create_template }); |
3545
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
95 return function(text) |
3637
bd491def3efb
util.template: Rewritten to be much faster than the util.stanza stanza building API.
Waqas Hussain <waqas20@gmail.com>
parents:
3546
diff
changeset
|
96 return templates[text]; |
3545
c85f9a4ae1c4
util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
97 end; |