Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 9880 in orxonox.OLD for trunk/src/lib/parser/ini_parser


Ignore:
Timestamp:
Oct 10, 2006, 3:42:31 PM (18 years ago)
Author:
bensch
Message:

new implementation of the IniParser
Now it is in Full stl-style, with iterators, and it does not have a strange internal state, that makes absolutely no sense

Location:
trunk/src/lib/parser/ini_parser
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/parser/ini_parser/ini_parser.cc

    r9869 r9880  
    2121#include "ini_parser.h"
    2222
    23 #include <stdlib.h>
    24 #include <string.h>
    25 
    2623#if HAVE_CONFIG_H
    2724#include <config.h>
    2825#endif
     26
     27#include <cassert>
     28#include <algorithm>
    2929
    3030#ifdef DEBUG_LEVEL
     
    3636
    3737
    38 
     38/// /// /// /// /// ///
     39/// INI-PARSER NODE ///
     40/// /// /// /// /// ///
     41IniParser::Node::Node(const std::string& name, const std::string& comment)
     42{
     43  this->_name = name;
     44  this->_comment = comment;
     45}
     46
     47/// /// /// /// /// ////
     48/// INI-PARSER ENTRY ///
     49/// /// /// /// /// ////
     50IniParser::Entry::Entry(const std::string& name, const std::string& value, const std::string& comment)
     51    : IniParser::Node(name, comment), _value(value)
     52{}
     53
     54void IniParser::Entry::debug() const
     55{
     56  printf("   %s = %s\n", this->name().c_str(), this->_value.c_str());
     57}
     58
     59
     60/// /// /// /// /// /// ///
     61/// INI-PARSER SECTION  ///
     62/// /// /// /// /// /// ///
     63IniParser::Section::Section(const std::string& sectionName, const std::string& comment)
     64    : IniParser::Node(sectionName, comment)
     65{}
     66
     67IniParser::Entry& IniParser::Section::addEntry(const std::string& entryName, const std::string& value, const std::string& comment)
     68{
     69  Entry::iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
     70  if (entry == this->_entries.end())
     71  {
     72    this->_entries.push_back(Entry(entryName, value, comment));
     73    entry = --this->_entries.end();
     74  }
     75  return *entry;
     76}
     77
     78bool IniParser::Section::editEntry(const std::string& entryName, const std::string& value, bool createMissing)
     79{
     80  Entry::iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
     81  if (entry == this->_entries.end())
     82  {
     83    if (createMissing)
     84    {
     85      this->addEntry(entryName, value);
     86      return true;
     87    }
     88    else
     89      return false;
     90  }
     91  (*entry).setValue(value);
     92  return true;
     93}
     94
     95const std::string& IniParser::Section::getValue(const std::string& entryName, const std::string& defaultValue) const
     96{
     97  Entry::const_iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
     98  if (entry != this->_entries.end())
     99    return (*entry).value();
     100  else
     101    return defaultValue;
     102}
     103
     104bool IniParser::Section::setEntryComment(const std::string& entryName, const std::string& comment)
     105{
     106  Entry::iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
     107  if (entry != this->_entries.end())
     108  {
     109    (*entry).setComment(comment);
     110    return true;
     111  }
     112  return false;
     113}
     114
     115const std::string& IniParser::Section::getEntryComment(const std::string& entryName) const
     116{
     117  Entry::const_iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
     118  if (entry != this->_entries.end())
     119  {
     120    return (*entry).comment();
     121  }
     122  return IniParser::_emptyString;
     123}
     124
     125
     126IniParser::Entry* IniParser::Section::getEntry(const std::string& entryName)
     127{
     128  Entry::iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
     129  if (entry != this->_entries.end())
     130    return &(*entry);
     131  else
     132    return NULL;
     133}
     134
     135IniParser::Entry::const_iterator IniParser::Section::getEntryIt(const std::string& entryName) const
     136{
     137  return std::find(this->_entries.begin(), this->_entries.end(), entryName);
     138}
     139
     140void IniParser::Section::clear()
     141{
     142  this->_entries.clear();
     143}
     144
     145void IniParser::Section::debug() const
     146{
     147  printf(" [%s]\n", this->name().c_str());
     148  for(Entry::const_iterator entry = this->_entries.begin(); entry != this->_entries.end(); ++entry)
     149    (*entry).debug();
     150}
     151
     152
     153
     154/// /// /// /// /// /// ///
     155/// INI-PARSER DOCUMENT ///
     156/// /// /// /// /// /// ///
     157IniParser::Document::Document(const std::string& fileName, const std::string& comment)
     158    : IniParser::Node(fileName, comment)
     159{}
     160
     161IniParser::Section& IniParser::Document::addSection(const std::string& sectionName, const std::string& comment)
     162{
     163  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     164  if (section == this->_sections.end())
     165  {
     166    this->_sections.push_back(Section(sectionName, comment));
     167    return *(--_sections.end());
     168  }
     169  else
     170    return *section;
     171}
     172
     173bool IniParser::Document::removeSection(const std::string& sectionName)
     174{
     175  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     176  if (section != this->_sections.end())
     177  {
     178    this->_sections.erase(section);
     179    return true;
     180  }
     181  else
     182    return false;
     183}
     184
     185bool IniParser::Document::setSectionComment(const std::string& sectionName, const std::string& comment)
     186{
     187  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     188  if (section != this->_sections.end())
     189  {
     190    (*section).setComment(comment);
     191    return true;
     192  }
     193  else
     194    return false;
     195}
     196
     197
     198
     199IniParser::Section* IniParser::Document::getSection(const std::string& sectionName)
     200{
     201  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     202  if (section != this->_sections.end())
     203  {
     204    return &(*section);
     205  }
     206  else
     207    return NULL;
     208}
     209
     210IniParser::Section::const_iterator IniParser::Document::getSectionIt(const std::string& sectionName) const
     211{
     212  Section::const_iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     213  return section;
     214}
     215
     216bool IniParser::Document::addEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, const std::string& comment)
     217{
     218  // locating section
     219  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     220  if (section == this->_sections.end())
     221  {
     222    // creating section if not found!!
     223    this->_sections.push_back(Section(sectionName));
     224    section = --_sections.end();
     225  }
     226
     227  (*section).addEntry(entryName, value, comment);
     228  return true;
     229}
     230
     231bool IniParser::Document::editEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, bool createMissing)
     232{
     233  // locating section
     234  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     235  if (section == this->_sections.end())
     236  {
     237    // creating section if not found!!
     238    if (createMissing)
     239    {
     240      this->_sections.push_back(Section(sectionName));
     241      section = --_sections.end();
     242    }
     243    else
     244      return false;
     245  }
     246
     247  return (*section).editEntry(entryName, value, createMissing);
     248}
     249
     250const std::string& IniParser::Document::getValue(const std::string& sectionName, const std::string& entryName, const std::string& defaultValue) const
     251{
     252  // locating section
     253  Section::const_iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     254  if (section != this->_sections.end())
     255    return (*section).getValue(entryName, defaultValue);
     256  return defaultValue;
     257}
     258
     259bool IniParser::Document::setEntryComment(const std::string& sectionName, const std::string& entryName, const std::string& comment)
     260{
     261  // locating section
     262  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     263  if (section != this->_sections.end())
     264    return (*section).setEntryComment(entryName, comment);
     265  else
     266    return false;
     267}
     268
     269const std::string& IniParser::Document::getEntryComment(const std::string& sectionName, const std::string& entryName) const
     270{
     271  Section::const_iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
     272  if (section != this->_sections.end())
     273    return (*section).getEntryComment(entryName);
     274  else
     275    return IniParser::_emptyString;
     276}
     277
     278void IniParser::Document::clear()
     279{
     280  this->_sections.clear();
     281}
     282
     283void IniParser::Document::debug() const
     284{
     285  for(Section::const_iterator section = this->_sections.begin(); section != this->_sections.end(); ++section)
     286    (*section).debug();
     287}
     288
     289
     290
     291
     292/// /// /// /// /// /// //
     293/// INI-PARSER ITSELF ////
     294/// /// /// /// /// /// //
     295const std::string IniParser::_emptyString = "";
    39296/**
    40297 * @brief constructs an IniParser using a file
     
    42299 */
    43300IniParser::IniParser (const std::string& fileName)
    44 {
    45   this->fileName = "";
    46   this->comment = "";
    47 
     301    : _document(fileName)
     302{
     303  this->_fileName = fileName;
    48304  if (!fileName.empty())
    49305    this->readFile(fileName);
     
    55311 */
    56312IniParser::~IniParser ()
    57 {
    58   this->deleteSections();
    59   this->setFileName("");
    60 }
    61 
    62 const std::string IniParser::emptyString = "";
    63 
    64 
    65 /**
    66  * @brief removes all the sections. This is like delete, but even cooler :)
    67  */
    68 void IniParser::deleteSections()
    69 {
    70   // in all sections
    71   this->sections.clear();
    72 
    73   this->currentSection = this->sections.end();
    74   this->setFileName("");
    75 }
    76 
    77 
    78 /**
    79  * @brief sets the Name of the input-file
    80  * @param fileName The new FileName to set to the IniParser
    81  * If fileName is NULL the new Name will be set to NULL too.
    82  */
    83 void IniParser::setFileName(const std::string& fileName)
    84 {
    85   this->comment = "";
    86   this->fileName = fileName;
    87 }
    88 
     313{}
    89314
    90315/**
    91316 * @brief opens a file to parse
    92317 * @param fileName: path and name of the new file to parse
     318 * @param keepSettings if the Settings (if already some are set) should be kept (false by default)
    93319 * @return true on success false otherwise;
    94320 *
     
    96322 * and the new one will be opened.
    97323 */
    98 bool IniParser::readFile(const std::string& fileName)
     324bool IniParser::readFile(const std::string& fileName, bool keepSettings)
    99325{
    100326  FILE*    stream;           //< The stream we use to read the file.
    101   int      lineCount = 0;    //< The Count of lines.
    102 
    103   if (!this->fileName.empty())
    104     this->deleteSections();
    105 
    106   if( fileName.empty())
    107     return false;
     327  int      lineCount = 0;    //< The Count of lines read.
     328  std::list<std::string>  commentList;     //< A list of Comments.
     329  Section* currentSection = NULL;
     330
     331  if (!keepSettings)
     332    this->_document.clear();
    108333
    109334  if( (stream = fopen (fileName.c_str(), "r")) == NULL)
     
    114339  else
    115340  {
    116     this->setFileName(fileName);
     341    this->_fileName = fileName;
    117342
    118343    /////////////////////////////
     
    143368      {
    144369        std::string newCommenLine = lineBegin;
    145         this->commentList.push_back(newCommenLine);
     370        commentList.push_back(newCommenLine);
    146371        continue;
    147372      }
    148       if (lineCount == 0 && !this->commentList.empty())
     373      if (lineCount == 0 && !commentList.empty())
    149374      {
    150         this->setFileComment();
     375        this->setNodeComment(&this->_document, &commentList);
    151376        lineCount++;
    152377      }
     
    158383        {
    159384          *ptr = 0;
    160           this->addSection(buffer);
    161           this->setSectionComment();
     385          Section& node = this->_document.addSection(buffer);
     386          setNodeComment(&node, &commentList);
     387          currentSection = &node;
    162388        }
    163389      }
     
    165391      else if( (ptr = strchr( lineBegin, '=')) != NULL)
    166392      {
    167         if (currentSection == this->sections.end())
     393        if (currentSection == NULL)
    168394        {
    169395          PRINTF(2)("Not in a Section yet for %s\n", lineBegin);
     
    188414        nameEnd[1] = '\0';
    189415
    190         this->addVar(lineBegin, valueBegin);
    191         this->setEntryComment();
     416        Entry& node = currentSection->addEntry(lineBegin, valueBegin);
     417        this->setNodeComment(&node, &commentList);
    192418
    193419        lineCount++;
     
    195421    }
    196422  }
    197   this->currentSection = this->sections.begin();
    198   if (!this->sections.empty())
    199     this->currentEntry = (*this->currentSection).entries.begin();
    200 
    201423  fclose(stream);
    202424  return true;
     
    222444  else
    223445  {
    224     if (!this->comment.empty())
    225       fprintf(stream, "%s\n\n", this->comment.c_str());
    226 
    227     std::list<IniSection>::const_iterator section;
    228     for (section = this->sections.begin(); section != this->sections.end(); section++)
     446    if (!this->_document.comment().empty())
     447      fprintf(stream, "%s\n\n", this->_document.comment().c_str());
     448
     449    Section::const_iterator section;
     450    for (section = this->_document.sections().begin(); section != this->_document.sections().end(); ++section)
    229451    {
    230       if (!(*section).comment.empty())
    231         fprintf(stream, "%s", (*section).comment.c_str());
    232       fprintf(stream, "\n [%s]\n", (*section).name.c_str());
    233 
    234       std::list<IniEntry>::const_iterator entry;
    235       for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
     452      if (!(*section).comment().empty())
     453        fprintf(stream, "%s", (*section).comment().c_str());
     454      fprintf(stream, "\n [%s]\n", (*section).name().c_str());
     455
     456      Entry::const_iterator entry;
     457      for (entry = (*section).entries().begin(); entry != (*section).entries().end(); ++entry)
    236458      {
    237         if (!(*entry).comment.empty())
    238           fprintf(stream, "%s", (*entry).comment.c_str());
    239         fprintf(stream, "   %s = %s\n", (*entry).name.c_str(), (*entry).value.c_str());
     459        if (!(*entry).comment().empty())
     460          fprintf(stream, "%s", (*entry).comment().c_str());
     461        fprintf(stream, "   %s = %s\n", (*entry).name().c_str(), (*entry).value().c_str());
    240462      }
    241463    }
     
    247469void IniParser::setFileComment(const std::string& fileComment)
    248470{
    249   this->comment = fileComment;
     471  this->_document.setComment(fileComment);
    250472}
    251473
     
    256478 * @return true on success... there is only success or segfault :)
    257479 */
    258 bool IniParser::addSection(const std::string& sectionName)
    259 {
    260   if (sectionName.empty())
    261     return false;
    262   IniSection newSection;
    263   newSection.name = sectionName;
    264   newSection.comment = "";
    265 
    266   this->sections.push_back(newSection);
    267 
    268   this->currentSection = --this->sections.end();
    269   if (!this->sections.empty())
    270     this->currentEntry = (*this->currentSection).entries.begin();
    271   PRINTF(5)("Added Section %s\n", sectionName.c_str());
    272   return true;
    273 }
    274 
    275 
    276 /**
    277  * @brief Set the parsing cursor to the specified section
    278  * @param sectionName: the name of the section to set the cursor to
    279  * @return true on success or false if the section could not be found
    280  */
    281 bool IniParser::getSection(const std::string& sectionName)
    282 {
    283   this->currentSection = this->getSectionIT(sectionName);
    284   if (this->currentSection != this->sections.end())
    285   {
    286     this->currentEntry = (*this->currentSection).entries.begin();
    287     return true;
    288   }
    289   else
    290     return false;
    291 }
    292 
    293 /**
    294  *
    295  */
    296 void IniParser::setSectionComment(const std::string& comment, const std::string& sectionName)
    297 {
    298   std::list<IniSection>::iterator section = this->getSectionIT(sectionName);
    299   if (section == this->sections.end())
    300     return;
    301 
    302   (*section).comment = comment;
    303 }
    304 
    305 /**
    306  * @param sectionName the Section to query for
    307  * @returns the Comment, or NULL on error.
    308  */
    309 const std::string& IniParser::getSectionComment(const std::string& sectionName) const
    310 {
    311   std::list<IniSection>::const_iterator section = this->getSectionIT(sectionName);
    312   if (section != this->sections.end())
    313     return (*section).comment;
    314   else
    315     return IniParser::emptyString;
    316 }
    317 
    318 
    319 /**
    320  * @brief moves to the first section
    321  */
    322 void IniParser::firstSection()
    323 {
    324   this->currentSection = this->sections.begin();
    325   if (!this->sections.empty())
    326     this->currentEntry = (*this->currentSection).entries.begin();
    327 }
    328 
    329 
    330 /**
    331  * @brief searches the next section
    332  * @returns the name of the section if found, NULL otherwise
    333  */
    334 const std::string& IniParser::nextSection()
    335 {
    336   if (this->currentSection == this->sections.end())
    337     return IniParser::emptyString;
    338 
    339   this->currentSection++;
    340 
    341   if (this->currentSection != this->sections.end())
    342   {
    343     this->currentEntry = (*this->currentSection).entries.begin();
    344     return this->currentSection->name;
    345   }
    346   else
    347     return IniParser::emptyString;
     480IniParser::Section& IniParser::addSection(const std::string& sectionName)
     481{
     482  return this->_document.addSection(sectionName);
    348483}
    349484
     
    356491 * otherwise to the section refered to by sectionName.
    357492 * If both are NULL no entry will be added
    358  * @return true if everything is ok false on error
    359  */
    360 bool IniParser::addVar(const std::string& entryName, const std::string& value, const std::string& sectionName)
    361 {
    362   std::list<IniSection>::iterator section;
    363 
    364   if (!sectionName.empty())
    365   {
    366     for (section = this->sections.begin(); section != this->sections.end(); section++)
    367       if ((*section).name == sectionName)
    368         break;
    369   }
    370   else
    371     section = this->currentSection;
    372 
    373   if (section == this->sections.end())
    374     return false;
    375 
    376   if (section == this->sections.end())
    377   {
    378     PRINTF(2)("section '%s' not found for value '%s'\n", sectionName.c_str(), entryName.c_str());
    379     return false;
    380   }
    381   else
    382   {
    383     (*section).entries.push_back(IniEntry());
    384     (*section).entries.back().comment = "";
    385     (*section).entries.back().name = entryName;
    386     (*section).entries.back().value = value;
    387     PRINTF(5)("Added Entry %s with Value '%s' to Section %s\n",
    388               (*section).entries.back().name.c_str(),
    389               (*section).entries.back().value.c_str(),
    390               (*section).name.c_str());
    391     this->currentEntry = --(*section).entries.end();
    392     return true;
    393   }
     493 * @return The Entry, that was added.
     494 */
     495bool IniParser::addEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, const std::string& comment)
     496{
     497  return this->_document.addEntry(sectionName, entryName, value, comment);
    394498}
    395499
     
    403507 * @return true if everything is ok false on error
    404508 */
    405 bool IniParser::editVar(const std::string& entryName, const std::string& value, const std::string& sectionName, bool createMissing)
    406 {
    407   std::list<IniSection>::iterator section;
    408 
    409   if (!sectionName.empty())
    410   {
    411     for (section = this->sections.begin(); section != this->sections.end(); section++)
    412       if ((*section).name == sectionName)
    413         break;
    414   }
    415   else
    416     section = this->currentSection;
    417 
    418   if (section == this->sections.end())
    419   {
    420     this->addSection(sectionName);
    421     for (section = this->sections.begin(); section != this->sections.end(); section++)
    422       if ((*section).name == sectionName)
    423         break;
    424   }
    425 
    426   //try find item
    427   std::list<IniEntry>::iterator entry;
    428   for (entry = section->entries.begin(); entry!=section->entries.end(); entry++)
    429     if (entry->name == entryName )
    430       break;
    431 
    432   //found it?
    433   if ( entry != section->entries.end() )
    434   {
    435     entry->value = value;
    436 
    437     return true;
    438   }
    439   else
    440   {
    441     //not found -> create it
    442     (*section).entries.push_back(IniEntry());
    443     (*section).entries.back().comment = "";
    444     (*section).entries.back().name = entryName;
    445     (*section).entries.back().value = value;
    446     PRINTF(5)("Added Entry '%s' with Value '%s' to Section '%s'\n",
    447               (*section).entries.back().name.c_str(),
    448               (*section).entries.back().value.c_str(),
    449               (*section).name.c_str());
    450     this->currentEntry = --(*section).entries.end();
    451     return true;
    452   }
    453   return false;
     509bool IniParser::editEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, bool createMissing)
     510{
     511  return this->_document.editEntry(sectionName, entryName, value, createMissing);
    454512}
    455513
     
    457515/**
    458516 * @brief directly acesses an entry in a section
     517 * @param sectionName: the section where the entry is to be found
    459518 * @param entryName: the name of the entry to find
    460  * @param sectionName: the section where the entry is to be found
    461519 * @param defaultValue: what should be returned in case the entry cannot be found
    462  * @return a pointer to a buffer conatining the value of the specified entry. This buffer will contain the data specified in defvalue in case the entry wasn't found
    463  *
    464  *  The returned pointer points to an internal buffer, so do not free it on your own. Do not give a NULL pointer to defvalue, this will certainly
    465  * lead to unwanted behaviour.
    466 */
    467 const std::string& IniParser::getVar(const std::string& entryName, const std::string& sectionName, const std::string& defaultValue) const
    468 {
    469   if (!this->fileName.empty())
    470   {
    471     std::list<IniEntry>::const_iterator entry = this->getEntryIT(entryName, sectionName);
    472     if (/** FIXME entry != NULL && */  (*entry).name == entryName)
    473       return (*entry).value;
    474     PRINTF(2)("Entry '%s' in section '%s' not found.\n", entryName.c_str(), sectionName.c_str());
    475   }
    476   else
    477     PRINTF(2)("no File opened\n");
    478 
    479   return defaultValue;
     520 * @return The Value of the Entry.
     521 */
     522const std::string& IniParser::getValue(const std::string& sectionName, const std::string& entryName, const std::string& defaultValue) const
     523{
     524  return this->_document.getValue(sectionName, entryName, defaultValue);
    480525}
    481526
     
    486531 * @param sectionName the Name of the Section
    487532 */
    488 void IniParser::setEntryComment(const std::string& comment, const std::string& entryName, const std::string& sectionName)
    489 {
    490   std::list<IniEntry>::iterator entry = this->getEntryIT(entryName, sectionName);
    491   (*entry).comment = comment;
     533void IniParser::setEntryComment(const std::string& sectionName, const std::string& entryName, const std::string& comment)
     534{
     535  this->_document.setEntryComment(sectionName, entryName, comment);
    492536}
    493537
     
    497541 * @returns the queried Comment.
    498542 */
    499 const std::string& IniParser::getEntryComment(const std::string& entryName, const std::string& sectionName) const
    500 {
    501   std::list<IniEntry>::const_iterator entry = this->getEntryIT(entryName, sectionName);
    502 
    503   return (*entry).comment;
    504 }
    505 
    506 
    507 /**
    508  * @brief moves to the first Variable of the current Section
    509  */
    510 void IniParser::firstVar()
    511 {
    512   if (!this->sections.empty() &&
    513       this->currentSection != this->sections.end())
    514     this->currentEntry = (*this->currentSection).entries.begin();
    515 }
    516 
    517 
    518 /**
    519  * @brief gets the next VarName = VarValue pair from the parsing stream
    520  * @return true on success, false otherwise (in the latter case name and value will be NULL)
    521  */
    522 bool IniParser::nextVar()
    523 {
    524   if ( this->sections.empty()
    525        || this->currentSection == this->sections.end()
    526        || this->currentEntry == (*this->currentSection).entries.end())
    527     return false;
    528 
    529   this->currentEntry++;
    530 
    531   if (this->currentEntry == (*this->currentSection).entries.end())
    532     return false;
    533   else
    534     return true;
    535 }
    536 
    537 
    538 
    539 /**
    540  * @returns the name of the Current selected Section
    541  */
    542 const std::string& IniParser::getCurrentSection() const
    543 {
    544   if (!this->sections.empty() &&
    545       this->currentSection != this->sections.end())
    546     return this->currentSection->name;
    547   else
    548     return IniParser::emptyString ;
    549 }
    550 
    551 
    552 /**
    553  * @returns the current entries Name, or NULL if we havn't selected a Entry
    554  */
    555 const std::string& IniParser::getCurrentName() const
    556 {
    557   if (!this->sections.empty() &&
    558       this->currentSection != this->sections.end() &&
    559       this->currentEntry != (*this->currentSection).entries.end())
    560     return (*this->currentEntry).name;
    561   else
    562     return emptyString;
    563 }
    564 
    565 /**
    566  * @returns the current entries Value, or NULL if we havn't selected a Entry
    567  */
    568 const std::string& IniParser::getCurrentValue() const
    569 {
    570   if (!this->sections.empty() &&
    571       this->currentSection != this->sections.end() &&
    572       this->currentEntry != (*this->currentSection).entries.end())
    573     return (*this->currentEntry).value;
    574   else
    575     return IniParser::emptyString;
    576 }
    577 
    578 
    579 /**
    580  * Finds the Section Iterator of the Section Called sectionName
    581  * @param sectionName the Name of the Section to get the Iterator from
    582  */
    583 std::list<IniParser::IniSection>::const_iterator IniParser::getSectionIT(const std::string& sectionName) const
    584 {
    585   std::list<IniSection>::const_iterator section = this->currentSection;
    586   if (sectionName.empty())
    587     return this->currentSection;
    588   else
    589     for (section = this->sections.begin(); section != this->sections.end(); section++)
    590       if ((*section).name == sectionName)
    591         break;
    592   return section;
    593 }
    594 
    595 
    596 /**
    597  * Finds the Section Iterator of the Section Called sectionName
    598  * @param sectionName the Name of the Section to get the Iterator from
    599  */
    600 std::list<IniParser::IniSection>::iterator IniParser::getSectionIT(const std::string& sectionName)
    601 {
    602   std::list<IniSection>::iterator section = this->currentSection;
    603   if (sectionName.empty())
    604     return this->currentSection;
    605   else
    606     for (section = this->sections.begin(); section != this->sections.end(); section++)
    607       if ((*section).name == sectionName)
    608         break;
    609   return section;
    610 }
    611 
    612 
    613 /**
    614  * Finds the Entry Iterator of the Section Called sectionName and entry called EntryName
    615  * @param entryName the Name of the Entry to get the Iterator from
    616  * @param sectionName the Name of the Section to get the Iterator from
    617  */
    618 std::list<IniParser::IniEntry>::const_iterator IniParser::getEntryIT(const std::string& entryName, const std::string& sectionName) const
    619 {
    620   if (entryName.empty())
    621     return this->currentEntry;
    622   std::list<IniSection>::const_iterator section = this->getSectionIT(sectionName);
    623   std::list<IniEntry>::const_iterator entry = this->currentEntry;
    624 
    625   if (section != this->sections.end())
    626     for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
    627       if ((*entry).name == entryName)
    628         break;
    629   return entry;
    630 }
    631 
    632 
    633 /**
    634  * Finds the Entry Iterator of the Section Called sectionName and entry called EntryName
    635  * @param entryName the Name of the Entry to get the Iterator from
    636  * @param sectionName the Name of the Section to get the Iterator from
    637  */
    638 std::list<IniParser::IniEntry>::iterator IniParser::getEntryIT(const std::string& entryName, const std::string& sectionName)
    639 {
    640   if (entryName.empty())
    641     return this->currentEntry;
    642   std::list<IniSection>::iterator section = this->getSectionIT(sectionName);
    643   std::list<IniEntry>::iterator entry = this->currentEntry;
    644 
    645   if (section != this->sections.end())
    646     for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
    647       if ((*entry).name == entryName)
    648         break;
    649   return entry;
    650 }
    651 
    652 
    653 /**
    654  * takes lines together to form one FileComment, ereasing the commentList
    655  */
    656 void IniParser::setFileComment()
    657 {
    658   if (this->commentList.empty())
    659   {
    660     this->comment = "";
    661     return;
    662   }
    663 
    664   std::list<char*>::iterator comment;
    665 
    666   while (!this->commentList.empty())
    667   {
    668     if (this->comment[0] != '\0')
    669       this->comment += "\n";
    670     this->comment += this->commentList.front();
    671     this->commentList.pop_front();
    672   }
    673 }
    674 
    675 /**
    676  * takes lines together to form one SectionComment, ereasing the commentList
    677  */
    678 void IniParser::setSectionComment()
    679 {
    680   (*this->currentSection).comment = "";
    681 
    682   if (this->commentList.empty())
    683     return;
    684 
    685   while (!this->commentList.empty())
    686   {
    687     if ((*this->currentSection).comment[0] != '\0')
    688       (*this->currentSection).comment += "\n";
    689     (*this->currentSection).comment += this->commentList.front();
    690     this->commentList.pop_front();
    691   }
    692 }
    693 
    694 /**
    695  * takes lines together to form one EntryComment, ereasing the commentList
    696  */
    697 void IniParser::setEntryComment()
    698 {
    699   (*this->currentEntry).comment = "";
    700   if (this->commentList.empty())
    701     return;
    702 
    703   while (!this->commentList.empty())
    704   {
    705     if ((*this->currentEntry).comment[0] != '\0')
    706       (*this->currentEntry).comment += "\n";
    707     (*this->currentEntry).comment += this->commentList.front();
    708     this->commentList.pop_front();
    709   }
    710 }
    711 
     543const std::string& IniParser::getEntryComment(const std::string& sectionName, const std::string& entryName) const
     544{
     545  return this->_document.getEntryComment(sectionName, entryName);
     546}
    712547
    713548/**
     
    716551void IniParser::debug() const
    717552{
    718   PRINT(0)("Iniparser '%s' - debug\n", this->fileName.c_str());
    719   if (!this->comment.empty())
    720     PRINT(0)("FileComment:\n '%s'\n\n", this->comment.c_str());
    721 
    722   if (!this->fileName.empty())
    723   {
    724     if (sections.empty())
    725       PRINT(0)("No Sections defined\n");
    726     std::list<IniSection>::const_iterator section;
    727     for (section = this->sections.begin(); section != this->sections.end(); section++)
     553  PRINT(0)("Iniparser '%s' - debug\n", this->_fileName.c_str());
     554  if (!this->_document.comment().empty())
     555    PRINT(0)("FileComment:\n '%s'\n\n", this->_document.comment().c_str());
     556
     557  if (!this->_document.sections().empty())
     558    this->_document.debug();
     559  else
     560    PRINTF(0)("no Sections Defined in this ini-file (%s).\n", _fileName.c_str());
     561}
     562
     563
     564/**
     565 * takes lines together to form one NodeComment, ereasing the commentList
     566 */
     567void IniParser::setNodeComment(Node* node, std::list<std::string>* comments)
     568{
     569  assert(node != NULL);
     570  assert(comments != NULL);
     571
     572  std::string comment;
     573  if (comments->empty())
     574  {
     575    comment = "";
     576  }
     577  else
     578  {
     579    while (!comments->empty())
    728580    {
    729       if (!(*section).comment.empty())
    730         PRINTF(0)(" %s\n", (*section).comment.c_str());
    731       PRINTF(0)(" [%s]\n", (*section).name.c_str());
    732 
    733       if ((*section).entries.empty())
    734         PRINT(0)("No Entries defined within Section '%s'\n", (*section).name.c_str());
    735 
    736       std::list<IniEntry>::const_iterator entry;
    737       for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
    738       {
    739         if (!(*entry).comment.empty())
    740           PRINTF(0)(" %s\n", (*entry).comment.c_str());
    741         PRINTF(0)("   '%s' -> '%s'\n", (*entry).name.c_str(), (*entry).value.c_str());
    742       }
     581      if (!comment.empty())
     582        comment += "\n";
     583      comment += comments->front();
     584      comments->pop_front();
    743585    }
    744586  }
    745   else
    746     PRINTF(0)("no opened ini-file.\n");
    747 }
    748 
     587  node->setComment(comment);
     588}
     589
     590
  • trunk/src/lib/parser/ini_parser/ini_parser.h

    r9869 r9880  
    1111#define PARSELINELENGHT     512       //!< how many chars to read at once
    1212
    13 #include "lib/util/filesys/file.h"
     13#include <string>
    1414#include <list>
    1515
     
    1818 * This class can be used to load an initializer file and parse it's contents for variablename=value pairs.
    1919 */
    20 class IniParser : public File
     20class IniParser
    2121{
     22public:
     23  ////////////////////////////////////
     24  /// A Node for a Ini-Node. The base of all INI-elements.
     25  class Node
     26  {
     27  public:
     28    Node(const std::string& name, const std::string& comment = "");
     29    virtual ~Node() {};
     30    const std::string& name() const  { return _name; };
     31    const std::string& comment() const  { return _comment; };
     32    void setName(const std::string& name) { this->_name = name; };
     33    void setComment(const std::string& comment) { this->_comment = comment; };
     34
     35    bool operator==(const std::string& name) const { return _name == name; };
     36    bool operator==(const Node& node) const { return this->_name == node._name; };
     37
     38    virtual void debug() const = 0;
     39
    2240  private:
    23     ////////////////////////////////////
    24     //! a struct for Entries in the Parser's File's Sections
    25     struct IniEntry
    26     {
    27       std::string         comment;  //!< A Comment that is appendet to the Top of this Entry.
    28       std::string         name;     //!< name of a given Entry
    29       std::string         value;    //!< value of a given Entry
    30     };
     41    std::string         _comment;  //!< A Comment that is appendet to the Top of this Node
     42    std::string         _name;     //!< name of a given Node
     43  };
    3144
    32     //! a struct for Sections in the Parser's file
    33     struct IniSection
    34     {
    35       std::string         comment;  //!< A Comment that is appendet to the Top of this Section.
    36       std::string         name;     //!< name of a given section
    37       std::list<IniEntry> entries;  //!< a list of entries for this section
    38     };
    39     ////////////////////////////////////
     45  //! a class for Entries in the Parser's File's Sections
     46class Entry : public Node
     47  {
     48  public:
     49    Entry(const std::string& name, const std::string& value = "", const std::string& comment = "");
     50    const std::string& value() const { return _value; };
     51    void setValue (const std::string& value) { _value = value; };
     52
     53    virtual void debug() const;
    4054
    4155  public:
    42     IniParser (const std::string& filename = "");
    43     virtual ~IniParser ();
    44 
    45     /** @returns true if the file is opened, false otherwise*/
    46     bool isOpen() const { return true; } ///HACK //(this->fileName.empty()) ? false : true; };
    47     /** @returns the fileName we have opened. */
    48     const std::string& getFileName() const { return this->fileName; };
    49 
    50     bool readFile(const std::string& fileName);
    51     bool writeFile(const std::string& fileName) const;
    52 
    53     void setFileComment(const std::string& fileComment);
    54     const std::string& getFileComment() const { return this->comment; };
    55 
    56     bool addSection(const std::string& sectionName);
    57     bool getSection(const std::string& sectionName);
    58     void setSectionComment(const std::string& comment, const std::string& sectionName);
    59     const std::string& getSectionComment(const std::string& sectionNane) const;
    60 
    61     // iterate through sections with these Functions
    62     void firstSection();
    63     const std::string& nextSection();
    64 
    65 
    66     bool addVar(const std::string& entryName, const std::string& value, const std::string& sectionName = "" );
    67     const std::string& getVar(const std::string& entryName, const std::string& sectionName, const std::string& defaultValue = "") const;
    68     bool editVar(const std::string& entryName, const std::string& value, const std::string& sectionName = "", bool createMissing = true);
    69     void setEntryComment(const std::string& comment, const std::string& entryName, const std::string& sectionName);
    70     const std::string& getEntryComment(const std::string& entryName, const std::string& sectionName) const;
    71 
    72     // iterate Through Variables with these Functions.
    73     void firstVar();
    74     bool nextVar();
    75 
    76 
    77     // retrieving functions when iterating.
    78     const std::string& getCurrentSection() const;
    79     const std::string& getCurrentName() const;
    80     const std::string& getCurrentValue() const;
    81 
    82 
    83     // maintenance.
    84     void debug() const;
    85 
     56    typedef std::list<Entry>                    list;
     57    typedef list::iterator                      iterator;
     58    typedef list::const_iterator                const_iterator;
    8659
    8760  private:
    88     void deleteSections();
    89     void setFileName(const std::string& fileName);
     61    std::string         _value;    //!< value of a given Entry
     62  };
    9063
    91     void setFileComment();
    92     void setSectionComment();
    93     void setEntryComment();
     64  //! a clas for Sections in the Parser's file
     65class Section : public Node
     66  {
     67  public:
     68    Section(const std::string& sectionName, const std::string& comment = "");
    9469
    95     std::list<IniSection>::const_iterator getSectionIT(const std::string& sectionName) const;
    96     std::list<IniSection>::iterator getSectionIT(const std::string& sectionName);
     70    Entry& addEntry(const std::string& entryName, const std::string& value = "", const std::string& comment = "");
     71    bool editEntry(const std::string& entryName, const std::string& value, bool createMissing = true);
     72    const std::string& getValue(const std::string& entryName, const std::string& defaultValue = "") const;
    9773
    98     std::list<IniEntry>::const_iterator getEntryIT(const std::string& entryName, const std::string& sectionName = "") const;
    99     std::list<IniEntry>::iterator getEntryIT(const std::string& entryName, const std::string& sectionName = "");
     74    bool setEntryComment(const std::string& entryName, const std::string& comment);
     75    const std::string& getEntryComment(const std::string& entryName) const;
     76
     77    const Entry::list& entries() const { return _entries; }
     78    Entry* getEntry(const std::string& entryName);
     79
     80    Entry::const_iterator getEntryIt(const std::string& entryName) const;
     81    Entry::iterator begin() { return _entries.begin(); };
     82    Entry::const_iterator begin() const { return _entries.begin(); };
     83    Entry::iterator end() { return _entries.end(); };
     84    Entry::const_iterator end() const { return _entries.end(); };
     85
     86    void clear();
     87
     88    virtual void debug() const;
     89
     90  public:
     91    typedef std::list<Section>                  list;
     92    typedef list::iterator                      iterator;
     93    typedef list::const_iterator                const_iterator;
    10094
    10195  private:
    102     std::string                      fileName;        //!< The name of the File that was parsed.
    103     std::string                      comment;         //!< A Comment for the header of this File.
    104     std::list<IniSection>            sections;        //!< a list of all stored Sections of the Parser
    105     std::list<IniSection>::iterator  currentSection;  //!< the current selected Section
    106     std::list<IniEntry>::iterator    currentEntry;    //!< the current selected entry (in currentSection)
     96    Entry::list     _entries;  //!< a list of entries for this section
     97  };
    10798
    108     std::list<std::string>           commentList;     //!< A list of Comments. (this is for temporary saving of Comments, that are inserted in front of Sections/Entries.)
     99  //! A class for a INI-file.
     100class Document : public Node
     101  {
     102  public:
     103    Document(const std::string& fileName, const std::string& comment = "");
    109104
     105    Section& addSection(const std::string& sectionName, const std::string& comment = "");
     106    bool removeSection(const std::string& sectionName);
     107    bool setSectionComment(const std::string& sectionName, const std::string& comment);
    110108
    111     static const std::string         emptyString;
     109    const Section::list& sections() const { return _sections; }
     110    Section* getSection(const std::string& sectionName);
     111
     112    Section::const_iterator getSectionIt(const std::string& sectionName) const;
     113    Section::iterator begin() { return _sections.begin(); };
     114    Section::const_iterator begin() const { return _sections.begin(); };
     115    Section::iterator end() { return _sections.end(); };
     116    Section::const_iterator end() const { return _sections.end(); };
     117
     118    bool addEntry(const std::string& sectionName, const std::string& entryName, const std::string& value = "", const std::string& comment = "");
     119    bool editEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, bool createMissing = true);
     120    const std::string& getValue(const std::string& sectionName, const std::string& entryName, const std::string& defaultValue = "") const;
     121
     122    bool setEntryComment(const std::string& sectionName, const std::string& entryName, const std::string& comment);
     123    const std::string& getEntryComment(const std::string& sectionName, const std::string& entryName) const;
     124
     125    void clear();
     126
     127    virtual void debug() const;
     128
     129  private:
     130    Section::list            _sections;        //!< a list of all stored Sections of the Parser.
     131  };
     132
     133public:
     134  IniParser (const std::string& filename = "");
     135  virtual ~IniParser ();
     136
     137  /** @returns true if the file is opened, false otherwise */
     138  bool isOpen() const { return !this->_document.sections().empty(); };
     139  /** @returns the fileName we have opened. */
     140  const std::string& getFileName() const { return this->_document.name(); };
     141
     142  /// Read and Write the File
     143  bool readFile(const std::string& fileName, bool keepSettings = false);
     144  bool writeFile(const std::string& fileName) const;
     145
     146  void setFileComment(const std::string& fileComment);
     147  const std::string& getFileComment() const { return this->_document.comment(); };
     148
     149  /// Woring with Sections.
     150  Section& addSection(const std::string& sectionName);
     151  // iterate through sections with these Functions
     152  Section* getSection(const std::string& sectionName) { return this->_document.getSection(sectionName); };
     153  Section::const_iterator getSectionIt(const std::string& sectionName) const;
     154
     155  Section::iterator begin() { return this->_document.begin(); };
     156  Section::const_iterator begin() const { return this->_document.begin(); };
     157  Section::iterator end() { return this->_document.end(); };
     158  Section::const_iterator end() const { return this->_document.end(); };
     159
     160  void setSectionComment(const std::string& sectionName, const std::string& comment);
     161  const std::string& getSectionsComment(const std::string& sectionNane) const;
     162
     163  /// Working on Entries. (globally)
     164  bool addEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, const std::string& comment);
     165  const std::string& getValue(const std::string& sectionNmae, const std::string& entryName, const std::string& defaultValue = "") const;
     166  bool editEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, bool createMissing = true);
     167
     168  void setEntryComment(const std::string& sectionName, const std::string& entryName, const std::string& comment);
     169  const std::string& getEntryComment(const std::string& sectionName, const std::string& entryName) const;
     170
     171  // maintenance.
     172  void debug() const;
     173
     174private:
     175  void setNodeComment(Node* node, std::list<std::string>* comments);
     176private:
     177  std::string                      _fileName;
     178  Document                         _document;
     179
     180  static const std::string         _emptyString;     //!< Just an Empty String that will be returned if nothing else is found.
    112181};
    113182
Note: See TracChangeset for help on using the changeset viewer.