* mu-msg-*: take mu_msg_cache into use

This commit is contained in:
Dirk-Jan C. Binnema 2011-05-14 18:07:51 +03:00
parent 0cd1e78239
commit c0a24cf7bc
5 changed files with 273 additions and 296 deletions

View File

@ -17,7 +17,6 @@
**
*/
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -26,6 +25,16 @@
#include <stdlib.h>
#include <ctype.h>
/* hopefully, the should get us a sane PATH_MAX */
#include <limits.h>
/* not all systems provide PATH_MAX in limits.h */
#ifndef PATH_MAX
#include <sys/param.h>
#ifndef PATH_MAX
#define PATH_MAX MAXPATHLEN
#endif /*!PATH_MAX */
#endif /*PATH_MAX */
#include <gmime/gmime.h>
#include "mu-util.h"
@ -33,31 +42,26 @@
#include "mu-maildir.h"
#include "mu-msg-priv.h"
static gboolean init_file_metadata (MuMsgFile *self, const char* path,
const char *mdir, GError **err);
static gboolean init_mime_msg (MuMsgFile *msg, GError **err);
#define CACHE(MFID) (self->_str_cache[(MFID)])
#define SET_CACHE(MFID,V)(self->_str_cache[(MFID)]=(V))
static gboolean init_mime_msg (MuMsgFile *msg, const char *path, GError **err);
MuMsgFile*
mu_msg_file_new (const char* filepath, const char *mdir, GError **err)
{
int i;
MuMsgFile *self;
g_return_val_if_fail (filepath, NULL);
self = g_slice_new0 (MuMsgFile);
for (i = 0; i != MU_MSG_FIELD_ID_NUM; ++i)
SET_CACHE(i,NULL);
if (!init_file_metadata (self, filepath, mdir, err)) {
mu_msg_file_destroy (self);
return NULL;
}
if (!init_mime_msg (self, err)) {
if (!init_mime_msg (self, filepath, err)) {
mu_msg_file_destroy (self);
return NULL;
}
@ -69,14 +73,9 @@ mu_msg_file_new (const char* filepath, const char *mdir, GError **err)
void
mu_msg_file_destroy (MuMsgFile *self)
{
int i;
if (!self)
return;
for (i = 0; i != MU_MSG_FIELD_ID_NUM; ++i)
g_free (self->_str_cache[i]);
if (self->_mime_msg)
g_object_unref (self->_mime_msg);
@ -110,13 +109,11 @@ init_file_metadata (MuMsgFile *self, const char* path, const gchar* mdir,
return FALSE;
}
self->_timestamp = statbuf.st_mtime;
/* size_t should be enough for message size... */
self->_timestamp = statbuf.st_mtime;
self->_size = (size_t)statbuf.st_size;
self->_size = (size_t)statbuf.st_size;
SET_CACHE(MU_MSG_FIELD_ID_PATH, g_strdup(path));
SET_CACHE(MU_MSG_FIELD_ID_MAILDIR, mdir ? g_strdup(mdir): NULL);
strncpy (self->_path, path, PATH_MAX);
strncpy (self->_maildir, mdir ? mdir : "", PATH_MAX);
return TRUE;
}
@ -124,17 +121,16 @@ init_file_metadata (MuMsgFile *self, const char* path, const gchar* mdir,
static GMimeStream*
get_mime_stream (MuMsgFile *self, GError **err)
get_mime_stream (MuMsgFile *self, const char *path, GError **err)
{
FILE *file;
GMimeStream *stream;
file = fopen (self->_str_cache [MU_MSG_FIELD_ID_PATH], "r");
file = fopen (path, "r");
if (!file) {
g_set_error (err, 0, MU_ERROR_FILE,
"cannot open %s: %s",
self->_str_cache [MU_MSG_FIELD_ID_PATH],
strerror (errno));
path, strerror (errno));
return NULL;
}
@ -142,7 +138,7 @@ get_mime_stream (MuMsgFile *self, GError **err)
if (!stream) {
g_set_error (err, 0, MU_ERROR_GMIME,
"cannot create mime stream for %s",
self->_str_cache [MU_MSG_FIELD_ID_PATH]);
path);
fclose (file);
return NULL;
}
@ -151,12 +147,12 @@ get_mime_stream (MuMsgFile *self, GError **err)
}
static gboolean
init_mime_msg (MuMsgFile *self, GError **err)
init_mime_msg (MuMsgFile *self, const char* path, GError **err)
{
GMimeStream *stream;
GMimeParser *parser;
stream = get_mime_stream (self, err);
stream = get_mime_stream (self, path, err);
if (!stream)
return FALSE;
@ -164,8 +160,8 @@ init_mime_msg (MuMsgFile *self, GError **err)
g_object_unref (stream);
if (!parser) {
g_set_error (err, 0, MU_ERROR_GMIME,
"cannot create mime parser for %s",
self->_str_cache [MU_MSG_FIELD_ID_PATH]);
"%s: cannot create mime parser for %s",
__FUNCTION__, path);
return FALSE;
}
@ -173,8 +169,8 @@ init_mime_msg (MuMsgFile *self, GError **err)
g_object_unref (parser);
if (!self->_mime_msg) {
g_set_error (err, 0, MU_ERROR_GMIME,
"cannot construct mime message for %s",
self->_str_cache [MU_MSG_FIELD_ID_PATH]);
"%s: cannot construct mime message for %s",
__FUNCTION__, path);
return FALSE;
}
@ -182,26 +178,12 @@ init_mime_msg (MuMsgFile *self, GError **err)
}
static const char*
static char*
get_recipient (MuMsgFile *self, GMimeRecipientType rtype)
{
const char *val;
char *recep;
InternetAddressList *receps;
switch (rtype) {
case GMIME_RECIPIENT_TYPE_TO:
val = CACHE(MU_MSG_FIELD_ID_TO);
if (val) return val; else break;
case GMIME_RECIPIENT_TYPE_CC:
val = CACHE(MU_MSG_FIELD_ID_CC);
if (val) return val; else break;
case GMIME_RECIPIENT_TYPE_BCC:
val = CACHE(MU_MSG_FIELD_ID_BCC);
if (val) return val; else break;
default: g_return_val_if_reached (NULL);
}
receps = g_mime_message_get_recipients (self->_mime_msg, rtype);
recep = (char*)internet_address_list_to_string (receps, TRUE);
@ -210,19 +192,7 @@ get_recipient (MuMsgFile *self, GMimeRecipientType rtype)
return NULL;
}
switch (rtype) {
case GMIME_RECIPIENT_TYPE_TO:
return SET_CACHE (MU_MSG_FIELD_ID_TO, recep);
case GMIME_RECIPIENT_TYPE_CC:
return SET_CACHE (MU_MSG_FIELD_ID_CC, recep);
case GMIME_RECIPIENT_TYPE_BCC:
return SET_CACHE (MU_MSG_FIELD_ID_BCC, recep);
default: g_return_val_if_reached (NULL);
}
return recep;
}
@ -317,15 +287,14 @@ get_content_flags (MuMsgFile *self)
static MuMsgFlags
get_flags (MuMsgFile *self)
{
MuMsgFlags flags;
g_return_val_if_fail (self, MU_MSG_FLAG_NONE);
flags = mu_maildir_get_flags_from_path (self->_path);
flags |= get_content_flags (self);
if (self->_flags == MU_MSG_FLAG_NONE) {
self->_flags = mu_maildir_get_flags_from_path
(CACHE(MU_MSG_FIELD_ID_PATH));
self->_flags |= get_content_flags (self);
}
return self->_flags;
return flags;
}
@ -377,8 +346,8 @@ parse_prio_str (const char* priostr)
{
int i;
struct {
const char* _str;
MuMsgPrio _prio;
const char* _str;
MuMsgPrio _prio;
} str_prio[] = {
{ "high", MU_MSG_PRIO_HIGH },
{ "1", MU_MSG_PRIO_HIGH },
@ -405,21 +374,19 @@ parse_prio_str (const char* priostr)
static MuMsgPrio
get_prio (MuMsgFile *self)
{
MuMsgPrio prio;
char* priostr;
g_return_val_if_fail (self, 0);
if (self->_prio != MU_MSG_PRIO_NONE)
return self->_prio;
g_return_val_if_fail (self, MU_MSG_PRIO_NONE);
priostr = get_prio_header_field (self);
if (!priostr)
return MU_MSG_PRIO_NORMAL;
self->_prio = parse_prio_str (priostr);
prio = parse_prio_str (priostr);
g_free (priostr);
return self->_prio;
return prio;
}
@ -663,56 +630,10 @@ get_body (MuMsgFile *self, gboolean want_html)
if (err)
g_warning ("error occured while retrieving %s body"
"for message %s",
want_html ? "html" : "text",
(CACHE(MU_MSG_FIELD_ID_PATH)));
want_html ? "html" : "text", self->_path);
return str;
}
static const char*
get_body_html (MuMsgFile *self)
{
g_return_val_if_fail (self, NULL);
if (CACHE(MU_MSG_FIELD_ID_BODY_HTML))
return CACHE(MU_MSG_FIELD_ID_BODY_HTML);
else
return SET_CACHE(MU_MSG_FIELD_ID_BODY_HTML,
get_body (self, TRUE));
}
static const char*
get_body_text (MuMsgFile *self)
{
g_return_val_if_fail (self, NULL);
if (CACHE(MU_MSG_FIELD_ID_BODY_TEXT))
return CACHE(MU_MSG_FIELD_ID_BODY_TEXT);
else
return SET_CACHE(MU_MSG_FIELD_ID_BODY_TEXT,
get_body (self, FALSE));
}
static const char*
get_summary (MuMsgFile *self, size_t max_lines)
{
const char *body;
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (max_lines > 0, NULL);
if (CACHE(MU_MSG_FIELD_ID_SUMMARY))
return CACHE(MU_MSG_FIELD_ID_SUMMARY);
/* nope; calculate it */
body = get_body_text (self);
if (!body)
return NULL; /* there was no text body */
return SET_CACHE(MU_MSG_FIELD_ID_SUMMARY,
mu_str_summarize (body, max_lines));
}
static GSList*
get_msgids_from_header (MuMsgFile *self, const char* header)
@ -743,16 +664,13 @@ get_msgids_from_header (MuMsgFile *self, const char* header)
static const GSList*
static GSList*
get_references (MuMsgFile *self)
{
GSList *refs, *inreply;
g_return_val_if_fail (self, NULL);
if (self->_refs)
return self->_refs;
refs = get_msgids_from_header (self, "References");
/* now, add in-reply-to:, we only take the first one if there
@ -765,22 +683,17 @@ get_references (MuMsgFile *self)
}
/* put in proper order */
self->_refs = g_slist_reverse (refs);
return self->_refs;
return g_slist_reverse (refs);
}
static const char*
static char*
get_references_str (MuMsgFile *self)
{
const GSList *refs;
GSList *refs;
gchar *refsstr;
g_return_val_if_fail (self, NULL);
if (CACHE(MU_MSG_FIELD_ID_REFS))
return CACHE(MU_MSG_FIELD_ID_REFS);
refsstr = NULL;
refs = get_references (self);
if (refs) {
@ -790,59 +703,68 @@ get_references_str (MuMsgFile *self)
tmp = g_strdup_printf ("%s%s%s",
refsstr ? refsstr : "",
refsstr ? "," : "",
g_strdup((gchar*)cur->data));
(gchar*)cur->data);
g_free (refsstr);
refsstr = tmp;
}
}
return SET_CACHE(MU_MSG_FIELD_ID_REFS, refsstr);
g_slist_foreach (refs, (GFunc)g_free, NULL);
g_slist_free (refs);
return refsstr;
}
const char*
mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid)
char*
mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid, gboolean *do_free)
{
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (mu_msg_field_is_string(mfid), NULL);
*do_free = FALSE; /* default */
switch (mfid) {
case MU_MSG_FIELD_ID_BCC:
*do_free = TRUE;
return get_recipient (self, GMIME_RECIPIENT_TYPE_BCC);
case MU_MSG_FIELD_ID_BODY_TEXT: return get_body_text (self);
case MU_MSG_FIELD_ID_BODY_HTML: return get_body_html (self);
case MU_MSG_FIELD_ID_BODY_TEXT:
*do_free = TRUE;
return get_body (self, FALSE);
case MU_MSG_FIELD_ID_BODY_HTML:
*do_free = TRUE;
return get_body (self, TRUE);
case MU_MSG_FIELD_ID_CC:
*do_free = TRUE;
return get_recipient (self, GMIME_RECIPIENT_TYPE_CC);
case MU_MSG_FIELD_ID_FROM:
return g_mime_message_get_sender (self->_mime_msg);
return (char*)g_mime_message_get_sender (self->_mime_msg);
case MU_MSG_FIELD_ID_PATH:
return CACHE(MU_MSG_FIELD_ID_PATH);
return self->_path;
case MU_MSG_FIELD_ID_SUBJECT:
return g_mime_message_get_subject (self->_mime_msg);
return (char*)g_mime_message_get_subject (self->_mime_msg);
case MU_MSG_FIELD_ID_TO:
*do_free = TRUE;
return get_recipient (self, GMIME_RECIPIENT_TYPE_TO);
case MU_MSG_FIELD_ID_MSGID:
return g_mime_message_get_message_id (self->_mime_msg);
return (char*)g_mime_message_get_message_id (self->_mime_msg);
case MU_MSG_FIELD_ID_MAILDIR:
return CACHE(MU_MSG_FIELD_ID_MAILDIR);
return self->_maildir;
case MU_MSG_FIELD_ID_REFS:
*do_free = TRUE;
return get_references_str (self);
case MU_MSG_FIELD_ID_SUMMARY:
return get_summary (self, 5);
default:
g_return_val_if_reached (NULL);
}
@ -875,4 +797,3 @@ mu_msg_file_get_num_field (MuMsgFile *self, const MuMsgFieldId mfid)
}
}

