📄 uri.cpp
字号:
//
// URI.cpp
//
// $Id: //poco/1.3/Foundation/src/URI.cpp#1 $
//
// Library: Foundation
// Package: URI
// Module: URI
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#include "Poco/URI.h"
#include "Poco/NumberFormatter.h"
#include "Poco/Exception.h"
#include "Poco/String.h"
#include "Poco/NumberParser.h"
namespace Poco {
const std::string URI::RESERVED_PATH = "?#";
const std::string URI::RESERVED_QUERY = "#";
const std::string URI::RESERVED_FRAGMENT = "";
const std::string URI::ILLEGAL = "%<>{}|\\\"^`";
URI::URI():
_port(0)
{
}
URI::URI(const std::string& uri):
_port(0)
{
parse(uri);
}
URI::URI(const char* uri):
_port(0)
{
parse(std::string(uri));
}
URI::URI(const std::string& scheme, const std::string& pathEtc):
_scheme(scheme),
_port(0)
{
toLowerInPlace(_scheme);
_port = getWellKnownPort();
std::string::const_iterator beg = pathEtc.begin();
std::string::const_iterator end = pathEtc.end();
parsePathEtc(beg, end);
}
URI::URI(const std::string& scheme, const std::string& authority, const std::string& pathEtc):
_scheme(scheme)
{
toLowerInPlace(_scheme);
std::string::const_iterator beg = authority.begin();
std::string::const_iterator end = authority.end();
parseAuthority(beg, end);
beg = pathEtc.begin();
end = pathEtc.end();
parsePathEtc(beg, end);
}
URI::URI(const std::string& scheme, const std::string& authority, const std::string& path, const std::string& query):
_scheme(scheme),
_path(path),
_query(query)
{
toLowerInPlace(_scheme);
std::string::const_iterator beg = authority.begin();
std::string::const_iterator end = authority.end();
parseAuthority(beg, end);
}
URI::URI(const std::string& scheme, const std::string& authority, const std::string& path, const std::string& query, const std::string& fragment):
_scheme(scheme),
_path(path),
_query(query),
_fragment(fragment)
{
toLowerInPlace(_scheme);
std::string::const_iterator beg = authority.begin();
std::string::const_iterator end = authority.end();
parseAuthority(beg, end);
}
URI::URI(const URI& uri):
_scheme(uri._scheme),
_userInfo(uri._userInfo),
_host(uri._host),
_port(uri._port),
_path(uri._path),
_query(uri._query),
_fragment(uri._fragment)
{
}
URI::URI(const URI& baseURI, const std::string& relativeURI):
_scheme(baseURI._scheme),
_userInfo(baseURI._userInfo),
_host(baseURI._host),
_port(baseURI._port),
_path(baseURI._path),
_query(baseURI._query),
_fragment(baseURI._fragment)
{
resolve(relativeURI);
}
URI::~URI()
{
}
URI& URI::operator = (const URI& uri)
{
if (&uri != this)
{
_scheme = uri._scheme;
_userInfo = uri._userInfo;
_host = uri._host;
_port = uri._port;
_path = uri._path;
_query = uri._query;
_fragment = uri._fragment;
}
return *this;
}
URI& URI::operator = (const std::string& uri)
{
clear();
parse(uri);
return *this;
}
URI& URI::operator = (const char* uri)
{
clear();
parse(std::string(uri));
return *this;
}
void URI::swap(URI& uri)
{
std::swap(_scheme, uri._scheme);
std::swap(_userInfo, uri._userInfo);
std::swap(_host, uri._host);
std::swap(_port, uri._port);
std::swap(_path, uri._path);
std::swap(_query, uri._query);
std::swap(_fragment, uri._fragment);
}
void URI::clear()
{
_scheme.clear();
_userInfo.clear();
_host.clear();
_port = 0;
_path.clear();
_query.clear();
_fragment.clear();
}
std::string URI::toString() const
{
std::string uri;
if (isRelative())
{
encode(_path, RESERVED_PATH, uri);
}
else
{
uri = _scheme;
uri += ':';
std::string auth = getAuthority();
if (!auth.empty() || _scheme == "file")
{
uri.append("//");
uri.append(auth);
}
if (!_path.empty())
{
if (!auth.empty() && _path[0] != '/')
uri += '/';
encode(_path, RESERVED_PATH, uri);
}
}
if (!_query.empty())
{
uri += '?';
uri.append(_query);
}
if (!_fragment.empty())
{
uri += '#';
encode(_fragment, RESERVED_FRAGMENT, uri);
}
return uri;
}
void URI::setScheme(const std::string& scheme)
{
_scheme = scheme;
toLowerInPlace(_scheme);
if (_port == 0)
_port = getWellKnownPort();
}
void URI::setUserInfo(const std::string& userInfo)
{
_userInfo.clear();
decode(userInfo, _userInfo);
}
void URI::setHost(const std::string& host)
{
_host = host;
}
unsigned short URI::getPort() const
{
if (_port == 0)
return getWellKnownPort();
else
return _port;
}
void URI::setPort(unsigned short port)
{
_port = port;
}
std::string URI::getAuthority() const
{
std::string auth;
if (!_userInfo.empty())
{
auth.append(_userInfo);
auth += '@';
}
auth.append(_host);
if (_port && !isWellKnownPort())
{
auth += ':';
auth.append(NumberFormatter::format(_port));
}
return auth;
}
void URI::setAuthority(const std::string& authority)
{
_userInfo.clear();
_host.clear();
_port = 0;
std::string::const_iterator beg = authority.begin();
std::string::const_iterator end = authority.end();
parseAuthority(beg, end);
}
void URI::setPath(const std::string& path)
{
_path.clear();
decode(path, _path);
}
void URI::setRawQuery(const std::string& query)
{
_query = query;
}
void URI::setQuery(const std::string& query)
{
_query.clear();
encode(query, RESERVED_QUERY, _query);
}
std::string URI::getQuery() const
{
std::string query;
decode(_query, query);
return query;
}
void URI::setFragment(const std::string& fragment)
{
_fragment.clear();
decode(fragment, _fragment);
}
void URI::setPathEtc(const std::string& pathEtc)
{
_path.clear();
_query.clear();
_fragment.clear();
std::string::const_iterator beg = pathEtc.begin();
std::string::const_iterator end = pathEtc.end();
parsePathEtc(beg, end);
}
std::string URI::getPathEtc() const
{
std::string pathEtc;
encode(_path, RESERVED_PATH, pathEtc);
if (!_query.empty())
{
pathEtc += '?';
encode(_query, RESERVED_QUERY, pathEtc);
}
if (!_fragment.empty())
{
pathEtc += '#';
encode(_fragment, RESERVED_FRAGMENT, pathEtc);
}
return pathEtc;
}
std::string URI::getPathAndQuery() const
{
std::string pathAndQuery;
encode(_path, RESERVED_PATH, pathAndQuery);
if (!_query.empty())
{
pathAndQuery += '?';
encode(_query, RESERVED_QUERY, pathAndQuery);
}
return pathAndQuery;
}
void URI::resolve(const std::string& relativeURI)
{
URI parsedURI(relativeURI);
resolve(parsedURI);
}
void URI::resolve(const URI& relativeURI)
{
if (!relativeURI._scheme.empty())
{
_scheme = relativeURI._scheme;
_userInfo = relativeURI._userInfo;
_host = relativeURI._host;
_port = relativeURI._port;
_path = relativeURI._path;
_query = relativeURI._query;
removeDotSegments();
}
else
{
if (!relativeURI._host.empty())
{
_userInfo = relativeURI._userInfo;
_host = relativeURI._host;
_port = relativeURI._port;
_path = relativeURI._path;
_query = relativeURI._query;
removeDotSegments();
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -