1 | // |
2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) |
3 | // |
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) |
6 | // |
7 | // Official repository: https://github.com/boostorg/url |
8 | // |
9 | |
10 | #ifndef BOOST_URL_DETAIL_PATH_HPP |
11 | #define BOOST_URL_DETAIL_PATH_HPP |
12 | |
13 | #include <boost/core/detail/string_view.hpp> |
14 | |
15 | namespace boost { |
16 | namespace urls { |
17 | namespace detail { |
18 | |
19 | // Return the number of characters at |
20 | // the front of the path that are reserved |
21 | inline |
22 | std::size_t |
23 | path_prefix( |
24 | char const* p, |
25 | std::size_t n) noexcept |
26 | { |
27 | switch(n) |
28 | { |
29 | case 0: |
30 | return 0; |
31 | |
32 | case 1: |
33 | if(p[0] == '/') |
34 | return 1; |
35 | return 0; |
36 | |
37 | case 2: |
38 | if(p[0] == '/') |
39 | return 1; |
40 | if( p[0] == '.' && |
41 | p[1] == '/') |
42 | return 2; |
43 | return 0; |
44 | |
45 | default: |
46 | if(p[0] == '/') |
47 | { |
48 | if( p[1] == '.' && |
49 | p[2] == '/') |
50 | return 3; |
51 | return 1; |
52 | } |
53 | if( p[0] == '.' && |
54 | p[1] == '/') |
55 | return 2; |
56 | break; |
57 | } |
58 | return 0; |
59 | } |
60 | |
61 | // VFALCO DEPRECATED |
62 | inline |
63 | std::size_t |
64 | path_prefix( |
65 | core::string_view s) noexcept |
66 | { |
67 | return path_prefix( |
68 | p: s.data(), n: s.size()); |
69 | } |
70 | |
71 | // returns the number of adjusted |
72 | // segments based on the malleable prefix. |
73 | inline |
74 | std::size_t |
75 | path_segments( |
76 | core::string_view s, |
77 | std::size_t nseg) noexcept |
78 | { |
79 | switch(s.size()) |
80 | { |
81 | case 0: |
82 | BOOST_ASSERT(nseg == 0); |
83 | return 0; |
84 | |
85 | case 1: |
86 | BOOST_ASSERT(nseg == 1); |
87 | if(s[0] == '/') |
88 | return 0; |
89 | return 1; |
90 | |
91 | case 2: |
92 | if(s[0] == '/') |
93 | return nseg; |
94 | if( s[0] == '.' && |
95 | s[1] == '/') |
96 | { |
97 | BOOST_ASSERT(nseg > 1); |
98 | return nseg - 1; |
99 | } |
100 | return nseg; |
101 | |
102 | default: |
103 | if(s[0] == '/') |
104 | { |
105 | if( s[1] == '.' && |
106 | s[2] == '/') |
107 | { |
108 | BOOST_ASSERT(nseg > 1); |
109 | return nseg - 1; |
110 | } |
111 | return nseg; |
112 | } |
113 | if( s[0] == '.' && |
114 | s[1] == '/') |
115 | { |
116 | BOOST_ASSERT(nseg > 1); |
117 | return nseg - 1; |
118 | } |
119 | break; |
120 | } |
121 | return nseg; |
122 | } |
123 | |
124 | // Trim reserved characters from |
125 | // the front of the path. |
126 | inline |
127 | core::string_view |
128 | clean_path( |
129 | core::string_view s) noexcept |
130 | { |
131 | s.remove_prefix( |
132 | n: path_prefix(s)); |
133 | return s; |
134 | } |
135 | |
136 | } // detail |
137 | } // urls |
138 | } // boost |
139 | |
140 | #endif |