]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
dbus-send: Add support for variants to arrays and dictionaries
authorFrederik Van Bogaert <frederik.vanbogaert@mind.be>
Sat, 17 Apr 2021 22:02:45 +0000 (00:02 +0200)
committerSimon McVittie <smcv@collabora.com>
Mon, 23 May 2022 12:15:02 +0000 (12:15 +0000)
Adds support for:
* Arrays of variants
* Dictionaries with variants as keys

Manually tested and confirmed working using dbus-monitor.
Example usage:
```
$ dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus \
    com.example.SomeExample dict:string:variant:one,int16:1
```
In dbus-monitor:
```
method call time=1652796044.991509 sender=:1.84 -> destination=org.freedesktop.DBus
    serial=2 path=/org/freedesktop/DBus; interface=com.example; member=SomeExample
   array [
      dict entry(
         string "one"
         variant             int16 1
      )
   ]
```

Signed-off-by: Frederik Van Bogaert <frederik.vanbogaert@mind.be>
tools/dbus-send.c

index 65f9854eec7ec6843f2859a36462b87de458a190..86858c505cb0e4cda75b8deac8bfffc5c06e10de 100644 (file)
@@ -69,6 +69,8 @@ handle_oom (dbus_bool_t success)
     }
 }
 
+static int type_from_name (const char *arg, dbus_bool_t allow_container_types);
+
 static void
 append_arg (DBusMessageIter *iter, int type, const char *value)
 {
@@ -151,6 +153,33 @@ append_arg (DBusMessageIter *iter, int type, const char *value)
        }
       break;
 
+    case DBUS_TYPE_VARIANT:
+      {
+        DBusMessageIter subiter;
+
+        char sig[2] = "\0\0";
+        char *subtype = strdup (value);
+        char *c = NULL;
+
+        handle_oom (subtype != NULL);
+        c = strchr (subtype, ':');
+        if (!c)
+          {
+            fprintf (stderr, "%s: missing variant subtype specifier\n",
+                     appname);
+            exit (1);
+          }
+        *c = '\0';
+
+        sig[0] = (char) type_from_name (subtype, TRUE);
+
+        handle_oom (dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT,
+                                                      sig, &subiter));
+        append_arg (&subiter, sig[0], c + 1);
+        free (subtype);
+        ret = dbus_message_iter_close_container (iter, &subiter);
+        break;
+      }
     default:
       fprintf (stderr, "%s: Unsupported data type %c\n", appname, (char) type);
       exit (1);
@@ -210,7 +239,7 @@ append_dict (DBusMessageIter *iter, int keytype, int valtype, const char *value)
 }
 
 static int
-type_from_name (const char *arg)
+type_from_name (const char *arg, dbus_bool_t allow_container_types)
 {
   int type;
   if (!strcmp (arg, "string"))
@@ -235,6 +264,16 @@ type_from_name (const char *arg)
     type = DBUS_TYPE_BOOLEAN;
   else if (!strcmp (arg, "objpath"))
     type = DBUS_TYPE_OBJECT_PATH;
+  else if (!strcmp(arg, "variant"))
+    {
+        if (!allow_container_types)
+          {
+            fprintf (stderr, "%s: A variant cannot be the key in a dictionary\n", appname);
+            exit (1);
+          }
+
+        type = DBUS_TYPE_VARIANT;
+    }
   else
     {
       fprintf (stderr, "%s: Unknown type \"%s\"\n", appname, arg);
@@ -609,7 +648,7 @@ main (int argc, char *argv[])
       if (arg[0] == 0)
        type2 = DBUS_TYPE_STRING;
       else
-       type2 = type_from_name (arg);
+       type2 = type_from_name (arg, FALSE);
 
       if (container_type == DBUS_TYPE_DICT_ENTRY)
        {
@@ -622,7 +661,7 @@ main (int argc, char *argv[])
              exit (1);
            }
          *(c++) = 0;
-         secondary_type = type_from_name (arg);
+         secondary_type = type_from_name (arg, TRUE);
          sig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
          sig[1] = type2;
          sig[2] = secondary_type;