lib/mu-msg: update to use mu-message-fields

Remove mu-msg-fields.[ch] and update sources to use mu-message-fields.
This commit is contained in:
Dirk-Jan C. Binnema 2022-03-04 00:04:30 +02:00
parent c3ae3da0de
commit 7c185590e4
8 changed files with 190 additions and 899 deletions

View File

@ -23,7 +23,7 @@
#include <errno.h>
#include <xapian.h>
#include "mu-msg-fields.h"
#include "mu-message.hh"
#include "mu-msg-doc.hh"
#include "utils/mu-util.h"
@ -32,6 +32,7 @@
#include "utils/mu-xapian-utils.hh"
using namespace Mu;
using namespace Mu::Message;
struct Mu::MuMsgDoc {
MuMsgDoc(Xapian::Document* doc) : _doc(doc) {}
@ -61,13 +62,12 @@ Mu::mu_msg_doc_destroy(MuMsgDoc* self)
}
gchar*
Mu::mu_msg_doc_get_str_field(MuMsgDoc* self, MuMsgFieldId mfid)
Mu::mu_msg_doc_get_str_field(MuMsgDoc* self, Field::Id field_id)
{
g_return_val_if_fail(self, NULL);
g_return_val_if_fail(mu_msg_field_id_is_valid(mfid), NULL);
// disable this check:
// g_return_val_if_fail (mu_msg_field_is_string(mfid), NULL);
// g_return_val_if_fail (mu_msg_field_is_string(field_id), NULL);
// because it's useful to get numerical field as strings,
// for example when sorting (which is much faster if don't
// have to convert to numbers first, esp. when it's a date
@ -75,41 +75,42 @@ Mu::mu_msg_doc_get_str_field(MuMsgDoc* self, MuMsgFieldId mfid)
return xapian_try(
[&] {
const std::string s(self->doc().get_value(mfid));
const auto value_no{message_field(field_id).value_no()};
const std::string s(self->doc().get_value(value_no));
return s.empty() ? NULL : g_strdup(s.c_str());
},
(gchar*)nullptr);
}
GSList*
Mu::mu_msg_doc_get_str_list_field(MuMsgDoc* self, MuMsgFieldId mfid)
Mu::mu_msg_doc_get_str_list_field(MuMsgDoc* self, Field::Id field_id)
{
g_return_val_if_fail(self, NULL);
g_return_val_if_fail(mu_msg_field_id_is_valid(mfid), NULL);
g_return_val_if_fail(mu_msg_field_is_string_list(mfid), NULL);
g_return_val_if_fail(message_field(field_id).type == Field::Type::StringList, NULL);
return xapian_try(
[&] {
/* return a comma-separated string as a GSList */
const std::string s(self->doc().get_value(mfid));
const auto value_no{message_field(field_id).value_no()};
const std::string s(self->doc().get_value(value_no));
return s.empty() ? NULL : mu_str_to_list(s.c_str(), ',', TRUE);
},
(GSList*)nullptr);
}
gint64
Mu::mu_msg_doc_get_num_field(MuMsgDoc* self, MuMsgFieldId mfid)
Mu::mu_msg_doc_get_num_field(MuMsgDoc* self, Field::Id field_id)
{
g_return_val_if_fail(self, -1);
g_return_val_if_fail(mu_msg_field_id_is_valid(mfid), -1);
g_return_val_if_fail(mu_msg_field_is_numeric(mfid), -1);
g_return_val_if_fail(message_field(field_id).is_numerical(), -1);
return xapian_try(
[&] {
const std::string s(self->doc().get_value(mfid));
const auto value_no{message_field(field_id).value_no()};
const std::string s(self->doc().get_value(value_no));
if (s.empty())
return (gint64)0;
else if (mfid == MU_MSG_FIELD_ID_DATE || mfid == MU_MSG_FIELD_ID_SIZE)
else if (field_id == Field::Id::Date || field_id == Field::Id::Size)
return static_cast<gint64>(strtol(s.c_str(), NULL, 10));
else {
return static_cast<gint64>(Xapian::sortable_unserialise(s));

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2012-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2012-2022 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 the
@ -22,6 +22,7 @@
#include <glib.h>
#include <utils/mu-util.h>
#include "mu-message.hh"
namespace Mu {
@ -54,35 +55,35 @@ void mu_msg_doc_destroy(MuMsgDoc* self);
* get a string parameter from the msgdoc
*
* @param self a MuMsgDoc instance
* @param mfid a MuMsgFieldId for a string field
* @param mfid a Message::Field::Id for a string field
*
* @return a string for the given field (see do_free), or NULL in case of error.
* free with g_free
*/
gchar* mu_msg_doc_get_str_field(MuMsgDoc* self, MuMsgFieldId mfid) G_GNUC_WARN_UNUSED_RESULT;
gchar* mu_msg_doc_get_str_field(MuMsgDoc* self, Message::Field::Id mfid) G_GNUC_WARN_UNUSED_RESULT;
/**
* get a string-list parameter from the msgdoc
*
* @param self a MuMsgDoc instance
* @param mfid a MuMsgFieldId for a string-list field
* @param mfid a Message::Field::Id for a string-list field
*
* @return a list for the given field (see do_free), or NULL in case
* of error. free with mu_str_free_list
*/
GSList* mu_msg_doc_get_str_list_field(MuMsgDoc* self, MuMsgFieldId mfid) G_GNUC_WARN_UNUSED_RESULT;
GSList* mu_msg_doc_get_str_list_field(MuMsgDoc* self, Message::Field::Id mfid) G_GNUC_WARN_UNUSED_RESULT;
/**
*
* get a numeric parameter from the msgdoc
*
* @param self a MuMsgDoc instance
* @param mfid a MuMsgFieldId for a numeric field
* @param mfid a Message::Field::Id for a numeric field
*
* @return the numerical value, or -1 in case of error. You'll need to
* cast this value to the actual type (e.g. time_t for MU_MSG_FIELD_ID_DATE)
* cast this value to the actual type (e.g. time_t for Field::Id::Date)
*/
gint64 mu_msg_doc_get_num_field(MuMsgDoc* self, MuMsgFieldId mfid);
gint64 mu_msg_doc_get_num_field(MuMsgDoc* self, Message::Field::Id mfid);
} // namespace Mu

View File

@ -1,425 +0,0 @@
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
/*
** Copyright (C) 2008-2017 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
** the Free Software Foundation; either version 3 of the License, 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.
**
*/
#include <string.h>
#include "mu-msg-fields.h"
/*
* note: the differences for our purposes between a xapian field and a
* term: - there is only a single value for some item in per document
* (msg), ie. one value containing the list of To: addresses - there
* can be multiple terms, each containing e.g. one of the To:
* addresses - searching uses terms, but to display some field, it
* must be in the value (at least when using MuMsgIter)
*/
enum _FieldFlags {
FLAG_GMIME = 1 << 0, /* field retrieved through
* gmime */
FLAG_XAPIAN_INDEX = 1 << 1, /* field is indexed in
* xapian (i.e., the text
* is processed */
FLAG_XAPIAN_TERM = 1 << 2, /* field stored as term in
* xapian (so it can be searched) */
FLAG_XAPIAN_VALUE = 1 << 3, /* field stored as value in
* xapian (so the literal
* value can be
* retrieved) */
FLAG_XAPIAN_CONTACT = 1 << 4, /* field contains one or more
* e-mail-addresses */
FLAG_XAPIAN_BOOLEAN = 1 << 5, /* use 'add_boolean_prefix'
* for Xapian queries;
* wildcards do NOT WORK
* for such fields */
FLAG_DONT_CACHE = 1 << 6, /* don't cache this field in
* the MuMsg cache */
FLAG_RANGE_FIELD = 1 << 7 /* whether this is a range field */
};
typedef enum _FieldFlags FieldFlags;
/*
* this struct describes the fields of an e-mail
/*/
struct _MuMsgField {
MuMsgFieldId _id; /* the id of the field */
MuMsgFieldType _type; /* the type of the field */
const char *_name; /* the name of the field */
const char _shortcut; /* the shortcut for use in
* --fields and sorting */
const char _xprefix; /* the Xapian-prefix */
FieldFlags _flags; /* the flags that tells us
* what to do */
};
typedef struct _MuMsgField MuMsgField;
/* the name and shortcut fields must be lower case, or they might be
* misinterpreted by the query-preprocesser which turns queries into
* lowercase */
static const MuMsgField FIELD_DATA[] = {
{
MU_MSG_FIELD_ID_BCC,
MU_MSG_FIELD_TYPE_STRING,
"bcc" , 'h', 'H', /* 'hidden */
FLAG_GMIME | FLAG_XAPIAN_CONTACT |
FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_BODY_TEXT,
MU_MSG_FIELD_TYPE_STRING,
"body", 'b', 'B',
FLAG_GMIME | FLAG_XAPIAN_INDEX |
FLAG_DONT_CACHE
},
{
MU_MSG_FIELD_ID_BODY_HTML,
MU_MSG_FIELD_TYPE_STRING,
"bodyhtml", 0, 0,
FLAG_GMIME | FLAG_DONT_CACHE
},
{
MU_MSG_FIELD_ID_CC,
MU_MSG_FIELD_TYPE_STRING,
"cc", 'c', 'C',
FLAG_GMIME | FLAG_XAPIAN_CONTACT | FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_DATE,
MU_MSG_FIELD_TYPE_TIME_T,
"date", 'd', 'D',
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE |
FLAG_XAPIAN_BOOLEAN | FLAG_RANGE_FIELD
},
{
MU_MSG_FIELD_ID_EMBEDDED_TEXT,
MU_MSG_FIELD_TYPE_STRING,
"embed", 'e', 'E',
FLAG_GMIME | FLAG_XAPIAN_INDEX | FLAG_DONT_CACHE
},
{
MU_MSG_FIELD_ID_FILE,
MU_MSG_FIELD_TYPE_STRING,
"file" , 'j', 'J',
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_DONT_CACHE
},
{
MU_MSG_FIELD_ID_FLAGS,
MU_MSG_FIELD_TYPE_INT,
"flag", 'g', 'G', /* flaGs */
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_FROM,
MU_MSG_FIELD_TYPE_STRING,
"from", 'f', 'F',
FLAG_GMIME | FLAG_XAPIAN_CONTACT | FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_MAILDIR,
MU_MSG_FIELD_TYPE_STRING,
"maildir", 'm', 'M',
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_MAILING_LIST,
MU_MSG_FIELD_TYPE_STRING,
"list", 'v', 'V',
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_MIME,
MU_MSG_FIELD_TYPE_STRING,
"mime" , 'y', 'Y',
FLAG_XAPIAN_TERM
},
{
MU_MSG_FIELD_ID_MSGID,
MU_MSG_FIELD_TYPE_STRING,
"msgid", 'i', 'I', /* 'i' for Id */
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_PATH,
MU_MSG_FIELD_TYPE_STRING,
"path", 'l', 'L', /* 'l' for location */
FLAG_GMIME | FLAG_XAPIAN_VALUE |
FLAG_XAPIAN_BOOLEAN
},
{
MU_MSG_FIELD_ID_PRIO,
MU_MSG_FIELD_TYPE_INT,
"prio", 'p', 'P',
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_REFS,
MU_MSG_FIELD_TYPE_STRING_LIST,
"refs", 'r', 'R',
FLAG_GMIME | FLAG_XAPIAN_VALUE
},
{
MU_MSG_FIELD_ID_SIZE,
MU_MSG_FIELD_TYPE_BYTESIZE,
"size", 'z', 'Z', /* siZe */
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE |
FLAG_RANGE_FIELD
},
{
MU_MSG_FIELD_ID_SUBJECT,
MU_MSG_FIELD_TYPE_STRING,
"subject", 's', 'S',
FLAG_GMIME | FLAG_XAPIAN_INDEX | FLAG_XAPIAN_VALUE |
FLAG_XAPIAN_TERM
},
{
MU_MSG_FIELD_ID_TAGS,
MU_MSG_FIELD_TYPE_STRING_LIST,
"tag", 'x', 'X',
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE
},
{ /* remember which thread this message is in */
MU_MSG_FIELD_ID_THREAD_ID,
MU_MSG_FIELD_TYPE_STRING,
"thread", 0, 'W',
FLAG_XAPIAN_TERM
},
{
MU_MSG_FIELD_ID_TO,
MU_MSG_FIELD_TYPE_STRING,
"to", 't', 'T',
FLAG_GMIME | FLAG_XAPIAN_CONTACT | FLAG_XAPIAN_VALUE
},
{ /* special, internal field, to get a unique key */
MU_MSG_FIELD_ID_UID,
MU_MSG_FIELD_TYPE_STRING,
"uid", 0, 'U',
FLAG_XAPIAN_TERM
}
/* note, mu-store also use the 'Q' internal prefix for its uids */
};
/* the MsgField data in an array, indexed by the MsgFieldId;
* this allows for O(1) access
*/
static MuMsgField* _msg_field_data[MU_MSG_FIELD_ID_NUM];
static const MuMsgField* mu_msg_field (MuMsgFieldId id)
{
static gboolean _initialized = FALSE;
/* initialize the array, but only once... */
if (G_UNLIKELY(!_initialized)) {
int i;
for (i = 0; i != G_N_ELEMENTS(FIELD_DATA); ++i)
_msg_field_data[FIELD_DATA[i]._id] =
(MuMsgField*)&FIELD_DATA[i];
_initialized = TRUE;
}
return _msg_field_data[id];
}
void
mu_msg_field_foreach (MuMsgFieldForeachFunc func, gconstpointer data)
{
int i;
for (i = 0; i != MU_MSG_FIELD_ID_NUM; ++i)
func (i, data);
}
MuMsgFieldId
mu_msg_field_id_from_name (const char* str, gboolean err)
{
int i;
g_return_val_if_fail (str, MU_MSG_FIELD_ID_NONE);
for (i = 0; i != G_N_ELEMENTS(FIELD_DATA); ++i)
if (g_strcmp0(str, FIELD_DATA[i]._name) == 0)
return FIELD_DATA[i]._id;
if (err)
g_return_val_if_reached (MU_MSG_FIELD_ID_NONE);
return MU_MSG_FIELD_ID_NONE;
}
MuMsgFieldId
mu_msg_field_id_from_shortcut (char kar, gboolean err)
{
int i;
for (i = 0; i != G_N_ELEMENTS(FIELD_DATA); ++i)
if (kar == FIELD_DATA[i]._shortcut)
return FIELD_DATA[i]._id;
if (err)
g_return_val_if_reached (MU_MSG_FIELD_ID_NONE);
return MU_MSG_FIELD_ID_NONE;
}
gboolean
mu_msg_field_gmime (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),FALSE);
return mu_msg_field(id)->_flags & FLAG_GMIME ? TRUE: FALSE;
}
gboolean
mu_msg_field_xapian_index (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),FALSE);
return mu_msg_field(id)->_flags &
(FLAG_XAPIAN_INDEX | FLAG_XAPIAN_CONTACT) ? TRUE: FALSE;
}
gboolean
mu_msg_field_xapian_value (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),FALSE);
return mu_msg_field(id)->_flags & FLAG_XAPIAN_VALUE ? TRUE: FALSE;
}
gboolean
mu_msg_field_xapian_term (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),FALSE);
return mu_msg_field(id)->_flags & FLAG_XAPIAN_TERM ? TRUE: FALSE;
}
gboolean
mu_msg_field_is_range_field (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),FALSE);
return mu_msg_field(id)->_flags & FLAG_RANGE_FIELD ? TRUE: FALSE;
}
gboolean
mu_msg_field_uses_boolean_prefix (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),FALSE);
return mu_msg_field(id)->_flags & FLAG_XAPIAN_BOOLEAN ? TRUE:FALSE;
}
gboolean
mu_msg_field_is_cacheable (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),FALSE);
/* note the FALSE: TRUE */
return mu_msg_field(id)->_flags & FLAG_DONT_CACHE ? FALSE : TRUE;
}
gboolean
mu_msg_field_xapian_contact (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),FALSE);
return mu_msg_field(id)->_flags & FLAG_XAPIAN_CONTACT ? TRUE: FALSE;
}
gboolean
mu_msg_field_is_numeric (MuMsgFieldId mfid)
{
MuMsgFieldType type;
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid),FALSE);
type = mu_msg_field_type (mfid);
return type == MU_MSG_FIELD_TYPE_BYTESIZE ||
type == MU_MSG_FIELD_TYPE_TIME_T ||
type == MU_MSG_FIELD_TYPE_INT;
}
const char*
mu_msg_field_name (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),NULL);
return mu_msg_field(id)->_name;
}
char
mu_msg_field_shortcut (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),0);
return mu_msg_field(id)->_shortcut;
}
char
mu_msg_field_xapian_prefix (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),0);
return mu_msg_field(id)->_xprefix;
}
MuMsgFieldType
mu_msg_field_type (MuMsgFieldId id)
{
g_return_val_if_fail (mu_msg_field_id_is_valid(id),
MU_MSG_FIELD_TYPE_NONE);
return mu_msg_field(id)->_type;
}

