How do you create a dictionary that maps onto an array in GLib?

2.2k views Asked by At

I'm trying to return a G_Variant pointer to a dictionary that takes uint16 as keys and maps it to arrays of bytes (ie: "a{qay}").

Here's my attempt:

    #define KEY   0xDEAD
    #define BYTE1 0xBE
    #define BYTE2 0xEF
    GVariantBuilder *arrBuilder, *builder;
    GVariant *arr;

    //build array of bytes ('ay') 
    arrBuilder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
    g_variant_builder_add(arrBuilder, "y", BYTE1);
    g_variant_builder_add(arrBuilder, "y", BYTE2);

    arr = g_variant_new("v",g_variant_new("ay", arrBuilder));

    //put it in a dict ('a{sv}')
    builder = g_variant_builder_new(G_VARIANT_TYPE("a{qay}"));
    g_variant_builder_add(builder, "{qay}", KEY, arr);
    return g_variant_builder_end(builder);

It doesn't work out and I get the following error message when I try to query this property on D-Bus:

(process:18319): GLib-CRITICAL **: g_variant_builder_end: assertion 'is_valid_builder (builder)' failed

(process:18319): GLib-CRITICAL **: g_variant_get_type: assertion 'value != NULL' failed

(process:18319): GLib-CRITICAL **: g_variant_type_is_array: assertion 'g_variant_type_check (type)' failed

(process:18319): GLib-CRITICAL **: g_variant_get_type_string: assertion 'value != NULL' failed

(process:18319): GLib-ERROR **: g_variant_new: expected array GVariantBuilder but the built value has type '(null)'
Trace/breakpoint trap (core dumped)
1

There are 1 answers

1
Constantin Chabirand On
arr = g_variant_new("v",g_variant_new("ay", arrBuilder));

Maybe you should end the array builder so that it returns your bytearray ?

arr = g_variant_builder_end(arrBuilder);

EDIT : I found an answer :

The following code will achieve what you wanted to do, the trick is that the array of bytes is a variant (everything is a variant) !

GVariant *arr_builder, *dict_builder;

/* Build the array of bytes */
arr_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
g_variant_builder_add(arr_builder, "y",0xAA);
// Add some more if you want
GVariant *byte_array = g_variant_builder_end(arr_builder);
g_variant_builder_unref(arr_builder);

/* Build the dictionary, now is the trick */
dict_builder = g_variant_builder_new(G_VARIANT_TYPE("a{qv}"));
g_variant_builder_add(dict_builder, "{qv}", 0x0F0F, byte_array);
GVariant *dict = g_variant_builder_end(dict_builder);
g_variant_builder_unref(dict_builder);

/* Now you can print your variants (dict and byte_array) and print their type */
g_print(g_variant_print(dict,TRUE));
g_print(g_variant_get_type_string(dict));

I had the same errors as you when trying what you wrote and this made work =)