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