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 #include <PsString.h> 00019 #include <string> 00020 00021 #include <ctype.h> //pour la fonction qui vire les blancs 00022 #include <PsPolator.h> 00023 #include "PsController.h" 00024 #include "PsOutgoingSynchronisationMessage.h" 00025 #include "PsIncomingSynchronisationMessage.h" 00026 00027 #ifdef _MOME 00028 #include <PsnSharedMemoryManager.h> 00029 #include <PsMomeController.h> 00030 #include <PsnMemoryElementDescriptor.h> 00031 #endif 00032 #ifdef _USESSTREAM 00033 #include <sstream> 00034 #else 00035 #include <strstream> 00036 #endif 00037 // Constructors and destructors ********************************** 00038 00039 PsString::PsString ( const string & aString) 00040 { 00041 _CString = NULL; // Nettoyage de la mémoire 00042 _nbCarac = strlen( aString.c_str() ) ; 00043 assert (_nbCarac == aString.length ()) ; 00044 alloue( _nbCarac ); 00045 // On vérifie que le nombre de caractères est différent de 0 00046 if (_nbCarac != 0) 00047 { 00048 strcpy(_CString, aString.c_str()); 00049 assert (_CString [_nbCarac] == '\0') ; 00050 } 00051 else 00052 { 00053 _CString[0] = '\0'; 00054 } 00055 } 00056 00057 00058 PsString::PsString (const char *Chn) 00059 { 00060 //cerr<<"PsString : constructeur par recopie d'un char *"<<endl; 00061 if (Chn == NULL) 00062 { 00063 cerr << "PsString::PsString(const char*) : " << endl; 00064 PsController::error("La chaine fournie est un pointeur NULL"); 00065 } 00066 _CString = NULL; // Nettoyage de la mémoire 00067 _nbCarac = strlen(Chn); 00068 alloue(_nbCarac); 00069 // On vérifie que le nombre de caractères est différent de 0 00070 if (_nbCarac != 0) 00071 { 00072 // On ne copie que si nbCarac != 0 00073 strcpy(_CString, Chn); 00074 } 00075 else 00076 { 00077 _CString[0] = '\0'; 00078 } 00079 //cerr<<_CString<<endl; 00080 //cerr<<"PsString::recopie terminée pour "<<_CString<<endl; 00081 } 00082 00083 00084 PsString::PsString (const PsString &Chn) 00085 { 00086 //cerr<<"PsString::PsString (const PsString &Chn)"<<endl; 00087 _CString = NULL; // Nettoyage de la mémoire 00088 _nbCarac = Chn.getStringLength(); 00089 alloue(_nbCarac); 00090 if (_nbCarac != 0) 00091 { 00092 // On ne copie que si nbCarac != 0 00093 strcpy (_CString, Chn._CString); 00094 } 00095 else 00096 { 00097 _CString[0] = '\0'; 00098 } 00099 //cerr<<Chn<<endl<<*this<<endl; 00100 } 00101 00102 PsString::PsString (const char Carac) 00103 { 00104 cerr<<"PsString : construction from a char: "<<Carac<<endl; 00105 _CString = NULL; // Nettoyage de la mémoire 00106 _nbCarac = 1; 00107 alloue(_nbCarac); 00108 // On copie la caractère et la fin de chaîne 00109 _CString[0]= Carac; 00110 _CString[1]= '\0'; 00111 } 00112 00113 PsString::~PsString () 00114 { 00115 //cerr<<"PsString::~PsString"<<endl; 00116 // Si la chaîne a été allouée, on la désalloue 00117 if (_CString != NULL) 00118 { 00119 delete [] _CString; 00120 } 00121 //cerr<<"PsString::~PsString fini"<<endl; 00122 //gereVarClasse (Delete); 00123 } 00124 00125 PsPolatorNT * PsString::createPolator (void) { 00126 return (PsPolatorNT *) new PsPolator<PsString>(); 00127 } 00128 // Recherche dans la chaîne de caractères ********************** 00129 00130 int PsString::getSubString(const int debut, const int nbCarac, 00131 PsString& sousChaine) const 00132 { 00133 //assert ( _nbCarac == _tailleMem - 1) ; 00134 00135 // Nombre de caractères à copier 00136 int nbMin; 00137 00138 // On vérifie que l'indice de début est bien dans la chaîne 00139 if ( (debut >= _nbCarac) || (debut < 0) ) 00140 { 00141 cerr << "WARNING : PsString::getSubString() :" << endl; 00142 cerr << "Indice de début de sous-chaîne (" << debut 00143 << ") sort de la chaîne de taille (" 00144 << _nbCarac << ")" << endl; 00145 // On n'a pas copié de caractères 00146 return 0; 00147 } 00148 00149 // On regarde s'il veut tout le reste de la chaîne 00150 if (nbCarac <= 0) 00151 { 00152 // On va copier tous les autres caractères 00153 nbMin = _nbCarac-debut; 00154 } 00155 // On détermine le nombre de caractère à fournir en regardant 00156 // la limite de fin de chaîne 00157 else if ( (_nbCarac-debut) < nbCarac) 00158 { 00159 nbMin = _nbCarac-debut; 00160 } 00161 else 00162 { 00163 nbMin = nbCarac; 00164 } 00165 00166 // On vérifie qu'il y a assez de place dans sousChaine 00167 if (sousChaine._tailleMem <= nbMin) 00168 { 00169 // On alloue la place suffisante nbMin+1 00170 sousChaine.alloue(nbMin); 00171 } 00172 00173 // On fait la copie (pas de vérification à cet endroit-là) 00174 strncpy(sousChaine._CString, _CString+debut, nbMin); 00175 00176 // On ajoute la fin de chaîne 00177 sousChaine._CString[nbMin]= '\0'; 00178 sousChaine._nbCarac= nbMin; 00179 00180 // On renvoie le nombre de caractères copîés 00181 return nbMin; 00182 } 00183 00184 // PsType * PsString::cloner (void) const { 00185 // return (new PsString (*this)) ; 00186 // } 00187 00188 int 00189 PsString::getSubStringIndex (const PsString &cherche) const 00190 { 00191 if (cherche._nbCarac == 0) 00192 { 00193 cerr << "WARNING : PsString::getSubStringIndex() :" 00194 << "Taille de la sous-chaîne recherchée nulle" << endl; 00195 return -1; 00196 } 00197 00198 char *ptrDebut = strstr(_CString, cherche._CString); 00199 // A-t-on trouvé la chaîne ? 00200 if (ptrDebut == NULL) 00201 { 00202 // Pas trouvé 00203 return -1; 00204 } 00205 else 00206 { 00207 // On a trouvé 00208 return (ptrDebut - _CString); 00209 } 00210 } 00211 00212 int 00213 PsString::findCaracter (char Carac) const 00214 { 00215 char *ptrDebut = strchr(_CString, Carac); 00216 // A-t-on trouvé la chaîne ? 00217 if (ptrDebut == NULL) 00218 { 00219 // Pas trouvé 00220 return -1; 00221 } 00222 else 00223 { 00224 // On a trouvé 00225 return (ptrDebut - _CString); 00226 } 00227 } 00228 00229 // Opérateurs unaires ****************************************** 00230 char PsString::operator[] (int i) const 00231 { 00232 if ( (i<0) || (i>=_nbCarac) ) 00233 { 00234 cerr << "PsString::operator[]: index (" << i << ") hors limite" << endl; 00235 PsController::error(""); 00236 // Pour la compilation 00237 return 0; 00238 } 00239 else 00240 { 00241 return _CString[i]; 00242 } 00243 } 00244 00245 PsString& PsString::operator = (const PsString &Source) 00246 { 00247 //cerr<<"PsString::operator = "<<*this<<";"<<Source<<endl; 00248 // On vérifie que ce ne sont pas les mêmes chaînes, 00249 // sinon c'est fini 00250 if (_CString != Source._CString) 00251 { 00252 // Si on n'a pas la capacité de recevoir 00253 if (getCapacity() < Source._nbCarac) 00254 { 00255 alloue(Source._nbCarac); 00256 } 00257 // On fait la copie 00258 _nbCarac = Source._nbCarac; 00259 strcpy(_CString, Source._CString); 00260 } 00261 // On a terminé, on se renvoie 00262 return *this; 00263 } 00264 00265 00266 00267 00268 // PsType & PsString::operator = (const PsType &Source) 00269 // { 00270 // //cout << "PsString::operator = (const PsType &Source)" << endl; 00271 00272 // // Le cast des PsType doit exister vers les PsString, d'où : 00273 // //operator = (*((PsString *)&Source)); 00274 00275 // // On utilise l'insertion du type vers le flux 00276 // strstream fluxTmp; 00277 // fluxTmp << Source; 00278 00279 // // On extrait la PsString du flux 00280 // *this = fluxTmp.str(); 00281 00282 // // On l'affecte à notre chaîne 00283 // //*this = temp; 00284 00285 // return *this; 00286 // } 00287 00288 PsString & PsString::operator + (const PsType &Source) 00289 { 00290 //cerr << "PsString::operator + (const PsType &Source)" << endl; 00291 00292 //first insert the type in a string 00293 #ifdef _USESSTREAM 00294 ostringstream fluxTmp; 00295 fluxTmp << Source ; 00296 #else 00297 strstream fluxTmp; 00298 fluxTmp << Source <<'\0' ; 00299 #endif 00300 00301 //then constructuct a string corresponding to this 00302 string temp( getCString() ) ; 00303 00304 // append the two stings and copy the result into this 00305 *this = temp + fluxTmp.str() ; 00306 00307 //cerr << "PsString::operator + (const PsType &Source) done " << endl; 00308 return *this; 00309 } 00310 00311 PsString & PsString::operator + (const string & source) 00312 { 00313 //then constructuct a string corresponding to this 00314 string temp( getCString() ) ; 00315 00316 // append the two stings and copy the result into this 00317 *this = temp + source ; 00318 00319 //cerr << "PsString::operator + (const PsType &Source) done " << endl; 00320 return *this; 00321 } 00322 00323 00324 // Gestion des flux ******************************************** 00325 void PsString::pack(PsOutgoingSynchronisationMessage & out) const 00326 { 00327 out<<_nbCarac<<_CString; 00328 } 00329 00330 void PsString::unpack(PsIncomingSynchronisationMessage & in) 00331 { 00332 in>> _nbCarac ; 00333 if (_tailleMem <= _nbCarac) 00334 { 00335 // Allocate the necessary memory 00336 alloue(_nbCarac); 00337 } 00338 in>>_CString ; 00339 } 00340 00341 // Gestion des flux ******************************************** 00342 void PsString::pack(ostream & out) const 00343 { 00344 out<<_nbCarac<<" "<<_CString<<" "; 00345 } 00346 00347 void PsString::unpack(istream & in) 00348 { 00349 in>> _nbCarac ; 00350 if (_tailleMem <= _nbCarac) 00351 { 00352 // Allocate the necessary memory 00353 alloue(_nbCarac); 00354 } 00355 in.get (_CString, _nbCarac +1 ) ; 00356 } 00357 00358 void PsString::extract (istream & in) 00359 { 00360 //It is impossible to correctly extract an inserted stream because the inserted stream could have whitespaces 00361 string result ; 00362 in >> result ; 00363 alloue (result.size() + 1 ) ; 00364 strcpy (_CString, const_cast<char *>(result.c_str()) ); 00365 } 00366 00367 void PsString::insertInStream (ostream & out) const 00368 { 00369 // insert the string 00370 out << _CString; 00371 } 00372 00373 /************************************ operator << */ 00374 PsString & PsString::operator <<(separator f) 00375 { 00376 PsString espace(" "); 00377 *this=*this+espace; 00378 return *this; 00379 } 00380 00381 PsString & sep(PsString & oChaine) 00382 { 00383 return (oChaine); 00384 } 00385 00386 PsString & PsString::operator << (const char * f) { 00387 PsString tmp(f); 00388 *this<<tmp; 00389 return (*this); 00390 } 00391 00392 00393 PsString & PsString::operator << (const PsFlowable & f) { 00394 #ifdef _USESSTREAM 00395 ostringstream myos ; 00396 myos << f ; 00397 *this = (*this) + myos.str() ; 00398 #else 00399 char tampon[LG_MAX_BUFFER]; 00400 ostrstream myos(tampon,LG_MAX_BUFFER); 00401 myos<<f; 00402 int i = myos.pcount() ; 00403 PsString * chaineTemp; 00404 if (myos.fail()||(i>=LG_MAX_BUFFER)) { 00405 int tailleTampon=LG_MAX_BUFFER; 00406 char * biggerTampon; 00407 ostrstream * biggeros; 00408 do { 00409 tailleTampon=tailleTampon*2; 00410 biggerTampon=new char[tailleTampon]; 00411 biggeros=new ostrstream(biggerTampon,tailleTampon); 00412 *biggeros<<f; 00413 i = biggeros->pcount() ; 00414 } 00415 while(biggeros->fail()||(i>=tailleTampon)); 00416 biggerTampon[i] = '\0' ; 00417 chaineTemp=new PsString(biggerTampon); 00418 delete [] biggerTampon; 00419 delete biggeros; 00420 } 00421 else { 00422 tampon[i]='\0' ; 00423 chaineTemp=new PsString(tampon); 00424 } 00425 *this=*this+*chaineTemp; 00426 delete chaineTemp; 00427 #endif 00428 return(*this); 00429 } 00430 00431 PsString & PsString::operator >> (PsFlowable & f) { 00432 char * nouvelleChaine; 00433 int indiceDebutSuite; 00434 #ifdef _USESSTREAM 00435 istringstream myis(_CString); 00436 #else 00437 istrstream myis(_CString,_tailleMem); 00438 #endif 00439 myis>>f; 00440 if(myis.fail()) { 00441 #ifdef _DEBUGPVMMESS 00442 cerr<<"Impossible extraction" 00443 <<endl 00444 <<"The 2 main causes of this error are : you are trying to extract stuff from a string that wasn't inserted, but iether hand constructed in the string or not inserted at all" 00445 <<endl 00446 throw PsUserException ("PsString::operator>>: extraction impossible"); 00447 #endif 00448 } 00449 indiceDebutSuite=myis.tellg();//si il y a une suite, elle va commencer à indiceDebutSuite 00450 //on supprime les séparateurs 00451 while(isspace(_CString[indiceDebutSuite])&&(_CString[indiceDebutSuite]!='\0')) { 00452 indiceDebutSuite++; 00453 }; 00454 nouvelleChaine=new char[_tailleMem-indiceDebutSuite]; 00455 strcpy(nouvelleChaine,_CString+indiceDebutSuite); 00456 if (_CString != NULL) delete [] _CString; 00457 _CString=nouvelleChaine; 00458 _nbCarac=strlen(_CString); 00459 _tailleMem=_tailleMem-indiceDebutSuite; 00460 return (*this); 00461 } 00462 00463 00464 // Accesseurs en lecture **************************************** 00465 00466 int PsString::getStringLength() const 00467 { 00468 //assert ( _nbCarac == _tailleMem - 1) ; 00469 return _nbCarac; 00470 } 00471 00472 int PsString::getCapacity() const 00473 { 00474 //assert ( _nbCarac == _tailleMem - 1) ; 00475 return _tailleMem-1; 00476 } 00477 00478 const char* PsString::getCString() const 00479 { 00480 //assert ( _nbCarac == _tailleMem - 1) ; 00481 return _CString; 00482 } 00483 00484 // Opérateurs amis ********************************************* 00485 00486 bool operator > (const PsString &Source1, const PsString &Source2) 00487 { 00488 return (strcmp(Source1._CString, Source2._CString)> 0); 00489 } 00490 00491 bool operator < (const PsString &Source1, const PsString &Source2) 00492 { 00493 // cout<<"operator < (const PsString , const PsString)"<<endl; 00494 // cout<<"_"<<Source1._CString<<"_"<<Source2._CString<<"_"<<endl; 00495 return (strcmp(Source1._CString, Source2._CString)< 0); 00496 } 00497 00498 bool operator >= (const PsString &Source1, const PsString &Source2) 00499 { 00500 return (!(Source1 < Source2)); 00501 } 00502 00503 bool operator <= (const PsString &Source1, const PsString &Source2) 00504 { 00505 return (!(Source1 > Source2)); 00506 } 00507 00508 bool operator != (const PsString &Source1, const PsString &Source2) 00509 { 00510 // cout<<"operator != (const PsString , const PsString)"<<endl; 00511 // cout<<"_"<<Source1._CString<<"_"<<Source2._CString<<endl; 00512 return (strcmp(Source1._CString, Source2._CString)); 00513 } 00514 00515 00516 00517 bool operator == (const PsString &Source1, const PsString &Source2) 00518 { 00519 return (!(Source1 != Source2)); 00520 } 00521 00522 00523 00524 PsString PsString::operator ++ (int i) { 00525 PsString retour (*this); 00526 ++(*this); 00527 return retour; 00528 } 00529 00530 PsString & PsString::operator ++ () { 00531 char * nouvelleChaine; 00532 char zero('0'); 00533 char neuf('9'); 00534 if ((_nbCarac==0)|| 00535 ((zero>_CString[_nbCarac-1])||(_CString[_nbCarac-1]>=neuf))) { 00536 //on a besoin d'écrire une case plus loin 00537 if(_tailleMem<=_nbCarac+1) { 00538 //on a potentiellement besoin de réallouer de la place 00539 _tailleMem=_nbCarac+2; 00540 nouvelleChaine=new char[_tailleMem]; 00541 if (!nouvelleChaine) { 00542 PsController::error("ERROR : Impossible d'allouer de la mémoire pour ++"); 00543 } 00544 strcpy(nouvelleChaine,_CString); 00545 if (_CString!=NULL) { 00546 delete [] _CString; 00547 } 00548 _CString=nouvelleChaine; 00549 } 00550 if(_CString[_nbCarac-1]!=neuf) { 00551 _CString[_nbCarac]=zero; 00552 _CString[_nbCarac+1]='\0'; 00553 _nbCarac++; 00554 } 00555 else {//le dernier caractère est 9 00556 int indicePremierPasNeuf=_nbCarac-1; 00557 do { 00558 _CString[indicePremierPasNeuf]=zero; 00559 indicePremierPasNeuf--; 00560 } 00561 while (_CString[indicePremierPasNeuf]==neuf); 00562 if ( (_CString[indicePremierPasNeuf]>=zero)&&(_CString[indicePremierPasNeuf]<neuf)) 00563 { 00564 _CString[indicePremierPasNeuf]++; 00565 } 00566 else { 00567 _CString[indicePremierPasNeuf+1]='1'; 00568 _CString[_nbCarac]=zero; 00569 _CString[_nbCarac+1]='\0'; 00570 _nbCarac++; 00571 } 00572 } 00573 } 00574 else { 00575 _CString[_nbCarac-1]=_CString[_nbCarac-1]+1; 00576 } 00577 return *this; 00578 } 00579 00580 PsString & PsString::operator -- () { 00581 00582 char nouvelleChaine[20]; 00583 char zero('0'); 00584 char neuf('9'); 00585 int nbNum ; 00586 int nombreTemps =0 ; 00587 int i,nb ; 00588 int puissance = 1; 00589 00590 // cas chaine vide 00591 if (_nbCarac==0) 00592 return *this ; 00593 00594 // cas ou il n'y as pas de caractere numerique en fin de chaine 00595 if ((zero>_CString[_nbCarac-1])||(_CString[_nbCarac-1]>neuf)) 00596 return *this ; 00597 00598 // bon cas 00599 if ((zero<_CString[_nbCarac-1])&&(_CString[_nbCarac-1]<=neuf)) 00600 { 00601 // cas si un chiffre entre 1 et 9 00602 // +1, meme nombre de caractere 00603 _CString[_nbCarac-1]--; 00604 return *this ; 00605 } 00606 // on est dans le cas zero 00607 // conbien de caractere numerique ? 00608 // on sait que le dernier en est un 00609 nbNum = 1 ; 00610 while ( (zero<=_CString[_nbCarac-1-nbNum])&&(_CString[_nbCarac-1-nbNum]<=neuf) ) 00611 nbNum++; 00612 00613 if ((nbNum==1)&&(_CString[_nbCarac-1]==zero)) 00614 { 00615 _nbCarac--; 00616 _CString[_nbCarac]='\0'; 00617 return *this ; 00618 } 00619 00620 for(i=0;i<nbNum;i++) 00621 { 00622 nombreTemps = (_CString[_nbCarac-1-i]-zero)*puissance + nombreTemps ; 00623 puissance = puissance *10 ; 00624 } 00625 00626 nombreTemps--; 00627 nb=0; 00628 while (nombreTemps!=0) 00629 { 00630 // on rentre les chiffres a l'envers dans une chaine temporaire 00631 int val = nombreTemps % 10 ; 00632 nombreTemps = nombreTemps / 10 ; 00633 nouvelleChaine[nb] = zero + val ; 00634 nb++; 00635 } 00636 00637 for(int j=1;j<=nb;j++) 00638 _CString[_nbCarac-nbNum+j-1] = nouvelleChaine[nb-j] ; 00639 00640 //cout << " _nbCarac : " << _nbCarac << endl ; 00641 //cout << "nb : " << nb << endl ; 00642 //cout << "nbNum : " << nbNum << endl ; 00643 _nbCarac = _nbCarac - nbNum + nb ; 00644 _CString[_nbCarac] = '\0' ; 00645 00646 return *this ; 00647 } 00648 00649 // Méthode privée ************************************************ 00650 00651 // Fonction privée d'allocation d'espace mémoire pour la chaîne stockée. 00652 // Renvoie un pointeur char* ou interrompt le programme si l'allocation 00653 // échoue. 00654 void PsString::alloue(const int length) 00655 { 00656 // Make sure length is correct 00657 // assert (length >= 0 ); 00658 00659 // Si la chaîne était déjà allouée, on libère 00660 if (_CString!=NULL) 00661 { 00662 delete [] _CString; 00663 _CString = NULL ; 00664 } 00665 00666 // On prévoit le caractère de fin de chaîne 00667 _tailleMem = length + 1; 00668 // On alloue la chaîne 00669 #ifdef _MOME 00670 //si la chaine se trouve dans la mémoire partagée, il faut allouer le tampon dans la mémoire partagée 00671 PsnSharedMemoryManager * myMemory = PsMomeController::whichSharedMemoryManager(this); 00672 HeapStackTop newAllocationContext(myMemory) ; 00673 #endif 00674 _CString = new char[_tailleMem]; 00675 // Si l'allocation ne s'est pas bien passée 00676 if (!_CString) 00677 { 00678 PsController::error("ERROR : PsString::alloue() : Echec de l'allocation"); 00679 } 00680 //cerr<<"Allocation d'une chaine dans la méméoire à "<<(void *)_CString<<endl; 00681 } 00682
| Documentation generated on Mon Nov 25 15:25:02 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |