forked from mirror/openmw-tes3mp
Relocate escape-related code to new files escape.hpp and escape.cpp.
This commit is contained in:
parent
7243583963
commit
20f73f4a32
7 changed files with 342 additions and 312 deletions
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <components/version/version.hpp>
|
#include <components/version/version.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
#include <components/files/escape.hpp>
|
||||||
#include <components/fallback/validate.hpp>
|
#include <components/fallback/validate.hpp>
|
||||||
|
|
||||||
#include <SDL_messagebox.h>
|
#include <SDL_messagebox.h>
|
||||||
|
|
|
@ -93,7 +93,7 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
add_definitions(-DGLOBAL_CONFIG_PATH="${GLOBAL_CONFIG_PATH}")
|
add_definitions(-DGLOBAL_CONFIG_PATH="${GLOBAL_CONFIG_PATH}")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
add_component_dir (files
|
add_component_dir (files
|
||||||
linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager
|
linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager escape
|
||||||
lowlevelfile constrainedfilestream memorystream
|
lowlevelfile constrainedfilestream memorystream
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,8 @@
|
||||||
#define OPENMW_COMPONENTS_FALLBACK_VALIDATE_H
|
#define OPENMW_COMPONENTS_FALLBACK_VALIDATE_H
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
|
||||||
#include <boost/iostreams/filtering_stream.hpp>
|
|
||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/escape.hpp>
|
||||||
#include <components/files/multidircollection.hpp>
|
|
||||||
|
|
||||||
// Parses and validates a fallback map from boost program_options.
|
// 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.
|
// 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<std::string> &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<std::string> &tokens, EscapeStringVector *, int)
|
|
||||||
{
|
|
||||||
if (v.empty())
|
|
||||||
v = boost::any(EscapeStringVector());
|
|
||||||
|
|
||||||
EscapeStringVector * eSV = boost::any_cast<EscapeStringVector>(&v);
|
|
||||||
|
|
||||||
for (std::vector<std::string>::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<EscapePath> & escapePathContainer);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<EscapePath> 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
|
#endif
|
||||||
|
|
|
@ -5,10 +5,13 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <components/files/escape.hpp>
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/algorithm/string/erase.hpp>
|
#include <boost/algorithm/string/erase.hpp>
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
#include <boost/iostreams/filtering_stream.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \namespace Files
|
* \namespace Files
|
||||||
|
@ -164,160 +167,6 @@ bool ConfigurationManager::loadConfig(const boost::filesystem::path& path,
|
||||||
return false;
|
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 <typename Source>
|
|
||||||
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<std::string>(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 <class InputIterator>
|
|
||||||
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<std::string> EscapeStringVector::toStdStringVector() const
|
|
||||||
{
|
|
||||||
std::vector<std::string> temp = std::vector<std::string>();
|
|
||||||
for (std::vector<EscapeHashString>::const_iterator it = mVector.begin(); it != mVector.end(); ++it)
|
|
||||||
{
|
|
||||||
temp.push_back(it->toStdString());
|
|
||||||
}
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getGlobalPath() const
|
const boost::filesystem::path& ConfigurationManager::getGlobalPath() const
|
||||||
{
|
{
|
||||||
return mFixedPath.getGlobalConfigPath();
|
return mFixedPath.getGlobalConfigPath();
|
||||||
|
|
|
@ -2,10 +2,8 @@
|
||||||
#define COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP
|
#define COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <boost/iostreams/filtering_stream.hpp>
|
|
||||||
|
|
||||||
#include <components/files/fixedpath.hpp>
|
#include <components/files/fixedpath.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
|
@ -64,109 +62,6 @@ struct ConfigurationManager
|
||||||
|
|
||||||
bool mSilent;
|
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 <typename Source> int get(Source & src);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::queue<int> mNext;
|
|
||||||
int mPrevious;
|
|
||||||
|
|
||||||
bool mSeenNonWhitespace;
|
|
||||||
bool mFinishLine;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct unescape_hash_filter : public boost::iostreams::input_filter
|
|
||||||
{
|
|
||||||
unescape_hash_filter();
|
|
||||||
virtual ~unescape_hash_filter();
|
|
||||||
|
|
||||||
template <typename Source> int get(Source & src);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool expectingIdentifier;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Source>
|
|
||||||
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 <class InputIterator>
|
|
||||||
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<Files::EscapeHashString> mVector;
|
|
||||||
|
|
||||||
EscapeStringVector();
|
|
||||||
virtual ~EscapeStringVector();
|
|
||||||
|
|
||||||
std::vector<std::string> toStdStringVector() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace Cfg */
|
} /* namespace Cfg */
|
||||||
|
|
||||||
#endif /* COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP */
|
#endif /* COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP */
|
||||||
|
|
140
components/files/escape.cpp
Normal file
140
components/files/escape.cpp
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
#include <escape.hpp>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
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<std::string>(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 <class InputIterator>
|
||||||
|
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<std::string> EscapeStringVector::toStdStringVector() const
|
||||||
|
{
|
||||||
|
std::vector<std::string> temp = std::vector<std::string>();
|
||||||
|
for (std::vector<EscapeHashString>::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<std::string> &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<std::string> &tokens, EscapeStringVector *, int)
|
||||||
|
{
|
||||||
|
if (v.empty())
|
||||||
|
v = boost::any(EscapeStringVector());
|
||||||
|
|
||||||
|
EscapeStringVector * eSV = boost::any_cast<EscapeStringVector>(&v);
|
||||||
|
|
||||||
|
for (std::vector<std::string>::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;
|
||||||
|
}
|
||||||
|
}
|
196
components/files/escape.hpp
Normal file
196
components/files/escape.hpp
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
#ifndef COMPONENTS_FILES_ESCAPE_HPP
|
||||||
|
#define COMPONENTS_FILES_ESCAPE_HPP
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include <components/files/multidircollection.hpp>
|
||||||
|
|
||||||
|
#include <boost/iostreams/filtering_stream.hpp>
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 <typename Source> int get(Source & src);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::queue<int> mNext;
|
||||||
|
int mPrevious;
|
||||||
|
|
||||||
|
bool mSeenNonWhitespace;
|
||||||
|
bool mFinishLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Source>
|
||||||
|
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 <typename Source> int get(Source & src);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool expectingIdentifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Source>
|
||||||
|
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 <class InputIterator>
|
||||||
|
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<Files::EscapeHashString> mVector;
|
||||||
|
|
||||||
|
EscapeStringVector();
|
||||||
|
virtual ~EscapeStringVector();
|
||||||
|
|
||||||
|
std::vector<std::string> toStdStringVector() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
//boost program options validation
|
||||||
|
|
||||||
|
void validate(boost::any &v, const std::vector<std::string> &tokens, Files::EscapeHashString * eHS, int a);
|
||||||
|
|
||||||
|
void validate(boost::any &v, const std::vector<std::string> &tokens, EscapeStringVector *, int);
|
||||||
|
|
||||||
|
struct EscapePath
|
||||||
|
{
|
||||||
|
boost::filesystem::path mPath;
|
||||||
|
|
||||||
|
static PathContainer toPathContainer(const std::vector<EscapePath> & escapePathContainer);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<EscapePath> EscapePathContainer;
|
||||||
|
|
||||||
|
std::istream & operator>> (std::istream & istream, EscapePath & escapePath);
|
||||||
|
} /* namespace Files */
|
||||||
|
#endif /* COMPONENTS_FILES_ESCAPE_HPP */
|
Loading…
Reference in a new issue