Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

PsMultipleConfigurationParameter.cxx

Go to the documentation of this file.
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 }

logo OpenMask

Documentation generated on Mon Nov 25 15:25:00 2002

Generated with doxygen 1.2.12 by Dimitri van Heesch ,   1997-2001