xml_settings.cpp
Go to the documentation of this file.
00001 #include <QMap>
00002 #include <QList>
00003 #include <QStringList>
00004 #include <QXmlStreamReader>
00005 #include <QXmlStreamWriter>
00006 #include "utilities/xml_settings.h"
00007 
00008 #include <ros/console.h>
00009 
00010 namespace utilities
00011 {
00012 const QSettings::Format XmlSettings::format =
00013     QSettings::registerFormat("xml", XmlSettings::read, XmlSettings::write);
00014 const QString XmlSettings::GROUP_SEPARATOR = "/";
00015 const QString XmlSettings::ATTRIBUTE_SEPARATOR = "@";
00016 
00017 bool XmlSettings::read(QIODevice& device, QSettings::SettingsMap& map)
00018 {
00019   QXmlStreamReader xml_reader(&device);
00020   QStringList groups;
00021   bool multiple_elements(false);
00022   while (!xml_reader.atEnd())
00023   {
00024     xml_reader.readNext();
00025     if (xml_reader.isStartElement())
00026     {
00027       groups.append(xml_reader.name().toString());
00028       multiple_elements = map.contains(groups.join(GROUP_SEPARATOR));
00029       QXmlStreamAttributes attributes(xml_reader.attributes());
00030       for (size_t i(0); i < attributes.count(); i++)
00031       {
00032         QString name(groups.join(GROUP_SEPARATOR) + "/" + ATTRIBUTE_SEPARATOR +
00033                      attributes[i].name().toString());
00034         if (!multiple_elements)
00035         {
00036           map[name] = attributes[i].value().toString();
00037         }
00038         else
00039         {
00040           QString values;
00041           if (!map.contains(name))
00042           {
00043             for (size_t j(0); j < i; j++)
00044             {
00045               values += ",";
00046             }
00047             values = "[" + values + "]";
00048           }
00049           values = map[name].toString();
00050           int count(values.count());
00051           QStringRef values_ref(&values, values[0] == '[' ? 1 : 0,
00052                                 count - (values[count - 1] == ']' ? 2 : 0));
00053           map[name] = "[" + values_ref.toString() + "," +
00054                       xml_reader.text().toString() + "]";
00055         }
00056       }
00057     }
00058     else if (xml_reader.isCharacters() && !xml_reader.isWhitespace())
00059     {
00060       if (!multiple_elements)
00061       {
00062         map[groups.join(GROUP_SEPARATOR)] = xml_reader.text().toString();
00063       }
00064       else
00065       {
00066         QString values(map[groups.join(GROUP_SEPARATOR)].toString());
00067         int count(values.count());
00068         QStringRef values_ref(&values, values[0] == '[' ? 1 : 0,
00069                               count - (values[count - 1] == ']' ? 2 : 0));
00070         map[groups.join(GROUP_SEPARATOR)] = "[" + values_ref.toString() + "," +
00071                                             xml_reader.text().toString() + "]";
00072       }
00073     }
00074     else if (xml_reader.isEndElement())
00075     {
00076       groups.removeLast();
00077     }
00078   }
00079   ROS_WARN("[XmlSettings] reading ...");
00080   for (QSettings::SettingsMap::iterator it(map.begin()); it != map.end(); it++)
00081   {
00082     ROS_WARN_STREAM(it.key().toStdString() << ": " << it.value().toString().toStdString());
00083   }
00084   return !xml_reader.hasError();
00085 }
00086 
00087 bool XmlSettings::write(QIODevice& device, const QSettings::SettingsMap& map)
00088 {
00089   ROS_WARN("[XmlSettings] writing ...");
00090   for (QSettings::SettingsMap::iterator it(map.begin()); it != map.end(); it++)
00091   {
00092     ROS_WARN_STREAM(it.key().toStdString() << ": " << it.value().toString().toStdString());
00093   }
00094   struct NestedMap;
00095   typedef QSharedPointer<NestedMap> NestedQSharedPointer;
00096   struct NestedMap : QMap<QString, NestedQSharedPointer>
00097   {
00098   };
00099   NestedQSharedPointer nested_map(new NestedMap());
00100   for (QSettings::SettingsMap::const_iterator it(map.begin()); it != map.end();
00101        ++it)
00102   {
00103     NestedQSharedPointer current_map(nested_map);
00104     QStringList groups(it.key().split(GROUP_SEPARATOR));
00105     for (QStringList::const_iterator jt(groups.begin()); jt != groups.end();
00106          ++jt)
00107     {
00108       NestedMap::iterator kt(current_map->find(*jt));
00109       if (kt == current_map->end())
00110       {
00111         kt = current_map->insert(*jt, NestedQSharedPointer(new NestedMap()));
00112       }
00113       current_map = kt.value();
00114     }
00115   }
00116   QXmlStreamWriter xml_writer(&device);
00117   xml_writer.setAutoFormatting(true);
00118   ROS_WARN_STREAM("[XmlSettings::write] writeStartDocument()");
00119   xml_writer.writeStartDocument();
00120   QStringList groups;
00121   QList<NestedQSharedPointer> nested_maps;
00122   QList<NestedMap::iterator> nested_map_iterators;
00123   nested_maps.append(nested_map);
00124   nested_map_iterators.append(nested_map->begin());
00125   QString tag;
00126   QString attribute;
00127   int value_index(0);
00128   while (!nested_maps.isEmpty())
00129   {
00130     ROS_WARN_STREAM("[XmlSettings::write] groups: " << groups.join("/").toStdString());
00131     NestedQSharedPointer current_map(nested_maps.last());
00132     NestedMap::iterator it(nested_map_iterators.last());
00133     if (it != current_map->end())
00134     {
00135       tag = it.key();
00136       if (it.key().startsWith(ATTRIBUTE_SEPARATOR))
00137       {
00138         attribute = it.key().right(it.key().count() - 1);
00139       }
00140       else
00141       {
00142         ROS_WARN_STREAM("[XmlSettings::write] writeStartElement(" << it.key().toStdString() << ")");
00143         xml_writer.writeStartElement(it.key());
00144       }
00145       groups.append(it.key());
00146       nested_maps.append(it.value());
00147       nested_map_iterators.append(it.value()->begin());
00148     }
00149     else
00150     {
00151       if (current_map->isEmpty())
00152       {
00153         QString value(map[groups.join(GROUP_SEPARATOR)].toString());
00154         if (!attribute.isEmpty())
00155         {
00156           ROS_WARN_STREAM("[XmlSettings::write] writeAttribute(" << attribute.toStdString()
00157                           << "," << map[groups.join(GROUP_SEPARATOR)].toString().toStdString() << ")");
00158           xml_writer.writeAttribute(
00159               attribute, map[groups.join(GROUP_SEPARATOR)].toString());
00160           if (groups.isEmpty())
00161           {
00162             nested_maps.removeLast();
00163             nested_map_iterators.removeLast();
00164             if (!nested_maps.isEmpty())
00165             {
00166               ++nested_map_iterators.last();
00167             }
00168             continue;
00169           }
00170           groups.removeLast();
00171           value = map[groups.join(GROUP_SEPARATOR)].toString();
00172           groups.append("@" + attribute);
00173         }
00174         if (value.startsWith("[") && value.endsWith("]"))
00175         {
00176           QStringRef value_ref(&value, 1, value.count() - 2);
00177           QStringList values(value_ref.toString().split(","));
00178           value = values[value_index];
00179           value_index = value_index == values.count() - 1 ? 0 : value_index + 1;
00180         }
00181         if (!value.isEmpty())
00182         {
00183           ROS_WARN_STREAM("[XmlSettings::write] writeCharacters(" << value.toStdString() << ")");
00184           xml_writer.writeCharacters(value);
00185         }
00186         if (value_index > 0)
00187         {
00188           ROS_WARN_STREAM("[XmlSettings::write] writeEndElement()");
00189           xml_writer.writeEndElement();
00190           ROS_WARN_STREAM("[XmlSettings::write] writeStartElement(" << tag.toStdString() << ")");
00191           xml_writer.writeStartElement(tag);
00192           continue;
00193         }
00194       }
00195       if (!attribute.isEmpty())
00196       {
00197         if (!groups.isEmpty())
00198         {
00199           groups.removeLast();
00200         }
00201         nested_maps.removeLast();
00202         nested_map_iterators.removeLast();
00203         if (!nested_maps.isEmpty())
00204         {
00205           ++nested_map_iterators.last();
00206         }
00207         attribute.clear();
00208       }
00209       ROS_WARN_STREAM("[XmlSettings::write] writeEndElement()");
00210       xml_writer.writeEndElement();
00211       if (!groups.isEmpty())
00212       {
00213         groups.removeLast();
00214       }
00215       nested_maps.removeLast();
00216       nested_map_iterators.removeLast();
00217       if (!nested_maps.isEmpty())
00218       {
00219         ++nested_map_iterators.last();
00220       }
00221     }
00222   }
00223   ROS_WARN_STREAM("[XmlSettings::write] writeEndDocument()");
00224   xml_writer.writeEndDocument();
00225   return true;
00226 }
00227 }


rqt_mrta
Author(s): Adriano Henrique Rossette Leite
autogenerated on Thu Jun 6 2019 18:50:52