ConfigFile.cpp
Go to the documentation of this file.
1 // ConfigFile.cpp
2 
4 
5 using std::string;
6 
7 namespace youbot {
8 
9  ConfigFile::ConfigFile(string filename, string filepath, string delimiter,
10  string comment, string sectionStartTag, string sectionEndTag, string sentry)
11  : myDelimiter(delimiter), myComment(comment), mySectionStartTag(sectionStartTag), mySectionEndTag(sectionEndTag), mySentry(sentry) {
12 
13  if (filepath.length() > 0 && filepath.at(filepath.length() - 1) != '/') {
14  filepath.append("/");
15  }
16  filepath.append(filename);
17 
18  //Ensure, that we are working with Config Files
19  if (filepath.substr(filepath.length() - 4, 4) != ".cfg")
20  filepath.append(".cfg");
21 
22  //Store for later use
23  myFilepath = filepath;
25 
26  // Construct a ConfigFile, getting keys and values from given file
27  std::ifstream in(filepath.c_str());
28 
29  if (!in) throw FileNotFoundException(filepath);
30 
31  in >> (*this);
32  }
33 
35  : myDelimiter(string(1, '=')), myComment(string(1, '#')), mySectionStartTag(string(1, '[')), mySectionEndTag(string(1, ']')) {
36  // Construct a ConfigFile without a file; empty
37  }
38 
39  void ConfigFile::remove(const string& key) {
40  // Remove key and its value
41  myContents.erase(myContents.find(key));
42  return;
43  }
44 
45  void ConfigFile::remove(const string& sectionKey, const string& key) {
46  mapciSect sp = mySectionRelatedContents.find(sectionKey);
47  if (sp != mySectionRelatedContents.end()) {
48  // Remove key and its value
49  myContents = sp->second;
50 
51  std::cout << "Size: " << myContents.size() << endl;
52 
53 
54  mapi p = myContents.find(key);
55  if (p == myContents.end()) throw KeyNotFoundException(key);
56  myContents.erase(p);
58  }
59  return;
60  }
61 
63 
64  ofstream outFile(myFilepath.c_str());
65 
66  outFile << (*this);
67 
68  }
69 
70  bool ConfigFile::keyExists(const string& key) const {
71  // Indicate whether key is found
72  mapci p = myContents.find(key);
73  return ( p != myContents.end());
74  }
75 
76  bool ConfigFile::keyExists(const string& sectionKey, const string& key) {
77  mapciSect sp = mySectionRelatedContents.find(sectionKey);
78  if (sp == mySectionRelatedContents.end()) {
79  return false;
80  }
81 
82  // Indicate whether key is found
83  mapci p = mySectionRelatedContents[sectionKey].find(key);
84  return ( p != mySectionRelatedContents[sectionKey].end());
85  }
86 
87  bool ConfigFile::sectionExists(const string& sectionKey) {
88 
89  mapciSect sp = mySectionRelatedContents.find(sectionKey);
90  if (sp == mySectionRelatedContents.end()) {
91  return false;
92  }
93  return true;
94  }
95 
96  /* static */
97  void ConfigFile::trim(string& s) {
98  // Remove leading and trailing whitespace
99  static const char whitespace[] = " \n\t\v\r\f";
100  s.erase(0, s.find_first_not_of(whitespace));
101  s.erase(s.find_last_not_of(whitespace) + 1U);
102  }
103 
104  std::ostream & operator<<(std::ostream& os, ConfigFile& cf) {
105 
106  for (unsigned int i = 0; i < cf.mySortVector.size(); i++) {
107 
108  SortTreeVector currentTreeVector = cf.mySortVector.at(i);
109  string currentSector = currentTreeVector.getKey();
110 
111  ConfigFile::mapciSect sp = cf.mySectionRelatedContents.find(currentSector.c_str());
112  //First section has no empty line
113  if (i > 0) {
114  os << endl;
115  }
116  os << "[" << sp->first << "]" << endl;
117 
118  cf.myContents = sp->second;
119 
120  std::vector<string> contentVector = currentTreeVector.getVector();
121  for (unsigned int j = 0; j < contentVector.size(); j++) {
122  string currentKey = contentVector.at(j);
123 
124  // Save a ConfigFile to os
125  ConfigFile::mapci p = cf.myContents.find(currentKey);
126 
127  if (p != cf.myContents.end()) {
128  os << p->first << " " << cf.myDelimiter << " ";
129  os << p->second << std::endl;
130  }
131  }
132  }
133 
134  return os;
135 
136  }
137 
138  std::istream & operator>>(std::istream& is, ConfigFile& cf) {
139  // Load a ConfigFile from is
140  // Read in keys and values, keeping internal whitespace
141  typedef string::size_type pos;
142  const string& delim = cf.myDelimiter; // separator
143  const string& comm = cf.myComment; // comment
144  const string& startTag = cf.mySectionStartTag; // starttag
145  const string& endTag = cf.mySectionEndTag; // endtag
146  const string& sentry = cf.mySentry; // end of file sentry
147  const pos skip = delim.length(); // length of separator
148 
149 
150 
151  string nextline = ""; // might need to read ahead to see where value ends
152  string sectHeader = "";
153  std::vector<string> currentVector; //holds key-value pairs for each section
154 
155 
156  while (is || nextline.length() > 0) {
157 
158  // Read an entire line at a time
159  string line;
160  if (nextline.length() > 0) {
161  line = nextline; // we read ahead; use it now
162  nextline = "";
163  } else {
164  std::getline(is, line);
165  }
166 
167  // Ignore comments
168  line = line.substr(0, line.find(comm));
169 
170  string lncopy = line;
171  ConfigFile::trim(lncopy);
172  //Sectionheader found
173  if (lncopy.substr(0, 1) == startTag && lncopy.substr(lncopy.length() - 1, 1) == endTag) {
174 
175  sectHeader = lncopy.substr(1, lncopy.length() - 2);
176  ConfigFile::trim(sectHeader);
177  //New instance for each section
178  string currentKey = cf.mySortVectorObj->getKey();
179 
180  if (!cf.mySortVectorObj || sectHeader != currentKey) {
181 
182  if (currentVector.size() > 0) {
183  cf.mySortVectorObj->setVector(currentVector);
184  cf.mySortVector.push_back(*cf.mySortVectorObj);
185 
186  }
188  //Create a new vector for KeyValue-Pairs
189  currentVector = cf.mySortVectorObj->getVector();
190  cf.mySortVectorObj->setKey(sectHeader);
191  }
192 
193  cf.mySectionRelatedContents[sectHeader] = cf.myContents;
194  continue;
195  }
196 
197  // Check for end of file sentry
198  if (sentry != "" && line.find(sentry) != string::npos) return is;
199 
200  // Parse the line if it contains a delimiter
201  pos delimPos = line.find(delim);
202  if (delimPos < string::npos) {
203  // Extract the key
204  string key = line.substr(0, delimPos);
205  line.replace(0, delimPos + skip, "");
206 
207  // See if value continues on the next line
208  // Stop at blank line, next line with a key, end of stream,
209  // or end of file sentry
210  bool terminate = false;
211  while (!terminate && is) {
212  std::getline(is, nextline);
213  terminate = true;
214 
215  string nlcopy = nextline;
216  ConfigFile::trim(nlcopy);
217  if (nlcopy == "") continue;
218 
219  nextline = nextline.substr(0, nextline.find(comm));
220  if (nextline.find(delim) != string::npos)
221  continue;
222  if (sentry != "" && nextline.find(sentry) != string::npos)
223  continue;
224 
225  nlcopy = nextline;
226  ConfigFile::trim(nlcopy);
227  if (nlcopy != "") line += "\n";
228  line += nextline;
229  terminate = false;
230  }
231 
232  // Store key and value
233  ConfigFile::trim(key);
234  ConfigFile::trim(line);
235 
236  currentVector.push_back(key);
237 
238  cf.mySectionRelatedContents[sectHeader][key] = line; // overwrites if key is repeated
239  }
240  }
241 
242  //finally get the last things done
243  if (currentVector.size() > 0) {
244  cf.mySortVectorObj->setVector(currentVector);
245  cf.mySortVector.push_back(*cf.mySortVectorObj);
246  }
247 
248 
249  return is;
250  }
251 
252 } // namespace youbot
void setKey(const string &sKey)
Definition: ConfigFile.hpp:105
std::map< string, std::map< string, string > > mySectionRelatedContents
Definition: ConfigFile.hpp:137
static void trim(string &s)
Definition: ConfigFile.cpp:97
void remove(const string &key)
Definition: ConfigFile.cpp:39
Reads and writes a configuration file.
Definition: ConfigFile.hpp:125
std::vector< SortTreeVector > mySortVector
Definition: ConfigFile.hpp:139
bool sectionExists(const string &sectionKey)
Definition: ConfigFile.cpp:87
std::map< string, string >::const_iterator mapci
Definition: ConfigFile.hpp:142
Keep track of sortorder from original configfile.
Definition: ConfigFile.hpp:82
File not found exception.
Definition: Exceptions.hpp:65
std::vector< string > getVector() const
Definition: ConfigFile.hpp:109
bool keyExists(const string &key) const
Definition: ConfigFile.cpp:70
SortTreeVector * mySortVectorObj
Definition: ConfigFile.hpp:134
Key in configuration file not found exception.
Definition: Exceptions.hpp:85
friend std::ostream & operator<<(std::ostream &os, ConfigFile &cf)
Definition: ConfigFile.cpp:104
std::map< string, string > myContents
Definition: ConfigFile.hpp:136
void setVector(const std::vector< string > &vVector)
Definition: ConfigFile.hpp:113
std::map< string, string >::iterator mapi
Definition: ConfigFile.hpp:141
std::map< string, map< string, string > >::const_iterator mapciSect
Definition: ConfigFile.hpp:143
friend std::istream & operator>>(std::istream &is, ConfigFile &cf)
Definition: ConfigFile.cpp:138


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Jun 10 2019 15:46:24