Developer Documentation
INIFile.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 #include "INIFile.hh"
54 
55 //std include
56 //#include <ios>
57 
58 // -----------------------------------------------------------------------------
59 
61 {
62  mf_isConnected = false;
63 }
64 
65 
66 // -----------------------------------------------------------------------------
67 
69 {
70  disconnect();
71 }
72 
73 
74 // -----------------------------------------------------------------------------
75 
76 bool INIFile::connect( const QString& _filename,
77  const bool _create )
78 {
79  QFile inputFile( _filename );
80 
81  if( is_connected() )
82  disconnect();
83 
84  // open given file for reading
85  if ( inputFile.exists() && inputFile.open(QIODevice::ReadOnly | QIODevice::Text) ) {
86 
87  // Successfull?
88  m_filename = _filename;
89 
90  // try to parse the INI file
91  mf_isConnected = parseFile( inputFile );
92 
93  inputFile.close();
94 
95  } else if( _create ) {
96 
97  // file does not exist yet, but user wants to create it.
98  // therefore: try to create file
99  QFile outputFile(_filename);
100 
101  if ( outputFile.open( QIODevice::Text |
102  QIODevice::WriteOnly |
103  QIODevice::Truncate ) ) {
104 
105  mf_isConnected = true;
106  m_filename = _filename;
107  outputFile.close();
108 
109  } else {
110 
111  std::cerr << "Unable to create File : " << std::endl;
112  mf_isConnected = false;
113 
114  }
115 
116  } else {
117  std::cerr << "Unable to open File : " << std::endl;
118  mf_isConnected = false;
119  }
120 
121  return mf_isConnected;
122 }
123 
124 
125 
126 // -----------------------------------------------------------------------------
127 
129 {
130  writeFile();
131  mf_isConnected = false;
132 }
133 
134 
135 // -----------------------------------------------------------------------------
136 
137 bool INIFile::parseFile( QFile & _inputStream )
138 {
139  QString line, section;
140  bool inSection = false;
141 
142  // read file line by line
143  while( !_inputStream.atEnd() ) {
144 
145  // get new line
146  QByteArray lineBuffer = _inputStream.readLine();
147  line = QString(lineBuffer);
148  line = line.trimmed();
149 
150  if( line.isEmpty() || line[ 0 ] == '#' )
151  continue;
152 
153  // does line contain the start of a section?
154  if( line[ 0 ] == '[' && line[ line.length()-1 ] == ']' ) {
155 
156  // yes
157  section = line.mid( 1, line.length() - 2 );
158  inSection = true;
159 
160  } else if( inSection ) {
161  // try to split line into a key and a value
162  QString key, value;
163 
164  int pos;
165  pos = line.indexOf( '=' );
166 
167  if( pos != -1 )
168  {
169  key = line.mid( 0, pos );
170  key = key.trimmed();
171  value = line.mid( pos + 1, line.length() - 1 );
172  value = value.trimmed();
173 
174  if( key.isEmpty() || value.isEmpty() )
175  continue;
176 
177  // store value in string-map
178  m_iniData[ section ][ key ] = value;
179  }
180 
181  }
182  }
183 
184  return true;
185 }
186 
187 
188 // -----------------------------------------------------------------------------
189 
190 
191 bool INIFile::writeFile( void )
192 {
193  if( !mf_isConnected )
194  return false;
195 
196  // open file for writing
197  QFile outputFile(m_filename);
198 
199  if ( ! outputFile.open( QIODevice::WriteOnly ) )
200  return false;
201 
202  QTextStream out(&outputFile);
203 
204  // file is open, start writing of data
205  SectionMap::const_iterator sIter, sEnd;
206  EntryMap::const_iterator eIter, eEnd;
207 
208  sEnd = m_iniData.end();
209  for( sIter = m_iniData.begin(); sIter != sEnd; ++sIter ) {
210  // write name of current section
211  out << "[" << sIter->first << "]\n";
212 
213  eEnd = sIter->second.end();
214  for( eIter = sIter->second.begin(); eIter != eEnd; ++eIter ) {
215  out << eIter->first << "=";
216  out << eIter->second;
217  out << "\n";
218  }
219 
220  out << "\n\n";
221  }
222 
223  outputFile.close();
224 
225  return true;
226 }
227 
228 
229 
230 // -----------------------------------------------------------------------------
231 
232 
233 bool INIFile::section_exists( const QString & _section ) const
234 {
235  return( m_iniData.find( _section ) != m_iniData.end() );
236 }
237 
238 
239 // -----------------------------------------------------------------------------
240 
241 
242 bool INIFile::entry_exists(const QString & _section, const QString & _key) const
243 {
244  static SectionMap::const_iterator mapIter;
245 
246  return( (mapIter = m_iniData.find( _section )) != m_iniData.end()
247  && mapIter->second.find( _key ) != mapIter->second.end() );
248 }
249 
250 
251 // -----------------------------------------------------------------------------
252 
253 void INIFile::add_section( const QString & _sectionname )
254 {
255  if( m_iniData.find( _sectionname ) == m_iniData.end() )
256  m_iniData[ _sectionname ] = EntryMap();
257 }
258 
259 
260 // -----------------------------------------------------------------------------
261 
262 
263 void INIFile::add_entry( const QString & _section,
264  const QString & _key,
265  const QString & _value )
266 {
267  m_iniData[ _section ][ _key ] = _value;
268 }
269 
270 
271 // -----------------------------------------------------------------------------
272 
273 
274 void INIFile::add_entry( const QString & _section,
275  const QString & _key,
276  const double & _value)
277 {
278  m_iniData[ _section ][ _key ] = QString::number( _value );
279 }
280 
281 
282 // -----------------------------------------------------------------------------
283 
284 
285 void INIFile::add_entry( const QString & _section,
286  const QString & _key,
287  const float & _value)
288 {
289  m_iniData[ _section ][ _key ] = QString::number( _value );
290 }
291 
292 
293 // -----------------------------------------------------------------------------
294 
295 
296 void INIFile::add_entry( const QString & _section,
297  const QString & _key ,
298  const int & _value)
299 {
300  m_iniData[ _section ][ _key ] = QString::number( _value );
301 }
302 
303 
304 // -----------------------------------------------------------------------------
305 
306 
307 void INIFile::add_entry( const QString & _section,
308  const QString & _key ,
309  const unsigned int & _value)
310 {
311  m_iniData[ _section ][ _key ] = QString::number( _value );
312 }
313 
314 
315 // -----------------------------------------------------------------------------
316 
317 
318 void INIFile::add_entry( const QString & _section,
319  const QString & _key ,
320  const bool & _value)
321 {
322  m_iniData[ _section ][ _key ] = (_value ? "true" : "false");
323 }
324 
325 
326 // -----------------------------------------------------------------------------
327 
328 
329 void INIFile::add_entry( const QString & _section,
330  const QString & _key,
331  const std::vector<float> & _value)
332 {
333  QString list;
334  std::vector<float>::const_iterator viter;
335  for(viter = _value.begin();viter!=_value.end();++viter)
336  list += QString::number( *viter ) + ";";
337  m_iniData[ _section ][ _key ] = list;
338 }
339 
340 
341 // -----------------------------------------------------------------------------
342 
343 
344 void INIFile::add_entry( const QString & _section,
345  const QString & _key,
346  const std::vector<double> & _value)
347 {
348  QString list;
349  std::vector<double>::const_iterator viter;
350  for(viter = _value.begin();viter!=_value.end();++viter)
351  list += QString::number( *viter ) + ";";
352  m_iniData[ _section ][ _key ] = list;
353 }
354 
355 
356 // -----------------------------------------------------------------------------
357 
358 
359 void INIFile::add_entry( const QString & _section,
360  const QString & _key,
361  const std::vector<bool> & _value)
362 {
363  QString list;
364  std::vector<bool>::const_iterator viter;
365  for(viter = _value.begin();viter!=_value.end();++viter){
366  if (*viter == true)
367  list += "true;";
368  else
369  list += "false;";
370  }
371  m_iniData[ _section ][ _key ] = list;
372 }
373 
374 
375 // -----------------------------------------------------------------------------
376 
377 void INIFile::add_entry( const QString & _section,
378  const QString & _key,
379  const std::vector<int> & _value)
380 {
381  QString list;
382  std::vector<int>::const_iterator viter;
383  for(viter = _value.begin();viter!=_value.end();++viter)
384  list += QString::number( *viter ) + ";";
385  m_iniData[ _section ][ _key ] = list;
386 }
387 
388 // -----------------------------------------------------------------------------
389 
390 void INIFile::add_entry( const QString & _section,
391  const QString & _key,
392  const std::vector<QString> & _value)
393 {
394  QString list;
395  std::vector<QString>::const_iterator viter;
396  for(viter = _value.begin();viter!=_value.end();++viter) {
397  list += *viter + ";";
398  }
399  m_iniData[ _section ][ _key ] = list;
400 }
401 
402 // -----------------------------------------------------------------------------
403 
404 void INIFile::add_entry( const QString & _section,
405  const QString & _key,
406  const QStringList & _value)
407 {
408  QString list = _value.join(";");
409  m_iniData[ _section ][ _key ] = list;
410 }
411 
412 
413 // -----------------------------------------------------------------------------
414 
415 void INIFile::delete_entry( const QString & _section, const QString & _key )
416 {
417  SectionMap::iterator sIter;
418  EntryMap::iterator eIter;
419 
420  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
421  return;
422 
423  if( (eIter = sIter->second.find( _key )) != sIter->second.end() )
424  sIter->second.erase( eIter );
425 }
426 
427 
428 // -----------------------------------------------------------------------------
429 
430 void INIFile::delete_section( const QString & _sectionname )
431 {
432  m_iniData.erase( _sectionname );
433 }
434 
435 
436 // -----------------------------------------------------------------------------
437 
438 
439 bool INIFile::get_entry( QString & _val,
440  const QString & _section,
441  const QString & _key ) const
442 {
443  SectionMap::const_iterator sIter;
444  EntryMap::const_iterator eIter;
445 
446  // does the given section exist?
447  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
448  return false;
449 
450  // does the given entry exist?
451  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
452  return false;
453 
454  _val = eIter->second;
455  return true;
456 }
457 
458 
459 // -----------------------------------------------------------------------------
460 
461 
462 bool INIFile::get_entry( double & _val,
463  const QString & _section,
464  const QString & _key ) const
465 {
466  SectionMap::const_iterator sIter;
467  EntryMap::const_iterator eIter;
468 
469  // does the given section exist?
470  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
471  return false;
472 
473  // does the given entry exist?
474  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
475  return false;
476 
477  bool ok;
478  _val = eIter->second.toDouble(&ok);
479  return( ok );
480 }
481 
482 
483 // -----------------------------------------------------------------------------
484 
485 
486 bool INIFile::get_entry( float & _val,
487  const QString & _section,
488  const QString & _key ) const
489 {
490  SectionMap::const_iterator sIter;
491  EntryMap::const_iterator eIter;
492 
493  // does the given section exist?
494  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
495  return false;
496 
497  // does the given entry exist?
498  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
499  return false;
500 
501  bool ok;
502  _val = eIter->second.toFloat(&ok);
503  return( ok );
504 }
505 
506 
507 // -----------------------------------------------------------------------------
508 
509 
510 bool INIFile::get_entry( int & _val,
511  const QString & _section,
512  const QString & _key ) const
513 {
514  SectionMap::const_iterator sIter;
515  EntryMap::const_iterator eIter;
516 
517  // does the given section exist?
518  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
519  return false;
520 
521  // does the given entry exist?
522  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
523  return false;
524 
525  bool ok;
526  _val = eIter->second.toInt(&ok);
527  return( ok );
528 }
529 
530 
531 // -----------------------------------------------------------------------------
532 
533 bool INIFile::get_entry( unsigned int & _val,
534  const QString & _section,
535  const QString & _key ) const
536 {
537  SectionMap::const_iterator sIter;
538  EntryMap::const_iterator eIter;
539 
540  // does the given section exist?
541  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
542  return false;
543 
544  // does the given entry exist?
545  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
546  return false;
547 
548  bool ok;
549  _val = eIter->second.toUInt(&ok);
550  return( ok );
551 }
552 
553 
554 // -----------------------------------------------------------------------------
555 
556 
557 bool INIFile::get_entry( bool & _val,
558  const QString & _section,
559  const QString & _key) const
560 {
561  SectionMap::const_iterator sIter;
562  EntryMap::const_iterator eIter;
563 
564  // does the given section exist?
565  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
566  return false;
567 
568  // does the given entry exist?
569  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
570  return false;
571 
572  if( eIter->second == "true" || eIter->second == "false" ) {
573  _val = (eIter->second == "true");
574  return true;
575  } else {
576  return false;
577  }
578 }
579 
580 
581 // -----------------------------------------------------------------------------
582 
583 
584 bool INIFile::get_entry( std::vector<float> & _val,
585  const QString & _section,
586  const QString & _key ) const
587 {
588  SectionMap::const_iterator sIter;
589  EntryMap::const_iterator eIter;
590 
591  _val.clear();
592 
593  // does the given section exist?
594  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
595  return false;
596 
597  // does the given entry exist?
598  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
599  return false;
600 
601  QStringList list = eIter->second.split(';');
602 
603  bool ok = true;
604  for ( int i = 0 ; i < list.size(); ++i) {
605  if ( list[i].isEmpty() )
606  continue;
607  bool tmpOk = false;
608  _val.push_back(list[i].toFloat(&tmpOk));
609  ok &= tmpOk;
610  }
611 
612  return ok;
613 }
614 
615 
616 // -----------------------------------------------------------------------------
617 
618 
619 bool INIFile::get_entry( std::vector<double> & _val,
620  const QString & _section,
621  const QString & _key ) const
622 {
623  SectionMap::const_iterator sIter;
624  EntryMap::const_iterator eIter;
625 
626  _val.clear();
627 
628  // does the given section exist?
629  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
630  return false;
631 
632  // does the given entry exist?
633  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
634  return false;
635 
636  QStringList list = eIter->second.split(';');
637 
638  bool ok = true;
639  for ( int i = 0 ; i < list.size(); ++i) {
640  if ( list[i].isEmpty() )
641  continue;
642  bool tmpOk = false;
643  _val.push_back(list[i].toDouble(&tmpOk));
644  ok &= tmpOk;
645  }
646 
647  return ok;
648 }
649 
650 
651 // -----------------------------------------------------------------------------
652 
653 
654 bool INIFile::get_entry( std::vector<bool> & _val,
655  const QString & _section,
656  const QString & _key ) const
657 {
658  SectionMap::const_iterator sIter;
659  EntryMap::const_iterator eIter;
660 
661  _val.clear();
662 
663  // does the given section exist?
664  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
665  return false;
666 
667  // does the given entry exist?
668  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
669  return false;
670 
671  QStringList list = eIter->second.split(';');
672 
673  bool ok = true;
674  for ( int i = 0 ; i < list.size(); ++i) {
675  if ( list[i].isEmpty() )
676  continue;
677  if (list[i] == "true")
678  _val.push_back(true);
679  else
680  _val.push_back(false);
681  }
682 
683  return ok;
684 }
685 
686 
687 // -----------------------------------------------------------------------------
688 
689 
690 bool INIFile::get_entry( std::vector<int> & _val,
691  const QString & _section,
692  const QString & _key ) const
693 {
694  SectionMap::const_iterator sIter;
695  EntryMap::const_iterator eIter;
696 
697  _val.clear();
698 
699  // does the given section exist?
700  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
701  return false;
702 
703  // does the given entry exist?
704  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
705  return false;
706 
707  QStringList list = eIter->second.split(';');
708 
709  bool ok = true;
710  for ( int i = 0 ; i < list.size(); ++i) {
711  if ( list[i].isEmpty() )
712  continue;
713  bool tmpOk = false;
714  _val.push_back(list[i].toInt(&tmpOk));
715  ok &= tmpOk;
716  }
717 
718  return ok;
719 }
720 
721 
722 // -----------------------------------------------------------------------------
723 
724 
725 bool INIFile::get_entry( std::vector<QString> & _val,
726  const QString & _section,
727  const QString & _key ) const
728 {
729  SectionMap::const_iterator sIter;
730  EntryMap::const_iterator eIter;
731 
732  _val.clear();
733 
734  // does the given section exist?
735  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
736  return false;
737 
738  // does the given entry exist?
739  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
740  return false;
741 
742  QStringList list = eIter->second.split(';');
743 
744  bool ok = true;
745  for ( int i = 0 ; i < list.size(); ++i) {
746  if ( list[i].isEmpty() )
747  continue;
748  _val.push_back(list[i]);
749  }
750 
751  return ok;
752 }
753 
754 
755 // -----------------------------------------------------------------------------
756 
757 
758 bool INIFile::get_entry( QStringList & _val,
759  const QString & _section,
760  const QString & _key ) const
761 {
762  SectionMap::const_iterator sIter;
763  EntryMap::const_iterator eIter;
764 
765  _val.clear();
766 
767  // does the given section exist?
768  if( (sIter = m_iniData.find( _section )) == m_iniData.end() )
769  return false;
770 
771  // does the given entry exist?
772  if( (eIter = sIter->second.find( _key )) == sIter->second.end() )
773  return false;
774 
775  _val = eIter->second.split(';');
776 
777  bool ok = true;
778  if ( _val.isEmpty() )
779  ok = false;
780 
781  return ok;
782 }
783 
784 
785 // -----------------------------------------------------------------------------
786 
bool writeFile(void)
Write data to file we are currently connected to.
Definition: INIFile.cc:191
void delete_entry(const QString &_section, const QString &_key)
Deletion of an entry.
Definition: INIFile.cc:415
void add_section(const QString &_sectionname)
Addition of a section.
Definition: INIFile.cc:253
std::map< QString, QString > EntryMap
Type for map of contained entries.
Definition: INIFile.hh:359
INIFile()
Default constructor.
Definition: INIFile.cc:60
void delete_section(const QString &_sectionname)
Deletion of an entire section.
Definition: INIFile.cc:430
QString m_filename
Name of current INI file.
Definition: INIFile.hh:376
~INIFile()
Destructor.
Definition: INIFile.cc:68
bool mf_isConnected
Flag: this object is connected to an INI file.
Definition: INIFile.hh:379
bool parseFile(QFile &_inputStream)
Read content of an INI file.
Definition: INIFile.cc:137
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:439
void disconnect()
Remove connection of this object to a file.
Definition: INIFile.cc:128
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:233
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:76
bool entry_exists(const QString &_section, const QString &_key) const
Check if given entry esists in the current INI file.
Definition: INIFile.cc:242
SectionMap m_iniData
Stored data of an INI file.
Definition: INIFile.hh:383
bool is_connected() const
Check if object is connected to file.
Definition: INIFile.hh:123
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:263