Mercurial > prosody-hg
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 |
| parents | 1b57e83266f0 |
| children | 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; |
