diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-08-15 14:25:22 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-08-15 14:25:22 +0100 |
commit | a0642b4897ef4b9d7c9b9f98faaedeee4b41177e (patch) | |
tree | 3c161329a2489f123748f6759ff0ea59b7a4d203 /src/libutil/str_util.c | |
parent | 79fe034e7cdbb09630e2bd5259421f5114fa4b81 (diff) | |
download | rspamd-a0642b4897ef4b9d7c9b9f98faaedeee4b41177e.tar.gz rspamd-a0642b4897ef4b9d7c9b9f98faaedeee4b41177e.zip |
[Minor] Add rspamd_string_len_split utility
Diffstat (limited to 'src/libutil/str_util.c')
-rw-r--r-- | src/libutil/str_util.c | 60 |
1 files changed, 60 insertions, 0 deletions
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 |