commit a0642b4: [Minor] Add rspamd_string_len_split utility

Vsevolod Stakhov vsevolod at highsecure.ru
Thu Aug 15 14:56:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-08-15 14:25:22 +0100
URL: https://github.com/rspamd/rspamd/commit/a0642b4897ef4b9d7c9b9f98faaedeee4b41177e

[Minor] Add rspamd_string_len_split utility

---
 src/libutil/str_util.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/libutil/str_util.h | 14 ++++++++++++
 2 files changed, 74 insertions(+)

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


More information about the Commits mailing list