IniFile.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <cob_utilities/IniFile.h>
19 
20 #include <math.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 using namespace std;
26 
27 //-------------------------------------------------------------------
28 IniFile::IniFile(): m_vectorSize(500), m_CurCharInd(0)
29 {
30  m_bFileOK=false;
31  m_CurLine.resize(m_vectorSize);
32 }
33 //--------------------------------------------------------------------------------
34 
35 IniFile::IniFile(std::string fileName): m_vectorSize(500), m_CurCharInd(0)
36 {
37  m_bFileOK=false;
38  m_CurLine.resize(m_vectorSize);
39  if(fileName != "")
40  SetFileName(fileName);
41 }
42 //--------------------------------------------------------------------------------
44 {
45 }
46 //--------------------------------------------------------------------------------
47 int IniFile::SetFileName(std::string fileName, std::string strIniFileUsedBy, bool bCreate)
48 {
49  m_fileName = fileName;
50  m_strIniFileUsedBy = strIniFileUsedBy;
51 
52  if ((f = fopen(m_fileName.c_str(),"r")) == NULL)
53  {
54  if (bCreate == true)
55  {
56  f = fopen(m_fileName.c_str(),"w"); // create new file
57  std::cout << "Creating new INI-File " << m_fileName.c_str() << std::endl;
58  fclose(f);
59  }
60  else
61  {
62  std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
63  return -1;
64  }
65  }
66  else fclose(f);
67  m_bFileOK = true;
68  return 0;
69 }
70 //--------------------------------------------------------------------------------
71 int IniFile::WriteKeyString(const char* pSect, const char* pKey, const std::string* pStrToWrite, bool bWarnIfNotfound)
72 {
73  std::string StrWithDelimeters = '"' + *pStrToWrite + '"';
74  return WriteKeyValue(pSect, pKey, StrWithDelimeters.c_str(), bWarnIfNotfound);
75 }
76 //--------------------------------------------------------------------------------
77 int IniFile::WriteKeyValue(const char* szSect,const char* szKey,const char* szValue, bool bWarnIfNotfound)
78 {
79  if (!m_bFileOK) return -1;
80 
81  FILE* ftemp;
82  int lS,lK,i,bEoff;
83  int bFoundSect,bFoundKey;
84  char c;
85  long fpos;
86 
87 
88 /*------------------------verifications*/
89 
90  bFoundSect = 1 /* true*/;
91  bFoundKey = 0 /* */;
92  bEoff = 0;
93  lS = strlen(szSect);
94  lK = strlen(szKey);
95  if ((lS * lK) == 0) return -1;
96 
97 /*--------------------- file opening */
98 
99  f = fopen(m_fileName.c_str(),"r");
100  if (f == NULL)
101  {
102  std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
103  return -1;
104  }
105  if ((ftemp = tmpfile()) == NULL)
106  {
107  std::cout << "tmpfile() did not work!" << std::endl;
108  return -1;
109  }
110 
111 
112 /* ---------------------- search section and key */
113  if (FindSection(szSect, bWarnIfNotfound) != 0)
114  {
115  bFoundSect = 0;
116  }
117  fpos = ftell(f);
118  if (bFoundSect)
119  {
120  if (!FindKey(szKey, false)) bFoundKey = 1;
121  fpos = ftell(f);
122  }
123  if (feof(f)) bEoff = 1;
124 
125 /* --------------------- updating the file */
126  fseek(f,0,SEEK_SET);
127  for (i=0;i<fpos;i++)
128  {
129  int res = fscanf(f,"%c",&c);
130  fprintf(ftemp,"%c",c);
131  // MMB/23.02.2006: The counter i must not be incremented here on Linux machines!
132 #ifdef WIN32
133  if (c=='\n')
134  i++;
135 #endif
136  };
137 
138  if (!bFoundSect) {
139  fprintf(ftemp,"\n\n[%s]\n",szSect);
140  }
141  if (bFoundSect && (!bFoundKey) && (bEoff))
142  {
143  fprintf(ftemp,"\n");
144  }
145 
146 
147  if (!bFoundKey)
148  {
149  fprintf(ftemp,"%s=",szKey);
150  }
151 
152  fprintf(ftemp,"%s",szValue);
153 
154  if (bFoundKey) FindNextLine(m_CurLine, m_CurCharInd);
155  if (!(bEoff || feof(f)))
156  { fprintf(ftemp,"\n");
157  while (!feof(f))
158  {
159  int res = fscanf(f,"%c",&c);
160  if (!feof(f))
161  {
162  fprintf(ftemp,"%c",c);
163  }
164  }
165  }
166  fpos = ftell(ftemp);
167  fclose(f);
168 
169  if ((f = fopen(m_fileName.c_str(),"w")) == NULL)
170  {
171  if ((f = fopen(m_fileName.c_str(),"r")) != NULL)
172  {
173  fclose(f);
174  std::cout << "INI-File is write protected " << m_fileName.c_str() << std::endl;
175  return -1;
176  }
177 
178  std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
179  return -1;
180  }
181  fseek(ftemp,0,SEEK_SET);
182  for (i=0;i<fpos;i++)
183  {
184  int res = fscanf(ftemp,"%c",&c);
185  fprintf(f,"%c",c);
186  };
187  fclose(f);
188  fclose(ftemp);
189  return 0;
190 
191 }
192 //--------------------------------------------------------------------------------
193 int IniFile::WriteKeyBool(const char* pSect, const char* pKey, bool bValue, bool bWarnIfNotfound)
194 { if(bValue)
195  return WriteKeyValue(pSect, pKey, "true", bWarnIfNotfound);
196  else
197  return WriteKeyValue(pSect, pKey, "false", bWarnIfNotfound);
198 }
199 //--------------------------------------------------------------------------------
200 int IniFile::WriteKeyInt(const char* szSect,const char* szKey,int nValue, bool bWarnIfNotfound)
201 {
202  char buff[20];
203  snprintf(buff, 10, "%d", nValue);
204  return WriteKeyValue(szSect,szKey,buff, bWarnIfNotfound);
205 }
206 //--------------------------------------------------------------------------------
207 int IniFile::WriteKeyDouble(const char* szSect,const char* szKey,double Value,
208  int Length/*=12*/,int decimals/*=5*/, bool bWarnIfNotfound)
209 {
210  char buff[100];
211  sprintf(buff, "%g", Value);
212  return WriteKeyValue(szSect,szKey, buff, bWarnIfNotfound);
213 }
214 //--------------------------------------------------------------------------------
215 int IniFile::GetKeyBool(const char* pSect, const char* pKey, bool* pValue,
216  bool bWarnIfNotfound)
217 {
218  std::string strRead;
219  char pBuf[20];
220  *pValue = false;
221  if (GetKeyValue(pSect, pKey, pBuf, 20, bWarnIfNotfound) == -1)
222  return -1;
223 
224  char* pChar = pBuf;
225  while( *pChar == ' ' ) pChar++; // skip spaces
226 
227  if( strncmp(pChar, "true", 4) == 0 )
228  {
229  *pValue = true;
230  return 0;
231  }
232  if( strncmp(pChar, "false", 5) == 0 )
233  {
234  *pValue = false;
235  return 0;
236  }
237 
238  return -1;
239 }
240 //--------------------------------------------------------------------------------
241 int IniFile::GetKeyInt(const char* szSect,const char* szKey,int* pValue,
242  bool bWarnIfNotfound)
243 {
244  char buf[9];
245  if (GetKeyValue(szSect,szKey,buf,9, bWarnIfNotfound)!=-1)
246  {
247  //first get rid of spaces
248  if (buf[0] == ' ')
249  {
250  for (int i=0; i<=6; i++)
251  buf[i] = buf[i+1];
252  buf[7]='\0';
253  }
254 
255  if ((buf[0]=='0') && (buf[1] == 'x'))
256  {
257  int iNumLength = 0;
258  //check how long the hex-number is
259  for (int z=0; z<=7; z++)
260  {
261  //if its not a number..
262  if ((buf[z+2]<0x30) || (buf[z+2]>0x3A))
263  {
264  iNumLength = z-1;
265  break;
266  }
267  }
268  *pValue = 0;
269  for (int i=0; i<=(iNumLength); i++)
270  {
271  //convert hex-string from character into int
272  *pValue += (buf[i+2]-0x30) * (int)pow((double)16, (iNumLength-i));
273  }
274  }
275  else
276  {
277  *pValue = atoi(buf);
278  }
279  return 0;
280 
281  }
282  else return -1;
283 }
284 //--------------------------------------------------------------------------------
285 int IniFile::GetKeyLong(const char* szSect,const char* szKey,long* pValue,
286  bool bWarnIfNotfound)
287 {
288  char buf[9];
289  if (GetKeyValue(szSect,szKey,buf,9, bWarnIfNotfound)!=-1)
290  {
291  *pValue = atol(buf);
292  return 0;
293  }
294  else return -1;
295 }
296 //--------------------------------------------------------------------------------
297 int IniFile::GetKeyDouble(const char* szSect,const char* szKey,double* pValue,
298  bool bWarnIfNotfound)
299 {
300  char buf[50];
301  if (GetKeyValue(szSect, szKey, buf, 50, bWarnIfNotfound) == -1)
302  {
303  if( bWarnIfNotfound )
304  std::cout << "Setting parameter " << szKey <<" = " << *pValue << " of section '" << szSect <<
305  "' in File '" << m_fileName.c_str() << std::endl;
306  return -1;
307  }
308 
309  *pValue = atof(buf);
310  return 0;
311 }
312 //-----------------------------------------------
313 int IniFile::GetKeyDouble(const char* pSect,const char* pKey,double* pValue,
314  double dDefault, bool bWarnIfNotfound)
315 {
316  (*pValue) = dDefault;
317  return GetKeyDouble(pSect, pKey, pValue, bWarnIfNotfound);
318 }
319 //--------------------------------------------------------------------------------
320 int IniFile::GetKeyValue(const char* szSect,const char* szKey,char* szBuf,
321  int lenBuf, bool bWarnIfNotfound)
322 {
323  if (!m_bFileOK) return -1;
324 
325  int lS,lK;
326 
327  lS = strlen(szSect);
328  lK = strlen(szKey);
329  if ((lS * lK) == 0) return -1;
330  if ((f = fopen(m_fileName.c_str(),"r")) == NULL)
331  {
332  std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
333  return -1;
334  }
335  if ( FindSection(szSect, bWarnIfNotfound) )
336  { fclose(f);
337  return -1;
338  }
339  if ( FindKey(szKey, bWarnIfNotfound) )
340  { fclose(f);
341  return -1;
342  }
343 
344  if (feof(f))
345  {
346  fclose(f);
347  return -1;
348  }
349 
350  //----------- read szBuf bytes from file into szKey
351  int BytesRead = fread( szBuf, 1, lenBuf, f );
352 
353  // terminate string
354  int StrLen;
355  if(BytesRead < lenBuf)
356  {
357  if( BytesRead == 0 && (!feof(f)) )
358  {
359  std::cout << "file read" << std::endl;
360  }
361  StrLen = BytesRead;
362  }
363  else
364  {
365  StrLen = lenBuf-1;
366  }
367  szBuf[StrLen] = '\0';
368 
369  fclose(f);
370  return StrLen;
371 }
372 //--------------------------------------------------------------------------------
373 int IniFile::GetKeyString(const char* szSect,const char* szKey, std::string* pStrToRead,
374  bool bWarnIfNotfound)
375 {
376  if (!m_bFileOK) return -1;
377 
378  int lS,lK;
379 
380  lS = strlen(szSect);
381  lK = strlen(szKey);
382  if ((lS * lK) == 0) return -1;
383  if ((f = fopen(m_fileName.c_str(),"r")) == NULL)
384  {
385  std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
386  return -1;
387  }
388  if ( FindSection(szSect, bWarnIfNotfound) )
389  { fclose(f);
390  return -1;
391  }
392  if ( FindKey(szKey, bWarnIfNotfound) )
393  { fclose(f);
394  return -1;
395  }
396 
397  if (feof(f))
398  {
399  fclose(f);
400  return -1;
401  }
402 
403  //----------- read szBuf bytes from file into szKey
404  int res = SkipLineUntil(f, '"'); // find begin of string
405  if(res == -1)
406  { if(bWarnIfNotfound)
407  {
408  std::cout << "GetKeyString section " << szSect << " key " << szKey << " first \" not found" << std::endl;
409  }
410  fclose(f);
411  return -1;
412  }
413 
414  std::string strRead;
415  res = ReadLineUntil(f, '"', strRead); // read string
416  if(res == -1)
417  {
418  if(bWarnIfNotfound)
419  {
420  std::cout << "GetKeyString section " << szSect << " key " << szKey << " string not found" << std::endl;
421  }
422  fclose(f);
423  return -1;
424  }
425 
426  // success
427  *pStrToRead = strRead;
428  fclose(f);
429  return 0;
430 }
431 //--------------------------------------------------------------------------------
432 int IniFile::SkipLineUntil(FILE* pFile, const char EndChar)
433 {
434  int CharsRead = 0;
435  while (1)
436  {
437  int Char = fgetc(pFile);
438 
439  if (Char == EndChar) // end found?
440  return CharsRead; // read finished
441 
442  if (Char == EOF || Char == '\n')
443  return -1; // end not found
444 
445  CharsRead++;
446  }
447 }
448 //--------------------------------------------------------------------------------
449 int IniFile::ReadLineUntil(FILE* pFile, const char EndChar, std::string& ReadIntoStr)
450 {
451  int CharsRead = 0;
452  while (1)
453  {
454  int Char = fgetc(pFile);
455 
456  if (Char == EndChar) // end found?
457  return CharsRead; // read finished
458 
459  if (Char == EOF || Char == '\n')
460  return -1; // end not found
461 
462  ReadIntoStr.append(1, char(Char));
463 
464  CharsRead++;
465  }
466 }
467 //--------------------------------------------------------------------------------
468 int IniFile::FindNextLine(std::vector<char>& NewLine, int& CharInd)
469 {
470  if (!feof(f))
471  {
472  std::string line = fgets(&NewLine[0], NewLine.size(), f); // store next line in NewLine
473  CharInd=0; // makes CharInd reference the first char of the line
474  return 0;
475  }
476  return -1;
477 }
478 //--------------------------------------------------------------------------------
479 int IniFile::FindNextSection(std::string* pSect, std::string prevSect, bool bWarnIfNotfound)
480 {
481  std::vector<char> line;
482  //int charInd = 0;
483  //int res = -1;
484 
485  if (!m_bFileOK) return -1;
486 
487  // Make sure that there is no old data.
488  pSect->erase();
489 
490 /*--------------------- file opening */
491  f = fopen(m_fileName.c_str(),"r");
492  if (f == NULL)
493  {
494  std::cout << "INI-File not found " << m_fileName.c_str() << std::endl;
495  return -1;
496  }
497  if (feof(f)) return -1;
498 
499 /*--------------------- search the section */
500  if( prevSect != "" ) {
501  FindSection( prevSect.c_str(), bWarnIfNotfound );
502  } else {
503  fseek(f,0,SEEK_SET);
504  }
505 
506  FindNextLine(m_CurLine, m_CurCharInd); //read first line of file
507  do
508  {
509  if (m_CurLine[0] == '[')
510  {
511  while( m_CurCharInd < (int)m_CurLine.size() ) {
512  m_CurCharInd++;
513  if (m_CurLine[m_CurCharInd] == ']') // if found section name equals searched one
514  {
515  for( int i=1; i<m_CurCharInd; ++i )
516  pSect->append(1, char(m_CurLine[i]));
517  return 0;
518  }
519  }
520  }
521  else
522  {
524  }
525  }while (!feof(f));
526 
527 /*--------------------- file closing */
528  fclose(f);
529 
530  return 0;
531 }
532 //--------------------------------------------------------------------------------
533 int IniFile::FindSection(const char* sect,
534  bool bWarnIfNotfound)
535 {
536  int lS;
537  lS = strlen(sect);
538  if (feof(f)) return -1;
539 
540  FindNextLine(m_CurLine, m_CurCharInd); //read first line of file
541  do
542  {
543  if (m_CurLine[0] == '[')
544  {
545  m_CurCharInd++;
546  if ((strncmp(&m_CurLine[m_CurCharInd], sect, lS) == 0) && (m_CurLine[m_CurCharInd+lS] == ']')) // if found section name equals searched one
547  {
548  return 0;
549  }
550  else
551  {
552  FindNextLine(m_CurLine, m_CurCharInd);
553  }
554  }
555  else if (m_CurLine[m_CurCharInd] == ' ') // if a blank is found
556  {
557  m_CurCharInd++;
558  }
559  else
560  {
562  }
563  }while (!feof(f));
564 
565  // not found
566  if(bWarnIfNotfound)
567  {
568  std::cout << "Section [" << sect << "] in IniFile " << m_fileName.c_str() << " used by "
569  << m_strIniFileUsedBy << " not found" << std::endl;
570  }
571 
572  return -1;
573 }
574 //--------------------------------------------------------------------------------
575 int IniFile::FindKey(const char* skey,
576  bool bWarnIfNotfound)
577 {
578  int lS;
579  long fpos = 0l;
580  lS = strlen(skey);
581  if (feof(f)) return -1;
582 
583  do
584  {
585  fpos=ftell(f);// pointer to the begin of the last read line
587 
588  while ( m_CurLine[m_CurCharInd] == ' ' ) // skip blanks
589  {
590  m_CurCharInd++;
591  fpos++;
592  }
593 
594  if (m_CurLine[m_CurCharInd] == '[') // next section?
595  break; // not found
596 
597  if (strncmp(&m_CurLine[m_CurCharInd], skey, lS) == 0) //Found
598  {
599  m_CurCharInd+=lS;
600  fpos+=lS; // set file pointer to end of found key
601  while ( m_CurLine[m_CurCharInd] == ' ' ) // skip blanks
602  {
603  m_CurCharInd++;
604  fpos++;
605  }
606  if ( m_CurLine[m_CurCharInd] == '=' )
607  {
608  m_CurCharInd++; // set index to first char after the =
609  fpos++;
610  fseek(f,fpos,SEEK_SET);// set file pointer to first char after the =
611  return 0;
612  }
613 
614  }
615 
616  }while (!feof(f));
617 
618  if(bWarnIfNotfound)
619  {
620  std::cout << "Key " << skey << " in IniFile '" << m_fileName.c_str() << "' used by "
621  << m_strIniFileUsedBy << " not found" << std::endl;
622  }
623  return -1;
624 }
625 //-----------------------------------------------
626 int IniFile::GetKey(const char* pSect,const char* pKey, std::string* pStrToRead, bool bWarnIfNotfound)
627 {
628  return GetKeyString(pSect,pKey,pStrToRead,bWarnIfNotfound);
629 }
630 //-----------------------------------------------
631 int IniFile::GetKey(const char* pSect,const char* pKey,int* pValue, bool bWarnIfNotfound)
632 {
633  return GetKeyInt(pSect,pKey,pValue,bWarnIfNotfound);
634 }
635 //-----------------------------------------------
636 
637 int IniFile::GetKey(const char* pSect, const char* pKey, bool* pValue, bool bWarnIfNotfound)
638 {
639  return GetKeyBool(pSect,pKey,pValue,bWarnIfNotfound);
640 }
641 //-----------------------------------------------
642 int IniFile::GetKey(const char* pSect,const char* pKey,double* pValue, bool bWarnIfNotfound)
643 {
644  return GetKeyDouble(pSect,pKey,pValue,bWarnIfNotfound);
645 }
646 
int SkipLineUntil(FILE *pFile, const char EndChar)
Definition: IniFile.cpp:432
bool m_bFileOK
Definition: IniFile.h:282
IniFile()
Definition: IniFile.cpp:28
~IniFile()
Definition: IniFile.cpp:43
int FindNextLine(std::vector< char > &NewLine, int &CharInd)
Definition: IniFile.cpp:468
int FindKey(const char *skey, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:575
FILE * f
Definition: IniFile.h:301
int GetKeyValue(const char *pSect, const char *pKey, char *pBuf, int lenBuf, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:320
const int m_vectorSize
Definition: IniFile.h:292
int WriteKeyString(const char *pSect, const char *pKey, const std::string *pStrToWrite, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:71
std::vector< char > m_CurLine
Definition: IniFile.h:287
int GetKeyBool(const char *pSect, const char *pKey, bool *pValue, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:215
int WriteKeyDouble(const char *pSect, const char *pKey, double dValue, int StringLen=12, int decimals=5, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:207
int WriteKeyInt(const char *pSect, const char *pKey, int nValue, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:200
int GetKeyInt(const char *pSect, const char *pKey, int *pValue, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:241
int FindNextSection(std::string *pSect, std::string prevSect, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:479
int GetKeyDouble(const char *pSect, const char *pKey, double *pValue, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:297
int FindSection(const char *sect, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:533
int m_CurCharInd
Definition: IniFile.h:297
int SetFileName(std::string fileName, std::string strIniFileUsedBy="", bool bCreate=false)
Definition: IniFile.cpp:47
int GetKey(const char *pSect, const char *pKey, std::string *pStrToRead, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:626
int GetKeyString(const char *pSect, const char *pKey, std::string *pStrToRead, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:373
int ReadLineUntil(FILE *pFile, const char EndChar, std::string &ReadIntoStr)
Definition: IniFile.cpp:449
std::string m_fileName
Definition: IniFile.h:299
int GetKeyLong(const char *pSect, const char *pKey, long *pValue, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:285
int WriteKeyBool(const char *pSect, const char *pKey, bool bValue, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:193
std::string m_strIniFileUsedBy
Definition: IniFile.h:300
int WriteKeyValue(const char *pSect, const char *pKey, const char *pBuf, bool bWarnIfNotfound=true)
Definition: IniFile.cpp:77


cob_utilities
Author(s): Christian Connette
autogenerated on Wed Apr 7 2021 02:11:52