### Home Classes Methods

### In Files

- lib/dbus/marshall.rb

### Parent

Object

### Methods

- ::make_variant
- ::new
- #align
- #append
- #append_signature
- #append_simple_string
- #append_string
- #array
- #num_align
- #struct

### Files

- README

### Class/Module Index

Quicksearch

- DBus
- DBus::ASessionBus
- DBus::ASystemBus
- DBus::AuthenticationFailed
- DBus::Authenticator
- DBus::Client
- DBus::Connection
- DBus::Connection::NameRequestError
- DBus::DBusCookieSHA1
- DBus::Error
- DBus::ErrorMessage
- DBus::External
- DBus::FormalParameter
- DBus::IncompleteBufferException
- DBus::Interface
- DBus::InterfaceElement
- DBus::IntrospectXMLParser
- DBus::InvalidClassDefinition
- DBus::InvalidDestinationName
- DBus::InvalidIntrospectionData
- DBus::InvalidMethodName
- DBus::InvalidPacketException
- DBus::InvalidParameters
- DBus::Main
- DBus::MatchRule
- DBus::MatchRuleException
- DBus::Message
- DBus::Method
- DBus::MethodNotImplemented
- DBus::MethodReturnMessage
- DBus::Node
- DBus::Object
- DBus::Object::UndefinedInterface
- DBus::PacketMarshaller
- DBus::PacketUnmarshaller
- DBus::ProxyObject
- DBus::ProxyObjectFactory
- DBus::ProxyObjectInterface
- DBus::RemoteBus
- DBus::Service
- DBus::SessionBus
- DBus::Signal
- DBus::SystemBus
- DBus::Type
- DBus::Type::Parser
- DBus::Type::SignatureException
- DBus::Type::Type
- DBus::TypeException
- DBus::UnknownSignal
- Integer

No matching classes.

# DBus::PacketMarshaller

D-Bus packet marshaller class

Class that handles the conversion (marshalling) of Ruby objects to (binary) payload data.

### Attributes

packet[R]

The current or result packet. FIXME: allow access only when marshalling is finished

### Public Class Methods

make_variant(value) click to toggle source

Make a [signature, value] pair for a variant

    # File lib/dbus/marshall.rb, line 414
    def self.make_variant(value)
      # TODO: mix in _make_variant to String, Integer...
      if value == true
        ["b", true]
      elsif value == false
        ["b", false]
      elsif value.nil?
        ["b", nil]
      elsif value.is_a? Float
        ["d", value]
      elsif value.is_a? Symbol
        ["s", value.to_s]
      elsif value.is_a? Array
        ["av", value.map {|i| make_variant(i) }]
      elsif value.is_a? Hash
        h = {}
        value.each_key {|k| h[k] = make_variant(value[k]) }
        ["a{sv}", h]
      elsif value.respond_to? :to_str
        ["s", value.to_str]
      elsif value.respond_to? :to_int
        i = value.to_int
        if -2_147_483_648 <= i && i < 2_147_483_648
          ["i", i]
        else
          ["x", i]
        end
      end
    end

new(offset = 0) click to toggle source

Create a new marshaller, setting the current packet to the empty packet.

    # File lib/dbus/marshall.rb, line 251
    def initialize(offset = 0)
      @packet = ""
      @offset = offset          # for correct alignment of nested marshallers
    end

### Public Instance Methods

align(a) click to toggle source

Align the buffer with NULL (0) bytes on a byte length of a.

    # File lib/dbus/marshall.rb, line 268
    def align(a)
      @packet = @packet.ljust(num_align(@offset + @packet.bytesize, a) - @offset, 0.chr)
    end

append(type, val) click to toggle source

Append a value val to the packet based on its type.