View File

@ -1,292 +0,0 @@
/*
** Copyright (C) 2008-2017 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
** the Free Software Foundation; either version 3 of the License, 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_FIELDS_H__
#define __MU_MSG_FIELDS_H__
#include <glib.h>
G_BEGIN_DECLS
/* don't change the order, add new types at the end, as these numbers
* are used in the database */
enum _MuMsgFieldId {
/* first all the string-based ones */
MU_MSG_FIELD_ID_BCC = 0,
MU_MSG_FIELD_ID_BODY_HTML,
MU_MSG_FIELD_ID_BODY_TEXT,
MU_MSG_FIELD_ID_CC,
MU_MSG_FIELD_ID_EMBEDDED_TEXT,
MU_MSG_FIELD_ID_FILE,
MU_MSG_FIELD_ID_FROM,
MU_MSG_FIELD_ID_MAILDIR,
MU_MSG_FIELD_ID_MIME, /* mime-type */
MU_MSG_FIELD_ID_MSGID,
MU_MSG_FIELD_ID_PATH,
MU_MSG_FIELD_ID_SUBJECT,
MU_MSG_FIELD_ID_TO,
MU_MSG_FIELD_ID_UID, /* special, generated from path */
/* string list items... */
MU_MSG_FIELD_ID_REFS,
MU_MSG_FIELD_ID_TAGS,
/* then the numerical ones */
MU_MSG_FIELD_ID_DATE,
MU_MSG_FIELD_ID_FLAGS,
MU_MSG_FIELD_ID_PRIO,
MU_MSG_FIELD_ID_SIZE,
/* add new ones here... */
MU_MSG_FIELD_ID_MAILING_LIST, /* mailing list */
MU_MSG_FIELD_ID_THREAD_ID,
MU_MSG_FIELD_ID_NUM
};
typedef guint8 MuMsgFieldId;
/* some specials... */
static const MuMsgFieldId MU_MSG_FIELD_ID_NONE = (MuMsgFieldId)-1;
#define MU_MSG_STRING_FIELD_ID_NUM (MU_MSG_FIELD_ID_UID + 1)
/* this is a shortcut for To/From/Cc/Bcc in queries; handled specially
* in mu-query.cc and mu-str.c */
#define MU_MSG_FIELD_PSEUDO_CONTACT "contact"
/* this is a shortcut for To/Cc/Bcc in queries; handled specially in
* mu-query.cc and mu-str.c */
#define MU_MSG_FIELD_PSEUDO_RECIP "recip"
#define mu_msg_field_id_is_valid(MFID) \
((MFID) < MU_MSG_FIELD_ID_NUM)
/* don't change the order, add new types at the end (before _NUM)*/
enum _MuMsgFieldType {
MU_MSG_FIELD_TYPE_STRING,
MU_MSG_FIELD_TYPE_STRING_LIST,
MU_MSG_FIELD_TYPE_BYTESIZE,
MU_MSG_FIELD_TYPE_TIME_T,
MU_MSG_FIELD_TYPE_INT,
MU_MSG_FIELD_TYPE_NUM
};
typedef guint8 MuMsgFieldType;
static const MuMsgFieldType MU_MSG_FIELD_TYPE_NONE = (MuMsgFieldType)-1;
typedef void (*MuMsgFieldForeachFunc) (MuMsgFieldId id,
gconstpointer data);
/**
* iterator over all possible message fields
*
* @param func a function called for each field
* @param data a user data pointer passed the callback function
*/
void mu_msg_field_foreach (MuMsgFieldForeachFunc func, gconstpointer data);
/**
* get the name of the field -- this a name that can be use in queries,
* ie. 'subject:foo', with 'subject' being the name
*
* @param id a MuMsgFieldId
*
* @return the name of the field as a constant string, or
* NULL if the field is unknown
*/
const char* mu_msg_field_name (MuMsgFieldId id) G_GNUC_PURE;
/**
* get the shortcut of the field -- this a shortcut that can be use in
* queries, ie. 's:foo', with 's' meaning 'subject' being the name
*
* @param id a MuMsgFieldId
*
* @return the shortcut character, or 0 if the field is unknown
*/
char mu_msg_field_shortcut (MuMsgFieldId id) G_GNUC_PURE;
/**
* get the xapian prefix of the field -- that is, the prefix used in
* the Xapian database to identify the field
*
* @param id a MuMsgFieldId
*
* @return the xapian prefix char or 0 if the field is unknown
*/
char mu_msg_field_xapian_prefix (MuMsgFieldId id) G_GNUC_PURE;
/**
* get the type of the field (string, size, time etc.)
*
* @param field a MuMsgField
*
* @return the type of the field (a #MuMsgFieldType), or
* MU_MSG_FIELD_TYPE_NONE if it is not found
*/
MuMsgFieldType mu_msg_field_type (MuMsgFieldId id) G_GNUC_PURE;
/**
* is the field a string?
*
* @param id a MuMsgFieldId
*
* @return TRUE if the field a string, FALSE otherwise
*/
#define mu_msg_field_is_string(MFID)\
(mu_msg_field_type((MFID))==MU_MSG_FIELD_TYPE_STRING?TRUE:FALSE)
/**
* is the field a string-list?
*
* @param id a MuMsgFieldId
*
* @return TRUE if the field a string-list, FALSE otherwise
*/
#define mu_msg_field_is_string_list(MFID)\
(mu_msg_field_type((MFID))==MU_MSG_FIELD_TYPE_STRING_LIST?TRUE:FALSE)
/**
* is the field numeric (has type MU_MSG_FIELD_TYPE_(BYTESIZE|TIME_T|INT))?
*
* @param id a MuMsgFieldId
*
* @return TRUE if the field is numeric, FALSE otherwise
*/
gboolean mu_msg_field_is_numeric (MuMsgFieldId id) G_GNUC_PURE;
/**
* whether the field value should be cached (in MuMsg) -- we cache
* values so we can use the MuMsg without needing to keep the
* underlying data source (the GMimeMessage or the database ptr) alive
* in practice, the fields we *don't* cache are the message body
* (html, txt), because they take too much memory
*/
gboolean mu_msg_field_is_cacheable (MuMsgFieldId id) G_GNUC_PURE;
/**
* is the field Xapian-indexable? That is, should this field be
* indexed in the Xapian database, so we can use the all the
* phrasing, stemming etc. magic
*
* @param id a MuMsgFieldId
*
* @return TRUE if the field is Xapian-enabled, FALSE otherwise
*/
gboolean mu_msg_field_xapian_index (MuMsgFieldId id) G_GNUC_PURE;
/**
* should this field be stored as a xapian term?
*
* @param id a MuMsgFieldId
*
* @return TRUE if the field is Xapian-enabled, FALSE otherwise
*/
gboolean mu_msg_field_xapian_term (MuMsgFieldId id) G_GNUC_PURE;
/**
* should this field be stored as a xapian value?
*
* @param field a MuMsgField
*
* @return TRUE if the field is Xapian-enabled, FALSE otherwise
*/
gboolean mu_msg_field_xapian_value (MuMsgFieldId id) G_GNUC_PURE;
/**
* whether we should use add_boolean_prefix (see Xapian documentation)
* for this field in queries. Used in mu-query.cc
*
* @param id a MuMsgFieldId
*
* @return TRUE if this field wants add_boolean_prefix, FALSE
* otherwise
*/
gboolean mu_msg_field_uses_boolean_prefix (MuMsgFieldId id) G_GNUC_PURE;
/**
* is this a range-field? ie. date, or size
*
* @param id a MuMsgField
*
* @return TRUE if this field is a range field, FALSE otherwise
*/
gboolean mu_msg_field_is_range_field (MuMsgFieldId id) G_GNUC_PURE;
/**
* should this field be stored as contact information? This means that
* e-mail address will be stored as terms, and names will be indexed
*
* @param id a MuMsgFieldId
*
* @return TRUE if the field should be stored as contact information,
* FALSE otherwise
*/
gboolean mu_msg_field_xapian_contact (MuMsgFieldId id) G_GNUC_PURE;
/**
* is the field gmime-enabled? That is, can be field be retrieved
* using GMime?
*
* @param id a MuMsgFieldId
*
* @return TRUE if the field is Gmime-enabled, FALSE otherwise
*/
gboolean mu_msg_field_gmime (MuMsgFieldId id) G_GNUC_PURE;
/**
* get the corresponding MuMsgField for a name (as in mu_msg_field_name)
*
* @param str a name
* @param err, if TRUE, when the shortcut is not found, will issue a
* g_critical warning
*
* @return a MuMsgField, or NULL if it could not be found
*/
MuMsgFieldId mu_msg_field_id_from_name (const char* str,
gboolean err) G_GNUC_PURE;
/**
* get the corresponding MuMsgField for a shortcut (as in mu_msg_field_shortcut)
*
* @param kar a shortcut character
* @param err, if TRUE, when the shortcut is not found, will issue a
* g_critical warning
*
* @return a MuMsgField, or NULL if it could not be found
*/
MuMsgFieldId mu_msg_field_id_from_shortcut (char kar,
gboolean err) G_GNUC_PURE;
G_END_DECLS
#endif /*__MU_MSG_FIELDS_H__*/

