Software /
code /
prosody
Comparison
util/xmppstream.lua @ 3987:8fbf57722368
util.xmppstream: Optimized stanza building by bypassing the stanza API.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Wed, 29 Dec 2010 18:49:59 +0500 |
parent | 3927:1b57e83266f0 |
child | 4274:7cc426988bcc |
comparison
equal
deleted
inserted
replaced
3986:671a660b20f9 | 3987:8fbf57722368 |
---|---|
7 -- | 7 -- |
8 | 8 |
9 | 9 |
10 local lxp = require "lxp"; | 10 local lxp = require "lxp"; |
11 local st = require "util.stanza"; | 11 local st = require "util.stanza"; |
12 local stanza_mt = st.stanza_mt; | |
12 | 13 |
13 local tostring = tostring; | 14 local tostring = tostring; |
14 local t_insert = table.insert; | 15 local t_insert = table.insert; |
15 local t_concat = table.concat; | 16 local t_concat = table.concat; |
17 local t_remove = table.remove; | |
18 local setmetatable = setmetatable; | |
16 | 19 |
17 local default_log = require "util.logger".init("xmppstream"); | 20 local default_log = require "util.logger".init("xmppstream"); |
18 | 21 |
19 local error = error; | 22 local error = error; |
20 | 23 |
51 end | 54 end |
52 local stream_error_tag = stream_ns..ns_separator..(stream_callbacks.error_tag or "error"); | 55 local stream_error_tag = stream_ns..ns_separator..(stream_callbacks.error_tag or "error"); |
53 | 56 |
54 local stream_default_ns = stream_callbacks.default_ns; | 57 local stream_default_ns = stream_callbacks.default_ns; |
55 | 58 |
59 local stack = {}; | |
56 local chardata, stanza = {}; | 60 local chardata, stanza = {}; |
57 local non_streamns_depth = 0; | 61 local non_streamns_depth = 0; |
58 function xml_handlers:StartElement(tagname, attr) | 62 function xml_handlers:StartElement(tagname, attr) |
59 if stanza and #chardata > 0 then | 63 if stanza and #chardata > 0 then |
60 -- We have some character data in the buffer | 64 -- We have some character data in the buffer |
61 stanza:text(t_concat(chardata)); | 65 t_insert(stanza, t_concat(chardata)); |
62 chardata = {}; | 66 chardata = {}; |
63 end | 67 end |
64 local curr_ns,name = tagname:match(ns_pattern); | 68 local curr_ns,name = tagname:match(ns_pattern); |
65 if name == "" then | 69 if name == "" then |
66 curr_ns, name = "", curr_ns; | 70 curr_ns, name = "", curr_ns; |
100 end | 104 end |
101 if curr_ns == "jabber:client" and name ~= "iq" and name ~= "presence" and name ~= "message" then | 105 if curr_ns == "jabber:client" and name ~= "iq" and name ~= "presence" and name ~= "message" then |
102 cb_error(session, "invalid-top-level-element"); | 106 cb_error(session, "invalid-top-level-element"); |
103 end | 107 end |
104 | 108 |
105 stanza = st.stanza(name, attr); | 109 stanza = setmetatable({ name = name, attr = attr, tags = {} }, stanza_mt); |
106 else -- we are inside a stanza, so add a tag | 110 else -- we are inside a stanza, so add a tag |
107 stanza:tag(name, attr); | 111 t_insert(stack, stanza); |
112 local oldstanza = stanza; | |
113 stanza = setmetatable({ name = name, attr = attr, tags = {} }, stanza_mt); | |
114 t_insert(oldstanza, stanza); | |
115 t_insert(oldstanza.tags, stanza); | |
108 end | 116 end |
109 end | 117 end |
110 function xml_handlers:CharacterData(data) | 118 function xml_handlers:CharacterData(data) |
111 if stanza then | 119 if stanza then |
112 t_insert(chardata, data); | 120 t_insert(chardata, data); |
117 non_streamns_depth = non_streamns_depth - 1; | 125 non_streamns_depth = non_streamns_depth - 1; |
118 end | 126 end |
119 if stanza then | 127 if stanza then |
120 if #chardata > 0 then | 128 if #chardata > 0 then |
121 -- We have some character data in the buffer | 129 -- We have some character data in the buffer |
122 stanza:text(t_concat(chardata)); | 130 t_insert(stanza, t_concat(chardata)); |
123 chardata = {}; | 131 chardata = {}; |
124 end | 132 end |
125 -- Complete stanza | 133 -- Complete stanza |
126 local last_add = stanza.last_add; | 134 if #stack == 0 then |
127 if not last_add or #last_add == 0 then | |
128 if tagname ~= stream_error_tag then | 135 if tagname ~= stream_error_tag then |
129 cb_handlestanza(session, stanza); | 136 cb_handlestanza(session, stanza); |
130 else | 137 else |
131 cb_error(session, "stream-error", stanza); | 138 cb_error(session, "stream-error", stanza); |
132 end | 139 end |
133 stanza = nil; | 140 stanza = nil; |
134 else | 141 else |
135 stanza:up(); | 142 stanza = t_remove(stack); |
136 end | 143 end |
137 else | 144 else |
138 if tagname == stream_tag then | 145 if tagname == stream_tag then |
139 if cb_streamclosed then | 146 if cb_streamclosed then |
140 cb_streamclosed(session); | 147 cb_streamclosed(session); |
145 curr_ns, name = "", curr_ns; | 152 curr_ns, name = "", curr_ns; |
146 end | 153 end |
147 cb_error(session, "parse-error", "unexpected-element-close", name); | 154 cb_error(session, "parse-error", "unexpected-element-close", name); |
148 end | 155 end |
149 stanza, chardata = nil, {}; | 156 stanza, chardata = nil, {}; |
157 stack = {}; | |
150 end | 158 end |
151 end | 159 end |
152 | 160 |
153 local function reset() | 161 local function reset() |
154 stanza, chardata = nil, {}; | 162 stanza, chardata = nil, {}; |
163 stack = {}; | |
155 end | 164 end |
156 | 165 |
157 local function set_session(stream, new_session) | 166 local function set_session(stream, new_session) |
158 session = new_session; | 167 session = new_session; |
159 log = new_session.log or default_log; | 168 log = new_session.log or default_log; |