Web lists-archives.com

Re: Using GVariantBuilder with complex structures




Does anyone have any pointers?

Thank you.

On Fri, Feb 22, 2019 at 11:58 AM Mitko Haralanov <voidtrance@xxxxxxxxx> wrote:
>
> Hi,
>
> I've been trying to figure out how to use GVariantBuilder to build a
> complex structure with little success. The type of structure that I
> would like to build is meant to partially encode a GtkTreeModel
> structure. So, I thought that I could use GVariantBuilder to build a
> structure of nested dictionaries.
>
> The structure roughly follows this model:
> [
>   {
>     "id": { "key1": (<int>, <string>, ...), "children": [
>                           { "id2" : { "key1" : (<int>, <string>, ...),
> "children" : []},
>                           { "id3" : { "key1" : (<int>, <string>, ...),
> "children" : [
>                               { ... }
>                               ]}
>                           ]}},
>   { "id" : ...}
> ]
>
> This type of encoding can naturally be done with recursion and using
> multiple GVariantBuilder's to add to the correct parent. However, I am
> having difficulty with getting the formatting strings correct. As it
> turns out, GLib insist on every dictionary entry being statically
> typed meaning that the values for both "key1" and "children" has to be
> of the same type. That seems to leave only 'v' as a valid format. So,
> I have the following code (only important parts are pasted, not a
> complete program):
>
> struct tree_entry_search {
>         uint32_t type;
>         const char *term;
> };
>
> struct tree_entry {
>         const char *id;
>         struct tree_entry_search search;
>         GList *children;
> };
>
> void add_elem(GVariantBuilder *builder, struct tree_entry *elem)
> {
>         GVariantBuilder *new, *child_builder;
>         GVariant *new_dict, *new_array, *search;
>         GList *item;
>
>         new = g_variant_builder_new(G_VARIANT_TYPE_DICTIONARY);
>         search = g_variant_new("(us)", elem->search.type, elem->search.term);
>         g_variant_builder_add(new, "{sv}", "search", search);
>         child_builder = g_variant_builder_new(G_VARIANT_TYPE("av"));
>         for (item = elem->children; item; item = item->next)
>                 add_elem(child_builder, item->data);
>         new_array = g_variant_builder_end(child_builder);
>         g_variant_builder_unref(child_builder);
>         g_variant_builder_add(new, "{sv}", "children", new_array);
>         new_dict = g_variant_builder_end(new);
>         g_variant_builder_unref(new);
>         g_variant_builder_add(builder, "{sv}", elem->id, new_dict);
> }
>
> int main(void) {
>         ...
>         /* Build up a fake tree. */
>         root.id = g_strdup("uid1");
>         root.search.type = 1;
>         root.search.term = g_strdup("term1");
>         elem = g_new0(struct tree_entry, 1);
>         elem->id = g_strdup("uid2");
>         elem->search.type = 2;
>         elem->search.term = g_strdup("term2");
>         root.children = g_list_append(root.children, elem);
>         elem = g_new0(struct tree_entry, 1);
>         elem->id = g_strdup("uid3");
>         elem->search.type = 2;
>         elem->search.term = g_strdup("term3");
>         root.children = g_list_append(root.children, elem);
>         child = g_new0(struct tree_entry, 1);
>         child->id = g_strdup("uid4");
>         child->search.type = 3;
>         child->search.term = g_strdup("term4");
>         elem->children = g_list_append(elem->children, child);
>
>         builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
>         add_elem(builder, &root);
>         dict = g_variant_builder_end(builder);
>         dictionary = g_variant_print(dict, TRUE);
>         printf("%s\n", dictionary);
>         ...
> }
>
> But when I compile the above and run it, I get the following errors
> when the tree is more than one level deep:
>
> (process:3873): GLib-CRITICAL **: 11:44:03.826:
> g_variant_builder_add_value: assertion '!GVSB(builder)->expected_type
> || g_variant_is_of_type (value, GVSB(builder)->expected_type)' failed
>
> (process:3873): GLib-CRITICAL **: 11:44:03.827:
> g_variant_builder_add_value: assertion '!GVSB(builder)->expected_type
> || g_variant_is_of_type (value, GVSB(builder)->expected_type)' failed
>
> (process:3873): GLib-CRITICAL **: 11:44:03.827:
> g_variant_builder_add_value: assertion '!GVSB(builder)->expected_type
> || g_variant_is_of_type (value, GVSB(builder)->expected_type)' failed
>
> What's the correct way to specify the builder and variant types so I
> can build the nested dictionary structure?
>
> Thank you for the help.
_______________________________________________
gtk-list mailing list
gtk-list@xxxxxxxxx
https://mail.gnome.org/mailman/listinfo/gtk-list