From af5404ea593d460d3ae843a23b295e3cfeade5bc Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 10 Jul 2011 19:29:57 +0000 Subject: Split the ini file reader into a stream decoder and a file wrapper. --- src/filesystem/inistream.cc | 269 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 src/filesystem/inistream.cc (limited to 'src/filesystem/inistream.cc') diff --git a/src/filesystem/inistream.cc b/src/filesystem/inistream.cc new file mode 100644 index 0000000..d07745b --- /dev/null +++ b/src/filesystem/inistream.cc @@ -0,0 +1,269 @@ +/* + filesystem/inistream.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "auxiliary/functions.h" +#include "math/mathlib.h" +#include "filesystem/inistream.h" + +#include + +namespace filesystem +{ + +IniStream::IniStream() +{ + clear(); +} + +IniStream::~IniStream() +{ + clear(); +} + +void IniStream::clear() { + last_read_was_section = false; + last_read_was_key = false; + + key_current.clear(); + value_current.clear(); + section_current.clear(); + + line_number = 0; +} + +bool IniStream::got_section() const +{ + return last_read_was_section; +} + +bool IniStream::got_section(const char * sectionlabel) const +{ + return (last_read_was_section && (section_current.compare(sectionlabel) == 0)); +} + +bool IniStream::in_section(const char * sectionlabel) const +{ + return ((section_current.compare(sectionlabel) == 0)); +} + +bool IniStream::getline(std::istream & istream) +{ + char line[1024]; + + last_read_was_section = false; + last_read_was_key = false; + key_current = ""; + value_current = ""; + + if (!istream.good() || istream.eof()) + return false; + + if (istream.getline(line, 1023)) { + std::string s(line); + aux::trim(s); + line_number++; + + if (s.size() == 0) { + // empty line + } else + // strip trailing EOL / FF characters + if ( (s[s.size() -1] == 0x0a) || (s[s.size() -1] == 0x0d)) + s.erase(s.size() -1); + + // comment + if (s[0] == '#' || s[0] == ';') { + // condebug << "IniStream got comment " << s << std::endl; + } else + // section header + if (s.size() > 2 && s[0] == '[' && s[s.size()-1] == ']') { + // condebug << "Inifile got section header " << s << std::endl; + section_current = s.substr(1, s.size() - 2); + + aux::trim(section_current); + aux::to_lowercase(section_current); + + last_read_was_section = true; + return true; + } else { + // key=value pair + size_t found = s.find('='); + if (found != std::string::npos && found > 0) { + // make lowercase and strip spaces + key_current = s.substr(0, found); + + aux::trim(key_current); + aux::to_lowercase(key_current); + + if (key_current.size()) { + value_current = s.substr(found + 1, s.size() - found - 1); + aux::trim(value_current); + last_read_was_key = true; + //con_debug << "IniStream got " << key_current << "=" << value_current << std::endl; + return true; + } + + } + } + return true; + } else + return false; +} + +bool IniStream::got_key() const +{ + return last_read_was_key; +} + +bool IniStream::got_key_string(const char * keylabel, std::string & valuestring) +{ + if (last_read_was_key && (key_current.compare(keylabel) == 0)) { + valuestring.assign(value_current); + return true; + } else { + return false; + } +} + +bool IniStream::got_key_label(const char * keylabel, std::string & labelstring) +{ + if (last_read_was_key && (key_current.compare(keylabel) == 0)) { + labelstring.assign(value_current); + aux::to_label(labelstring); + return true; + } else { + return false; + } +} + +bool IniStream::got_key_vector3f(const char * keylabel, math::Vector3f & v) +{ + if (last_read_was_key && (key_current.compare(keylabel) == 0)) { + std::istringstream is(value_current); + float x, y, z; + if ((is >> x) && (is >> y) && (is >> z)) { + v = math::Vector3f(x, y, z); + } else { + v = math::Vector3f(); + } + return true; + } else { + return false; + } +} + +bool IniStream::got_key_float(const char * keylabel, float & f) +{ + if (last_read_was_key && (key_current.compare(keylabel) == 0)) { + std::istringstream is(value_current); + if (!(is >> f)) { + f = 0; + } + return true; + } else { + return false; + } +} + +bool IniStream::got_key_long(const char * keylabel, long & l) +{ + if (last_read_was_key && (key_current.compare(keylabel) == 0)) { + std::istringstream is(value_current); + if (!(is >> l)) { + l = 0; + } + return true; + } else { + return false; + } +} + +bool IniStream::got_key(const char * keylabel) +{ + return (last_read_was_key && (key_current.compare(keylabel) == 0)); +} + +bool IniStream::got_key_angle(const char * keylabel, float & f) +{ + if (last_read_was_key && (key_current.compare(keylabel) == 0)) { + std::istringstream is(value_current); + if ((is >> f)) { + f = math::degrees360f(f); + } else { + f = 0; + } + return true; + } else { + return false; + } +} + +bool IniStream::got_key_color(const char * keylabel, math::Color & color) +{ + if (last_read_was_key && (key_current.compare(keylabel) == 0)) { + std::istringstream is(value_current); + float r, g, b, a; + if ((is >> r) && (is >> g) && (is >> b)) { + if ((r > 1.0f) || (g > 1.0f) || (b > 1.0f)) { + if (is >> a) { + a /= 255.0f; + } + r /= 255.0f; + g /= 255.0f; + b /= 255.0f; + } else { + if (!(is >> a)) { + a = 1.0f; + } + } + color = math::Color(r, g, b, a); + } else { + color = math::Color(); + } + return true; + } else { + return false; + } +} + +bool IniStream::got_key_bool(const char * keylabel, bool & b) +{ + if (last_read_was_key && (key_current.compare(keylabel) == 0)) { + std::istringstream is(value_current); + + unsigned int i; + if (is >> i) { + if (i > 0 ) { + b = true; + } else { + b = false; + } + return true; + } + + std::string val(value_current); + aux::trim(val); + aux::lowercase(val); + + if (val.compare("yes") == 0) { + b = true; + return true; + } else if (val.compare("true") == 0) { + b = true; + return true; + } else if (val.compare("no") == 0) { + b = false; + return true; + } else if (val.compare("false") == 0) { + b = false; + return true; + } + } + + return false; +} + +} // namespace filesystem + -- cgit v1.2.3