Mon, 06 Dec 2010 04:00:24 +0000
A few changes to support RSS (converts to Atom \o/)
0 | 1 | -- Prosody IM |
2 | -- Copyright (C) 2008-2010 Matthew Wild | |
3 | -- Copyright (C) 2008-2010 Waqas Hussain | |
4 | -- | |
5 | -- This project is MIT/X11 licensed. Please see the | |
6 | -- COPYING file in the source package for more information. | |
7 | -- | |
8 | ||
9 | ||
10 | local lxp = require "lxp"; | |
11 | local st = require "stanza"; | |
12 | ||
13 | local tostring = tostring; | |
14 | local t_insert = table.insert; | |
15 | local t_concat = table.concat; | |
16 | ||
17 | local error = error; | |
18 | ||
19 | module "xmppstream" | |
20 | ||
21 | local new_parser = lxp.new; | |
22 | ||
23 | local ns_prefixes = { | |
24 | ["http://www.w3.org/XML/1998/namespace"] = "xml"; | |
25 | }; | |
26 | ||
27 | local xmlns_streams = "http://etherx.jabber.org/streams"; | |
28 | ||
29 | local ns_separator = "\1"; | |
30 | local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$"; | |
31 | ||
32 | function new_sax_handlers(session, stream_callbacks) | |
33 | local xml_handlers = {}; | |
34 | ||
35 | local log = session.log; | |
36 | ||
37 | local cb_streamopened = stream_callbacks.streamopened; | |
38 | local cb_streamclosed = stream_callbacks.streamclosed; | |
39 | local cb_error = stream_callbacks.error or function(session, e) error("XML stream error: "..tostring(e)); end; | |
40 | local cb_handlestanza = stream_callbacks.handlestanza; | |
41 | ||
42 | local stream_ns = stream_callbacks.stream_ns or xmlns_streams; | |
43 | local stream_tag = stream_ns..ns_separator..(stream_callbacks.stream_tag or "stream"); | |
44 | local stream_error_tag = stream_ns..ns_separator..(stream_callbacks.error_tag or "error"); | |
45 | ||
46 | local stream_default_ns = stream_callbacks.default_ns; | |
47 | ||
48 | local chardata, stanza = {}; | |
49 | function xml_handlers:StartElement(tagname, attr) | |
50 | if stanza and #chardata > 0 then | |
51 | -- We have some character data in the buffer | |
52 | stanza:text(t_concat(chardata)); | |
53 | chardata = {}; | |
54 | end | |
55 | local curr_ns,name = tagname:match(ns_pattern); | |
56 | if name == "" then | |
57 | curr_ns, name = "", curr_ns; | |
58 | end | |
59 | ||
60 | if curr_ns ~= stream_default_ns then | |
61 | attr.xmlns = curr_ns; | |
62 | end | |
63 | ||
64 | -- FIXME !!!!! | |
65 | for i=1,#attr do | |
66 | local k = attr[i]; | |
67 | attr[i] = nil; | |
68 | local ns, nm = k:match(ns_pattern); | |
69 | if nm ~= "" then | |
70 | ns = ns_prefixes[ns]; | |
71 | if ns then | |
72 | attr[ns..":"..nm] = attr[k]; | |
73 | attr[k] = nil; | |
74 | end | |
75 | end | |
76 | end | |
77 | ||
78 | if not stanza then --if we are not currently inside a stanza | |
79 | if session.notopen then | |
3
ab02540afcf3
A few changes to support RSS (converts to Atom \o/)
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
80 | if cb_streamopened then |
ab02540afcf3
A few changes to support RSS (converts to Atom \o/)
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
81 | cb_streamopened(session, attr, name); |
0 | 82 | end |
83 | return; | |
84 | end | |
85 | stanza = st.stanza(name, attr); | |
86 | else -- we are inside a stanza, so add a tag | |
87 | attr.xmlns = nil; | |
88 | if curr_ns ~= stream_default_ns then | |
89 | attr.xmlns = curr_ns; | |
90 | end | |
91 | stanza:tag(name, attr); | |
92 | end | |
93 | end | |
94 | function xml_handlers:CharacterData(data) | |
95 | if stanza then | |
96 | t_insert(chardata, data); | |
97 | end | |
98 | end | |
99 | function xml_handlers:EndElement(tagname) | |
100 | if stanza then | |
101 | if #chardata > 0 then | |
102 | -- We have some character data in the buffer | |
103 | stanza:text(t_concat(chardata)); | |
104 | chardata = {}; | |
105 | end | |
106 | -- Complete stanza | |
107 | if #stanza.last_add == 0 then | |
108 | if tagname ~= stream_error_tag then | |
109 | cb_handlestanza(session, stanza); | |
110 | else | |
111 | cb_error(session, "stream-error", stanza); | |
112 | end | |
113 | stanza = nil; | |
114 | else | |
115 | stanza:up(); | |
116 | end | |
117 | else | |
3
ab02540afcf3
A few changes to support RSS (converts to Atom \o/)
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
118 | if cb_streamclosed then |
ab02540afcf3
A few changes to support RSS (converts to Atom \o/)
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
119 | cb_streamclosed(session); |
0 | 120 | end |
121 | stanza, chardata = nil, {}; | |
122 | end | |
123 | end | |
124 | ||
125 | local function reset() | |
126 | stanza, chardata = nil, {}; | |
127 | end | |
128 | ||
129 | return xml_handlers, { reset = reset }; | |
130 | end | |
131 | ||
132 | function new(session, stream_callbacks) | |
133 | local handlers, meta = new_sax_handlers(session, stream_callbacks); | |
134 | local parser = new_parser(handlers, ns_separator); | |
135 | local parse = parser.parse; | |
136 | ||
137 | return { | |
138 | reset = function () | |
139 | parser = new_parser(handlers, ns_separator); | |
140 | parse = parser.parse; | |
141 | meta.reset(); | |
142 | end, | |
143 | feed = function (self, data) | |
144 | return parse(parser, data); | |
145 | end | |
146 | }; | |
147 | end | |
148 | ||
149 | return _M; |