diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 6cc3fbf4e..cfe7fe305 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 6d2436824..f50f30fa6 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -93,7 +93,7 @@ IF(NOT WIN32 AND NOT APPLE) add_definitions(-DGLOBAL_CONFIG_PATH="${GLOBAL_CONFIG_PATH}") ENDIF() add_component_dir (files - linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager + linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager escape lowlevelfile constrainedfilestream memorystream ) diff --git a/components/fallback/validate.hpp b/components/fallback/validate.hpp index 43d51dd5e..a1d3f9601 100644 --- a/components/fallback/validate.hpp +++ b/components/fallback/validate.hpp @@ -2,11 +2,8 @@ #define OPENMW_COMPONENTS_FALLBACK_VALIDATE_H #include -#include -#include -#include -#include +#include // Parses and validates a fallback map from boost program_options. // Note: for boost to pick up the validate function, you need to pull in the namespace e.g. @@ -50,52 +47,4 @@ namespace Fallback } } -namespace Files { - void validate(boost::any &v, const std::vector &tokens, Files::EscapeHashString * eHS, int a) - { - boost::program_options::validators::check_first_occurrence(v); - - if (v.empty()) - v = boost::any(EscapeHashString(boost::program_options::validators::get_single_string(tokens))); - } - - void validate(boost::any &v, const std::vector &tokens, EscapeStringVector *, int) - { - if (v.empty()) - v = boost::any(EscapeStringVector()); - - EscapeStringVector * eSV = boost::any_cast(&v); - - for (std::vector::const_iterator it = tokens.begin(); it != tokens.end(); ++it) - eSV->mVector.push_back(EscapeHashString(*it)); - } - - struct EscapePath { - boost::filesystem::path mPath; - - static PathContainer toPathContainer(const std::vector & escapePathContainer); - }; - - typedef std::vector EscapePathContainer; - - PathContainer EscapePath::toPathContainer(const EscapePathContainer & escapePathContainer) - { - PathContainer temp; - for (EscapePathContainer::const_iterator it = escapePathContainer.begin(); it != escapePathContainer.end(); ++it) - temp.push_back(it->mPath); - return temp; - } - - std::istream & operator>> (std::istream & istream, EscapePath & escapePath) - { - boost::iostreams::filtering_istream filteredStream; - filteredStream.push(unescape_hash_filter()); - filteredStream.push(istream); - - filteredStream >> escapePath.mPath; - - return istream; - } -} - #endif diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index e5313bfee..b53e3834a 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -5,10 +5,13 @@ #include #include +#include + #include #include #include #include +#include /** * \namespace Files @@ -164,160 +167,6 @@ bool ConfigurationManager::loadConfig(const boost::filesystem::path& path, return false; } -const int escape_hash_filter::sEscape = '@'; -const int escape_hash_filter::sEscapeIdentifier = 'a'; -const int escape_hash_filter::sHashIdentifier = 'h'; - -escape_hash_filter::escape_hash_filter() : mNext(), mSeenNonWhitespace(false), mFinishLine(false) -{ -} - -escape_hash_filter::~escape_hash_filter() -{ -} - -template -int escape_hash_filter::get(Source & src) -{ - if (mNext.empty()) - { - int character = boost::iostreams::get(src); - bool record = true; - if (character == boost::iostreams::WOULD_BLOCK) - { - mNext.push(character); - record = false; - } - else if (character == EOF) - { - mSeenNonWhitespace = false; - mFinishLine = false; - mNext.push(character); - } - else if (character == '\n') - { - mSeenNonWhitespace = false; - mFinishLine = false; - mNext.push(character); - } - else if (mFinishLine) - { - mNext.push(character); - } - else if (character == '#') - { - if (mSeenNonWhitespace) - { - mNext.push(sEscape); - mNext.push(sHashIdentifier); - } - else - { - //it's fine being interpreted by Boost as a comment, and so is anything afterwards - mNext.push(character); - mFinishLine = true; - } - } - else if (mPrevious == sEscape) - { - mNext.push(sEscape); - mNext.push(sEscapeIdentifier); - } - else - { - mNext.push(character); - } - if (!mSeenNonWhitespace && !isspace(character)) - mSeenNonWhitespace = true; - if (record) - mPrevious = character; - } - int retval = mNext.front(); - mNext.pop(); - return retval; -} - -unescape_hash_filter::unescape_hash_filter() : expectingIdentifier(false) -{ -} - -unescape_hash_filter::~unescape_hash_filter() -{ -} - -std::string EscapeHashString::processString(const std::string & str) -{ - std::string temp = boost::replace_all_copy(str, std::string() + (char)escape_hash_filter::sEscape + (char)escape_hash_filter::sHashIdentifier, "#"); - boost::replace_all(temp, std::string() + (char)escape_hash_filter::sEscape + (char)escape_hash_filter::sEscapeIdentifier, std::string((char) escape_hash_filter::sEscape, 1)); - return temp; -} - -EscapeHashString::EscapeHashString() : mData() -{ -} - -EscapeHashString::EscapeHashString(const std::string & str) : mData(EscapeHashString::processString(str)) -{ -} - -EscapeHashString::EscapeHashString(const std::string & str, size_t pos, size_t len) : mData(EscapeHashString::processString(str), pos, len) -{ -} - -EscapeHashString::EscapeHashString(const char * s) : mData(EscapeHashString::processString(std::string(s))) -{ -} - -EscapeHashString::EscapeHashString(const char * s, size_t n) : mData(EscapeHashString::processString(std::string(s)), 0, n) -{ -} - -EscapeHashString::EscapeHashString(size_t n, char c) : mData(n, c) -{ -} - -template -EscapeHashString::EscapeHashString(InputIterator first, InputIterator last) : mData(EscapeHashString::processString(std::string(first, last))) -{ -} - -std::string EscapeHashString::toStdString() const -{ - return std::string(mData); -} - -std::istream & operator>> (std::istream & is, EscapeHashString & eHS) -{ - std::string temp; - is >> temp; - eHS = EscapeHashString(temp); - return is; -} - -std::ostream & operator<< (std::ostream & os, const EscapeHashString & eHS) -{ - os << eHS.mData; - return os; -} - -EscapeStringVector::EscapeStringVector() : mVector() -{ -} - -EscapeStringVector::~EscapeStringVector() -{ -} - -std::vector EscapeStringVector::toStdStringVector() const -{ - std::vector temp = std::vector(); - for (std::vector::const_iterator it = mVector.begin(); it != mVector.end(); ++it) - { - temp.push_back(it->toStdString()); - } - return temp; -} - const boost::filesystem::path& ConfigurationManager::getGlobalPath() const { return mFixedPath.getGlobalConfigPath(); diff --git a/components/files/configurationmanager.hpp b/components/files/configurationmanager.hpp index 494dfdd0c..df131e671 100644 --- a/components/files/configurationmanager.hpp +++ b/components/files/configurationmanager.hpp @@ -2,10 +2,8 @@ #define COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP #include -#include #include -#include #include #include @@ -64,109 +62,6 @@ struct ConfigurationManager bool mSilent; }; - - -/** - * \struct escape_hash_filter - */ -struct escape_hash_filter : public boost::iostreams::input_filter -{ - static const int sEscape; - static const int sHashIdentifier; - static const int sEscapeIdentifier; - - escape_hash_filter(); - virtual ~escape_hash_filter(); - - template int get(Source & src); - - private: - std::queue mNext; - int mPrevious; - - bool mSeenNonWhitespace; - bool mFinishLine; -}; - -struct unescape_hash_filter : public boost::iostreams::input_filter -{ - unescape_hash_filter(); - virtual ~unescape_hash_filter(); - - template int get(Source & src); - - private: - bool expectingIdentifier; -}; - -template -int unescape_hash_filter::get(Source & src) -{ - int character; - if (!expectingIdentifier) - character = boost::iostreams::get(src); - else - { - character = escape_hash_filter::sEscape; - expectingIdentifier = false; - } - if (character == escape_hash_filter::sEscape) - { - int nextChar = boost::iostreams::get(src); - int intended; - if (nextChar == escape_hash_filter::sEscapeIdentifier) - intended = escape_hash_filter::sEscape; - else if (nextChar == escape_hash_filter::sHashIdentifier) - intended = '#'; - else if (nextChar == boost::iostreams::WOULD_BLOCK) - { - expectingIdentifier = true; - intended = nextChar; - } - else - intended = '?'; - return intended; - } - else - return character; -} - -/** - * \class EscapeHashString - */ -class EscapeHashString -{ - private: - std::string mData; - public: - static std::string processString(const std::string & str); - - EscapeHashString(); - EscapeHashString(const std::string & str); - EscapeHashString(const std::string & str, size_t pos, size_t len = std::string::npos); - EscapeHashString(const char * s); - EscapeHashString(const char * s, size_t n); - EscapeHashString(size_t n, char c); - template - EscapeHashString(InputIterator first, InputIterator last); - - std::string toStdString() const; - - friend std::ostream & operator<< (std::ostream & os, const EscapeHashString & eHS); -}; - -std::istream & operator>> (std::istream & is, EscapeHashString & eHS); - -struct EscapeStringVector -{ - std::vector mVector; - - EscapeStringVector(); - virtual ~EscapeStringVector(); - - std::vector toStdStringVector() const; -}; - } /* namespace Cfg */ #endif /* COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP */ diff --git a/components/files/escape.cpp b/components/files/escape.cpp new file mode 100644 index 000000000..78365288a --- /dev/null +++ b/components/files/escape.cpp @@ -0,0 +1,140 @@ +#include + +#include +#include + +namespace Files +{ + const int escape_hash_filter::sEscape = '@'; + const int escape_hash_filter::sEscapeIdentifier = 'a'; + const int escape_hash_filter::sHashIdentifier = 'h'; + + escape_hash_filter::escape_hash_filter() : mNext(), mSeenNonWhitespace(false), mFinishLine(false) + { + } + + escape_hash_filter::~escape_hash_filter() + { + } + + unescape_hash_filter::unescape_hash_filter() : expectingIdentifier(false) + { + } + + unescape_hash_filter::~unescape_hash_filter() + { + } + + std::string EscapeHashString::processString(const std::string & str) + { + std::string temp = boost::replace_all_copy(str, std::string() + (char)escape_hash_filter::sEscape + (char)escape_hash_filter::sHashIdentifier, "#"); + boost::replace_all(temp, std::string() + (char)escape_hash_filter::sEscape + (char)escape_hash_filter::sEscapeIdentifier, std::string((char)escape_hash_filter::sEscape, 1)); + return temp; + } + + EscapeHashString::EscapeHashString() : mData() + { + } + + EscapeHashString::EscapeHashString(const std::string & str) : mData(EscapeHashString::processString(str)) + { + } + + EscapeHashString::EscapeHashString(const std::string & str, size_t pos, size_t len) : mData(EscapeHashString::processString(str), pos, len) + { + } + + EscapeHashString::EscapeHashString(const char * s) : mData(EscapeHashString::processString(std::string(s))) + { + } + + EscapeHashString::EscapeHashString(const char * s, size_t n) : mData(EscapeHashString::processString(std::string(s)), 0, n) + { + } + + EscapeHashString::EscapeHashString(size_t n, char c) : mData(n, c) + { + } + + template + EscapeHashString::EscapeHashString(InputIterator first, InputIterator last) : mData(EscapeHashString::processString(std::string(first, last))) + { + } + + std::string EscapeHashString::toStdString() const + { + return std::string(mData); + } + + std::istream & operator>> (std::istream & is, EscapeHashString & eHS) + { + std::string temp; + is >> temp; + eHS = EscapeHashString(temp); + return is; + } + + std::ostream & operator<< (std::ostream & os, const EscapeHashString & eHS) + { + os << eHS.mData; + return os; + } + + EscapeStringVector::EscapeStringVector() : mVector() + { + } + + EscapeStringVector::~EscapeStringVector() + { + } + + std::vector EscapeStringVector::toStdStringVector() const + { + std::vector temp = std::vector(); + for (std::vector::const_iterator it = mVector.begin(); it != mVector.end(); ++it) + { + temp.push_back(it->toStdString()); + } + return temp; + } + + // boost program options validation + + void validate(boost::any &v, const std::vector &tokens, Files::EscapeHashString * eHS, int a) + { + boost::program_options::validators::check_first_occurrence(v); + + if (v.empty()) + v = boost::any(EscapeHashString(boost::program_options::validators::get_single_string(tokens))); + } + + void validate(boost::any &v, const std::vector &tokens, EscapeStringVector *, int) + { + if (v.empty()) + v = boost::any(EscapeStringVector()); + + EscapeStringVector * eSV = boost::any_cast(&v); + + for (std::vector::const_iterator it = tokens.begin(); it != tokens.end(); ++it) + eSV->mVector.push_back(EscapeHashString(*it)); + } + + PathContainer EscapePath::toPathContainer(const EscapePathContainer & escapePathContainer) + { + PathContainer temp; + for (EscapePathContainer::const_iterator it = escapePathContainer.begin(); it != escapePathContainer.end(); ++it) + temp.push_back(it->mPath); + return temp; + } + + std::istream & operator>> (std::istream & istream, EscapePath & escapePath) + { + boost::iostreams::filtering_istream filteredStream; + filteredStream.push(unescape_hash_filter()); + filteredStream.push(istream); + + filteredStream >> escapePath.mPath; + + return istream; + } +} \ No newline at end of file diff --git a/components/files/escape.hpp b/components/files/escape.hpp new file mode 100644 index 000000000..3b016a12d --- /dev/null +++ b/components/files/escape.hpp @@ -0,0 +1,196 @@ +#ifndef COMPONENTS_FILES_ESCAPE_HPP +#define COMPONENTS_FILES_ESCAPE_HPP + +#include + +#include + +#include +#include +#include + +/** + * \namespace Files + */ +namespace Files +{ + /** + * \struct escape_hash_filter + */ + struct escape_hash_filter : public boost::iostreams::input_filter + { + static const int sEscape; + static const int sHashIdentifier; + static const int sEscapeIdentifier; + + escape_hash_filter(); + virtual ~escape_hash_filter(); + + template int get(Source & src); + + private: + std::queue mNext; + int mPrevious; + + bool mSeenNonWhitespace; + bool mFinishLine; + }; + + template + int escape_hash_filter::get(Source & src) + { + if (mNext.empty()) + { + int character = boost::iostreams::get(src); + bool record = true; + if (character == boost::iostreams::WOULD_BLOCK) + { + mNext.push(character); + record = false; + } + else if (character == EOF) + { + mSeenNonWhitespace = false; + mFinishLine = false; + mNext.push(character); + } + else if (character == '\n') + { + mSeenNonWhitespace = false; + mFinishLine = false; + mNext.push(character); + } + else if (mFinishLine) + { + mNext.push(character); + } + else if (character == '#') + { + if (mSeenNonWhitespace) + { + mNext.push(sEscape); + mNext.push(sHashIdentifier); + } + else + { + //it's fine being interpreted by Boost as a comment, and so is anything afterwards + mNext.push(character); + mFinishLine = true; + } + } + else if (mPrevious == sEscape) + { + mNext.push(sEscape); + mNext.push(sEscapeIdentifier); + } + else + { + mNext.push(character); + } + if (!mSeenNonWhitespace && !isspace(character)) + mSeenNonWhitespace = true; + if (record) + mPrevious = character; + } + int retval = mNext.front(); + mNext.pop(); + return retval; + } + + struct unescape_hash_filter : public boost::iostreams::input_filter + { + unescape_hash_filter(); + virtual ~unescape_hash_filter(); + + template int get(Source & src); + + private: + bool expectingIdentifier; + }; + + template + int unescape_hash_filter::get(Source & src) + { + int character; + if (!expectingIdentifier) + character = boost::iostreams::get(src); + else + { + character = escape_hash_filter::sEscape; + expectingIdentifier = false; + } + if (character == escape_hash_filter::sEscape) + { + int nextChar = boost::iostreams::get(src); + int intended; + if (nextChar == escape_hash_filter::sEscapeIdentifier) + intended = escape_hash_filter::sEscape; + else if (nextChar == escape_hash_filter::sHashIdentifier) + intended = '#'; + else if (nextChar == boost::iostreams::WOULD_BLOCK) + { + expectingIdentifier = true; + intended = nextChar; + } + else + intended = '?'; + return intended; + } + else + return character; + } + + /** + * \class EscapeHashString + */ + class EscapeHashString + { + private: + std::string mData; + public: + static std::string processString(const std::string & str); + + EscapeHashString(); + EscapeHashString(const std::string & str); + EscapeHashString(const std::string & str, size_t pos, size_t len = std::string::npos); + EscapeHashString(const char * s); + EscapeHashString(const char * s, size_t n); + EscapeHashString(size_t n, char c); + template + EscapeHashString(InputIterator first, InputIterator last); + + std::string toStdString() const; + + friend std::ostream & operator<< (std::ostream & os, const EscapeHashString & eHS); + }; + + std::istream & operator>> (std::istream & is, EscapeHashString & eHS); + + struct EscapeStringVector + { + std::vector mVector; + + EscapeStringVector(); + virtual ~EscapeStringVector(); + + std::vector toStdStringVector() const; + }; + + //boost program options validation + + void validate(boost::any &v, const std::vector &tokens, Files::EscapeHashString * eHS, int a); + + void validate(boost::any &v, const std::vector &tokens, EscapeStringVector *, int); + + struct EscapePath + { + boost::filesystem::path mPath; + + static PathContainer toPathContainer(const std::vector & escapePathContainer); + }; + + typedef std::vector EscapePathContainer; + + std::istream & operator>> (std::istream & istream, EscapePath & escapePath); +} /* namespace Files */ +#endif /* COMPONENTS_FILES_ESCAPE_HPP */ \ No newline at end of file