📄 uri.cpp
字号:
//
// URI.cpp
//
// $Id: //poco/Main/Foundation/src/URI.cpp#5 $
//
// Copyright (c) 2004, Guenter Obiltschnig/Applied Informatics.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Redistributions in any form must be accompanied by information on
// how to obtain complete source code for this software and any
// accompanying software that uses this software. The source code
// must either be included in the distribution or be available for no
// more than the cost of distribution plus a nominal fee, and must be
// freely redistributable under reasonable conditions. For an
// executable file, complete source code means the source code for all
// modules it contains. It does not include source code for modules or
// files that typically accompany the major components of the operating
// system on which the executable file runs.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#include "Foundation/URI.h"
#include "Foundation/NumberFormatter.h"
#include "Foundation/Exception.h"
#include "Foundation/String.h"
#include "Foundation/NumberParser.h"
Foundation_BEGIN
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 std::string& scheme, const std::string& path):
_scheme(scheme),
_port(0),
_path(path)
{
toLowerInPlace(_scheme);
_port = getWellKnownPort();
}
URI::URI(const std::string& scheme, const std::string& authority, const std::string& path):
_scheme(scheme),
_path(path)
{
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):
_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;
}
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 += '?';
encode(_query, RESERVED_QUERY, uri);
}
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::setQuery(const std::string& query)
{
_query.clear();
decode(query, _query);
}
void URI::setFragment(const std::string& fragment)
{
_fragment.clear();
decode(fragment, _fragment);
}
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
{
if (relativeURI._path.empty())
{
if (!relativeURI._query.empty())
_query = relativeURI._query;
}
else
{
if (relativeURI._path[0] == '/')
{
_path = relativeURI._path;
removeDotSegments();
}
else
{
mergePath(relativeURI._path);
}
_query = relativeURI._query;
}
}
}
_fragment = relativeURI._fragment;
}
bool URI::isRelative() const
{
return _scheme.empty();
}
bool URI::empty() const
{
return _scheme.empty() && _host.empty() && _path.empty() && _query.empty() && _fragment.empty();
}
bool URI::operator == (const URI& uri) const
{
return equals(uri);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -