Added strf validation
This commit is contained in:
committed by
borgmanJeremy
parent
f54538ee1e
commit
f7e8d34c82
@@ -7,6 +7,7 @@ target_sources(
|
||||
systemnotification.h
|
||||
configshortcuts.h
|
||||
request.h
|
||||
strfparse.h
|
||||
)
|
||||
|
||||
target_sources(
|
||||
@@ -24,5 +25,6 @@ target_sources(
|
||||
colorutils.cpp
|
||||
history.cpp
|
||||
configshortcuts.cpp
|
||||
strfparse.cpp
|
||||
request.cpp
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "filenamehandler.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/strfparse.h"
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <ctime>
|
||||
@@ -41,13 +42,9 @@ QString FileNameHandler::parseFilename(const QString& name)
|
||||
while (res.endsWith('%')) {
|
||||
res.chop(1);
|
||||
}
|
||||
std::time_t t = std::time(NULL);
|
||||
|
||||
char* tempData = QStringToCharArr(res);
|
||||
char data[MAX_CHARACTERS] = { 0 };
|
||||
std::strftime(data, sizeof(data), tempData, std::localtime(&t));
|
||||
res = QString::fromLocal8Bit(data, (int)strlen(data));
|
||||
free(tempData);
|
||||
res =
|
||||
QString::fromStdString(strfparse::format_time_string(name.toStdString()));
|
||||
|
||||
// add the parsed pattern in a correct format for the filesystem
|
||||
res = res.replace(QLatin1String("/"), QStringLiteral("⁄"))
|
||||
|
||||
105
src/utils/strfparse.cpp
Normal file
105
src/utils/strfparse.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "strfparse.h"
|
||||
|
||||
namespace strfparse {
|
||||
std::vector<std::string> split(std::string const& s, char delimiter)
|
||||
{
|
||||
std::vector<std::string> tokens;
|
||||
std::string token;
|
||||
std::istringstream tokenStream(s);
|
||||
while (std::getline(tokenStream, token, delimiter)) {
|
||||
tokens.push_back(token);
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::vector<char> create_specifier_list()
|
||||
{
|
||||
|
||||
std::vector<char> allowed_specifier{ 'Y', 'H', 'a', 'A', 'b', 'B', 'c', 'C',
|
||||
'd', 'D', 'e', 'F', 'g', 'G', 'h', 'H',
|
||||
'I', 'j', 'm', 'M', 'n', 'p', 'r', 'R',
|
||||
'S', 't', 'T', 'u', 'U', 'V', 'w', 'W',
|
||||
'x', 'X', 'y', 'Y', 'z', 'Z' };
|
||||
return allowed_specifier;
|
||||
}
|
||||
|
||||
std::string replace_all(std::string input,
|
||||
std::string const& to_find,
|
||||
std::string const& to_replace)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = input.find(to_find, pos)) != std::string::npos) {
|
||||
input.replace(pos, to_find.length(), to_replace);
|
||||
pos += to_replace.length();
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
std::vector<char> match_specifiers(std::string const& specifier,
|
||||
std::vector<char> allowed_specifier)
|
||||
{
|
||||
|
||||
std::vector<char> spec_list;
|
||||
|
||||
for (uint i = 0; i < specifier.size() - 1; i++) {
|
||||
if (specifier[i] == '%') {
|
||||
spec_list.push_back(specifier[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(spec_list.begin(), spec_list.end());
|
||||
std::sort(allowed_specifier.begin(), allowed_specifier.end());
|
||||
|
||||
std::vector<char> overlap;
|
||||
std::set_intersection(spec_list.begin(),
|
||||
spec_list.end(),
|
||||
allowed_specifier.begin(),
|
||||
allowed_specifier.end(),
|
||||
back_inserter(overlap));
|
||||
|
||||
return overlap;
|
||||
}
|
||||
|
||||
std::string format_time_string(std::string const& specifier)
|
||||
{
|
||||
|
||||
if (specifier.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::time_t t = std::time(nullptr);
|
||||
char buff[100];
|
||||
|
||||
auto allowed_specifier = create_specifier_list();
|
||||
|
||||
auto overlap = match_specifiers(specifier, allowed_specifier);
|
||||
|
||||
// Create "Safe" string for strftime which is the specfiers delimited by *
|
||||
std::string lookup_string;
|
||||
for (auto const& e : overlap) {
|
||||
lookup_string.push_back('%');
|
||||
lookup_string.push_back(e);
|
||||
lookup_string.push_back('*');
|
||||
}
|
||||
|
||||
std::strftime(
|
||||
buff, sizeof(buff), lookup_string.c_str(), std::localtime(&t));
|
||||
|
||||
std::map<char, std::string> lookup_table;
|
||||
auto result = split(buff, '*');
|
||||
|
||||
for (size_t i = 0; i < result.size(); i++) {
|
||||
lookup_table.emplace(std::make_pair(overlap[i], result[i]));
|
||||
}
|
||||
|
||||
// Sub into original string
|
||||
std::string delim = "%";
|
||||
auto output_string = specifier;
|
||||
for (auto const& row : lookup_table) {
|
||||
auto to_find = delim + row.first;
|
||||
output_string = replace_all(output_string, to_find, row.second);
|
||||
}
|
||||
return output_string;
|
||||
}
|
||||
}
|
||||
20
src/utils/strfparse.h
Normal file
20
src/utils/strfparse.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace strfparse {
|
||||
std::vector<std::string> split(std::string const& s, char delimiter);
|
||||
|
||||
std::vector<char> create_specifier_list();
|
||||
|
||||
std::string replace_all(std::string input,
|
||||
std::string const& to_find,
|
||||
std::string const& to_replace);
|
||||
|
||||
std::vector<char> match_specifiers(std::string const& specifier,
|
||||
std::vector<char> allowed_specifier);
|
||||
|
||||
std::string format_time_string(std::string const& specifier);
|
||||
}
|
||||
Reference in New Issue
Block a user