Re: Construct Glib::VariantContainerBase for "container of container" types?



On Fri, Dec 21, 2012 at 3:12 PM, Phong Cao <phongvcao phongvcao com> wrote:
For example, what should "a{sv}" be implemented as in Glib::VariantContainerBase? Should it be Glib::Variant<std::vector<std::map<Glib::ustring, Glib::VariantBase> > >?
Disclaimer, all examples below are untested :)
 
Right now it seems that you can only create arrays of basic types (int, float, strings) with Glibmm. To create an array of variants, you'll need to call a C function:

std::vector<std::map<Glib::ustring, Glib::VariantBase>> my_maps; // given
const gsize n_children = my_maps.size();
GVariant**  vmap_array = g_malloc(sizeof(GVariant*) * n_children );

for( gsize i = 0; i < n_children; ++i ) {
  Glib::Variant<std::map<Glib::ustring, Glib::VariantBase> > v = Glib::Variant<std::map<Glib::ustring, Glib::VariantBase> >::create( my_maps[i] );
  vmap_array[i] = v.gobj_copy();
}

GVariant *vcarray = g_variant_new_array(g_variant_get_type(vmap_array[0]), vmap_array, n_children);
Glib::VariantContainerBase varray = Glib::wrap(vcarray);
for (gsize i = 0; i < n_children; ++i)  g_variant_unref(vmap_array[i]);
g_free(vmap_array);

Note that if you only need to process such a variant that is passed to you from DBus (i.e. the music player created the array of maps and you just want to get the maps) then you don't need to use C:
Glib::VariantContainerBase varray; // This was a variant passed to us. You might need to use ::cast_dynamic() if all you have is a VariantBase
for (gsize i = 0; i < varray.get_n_children(); ++i) {
Glib::VariantBase vbase = varray.get_child(i);
Glib::Variant<std::map<Glib::ustring, Glib::VariantBase> > vmap = Glib::VariantBase::cast_dynamic<Glib::Variant<std::map<Glib::ustring, Glib::VariantBase> >(vbase);
std::map<Glib::ustring, Glib::VariantBase> my_map = vmap.get();
// Now do whatever you want with my_map
}


I also wonder how I can implement structure types, such as "(b(oss))"? I did take careful look at Glib::VariantContainerBase reference, but I don't see anywhere talking about DBus structure types.
That's a tuple. You can use Glib::VariantContainerBase::create_tuple():

Glib::Variant<bool> vbool;
Glib::VariantBase objectpath;
Glib::Variant<Glib::ustring> s1, s2;
std::vector<Glib::VariantBase> v1, v2;
v1.push_back(objectpath); v1.push_back(s1); v1.push_back(s2);
Glib::VariantContainerBase inner_tuple =Glib::VariantContainerBase::create_tuple(v1);
v2.push_back(bvool);
v2.push_back(inner_tuple);
Glib::VariantContainerBase tuple = Glib::VariantContainerBase::create_tuple(v2);
 

Actually it appears Glibmm doesn't have a way to create the "Object Path" Variant type. So you'd have to do that in C...

To be very honest, doing work with Variants in C is often easier.
Thank you for reading and answering my question! Merry Christmas!
Merry Christmas!


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]