Relocate escape-related code to new files escape.hpp and escape.cpp.

coverity_scan^2
AnyOldName3 9 years ago
parent 7243583963
commit 20f73f4a32

@ -3,6 +3,7 @@
#include <components/version/version.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/files/escape.hpp>
#include <components/fallback/validate.hpp>
#include <SDL_messagebox.h>

@ -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
)

@ -2,11 +2,8 @@
#define OPENMW_COMPONENTS_FALLBACK_VALIDATE_H
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/files/multidircollection.hpp>
#include <components/files/escape.hpp>
// 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<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

@ -5,10 +5,13 @@
#include <algorithm>
#include <ctype.h>
#include <components/files/escape.hpp>
#include <boost/bind.hpp>
#include <boost/algorithm/string/erase.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/iostreams/filtering_stream.hpp>
/**
* \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 <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
{
return mFixedPath.getGlobalConfigPath();

@ -2,10 +2,8 @@
#define COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP
#include <map>
#include <queue>
#include <boost/program_options.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <components/files/fixedpath.hpp>
#include <components/files/collections.hpp>
@ -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 <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 */
#endif /* COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP */

@ -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;
}
}

@ -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…
Cancel
Save