Next: , Previous: Inspection, Up: Top

3 Mapping Lisp types and D-Bus types.

D-Bus method calls and signals accept usually several arguments as parameters, either as input parameter, or as output parameter. Every argument belongs to a D-Bus type.

Such arguments must be mapped between the value encoded as a D-Bus type, and the corresponding type of Lisp objects. The mapping is applied Lisp object ==> D-Bus type for input parameters, and D-Bus type ==> Lisp object for output parameters.

3.1 Input parameters.

Input parameters for D-Bus methods and signals occur as arguments of a Lisp function call. The following mapping to D-Bus types is applied, when the corresponding D-Bus message is created:

     

Lisp type D-Bus type

t and nil ==> DBUS_TYPE_BOOLEAN
natural number ==> DBUS_TYPE_UINT32
negative integer ==> DBUS_TYPE_INT32
float ==> DBUS_TYPE_DOUBLE
string ==> DBUS_TYPE_STRING
list ==> DBUS_TYPE_ARRAY

Other Lisp objects, like symbols or hash tables, are not accepted as input parameters.

If it is necessary to use another D-Bus type, a corresponding type symbol can be prepended to the corresponding Lisp object. Basic D-Bus types are represented by the type symbols :byte, :boolean, :int16, :uint16, :int32, :uint32, :int64, :uint64, :double, :string, :object-path, :signature and :unix-fd.

Example:

     (dbus-call-method ... NAT-NUMBER STRING)

is equivalent to

     (dbus-call-method ... :uint32 NAT-NUMBER :string STRING)

but different to

     (dbus-call-method ... :int32 NAT-NUMBER :signature STRING)

The value for a byte D-Bus type can be any integer in the range 0 through 255. If a character is used as argument, modifiers represented outside this range are stripped of. For example, :byte ?x is equal to :byte ?\M-x, but it is not equal to :byte ?\C-x or :byte ?\M-\C-x.

Signed and unsigned integer D-Bus types expect a corresponding integer value. If the value does not fit Emacs's integer range, it is also possible to use an equivalent floating point number.

A D-Bus compound type is always represented as a list. The car of this list can be the type symbol :array, :variant, :struct or :dict-entry, which would result in a corresponding D-Bus container. :array is optional, because this is the default compound D-Bus type for a list.

The objects being elements of the list are checked according to the D-Bus compound type rules.

If an empty array needs an element D-Bus type other than string, it can contain exactly one element of D-Bus type :signature. The value of this element (a string) is used as the signature of the elements of this array. Example:

     (dbus-call-method
       :session "org.freedesktop.Notifications"
       "/org/freedesktop/Notifications"
       "org.freedesktop.Notifications" "Notify"
       "GNU Emacs"                 ;; Application name.
       0                           ;; No replacement of other notifications.
       ""                          ;; No icon.
       "Notification summary"      ;; Summary.
       (format                     ;; Body.
         "This is a test notification, raised from\n%S" (emacs-version))
       '(:array)                   ;; No actions (empty array of strings).
       '(:array :signature "{sv}") ;; No hints
                                   ;; (empty array of dictionary entries).
       :int32 -1)                  ;; Default timeout.
     
     ⇒ 3
— Function: dbus-string-to-byte-array string

Sometimes, D-Bus methods require as input parameter an array of bytes, instead of a string. If it is guaranteed, that string is an UTF8 string, this function performs the conversion. Example:

          (dbus-string-to-byte-array "/etc/hosts")
          
          ⇒ (:array :byte 47 :byte 101 :byte 116 :byte 99 :byte 47
                     :byte 104 :byte 111 :byte 115 :byte 116 :byte 115)
— Function: dbus-escape-as-identifier string

Escape an arbitrary string so it follows the rules for a C identifier. The escaped string can be used as object path component, interface element component, bus name component or member name in D-Bus.

The escaping consists of replacing all non-alphanumerics, and the first character if it's a digit, with an underscore and two lower-case hex digits. As a special case, "" is escaped to "_". Example:

          (dbus-escape-as-identifier "0123abc_xyz\x01\xff")
          
          ⇒ "_30123abc_5fxyz_01_ff"

3.2 Output parameters.

Output parameters of D-Bus methods and signals are mapped to Lisp objects.

     

D-Bus type Lisp type

DBUS_TYPE_BOOLEAN ==> t or nil
DBUS_TYPE_BYTE ==> natural number
DBUS_TYPE_UINT16 ==> natural number
DBUS_TYPE_INT16 ==> integer
DBUS_TYPE_UINT32 ==> natural number or float
DBUS_TYPE_UNIX_FD ==> natural number or float
DBUS_TYPE_INT32 ==> integer or float
DBUS_TYPE_UINT64 ==> natural number or float
DBUS_TYPE_INT64 ==> integer or float
DBUS_TYPE_DOUBLE ==> float
DBUS_TYPE_STRING ==> string
DBUS_TYPE_OBJECT_PATH ==> string
DBUS_TYPE_SIGNATURE ==> string
DBUS_TYPE_ARRAY ==> list
DBUS_TYPE_VARIANT ==> list
DBUS_TYPE_STRUCT ==> list
DBUS_TYPE_DICT_ENTRY ==> list

A float object in case of DBUS_TYPE_UINT32, DBUS_TYPE_INT32, DBUS_TYPE_UINT64, DBUS_TYPE_INT64 and DBUS_TYPE_UNIX_FD is returned, when the C value exceeds the Emacs number size range.

The resulting list of the last 4 D-Bus compound types contains as elements the elements of the D-Bus container, mapped according to the same rules.

The signal PropertyModified, discussed as example in Inspection, would offer as Lisp data the following object (BOOL stands here for either nil or t):

     (INTEGER ((STRING BOOL BOOL) (STRING BOOL BOOL) ...))
— Function: dbus-byte-array-to-string byte-array &optional multibyte

If a D-Bus method or signal returns an array of bytes, which are known to represent an UTF8 string, this function converts byte-array to the corresponding string. The string is unibyte encoded, unless multibyte is non-nil. Example:

          (dbus-byte-array-to-string '(47 101 116 99 47 104 111 115 116 115))
          
          ⇒ "/etc/hosts"
— Function: dbus-unescape-from-identifier string

Retrieve the original string from the encoded string as unibyte string. string must have been encoded with dbus-escape-as-identifier. Example:

          (dbus-unescape-from-identifier "_30123abc_5fxyz_01_ff")
          
          ⇒ "0123abc_xyz\x01\xff"

If the original string used in dbus-escape-as-identifier is a multibyte string, it cannot be expected that this function returns that string:

          (string-equal
            (dbus-unescape-from-identifier
              (dbus-escape-as-identifier "Grüß Göttin"))
            "Grüß Göttin")
          
          ⇒ nil