UriComponents.hpp
Go to the documentation of this file.
1 // @formatter:off
2 //
3 // Balau core C++ library
4 //
5 // Copyright (C) 2008 Bora Software (contact@borasoftware.com)
6 //
7 // Licensed under the Boost Software License - Version 1.0 - August 17th, 2003.
8 // See the LICENSE file for the full license text.
9 //
10 
16 
17 #ifndef COM_BORA_SOFTWARE__BALAU_RESOURCE__URI_COMPONENTS
18 #define COM_BORA_SOFTWARE__BALAU_RESOURCE__URI_COMPONENTS
19 
20 #include <Balau/Dev/Assert.hpp>
21 #include <Balau/Type/ToString.hpp>
22 
23 namespace Balau::Resource {
24 
25 class Uri;
26 
52 struct UriComponents {
59  public: static std::string normalizePath(std::string_view path);
60 
64  public: const std::string & getUri() const {
65  return uri;
66  }
67 
79  public: explicit UriComponents(const Uri & uri_);
80 
92  public: explicit UriComponents(std::string uri_);
93 
97  public: UriComponents(const UriComponents & ) = default;
98 
102  public: UriComponents(UriComponents && ) = default;
103 
109  public: UriComponents & operator = (const UriComponents & ) = default;
110 
116  public: UriComponents & operator = (UriComponents && ) = default;
117 
123  public: bool hasAuthority() const {
124  return hostOffset != -1;
125  }
126 
132  public: bool hasUserInfo() const {
133  return userinfoOffset != -1;
134  }
135 
141  public: bool hasHost() const {
142  return hostOffset != -1;
143  }
144 
150  public: bool hasPort() const {
151  return portOffset != -1;
152  }
153 
159  public: bool hasQuery() const {
160  return queryOffset != -1;
161  }
162 
168  public: bool hasFragment() const {
169  return fragmentOffset != -1;
170  }
171 
177  public: std::string_view scheme() const {
178  return std::string_view(uri.c_str(), (size_t) schemeEndOffset);
179  }
180 
188  public: std::string_view userInfo() const {
189  if (!hasUserInfo()) {
190  return std::string_view();
191  }
192 
193  const int endOffset = hostOffset - 1; // "@"
194  Assert::assertion(endOffset > 0);
195  return std::string_view(uri.c_str() + userinfoOffset, (size_t) (endOffset - userinfoOffset));
196  }
197 
205  public: std::string_view host() const {
206  if (!hasHost()) {
207  return std::string_view();
208  }
209 
210  const int endOffset = hasPort()
211  ? portOffset - 1 // ":"
212  : pathOffset;
213 
214  Assert::assertion(endOffset > 0);
215  return std::string_view(uri.c_str() + hostOffset, (size_t) (endOffset - hostOffset));
216  }
217 
223  public: unsigned short port() const {
224  return parsedPort;
225  }
226 
234  public: std::string_view path() const {
235  const int endOffset = hasQuery()
236  ? queryOffset - 1 // "?"
237  : hasFragment()
238  ? fragmentOffset - 1 // "#"
239  : (int) uri.length();
240 
241  Assert::assertion(endOffset > 0);
242  return std::string_view(uri.c_str() + pathOffset, (size_t) (endOffset - pathOffset));
243  }
244 
252  public: std::string_view query() const {
253  if (!hasQuery()) {
254  return std::string_view();
255  }
256 
257  const int endOffset = hasFragment()
258  ? fragmentOffset - 1 // "#"
259  : (int) uri.length();
260 
261  Assert::assertion(endOffset > 0);
262  return std::string_view(uri.c_str() + queryOffset, (size_t) (endOffset - queryOffset));
263  }
264 
272  public: std::string_view fragment() const {
273  if (!hasFragment()) {
274  return std::string_view();
275  }
276 
277  return std::string_view(uri.c_str() + fragmentOffset, (size_t) (uri.length() - fragmentOffset));
278  }
279 
287  public: std::string_view pathQueryFragment() const {
288  return std::string_view(uri.c_str() + pathOffset, (size_t) (uri.length() - pathOffset));
289  }
290 
292 
293  friend struct UriComponentsTest;
294 
295  // For testing.
296  private: UriComponents(std::string uri_,
297  short schemeEndOffset_,
298  short userinfoOffset_,
299  short hostOffset_,
300  short portOffset_,
301  short pathOffset_,
302  short queryOffset_,
303  short fragmentOffset_,
304  unsigned short parsedPort_)
305  : uri(std::move(uri_))
306  , schemeEndOffset(schemeEndOffset_)
307  , userinfoOffset(userinfoOffset_)
308  , hostOffset(hostOffset_)
309  , portOffset(portOffset_)
310  , pathOffset(pathOffset_)
311  , queryOffset(queryOffset_)
312  , fragmentOffset(fragmentOffset_)
313  , parsedPort(parsedPort_) {}
314 
315  private: std::string uri;
316  private: short schemeEndOffset;
317  private: short userinfoOffset;
318  private: short hostOffset;
319  private: short portOffset;
320  private: short pathOffset;
321  private: short queryOffset;
322  private: short fragmentOffset;
323  private: unsigned short parsedPort;
324 
325  friend bool operator == (const UriComponents & lhs, const UriComponents & rhs);
326 };
327 
335 inline bool operator == (const UriComponents & lhs, const UriComponents & rhs) {
336  return lhs.uri == rhs.uri;
337 }
338 
346 template <typename AllocatorT>
347 inline Balau::U8String<AllocatorT> toString(const UriComponents & uriComponents) {
348  return toString<AllocatorT>(uriComponents.getUri());
349 }
350 
358 inline std::string toString(const UriComponents & uriComponents) {
359  return uriComponents.getUri();
360 }
361 
362 } // namespace Balau::Resource
363 
364 #endif // COM_BORA_SOFTWARE__BALAU_RESOURCE__URI_COMPONENTS
Pre-defined universal to-string functions.
friend bool operator==(const UriComponents &lhs, const UriComponents &rhs)
Returns true if the two URI component instances are equal.
Definition: UriComponents.hpp:335
const std::string & getUri() const
Get the URI string contained within the URI component structure.
Definition: UriComponents.hpp:64
std::string_view fragment() const
Obtain a string view to the fragment.
Definition: UriComponents.hpp:272
unsigned short port() const
Obtain the port.
Definition: UriComponents.hpp:223
An abstract universal resource identifier.
Definition: Uri.hpp:131
UriComponents(const Uri &uri_)
Parse the URI into its components.
UriComponents & operator=(const UriComponents &)=default
Assign a URI components instance by copying the supplied instance.
The unified resource class hierarchy.
Definition: ByteReadResource.hpp:24
std::string_view query() const
Obtain a string view to the query.
Definition: UriComponents.hpp:252
bool hasFragment() const
Returns true if the URI has a fragment.
Definition: UriComponents.hpp:168
std::string_view host() const
Obtain a string view to the host.
Definition: UriComponents.hpp:205
Balau::U8String< AllocatorT > toString(const File &file)
Print the file URI as a UTF-8 string.
Definition: File.hpp:724
static std::string normalizePath(std::string_view path)
Remove instances of "." and "blah/.." and remove any trailing slashes.
bool hasUserInfo() const
Returns true if the URI has user info.
Definition: UriComponents.hpp:132
bool hasAuthority() const
Returns true if the URI has an authority section.
Definition: UriComponents.hpp:123
bool hasHost() const
Returns true if the URI has a host entry.
Definition: UriComponents.hpp:141
std::string_view userInfo() const
Obtain a string view to the user info.
Definition: UriComponents.hpp:188
Assertion utilities for development purposes.
std::basic_string< char, std::char_traits< char >, AllocatorT > U8String
UTF-8 string type with selectable allocator.
Definition: ToStringA.hpp:41
std::string_view pathQueryFragment() const
Obtain a string view to the path-query-fragment.
Definition: UriComponents.hpp:287
std::string_view scheme() const
Obtain a string view to the scheme.
Definition: UriComponents.hpp:177
bool hasQuery() const
Returns true if the URI has a query.
Definition: UriComponents.hpp:159
std::string_view path() const
Obtain a string view to the path.
Definition: UriComponents.hpp:234
bool hasPort() const
Returns true if the URI has port information.
Definition: UriComponents.hpp:150
static void assertion(bool test, StringFunctionT function)
If the bug test assertion fails, abort after logging the message supplied by the function.
Definition: Assert.hpp:49
Parses a URI and provides views into the URI&#39;s components.
Definition: UriComponents.hpp:52