1#include "WebFrameworkDynamicPages.h"
6#include "Exceptions/DynamicPagesSyntaxException.h"
7#include "StandardWebFrameworkDynamicPagesFunctions.h"
9#pragma warning(disable: 26800)
13static constexpr string_view argumentsDelimiter =
"</arg>";
17 WebFrameworkDynamicPages::ExecutionUnit::ExecutionUnit(
string&& functionName, vector<string>&& arguments) noexcept :
18 functionName(move(functionName)),
19 arguments(move(arguments))
24 void WebFrameworkDynamicPages::clear(
string& code)
26 code.erase(remove_if(code.begin(), code.end(), [](
const char& c) { return iscntrl(c) || isspace(c); }), code.end());
29 void WebFrameworkDynamicPages::separateArguments(
string& code)
31 bool stringArgument =
false;
33 for (
size_t i = 0; i < code.size(); i++)
38 stringArgument = !stringArgument;
48 code.replace(i, 1, argumentsDelimiter);
58 string WebFrameworkDynamicPages::insertVariables(
const unordered_map<string, string>& variables,
string code)
60 size_t changeVariableStart = code.find(
'$');
62 while (changeVariableStart != string::npos)
64 changeVariableStart++;
66 size_t changeVariableEnd = code.find(
'$', changeVariableStart);
68 if (changeVariableEnd == string::npos)
70 throw exceptions::DynamicPagesSyntaxException(::exceptions::variableDeclarationSyntaxError);
73 const string& variable = variables.at(
string(code.data() + changeVariableStart, changeVariableEnd - changeVariableStart));
75 code.replace(code.begin() + changeVariableStart - 1, code.begin() + changeVariableEnd + 1, variable);
77 changeVariableStart = code.find(
'$');
83 vector<WebFrameworkDynamicPages::ExecutionUnit> WebFrameworkDynamicPages::preExecute(
const string& code)
85 vector<ExecutionUnit> result;
87 size_t endLine = code.find(
';');
89 if (endLine == string::npos)
91 throw exceptions::DynamicPagesSyntaxException(::exceptions::missingSemicolonSyntaxError);
94 result.reserve(count(code.begin(), code.end(),
';'));
96 while (endLine != string::npos)
100 string_view line(code.data() + startLine, endLine - startLine);
101 size_t openBracket = line.find(
'(');
102 string functionName(line.substr(0, openBracket));
107 utility::strings::split(string_view(line.data() + openBracket + 1, line.find(
')') - openBracket - 1), argumentsDelimiter)
111 endLine = code.find(
';', endLine + 1);
117 string WebFrameworkDynamicPages::execute(
const vector<ExecutionUnit>& codes)
121 for (
const auto& [functionName, arguments] : codes)
125 result += dynamicPagesFunctions.at(functionName)(arguments);
127 catch (
const exception& e)
131 Log::error(
"WebFrameworkDynamicPages execute exception: {}",
"LogWebFrameworkDynamicPages", e.what());
141 WebFrameworkDynamicPages::WebFrameworkDynamicPages(
const filesystem::path& pathToTemplates) :
142 pathToTemplates(pathToTemplates)
144 dynamicPagesFunctions.try_emplace(
"print", print);
145 dynamicPagesFunctions.try_emplace(
"include", bind(include, placeholders::_1, pathToTemplates.string()));
146 dynamicPagesFunctions.try_emplace(
"for", bind(forWFDP, placeholders::_1, ref(dynamicPagesFunctions)));
149 void WebFrameworkDynamicPages::run(
const unordered_map<string, string>& variables,
string& source)
151 size_t nextSectionStart = source.find(
"{%");
153 while (nextSectionStart != string::npos)
155 size_t nextSectionEnd = source.find(
"%}", nextSectionStart);
157 if (nextSectionEnd == string::npos)
159 throw exceptions::DynamicPagesSyntaxException(::exceptions::sectionDeclarationSyntaxError);
162 string code(source.begin() + nextSectionStart + 2, source.begin() + nextSectionEnd);
164 WebFrameworkDynamicPages::clear(code);
166 WebFrameworkDynamicPages::separateArguments(code);
168 if (variables.size())
170 code = WebFrameworkDynamicPages::insertVariables(variables, code);
173 source.replace(source.begin() + nextSectionStart, source.begin() + nextSectionEnd + 2, this->execute(WebFrameworkDynamicPages::preExecute(code)));
175 nextSectionStart = source.find(
"{%", nextSectionStart + 1);
178 if (source.find(
"{%") != string::npos)
180 this->run(variables, source);
184 void WebFrameworkDynamicPages::registerDynamicFunction(
const string& functionName, function<
string(
const vector<string>&)>&& function)
186 dynamicPagesFunctions.try_emplace(functionName, move(function));
189 void WebFrameworkDynamicPages::unregisterDynamicFunction(
const string& functionName)
191 dynamicPagesFunctions.erase(functionName);
194 bool WebFrameworkDynamicPages::isDynamicFunctionRegistered(
const string& functionName)
196 return dynamicPagesFunctions.find(functionName) != dynamicPagesFunctions.end();
199 const filesystem::path& WebFrameworkDynamicPages::getPathToTemplates()
const
201 return pathToTemplates;