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 "rviz/config.h"
00031 
00032 namespace rviz
00033 {
00034 
00036 // Config::Node internal data storage class
00038 
00039 class Config::Node
00040 {
00041 public:
00042   Node();
00043   ~Node();
00044 
00045   void setType( Config::Type new_type );
00046   void deleteData();
00047 
00048   typedef QMap<QString, NodePtr> ChildMap;
00049   typedef QList<NodePtr> ChildList;
00050 
00051   Config::Type type_;
00052   union
00053   {
00054     ChildMap* map;
00055     ChildList* list;
00056     QVariant* value;
00057   } data_;
00058 };
00059 
00060 Config::Node::Node()
00061   : type_( Empty )
00062 {
00063   data_.map = NULL;
00064 }
00065 
00066 Config::Node::~Node()
00067 {
00068   deleteData();
00069 }
00070 
00071 void Config::Node::deleteData()
00072 {
00073   switch( type_ )
00074   {
00075   case Map: delete data_.map; break;
00076   case List: delete data_.list; break;
00077   case Value: delete data_.value; break;
00078   default:
00079     break;
00080   }
00081   data_.map = NULL;
00082 }
00083 
00084 void Config::Node::setType( Config::Type new_type )
00085 {
00086   if( type_ == new_type )
00087   {
00088     return;
00089   }
00090   deleteData();
00091   type_ = new_type;
00092   switch( type_ )
00093   {
00094   case Map:   data_.map =   new ChildMap;  break;
00095   case List:  data_.list =  new ChildList; break;
00096   case Value: data_.value = new QVariant;  break;
00097   default:                                 break;
00098   }
00099 }
00100 
00102 // Config wrapper class
00104 
00105 Config::Config()
00106   : node_( new Config::Node() )
00107 {}
00108 
00109 Config::Config( const Config& source )
00110   : node_( source.node_ )
00111 {}
00112 
00113 Config::Config( QVariant value )
00114   : node_( new Config::Node() )
00115 {
00116   setValue( value );
00117 }
00118 
00119 Config::Config( NodePtr node )
00120   : node_( node )
00121 {}
00122 
00123 void Config::copy( const Config& source )
00124 {
00125   if( !source.isValid() )
00126   {
00127     node_ = NodePtr();
00128     return;
00129   }
00130 
00131   setType( source.getType() );
00132   switch( source.getType() )
00133   {
00134   case Map:
00135   {
00136     MapIterator iter = source.mapIterator();
00137     while( iter.isValid() )
00138     {
00139       mapMakeChild( iter.currentKey() ).copy( iter.currentChild() );
00140       iter.advance();
00141     }
00142     break;
00143   }
00144   case List:
00145   {
00146     int num_children = source.listLength();
00147     for( int i = 0; i < num_children; i++ )
00148     {
00149       listAppendNew().copy( source.listChildAt( i ));
00150     }
00151   }
00152   case Value:
00153     setValue( source.getValue() );
00154     break;
00155   default:
00156     break;
00157   }
00158 }
00159 
00160 Config Config::invalidConfig()
00161 {
00162   return Config( NodePtr() );
00163 }
00164 
00165 Config::Type Config::getType() const
00166 {
00167   return isValid() ? node_->type_ : Invalid;
00168 }
00169 
00170 void Config::setType( Type new_type )
00171 {
00172   if( new_type == Invalid )
00173   {
00174     node_ = NodePtr();
00175   }
00176   else
00177   {
00178     makeValid();
00179     node_->setType( new_type );
00180   }
00181 }
00182 
00183 void Config::mapSetValue( const QString& key, QVariant value )
00184 {
00185   mapMakeChild( key ).setValue( value );
00186 }
00187 
00188 Config Config::mapMakeChild( const QString& key )
00189 {
00190   Config child;
00191 
00192   makeValid();
00193   node_->setType( Map );
00194   (*node_->data_.map)[ key ] = child.node_;
00195 
00196   return child;
00197 }
00198 
00199 Config Config::mapGetChild( const QString& key ) const
00200 {
00201   if( node_.get() == NULL || node_->type_ != Map )
00202   {
00203     return invalidConfig();
00204   }
00205   Node::ChildMap::const_iterator iter = node_->data_.map->find( key );
00206   if( iter == node_->data_.map->end() )
00207   {
00208     return invalidConfig();
00209   }
00210   else
00211   {
00212     return Config( iter.value() );
00213   }
00214 }
00215 
00216 bool Config::mapGetValue( const QString& key, QVariant *value_out ) const
00217 {
00218   Config child = mapGetChild( key );
00219   if( child.getType() == Value ) // getType() checks for validity as well.
00220   {
00221     *value_out = child.getValue();
00222     return true;
00223   }
00224   return false;
00225 }
00226 
00227 bool Config::mapGetInt( const QString& key, int *value_out ) const
00228 {
00229   QVariant v;
00230   if( mapGetValue( key, &v ) && (v.type() == QVariant::Int || v.type() == QVariant::String ))
00231   {
00232     bool ok;
00233     int i = v.toInt( &ok );
00234     if( ok )
00235     {
00236       *value_out = i;
00237       return true;
00238     }
00239   }
00240   return false;
00241 }
00242 
00243 bool Config::mapGetFloat( const QString& key, float *value_out ) const
00244 {
00245   QVariant v;
00246   if( mapGetValue( key, &v ) && (int(v.type()) == int(QMetaType::Float) || v.type() == QVariant::Double || v.type() == QVariant::String ))
00247   {
00248     bool ok;
00249     float f = v.toFloat( &ok );
00250     if( ok )
00251     {
00252       *value_out = f;
00253       return true;
00254     }
00255   }
00256   return false;
00257 }
00258 
00259 bool Config::mapGetBool( const QString& key, bool *value_out ) const
00260 {
00261   QVariant v;
00262   if( mapGetValue( key, &v ) && (v.type() == QVariant::Bool || v.type() == QVariant::String ))
00263   {
00264     *value_out = v.toBool();
00265     return true;
00266   }
00267   return false;
00268 }
00269 
00270 bool Config::mapGetString( const QString& key, QString *value_out ) const
00271 {
00272   QVariant v;
00273   if( mapGetValue( key, &v ) && v.type() == QVariant::String )
00274   {
00275     *value_out = v.toString();
00276     return true;
00277   }
00278   return false;
00279 }
00280 
00281 void Config::makeValid()
00282 {
00283   if( node_.get() == NULL )
00284   {
00285     node_.reset( new Node() );
00286   }
00287 }
00288 
00289 bool Config::isValid() const
00290 {
00291   return node_.get() != NULL;
00292 }
00293 
00294 void Config::setValue( const QVariant& value )
00295 {
00296   makeValid();
00297   node_->setType( Value );
00298   *node_->data_.value = value;
00299 }
00300 
00301 QVariant Config::getValue() const
00302 {
00303   return ( isValid() && node_->type_ == Value ) ? *node_->data_.value : QVariant();
00304 }
00305 
00306 int Config::listLength() const
00307 {
00308   return ( isValid() && node_->type_ == List ) ? node_->data_.list->size() : 0;
00309 }
00310 
00311 Config Config::listChildAt( int i ) const
00312 {
00313   if( isValid() && node_->type_ == List && i >= 0 && i < node_->data_.list->size() )
00314   {
00315     return Config( node_->data_.list->at( i ));
00316   }
00317   else
00318   {
00319     return invalidConfig();
00320   }
00321 }
00322 
00323 Config Config::listAppendNew()
00324 {
00325   Config child;
00326 
00327   setType( List );
00328   node_->data_.list->append( child.node_ );
00329 
00330   return child;
00331 }
00332 
00333 Config::MapIterator Config::mapIterator() const
00334 {
00335   // Create a new (invalid) iterator.
00336   Config::MapIterator iter;
00337 
00338   if( node_.get() == NULL || node_->type_ != Map )
00339   {
00340     // Force the node to be invalid, since this node does not have a map.
00341     iter.node_.reset();
00342   }
00343   else
00344   {
00345     // Copy this config's node reference into the iterator's node reference.
00346     iter.node_ = node_;
00347     iter.start();
00348   }
00349   return iter;
00350 }
00351 
00352 Config::MapIterator::MapIterator()
00353   : iterator_valid_( false )
00354 {}
00355 
00356 void Config::MapIterator::advance()
00357 {
00358   if( node_.get() == NULL || node_->type_ != Config::Map )
00359   {
00360     iterator_valid_ = false;
00361     return;
00362   }
00363   if( !iterator_valid_ )
00364   {
00365     iterator_ = node_->data_.map->begin();
00366     iterator_valid_ = true;
00367   }
00368   else
00369   {
00370     iterator_++;
00371   }
00372 }
00373 
00374 bool Config::MapIterator::isValid()
00375 {
00376   if( node_.get() == NULL || node_->type_ != Config::Map )
00377   {
00378     iterator_valid_ = false;
00379     return false;
00380   }
00381   if( !iterator_valid_ )
00382   {
00383     return false;
00384   }
00385   else
00386   {
00387     return iterator_ != node_->data_.map->end();
00388   }
00389 }
00390 
00391 void Config::MapIterator::start()
00392 {
00393   if( node_.get() == NULL || node_->type_ != Config::Map )
00394   {
00395     iterator_valid_ = false;
00396     return;
00397   }
00398   iterator_ = node_->data_.map->begin();
00399   iterator_valid_ = true;
00400 }
00401 
00402 QString Config::MapIterator::currentKey()
00403 {
00404   if( node_.get() == NULL || node_->type_ != Config::Map || !iterator_valid_ )
00405   {
00406     iterator_valid_ = false;
00407     return QString();
00408   }
00409   return iterator_.key();
00410 }
00411 
00412 Config Config::MapIterator::currentChild()
00413 {
00414   if( node_.get() == NULL || node_->type_ != Config::Map || !iterator_valid_ )
00415   {
00416     iterator_valid_ = false;
00417     return Config();
00418   }
00419   return Config( iterator_.value() );
00420 }
00421 
00422 } // end namespace rviz


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Mon Oct 6 2014 07:26:35