$search
00001 /**************************************************************** 00002 * 00003 * Copyright (c) 2010 00004 * 00005 * Fraunhofer Institute for Manufacturing Engineering 00006 * and Automation (IPA) 00007 * 00008 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00009 * 00010 * Project name: care-o-bot 00011 * ROS stack name: cob3_driver 00012 * ROS package name: sickS300 00013 * Description: 00014 * 00015 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00016 * 00017 * Author: Christian Connette, email:christian.connette@ipa.fhg.de 00018 * Supervised by: Christian Connette, email:christian.connette@ipa.fhg.de 00019 * 00020 * Date of creation: Jan 2009 00021 * ToDo: Remove it! 00022 * 00023 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00024 * 00025 * Redistribution and use in source and binary forms, with or without 00026 * modification, are permitted provided that the following conditions are met: 00027 * 00028 * * Redistributions of source code must retain the above copyright 00029 * notice, this list of conditions and the following disclaimer. 00030 * * Redistributions in binary form must reproduce the above copyright 00031 * notice, this list of conditions and the following disclaimer in the 00032 * documentation and/or other materials provided with the distribution. 00033 * * Neither the name of the Fraunhofer Institute for Manufacturing 00034 * Engineering and Automation (IPA) nor the names of its 00035 * contributors may be used to endorse or promote products derived from 00036 * this software without specific prior written permission. 00037 * 00038 * This program is free software: you can redistribute it and/or modify 00039 * it under the terms of the GNU Lesser General Public License LGPL as 00040 * published by the Free Software Foundation, either version 3 of the 00041 * License, or (at your option) any later version. 00042 * 00043 * This program is distributed in the hope that it will be useful, 00044 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00045 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00046 * GNU Lesser General Public License LGPL for more details. 00047 * 00048 * You should have received a copy of the GNU Lesser General Public 00049 * License LGPL along with this program. 00050 * If not, see <http://www.gnu.org/licenses/>. 00051 * 00052 ****************************************************************/ 00053 00054 #include <cob_utilities/IniFile.h> 00055 00056 #include <math.h> 00057 #include <string.h> 00058 #include <stdio.h> 00059 #include <stdlib.h> 00060 00061 using namespace std; 00062 00063 //------------------------------------------------------------------- 00064 IniFile::IniFile(): m_vectorSize(500), m_CurCharInd(0) 00065 { 00066 m_bFileOK=false; 00067 m_CurLine.resize(m_vectorSize); 00068 } 00069 //-------------------------------------------------------------------------------- 00070 00071 IniFile::IniFile(std::string fileName): m_vectorSize(500), m_CurCharInd(0) 00072 { 00073 m_bFileOK=false; 00074 m_CurLine.resize(m_vectorSize); 00075 if(fileName != "") 00076 SetFileName(fileName); 00077 } 00078 //-------------------------------------------------------------------------------- 00079 IniFile::~IniFile() 00080 { 00081 } 00082 //-------------------------------------------------------------------------------- 00083 int IniFile::SetFileName(std::string fileName, std::string strIniFileUsedBy, bool bCreate) 00084 { 00085 m_fileName = fileName; 00086 m_strIniFileUsedBy = strIniFileUsedBy; 00087 00088 if ((f = fopen(m_fileName.c_str(),"r")) == NULL) 00089 { 00090 if (bCreate == true) 00091 { 00092 f = fopen(m_fileName.c_str(),"w"); // create new file 00093 std::cout << "Creating new INI-File " << m_fileName.c_str() << std::endl; 00094 fclose(f); 00095 } 00096 else 00097 { 00098 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl; 00099 return -1; 00100 } 00101 } 00102 else fclose(f); 00103 m_bFileOK = true; 00104 return 0; 00105 } 00106 //-------------------------------------------------------------------------------- 00107 int IniFile::WriteKeyString(const char* pSect, const char* pKey, const std::string* pStrToWrite, bool bWarnIfNotfound) 00108 { 00109 std::string StrWithDelimeters = '"' + *pStrToWrite + '"'; 00110 return WriteKeyValue(pSect, pKey, StrWithDelimeters.c_str(), bWarnIfNotfound); 00111 } 00112 //-------------------------------------------------------------------------------- 00113 int IniFile::WriteKeyValue(const char* szSect,const char* szKey,const char* szValue, bool bWarnIfNotfound) 00114 { 00115 if (!m_bFileOK) return -1; 00116 00117 FILE* ftemp; 00118 int lS,lK,i,bEoff; 00119 int bFoundSect,bFoundKey; 00120 char c; 00121 long fpos; 00122 00123 00124 /*------------------------verifications*/ 00125 00126 bFoundSect = 1 /* true*/; 00127 bFoundKey = 0 /* */; 00128 bEoff = 0; 00129 lS = strlen(szSect); 00130 lK = strlen(szKey); 00131 if ((lS * lK) == 0) return -1; 00132 00133 /*--------------------- file opening */ 00134 00135 f = fopen(m_fileName.c_str(),"r"); 00136 if (f == NULL) 00137 { 00138 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl; 00139 return -1; 00140 } 00141 if ((ftemp = tmpfile()) == NULL) 00142 { 00143 std::cout << "tmpfile() did not work!" << std::endl; 00144 return -1; 00145 } 00146 00147 00148 /* ---------------------- search section and key */ 00149 if (FindSection(szSect, bWarnIfNotfound) != 0) 00150 { 00151 bFoundSect = 0; 00152 } 00153 fpos = ftell(f); 00154 if (bFoundSect) 00155 { 00156 if (!FindKey(szKey, false)) bFoundKey = 1; 00157 fpos = ftell(f); 00158 } 00159 if (feof(f)) bEoff = 1; 00160 00161 /* --------------------- updating the file */ 00162 fseek(f,0,SEEK_SET); 00163 for (i=0;i<fpos;i++) 00164 { 00165 fscanf(f,"%c",&c); 00166 fprintf(ftemp,"%c",c); 00167 // MMB/23.02.2006: The counter i must not be incremented here on Linux machines! 00168 #ifdef WIN32 00169 if (c=='\n') 00170 i++; 00171 #endif 00172 }; 00173 00174 if (!bFoundSect) { 00175 fprintf(ftemp,"\n\n[%s]\n",szSect); 00176 } 00177 if (bFoundSect && (!bFoundKey) && (bEoff)) 00178 { 00179 fprintf(ftemp,"\n"); 00180 } 00181 00182 00183 if (!bFoundKey) 00184 { 00185 fprintf(ftemp,"%s=",szKey); 00186 } 00187 00188 fprintf(ftemp,"%s",szValue); 00189 00190 if (bFoundKey) FindNextLine(m_CurLine, m_CurCharInd); 00191 if (!(bEoff || feof(f))) 00192 { fprintf(ftemp,"\n"); 00193 while (!feof(f)) 00194 { 00195 fscanf(f,"%c",&c); 00196 if (!feof(f)) 00197 { 00198 fprintf(ftemp,"%c",c); 00199 } 00200 } 00201 } 00202 fpos = ftell(ftemp); 00203 fclose(f); 00204 00205 if ((f = fopen(m_fileName.c_str(),"w")) == NULL) 00206 { 00207 if ((f = fopen(m_fileName.c_str(),"r")) != NULL) 00208 { 00209 fclose(f); 00210 std::cout << "INI-File is write protected " << m_fileName.c_str() << std::endl; 00211 return -1; 00212 } 00213 00214 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl; 00215 return -1; 00216 } 00217 fseek(ftemp,0,SEEK_SET); 00218 for (i=0;i<fpos;i++) 00219 { 00220 fscanf(ftemp,"%c",&c); 00221 fprintf(f,"%c",c); 00222 }; 00223 fclose(f); 00224 fclose(ftemp); 00225 return 0; 00226 00227 } 00228 //-------------------------------------------------------------------------------- 00229 int IniFile::WriteKeyBool(const char* pSect, const char* pKey, bool bValue, bool bWarnIfNotfound) 00230 { if(bValue) 00231 return WriteKeyValue(pSect, pKey, "true", bWarnIfNotfound); 00232 else 00233 return WriteKeyValue(pSect, pKey, "false", bWarnIfNotfound); 00234 } 00235 //-------------------------------------------------------------------------------- 00236 int IniFile::WriteKeyInt(const char* szSect,const char* szKey,int nValue, bool bWarnIfNotfound) 00237 { 00238 char buff[20]; 00239 snprintf(buff, 10, "%d", nValue); 00240 return WriteKeyValue(szSect,szKey,buff, bWarnIfNotfound); 00241 } 00242 //-------------------------------------------------------------------------------- 00243 int IniFile::WriteKeyDouble(const char* szSect,const char* szKey,double Value, 00244 int Length/*=12*/,int decimals/*=5*/, bool bWarnIfNotfound) 00245 { 00246 char buff[100]; 00247 sprintf(buff, "%g", Value); 00248 return WriteKeyValue(szSect,szKey, buff, bWarnIfNotfound); 00249 } 00250 //-------------------------------------------------------------------------------- 00251 int IniFile::GetKeyBool(const char* pSect, const char* pKey, bool* pValue, 00252 bool bWarnIfNotfound) 00253 { 00254 std::string strRead; 00255 char pBuf[20]; 00256 *pValue = false; 00257 if (GetKeyValue(pSect, pKey, pBuf, 20, bWarnIfNotfound) == -1) 00258 return -1; 00259 00260 char* pChar = pBuf; 00261 while( *pChar == ' ' ) pChar++; // skip spaces 00262 00263 if( strncmp(pChar, "true", 4) == 0 ) 00264 { 00265 *pValue = true; 00266 return 0; 00267 } 00268 if( strncmp(pChar, "false", 5) == 0 ) 00269 { 00270 *pValue = false; 00271 return 0; 00272 } 00273 00274 return -1; 00275 } 00276 //-------------------------------------------------------------------------------- 00277 int IniFile::GetKeyInt(const char* szSect,const char* szKey,int* pValue, 00278 bool bWarnIfNotfound) 00279 { 00280 char buf[9]; 00281 if (GetKeyValue(szSect,szKey,buf,9, bWarnIfNotfound)!=-1) 00282 { 00283 //first get rid of spaces 00284 if (buf[0] == ' ') 00285 { 00286 for (int i=0; i<=6; i++) 00287 buf[i] = buf[i+1]; 00288 buf[7]='\0'; 00289 } 00290 00291 if ((buf[0]=='0') && (buf[1] == 'x')) 00292 { 00293 int iNumLength = 0; 00294 //check how long the hex-number is 00295 for (int z=0; z<=7; z++) 00296 { 00297 //if its not a number.. 00298 if ((buf[z+2]<0x30) || (buf[z+2]>0x3A)) 00299 { 00300 iNumLength = z-1; 00301 break; 00302 } 00303 } 00304 *pValue = 0; 00305 for (int i=0; i<=(iNumLength); i++) 00306 { 00307 //convert hex-string from character into int 00308 *pValue += (buf[i+2]-0x30) * (int)pow((double)16, (iNumLength-i)); 00309 } 00310 } 00311 else 00312 { 00313 *pValue = atoi(buf); 00314 } 00315 return 0; 00316 00317 } 00318 else return -1; 00319 } 00320 //-------------------------------------------------------------------------------- 00321 int IniFile::GetKeyLong(const char* szSect,const char* szKey,long* pValue, 00322 bool bWarnIfNotfound) 00323 { 00324 char buf[9]; 00325 if (GetKeyValue(szSect,szKey,buf,9, bWarnIfNotfound)!=-1) 00326 { 00327 *pValue = atol(buf); 00328 return 0; 00329 } 00330 else return -1; 00331 } 00332 //-------------------------------------------------------------------------------- 00333 int IniFile::GetKeyDouble(const char* szSect,const char* szKey,double* pValue, 00334 bool bWarnIfNotfound) 00335 { 00336 char buf[50]; 00337 if (GetKeyValue(szSect, szKey, buf, 50, bWarnIfNotfound) == -1) 00338 { 00339 if( bWarnIfNotfound ) 00340 std::cout << "Setting parameter " << szKey <<" = " << *pValue << " of section '" << szSect << 00341 "' in File '" << m_fileName.c_str() << std::endl; 00342 return -1; 00343 } 00344 00345 *pValue = atof(buf); 00346 return 0; 00347 } 00348 //----------------------------------------------- 00349 int IniFile::GetKeyDouble(const char* pSect,const char* pKey,double* pValue, 00350 double dDefault, bool bWarnIfNotfound) 00351 { 00352 (*pValue) = dDefault; 00353 return GetKeyDouble(pSect, pKey, pValue, bWarnIfNotfound); 00354 } 00355 //-------------------------------------------------------------------------------- 00356 int IniFile::GetKeyValue(const char* szSect,const char* szKey,char* szBuf, 00357 int lenBuf, bool bWarnIfNotfound) 00358 { 00359 if (!m_bFileOK) return -1; 00360 00361 int lS,lK; 00362 00363 lS = strlen(szSect); 00364 lK = strlen(szKey); 00365 if ((lS * lK) == 0) return -1; 00366 if ((f = fopen(m_fileName.c_str(),"r")) == NULL) 00367 { 00368 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl; 00369 return -1; 00370 } 00371 if ( FindSection(szSect, bWarnIfNotfound) ) 00372 { fclose(f); 00373 return -1; 00374 } 00375 if ( FindKey(szKey, bWarnIfNotfound) ) 00376 { fclose(f); 00377 return -1; 00378 } 00379 00380 if (feof(f)) 00381 { 00382 fclose(f); 00383 return -1; 00384 } 00385 00386 //----------- read szBuf bytes from file into szKey 00387 int BytesRead = fread( szBuf, 1, lenBuf, f ); 00388 00389 // terminate string 00390 int StrLen; 00391 if(BytesRead < lenBuf) 00392 { 00393 if( BytesRead == 0 && (!feof(f)) ) 00394 { 00395 std::cout << "file read" << std::endl; 00396 } 00397 StrLen = BytesRead; 00398 } 00399 else 00400 { 00401 StrLen = lenBuf-1; 00402 } 00403 szBuf[StrLen] = '\0'; 00404 00405 fclose(f); 00406 return StrLen; 00407 } 00408 //-------------------------------------------------------------------------------- 00409 int IniFile::GetKeyString(const char* szSect,const char* szKey, std::string* pStrToRead, 00410 bool bWarnIfNotfound) 00411 { 00412 if (!m_bFileOK) return -1; 00413 00414 int lS,lK; 00415 00416 lS = strlen(szSect); 00417 lK = strlen(szKey); 00418 if ((lS * lK) == 0) return -1; 00419 if ((f = fopen(m_fileName.c_str(),"r")) == NULL) 00420 { 00421 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl; 00422 return -1; 00423 } 00424 if ( FindSection(szSect, bWarnIfNotfound) ) 00425 { fclose(f); 00426 return -1; 00427 } 00428 if ( FindKey(szKey, bWarnIfNotfound) ) 00429 { fclose(f); 00430 return -1; 00431 } 00432 00433 if (feof(f)) 00434 { 00435 fclose(f); 00436 return -1; 00437 } 00438 00439 //----------- read szBuf bytes from file into szKey 00440 int res = SkipLineUntil(f, '"'); // find begin of string 00441 if(res == -1) 00442 { if(bWarnIfNotfound) 00443 { 00444 std::cout << "GetKeyString section " << szSect << " key " << szKey << " first \" not found" << std::endl; 00445 } 00446 fclose(f); 00447 return -1; 00448 } 00449 00450 std::string strRead; 00451 res = ReadLineUntil(f, '"', strRead); // read string 00452 if(res == -1) 00453 { 00454 if(bWarnIfNotfound) 00455 { 00456 std::cout << "GetKeyString section " << szSect << " key " << szKey << " string not found" << std::endl; 00457 } 00458 fclose(f); 00459 return -1; 00460 } 00461 00462 // success 00463 *pStrToRead = strRead; 00464 fclose(f); 00465 return 0; 00466 } 00467 //-------------------------------------------------------------------------------- 00468 int IniFile::SkipLineUntil(FILE* pFile, const char EndChar) 00469 { 00470 int CharsRead = 0; 00471 while (1) 00472 { 00473 int Char = fgetc(pFile); 00474 00475 if (Char == EndChar) // end found? 00476 return CharsRead; // read finished 00477 00478 if (Char == EOF || Char == '\n') 00479 return -1; // end not found 00480 00481 CharsRead++; 00482 } 00483 } 00484 //-------------------------------------------------------------------------------- 00485 int IniFile::ReadLineUntil(FILE* pFile, const char EndChar, std::string& ReadIntoStr) 00486 { 00487 int CharsRead = 0; 00488 while (1) 00489 { 00490 int Char = fgetc(pFile); 00491 00492 if (Char == EndChar) // end found? 00493 return CharsRead; // read finished 00494 00495 if (Char == EOF || Char == '\n') 00496 return -1; // end not found 00497 00498 ReadIntoStr.append(1, char(Char)); 00499 00500 CharsRead++; 00501 } 00502 } 00503 //-------------------------------------------------------------------------------- 00504 int IniFile::FindNextLine(std::vector<char>& NewLine, int& CharInd) 00505 { 00506 if (!feof(f)) 00507 { 00508 fgets(&NewLine[0], NewLine.size(), f); // store next line in NewLine 00509 CharInd=0; // makes CharInd reference the first char of the line 00510 return 0; 00511 } 00512 return -1; 00513 } 00514 //-------------------------------------------------------------------------------- 00515 int IniFile::FindNextSection(std::string* pSect, std::string prevSect, bool bWarnIfNotfound) 00516 { 00517 std::vector<char> line; 00518 //int charInd = 0; 00519 //int res = -1; 00520 00521 if (!m_bFileOK) return -1; 00522 00523 // Make sure that there is no old data. 00524 pSect->erase(); 00525 00526 /*--------------------- file opening */ 00527 f = fopen(m_fileName.c_str(),"r"); 00528 if (f == NULL) 00529 { 00530 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl; 00531 return -1; 00532 } 00533 if (feof(f)) return -1; 00534 00535 /*--------------------- search the section */ 00536 if( prevSect != "" ) { 00537 FindSection( prevSect.c_str(), bWarnIfNotfound ); 00538 } else { 00539 fseek(f,0,SEEK_SET); 00540 } 00541 00542 FindNextLine(m_CurLine, m_CurCharInd); //read first line of file 00543 do 00544 { 00545 if (m_CurLine[0] == '[') 00546 { 00547 while( m_CurCharInd < (int)m_CurLine.size() ) { 00548 m_CurCharInd++; 00549 if (m_CurLine[m_CurCharInd] == ']') // if found section name equals searched one 00550 { 00551 for( int i=1; i<m_CurCharInd; ++i ) 00552 pSect->append(1, char(m_CurLine[i])); 00553 return 0; 00554 } 00555 } 00556 } 00557 else 00558 { 00559 FindNextLine(m_CurLine, m_CurCharInd); 00560 } 00561 }while (!feof(f)); 00562 00563 /*--------------------- file closing */ 00564 fclose(f); 00565 00566 return 0; 00567 } 00568 //-------------------------------------------------------------------------------- 00569 int IniFile::FindSection(const char* sect, 00570 bool bWarnIfNotfound) 00571 { 00572 int lS; 00573 lS = strlen(sect); 00574 if (feof(f)) return -1; 00575 00576 FindNextLine(m_CurLine, m_CurCharInd); //read first line of file 00577 do 00578 { 00579 if (m_CurLine[0] == '[') 00580 { 00581 m_CurCharInd++; 00582 if ((strncmp(&m_CurLine[m_CurCharInd], sect, lS) == 0) && (m_CurLine[m_CurCharInd+lS] == ']')) // if found section name equals searched one 00583 { 00584 return 0; 00585 } 00586 else 00587 { 00588 FindNextLine(m_CurLine, m_CurCharInd); 00589 } 00590 } 00591 else if (m_CurLine[m_CurCharInd] == ' ') // if a blank is found 00592 { 00593 m_CurCharInd++; 00594 } 00595 else 00596 { 00597 FindNextLine(m_CurLine, m_CurCharInd); 00598 } 00599 }while (!feof(f)); 00600 00601 // not found 00602 if(bWarnIfNotfound) 00603 { 00604 std::cout << "Section [" << sect << "] in IniFile " << m_fileName.c_str() << " used by " 00605 << m_strIniFileUsedBy << " not found" << std::endl; 00606 } 00607 00608 return -1; 00609 } 00610 //-------------------------------------------------------------------------------- 00611 int IniFile::FindKey(const char* skey, 00612 bool bWarnIfNotfound) 00613 { 00614 int lS; 00615 long fpos = 0l; 00616 lS = strlen(skey); 00617 if (feof(f)) return -1; 00618 00619 do 00620 { 00621 fpos=ftell(f);// pointer to the begin of the last read line 00622 FindNextLine(m_CurLine, m_CurCharInd); 00623 00624 while ( m_CurLine[m_CurCharInd] == ' ' ) // skip blanks 00625 { 00626 m_CurCharInd++; 00627 fpos++; 00628 } 00629 00630 if (m_CurLine[m_CurCharInd] == '[') // next section? 00631 break; // not found 00632 00633 if (strncmp(&m_CurLine[m_CurCharInd], skey, lS) == 0) //Found 00634 { 00635 m_CurCharInd+=lS; 00636 fpos+=lS; // set file pointer to end of found key 00637 while ( m_CurLine[m_CurCharInd] == ' ' ) // skip blanks 00638 { 00639 m_CurCharInd++; 00640 fpos++; 00641 } 00642 if ( m_CurLine[m_CurCharInd] == '=' ) 00643 { 00644 m_CurCharInd++; // set index to first char after the = 00645 fpos++; 00646 fseek(f,fpos,SEEK_SET);// set file pointer to first char after the = 00647 return 0; 00648 } 00649 00650 } 00651 00652 }while (!feof(f)); 00653 00654 if(bWarnIfNotfound) 00655 { 00656 std::cout << "Key " << skey << " in IniFile '" << m_fileName.c_str() << "' used by " 00657 << m_strIniFileUsedBy << " not found" << std::endl; 00658 } 00659 return -1; 00660 } 00661 //----------------------------------------------- 00662 int IniFile::GetKey(const char* pSect,const char* pKey, std::string* pStrToRead, bool bWarnIfNotfound) 00663 { 00664 return GetKeyString(pSect,pKey,pStrToRead,bWarnIfNotfound); 00665 } 00666 //----------------------------------------------- 00667 int IniFile::GetKey(const char* pSect,const char* pKey,int* pValue, bool bWarnIfNotfound) 00668 { 00669 return GetKeyInt(pSect,pKey,pValue,bWarnIfNotfound); 00670 } 00671 //----------------------------------------------- 00672 00673 int IniFile::GetKey(const char* pSect, const char* pKey, bool* pValue, bool bWarnIfNotfound) 00674 { 00675 return GetKeyBool(pSect,pKey,pValue,bWarnIfNotfound); 00676 } 00677 //----------------------------------------------- 00678 int IniFile::GetKey(const char* pSect,const char* pKey,double* pValue, bool bWarnIfNotfound) 00679 { 00680 return GetKeyDouble(pSect,pKey,pValue,bWarnIfNotfound); 00681 } 00682