00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <cob_utilities/IniFile.h>
00019
00020 #include <math.h>
00021 #include <string.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024
00025 using namespace std;
00026
00027
00028 IniFile::IniFile(): m_vectorSize(500), m_CurCharInd(0)
00029 {
00030 m_bFileOK=false;
00031 m_CurLine.resize(m_vectorSize);
00032 }
00033
00034
00035 IniFile::IniFile(std::string fileName): m_vectorSize(500), m_CurCharInd(0)
00036 {
00037 m_bFileOK=false;
00038 m_CurLine.resize(m_vectorSize);
00039 if(fileName != "")
00040 SetFileName(fileName);
00041 }
00042
00043 IniFile::~IniFile()
00044 {
00045 }
00046
00047 int IniFile::SetFileName(std::string fileName, std::string strIniFileUsedBy, bool bCreate)
00048 {
00049 m_fileName = fileName;
00050 m_strIniFileUsedBy = strIniFileUsedBy;
00051
00052 if ((f = fopen(m_fileName.c_str(),"r")) == NULL)
00053 {
00054 if (bCreate == true)
00055 {
00056 f = fopen(m_fileName.c_str(),"w");
00057 std::cout << "Creating new INI-File " << m_fileName.c_str() << std::endl;
00058 fclose(f);
00059 }
00060 else
00061 {
00062 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
00063 return -1;
00064 }
00065 }
00066 else fclose(f);
00067 m_bFileOK = true;
00068 return 0;
00069 }
00070
00071 int IniFile::WriteKeyString(const char* pSect, const char* pKey, const std::string* pStrToWrite, bool bWarnIfNotfound)
00072 {
00073 std::string StrWithDelimeters = '"' + *pStrToWrite + '"';
00074 return WriteKeyValue(pSect, pKey, StrWithDelimeters.c_str(), bWarnIfNotfound);
00075 }
00076
00077 int IniFile::WriteKeyValue(const char* szSect,const char* szKey,const char* szValue, bool bWarnIfNotfound)
00078 {
00079 if (!m_bFileOK) return -1;
00080
00081 FILE* ftemp;
00082 int lS,lK,i,bEoff;
00083 int bFoundSect,bFoundKey;
00084 char c;
00085 long fpos;
00086
00087
00088
00089
00090 bFoundSect = 1 ;
00091 bFoundKey = 0 ;
00092 bEoff = 0;
00093 lS = strlen(szSect);
00094 lK = strlen(szKey);
00095 if ((lS * lK) == 0) return -1;
00096
00097
00098
00099 f = fopen(m_fileName.c_str(),"r");
00100 if (f == NULL)
00101 {
00102 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
00103 return -1;
00104 }
00105 if ((ftemp = tmpfile()) == NULL)
00106 {
00107 std::cout << "tmpfile() did not work!" << std::endl;
00108 return -1;
00109 }
00110
00111
00112
00113 if (FindSection(szSect, bWarnIfNotfound) != 0)
00114 {
00115 bFoundSect = 0;
00116 }
00117 fpos = ftell(f);
00118 if (bFoundSect)
00119 {
00120 if (!FindKey(szKey, false)) bFoundKey = 1;
00121 fpos = ftell(f);
00122 }
00123 if (feof(f)) bEoff = 1;
00124
00125
00126 fseek(f,0,SEEK_SET);
00127 for (i=0;i<fpos;i++)
00128 {
00129 fscanf(f,"%c",&c);
00130 fprintf(ftemp,"%c",c);
00131
00132 #ifdef WIN32
00133 if (c=='\n')
00134 i++;
00135 #endif
00136 };
00137
00138 if (!bFoundSect) {
00139 fprintf(ftemp,"\n\n[%s]\n",szSect);
00140 }
00141 if (bFoundSect && (!bFoundKey) && (bEoff))
00142 {
00143 fprintf(ftemp,"\n");
00144 }
00145
00146
00147 if (!bFoundKey)
00148 {
00149 fprintf(ftemp,"%s=",szKey);
00150 }
00151
00152 fprintf(ftemp,"%s",szValue);
00153
00154 if (bFoundKey) FindNextLine(m_CurLine, m_CurCharInd);
00155 if (!(bEoff || feof(f)))
00156 { fprintf(ftemp,"\n");
00157 while (!feof(f))
00158 {
00159 fscanf(f,"%c",&c);
00160 if (!feof(f))
00161 {
00162 fprintf(ftemp,"%c",c);
00163 }
00164 }
00165 }
00166 fpos = ftell(ftemp);
00167 fclose(f);
00168
00169 if ((f = fopen(m_fileName.c_str(),"w")) == NULL)
00170 {
00171 if ((f = fopen(m_fileName.c_str(),"r")) != NULL)
00172 {
00173 fclose(f);
00174 std::cout << "INI-File is write protected " << m_fileName.c_str() << std::endl;
00175 return -1;
00176 }
00177
00178 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
00179 return -1;
00180 }
00181 fseek(ftemp,0,SEEK_SET);
00182 for (i=0;i<fpos;i++)
00183 {
00184 fscanf(ftemp,"%c",&c);
00185 fprintf(f,"%c",c);
00186 };
00187 fclose(f);
00188 fclose(ftemp);
00189 return 0;
00190
00191 }
00192
00193 int IniFile::WriteKeyBool(const char* pSect, const char* pKey, bool bValue, bool bWarnIfNotfound)
00194 { if(bValue)
00195 return WriteKeyValue(pSect, pKey, "true", bWarnIfNotfound);
00196 else
00197 return WriteKeyValue(pSect, pKey, "false", bWarnIfNotfound);
00198 }
00199
00200 int IniFile::WriteKeyInt(const char* szSect,const char* szKey,int nValue, bool bWarnIfNotfound)
00201 {
00202 char buff[20];
00203 snprintf(buff, 10, "%d", nValue);
00204 return WriteKeyValue(szSect,szKey,buff, bWarnIfNotfound);
00205 }
00206
00207 int IniFile::WriteKeyDouble(const char* szSect,const char* szKey,double Value,
00208 int Length,int decimals, bool bWarnIfNotfound)
00209 {
00210 char buff[100];
00211 sprintf(buff, "%g", Value);
00212 return WriteKeyValue(szSect,szKey, buff, bWarnIfNotfound);
00213 }
00214
00215 int IniFile::GetKeyBool(const char* pSect, const char* pKey, bool* pValue,
00216 bool bWarnIfNotfound)
00217 {
00218 std::string strRead;
00219 char pBuf[20];
00220 *pValue = false;
00221 if (GetKeyValue(pSect, pKey, pBuf, 20, bWarnIfNotfound) == -1)
00222 return -1;
00223
00224 char* pChar = pBuf;
00225 while( *pChar == ' ' ) pChar++;
00226
00227 if( strncmp(pChar, "true", 4) == 0 )
00228 {
00229 *pValue = true;
00230 return 0;
00231 }
00232 if( strncmp(pChar, "false", 5) == 0 )
00233 {
00234 *pValue = false;
00235 return 0;
00236 }
00237
00238 return -1;
00239 }
00240
00241 int IniFile::GetKeyInt(const char* szSect,const char* szKey,int* pValue,
00242 bool bWarnIfNotfound)
00243 {
00244 char buf[9];
00245 if (GetKeyValue(szSect,szKey,buf,9, bWarnIfNotfound)!=-1)
00246 {
00247
00248 if (buf[0] == ' ')
00249 {
00250 for (int i=0; i<=6; i++)
00251 buf[i] = buf[i+1];
00252 buf[7]='\0';
00253 }
00254
00255 if ((buf[0]=='0') && (buf[1] == 'x'))
00256 {
00257 int iNumLength = 0;
00258
00259 for (int z=0; z<=7; z++)
00260 {
00261
00262 if ((buf[z+2]<0x30) || (buf[z+2]>0x3A))
00263 {
00264 iNumLength = z-1;
00265 break;
00266 }
00267 }
00268 *pValue = 0;
00269 for (int i=0; i<=(iNumLength); i++)
00270 {
00271
00272 *pValue += (buf[i+2]-0x30) * (int)pow((double)16, (iNumLength-i));
00273 }
00274 }
00275 else
00276 {
00277 *pValue = atoi(buf);
00278 }
00279 return 0;
00280
00281 }
00282 else return -1;
00283 }
00284
00285 int IniFile::GetKeyLong(const char* szSect,const char* szKey,long* pValue,
00286 bool bWarnIfNotfound)
00287 {
00288 char buf[9];
00289 if (GetKeyValue(szSect,szKey,buf,9, bWarnIfNotfound)!=-1)
00290 {
00291 *pValue = atol(buf);
00292 return 0;
00293 }
00294 else return -1;
00295 }
00296
00297 int IniFile::GetKeyDouble(const char* szSect,const char* szKey,double* pValue,
00298 bool bWarnIfNotfound)
00299 {
00300 char buf[50];
00301 if (GetKeyValue(szSect, szKey, buf, 50, bWarnIfNotfound) == -1)
00302 {
00303 if( bWarnIfNotfound )
00304 std::cout << "Setting parameter " << szKey <<" = " << *pValue << " of section '" << szSect <<
00305 "' in File '" << m_fileName.c_str() << std::endl;
00306 return -1;
00307 }
00308
00309 *pValue = atof(buf);
00310 return 0;
00311 }
00312
00313 int IniFile::GetKeyDouble(const char* pSect,const char* pKey,double* pValue,
00314 double dDefault, bool bWarnIfNotfound)
00315 {
00316 (*pValue) = dDefault;
00317 return GetKeyDouble(pSect, pKey, pValue, bWarnIfNotfound);
00318 }
00319
00320 int IniFile::GetKeyValue(const char* szSect,const char* szKey,char* szBuf,
00321 int lenBuf, bool bWarnIfNotfound)
00322 {
00323 if (!m_bFileOK) return -1;
00324
00325 int lS,lK;
00326
00327 lS = strlen(szSect);
00328 lK = strlen(szKey);
00329 if ((lS * lK) == 0) return -1;
00330 if ((f = fopen(m_fileName.c_str(),"r")) == NULL)
00331 {
00332 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
00333 return -1;
00334 }
00335 if ( FindSection(szSect, bWarnIfNotfound) )
00336 { fclose(f);
00337 return -1;
00338 }
00339 if ( FindKey(szKey, bWarnIfNotfound) )
00340 { fclose(f);
00341 return -1;
00342 }
00343
00344 if (feof(f))
00345 {
00346 fclose(f);
00347 return -1;
00348 }
00349
00350
00351 int BytesRead = fread( szBuf, 1, lenBuf, f );
00352
00353
00354 int StrLen;
00355 if(BytesRead < lenBuf)
00356 {
00357 if( BytesRead == 0 && (!feof(f)) )
00358 {
00359 std::cout << "file read" << std::endl;
00360 }
00361 StrLen = BytesRead;
00362 }
00363 else
00364 {
00365 StrLen = lenBuf-1;
00366 }
00367 szBuf[StrLen] = '\0';
00368
00369 fclose(f);
00370 return StrLen;
00371 }
00372
00373 int IniFile::GetKeyString(const char* szSect,const char* szKey, std::string* pStrToRead,
00374 bool bWarnIfNotfound)
00375 {
00376 if (!m_bFileOK) return -1;
00377
00378 int lS,lK;
00379
00380 lS = strlen(szSect);
00381 lK = strlen(szKey);
00382 if ((lS * lK) == 0) return -1;
00383 if ((f = fopen(m_fileName.c_str(),"r")) == NULL)
00384 {
00385 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
00386 return -1;
00387 }
00388 if ( FindSection(szSect, bWarnIfNotfound) )
00389 { fclose(f);
00390 return -1;
00391 }
00392 if ( FindKey(szKey, bWarnIfNotfound) )
00393 { fclose(f);
00394 return -1;
00395 }
00396
00397 if (feof(f))
00398 {
00399 fclose(f);
00400 return -1;
00401 }
00402
00403
00404 int res = SkipLineUntil(f, '"');
00405 if(res == -1)
00406 { if(bWarnIfNotfound)
00407 {
00408 std::cout << "GetKeyString section " << szSect << " key " << szKey << " first \" not found" << std::endl;
00409 }
00410 fclose(f);
00411 return -1;
00412 }
00413
00414 std::string strRead;
00415 res = ReadLineUntil(f, '"', strRead);
00416 if(res == -1)
00417 {
00418 if(bWarnIfNotfound)
00419 {
00420 std::cout << "GetKeyString section " << szSect << " key " << szKey << " string not found" << std::endl;
00421 }
00422 fclose(f);
00423 return -1;
00424 }
00425
00426
00427 *pStrToRead = strRead;
00428 fclose(f);
00429 return 0;
00430 }
00431
00432 int IniFile::SkipLineUntil(FILE* pFile, const char EndChar)
00433 {
00434 int CharsRead = 0;
00435 while (1)
00436 {
00437 int Char = fgetc(pFile);
00438
00439 if (Char == EndChar)
00440 return CharsRead;
00441
00442 if (Char == EOF || Char == '\n')
00443 return -1;
00444
00445 CharsRead++;
00446 }
00447 }
00448
00449 int IniFile::ReadLineUntil(FILE* pFile, const char EndChar, std::string& ReadIntoStr)
00450 {
00451 int CharsRead = 0;
00452 while (1)
00453 {
00454 int Char = fgetc(pFile);
00455
00456 if (Char == EndChar)
00457 return CharsRead;
00458
00459 if (Char == EOF || Char == '\n')
00460 return -1;
00461
00462 ReadIntoStr.append(1, char(Char));
00463
00464 CharsRead++;
00465 }
00466 }
00467
00468 int IniFile::FindNextLine(std::vector<char>& NewLine, int& CharInd)
00469 {
00470 if (!feof(f))
00471 {
00472 fgets(&NewLine[0], NewLine.size(), f);
00473 CharInd=0;
00474 return 0;
00475 }
00476 return -1;
00477 }
00478
00479 int IniFile::FindNextSection(std::string* pSect, std::string prevSect, bool bWarnIfNotfound)
00480 {
00481 std::vector<char> line;
00482
00483
00484
00485 if (!m_bFileOK) return -1;
00486
00487
00488 pSect->erase();
00489
00490
00491 f = fopen(m_fileName.c_str(),"r");
00492 if (f == NULL)
00493 {
00494 std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
00495 return -1;
00496 }
00497 if (feof(f)) return -1;
00498
00499
00500 if( prevSect != "" ) {
00501 FindSection( prevSect.c_str(), bWarnIfNotfound );
00502 } else {
00503 fseek(f,0,SEEK_SET);
00504 }
00505
00506 FindNextLine(m_CurLine, m_CurCharInd);
00507 do
00508 {
00509 if (m_CurLine[0] == '[')
00510 {
00511 while( m_CurCharInd < (int)m_CurLine.size() ) {
00512 m_CurCharInd++;
00513 if (m_CurLine[m_CurCharInd] == ']')
00514 {
00515 for( int i=1; i<m_CurCharInd; ++i )
00516 pSect->append(1, char(m_CurLine[i]));
00517 return 0;
00518 }
00519 }
00520 }
00521 else
00522 {
00523 FindNextLine(m_CurLine, m_CurCharInd);
00524 }
00525 }while (!feof(f));
00526
00527
00528 fclose(f);
00529
00530 return 0;
00531 }
00532
00533 int IniFile::FindSection(const char* sect,
00534 bool bWarnIfNotfound)
00535 {
00536 int lS;
00537 lS = strlen(sect);
00538 if (feof(f)) return -1;
00539
00540 FindNextLine(m_CurLine, m_CurCharInd);
00541 do
00542 {
00543 if (m_CurLine[0] == '[')
00544 {
00545 m_CurCharInd++;
00546 if ((strncmp(&m_CurLine[m_CurCharInd], sect, lS) == 0) && (m_CurLine[m_CurCharInd+lS] == ']'))
00547 {
00548 return 0;
00549 }
00550 else
00551 {
00552 FindNextLine(m_CurLine, m_CurCharInd);
00553 }
00554 }
00555 else if (m_CurLine[m_CurCharInd] == ' ')
00556 {
00557 m_CurCharInd++;
00558 }
00559 else
00560 {
00561 FindNextLine(m_CurLine, m_CurCharInd);
00562 }
00563 }while (!feof(f));
00564
00565
00566 if(bWarnIfNotfound)
00567 {
00568 std::cout << "Section [" << sect << "] in IniFile " << m_fileName.c_str() << " used by "
00569 << m_strIniFileUsedBy << " not found" << std::endl;
00570 }
00571
00572 return -1;
00573 }
00574
00575 int IniFile::FindKey(const char* skey,
00576 bool bWarnIfNotfound)
00577 {
00578 int lS;
00579 long fpos = 0l;
00580 lS = strlen(skey);
00581 if (feof(f)) return -1;
00582
00583 do
00584 {
00585 fpos=ftell(f);
00586 FindNextLine(m_CurLine, m_CurCharInd);
00587
00588 while ( m_CurLine[m_CurCharInd] == ' ' )
00589 {
00590 m_CurCharInd++;
00591 fpos++;
00592 }
00593
00594 if (m_CurLine[m_CurCharInd] == '[')
00595 break;
00596
00597 if (strncmp(&m_CurLine[m_CurCharInd], skey, lS) == 0)
00598 {
00599 m_CurCharInd+=lS;
00600 fpos+=lS;
00601 while ( m_CurLine[m_CurCharInd] == ' ' )
00602 {
00603 m_CurCharInd++;
00604 fpos++;
00605 }
00606 if ( m_CurLine[m_CurCharInd] == '=' )
00607 {
00608 m_CurCharInd++;
00609 fpos++;
00610 fseek(f,fpos,SEEK_SET);
00611 return 0;
00612 }
00613
00614 }
00615
00616 }while (!feof(f));
00617
00618 if(bWarnIfNotfound)
00619 {
00620 std::cout << "Key " << skey << " in IniFile '" << m_fileName.c_str() << "' used by "
00621 << m_strIniFileUsedBy << " not found" << std::endl;
00622 }
00623 return -1;
00624 }
00625
00626 int IniFile::GetKey(const char* pSect,const char* pKey, std::string* pStrToRead, bool bWarnIfNotfound)
00627 {
00628 return GetKeyString(pSect,pKey,pStrToRead,bWarnIfNotfound);
00629 }
00630
00631 int IniFile::GetKey(const char* pSect,const char* pKey,int* pValue, bool bWarnIfNotfound)
00632 {
00633 return GetKeyInt(pSect,pKey,pValue,bWarnIfNotfound);
00634 }
00635
00636
00637 int IniFile::GetKey(const char* pSect, const char* pKey, bool* pValue, bool bWarnIfNotfound)
00638 {
00639 return GetKeyBool(pSect,pKey,pValue,bWarnIfNotfound);
00640 }
00641
00642 int IniFile::GetKey(const char* pSect,const char* pKey,double* pValue, bool bWarnIfNotfound)
00643 {
00644 return GetKeyDouble(pSect,pKey,pValue,bWarnIfNotfound);
00645 }
00646