Class: Babylon::XmppParser

Inherits:
Nokogiri::XML::SAX::Document
  • Object
show all
Defined in:
lib/babylon/xmpp_parser.rb

Overview

This is the XML SAX Parser that accepts “pushed” content

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(callback) ⇒ XmppParser

Initialize the parser and adds the callback that will be called upon stanza completion



11
12
13
14
15
16
# File 'lib/babylon/xmpp_parser.rb', line 11

def initialize(callback)
  @callback = callback
  @buffer = ""
  super()
  reset
end

Instance Attribute Details

#docObject

Returns the value of attribute doc.



7
8
9
# File 'lib/babylon/xmpp_parser.rb', line 7

def doc
  @doc
end

#elemObject

Returns the value of attribute elem.



7
8
9
# File 'lib/babylon/xmpp_parser.rb', line 7

def elem
  @elem
end

#parserObject

Returns the value of attribute parser.



7
8
9
# File 'lib/babylon/xmpp_parser.rb', line 7

def parser
  @parser
end

Instance Method Details

#characters(string) ⇒ Object

Adds characters to the current element (being parsed)



33
34
35
36
# File 'lib/babylon/xmpp_parser.rb', line 33

def characters(string)
  @buffer ||= ""
  @buffer += string 
end

#clear_characters_bufferObject

Clears the characters buffer



59
60
61
62
63
64
65
# File 'lib/babylon/xmpp_parser.rb', line 59

def clear_characters_buffer
  if @buffer && @elem
    @buffer.strip!
    @elem.add_child(Nokogiri::XML::Text.new(Babylon.decode_xml(@buffer), @doc)) unless @buffer.empty?
    @buffer = nil # empty the buffer
  end
end

#end_element(name) ⇒ Object

Terminates the current element and calls the callback



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/babylon/xmpp_parser.rb', line 69

def end_element(name)
  clear_characters_buffer
  if @elem
    if @elem.parent == @doc
      # If we're actually finishing the stanza (a stanza is always a document's root)
      @callback.call(@elem) 
      # We delete the current element and the doc (1 doc per stanza policy)
      @elem = @doc = nil 
    else
      @elem = @elem.parent 
    end 
  else 
    # Not sure what to do since it seems we're not processing any element at this time, so how can one end?
  end 
end

#push(data) ⇒ Object

Pushes the received data to the parser. The parser will then callback the document’s methods (start_tag, end_tag… etc)



27
28
29
# File 'lib/babylon/xmpp_parser.rb', line 27

def push(data)
  @parser << data
end

#resetObject

Resets the Pushed SAX Parser.



20
21
22
23
# File 'lib/babylon/xmpp_parser.rb', line 20

def reset
  @parser = Nokogiri::XML::SAX::PushParser.new(self, "UTF-8")
  @elem = @doc = nil
end

#start_element(qname, attributes = []) ⇒ Object

Instantiate a new current Element, adds the corresponding attributes and namespaces. The new element is eventually added to a parent element (if present). If no element is being parsed, then, we create a new document, to which we add this new element as root. (we create one document per stanza to avoid memory problems)



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/babylon/xmpp_parser.rb', line 42

def start_element(qname, attributes = [])
  clear_characters_buffer
  @doc ||= Nokogiri::XML::Document.new
  @elem ||= @doc # If we have no current element, then, we take the doc
  @elem = @elem.add_child(Nokogiri::XML::Element.new(qname, @doc))
  add_namespaces_and_attributes_to_current_node(attributes)
  
  if @elem.name == "stream:stream"
    # We activate the callback since this element  will never end.
    @callback.call(@elem)
    @doc = @elem = nil # Let's prepare for the next stanza
    # And then, we start a new Sax Push Parser
  end
end