X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=lib%2Fmessage.cc;h=692fd897813873892f832485c003fd83e661fd4f;hp=28f19a88502dc79ff29210297abfbed4f5ef2562;hb=387828c4356416278fdac8446c904fe4c5ad283d;hpb=146549321044615d9aef2b30cedccda9c49f3f38;ds=sidebyside diff --git a/lib/message.cc b/lib/message.cc index 28f19a88..692fd897 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -21,6 +21,8 @@ #include "notmuch-private.h" #include "database-private.h" +#include + #include #include @@ -31,8 +33,11 @@ struct _notmuch_message { int frozen; char *message_id; char *thread_id; + char *in_reply_to; char *filename; notmuch_message_file_t *message_file; + notmuch_message_list_t *replies; + Xapian::Document doc; }; @@ -107,9 +112,17 @@ _notmuch_message_create (const void *talloc_owner, /* Each of these will be lazily created as needed. */ message->message_id = NULL; message->thread_id = NULL; + message->in_reply_to = NULL; message->filename = NULL; message->message_file = NULL; + message->replies = _notmuch_message_list_create (message); + if (unlikely (message->replies == NULL)) { + if (status) + *status = NOTMUCH_PRIVATE_STATUS_OUT_OF_MEMORY; + return NULL; + } + /* This is C++'s creepy "placement new", which is really just an * ugly way to call a constructor for a pre-allocated object. So * it's really not an error to not be checking for OUT_OF_MEMORY @@ -259,6 +272,59 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header) return notmuch_message_file_get_header (message->message_file, header); } +/* Return the message ID from the In-Reply-To header of 'message'. + * + * Returns an empty string ("") if 'message' has no In-Reply-To + * header. + * + * Returns NULL if any error occurs. + */ +const char * +_notmuch_message_get_in_reply_to (notmuch_message_t *message) +{ + const char *prefix = _find_prefix ("replyto"); + int prefix_len = strlen (prefix); + Xapian::TermIterator i; + std::string in_reply_to; + + if (message->in_reply_to) + return message->in_reply_to; + + i = message->doc.termlist_begin (); + i.skip_to (prefix); + + in_reply_to = *i; + + /* It's perfectly valid for a message to have no In-Reply-To + * header. For these cases, we return an empty string. */ + if (i == message->doc.termlist_end () || + strncmp (in_reply_to.c_str (), prefix, prefix_len)) + { + message->in_reply_to = talloc_strdup (message, ""); + return message->in_reply_to; + } + + message->in_reply_to = talloc_strdup (message, + in_reply_to.c_str () + prefix_len); + +#if DEBUG_DATABASE_SANITY + i++; + + in_reply_to = *i; + + if (i != message->doc.termlist_end () && + strncmp ((*i).c_str (), prefix, prefix_len)) + { + INTERNAL_ERROR ("Message %s has duplicate In-Reply-To IDs: %s and %s\n" + notmuch_message_get_message_id (message), + message->in_reply_to, + (*i).c_str () + prefix_len); + } +#endif + + return message->in_reply_to; +} + const char * notmuch_message_get_thread_id (notmuch_message_t *message) { @@ -293,6 +359,19 @@ notmuch_message_get_thread_id (notmuch_message_t *message) return message->thread_id; } +void +_notmuch_message_add_reply (notmuch_message_t *message, + notmuch_message_node_t *reply) +{ + _notmuch_message_list_append (message->replies, reply); +} + +notmuch_messages_t * +notmuch_message_get_replies (notmuch_message_t *message) +{ + return _notmuch_messages_create (message->replies); +} + /* Set the filename for 'message' to 'filename'. * * XXX: We should still figure out if we think it's important to store