config.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <QLocale>
31 
32 #include "rviz/config.h"
33 
34 namespace rviz
35 {
37 // Config::Node internal data storage class
39 
41 {
42 public:
43  Node();
44  ~Node();
45 
46  void setType(Config::Type new_type);
47  void deleteData();
48 
49  typedef QMap<QString, NodePtr> ChildMap;
50  typedef QList<NodePtr> ChildList;
51 
53  union
54  {
55  ChildMap* map;
56  ChildList* list;
57  QVariant* value;
58  } data_;
59 };
60 
62 {
63  data_.map = nullptr;
64 }
65 
67 {
68  deleteData();
69 }
70 
72 {
73  switch (type_)
74  {
75  case Map:
76  delete data_.map;
77  break;
78  case List:
79  delete data_.list;
80  break;
81  case Value:
82  delete data_.value;
83  break;
84  default:
85  break;
86  }
87  data_.map = nullptr;
88 }
89 
91 {
92  if (type_ == new_type)
93  {
94  return;
95  }
96  deleteData();
97  type_ = new_type;
98  switch (type_)
99  {
100  case Map:
101  data_.map = new ChildMap;
102  break;
103  case List:
104  data_.list = new ChildList;
105  break;
106  case Value:
107  data_.value = new QVariant;
108  break;
109  default:
110  break;
111  }
112 }
113 
115 // Config wrapper class
117 
119 {
120 }
121 
122 Config::Config(const Config& source) : node_(source.node_)
123 {
124 }
125 
126 Config::Config(QVariant value) : node_(new Config::Node())
127 {
128  setValue(value);
129 }
130 
132 {
133 }
134 
135 void Config::copy(const Config& source)
136 {
137  if (!source.isValid())
138  {
139  node_ = NodePtr();
140  return;
141  }
142 
143  setType(source.getType());
144  switch (source.getType())
145  {
146  case Map:
147  {
148  MapIterator iter = source.mapIterator();
149  while (iter.isValid())
150  {
151  mapMakeChild(iter.currentKey()).copy(iter.currentChild());
152  iter.advance();
153  }
154  break;
155  }
156  case List:
157  {
158  int num_children = source.listLength();
159  for (int i = 0; i < num_children; i++)
160  {
161  listAppendNew().copy(source.listChildAt(i));
162  }
163  break;
164  }
165  case Value:
166  setValue(source.getValue());
167  break;
168  default:
169  break;
170  }
171 }
172 
174 {
175  return Config(NodePtr());
176 }
177 
179 {
180  return isValid() ? node_->type_ : Invalid;
181 }
182 
183 void Config::setType(Type new_type)
184 {
185  if (new_type == Invalid)
186  {
187  node_ = NodePtr();
188  }
189  else
190  {
191  makeValid();
192  node_->setType(new_type);
193  }
194 }
195 
196 void Config::mapSetValue(const QString& key, QVariant value)
197 {
198  mapMakeChild(key).setValue(value);
199 }
200 
201 Config Config::mapMakeChild(const QString& key)
202 {
203  Config child;
204 
205  makeValid();
206  node_->setType(Map);
207  (*node_->data_.map)[key] = child.node_;
208 
209  return child;
210 }
211 
212 Config Config::mapGetChild(const QString& key) const
213 {
214  if (node_.get() == nullptr || node_->type_ != Map)
215  {
216  return invalidConfig();
217  }
218  Node::ChildMap::const_iterator iter = node_->data_.map->find(key);
219  if (iter == node_->data_.map->end())
220  {
221  return invalidConfig();
222  }
223  else
224  {
225  return Config(iter.value());
226  }
227 }
228 
229 bool Config::mapGetValue(const QString& key, QVariant* value_out) const
230 {
231  Config child = mapGetChild(key);
232  if (child.getType() == Value) // getType() checks for validity as well.
233  {
234  *value_out = child.getValue();
235  return true;
236  }
237  return false;
238 }
239 
240 bool Config::mapGetInt(const QString& key, int* value_out) const
241 {
242  QVariant v;
243  if (mapGetValue(key, &v) && (v.type() == QVariant::Int || v.type() == QVariant::String))
244  {
245  bool ok;
246  int i = v.toInt(&ok);
247  if (ok)
248  {
249  *value_out = i;
250  return true;
251  }
252  }
253  return false;
254 }
255 
256 bool Config::mapGetFloat(const QString& key, float* value_out) const
257 {
258  QVariant v;
259  if (mapGetValue(key, &v) && (int(v.type()) == int(QMetaType::Float) || v.type() == QVariant::Double ||
260  v.type() == QVariant::String))
261  {
262  bool ok;
263  float f = v.toFloat(&ok);
264  if (ok)
265  {
266  *value_out = f;
267  return true;
268  }
269  QString as_string = v.toString();
270  // Try as European, e.g. 1.234,56 rather than 1,234.56
271  QLocale german(QLocale::German);
272  f = german.toFloat(as_string, &ok);
273  if (ok)
274  {
275  *value_out = f;
276  return true;
277  }
278  }
279  return false;
280 }
281 
282 bool Config::mapGetBool(const QString& key, bool* value_out) const
283 {
284  QVariant v;
285  if (mapGetValue(key, &v) && (v.type() == QVariant::Bool || v.type() == QVariant::String))
286  {
287  *value_out = v.toBool();
288  return true;
289  }
290  return false;
291 }
292 
293 bool Config::mapGetString(const QString& key, QString* value_out) const
294 {
295  QVariant v;
296  if (mapGetValue(key, &v) && v.type() == QVariant::String)
297  {
298  *value_out = v.toString();
299  return true;
300  }
301  return false;
302 }
303 
305 {
306  if (node_.get() == nullptr)
307  {
308  node_.reset(new Node());
309  }
310 }
311 
312 bool Config::isValid() const
313 {
314  return node_.get() != nullptr;
315 }
316 
317 void Config::setValue(const QVariant& value)
318 {
319  makeValid();
320  node_->setType(Value);
321  *node_->data_.value = value;
322 }
323 
324 QVariant Config::getValue() const
325 {
326  return (isValid() && node_->type_ == Value) ? *node_->data_.value : QVariant();
327 }
328 
330 {
331  return (isValid() && node_->type_ == List) ? node_->data_.list->size() : 0;
332 }
333 
335 {
336  if (isValid() && node_->type_ == List && i >= 0 && i < node_->data_.list->size())
337  {
338  return Config(node_->data_.list->at(i));
339  }
340  else
341  {
342  return invalidConfig();
343  }
344 }
345 
347 {
348  Config child;
349 
350  setType(List);
351  node_->data_.list->append(child.node_);
352 
353  return child;
354 }
355 
357 {
358  // Create a new (invalid) iterator.
359  Config::MapIterator iter;
360 
361  if (node_.get() == nullptr || node_->type_ != Map)
362  {
363  // Force the node to be invalid, since this node does not have a map.
364  iter.node_.reset();
365  }
366  else
367  {
368  // Copy this config's node reference into the iterator's node reference.
369  iter.node_ = node_;
370  iter.start();
371  }
372  return iter;
373 }
374 
375 Config::MapIterator::MapIterator() : iterator_valid_(false)
376 {
377 }
378 
380 {
381  if (node_.get() == nullptr || node_->type_ != Config::Map)
382  {
383  iterator_valid_ = false;
384  return;
385  }
386  if (!iterator_valid_)
387  {
388  iterator_ = node_->data_.map->begin();
389  iterator_valid_ = true;
390  }
391  else
392  {
393  iterator_++;
394  }
395 }
396 
398 {
399  if (node_.get() == nullptr || node_->type_ != Config::Map)
400  {
401  iterator_valid_ = false;
402  return false;
403  }
404  if (!iterator_valid_)
405  {
406  return false;
407  }
408  else
409  {
410  return iterator_ != node_->data_.map->end();
411  }
412 }
413 
415 {
416  if (node_.get() == nullptr || node_->type_ != Config::Map)
417  {
418  iterator_valid_ = false;
419  return;
420  }
421  iterator_ = node_->data_.map->begin();
422  iterator_valid_ = true;
423 }
424 
426 {
427  if (node_.get() == nullptr || node_->type_ != Config::Map || !iterator_valid_)
428  {
429  iterator_valid_ = false;
430  return QString();
431  }
432  return iterator_.key();
433 }
434 
436 {
437  if (node_.get() == nullptr || node_->type_ != Config::Map || !iterator_valid_)
438  {
439  iterator_valid_ = false;
440  return Config();
441  }
442  return Config(iterator_.value());
443 }
444 
445 } // end namespace rviz
Config::Type type_
Definition: config.cpp:52
void setValue(const QVariant &value)
Ensures this is a valid Config object, sets the type to Value then sets the value.
Definition: config.cpp:317
void setType(Config::Type new_type)
Definition: config.cpp:90
Config::NodePtr node_
Definition: config.h:313
static Config invalidConfig()
Definition: config.cpp:173
f
QVariant getValue() const
If this config object is valid and is a Value type, this returns its value. Otherwise it returns an i...
Definition: config.cpp:324
Config()
Default constructor. Creates an empty config object.
Definition: config.cpp:118
ChildList * list
Definition: config.cpp:56
MapIterator()
Private constructor enforces that MapIterators are only made by their friend the Config class...
Definition: config.cpp:375
int listLength() const
Returns the length of the List in this Node, or 0 if this Node does not have type List...
Definition: config.cpp:329
bool isValid()
Return true if the iterator currently points to a valid entry, false if not.
Definition: config.cpp:397
Config mapGetChild(const QString &key) const
If the referenced Node is a Map and it has a child with the given key, return a reference to the chil...
Definition: config.cpp:212
bool mapGetString(const QString &key, QString *value_out) const
Convenience function for looking up a named string.
Definition: config.cpp:293
void makeValid()
If the node pointer is NULL, this sets it to a new empty node.
Definition: config.cpp:304
boost::shared_ptr< Node > NodePtr
Definition: config.h:127
void start()
Resets the iterator to the start of the map.
Definition: config.cpp:414
bool isValid() const
Returns true if the internal Node reference is valid, false if not. Same as (getType() != Invalid)...
Definition: config.cpp:312
void mapSetValue(const QString &key, QVariant value)
Set a named child to the given value.
Definition: config.cpp:196
Configuration data storage class.
Definition: config.h:124
QString currentKey()
Return the name of the current map entry.
Definition: config.cpp:425
Type
Possible types a Config Node can have are Map, List, Value, and Empty. Invalid means the Config objec...
Definition: config.h:148
Config mapMakeChild(const QString &key)
Create a child node stored with the given key, and return the child.
Definition: config.cpp:201
Iterator class for looping over all entries in a Map type Config Node.
Definition: config.h:288
ROSCPP_DECL bool ok()
bool mapGetValue(const QString &key, QVariant *value_out) const
Convenience function for looking up a named value.
Definition: config.cpp:229
bool mapGetFloat(const QString &key, float *value_out) const
Convenience function for looking up a named float.
Definition: config.cpp:256
NodePtr node_
Definition: config.h:335
Type getType() const
Return the Type of the referenced Node, or Invalid if this Config does not refer to a Node at all...
Definition: config.cpp:178
bool mapGetBool(const QString &key, bool *value_out) const
Convenience function for looking up a named boolean.
Definition: config.cpp:282
ChildMap * map
Definition: config.cpp:55
Config listAppendNew()
Ensure the referenced Node is of type List, append a new Empty Node to the end of the list...
Definition: config.cpp:346
Config listChildAt(int i) const
Return the i&#39;th child in the list, if the referenced Node has type List. Returns an Invalid Config if...
Definition: config.cpp:334
Config currentChild()
Return a Config reference to the current map entry.
Definition: config.cpp:435
MapIterator mapIterator() const
Return a new iterator for looping over key/value pairs.
Definition: config.cpp:356
QMap< QString, Config::NodePtr >::const_iterator iterator_
Definition: config.h:314
void deleteData()
Definition: config.cpp:71
bool mapGetInt(const QString &key, int *value_out) const
Convenience function for looking up a named integer.
Definition: config.cpp:240
QVariant * value
Definition: config.cpp:57
friend class Config
Definition: config.h:316
QList< NodePtr > ChildList
Definition: config.cpp:50
void copy(const Config &source)
Make this a deep copy of source.
Definition: config.cpp:135
void setType(Type new_type)
Set the type of this Config Node.
Definition: config.cpp:183
union rviz::Config::Node::@0 data_
QMap< QString, NodePtr > ChildMap
Definition: config.cpp:49
void advance()
Advance iterator to next entry.
Definition: config.cpp:379


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Sat May 27 2023 02:06:24