Host native endianness is used, declared in Message#marshall

    # File lib/dbus/marshall.rb, line 312
    def append(type, val)
      raise TypeException, "Cannot send nil" if val.nil?

      type = type.chr if type.kind_of?(Fixnum)
      type = Type::Parser.new(type).parse[0] if type.kind_of?(String)
      case type.sigtype
      when Type::BYTE
        @packet += val.chr
      when Type::UINT32
        align(4)
        @packet += [val].pack("L")
      when Type::UINT64
        align(8)
        @packet += [val].pack("Q")
      when Type::INT64
        align(8)
        @packet += [val].pack("q")
      when Type::INT32
        align(4)
        @packet += [val].pack("l")
      when Type::UINT16
        align(2)
        @packet += [val].pack("S")
      when Type::INT16
        align(2)
        @packet += [val].pack("s")
      when Type::DOUBLE
        align(8)
        @packet += [val].pack("d")
      when Type::BOOLEAN
        align(4)
        if val
          @packet += [1].pack("L")
        else
          @packet += [0].pack("L")
        end
      when Type::OBJECT_PATH
        append_string(val)
      when Type::STRING
        append_string(val)
      when Type::SIGNATURE
        append_signature(val)
      when Type::VARIANT
        vartype = nil
        if val.is_a?(Array) and val.size == 2
          if val[0].is_a?(DBus::Type::Type)
            vartype, vardata = val
          elsif val[0].is_a?(String)
            begin
              parsed = Type::Parser.new(val[0]).parse
              vartype = parsed[0] if parsed.size == 1
              vardata = val[1]
            rescue Type::SignatureException
              # no assignment
            end
          end
        end
        if vartype.nil?
          vartype, vardata = PacketMarshaller.make_variant(val)
          vartype = Type::Parser.new(vartype).parse[0]
        end

        append_signature(vartype.to_s)
        align(vartype.alignment)
        sub = PacketMarshaller.new(@offset + @packet.bytesize)
        sub.append(vartype, vardata)
        @packet += sub.packet
      when Type::ARRAY
        if val.kind_of?(Hash)
          raise TypeException, "Expected an Array but got a Hash" if type.child.sigtype != Type::DICT_ENTRY
          # Damn ruby rocks here
          val = val.to_a
        end
        if not val.kind_of?(Array)
          raise TypeException, "Expected an Array but got a #{val.class}"
        end
        array(type.child) do
          val.each do |elem|
            append(type.child, elem)
          end
        end
      when Type::STRUCT, Type::DICT_ENTRY
        # TODO use duck typing, val.respond_to?
        raise TypeException, "Struct/DE expects an Array" if not val.kind_of?(Array)
        if type.sigtype == Type::DICT_ENTRY and val.size != 2
          raise TypeException, "Dict entry expects a pair"
        end
        if type.members.size != val.size
          raise TypeException, "Struct/DE has #{val.size} elements but type info for #{type.members.size}"
        end
        struct do
          type.members.zip(val).each do |t, v|
            append(t, v)
          end
        end
      else
        raise NotImplementedError,
          "sigtype: #{type.sigtype} (#{type.sigtype.chr})"
      end
    end

append_signature(str) click to toggle source

Append the the signature signature itself to the packet.

    # File lib/dbus/marshall.rb, line 279
    def append_signature(str)
      @packet += str.bytesize.chr + str + "\00""
    end

append_simple_string(s) click to toggle source

Append a string of bytes without type.

    # File lib/dbus/marshall.rb, line 305
    def append_simple_string(s)
      @packet += s + "\00""
    end

append_string(str) click to toggle source

Append the the string str itself to the packet.

    # File lib/dbus/marshall.rb, line 273
    def append_string(str)
      align(4)
      @packet += [str.bytesize].pack("L") + [str].pack("Z*")
    end

array(type) click to toggle source

Append the array type type to the packet and allow for appending the child elements.

    # File lib/dbus/marshall.rb, line 285
    def array(type)
      # Thanks to Peter Rullmann for this line
      align(4)
      sizeidx = @packet.bytesize
      @packet += "ABCD"
      align(type.alignment)
      contentidx = @packet.bytesize
      yield
      sz = @packet.bytesize - contentidx
      raise InvalidPacketException if sz > 67108864
      @packet[sizeidx...sizeidx + 4] = [sz].pack("L")
    end

num_align(n, a) click to toggle source

Round n up to the specified power of two, a

    # File lib/dbus/marshall.rb, line 257
    def num_align(n, a)
      case a
      when 1, 2, 4, 8
        bits = a - 1
        n + bits & ~bits
      else
        raise "Unsupported alignment"
      end
    end

struct() click to toggle source

Align and allow for appending struct fields.

    # File lib/dbus/marshall.rb, line 299
    def struct
      align(8)
      yield
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.