Re: Using GVariantBuilder with complex structures

2019-02-27 Thread Mitko Haralanov via gtk-list
Answering my own question in case anyone else can benefit from the information.

The code that I ended up with in order to encode the described
structure is the following:

void add_elem(GVariantBuilder *builder, struct tree_entry *elem)
{
GVariantBuilder *new, *child_builder, *children;
GVariant *new_dict, *new_array, *search;
GList *item;

/* This is the new dictionary that will be inserted into the
 * 'children' array of the parent. The parent could be a regular
 * element of the master list since both are using an array of
 * dictionaries for the "children". */
new = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
/* This is the dictionary that will contain the child information.
 * It only has one key - the id of the current element. */
child_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
/* Construct and add the 'search' type information tuple to the
 * current element's dictionary. */
search = g_variant_new("(us)", elem->search.type, elem->search.term);
g_variant_builder_add(child_builder, "{sv}", "search", search);
/* Construct the 'children' array for the child element. This is
 * effectively the same as what we are doing for the master array. */
children = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
for (item = elem->children; item; item = item->next)
add_elem(children, item->data);
new_array = g_variant_builder_end(children);
g_variant_builder_unref(children);
/* Add the 'children' array to the current element dictionary. */
g_variant_builder_add(child_builder, "{sv}", "children", new_array);
new_dict = g_variant_builder_end(child_builder);
g_variant_builder_unref(child_builder);
/* Insert the new child into the top level dictionary describing the
 * current element. */
g_variant_builder_add(new, "{sv}", elem->id, new_dict);
/* Insert this element into the parent's 'children' array. */
g_variant_builder_add(builder, "a{sv}", new);
}

builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
add_elem(builder, );
dict = g_variant_builder_end(builder);


On Tue, Feb 26, 2019 at 7:49 AM Mitko Haralanov  wrote:
>
> Does anyone have any pointers?
>
> Thank you.
>
> On Fri, Feb 22, 2019 at 11:58 AM Mitko Haralanov  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": (, , ...), "children": [
> >   { "id2" : { "key1" : (, , ...),
> > "children" : []},
> >   { "id3" : { "key1" : (, , ...),
> > "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) 

Re: Using GVariantBuilder with complex structures

2019-02-26 Thread Mitko Haralanov via gtk-list
Does anyone have any pointers?

Thank you.

On Fri, Feb 22, 2019 at 11:58 AM Mitko Haralanov  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": (, , ...), "children": [
>   { "id2" : { "key1" : (, , ...),
> "children" : []},
>   { "id3" : { "key1" : (, , ...),
> "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, );
> 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@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-list