Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
UniformResourceIdentification.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_IO_Network_URL_UniformResourceIdentification_
5#define _Stroika_Foundation_IO_Network_URL_UniformResourceIdentification_ 1
6
7/*
8 ********************************************************************************
9 ***************************** Implementation Details ***************************
10 ********************************************************************************
11 */
13
14namespace Stroika::Foundation::IO::Network::UniformResourceIdentification {
15
16 /*
17 ********************************************************************************
18 ******************* UniformResourceIdentification::SchemeType ******************
19 ********************************************************************************
20 */
21 template <Characters::IConvertibleToString STRINGISH_T>
22 inline SchemeType::SchemeType (STRINGISH_T&& s)
23 : inherited{s}
24 {
25 }
26 inline strong_ordering SchemeType::operator<=> (const SchemeType& rhs) const
27 {
28 return TWC_ (*this, rhs);
29 }
30 inline bool SchemeType::operator== (const SchemeType& rhs) const
31 {
32 return TWC_ (*this, rhs) == 0;
33 }
34
35 /*
36 ********************************************************************************
37 ************************************* Host *************************************
38 ********************************************************************************
39 */
40 inline Host::Host (const String& registeredName)
41 : fEncodedName_{EncodeAsRawURL_ (registeredName)}
42 , fRegisteredName_{registeredName}
43 {
44 Require (not registeredName.empty ());
45 }
46 inline Host::Host (const InternetAddress& addr)
47 : fEncodedName_{EncodeAsRawURL_ (addr)}
48 , fInternetAddress_{addr}
49 {
50 }
51 inline Host Host::Parse (const String& rawURLHostnameText)
52 {
53 Require (not rawURLHostnameText.empty ());
54 pair<optional<String>, optional<InternetAddress>> tmp{ParseRaw_ (rawURLHostnameText)};
55 Host h;
56 h.fEncodedName_ = rawURLHostnameText;
57 h.fRegisteredName_ = tmp.first;
58 h.fInternetAddress_ = tmp.second;
59 return h;
60 }
61 inline optional<String> Host::AsRegisteredName () const
62 {
63 return fRegisteredName_;
64 }
65 inline optional<InternetAddress> Host::AsInternetAddress () const
66 {
67 return fInternetAddress_;
68 }
69 template <typename T>
70 inline T Host::As (optional<StringPCTEncodedFlag> pctEncode) const
71 requires (same_as<T, String> or same_as<T, string>)
72 {
73 if constexpr (same_as<T, String>) {
74 switch (pctEncode.value_or (eDecoded)) {
75 case StringPCTEncodedFlag::eDecoded: {
76 if (fRegisteredName_) {
77 return *fRegisteredName_;
78 }
79 Assert (fInternetAddress_);
80 if (fInternetAddress_->GetAddressFamily () == InternetAddress::AddressFamily::V6) {
81 return "["sv + fInternetAddress_->As<String> () + "]"sv;
82 }
83 return fInternetAddress_->As<String> ();
84 }
85 case StringPCTEncodedFlag::ePCTEncoded:
86 return fEncodedName_;
87 default:
89 return {};
90 }
91 }
92 else if constexpr (same_as<T, string>) {
93 return As<String> (pctEncode.value_or (ePCTEncoded)).AsASCII (); // may throw due to non-ascii characters...
94 }
95 }
96 inline strong_ordering Host::operator<=> (const Host& rhs) const
97 {
98 return TWC_ (*this, rhs);
99 }
100 inline bool Host::operator== (const Host& rhs) const
101 {
102 return TWC_ (*this, rhs) == 0;
103 }
104 inline strong_ordering Host::TWC_ (const Host& lhs, const Host& rhs)
105 {
106 if (strong_ordering cmp = Common::StdCompat::compare_three_way{}(lhs.AsInternetAddress (), rhs.AsInternetAddress ());
107 cmp != strong_ordering::equal) {
108 return cmp;
109 }
110 return Common::OptionalThreeWayComparer<String, String::ThreeWayComparer>{String::ThreeWayComparer{Characters::eCaseInsensitive}}(
111 lhs.AsRegisteredName (), rhs.AsRegisteredName ());
112 }
113
114 /*
115 ********************************************************************************
116 ********************************* UserInfo *************************************
117 ********************************************************************************
118 */
119 inline UserInfo::UserInfo (const String& decodedUserInfo)
120 : fEncodedUserInfo_{EncodeAsRawURL_ (decodedUserInfo)}
121 , fUserInfo_{decodedUserInfo}
122 {
123 Require (not decodedUserInfo.empty ());
124 }
125 inline UserInfo UserInfo::Parse (const String& rawURLUserInfo)
126 {
127 Require (not rawURLUserInfo.empty ());
128 UserInfo h;
129 h.fEncodedUserInfo_ = rawURLUserInfo;
130 h.fUserInfo_ = ParseRaw_ (rawURLUserInfo);
131 return h;
132 }
133 template <typename T>
134 inline T UserInfo::As (optional<StringPCTEncodedFlag> pctEncode) const
135 requires (same_as<T, String> or same_as<T, string>)
136 {
137 if constexpr (same_as<T, String>) {
138 switch (pctEncode.value_or (eDecoded)) {
139 case StringPCTEncodedFlag::eDecoded:
140 return fUserInfo_;
141 case StringPCTEncodedFlag::ePCTEncoded:
142 return fEncodedUserInfo_;
143 default:
145 return {};
146 }
147 }
148 else if constexpr (same_as<T, string>) {
149 return As<String> (pctEncode.value_or (ePCTEncoded)).AsASCII (); // may throw due to non-ascii characters...
150 }
151 }
152 inline strong_ordering UserInfo::operator<=> (const UserInfo& rhs) const
153 {
154 return TWC_ (*this, rhs);
155 }
156 inline bool UserInfo::operator== (const UserInfo& rhs) const
157 {
158 return As (eDecoded) == rhs.As (eDecoded);
159 }
160 inline strong_ordering UserInfo::TWC_ (const UserInfo& lhs, const UserInfo& rhs)
161 {
162 return lhs.As (eDecoded) <=> rhs.As (eDecoded);
163 }
164
165 /*
166 ********************************************************************************
167 ********************************* Authority ************************************
168 ********************************************************************************
169 */
170 inline Authority::Authority (const optional<Host>& h, const optional<PortType>& port, const optional<UserInfo>& userInfo)
171 : fHost_{h}
172 , fPort_{port}
173 , fUserInfo_{userInfo}
174 {
175 }
176 inline optional<Host> Authority::GetHost () const
177 {
178 return fHost_;
179 }
180 inline void Authority::SetHost (const optional<Host>& host)
181 {
182 fHost_ = host;
183 }
184 inline optional<PortType> Authority::GetPort () const
185 {
186 return fPort_;
187 }
188 inline void Authority::SetPort (const optional<PortType>& port)
189 {
190 fPort_ = port;
191 }
192 inline optional<UserInfo> Authority::GetUserInfo () const
193 {
194 return fUserInfo_;
195 }
196 inline void Authority::SetUserInfo (const optional<UserInfo>& userInfo)
197 {
198 fUserInfo_ = userInfo;
199 }
200 inline strong_ordering Authority::operator<=> (const Authority& rhs) const
201 {
202 return TWC_ (*this, rhs);
203 }
204 inline bool Authority::operator== (const Authority& rhs) const
205 {
206 return TWC_ (*this, rhs) == 0;
207 }
208 inline strong_ordering Authority::TWC_ (const Authority& lhs, const Authority& rhs)
209 {
210 if (auto cmp = Common::StdCompat::compare_three_way{}(lhs.GetHost (), rhs.GetHost ()); cmp != strong_ordering::equal) {
211 return cmp;
212 }
213 if (auto cmp = Common::StdCompat::compare_three_way{}(lhs.GetUserInfo (), rhs.GetUserInfo ()); cmp != strong_ordering::equal) {
214 return cmp;
215 }
216 return Common::StdCompat::compare_three_way{}(lhs.GetPort (), rhs.GetPort ());
217 }
218
219 /*
220 ********************************************************************************
221 ************************************ Query *************************************
222 ********************************************************************************
223 */
224 inline const Containers::Mapping<String, String>& Query::GetMap () const
225 {
226 return fMap_;
227 }
228 inline String Query::operator() (const String& idx) const
229 {
230 return Memory::NullCoalesce (fMap_.Lookup (idx));
231 }
232 inline String Query::operator() (const u8string& idx) const
233 {
234 return operator() (Characters::String::FromUTF8 (idx));
235 }
236 inline bool Query::HasField (const String& idx) const
237 {
238 return fMap_.ContainsKey (idx);
239 }
240 inline bool Query::HasField (const u8string& idx) const
241 {
242 return HasField (Characters::String::FromUTF8 (idx));
243 }
244 inline optional<String> Query::Lookup (const String& idx) const
245 {
246 return fMap_.Lookup (idx);
247 }
248 inline void Query::AddField (const String& idx, const String& value)
249 {
250 fMap_.Add (idx, value);
251 }
252 inline void Query::RemoveFieldIfAny (const u8string& idx)
253 {
254 RemoveFieldIfAny (Characters::String::FromUTF8 (idx));
255 }
256 inline strong_ordering Query::operator<=> (const Query& rhs) const
257 {
258 return TWC_ (*this, rhs);
259 }
260 inline bool Query::operator== (const Query& rhs) const
261 {
262 return TWC_ (*this, rhs) == 0;
263 }
264}
265
266#endif /*_Stroika_Foundation_IO_Network_URL_UniformResourceIdentification_*/
#define RequireNotReached()
Definition Assertions.h:385
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
static String FromUTF8(span< CHAR_T > from)
Definition String.inl:420
Authority is roughly the part of a URL where you say the hostname (and portnumber etc) - part just af...
Authority(const optional< Host > &h=nullopt, const optional< PortType > &port=nullopt, const optional< UserInfo > &userInfo=nullopt)
nonvirtual RESULT_TYPE As(optional< StringPCTEncodedFlag > pctEncode={}) const
Returns the hostname, either encoded or decoded (PCT encoding) as some form of printed derivitive str...
nonvirtual optional< String > Lookup(const String &idx) const
lookup argument in map
nonvirtual RESULT_TYPE As(optional< StringPCTEncodedFlag > pctEncoded={}) const
Returns the hostname, either encoded or decoded (PCT encoding) as some form of printed derivitive str...