Formatted code and added .clang-format, small refactors
This commit is contained in:
144
.clang-format
Normal file
144
.clang-format
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: false
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveBitFields: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
Standard: Latest
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 8
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- STRINGIZE
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
...
|
||||||
|
|
2
Makefile
2
Makefile
@@ -1,5 +1,5 @@
|
|||||||
INCLUDES = -Isrc/
|
INCLUDES = -Isrc/
|
||||||
CXXFLAGS_debug = -Wall -DDEBUG -g -rdynamic
|
CXXFLAGS_debug = -Wall -DDEBUG -g -rdynamic -std=c++2a $(INCLUDES)
|
||||||
CXXFLAGS_release = -Wall -fvisibility=hidden -fvisibility-inlines-hidden -std=c++2a -march=x86-64 -mtune=generic -O3 -pipe -fno-plt $(INCLUDES)
|
CXXFLAGS_release = -Wall -fvisibility=hidden -fvisibility-inlines-hidden -std=c++2a -march=x86-64 -mtune=generic -O3 -pipe -fno-plt $(INCLUDES)
|
||||||
SRCS = src/curl.hpp \
|
SRCS = src/curl.hpp \
|
||||||
src/mpvopts.hpp \
|
src/mpvopts.hpp \
|
||||||
|
34
src/ipc.hpp
34
src/ipc.hpp
@@ -1,11 +1,12 @@
|
|||||||
#ifndef MPVIPC_HPP_
|
#ifndef OIM_IPC_HPP_
|
||||||
#define MPVIPC_HPP_
|
#define OIM_IPC_HPP_
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <unistd.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
const char *DEFAULT_SOCK = "/tmp/mpvsocket";
|
const char *DEFAULT_SOCK = "/tmp/mpvsocket";
|
||||||
@@ -14,13 +15,14 @@ namespace oim {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The class oim::ipc provides easy communication and basic socket management
|
* The class oim::ipc provides easy communication and basic socket management
|
||||||
* for any running mpv instance configured to receive commands over a JSON-IPC server/socket.
|
* for any running mpv instance configured to receive commands over a JSON-IPC
|
||||||
|
* server/socket.
|
||||||
*/
|
*/
|
||||||
class ipc {
|
class ipc {
|
||||||
private:
|
private:
|
||||||
sockaddr_un sockaddress;
|
sockaddr_un sockaddress_;
|
||||||
int sockfd;
|
int sockfd_;
|
||||||
int socklen;
|
int socklen_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ipc() : ipc(DEFAULT_SOCK){};
|
ipc() : ipc(DEFAULT_SOCK){};
|
||||||
@@ -34,28 +36,26 @@ public:
|
|||||||
* Constructor for oim::ipc
|
* Constructor for oim::ipc
|
||||||
*/
|
*/
|
||||||
ipc::ipc(const char *sockpath) {
|
ipc::ipc(const char *sockpath) {
|
||||||
this->sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
sockfd_ = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
this->sockaddress.sun_family = AF_UNIX;
|
sockaddress_.sun_family = AF_UNIX;
|
||||||
std::strcpy(this->sockaddress.sun_path, sockpath);
|
std::strcpy(sockaddress_.sun_path, sockpath);
|
||||||
this->socklen = sizeof(this->sockaddress);
|
socklen_ = sizeof(sockaddress_);
|
||||||
|
|
||||||
connect(this->sockfd, (const sockaddr*)&this->sockaddress, this->socklen);
|
connect(sockfd_, (const sockaddr *)&sockaddress_, socklen_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destructor for oim::ipc
|
* Destructor for oim::ipc
|
||||||
*/
|
*/
|
||||||
ipc::~ipc() {
|
ipc::~ipc() { close(sockfd_); }
|
||||||
close(this->sockfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sends a raw command string to the internal socket at DEFAULT_SOCK
|
* Sends a raw command string to the internal socket at DEFAULT_SOCK
|
||||||
*/
|
*/
|
||||||
bool ipc::send(string cmd) {
|
bool ipc::send(string cmd) {
|
||||||
return write(this->sockfd, cmd.c_str(), cmd.length()) != -1;
|
return write(sockfd_, cmd.c_str(), cmd.length()) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace name
|
} // namespace oim
|
||||||
|
|
||||||
#endif
|
#endif
|
20
src/main.cpp
20
src/main.cpp
@@ -1,5 +1,5 @@
|
|||||||
#include "options.hpp"
|
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
#include "options.hpp"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -10,8 +10,8 @@ using std::string;
|
|||||||
|
|
||||||
const char *help[2] = {
|
const char *help[2] = {
|
||||||
"This program is not supposed to be called from the command line!",
|
"This program is not supposed to be called from the command line!",
|
||||||
"Call with 'install-protocol' to instal the xdg-compatible protocol file in ~/.local/share/applications/"
|
"Call with 'install-protocol' to instal the xdg-compatible protocol file "
|
||||||
};
|
"in ~/.local/share/applications/"};
|
||||||
|
|
||||||
bool install_protocol() {
|
bool install_protocol() {
|
||||||
const char *protocol_file = R"([Desktop Entry]
|
const char *protocol_file = R"([Desktop Entry]
|
||||||
@@ -24,9 +24,11 @@ MimeType=x-scheme-handler/mpv
|
|||||||
)";
|
)";
|
||||||
|
|
||||||
const char *homedir = std::getenv("HOME");
|
const char *homedir = std::getenv("HOME");
|
||||||
if (!homedir) return false;
|
if (!homedir)
|
||||||
|
return false;
|
||||||
|
|
||||||
std::ofstream protfile(string(homedir) + "/.local/share/applications/open-in-mpv.desktop");
|
std::ofstream protfile(string(homedir) +
|
||||||
|
"/.local/share/applications/open-in-mpv.desktop");
|
||||||
protfile << protocol_file;
|
protfile << protocol_file;
|
||||||
protfile.flush();
|
protfile.flush();
|
||||||
protfile.close();
|
protfile.close();
|
||||||
@@ -40,9 +42,8 @@ int main(int argc, char const *argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (string(argv[1]) == "install-protocol") {
|
if (string(argv[1]) == "install-protocol")
|
||||||
return install_protocol();
|
return install_protocol() ? 0 : 1;
|
||||||
}
|
|
||||||
|
|
||||||
oim::options *mo = new oim::options();
|
oim::options *mo = new oim::options();
|
||||||
try {
|
try {
|
||||||
@@ -59,7 +60,8 @@ int main(int argc, char const *argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Error writing to socket, opening new instance" << std::endl;
|
std::cout << "Error writing to socket, opening new instance"
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
std::system(mo->build_cmd().c_str());
|
std::system(mo->build_cmd().c_str());
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#ifndef MPVOPTS_HPP_
|
#ifndef OIM_OPTS_HPP_
|
||||||
#define MPVOPTS_HPP_
|
#define OIM_OPTS_HPP_
|
||||||
|
|
||||||
#include "url.hpp"
|
#include "url.hpp"
|
||||||
|
|
||||||
@@ -18,13 +18,13 @@ namespace oim {
|
|||||||
*/
|
*/
|
||||||
class options {
|
class options {
|
||||||
private:
|
private:
|
||||||
string url;
|
string url_;
|
||||||
string flags;
|
string flags_;
|
||||||
string player;
|
string player_;
|
||||||
bool fullscreen;
|
bool fullscreen_;
|
||||||
bool pip;
|
bool pip_;
|
||||||
bool enqueue;
|
bool enqueue_;
|
||||||
bool new_window;
|
bool new_window_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
options();
|
options();
|
||||||
@@ -40,12 +40,12 @@ public:
|
|||||||
* Constructor for oim::options
|
* Constructor for oim::options
|
||||||
*/
|
*/
|
||||||
options::options() {
|
options::options() {
|
||||||
this->url = "";
|
url_ = "";
|
||||||
this->flags = "";
|
flags_ = "";
|
||||||
this->player = "mpv";
|
player_ = "mpv";
|
||||||
this->fullscreen = false;
|
fullscreen_ = false;
|
||||||
this->pip = false;
|
pip_ = false;
|
||||||
this->enqueue = false;
|
enqueue_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -57,14 +57,16 @@ string options::build_cmd() {
|
|||||||
// TODO: some of these options work only in mpv and not other players
|
// TODO: some of these options work only in mpv and not other players
|
||||||
// This can be solved by adding a list of some sorts (json/toml/whatever)
|
// This can be solved by adding a list of some sorts (json/toml/whatever)
|
||||||
// containing the flags to use for each functionality and each player
|
// containing the flags to use for each functionality and each player
|
||||||
ret << this->player << " ";
|
ret << player_ << " ";
|
||||||
if (this->fullscreen) ret << "--fs ";
|
if (fullscreen_)
|
||||||
if (this->pip) ret << "--ontop --no-border --autofit=384x216 --geometry=98\%:98\% ";
|
ret << "--fs ";
|
||||||
if (!this->flags.empty())
|
if (pip_)
|
||||||
ret << this->flags << " ";
|
ret << "--ontop --no-border --autofit=384x216 --geometry=98\%:98\% ";
|
||||||
// NOTE: this is not needed for mpv (it always opens a new window), maybe for other players?
|
if (!flags_.empty())
|
||||||
// if (this->new_window) ret << "--new-window";
|
ret << flags_ << " ";
|
||||||
ret << this->url;
|
// NOTE: this is not needed for mpv (it always opens a new window), maybe
|
||||||
|
// for other players? if (this->new_window_) ret << "--new-window";
|
||||||
|
ret << url_;
|
||||||
|
|
||||||
return ret.str();
|
return ret.str();
|
||||||
}
|
}
|
||||||
@@ -75,20 +77,20 @@ string options::build_cmd() {
|
|||||||
string options::build_ipc() {
|
string options::build_ipc() {
|
||||||
std::ostringstream ret;
|
std::ostringstream ret;
|
||||||
|
|
||||||
if (!this->needs_ipc()) return "";
|
if (!needs_ipc())
|
||||||
|
return "";
|
||||||
|
|
||||||
// TODO: in the future this may need a more serious json serializer for
|
// In the future this may need a more serious json serializer for
|
||||||
// more complicated commands
|
// more complicated commands
|
||||||
// Syntax: {"command": ["loadfile", "%s", "append-play"]}\n
|
// Syntax: {"command": ["loadfile", "%s", "append-play"]}\n
|
||||||
ret << R"({"command": ["loadfile", ")"
|
ret << R"({"command": ["loadfile", ")" << url_ << R"(", "append-play"]})"
|
||||||
<< this->url
|
<< std::endl;
|
||||||
<< R"(", "append-play"]})" << std::endl;
|
|
||||||
|
|
||||||
return ret.str();
|
return ret.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a URL and populate the current MpvOptions (uses libcurl for parsing)
|
* Parse a URL and populate the current oim::options
|
||||||
*/
|
*/
|
||||||
void options::parse(const char *url_s) {
|
void options::parse(const char *url_s) {
|
||||||
oim::url u(url_s);
|
oim::url u(url_s);
|
||||||
@@ -102,13 +104,14 @@ void options::parse(const char *url_s) {
|
|||||||
if (u.query().empty())
|
if (u.query().empty())
|
||||||
throw string("Empty query");
|
throw string("Empty query");
|
||||||
|
|
||||||
this->url = oim::url_decode(u.query_value("url"));
|
url_ = oim::url_decode(u.query_value("url"));
|
||||||
this->flags = oim::url_decode(u.query_value("flags"));
|
flags_ = oim::url_decode(u.query_value("flags"));
|
||||||
this->player = u.query_value("player", "mpv");
|
player_ = u.query_value("player", "mpv");
|
||||||
this->fullscreen = u.query_value("fullscreen") == "1";
|
|
||||||
this->pip = u.query_value("pip") == "1";
|
fullscreen_ = u.query_value("fullscreen") == "1";
|
||||||
this->enqueue = u.query_value("enqueue") == "1";
|
pip_ = u.query_value("pip") == "1";
|
||||||
this->new_window = u.query_value("new_window") == "1";
|
enqueue_ = u.query_value("enqueue") == "1";
|
||||||
|
new_window_ = u.query_value("new_window") == "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -117,7 +120,7 @@ void options::parse(const char *url_s) {
|
|||||||
*/
|
*/
|
||||||
bool options::needs_ipc() {
|
bool options::needs_ipc() {
|
||||||
// For now this is needed only when queuing videos
|
// For now this is needed only when queuing videos
|
||||||
return this->enqueue;
|
return enqueue_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace oim
|
} // namespace oim
|
||||||
|
33
src/url.hpp
33
src/url.hpp
@@ -1,5 +1,5 @@
|
|||||||
#ifndef MPVURL_HPP_
|
#ifndef OIM_URL_HPP_
|
||||||
#define MPVURL_HPP_
|
#define OIM_URL_HPP_
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@@ -11,7 +11,8 @@ using std::string;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Converts a single character to a percent-decodable byte representation
|
* Converts a single character to a percent-decodable byte representation
|
||||||
* Taken from https://github.com/cpp-netlib/url/blob/main/include/skyr/v1/percent_encoding/percent_decode_range.hpp
|
* Taken from
|
||||||
|
* https://github.com/cpp-netlib/url/blob/main/include/skyr/v1/percent_encoding/percent_decode_range.hpp
|
||||||
*/
|
*/
|
||||||
inline std::byte alnum_to_hex(char value) {
|
inline std::byte alnum_to_hex(char value) {
|
||||||
if ((value >= '0') && (value <= '9')) {
|
if ((value >= '0') && (value <= '9')) {
|
||||||
@@ -47,11 +48,10 @@ public:
|
|||||||
/* Constructor with C++ std::string URL */
|
/* Constructor with C++ std::string URL */
|
||||||
url(const string &url_s) {
|
url(const string &url_s) {
|
||||||
const string prot_end("://");
|
const string prot_end("://");
|
||||||
string::const_iterator prot_i = std::search(url_s.begin(), url_s.end(),
|
string::const_iterator prot_i = std::search(
|
||||||
prot_end.begin(), prot_end.end());
|
url_s.begin(), url_s.end(), prot_end.begin(), prot_end.end());
|
||||||
protocol_.reserve(std::distance(url_s.begin(), prot_i));
|
protocol_.reserve(std::distance(url_s.begin(), prot_i));
|
||||||
std::transform(url_s.begin(), prot_i,
|
std::transform(url_s.begin(), prot_i, std::back_inserter(protocol_),
|
||||||
std::back_inserter(protocol_),
|
|
||||||
std::ptr_fun<int, int>(tolower)); // protocol is icase
|
std::ptr_fun<int, int>(tolower)); // protocol is icase
|
||||||
if (prot_i == url_s.end())
|
if (prot_i == url_s.end())
|
||||||
return;
|
return;
|
||||||
@@ -59,8 +59,7 @@ public:
|
|||||||
|
|
||||||
string::const_iterator path_i = std::find(prot_i, url_s.end(), '/');
|
string::const_iterator path_i = std::find(prot_i, url_s.end(), '/');
|
||||||
host_.reserve(std::distance(prot_i, path_i));
|
host_.reserve(std::distance(prot_i, path_i));
|
||||||
std::transform(prot_i, path_i,
|
std::transform(prot_i, path_i, std::back_inserter(host_),
|
||||||
std::back_inserter(host_),
|
|
||||||
std::ptr_fun<int, int>(tolower)); // host is icase
|
std::ptr_fun<int, int>(tolower)); // host is icase
|
||||||
|
|
||||||
string::const_iterator query_i = std::find(path_i, url_s.end(), '?');
|
string::const_iterator query_i = std::find(path_i, url_s.end(), '?');
|
||||||
@@ -96,7 +95,8 @@ public:
|
|||||||
string query_value(string key) {
|
string query_value(string key) {
|
||||||
// Find the beginning of the last occurrence of `key` in `query`
|
// Find the beginning of the last occurrence of `key` in `query`
|
||||||
auto pos = query_.rfind(key + "=");
|
auto pos = query_.rfind(key + "=");
|
||||||
if (pos == string::npos) return "";
|
if (pos == string::npos)
|
||||||
|
return "";
|
||||||
|
|
||||||
// Offset calculation (beginning of the value string associated with
|
// Offset calculation (beginning of the value string associated with
|
||||||
// `key`):
|
// `key`):
|
||||||
@@ -111,12 +111,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets a value from a query string given a key (overload with optional fallback if
|
* Gets a value from a query string given a key (overload with optional
|
||||||
* value isn't found)
|
* fallback if value isn't found)
|
||||||
*/
|
*/
|
||||||
string query_value(string key, string fallback) {
|
string query_value(string key, string fallback) {
|
||||||
string ret = query_value(key);
|
string ret = query_value(key);
|
||||||
if (ret.empty()) return fallback;
|
if (ret.empty())
|
||||||
|
return fallback;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -131,9 +132,9 @@ string url_decode(const string encoded) {
|
|||||||
std::byte b1 = alnum_to_hex(*++i);
|
std::byte b1 = alnum_to_hex(*++i);
|
||||||
std::byte b2 = alnum_to_hex(*++i);
|
std::byte b2 = alnum_to_hex(*++i);
|
||||||
|
|
||||||
char parsed = static_cast<char>(
|
char parsed =
|
||||||
(0x10u * std::to_integer<unsigned int>(b1)) + std::to_integer<unsigned int>(b2)
|
static_cast<char>((0x10u * std::to_integer<unsigned int>(b1)) +
|
||||||
);
|
std::to_integer<unsigned int>(b2));
|
||||||
ret += parsed;
|
ret += parsed;
|
||||||
} else {
|
} else {
|
||||||
ret += *i;
|
ret += *i;
|
||||||
|
Reference in New Issue
Block a user