// 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 # include # include # include # include # include # include # include # include # include # include namespace boost { namespace network { namespace uri { namespace detail { bool parse(std::string::const_iterator first, std::string::const_iterator last, uri_parts &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_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 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 port_us(const uri &uri_) { uri::string_type port = uri_.port(); return (port.empty())? boost::optional() : boost::optional(boost::lexical_cast(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 # include # include 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 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__