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