flatten 20260225
This commit is contained in:
207
tjp/core/internet/URL.cpp
Executable file
207
tjp/core/internet/URL.cpp
Executable file
@@ -0,0 +1,207 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
// TJP 4/09/01 relative URLs have not been checked yet. don't expect them
|
||||
// to work the first time you use this class!
|
||||
//
|
||||
// TJP 4/11/01 getAsLocalPath needs to be modified to work with all sorts
|
||||
// of protocols and port numbers... right now, probably not
|
||||
|
||||
#include "URL.h"
|
||||
|
||||
#include "../file/Path.h"
|
||||
#include <tjp/core/string/cmp_case.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace internet {
|
||||
|
||||
const URL Empty;
|
||||
|
||||
const char FS = '/';
|
||||
//const char BS = '\\';
|
||||
const char *DD = "..";
|
||||
|
||||
bool URL::isAbsoluteURL (const std::string &url)
|
||||
{
|
||||
return url.find("://") != -1;
|
||||
}
|
||||
|
||||
void URL::parseAbsoluteURL (const std::string &url)
|
||||
{
|
||||
auto protocolBegin = 0;
|
||||
auto protocolEnd = url.find("://");
|
||||
|
||||
if (protocolEnd==-1)
|
||||
{
|
||||
throw Exception ("Could not find protocol");
|
||||
}
|
||||
|
||||
auto serverBegin = protocolEnd + std::string("://").length();
|
||||
auto serverEnd = url.find (FS, serverBegin);
|
||||
|
||||
if (serverEnd==-1)
|
||||
{
|
||||
throw Exception ("Could not find server");
|
||||
}
|
||||
|
||||
auto directoryBegin = serverEnd + 1;
|
||||
auto directoryEnd = url.find_last_of (FS) + 1;
|
||||
|
||||
auto fileBegin = directoryEnd;
|
||||
auto fileEnd = url.length();
|
||||
|
||||
protocol = url.substr (protocolBegin, protocolEnd-protocolBegin);
|
||||
|
||||
server = url.substr (serverBegin, serverEnd-serverBegin);
|
||||
directory = url.substr (directoryBegin, directoryEnd-directoryBegin);
|
||||
file = url.substr (fileBegin, fileEnd-fileBegin);
|
||||
}
|
||||
|
||||
void URL::parseRelativeURL (const std::string &url)
|
||||
{
|
||||
auto directoryBegin = 0;
|
||||
auto directoryEnd = url.find_last_of (FS) + 1;
|
||||
|
||||
auto fileBegin = directoryEnd;
|
||||
auto fileEnd = url.length();
|
||||
|
||||
std::string relativeDirectory = url.substr (directoryBegin, directoryEnd-directoryBegin);
|
||||
|
||||
if (relativeDirectory.substr (0,2) == "./")
|
||||
{
|
||||
relativeDirectory = relativeDirectory.substr(2);
|
||||
}
|
||||
|
||||
std::string relativeFile = url.substr (fileBegin, fileEnd-fileBegin);
|
||||
|
||||
if ( (relativeDirectory.length()>0 && directory.length()>0) &&
|
||||
((directory[directory.length()-1]==FS) && relativeDirectory[0]==FS) )
|
||||
{
|
||||
directory += relativeDirectory.substr(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
directory += relativeDirectory;
|
||||
}
|
||||
|
||||
file = url.substr (fileBegin, fileEnd-fileBegin);
|
||||
}
|
||||
|
||||
URL::URL ()
|
||||
{
|
||||
}
|
||||
|
||||
URL::URL (const std::string &url)
|
||||
{
|
||||
parseAbsoluteURL (url);
|
||||
}
|
||||
|
||||
URL::URL (const URL &parent, const std::string &url)
|
||||
{
|
||||
if (isAbsoluteURL (url))
|
||||
{
|
||||
parseAbsoluteURL (url);
|
||||
}
|
||||
else
|
||||
{
|
||||
protocol = parent.getProtocol();
|
||||
server = parent.getServer();
|
||||
directory = parent.getDirectory();
|
||||
|
||||
parseRelativeURL (url);
|
||||
}
|
||||
}
|
||||
|
||||
URL::URL (const URL &url)
|
||||
{
|
||||
protocol = url.protocol;
|
||||
server = url.server;
|
||||
directory = url.directory;
|
||||
file = url.file;
|
||||
}
|
||||
|
||||
URL::~URL ()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &URL::getProtocol () const
|
||||
{
|
||||
return protocol;
|
||||
}
|
||||
|
||||
const std::string &URL::getServer() const
|
||||
{
|
||||
return server;
|
||||
}
|
||||
|
||||
std::string URL::getPath () const
|
||||
{
|
||||
return directory + file;
|
||||
}
|
||||
|
||||
const std::string &URL::getDirectory () const
|
||||
{
|
||||
return directory;
|
||||
}
|
||||
|
||||
const std::string &URL::getFile () const
|
||||
{
|
||||
return file;
|
||||
}
|
||||
|
||||
URL URL::join(const URL &url, const std::string &append)
|
||||
{
|
||||
if (append.empty())
|
||||
return url;
|
||||
|
||||
return URL((std::string)url + FS + append);
|
||||
}
|
||||
|
||||
URL::operator std::string() const
|
||||
{
|
||||
return getProtocol() + "://" + getServer() + FS + getPath();
|
||||
}
|
||||
|
||||
bool URL::operator <(const URL &right) const
|
||||
{
|
||||
// this implementation should be redone probably
|
||||
|
||||
auto p = cmp_case(protocol, right.protocol);
|
||||
if (p < 0) return true;
|
||||
if (p > 0) return false;
|
||||
|
||||
auto s = cmp_case(server, right.server);
|
||||
if (s < 0) return true;
|
||||
if (s > 0) return false;
|
||||
|
||||
auto d = cmp_case(directory, right.directory);
|
||||
if (d < 0) return true;
|
||||
if (d > 0) return false;
|
||||
|
||||
return less_case(file, right.file);
|
||||
}
|
||||
|
||||
bool URL::operator ==(const URL &right) const
|
||||
{
|
||||
return (
|
||||
equal_case(protocol, right.protocol) &&
|
||||
equal_case(server, right.server) &&
|
||||
equal_case(directory, right.directory) &&
|
||||
equal_case(file, right.file)
|
||||
);
|
||||
}
|
||||
|
||||
bool URL::operator !=(const URL &right) const
|
||||
{
|
||||
return (!(*this == right));
|
||||
}
|
||||
|
||||
std::ostream &operator <<(std::ostream &out, const URL &url)
|
||||
{
|
||||
return out << (std::string)url;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user