STK++ 1.0
STK_Option.cpp
Go to the documentation of this file.
00001 /*--------------------------------------------------------------------*/
00002 /*     Copyright (C) 2004-2010  Serge Iovleff
00003 
00004  This program is free software; you can redistribute it and/or modify
00005  it under the terms of the GNU Lesser General Public License as
00006  published by the Free Software Foundation; either version 2 of the
00007  License, or (at your option) any later version.
00008 
00009  This program is distributed in the hope that it will be useful,
00010  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  GNU Lesser General Public License for more details.
00013 
00014  You should have received a copy of the GNU Lesser General Public
00015  License along with this program; if not, write to the
00016  Free Software Foundation, Inc.,
00017  59 Temple Place,
00018  Suite 330,
00019  Boston, MA 02111-1307
00020  USA
00021 
00022  Contact : Serge.Iovleff@stkpp.org
00023  */
00024 
00025 /*
00026  * Project:  stkpp::Dmanager
00027  * created on: 18 oct. 2010
00028  * Purpose:  .
00029  * Author:   iovleff, serge.iovleff@stkpp.org
00030  *
00031  **/
00032 
00037 #include "../include/STK_Option.h"
00038 #include "../include/STK_IPage.h"
00039 
00040 #include "../../STKernel/include/STK_String_Util.h"
00041 #include "../../STKernel/include/STK_Exceptions.h"
00042 
00043 namespace STK
00044 {
00045 
00046 /* defaut constructor
00047  * @param name the name of the Option
00048  **/
00049 Option::Option( String const& name, TypeOption type, bool isOptional)
00050               : name_(name)
00051               , sep_(CHAR_SEP)
00052               , type_(type)
00053               , isOptional_(isOptional)
00054               , isValued_(false)
00055               , p_String_(0)
00056 {
00057   toUpperString(name_);
00058   setDefaultValue();
00059 }
00060 
00061 /* Special constructor. This will construct an option as a sub-page. The
00062  * name of the option will be the name of the page.
00063  * @param page the page to set as option
00064  **/
00065 Option::Option( IPage const& page)
00066               : name_(page.name())
00067               , sep_(CHAR_SEP)
00068               , type_(page_)
00069               , isOptional_(page.isOptional())
00070               , isValued_(true)
00071               , p_Page_(page.clone())
00072 {
00073   toUpperString(name_);
00074 }
00075 
00076 /* Copy constructor.
00077  * @param opt the Option to copy
00078  **/
00079 Option::Option( Option const& opt)
00080               : name_(opt.name_)
00081               , sep_(opt.sep_)
00082               , type_(opt.type_)
00083               , isOptional_(opt.isOptional_)
00084               , isValued_(opt.isOptional_)
00085               , p_String_(0)
00086 {
00087   // copy rhs value
00088   switch (type_)
00089   {
00090     case string_:
00091       if (opt.p_String_) set(*(opt.p_String_));
00092       else p_String_ = 0;
00093       break;
00094     case real_:
00095       if (opt.p_Real_) set(*(opt.p_Real_));
00096       else p_Real_ = 0;
00097       break;
00098     case integer_:
00099       if (opt.p_Integer_) set(*(opt.p_Integer_));
00100       else p_Integer_ = 0;
00101       break;
00102     case range_:
00103       if (opt.p_Range_) set(*(opt.p_Range_));
00104       else p_Range_ = 0;
00105       break;
00106     case lstring_:
00107       if (opt.p_lString_) set(*(opt.p_lString_));
00108       else p_lString_ = 0;
00109       break;
00110     case lreal_:
00111       if (opt.p_lReal_) set(*(opt.p_lReal_));
00112       else p_lReal_ = 0;
00113       break;
00114     case linteger_:
00115       if (opt.p_lInteger_) set(*(opt.p_lInteger_));
00116       else p_lInteger_ = 0;
00117       break;
00118     case lrange_:
00119       if (opt.p_lRange_) set(*(opt.p_lRange_));
00120       else p_lRange_ = 0;
00121       break;
00122     case page_:
00123       if (opt.p_Page_) setPage(*(opt.p_Page_));
00124       else p_Page_ = 0;
00125       break;
00126     case unknown_:
00127       runtime_error("Error in Option(opt). Unknown type option.\n");
00128   };
00129 }
00130 
00131 /*
00132  * destructor.
00133  */
00134 Option::~Option()
00135 { deleteValue();}
00136 
00137 /*
00138  * copy
00139  */
00140 Option& Option::operator=( Option const& opt)
00141 {
00142   // Do the assignment operation of the members
00143   name_ = opt.name_;
00144   sep_ = opt.sep_;
00145   type_ = opt.type_;
00146   isOptional_ = opt.isOptional_;
00147   isValued_ = opt.isValued_;
00148   // copy rhs value
00149   switch (type_)
00150   {
00151     case string_:
00152       if (opt.p_String_) set(*(opt.p_String_));
00153       else p_String_ = 0;
00154       break;
00155     case real_:
00156       if (opt.p_Real_) set(*(opt.p_Real_));
00157       else p_Real_ = 0;
00158       break;
00159     case integer_:
00160       if (opt.p_Integer_) set(*(opt.p_Integer_));
00161       else p_Integer_ = 0;
00162       break;
00163     case range_:
00164       if (opt.p_Range_) set(*(opt.p_Range_));
00165       else p_Range_ = 0;
00166       break;
00167     case lstring_:
00168       if (opt.p_lString_) set(*(opt.p_lString_));
00169       else p_lString_ = 0;
00170       break;
00171     case lreal_:
00172       if (opt.p_lReal_) set(*(opt.p_lReal_));
00173       else p_lReal_ = 0;
00174       break;
00175     case linteger_:
00176       if (opt.p_lInteger_) set(*(opt.p_lInteger_));
00177       else p_lInteger_ = 0;
00178       break;
00179     case lrange_:
00180       if (opt.p_lRange_) set(*(opt.p_lRange_));
00181       else p_lRange_ = 0;
00182       break;
00183     case page_:
00184       if (opt.p_Page_) setPage(*(opt.p_Page_));
00185       else p_Page_ = 0;
00186       break;
00187     case unknown_:
00188       runtime_error("Error in Option::operator=(opt). Unknown type option.\n");
00189   };
00190   // return this
00191   return *this;  // Return a reference to myself.
00192 }
00193 /* Convert a string in a value
00194  * @param str the string to convert
00195  * @return @c true if the conversion success, @c false otherwise
00196  */
00197 bool Option::setValue( String const& str )
00198 {
00199   // list of values
00200   Range rangeValue;
00201   std::list<String> lStringValue;
00202   std::list<Real> lRealValue;
00203   std::list<Integer> lIntegerValue;
00204   std::list<Range> lRangeValue;
00205   // choose type
00206   switch (type_)
00207   {
00208     case string_:
00209       set(str);
00210       break;
00211     case real_:
00212       Real realValue;
00213       if (stringToType(realValue, str))
00214         set(realValue);
00215       else
00216         runtime_error("Error in Option::setValue(value). Conversion failed.\n");
00217       break;
00218     case integer_:
00219       Integer integerValue;
00220       if (stringToType(integerValue, str))
00221         set(integerValue);
00222       else
00223         runtime_error("Error in Option::setValue(value). Conversion failed.\n");
00224       break;
00225     case range_:
00226       if (stringToType(rangeValue, str))
00227       { set(rangeValue);}
00228       else
00229         runtime_error("Error in Option::setValue(value). Conversion failed.\n");
00230       break;
00231     case lstring_:
00232       DManager::readList(str, lStringValue);
00233       set(lStringValue);
00234       break;
00235     case lreal_:
00236       DManager::readList(str, lRealValue);
00237       set(lRealValue);
00238       break;
00239     case linteger_:
00240       DManager::readList(str, lIntegerValue);
00241       set(lIntegerValue);
00242       break;
00243     case lrange_:
00244       DManager::readList(str, lRangeValue);
00245       set(lRangeValue);
00246       break;
00247     case page_:
00248       runtime_error("Error in Option::setValue(value). Page option.\n");
00249       break;
00250     case unknown_:
00251       runtime_error("Error in Option::setValue(value). Unknown type option.\n");
00252   };
00253   // error if an error occur in readList ?
00254   return true;
00255 }
00256 
00257 /*  set a value from a Page.
00258  *  @param value the Page to set
00259  **/
00260 void Option::setPage( IPage const& value )
00261 {
00262   deleteValue();
00263   p_Page_ = value.clone();
00264   isValued_ = true;
00265   type_ = page_;
00266 }
00267 
00268 
00269 /* @brief write out the option in the output stream
00270  *  @param os output stream
00271  */
00272 void Option::write( ostream& os) const
00273 {
00274   // write option name if it's not a page
00275   if (type_ != page_)
00276   {  // write name and " = "
00277     os << name_ << STRING_BLANK << CHAR_EQUAL << STRING_BLANK;
00278   }
00279   // write option value
00280   switch (type_)
00281   {
00282     case string_:
00283       if (p_String_)
00284         os << *p_String_;
00285       break;
00286     case real_:
00287       if (p_Real_)
00288         os << *p_Real_;
00289       break;
00290     case integer_:
00291       if (p_Integer_)
00292         os << *p_Integer_;
00293       break;
00294     case range_:
00295       if (p_Range_)
00296         os << *p_Range_;
00297       break;
00298     case lstring_:
00299       if (p_lString_)
00300         DManager::writeList(os, *p_lString_, sep_);
00301       break;
00302     case lreal_:
00303       if (p_lReal_)
00304       DManager::writeList(os, *p_lReal_, sep_);
00305       break;
00306     case linteger_:
00307       if (p_lInteger_)
00308         DManager::writeList(os, *p_lInteger_, sep_);
00309       break;
00310     case lrange_:
00311       if (p_lRange_)
00312         DManager::writeList(os, *p_lRange_, sep_);
00313       break;
00314     case page_:
00315       if (p_Page_)
00316         p_Page_->write(os);
00317       break;
00318     case unknown_:
00319       runtime_error("Error in Option::setValue(value). Unknown type option.\n");
00320 
00321   };
00322 }
00323 
00324 /* @brief read out the option from the input stream
00325  *  @param is input stream
00326  */
00327 void Option::read( istream& is)
00328 {
00329   // read option value
00330   if (type_ == page_)
00331   {
00332       if (p_Page_)
00333       {
00334         p_Page_->read(is);
00335         if (!p_Page_->validate())
00336         {
00337           throw runtime_error("Error in Option::read(is) <A sub-page is not validated>.\n");
00338         }
00339       }
00340   };
00341 }
00342 
00343 /*  set a value from string.
00344  *  @param value the string value to set
00345  **/
00346 void Option::set( String const& value )
00347 {
00348   deleteValue();
00349   p_String_ = new String(value);
00350   isValued_ = true;
00351 }
00352 
00353 /*  set a value from a Real.
00354  *  @param value the real value to set
00355  **/
00356 void Option::set( Real const& value )
00357 {
00358   deleteValue();
00359   p_Real_ = new Real(value);
00360   isValued_ = true;
00361 }
00362 
00363 /*  set a value from an Integer.
00364  *  @param value the integer value to set
00365  **/
00366 void Option::set( Integer const& value )
00367 {
00368   deleteValue();
00369   p_Integer_ = new Integer(value);
00370   isValued_ = true;
00371 }
00372 
00373 /*  set a value from a Range.
00374  *  @param value the Range value to set
00375  **/
00376 void Option::set( Range const& value )
00377 {
00378   deleteValue();
00379   p_Range_ = new Range(value);
00380   isValued_ = true;
00381 }
00382 
00383 /*  set a value from a list of Real.
00384  *  @param value the list real values to set
00385  **/
00386 void Option::set( std::list<String> const& value )
00387 {
00388   deleteValue();
00389   p_lString_ = new std::list<String>(value);
00390   isValued_ = true;
00391 }
00392 
00393 /*  set a value from a list of Real.
00394  *  @param value the list real values to set
00395  **/
00396 void Option::set( std::list<Real> const& value )
00397 {
00398   deleteValue();
00399   p_lReal_ = new std::list<Real>(value);
00400   isValued_ = true;
00401 }
00402 
00403 /*  set a value from a list of Integer.
00404  *  @param value the list of integer value to set
00405  **/
00406 void Option::set( std::list<Integer> const& value )
00407 {
00408   deleteValue();
00409   p_lInteger_ = new std::list<Integer>(value);
00410   isValued_ = true;
00411 }
00412 /*  set a value from a list of Range.
00413  *  @param value the list of Range to set
00414  **/
00415 void Option::set( std::list<Range> const& value )
00416 {
00417   deleteValue();
00418   p_lRange_ = new std::list<Range>(value);
00419   isValued_ = true;
00420 }
00421 
00422 // delete allocated value
00423 void Option::deleteValue()
00424 {
00425   switch (type_)
00426   {
00427     case string_:
00428       if (p_String_) delete p_String_;
00429       p_String_ = 0;
00430       break;
00431     case real_:
00432       if (p_Real_) delete p_Real_;
00433       p_Real_ = 0;
00434       break;
00435     case integer_:
00436       if (p_Integer_) delete p_Integer_;
00437       p_Integer_ = 0;
00438       break;
00439     case range_:
00440       if (p_Range_) delete p_Range_;
00441       p_Range_ = 0;
00442       break;
00443     case lstring_:
00444       if (p_lString_) delete p_lString_;
00445       p_lString_ = 0;
00446       break;
00447     case lreal_:
00448       if (p_lReal_) delete p_lReal_;
00449       p_lReal_ = 0;
00450       break;
00451     case linteger_:
00452       if (p_lInteger_) delete p_lInteger_;
00453       p_lInteger_ = 0;
00454       break;
00455     case lrange_:
00456       if (p_lRange_) delete p_lRange_;
00457       p_lRange_ = 0;
00458       break;
00459     case page_:
00460       if (p_Page_) delete p_Page_;
00461       p_Page_ = 0;
00462       break;
00463     default:
00464       break;
00465   };
00466   isValued_ = false;
00467 }
00468 
00469 /*set A default value to the option.
00470  */
00471 void Option::setDefaultValue()
00472 {
00473   //deleteValue();
00474   switch (type_)
00475   {
00476     case string_:
00477       p_String_ = new String;
00478       *p_String_ = STRING_NA;
00479       break;
00480     case real_:
00481       p_Real_ = new Real;
00482       *p_Real_ = Arithmetic<Real>::NA();
00483       break;
00484     case integer_:
00485       p_Integer_ = new Integer;
00486       *p_Integer_ = Arithmetic<Integer>::NA();
00487       break;
00488     case range_:
00489       p_Range_ = new Range;
00490       break;
00491     case lstring_:
00492       p_lString_ = new std::list<String>;
00493       break;
00494     case lreal_:
00495       p_lReal_ = new std::list<Real>;
00496       break;
00497     case linteger_:
00498       p_lInteger_ = new std::list<Integer>;
00499       break;
00500     case lrange_:
00501       p_lRange_ = new std::list<Range>;
00502       break;
00503     case page_:
00504       p_Page_ = 0;
00505       break;
00506     default:
00507       break;
00508   };
00509 }
00510 
00511 } // namespace STK