[evolution-data-server/wip/camel-more-gobject] Introduce camel-utils.c/.h for miscellaneous utility functions and such



commit b2c29691a8dd78960b8f948f43ea12b998bd7c3c
Author: Milan Crha <mcrha redhat com>
Date:   Fri Sep 9 14:31:27 2016 +0200

    Introduce camel-utils.c/.h for miscellaneous utility functions and such

 camel/Makefile.am          |    2 +
 camel/camel-message-info.h |    2 +-
 camel/camel-mime-utils.c   | 1052 ------------------------------------------
 camel/camel-mime-utils.h   |  107 +-----
 camel/camel-utils.c        | 1079 ++++++++++++++++++++++++++++++++++++++++++++
 camel/camel-utils.h        |  133 ++++++
 camel/camel.h              |    1 +
 7 files changed, 1217 insertions(+), 1159 deletions(-)
---
diff --git a/camel/Makefile.am b/camel/Makefile.am
index f7a0cdd..d730ff3 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -168,6 +168,7 @@ libcamel_1_2_la_SOURCES = \
        camel-url-scanner.c \
        camel-url.c \
        camel-utf8.c \
+       camel-utils.c \
        camel-vee-data-cache.c \
        camel-vee-folder.c \
        camel-vee-message-info.c \
@@ -290,6 +291,7 @@ libcamelinclude_HEADERS = \
        camel-url-scanner.h \
        camel-url.h \
        camel-utf8.h \
+       camel-utils.h \
        camel-vee-data-cache.h \
        camel-vee-folder.h \
        camel-vee-message-info.h \
diff --git a/camel/camel-message-info.h b/camel/camel-message-info.h
index 8af5348..acdbee7 100644
--- a/camel/camel-message-info.h
+++ b/camel/camel-message-info.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 
-#include <camel/camel-mime-utils.h>
+#include <camel/camel-utils.h>
 
 /* Standard GObject macros */
 #define CAMEL_TYPE_MESSAGE_INFO \
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 1ba410e..cdd88c1 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -105,1058 +105,6 @@ G_DEFINE_BOXED_TYPE (CamelHeaderAddress,
                camel_header_address_ref,
                camel_header_address_unref)
 
