[evolution-data-server/wip/camel-more-gobject] More file splitting



commit 35033cb6af77a9fd01e2f83ed5ca0a928699bb4e
Author: Milan Crha <mcrha redhat com>
Date:   Mon Sep 12 13:51:37 2016 +0200

    More file splitting
    
    Let's have a separate file for CamelNamedFlags and CamelNameValueArray
    structured, which is a cleaner solution than having them each in one file.

 camel/Makefile.am              |    4 +
 camel/camel-message-info.h     |    2 +
 camel/camel-name-value-array.c |  633 ++++++++++++++++++++++++++++
 camel/camel-name-value-array.h |   96 +++++
 camel/camel-named-flags.c      |  317 ++++++++++++++
 camel/camel-named-flags.h      |   62 +++
 camel/camel-utils.c            |  906 ----------------------------------------
 camel/camel-utils.h            |   99 +-----
 camel/camel.h                  |    2 +
 9 files changed, 1119 insertions(+), 1002 deletions(-)
---
diff --git a/camel/Makefile.am b/camel/Makefile.am
index d730ff3..cad8480 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -121,6 +121,8 @@ libcamel_1_2_la_SOURCES = \
        camel-multipart-encrypted.c \
        camel-multipart-signed.c \
        camel-multipart.c \
+       camel-named-flags.c \
+       camel-name-value-array.c \
        camel-net-utils.c \
        camel-network-service.c \
        camel-network-settings.c \
@@ -243,6 +245,8 @@ libcamelinclude_HEADERS = \
        camel-multipart-encrypted.h \
        camel-multipart-signed.h \
        camel-multipart.h \
+       camel-named-flags.h \
+       camel-name-value-array.h \
        camel-net-utils.h \
        camel-network-service.h \
        camel-network-settings.h \
diff --git a/camel/camel-message-info.h b/camel/camel-message-info.h
index acdbee7..52b3394 100644
--- a/camel/camel-message-info.h
+++ b/camel/camel-message-info.h
@@ -24,6 +24,8 @@
 
 #include <glib-object.h>
 
+#include <camel/camel-named-flags.h>
+#include <camel/camel-name-value-array.h>
 #include <camel/camel-utils.h>
 
 /* Standard GObject macros */
diff --git a/camel/camel-name-value-array.c b/camel/camel-name-value-array.c
new file mode 100644
index 0000000..48a11a4
--- /dev/null
+++ b/camel/camel-name-value-array.c
@@ -0,0 +1,633 @@
+/* -*- 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-name-value-array.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;
+}
diff --git a/camel/camel-name-value-array.h b/camel/camel-name-value-array.h
new file mode 100644
index 0000000..aa902a9
--- /dev/null
+++ b/camel/camel-name-value-array.h
@@ -0,0 +1,96 @@
+/* -*- 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_NAME_VALUE_ARRAY_H
+#define CAMEL_NAME_VALUE_ARRAY_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * 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);
+
+G_END_DECLS
+
+#endif /* CAMEL_NAME_VALUE_ARRAY_H */
diff --git a/camel/camel-named-flags.c b/camel/camel-named-flags.c
new file mode 100644
index 0000000..c2869b4
--- /dev/null
+++ b/camel/camel-named-flags.c
@@ -0,0 +1,317 @@
+/* -*- 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-named-flags.h"
+
+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;
+}
diff --git a/camel/camel-named-flags.h b/camel/camel-named-flags.h
new file mode 100644
index 0000000..e5e7ca5
--- /dev/null
+++ b/camel/camel-named-flags.h
@@ -0,0 +1,62 @@
+/* -*- 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_NAMED_FLAGS_H
+#define CAMEL_NAMED_FLAGS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * 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);
+
+G_END_DECLS
+
+#endif /* CAMEL_NAMED_FLAGS_H */
diff --git a/camel/camel-utils.c b/camel/camel-utils.c
index 71901a4..b7a0f5d 100644
--- a/camel/camel-utils.c
+++ b/camel/camel-utils.c
@@ -22,912 +22,8 @@
 #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
@@ -1075,5 +171,3 @@ camel_util_bdata_put_string (GString *bdata_str,
 
        g_string_append_printf (bdata_str, "-%s", value);
 }
-
-/* ------------------------------------------------------------------------ */
diff --git a/camel/camel-utils.h b/camel/camel-utils.h
index 94551c1..25c2864 100644
--- a/camel/camel-utils.h
+++ b/camel/camel-utils.h
@@ -24,103 +24,8 @@
 
 #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;
+G_BEGIN_DECLS
 
-#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,
@@ -130,4 +35,6 @@ gchar *              camel_util_bdata_get_string     (/* const */ gchar **bdata_ptr,
 void           camel_util_bdata_put_string     (GString *bdata_str,
                                                 const gchar *value);
 
+G_END_DECLS
+
 #endif /* CAMEL_UTILS_H */
diff --git a/camel/camel.h b/camel/camel.h
index 9aacbe6..b405baf 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -85,6 +85,8 @@
 #include <camel/camel-multipart.h>
 #include <camel/camel-multipart-encrypted.h>
 #include <camel/camel-multipart-signed.h>
+#include <camel/camel-named-flags.h>
+#include <camel/camel-name-value-array.h>
 #include <camel/camel-net-utils.h>
 #include <camel/camel-network-service.h>
 #include <camel/camel-nntp-address.h>


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