Open Broadcaster Software
Free, open source software for live streaming and recording
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, const size_t len);
83 EXPORT void dstr_ncopy_dstr(struct dstr *dst, const struct dstr *src,
84  const size_t len);
85 
86 static inline void dstr_resize(struct dstr *dst, const size_t num);
87 static inline void dstr_reserve(struct dstr *dst, const size_t num);
88 
89 static inline bool dstr_is_empty(const struct dstr *str);
90 
91 static inline void dstr_cat(struct dstr *dst, const char *array);
92 EXPORT void dstr_cat_dstr(struct dstr *dst, const struct dstr *str);
93 EXPORT void dstr_cat_strref(struct dstr *dst, const struct strref *str);
94 
95 static inline void dstr_cat_ch(struct dstr *dst, char ch);
96 
97 EXPORT void dstr_ncat(struct dstr *dst, const char *array, const size_t len);
98 EXPORT void dstr_ncat_dstr(struct dstr *dst, const struct dstr *str,
99  const size_t len);
100 
101 EXPORT void dstr_insert(struct dstr *dst, const size_t idx, const char *array);
102 EXPORT void dstr_insert_dstr(struct dstr *dst, const size_t idx,
103  const struct dstr *str);
104 EXPORT void dstr_insert_ch(struct dstr *dst, const size_t idx, const char ch);
105 
106 EXPORT void dstr_remove(struct dstr *dst, const size_t idx, const size_t count);
107 
108 PRINTFATTR(2, 3)
109 EXPORT void dstr_printf(struct dstr *dst, const char *format, ...);
110 PRINTFATTR(2, 3)
111 EXPORT void dstr_catf(struct dstr *dst, const char *format, ...);
112 
113 EXPORT void dstr_vprintf(struct dstr *dst, const char *format, va_list args);
114 EXPORT void dstr_vcatf(struct dstr *dst, const char *format, va_list args);
115 
116 EXPORT void dstr_safe_printf(struct dstr *dst, const char *format,
117  const char *val1, const char *val2,
118  const char *val3, const char *val4);
119 
120 static inline const char *dstr_find_i(const struct dstr *str, const char *find);
121 static inline const char *dstr_find(const struct dstr *str, const char *find);
122 
123 EXPORT void dstr_replace(struct dstr *str, const char *find,
124  const char *replace);
125 
126 static inline int dstr_cmp(const struct dstr *str1, const char *str2);
127 static inline int dstr_cmpi(const struct dstr *str1, const char *str2);
128 static inline int dstr_ncmp(const struct dstr *str1, const char *str2,
129  const size_t n);
130 static inline int dstr_ncmpi(const struct dstr *str1, const char *str2,
131  const size_t n);
132 
133 EXPORT void dstr_depad(struct dstr *dst);
134 
135 EXPORT void dstr_left(struct dstr *dst, const struct dstr *str,
136  const size_t pos);
137 EXPORT void dstr_mid(struct dstr *dst, const struct dstr *str,
138  const size_t start, const size_t count);
139 EXPORT void dstr_right(struct dstr *dst, const struct dstr *str,
140  const size_t pos);
141 
142 static inline char dstr_end(const struct dstr *str);
143 
144 EXPORT void dstr_from_mbs(struct dstr *dst, const char *mbstr);
145 EXPORT char *dstr_to_mbs(const struct dstr *str);
146 EXPORT void dstr_from_wcs(struct dstr *dst, const wchar_t *wstr);
147 EXPORT wchar_t *dstr_to_wcs(const struct dstr *str);
148 
149 EXPORT void dstr_to_upper(struct dstr *str);
150 EXPORT void dstr_to_lower(struct dstr *str);
151 
152 #undef PRINTFATTR
153 
154 /* ------------------------------------------------------------------------- */
155 
156 static inline void dstr_init(struct dstr *dst)
157 {
158  dst->array = NULL;
159  dst->len = 0;
160  dst->capacity = 0;
161 }
162 
163 static inline void dstr_init_move_array(struct dstr *dst, char *str)
164 {
165  dst->array = str;
166  dst->len = (!str) ? 0 : strlen(str);
167  dst->capacity = dst->len + 1;
168 }
169 
170 static inline void dstr_init_move(struct dstr *dst, struct dstr *src)
171 {
172  *dst = *src;
173  dstr_init(src);
174 }
175 
176 static inline void dstr_init_copy(struct dstr *dst, const char *str)
177 {
178  dstr_init(dst);
179  dstr_copy(dst, str);
180 }
181 
182 static inline void dstr_init_copy_dstr(struct dstr *dst, const struct dstr *src)
183 {
184  dstr_init(dst);
185  dstr_copy_dstr(dst, src);
186 }
187 
188 static inline void dstr_free(struct dstr *dst)
189 {
190  bfree(dst->array);
191  dst->array = NULL;
192  dst->len = 0;
193  dst->capacity = 0;
194 }
195 
196 static inline void dstr_array_free(struct dstr *array, const size_t count)
197 {
198  size_t i;
199  for (i = 0; i < count; i++)
200  dstr_free(array + i);
201 }
202 
203 static inline void dstr_move_array(struct dstr *dst, char *str)
204 {
205  dstr_free(dst);
206  dst->array = str;
207  dst->len = (!str) ? 0 : strlen(str);
208  dst->capacity = dst->len + 1;
209 }
210 
211 static inline void dstr_move(struct dstr *dst, struct dstr *src)
212 {
213  dstr_free(dst);
214  dstr_init_move(dst, src);
215 }
216 
217 static inline void dstr_ensure_capacity(struct dstr *dst, const size_t new_size)
218 {
219  size_t new_cap;
220  if (new_size <= dst->capacity)
221  return;
222 
223  new_cap = (!dst->capacity) ? new_size : dst->capacity * 2;
224  if (new_size > new_cap)
225  new_cap = new_size;
226  dst->array = (char *)brealloc(dst->array, new_cap);
227  dst->capacity = new_cap;
228 }
229 
230 static inline void dstr_copy_dstr(struct dstr *dst, const struct dstr *src)
231 {
232  if (dst->array)
233  dstr_free(dst);
234 
235  if (src->len) {
236  dstr_ensure_capacity(dst, src->len + 1);
237  memcpy(dst->array, src->array, src->len + 1);
238  dst->len = src->len;
239  }
240 }
241 
242 static inline void dstr_reserve(struct dstr *dst, const size_t capacity)
243 {
244  if (capacity == 0 || capacity <= dst->len)
245  return;
246 
247  dst->array = (char *)brealloc(dst->array, capacity);
248  dst->capacity = capacity;
249 }
250 
251 static inline void dstr_resize(struct dstr *dst, const size_t num)
252 {
253  if (!num) {
254  dstr_free(dst);
255  return;
256  }
257 
258  dstr_ensure_capacity(dst, num + 1);
259  dst->array[num] = 0;
260  dst->len = num;
261 }
262 
263 static inline bool dstr_is_empty(const struct dstr *str)
264 {
265  if (!str->array || !str->len)
266  return true;
267  if (!*str->array)
268  return true;
269 
270  return false;
271 }
272 
273 static inline void dstr_cat(struct dstr *dst, const char *array)
274 {
275  size_t len;
276  if (!array || !*array)
277  return;
278 
279  len = strlen(array);
280  dstr_ncat(dst, array, len);
281 }
282 
283 static inline void dstr_cat_ch(struct dstr *dst, char ch)
284 {
285  dstr_ensure_capacity(dst, ++dst->len + 1);
286  dst->array[dst->len - 1] = ch;
287  dst->array[dst->len] = 0;
288 }
289 
290 static inline const char *dstr_find_i(const struct dstr *str, const char *find)
291 {
292  return astrstri(str->array, find);
293 }
294 
295 static inline const char *dstr_find(const struct dstr *str, const char *find)
296 {
297  return strstr(str->array, find);
298 }
299 
300 static inline int dstr_cmp(const struct dstr *str1, const char *str2)
301 {
302  return strcmp(str1->array, str2);
303 }
304 
305 static inline int dstr_cmpi(const struct dstr *str1, const char *str2)
306 {
307  return astrcmpi(str1->array, str2);
308 }
309 
310 static inline int dstr_ncmp(const struct dstr *str1, const char *str2,
311  const size_t n)
312 {
313  return astrcmp_n(str1->array, str2, n);
314 }
315 
316 static inline int dstr_ncmpi(const struct dstr *str1, const char *str2,
317  const size_t n)
318 {
319  return astrcmpi_n(str1->array, str2, n);
320 }
321 
322 static inline char dstr_end(const struct dstr *str)
323 {
324  if (dstr_is_empty(str))
325  return 0;
326 
327  return str->array[str->len - 1];
328 }
329 
330 #ifdef __cplusplus
331 }
332 #endif
brealloc
EXPORT void * brealloc(void *ptr, size_t size)
wstrcmpi_n
EXPORT int wstrcmpi_n(const wchar_t *str1, const wchar_t *str2, size_t n)
strref
Definition: lexer.h:30
strlist_split
EXPORT char ** strlist_split(const char *str, char split_ch, bool include_empty)
dstr_init_copy_strref
EXPORT void dstr_init_copy_strref(struct dstr *dst, const struct strref *src)
strlist_free
EXPORT void strlist_free(char **strlist)
wstrcmp_n
EXPORT int wstrcmp_n(const wchar_t *str1, const wchar_t *str2, size_t n)
dstr_ncat
EXPORT void dstr_ncat(struct dstr *dst, const char *array, const size_t len)
dstr_cat_strref
EXPORT void dstr_cat_strref(struct dstr *dst, const struct strref *str)
wcsdepad
EXPORT wchar_t * wcsdepad(wchar_t *str)
wstrstri
EXPORT wchar_t * wstrstri(const wchar_t *str, const wchar_t *find)
astrcmpi
EXPORT int astrcmpi(const char *str1, const char *str2)
dstr_cat_dstr
EXPORT void dstr_cat_dstr(struct dstr *dst, const struct dstr *str)
bfree
EXPORT void bfree(void *ptr)
dstr_catf
EXPORT void dstr_catf(struct dstr *dst, const char *format,...)
EXPORT
#define EXPORT
Definition: c99defs.h:37
dstr_remove
EXPORT void dstr_remove(struct dstr *dst, const size_t idx, const size_t count)
dstr_to_lower
EXPORT void dstr_to_lower(struct dstr *str)
dstr_insert_dstr
EXPORT void dstr_insert_dstr(struct dstr *dst, const size_t idx, const struct dstr *str)
dstr_copy_strref
EXPORT void dstr_copy_strref(struct dstr *dst, const struct strref *src)
dstr_from_mbs
EXPORT void dstr_from_mbs(struct dstr *dst, const char *mbstr)
dstr_safe_printf
EXPORT void dstr_safe_printf(struct dstr *dst, const char *format, const char *val1, const char *val2, const char *val3, const char *val4)
dstr_left
EXPORT void dstr_left(struct dstr *dst, const struct dstr *str, const size_t pos)
dstr_to_wcs
EXPORT wchar_t * dstr_to_wcs(const struct dstr *str)
c99defs.h
dstr_ncopy
EXPORT void dstr_ncopy(struct dstr *dst, const char *array, const size_t len)
astrstri
EXPORT char * astrstri(const char *str, const char *find)
strdepad
EXPORT char * strdepad(char *str)
dstr_to_upper
EXPORT void dstr_to_upper(struct dstr *str)
dstr_to_mbs
EXPORT char * dstr_to_mbs(const struct dstr *str)
dstr::array
char * array
Definition: dstr.h:37
dstr_vcatf
EXPORT void dstr_vcatf(struct dstr *dst, const char *format, va_list args)
dstr_right
EXPORT void dstr_right(struct dstr *dst, const struct dstr *str, const size_t pos)
PRINTFATTR
#define PRINTFATTR(f, a)
Definition: dstr.h:43
bmem.h
dstr_ncopy_dstr
EXPORT void dstr_ncopy_dstr(struct dstr *dst, const struct dstr *src, const size_t len)
dstr_from_wcs
EXPORT void dstr_from_wcs(struct dstr *dst, const wchar_t *wstr)
astrcmpi_n
EXPORT int astrcmpi_n(const char *str1, const char *str2, size_t n)
dstr_mid
EXPORT void dstr_mid(struct dstr *dst, const struct dstr *str, const size_t start, const size_t count)
dstr_copy
EXPORT void dstr_copy(struct dstr *dst, const char *array)
dstr::len
size_t len
Definition: dstr.h:38
dstr_insert_ch
EXPORT void dstr_insert_ch(struct dstr *dst, const size_t idx, const char ch)
dstr_depad
EXPORT void dstr_depad(struct dstr *dst)
dstr_vprintf
EXPORT void dstr_vprintf(struct dstr *dst, const char *format, va_list args)
wstrcmpi
EXPORT int wstrcmpi(const wchar_t *str1, const wchar_t *str2)
dstr
Definition: dstr.h:36
dstr::capacity
size_t capacity
Definition: dstr.h:39
dstr_replace
EXPORT void dstr_replace(struct dstr *str, const char *find, const char *replace)
dstr_printf
EXPORT void dstr_printf(struct dstr *dst, const char *format,...)
dstr_ncat_dstr
EXPORT void dstr_ncat_dstr(struct dstr *dst, const struct dstr *str, const size_t len)
astrcmp_n
EXPORT int astrcmp_n(const char *str1, const char *str2, size_t n)
dstr_insert
EXPORT void dstr_insert(struct dstr *dst, const size_t idx, const char *array)