/* filesystem/inifile.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/filesystem.h" #include "filesystem/inifile.h" #include namespace filesystem { IniFile::IniFile(const char *ininame) { if (ininame) open(ininame); } IniFile::IniFile(const std::string & ininame) { if (ininame.size()) open(ininame.c_str()); } IniFile::~IniFile() { if (inifile_stream.is_open()) inifile_stream.close(); } bool IniFile::open(std::string const & ininame) { return open(ininame.c_str()); } bool IniFile::open(const char *ininame) { if (!ininame) return false; if (inifile_stream.is_open()) return false; last_read_was_section = false; last_read_was_key = false; key_current = ""; value_current = ""; section_current = ""; line_number = 0; std::string inifile_name("ini/"); inifile_name.append(ininame); inifile_name.append(".ini"); inifile_stream.open(inifile_name); if (!inifile_stream.good()) { con_warn << "Could not open " << inifile_stream.name() << "!\n"; return false; } return true; } bool IniFile::got_section() const { return last_read_was_section; } bool IniFile::got_section(const char * sectionlabel) const { return (last_read_was_section && (section_current.compare(sectionlabel) == 0)); } bool IniFile::in_section(const char * sectionlabel) const { return ((section_current.compare(sectionlabel) == 0)); } bool IniFile::getline() { char line[1024]; last_read_was_section = false; last_read_was_key = false; key_current = ""; value_current = ""; if (!inifile_stream.is_open()) return false; if (inifile_stream.getline(line, 1023)) { std::string s(line); aux::trim(s); line_number++; if (s.size() == 0) { // empty line } else // comment if (s[0] == '#' || s[0] == ';') { // condebug << "IniFile 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 << "IniFile got " << key_current << "=" << value_current << std::endl; return true; } } } return true; } else return false; } bool IniFile::got_key() const { return last_read_was_key; } bool IniFile::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 IniFile::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 IniFile::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 IniFile::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 IniFile::got_key(const char * keylabel) { return (last_read_was_key && (key_current.compare(keylabel) == 0 )); } bool IniFile::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 IniFile::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 IniFile::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) 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; } void IniFile::unknown_value() const { con_warn << name() << " unknown value '" << value() << "' for key '" << key() << "' at line " << line() << std::endl; } void IniFile::unkown_key() const { con_warn << name() << " unknown key '" << key() << "' at line " << line() << std::endl; } void IniFile::unknown_section() const { con_warn << name() << " unknown section '" << section() << "' at line " << line() << std::endl; } void IniFile::close() { inifile_stream.close(); } } // namespace filesystem