| Class | Jabber::StreamParser |
| In: |
lib/xmpp4r/streamparser.rb
|
| Parent: | Object |
The StreamParser uses REXML to parse the incoming XML stream of the Jabber protocol and fires XMPPStanza at the Connection instance.
| started | [R] | status if the parser is started |
Constructs a parser for the supplied stream (socket input)
| stream: | [IO] Socket input stream |
| listener: | [Object.receive(XMPPStanza)] The listener (usually a Jabber::Protocol::Connection instance) |
# File lib/xmpp4r/streamparser.rb, line 26
26: def initialize(stream, listener)
27: @stream = stream
28: @listener = listener
29: @current = nil
30: end
Begins parsing the XML stream and does not return until the stream closes.
# File lib/xmpp4r/streamparser.rb, line 36
36: def parse
37: @started = false
38: begin
39: parser = REXML::Parsers::SAX2Parser.new @stream
40:
41: parser.listen( :start_element ) do |uri, localname, qname, attributes|
42: e = REXML::Element.new(qname)
43: e.add_attributes attributes
44: @current = @current.nil? ? e : @current.add_element(e)
45:
46: # Handling <stream:stream> not only when it is being
47: # received as a top-level tag but also as a child of the
48: # top-level element itself. This way, we handle stream
49: # restarts (ie. after SASL authentication).
50: if @current.name == 'stream' and @current.parent.nil?
51: @started = true
52: @listener.receive(@current)
53: @current = nil
54: end
55: end
56:
57: parser.listen( :end_element ) do |uri, localname, qname|
58: if qname == 'stream:stream' and @current.nil?
59: @started = false
60: @listener.parser_end
61: else
62: @listener.receive(@current) unless @current.parent
63: @current = @current.parent
64: end
65: end
66:
67: parser.listen( :end_document ) do
68: raise Jabber::ServerDisconnected, "Server Disconnected!"
69: end
70:
71: parser.listen( :characters ) do | text |
72: @current.add(REXML::Text.new(text.to_s, @current.whitespace, nil, true)) if @current
73: end
74:
75: parser.listen( :cdata ) do | text |
76: @current.add(REXML::CData.new(text)) if @current
77: end
78:
79: parser.parse
80: rescue REXML::ParseException => e
81: @listener.parse_failure(e)
82: end
83: end