dbus: Type Conversion

 
 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.
 
    • An array must contain only elements of the same D-Bus type.  It can
      be empty.
 
    • A variant must contain only one single element.
 
    • A dictionary entry must be element of an array, and it must contain
      only a key-value pair of two elements, with a basic D-Bus type key.
 
    • There is no restriction for structs.
 
    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 See
 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