config.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2012, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <QLocale>
00031 
00032 #include "rviz/config.h"
00033 
00034 namespace rviz
00035 {
00036 
00038 // Config::Node internal data storage class
00040 
00041 class Config::Node
00042 {
00043 public:
00044   Node();
00045   ~Node();
00046 
00047   void setType( Config::Type new_type );
00048   void deleteData();
00049 
00050   typedef QMap<QString, NodePtr> ChildMap;
00051   typedef QList<NodePtr> ChildList;
00052 
00053   Config::Type type_;
00054   union
00055   {
00056     ChildMap* map;
00057     ChildList* list;
00058     QVariant* value;
00059   } data_;
00060 };
00061 
00062 Config::Node::Node()
00063   : type_( Empty )
00064 {
00065   data_.map = NULL;
00066 }
00067 
00068 Config::Node::~Node()
00069 {
00070   deleteData();
00071 }
00072 
00073 void Config::Node::deleteData()
00074 {
00075   switch( type_ )
00076   {
00077   case Map: delete data_.map; break;
00078   case List: delete data_.list; break;
00079   case Value: delete data_.value; break;
00080   default:
00081     break;
00082   }
00083   data_.map = NULL;
00084 }
00085 
00086 void Config::Node::setType( Config::Type new_type )
00087 {
00088   if( type_ == new_type )
00089   {
00090     return;
00091   }
00092   deleteData();
00093   type_ = new_type;
00094   switch( type_ )
00095   {
00096   case Map:   data_.map =   new ChildMap;  break;
00097   case List:  data_.list =  new ChildList; break;
00098   case Value: data_.value = new QVariant;  break;
00099   default:                                 break;
00100   }
00101 }
00102 
00104 // Config wrapper class
00106 
00107 Config::Config()
00108   : node_( new Config::Node() )
00109 {}
00110 
00111 Config::Config( const Config& source )
00112   : node_( source.node_ )
00113 {}
00114 
00115 Config::Config( QVariant value )
00116   : node_( new Config::Node() )
00117 {
00118   setValue( value );
00119 }
00120 
00121 Config::Config( NodePtr node )
00122   : node_( node )
00123 {}
00124 
00125 void Config::copy( const Config& source )
00126 {
00127   if( !source.isValid() )
00128   {
00129     node_ = NodePtr();
00130     return;
00131   }
00132 
00133   setType( source.getType() );
00134   switch( source.getType() )
00135   {
00136   case Map:
00137   {
00138     MapIterator iter = source.mapIterator();
00139     while( iter.isValid() )
00140     {
00141       mapMakeChild( iter.currentKey() ).copy( iter.currentChild() );
00142       iter.advance();
00143     }
00144     break;
00145   }
00146   case List:
00147   {
00148     int num_children = source.listLength();
00149     for( int i = 0; i < num_children; i++ )
00150     {
00151       listAppendNew().copy( source.listChildAt( i ));
00152     }
00153   }
00154   case Value:
00155     setValue( source.getValue() );
00156     break;
00157   default:
00158     break;
00159   }
00160 }
00161 
00162 Config Config::invalidConfig()
00163 {
00164   return Config( NodePtr() );
00165 }
00166 
00167 Config::Type Config::getType() const
00168 {
00169   return isValid() ? node_->type_ : Invalid;
00170 }
00171 
00172 void Config::setType( Type new_type )
00173 {
00174   if( new_type == Invalid )
00175   {
00176     node_ = NodePtr();
00177   }
00178   else
00179   {
00180     makeValid();
00181     node_->setType( new_type );
00182   }
00183 }
00184 
00185 void Config::mapSetValue( const QString& key, QVariant value )
00186 {
00187   mapMakeChild( key ).setValue( value );
00188 }
00189 
00190 Config Config::mapMakeChild( const QString& key )
00191 {
00192   Config child;
00193 
00194   makeValid();
00195   node_->setType( Map );
00196   (*node_->data_.map)[ key ] = child.node_;
00197 
00198   return child;
00199 }
00200 
00201 Config Config::mapGetChild( const QString& key ) const
00202 {
00203   if( node_.get() == NULL || node_->type_ != Map )
00204   {
00205     return invalidConfig();
00206   }
00207   Node::ChildMap::const_iterator iter = node_->data_.map->find( key );
00208   if( iter == node_->data_.map->end() )
00209   {
00210     return invalidConfig();
00211   }
00212   else
00213   {
00214     return Config( iter.value() );
00215   }
00216 }
00217 
00218 bool Config::mapGetValue( const QString& key, QVariant *value_out ) const
00219 {
00220   Config child = mapGetChild( key );
00221   if( child.getType() == Value ) // getType() checks for validity as well.
00222   {
00223     *value_out = child.getValue();
00224     return true;
00225   }
00226   return false;
00227 }
00228 
00229 bool Config::mapGetInt( const QString& key, int *value_out ) const
00230 {
00231   QVariant v;
00232   if( mapGetValue( key, &v ) && (v.type() == QVariant::Int || v.type() == QVariant::String ))
00233   {
00234     bool ok;
00235     int i = v.toInt( &ok );
00236     if( ok )
00237     {
00238       *value_out = i;
00239       return true;
00240     }
00241   }
00242   return false;
00243 }
00244 
00245 bool Config::mapGetFloat( const QString& key, float *value_out ) const
00246 {
00247   QVariant v;
00248   if( mapGetValue( key, &v ) && (int(v.type()) == int(QMetaType::Float) || v.type() == QVariant::Double || v.type() == QVariant::String ))
00249   {
00250     bool ok;
00251     float f = v.toFloat( &ok );
00252     if( ok )
00253     {
00254       *value_out = f;
00255       return true;
00256     }
00257     QString as_string = v.toString();
00258     // Try as European, e.g. 1.234,56 rather than 1,234.56
00259     QLocale german(QLocale::German);
00260     f = german.toFloat(as_string, &ok);
00261     if ( ok )
00262     {
00263       *value_out = f;
00264       return true;
00265     }
00266   }
00267   return false;
00268 }
00269 
00270 bool Config::mapGetBool( const QString& key, bool *value_out ) const
00271 {
00272   QVariant v;
00273   if( mapGetValue( key, &v ) && (v.type() == QVariant::Bool || v.type() == QVariant::String ))
00274   {
00275     *value_out = v.toBool();
00276     return true;
00277   }
00278   return false;
00279 }
00280 
00281 bool Config::mapGetString( const QString& key, QString *value_out ) const
00282 {
00283   QVariant v;
00284   if( mapGetValue( key, &v ) && v.type() == QVariant::String )
00285   {
00286     *value_out = v.toString();
00287     return true;
00288   }
00289   return false;
00290 }
00291 
00292 void Config::makeValid()
00293 {
00294   if( node_.get() == NULL )
00295   {
00296     node_.reset( new Node() );
00297   }
00298 }
00299 
00300 bool Config::isValid() const
00301 {
00302   return node_.get() != NULL;
00303 }
00304 
00305 void Config::setValue( const QVariant& value )
00306 {
00307   makeValid();
00308   node_->setType( Value );
00309   *node_->data_.value = value;
00310 }
00311 
00312 QVariant Config::getValue() const
00313 {
00314   return ( isValid() && node_->type_ == Value ) ? *node_->data_.value : QVariant();
00315 }
00316 
00317 int Config::listLength() const
00318 {
00319   return ( isValid() && node_->type_ == List ) ? node_->data_.list->size() : 0;
00320 }
00321 
00322 Config Config::listChildAt( int i ) const
00323 {
00324   if( isValid() && node_->type_ == List && i >= 0 && i < node_->data_.list->size() )
00325   {
00326     return Config( node_->data_.list->at( i ));
00327   }
00328   else
00329   {
00330     return invalidConfig();
00331   }
00332 }
00333 
00334 Config Config::listAppendNew()
00335 {
00336   Config child;
00337 
00338   setType( List );
00339   node_->data_.list->append( child.node_ );
00340 
00341   return child;
00342 }
00343 
00344 Config::MapIterator Config::mapIterator() const
00345 {
00346   // Create a new (invalid) iterator.
00347   Config::MapIterator iter;
00348 
00349   if( node_.get() == NULL || node_->type_ != Map )
00350   {
00351     // Force the node to be invalid, since this node does not have a map.
00352     iter.node_.reset();
00353   }
00354   else
00355   {
00356     // Copy this config's node reference into the iterator's node reference.
00357     iter.node_ = node_;
00358     iter.start();
00359   }
00360   return iter;
00361 }
00362 
00363 Config::MapIterator::MapIterator()
00364   : iterator_valid_( false )
00365 {}
00366 
00367 void Config::MapIterator::advance()
00368 {
00369   if( node_.get() == NULL || node_->type_ != Config::Map )
00370   {
00371     iterator_valid_ = false;
00372     return;
00373   }
00374   if( !iterator_valid_ )
00375   {
00376     iterator_ = node_->data_.map->begin();
00377     iterator_valid_ = true;
00378   }
00379   else
00380   {
00381     iterator_++;
00382   }
00383 }
00384 
00385 bool Config::MapIterator::isValid()
00386 {
00387   if( node_.get() == NULL || node_->type_ != Config::Map )
00388   {
00389     iterator_valid_ = false;
00390     return false;
00391   }
00392   if( !iterator_valid_ )
00393   {
00394     return false;
00395   }
00396   else
00397   {
00398     return iterator_ != node_->data_.map->end();
00399   }
00400 }
00401 
00402 void Config::MapIterator::start()
00403 {
00404   if( node_.get() == NULL || node_->type_ != Config::Map )
00405   {
00406     iterator_valid_ = false;
00407     return;
00408   }
00409   iterator_ = node_->data_.map->begin();
00410   iterator_valid_ = true;
00411 }
00412 
00413 QString Config::MapIterator::currentKey()
00414 {
00415   if( node_.get() == NULL || node_->type_ != Config::Map || !iterator_valid_ )
00416   {
00417     iterator_valid_ = false;
00418     return QString();
00419   }
00420   return iterator_.key();
00421 }
00422 
00423 Config Config::MapIterator::currentChild()
00424 {
00425   if( node_.get() == NULL || node_->type_ != Config::Map || !iterator_valid_ )
00426   {
00427     iterator_valid_ = false;
00428     return Config();
00429   }
00430   return Config( iterator_.value() );
00431 }
00432 
00433 } // end namespace rviz


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Thu Jun 6 2019 18:02:15