]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Add rspamd_string_len_split utility
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 15 Aug 2019 13:25:22 +0000 (14:25 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 15 Aug 2019 13:25:22 +0000 (14:25 +0100)
src/libutil/str_util.c
src/libutil/str_util.h

index 4ce84fa65a4f75e8488e3606b634ebebda3496bd..89d94992ba729524cf237be1e40a4e0dd9a7a69f 100644 (file)
@@ -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
index b255c125be5fbb799c644503973eb5253a0aa154..02e0ade4528cf495014be79429d634db13766376 100644 (file)
@@ -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 || \