1 /** @file str.h Dynamic text string.
2  *
3  * Dynamic string management and other text utilities.
4  *
5  * Uses @ref memzone or standard malloc for memory allocation, chosen during
6  * initialization of a string. The string instance itself is always allocated
7  * with malloc.
8  *
9  * AutoStr is a variant of ddstring_t that is automatically put up for garbage
10  * collection. You may create an AutoStr instance either by converting an
11  * existing string to one with AutoStr_FromStr() or by allocating a new
12  * instance with AutoStr_New(). You are @em not allowed to manually delete an
13  * AutoStr instance; it will be deleted automatically during the next garbage
14  * recycling.
15  *
16  * Using AutoStr instances is recommended when you have a dynamic string as a
17  * return value from a function, or when you have strings with a limited scope
18  * that need to be deleted after exiting the scope.
19  *
20  * @todo Make this opaque for better forward compatibility -- prevents initialization
21  *       with static C strings, though (which is probably for the better anyway).
22  * @todo Derive from Qt::QString
23  *
24  * @authors Copyright © 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
25  * @authors Copyright © 2008-2013 Daniel Swanson <danij@dengine.net>
26  *
27  * @par License
28  * GPL: http://www.gnu.org/licenses/gpl.html
29  *
30  * <small>This program is free software; you can redistribute it and/or modify
31  * it under the terms of the GNU General Public License as published by the
32  * Free Software Foundation; either version 2 of the License, or (at your
33  * option) any later version. This program is distributed in the hope that it
34  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
35  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
36  * Public License for more details. You should have received a copy of the GNU
37  * General Public License along with this program; if not, write to the Free
38  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
39  * 02110-1301 USA</small>
40  */
41 
42 #ifndef LIBDENG_API_STRING_H
43 #define LIBDENG_API_STRING_H
44 
45 #include "liblegacy.h"
46 #include "types.h"
47 #include "reader.h"
48 #include "writer.h"
49 #include <stdarg.h>
50 
51 /**
52  * @defgroup copyDelimiterFlags Copy Delimiter Flags
53  * Flags for Str_CopyDelim2().
54  * @ingroup legacyFlags
55  * @{
56  */
57 #define CDF_OMIT_DELIMITER      0x1 ///< Do not copy delimiters into the dest path.
58 #define CDF_OMIT_WHITESPACE     0x2 ///< Do not copy whitespace into the dest path.
59 /** @} */
60 
61 /// @addtogroup legacyData
62 /// @{
63 
64 #define DENG_LAST_CHAR(strNullTerminated)  (strNullTerminated[strlen(strNullTerminated) - 1])
65 
66 #ifdef __cplusplus
67 extern "C" {
68 #endif
69 
70 /**
71  * Dynamic string instance. Use Str_New() to allocate one from the heap, or
72  * Str_Init() to initialize a string located on the stack.
73  *
74  * You can init global ddstring_t variables with static string constants,
75  * for example: @code ddstring_t mystr = { "Hello world." }; @endcode
76  */
77 typedef struct ddstring_s {
78     /// String buffer.
79     char *str;
80 
81     /// String length (no terminating nulls).
82     size_t length;
83 
84     /// Allocated buffer size: includes the terminating null and possibly
85     /// some extra space.
86     size_t size;
87 
88     // Memory management.
89     void (*memFree)(void *);
90     void *(*memAlloc)(size_t n);
91     void *(*memCalloc)(size_t n);
92 } ddstring_t;
93 
94 /**
95  * The primary alias for the ddstring struct.
96  */
97 typedef struct ddstring_s Str;
98 
99 /**
100  * An alias for ddstring_t that is used with the convention of automatically
101  * trashing the string during construction so that it gets deleted during the
102  * next recycling. Thus it is useful for strings restricted to the local scope
103  * or for return values in cases when caller is not always required to take
104  * ownership.
105  */
106 typedef ddstring_t AutoStr;
107 
108 // Format checking for Str_Appendf in GCC2
109 #if defined(__GNUC__) && __GNUC__ >= 2
110 #   define PRINTF_F(f,v) __attribute__ ((format (printf, f, v)))
111 #else
112 #   define PRINTF_F(f,v)
113 #endif
114 
115 /**
116  * Allocate a new uninitialized string. Use Str_Delete() to destroy
117  * the returned string. Memory for the string is allocated with de::Zone.
118  *
119  * @return New ddstring_t instance.
120  *
121  * @see Str_Delete
122  */
123 DENG_PUBLIC Str *Str_New(void);
124 
125 /**
126  * Allocate a new uninitialized string. Use Str_Delete() to destroy
127  * the returned string. Memory for the string is allocated with malloc.
128  *
129  * @return New ddstring_t instance.
130  *
131  * @see Str_Delete
132  */
133 DENG_PUBLIC Str *Str_NewStd(void);
134 
135 /**
136  * Constructs a new string by reading it from @a reader.
137  * Memory for the string is allocated with de::Zone.
138  */
139 DENG_PUBLIC Str *Str_NewFromReader(Reader1 *reader);
140 
141 /**
142  * Call this for uninitialized strings. Global variables are
143  * automatically cleared, so they don't need initialization.
144  */
145 DENG_PUBLIC Str *Str_Init(Str *ds);
146 
147 /**
148  * Call this for uninitialized strings. Makes the string use standard
149  * malloc for memory allocations.
150  */
151 DENG_PUBLIC Str *Str_InitStd(Str *ds);
152 
153 /**
154  * Initializes @a ds with a static const C string. No memory allocation
155  * model is selected; use this for strings that remain constant.
156  * If the string is never modified calling Str_Free() is not needed.
157  */
158 DENG_PUBLIC Str *Str_InitStatic(Str *ds, char const *staticConstStr);
159 
160 /**
161  * Empty an existing string. After this the string is in the same
162  * state as just after being initialized.
163  */
164 DENG_PUBLIC void Str_Free(Str *ds);
165 
166 /**
167  * Destroy a string allocated with Str_New(). In addition to freeing
168  * the contents of the string, it also unallocates the string instance
169  * that was created by Str_New().
170  *
171  * @param ds  String to delete (that was returned by Str_New()).
172  */
173 DENG_PUBLIC void Str_Delete(Str *ds);
174 
175 /**
176  * Empties a string, but does not free its memory.
177  */
178 DENG_PUBLIC Str *Str_Clear(Str *ds);
179 
180 DENG_PUBLIC Str *Str_Reserve(Str *ds, int length);
181 
182 /**
183  * Reserves memory for the string. There will be at least @a length bytes
184  * allocated for the string after this. If the string needs to be resized, its
185  * contents are @em not preserved.
186  */
187 DENG_PUBLIC Str *Str_ReserveNotPreserving(Str *str, int length);
188 
189 DENG_PUBLIC Str *Str_Set(Str *ds, char const *text);
190 
191 DENG_PUBLIC Str *Str_Append(Str *ds, char const *appendText);
192 
193 DENG_PUBLIC Str *Str_AppendChar(Str *ds, char ch);
194 
195 /**
196  * Appends the contents of another string. Enough memory must already be
197  * reserved before calling this. Use in situations where good performance is
198  * critical.
199  */
200 DENG_PUBLIC Str *Str_AppendWithoutAllocs(Str *str, Str const *append);
201 
202 /**
203  * Appends a single character. Enough memory must already be reserved before
204  * calling this. Use in situations where good performance is critical.
205  *
206  * @param str  String.
207  * @param ch   Character to append. Cannot be 0.
208  */
209 DENG_PUBLIC Str *Str_AppendCharWithoutAllocs(Str *str, char ch);
210 
211 /**
212  * Append formated text.
213  */
214 DENG_PUBLIC Str *Str_Appendf(Str *ds, char const *format, ...) PRINTF_F(2,3);
215 
216 /**
217  * Appends a portion of a string.
218  */
219 DENG_PUBLIC Str *Str_PartAppend(Str *dest, char const *src, int start, int count);
220 
221 /**
222  * Prepend is not even a word, is it? It should be 'prefix'?
223  */
224 DENG_PUBLIC Str *Str_Prepend(Str *ds, char const *prependText);
225 DENG_PUBLIC Str *Str_PrependChar(Str *ds, char ch);
226 
227 /**
228  * Determines the length of the string in characters. This is safe for all
229  * strings.
230  *
231  * @param ds  String instance.
232  *
233  * @return Length of the string as an integer.
234  * @see Str_Size()
235  */
236 DENG_PUBLIC int Str_Length(Str const *ds);
237 
238 /**
239  * Determines the length of the string in characters. This is safe for all
240  * strings.
241  *
242  * @param ds  String instance.
243  *
244  * @return Length of the string.
245  * @see Str_Length()
246  */
247 DENG_PUBLIC size_t Str_Size(Str const *ds);
248 
249 DENG_PUBLIC dd_bool Str_IsEmpty(Str const *ds);
250 
251 /**
252  * This is safe for all strings.
253  */
254 DENG_PUBLIC char *Str_Text(Str const *ds);
255 
256 /**
257  * Makes a copy of @a src and replaces the previous contents of @a dest with
258  * it. The copy will have least as much memory reserved in its internal buffer
259  * as the original.
260  *
261  * If @a src is a static string (i.e., no memory allocated for its buffer), new
262  * memory will be allocated for the copy.
263  *
264  * @param dest  String where the copy is stored.
265  * @param src   Original string to copy.
266  *
267  * @return  The @a dest string with the copied content.
268  */
269 DENG_PUBLIC Str *Str_Copy(Str *dest, Str const *src);
270 
271 DENG_PUBLIC Str *Str_CopyOrClear(Str *dest, Str const *src);
272 
273 /**
274  * Strip whitespace from beginning.
275  *
276  * @param ds  String instance.
277  * @param count  If not @c NULL the number of characters stripped is written here.
278  * @return  Same as @a str for caller convenience.
279  */
280 DENG_PUBLIC Str *Str_StripLeft2(Str *ds, int *count);
281 
282 DENG_PUBLIC Str *Str_StripLeft(Str *ds);
283 
284 /**
285  * Strip whitespace from end.
286  *
287  * @param ds  String instance.
288  * @param count  If not @c NULL the number of characters stripped is written here.
289  * @return  Same as @a str for caller convenience.
290  */
291 DENG_PUBLIC Str *Str_StripRight2(Str *ds, int *count);
292 
293 DENG_PUBLIC Str *Str_StripRight(Str *ds);
294 
295 /**
296  * Strip whitespace from beginning and end.
297  *
298  * @param ds  String instance.
299  * @param count  If not @c NULL the number of characters stripped is written here.
300  * @return  Same as @a ds for caller convenience.
301  */
302 DENG_PUBLIC Str *Str_Strip2(Str *ds, int *count);
303 
304 DENG_PUBLIC Str *Str_Strip(Str *ds);
305 
306 /**
307  * Replaces all characters @a from to @a to in the string.
308  *
309  * @param ds    String instance.
310  * @param from  Characters to replace.
311  * @param to    @a from will be replaced with this.
312  *
313  * @return Str @a ds.
314  */
315 DENG_PUBLIC Str *Str_ReplaceAll(Str *ds, char from, char to);
316 
317 /**
318  * Determines if the string starts with the given substring. The comparison is done
319  * case sensitively.
320  *
321  * @param ds    String instance.
322  * @param text  Text to look for at the start of @a ds.
323  *
324  * @return  @c true, if the string is found.
325  */
326 DENG_PUBLIC dd_bool Str_StartsWith(Str const *ds, char const *text);
327 
328 /**
329  * Determines if the string ends with a specific suffic. The comparison is done
330  * case sensitively.
331  *
332  * @param ds    String instance.
333  * @param text  Text to look for in the end of @a ds.
334  *
335  * @return  @c true, if the string is found.
336  */
337 DENG_PUBLIC dd_bool Str_EndsWith(Str const *ds, char const *text);
338 
339 /**
340  * Extract a line of text from the source.
341  *
342  * @param ds   String instance where to put the extracted line.
343  * @param src  Source string. Must be @c NULL terminated.
344  */
345 DENG_PUBLIC char const *Str_GetLine(Str *ds, char const *src);
346 
347 /**
348  * Copies characters from @a src to @a dest until a @a delimiter character is encountered.
349  *
350  * @param dest          Destination string.
351  * @param src           Source string.
352  * @param delimiter     Delimiter character.
353  * @param cdflags       @ref copyDelimiterFlags
354  *
355  * @return              Pointer to the character within @a src where copy stopped
356  *                      else @c NULL if the end was reached.
357  */
358 DENG_PUBLIC char const *Str_CopyDelim2(Str *dest, char const *src, char delimiter, int cdflags);
359 
360 DENG_PUBLIC char const *Str_CopyDelim(Str *dest, char const *src, char delimiter);
361 
362 /**
363  * Case sensitive comparison.
364  */
365 DENG_PUBLIC int Str_Compare(Str const *str, char const *text);
366 
367 /**
368  * Non case sensitive comparison.
369  */
370 DENG_PUBLIC int Str_CompareIgnoreCase(Str const *ds, char const *text);
371 
372 /**
373  * Retrieves a character in the string.
374  *
375  * @param str           String to get the character from.
376  * @param index         Index of the character.
377  *
378  * @return              The character at @c index, or 0 if the index is not in range.
379  */
380 DENG_PUBLIC char Str_At(Str const *str, int index);
381 
382 /**
383  * Retrieves a character in the string. Indices start from the end of the string.
384  *
385  * @param str           String to get the character from.
386  * @param reverseIndex  Index of the character, where 0 is the last character of the string.
387  *
388  * @return              The character at @c index, or 0 if the index is not in range.
389  */
390 DENG_PUBLIC char Str_RAt(Str const *str, int reverseIndex);
391 
392 DENG_PUBLIC void Str_Truncate(Str *str, int position);
393 
394 /**
395  * Percent-encode characters in string. Will encode the default set of
396  * characters for the unicode utf8 charset.
397  *
398  * @param str           String instance.
399  * @return              Same as @a str.
400  */
401 DENG_PUBLIC Str *Str_PercentEncode(Str *str);
402 
403 /**
404  * Percent-encode characters in string.
405  *
406  * @param str           String instance.
407  * @param excludeChars  List of characters that should NOT be encoded. @c 0 terminated.
408  * @param includeChars  List of characters that will always be encoded (has precedence over
409  *                      @a excludeChars). @c 0 terminated.
410  * @return              Same as @a str.
411  */
412 DENG_PUBLIC Str *Str_PercentEncode2(Str *str, char const *excludeChars, char const *includeChars);
413 
414 /**
415  * Decode the percent-encoded string. Will match codes for the unicode
416  * utf8 charset.
417  *
418  * @param str           String instance.
419  * @return              Same as @a str.
420  */
421 DENG_PUBLIC Str *Str_PercentDecode(Str *str);
422 
423 DENG_PUBLIC void Str_Write(Str const *str, Writer1 *writer);
424 
425 DENG_PUBLIC void Str_Read(Str *str, Reader1 *reader);
426 
427 /*
428  * AutoStr
429  */
430 DENG_PUBLIC AutoStr *AutoStr_New(void);
431 
432 DENG_PUBLIC AutoStr *AutoStr_NewStd(void);
433 
434 /**
435  * Converts a ddstring to an AutoStr. After this you are not allowed
436  * to call Str_Delete() manually on the string; the garbage collector
437  * will destroy the string during the next recycling.
438  *
439  * No memory allocations are done in this function.
440  *
441  * @param str  String instance.
442  *
443  * @return  AutoStr instance. The returned instance is @a str after
444  * having been trashed.
445  */
446 DENG_PUBLIC AutoStr *AutoStr_FromStr(Str *str);
447 
448 /**
449  * Constructs an AutoStr instance (zone allocated) and initializes its
450  * contents with @a text.
451  *
452  * @param text  Text for the new string.
453  *
454  * @return  AutoStr instance.
455  */
456 DENG_PUBLIC AutoStr *AutoStr_FromText(char const *text);
457 
458 /**
459  * Constructs an AutoStr instance (standard malloc) and initializes its
460  * contents with @a text.
461  *
462  * @param text  Text for the new string.
463  *
464  * @return  AutoStr instance.
465  */
466 DENG_PUBLIC AutoStr *AutoStr_FromTextStd(char const *text);
467 
468 /**
469  * Converts an AutoStr to a normal ddstring. You must call Str_Delete()
470  * on the returned string manually to destroy it.
471  *
472  * No memory allocations are done in this function.
473  *
474  * @param as  AutoStr instance.
475  *
476  * @return  ddstring instance. The returned instance is @a as after
477  * having been taken out of the garbage.
478  */
479 DENG_PUBLIC Str *Str_FromAutoStr(AutoStr *as);
480 
481 /// @}
482 
483 #ifdef __cplusplus
484 } // extern "C"
485 #  include "str.hh" // C++ wrapper for ddstring_t
486 #endif
487 
488 #endif /* LIBDENG_API_STRING_H */
489