util/xmppstream.lua

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
local tblinsert = table.insert
10
 
11
local lex = require "util.xmllex";
12
local index = lex.index
13
local tagindex_to_tree  = lex.tagindex_to_tree;
14
local get_name, get_attr = lex.get_name, lex.get_attr;
15
 
16
local default_log = require "util.logger".init("xmppstream");
17
 
18
local xmlns_streams = "http://etherx.jabber.org/streams";
19
 
20
local function new(session, stream_callbacks)
21
	local partial
22
	local openindexes = { }
23
	local lastindex = 0
24
	
25
	return {
26
		reset = function ( )
27
			partial = nil
28
			openindexes = { }
29
			lastindex = 0
30
		end ;
31
		feed = function ( stream , data )
32
			--print("FFEED", data)
33
			partial = index ( data , partial )
34
			local tmp = lastindex
35
			lastindex = #partial - 1
36
			for i = tmp + 1 , #partial - 1 do
37
				local v = partial [ i ]
38
				
39
				if v.finish then
40
					if v.type == "open" or v.type == "selfclosing" then
41
						tblinsert ( openindexes , i )
42
						if #openindexes == 1 then
43
							local vstr = tostring(v);
44
							local name = get_name ( vstr )
45
							if name == "stream:stream" then
46
								local attr = get_attr ( vstr );
47
								stream_callbacks.streamopened ( session , attr )
48
							end
49
						end
50
					end
51
					if v.type == "close" or v.type == "selfclosing" then
52
						if #openindexes == 2 then -- If closing level 2...
53
							local attr = get_attr ( tostring(partial[openindexes[1]]) )
54
							local stanza = tagindex_to_tree ( partial , openindexes [ #openindexes ] , i , {
55
								attr = attr,
56
							} )
57
							if stanza[1].attr.xmlns == attr.xmlns then
58
								stanza[1].attr.xmlns = false;
59
							end
60
							stream_callbacks.handlestanza ( session , stanza[1] )
61
						elseif #openindexes == 1 then
62
							local prefix, name = get_name ( tostring(v) )
63
							if name == "stream" then
64
								stream_callbacks.streamclosed ( session )
65
							end
66
						end
67
						openindexes [ #openindexes ] = nil
68
					end
69
				end
70
			end
71
			return true
72
		end ;
73
		set_session = function ( newsession ) session = newsession end
74
	};
75
end
76
 
77
return {
78
	new = new ;
79
}