Search code examples
c++linuxglibdbusglibmm

Parsing DBUS response type as Array of Dictionary or Map using C++


I am working on Linux DBUS APIs using C++ code, trying to run a dbus method and parse response message typeof (a{sv}) But having few problems. I am using glib and glibmm libraries.

here is my code:

    const auto call_result = proxy -> call_sync("GetConfiguration",
    tuple, 1000);

std::cout << "Contents of call_result: " << call_result.print() <<
    std::endl;
std::cout << "call_result type: " <<
    call_result.get_type_string() << std::endl;

Glib::Variant < std::vector < std::map < Glib::ustring, Glib::VariantBase >>> testConfigVect;

call_result.get_child(testConfigVect, 0);
std::cout << "testConfigVect type: " <<
    testConfigVect.get_type_string() << std::endl;

std::size_t numChildren = testConfigVect.get_n_children();
std::cout << "numChildren: " << numChildren << std::endl;

for (std::size_t i = 0; i < numChildren; i++) {

    auto mapa = testConfigVect.get_child(i);
    const char * typeName = typeid(mapa).name();
    std::cout << "Type of mapa: " << typeName << std::endl;

    if (mapa.empty()) {
        std::cout << "Map is empty." << std::endl;
    } else {
        std::cout << "Map is not empty." << std::endl;
    }

    for (const auto & pair: mapa) {
        const Glib::ustring & key = pair.first;
        const Glib::VariantBase & value = pair.second;

        std::cout << "Key: " << key << ", Value: " << value.print() << std::endl;
    }
}

I found an empty map But I can see a valid dbus response is a{sv} format with map information. Wonder why I am not able to read map here ! here is the output of my code:

Contents of call_result: ({'SecureBoot': <'False'>},) 
call_result type: (a{sv}) 
testConfigVect type: a{sv} 
numChildren: 1 
Type of mapa:
St3mapIN4Glib7ustringENS0_11VariantBaseESt4lessIS1_ESaISt4pairIKS1_S2_EEE
Map is empty.

Thanks for the help !


Solution

  • The confusion here seems to be in a{sv}: this is not an array of dictionary, it's just a dictionary. You can read the format string as "array of key-value pairs", see GVariant format strings for more details.

    So if you treat testConfigVect as a map, that will likely start working.