Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
URI.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
6
7 /*
8 ********************************************************************************
9 *************************************** URI ************************************
10 ********************************************************************************
11 */
12 inline URI::URI (const optional<SchemeType>& scheme, const optional<Authority>& authority, const String& path,
13 const optional<String>& query, const optional<String>& fragment)
14 : fScheme_{scheme}
15 , fAuthority_{authority}
16 , fPath_{path}
17 , fQuery_{query}
18 , fFragment_{fragment}
19 {
20 // @todo probably validate query and fragment args?? Maybe not needed (if not document why)
21 if (scheme) {
22 scheme->Validate ();
23 }
24 CheckValidPathForAuthority_ (authority, path);
25 }
26 template <Characters::IConvertibleToString STRISH_TYPE>
27 inline URI::URI (STRISH_TYPE&& encodedURI)
28 : URI{Parse (forward<STRISH_TYPE> (encodedURI))}
29 {
30 }
31 inline bool URI::IsRelativeReference () const
32 {
33 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
34 return fScheme_.has_value ();
35 }
36 inline optional<URI::SchemeType> URI::GetScheme () const
37 {
38 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
39 return fScheme_;
40 }
41 inline void URI::SetScheme (const optional<SchemeType>& scheme)
42 {
43 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
44 if (scheme) {
45 scheme->Validate ();
46 }
47 fScheme_ = scheme;
48 }
49 inline void URI::SetScheme (const SchemeType& scheme)
50 {
51 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
52 scheme.Validate ();
53 fScheme_ = scheme;
54 }
55 inline optional<URI::Authority> URI::GetAuthority () const
56 {
57 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
58 return fAuthority_;
59 }
60 inline void URI::SetAuthority (const optional<Authority>& authority)
61 {
62 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
63 CheckValidPathForAuthority_ (authority, fPath_);
64 fAuthority_ = authority;
65 }
66 inline PortType URI::GetPortValue () const
67 {
68 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
69 optional<PortType> op = fAuthority_ ? fAuthority_->GetPort () : optional<PortType>{};
70 if (op) {
71 return *op;
72 }
73 static constexpr PortType kDefault_{0}; // should return 80????
74 if (fScheme_) {
75 return fScheme_->GetDefaultPort ().value_or (kDefault_);
76 }
77 return kDefault_;
78 }
79 inline String URI::GetPath () const
80 {
81 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
82 return fPath_;
83 }
84 inline void URI::SetPath (const String& path)
85 {
86 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
87 CheckValidPathForAuthority_ (fAuthority_, path);
88 fPath_ = path;
89 }
90 inline URI URI::GetSchemeAndAuthority () const
91 {
92 return URI{GetScheme (), GetAuthority ()};
93 }
94 template <Common::IAnyOf<String, string, URI> RETURN_TYPE>
95 RETURN_TYPE URI::GetAuthorityRelativeResource () const
96 {
97 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
98 if constexpr (same_as<RETURN_TYPE, String>) {
99 static constexpr UniformResourceIdentification::PCTEncodeOptions kPathEncodeOptions_{
100 .allowSubDelims = false, .allowGenDelims = false, .allowPChar = true, .allowFragOrQueryChars = false, .allowPathCharacters = true};
101 Characters::StringBuilder result = UniformResourceIdentification::PCTEncode2String (fPath_, kPathEncodeOptions_);
102 if (fQuery_) {
103 static constexpr UniformResourceIdentification::PCTEncodeOptions kQueryEncodeOptions_{
104 .allowSubDelims = false, .allowGenDelims = false, .allowPChar = false, .allowFragOrQueryChars = true};
105 result << "?"sv << UniformResourceIdentification::PCTEncode2String (*fQuery_, kQueryEncodeOptions_);
106 }
107 return result.str ();
108 }
109 if constexpr (same_as<RETURN_TYPE, string>) {
110 return GetAuthorityRelativeResource<String> ().AsASCII ();
111 }
112 if constexpr (same_as<RETURN_TYPE, URI>) {
113 return URI{nullopt, nullopt, GetPath (), GetQuery<String> ()};
114 }
115 }
116 template <Common::IAnyOf<String, optional<String>> RETURN_VALUE>
117 RETURN_VALUE URI::GetAbsPath () const
118 {
119 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
120 if constexpr (same_as<RETURN_VALUE, String>) {
121 if (auto op = GetAbsPath<optional<String>> ()) {
122 return *op;
123 }
124 static const auto kException_ = Execution::RuntimeErrorException{"This URI does not have an absolute path"sv};
125 Execution::Throw (kException_);
126 }
127 if constexpr (same_as<RETURN_VALUE, optional<String>>) {
128 if (fPath_.empty ()) {
129 return "/"sv;
130 }
131 if (fPath_.StartsWith ("/"sv)) {
132 return fPath_;
133 }
134 return nullopt;
135 }
136 }
137 template <Common::IAnyOf<String, URI::Query> RETURN_TYPE>
138 inline optional<RETURN_TYPE> URI::GetQuery () const
139 {
140 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
141 if constexpr (same_as<RETURN_TYPE, String>) {
142 return fQuery_;
143 }
144 if constexpr (same_as<RETURN_TYPE, Query>) {
145 if (fQuery_) {
146 return Query{*fQuery_};
147 }
148 return nullopt;
149 }
150 }
151 inline void URI::SetQuery (const optional<String>& query)
152 {
153 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
154 fQuery_ = query;
155 }
156 inline void URI::SetQuery (const optional<Query>& query)
157 {
158 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
159 fQuery_ = query ? query->ComputeQueryString () : optional<String>{};
160 }
161 inline optional<String> URI::LookupQueryArg (const String& arg) const
162 {
163 if (fQuery_) {
164 // note could be more efficient, and just lookup the single argument here...
165 return Query{*fQuery_}.Lookup (arg);
166 }
167 return nullopt;
168 }
169 inline optional<String> URI::GetFragment () const
170 {
171 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
172 return fFragment_;
173 }
174 inline void URI::SetFragment (const optional<String>& fragment)
175 {
176 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
177 fFragment_ = fragment;
178 }
179 inline strong_ordering URI::operator<=> (const URI& rhs) const
180 {
181 return URI::TWC_ (*this, rhs);
182 }
183 inline bool URI::operator== (const URI& rhs) const
184 {
185 return URI::TWC_ (*this, rhs) == 0;
186 }
187 template <Common::IAnyOf<String, string> T>
188 inline T URI::As (optional<StringPCTEncodedFlag> pctEncode) const
189 {
190 if constexpr (same_as<T, String>) {
191 return AsString_ (pctEncode);
192 }
193 if constexpr (same_as<T, string>) {
194 return AsString_ (pctEncode).AsASCII ();
195 }
196 }
197
198}
199
201 template <>
202 constexpr EnumNames<IO::Network::URI::NormalizationStyle> DefaultNames<IO::Network::URI::NormalizationStyle>::k{{{
203 {IO::Network::URI::NormalizationStyle::eRFC3986, L"RFC3986"},
205 }}};
206}
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
shared_lock< const AssertExternallySynchronizedMutex > ReadContext
Instantiate AssertExternallySynchronizedMutex::ReadContext to designate an area of code where protect...
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...
nonvirtual optional< String > Lookup(const String &idx) const
lookup argument in map