summaryrefslogtreecommitdiff
path: root/ext/dsent/libutil/Config.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/dsent/libutil/Config.cc')
-rw-r--r--ext/dsent/libutil/Config.cc144
1 files changed, 144 insertions, 0 deletions
diff --git a/ext/dsent/libutil/Config.cc b/ext/dsent/libutil/Config.cc
new file mode 100644
index 000000000..f858c6926
--- /dev/null
+++ b/ext/dsent/libutil/Config.cc
@@ -0,0 +1,144 @@
+#include "Config.h"
+
+#include <fstream>
+
+#include "Assert.h"
+
+namespace LibUtil
+{
+ Config::Config(const String& delimiter_, const String& comment_, const String& sentry_)
+ : mDelimiter(delimiter_), mComment(comment_), mSentry(sentry_)
+ {}
+
+ Config::Config(const Config& config_)
+ : StringMap(config_)
+ {
+ mDelimiter = config_.mDelimiter;
+ mComment = config_.mComment;
+ mSentry = config_.mSentry;
+ }
+
+ Config::~Config()
+ {}
+
+ Config* Config::clone() const
+ {
+ return new Config(*this);
+ }
+
+ void Config::readFile(const String& filename_)
+ {
+ std::ifstream fin(filename_.c_str());
+
+ ASSERT(fin, "File not found: " + filename_);
+ fin >> (*this);
+ return;
+ }
+
+ void Config::readString(const String& str_)
+ {
+ String newString = str_;
+ newString.substitute(";", "\n");
+ std::istringstream iss(newString, std::istringstream::in);
+
+ iss >> (*this);
+ }
+
+ std::ostream& operator<<(std::ostream& ost_, const Config& config_)
+ {
+ Config::ConstIterator it;
+ for(it = config_.begin(); it != config_.end(); it++)
+ {
+ ost_ << it->first << " " << config_.mDelimiter << " ";
+ ost_ << it->second << std::endl;
+ }
+ return ost_;
+ }
+
+ std::istream& operator>>(std::istream& ist_, Config& config_)
+ {
+ // Set a Config from ist_
+ // Read in keys and values, keeping internal whitespace
+ typedef String::size_type pos;
+ const String& delim = config_.mDelimiter; // separator
+ const String& comm = config_.mComment; // comment
+ const String& sentry = config_.mSentry; // end of file sentry
+ const pos skip = delim.length(); // length of separator
+
+ String nextline = ""; // might need to read ahead to see where value ends
+
+ while(ist_ || nextline.length() > 0)
+ {
+ // Read an entire line at a time
+ String line;
+ if(nextline.length() > 0)
+ {
+ line = nextline; // we read ahead; use it now
+ nextline = "";
+ }
+ else
+ {
+ //std::getline(ist_, line);
+ safeGetline(ist_, line);
+ }
+
+ // Ignore comments and the spaces on both ends
+ line = line.substr(0, line.find(comm));
+ line.trim();
+
+ // Check for end of file sentry
+ if((sentry != "") && (line.find(sentry) != String::npos)) return ist_;
+
+ if(line.length() == 0)
+ continue;
+
+ // Parse the line if it contains a delimiter
+ pos delimPos = line.find(delim);
+ ASSERT((delimPos < String::npos), "Invalid config line: '" + line + "'");
+
+ // Extract the key
+ String key = line.substr(0, delimPos);
+ line.replace(0, delimPos+skip, "");
+
+ // See if value continues on the next line
+ // Stop at blank line, next line with a key, end of stream,
+ // or end of file sentry
+ bool terminate = false;
+ while(!terminate && ist_)
+ {
+ if(line.at(line.size() - 1) == '\\')
+ line.erase(line.size() - 1);
+ else
+ break;
+
+ //std::getline(ist_, nextline);
+ safeGetline(ist_, nextline);
+ terminate = true;
+
+ String nlcopy = nextline;
+ nlcopy.trim();
+ if(nlcopy == "") continue;
+
+ nextline = nextline.substr(0, nextline.find(comm));
+ //if(nextline.find(delim) != String::npos)
+ // continue;
+ if((sentry != "") && (nextline.find(sentry) != String::npos))
+ continue;
+
+ //nlcopy = nextline;
+ //nlcopy.trim();
+ //if(nlcopy != "") line += "\n";
+ line += nextline;
+ nextline = "";
+ terminate = false;
+ }
+
+ // Store key and value
+ key.trim();
+ line.trim();
+ config_.set(key, line); // overwrites if key is repeated
+ }
+ return ist_;
+ }
+}
+