4#include "Stroika/Foundation/StroikaPreComp.h"
9#include "Stroika/Foundation/Characters/String2Int.h"
12#include "Stroika/Foundation/Execution/Exceptions.h"
13#include "Stroika/Foundation/Execution/Throw.h"
23using namespace Stroika::Foundation::IO;
37#if USE_NOISY_TRACE_IN_THIS_MODULE_
41 vector<String> segments;
44 if (c ==
'/' and not accumulatingSegment.
empty ()) {
45 segments.push_back (accumulatingSegment.
str ());
46 accumulatingSegment.clear ();
48 accumulatingSegment << c;
50 if (not accumulatingSegment.
empty ()) {
51 segments.push_back (accumulatingSegment.
str ());
53 vector<String> segments2;
54 bool lastSegmentShouldHaveSlash{
false};
55 for (
const String& segment : segments) {
56 lastSegmentShouldHaveSlash =
false;
57 if (segment ==
"."sv or segment ==
"/."sv) {
59 if (segment[0] ==
'/') {
60 lastSegmentShouldHaveSlash =
true;
63 else if (segment ==
".."sv or segment ==
"/.."sv) {
64 if (not segments2.empty ()) {
65 segments2.pop_back ();
67 if (segment[0] ==
'/') {
68 lastSegmentShouldHaveSlash =
true;
72 segments2.push_back (segment);
77 bool soFarEndsWithSlash =
false;
78 for (
const String& segment : segments2) {
79 if (normalization == URI::NormalizationStyle::eAggressive) {
80 if (segment.StartsWith (
'/') and soFarEndsWithSlash) {
82 if (not add.empty ()) {
84 soFarEndsWithSlash = add.
EndsWith (
'/');
89 soFarEndsWithSlash = segment.EndsWith (
'/');
96 if (lastSegmentShouldHaveSlash and not result.
str ().
EndsWith (
"/"sv)) {
105#if USE_NOISY_TRACE_IN_THIS_MODULE_
117 if (
not s->empty ()) {
136#if USE_NOISY_TRACE_IN_THIS_MODULE_
148 if (
not s->empty ()) {
165String URI::AsString_ (optional<StringPCTEncodedFlag> pctEncode)
const
169 AssertExternallySynchronizedChecker::ReadContext
declareContext{fThisAssertExternallySynchronized_};
175 Assert (fScheme_->All ([] (
Character c) { return c.IsASCII (); }));
176 result << *fScheme_ <<
":"sv;
194 .allowSubDelims =
false, .allowGenDelims =
false, .allowPChar =
true, .allowFragOrQueryChars =
false, .allowPathCharacters =
true};
200 .allowSubDelims =
false, .allowGenDelims =
false, .allowPChar =
false, .allowFragOrQueryChars =
true};
202 result <<
"?"sv << *fQuery_;
210 result <<
"#"sv << *fFragment_;
217 Ensure (result.
str ().
All ([] (
Character c) { return c.IsASCII (); }));
218 return result.
str ();
221URI::operator bool ()
const
223 AssertExternallySynchronizedChecker::ReadContext declareContext{fThisAssertExternallySynchronized_};
230 if (not fPath_.empty ()) {
244 AssertExternallySynchronizedChecker::ReadContext
declareContext{fThisAssertExternallySynchronized_};
253 AssertExternallySynchronizedChecker::ReadContext
declareContext{fThisAssertExternallySynchronized_};
269 AssertExternallySynchronizedChecker::ReadContext
declareContext{fThisAssertExternallySynchronized_};
272 result << *fScheme_ <<
":"sv;
275 result <<
"//"sv << fAuthority_->As<
String> ();
279 result <<
"?"sv << *fQuery_;
282 result <<
"#"sv << *fFragment_;
287void URI::CheckValidPathForAuthority_ (
const optional<Authority>& authority,
const String& path)
302 AssertExternallySynchronizedChecker::ReadContext
declareContext{fThisAssertExternallySynchronized_};
329 if (
baseURI.GetAuthority ()
and base.empty ()) {
367 result.SetAuthority (
baseURI.GetAuthority ());
387strong_ordering URI::TWC_ (
const URI& lhs,
const URI& rhs)
389 using namespace UniformResourceIdentification;
390 if (
auto cmp = Common::StdCompat::compare_three_way{}(
lhs.GetScheme (),
rhs.GetScheme ());
cmp != strong_ordering::equal) {
393 if (
auto cmp = Common::StdCompat::compare_three_way{}(
lhs.GetAuthority (),
rhs.GetAuthority ());
cmp != strong_ordering::equal) {
396 if (
auto cmp = Common::StdCompat::compare_three_way{}(
lhs.GetPath (),
rhs.GetPath ());
cmp != strong_ordering::equal) {
399 if (
auto cmp = Common::StdCompat::compare_three_way{}(
lhs.GetQuery (),
rhs.GetQuery ());
cmp != strong_ordering::equal) {
402 if (
auto cmp = Common::StdCompat::compare_three_way{}(
lhs.GetFragment (),
rhs.GetFragment ());
cmp != strong_ordering::equal) {
405 return strong_ordering::equal;
RegularExpression is a compiled regular expression which can be used to match on a String class.
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
nonvirtual bool empty() const noexcept
nonvirtual String str() const
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual bool Matches(const RegularExpression ®Ex) const
nonvirtual bool EndsWith(const Character &c, CompareOptions co=eWithCase) const
nonvirtual String SubString(SZ from) const
nonvirtual bool StartsWith(const Character &c, CompareOptions co=eWithCase) const
NOT a real mutex - just a debugging infrastructure support tool so in debug builds can be assured thr...
nonvirtual String GetAuthorityRelativeResourceDir() const
Return the path component, excluding any text after the final /.
static URI Parse(const String &rawURL)
nonvirtual String ToString() const
nonvirtual T As(optional< StringPCTEncodedFlag > pctEncoded={}) const
nonvirtual void SetPath(const String &path)
nonvirtual URI Combine(const URI &overridingURI) const
Combine overridingURI possibly relative url with this base url, to produce a new URI.
static URI ParseRelative(const String &rawRelativeURL)
nonvirtual URI Normalize(NormalizationStyle normalization=NormalizationStyle::eDefault) const
Produce a normalized representation of the URI.
nonvirtual void SetScheme(const optional< SchemeType > &scheme)
nonvirtual bool All(const function< bool(ArgByValueType< T >)> &testEachElt) const
return true iff argument predicate returns true for each element of the iterable
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...