Object
D-Bus packet marshaller class
Class that handles the conversion (marshalling) of Ruby objects to (binary) payload data.
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
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 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 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 a string of bytes without type.
# File lib/dbus/marshall.rb, line 305 def append_simple_string(s) @packet += s + "\00"" end
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
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
Generated with the Darkfish Rdoc Generator 2.