Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2011-07-10 19:29:57 +0000
committerStijn Buys <ingar@osirion.org>2011-07-10 19:29:57 +0000
commitaf5404ea593d460d3ae843a23b295e3cfeade5bc (patch)
tree71b52f1700c82e970e6b49d786612825cc714887 /src/filesystem
parent5b9baa97e65314454005edb1231e18cf0f5bfb43 (diff)
Split the ini file reader into a stream decoder and a file wrapper.
Diffstat (limited to 'src/filesystem')
-rw-r--r--src/filesystem/Makefile.am6
-rw-r--r--src/filesystem/inifile.cc232
-rw-r--r--src/filesystem/inifile.h72
-rw-r--r--src/filesystem/inistream.cc269
-rw-r--r--src/filesystem/inistream.h103
5 files changed, 382 insertions, 300 deletions
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 <sstream>
+
+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 <string>
+#include <fstream>
+
+#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__