00001 /* 00002 * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software 00003 * 00004 * The Software has been developped within the Siames Project. 00005 * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights 00006 * 00007 * The Software has been registered with the Agence pour la Protection des 00008 * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200 00009 * 00010 * This file may be distributed under the terms of the Q Public License 00011 * version 1.0 as defined by Trolltech AS of Norway and appearing in the file 00012 * LICENSE.QPL included in the packaging of this file. 00013 * 00014 * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 00015 * for the software may use this file in accordance with that specific license 00016 * 00017 */ 00018 00019 #ifdef _USESSTREAM 00020 #include <sstream> 00021 #else 00022 #include <strstream> 00023 #endif 00024 00025 #include "PsMultipleConfigurationParameter.h" 00026 #include "PsController.h" 00027 #include "tokens.h" 00028 #include "string" 00029 00030 #include "stdio.h" 00031 #include "genericKernelParser.h" 00032 #include "KernelIstreamLexer.h" 00033 #include "DLGLexer.h" 00034 #include "ATokenBuffer.h" 00035 #include "ATokPtr.h" 00036 00037 PsMultipleConfigurationParameter::PsMultipleConfigurationParameter(const PsMultipleConfigurationParameter & orig ) : 00038 PsConfigurationParameterDescriptor ( orig ), 00039 _subDescriptors () 00040 { 00041 if (orig._associatedStringValid) 00042 { 00043 _associatedStringValid = true ; 00044 _associatedString= orig._associatedString ; 00045 } 00046 else 00047 { 00048 _associatedStringValid = false ; 00049 } 00050 00051 //reconstruct the data containers after having duplicated the subdescriptors 00052 FastAccessContainer::const_iterator j ; 00053 for (DataContainerType::const_iterator i = orig._subDescriptors.begin() ; 00054 i != orig._subDescriptors.end() ; 00055 ++i) 00056 { 00057 PsConfigurationParameterDescriptor * subdescriptorCopy = (*i).second->clone() ; 00058 _subDescriptors.push_back( DataContainerType::value_type( (*i).first, 00059 subdescriptorCopy ) 00060 ) ; 00061 00062 j = orig._hashtable.find ((*i).first ) ; 00063 if ( j != orig._hashtable.end() ) 00064 { 00065 _hashtable.insert ( FastAccessContainer::value_type ( (*i).first, 00066 subdescriptorCopy ) 00067 ) ; 00068 00069 } 00070 } 00071 } 00072 00073 00074 PsConfigurationParameterDescriptor * PsMultipleConfigurationParameter::clone() const 00075 { 00076 return new PsMultipleConfigurationParameter( *this ) ; 00077 } 00078 00079 00080 00081 00082 PsMultipleConfigurationParameter::PsMultipleConfigurationParameter( ) : 00083 PsConfigurationParameterDescriptor (), 00084 _subDescriptors (), 00085 _associatedStringValid ( false ) 00086 { 00087 00088 } 00089 00090 PsMultipleConfigurationParameter::~PsMultipleConfigurationParameter() 00091 { 00092 DataContainerType::iterator i ; 00093 for ( i = _subDescriptors.begin() ; 00094 i != _subDescriptors.end() ; 00095 i++ ) 00096 { 00097 delete i->second ; 00098 } 00099 } 00100 00101 00102 00103 const string & PsMultipleConfigurationParameter::getAssociatedString () const 00104 { 00105 if ( ! _associatedStringValid ) 00106 { 00107 string emptyString ; 00108 int numberOfSubItems = getNumberOfSubItems() ; 00109 _associatedString = "{ \n" ; 00110 DataContainerType::const_iterator i = _subDescriptors.begin() ; 00111 for ( int j = 0 ; 00112 j != numberOfSubItems - 1; 00113 ++j ) 00114 { 00115 //indent the subdescriptors 00116 _associatedString += " " ; 00117 if ( i-> first != emptyString ) 00118 { 00119 _associatedString += i-> first ; 00120 _associatedString += " = " ; 00121 } 00122 _associatedString += i->second->getAssociatedString() ; 00123 _associatedString += ",\n" ; 00124 i++ ; 00125 } 00126 //print the last item 00127 _associatedString += " " ; 00128 if ( i-> first != emptyString ) 00129 { 00130 _associatedString += i-> first ; 00131 _associatedString += " = " ; 00132 } 00133 _associatedString += i->second->getAssociatedString() ; 00134 _associatedString += "\n" ; 00135 00136 00137 _associatedString += "}" ; 00138 } 00139 _associatedStringValid = true ; 00140 return _associatedString ; 00141 } 00142 00143 00144 void PsMultipleConfigurationParameter::printToStream (ostream & out, int offset ) const 00145 { 00146 string emptyString ; 00147 int numberOfSubItems = getNumberOfSubItems() ; 00148 00149 DataContainerType::const_iterator i = _subDescriptors.begin() ; 00150 if ( i != _subDescriptors.end () ) 00151 { 00152 bool inList ; 00153 if ( i->first == emptyString ) 00154 { 00155 if ( ! _hashtable.empty() ) 00156 { 00157 out<<endl; 00158 printTabToStream(out,offset) ; 00159 out << "{" ; 00160 out<<endl; 00161 printTabToStream(out,offset+2) ; 00162 } 00163 out << "[ " ; 00164 inList = true ; 00165 } 00166 else 00167 { 00168 out<<endl; 00169 printTabToStream(out,offset) ; 00170 out << "{" ; 00171 inList = false ; 00172 } 00173 00174 for ( int j = 0 ; 00175 j != numberOfSubItems ; 00176 ++j ) 00177 { 00178 //at each step, if not printing a list of unamed values, new line has just been inserted 00179 if ( inList ) 00180 { 00181 if ( i-> first != emptyString ) 00182 { 00183 // the list was finished by the preceeding value 00184 out << "]" ; 00185 inList = false ; 00186 out<<endl; 00187 printTabToStream (out, offset + 2 ) ; 00188 out<< i->first <<" "; 00189 i->second->printToStream (out, offset + 2 ) ; 00190 } 00191 else 00192 { 00193 i->second->printToStream (out, offset + 4 ) ; 00194 out<<" "; 00195 } 00196 } 00197 else 00198 { 00199 if ( i-> first == emptyString ) 00200 { 00201 //starting a list 00202 out << "[ " ; 00203 inList = true ; 00204 i->second->printToStream (out, offset + 4 ) ; 00205 out<<" "; 00206 } 00207 else 00208 { 00209 out << endl ; 00210 printTabToStream (out, offset + 2 ) ; 00211 out<< i->first <<" " ; 00212 i->second->printToStream (out, offset + 4 ) ; 00213 } 00214 } 00215 i++ ; 00216 } 00217 if (inList) 00218 { 00219 out<<"]"; 00220 if ( ! _hashtable.empty() ) 00221 { 00222 out<<endl; 00223 printTabToStream (out, offset ) ; 00224 out<<"}"; 00225 } 00226 } 00227 else 00228 { 00229 out<<endl; 00230 printTabToStream (out, offset ) ; 00231 out<<"}"; 00232 } 00233 } 00234 else 00235 { 00236 out<<" - undefined - "; 00237 } 00238 } 00239 00240 00241 00242 const PsConfigurationParameterDescriptor * PsMultipleConfigurationParameter::getSubDescriptorByName (const string & descriptorName ) const 00243 { 00244 PsConfigurationParameterDescriptor * result = NULL ; 00245 FastAccessContainer::const_iterator i ; 00246 i = _hashtable.find (descriptorName) ; 00247 if ( i != _hashtable.end() ) 00248 { 00249 result = i->second ; 00250 assert ( result != NULL ) ; 00251 } 00252 else 00253 { 00254 result = NULL ; 00255 } 00256 return result ; 00257 } 00258 00259 00260 PsConfigurationParameterDescriptor * PsMultipleConfigurationParameter::getSubDescriptorByName (const string & descriptorName ) 00261 { 00262 PsConfigurationParameterDescriptor * result = NULL ; 00263 FastAccessContainer::const_iterator i ; 00264 i = _hashtable.find (descriptorName) ; 00265 if ( i != _hashtable.end() ) 00266 { 00267 result = i->second ; 00268 assert ( result != NULL ) ; 00269 } 00270 else 00271 { 00272 result = NULL ; 00273 } 00274 return result ; 00275 } 00276 00277 00278 00279 const PsConfigurationParameterDescriptor * PsMultipleConfigurationParameter::getSubDescriptorByPosition (int descriptorPosition) const 00280 { 00281 if (descriptorPosition >= _subDescriptors.size() ) 00282 { 00283 return NULL ; 00284 } 00285 else 00286 { 00287 assert ( _subDescriptors[descriptorPosition].second != NULL ) ; 00288 return _subDescriptors[descriptorPosition].second ; 00289 } 00290 } 00291 00292 const string & PsMultipleConfigurationParameter::getNameOfSubDescriptor (int descriptorPosition) const 00293 { 00294 assert (descriptorPosition < _subDescriptors.size() ) ; 00295 return _subDescriptors[descriptorPosition].first ; 00296 } 00297 00298 00299 PsConfigurationParameterDescriptor * PsMultipleConfigurationParameter::getSubDescriptorByPosition (int descriptorPosition) 00300 { 00301 if (descriptorPosition >= _subDescriptors.size() ) 00302 { 00303 return NULL ; 00304 } 00305 else 00306 { 00307 assert ( _subDescriptors[descriptorPosition].second != NULL ) ; 00308 return _subDescriptors[descriptorPosition].second ; 00309 } 00310 } 00311 00312 00313 00314 int PsMultipleConfigurationParameter::getNumberOfSubItems () const 00315 { 00316 return _subDescriptors.size() ; 00317 } 00318 00319 00320 00321 int PsMultipleConfigurationParameter::appendSubDescriptor(PsConfigurationParameterDescriptor * subDescriptor ) 00322 { 00323 assert ( subDescriptor != NULL ) ; 00324 _subDescriptors.push_back ( DataContainedType ( string() ,subDescriptor ) ) ; 00325 return _subDescriptors.size() - 1 ; 00326 } 00327 00328 00329 00330 int PsMultipleConfigurationParameter::appendSubDescriptorNamed (const string & descriptorName, PsConfigurationParameterDescriptor * subDescriptor ) 00331 { 00332 assert ( subDescriptor != NULL ) ; 00333 pair<FastAccessContainer::iterator ,bool > result = _hashtable.insert( FastAccessContainer::value_type(descriptorName, subDescriptor) ) ; 00334 // only add the sub descriptor if no subsdescriptor with the same name was allready added 00335 if (result.second) 00336 { 00337 _subDescriptors.push_back ( DataContainedType ( descriptorName, subDescriptor ) ) ; 00338 } 00339 else 00340 { 00341 replaceSubDescriptorNamed ( descriptorName, subDescriptor ) ; 00342 } 00343 return _subDescriptors.size() - 1 ; 00344 } 00345 00346 00347 int PsMultipleConfigurationParameter::appendSubDescriptorsOf (const PsMultipleConfigurationParameter & otherDescriptor) 00348 { 00349 if ( _hashtable.size() == 0 ) 00350 { 00351 *this = otherDescriptor ; 00352 } 00353 else 00354 { 00355 string emptyString ; 00356 for ( DataContainerType::const_iterator i = otherDescriptor._subDescriptors.begin() ; 00357 i != otherDescriptor._subDescriptors.end() ; 00358 ++i) 00359 { 00360 //_subDescriptors.push_back ( *i ) ; 00361 if ( (*i).first != emptyString ) 00362 { 00363 PsConfigurationParameterDescriptor * existingDescriptor = getSubDescriptorByName ((*i).first) ; 00364 if ( existingDescriptor == NULL ) 00365 { 00366 PsConfigurationParameterDescriptor * newDescriptor = (*i).second->clone() ; 00367 00368 _hashtable.insert( FastAccessContainer::value_type ( (*i).first , newDescriptor ) ) ; 00369 00370 _subDescriptors.push_back( DataContainedType((*i).first,newDescriptor) ) ; 00371 } 00372 else 00373 { 00374 #ifdef _USESSTREAM 00375 ostringstream warningMessage ; 00376 #else 00377 ostrstream warningMessage ; 00378 #endif 00379 warningMessage << "While merging two PsMultipleConfigurationParameter: " 00380 <<"2 subdescriptors named "<<(*i).first<<" found: "; 00381 00382 PsMultipleConfigurationParameter * originalDescriptor ; 00383 originalDescriptor = dynamic_cast<PsMultipleConfigurationParameter * > (existingDescriptor) ; 00384 PsMultipleConfigurationParameter * appendedDescriptor ; 00385 appendedDescriptor = dynamic_cast<PsMultipleConfigurationParameter * > ((*i).second) ; 00386 if ( (originalDescriptor != NULL) && 00387 (appendedDescriptor != NULL) ) 00388 { 00389 if ( originalDescriptor->_hashtable.size() == 0 ) 00390 { 00391 //it is a list of values, replace 00392 replaceSubDescriptorNamed ((*i).first, appendedDescriptor) ; 00393 } 00394 else 00395 { 00396 originalDescriptor->appendSubDescriptorsOf ( *appendedDescriptor ) ; 00397 } 00398 } 00399 else 00400 { 00401 _hashtable.erase ( (*i).first ) ; 00402 00403 //find (*i).first in the vector 00404 DataContainerType::iterator j = _subDescriptors.begin() ; 00405 00406 //(*i).first should be present in the vector 00407 assert ( j != _subDescriptors.end() ); 00408 while ( (*j).first != (*i).first ) 00409 { 00410 ++j ; 00411 assert ( j != _subDescriptors.end() ); 00412 } 00413 00414 PsConfigurationParameterDescriptor * newDescriptor = (*i).second->clone() ; 00415 00416 _hashtable.insert( FastAccessContainer::value_type ( (*i).first , newDescriptor ) ) ; 00417 00418 (*j).second = newDescriptor ; 00419 00420 warningMessage<<"Replaced original value: that was "<<existingDescriptor->getAssociatedString() ; 00421 assert ( existingDescriptor != NULL ) ; 00422 delete existingDescriptor ; 00423 } 00424 #ifdef _USESSTREAM 00425 PsController::warning (warningMessage.str(), PsController::AllWarnings) ; 00426 #else 00427 warningMessage.put('\0') ; 00428 PsController::warning (warningMessage.str(), PsController::AllWarnings) ; 00429 delete warningMessage.str() ; 00430 #endif 00431 } 00432 } 00433 } 00434 } 00435 return _subDescriptors.size() - 1 ; 00436 } 00437 00438 00439 00440 int PsMultipleConfigurationParameter::replaceSubDescriptorNamed (const string & descriptorName, PsConfigurationParameterDescriptor * subDescriptor) 00441 { 00442 FastAccessContainer::iterator i ; 00443 i = _hashtable.find (descriptorName) ; 00444 if ( i == _hashtable.end() ) 00445 { 00446 return appendSubDescriptorNamed ( descriptorName, subDescriptor) ; 00447 } 00448 else 00449 { 00450 int result = 0 ; 00451 00452 //find descriptorName in the vector 00453 DataContainerType::iterator j = _subDescriptors.begin() ; 00454 00455 //It should be present 00456 assert ( j != _subDescriptors.end() ); 00457 00458 while ( (*j).first != descriptorName ) 00459 { 00460 ++j ; 00461 ++result ; 00462 //descriptorName should be present 00463 assert ( j != _subDescriptors.end() ); 00464 } 00465 00466 //delete the old descriptor 00467 delete (*i).second ; 00468 00469 //replace it 00470 (*i).second = subDescriptor ; 00471 (*j).second = subDescriptor ; 00472 00473 assert (_subDescriptors[result].second == subDescriptor) ; 00474 return result ; 00475 } 00476 } 00477 00478 00479 int PsMultipleConfigurationParameter::replaceSubDescriptor (int position, PsConfigurationParameterDescriptor * subDescriptor) 00480 { 00481 assert (position < _subDescriptors.size() ) ; 00482 string descriptorName = _subDescriptors[position].first ; 00483 string emptyString ; 00484 PsConfigurationParameterDescriptor * replacedDescription = _subDescriptors[position].second ; 00485 00486 if ( descriptorName != emptyString ) 00487 { 00488 FastAccessContainer::iterator i ; 00489 i = _hashtable.find (descriptorName) ; 00490 00491 //the descriptor should be present in the hash table 00492 assert ( i != _hashtable.end() ) ; 00493 (*i).second = subDescriptor ; 00494 } 00495 delete replacedDescription ; 00496 _subDescriptors[position].second = subDescriptor ; 00497 return position ; 00498 } 00499 00500 00501 00502 void PsMultipleConfigurationParameter::pack ( PsOutgoingSynchronisationMessage & out) const 00503 { 00504 #ifdef _USESSTREAM 00505 ostringstream char_out ; 00506 printToStream ( char_out, 0 ) ; 00507 out<<char_out.str() ; 00508 #else 00509 ostrstream char_out ; 00510 printToStream ( char_out, 0 ) ; 00511 char_out.put ('\0') ; 00512 char * C_string = char_out.str() ; 00513 assert (C_string[char_out.pcount()-1] == '\0') ; 00514 out<<char_out.pcount() ; 00515 out<<C_string; 00516 delete C_string ; 00517 #endif 00518 } 00519 00520 void PsMultipleConfigurationParameter::unpack ( PsIncomingSynchronisationMessage & in) 00521 { 00522 _hashtable.clear () ; 00523 _subDescriptors.clear () ; 00524 00525 int messageSize ; 00526 00527 #ifdef _USESSTREAM 00528 string messageBuffer ; 00529 in>>messageBuffer ; 00530 istringstream message ( messageBuffer ) ; 00531 #else 00532 in>>messageSize ; 00533 char * messageBuffer = new char [messageSize + 1]; 00534 in>>messageBuffer ; 00535 00536 assert (messageBuffer[messageSize] == '\0' ) ; 00537 00538 istrstream message ( messageBuffer ); 00539 #endif 00540 extract (message ) ; 00541 00542 // //this doesn't work, because a IncomingSynchronisationMessage dosn't known the size of what has to be extracted 00543 // KernelIstreamLexer<PsIncomingSynchronisationMessage> inputStream (in) ; 00544 // DLGLexer scan( & inputStream ) ; 00545 // ANTLRTokenBuffer pipe ( & scan ) ; 00546 // ANTLRTokenPtr aToken = new ANTLRToken() ; 00547 // scan.setToken(mytoken(aToken)) ; 00548 // genericKernelParser extractor ( &pipe ) ; 00549 // extractor.init() ; 00550 // extractor.multipleValue ( this ) ; 00551 } 00552 00553 void PsMultipleConfigurationParameter::insertInStream (ostream & out) const 00554 { 00555 printToStream ( out, 0 ) ; 00556 } 00557 00558 void PsMultipleConfigurationParameter::extract (istream & in) 00559 { 00560 _hashtable.clear () ; 00561 _subDescriptors.clear () ; 00562 00563 KernelIstreamLexer<istream> inputStream (in) ; 00564 DLGLexer scan( & inputStream ) ; 00565 ANTLRTokenBuffer pipe ( & scan ) ; 00566 ANTLRTokenPtr aToken = new ANTLRToken() ; 00567 scan.setToken(mytoken(aToken)) ; 00568 genericKernelParser extractor ( &pipe ) ; 00569 extractor.init() ; 00570 extractor.multipleValue ( this ) ; 00571 }
| Documentation generated on Mon Nov 25 15:25:00 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |