ConfigFile.cpp
Go to the documentation of this file.
00001 // ConfigFile.cpp
00002 
00003 #include <youbot_driver/generic/ConfigFile.hpp>
00004 
00005 using std::string;
00006 
00007 namespace youbot
00008 {
00009 
00010 ConfigFile::ConfigFile(string filename, string filepath, string delimiter, string comment, string sectionStartTag,
00011                        string sectionEndTag, string sentry) :
00012     myDelimiter(delimiter), myComment(comment), mySectionStartTag(sectionStartTag), mySectionEndTag(sectionEndTag), mySentry(
00013         sentry)
00014 {
00015 
00016   if (filepath.at(filepath.length() - 1) != '/')
00017   {
00018     filepath.append("/");
00019   }
00020   filepath.append(filename);
00021 
00022   //Ensure, that we are working with Config Files
00023   if (filepath.substr(filepath.length() - 4, 4) != ".cfg")
00024     filepath.append(".cfg");
00025 
00026   //Store for later use
00027   myFilepath = filepath;
00028   mySortVectorObj = new SortTreeVector();
00029 
00030   // Construct a ConfigFile, getting keys and values from given file
00031   std::ifstream in(filepath.c_str());
00032 
00033   if (!in)
00034     throw FileNotFoundException(filepath);
00035 
00036   in >> (*this);
00037 }
00038 
00039 ConfigFile::ConfigFile() :
00040     myDelimiter(string(1, '=')), myComment(string(1, '#')), mySectionStartTag(string(1, '[')), mySectionEndTag(
00041         string(1, ']'))
00042 {
00043   // Construct a ConfigFile without a file; empty
00044 }
00045 
00046 void ConfigFile::remove(const string& key)
00047 {
00048   // Remove key and its value
00049   myContents.erase(myContents.find(key));
00050   return;
00051 }
00052 
00053 void ConfigFile::remove(const string& sectionKey, const string& key)
00054 {
00055   mapciSect sp = mySectionRelatedContents.find(sectionKey);
00056   if (sp != mySectionRelatedContents.end())
00057   {
00058     // Remove key and its value
00059     myContents = sp->second;
00060 
00061     std::cout << "Size: " << myContents.size() << endl;
00062 
00063     mapi p = myContents.find(key);
00064     if (p == myContents.end())
00065       throw KeyNotFoundException(key);
00066     myContents.erase(p);
00067     mySectionRelatedContents[sectionKey] = myContents;
00068   }
00069   return;
00070 }
00071 
00072 void ConfigFile::save()
00073 {
00074 
00075   ofstream outFile(myFilepath.c_str());
00076 
00077   outFile << (*this);
00078 
00079 }
00080 
00081 bool ConfigFile::keyExists(const string& key) const
00082 {
00083   // Indicate whether key is found
00084   mapci p = myContents.find(key);
00085   return (p != myContents.end());
00086 }
00087 
00088 bool ConfigFile::keyExists(const string& sectionKey, const string& key)
00089 {
00090   mapciSect sp = mySectionRelatedContents.find(sectionKey);
00091   if (sp == mySectionRelatedContents.end())
00092   {
00093     return false;
00094   }
00095 
00096   // Indicate whether key is found
00097   mapci p = mySectionRelatedContents[sectionKey].find(key);
00098   return (p != mySectionRelatedContents[sectionKey].end());
00099 }
00100 
00101 bool ConfigFile::sectionExists(const string& sectionKey)
00102 {
00103 
00104   mapciSect sp = mySectionRelatedContents.find(sectionKey);
00105   if (sp == mySectionRelatedContents.end())
00106   {
00107     return false;
00108   }
00109   return true;
00110 }
00111 
00112 /* static */
00113 void ConfigFile::trim(string& s)
00114 {
00115   // Remove leading and trailing whitespace
00116   static const char whitespace[] = " \n\t\v\r\f";
00117   s.erase(0, s.find_first_not_of(whitespace));
00118   s.erase(s.find_last_not_of(whitespace) + 1U);
00119 }
00120 
00121 std::ostream & operator<<(std::ostream& os, ConfigFile& cf)
00122 {
00123 
00124   for (unsigned int i = 0; i < cf.mySortVector.size(); i++)
00125   {
00126 
00127     SortTreeVector currentTreeVector = cf.mySortVector.at(i);
00128     string currentSector = currentTreeVector.getKey();
00129 
00130     ConfigFile::mapciSect sp = cf.mySectionRelatedContents.find(currentSector.c_str());
00131     //First section has no empty line
00132     if (i > 0)
00133     {
00134       os << endl;
00135     }
00136     os << "[" << sp->first << "]" << endl;
00137 
00138     cf.myContents = sp->second;
00139 
00140     std::vector<string> contentVector = currentTreeVector.getVector();
00141     for (unsigned int j = 0; j < contentVector.size(); j++)
00142     {
00143       string currentKey = contentVector.at(j);
00144 
00145       // Save a ConfigFile to os
00146       ConfigFile::mapci p = cf.myContents.find(currentKey);
00147 
00148       if (p != cf.myContents.end())
00149       {
00150         os << p->first << " " << cf.myDelimiter << " ";
00151         os << p->second << std::endl;
00152       }
00153     }
00154   }
00155 
00156   return os;
00157 
00158 }
00159 
00160 std::istream & operator>>(std::istream& is, ConfigFile& cf)
00161 {
00162   // Load a ConfigFile from is
00163   // Read in keys and values, keeping internal whitespace
00164   typedef string::size_type pos;
00165   const string& delim = cf.myDelimiter; // separator
00166   const string& comm = cf.myComment; // comment
00167   const string& startTag = cf.mySectionStartTag; // starttag
00168   const string& endTag = cf.mySectionEndTag; // endtag
00169   const string& sentry = cf.mySentry; // end of file sentry
00170   const pos skip = delim.length(); // length of separator
00171 
00172   string nextline = ""; // might need to read ahead to see where value ends
00173   string sectHeader = "";
00174   std::vector<string> currentVector; //holds key-value pairs for each section
00175 
00176   while (is || nextline.length() > 0)
00177   {
00178 
00179     // Read an entire line at a time
00180     string line;
00181     if (nextline.length() > 0)
00182     {
00183       line = nextline; // we read ahead; use it now
00184       nextline = "";
00185     }
00186     else
00187     {
00188       std::getline(is, line);
00189     }
00190 
00191     // Ignore comments
00192     line = line.substr(0, line.find(comm));
00193 
00194     string lncopy = line;
00195     ConfigFile::trim(lncopy);
00196     //Sectionheader found
00197     if (lncopy.substr(0, 1) == startTag && lncopy.substr(lncopy.length() - 1, 1) == endTag)
00198     {
00199 
00200       sectHeader = lncopy.substr(1, lncopy.length() - 2);
00201       ConfigFile::trim(sectHeader);
00202       //New instance for each section
00203       string currentKey = cf.mySortVectorObj->getKey();
00204 
00205       if (!cf.mySortVectorObj || sectHeader != currentKey)
00206       {
00207 
00208         if (currentVector.size() > 0)
00209         {
00210           cf.mySortVectorObj->setVector(currentVector);
00211           cf.mySortVector.push_back(*cf.mySortVectorObj);
00212 
00213         }
00214         cf.mySortVectorObj = new SortTreeVector;
00215         //Create a new vector for KeyValue-Pairs
00216         currentVector = cf.mySortVectorObj->getVector();
00217         cf.mySortVectorObj->setKey(sectHeader);
00218       }
00219 
00220       cf.mySectionRelatedContents[sectHeader] = cf.myContents;
00221       continue;
00222     }
00223 
00224     // Check for end of file sentry
00225     if (sentry != "" && line.find(sentry) != string::npos)
00226       return is;
00227 
00228     // Parse the line if it contains a delimiter
00229     pos delimPos = line.find(delim);
00230     if (delimPos < string::npos)
00231     {
00232       // Extract the key
00233       string key = line.substr(0, delimPos);
00234       line.replace(0, delimPos + skip, "");
00235 
00236       // See if value continues on the next line
00237       // Stop at blank line, next line with a key, end of stream,
00238       // or end of file sentry
00239       bool terminate = false;
00240       while (!terminate && is)
00241       {
00242         std::getline(is, nextline);
00243         terminate = true;
00244 
00245         string nlcopy = nextline;
00246         ConfigFile::trim(nlcopy);
00247         if (nlcopy == "")
00248           continue;
00249 
00250         nextline = nextline.substr(0, nextline.find(comm));
00251         if (nextline.find(delim) != string::npos)
00252           continue;
00253         if (sentry != "" && nextline.find(sentry) != string::npos)
00254           continue;
00255 
00256         nlcopy = nextline;
00257         ConfigFile::trim(nlcopy);
00258         if (nlcopy != "")
00259           line += "\n";
00260         line += nextline;
00261         terminate = false;
00262       }
00263 
00264       // Store key and value
00265       ConfigFile::trim(key);
00266       ConfigFile::trim(line);
00267 
00268       currentVector.push_back(key);
00269 
00270       cf.mySectionRelatedContents[sectHeader][key] = line; // overwrites if key is repeated
00271     }
00272   }
00273 
00274   //finally get the last things done
00275   if (currentVector.size() > 0)
00276   {
00277     cf.mySortVectorObj->setVector(currentVector);
00278     cf.mySortVector.push_back(*cf.mySortVectorObj);
00279   }
00280 
00281   return is;
00282 }
00283 
00284 } // namespace youbot


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Oct 6 2014 09:08:01