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