mirror of
https://github.com/idolpx/libMeatloaf.git
synced 2025-12-06 04:38:49 -05:00
282 lines
6.4 KiB
C++
282 lines
6.4 KiB
C++
// This code uses code from the Meatloaf Project:
|
|
// Meatloaf - A Commodore 64/128 multi-device emulator
|
|
// https://github.com/idolpx/meatloaf
|
|
// Copyright(C) 2020 James Johnston
|
|
//
|
|
// Meatloaf is free software : you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Meatloaf is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Meatloaf. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
#include "peoples_url_parser.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <sstream>
|
|
|
|
#include "../../include/debug.h"
|
|
|
|
#include "string_utils.h"
|
|
|
|
void PeoplesUrlParser::processHostPort(std::string hostPort) {
|
|
auto byColon = mstr::split(hostPort,':',2);
|
|
host = byColon[0];
|
|
if(byColon.size()>1) {
|
|
port = byColon[1];
|
|
}
|
|
}
|
|
|
|
void PeoplesUrlParser::processAuthorityPath(std::string authorityPath) {
|
|
// /path
|
|
// authority:80/path
|
|
// authority:100
|
|
// authority
|
|
auto bySlash = mstr::split(authorityPath,'/',2);
|
|
|
|
processHostPort(bySlash[0]);
|
|
if(bySlash.size()>1) {
|
|
// hasPath
|
|
path = bySlash[1];
|
|
}
|
|
|
|
}
|
|
|
|
void PeoplesUrlParser::processUserPass(std::string userPass) {
|
|
// user:pass
|
|
auto byColon = mstr::split(userPass,':',2);
|
|
if(byColon.size()==1) {
|
|
user = byColon[0];
|
|
}
|
|
else {
|
|
user = byColon[0];
|
|
password = byColon[1];
|
|
}
|
|
}
|
|
|
|
void PeoplesUrlParser::processAuthority(std::string pastTheColon) {
|
|
// //user:password@/path
|
|
// //user:password@host:80/path
|
|
// // host:100
|
|
// // host:30/path
|
|
auto byAtSign = mstr::split(pastTheColon,'@', 2);
|
|
|
|
if(byAtSign.size()==1) {
|
|
// just address, port, path
|
|
processAuthorityPath(mstr::drop(byAtSign[0],2));
|
|
}
|
|
else {
|
|
// user:password
|
|
processUserPass(mstr::drop(byAtSign[0],2));
|
|
// address, port, path
|
|
processAuthorityPath(byAtSign[1]);
|
|
}
|
|
}
|
|
|
|
void PeoplesUrlParser::cleanPath() {
|
|
if(path.size() == 0)
|
|
return;
|
|
|
|
while(mstr::endsWith(path,"/")) {
|
|
path=mstr::dropLast(path, 1);
|
|
}
|
|
mstr::replaceAll(path, "//", "/");
|
|
}
|
|
|
|
void PeoplesUrlParser::processPath() {
|
|
if(path.size() == 0)
|
|
return;
|
|
|
|
auto pathParts = mstr::split(path, '/');
|
|
auto queryParts = mstr::split(*(--pathParts.end()), '?');
|
|
auto fragmentParts = mstr::split(*(--queryParts.end()), '#');
|
|
|
|
// path
|
|
if(pathParts.size() > 1)
|
|
name = *(--pathParts.end());
|
|
else
|
|
name = path;
|
|
|
|
// filename
|
|
if(queryParts.size() > 1)
|
|
name = queryParts.front();
|
|
|
|
auto nameParts = mstr::split(name, '.');
|
|
|
|
// base name
|
|
if(nameParts.size() > 1)
|
|
base_name = nameParts.front();
|
|
|
|
// extension
|
|
if(nameParts.size() > 1)
|
|
extension = *(--nameParts.end());
|
|
|
|
// query
|
|
if(queryParts.size() > 1)
|
|
query = *(fragmentParts.begin());
|
|
|
|
// fragment
|
|
if(fragmentParts.size() > 1)
|
|
fragment = *(--fragmentParts.end());
|
|
}
|
|
|
|
|
|
std::string PeoplesUrlParser::pathToFile(void)
|
|
{
|
|
if (name.size() > 0)
|
|
return path.substr(0, path.size() - name.size() - 1);
|
|
else
|
|
return path;
|
|
}
|
|
|
|
std::string PeoplesUrlParser::root(void)
|
|
{
|
|
// set root URL
|
|
std::string root;
|
|
if ( scheme.size() )
|
|
root = scheme + ":";
|
|
|
|
if ( host.size() )
|
|
root += "//";
|
|
|
|
if ( user.size() )
|
|
{
|
|
root += user;
|
|
if ( password.size() )
|
|
root += ':' + password;
|
|
root += '@';
|
|
}
|
|
|
|
root += host;
|
|
|
|
if ( port.size() )
|
|
root += ':' + port;
|
|
|
|
//Debug_printv("root[%s]", root.c_str());
|
|
return root;
|
|
}
|
|
|
|
std::string PeoplesUrlParser::base(void)
|
|
{
|
|
// set base URL
|
|
//Debug_printv("base[%s]", (root() + "/" + path).c_str());
|
|
if ( !mstr::startsWith(path, "/") )
|
|
path = "/" + path;
|
|
|
|
cleanPath();
|
|
|
|
return root() + pathToFile() ;
|
|
}
|
|
|
|
|
|
|
|
uint16_t PeoplesUrlParser::getPort() {
|
|
return std::stoi(port);
|
|
}
|
|
|
|
|
|
PeoplesUrlParser* PeoplesUrlParser::parseURL(const std::string &u) {
|
|
PeoplesUrlParser *url = new PeoplesUrlParser;
|
|
url->resetURL(u);
|
|
return url;
|
|
}
|
|
|
|
void PeoplesUrlParser::resetURL(const std::string u) {
|
|
|
|
if ( u.empty() )
|
|
return;
|
|
|
|
//Debug_printv("u[%s]", u.c_str());
|
|
|
|
url = u;
|
|
|
|
//Debug_printv("Before [%s]", url.c_str());
|
|
|
|
auto byColon = mstr::split(url, ':', 2);
|
|
|
|
scheme = "";
|
|
path = "";
|
|
user = "";
|
|
password = "";
|
|
host = "";
|
|
port = "";
|
|
|
|
if(byColon.size()==1) {
|
|
// no scheme, good old local path
|
|
path = byColon[0];
|
|
}
|
|
else
|
|
{
|
|
scheme = byColon[0];
|
|
|
|
auto pastTheColon = byColon[1]; // don't visualise!
|
|
|
|
if(pastTheColon[0]=='/' && pastTheColon[1]=='/') {
|
|
// //user:pass@/path
|
|
// //user:pass@authority:80/path
|
|
// //authority:100
|
|
// //authority:30/path
|
|
|
|
processAuthority(pastTheColon);
|
|
}
|
|
else {
|
|
// we have just a plain old path
|
|
// /path
|
|
// user@server
|
|
// etc.
|
|
path = pastTheColon;
|
|
}
|
|
}
|
|
|
|
// Clean things up before exiting
|
|
cleanPath();
|
|
processPath();
|
|
rebuildURL();
|
|
|
|
//dump();
|
|
|
|
return;
|
|
}
|
|
|
|
std::string PeoplesUrlParser::rebuildURL(void)
|
|
{
|
|
// set full URL
|
|
if ( !mstr::startsWith(path, "/") )
|
|
path = "/" + path;
|
|
|
|
cleanPath();
|
|
|
|
url = root() + path;
|
|
//Debug_printv("url[%s]", url.c_str());
|
|
// url += name;
|
|
// Debug_printv("url[%s]", url.c_str());
|
|
// if ( query.size() )
|
|
// url += '?' + query;
|
|
// if ( fragment.size() )
|
|
// url += '#' + fragment;
|
|
|
|
return url;
|
|
}
|
|
|
|
|
|
// void dump() {
|
|
// printf("scheme: %s\r\n", scheme.c_str());
|
|
// printf("user pass: %s -- %s\r\n", user.c_str(), pass.c_str());
|
|
// printf("host port: %s -- %s\r\n", host.c_str(), port.c_str());
|
|
// printf("path: %s\r\n", path.c_str());
|
|
// printf("name: %s\r\n", name.c_str());
|
|
// printf("extension: %s\r\n", extension.c_str());
|
|
// printf("root: %s\r\n", root().c_str());
|
|
// printf("base: %s\r\n", base().c_str());
|
|
// printf("pathToFile: %s\r\n", pathToFile().c_str());
|
|
// }
|
|
|