1  
//
1  
//
2  
// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
 
3 +
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3  
//
4  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
7  
//
7  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
8  
//
9  
//
9  

10  

10  
#ifndef BOOST_URL_DETAIL_URL_IMPL_HPP
11  
#ifndef BOOST_URL_DETAIL_URL_IMPL_HPP
11  
#define BOOST_URL_DETAIL_URL_IMPL_HPP
12  
#define BOOST_URL_DETAIL_URL_IMPL_HPP
12  

13  

13  
#include <boost/url/host_type.hpp>
14  
#include <boost/url/host_type.hpp>
14  
#include <boost/url/pct_string_view.hpp>
15  
#include <boost/url/pct_string_view.hpp>
15  
#include <boost/url/scheme.hpp>
16  
#include <boost/url/scheme.hpp>
16  
#include <boost/core/detail/string_view.hpp>
17  
#include <boost/core/detail/string_view.hpp>
17  
#include <boost/url/detail/parts_base.hpp>
18  
#include <boost/url/detail/parts_base.hpp>
18  
#include <boost/assert.hpp>
19  
#include <boost/assert.hpp>
19  
#include <cstddef>
20  
#include <cstddef>
20  
#include <cstdint>
21  
#include <cstdint>
21  

22  

22  
namespace boost {
23  
namespace boost {
23  
namespace urls {
24  
namespace urls {
24  

25  

25  
class url_view;
26  
class url_view;
26  
class authority_view;
27  
class authority_view;
27  

28  

28  
namespace detail {
29  
namespace detail {
29  

30  

30  
constexpr char const* const empty_c_str_ = "";
31  
constexpr char const* const empty_c_str_ = "";
31  

32  

32  
// This is the private 'guts' of a
33  
// This is the private 'guts' of a
33  
// url_view, exposed so different parts
34  
// url_view, exposed so different parts
34  
// of the implementation can work on it.
35  
// of the implementation can work on it.
35  
// It stores the offsets and properties of
36  
// It stores the offsets and properties of
36  
// a URL string stored elsewhere and pointed
37  
// a URL string stored elsewhere and pointed
37  
// to by cs_.
38  
// to by cs_.
38 -
struct BOOST_URL_DECL url_impl : parts_base
39 +
struct url_impl : parts_base
39  
{
40  
{
40  
    using size_type = std::uint32_t;
41  
    using size_type = std::uint32_t;
41  

42  

42  
    static_assert(
43  
    static_assert(
43  
        BOOST_URL_MAX_SIZE <= UINT32_MAX,
44  
        BOOST_URL_MAX_SIZE <= UINT32_MAX,
44  
        "BOOST_URL_MAX_SIZE exceeds 32-bit url_impl capacity");
45  
        "BOOST_URL_MAX_SIZE exceeds 32-bit url_impl capacity");
45  

46  

46  
    static
47  
    static
47  
    constexpr
48  
    constexpr
48  
    std::size_t const zero_ = 0;
49  
    std::size_t const zero_ = 0;
49  

50  

50  
    // never nullptr
51  
    // never nullptr
51  
    char const* cs_ = empty_c_str_;
52  
    char const* cs_ = empty_c_str_;
52  

53  

53  
    size_type offset_[id_end + 1] = {};
54  
    size_type offset_[id_end + 1] = {};
54  
    size_type decoded_[id_end] = {};
55  
    size_type decoded_[id_end] = {};
55  
    size_type nseg_ = 0;
56  
    size_type nseg_ = 0;
56  
    size_type nparam_ = 0;
57  
    size_type nparam_ = 0;
57  
    unsigned char ip_addr_[16] = {};
58  
    unsigned char ip_addr_[16] = {};
58  
    // VFALCO don't we need a bool?
59  
    // VFALCO don't we need a bool?
59  
    std::uint16_t port_number_ = 0;
60  
    std::uint16_t port_number_ = 0;
60  
    host_type host_type_ =
61  
    host_type host_type_ =
61  
        urls::host_type::none;
62  
        urls::host_type::none;
62  
    scheme scheme_ =
63  
    scheme scheme_ =
63  
        urls::scheme::none;
64  
        urls::scheme::none;
64  

65  

65  
    from from_ = from::string;
66  
    from from_ = from::string;
66  

67  

 
68 +
    BOOST_URL_CXX14_CONSTEXPR
67  
    url_impl(
69  
    url_impl(
68  
        from b) noexcept
70  
        from b) noexcept
69  
        : from_(b)
71  
        : from_(b)
70  
    {
72  
    {
71  
    }
73  
    }
72  

74  

73 -
    // in url_view.ipp
75 +
    BOOST_URL_CXX14_CONSTEXPR
74  
    url_view construct() const noexcept;
76  
    url_view construct() const noexcept;
75  

77  

76 -
    // in authority_view.ipp
78 +
    BOOST_URL_CXX20_CONSTEXPR
77  
    authority_view
79  
    authority_view
78  
    construct_authority() const noexcept;
80  
    construct_authority() const noexcept;
79  

81  

80 -
    std::size_t len(int, int) const noexcept;
82 +
    BOOST_URL_CXX20_CONSTEXPR std::size_t len(int, int) const noexcept;
81 -
    std::size_t len(int) const noexcept;
83 +
    BOOST_URL_CXX20_CONSTEXPR std::size_t len(int) const noexcept;
82 -
    std::size_t offset(int) const noexcept;
84 +
    BOOST_URL_CXX20_CONSTEXPR std::size_t offset(int) const noexcept;
83 -
    core::string_view get(int) const noexcept;
85 +
    BOOST_URL_CXX20_CONSTEXPR core::string_view get(int) const noexcept;
84 -
    core::string_view get(int, int) const noexcept;
86 +
    BOOST_URL_CXX20_CONSTEXPR core::string_view get(int, int) const noexcept;
85 -
    pct_string_view pct_get(int) const noexcept;
87 +
    BOOST_URL_CXX20_CONSTEXPR pct_string_view pct_get(int) const noexcept;
86 -
    pct_string_view pct_get(int, int) const noexcept;
88 +
    BOOST_URL_CXX20_CONSTEXPR pct_string_view pct_get(int, int) const noexcept;
87 -
    void set_size(int, std::size_t) noexcept;
89 +
    BOOST_URL_CXX20_CONSTEXPR void set_size(int, std::size_t) noexcept;
88 -
    void split(int, std::size_t) noexcept;
90 +
    BOOST_URL_CXX20_CONSTEXPR void split(int, std::size_t) noexcept;
89 -
    void adjust_right(int first, int last, std::size_t n) noexcept;
91 +
    BOOST_URL_CXX20_CONSTEXPR void adjust_right(int first, int last, std::size_t n) noexcept;
90 -
    void adjust_left(int first, int last, std::size_t n) noexcept;
92 +
    BOOST_URL_CXX20_CONSTEXPR void adjust_left(int first, int last, std::size_t n) noexcept;
91 -
    void collapse(int, int, std::size_t) noexcept;
93 +
    BOOST_URL_CXX20_CONSTEXPR void collapse(int, int, std::size_t) noexcept;
92  

94  

93 -
    void apply_scheme(core::string_view) noexcept;
95 +
    BOOST_URL_CXX20_CONSTEXPR void apply_scheme(core::string_view) noexcept;
94 -
    void apply_userinfo(pct_string_view const&,
96 +
    BOOST_URL_CXX20_CONSTEXPR void apply_userinfo(pct_string_view const&,
95  
        pct_string_view const*) noexcept;
97  
        pct_string_view const*) noexcept;
96 -
    void apply_host(host_type, pct_string_view,
98 +
    BOOST_URL_CXX20_CONSTEXPR void apply_host(host_type, pct_string_view,
97  
        unsigned char const*) noexcept;
99  
        unsigned char const*) noexcept;
98 -
    void apply_port(core::string_view, unsigned short) noexcept;
100 +
    BOOST_URL_CXX20_CONSTEXPR void apply_port(core::string_view, unsigned short) noexcept;
99 -
    void apply_authority(authority_view const&) noexcept;
101 +
    BOOST_URL_CXX20_CONSTEXPR void apply_authority(authority_view const&) noexcept;
100 -
    void apply_path(pct_string_view, std::size_t) noexcept;
102 +
    BOOST_URL_CXX20_CONSTEXPR void apply_path(pct_string_view, std::size_t) noexcept;
101 -
    void apply_query(pct_string_view, std::size_t) noexcept;
103 +
    BOOST_URL_CXX20_CONSTEXPR void apply_query(pct_string_view, std::size_t) noexcept;
102 -
    void apply_frag(pct_string_view) noexcept;
104 +
    BOOST_URL_CXX20_CONSTEXPR void apply_frag(pct_string_view) noexcept;
103  
};
105  
};
104  

106  

105  
// url_impl stores 32-bit sizes; centralize narrowing with checks.
107  
// url_impl stores 32-bit sizes; centralize narrowing with checks.
106  
inline
108  
inline
 
109 +
BOOST_URL_CXX14_CONSTEXPR
107  
url_impl::size_type
110  
url_impl::size_type
108  
to_size_type(std::size_t n) noexcept
111  
to_size_type(std::size_t n) noexcept
109  
{
112  
{
110  
    BOOST_ASSERT(n <= BOOST_URL_MAX_SIZE);
113  
    BOOST_ASSERT(n <= BOOST_URL_MAX_SIZE);
111  
    BOOST_ASSERT(n <= UINT32_MAX);
114  
    BOOST_ASSERT(n <= UINT32_MAX);
112  
    return static_cast<url_impl::size_type>(n);
115  
    return static_cast<url_impl::size_type>(n);
113  
}
116  
}
114  

117  

115  
inline
118  
inline
 
119 +
BOOST_URL_CXX14_CONSTEXPR
116  
url_impl::size_type
120  
url_impl::size_type
117  
to_size_type(std::ptrdiff_t n) noexcept
121  
to_size_type(std::ptrdiff_t n) noexcept
118  
{
122  
{
119  
    BOOST_ASSERT(n >= 0);
123  
    BOOST_ASSERT(n >= 0);
120  
    return to_size_type(
124  
    return to_size_type(
121  
        static_cast<std::size_t>(n));
125  
        static_cast<std::size_t>(n));
122  
}
126  
}
123  

127  

124  
//------------------------------------------------
128  
//------------------------------------------------
125  

129  

126  
// this allows a path to come from a
130  
// this allows a path to come from a
127  
// url_impl or a separate core::string_view
131  
// url_impl or a separate core::string_view
128 -
class path_ref
132 +
//
 
133 +
// Exported (BOOST_URL_DECL) so that public classes
 
134 +
// like segments_base and segments_encoded_base can
 
135 +
// hold a path_ref member without triggering C4251.
 
136 +
class BOOST_URL_DECL path_ref
129  
    : private parts_base
137  
    : private parts_base
130  
{
138  
{
131  
    url_impl const* impl_ = nullptr;
139  
    url_impl const* impl_ = nullptr;
132  
    char const* data_ = nullptr;
140  
    char const* data_ = nullptr;
133  
    std::size_t size_ = 0;
141  
    std::size_t size_ = 0;
134  
    std::size_t nseg_ = 0;
142  
    std::size_t nseg_ = 0;
135  
    std::size_t dn_ = 0;
143  
    std::size_t dn_ = 0;
136  

144  

137  
public:
145  
public:
138 -
    path_ref() = default;
146 +
    path_ref() noexcept;
139  
    path_ref(url_impl const& impl) noexcept;
147  
    path_ref(url_impl const& impl) noexcept;
140  
    path_ref(core::string_view,
148  
    path_ref(core::string_view,
141  
        std::size_t, std::size_t) noexcept;
149  
        std::size_t, std::size_t) noexcept;
142  
    pct_string_view buffer() const noexcept;
150  
    pct_string_view buffer() const noexcept;
143  
    std::size_t size() const noexcept;
151  
    std::size_t size() const noexcept;
144  
    char const* data() const noexcept;
152  
    char const* data() const noexcept;
145  
    char const* end() const noexcept;
153  
    char const* end() const noexcept;
146  
    std::size_t nseg() const noexcept;
154  
    std::size_t nseg() const noexcept;
147  
    std::size_t decoded_size() const noexcept;
155  
    std::size_t decoded_size() const noexcept;
148  

156  

149  
    bool
157  
    bool
150  
    alias_of(
158  
    alias_of(
151  
        url_impl const& impl) const noexcept
159  
        url_impl const& impl) const noexcept
152  
    {
160  
    {
153  
        return impl_ == &impl;
161  
        return impl_ == &impl;
154  
    }
162  
    }
155  

163  

156  
    bool
164  
    bool
157  
    alias_of(
165  
    alias_of(
158  
        path_ref const& ref) const noexcept
166  
        path_ref const& ref) const noexcept
159  
    {
167  
    {
160  
        if(impl_)
168  
        if(impl_)
161  
            return impl_ == ref.impl_;
169  
            return impl_ == ref.impl_;
162  
        BOOST_ASSERT(data_ != ref.data_ || (
170  
        BOOST_ASSERT(data_ != ref.data_ || (
163  
            size_ == ref.size_ &&
171  
            size_ == ref.size_ &&
164  
            nseg_ == ref.nseg_ &&
172  
            nseg_ == ref.nseg_ &&
165  
            dn_ == ref.dn_));
173  
            dn_ == ref.dn_));
166  
        return data_ == ref.data_;
174  
        return data_ == ref.data_;
167  
    }
175  
    }
168  
};
176  
};
169  

177  

170  
//------------------------------------------------
178  
//------------------------------------------------
171  

179  

172  
// This class represents a query string, which
180  
// This class represents a query string, which
173  
// can originate from either an url_impl object
181  
// can originate from either an url_impl object
174  
// or an independent core::string_view.
182  
// or an independent core::string_view.
175  
class BOOST_URL_DECL query_ref
183  
class BOOST_URL_DECL query_ref
176  
    : private parts_base
184  
    : private parts_base
177  
{
185  
{
178  
    url_impl const* impl_ = nullptr;
186  
    url_impl const* impl_ = nullptr;
179  
    char const* data_ = nullptr;
187  
    char const* data_ = nullptr;
180  
    std::size_t size_ = 0;
188  
    std::size_t size_ = 0;
181  
    std::size_t nparam_ = 0;
189  
    std::size_t nparam_ = 0;
182  
    std::size_t dn_ = 0;
190  
    std::size_t dn_ = 0;
183  
    bool question_mark_ = false;
191  
    bool question_mark_ = false;
184  

192  

185  
public:
193  
public:
186  
    query_ref(
194  
    query_ref(
187  
        core::string_view s,      // buffer, no '?'
195  
        core::string_view s,      // buffer, no '?'
188  
        std::size_t dn,     // decoded size
196  
        std::size_t dn,     // decoded size
189  
        std::size_t nparam
197  
        std::size_t nparam
190  
            ) noexcept;
198  
            ) noexcept;
191  
    query_ref() = default;
199  
    query_ref() = default;
192  
    query_ref(url_impl const& impl) noexcept;
200  
    query_ref(url_impl const& impl) noexcept;
193  
    pct_string_view buffer() const noexcept;
201  
    pct_string_view buffer() const noexcept;
194  
    std::size_t size() const noexcept; // with '?'
202  
    std::size_t size() const noexcept; // with '?'
195  
    char const* begin() const noexcept; // no '?'
203  
    char const* begin() const noexcept; // no '?'
196  
    char const* end() const noexcept;
204  
    char const* end() const noexcept;
197  
    std::size_t nparam() const noexcept;
205  
    std::size_t nparam() const noexcept;
198  

206  

199  
    bool
207  
    bool
200  
    alias_of(
208  
    alias_of(
201  
        url_impl const& impl) const noexcept
209  
        url_impl const& impl) const noexcept
202  
    {
210  
    {
203  
        return impl_ == &impl;
211  
        return impl_ == &impl;
204  
    }
212  
    }
205  

213  

206  
    bool
214  
    bool
207  
    alias_of(
215  
    alias_of(
208  
        query_ref const& ref) const noexcept
216  
        query_ref const& ref) const noexcept
209  
    {
217  
    {
210  
        if(impl_)
218  
        if(impl_)
211  
            return impl_ == ref.impl_;
219  
            return impl_ == ref.impl_;
212  
        BOOST_ASSERT(data_ != ref.data_ || (
220  
        BOOST_ASSERT(data_ != ref.data_ || (
213  
            size_ == ref.size_ &&
221  
            size_ == ref.size_ &&
214  
            nparam_ == ref.nparam_ &&
222  
            nparam_ == ref.nparam_ &&
215  
            dn_ == ref.dn_));
223  
            dn_ == ref.dn_));
216  
        return data_ == ref.data_;
224  
        return data_ == ref.data_;
217  
    }
225  
    }
218  
};
226  
};
219  

227  

220  
} // detail
228  
} // detail
221  

229  

222  
} // urls
230  
} // urls
223  
} // boost
231  
} // boost
 
232 +

 
233 +
// url_impl member definitions live in detail/impl/url_impl.hpp.
 
234 +
// Some of those definitions (construct_authority, apply_authority)
 
235 +
// need the complete authority_view type, and authority_view.hpp
 
236 +
// includes this header — creating a circular dependency.
 
237 +
// When authority_view.hpp is the includer, it defers this
 
238 +
// include until after authority_view is fully defined.
 
239 +
#ifndef BOOST_URL_AUTHORITY_VIEW_HPP
 
240 +
#include <boost/url/detail/impl/url_impl.hpp>
 
241 +
#endif
224  

242  

225  
#endif
243  
#endif