Open Broadcaster Software
Free, open source software for live streaming and recording
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
dstr.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Hugh Bailey <obs.jim@gmail.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #pragma once
18 
19 #include <string.h>
20 #include <stdarg.h>
21 #include "c99defs.h"
22 #include "bmem.h"
23 
24 /*
25  * Dynamic string
26  *
27  * Helper struct/functions for dynamically sizing string buffers.
28  */
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 struct strref;
35 
36 struct dstr {
37  char *array;
38  size_t len; /* number of characters, excluding null terminator */
39  size_t capacity;
40 };
41 
42 #ifndef _MSC_VER
43 #define PRINTFATTR(f, a) __attribute__((__format__(__printf__, f, a)))
44 #else
45 #define PRINTFATTR(f, a)
46 #endif
47 
48 EXPORT int astrcmpi(const char *str1, const char *str2);
49 EXPORT int wstrcmpi(const wchar_t *str1, const wchar_t *str2);
50 EXPORT int astrcmp_n(const char *str1, const char *str2, size_t n);
51 EXPORT int wstrcmp_n(const wchar_t *str1, const wchar_t *str2, size_t n);
52 EXPORT int astrcmpi_n(const char *str1, const char *str2, size_t n);
53 EXPORT int wstrcmpi_n(const wchar_t *str1, const wchar_t *str2, size_t n);
54 
55 EXPORT char *astrstri(const char *str, const char *find);
56 EXPORT wchar_t *wstrstri(const wchar_t *str, const wchar_t *find);
57 
58 EXPORT char *strdepad(char *str);
59 EXPORT wchar_t *wcsdepad(wchar_t *str);
60 
61 EXPORT char **strlist_split(const char *str, char split_ch, bool include_empty);
62 EXPORT void strlist_free(char **strlist);
63 
64 static inline void dstr_init(struct dstr *dst);
65 static inline void dstr_init_move(struct dstr *dst, struct dstr *src);
66 static inline void dstr_init_move_array(struct dstr *dst, char *str);
67 static inline void dstr_init_copy(struct dstr *dst, const char *src);
68 static inline void dstr_init_copy_dstr(struct dstr *dst,
69  const struct dstr *src);
70 EXPORT void dstr_init_copy_strref(struct dstr *dst, const struct strref *src);
71 
72 static inline void dstr_free(struct dstr *dst);
73 static inline void dstr_array_free(struct dstr *array, const size_t count);
74 
75 static inline void dstr_move(struct dstr *dst, struct dstr *src);
76 static inline void dstr_move_array(struct dstr *dst, char *str);
77 
78 EXPORT void dstr_copy(struct dstr *dst, const char *array);
79 static inline void dstr_copy_dstr(struct dstr *dst, const struct dstr *src);
80 EXPORT void dstr_copy_strref(struct dstr *dst, const struct strref *src);
81 
82 EXPORT void dstr_ncopy(struct dstr *dst, const char *array,
83  const size_t len);
84 EXPORT void dstr_ncopy_dstr(struct dstr *dst, const struct dstr *src,
85  const size_t len);
86 
87 static inline void dstr_resize(struct dstr *dst, const size_t num);
88 static inline void dstr_reserve(struct dstr *dst, const size_t num);
89 
90 static inline bool dstr_is_empty(const struct dstr *str);
91 
92 static inline void dstr_cat(struct dstr *dst, const char *array);
93 EXPORT void dstr_cat_dstr(struct dstr *dst, const struct dstr *str);
94 EXPORT void dstr_cat_strref(struct dstr *dst, const struct strref *str);
95 
96 static inline void dstr_cat_ch(struct dstr *dst, char ch);
97 
98 EXPORT void dstr_ncat(struct dstr *dst, const char *array, const size_t len);
99 EXPORT void dstr_ncat_dstr(struct dstr *dst, const struct dstr *str,
100  const size_t len);
101 
102 EXPORT void dstr_insert(struct dstr *dst, const size_t idx,
103  const char *array);
104 EXPORT void dstr_insert_dstr(struct dstr *dst, const size_t idx,
105  const struct dstr *str);
106 EXPORT void dstr_insert_ch(struct dstr *dst, const size_t idx,
107  const char ch);
108 
109 EXPORT void dstr_remove(struct dstr *dst, const size_t idx, const size_t count);
110 
111 PRINTFATTR(2, 3)
112 EXPORT void dstr_printf(struct dstr *dst, const char *format, ...);
113 PRINTFATTR(2, 3)
114 EXPORT void dstr_catf(struct dstr *dst, const char *format, ...);
115 
116 EXPORT void dstr_vprintf(struct dstr *dst, const char *format, va_list args);
117 EXPORT void dstr_vcatf(struct dstr *dst, const char *format, va_list args);
118 
119 EXPORT void dstr_safe_printf(struct dstr *dst, const char *format,
120  const char *val1, const char *val2, const char *val3,
121  const char *val4);
122 
123 static inline const char *dstr_find_i(const struct dstr *str,
124  const char *find);
125 static inline const char *dstr_find(const struct dstr *str,
126  const char *find);
127 
128 EXPORT void dstr_replace(struct dstr *str, const char *find,
129  const char *replace);
130 
131 static inline int dstr_cmp(const struct dstr *str1, const char *str2);
132 static inline int dstr_cmpi(const struct dstr *str1, const char *str2);
133 static inline int dstr_ncmp(const struct dstr *str1, const char *str2,
134  const size_t n);
135 static inline int dstr_ncmpi(const struct dstr *str1, const char *str2,
136  const size_t n);
137 
138 EXPORT void dstr_depad(struct dstr *dst);
139 
140 EXPORT void dstr_left(struct dstr *dst, const struct dstr *str,
141  const size_t pos);
142 EXPORT void dstr_mid(struct dstr *dst, const struct dstr *str,
143  const size_t start, const size_t count);
144 EXPORT void dstr_right(struct dstr *dst, const struct dstr *str,
145  const size_t pos);
146 
147 static inline char dstr_end(const struct dstr *str);
148 
149 EXPORT void dstr_from_mbs(struct dstr *dst, const char *mbstr);
150 EXPORT char *dstr_to_mbs(const struct dstr *str);
151 EXPORT void dstr_from_wcs(struct dstr *dst, const wchar_t *wstr);
152 EXPORT wchar_t *dstr_to_wcs(const struct dstr *str);
153 
154 EXPORT void dstr_to_upper(struct dstr *str);
155 EXPORT void dstr_to_lower(struct dstr *str);
156 
157 #undef PRINTFATTR
158 
159 /* ------------------------------------------------------------------------- */
160 
161 static inline void dstr_init(struct dstr *dst)
162 {
163  dst->array = NULL;
164  dst->len = 0;
165  dst->capacity = 0;
166 }
167 
168 static inline void dstr_init_move_array(struct dstr *dst, char *str)
169 {
170  dst->array = str;
171  dst->len = (!str) ? 0 : strlen(str);
172  dst->capacity = dst->len + 1;
173 }
174 
175 static inline void dstr_init_move(struct dstr *dst, struct dstr *src)
176 {
177  *dst = *src;
178  dstr_init(src);
179 }
180 
181 static inline void dstr_init_copy(struct dstr *dst, const char *str)
182 {
183  dstr_init(dst);
184  dstr_copy(dst, str);
185 }
186 
187 static inline void dstr_init_copy_dstr(struct dstr *dst, const struct dstr *src)
188 {
189  dstr_init(dst);
190  dstr_copy_dstr(dst, src);
191 }
192 
193 static inline void dstr_free(struct dstr *dst)
194 {
195  bfree(dst->array);
196  dst->array = NULL;
197  dst->len = 0;
198  dst->capacity = 0;
199 }
200 
201 static inline void dstr_array_free(struct dstr *array, const size_t count)
202 {
203  size_t i;
204  for (i = 0; i < count; i++)
205  dstr_free(array+i);
206 }
207 
208 static inline void dstr_move_array(struct dstr *dst, char *str)
209 {
210  dstr_free(dst);
211  dst->array = str;
212  dst->len = (!str) ? 0 : strlen(str);
213  dst->capacity = dst->len + 1;
214 }
215 
216 static inline void dstr_move(struct dstr *dst, struct dstr *src)
217 {
218  dstr_free(dst);
219  dstr_init_move(dst, src);
220 }
221 
222 static inline void dstr_ensure_capacity(struct dstr *dst, const size_t new_size)
223 {
224  size_t new_cap;
225  if (new_size <= dst->capacity)
226  return;
227 
228  new_cap = (!dst->capacity) ? new_size : dst->capacity*2;
229  if (new_size > new_cap)
230  new_cap = new_size;
231  dst->array = (char*)brealloc(dst->array, new_cap);
232  dst->capacity = new_cap;
233 }
234 
235 static inline void dstr_copy_dstr(struct dstr *dst, const struct dstr *src)
236 {
237  if (dst->array)
238  dstr_free(dst);
239 
240  if (src->len) {
241  dstr_ensure_capacity(dst, src->len + 1);
242  memcpy(dst->array, src->array, src->len + 1);
243  dst->len = src->len;
244  }
245 }
246 
247 static inline void dstr_reserve(struct dstr *dst, const size_t capacity)
248 {
249  if (capacity == 0 || capacity <= dst->len)
250  return;
251 
252  dst->array = (char*)brealloc(dst->array, capacity);
253  dst->capacity = capacity;
254 }
255 
256 static inline void dstr_resize(struct dstr *dst, const size_t num)
257 {
258  if (!num) {
259  dstr_free(dst);
260  return;
261  }
262 
263  dstr_ensure_capacity(dst, num + 1);
264  dst->array[num] = 0;
265  dst->len = num;
266 }
267 
268 static inline bool dstr_is_empty(const struct dstr *str)
269 {
270  if (!str->array || !str->len)
271  return true;
272  if (!*str->array)
273  return true;
274 
275  return false;
276 }
277 
278 static inline void dstr_cat(struct dstr *dst, const char *array)
279 {
280  size_t len;
281  if (!array || !*array)
282  return;
283 
284  len = strlen(array);
285  dstr_ncat(dst, array, len);
286 }
287 
288 static inline void dstr_cat_ch(struct dstr *dst, char ch)
289 {
290  dstr_ensure_capacity(dst, ++dst->len + 1);
291  dst->array[dst->len-1] = ch;
292  dst->array[dst->len] = 0;
293 }
294 
295 static inline const char *dstr_find_i(const struct dstr *str, const char *find)
296 {
297  return astrstri(str->array, find);
298 }
299 
300 static inline const char *dstr_find(const struct dstr *str, const char *find)
301 {
302  return strstr(str->array, find);
303 }
304 
305 static inline int dstr_cmp(const struct dstr *str1, const char *str2)
306 {
307  return strcmp(str1->array, str2);
308 }
309 
310 static inline int dstr_cmpi(const struct dstr *str1, const char *str2)
311 {
312  return astrcmpi(str1->array, str2);
313 }
314 
315 static inline int dstr_ncmp(const struct dstr *str1, const char *str2,
316  const size_t n)
317 {
318  return astrcmp_n(str1->array, str2, n);
319 }
320 
321 static inline int dstr_ncmpi(const struct dstr *str1, const char *str2,
322  const size_t n)
323 {
324  return astrcmpi_n(str1->array, str2, n);
325 }
326 
327 static inline char dstr_end(const struct dstr *str)
328 {
329  if (dstr_is_empty(str))
330  return 0;
331 
332  return str->array[str->len - 1];
333 }
334 
335 #ifdef __cplusplus
336 }
337 #endif
EXPORT void dstr_ncopy_dstr(struct dstr *dst, const struct dstr *src, const size_t len)
EXPORT int wstrcmpi(const wchar_t *str1, const wchar_t *str2)
EXPORT int astrcmpi(const char *str1, const char *str2)
EXPORT void dstr_depad(struct dstr *dst)
EXPORT void dstr_ncopy(struct dstr *dst, const char *array, const size_t len)
EXPORT void dstr_mid(struct dstr *dst, const struct dstr *str, const size_t start, const size_t count)
EXPORT void dstr_to_upper(struct dstr *str)
EXPORT int astrcmp_n(const char *str1, const char *str2, size_t n)
EXPORT void dstr_replace(struct dstr *str, const char *find, const char *replace)
EXPORT void * brealloc(void *ptr, size_t size)
EXPORT char * dstr_to_mbs(const struct dstr *str)
EXPORT wchar_t * dstr_to_wcs(const struct dstr *str)
EXPORT void dstr_copy_strref(struct dstr *dst, const struct strref *src)
EXPORT wchar_t * wcsdepad(wchar_t *str)
EXPORT char ** strlist_split(const char *str, char split_ch, bool include_empty)
EXPORT int wstrcmp_n(const wchar_t *str1, const wchar_t *str2, size_t n)
EXPORT void dstr_ncat(struct dstr *dst, const char *array, const size_t len)
EXPORT void dstr_vcatf(struct dstr *dst, const char *format, va_list args)
EXPORT void dstr_init_copy_strref(struct dstr *dst, const struct strref *src)
EXPORT void dstr_insert_ch(struct dstr *dst, const size_t idx, const char ch)
EXPORT void dstr_insert(struct dstr *dst, const size_t idx, const char *array)
EXPORT void dstr_cat_dstr(struct dstr *dst, const struct dstr *str)
#define EXPORT
Definition: c99defs.h:49
EXPORT wchar_t * wstrstri(const wchar_t *str, const wchar_t *find)
EXPORT void dstr_copy(struct dstr *dst, const char *array)
EXPORT void dstr_to_lower(struct dstr *str)
EXPORT void dstr_safe_printf(struct dstr *dst, const char *format, const char *val1, const char *val2, const char *val3, const char *val4)
char * array
Definition: dstr.h:37
EXPORT void dstr_insert_dstr(struct dstr *dst, const size_t idx, const struct dstr *str)
EXPORT void dstr_vprintf(struct dstr *dst, const char *format, va_list args)
Definition: dstr.h:36
EXPORT char * astrstri(const char *str, const char *find)
EXPORT void dstr_cat_strref(struct dstr *dst, const struct strref *str)
EXPORT void dstr_printf(struct dstr *dst, const char *format,...)
size_t capacity
Definition: dstr.h:39
EXPORT int wstrcmpi_n(const wchar_t *str1, const wchar_t *str2, size_t n)
EXPORT void dstr_remove(struct dstr *dst, const size_t idx, const size_t count)
EXPORT void dstr_catf(struct dstr *dst, const char *format,...)
EXPORT void dstr_from_wcs(struct dstr *dst, const wchar_t *wstr)
EXPORT void dstr_right(struct dstr *dst, const struct dstr *str, const size_t pos)
#define PRINTFATTR(f, a)
Definition: dstr.h:43
EXPORT void strlist_free(char **strlist)
EXPORT void dstr_from_mbs(struct dstr *dst, const char *mbstr)
EXPORT int astrcmpi_n(const char *str1, const char *str2, size_t n)
size_t len
Definition: dstr.h:38
EXPORT char * strdepad(char *str)
EXPORT void bfree(void *ptr)
EXPORT void dstr_ncat_dstr(struct dstr *dst, const struct dstr *str, const size_t len)
EXPORT void dstr_left(struct dstr *dst, const struct dstr *str, const size_t pos)
Definition: lexer.h:30