// // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) // // 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) // // Official repository: https://github.com/boostorg/url // #ifndef BOOST_URL_DETAIL_IMPL_URL_IMPL_IPP #define BOOST_URL_DETAIL_IMPL_URL_IMPL_IPP #include #include #include #include namespace boost { namespace urls { namespace detail { //------------------------------------------------ // // url_impl // //------------------------------------------------ void url_impl:: apply_scheme( string_view s) noexcept { scheme_ = string_to_scheme(s); set_size(id_scheme, s.size() + 1); } void url_impl:: apply_userinfo( pct_string_view const& user, pct_string_view const* pass) noexcept { // this function is for // authority_view_rule only BOOST_ASSERT(from_ == from::authority); // userinfo set_size(id_user, user.size()); decoded_[id_user] = user.decoded_size(); if(pass) { set_size(id_pass, pass->size() + 2); decoded_[id_pass] = pass->decoded_size(); } else { // trailing '@' set_size(id_pass, 1 ); } } void url_impl:: apply_host( host_type ht, pct_string_view s, unsigned char const* addr) noexcept { // this function is for // authority_view_rule only BOOST_ASSERT(from_ == from::authority); // host, port host_type_ = ht; set_size(id_host, s.size()); decoded_[id_host] = s.decoded_size(); std::memcpy( ip_addr_, addr, sizeof(ip_addr_)); } void url_impl:: apply_port( string_view s, unsigned short pn) noexcept { // this function is for // authority_view_rule only BOOST_ASSERT(from_ == from::authority); port_number_ = pn; set_size(id_port, 1 + s.size()); } void url_impl:: apply_authority( authority_view const& a) noexcept { BOOST_ASSERT(from_ != from::authority); // userinfo set_size(id_user, a.u_.len(id_user) + (from_ == from::authority ? 0 : 2)); set_size(id_pass, a.u_.len(id_pass)); decoded_[id_user] = a.u_.decoded_[id_user]; decoded_[id_pass] = a.u_.decoded_[id_pass]; // host, port host_type_ = a.u_.host_type_; port_number_ = a.u_.port_number_; set_size(id_host, a.u_.len(id_host)); set_size(id_port, a.u_.len(id_port)); std::memcpy( ip_addr_, a.u_.ip_addr_, sizeof(ip_addr_)); decoded_[id_host] = a.u_.decoded_[id_host]; } void url_impl:: apply_path( pct_string_view s, std::size_t nseg) noexcept { set_size(id_path, s.size()); decoded_[id_path] = s.decoded_size(); nseg_ = detail::path_segments(s, nseg); } void url_impl:: apply_query( pct_string_view s, std::size_t n) noexcept { nparam_ = n; set_size(id_query, 1 + s.size()); decoded_[id_query] = s.decoded_size(); } void url_impl:: apply_frag( pct_string_view s) noexcept { set_size(id_frag, s.size() + 1); decoded_[id_frag] = s.decoded_size(); } //------------------------------------------------ // // path_ref // //------------------------------------------------ path_ref:: path_ref( url_impl const& impl) noexcept { if(impl.from_ == url_impl::from::url) { impl_ = &impl; } else { string_view s = impl.get(id_path); data_ = s.data(); size_ = s.size(); nseg_ = impl.nseg_; dn_ = impl.decoded_[id_path]; } } path_ref:: path_ref( string_view s, std::size_t dn, std::size_t nseg) noexcept : data_(s.data()) , size_(s.size()) , nseg_(nseg) , dn_(dn) { } pct_string_view path_ref:: buffer() const noexcept { if(impl_) return make_pct_string_view_unsafe( impl_->cs_ + impl_->offset(id_path), impl_->len(id_path), impl_->decoded_[id_path]); return make_pct_string_view_unsafe( data_, size_, dn_); } std::size_t path_ref:: size() const noexcept { if(impl_) return impl_->len(id_path); return size_; } char const* path_ref:: data() const noexcept { if(impl_) return impl_->cs_ + impl_->offset(id_path); return data_; } char const* path_ref:: end() const noexcept { if(impl_) return impl_->cs_ + impl_->offset(id_query); return data_ + size_; } std::size_t path_ref:: nseg() const noexcept { if(impl_) return impl_->nseg_; return nseg_; } //------------------------------------------------ // // query_ref // //------------------------------------------------ query_ref:: query_ref( string_view s, std::size_t dn, std::size_t nparam) noexcept : data_(s.data()) , size_(s.size()) , nparam_(nparam) , dn_(dn) { } query_ref:: query_ref( url_impl const& impl) noexcept { if(impl.from_ == url_impl::from::url) { impl_ = &impl; } else { string_view s = impl.get(id_query); if (!s.empty()) { s.remove_prefix(1); question_mark_ = true; } data_ = s.data(); size_ = s.size(); nparam_ = impl.nparam_; dn_ = impl.decoded_[id_query]; } } pct_string_view query_ref:: buffer() const noexcept { if(impl_) { auto pos = impl_->offset_[id_query]; auto pos1 = impl_->offset_[id_frag]; if(pos < pos1) { ++pos; // no '?' return make_pct_string_view_unsafe( impl_->cs_ + pos, pos1 - pos, impl_->decoded_[id_query]); } // empty return make_pct_string_view_unsafe( impl_->cs_ + pos, 0, 0); } // no '?' return make_pct_string_view_unsafe( data_, size_, dn_); } // with '?' std::size_t query_ref:: size() const noexcept { if(impl_) return impl_->len(id_query); if(size_ > 0) return size_ + 1; return question_mark_; } // no '?' char const* query_ref:: begin() const noexcept { if(impl_) { // using the offset array here auto pos = impl_->offset_[id_query]; auto pos1 = impl_->offset_[id_frag]; if(pos < pos1) return impl_->cs_ + pos + 1; // no '?' // empty return impl_->cs_ + pos; } return data_; } char const* query_ref:: end() const noexcept { if(impl_) return impl_->cs_ + impl_->offset(id_frag); return data_ + size_; } std::size_t query_ref:: nparam() const noexcept { if(impl_) return impl_->nparam_; return nparam_; } } // detail } // urls } // boost #endif