comparison src/lib/strescape.c @ 22636:96e51a11c0aa

lib: Implement t_strsplit_tabescaped_inplace() This is a more efficient version of t_strsplit_tabescaped(), which modifies the input string instead of duplicating it.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sat, 04 Nov 2017 01:39:38 +0200
parents 82d8656bb3ad
children cb108f786fb4
comparison
equal deleted inserted replaced
22635:82d8656bb3ad 22636:96e51a11c0aa
247 return str; 247 return str;
248 else 248 else
249 return str_tabunescape(t_strdup_noconst(str)); 249 return str_tabunescape(t_strdup_noconst(str));
250 } 250 }
251 251
252 const char *const *t_strsplit_tabescaped_inplace(char *data)
253 {
254 /* @UNSAFE */
255 char **array;
256 unsigned int count, new_alloc_count, alloc_count;
257
258 if (*data == '\0')
259 return t_new(const char *, 1);
260
261 alloc_count = 32;
262 array = t_malloc(sizeof(char *) * alloc_count);
263
264 array[0] = data; count = 1;
265 bool need_unescape = FALSE;
266 while ((data = strpbrk(data, "\t\001")) != NULL) {
267 /* separator or escape char found */
268 if (*data == '\001') {
269 need_unescape = TRUE;
270 data++;
271 continue;
272 }
273 if (count+1 >= alloc_count) {
274 new_alloc_count = nearest_power(alloc_count+1);
275 array = p_realloc(unsafe_data_stack_pool, array,
276 sizeof(char *) * alloc_count,
277 sizeof(char *) *
278 new_alloc_count);
279 alloc_count = new_alloc_count;
280 }
281 *data++ = '\0';
282 if (need_unescape) {
283 str_tabunescape(array[count-1]);
284 need_unescape = FALSE;
285 }
286 array[count++] = data;
287 }
288 if (need_unescape)
289 str_tabunescape(array[count-1]);
290 i_assert(count < alloc_count);
291 array[count] = NULL;
292
293 return (const char *const *)array;
294 }
295
252 char **p_strsplit_tabescaped(pool_t pool, const char *str) 296 char **p_strsplit_tabescaped(pool_t pool, const char *str)
253 { 297 {
254 char **args; 298 char **args;
255 unsigned int i; 299 unsigned int i;
256 300