View File

@ -33,9 +33,11 @@
#include "mu-msg-priv.hh"
#include "utils/mu-util.h"
#include "utils/mu-utils.hh"
#include "utils/mu-str.h"
using namespace Mu;
using namespace Mu::Message;
static gboolean
init_file_metadata(MuMsgFile* self, const char* path, const char* mdir, GError** err);
@ -85,19 +87,19 @@ init_file_metadata(MuMsgFile* self, const char* path, const gchar* mdir, GError*
if (access(path, R_OK) != 0) {
mu_util_g_set_error(err,
MU_ERROR_FILE,
"cannot read file %s: %s",
path,
g_strerror(errno));
MU_ERROR_FILE,
"cannot read file %s: %s",
path,
g_strerror(errno));
return FALSE;
}
if (stat(path, &statbuf) < 0) {
mu_util_g_set_error(err,
MU_ERROR_FILE,
"cannot stat %s: %s",
path,
g_strerror(errno));
MU_ERROR_FILE,
"cannot stat %s: %s",
path,
g_strerror(errno));
return FALSE;
}
@ -147,21 +149,21 @@ get_mime_stream(MuMsgFile* self, const char* path, GError** err)
file = fopen(path, "r");
if (!file) {
g_set_error(err,
MU_ERROR_DOMAIN,
MU_ERROR_FILE,
"cannot open %s: %s",
path,
g_strerror(errno));
MU_ERROR_DOMAIN,
MU_ERROR_FILE,
"cannot open %s: %s",
path,
g_strerror(errno));
return NULL;
}
stream = g_mime_stream_file_new(file);
if (!stream) {
g_set_error(err,
MU_ERROR_DOMAIN,
MU_ERROR_GMIME,
"cannot create mime stream for %s",
path);
MU_ERROR_DOMAIN,
MU_ERROR_GMIME,
"cannot create mime stream for %s",
path);
fclose(file);
return NULL;
}
@ -170,10 +172,10 @@ get_mime_stream(MuMsgFile* self, const char* path, GError** err)
if (!self->_sha1) {
::fclose(file);
g_set_error(err,
MU_ERROR_DOMAIN,
MU_ERROR_FILE,
"failed to get sha-1 for %s",
path);
MU_ERROR_DOMAIN,
MU_ERROR_FILE,
"failed to get sha-1 for %s",
path);
return NULL;
}
@ -194,10 +196,10 @@ init_mime_msg(MuMsgFile* self, const char* path, GError** err)
g_object_unref(stream);
if (!parser) {
g_set_error(err,
MU_ERROR_DOMAIN,
MU_ERROR_GMIME,
"cannot create mime parser for %s",
path);
MU_ERROR_DOMAIN,
MU_ERROR_GMIME,
"cannot create mime parser for %s",
path);
return FALSE;
}
@ -205,10 +207,10 @@ init_mime_msg(MuMsgFile* self, const char* path, GError** err)
g_object_unref(parser);
if (!self->_mime_msg) {
g_set_error(err,
MU_ERROR_DOMAIN,
MU_ERROR_GMIME,
"message seems invalid, ignoring (%s)",
path);
MU_ERROR_DOMAIN,
MU_ERROR_GMIME,
"message seems invalid, ignoring (%s)",
path);
return FALSE;
}
@ -307,9 +309,9 @@ looks_like_attachment(GMimeObject* part)
const char* type;
const char* sub_type;
} att_types[] = {{"image", "*"},
{"audio", "*"},
{"application", "*"},
{"application", "x-patch"}};
{"audio", "*"},
{"application", "*"},
{"application", "x-patch"}};
disp = g_mime_object_get_content_disposition(part);
@ -392,9 +394,9 @@ get_content_flags(MuMsgFile* self)
msg_cflags_cb(NULL, GMIME_OBJECT(self->_mime_msg), &flags);
/* parts */
mu_mime_message_foreach(self->_mime_msg,
FALSE, /* never decrypt for this */
(GMimeObjectForeachFunc)msg_cflags_cb,
&flags);
FALSE, /* never decrypt for this */
(GMimeObjectForeachFunc)msg_cflags_cb,
&flags);
}
char *ml{get_mailing_list(self)};
@ -439,17 +441,17 @@ parse_prio_str(const char* priostr)
const char* _str;
MessagePriority _prio;
} str_prio[] = {{"high", MessagePriority::High},
{"1", MessagePriority::High},
{"2", MessagePriority::High},
{"1", MessagePriority::High},
{"2", MessagePriority::High},
{"normal", MessagePriority::Normal},
{"3", MessagePriority::Normal},
{"normal", MessagePriority::Normal},
{"3", MessagePriority::Normal},
{"low", MessagePriority::Low},
{"list", MessagePriority::Low},
{"bulk", MessagePriority::Low},
{"4", MessagePriority::Low},
{"5", MessagePriority::Low}};
{"low", MessagePriority::Low},
{"list", MessagePriority::Low},
{"bulk", MessagePriority::Low},
{"4", MessagePriority::Low},
{"5", MessagePriority::Low}};
for (i = 0; i != G_N_ELEMENTS(str_prio); ++i)
if (g_ascii_strcasecmp(priostr, str_prio[i]._str) == 0)
@ -682,13 +684,13 @@ cleanup_maybe(const char* str, gboolean* do_free)
}
G_GNUC_CONST static GMimeAddressType
address_type(MuMsgFieldId mfid)
address_type(Field::Id field_id)
{
switch (mfid) {
case MU_MSG_FIELD_ID_BCC: return GMIME_ADDRESS_TYPE_BCC;
case MU_MSG_FIELD_ID_CC: return GMIME_ADDRESS_TYPE_CC;
case MU_MSG_FIELD_ID_TO: return GMIME_ADDRESS_TYPE_TO;
case MU_MSG_FIELD_ID_FROM: return GMIME_ADDRESS_TYPE_FROM;
switch (field_id) {
case Field::Id::Bcc: return GMIME_ADDRESS_TYPE_BCC;
case Field::Id::Cc: return GMIME_ADDRESS_TYPE_CC;
case Field::Id::To: return GMIME_ADDRESS_TYPE_TO;
case Field::Id::From: return GMIME_ADDRESS_TYPE_FROM;
default: g_return_val_if_reached((GMimeAddressType)-1);
}
}
@ -708,34 +710,35 @@ get_msgid(MuMsgFile* self, gboolean* do_free)
}
char*
Mu::mu_msg_file_get_str_field(MuMsgFile* self, MuMsgFieldId mfid, gboolean* do_free)
Mu::mu_msg_file_get_str_field(MuMsgFile* self, Field::Id field_id, gboolean* do_free)
{
g_return_val_if_fail(self, NULL);
g_return_val_if_fail(mu_msg_field_is_string(mfid), NULL);
g_return_val_if_fail(message_field(field_id).is_string(), NULL);
*do_free = FALSE; /* default */
switch (mfid) {
case MU_MSG_FIELD_ID_BCC:
case MU_MSG_FIELD_ID_CC:
case MU_MSG_FIELD_ID_FROM:
case MU_MSG_FIELD_ID_TO: *do_free = TRUE; return get_recipient(self, address_type(mfid));
switch (field_id) {
case Field::Id::Bcc:
case Field::Id::Cc:
case Field::Id::From:
case Field::Id::To: *do_free = TRUE; return get_recipient(self, address_type(field_id));
case MU_MSG_FIELD_ID_PATH: return self->_path;
case Field::Id::Path: return self->_path;
case MU_MSG_FIELD_ID_MAILING_LIST: *do_free = TRUE; return (char*)get_mailing_list(self);
case Field::Id::MailingList: *do_free = TRUE; return (char*)get_mailing_list(self);
case MU_MSG_FIELD_ID_SUBJECT:
case Field::Id::Subject:
return (char*)cleanup_maybe(g_mime_message_get_subject(self->_mime_msg), do_free);
case MU_MSG_FIELD_ID_MSGID: return get_msgid(self, do_free);
case Field::Id::MessageId: return get_msgid(self, do_free);
case MU_MSG_FIELD_ID_MAILDIR: return self->_maildir;
case Field::Id::Maildir: return self->_maildir;
case MU_MSG_FIELD_ID_BODY_TEXT: /* use mu_msg_get_body_text */
case MU_MSG_FIELD_ID_BODY_HTML: /* use mu_msg_get_body_html */
case MU_MSG_FIELD_ID_EMBEDDED_TEXT:
g_warning("%s is not retrievable through: %s", mu_msg_field_name(mfid), __func__);
case Field::Id::BodyText: /* use mu_msg_get_body_text */
case Field::Id::BodyHtml: /* use mu_msg_get_body_html */
case Field::Id::EmbeddedText:
g_warning("%*s is not retrievable through: %s",
STR_V(message_field(field_id).name), __func__);
return NULL;
default: g_return_val_if_reached(NULL);
@ -743,36 +746,36 @@ Mu::mu_msg_file_get_str_field(MuMsgFile* self, MuMsgFieldId mfid, gboolean* do_f
}
GSList*
Mu::mu_msg_file_get_str_list_field(MuMsgFile* self, MuMsgFieldId mfid)
Mu::mu_msg_file_get_str_list_field(MuMsgFile* self, Field::Id field_id)
{
g_return_val_if_fail(self, NULL);
g_return_val_if_fail(mu_msg_field_is_string_list(mfid), NULL);
g_return_val_if_fail(message_field(field_id).is_string_list(), NULL);
switch (mfid) {
case MU_MSG_FIELD_ID_REFS: return get_references(self);
case MU_MSG_FIELD_ID_TAGS: return get_tags(self);
switch (field_id) {
case Field::Id::References: return get_references(self);
case Field::Id::Tags: return get_tags(self);
default: g_return_val_if_reached(NULL);
}
}
gint64
Mu::mu_msg_file_get_num_field(MuMsgFile* self, const MuMsgFieldId mfid)
Mu::mu_msg_file_get_num_field(MuMsgFile* self, const Field::Id field_id)
{
g_return_val_if_fail(self, -1);
g_return_val_if_fail(mu_msg_field_is_numeric(mfid), -1);
g_return_val_if_fail(message_field(field_id).is_numerical(), -1);
switch (mfid) {
case MU_MSG_FIELD_ID_DATE: {
switch (field_id) {
case Field::Id::Date: {
GDateTime* dt;
dt = g_mime_message_get_date(self->_mime_msg);
return dt ? g_date_time_to_unix(dt) : 0;
}
case MU_MSG_FIELD_ID_FLAGS: return (gint64)get_flags(self);
case Field::Id::Flags: return (gint64)get_flags(self);
case MU_MSG_FIELD_ID_PRIO: return (gint64)get_prio(self);
case Field::Id::Priority: return (gint64)get_prio(self);
case MU_MSG_FIELD_ID_SIZE: return (gint64)get_size(self);
case Field::Id::Size: return (gint64)get_size(self);
default: g_return_val_if_reached(-1);
}
@ -811,17 +814,17 @@ foreach_cb(GMimeObject* parent, GMimeObject* part, ForeachData* fdata)
if (fdata->decrypt && GMIME_IS_MULTIPART_ENCRYPTED(part)) {
GMimeObject* dec;
dec = mu_msg_crypto_decrypt_part(GMIME_MULTIPART_ENCRYPTED(part),
MU_MSG_OPTION_NONE,
NULL,
NULL,
NULL);
MU_MSG_OPTION_NONE,
NULL,
NULL,
NULL);
if (!dec)
return;
if (GMIME_IS_MULTIPART(dec))
g_mime_multipart_foreach((GMIME_MULTIPART(dec)),
(GMimeObjectForeachFunc)foreach_cb,
fdata);
(GMimeObjectForeachFunc)foreach_cb,
fdata);
else
foreach_cb(parent, dec, fdata);
@ -831,9 +834,9 @@ foreach_cb(GMimeObject* parent, GMimeObject* part, ForeachData* fdata)
void
Mu::mu_mime_message_foreach(GMimeMessage* msg,
gboolean decrypt,
GMimeObjectForeachFunc func,
gpointer user_data)
gboolean decrypt,
GMimeObjectForeachFunc func,
gpointer user_data)
{
ForeachData fdata;

View File

@ -20,6 +20,8 @@
#ifndef MU_MSG_FILE_HH__
#define MU_MSG_FILE_HH__
#include "mu-message.hh"
namespace Mu {
struct MuMsgFile;
@ -34,8 +36,8 @@ struct MuMsgFile;
* @return a new MuMsg, or NULL in case of error
*/
MuMsgFile* mu_msg_file_new(const char* path,
const char* mdir,
GError** err) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
const char* mdir,
GError** err) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
/**
* destroy a MuMsgFile object
@ -68,8 +70,8 @@ char* mu_msg_file_get_header(MuMsgFile* self, const char* header);
* @return a string, or NULL
*/
char* mu_msg_file_get_str_field(MuMsgFile* self,
MuMsgFieldId msfid,
gboolean* do_free) G_GNUC_WARN_UNUSED_RESULT;
Message::Field::Id msfid,
gboolean* do_free) G_GNUC_WARN_UNUSED_RESULT;
/**
* get a string-list value for this message
@ -80,7 +82,7 @@ char* mu_msg_file_get_str_field(MuMsgFile* self,
* @return a GSList*, or NULL; free with mu_str_free_list
*/
GSList* mu_msg_file_get_str_list_field(MuMsgFile* self,
MuMsgFieldId msfid) G_GNUC_WARN_UNUSED_RESULT;
Message::Field::Id msfid) G_GNUC_WARN_UNUSED_RESULT;
/**
* get a numeric value for this message -- the return value should be
@ -91,7 +93,7 @@ GSList* mu_msg_file_get_str_list_field(MuMsgFile* self,
*
* @return the numeric value, or -1 in case of error
*/
gint64 mu_msg_file_get_num_field(MuMsgFile* self, MuMsgFieldId mfid);
gint64 mu_msg_file_get_num_field(MuMsgFile* self, Message::Field::Id mfid);
} // namespace Mu

View File

@ -40,6 +40,7 @@
#include "mu-maildir.hh"
using namespace Mu;
using namespace Mu::Message;
/* note, we do the gmime initialization here rather than in
* mu-runtime, because this way we don't need mu-runtime for simple
@ -101,8 +102,8 @@ Mu::mu_msg_new_from_file(const char* path, const char* mdir, GError** err)
self->_file = msgfile;
g_debug("created message from %s in %" G_GINT64_FORMAT " μs",
path,
g_get_monotonic_time() - start);
path,
g_get_monotonic_time() - start);
return self;
}
@ -197,12 +198,12 @@ get_path(MuMsg* self)
val = NULL;
if (self->_doc)
val = mu_msg_doc_get_str_field(self->_doc, MU_MSG_FIELD_ID_PATH);
val = mu_msg_doc_get_str_field(self->_doc, Field::Id::Path);
/* not in the cache yet? try to get it from the file backend,
* in case we are using that */
if (!val && self->_file)
val = mu_msg_file_get_str_field(self->_file, MU_MSG_FIELD_ID_PATH, &do_free);
val = mu_msg_file_get_str_field(self->_file, Field::Id::Path, &do_free);
/* shouldn't happen */
if (!val)
@ -242,27 +243,28 @@ Mu::mu_msg_unload_msg_file(MuMsg* msg)
}
static const GSList*
get_str_list_field(MuMsg* self, MuMsgFieldId mfid)
get_str_list_field(MuMsg* self, Field::Id field_id)
{
GSList* val;
val = NULL;
if (self->_doc && mu_msg_field_xapian_value(mfid))
val = mu_msg_doc_get_str_list_field(self->_doc, mfid);
else if (mu_msg_field_gmime(mfid)) {
if (self->_doc &&
any_of(message_field(field_id).flags & Field::Flag::Value))
val = mu_msg_doc_get_str_list_field(self->_doc, field_id);
else if (any_of(message_field(field_id).flags & Field::Flag::GMime)) {
/* if we don't have a file object yet, we need to
* create it from the file on disk */
if (!mu_msg_load_msg_file(self, NULL))
return NULL;
val = mu_msg_file_get_str_list_field(self->_file, mfid);
val = mu_msg_file_get_str_list_field(self->_file, field_id);
}
return free_later_lst(self, val);
}
static const char*
get_str_field(MuMsg* self, MuMsgFieldId mfid)
get_str_field(MuMsg* self, Field::Id field_id)
{
char* val;
gboolean do_free;
@ -270,15 +272,16 @@ get_str_field(MuMsg* self, MuMsgFieldId mfid)
do_free = TRUE;
val = NULL;
if (self->_doc && mu_msg_field_xapian_value(mfid))
val = mu_msg_doc_get_str_field(self->_doc, mfid);
if (self->_doc &&
any_of(message_field(field_id).flags & Field::Flag::Value))
val = mu_msg_doc_get_str_field(self->_doc, field_id);
else if (mu_msg_field_gmime(mfid)) {
else if (any_of(message_field(field_id).flags & Field::Flag::GMime)) {
/* if we don't have a file object yet, we need to
* create it from the file on disk */
if (!mu_msg_load_msg_file(self, NULL))
return NULL;
val = mu_msg_file_get_str_field(self->_file, mfid, &do_free);
val = mu_msg_file_get_str_field(self->_file, field_id, &do_free);
} else
val = NULL;
@ -286,17 +289,18 @@ get_str_field(MuMsg* self, MuMsgFieldId mfid)
}
static gint64
get_num_field(MuMsg* self, MuMsgFieldId mfid)
get_num_field(MuMsg* self, Field::Id field_id)
{
if (self->_doc && mu_msg_field_xapian_value(mfid))
return mu_msg_doc_get_num_field(self->_doc, mfid);
if (self->_doc &&
any_of(message_field(field_id).flags & Field::Flag::Value))
return mu_msg_doc_get_num_field(self->_doc, field_id);
/* if we don't have a file object yet, we need to
* create it from the file on disk */
if (!mu_msg_load_msg_file(self, NULL))
return -1;
return mu_msg_file_get_num_field(self->_file, mfid);
return mu_msg_file_get_num_field(self->_file, field_id);
}
const char*
@ -312,7 +316,7 @@ Mu::mu_msg_get_header(MuMsg* self, const char* header)
err = NULL;
if (!mu_msg_load_msg_file(self, &err)) {
g_warning("failed to load message file: %s",
err ? err->message : "something went wrong");
err ? err->message : "something went wrong");
return NULL;
}
@ -341,21 +345,21 @@ const char*
Mu::mu_msg_get_path(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, MU_MSG_FIELD_ID_PATH);
return get_str_field(self, Field::Id::Path);
}
const char*
Mu::mu_msg_get_subject(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, MU_MSG_FIELD_ID_SUBJECT);
return get_str_field(self, Field::Id::Subject);
}
const char*
Mu::mu_msg_get_msgid(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, MU_MSG_FIELD_ID_MSGID);
return get_str_field(self, Field::Id::MessageId);
}
const char*
@ -366,7 +370,7 @@ Mu::mu_msg_get_mailing_list(MuMsg* self)
g_return_val_if_fail(self, NULL);
ml = get_str_field(self, MU_MSG_FIELD_ID_MAILING_LIST);
ml = get_str_field(self, Field::Id::MailingList);
if (!ml)
return NULL;
@ -381,56 +385,56 @@ const char*
Mu::mu_msg_get_maildir(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, MU_MSG_FIELD_ID_MAILDIR);
return get_str_field(self, Field::Id::Maildir);
}
const char*
Mu::mu_msg_get_from(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, MU_MSG_FIELD_ID_FROM);
return get_str_field(self, Field::Id::From);
}
const char*
Mu::mu_msg_get_to(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, MU_MSG_FIELD_ID_TO);
return get_str_field(self, Field::Id::To);
}
const char*
Mu::mu_msg_get_cc(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, MU_MSG_FIELD_ID_CC);
return get_str_field(self, Field::Id::Cc);
}
const char*
Mu::mu_msg_get_bcc(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, MU_MSG_FIELD_ID_BCC);
return get_str_field(self, Field::Id::Bcc);
}
time_t
Mu::mu_msg_get_date(MuMsg* self)
{
g_return_val_if_fail(self, (time_t)-1);
return (time_t)get_num_field(self, MU_MSG_FIELD_ID_DATE);
return (time_t)get_num_field(self, Field::Id::Date);
}
MessageFlags
Mu::mu_msg_get_flags(MuMsg* self)
{
g_return_val_if_fail(self, MessageFlags::None);
return static_cast<MessageFlags>(get_num_field(self, MU_MSG_FIELD_ID_FLAGS));
return static_cast<MessageFlags>(get_num_field(self, Field::Id::Flags));
}
size_t
Mu::mu_msg_get_size(MuMsg* self)
{
g_return_val_if_fail(self, (size_t)-1);
return (size_t)get_num_field(self, MU_MSG_FIELD_ID_SIZE);
return (size_t)get_num_field(self, Field::Id::Size);
}
Mu::MessagePriority
@ -439,7 +443,7 @@ Mu::mu_msg_get_prio(MuMsg* self)
g_return_val_if_fail(self, MessagePriority{});
return message_priority_from_char(
static_cast<char>(get_num_field(self, MU_MSG_FIELD_ID_PRIO)));
static_cast<char>(get_num_field(self, Field::Id::Priority)));
}
struct _BodyData {
@ -514,7 +518,7 @@ find_content_type(MuMsg* msg, MuMsgPart* mpart, ContentTypeData* cdata)
if (!cdata->want_html && (mpart->part_type & MU_MSG_PART_TYPE_TEXT_PLAIN))
wanted = (GMimePart*)mpart->data;
else if (!(mpart->part_type & MU_MSG_PART_TYPE_ATTACHMENT) && cdata->want_html &&
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_HTML))
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_HTML))
wanted = (GMimePart*)mpart->data;
else
wanted = NULL;
@ -583,35 +587,35 @@ const GSList*
Mu::mu_msg_get_references(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_list_field(self, MU_MSG_FIELD_ID_REFS);
return get_str_list_field(self, Field::Id::References);
}
const GSList*
Mu::mu_msg_get_tags(MuMsg* self)
{
g_return_val_if_fail(self, NULL);
return get_str_list_field(self, MU_MSG_FIELD_ID_TAGS);
return get_str_list_field(self, Field::Id::Tags);
}
const char*
Mu::mu_msg_get_field_string(MuMsg* self, MuMsgFieldId mfid)
Mu::mu_msg_get_field_string(MuMsg* self, Field::Id field_id)
{
g_return_val_if_fail(self, NULL);
return get_str_field(self, mfid);
return get_str_field(self, field_id);
}
const GSList*
Mu::mu_msg_get_field_string_list(MuMsg* self, MuMsgFieldId mfid)
Mu::mu_msg_get_field_string_list(MuMsg* self, Field::Id field_id)
{
g_return_val_if_fail(self, NULL);
return get_str_list_field(self, mfid);
return get_str_list_field(self, field_id);
}
gint64
Mu::mu_msg_get_field_numeric(MuMsg* self, MuMsgFieldId mfid)
Mu::mu_msg_get_field_numeric(MuMsg* self, Field::Id field_id)
{
g_return_val_if_fail(self, -1);
return get_num_field(self, mfid);
return get_num_field(self, field_id);
}
@ -624,14 +628,14 @@ get_all_contacts(MuMsg *self)
MessageContact::Type::Cc, MessageContact::Type::ReplyTo,
MessageContact::Type::Bcc}) {
auto type_contacts{mu_msg_get_contacts(self, mtype)};
contacts.reserve(contacts.size() + type_contacts.size());
contacts.insert(contacts.end(), type_contacts.begin(), type_contacts.end());
}
return contacts;
}
Mu::MessageContacts
Mu::mu_msg_get_contacts(MuMsg *self, MessageContact::Type mtype)
{
@ -642,7 +646,7 @@ Mu::mu_msg_get_contacts(MuMsg *self, MessageContact::Type mtype)
if (mtype == MessageContact::Type::Unknown)
return get_all_contacts(self);
const auto info = std::invoke([&]()->AddressInfo {
switch (mtype) {
case MessageContact::Type::From:
@ -666,12 +670,12 @@ Mu::mu_msg_get_contacts(MuMsg *self, MessageContact::Type mtype)
self->_file->_mime_msg, info.first)}; lst)
return make_message_contacts(lst, mtype, mdate);
} else if (info.second) {
if (auto&& lst_str{info.second(self)}; lst_str)
if (auto&& lst_str{info.second(self)}; lst_str)
return make_message_contacts(lst_str, mtype, mdate);
}
return {};
}
@ -692,11 +696,11 @@ Mu::mu_msg_is_readable(MuMsg* self)
bool
Mu::mu_msg_move_to_maildir(MuMsg* self,
const std::string& root_maildir_path,
const std::string& target_maildir,
const std::string& target_maildir,
MessageFlags flags,
bool ignore_dups,
bool new_name,
GError** err)
bool ignore_dups,
bool new_name,
GError** err)
{
g_return_val_if_fail(self, false);
@ -763,7 +767,7 @@ Mu::mu_str_display_contact_s(const char* str)
for (c2 = contact; c2 < c && !(isalnum(*c2)); ++c2)
;
if (c2 != c) /* apparently, there was something,
* so we can remove the <... part*/
* so we can remove the <... part*/
*c = '\0';
}