-G_DEFINE_BOXED_TYPE (CamelNameValueArray,
-               camel_name_value_array,
-               camel_name_value_array_copy,
-               camel_name_value_array_free)
-
-typedef struct _CamelNameValuePair {
-       gchar *name;
-       gchar *value;
-} CamelNameValuePair;
-
-static void
-free_name_value_content (gpointer ptr)
-{
-       CamelNameValuePair *pair = ptr;
-
-       if (pair) {
-               g_free (pair->name);
-               g_free (pair->value);
-
-               pair->name = NULL;
-               pair->value = NULL;
-       }
-}
-
-/**
- * camel_name_value_array_new:
- *
- * Created a new #CamelNameValueArray. The returned pointer should be freed
- * with camel_name_value_array_free() when no longer needed.
- *
- * Returns: (transfer full): A new #CamelNameValueArray.
- *
- * See: camel_name_value_array_new_sized, camel_name_value_array_copy
- *
- * Since: 3.24
- **/
-CamelNameValueArray *
-camel_name_value_array_new (void)
-{
-       GArray *arr;
-
-       arr = g_array_new (FALSE, FALSE, sizeof (CamelNameValuePair));
-       g_array_set_clear_func (arr, free_name_value_content);
-
-       return (CamelNameValueArray *) arr;
-}
-
-/**
- * camel_name_value_array_new_sized:
- * @reserve_size: an array size to reserve
- *
- * Created a new #CamelNameValueArray, which has reserved @reserve_size
- * elements. This value doesn't influence the camel_name_value_array_get_length(),
- * which returns zero on the array returned from this function. The returned
- * pointer should be freed with camel_name_value_array_free() when no longer needed.
- *
- * Returns: (transfer full): A new #CamelNameValueArray.
- *
- * See: camel_name_value_array_new, camel_name_value_array_copy
- *
- * Since: 3.24
- **/
-CamelNameValueArray *
-camel_name_value_array_new_sized (guint reserve_size)
-{
-       GArray *arr;
-
-       arr = g_array_sized_new (FALSE, FALSE, sizeof (CamelNameValuePair), reserve_size);
-       g_array_set_clear_func (arr, free_name_value_content);
-
-       return (CamelNameValueArray *) arr;
-}
-
-/**
- * camel_name_value_array_copy:
- * @array: (nullable): a #CamelNameValueArray
- *
- * Created a new copy of the @array. The returned pointer should be freed
- * with camel_name_value_array_free() when no longer needed.
- *
- * Returns: (transfer full): A new copy of the @array.
- *
- * See: camel_name_value_array_new, camel_name_value_array_new_sized
- *
- * Since: 3.24
- **/
-CamelNameValueArray *
-camel_name_value_array_copy (const CamelNameValueArray *array)
-{
-       CamelNameValueArray *copy;
-       guint ii, len;
-
-       if (!array)
-               return NULL;
-
-       len = camel_name_value_array_get_length (array);
-       copy = camel_name_value_array_new_sized (len);
-
-       for (ii = 0; ii < len; ii++) {
-               const gchar *name = NULL, *value = NULL;
-
-               if (camel_name_value_array_get (array, ii, &name, &value))
-                       camel_name_value_array_append (copy, name, value);
-       }
-
-       return copy;
-}
-
-/**
- * camel_name_value_array_free:
- * @array: (nullable): a #CamelNameValueArray, or %NULL
- *
- * Frees the @array, previously allocated by camel_name_value_array_new(),
- * camel_name_value_array_new_sized() or camel_name_value_array_copy().
- * If the @array is %NULL, then does nothing.
- *
- * Since: 3.24
- **/
-void
-camel_name_value_array_free (CamelNameValueArray *array)
-{
-       if (array)
-               g_array_free ((GArray *) array, TRUE);
-}
-
-/**
- * camel_name_value_array_get_length:
- * @array: (nullable): a #CamelNameValueArray
- *
- * Returns: Length of the @array, aka how many elements are stored in the @array.
- *
- * Since: 3.24
- **/
-guint
-camel_name_value_array_get_length (const CamelNameValueArray *array)
-{
-       GArray *arr = (GArray *) array;
-
-       if (!array)
-               return 0;
-
-       return arr->len;
-}
-
-/**
- * camel_name_value_array_get:
- * @array: a #CamelNameValueArray
- * @index: an index
- * @out_name: (out) (nullable): A place to store the name of the element, or %NULL
- * @out_value: (out) (nullable): A place to store the value of the element, or %NULL
- *
- * Returns the name and the value of the element at index @index. Either
- * of the @out_name and @out_value can be %NULL, to not return that part.
- *
- * Returns: %TRUE on success, %FALSE otherwise.
- *
- * See: camel_name_value_array_get_name, camel_name_value_array_get_value, camel_name_value_array_get_named
- *
- * Since: 3.24
- **/
-gboolean
-camel_name_value_array_get (const CamelNameValueArray *array,
-                           guint index,
-                           const gchar **out_name,
-                           const gchar **out_value)
-{
-       GArray *arr = (GArray *) array;
-       CamelNameValuePair *pair;
-
-       g_return_val_if_fail (array != NULL, FALSE);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
-
-       pair = &g_array_index (arr, CamelNameValuePair, index);
-
-       if (out_name)
-               *out_name = pair->name;
-       if (out_value)
-               *out_value= pair->value;
-
-       return TRUE;
-}
-
-static guint
-camel_name_value_array_find_named (const CamelNameValueArray *array,
-                                  gboolean case_sensitive,
-                                  const gchar *name)
-{
-       GArray *arr = (GArray *) array;
-       gint ii;
-
-       g_return_val_if_fail (array != NULL, (guint) -1);
-       g_return_val_if_fail (name != NULL, (guint) -1);
-
-       for (ii = 0; ii < arr->len; ii++) {
-               CamelNameValuePair *pair = &g_array_index (arr, CamelNameValuePair, ii);
-
-               if ((case_sensitive && g_strcmp0 (name, pair->name) == 0) ||
-                   (!case_sensitive && pair->name && camel_strcase_equal (name, pair->name))) {
-                       return ii;
-               }
-       }
-
-       return (guint) -1;
-}
-
-/**
- * camel_name_value_array_set_named:
- * @array: a #CamelNameValueArray
- * @case_sensitive: whether to compare names case sensitively
- * @name: a name
- *
- * Returns the value of the first element named @name, or %NULL when there
- * is no element of such @name in the @array. The @case_sensitive determines
- * whether compare names case sensitively (%TRUE) or insensitively (%FALSE).
- *
- * Returns: (transfer none) (nullable): Value of the first element named @name, or %NULL.
- *
- * See: camel_name_value_array_get, camel_name_value_array_get_name
- *
- * Since: 3.24
- **/
-const gchar *
-camel_name_value_array_get_named (const CamelNameValueArray *array,
-                                 gboolean case_sensitive,
-                                 const gchar *name)
-{
-       guint index;
-
-       g_return_val_if_fail (array != NULL, NULL);
-       g_return_val_if_fail (name != NULL, NULL);
-
-       index = camel_name_value_array_find_named (array, case_sensitive, name);
-       if (index == (guint) -1)
-               return NULL;
-
-       return camel_name_value_array_get_value (array, index);
-}
-
-/**
- * camel_name_value_array_get_name:
- * @array: a #CamelNameValueArray
- * @index: an index
- *
- * Returns the name of the element at index @index.
- *
- * Returns: (transfer none) (nullable): Name of the element at the given @index,
- *    or %NULL on error.
- *
- * See: camel_name_value_array_get, camel_name_value_array_get_value
- *
- * Since: 3.24
- **/
-const gchar *
-camel_name_value_array_get_name (const CamelNameValueArray *array,
-                                guint index)
-{
-       const gchar *name = NULL;
-
-       g_return_val_if_fail (array != NULL, NULL);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), NULL);
-
-       if (!camel_name_value_array_get (array, index, &name, NULL))
-               return NULL;
-
-       return name;
-}
-
-/**
- * camel_name_value_array_get_value:
- * @array: a #CamelNameValueArray
- * @index: an index
- *
- * Returns the value of the element at index @index.
- *
- * Returns: (transfer none) (nullable): Value of the element at the given @index,
- *    or %NULL on error.
- *
- * See: camel_name_value_array_get, camel_name_value_array_get_name
- *
- * Since: 3.24
- **/
-const gchar *
-camel_name_value_array_get_value (const CamelNameValueArray *array,
-                                 guint index)
-{
-       const gchar *value = NULL;
-
-       g_return_val_if_fail (array != NULL, NULL);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), NULL);
-
-       if (!camel_name_value_array_get (array, index, NULL, &value))
-               return NULL;
-
-       return value;
-}
-
-/**
- * camel_name_value_array_append:
- * @array: a #CamelNameValueArray
- * @name: a name
- * @value: a value
- *
- * Appends a new element of the name @name and the value @value
- * at the end of @array.
- *
- * See: camel_name_value_array_set_named
- *
- * Since: 3.24
- **/
-void
-camel_name_value_array_append (CamelNameValueArray *array,
-                              const gchar *name,
-                              const gchar *value)
-{
-       GArray *arr = (GArray *) array;
-       CamelNameValuePair pair;
-
-       g_return_if_fail (array != NULL);
-       g_return_if_fail (name != NULL);
-       g_return_if_fail (value != NULL);
-
-       pair.name = g_strdup (name);
-       pair.value = g_strdup (value);
-
-       g_array_append_val (arr, pair);
-}
-
-static gboolean
-camel_name_value_array_set_internal (CamelNameValueArray *array,
-                                    guint index,
-                                    const gchar *name,
-                                    const gchar *value)
-{
-       GArray *arr = (GArray *) array;
-       CamelNameValuePair *pair;
-       gboolean changed = FALSE;
-
-       g_return_val_if_fail (array != NULL, FALSE);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
-
-       pair = &g_array_index (arr, CamelNameValuePair, index);
-
-       if (name && g_strcmp0 (pair->name, name) != 0) {
-               g_free (pair->name);
-               pair->name = g_strdup (name);
-               changed = TRUE;
-       }
-
-       if (value && g_strcmp0 (pair->value, value) != 0) {
-               g_free (pair->value);
-               pair->value = g_strdup (value);
-               changed = TRUE;
-       }
-
-       return changed;
-}
-
-/**
- * camel_name_value_array_set:
- * @array: a #CamelNameValueArray
- * @index: an index
- * @name: a name
- * @value: a value
- *
- * Sets both the @name and the @value of the element at index @index.
- *
- * Returns: Whether the @array changed.
- *
- * See: camel_name_value_array_append, camel_name_value_array_set_name, camel_name_value_array_set_value
- *
- * Since: 3.24
- **/
-gboolean
-camel_name_value_array_set (CamelNameValueArray *array,
-                           guint index,
-                           const gchar *name,
-                           const gchar *value)
-{
-       g_return_val_if_fail (array != NULL, FALSE);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
-       g_return_val_if_fail (name != NULL, FALSE);
-       g_return_val_if_fail (value != NULL, FALSE);
-
-       return camel_name_value_array_set_internal (array, index, name, value);
-}
-
-/**
- * camel_name_value_array_set_name:
- * @array: a #CamelNameValueArray
- * @index: an index
- * @name: a name
- *
- * Sets the @name of the element at index @index.
- *
- * Returns: Whether the @array changed.
- *
- * See: camel_name_value_array_set, camel_name_value_array_set_value
- *
- * Since: 3.24
- **/
-gboolean
-camel_name_value_array_set_name (CamelNameValueArray *array,
-                                guint index,
-                                const gchar *name)
-{
-       g_return_val_if_fail (array != NULL, FALSE);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
-       g_return_val_if_fail (name != NULL, FALSE);
-
-       return camel_name_value_array_set_internal (array, index, name, NULL);
-}
-
-/**
- * camel_name_value_array_set_value:
- * @array: a #CamelNameValueArray
- * @index: an index
- * @value: a value
- *
- * Sets the @value of the element at index @index.
- *
- * Returns: Whether the @array changed.
- *
- * See: camel_name_value_array_set, camel_name_value_array_set_name
- *
- * Since: 3.24
- **/
-gboolean
-camel_name_value_array_set_value (CamelNameValueArray *array,
-                                 guint index,
-                                 const gchar *value)
-{
-       g_return_val_if_fail (array != NULL, FALSE);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
-       g_return_val_if_fail (value != NULL, FALSE);
-
-       return camel_name_value_array_set_internal (array, index, NULL, value);
-}
-
-/**
- * camel_name_value_array_set_named:
- * @array: a #CamelNameValueArray
- * @case_sensitive: whether to compare names case sensitively
- * @name: a name
- * @value: a value
- *
- * Finds an element named @name and sets its value to @value, or appends
- * a new element, in case no such named lement exists in the @array yet.
- * In case there are more elements named with @name only the first
- * occurrence is changed. The @case_sensitive determines whether compare
- * names case sensitively (%TRUE) or insensitively (%FALSE).
- *
- * Returns: Whether the @array changed.
- *
- * See: camel_name_value_array_append, camel_name_value_array_set
- *
- * Since: 3.24
- **/
-gboolean
-camel_name_value_array_set_named (CamelNameValueArray *array,
-                                 gboolean case_sensitive,
-                                 const gchar *name,
-                                 const gchar *value)
-{
-       gboolean changed = FALSE;
-       guint index;
-
-       g_return_val_if_fail (array != NULL, FALSE);
-       g_return_val_if_fail (name != NULL, FALSE);
-       g_return_val_if_fail (value != NULL, FALSE);
-
-       index = camel_name_value_array_find_named (array, case_sensitive, name);
-       if (index == (guint) -1) {
-               camel_name_value_array_append (array, name, value);
-               changed = TRUE;
-       } else {
-               changed = camel_name_value_array_set_value (array, index, value);
-       }
-
-       return changed;
-}
-
-/**
- * camel_name_value_array_remove:
- * @array: a #CamelNameValueArray
- * @index: an index to remove
- *
- * Removes element at index @index.
- *
- * Returns: Whether the element was removed.
- *
- * Since: 3.24
- **/
-gboolean
-camel_name_value_array_remove (CamelNameValueArray *array,
-                              guint index)
-{
-       g_return_val_if_fail (array != NULL, FALSE);
-       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
-
-       g_array_remove_index ((GArray *) array, index);
-
-       return TRUE;
-}
-
-/**
- * camel_name_value_array_remove_named:
- * @array: a #CamelNameValueArray
- * @case_sensitive: whether to compare names case sensitively
- * @name: a name to remove
- * @all_occurrences: whether to remove all occurrences of the @name
- *
- * Removes elements of the @array with the given @name. The @case_sensitive
- * determines whether compare case sensitively (%TRUE) or insensitively (%FALSE).
- * If the @all_occurrences is set to %TRUE, then every elements with the @name
- * are removed, otherwise only the first occurrence is removed.
- *
- * Returns: How many elements had been removed.
- *
- * Since: 3.24
- **/
-guint
-camel_name_value_array_remove_named (CamelNameValueArray *array,
-                                    gboolean case_sensitive,
-                                    const gchar *name,
-                                    gboolean all_occurrences)
-{
-       guint index, removed = 0;
-
-       g_return_val_if_fail (array != NULL, 0);
-       g_return_val_if_fail (name != NULL, 0);
-
-       while (index = camel_name_value_array_find_named (array, case_sensitive, name), index != (guint) -1) {
-               if (!camel_name_value_array_remove (array, index))
-                       break;
-
-               removed++;
-
-               if (!all_occurrences)
-                       break;
-       }
-
-       return removed;
-}
-
-/**
- * camel_name_value_array_clear:
- * @array: a #CamelNameValueArray
- *
- * Removes all elements of the @array.
- *
- * Since: 3.24
- **/
-void
-camel_name_value_array_clear (CamelNameValueArray *array)
-{
-       GArray *arr = (GArray *) array;
-
-       g_return_if_fail (array != NULL);
-
-       g_array_remove_range (arr, 0, arr->len);
-}
-
-/**
- * camel_name_value_array_equal:
- * @array_a: (nullable): the first #CamelNameValueArray
- * @array_b: (nullable): the second #CamelNameValueArray
- * @case_sensitive: whether to search for names case sensitively
- *
- * Compares content of the two #CamelNameValueArray and returns whether
- * they equal. Note this is an expensive operation for large arrays.
- *
- * Returns: Whether the two #CamelNameValueArray have the same content.
- *
- * Since: 3.24
- **/
-gboolean
-camel_name_value_array_equal (const CamelNameValueArray *array_a,
-                             const CamelNameValueArray *array_b,
-                             gboolean case_sensitive)
-{
-       guint ii, len;
-
-       if (array_a == array_b)
-               return TRUE;
-
-       if (!array_a || !array_b)
-               return FALSE;
-
-       len = camel_name_value_array_get_length (array_a);
-       if (len != camel_name_value_array_get_length (array_b))
-               return FALSE;
-
-       for (ii = 0; ii < len; ii++) {
-               const gchar *value1, *value2;
-
-               value1 = camel_name_value_array_get_value (array_a, ii);
-               value2 = camel_name_value_array_get_named (array_b, case_sensitive,
-                       camel_name_value_array_get_name (array_a, ii));
-
-               if (g_strcmp0 (value1, value2) != 0)
-                       return FALSE;
-       }
-
-       return TRUE;
-}
-
-/* ------------------------------------------------------------------------ */
-
-G_DEFINE_BOXED_TYPE (CamelNamedFlags,
-               camel_named_flags,
-               camel_named_flags_copy,
-               camel_named_flags_free)
-
-/**
- * camel_named_flags_new:
- *
- * Creates a new #CamelNamedFlags.
- *
- * Returns: (transfer full): A newly allocated #CamelNamedFlags.
- *    Free it with camel_named_flags_free() when done with it.
- *
- * Since: 3.24
- **/
-CamelNamedFlags *
-camel_named_flags_new (void)
-{
-       return (CamelNamedFlags *) g_ptr_array_new_with_free_func (g_free);
-}
-
-/**
- * camel_named_flags_new_sized:
- * @reserve_size: an array size to reserve
- *
- * Created a new #CamelNamedFlags, which has reserved @reserve_size
- * elements. This value doesn't influence the camel_named_flags_get_length(),
- * which returns zero on the array returned from this function.
- *
- * Returns: (transfer full): A newly allocated #CamelNameValueArray.
- *    Free it with camel_named_flags_free() when done with it.
- *
- * See: camel_name_value_array_new, camel_name_value_array_copy
- *
- * Since: 3.24
- **/
-CamelNamedFlags *
-camel_named_flags_new_sized (guint reserve_size)
-{
-       return (CamelNamedFlags *) g_ptr_array_new_full (reserve_size, g_free);
-}
-
-/**
- * camel_named_flags_copy:
- * @named_flags: (nullable): a #CamelNamedFlags
- *
- * Creates a copy of the @named_flags and returns it.
- *
- * Returns: (transfer full): A newly allocated #CamelNamedFlags.
- *    Free it with camel_named_flags_free() when done with it.
- *
- * Since: 3.24
- **/
-CamelNamedFlags *
-camel_named_flags_copy (const CamelNamedFlags *named_flags)
-{
-       const GPtrArray *src = (const GPtrArray *) named_flags;
-       GPtrArray *arr;
-       guint ii;
-
-       if (!src)
-               return NULL;
-
-       arr = (GPtrArray *) camel_named_flags_new_sized (src->len);
-       for (ii = 0; ii < src->len; ii++) {
-               const gchar *name = g_ptr_array_index (src, ii);
-
-               if (name && *name)
-                       g_ptr_array_add (arr, g_strdup (name));
-       }
-
-       return (CamelNamedFlags *) arr;
-}
-
-/**
- * camel_named_flags_free:
- * @named_flags: (nullable): a #CamelNamedFlags, or %NULL
- *
- * Frees memory associated iwth the @named_flags. Does nothing,
- * if @named_flags is %NULL.
- *
- * Since: 3.24
- **/
-void
-camel_named_flags_free (CamelNamedFlags *named_flags)
-{
-       if (named_flags)
-               g_ptr_array_unref ((GPtrArray *) named_flags);
-}
-
-static guint
-camel_named_flags_find (const CamelNamedFlags *named_flags,
-                       const gchar *name)
-{
-       GPtrArray *arr = (GPtrArray *) named_flags;
-       guint ii;
-
-       g_return_val_if_fail (named_flags != NULL, (guint) -1);
-       g_return_val_if_fail (name != NULL, (guint) -1);
-
-       for (ii = 0; ii < arr->len; ii++) {
-               const gchar *nm = g_ptr_array_index (arr, ii);
-
-               if (g_strcmp0 (nm, name) == 0)
-                       return ii;
-       }
-
-       return (guint) -1;
-}
-
-/**
- * camel_named_flags_insert:
- * @named_flags: a #CamelNamedFlags
- * @name: name of the flag
- *
- * Inserts a flag named @name into the @named_flags, if it is not included
- * already (comparing case sensitively), or does nothing otherwise.
- *
- * Returns: %TRUE the flag named @name was inserted; %FALSE otherwise.
- *
- * Since: 3.24
- **/
-gboolean
-camel_named_flags_insert (CamelNamedFlags *named_flags,
-                         const gchar *name)
-{
-       GPtrArray *arr = (GPtrArray *) named_flags;
-       guint index;
-
-       g_return_val_if_fail (named_flags != NULL, FALSE);
-       g_return_val_if_fail (name != NULL, FALSE);
-
-       index = camel_named_flags_find (named_flags, name);
-
-       /* already there */
-       if (index != (guint) -1)
-               return FALSE;
-
-       g_ptr_array_add (arr, g_strdup (name));
-
-       return TRUE;
-}
-
-/**
- * camel_named_flags_remove:
- * @named_flags: a #CamelNamedFlags
- * @name: name of the flag
- *
- * Removes a flag named @name from the @named_flags.
- *
- * Returns: %TRUE when the @named_flags contained a flag named @name,
- *    comparing case sensitively, and it was removed; %FALSE otherwise.
- *
- * Since: 3.24
- **/
-gboolean
-camel_named_flags_remove (CamelNamedFlags *named_flags,
-                         const gchar *name)
-{
-       GPtrArray *arr = (GPtrArray *) named_flags;
-       guint index;
-
-       g_return_val_if_fail (named_flags != NULL, FALSE);
-       g_return_val_if_fail (name != NULL, FALSE);
-
-       index = camel_named_flags_find (named_flags, name);
-
-       /* not there */
-       if (index == (guint) -1)
-               return FALSE;
-
-       g_ptr_array_remove_index (arr, index);
-
-       return TRUE;
-}
-
-/**
- * camel_named_flags_contains:
- * @named_flags: a #CamelNamedFlags
- * @name: name of the flag
- *
- * Returns: Whether the @named_flags contains a flag named @name,
- *    comparing case sensitively.
- *
- * Since: 3.24
- **/
-gboolean
-camel_named_flags_contains (const CamelNamedFlags *named_flags,
-                           const gchar *name)
-{
-       g_return_val_if_fail (named_flags != NULL, FALSE);
-       g_return_val_if_fail (name != NULL, FALSE);
-
-       return camel_named_flags_find (named_flags, name) != (guint) -1;
-}
-
-/**
- * camel_named_flags_clear:
- * @named_flags: a #CamelNamedFlags
- *
- * Removes all the elements of the array.
- *
- * Since: 3.24
- **/
-void
-camel_named_flags_clear (CamelNamedFlags *named_flags)
-{
-       GPtrArray *arr = (GPtrArray *) named_flags;
-
-       g_return_if_fail (named_flags != NULL);
-
-       if (arr->len)
-               g_ptr_array_remove_range (arr, 0, arr->len);
-}
-
-/**
- * camel_named_flags_get_length:
- * @named_flags: (nullable): a #CamelNamedFlags
- *
- * Returns: Length of the array, aka how many named flags are stored there.
- *
- * Since: 3.24
- **/
-guint
-camel_named_flags_get_length (const CamelNamedFlags *named_flags)
-{
-       const GPtrArray *arr = (const GPtrArray *) named_flags;
-
-       if (!named_flags)
-               return 0;
-
-       return arr->len;
-}
-
-/**
- * camel_named_flags_get:
- * @named_flags: a #CamelNamedFlags
- * @index: an index of an element
- *
- * Returns: (transfer none) (nullable): Name of the flag in at the given @index,
- *   or %NULL on error.
- *
- * Since: 3.24
- **/
-const gchar *
-camel_named_flags_get (const CamelNamedFlags *named_flags,
-                      guint index)
-{
-       const GPtrArray *arr = (const GPtrArray *) named_flags;
-
-       g_return_val_if_fail (named_flags != NULL, NULL);
-       g_return_val_if_fail (index < camel_named_flags_get_length (named_flags), NULL);
-
-       return g_ptr_array_index (arr, index);
-}
-
-/**
- * camel_named_flags_equal:
- * @named_flags_a: (nullable): the first #CamelNamedFlags
- * @named_flags_b: (nullable): the second #CamelNamedFlags
- *
- * Compares content of the two #CamelNamedFlags and returns whether
- * they equal. Note this is an expensive operation for large sets.
- *
- * Returns: Whether the two #CamelNamedFlags have the same content.
- *
- * Since: 3.24
- **/
-gboolean
-camel_named_flags_equal (const CamelNamedFlags *named_flags_a,
-                        const CamelNamedFlags *named_flags_b)
-{
-       guint ii, len;
-
-       if (named_flags_a == named_flags_b)
-               return TRUE;
-
-       if (!named_flags_a || !named_flags_b)
-               return FALSE;
-
-       len = camel_named_flags_get_length (named_flags_a);
-       if (len != camel_named_flags_get_length (named_flags_b))
-               return FALSE;
-
-       for (ii = 0; ii < len; ii++) {
-               if (!camel_named_flags_contains (named_flags_a, camel_named_flags_get (named_flags_b, ii)))
-                       return FALSE;
-       }
-
-       return TRUE;
-}
-
-/* ------------------------------------------------------------------------ */
-
-/**
- * camel_util_bdata_get_number:
- * @bdata_ptr: a backend specific data (bdata) pointer
- * @default_value: a value to return, when no data can be read
- *
- * Reads a numeric data from the @bdata_ptr and moves the @bdata_ptr
- * after that number. If the number cannot be read, then the @default_value
- * is returned instead and the @bdata_ptr is left unchanged. The number
- * might be previously stored with the camel_util_bdata_put_number().
- *
- * Returns: The read number, or the @default_value, if the @bdata_ptr doesn't
- *    point to a number.
- *
- * Since: 3.24
- **/
-gint64
-camel_util_bdata_get_number (/* const */ gchar **bdata_ptr,
-                            gint64 default_value)
-{
-       gint64 result;
-       gchar *endptr;
-
-       g_return_val_if_fail (bdata_ptr != NULL, default_value);
-
-       if (!bdata_ptr || !*bdata_ptr || !**bdata_ptr)
-               return default_value;
-
-       if (**bdata_ptr == ' ')
-               *bdata_ptr += 1;
-
-       if (!**bdata_ptr)
-               return default_value;
-
-       endptr = *bdata_ptr;
-
-       result = g_ascii_strtoll (*bdata_ptr, &endptr, 10);
-
-       if (endptr == *bdata_ptr)
-               result = default_value;
-       else
-               *bdata_ptr = endptr;
-
-       return result;
-}
-
-/**
- * camel_util_bdata_put_number:
- * @bdata_str: a #GString to store a backend specific data (bdata)
- * @value: a value to store
- *
- * Puts the number @value at the end of the @bdata_str. In case the @bdata_str
- * is not empty a space is added before the numeric @value. The stored value
- * can be read back with the camel_util_bdata_get_number().
- *
- * Since: 3.24
- **/
-void
-camel_util_bdata_put_number (GString *bdata_str,
-                            gint64 value)
-{
-       g_return_if_fail (bdata_str != NULL);
-
-       if (bdata_str->len && bdata_str->str[bdata_str->len - 1] != ' ')
-               g_string_append_c (bdata_str, ' ');
-
-       g_string_append_printf (bdata_str, "%" G_GINT64_FORMAT, value);
-}
-
-/**
- * camel_util_bdata_get_string:
- * @bdata_ptr: a backend specific data (bdata) pointer
- * @default_value: a value to return, when no data can be read
- *
- * Reads a string data from the @bdata_ptr and moves the @bdata_ptr
- * after that string. If the string cannot be read, then the @default_value
- * is returned instead and the @bdata_ptr is left unchanged. The string
- * might be previously stored with the camel_util_bdata_put_string().
- *
- * Returns: (transfer full): Newly allocated string, which was read, or
- *    dupped the @default_value, if the @bdata_ptr doesn't point to a string.
- *    Free returned pointer with g_free() when done with it.
- *
- * Since: 3.24
- **/
-gchar *
-camel_util_bdata_get_string (/* const */ gchar **bdata_ptr,
-                            const gchar *default_value)
-{
-       gint64 length, has_length;
-       gchar *orig_bdata_ptr;
-       gchar *result;
-
-       g_return_val_if_fail (bdata_ptr != NULL, NULL);
-
-       orig_bdata_ptr = *bdata_ptr;
-
-       length = camel_util_bdata_get_number (bdata_ptr, -1);
-
-       /* might be a '-' sign */
-       if (*bdata_ptr && **bdata_ptr == '-')
-               *bdata_ptr += 1;
-       else
-               length = -1;
-
-       if (length < 0 || !*bdata_ptr || !**bdata_ptr || *bdata_ptr == orig_bdata_ptr) {
-               *bdata_ptr = orig_bdata_ptr;
-
-               return g_strdup (default_value);
-       }
-
-       if (!length)
-               return g_strdup ("");
-
-       has_length = strlen (*bdata_ptr);
-       if (has_length < length)
-               length = has_length;
-
-       result = g_strndup (*bdata_ptr, length);
-       *bdata_ptr += length;
-
-       return result;
-}
-
-/**
- * camel_util_bdata_put_string:
- * @bdata_str: a #GString to store a backend specific data (bdata)
- * @value: a value to store
- *
- * Puts the string @value at the end of the @bdata_str. In case the @bdata_str
- * is not empty a space is added before the string @value. The stored value
- * can be read back with the camel_util_bdata_get_string().
- *
- * The strings are encoded as "length-value", quotes for clarity only.
- *
- * Since: 3.24
- **/
-void
-camel_util_bdata_put_string (GString *bdata_str,
-                            const gchar *value)
-{
-       g_return_if_fail (bdata_str != NULL);
-       g_return_if_fail (value != NULL);
-
-       camel_util_bdata_put_number (bdata_str, strlen (value));
-
-       g_string_append_printf (bdata_str, "-%s", value);
-}
-
-/* ------------------------------------------------------------------------ */
-
 /**
  * camel_mktime_utc:
  * @tm: the #tm to convert to a calendar time representation
diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h
index cca22dd..f692214 100644
--- a/camel/camel-mime-utils.h
+++ b/camel/camel-mime-utils.h
@@ -29,6 +29,7 @@
 #include <glib.h>
 #include <glib-object.h>
 #include <camel/camel-enums.h>
+#include <camel/camel-utils.h>
 
 G_BEGIN_DECLS
 
@@ -45,112 +46,6 @@ typedef enum {
 
 #define CAMEL_UUDECODE_STATE_MASK   (CAMEL_UUDECODE_STATE_BEGIN | CAMEL_UUDECODE_STATE_END)
 
-/**
- * CamelNameValueArray:
- *
- * Since: 3.24
- **/
-struct _CamelNameValueArray;
-typedef struct _CamelNameValueArray CamelNameValueArray;
-
-#define CAMEL_TYPE_NAME_VALUE_ARRAY (camel_name_value_array_get_type ())
-
-GType           camel_name_value_array_get_type        (void) G_GNUC_CONST;
-CamelNameValueArray *
-               camel_name_value_array_new      (void);
-CamelNameValueArray *
-               camel_name_value_array_new_sized
-                                               (guint reserve_size);
-CamelNameValueArray *
-               camel_name_value_array_copy     (const CamelNameValueArray *array);
-void           camel_name_value_array_free     (CamelNameValueArray *array);
-guint          camel_name_value_array_get_length
-                                               (const CamelNameValueArray *array);
-gboolean       camel_name_value_array_get      (const CamelNameValueArray *array,
-                                                guint index,
-                                                const gchar **out_name,
-                                                const gchar **out_value);
-const gchar *  camel_name_value_array_get_named
-                                               (const CamelNameValueArray *array,
-                                                gboolean case_sensitive,
-                                                const gchar *name);
-const gchar *  camel_name_value_array_get_name (const CamelNameValueArray *array,
-                                                guint index);
-const gchar *  camel_name_value_array_get_value
-                                               (const CamelNameValueArray *array,
-                                                guint index);
-void           camel_name_value_array_append   (CamelNameValueArray *array,
-                                                const gchar *name,
-                                                const gchar *value);
-gboolean       camel_name_value_array_set      (CamelNameValueArray *array,
-                                                guint index,
-                                                const gchar *name,
-                                                const gchar *value);
-gboolean       camel_name_value_array_set_name (CamelNameValueArray *array,
-                                                guint index,
-                                                const gchar *name);
-gboolean       camel_name_value_array_set_value
-                                               (CamelNameValueArray *array,
-                                                guint index,
-                                                const gchar *value);
-gboolean       camel_name_value_array_set_named
-                                               (CamelNameValueArray *array,
-                                                gboolean case_sensitive,
-                                                const gchar *name,
-                                                const gchar *value);
-gboolean       camel_name_value_array_remove   (CamelNameValueArray *array,
-                                                guint index);
-guint          camel_name_value_array_remove_named
-                                               (CamelNameValueArray *array,
-                                                gboolean case_sensitive,
-                                                const gchar *name,
-                                                gboolean all_occurrences);
-void           camel_name_value_array_clear    (CamelNameValueArray *array);
-gboolean       camel_name_value_array_equal    (const CamelNameValueArray *array_a,
-                                                const CamelNameValueArray *array_b,
-                                                gboolean case_sensitive);
-
-/**
- * CamelNamedFlags:
- *
- * Since: 3.24
- **/
-struct _CamelNamedFlags;
-typedef struct _CamelNamedFlags CamelNamedFlags;
-
-#define CAMEL_TYPE_NAMED_FLAGS (camel_named_flags_get_type ())
-
-GType           camel_named_flags_get_type     (void) G_GNUC_CONST;
-CamelNamedFlags *
-               camel_named_flags_new           (void);
-CamelNamedFlags *
-               camel_named_flags_new_sized     (guint reserve_size);
-CamelNamedFlags *
-               camel_named_flags_copy          (const CamelNamedFlags *named_flags);
-void           camel_named_flags_free          (CamelNamedFlags *named_flags);
-gboolean       camel_named_flags_insert        (CamelNamedFlags *named_flags,
-                                                const gchar *name);
-gboolean       camel_named_flags_remove        (CamelNamedFlags *named_flags,
-                                                const gchar *name);
-gboolean       camel_named_flags_contains      (const CamelNamedFlags *named_flags,
-                                                const gchar *name);
-void           camel_named_flags_clear         (CamelNamedFlags *named_flags);
-guint          camel_named_flags_get_length    (const CamelNamedFlags *named_flags);
-const gchar *  camel_named_flags_get           (const CamelNamedFlags *named_flags,
-                                                guint index);
-gboolean       camel_named_flags_equal         (const CamelNamedFlags *named_flags_a,
-                                                const CamelNamedFlags *named_flags_b);
-
-/* Utility functions */
-gint64         camel_util_bdata_get_number     (/* const */ gchar **bdata_ptr,
-                                                gint64 default_value);
-void           camel_util_bdata_put_number     (GString *bdata_str,
-                                                gint64 value);
-gchar *                camel_util_bdata_get_string     (/* const */ gchar **bdata_ptr,
-                                                const gchar *default_value);
-void           camel_util_bdata_put_string     (GString *bdata_str,
-                                                const gchar *value);
-
 typedef struct _camel_header_param {
        struct _camel_header_param *next;
        gchar *name;
diff --git a/camel/camel-utils.c b/camel/camel-utils.c
new file mode 100644
index 0000000..71901a4
--- /dev/null
+++ b/camel/camel-utils.c
@@ -0,0 +1,1079 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "camel-string-utils.h"
+
+#include "camel-utils.h"
+
+G_DEFINE_BOXED_TYPE (CamelNameValueArray,
+               camel_name_value_array,
+               camel_name_value_array_copy,
+               camel_name_value_array_free)
+
+typedef struct _CamelNameValuePair {
+       gchar *name;
+       gchar *value;
+} CamelNameValuePair;
+
+static void
+free_name_value_content (gpointer ptr)
+{
+       CamelNameValuePair *pair = ptr;
+
+       if (pair) {
+               g_free (pair->name);
+               g_free (pair->value);
+
+               pair->name = NULL;
+               pair->value = NULL;
+       }
+}
+
+/**
+ * camel_name_value_array_new:
+ *
+ * Created a new #CamelNameValueArray. The returned pointer should be freed
+ * with camel_name_value_array_free() when no longer needed.
+ *
+ * Returns: (transfer full): A new #CamelNameValueArray.
+ *
+ * See: camel_name_value_array_new_sized, camel_name_value_array_copy
+ *
+ * Since: 3.24
+ **/
+CamelNameValueArray *
+camel_name_value_array_new (void)
+{
+       GArray *arr;
+
+       arr = g_array_new (FALSE, FALSE, sizeof (CamelNameValuePair));
+       g_array_set_clear_func (arr, free_name_value_content);
+
+       return (CamelNameValueArray *) arr;
+}
+
+/**
+ * camel_name_value_array_new_sized:
+ * @reserve_size: an array size to reserve
+ *
+ * Created a new #CamelNameValueArray, which has reserved @reserve_size
+ * elements. This value doesn't influence the camel_name_value_array_get_length(),
+ * which returns zero on the array returned from this function. The returned
+ * pointer should be freed with camel_name_value_array_free() when no longer needed.
+ *
+ * Returns: (transfer full): A new #CamelNameValueArray.
+ *
+ * See: camel_name_value_array_new, camel_name_value_array_copy
+ *
+ * Since: 3.24
+ **/
+CamelNameValueArray *
+camel_name_value_array_new_sized (guint reserve_size)
+{
+       GArray *arr;
+
+       arr = g_array_sized_new (FALSE, FALSE, sizeof (CamelNameValuePair), reserve_size);
+       g_array_set_clear_func (arr, free_name_value_content);
+
+       return (CamelNameValueArray *) arr;
+}
+
+/**
+ * camel_name_value_array_copy:
+ * @array: (nullable): a #CamelNameValueArray
+ *
+ * Created a new copy of the @array. The returned pointer should be freed
+ * with camel_name_value_array_free() when no longer needed.
+ *
+ * Returns: (transfer full): A new copy of the @array.
+ *
+ * See: camel_name_value_array_new, camel_name_value_array_new_sized
+ *
+ * Since: 3.24
+ **/
+CamelNameValueArray *
+camel_name_value_array_copy (const CamelNameValueArray *array)
+{
+       CamelNameValueArray *copy;
+       guint ii, len;
+
+       if (!array)
+               return NULL;
+
+       len = camel_name_value_array_get_length (array);
+       copy = camel_name_value_array_new_sized (len);
+
+       for (ii = 0; ii < len; ii++) {
+               const gchar *name = NULL, *value = NULL;
+
+               if (camel_name_value_array_get (array, ii, &name, &value))
+                       camel_name_value_array_append (copy, name, value);
+       }
+
+       return copy;
+}
+
+/**
+ * camel_name_value_array_free:
+ * @array: (nullable): a #CamelNameValueArray, or %NULL
+ *
+ * Frees the @array, previously allocated by camel_name_value_array_new(),
+ * camel_name_value_array_new_sized() or camel_name_value_array_copy().
+ * If the @array is %NULL, then does nothing.
+ *
+ * Since: 3.24
+ **/
+void
+camel_name_value_array_free (CamelNameValueArray *array)
+{
+       if (array)
+               g_array_free ((GArray *) array, TRUE);
+}
+
+/**
+ * camel_name_value_array_get_length:
+ * @array: (nullable): a #CamelNameValueArray
+ *
+ * Returns: Length of the @array, aka how many elements are stored in the @array.
+ *
+ * Since: 3.24
+ **/
+guint
+camel_name_value_array_get_length (const CamelNameValueArray *array)
+{
+       GArray *arr = (GArray *) array;
+
+       if (!array)
+               return 0;
+
+       return arr->len;
+}
+
+/**
+ * camel_name_value_array_get:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ * @out_name: (out) (nullable): A place to store the name of the element, or %NULL
+ * @out_value: (out) (nullable): A place to store the value of the element, or %NULL
+ *
+ * Returns the name and the value of the element at index @index. Either
+ * of the @out_name and @out_value can be %NULL, to not return that part.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise.
+ *
+ * See: camel_name_value_array_get_name, camel_name_value_array_get_value, camel_name_value_array_get_named
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_get (const CamelNameValueArray *array,
+                           guint index,
+                           const gchar **out_name,
+                           const gchar **out_value)
+{
+       GArray *arr = (GArray *) array;
+       CamelNameValuePair *pair;
+
+       g_return_val_if_fail (array != NULL, FALSE);
+       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+
+       pair = &g_array_index (arr, CamelNameValuePair, index);
+
+       if (out_name)
+               *out_name = pair->name;
+       if (out_value)
+               *out_value= pair->value;
+
+       return TRUE;
+}
+
+static guint
+camel_name_value_array_find_named (const CamelNameValueArray *array,
+                                  gboolean case_sensitive,
+                                  const gchar *name)
+{
+       GArray *arr = (GArray *) array;
+       gint ii;
+
+       g_return_val_if_fail (array != NULL, (guint) -1);
+       g_return_val_if_fail (name != NULL, (guint) -1);
+
+       for (ii = 0; ii < arr->len; ii++) {
+               CamelNameValuePair *pair = &g_array_index (arr, CamelNameValuePair, ii);
+
+               if ((case_sensitive && g_strcmp0 (name, pair->name) == 0) ||
+                   (!case_sensitive && pair->name && camel_strcase_equal (name, pair->name))) {
+                       return ii;
+               }
+       }
+
+       return (guint) -1;
+}
+
+/**
+ * camel_name_value_array_set_named:
+ * @array: a #CamelNameValueArray
+ * @case_sensitive: whether to compare names case sensitively
+ * @name: a name
+ *
+ * Returns the value of the first element named @name, or %NULL when there
+ * is no element of such @name in the @array. The @case_sensitive determines
+ * whether compare names case sensitively (%TRUE) or insensitively (%FALSE).
+ *
+ * Returns: (transfer none) (nullable): Value of the first element named @name, or %NULL.
+ *
+ * See: camel_name_value_array_get, camel_name_value_array_get_name
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_name_value_array_get_named (const CamelNameValueArray *array,
+                                 gboolean case_sensitive,
+                                 const gchar *name)
+{
+       guint index;
+
+       g_return_val_if_fail (array != NULL, NULL);
+       g_return_val_if_fail (name != NULL, NULL);
+
+       index = camel_name_value_array_find_named (array, case_sensitive, name);
+       if (index == (guint) -1)
+               return NULL;
+
+       return camel_name_value_array_get_value (array, index);
+}
+
+/**
+ * camel_name_value_array_get_name:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ *
+ * Returns the name of the element at index @index.
+ *
+ * Returns: (transfer none) (nullable): Name of the element at the given @index,
+ *    or %NULL on error.
+ *
+ * See: camel_name_value_array_get, camel_name_value_array_get_value
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_name_value_array_get_name (const CamelNameValueArray *array,
+                                guint index)
+{
+       const gchar *name = NULL;
+
+       g_return_val_if_fail (array != NULL, NULL);
+       g_return_val_if_fail (index < camel_name_value_array_get_length (array), NULL);
+
+       if (!camel_name_value_array_get (array, index, &name, NULL))
+               return NULL;
+
+       return name;
+}
+
+/**
+ * camel_name_value_array_get_value:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ *
+ * Returns the value of the element at index @index.
+ *
+ * Returns: (transfer none) (nullable): Value of the element at the given @index,
+ *    or %NULL on error.
+ *
+ * See: camel_name_value_array_get, camel_name_value_array_get_name
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_name_value_array_get_value (const CamelNameValueArray *array,
+                                 guint index)
+{
+       const gchar *value = NULL;
+
+       g_return_val_if_fail (array != NULL, NULL);
+       g_return_val_if_fail (index < camel_name_value_array_get_length (array), NULL);
+
+       if (!camel_name_value_array_get (array, index, NULL, &value))
+               return NULL;
+
+       return value;
+}
+
+/**
+ * camel_name_value_array_append:
+ * @array: a #CamelNameValueArray
+ * @name: a name
+ * @value: a value
+ *
+ * Appends a new element of the name @name and the value @value
+ * at the end of @array.
+ *
+ * See: camel_name_value_array_set_named
+ *
+ * Since: 3.24
+ **/
+void
+camel_name_value_array_append (CamelNameValueArray *array,
+                              const gchar *name,
+                              const gchar *value)
+{
+       GArray *arr = (GArray *) array;
+       CamelNameValuePair pair;
+
+       g_return_if_fail (array != NULL);
+       g_return_if_fail (name != NULL);
+       g_return_if_fail (value != NULL);
+
+       pair.name = g_strdup (name);
+       pair.value = g_strdup (value);
+
+       g_array_append_val (arr, pair);
+}
+
+static gboolean
+camel_name_value_array_set_internal (CamelNameValueArray *array,
+                                    guint index,
+                                    const gchar *name,
+                                    const gchar *value)
+{
+       GArray *arr = (GArray *) array;
+       CamelNameValuePair *pair;
+       gboolean changed = FALSE;
+
+       g_return_val_if_fail (array != NULL, FALSE);
+       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+
+       pair = &g_array_index (arr, CamelNameValuePair, index);
+
+       if (name && g_strcmp0 (pair->name, name) != 0) {
+               g_free (pair->name);
+               pair->name = g_strdup (name);
+               changed = TRUE;
+       }
+
+       if (value && g_strcmp0 (pair->value, value) != 0) {
+               g_free (pair->value);
+               pair->value = g_strdup (value);
+               changed = TRUE;
+       }
+
+       return changed;
+}
+
+/**
+ * camel_name_value_array_set:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ * @name: a name
+ * @value: a value
+ *
+ * Sets both the @name and the @value of the element at index @index.
+ *
+ * Returns: Whether the @array changed.
+ *
+ * See: camel_name_value_array_append, camel_name_value_array_set_name, camel_name_value_array_set_value
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_set (CamelNameValueArray *array,
+                           guint index,
+                           const gchar *name,
+                           const gchar *value)
+{
+       g_return_val_if_fail (array != NULL, FALSE);
+       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+       g_return_val_if_fail (name != NULL, FALSE);
+       g_return_val_if_fail (value != NULL, FALSE);
+
+       return camel_name_value_array_set_internal (array, index, name, value);
+}
+
+/**
+ * camel_name_value_array_set_name:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ * @name: a name
+ *
+ * Sets the @name of the element at index @index.
+ *
+ * Returns: Whether the @array changed.
+ *
+ * See: camel_name_value_array_set, camel_name_value_array_set_value
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_set_name (CamelNameValueArray *array,
+                                guint index,
+                                const gchar *name)
+{
+       g_return_val_if_fail (array != NULL, FALSE);
+       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+       g_return_val_if_fail (name != NULL, FALSE);
+
+       return camel_name_value_array_set_internal (array, index, name, NULL);
+}
+
+/**
+ * camel_name_value_array_set_value:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ * @value: a value
+ *
+ * Sets the @value of the element at index @index.
+ *
+ * Returns: Whether the @array changed.
+ *
+ * See: camel_name_value_array_set, camel_name_value_array_set_name
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_set_value (CamelNameValueArray *array,
+                                 guint index,
+                                 const gchar *value)
+{
+       g_return_val_if_fail (array != NULL, FALSE);
+       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+       g_return_val_if_fail (value != NULL, FALSE);
+
+       return camel_name_value_array_set_internal (array, index, NULL, value);
+}
+
+/**
+ * camel_name_value_array_set_named:
+ * @array: a #CamelNameValueArray
+ * @case_sensitive: whether to compare names case sensitively
+ * @name: a name
+ * @value: a value
+ *
+ * Finds an element named @name and sets its value to @value, or appends
+ * a new element, in case no such named lement exists in the @array yet.
+ * In case there are more elements named with @name only the first
+ * occurrence is changed. The @case_sensitive determines whether compare
+ * names case sensitively (%TRUE) or insensitively (%FALSE).
+ *
+ * Returns: Whether the @array changed.
+ *
+ * See: camel_name_value_array_append, camel_name_value_array_set
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_set_named (CamelNameValueArray *array,
+                                 gboolean case_sensitive,
+                                 const gchar *name,
+                                 const gchar *value)
+{
+       gboolean changed = FALSE;
+       guint index;
+
+       g_return_val_if_fail (array != NULL, FALSE);
+       g_return_val_if_fail (name != NULL, FALSE);
+       g_return_val_if_fail (value != NULL, FALSE);
+
+       index = camel_name_value_array_find_named (array, case_sensitive, name);
+       if (index == (guint) -1) {
+               camel_name_value_array_append (array, name, value);
+               changed = TRUE;
+       } else {
+               changed = camel_name_value_array_set_value (array, index, value);
+       }
+
+       return changed;
+}
+
+/**
+ * camel_name_value_array_remove:
+ * @array: a #CamelNameValueArray
+ * @index: an index to remove
+ *
+ * Removes element at index @index.
+ *
+ * Returns: Whether the element was removed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_remove (CamelNameValueArray *array,
+                              guint index)
+{
+       g_return_val_if_fail (array != NULL, FALSE);
+       g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+
+       g_array_remove_index ((GArray *) array, index);
+
+       return TRUE;
+}
+
+/**
+ * camel_name_value_array_remove_named:
+ * @array: a #CamelNameValueArray
+ * @case_sensitive: whether to compare names case sensitively
+ * @name: a name to remove
+ * @all_occurrences: whether to remove all occurrences of the @name
+ *
+ * Removes elements of the @array with the given @name. The @case_sensitive
+ * determines whether compare case sensitively (%TRUE) or insensitively (%FALSE).
+ * If the @all_occurrences is set to %TRUE, then every elements with the @name
+ * are removed, otherwise only the first occurrence is removed.
+ *
+ * Returns: How many elements had been removed.
+ *
+ * Since: 3.24
+ **/
+guint
+camel_name_value_array_remove_named (CamelNameValueArray *array,
+                                    gboolean case_sensitive,
+                                    const gchar *name,
+                                    gboolean all_occurrences)
+{
+       guint index, removed = 0;
+
+       g_return_val_if_fail (array != NULL, 0);
+       g_return_val_if_fail (name != NULL, 0);
+
+       while (index = camel_name_value_array_find_named (array, case_sensitive, name), index != (guint) -1) {
+               if (!camel_name_value_array_remove (array, index))
+                       break;
+
+               removed++;
+
+               if (!all_occurrences)
+                       break;
+       }
+
+       return removed;
+}
+
+/**
+ * camel_name_value_array_clear:
+ * @array: a #CamelNameValueArray
+ *
+ * Removes all elements of the @array.
+ *
+ * Since: 3.24
+ **/
+void
+camel_name_value_array_clear (CamelNameValueArray *array)
+{
+       GArray *arr = (GArray *) array;
+
+       g_return_if_fail (array != NULL);
+
+       g_array_remove_range (arr, 0, arr->len);
+}
+
+/**
+ * camel_name_value_array_equal:
+ * @array_a: (nullable): the first #CamelNameValueArray
+ * @array_b: (nullable): the second #CamelNameValueArray
+ * @case_sensitive: whether to search for names case sensitively
+ *
+ * Compares content of the two #CamelNameValueArray and returns whether
+ * they equal. Note this is an expensive operation for large arrays.
+ *
+ * Returns: Whether the two #CamelNameValueArray have the same content.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_equal (const CamelNameValueArray *array_a,
+                             const CamelNameValueArray *array_b,
+                             gboolean case_sensitive)
+{
+       guint ii, len;
+
+       if (array_a == array_b)
+               return TRUE;
+
+       if (!array_a || !array_b)
+               return FALSE;
+
+       len = camel_name_value_array_get_length (array_a);
+       if (len != camel_name_value_array_get_length (array_b))
+               return FALSE;
+
+       for (ii = 0; ii < len; ii++) {
+               const gchar *value1, *value2;
+
+               value1 = camel_name_value_array_get_value (array_a, ii);
+               value2 = camel_name_value_array_get_named (array_b, case_sensitive,
+                       camel_name_value_array_get_name (array_a, ii));
+
+               if (g_strcmp0 (value1, value2) != 0)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+/* ------------------------------------------------------------------------ */
+
+G_DEFINE_BOXED_TYPE (CamelNamedFlags,
+               camel_named_flags,
+               camel_named_flags_copy,
+               camel_named_flags_free)
+
+/**
+ * camel_named_flags_new:
+ *
+ * Creates a new #CamelNamedFlags.
+ *
+ * Returns: (transfer full): A newly allocated #CamelNamedFlags.
+ *    Free it with camel_named_flags_free() when done with it.
+ *
+ * Since: 3.24
+ **/
+CamelNamedFlags *
+camel_named_flags_new (void)
+{
+       return (CamelNamedFlags *) g_ptr_array_new_with_free_func (g_free);
+}
+
+/**
+ * camel_named_flags_new_sized:
+ * @reserve_size: an array size to reserve
+ *
+ * Created a new #CamelNamedFlags, which has reserved @reserve_size
+ * elements. This value doesn't influence the camel_named_flags_get_length(),
+ * which returns zero on the array returned from this function.
+ *
+ * Returns: (transfer full): A newly allocated #CamelNameValueArray.
+ *    Free it with camel_named_flags_free() when done with it.
+ *
+ * See: camel_name_value_array_new, camel_name_value_array_copy
+ *
+ * Since: 3.24
+ **/
+CamelNamedFlags *
+camel_named_flags_new_sized (guint reserve_size)
+{
+       return (CamelNamedFlags *) g_ptr_array_new_full (reserve_size, g_free);
+}
+
+/**
+ * camel_named_flags_copy:
+ * @named_flags: (nullable): a #CamelNamedFlags
+ *
+ * Creates a copy of the @named_flags and returns it.
+ *
+ * Returns: (transfer full): A newly allocated #CamelNamedFlags.
+ *    Free it with camel_named_flags_free() when done with it.
+ *
+ * Since: 3.24
+ **/
+CamelNamedFlags *
+camel_named_flags_copy (const CamelNamedFlags *named_flags)
+{
+       const GPtrArray *src = (const GPtrArray *) named_flags;
+       GPtrArray *arr;
+       guint ii;
+
+       if (!src)
+               return NULL;
+
+       arr = (GPtrArray *) camel_named_flags_new_sized (src->len);
+       for (ii = 0; ii < src->len; ii++) {
+               const gchar *name = g_ptr_array_index (src, ii);
+
+               if (name && *name)
+                       g_ptr_array_add (arr, g_strdup (name));
+       }
+
+       return (CamelNamedFlags *) arr;
+}
+
+/**
+ * camel_named_flags_free:
+ * @named_flags: (nullable): a #CamelNamedFlags, or %NULL
+ *
+ * Frees memory associated iwth the @named_flags. Does nothing,
+ * if @named_flags is %NULL.
+ *
+ * Since: 3.24
+ **/
+void
+camel_named_flags_free (CamelNamedFlags *named_flags)
+{
+       if (named_flags)
+               g_ptr_array_unref ((GPtrArray *) named_flags);
+}
+
+static guint
+camel_named_flags_find (const CamelNamedFlags *named_flags,
+                       const gchar *name)
+{
+       GPtrArray *arr = (GPtrArray *) named_flags;
+       guint ii;
+
+       g_return_val_if_fail (named_flags != NULL, (guint) -1);
+       g_return_val_if_fail (name != NULL, (guint) -1);
+
+       for (ii = 0; ii < arr->len; ii++) {
+               const gchar *nm = g_ptr_array_index (arr, ii);
+
+               if (g_strcmp0 (nm, name) == 0)
+                       return ii;
+       }
+
+       return (guint) -1;
+}
+
+/**
+ * camel_named_flags_insert:
+ * @named_flags: a #CamelNamedFlags
+ * @name: name of the flag
+ *
+ * Inserts a flag named @name into the @named_flags, if it is not included
+ * already (comparing case sensitively), or does nothing otherwise.
+ *
+ * Returns: %TRUE the flag named @name was inserted; %FALSE otherwise.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_insert (CamelNamedFlags *named_flags,
+                         const gchar *name)
+{
+       GPtrArray *arr = (GPtrArray *) named_flags;
+       guint index;
+
+       g_return_val_if_fail (named_flags != NULL, FALSE);
+       g_return_val_if_fail (name != NULL, FALSE);
+
+       index = camel_named_flags_find (named_flags, name);
+
+       /* already there */
+       if (index != (guint) -1)
+               return FALSE;
+
+       g_ptr_array_add (arr, g_strdup (name));
+
+       return TRUE;
+}
+
+/**
+ * camel_named_flags_remove:
+ * @named_flags: a #CamelNamedFlags
+ * @name: name of the flag
+ *
+ * Removes a flag named @name from the @named_flags.
+ *
+ * Returns: %TRUE when the @named_flags contained a flag named @name,
+ *    comparing case sensitively, and it was removed; %FALSE otherwise.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_remove (CamelNamedFlags *named_flags,
+                         const gchar *name)
+{
+       GPtrArray *arr = (GPtrArray *) named_flags;
+       guint index;
+
+       g_return_val_if_fail (named_flags != NULL, FALSE);
+       g_return_val_if_fail (name != NULL, FALSE);
+
+       index = camel_named_flags_find (named_flags, name);
+
+       /* not there */
+       if (index == (guint) -1)
+               return FALSE;
+
+       g_ptr_array_remove_index (arr, index);
+
+       return TRUE;
+}
+
+/**
+ * camel_named_flags_contains:
+ * @named_flags: a #CamelNamedFlags
+ * @name: name of the flag
+ *
+ * Returns: Whether the @named_flags contains a flag named @name,
+ *    comparing case sensitively.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_contains (const CamelNamedFlags *named_flags,
+                           const gchar *name)
+{
+       g_return_val_if_fail (named_flags != NULL, FALSE);
+       g_return_val_if_fail (name != NULL, FALSE);
+
+       return camel_named_flags_find (named_flags, name) != (guint) -1;
+}
+
+/**
+ * camel_named_flags_clear:
+ * @named_flags: a #CamelNamedFlags
+ *
+ * Removes all the elements of the array.
+ *
+ * Since: 3.24
+ **/
+void
+camel_named_flags_clear (CamelNamedFlags *named_flags)
+{
+       GPtrArray *arr = (GPtrArray *) named_flags;
+
+       g_return_if_fail (named_flags != NULL);
+
+       if (arr->len)
+               g_ptr_array_remove_range (arr, 0, arr->len);
+}
+
+/**
+ * camel_named_flags_get_length:
+ * @named_flags: (nullable): a #CamelNamedFlags
+ *
+ * Returns: Length of the array, aka how many named flags are stored there.
+ *
+ * Since: 3.24
+ **/
+guint
+camel_named_flags_get_length (const CamelNamedFlags *named_flags)
+{
+       const GPtrArray *arr = (const GPtrArray *) named_flags;
+
+       if (!named_flags)
+               return 0;
+
+       return arr->len;
+}
+
+/**
+ * camel_named_flags_get:
+ * @named_flags: a #CamelNamedFlags
+ * @index: an index of an element
+ *
+ * Returns: (transfer none) (nullable): Name of the flag in at the given @index,
+ *   or %NULL on error.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_named_flags_get (const CamelNamedFlags *named_flags,
+                      guint index)
+{
+       const GPtrArray *arr = (const GPtrArray *) named_flags;
+
+       g_return_val_if_fail (named_flags != NULL, NULL);
+       g_return_val_if_fail (index < camel_named_flags_get_length (named_flags), NULL);
+
+       return g_ptr_array_index (arr, index);
+}
+
+/**
+ * camel_named_flags_equal:
+ * @named_flags_a: (nullable): the first #CamelNamedFlags
+ * @named_flags_b: (nullable): the second #CamelNamedFlags
+ *
+ * Compares content of the two #CamelNamedFlags and returns whether
+ * they equal. Note this is an expensive operation for large sets.
+ *
+ * Returns: Whether the two #CamelNamedFlags have the same content.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_equal (const CamelNamedFlags *named_flags_a,
+                        const CamelNamedFlags *named_flags_b)
+{
+       guint ii, len;
+
+       if (named_flags_a == named_flags_b)
+               return TRUE;
+
+       if (!named_flags_a || !named_flags_b)
+               return FALSE;
+
+       len = camel_named_flags_get_length (named_flags_a);
+       if (len != camel_named_flags_get_length (named_flags_b))
+               return FALSE;
+
+       for (ii = 0; ii < len; ii++) {
+               if (!camel_named_flags_contains (named_flags_a, camel_named_flags_get (named_flags_b, ii)))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/**
+ * camel_util_bdata_get_number:
+ * @bdata_ptr: a backend specific data (bdata) pointer
+ * @default_value: a value to return, when no data can be read
+ *
+ * Reads a numeric data from the @bdata_ptr and moves the @bdata_ptr
+ * after that number. If the number cannot be read, then the @default_value
+ * is returned instead and the @bdata_ptr is left unchanged. The number
+ * might be previously stored with the camel_util_bdata_put_number().
+ *
+ * Returns: The read number, or the @default_value, if the @bdata_ptr doesn't
+ *    point to a number.
+ *
+ * Since: 3.24
+ **/
+gint64
+camel_util_bdata_get_number (/* const */ gchar **bdata_ptr,
+                            gint64 default_value)
+{
+       gint64 result;
+       gchar *endptr;
+
+       g_return_val_if_fail (bdata_ptr != NULL, default_value);
+
+       if (!bdata_ptr || !*bdata_ptr || !**bdata_ptr)
+               return default_value;
+
+       if (**bdata_ptr == ' ')
+               *bdata_ptr += 1;
+
+       if (!**bdata_ptr)
+               return default_value;
+
+       endptr = *bdata_ptr;
+
+       result = g_ascii_strtoll (*bdata_ptr, &endptr, 10);
+
+       if (endptr == *bdata_ptr)
+               result = default_value;
+       else
+               *bdata_ptr = endptr;
+
+       return result;
+}
+
+/**
+ * camel_util_bdata_put_number:
+ * @bdata_str: a #GString to store a backend specific data (bdata)
+ * @value: a value to store
+ *
+ * Puts the number @value at the end of the @bdata_str. In case the @bdata_str
+ * is not empty a space is added before the numeric @value. The stored value
+ * can be read back with the camel_util_bdata_get_number().
+ *
+ * Since: 3.24
+ **/
+void
+camel_util_bdata_put_number (GString *bdata_str,
+                            gint64 value)
+{
+       g_return_if_fail (bdata_str != NULL);
+
+       if (bdata_str->len && bdata_str->str[bdata_str->len - 1] != ' ')
+               g_string_append_c (bdata_str, ' ');
+
+       g_string_append_printf (bdata_str, "%" G_GINT64_FORMAT, value);
+}
+
+/**
+ * camel_util_bdata_get_string:
+ * @bdata_ptr: a backend specific data (bdata) pointer
+ * @default_value: a value to return, when no data can be read
+ *
+ * Reads a string data from the @bdata_ptr and moves the @bdata_ptr
+ * after that string. If the string cannot be read, then the @default_value
+ * is returned instead and the @bdata_ptr is left unchanged. The string
+ * might be previously stored with the camel_util_bdata_put_string().
+ *
+ * Returns: (transfer full): Newly allocated string, which was read, or
+ *    dupped the @default_value, if the @bdata_ptr doesn't point to a string.
+ *    Free returned pointer with g_free() when done with it.
+ *
+ * Since: 3.24
+ **/
+gchar *
+camel_util_bdata_get_string (/* const */ gchar **bdata_ptr,
+                            const gchar *default_value)
+{
+       gint64 length, has_length;
+       gchar *orig_bdata_ptr;
+       gchar *result;
+
+       g_return_val_if_fail (bdata_ptr != NULL, NULL);
+
+       orig_bdata_ptr = *bdata_ptr;
+
+       length = camel_util_bdata_get_number (bdata_ptr, -1);
+
+       /* might be a '-' sign */
+       if (*bdata_ptr && **bdata_ptr == '-')
+               *bdata_ptr += 1;
+       else
+               length = -1;
+
+       if (length < 0 || !*bdata_ptr || !**bdata_ptr || *bdata_ptr == orig_bdata_ptr) {
+               *bdata_ptr = orig_bdata_ptr;
+
+               return g_strdup (default_value);
+       }
+
+       if (!length)
+               return g_strdup ("");
+
+       has_length = strlen (*bdata_ptr);
+       if (has_length < length)
+               length = has_length;
+
+       result = g_strndup (*bdata_ptr, length);
+       *bdata_ptr += length;
+
+       return result;
+}
+
+/**
+ * camel_util_bdata_put_string:
+ * @bdata_str: a #GString to store a backend specific data (bdata)
+ * @value: a value to store
+ *
+ * Puts the string @value at the end of the @bdata_str. In case the @bdata_str
+ * is not empty a space is added before the string @value. The stored value
+ * can be read back with the camel_util_bdata_get_string().
+ *
+ * The strings are encoded as "length-value", quotes for clarity only.
+ *
+ * Since: 3.24
+ **/
+void
+camel_util_bdata_put_string (GString *bdata_str,
+                            const gchar *value)
+{
+       g_return_if_fail (bdata_str != NULL);
+       g_return_if_fail (value != NULL);
+
+       camel_util_bdata_put_number (bdata_str, strlen (value));
+
+       g_string_append_printf (bdata_str, "-%s", value);
+}
+
+/* ------------------------------------------------------------------------ */
diff --git a/camel/camel-utils.h b/camel/camel-utils.h
new file mode 100644
index 0000000..94551c1
--- /dev/null
+++ b/camel/camel-utils.h
@@ -0,0 +1,133 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_UTILS_H
+#define CAMEL_UTILS_H
+
+#include <glib-object.h>
+
+/**
+ * CamelNameValueArray:
+ *
+ * Since: 3.24
+ **/
+struct _CamelNameValueArray;
+typedef struct _CamelNameValueArray CamelNameValueArray;
+
+#define CAMEL_TYPE_NAME_VALUE_ARRAY (camel_name_value_array_get_type ())
+
+GType           camel_name_value_array_get_type        (void) G_GNUC_CONST;
+CamelNameValueArray *
+               camel_name_value_array_new      (void);
+CamelNameValueArray *
+               camel_name_value_array_new_sized
+                                               (guint reserve_size);
+CamelNameValueArray *
+               camel_name_value_array_copy     (const CamelNameValueArray *array);
+void           camel_name_value_array_free     (CamelNameValueArray *array);
+guint          camel_name_value_array_get_length
+                                               (const CamelNameValueArray *array);
+gboolean       camel_name_value_array_get      (const CamelNameValueArray *array,
+                                                guint index,
+                                                const gchar **out_name,
+                                                const gchar **out_value);
+const gchar *  camel_name_value_array_get_named
+                                               (const CamelNameValueArray *array,
+                                                gboolean case_sensitive,
+                                                const gchar *name);
+const gchar *  camel_name_value_array_get_name (const CamelNameValueArray *array,
+                                                guint index);
+const gchar *  camel_name_value_array_get_value
+                                               (const CamelNameValueArray *array,
+                                                guint index);
+void           camel_name_value_array_append   (CamelNameValueArray *array,
+                                                const gchar *name,
+                                                const gchar *value);
+gboolean       camel_name_value_array_set      (CamelNameValueArray *array,
+                                                guint index,
+                                                const gchar *name,
+                                                const gchar *value);
+gboolean       camel_name_value_array_set_name (CamelNameValueArray *array,
+                                                guint index,
+                                                const gchar *name);
+gboolean       camel_name_value_array_set_value
+                                               (CamelNameValueArray *array,
+                                                guint index,
+                                                const gchar *value);
+gboolean       camel_name_value_array_set_named
+                                               (CamelNameValueArray *array,
+                                                gboolean case_sensitive,
+                                                const gchar *name,
+                                                const gchar *value);
+gboolean       camel_name_value_array_remove   (CamelNameValueArray *array,
+                                                guint index);
+guint          camel_name_value_array_remove_named
+                                               (CamelNameValueArray *array,
+                                                gboolean case_sensitive,
+                                                const gchar *name,
+                                                gboolean all_occurrences);
+void           camel_name_value_array_clear    (CamelNameValueArray *array);
+gboolean       camel_name_value_array_equal    (const CamelNameValueArray *array_a,
+                                                const CamelNameValueArray *array_b,
+                                                gboolean case_sensitive);
+
+/**
+ * CamelNamedFlags:
+ *
+ * Since: 3.24
+ **/
+struct _CamelNamedFlags;
+typedef struct _CamelNamedFlags CamelNamedFlags;
+
+#define CAMEL_TYPE_NAMED_FLAGS (camel_named_flags_get_type ())
+
+GType           camel_named_flags_get_type     (void) G_GNUC_CONST;
+CamelNamedFlags *
+               camel_named_flags_new           (void);
+CamelNamedFlags *
+               camel_named_flags_new_sized     (guint reserve_size);
+CamelNamedFlags *
+               camel_named_flags_copy          (const CamelNamedFlags *named_flags);
+void           camel_named_flags_free          (CamelNamedFlags *named_flags);
+gboolean       camel_named_flags_insert        (CamelNamedFlags *named_flags,
+                                                const gchar *name);
+gboolean       camel_named_flags_remove        (CamelNamedFlags *named_flags,
+                                                const gchar *name);
+gboolean       camel_named_flags_contains      (const CamelNamedFlags *named_flags,
+                                                const gchar *name);
+void           camel_named_flags_clear         (CamelNamedFlags *named_flags);
+guint          camel_named_flags_get_length    (const CamelNamedFlags *named_flags);
+const gchar *  camel_named_flags_get           (const CamelNamedFlags *named_flags,
+                                                guint index);
+gboolean       camel_named_flags_equal         (const CamelNamedFlags *named_flags_a,
+                                                const CamelNamedFlags *named_flags_b);
+
+/* Utility functions */
+gint64         camel_util_bdata_get_number     (/* const */ gchar **bdata_ptr,
+                                                gint64 default_value);
+void           camel_util_bdata_put_number     (GString *bdata_str,
+                                                gint64 value);
+gchar *                camel_util_bdata_get_string     (/* const */ gchar **bdata_ptr,
+                                                const gchar *default_value);
+void           camel_util_bdata_put_string     (GString *bdata_str,
+                                                const gchar *value);
+
+#endif /* CAMEL_UTILS_H */
diff --git a/camel/camel.h b/camel/camel.h
index d99c95a..9aacbe6 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -130,6 +130,7 @@
 #include <camel/camel-url.h>
 #include <camel/camel-url-scanner.h>
 #include <camel/camel-utf8.h>
+#include <camel/camel-utils.h>
 #include <camel/camel-vee-data-cache.h>
 #include <camel/camel-vee-folder.h>
 #include <camel/camel-vee-message-info.h>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]