}
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
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 || \