From: Frederik Van Bogaert Date: Sat, 17 Apr 2021 22:02:45 +0000 (+0200) Subject: dbus-send: Add support for variants to arrays and dictionaries X-Git-Tag: dbus-1.15.0~46^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38a98dbf026c93ddd4b6221e3640505e6fdccdc5;p=thirdparty%2Fdbus.git dbus-send: Add support for variants to arrays and dictionaries 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 --- diff --git a/tools/dbus-send.c b/tools/dbus-send.c index 65f9854ee..86858c505 100644 --- a/tools/dbus-send.c +++ b/tools/dbus-send.c @@ -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;