|
STK++ 1.0
|
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