View File

@ -32,8 +32,8 @@ typedef struct _MuMsgFile MuMsgFile;
*
* @return a new MuMsg, or NULL in case of error
*/
MuMsgFile *mu_msg_file_new (const char *path, const char* mdir, GError **err);
MuMsgFile *mu_msg_file_new (const char *path,
const char* mdir, GError **err);
/**
* destroy a MuMsgFile object
@ -47,12 +47,16 @@ void mu_msg_file_destroy (MuMsgFile *self);
* get a string value for this message
*
* @param self a valid MuMsgFile
* @param msfid the message field id to get (must be string-based one)
* @param msfid the message field id to get (must be string-based one) *
* @param do_free receives TRUE or FALSE, conveying if this string
* should be freed (TRUE) or not by caller. In case 'FALSE', this
* function should be treated as if it were return a const char*
*
* @return a const string, or NULL
*/
const char* mu_msg_file_get_str_field (MuMsgFile *self,
MuMsgFieldId msfid);
char* mu_msg_file_get_str_field (MuMsgFile *self,
MuMsgFieldId msfid,
gboolean *do_free);
/**
* get a numeric value for this message -- the return value should be
@ -65,4 +69,5 @@ const char* mu_msg_file_get_str_field (MuMsgFile *self,
*/
gint64 mu_msg_file_get_num_field (MuMsgFile *self, MuMsgFieldId msfid);
#endif /*__MU_MSG_FILE_H__*/

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** 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
@ -25,31 +25,27 @@
#include "mu-msg.h"
#include "mu-msg-file.h"
#include "mu-msg-cache.h"
G_BEGIN_DECLS
/* we put the the MuMsg definition in this separate -priv file, so we
* can split the mu_msg implementations over separate files */
struct _MuMsgFile {
GMimeMessage *_mime_msg;
/* we waste a few bytes here for none-string fields... */
gchar *_str_cache[MU_MSG_FIELD_ID_NUM];
GSList *_refs;
time_t _timestamp;
size_t _size;
MuMsgFlags _flags;
MuMsgPrio _prio;
GMimeMessage *_mime_msg;
time_t _timestamp;
size_t _size;
char _path [PATH_MAX + 1];
char _maildir [PATH_MAX + 1];
};
/* we put the the MuMsg definition in this separate -priv file, so we
* can split the mu_msg implementations over separate files */
struct _MuMsg {
guint _refcount;
MuMsgFile *_file;
MuMsgCache *_cache;
};
G_END_DECLS

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
/*
** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** 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
@ -41,160 +41,241 @@ static gboolean _gmime_initialized = FALSE;
static void
gmime_init (void)
{
g_return_if_fail (!_gmime_initialized);
g_return_if_fail (!_gmime_initialized);
#ifdef GMIME_ENABLE_RFC2047_WORKAROUNDS
g_mime_init(GMIME_ENABLE_RFC2047_WORKAROUNDS);
g_mime_init(GMIME_ENABLE_RFC2047_WORKAROUNDS);
#else
g_mime_init(0);
g_mime_init(0);
#endif /* GMIME_ENABLE_RFC2047_WORKAROUNDS */
_gmime_initialized = TRUE;
_gmime_initialized = TRUE;
}
static void
gmime_uninit (void)
{
g_return_if_fail (_gmime_initialized);
g_return_if_fail (_gmime_initialized);
g_mime_shutdown();
_gmime_initialized = FALSE;
g_mime_shutdown();
_gmime_initialized = FALSE;
}
MuMsg*
mu_msg_new_from_file (const char *path, const char *mdir, GError **err)
{
MuMsg *self;
MuMsgFile *msgfile;
MuMsg *self;
MuMsgFile *msgfile;
g_return_val_if_fail (path, NULL);
g_return_val_if_fail (path, NULL);
if (G_UNLIKELY(!_gmime_initialized)) {
gmime_init ();
g_atexit (gmime_uninit);
}
msgfile = mu_msg_file_new (path, mdir, err);
if (!msgfile)
return NULL;
if (G_UNLIKELY(!_gmime_initialized)) {
gmime_init ();
g_atexit (gmime_uninit);
}
msgfile = mu_msg_file_new (path, mdir, err);
if (!msgfile)
return NULL;
self = g_slice_new0 (MuMsg);
self->_file = msgfile;
self->_refcount = 1;
return self;
self = g_slice_new0 (MuMsg);
self->_file = msgfile;
self->_refcount = 1;
self->_cache = mu_msg_cache_new ();
return self;
}
static void
mu_msg_destroy (MuMsg *self)
{
if (!self)
return;
if (!self)
return;
mu_msg_file_destroy (self->_file);
g_slice_free (MuMsg, self);
mu_msg_file_destroy (self->_file);
mu_msg_cache_destroy (self->_cache);
g_slice_free (MuMsg, self);
}
MuMsg*
mu_msg_ref (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (self, NULL);
++self->_refcount;
++self->_refcount;
return self;
return self;
}
void
mu_msg_unref (MuMsg *self)
{
g_return_if_fail (self);
g_return_if_fail (self->_refcount >= 1);
g_return_if_fail (self);
g_return_if_fail (self->_refcount >= 1);
if (--self->_refcount == 0)
mu_msg_destroy (self);
if (--self->_refcount == 0)
mu_msg_destroy (self);
}
const char*
mu_msg_get_path (MuMsg *self)
/* for some data, we need to read the message file from disk */
static MuMsgFile*
get_msg_file (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_PATH);
MuMsgFile *file;
const char *path;
GError *err;
path = mu_msg_cache_str (self->_cache, MU_MSG_FIELD_ID_PATH);
if (!path) {
g_warning ("%s: cannot find path info", __FUNCTION__);
return NULL;
}
err = NULL;
file = mu_msg_file_new (path, NULL, &err);
if (!file) {
g_warning ("%s: failed to create MuMsgFile: %s",
__FUNCTION__,
err->message ? err->message : "?");
g_error_free (err);
return NULL;
}
return file;
}
static const char*
get_str_field (MuMsg *self, MuMsgFieldId mfid)
{
gboolean do_free;
char *val;
if (mu_msg_cache_cached (self->_cache, mfid))
return mu_msg_cache_str (self->_cache, mfid);
/* if we don't have a file object yet, we need to create from
* the file on disk */
if (!self->_file) {
self->_file = get_msg_file (self);
if (!self->_file) {
g_warning ("failed to open message file");
return NULL;
}
}
/* if we get a string that needs freeing, we tell the cache to
* mark the string as such, so it will be freed when the cache
* is freed (or when the value is overwritten) */
val = mu_msg_file_get_str_field (self->_file, mfid, &do_free);
if (do_free)
mu_msg_cache_set_str_alloc (self->_cache, mfid, val);
else
mu_msg_cache_set_str (self->_cache, mfid, val);
return val;
}
static gint64
get_num_field (MuMsg *self, MuMsgFieldId mfid)
{
guint64 val;
if (mu_msg_cache_cached (self->_cache, mfid))
return mu_msg_cache_num (self->_cache, mfid);
/* if we don't have a file object yet, we need to create from
* the file on disk */
if (!self->_file) {
self->_file = get_msg_file (self);
if (!self->_file) {
g_warning ("failed to open message file");
return -1;
}
}
val = mu_msg_file_get_num_field (self->_file, mfid);
mu_msg_cache_set_num (self->_cache, mfid, val);
return val;
}
const char*
mu_msg_get_path (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_PATH);
}
const char*
mu_msg_get_subject (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_SUBJECT);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_SUBJECT);
}
const char*
mu_msg_get_msgid (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_MSGID);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_MSGID);
}
const char*
mu_msg_get_maildir (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_MAILDIR);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_MAILDIR);
}
const char*
mu_msg_get_from (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_FROM);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_FROM);
}
const char*
mu_msg_get_to (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_TO);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_TO);
}
const char*
mu_msg_get_cc (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_CC);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_CC);
}
const char*
mu_msg_get_bcc (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_BCC);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_BCC);
}
time_t
mu_msg_get_date (MuMsg *self)
{
g_return_val_if_fail (self, (time_t)-1);
return (time_t)mu_msg_file_get_num_field (self->_file,
MU_MSG_FIELD_ID_DATE);
g_return_val_if_fail (self, (time_t)-1);
return (time_t)get_num_field (self, MU_MSG_FIELD_ID_DATE);
}
@ -202,26 +283,23 @@ mu_msg_get_date (MuMsg *self)
MuMsgFlags
mu_msg_get_flags (MuMsg *self)
{
g_return_val_if_fail (self, MU_MSG_FLAG_NONE);
return (MuMsgFlags)mu_msg_file_get_num_field (self->_file,
MU_MSG_FIELD_ID_FLAGS);
g_return_val_if_fail (self, MU_MSG_FLAG_NONE);
return (MuMsgFlags)get_num_field (self, MU_MSG_FIELD_ID_FLAGS);
}
size_t
mu_msg_get_size (MuMsg *self)
{
g_return_val_if_fail (self, 0);
return (size_t)mu_msg_file_get_num_field (self->_file,
MU_MSG_FIELD_ID_SIZE);
g_return_val_if_fail (self, 0);
return (size_t)get_num_field (self, MU_MSG_FIELD_ID_SIZE);
}
MuMsgPrio
mu_msg_get_prio (MuMsg *self)
{
g_return_val_if_fail (self, (time_t)-1);
return (MuMsgPrio)mu_msg_file_get_num_field (self->_file,
MU_MSG_FIELD_ID_PRIO);
g_return_val_if_fail (self, (time_t)-1);
return (MuMsgPrio)get_num_field (self, MU_MSG_FIELD_ID_PRIO);
}
@ -239,60 +317,47 @@ mu_msg_get_prio (MuMsg *self)
time_t
mu_msg_get_timestamp (MuMsg *self)
{
g_return_val_if_fail (self, (time_t)-1);
return (MuMsgPrio)mu_msg_file_get_num_field (self->_file,
MU_MSG_FIELD_ID_TIMESTAMP);
g_return_val_if_fail (self, (time_t)-1);
return (MuMsgPrio)get_num_field (self, MU_MSG_FIELD_ID_TIMESTAMP);
}
const char*
mu_msg_get_body_html (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_BODY_HTML);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_BODY_HTML);
}
const char*
mu_msg_get_body_text (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_BODY_TEXT);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_BODY_TEXT);
}
const char*
mu_msg_get_summary (MuMsg *self, size_t max_lines)
{
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (max_lines > 0, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_SUMMARY);
}
const char*
mu_msg_get_references_str (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file,
MU_MSG_FIELD_ID_REFS);
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_REFS);
}
const char*
mu_msg_get_field_string (MuMsg *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, NULL);
return mu_msg_file_get_str_field (self->_file, mfid);
g_return_val_if_fail (self, NULL);
return get_str_field (self, mfid);
}
gint64
mu_msg_get_field_numeric (MuMsg *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, -1);
return mu_msg_file_get_num_field (self->_file, mfid);
g_return_val_if_fail (self, -1);
return get_num_field (self, mfid);
}

View File

@ -69,6 +69,15 @@ void mu_msg_unref (MuMsg *msg);
/**
* cache the values from the backend (file or db), so we don't the
* backend anymore
*
* @param self a message
*/
void mu_msg_cache_values (MuMsg *self);
/**
* get the plain text body of this message
*
@ -91,25 +100,6 @@ const char* mu_msg_get_body_text (MuMsg *msg);
*/
const char* mu_msg_get_body_html (MuMsg *msg);
/**
* get a summary of the body of this message; a summary takes up to
* the first @max_lines from the message, and replaces newlines
* etc. with single whitespace characters. This only works if there's
* a text-body for the message
*
* @param msg a valid MuMsg* instance
* @param max_lines the max number of lines to summarize
*
* @return the summary of the message or NULL in case of error or if
* there is no such body. the returned string should *not* be modified
* or freed. When called multiple times, the function will always
* return the same summary, regardless of a different max_lines value.
*/
const char* mu_msg_get_summary (MuMsg *msg, size_t max_lines);
/**
* get the sender (From:) of this message
*