View File

@ -22,11 +22,8 @@
#include <utils/mu-result.hh>
#include <mu-message-flags.hh>
#include <mu-message-priority.hh>
#include <mu-message-contact.hh>
#include <mu-message.hh>
#include <mu-msg-fields.h>
#include <utils/mu-util.h>
#include <utils/mu-utils.hh>
#include <utils/mu-option.hh>
@ -83,8 +80,8 @@ MU_ENABLE_BITOPS(MuMsgOptions);
* mu_msg_unref when done with this message
*/
MuMsg* mu_msg_new_from_file(const char* filepath,
const char* maildir,
GError** err) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
const char* maildir,
GError** err) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
/**
* create a new MuMsg* instance based on a Xapian::Document
@ -100,7 +97,7 @@ MuMsg* mu_msg_new_from_file(const char* filepath,
* mu_msg_unref when done with this message
*/
MuMsg* mu_msg_new_from_doc(XapianDocument* doc,
GError** err) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
GError** err) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
/**
* if we don't have a message file yet (because this message is
@ -320,7 +317,7 @@ size_t mu_msg_get_size(MuMsg* msg);
*
* @return a string that should not be freed
*/
const char* mu_msg_get_field_string(MuMsg* msg, MuMsgFieldId mfid);
const char* mu_msg_get_field_string(MuMsg* msg, Message::Field::Id mfid);
/**
* get some field value as string-list
@ -330,7 +327,7 @@ const char* mu_msg_get_field_string(MuMsg* msg, MuMsgFieldId mfid);
*
* @return a list that should not be freed
*/
const GSList* mu_msg_get_field_string_list(MuMsg* self, MuMsgFieldId mfid);
const GSList* mu_msg_get_field_string_list(MuMsg* self, Message::Field::Id mfid);
/**
* get some field value as string
@ -340,7 +337,7 @@ const GSList* mu_msg_get_field_string_list(MuMsg* self, MuMsgFieldId mfid);
*
* @return a string that should not be freed
*/
gint64 mu_msg_get_field_numeric(MuMsg* msg, MuMsgFieldId mfid);
gint64 mu_msg_get_field_numeric(MuMsg* msg, Message::Field::Id mfid);
/**
* get the message priority for this message. The X-Priority, X-MSMailPriority,
@ -404,7 +401,7 @@ const GSList* mu_msg_get_tags(MuMsg* self);
* @return negative if m1 is smaller, positive if m1 is smaller, 0 if
* they are equal
*/
int mu_msg_cmp(MuMsg* m1, MuMsg* m2, MuMsgFieldId mfid);
int mu_msg_cmp(MuMsg* m1, MuMsg* m2, Message::Field::Id mfid);
/**
* check whether there there's a readable file behind this message
@ -440,17 +437,17 @@ bool mu_msg_move_to_maildir(MuMsg* msg,
bool ignore_dups,
bool new_name,
GError** err);
/**
/**
* Get a sequence with contacts of the given type for this message.
*
* @param msg a valid MuMsg* instance
* @param mtype the contact type; with Type::Unknown, get _all_ types.
*
*
* @return a sequence
*/
Mu::MessageContacts mu_msg_get_contacts (MuMsg *self,
MessageContact::Type mtype=MessageContact::Type::Unknown);
/**
* create a 'display contact' from an email header To/Cc/Bcc/From-type address
* ie., turn
@ -489,7 +486,7 @@ struct QueryMatch;
* - MU_MSG_OPTION_EXTRACT_IMAGES: extract image attachments as temporary
* files and include links to those in the sexp
* and for message parts:
* MU_MSG_OPTION_CHECK_SIGNATURES: check signatures
* MU_MSG_OPTION_CHECK_SIGNATURES: check signatures
* MU_MSG_OPTION_AUTO_RETRIEVE_KEY: attempt to retrieve keys online
* MU_MSG_OPTION_USE_AGENT: attempt to use GPG-agent
* MU_MSG_OPTION_USE_PKCS7: attempt to use PKCS (instead of gpg)