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
54 INIFile::INIFile()
55 {
56 mf_isConnected = false;
57 }
58
59
60 // -----------------------------------------------------------------------------
61
62 INIFile::~INIFile()
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
122 void INIFile::disconnect()
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::~INIFile
~INIFile()
Destructor.
Definition: INIFile.cc:62
INIFile::disconnect
void disconnect()
Remove connection of this object to a file.
Definition: INIFile.cc:122
INIFile::is_connected
bool is_connected() const
Check if object is connected to file.
Definition: INIFile.hh:117
INIFile::m_iniData
SectionMap m_iniData
Stored data of an INI file.
Definition: INIFile.hh:377
INIFile::add_entry
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:257
INIFile::parseFile
bool parseFile(QFile &_inputStream)
Read content of an INI file.
Definition: INIFile.cc:131
INIFile::entry_exists
bool entry_exists(const QString &_section, const QString &_key) const
Check if given entry esists in the current INI file.
Definition: INIFile.cc:236
INIFile::get_entry
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433
INIFile::INIFile
INIFile()
Default constructor.
Definition: INIFile.cc:54
INIFile::m_filename
QString m_filename
Name of current INI file.
Definition: INIFile.hh:370
INIFile::mf_isConnected
bool mf_isConnected
Flag: this object is connected to an INI file.
Definition: INIFile.hh:373
INIFile::delete_section
void delete_section(const QString &_sectionname)
Deletion of an entire section.
Definition: INIFile.cc:424
INIFile::writeFile
bool writeFile(void)
Write data to file we are currently connected to.
Definition: INIFile.cc:185
INIFile::connect
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:70
INIFile::delete_entry
void delete_entry(const QString &_section, const QString &_key)
Deletion of an entry.
Definition: INIFile.cc:409
INIFile::section_exists
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:227
INIFile::EntryMap
std::map< QString, QString > EntryMap
Type for map of contained entries.
Definition: INIFile.hh:353
INIFile::add_section
void add_section(const QString &_sectionname)
Addition of a section.
Definition: INIFile.cc:247