Files
2026-06-01 12:46:52 +02:00

435 lines
10 KiB
C++

// Copyright 2009, 2010, 2011, 2012 Dean Michael Berris, Jeroen Habraken, Glyn Matthews.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef __BOOST_NETWORK_URI_INC__
# define __BOOST_NETWORK_URI_INC__
# pragma once
# include <boost/network/uri/config.hpp>
# include <boost/network/uri/detail/uri_parts.hpp>
# include <boost/network/uri/schemes.hpp>
# include <boost/utility/swap.hpp>
# include <boost/range/algorithm/equal.hpp>
# include <boost/range/algorithm/copy.hpp>
# include <boost/range/as_literal.hpp>
# include <boost/range/iterator_range.hpp>
# include <boost/lexical_cast.hpp>
# include <boost/optional.hpp>
# include <boost/functional/hash_fwd.hpp>
namespace boost {
namespace network {
namespace uri {
namespace detail {
bool parse(std::string::const_iterator first,
std::string::const_iterator last,
uri_parts<std::string::const_iterator> &parts);
} // namespace detail
class BOOST_URI_DECL uri {
friend class builder;
public:
typedef std::string string_type;
typedef string_type::value_type value_type;
typedef string_type::const_iterator const_iterator;
typedef boost::iterator_range<const_iterator> const_range_type;
uri()
: is_valid_(false) {
}
//uri(const value_type *uri)
// : uri_(uri), is_valid_(false) {
// parse();
//}
uri(const string_type &uri)
: uri_(uri), is_valid_(false) {
parse();
}
template <
class FwdIter
>
uri(const FwdIter &first, const FwdIter &last)
: uri_(first, last), is_valid_(false) {
parse();
}
uri(const uri &other)
: uri_(other.uri_) {
parse();
}
uri &operator = (const uri &other) {
uri(other).swap(*this);
return *this;
}
uri &operator = (const string_type &uri_string) {
uri(uri_string).swap(*this);
return *this;
}
~uri() {
}
void swap(uri &other) {
boost::swap(uri_, other.uri_);
boost::swap(uri_parts_, other.uri_parts_);
boost::swap(is_valid_, other.is_valid_);
}
const_iterator begin() const {
return uri_.begin();
}
const_iterator end() const {
return uri_.end();
}
const_range_type scheme_range() const {
return uri_parts_.scheme;
}
const_range_type user_info_range() const {
return uri_parts_.hier_part.user_info?
uri_parts_.hier_part.user_info.get() :
const_range_type();
}
const_range_type host_range() const {
return uri_parts_.hier_part.host?
uri_parts_.hier_part.host.get() :
const_range_type();
}
const_range_type port_range() const {
return uri_parts_.hier_part.port?
uri_parts_.hier_part.port.get() :
const_range_type();
}
const_range_type path_range() const {
return uri_parts_.hier_part.path?
uri_parts_.hier_part.path.get() :
const_range_type();
}
const_range_type query_range() const {
return uri_parts_.query ?
uri_parts_.query.get() :
const_range_type();
}
const_range_type fragment_range() const {
return uri_parts_.fragment?
uri_parts_.fragment.get() :
const_range_type();
}
string_type scheme() const {
const_range_type range = scheme_range();
return range? string_type(boost::begin(range), boost::end(range)) : string_type();
}
string_type user_info() const {
const_range_type range = user_info_range();
return range? string_type(boost::begin(range), boost::end(range)) : string_type();
}
string_type host() const {
const_range_type range = host_range();
return range? string_type(boost::begin(range), boost::end(range)) : string_type();
}
string_type port() const {
const_range_type range = port_range();
return range? string_type(boost::begin(range), boost::end(range)) : string_type();
}
string_type path() const {
const_range_type range = path_range();
return range? string_type(boost::begin(range), boost::end(range)) : string_type();
}
string_type query() const {
const_range_type range = query_range();
return range? string_type(boost::begin(range), boost::end(range)) : string_type();
}
string_type fragment() const {
const_range_type range = fragment_range();
return range? string_type(boost::begin(range), boost::end(range)) : string_type();
}
string_type string() const {
return uri_;
}
bool is_valid() const {
return is_valid_;
}
void append(const string_type &data) {
uri_.append(data);
parse();
}
template <
class FwdIter
>
void append(const FwdIter &first, const FwdIter &last) {
uri_.append(first, last);
parse();
}
private:
void parse();
string_type uri_;
detail::uri_parts<const_iterator> uri_parts_;
bool is_valid_;
};
inline
void uri::parse() {
const_iterator first(boost::begin(uri_)), last(boost::end(uri_));
is_valid_ = detail::parse(first, last, uri_parts_);
if (is_valid_) {
if (!uri_parts_.scheme) {
uri_parts_.scheme = const_range_type(boost::begin(uri_),
boost::begin(uri_));
}
uri_parts_.update();
}
}
inline
uri::string_type scheme(const uri &uri_) {
return uri_.scheme();
}
inline
uri::string_type user_info(const uri &uri_) {
return uri_.user_info();
}
inline
uri::string_type host(const uri &uri_) {
return uri_.host();
}
inline
uri::string_type port(const uri &uri_) {
return uri_.port();
}
inline
boost::optional<unsigned short> port_us(const uri &uri_) {
uri::string_type port = uri_.port();
return (port.empty())?
boost::optional<unsigned short>() :
boost::optional<unsigned short>(boost::lexical_cast<unsigned short>(port));
}
inline
uri::string_type path(const uri &uri_) {
return uri_.path();
}
inline
uri::string_type query(const uri &uri_) {
return uri_.query();
}
inline
uri::string_type fragment(const uri &uri_) {
return uri_.fragment();
}
inline
uri::string_type hierarchical_part(const uri &uri_) {
return uri::string_type(boost::begin(uri_.user_info_range()),
boost::end(uri_.path_range()));
}
inline
uri::string_type authority(const uri &uri_) {
return uri::string_type(boost::begin(uri_.user_info_range()),
boost::end(uri_.port_range()));
}
inline
bool valid(const uri &uri_) {
return uri_.is_valid();
}
inline
bool is_absolute(const uri &uri_) {
return uri_.is_valid() && !boost::empty(uri_.scheme_range());
}
inline
bool is_relative(const uri &uri_) {
return uri_.is_valid() && boost::empty(uri_.scheme_range());
}
inline
bool is_hierarchical(const uri &uri_) {
return is_absolute(uri_) && hierarchical_schemes::exists(scheme(uri_));
}
inline
bool is_opaque(const uri &uri_) {
return is_absolute(uri_) && opaque_schemes::exists(scheme(uri_));
}
inline
bool is_valid(const uri &uri_) {
return valid(uri_);
}
inline
void swap(uri &lhs, uri &rhs) {
lhs.swap(rhs);
}
inline
std::size_t hash_value(const uri &uri_)
{
std::size_t seed = 0;
for (uri::const_iterator it = begin(uri_); it != end(uri_); ++it) {
hash_combine(seed, *it);
}
return seed;
}
inline
bool operator == (const uri &lhs, const uri &rhs) {
return boost::equal(lhs, rhs);
}
inline
bool operator == (const uri &lhs, const uri::string_type &rhs) {
return boost::equal(lhs, rhs);
}
inline
bool operator == (const uri::string_type &lhs, const uri &rhs) {
return boost::equal(lhs, rhs);
}
inline
bool operator == (const uri &lhs, const uri::value_type *rhs) {
return boost::equal(lhs, boost::as_literal(rhs));
}
inline
bool operator == (const uri::value_type *lhs, const uri &rhs) {
return boost::equal(boost::as_literal(lhs), rhs);
}
inline
bool operator != (const uri &lhs, const uri &rhs) {
return !(lhs == rhs);
}
inline
bool operator < (const uri &lhs, const uri &rhs) {
return lhs.string() < rhs.string();
}
} // namespace uri
} // namespace network
} // namespace boost
# include <boost/network/uri/accessors.hpp>
# include <boost/network/uri/directives.hpp>
# include <boost/network/uri/builder.hpp>
namespace boost {
namespace network {
namespace uri {
inline
uri from_parts(const uri &base_uri,
const uri::string_type &path_,
const uri::string_type &query_,
const uri::string_type &fragment_) {
uri uri_(base_uri);
builder(uri_).path(path_).query(query_).fragment(fragment_);
return uri_;
}
inline
uri from_parts(const uri &base_uri,
const uri::string_type &path_,
const uri::string_type &query_) {
uri uri_(base_uri);
builder(uri_).path(path_).query(query_);
return uri_;
}
inline
uri from_parts(const uri &base_uri,
const uri::string_type &path_) {
uri uri_(base_uri);
builder(uri_).path(path_);
return uri_;
}
inline
uri from_parts(const uri::string_type &base_uri,
const uri::string_type &path,
const uri::string_type &query,
const uri::string_type &fragment) {
return from_parts(uri(base_uri), path, query, fragment);
}
inline
uri from_parts(const uri::string_type &base_uri,
const uri::string_type &path,
const uri::string_type &query) {
return from_parts(uri(base_uri), path, query);
}
inline
uri from_parts(const uri::string_type &base_uri,
const uri::string_type &path) {
return from_parts(uri(base_uri), path);
}
} // namespace uri
} // namespace network
} // namespace boost
# include <boost/filesystem/path.hpp>
namespace boost {
namespace network {
namespace uri {
inline
uri from_file(const filesystem::path &path_) {
uri uri_;
builder(uri_).scheme("file").path(path_.string());
return uri_;
}
} // namespace uri
} // namespace network
} // namespace boost
#endif // __BOOST_NETWORK_URI_INC__