From: Vsevolod Stakhov Date: Thu, 15 Aug 2019 13:25:22 +0000 (+0100) Subject: [Minor] Add rspamd_string_len_split utility X-Git-Tag: 2.0~419 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a0642b4897ef4b9d7c9b9f98faaedeee4b41177e;p=rspamd.git [Minor] Add rspamd_string_len_split utility --- diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c index 4ce84fa65..89d94992b 100644 --- a/src/libutil/str_util.c +++ b/src/libutil/str_util.c @@ -3024,4 +3024,64 @@ const gchar* rspamd_string_len_strip (const gchar *in, } return in; +} + +gchar ** +rspamd_string_len_split (const gchar *in, gsize len, const gchar *spill, + gint max_elts, rspamd_mempool_t *pool) +{ + const gchar *p = in, *end = in + len; + gsize detected_elts = 0; + gchar **res; + + /* Detect number of elements */ + while (p < end) { + gsize cur_fragment = rspamd_memcspn (p, spill, end - p); + + if (cur_fragment > 0) { + detected_elts ++; + p += cur_fragment; + + if (max_elts > 0 && detected_elts >= max_elts) { + break; + } + } + + /* Something like a,,b produces {'a', 'b'} not {'a', '', 'b'} */ + p += rspamd_memspn (p, spill, end - p); + } + + res = pool ? + rspamd_mempool_alloc (pool, sizeof (gchar *) * (detected_elts + 1)) : + g_malloc (sizeof (gchar *) * (detected_elts + 1)); + /* Last one */ + res[detected_elts] = NULL; + detected_elts = 0; + p = in; + + while (p < end) { + gsize cur_fragment = rspamd_memcspn (p, spill, end - p); + + if (cur_fragment > 0) { + gchar *elt; + + elt = pool ? + rspamd_mempool_alloc (pool, cur_fragment + 1) : + g_malloc (cur_fragment + 1); + + memcpy (elt, p, cur_fragment); + elt[cur_fragment] = '\0'; + + res[detected_elts ++] = elt; + p += cur_fragment; + + if (max_elts > 0 && detected_elts >= max_elts) { + break; + } + } + + p += rspamd_memspn (p, spill, end - p); + } + + return res; } \ No newline at end of file diff --git a/src/libutil/str_util.h b/src/libutil/str_util.h index b255c125b..02e0ade45 100644 --- a/src/libutil/str_util.h +++ b/src/libutil/str_util.h @@ -533,6 +533,20 @@ gsize rspamd_gstring_strip (GString *s, const gchar *strip_chars); const gchar *rspamd_string_len_strip (const gchar *in, gsize *len, const gchar *strip_chars); +/** + * Returns a NULL terminated list of zero terminated strings based on splitting of + * the base string into parts. If pool is not NULL then memory is allocated from + * the pool. Otherwise, it is allocated from the heap using `g_malloc` (so + * g_strfreev could be used to free stuff) + * @param in + * @param len + * @param spill + * @param max_elts + * @return + */ +gchar ** rspamd_string_len_split (const gchar *in, gsize len, + const gchar *spill, gint max_elts, rspamd_mempool_t *pool); + #define IS_ZERO_WIDTH_SPACE(uc) ((uc) == 0x200B || \ (uc) == 0x200C || \ (uc) == 0x200D || \