class DBus::IntrospectXMLParser

D-Bus introspect XML parser class

This class parses introspection XML of an object and constructs a tree of Node, Interface, Method, Signal instances.

Attributes

backend[RW]

Public Class Methods

new(xml) click to toggle source

Creates a new parser for XML data in string xml. @param xml [String]

# File lib/dbus/xml.rb, line 37
def initialize(xml)
  @xml = xml
end

Public Instance Methods

parse() click to toggle source

@return [Array(Array<Interface>,Array<String>)]

a pair: [list of Interfaces, list of direct subnode names]
# File lib/dbus/xml.rb, line 117
def parse
  # Using a Hash instead of a list helps merge split-up interfaces,
  # a quirk observed in ModemManager (I#41).
  interfaces = Hash.new do |hash, missing_key|
    hash[missing_key] = Interface.new(missing_key)
  end
  subnodes = []
  t = Time.now

  d = IntrospectXMLParser.backend.new(@xml)
  d.each("node/node") do |e|
    subnodes << e["name"]
  end
  d.each("node/interface") do |e|
    i = interfaces[e["name"]]
    e.each("method") do |me|
      m = Method.new(me["name"])
      parse_methsig(me, m)
      i << m
    end
    e.each("signal") do |se|
      s = Signal.new(se["name"])
      parse_methsig(se, s)
      i << s
    end
    e.each("property") do |pe|
      p = Property.from_xml(pe)
      i << p
    end
  end
  d = Time.now - t
  if d > 2
    DBus.logger.debug "Some XML took more that two secs to parse. Optimize me!"
  end
  [interfaces.values, subnodes]
end

Private Instance Methods

parse_methsig(elem, methsig) click to toggle source

Parses a method signature XML element elem and initialises method/signal methsig. @param elem [AbstractXML::Node]

# File lib/dbus/xml.rb, line 160
def parse_methsig(elem, methsig)
  elem.each("arg") do |ae|
    name = ae["name"]
    dir = ae["direction"]
    sig = ae["type"]
    case methsig
    when DBus::Signal
      # Direction can only be "out", ignore it
      methsig.add_fparam(name, sig)
    when DBus::Method
      case dir
      # This is a method, so dir defaults to "in"
      when "in", nil
        methsig.add_fparam(name, sig)
      when "out"
        methsig.add_return(name, sig)
      end
    else
      raise NotImplementedError, dir
    end
  end
end