# 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.

    # File lib/dbus/xml.rb, line 29
    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 103
    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
      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(e, m) click to toggle source

Parses a method signature XML element e and initialises method/signal m.

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