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/Makefile.am | 6 +- src/filesystem/inifile.cc | 232 +------------------------------------- src/filesystem/inifile.h | 72 +----------- src/filesystem/inistream.cc | 269 ++++++++++++++++++++++++++++++++++++++++++++ src/filesystem/inistream.h | 103 +++++++++++++++++ 5 files changed, 382 insertions(+), 300 deletions(-) create mode 100644 src/filesystem/inistream.cc create mode 100644 src/filesystem/inistream.h (limited to 'src/filesystem') diff --git a/src/filesystem/Makefile.am b/src/filesystem/Makefile.am index 05c1a3f..ed2e6bf 100644 --- a/src/filesystem/Makefile.am +++ b/src/filesystem/Makefile.am @@ -7,14 +7,16 @@ noinst_HEADERS = \ file.h \ filestream.h \ filesystem.h \ - inifile.h + inifile.h \ + inistream.h libfilesystem_la_SOURCES = \ diskfile.cc \ file.cc \ filestream.cc \ filesystem.cc \ - inifile.cc + inifile.cc \ + inistream.cc libfilesystem_la_LDFLAGS = -avoid-version -no-undefined diff --git a/src/filesystem/inifile.cc b/src/filesystem/inifile.cc index 5f87591..b0cab02 100644 --- a/src/filesystem/inifile.cc +++ b/src/filesystem/inifile.cc @@ -46,12 +46,7 @@ bool IniFile::open(const char *ininame) 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; + clear(); std::string inifile_name(ininame); inifile_name.append(".ini"); @@ -65,232 +60,9 @@ bool IniFile::open(const char *ininame) } -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 - // 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 << "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_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 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; + return IniStream::getline(inifile_stream); } void IniFile::unknown_value() const diff --git a/src/filesystem/inifile.h b/src/filesystem/inifile.h index 660a981..701b435 100644 --- a/src/filesystem/inifile.h +++ b/src/filesystem/inifile.h @@ -1,5 +1,5 @@ /* - common/inifile.h + filesystem/inifile.h This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ @@ -13,16 +13,13 @@ #include "math/vector3f.h" #include "math/color.h" #include "filesystem/filestream.h" +#include "filesystem/inistream.h" namespace filesystem { -/// a class to read .ini files -/** The IniFile class provides functions to read .ini files. A .ini file - * consists of one or more [section] headers followed by one or more key=value - * pairs. Lines starting with # or ; are considered comments - */ -class IniFile +/// wrapper class for the IniStream reader +class IniFile : public IniStream { public: IniFile(const char *ininame = 0); @@ -40,58 +37,6 @@ public: /// parse one line, returns false on end-of-file bool getline(); - /// current section label - inline std::string section() const { - return section_current; - } - - /// current key - inline std::string key() const { - return key_current; - } - - /// current value - inline std::string value() const { - return value_current; - } - - /// true if the last read statement was a section header - bool got_section() const; - - /// true if the current section matches - bool in_section(const char *sectionlabel) const; - - /// true if the last read statement was a certain section header - bool got_section(const char * sectionlabel) const; - - /// true if the last read statement was a key=value pair - bool got_key() const; - - bool got_key(const char * keylabel); - - /// check if the last read key=value pair matches keylabel and store the value in valuestring - bool got_key_string(const char * keylabel, std::string & valuestring); - - /// check if the last read key=value pair matches keylabel and store the value in valuestring, converted to label - bool got_key_label(const char * keylabel, std::string & labelstring); - - bool got_key_color(const char * keylabel, math::Color & color); - - bool got_key_float(const char * keylabel, float & f); - - bool got_key_angle(const char * keylabel, float & f); - - bool got_key_long(const char * keylabel, long & l); - - bool got_key_vector3f(const char * keylabel, math::Vector3f & v); - - bool got_key_bool(const char * keylabel, bool & b); - - - inline unsigned int line() const { - return line_number; - } - /// print a default unkown value error void unknown_value() const; @@ -130,15 +75,6 @@ public: void close(); private: - std::string section_current; - std::string key_current; - std::string value_current; - - bool last_read_was_key; - bool last_read_was_section; - - unsigned int line_number; - IFileStream inifile_stream; }; 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 + diff --git a/src/filesystem/inistream.h b/src/filesystem/inistream.h new file mode 100644 index 0000000..7c99120 --- /dev/null +++ b/src/filesystem/inistream.h @@ -0,0 +1,103 @@ +/* + filesystem/inistream.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_FILESTREAM_INIFILE_H__ +#define __INCLUDED_FILESTREAM_INIFILE_H__ + +#include +#include + +#include "math/vector3f.h" +#include "math/color.h" +#include "filesystem/filestream.h" + +namespace filesystem +{ + +/// a class to read ini streams +/** + * The IniStream class is able to decode the structure of a windows-like + * .ini file from a text stream. + **/ +class IniStream +{ +public: + IniStream(); + + ~IniStream(); + + /// parse one line, returns false on end-of-file + bool getline(std::istream & istream); + + /// current section label + inline std::string section() const { + return section_current; + } + + /// current key + inline std::string key() const { + return key_current; + } + + /// current value + inline std::string value() const { + return value_current; + } + + /// current line number + inline unsigned int line() const { + return line_number; + } + + /// true if the last read statement was a section header + bool got_section() const; + + /// true if the current section matches + bool in_section(const char *sectionlabel) const; + + /// true if the last read statement was a certain section header + bool got_section(const char * sectionlabel) const; + + /// true if the last read statement was a key=value pair + bool got_key() const; + + bool got_key(const char * keylabel); + + /// check if the last read key=value pair matches keylabel and store the value in valuestring + bool got_key_string(const char * keylabel, std::string & valuestring); + + /// check if the last read key=value pair matches keylabel and store the value in valuestring, converted to label + bool got_key_label(const char * keylabel, std::string & labelstring); + + bool got_key_color(const char * keylabel, math::Color & color); + + bool got_key_float(const char * keylabel, float & f); + + bool got_key_angle(const char * keylabel, float & f); + + bool got_key_long(const char * keylabel, long & l); + + bool got_key_vector3f(const char * keylabel, math::Vector3f & v); + + bool got_key_bool(const char * keylabel, bool & b); + +protected: + void clear(); + +private: + std::string section_current; + std::string key_current; + std::string value_current; + + bool last_read_was_key; + bool last_read_was_section; + + unsigned int line_number; +}; + +} + +#endif // __INCLUDED_FILESYSTEM_INISTREAM_H__ -- cgit v1.2.3