/* 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) { // 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_vector2f(const char * keylabel, math::Vector2f & v) { if (last_read_was_key && (key_current.compare(keylabel) == 0)) { std::istringstream is(value_current); float x, y; if ((is >> x) && (is >> y)) { v.assign(x, y); } else { v.clear(); } return true; } else { return false; } } bool IniStream::got_key_vector2f_opt(const char * keylabel, math::Vector2f & v) { if (last_read_was_key && (key_current.compare(keylabel) == 0)) { std::istringstream is(value_current); float x, y; if (is >> x) { if (!(is >> y)) { v.assign(x, x); } else { v.assign(x, y); } } else { v.clear(); } 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.assign(x, y, z); } else { v.clear(); } return true; } else { return false; } } bool IniStream::got_key_vector3f_opt(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) { if (is >> y) { if (!(is >> z)) { z = y; y = ( x + z ) * 0.5f; } } else { y = x; z = x; } v.assign(x, y, z); } else { v.clear(); } 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; } else { a = 1.0f; } r /= 255.0f; g /= 255.0f; b /= 255.0f; } else { if (!(is >> a)) { a = 1.0f; } } color.assign(r, g, b, a); } else { color.assign(1.0f, 1.0f); } 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