Software / code / prosody
Annotate
util/template.lua @ 6988:329d5fb8a9d3
Merge 0.10->trunk
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Thu, 10 Dec 2015 18:58:30 +0000 |
| parent | 6777:5de6b93d0190 |
| child | 7196:94ec474debf5 |
| 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 |
|
6777
5de6b93d0190
util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents:
5214
diff
changeset
|
12 local _ENV = nil; |
|
3545
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; |