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 &copy; 2010-2013 Daniel Swanson <danij@dengine.net>
9  * @author Copyright &copy; 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