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

9  

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

12  

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

20  

21  
namespace boost {
21  
namespace boost {
22  
namespace urls {
22  
namespace urls {
23  

23  

24  
class url_view;
24  
class url_view;
25  
class authority_view;
25  
class authority_view;
26  

26  

27  
namespace detail {
27  
namespace detail {
28  

28  

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

30  

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

42  

43  
    // never nullptr
43  
    // never nullptr
44  
    char const* cs_ = empty_c_str_;
44  
    char const* cs_ = empty_c_str_;
45  

45  

46  
    std::size_t offset_[id_end + 1] = {};
46  
    std::size_t offset_[id_end + 1] = {};
47  
    std::size_t decoded_[id_end] = {};
47  
    std::size_t decoded_[id_end] = {};
48  
    std::size_t nseg_ = 0;
48  
    std::size_t nseg_ = 0;
49  
    std::size_t nparam_ = 0;
49  
    std::size_t nparam_ = 0;
50  
    unsigned char ip_addr_[16] = {};
50  
    unsigned char ip_addr_[16] = {};
51  
    // VFALCO don't we need a bool?
51  
    // VFALCO don't we need a bool?
52  
    std::uint16_t port_number_ = 0;
52  
    std::uint16_t port_number_ = 0;
53  
    host_type host_type_ =
53  
    host_type host_type_ =
54  
        urls::host_type::none;
54  
        urls::host_type::none;
55  
    scheme scheme_ =
55  
    scheme scheme_ =
56  
        urls::scheme::none;
56  
        urls::scheme::none;
57  

57  

58  
    from from_ = from::string;
58  
    from from_ = from::string;
59  

59  

60  
    url_impl(
60  
    url_impl(
61  
        from b) noexcept
61  
        from b) noexcept
62  
        : from_(b)
62  
        : from_(b)
63  
    {
63  
    {
64  
    }
64  
    }
65  

65  

66  
    // in url_view.ipp
66  
    // in url_view.ipp
67  
    url_view construct() const noexcept;
67  
    url_view construct() const noexcept;
68  

68  

69  
    // in authority_view.ipp
69  
    // in authority_view.ipp
70  
    authority_view
70  
    authority_view
71  
    construct_authority() const noexcept;
71  
    construct_authority() const noexcept;
72  

72  

73  
    std::size_t len(int, int) const noexcept;
73  
    std::size_t len(int, int) const noexcept;
74  
    std::size_t len(int) const noexcept;
74  
    std::size_t len(int) const noexcept;
75  
    std::size_t offset(int) const noexcept;
75  
    std::size_t offset(int) const noexcept;
76  
    core::string_view get(int) const noexcept;
76  
    core::string_view get(int) const noexcept;
77  
    core::string_view get(int, int) const noexcept;
77  
    core::string_view get(int, int) const noexcept;
78  
    pct_string_view pct_get(int) const noexcept;
78  
    pct_string_view pct_get(int) const noexcept;
79  
    pct_string_view pct_get(int, int) const noexcept;
79  
    pct_string_view pct_get(int, int) const noexcept;
80  
    void set_size(int, std::size_t) noexcept;
80  
    void set_size(int, std::size_t) noexcept;
81  
    void split(int, std::size_t) noexcept;
81  
    void split(int, std::size_t) noexcept;
82  
    void adjust_right(int first, int last, std::size_t n) noexcept;
82  
    void adjust_right(int first, int last, std::size_t n) noexcept;
83  
    void adjust_left(int first, int last, std::size_t n) noexcept;
83  
    void adjust_left(int first, int last, std::size_t n) noexcept;
84  
    void collapse(int, int, std::size_t) noexcept;
84  
    void collapse(int, int, std::size_t) noexcept;
85  

85  

86  
    void apply_scheme(core::string_view) noexcept;
86  
    void apply_scheme(core::string_view) noexcept;
87  
    void apply_userinfo(pct_string_view const&,
87  
    void apply_userinfo(pct_string_view const&,
88  
        pct_string_view const*) noexcept;
88  
        pct_string_view const*) noexcept;
89  
    void apply_host(host_type, pct_string_view,
89  
    void apply_host(host_type, pct_string_view,
90  
        unsigned char const*) noexcept;
90  
        unsigned char const*) noexcept;
91  
    void apply_port(core::string_view, unsigned short) noexcept;
91  
    void apply_port(core::string_view, unsigned short) noexcept;
92  
    void apply_authority(authority_view const&) noexcept;
92  
    void apply_authority(authority_view const&) noexcept;
93  
    void apply_path(pct_string_view, std::size_t) noexcept;
93  
    void apply_path(pct_string_view, std::size_t) noexcept;
94  
    void apply_query(pct_string_view, std::size_t) noexcept;
94  
    void apply_query(pct_string_view, std::size_t) noexcept;
95  
    void apply_frag(pct_string_view) noexcept;
95  
    void apply_frag(pct_string_view) noexcept;
96  
};
96  
};
97  

97  

98  
//------------------------------------------------
98  
//------------------------------------------------
99  

99  

100  
// this allows a path to come from a
100  
// this allows a path to come from a
101  
// url_impl or a separate core::string_view
101  
// url_impl or a separate core::string_view
102  
class path_ref
102  
class path_ref
103  
    : private parts_base
103  
    : private parts_base
104  
{
104  
{
105  
    url_impl const* impl_ = nullptr;
105  
    url_impl const* impl_ = nullptr;
106  
    char const* data_ = nullptr;
106  
    char const* data_ = nullptr;
107  
    std::size_t size_ = 0;
107  
    std::size_t size_ = 0;
108  
    std::size_t nseg_ = 0;
108  
    std::size_t nseg_ = 0;
109  
    std::size_t dn_ = 0;
109  
    std::size_t dn_ = 0;
110  

110  

111  
public:
111  
public:
112  
    path_ref() = default;
112  
    path_ref() = default;
113  
    path_ref(url_impl const& impl) noexcept;
113  
    path_ref(url_impl const& impl) noexcept;
114  
    path_ref(core::string_view,
114  
    path_ref(core::string_view,
115  
        std::size_t, std::size_t) noexcept;
115  
        std::size_t, std::size_t) noexcept;
116  
    pct_string_view buffer() const noexcept;
116  
    pct_string_view buffer() const noexcept;
117  
    std::size_t size() const noexcept;
117  
    std::size_t size() const noexcept;
118  
    char const* data() const noexcept;
118  
    char const* data() const noexcept;
119  
    char const* end() const noexcept;
119  
    char const* end() const noexcept;
120  
    std::size_t nseg() const noexcept;
120  
    std::size_t nseg() const noexcept;
121  
    std::size_t decoded_size() const noexcept;
121  
    std::size_t decoded_size() const noexcept;
122  

122  

123  
    bool
123  
    bool
124  
    alias_of(
124  
    alias_of(
125  
        url_impl const& impl) const noexcept
125  
        url_impl const& impl) const noexcept
126  
    {
126  
    {
127  
        return impl_ == &impl;
127  
        return impl_ == &impl;
128  
    }
128  
    }
129  

129  

130  
    bool
130  
    bool
131  
    alias_of(
131  
    alias_of(
132  
        path_ref const& ref) const noexcept
132  
        path_ref const& ref) const noexcept
133  
    {
133  
    {
134  
        if(impl_)
134  
        if(impl_)
135  
            return impl_ == ref.impl_;
135  
            return impl_ == ref.impl_;
136  
        BOOST_ASSERT(data_ != ref.data_ || (
136  
        BOOST_ASSERT(data_ != ref.data_ || (
137  
            size_ == ref.size_ &&
137  
            size_ == ref.size_ &&
138  
            nseg_ == ref.nseg_ &&
138  
            nseg_ == ref.nseg_ &&
139  
            dn_ == ref.dn_));
139  
            dn_ == ref.dn_));
140  
        return data_ == ref.data_;
140  
        return data_ == ref.data_;
141  
    }
141  
    }
142  
};
142  
};
143  

143  

144  
//------------------------------------------------
144  
//------------------------------------------------
145  

145  

146  
// This class represents a query string, which
146  
// This class represents a query string, which
147  
// can originate from either an url_impl object
147  
// can originate from either an url_impl object
148  
// or an independent core::string_view.
148  
// or an independent core::string_view.
149  
class BOOST_URL_DECL query_ref
149  
class BOOST_URL_DECL query_ref
150  
    : private parts_base
150  
    : private parts_base
151  
{
151  
{
152  
    url_impl const* impl_ = nullptr;
152  
    url_impl const* impl_ = nullptr;
153  
    char const* data_ = nullptr;
153  
    char const* data_ = nullptr;
154  
    std::size_t size_ = 0;
154  
    std::size_t size_ = 0;
155  
    std::size_t nparam_ = 0;
155  
    std::size_t nparam_ = 0;
156  
    std::size_t dn_ = 0;
156  
    std::size_t dn_ = 0;
157  
    bool question_mark_ = false;
157  
    bool question_mark_ = false;
158  

158  

159  
public:
159  
public:
160  
    query_ref(
160  
    query_ref(
161  
        core::string_view s,      // buffer, no '?'
161  
        core::string_view s,      // buffer, no '?'
162  
        std::size_t dn,     // decoded size
162  
        std::size_t dn,     // decoded size
163  
        std::size_t nparam
163  
        std::size_t nparam
164  
            ) noexcept;
164  
            ) noexcept;
165  
    query_ref() = default;
165  
    query_ref() = default;
166  
    query_ref(url_impl const& impl) noexcept;
166  
    query_ref(url_impl const& impl) noexcept;
167  
    pct_string_view buffer() const noexcept;
167  
    pct_string_view buffer() const noexcept;
168  
    std::size_t size() const noexcept; // with '?'
168  
    std::size_t size() const noexcept; // with '?'
169  
    char const* begin() const noexcept; // no '?'
169  
    char const* begin() const noexcept; // no '?'
170  
    char const* end() const noexcept;
170  
    char const* end() const noexcept;
171  
    std::size_t nparam() const noexcept;
171  
    std::size_t nparam() const noexcept;
172  

172  

173  
    bool
173  
    bool
174  
    alias_of(
174  
    alias_of(
175  
        url_impl const& impl) const noexcept
175  
        url_impl const& impl) const noexcept
176  
    {
176  
    {
177  
        return impl_ == &impl;
177  
        return impl_ == &impl;
178  
    }
178  
    }
179  

179  

180  
    bool
180  
    bool
181  
    alias_of(
181  
    alias_of(
182  
        query_ref const& ref) const noexcept
182  
        query_ref const& ref) const noexcept
183  
    {
183  
    {
184  
        if(impl_)
184  
        if(impl_)
185  
            return impl_ == ref.impl_;
185  
            return impl_ == ref.impl_;
186  
        BOOST_ASSERT(data_ != ref.data_ || (
186  
        BOOST_ASSERT(data_ != ref.data_ || (
187  
            size_ == ref.size_ &&
187  
            size_ == ref.size_ &&
188  
            nparam_ == ref.nparam_ &&
188  
            nparam_ == ref.nparam_ &&
189  
            dn_ == ref.dn_));
189  
            dn_ == ref.dn_));
190  
        return data_ == ref.data_;
190  
        return data_ == ref.data_;
191  
    }
191  
    }
192  
};
192  
};
193  

193  

194  
} // detail
194  
} // detail
195  

195  

196  
} // urls
196  
} // urls
197  
} // boost
197  
} // boost
198  

198  

199  
#endif
199  
#endif