From 8ad4350fef132b016bbab5eeb1c4a713e51035c6 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 21 Oct 2009 15:23:08 -0700 Subject: [PATCH] Add notmuch_message_get_thread_ids function Along with all of the notmuch_thread_ids_t iterator functions. Using a consistent idiom seems better here rather than returning a comma-separated string and forcing the user to parse it. --- message.cc | 51 +++++++++++++++++++++++++++++++ notmuch.h | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 133 insertions(+), 6 deletions(-) diff --git a/message.cc b/message.cc index cce304ce..8ca8fdee 100644 --- a/message.cc +++ b/message.cc @@ -32,6 +32,11 @@ struct _notmuch_tags { Xapian::TermIterator iterator_end; }; +struct _notmuch_thread_ids { + char *current; + char *next; +}; + #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0])) /* These prefix values are specifically chosen to be compatible @@ -167,6 +172,25 @@ notmuch_message_get_tags (notmuch_message_t *message) return tags; } +notmuch_thread_ids_t * +notmuch_message_get_thread_ids (notmuch_message_t *message) +{ + notmuch_thread_ids_t *thread_ids; + const char *id_str; + + thread_ids = talloc (message, notmuch_thread_ids_t); + if (unlikely (thread_ids == NULL)) + return NULL; + + id_str = message->doc.get_value (NOTMUCH_VALUE_THREAD).c_str (); + thread_ids->next = talloc_strdup (message, id_str); + + /* Initialize thread_ids->current and terminate first ID. */ + notmuch_thread_ids_advance (thread_ids); + + return thread_ids; +} + void notmuch_message_destroy (notmuch_message_t *message) { @@ -205,3 +229,30 @@ notmuch_tags_destroy (notmuch_tags_t *tags) { talloc_free (tags); } + +notmuch_bool_t +notmuch_thread_ids_has_more (notmuch_thread_ids_t *thread_ids) +{ + if (thread_ids->current == NULL || *thread_ids->current == '\0') + return FALSE; + else + return TRUE; +} + +const char * +notmuch_thread_ids_get (notmuch_thread_ids_t *thread_ids) +{ + return thread_ids->current; +} + +void +notmuch_thread_ids_advance (notmuch_thread_ids_t *thread_ids) +{ + thread_ids->current = strsep (&thread_ids->next, ","); +} + +void +notmuch_thread_ids_destroy (notmuch_thread_ids_t *thread_ids) +{ + talloc_free (thread_ids); +} diff --git a/notmuch.h b/notmuch.h index df432bcc..41987b58 100644 --- a/notmuch.h +++ b/notmuch.h @@ -67,6 +67,7 @@ typedef struct _notmuch_query notmuch_query_t; typedef struct _notmuch_results notmuch_results_t; typedef struct _notmuch_message notmuch_message_t; typedef struct _notmuch_tags notmuch_tags_t; +typedef struct _notmuch_thread_ids notmuch_thread_ids_t; /* Create a new, empty notmuch database located at 'path'. * @@ -304,24 +305,59 @@ notmuch_message_get_message_id (notmuch_message_t *message); * notmuch_tags_t *tags; * const char *tag; * - * message = notmuch_results_get (results); + * message = notmuch_database_find_message (database, message_id); * * for (tags = notmuch_message_get_tags (message); * notmuch_tags_has_more (tags); * notmuch_result_advance (tags)) * { - * tag = notmuch_tags_get_string (tags); + * tag = notmuch_tags_get (tags); * .... * } * - * Note: If you are finished with a message before its containing - * query, you can call notmuch_message_destroy to clean up some memory - * sooner. If you don't call it, all the memory will still be - * reclaimed when the query is destroyed. + * notmuch_message_destroy (message); + * + * Note that there's no explicit destructor needed for the + * notmuch_tags_t object. (For consistency, we do provide a + * notmuch_tags_destroy function, but there's no good reason to call + * it if the message is about to be destroyed). */ notmuch_tags_t * notmuch_message_get_tags (notmuch_message_t *message); +/* Get the thread IDs for 'message', returning a notmuch_thread_ids_t + * object which can be used to iterate over all thread IDs. + * + * The thread_ids object is owned by the message and as such, will + * only be valid for as long as the message is valid, (which is until + * the query from which it derived is destroyed). + * + * Typical usage might be: + * + * notmuch_message_t *message; + * notmuch_thread_ids_t *thread_ids; + * const char *thread_id; + * + * message = notmuch_database_find_message (database, message_id); + * + * for (thread_ids = notmuch_message_get_thread_ids (message); + * notmuch_thread_ids_has_more (thread_ids); + * notmuch_thread_ids_advance (thread_ids)) + * { + * thread_id = notmuch_thread_ids_get (thread_ids); + * .... + * } + * + * notmuch_message_destroy (message); + * + * Note that there's no explicit destructor needed for the + * notmuch_thread_ids_t object. (For consistency, we do provide a + * notmuch_thread_ids_destroy function, but there's no good reason to + * call it if the message is about to be destroyed). + */ +notmuch_thread_ids_t * +notmuch_message_get_thread_ids (notmuch_message_t *message); + /* Destroy a notmuch_message_t object. * * It can be useful to call this function in the case of a single @@ -373,6 +409,46 @@ notmuch_tags_advance (notmuch_tags_t *results); void notmuch_tags_destroy (notmuch_tags_t *tags); +/* Does the given notmuch_thread_ids_t object contain any more thread IDs. + * + * When this function returns TRUE, notmuch_thread_ids_get will return a + * valid string. Whereas when this function returns FALSE, + * notmuch_thread_ids_get will return NULL. + * + * See the documentation of notmuch_message_get_thread_ids for example code + * showing how to iterate over a notmuch_thread_ids_t object. + */ +notmuch_bool_t +notmuch_thread_ids_has_more (notmuch_thread_ids_t *thread_ids); + +/* Get the current thread ID from 'thread_ids' as a string. + * + * Note: The returned string belongs to 'thread_ids' and has a lifetime + * identical to it (and the query to which it utlimately belongs). + * + * See the documentation of notmuch_message_get_thread_ids for example code + * showing how to iterate over a notmuch_thread_ids_t object. + */ +const char * +notmuch_thread_ids_get (notmuch_thread_ids_t *thread_ids); + +/* Advance the 'thread_ids' iterator to the next tag. + * + * See the documentation of notmuch_message_get_thread_ids for example code + * showing how to iterate over a notmuch_thread_ids_t object. + */ +void +notmuch_thread_ids_advance (notmuch_thread_ids_t *thread_ids); + +/* Destroy a notmuch_thread_ids_t object. + * + * It's not strictly necessary to call this function. All memory from + * the notmuch_thread_ids_t object will be reclaimed when the containg + * message or query objects are destroyed. + */ +void +notmuch_thread_ids_destroy (notmuch_thread_ids_t *thread_ids); + NOTMUCH_END_DECLS #endif