1 /** @file api_uri.h Public API for Universal Resource Identifiers.
2 * @ingroup base
3 *
4 * @todo de::Uri will eventually be moved to libcore, at which point this API
5 * is deprecated and the libcore c_wrapper will provide C API functions
6 * equivalent to these.
7 *
8 * @author Copyright © 2010-2013 Daniel Swanson <danij@dengine.net>
9 * @author Copyright © 2010-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
10 *
11 * @par License
12 * GPL: http://www.gnu.org/licenses/gpl.html
13 *
14 * <small>This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. This program is distributed in the hope that it
18 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
20 * Public License for more details. You should have received a copy of the GNU
21 * General Public License along with this program; if not, write to the Free
22 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA</small>
24 */
25
26 #ifndef LIBDENG_API_URI_H
27 #define LIBDENG_API_URI_H
28
29 #include "api_base.h"
30 #include <de/str.h>
31 #include <de/reader.h>
32 #include <de/writer.h>
33
34 /// Schemes must be at least this many characters.
35 #define URI_MINSCHEMELENGTH 2
36
37 /**
38 * @defgroup uriComponentFlags Uri Component Flags
39 * @ingroup base
40 *
41 * Flags which identify the logical components of a uri. Used with Uri_Write() to
42 * indicate which components of the Uri should be serialized.
43 */
44 ///@{
45 #define UCF_SCHEME 0x1 ///< Scheme.
46 #define UCF_USER 0x2 ///< User. (Reserved) Not presently implemented.
47 #define UCF_PASSWORD 0x4 ///< Password. (Reserved) Not presently implemented.
48 #define UCF_HOST 0x8 ///< Host. (Reserved) Not presently implemented.
49 #define UCF_PORT 0x10 ///< Port. (Reserved) Not presently implemented.
50 #define UCF_PATH 0x20 ///< Path.
51 #define UCF_FRAGMENT 0x40 ///< Fragment. (Reserved) Not presently implemented.
52 #define UCF_QUERY 0x80 ///< Query. (Reserved) Not presently implemented.
53 ///@}
54
55 /**
56 * @defgroup uriComposeAsTextFlags Uri Compose As Text Flags
57 * @ingroup base
58 *
59 * Flags which determine how a textual URI representation is composited.
60 */
61 ///@{
62 #define UCTF_OMITSCHEME 0x1 ///< Exclude the scheme.
63 #define UCTF_OMITPATH 0x2 ///< Exclude the path.
64 #define UCTF_DECODEPATH 0x4 ///< Decode percent-endcoded characters in the path.
65
66 #define DEFAULT_URI_COMPOSE_AS_TEXT_FLAGS 0
67 ///@}
68
69 struct uri_s; // The uri instance (opaque).
70
71 /**
72 * Uri instance. Created with Uri_New() or one of the other constructors.
73 */
74 typedef struct uri_s UriWrapper;
75 typedef UriWrapper Uri;
76
DENG_API_TYPEDEF(Uri)77 DENG_API_TYPEDEF(Uri) // v1
78 {
79 de_api_t api;
80
81 /**
82 * Constructs a default (empty) Uri instance. The uri should be destroyed with
83 * Uri_Delete() once it is no longer needed.
84 */
85 UriWrapper* (*New)(void);
86
87 UriWrapper* (*NewWithPath3)(char const *defaultScheme, char const *path);
88
89 /**
90 * Constructs a Uri instance from @a path. The uri should be destroyed with
91 * Uri_Delete() once it is no longer needed.
92 *
93 * @param path Path to be parsed. Assumed to be in percent-encoded representation.
94 * @param defaultResourceClass If no scheme is defined in @a path and this is not @c FC_NULL,
95 * look for an appropriate default scheme for this class of resource.
96 */
97 UriWrapper* (*NewWithPath2)(char const *path, resourceclassid_t defaultResourceClass);
98
99 UriWrapper* (*NewWithPath)(char const *path);
100
101 /**
102 * Constructs a Uri instance by duplicating @a other. The uri should be destroyed
103 * with Uri_Delete() once it is no longer needed.
104 */
105 UriWrapper* (*Dup)(UriWrapper const* other);
106
107 /**
108 * Constructs a Uri instance by reading it from @a reader. The uri should be
109 * destroyed with Uri_Delete() once it is no longer needed.
110 */
111 UriWrapper* (*FromReader)(Reader1* reader);
112
113 /**
114 * Destroys the uri.
115 */
116 void (*Delete)(UriWrapper* uri);
117
118 /**
119 * Returns true if the path component of the URI is empty; otherwise false.
120 * @param uri Uri instance.
121 */
122 dd_bool (*IsEmpty)(UriWrapper const* uri);
123
124 /**
125 * Clears the uri, returning it to an empty state.
126 * @param uri Uri instance.
127 * @return Same as @a uri, for caller convenience.
128 */
129 UriWrapper* (*Clear)(UriWrapper* uri);
130
131 /**
132 * Copy the contents of @a other into this uri.
133 *
134 * @param uri Uri instance.
135 * @param other Uri to be copied.
136 * @return Same as @a uri, for caller convenience.
137 */
138 UriWrapper* (*Copy)(Uri* uri, UriWrapper const* other);
139
140 /**
141 * Attempt to compose a resolved copy of this Uri. Substitutes known symbolics
142 * in the possibly templated path. Resulting path is a well-formed, filesys
143 * compatible path (perhaps base-relative).
144 *
145 * @param uri Uri instance.
146 *
147 * @return Resolved path else @c NULL if non-resolvable.
148 */
149 AutoStr* (*Resolved)(UriWrapper const* uri);
150
151 /**
152 * @param uri Uri instance.
153 * @return Plain-text String representation of the current scheme.
154 */
155 const Str* (*Scheme)(UriWrapper const* uri);
156
157 /**
158 * @param uri Uri instance.
159 * @return Plain-text String representation of the current path.
160 */
161 const Str* (*Path)(UriWrapper const* uri);
162
163 /**
164 * @param uri Uri instance.
165 * @param scheme New scheme to be parsed.
166 * @return Same as @a uri, for caller convenience.
167 */
168 UriWrapper* (*SetScheme)(UriWrapper* uri, char const* scheme);
169
170 /**
171 * @param uri Uri instance.
172 * @param path New path to be parsed.
173 * @return Same as @a uri, for caller convenience.
174 */
175 UriWrapper* (*SetPath)(UriWrapper* uri, char const* path);
176
177 /**
178 * Update uri by parsing new values from the specified arguments.
179 *
180 * @param uri Uri instance.
181 * @param path Path to be parsed. Assumed to be in percent-encoded representation.
182 * @param defaultResourceClass If no scheme is defined in @a path and this is not
183 * @c FC_NULL, look for an appropriate default scheme for this class
184 * of resource.
185 *
186 * @return Same as @a uri, for caller convenience.
187 */
188 UriWrapper* (*SetUri2)(UriWrapper* uri, char const* path, resourceclassid_t defaultResourceClass);
189
190 UriWrapper* (*SetUri)(UriWrapper* uri, char const* path/* defaultResourceClass = RC_IMPLICIT*/);
191
192 UriWrapper* (*SetUriStr)(UriWrapper* uri, ddstring_t const* path);
193
194 /**
195 * Transform the uri into a plain-text representation. Any internal encoding method
196 * or symbolic identifiers will be included in their original, unresolved form in
197 * the resultant string.
198 *
199 * @param uri Uri instance.
200 * @param flags @ref uriComposeAsTextFlags.
201 *
202 * @return Plain-text String representation.
203 */
204 AutoStr* (*Compose2)(UriWrapper const* uri, int flags);
205
206 AutoStr* (*Compose)(UriWrapper const* uri);
207
208 /**
209 * Transform the uri into a human-friendly representation (percent decoding is done).
210 *
211 * @param uri Uri instance.
212 *
213 * @return Human-friendly String representation.
214 */
215 AutoStr* (*ToString)(UriWrapper const* uri);
216
217 /**
218 * Are these two uri instances considered equal once resolved?
219 *
220 * @todo Return a delta of lexicographical difference.
221 *
222 * @param uri Uri instance.
223 * @param other Other uri instance.
224 */
225 dd_bool (*Equality)(UriWrapper const* uri, UriWrapper const* other);
226
227 /**
228 * Serialize @a uri using @a writer.
229 *
230 * @note Scheme should only be omitted when it can be unambiguously deduced from context.
231 *
232 * @param uri Uri instance.
233 * @param writer Writer instance.
234 * @param omitComponents @ref uriComponentFlags
235 */
236 void (*Write2)(UriWrapper const* uri, Writer1* writer, int omitComponents);
237
238 void (*Write)(UriWrapper const* uri, Writer1* writer/*, omitComponents = 0 (include everything)*/);
239
240 /**
241 * Deserializes @a uri using @a reader.
242 *
243 * @param uri Uri instance.
244 * @param reader Reader instance.
245 * @return Same as @a uri, for caller convenience.
246 */
247 UriWrapper* (*Read)(UriWrapper* uri, Reader1* reader);
248
249 /**
250 * Deserializes @a uri using @a reader. If the deserialized Uri lacks a scheme,
251 * @a defaultScheme will be used instead.
252 *
253 * @param uri Uri instance.
254 * @param reader Reader instance.
255 * @param defaultScheme Default scheme.
256 */
257 void (*ReadWithDefaultScheme)(UriWrapper* uri, Reader1* reader, char const* defaultScheme);
258
259 } DENG_API_T(Uri);
260
261 // Macros for accessing exported functions.
262 #ifndef DENG_NO_API_MACROS_URI
263 #define Uri_New _api_Uri.New
264 #define Uri_NewWithPath3 _api_Uri.NewWithPath3
265 #define Uri_NewWithPath2 _api_Uri.NewWithPath2
266 #define Uri_NewWithPath _api_Uri.NewWithPath
267 #define Uri_Dup _api_Uri.Dup
268 #define Uri_FromReader _api_Uri.FromReader
269 #define Uri_Delete _api_Uri.Delete
270 #define Uri_IsEmpty _api_Uri.IsEmpty
271 #define Uri_Clear _api_Uri.Clear
272 #define Uri_Copy _api_Uri.Copy
273 #define Uri_Resolved _api_Uri.Resolved
274 #define Uri_Scheme _api_Uri.Scheme
275 #define Uri_Path _api_Uri.Path
276 #define Uri_SetScheme _api_Uri.SetScheme
277 #define Uri_SetPath _api_Uri.SetPath
278 #define Uri_SetUri2 _api_Uri.SetUri2
279 #define Uri_SetUri _api_Uri.SetUri
280 #define Uri_SetUriStr _api_Uri.SetUriStr
281 #define Uri_Compose _api_Uri.Compose
282 #define Uri_Compose2 _api_Uri.Compose2
283 #define Uri_ToString _api_Uri.ToString
284 #define Uri_Equality _api_Uri.Equality
285 #define Uri_Write2 _api_Uri.Write2
286 #define Uri_Write _api_Uri.Write
287 #define Uri_Read _api_Uri.Read
288 #define Uri_ReadWithDefaultScheme _api_Uri.ReadWithDefaultScheme
289 #endif
290
291 // Internal access.
292 #ifdef __DOOMSDAY__
293 DENG_USING_API(Uri);
294 #endif
295
296 #endif /* LIBDENG_API_URI_H */
297