1  
//
1  
//
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// 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)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_URL_DETAIL_NORMALIZED_HPP
11  
#ifndef BOOST_URL_DETAIL_NORMALIZED_HPP
12  
#define BOOST_URL_DETAIL_NORMALIZED_HPP
12  
#define BOOST_URL_DETAIL_NORMALIZED_HPP
13  

13  

14  
#include <boost/core/detail/string_view.hpp>
14  
#include <boost/core/detail/string_view.hpp>
15  
#include "boost/url/segments_encoded_view.hpp"
15  
#include "boost/url/segments_encoded_view.hpp"
16  

16  

17  
namespace boost {
17  
namespace boost {
18  
namespace urls {
18  
namespace urls {
19  
namespace detail {
19  
namespace detail {
20  

20  

21  
class fnv_1a
21  
class fnv_1a
22  
{
22  
{
23  
public:
23  
public:
24  
    using digest_type = std::size_t;
24  
    using digest_type = std::size_t;
25  

25  

26  
#if BOOST_URL_ARCH == 64
26  
#if BOOST_URL_ARCH == 64
27  
    static constexpr std::size_t const prime =
27  
    static constexpr std::size_t const prime =
28  
        static_cast<std::size_t>(0x100000001B3ULL);
28  
        static_cast<std::size_t>(0x100000001B3ULL);
29  
    static constexpr std::size_t init_hash  =
29  
    static constexpr std::size_t init_hash  =
30  
        static_cast<std::size_t>(0xcbf29ce484222325ULL);
30  
        static_cast<std::size_t>(0xcbf29ce484222325ULL);
31  
#else
31  
#else
32  
    static constexpr std::size_t const prime =
32  
    static constexpr std::size_t const prime =
33  
        static_cast<std::size_t>(0x01000193UL);
33  
        static_cast<std::size_t>(0x01000193UL);
34  
    static constexpr std::size_t init_hash  =
34  
    static constexpr std::size_t init_hash  =
35  
        static_cast<std::size_t>(0x811C9DC5UL);
35  
        static_cast<std::size_t>(0x811C9DC5UL);
36  
#endif
36  
#endif
37  

37  

38  
    explicit
38  
    explicit
39  
    fnv_1a(std::size_t salt) noexcept
39  
    fnv_1a(std::size_t salt) noexcept
40  
    : h_(init_hash + salt)
40  
    : h_(init_hash + salt)
41  
    {
41  
    {
42  
    }
42  
    }
43  

43  

44  
    void
44  
    void
45  
    put(char c) noexcept
45  
    put(char c) noexcept
46  
    {
46  
    {
47  
        h_ ^= c;
47  
        h_ ^= c;
48  
        h_ *= prime;
48  
        h_ *= prime;
49  
    }
49  
    }
50  

50  

51  
    void
51  
    void
52  
    put(core::string_view s) noexcept
52  
    put(core::string_view s) noexcept
53  
    {
53  
    {
54  
        for (char c: s)
54  
        for (char c: s)
55  
        {
55  
        {
56  
            put(c);
56  
            put(c);
57  
        }
57  
        }
58  
    }
58  
    }
59  

59  

60  
    digest_type
60  
    digest_type
61  
    digest() const noexcept
61  
    digest() const noexcept
62  
    {
62  
    {
63  
        return h_;
63  
        return h_;
64  
    }
64  
    }
65  

65  

66  
private:
66  
private:
67  
    std::size_t h_;
67  
    std::size_t h_;
68  
};
68  
};
69  

69  

70  
void
70  
void
71  
pop_encoded_front(
71  
pop_encoded_front(
72  
    core::string_view& s,
72  
    core::string_view& s,
73  
    char& c,
73  
    char& c,
74  
    std::size_t& n) noexcept;
74  
    std::size_t& n) noexcept;
75  

75  

76  
// compare two core::string_views as if they are both
76  
// compare two core::string_views as if they are both
77  
// percent-decoded
77  
// percent-decoded
78  
int
78  
int
79  
compare_encoded(
79  
compare_encoded(
80  
    core::string_view lhs,
80  
    core::string_view lhs,
81  
    core::string_view rhs) noexcept;
81  
    core::string_view rhs) noexcept;
82  

82  

83  
// compare two core::string_views as if they are both
83  
// compare two core::string_views as if they are both
84  
// percent-decoded but do not consider the special
84  
// percent-decoded but do not consider the special
85  
// query chars ("&=+") equivalent unless they are
85  
// query chars ("&=+") equivalent unless they are
86  
// both decoded or encoded the same way, because
86  
// both decoded or encoded the same way, because
87  
// that gives them different meanings
87  
// that gives them different meanings
88  
int
88  
int
89  
compare_encoded_query(
89  
compare_encoded_query(
90  
    core::string_view lhs,
90  
    core::string_view lhs,
91  
    core::string_view rhs) noexcept;
91  
    core::string_view rhs) noexcept;
92  

92  

93  
// digest a core::string_view as if it were
93  
// digest a core::string_view as if it were
94  
// percent-decoded
94  
// percent-decoded
95  
void
95  
void
96  
digest_encoded(
96  
digest_encoded(
97  
    core::string_view s,
97  
    core::string_view s,
98  
    fnv_1a& hasher) noexcept;
98  
    fnv_1a& hasher) noexcept;
99  

99  

100  
void
100  
void
101  
digest(
101  
digest(
102  
    core::string_view s,
102  
    core::string_view s,
103  
    fnv_1a& hasher) noexcept;
103  
    fnv_1a& hasher) noexcept;
104  

104  

105  
// check if core::string_view lhs starts with core::string_view
105  
// check if core::string_view lhs starts with core::string_view
106  
// rhs as if they are both percent-decoded. If
106  
// rhs as if they are both percent-decoded. If
107  
// lhs starts with rhs, return number of chars
107  
// lhs starts with rhs, return number of chars
108  
// matched in the encoded core::string_view
108  
// matched in the encoded core::string_view
109  
std::size_t
109  
std::size_t
110  
path_starts_with(
110  
path_starts_with(
111  
    core::string_view lhs,
111  
    core::string_view lhs,
112  
    core::string_view rhs) noexcept;
112  
    core::string_view rhs) noexcept;
113  

113  

114  
// check if core::string_view lhs ends with core::string_view
114  
// check if core::string_view lhs ends with core::string_view
115  
// rhs as if they are both percent-decoded. If
115  
// rhs as if they are both percent-decoded. If
116  
// lhs ends with rhs, return number of chars
116  
// lhs ends with rhs, return number of chars
117  
// matched in the encoded core::string_view
117  
// matched in the encoded core::string_view
118  
std::size_t
118  
std::size_t
119  
path_ends_with(
119  
path_ends_with(
120  
    core::string_view lhs,
120  
    core::string_view lhs,
121  
    core::string_view rhs) noexcept;
121  
    core::string_view rhs) noexcept;
122  

122  

123  
// compare two core::string_views as if they are both
123  
// compare two core::string_views as if they are both
124  
// percent-decoded and lowercase
124  
// percent-decoded and lowercase
125  
int
125  
int
126  
ci_compare_encoded(
126  
ci_compare_encoded(
127  
    core::string_view lhs,
127  
    core::string_view lhs,
128  
    core::string_view rhs) noexcept;
128  
    core::string_view rhs) noexcept;
129  

129  

130  
// digest a core::string_view as if it were decoded
130  
// digest a core::string_view as if it were decoded
131  
// and lowercase
131  
// and lowercase
132  
void
132  
void
133  
ci_digest_encoded(
133  
ci_digest_encoded(
134  
    core::string_view s,
134  
    core::string_view s,
135  
    fnv_1a& hasher) noexcept;
135  
    fnv_1a& hasher) noexcept;
136  

136  

137  
// compare two ascii core::string_views
137  
// compare two ascii core::string_views
138  
int
138  
int
139  
compare(
139  
compare(
140  
    core::string_view lhs,
140  
    core::string_view lhs,
141  
    core::string_view rhs) noexcept;
141  
    core::string_view rhs) noexcept;
142  

142  

143  
// compare two core::string_views as if they are both
143  
// compare two core::string_views as if they are both
144  
// lowercase
144  
// lowercase
145  
int
145  
int
146  
ci_compare(
146  
ci_compare(
147  
    core::string_view lhs,
147  
    core::string_view lhs,
148  
    core::string_view rhs) noexcept;
148  
    core::string_view rhs) noexcept;
149  

149  

150  
// digest a core::string_view as if it were lowercase
150  
// digest a core::string_view as if it were lowercase
151  
void
151  
void
152  
ci_digest(
152  
ci_digest(
153  
    core::string_view s,
153  
    core::string_view s,
154  
    fnv_1a& hasher) noexcept;
154  
    fnv_1a& hasher) noexcept;
155  

155  

156  
BOOST_URL_DECL
156  
BOOST_URL_DECL
157  
std::size_t
157  
std::size_t
158  
remove_dot_segments(
158  
remove_dot_segments(
159  
    char* dest,
159  
    char* dest,
160  
    char const* end,
160  
    char const* end,
161  
    core::string_view input) noexcept;
161  
    core::string_view input) noexcept;
162  

162  

163  
void
163  
void
164  
pop_last_segment(
164  
pop_last_segment(
165  
    core::string_view& str,
165  
    core::string_view& str,
166  
    core::string_view& seg,
166  
    core::string_view& seg,
167  
    std::size_t& level,
167  
    std::size_t& level,
168  
    bool remove_unmatched) noexcept;
168  
    bool remove_unmatched) noexcept;
169  

169  

170  
char
170  
char
171  
path_pop_back( core::string_view& s );
171  
path_pop_back( core::string_view& s );
172  

172  

173  
void
173  
void
174  
normalized_path_digest(
174  
normalized_path_digest(
175  
    core::string_view str,
175  
    core::string_view str,
176  
    bool remove_unmatched,
176  
    bool remove_unmatched,
177  
    fnv_1a& hasher) noexcept;
177  
    fnv_1a& hasher) noexcept;
178  

178  

179  
int
179  
int
180  
segments_compare(
180  
segments_compare(
181  
    segments_encoded_view seg0,
181  
    segments_encoded_view seg0,
182  
    segments_encoded_view seg1) noexcept;
182  
    segments_encoded_view seg1) noexcept;
183  

183  

184  
} // detail
184  
} // detail
185  
} // urls
185  
} // urls
186  
} // boost
186  
} // boost
187  

187  

188  
#endif
188  
#endif