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