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
70bool 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
131bool 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
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
227bool INIFile::section_exists( const QString & _section ) const
228{
229 return( m_iniData.find( _section ) != m_iniData.end() );
230}
231
232
233// -----------------------------------------------------------------------------
234
235
236bool 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
247void 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
257void 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
268void 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
279void 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
290void 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
301void 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
312void 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
323void 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
338void 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
353void 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
371void 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
384void 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
398void 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
409void 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
424void INIFile::delete_section( const QString & _sectionname )
425{
426 m_iniData.erase( _sectionname );
427}
428
429
430// -----------------------------------------------------------------------------
431
432
433bool 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
456bool 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
480bool 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
504bool 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
527bool 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
551bool 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
578bool 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
613bool 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
648bool 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
684bool 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
719bool 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
752bool 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
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()
Default constructor.
Definition: INIFile.cc:54
bool is_connected() const
Check if object is connected to file.
Definition: INIFile.hh:117
bool writeFile(void)
Write data to file we are currently connected to.
Definition: INIFile.cc:185
std::map< QString, QString > EntryMap
Type for map of contained entries.
Definition: INIFile.hh:353
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:70
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:227
void disconnect()
Remove connection of this object to a file.
Definition: INIFile.cc:122
bool mf_isConnected
Flag: this object is connected to an INI file.
Definition: INIFile.hh:373
void delete_entry(const QString &_section, const QString &_key)
Deletion of an entry.
Definition: INIFile.cc:409
~INIFile()
Destructor.
Definition: INIFile.cc:62
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:257
void add_section(const QString &_sectionname)
Addition of a section.
Definition: INIFile.cc:247
SectionMap m_iniData
Stored data of an INI file.
Definition: INIFile.hh:377
bool parseFile(QFile &_inputStream)
Read content of an INI file.
Definition: INIFile.cc:131
QString m_filename
Name of current INI file.
Definition: INIFile.hh:370
void delete_section(const QString &_sectionname)
Deletion of an entire section.
Definition: INIFile.cc:424