From 93590436c1a9823b83b14c0f806a9bb97888d860 Mon Sep 17 00:00:00 2001 From: djcb Date: Thu, 19 Aug 2010 22:15:19 +0300 Subject: [PATCH] * MuMsgContact refactoring (split off) --- src/Makefile.am | 2 + src/mu-msg-contact.c | 78 ++++++++++++++++++++++ src/mu-msg-contact.h | 122 ++++++++++++++++++++++++++++++++++ src/mu-msg-gmime.c | 68 ++++++++++++++----- src/mu-msg-gmime.h | 21 +++--- src/mu-msg.h | 16 ----- src/tests/test-mu-msg-gmime.c | 34 +++++----- 7 files changed, 281 insertions(+), 60 deletions(-) create mode 100644 src/mu-msg-contact.c create mode 100644 src/mu-msg-contact.h diff --git a/src/Makefile.am b/src/Makefile.am index db49f7c6..c5357984 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,6 +60,8 @@ libmu_la_SOURCES= \ mu-log.h \ mu-maildir.c \ mu-maildir.h \ + mu-msg-contact.c \ + mu-msg-contact.h \ mu-msg-fields.c \ mu-msg-fields.h \ mu-msg-flags.c \ diff --git a/src/mu-msg-contact.c b/src/mu-msg-contact.c new file mode 100644 index 00000000..c1ae9342 --- /dev/null +++ b/src/mu-msg-contact.c @@ -0,0 +1,78 @@ +/* +** Copyright (C) 2008-2010 Dirk-Jan C. Binnema +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 3, or (at your option) any +** later version. +** +** This program 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 General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, +** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /*HAVE_CONFIG_H*/ + +#include +#include "mu-msg-contact.h" + + +MuMsgContact* +mu_msg_contact_new (const char *name, const char* address, + MuMsgContactType ctype) +{ + MuMsgContact *ct; + + g_return_val_if_fail (ctype == MU_MSG_CONTACT_TYPE_TO || + ctype == MU_MSG_CONTACT_TYPE_FROM || + ctype == MU_MSG_CONTACT_TYPE_CC || + ctype == MU_MSG_CONTACT_TYPE_BCC, + NULL); + + ct = g_slice_new (MuMsgContact); + ct->name = name ? g_strdup(name) : NULL; + ct->address = address ? g_strdup(address) : NULL; + ct->type = ctype; + + return ct; +} + + +void +mu_msg_contact_destroy (MuMsgContact *ct) +{ + if (ct) { + g_free (ct->name); + g_free (ct->address); + } + + g_slice_free (MuMsgContact, ct); +} + + + +void +mu_msg_contact_list_foreach (GSList *lst, + MuMsgContactForeachFunc func, + gpointer user_data) +{ + while (lst && func((MuMsgContact*)lst->data, user_data)) + lst = g_slist_next(lst); +} + + + +void +mu_msg_contact_list_free (GSList *lst) +{ + g_slist_foreach (lst, (GFunc)mu_msg_contact_destroy, NULL); + g_slist_free (lst); +} diff --git a/src/mu-msg-contact.h b/src/mu-msg-contact.h new file mode 100644 index 00000000..35b8df5a --- /dev/null +++ b/src/mu-msg-contact.h @@ -0,0 +1,122 @@ +/* +** Copyright (C) 2008-2010 Dirk-Jan C. Binnema +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 3, or (at your option) any +** later version. +** +** This program 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 General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, +** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +*/ + +#ifndef __MU_MSG_CONTACT_H__ +#define __MU_MSG_CONTACT_H__ + +#include + +enum _MuMsgContactType { /* Reply-To:? */ + MU_MSG_CONTACT_TYPE_TO, + MU_MSG_CONTACT_TYPE_FROM, + MU_MSG_CONTACT_TYPE_CC, + MU_MSG_CONTACT_TYPE_BCC +}; +typedef enum _MuMsgContactType MuMsgContactType; + + +struct _MuMsgContact { + char *name; /* Foo Bar */ + char *address; /* foo@bar.cuux */ + MuMsgContactType type; /*MU_MSG_CONTACT_TYPE_{TO,CC,BCC,FROM}*/ +}; +typedef struct _MuMsgContact MuMsgContact; + + +/** + * create a new MuMsgContact instance + * + * @param name name of the contact (or NULL) + * @param addr address of the contact (or NULL) + * @param ctype a valid contact type + * + * @return a new MuMsgContact instance; use mu_msg_contact_destroy + * when finished. + */ +MuMsgContact *mu_msg_contact_new (const char *name, const char *addr, + MuMsgContactType ctype); + +/** + * destroy a MuMsgContact + * + * @param ct a MuMsgContact, or NULL + */ +void mu_msg_contact_destroy (MuMsgContact *ct); + + +/** + * macro to get the name of a contact + * + * @param ct a MuMsgContact + * + * @return the name + */ +#define mu_msg_contact_name(ct) ((ct)->name) + +/** + * macro to get the address of a contact + * + * @param ct a MuMsgContact + * + * @return the address + */ +#define mu_msg_contact_address(ct) ((ct)->address) + +/** + * macro to get the contact type + * + * @param ct a MuMsgContact + * + * @return the contact type + */ +#define mu_msg_contact_type(ct) ((ct)->type) + + +/** + * callback function + * + * @param contact + * @param user_data a user provided data pointer + * + * @return TRUE if we should continue the foreach, FALSE otherwise + */ +typedef gboolean (*MuMsgContactForeachFunc) (MuMsgContact* contact, + gpointer user_data); + +/** + * call a function for each MuMsgContact in the list + * + * @param lst a list of MuMsgContact objects + * @param func a callback function + * @param user_data user pointer, passed to the callback + */ +void mu_msg_contact_list_foreach (GSList *lst, + MuMsgContactForeachFunc func, + gpointer user_data); + +/** + * free a list of MuMsgContact objects + * + * @param lst list of MuMsgContact object + */ +void mu_msg_contact_list_free (GSList *lst); + + + +#endif /*__MU_MSG_CONTACT_H__*/ diff --git a/src/mu-msg-gmime.c b/src/mu-msg-gmime.c index 74f6f87c..34009148 100644 --- a/src/mu-msg-gmime.c +++ b/src/mu-msg-gmime.c @@ -843,13 +843,13 @@ fill_contact (MuMsgContact *contact, InternetAddress *addr, if (!addr) return FALSE; - contact->name = internet_address_get_name (addr); + contact->name = (char*)internet_address_get_name (addr); contact->type = ctype; /* we only support internet addresses; * if we don't check, g_mime hits an assert */ - contact->address = internet_address_mailbox_get_addr + contact->address = (char*)internet_address_mailbox_get_addr (INTERNET_ADDRESS_MAILBOX(addr)); return TRUE; @@ -858,9 +858,9 @@ fill_contact (MuMsgContact *contact, InternetAddress *addr, static int address_list_foreach (InternetAddressList *addrlist, - MuMsgContactType ctype, - MuMsgGMimeContactsForeachFunc func, - gpointer user_data) + MuMsgContactType ctype, + MuMsgContactForeachFunc func, + gpointer user_data) { int i,rv; @@ -868,7 +868,7 @@ address_list_foreach (InternetAddressList *addrlist, return 0; for (i = 0, rv = 0; i != internet_address_list_length(addrlist); ++i) { - + MuMsgContact contact; if (!fill_contact(&contact, internet_address_list_get_address (addrlist, i), @@ -887,10 +887,10 @@ address_list_foreach (InternetAddressList *addrlist, static int -mu_msg_gmime_get_contacts_from (MuMsgGMime *msg, MuMsgGMimeContactsForeachFunc func, +get_contacts_from (MuMsgGMime *msg, MuMsgContactForeachFunc func, gpointer user_data) { - InternetAddressList *list; + InternetAddressList *lst; int rv; /* we go through this whole excercise of trying to get a *list* @@ -898,20 +898,22 @@ mu_msg_gmime_get_contacts_from (MuMsgGMime *msg, MuMsgGMimeContactsForeachFunc f * internet_address_parse_string has the nice side-effect of * splitting in names and addresses for us */ - list = internet_address_list_parse_string ( + lst = internet_address_list_parse_string ( g_mime_message_get_sender (msg->_mime_msg)); - - rv = address_list_foreach (list, MU_MSG_CONTACT_TYPE_FROM, func, user_data); - - if (list) - g_object_unref (G_OBJECT(list)); - + if (lst) { + rv = address_list_foreach (lst, MU_MSG_CONTACT_TYPE_FROM, + func, user_data); + g_object_unref (G_OBJECT(lst)); + } + return rv; } + + void -mu_msg_gmime_contacts_foreach (MuMsgGMime *msg, MuMsgGMimeContactsForeachFunc func, +mu_msg_gmime_contacts_foreach (MuMsgGMime *msg, MuMsgContactForeachFunc func, gpointer user_data) { int i, rv; @@ -926,8 +928,8 @@ mu_msg_gmime_contacts_foreach (MuMsgGMime *msg, MuMsgGMimeContactsForeachFunc fu g_return_if_fail (func && msg); - /* first, get the from address */ - rv = mu_msg_gmime_get_contacts_from (msg, func, user_data); + /* first, get the from address(es) */ + rv = get_contacts_from (msg, func, user_data); if (rv != 0) return; /* callback told us to stop */ @@ -942,6 +944,36 @@ mu_msg_gmime_contacts_foreach (MuMsgGMime *msg, MuMsgGMimeContactsForeachFunc fu } +static gboolean +each_contact (MuMsgContact *contact, GSList **lst) +{ + MuMsgContact *ct; + + ct = mu_msg_contact_new (mu_msg_contact_name(contact), + mu_msg_contact_address (contact), + mu_msg_contact_type (contact)); + + *lst = g_slist_append (*lst, ct); + return TRUE; +} + + +GSList * +mu_msg_gmime_contacts_list (MuMsgGMime *msg) +{ + GSList *contacts; + + g_return_val_if_fail (msg, NULL); + + contacts = NULL; + mu_msg_gmime_contacts_foreach (msg, + (MuMsgContactForeachFunc)each_contact, + &contacts); + return contacts; +} + + + static gboolean _initialized = FALSE; void diff --git a/src/mu-msg-gmime.h b/src/mu-msg-gmime.h index 88d41e39..ec41b495 100644 --- a/src/mu-msg-gmime.h +++ b/src/mu-msg-gmime.h @@ -21,6 +21,7 @@ #define __MU_MSG_GMIME_H__ #include "mu-msg.h" +#include "mu-msg-contact.h" G_BEGIN_DECLS @@ -316,16 +317,18 @@ time_t mu_msg_gmime_get_timestamp (MuMsgGMime *msg); + /** - * callback function - * - * @param contact - * @param user_data a user provided data pointer - * - * @return TRUE if we should continue the foreach, FALSE otherwise + * get a list of contacts (MuMsgContact) for this message; you can use + * GSList functions or mu_msg_contact_list_foreach to read the items. + * + * @param msg a valid MuMsgGMime* instance + * + * @return a list of contacts for this message; use mu_msg_contact_list_free + * to free it when done */ -typedef gboolean (*MuMsgGMimeContactsForeachFunc) (MuMsgContact* contact, - gpointer user_data); +GSList * mu_msg_gmime_contacts_list (MuMsgGMime *msg); + /** * call a function for each of the contacts in a message @@ -337,7 +340,7 @@ typedef gboolean (*MuMsgGMimeContactsForeachFunc) (MuMsgContact* contact, * */ void mu_msg_gmime_contacts_foreach (MuMsgGMime *msg, - MuMsgGMimeContactsForeachFunc func, + MuMsgContactForeachFunc func, gpointer user_data); G_END_DECLS diff --git a/src/mu-msg.h b/src/mu-msg.h index 50bc5a95..4026689b 100644 --- a/src/mu-msg.h +++ b/src/mu-msg.h @@ -43,20 +43,4 @@ enum _MuMsgPriority { }; typedef enum _MuMsgPriority MuMsgPriority; -enum _MuMsgContactType { /* Reply-To:? */ - MU_MSG_CONTACT_TYPE_TO, - MU_MSG_CONTACT_TYPE_FROM, - MU_MSG_CONTACT_TYPE_CC, - MU_MSG_CONTACT_TYPE_BCC -}; -typedef enum _MuMsgContactType MuMsgContactType; - -struct _MuMsgContact { - const char *name; /* Foo Bar */ - const char *address; /* foo@bar.cuux */ - MuMsgContactType type; /*MU_MSG_CONTACT_TYPE_{TO,CC,BCC,FROM}*/ -}; -typedef struct _MuMsgContact MuMsgContact; - - #endif /*__MU_MSG_H__*/ diff --git a/src/tests/test-mu-msg-gmime.c b/src/tests/test-mu-msg-gmime.c index 84717c60..35af794f 100644 --- a/src/tests/test-mu-msg-gmime.c +++ b/src/tests/test-mu-msg-gmime.c @@ -91,17 +91,16 @@ test_mu_msg_gmime_01 (void) ==, 1217530645); { GSList *lst, *cur; - lst = NULL; - mu_msg_gmime_contacts_foreach (msg, - (MuMsgGMimeContactsForeachFunc)each_contact, - &lst); + lst = mu_msg_gmime_contacts_list (msg); g_assert_cmpuint (g_slist_length(lst),==, 1); cur = lst; - g_assert_cmpstr ((const char*)cur->data, ==, - " "); - g_slist_foreach (lst, (GFunc)g_free, NULL); - g_slist_free (lst); + g_assert_cmpstr (mu_msg_contact_name ((MuMsgContact*)cur->data), + ==, NULL); + g_assert_cmpstr (mu_msg_contact_address ((MuMsgContact*)cur->data), + ==, "anon@example.com"); + + mu_msg_contact_list_free (lst); } mu_msg_gmime_destroy (msg); @@ -138,21 +137,22 @@ test_mu_msg_gmime_02 (void) ==, MU_MSG_PRIORITY_LOW); g_assert_cmpuint (mu_msg_gmime_get_date(msg), ==, 1218051515); + { GSList *lst, *cur; - lst = NULL; - mu_msg_gmime_contacts_foreach (msg, - (MuMsgGMimeContactsForeachFunc)each_contact, - &lst); + lst = mu_msg_gmime_contacts_list (msg); g_assert_cmpuint (g_slist_length(lst),==, 1); cur = lst; - g_assert_cmpstr ((const char*)cur->data, ==, - " "); - g_slist_foreach (lst, (GFunc)g_free, NULL); - g_slist_free (lst); + g_assert_cmpstr (mu_msg_contact_name ((MuMsgContact*)cur->data), + ==, NULL); + g_assert_cmpstr (mu_msg_contact_address ((MuMsgContact*)cur->data), + ==, "anon@example.com"); + + mu_msg_contact_list_free (lst); } - + + mu_msg_gmime_destroy (msg); g_free (mfile);