lib: Update for new querying machinery

Port to c++ and use new APIs.
This commit is contained in:
Dirk-Jan C. Binnema 2020-11-28 10:15:49 +02:00
parent 95dffb98a6
commit e282d80bc0
24 changed files with 433 additions and 513 deletions

1
.gitignore vendored
View File

@ -126,3 +126,4 @@ compile_commands.json
/lib/test-mu-threader
/lib/test-mu-tokenizer
/lib/test-mu-parser
/lib/test-mu-query-threader

View File

@ -63,13 +63,16 @@ libmu_la_SOURCES= \
mu-bookmarks.hh \
mu-contacts.cc \
mu-contacts.hh \
mu-container.cc \
mu-container.hh \
mu-data.hh \
mu-parser.cc \
mu-parser.hh \
mu-query.cc \
mu-query.hh \
mu-query-results.hh \
mu-query-match-deciders.cc \
mu-query-match-deciders.hh \
mu-query-threader.cc \
mu-query-threader.hh \
mu-runtime.cc \
mu-runtime.hh \
mu-script.cc \
@ -78,34 +81,30 @@ libmu_la_SOURCES= \
mu-server.hh \
mu-store.cc \
mu-store.hh \
mu-threader.cc \
mu-threader.hh \
mu-tokenizer.cc \
mu-tokenizer.hh \
mu-tree.hh \
mu-xapian.cc \
mu-xapian.hh \
mu-flags.c \
mu-maildir.c \
mu-maildir.h \
mu-flags.h \
mu-msg-crypto.c \
mu-maildir.cc \
mu-maildir.hh \
mu-flags.cc \
mu-flags.hh \
mu-msg-crypto.cc \
mu-msg-doc.cc \
mu-msg-doc.h \
mu-msg-doc.hh \
mu-msg-fields.c \
mu-msg-fields.h \
mu-msg-file.c \
mu-msg-file.h \
mu-msg-iter.cc \
mu-msg-iter.h \
mu-msg-part.c \
mu-msg-part.h \
mu-msg-file.cc \
mu-msg-file.hh \
mu-msg-part.cc \
mu-msg-part.hh \
mu-msg-prio.c \
mu-msg-prio.h \
mu-msg-priv.h \
mu-msg-priv.hh \
mu-msg-sexp.cc \
mu-msg.c \
mu-msg.h
mu-msg.cc \
mu-msg.hh
libmu_la_LIBADD= \
$(XAPIAN_LIBS) \
@ -130,7 +129,6 @@ tokenize_LDADD= \
utils/libmu-utils.la
EXTRA_DIST= \
mu-msg-crypto.c \
doxyfile.in
noinst_PROGRAMS+=$(TEST_PROGS)
@ -154,14 +152,14 @@ TEST_PROGS += test-mu-store
test_mu_store_SOURCES= test-mu-store.cc
test_mu_store_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-query
test_mu_query_SOURCES= test-query.cc
test_mu_query_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-flags
test_mu_flags_SOURCES= test-mu-flags.cc
test_mu_flags_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-container
test_mu_container_SOURCES= test-mu-container.cc
test_mu_container_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-contacts
test_mu_contacts_SOURCES= test-mu-contacts.cc
test_mu_contacts_LDADD= libtestmucommon.la

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2011-2012 <djcb@djcbsoftware.nl>
** Copyright (C) 2011-2020 <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
@ -18,15 +18,16 @@
*/
#include <string.h>
#include "mu-flags.h"
#include "mu-flags.hh"
struct _FlagInfo {
using namespace Mu;
struct FlagInfo {
MuFlags flag;
char kar;
const char *name;
MuFlagType flag_type;
};
typedef struct _FlagInfo FlagInfo;
static const FlagInfo FLAG_INFO[] = {
@ -53,7 +54,7 @@ static const FlagInfo FLAG_INFO[] = {
MuFlagType
mu_flag_type (MuFlags flag)
Mu::mu_flag_type (MuFlags flag)
{
unsigned u;
@ -66,7 +67,7 @@ mu_flag_type (MuFlags flag)
char
mu_flag_char (MuFlags flag)
Mu::mu_flag_char (MuFlags flag)
{
unsigned u;
@ -78,7 +79,7 @@ mu_flag_char (MuFlags flag)
MuFlags
mu_flag_char_from_name (const char *str)
Mu::mu_flag_char_from_name (const char *str)
{
unsigned u;
@ -86,9 +87,9 @@ mu_flag_char_from_name (const char *str)
for (u = 0; u != G_N_ELEMENTS (FLAG_INFO); ++u)
if (g_strcmp0(FLAG_INFO[u].name, str) == 0)
return FLAG_INFO[u].kar;
return (MuFlags)FLAG_INFO[u].kar;
return 0;
return (MuFlags)0;
}
@ -106,7 +107,7 @@ mu_flag_from_char (char kar)
const char*
mu_flag_name (MuFlags flag)
Mu::mu_flag_name (MuFlags flag)
{
unsigned u;
@ -119,7 +120,7 @@ mu_flag_name (MuFlags flag)
const char*
mu_flags_to_str_s (MuFlags flags, MuFlagType types)
Mu::mu_flags_to_str_s (MuFlags flags, MuFlagType types)
{
unsigned u,v;
static char str[sizeof(FLAG_INFO) + 1];
@ -135,7 +136,7 @@ mu_flags_to_str_s (MuFlags flags, MuFlagType types)
MuFlags
mu_flags_from_str (const char *str, MuFlagType types,
Mu::mu_flags_from_str (const char *str, MuFlagType types,
gboolean ignore_invalid)
{
const char *cur;
@ -165,7 +166,7 @@ mu_flags_from_str (const char *str, MuFlagType types,
char*
mu_flags_custom_from_str (const char *str)
Mu::mu_flags_custom_from_str (const char *str)
{
char *custom;
const char* cur;
@ -195,7 +196,7 @@ mu_flags_custom_from_str (const char *str)
void
mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data)
Mu::mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data)
{
unsigned u;
@ -207,7 +208,7 @@ mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data)
MuFlags
mu_flags_from_str_delta (const char *str, MuFlags oldflags,
Mu::mu_flags_from_str_delta (const char *str, MuFlags oldflags,
MuFlagType types)
{
const char *cur;

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2011-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2011-2020 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
@ -18,14 +18,15 @@
*/
#ifndef __MU_FLAGS_H__
#define __MU_FLAGS_H__
#ifndef MU_FLAGS_HH__
#define MU_FLAGS_HH__
#include <glib.h>
#include <utils/mu-utils.hh>
G_BEGIN_DECLS
namespace Mu {
enum _MuFlags {
enum MuFlags {
MU_FLAG_NONE = 0,
/* next 6 are seen in the file-info part of maildir message
@ -56,17 +57,18 @@ enum _MuFlags {
/* other content flags */
MU_FLAG_LIST = 1 << 11
};
typedef enum _MuFlags MuFlags;
MU_ENABLE_BITOPS(MuFlags);
#define MU_FLAG_INVALID ((MuFlags)-1)
enum _MuFlagType {
enum MuFlagType {
MU_FLAG_TYPE_MAILFILE = 1 << 0,
MU_FLAG_TYPE_MAILDIR = 1 << 1,
MU_FLAG_TYPE_CONTENT = 1 << 2,
MU_FLAG_TYPE_PSEUDO = 1 << 3
};
typedef enum _MuFlagType MuFlagType;
MU_ENABLE_BITOPS(MuFlagType);
#define MU_FLAG_TYPE_ANY ((MuFlagType)-1)
#define MU_FLAG_TYPE_INVALID ((MuFlagType)-1)
@ -179,6 +181,7 @@ typedef void (*MuFlagsForeachFunc) (MuFlags flag, gpointer user_data);
*/
void mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data);
G_END_DECLS
} // namespace Mu
#endif /*__MU_FLAGS_H__*/

View File

@ -30,9 +30,11 @@
#include <glib/gprintf.h>
#include <gio/gio.h>
#include "mu-maildir.h"
#include "mu-maildir.hh"
#include "utils/mu-str.h"
using namespace Mu;
#define MU_MAILDIR_NOINDEX_FILE ".noindex"
#define MU_MAILDIR_NOUPDATE_FILE ".noupdate"
@ -115,7 +117,7 @@ create_noindex (const char *path, GError **err)
}
gboolean
mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex, GError **err)
Mu::mu_maildir_mkdir (const char* path, mode_t mode, gboolean noindex, GError **err)
{
g_return_val_if_fail (path, FALSE);
@ -181,7 +183,7 @@ get_target_fullpath (const char* src, const char *targetpath, GError **err)
gboolean
mu_maildir_link (const char* src, const char *targetpath, GError **err)
Mu::mu_maildir_link (const char* src, const char *targetpath, GError **err)
{
char *targetfullpath;
int rv;
@ -248,7 +250,7 @@ process_file (const char* fullpath, const char* mdir,
* (we're skipping 'tmp' for obvious reasons)
*/
gboolean
mu_maildir_is_leaf_dir (const char *path)
Mu::mu_maildir_is_leaf_dir (const char *path)
{
size_t len;
@ -468,7 +470,7 @@ process_dir_entries (DIR *dir, const char* path, const char* mdir,
errno = 0;
res = readdir (dir);
if (res) {
entry = g_memdup (res, sizeof(struct dirent));
entry = (struct dirent*)g_memdup (res, sizeof(struct dirent));
lst = g_slist_prepend (lst, entry);
} else if (errno == 0) {
break;
@ -540,7 +542,7 @@ process_dir (const char* path, const char* mdir,
MuError
mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg,
Mu::mu_maildir_walk (const char *path, MuMaildirWalkMsgCallback cb_msg,
MuMaildirWalkDirCallback cb_dir, gboolean full,
void *data)
{
@ -612,7 +614,7 @@ clear_links (const char *path, DIR *dir)
}
gboolean
mu_maildir_clear_links (const char *path, GError **err)
Mu::mu_maildir_clear_links (const char *path, GError **err)
{
DIR *dir;
gboolean rv;
@ -633,11 +635,8 @@ mu_maildir_clear_links (const char *path, GError **err)
return rv;
}
MuFlags
mu_maildir_get_flags_from_path (const char *path)
Mu::mu_maildir_get_flags_from_path (const char *path)
{
g_return_val_if_fail (path, MU_FLAG_INVALID);
@ -678,7 +677,7 @@ mu_maildir_get_flags_from_path (const char *path)
/* get the file flags */
{
char *info;
const char *info;
info = strrchr (path, '2');
if (!info || info == path ||
@ -728,14 +727,15 @@ get_new_path (const char *mdir, const char *mfile, MuFlags flags,
char*
mu_maildir_get_maildir_from_path (const char* path)
Mu::mu_maildir_get_maildir_from_path (const char* path)
{
char *mdir;
/* determine the maildir */
mdir = g_path_get_dirname (path);
if (!g_str_has_suffix (mdir, "cur") &&
!g_str_has_suffix (mdir, "new")) {
!g_str_has_suffix (mdir, "new")) {
g_warning ("%s: not a valid maildir path: %s",
__func__, path);
g_free (mdir);
@ -773,7 +773,7 @@ find_path_separator(const char *path)
}
char*
mu_maildir_get_new_path (const char *oldpath, const char *new_mdir,
Mu::mu_maildir_get_new_path (const char *oldpath, const char *new_mdir,
MuFlags newflags, gboolean new_name)
{
char *mfile, *mdir, *custom_flags, *cur, *newpath, flags_sep = ':';
@ -933,7 +933,7 @@ msg_move (const char* src, const char *dst, GError **err)
}
char*
mu_maildir_move_message (const char* oldpath, const char* targetmdir,
Mu::mu_maildir_move_message (const char* oldpath, const char* targetmdir,
MuFlags newflags, gboolean ignore_dups,
gboolean new_name, GError **err)
{

View File

@ -17,18 +17,16 @@
**
*/
#ifndef __MU_MAILDIR_H__
#define __MU_MAILDIR_H__
#ifndef MU_MAILDIR_HH__
#define MU_MAILDIR_HH__
#include <glib.h>
#include <time.h>
#include <sys/types.h> /* for mode_t */
#include <utils/mu-util.h>
#include <mu-flags.h>
G_BEGIN_DECLS
#include <mu-flags.hh>
namespace Mu {
/**
* create a new maildir. if parts of the maildir already exists, those
* will simply be ignored. IOW, if you try to create the same maildir
@ -218,6 +216,6 @@ char* mu_maildir_move_message (const char* oldpath, const char* targetmdir,
gboolean new_name, GError **err)
G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
} // namespace Mu
#endif /*__MU_MAILDIR_H__*/
#endif /*MU_MAILDIR_HH__*/

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2012-2018 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2012-2020 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
@ -17,24 +17,25 @@
**
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <string.h>
#include "mu-msg.h"
#include "mu-msg-priv.h"
#include "mu-msg-part.h"
#include "mu-msg.hh"
#include "mu-msg-priv.hh"
#include "mu-msg-part.hh"
#include "utils/mu-date.h"
#include <gmime/gmime.h>
#include <gmime/gmime-multipart-signed.h>
using namespace Mu;
static const char*
get_pubkey_algo_name (GMimePubKeyAlgo algo)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
switch (algo) {
case GMIME_PUBKEY_ALGO_DEFAULT:
return "default";
@ -53,11 +54,15 @@ get_pubkey_algo_name (GMimePubKeyAlgo algo)
default:
return "unknown pubkey algorithm";
}
#pragma GCC diagnostic pop
}
static const gchar*
get_digestkey_algo_name (GMimeDigestAlgo algo)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
switch (algo) {
case GMIME_DIGEST_ALGO_DEFAULT:
return "default";
@ -86,6 +91,7 @@ get_digestkey_algo_name (GMimeDigestAlgo algo)
default:
return "unknown digest algorithm";
}
#pragma GCC diagnostic pop
}
@ -196,16 +202,17 @@ get_verdict_report (GMimeSignature *msig)
static char*
get_signers (GHashTable *signerhash)
{
GString *gstr;
GHashTableIter iter;
const char *name;
GString *gstr;
GHashTableIter iter;
char *name;
if (!signerhash || g_hash_table_size(signerhash) == 0)
return NULL;
gstr = g_string_new (NULL);
g_hash_table_iter_init (&iter, signerhash);
while (g_hash_table_iter_next (&iter, (gpointer)&name, NULL)) {
while (g_hash_table_iter_next (&iter, reinterpret_cast<void**>(&name), NULL)) {
if (gstr->len != 0)
g_string_append_c (gstr, ',');
gstr = g_string_append (gstr, name);
@ -272,7 +279,7 @@ get_status_report (GMimeSignatureList *sigs)
}
void
mu_msg_part_sig_status_report_destroy (MuMsgPartSigStatusReport *report)
Mu::mu_msg_part_sig_status_report_destroy (MuMsgPartSigStatusReport *report)
{
if (!report)
return;
@ -295,7 +302,7 @@ tag_with_sig_status(GObject *part,
void
mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts,
Mu::mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts,
GError **err)
{
/* the signature status */
@ -349,7 +356,7 @@ check_decrypt_result(GMimeMultipartEncrypted *part, GMimeDecryptResult *res,
GMimeObject* /* this is declared in mu-msg-priv.h */
mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOptions opts,
Mu::mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOptions opts,
MuMsgPartPasswordFunc func, gpointer user_data,
GError **err)
{

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2008-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2020 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
@ -24,17 +24,18 @@
#include <xapian.h>
#include "mu-msg-fields.h"
#include "mu-msg-doc.h"
#include "mu-msg-doc.hh"
#include "utils/mu-util.h"
#include "utils/mu-str.h"
#include "utils/mu-date.h"
#include "utils/mu-utils.hh"
struct _MuMsgDoc {
using namespace Mu;
_MuMsgDoc (Xapian::Document *doc): _doc (doc) { }
~_MuMsgDoc () { delete _doc; }
struct Mu::MuMsgDoc {
MuMsgDoc (Xapian::Document *doc): _doc (doc) { }
~MuMsgDoc () { delete _doc; }
const Xapian::Document doc() const { return *_doc; }
private:
Xapian::Document *_doc;
@ -42,7 +43,7 @@ private:
MuMsgDoc*
mu_msg_doc_new (XapianDocument *doc, GError **err)
Mu::mu_msg_doc_new (XapianDocument *doc, GError **err)
{
g_return_val_if_fail (doc, NULL);
@ -55,7 +56,7 @@ mu_msg_doc_new (XapianDocument *doc, GError **err)
}
void
mu_msg_doc_destroy (MuMsgDoc *self)
Mu::mu_msg_doc_destroy (MuMsgDoc *self)
{
try {
delete self;
@ -65,7 +66,7 @@ mu_msg_doc_destroy (MuMsgDoc *self)
gchar*
mu_msg_doc_get_str_field (MuMsgDoc *self, MuMsgFieldId mfid)
Mu::mu_msg_doc_get_str_field (MuMsgDoc *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), NULL);
@ -86,7 +87,7 @@ mu_msg_doc_get_str_field (MuMsgDoc *self, MuMsgFieldId mfid)
GSList*
mu_msg_doc_get_str_list_field (MuMsgDoc *self, MuMsgFieldId mfid)
Mu::mu_msg_doc_get_str_list_field (MuMsgDoc *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), NULL);
@ -102,7 +103,7 @@ mu_msg_doc_get_str_list_field (MuMsgDoc *self, MuMsgFieldId mfid)
gint64
mu_msg_doc_get_num_field (MuMsgDoc *self, MuMsgFieldId mfid)
Mu::mu_msg_doc_get_num_field (MuMsgDoc *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, -1);
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), -1);

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2012-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2012-2020 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
@ -17,16 +17,16 @@
**
*/
#ifndef __MU_MSG_DOC_H__
#define __MU_MSG_DOC_H__
#ifndef MU_MSG_DOC_HH__
#define MU_MSG_DOC_HH__
#include <glib.h>
#include <utils/mu-util.h>
G_BEGIN_DECLS
struct _MuMsgDoc;
typedef struct _MuMsgDoc MuMsgDoc;
namespace Mu {
struct MuMsgDoc;
/**
* create a new MuMsgDoc instance
@ -90,7 +90,6 @@ GSList* mu_msg_doc_get_str_list_field (MuMsgDoc *self, MuMsgFieldId mfid)
*/
gint64 mu_msg_doc_get_num_field (MuMsgDoc *self, MuMsgFieldId mfid);
} // namespace Mu
G_END_DECLS
#endif /*__MU_MSG_DOC_H__*/
#endif /*MU_MSG_DOC_HH__*/

View File

@ -27,25 +27,27 @@
#include <inttypes.h>
#include <gmime/gmime.h>
#include "mu-maildir.h"
#include "mu-maildir.hh"
#include "mu-store.hh"
#include "mu-msg-priv.h"
#include "mu-msg-priv.hh"
#include "utils/mu-util.h"
#include "utils/mu-str.h"
using namespace Mu;
static gboolean init_file_metadata (MuMsgFile *self, const char* path,
const char *mdir, GError **err);
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)
Mu::mu_msg_file_new (const char* filepath, const char *mdir, GError **err)
{
MuMsgFile *self;
g_return_val_if_fail (filepath, NULL);
self = g_slice_new0 (MuMsgFile);
self = g_new0(MuMsgFile, 1);
if (!init_file_metadata (self, filepath, mdir, err)) {
mu_msg_file_destroy (self);
@ -61,18 +63,17 @@ mu_msg_file_new (const char* filepath, const char *mdir, GError **err)
}
void
mu_msg_file_destroy (MuMsgFile *self)
Mu::mu_msg_file_destroy (MuMsgFile *self)
{
if (!self)
return;
if (self->_mime_msg)
g_object_unref (self->_mime_msg);
g_clear_object(&self->_mime_msg);
g_free(self->_path);
g_free(self->_maildir);
g_slice_free (MuMsgFile, self);
g_free (self);
}
static gboolean
@ -477,7 +478,7 @@ stream_to_string (GMimeStream *stream, size_t buflen)
}
gchar*
mu_msg_mime_part_to_string (GMimePart *part, gboolean *err)
Mu::mu_msg_mime_part_to_string (GMimePart *part, gboolean *err)
{
GMimeDataWrapper *wrapper;
GMimeStream *stream;
@ -641,7 +642,7 @@ address_type (MuMsgFieldId mfid)
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;
default: g_return_val_if_reached (-1);
default: g_return_val_if_reached ((GMimeAddressType)-1);
}
}
@ -661,7 +662,7 @@ get_msgid (MuMsgFile *self, gboolean *do_free)
}
char*
mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid,
Mu::mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid,
gboolean *do_free)
{
g_return_val_if_fail (self, NULL);
@ -705,7 +706,7 @@ mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid,
}
GSList*
mu_msg_file_get_str_list_field (MuMsgFile *self, MuMsgFieldId mfid)
Mu::mu_msg_file_get_str_list_field (MuMsgFile *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (mu_msg_field_is_string_list(mfid), NULL);
@ -718,7 +719,7 @@ mu_msg_file_get_str_list_field (MuMsgFile *self, MuMsgFieldId mfid)
}
gint64
mu_msg_file_get_num_field (MuMsgFile *self, const MuMsgFieldId mfid)
Mu::mu_msg_file_get_num_field (MuMsgFile *self, const MuMsgFieldId mfid)
{
g_return_val_if_fail (self, -1);
g_return_val_if_fail (mu_msg_field_is_numeric(mfid), -1);
@ -745,7 +746,7 @@ mu_msg_file_get_num_field (MuMsgFile *self, const MuMsgFieldId mfid)
}
char*
mu_msg_file_get_header (MuMsgFile *self, const char *header)
Mu::mu_msg_file_get_header (MuMsgFile *self, const char *header)
{
const gchar *hdr;
@ -797,8 +798,8 @@ foreach_cb (GMimeObject *parent, GMimeObject *part, ForeachData *fdata)
}
void
mu_mime_message_foreach (GMimeMessage *msg, gboolean decrypt,
GMimeObjectForeachFunc func, gpointer user_data)
Mu::mu_mime_message_foreach (GMimeMessage *msg, gboolean decrypt,
GMimeObjectForeachFunc func, gpointer user_data)
{
ForeachData fdata;

View File

@ -1,7 +1,5 @@
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
/*
** Copyright (C) 2012-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2012-2020 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
@ -19,11 +17,12 @@
**
*/
#ifndef __MU_MSG_FILE_H__
#define __MU_MSG_FILE_H__
#ifndef MU_MSG_FILE_HH__
#define MU_MSG_FILE_HH__
struct _MuMsgFile;
typedef struct _MuMsgFile MuMsgFile;
namespace Mu {
struct MuMsgFile;
/**
* create a new message from a file
@ -101,5 +100,6 @@ GSList* mu_msg_file_get_str_list_field (MuMsgFile *self, MuMsgFieldId msfid)
*/
gint64 mu_msg_file_get_num_field (MuMsgFile *self, MuMsgFieldId mfid);
} // namespace Mu
#endif /*__MU_MSG_FILE_H__*/
#endif /*MU_MSG_FILE_HH__*/

View File

@ -1,6 +1,5 @@
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
/*
** Copyright (C) 2008-2014 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2020 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
@ -18,17 +17,18 @@
**
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <string.h>
#include <unistd.h>
#include "mu-msg.hh"
#include "utils/mu-util.h"
#include "utils/mu-str.h"
#include "mu-msg-priv.h"
#include "mu-msg-part.h"
#include "mu-msg-priv.hh"
#include "mu-msg-part.hh"
using namespace Mu;
struct _DoData {
GMimeObject *mime_obj;
@ -60,7 +60,7 @@ get_mime_object_at_index (MuMsg *msg, MuMsgOptions opts, unsigned index)
ddata.index = index;
/* wipe out some irrelevant options */
opts &= ~MU_MSG_OPTION_VERIFY;
opts &= (MuMsgOptions)~MU_MSG_OPTION_VERIFY;
opts &= ~MU_MSG_OPTION_EXTRACT_IMAGES;
mu_msg_part_foreach (msg, opts,
@ -192,7 +192,7 @@ get_text_from_mime_msg (MuMsg *msg, GMimeMessage *mmsg, MuMsgOptions opts)
char*
mu_msg_part_get_text (MuMsg *msg, MuMsgPart *self, MuMsgOptions opts)
Mu::mu_msg_part_get_text (MuMsg *msg, MuMsgPart *self, MuMsgOptions opts)
{
GMimeObject *mobj;
GMimeMessage *mime_msg;
@ -336,7 +336,7 @@ mime_part_get_filename (GMimeObject *mobj, unsigned index,
char*
mu_msg_part_get_filename (MuMsgPart *mpart, gboolean construct_if_needed)
Mu::mu_msg_part_get_filename (MuMsgPart *mpart, gboolean construct_if_needed)
{
g_return_val_if_fail (mpart, NULL);
g_return_val_if_fail (GMIME_IS_OBJECT(mpart->data), NULL);
@ -346,7 +346,7 @@ mu_msg_part_get_filename (MuMsgPart *mpart, gboolean construct_if_needed)
}
const gchar*
mu_msg_part_get_content_id (MuMsgPart *mpart)
Mu::mu_msg_part_get_content_id (MuMsgPart *mpart)
{
g_return_val_if_fail (mpart, NULL);
g_return_val_if_fail (GMIME_IS_OBJECT(mpart->data), NULL);
@ -494,7 +494,8 @@ copy_status_report_maybe (GObject *obj)
{
MuMsgPartSigStatusReport *report, *copy;
report = g_object_get_data (obj, SIG_STATUS_REPORT);
report = (MuMsgPartSigStatusReport*)
g_object_get_data (obj, SIG_STATUS_REPORT);
if (!report)
return NULL; /* nothing to copy */
@ -661,7 +662,7 @@ handle_mime_object (MuMsg *msg, GMimeObject *mobj, GMimeObject *parent,
gboolean
mu_msg_part_foreach (MuMsg *msg, MuMsgOptions opts,
Mu::mu_msg_part_foreach (MuMsg *msg, MuMsgOptions opts,
MuMsgPartForeachFunc func, gpointer user_data)
{
unsigned index;
@ -788,8 +789,8 @@ save_object (GMimeObject *obj, MuMsgOptions opts, const char *fullpath,
gchar*
mu_msg_part_get_path (MuMsg *msg, MuMsgOptions opts,
const char* targetdir, unsigned index, GError **err)
Mu::mu_msg_part_get_path (MuMsg *msg, MuMsgOptions opts,
const char* targetdir, unsigned index, GError **err)
{
char *fname, *filepath;
GMimeObject* mobj;
@ -821,7 +822,7 @@ mu_msg_part_get_path (MuMsg *msg, MuMsgOptions opts,
gchar*
mu_msg_part_get_cache_path (MuMsg *msg, MuMsgOptions opts, guint partid,
Mu::mu_msg_part_get_cache_path (MuMsg *msg, MuMsgOptions opts, guint partid,
GError **err)
{
char *dirname, *filepath;
@ -856,7 +857,7 @@ mu_msg_part_get_cache_path (MuMsg *msg, MuMsgOptions opts, guint partid,
gboolean
mu_msg_part_save (MuMsg *msg, MuMsgOptions opts,
Mu::mu_msg_part_save (MuMsg *msg, MuMsgOptions opts,
const char *fullpath, guint partidx, GError **err)
{
gboolean rv;
@ -897,7 +898,7 @@ mu_msg_part_save (MuMsg *msg, MuMsgOptions opts,
gchar*
mu_msg_part_save_temp (MuMsg *msg, MuMsgOptions opts, guint partidx,
Mu::mu_msg_part_save_temp (MuMsg *msg, MuMsgOptions opts, guint partidx,
GError **err)
{
gchar *filepath;
@ -925,7 +926,7 @@ match_cid (MuMsgPart *mpart, const char *cid)
}
int
mu_msg_find_index_for_cid (MuMsg *msg, MuMsgOptions opts,
Mu::mu_msg_find_index_for_cid (MuMsg *msg, MuMsgOptions opts,
const char *sought_cid)
{
const char* cid;
@ -961,7 +962,7 @@ match_filename_rx (MuMsg *msg, MuMsgPart *mpart, RxMatchData *mdata)
if (!fname)
return;
if (g_regex_match (mdata->_rx, fname, 0, NULL))
if (g_regex_match (mdata->_rx, fname, (GRegexMatchFlags)0, NULL))
mdata->_lst = g_slist_prepend (mdata->_lst,
GUINT_TO_POINTER(mpart->index));
g_free (fname);
@ -969,7 +970,7 @@ match_filename_rx (MuMsg *msg, MuMsgPart *mpart, RxMatchData *mdata)
GSList*
mu_msg_find_files (MuMsg *msg, MuMsgOptions opts, const GRegex *pattern)
Mu::mu_msg_find_files (MuMsg *msg, MuMsgOptions opts, const GRegex *pattern)
{
RxMatchData mdata;
@ -991,7 +992,7 @@ mu_msg_find_files (MuMsg *msg, MuMsgOptions opts, const GRegex *pattern)
gboolean
mu_msg_part_maybe_attachment (MuMsgPart *part)
Mu::mu_msg_part_maybe_attachment (MuMsgPart *part)
{
g_return_val_if_fail (part, FALSE);

View File

@ -1,7 +1,5 @@
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
/*
** Copyright (C) 2008-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2020 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
@ -19,17 +17,18 @@
**
*/
#ifndef __MU_MSG_PART_H__
#define __MU_MSG_PART_H__
#ifndef MU_MSG_PART_HH__
#define MU_MSG_PART_HH__
#include "utils/mu-utils.hh"
#include <glib.h>
#include <unistd.h> /* for ssize_t */
namespace Mu {
#define SIG_STATUS_REPORT "sig-status-report"
G_BEGIN_DECLS
enum _MuMsgPartType {
enum MuMsgPartType {
MU_MSG_PART_TYPE_NONE = 0,
/* MIME part without children */
@ -51,8 +50,7 @@ enum _MuMsgPartType {
/* a text/html part? */
MU_MSG_PART_TYPE_TEXT_HTML = 1 << 9
};
typedef enum _MuMsgPartType MuMsgPartType;
MU_ENABLE_BITOPS(MuMsgPartType);
/* the signature status */
enum _MuMsgPartSigStatus {
@ -113,7 +111,6 @@ typedef struct _MuMsgPart MuMsgPart;
char *mu_msg_part_get_filename (MuMsgPart *mpart, gboolean construct_if_needed)
G_GNUC_WARN_UNUSED_RESULT;
/**
* get appropriate content id for the mime-part
*
@ -263,6 +260,6 @@ typedef void (*MuMsgPartForeachFunc) (MuMsg *msg, MuMsgPart*, gpointer);
gboolean mu_msg_part_foreach (MuMsg *msg, MuMsgOptions opts,
MuMsgPartForeachFunc func, gpointer user_data);
G_END_DECLS
} // namespace Mu
#endif /*__MU_MSG_PART_H__*/
#endif /*MU_MSG_PART_HH__*/

View File

@ -1,7 +1,5 @@
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
/*
** Copyright (C) 2008-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2020 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
@ -19,24 +17,20 @@
**
*/
#ifndef __MU_MSG_PRIV_H__
#define __MU_MSG_PRIV_H__
#if HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#ifndef MU_MSG_PRIV_HH__
#define MU_MSG_PRIV_HH__
#include <gmime/gmime.h>
#include <stdlib.h>
#include <mu-msg.h>
#include <mu-msg-file.h>
#include <mu-msg-doc.h>
#include "mu-msg-part.h"
#include <mu-msg.hh>
#include <mu-msg-file.hh>
#include <mu-msg-doc.hh>
#include "mu-msg-part.hh"
G_BEGIN_DECLS
namespace Mu {
struct _MuMsgFile {
struct MuMsgFile {
GMimeMessage *_mime_msg;
time_t _timestamp;
size_t _size;
@ -47,7 +41,7 @@ struct _MuMsgFile {
/* we put the the MuMsg definition in this separate -priv file, so we
* can split the mu_msg implementations over separate files */
struct _MuMsg {
struct MuMsg {
guint _refcount;
@ -135,6 +129,6 @@ GMimeObject* mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOpti
GError **err)
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
} // namespace Mu
#endif /*__MU_MSG_PRIV_H__*/
#endif /*MU_MSG_PRIV_HH__*/

View File

@ -19,11 +19,11 @@
#include <string.h>
#include <ctype.h>
#include "mu-query-results.hh"
#include "utils/mu-str.h"
#include "mu-msg.h"
#include "mu-msg-iter.h"
#include "mu-msg-part.h"
#include "mu-maildir.h"
#include "mu-msg.hh"
#include "mu-msg-part.hh"
#include "mu-maildir.hh"
using namespace Mu;
@ -31,7 +31,7 @@ static void
add_prop_nonempty (Sexp::List& list, const char* elm, const GSList *str_lst)
{
Sexp::List elms;
while (str_lst) {
while (str_lst) {
elms.add(Sexp::make_string((const char*)str_lst->data));
str_lst = g_slist_next(str_lst);
}
@ -43,7 +43,7 @@ add_prop_nonempty (Sexp::List& list, const char* elm, const GSList *str_lst)
static void
add_prop_nonempty (Sexp::List& list, const char* name, const char *str)
{
if (str && str[0])
if (str && str[0])
list.add_prop(name, Sexp::make_string(str));
}
@ -68,22 +68,22 @@ make_contact_sexp (MuMsgContact *c)
static void
add_list_post (Sexp::List& list, MuMsg *msg)
{
/* some mailing lists do not set the reply-to; see pull #1278. So for
* those cases, check the List-Post address and use that instead */
/* some mailing lists do not set the reply-to; see pull #1278. So for
* those cases, check the List-Post address and use that instead */
GMatchInfo *minfo;
GRegex *rx;
const char* list_post;
GMatchInfo *minfo;
GRegex *rx;
const char* list_post;
list_post = mu_msg_get_header (msg, "List-Post");
if (!list_post)
return;
list_post = mu_msg_get_header (msg, "List-Post");
if (!list_post)
return;
rx = g_regex_new ("<?mailto:([a-z0-9%+@._-]+)>?", G_REGEX_CASELESS,
rx = g_regex_new ("<?mailto:([a-z0-9%+@._-]+)>?", G_REGEX_CASELESS,
(GRegexMatchFlags)0, NULL);
g_return_if_fail(rx);
g_return_if_fail(rx);
if (g_regex_match (rx, list_post, (GRegexMatchFlags)0, &minfo)) {
if (g_regex_match (rx, list_post, (GRegexMatchFlags)0, &minfo)) {
auto address = (char*)g_match_info_fetch (minfo, 1);
MuMsgContact contact{NULL, address};
list.add_prop(":list-post",
@ -91,8 +91,8 @@ add_list_post (Sexp::List& list, MuMsg *msg)
g_free(address);
}
g_match_info_free (minfo);
g_regex_unref (rx);
g_match_info_free (minfo);
g_regex_unref (rx);
}
@ -105,28 +105,28 @@ typedef struct _ContactData ContactData;
static gboolean
each_contact (MuMsgContact *c, ContactData *cdata)
{
switch (mu_msg_contact_type (c)) {
switch (mu_msg_contact_type (c)) {
case MU_MSG_CONTACT_TYPE_FROM:
case MU_MSG_CONTACT_TYPE_FROM:
cdata->from.add(make_contact_sexp(c));
break;
case MU_MSG_CONTACT_TYPE_TO:
case MU_MSG_CONTACT_TYPE_TO:
cdata->to.add(make_contact_sexp(c));
break;
case MU_MSG_CONTACT_TYPE_CC:
break;
case MU_MSG_CONTACT_TYPE_CC:
cdata->cc.add(make_contact_sexp(c));
break;
case MU_MSG_CONTACT_TYPE_BCC:
break;
case MU_MSG_CONTACT_TYPE_BCC:
cdata->bcc.add(make_contact_sexp(c));
break;
case MU_MSG_CONTACT_TYPE_REPLY_TO:
break;
case MU_MSG_CONTACT_TYPE_REPLY_TO:
cdata->reply_to.add(make_contact_sexp(c));
break;
default:
break;
default:
g_return_val_if_reached (FALSE);
return FALSE;
}
return TRUE;
}
return TRUE;
}
static void
@ -144,9 +144,9 @@ add_prop_nonempty_list(Sexp::List& list, std::string&& name,
static void
add_contacts (Sexp::List& list, MuMsg *msg)
{
ContactData cdata{};
mu_msg_contact_foreach (msg, (MuMsgContactForeachFunc)each_contact,
&cdata);
ContactData cdata{};
mu_msg_contact_foreach (msg, (MuMsgContactForeachFunc)each_contact,
&cdata);
add_prop_nonempty_list (list, ":from", std::move(cdata.from));
add_prop_nonempty_list (list, ":to", std::move(cdata.to));
@ -159,23 +159,23 @@ add_contacts (Sexp::List& list, MuMsg *msg)
typedef struct {
Sexp::List flaglist;
MuFlags msgflags;
MuFlags msgflags;
} FlagData;
static void
each_flag (MuFlags flag, FlagData *fdata)
{
if (flag & fdata->msgflags)
if (flag & fdata->msgflags)
fdata->flaglist.add(Sexp::make_symbol(mu_flag_name(flag)));
}
static void
add_flags (Sexp::List& list, MuMsg *msg)
{
FlagData fdata{};
fdata.msgflags = mu_msg_get_flags (msg);
FlagData fdata{};
fdata.msgflags = mu_msg_get_flags (msg);
mu_flags_foreach ((MuFlagsForeachFunc)each_flag, &fdata);
mu_flags_foreach ((MuFlagsForeachFunc)each_flag, &fdata);
if (!fdata.flaglist.empty())
list.add_prop(":flags",
Sexp::make_list(std::move(fdata.flaglist)));
@ -184,24 +184,24 @@ add_flags (Sexp::List& list, MuMsg *msg)
static char*
get_temp_file (MuMsg *msg, MuMsgOptions opts, unsigned index)
{
char *path;
GError *err;
char *path;
GError *err;
err = NULL;
path = mu_msg_part_get_cache_path (msg, opts, index, &err);
if (!path)
goto errexit;
err = NULL;
path = mu_msg_part_get_cache_path (msg, opts, index, &err);
if (!path)
goto errexit;
if (!mu_msg_part_save (msg, opts, path, index, &err))
goto errexit;
if (!mu_msg_part_save (msg, opts, path, index, &err))
goto errexit;
return path;
return path;
errexit:
g_warning ("failed to save mime part: %s",
err->message ? err->message : "something went wrong");
g_clear_error (&err);
g_free (path);
g_warning ("failed to save mime part: %s",
err->message ? err->message : "something went wrong");
g_clear_error (&err);
g_free (path);
return NULL;
}
@ -209,41 +209,41 @@ errexit:
static gchar*
get_temp_file_maybe (MuMsg *msg, MuMsgPart *part, MuMsgOptions opts)
{
opts = (MuMsgOptions)((int)opts | (int)MU_MSG_OPTION_USE_EXISTING);
if (!(opts & MU_MSG_OPTION_EXTRACT_IMAGES) ||
g_ascii_strcasecmp (part->type, "image") != 0)
return NULL;
opts = (MuMsgOptions)((int)opts | (int)MU_MSG_OPTION_USE_EXISTING);
if (!(opts & MU_MSG_OPTION_EXTRACT_IMAGES) ||
g_ascii_strcasecmp (part->type, "image") != 0)
return NULL;
else
return get_temp_file (msg, opts, part->index);
}
struct PartInfo {
Sexp::List parts;
MuMsgOptions opts;
Sexp::List parts;
MuMsgOptions opts;
};
static void
sig_verdict (Sexp::List& partlist, MuMsgPart *mpart)
{
MuMsgPartSigStatusReport *report = mpart->sig_status_report;
if (!report)
return;
MuMsgPartSigStatusReport *report = mpart->sig_status_report;
if (!report)
return;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
switch (report->verdict) {
case MU_MSG_PART_SIG_STATUS_GOOD:
switch (report->verdict) {
case MU_MSG_PART_SIG_STATUS_GOOD:
partlist.add_prop(":signature", Sexp::make_symbol("verified"));
break;
case MU_MSG_PART_SIG_STATUS_BAD:
break;
case MU_MSG_PART_SIG_STATUS_BAD:
partlist.add_prop(":signature", Sexp::make_symbol("bad"));
break;
case MU_MSG_PART_SIG_STATUS_ERROR:
break;
case MU_MSG_PART_SIG_STATUS_ERROR:
partlist.add_prop(":signature", Sexp::make_symbol("unverified"));
break;
default:
break;
}
break;
default:
break;
}
#pragma GCC diagnostic pop
if (report->signers)
@ -253,7 +253,7 @@ sig_verdict (Sexp::List& partlist, MuMsgPart *mpart)
static void
dec_verdict (Sexp::List& partlist, MuMsgPart *mpart)
{
if (mpart->part_type & MU_MSG_PART_TYPE_DECRYPTED)
if (mpart->part_type & MU_MSG_PART_TYPE_DECRYPTED)
partlist.add_prop(":decryption", Sexp::make_symbol("succeeded"));
else if (mpart->part_type & MU_MSG_PART_TYPE_ENCRYPTED)
partlist.add_prop(":decryption", Sexp::make_symbol("failed"));
@ -263,21 +263,21 @@ dec_verdict (Sexp::List& partlist, MuMsgPart *mpart)
static Sexp
make_part_types (MuMsgPartType ptype)
{
struct PartTypes {
MuMsgPartType ptype;
const char* name;
} ptypes[] = {
{ MU_MSG_PART_TYPE_LEAF, "leaf" },
{ MU_MSG_PART_TYPE_MESSAGE, "message" },
{ MU_MSG_PART_TYPE_INLINE, "inline" },
{ MU_MSG_PART_TYPE_ATTACHMENT, "attachment" },
{ MU_MSG_PART_TYPE_SIGNED, "signed" },
{ MU_MSG_PART_TYPE_ENCRYPTED, "encrypted" }
};
struct PartTypes {
MuMsgPartType ptype;
const char* name;
} ptypes[] = {
{ MU_MSG_PART_TYPE_LEAF, "leaf" },
{ MU_MSG_PART_TYPE_MESSAGE, "message" },
{ MU_MSG_PART_TYPE_INLINE, "inline" },
{ MU_MSG_PART_TYPE_ATTACHMENT, "attachment" },
{ MU_MSG_PART_TYPE_SIGNED, "signed" },
{ MU_MSG_PART_TYPE_ENCRYPTED, "encrypted" }
};
Sexp::List list;
for (auto u = 0U; u!= G_N_ELEMENTS(ptypes); ++u)
if (ptype & ptypes[u].ptype)
for (auto u = 0U; u!= G_N_ELEMENTS(ptypes); ++u)
if (ptype & ptypes[u].ptype)
list.add(Sexp::make_symbol(ptypes[u].name));
return Sexp::make_list(std::move(list));
@ -298,7 +298,6 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
part->subtype ? part->subtype : "octet-stream");
auto maybe_attach = Sexp::make_symbol(mu_msg_part_maybe_attachment (part) ?
"t" : "nil");
Sexp::List partlist;
partlist.add_prop(":index", Sexp::make_number(part->index));
@ -334,31 +333,35 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
static void
add_parts (Sexp::List& items, MuMsg *msg, MuMsgOptions opts)
{
PartInfo pinfo;
pinfo.opts = opts;
PartInfo pinfo;
pinfo.opts = opts;
if (mu_msg_part_foreach (msg, opts, (MuMsgPartForeachFunc)each_part, &pinfo) &&
if (mu_msg_part_foreach (msg, opts, (MuMsgPartForeachFunc)each_part, &pinfo) &&
!pinfo.parts.empty())
items.add_prop(":parts", Sexp::make_list(std::move(pinfo.parts)));
}
static void
add_thread_info (Sexp::List& items, const MuMsgIterThreadInfo *ti)
add_thread_info (Sexp::List& items, const QueryMatch& qmatch)
{
Sexp::List info;
info.add_prop( ":path", Sexp::make_string(ti->threadpath));
info.add_prop( ":level", Sexp::make_number(ti->level));
info.add_prop(":path", Sexp::make_string(qmatch.thread_path));
info.add_prop(":level", Sexp::make_number(qmatch.thread_level));
if (ti->prop & MU_MSG_ITER_THREAD_PROP_FIRST_CHILD)
if (any_of(qmatch.flags & QueryMatch::Flags::Root))
info.add_prop( ":root", symbol_t());
if (any_of(qmatch.flags & QueryMatch::Flags::Related))
info.add_prop( ":related", symbol_t());
if (any_of(qmatch.flags & QueryMatch::Flags::First))
info.add_prop( ":first-child", symbol_t());
if (ti->prop & MU_MSG_ITER_THREAD_PROP_LAST_CHILD)
if (any_of(qmatch.flags & QueryMatch::Flags::Last))
info.add_prop( ":last-child", symbol_t());
if (ti->prop & MU_MSG_ITER_THREAD_PROP_EMPTY_PARENT)
if (any_of(qmatch.flags & QueryMatch::Flags::Orphan))
info.add_prop( ":empty-parent", symbol_t());
if (ti->prop & MU_MSG_ITER_THREAD_PROP_DUP)
if (any_of(qmatch.flags & QueryMatch::Flags::Duplicate))
info.add_prop( ":duplicate", symbol_t());
if (ti->prop & MU_MSG_ITER_THREAD_PROP_HAS_CHILD)
if (any_of(qmatch.flags & QueryMatch::Flags::HasChild))
info.add_prop( ":has-child", symbol_t());
items.add_prop(":thread", Sexp::make_list(std::move(info)));
@ -369,18 +372,18 @@ static void
add_message_file_parts (Sexp::List& items, MuMsg *msg, MuMsgOptions opts)
{
GError *err{NULL};
if (!mu_msg_load_msg_file (msg, &err)) {
g_warning ("failed to load message file: %s",
err ? err->message : "some error occurred");
g_clear_error (&err);
return;
}
if (!mu_msg_load_msg_file (msg, &err)) {
g_warning ("failed to load message file: %s",
err ? err->message : "some error occurred");
g_clear_error (&err);
return;
}
add_parts (items, msg, opts);
add_contacts (items, msg);
add_parts (items, msg, opts);
add_contacts (items, msg);
/* add the user-agent / x-mailer */
auto str = mu_msg_get_header (msg, "User-Agent");
/* add the user-agent / x-mailer */
auto str = mu_msg_get_header (msg, "User-Agent");
if (!str)
str = mu_msg_get_header (msg, "X-Mailer");
@ -396,8 +399,8 @@ static void
add_date_and_size (Sexp::List& items, MuMsg *msg)
{
auto t = mu_msg_get_date (msg);
if (t == (time_t)-1) /* invalid date? */
t = 0;
if (t == (time_t)-1) /* invalid date? */
t = 0;
Sexp::List dlist;
dlist.add(Sexp::make_number((unsigned)(t >> 16)));
@ -407,8 +410,8 @@ add_date_and_size (Sexp::List& items, MuMsg *msg)
items.add_prop(":date", Sexp::make_list(std::move(dlist)));
auto s = mu_msg_get_size (msg);
if (s == (size_t)-1) /* invalid size? */
s = 0;
if (s == (size_t)-1) /* invalid size? */
s = 0;
items.add_prop(":size", Sexp::make_number(s));
}
@ -428,64 +431,45 @@ add_tags (Sexp::List& items, MuMsg *msg)
Mu::Sexp
Mu::msg_to_sexp (MuMsg *msg, unsigned docid,
const struct _MuMsgIterThreadInfo *ti,
MuMsgOptions opts)
const Option<QueryMatch&> qm, MuMsgOptions opts)
{
g_return_val_if_fail (msg, Sexp::make_symbol("error"));
g_return_val_if_fail (!((opts & MU_MSG_OPTION_HEADERS_ONLY) &&
(opts & MU_MSG_OPTION_EXTRACT_IMAGES)),
g_return_val_if_fail (!((opts & MU_MSG_OPTION_HEADERS_ONLY) &&
(opts & MU_MSG_OPTION_EXTRACT_IMAGES)),
Sexp::make_symbol("error"));
Sexp::List items;
if (docid != 0)
items.add_prop(":docid", Sexp::make_number(docid));
if (ti)
add_thread_info (items, ti);
if (qm)
add_thread_info (items, *qm);
add_prop_nonempty (items, ":subject", mu_msg_get_subject (msg));
add_prop_nonempty (items, ":message-id", mu_msg_get_msgid (msg));
add_prop_nonempty (items, ":mailing-list", mu_msg_get_mailing_list (msg));
add_prop_nonempty (items, ":path", mu_msg_get_path (msg));
add_prop_nonempty (items, ":maildir", mu_msg_get_maildir (msg));
add_prop_nonempty (items, ":subject", mu_msg_get_subject (msg));
add_prop_nonempty (items, ":message-id", mu_msg_get_msgid (msg));
add_prop_nonempty (items, ":mailing-list", mu_msg_get_mailing_list (msg));
add_prop_nonempty (items, ":path", mu_msg_get_path (msg));
add_prop_nonempty (items, ":maildir", mu_msg_get_maildir (msg));
items.add_prop(":priority", Sexp::make_symbol(mu_msg_prio_name(mu_msg_get_prio(msg))));
/* in the no-headers-only case (see below) we get a more complete list of contacts, so no
* need to get them here if that's the case */
if (opts & MU_MSG_OPTION_HEADERS_ONLY)
add_contacts (items, msg);
/* in the no-headers-only case (see below) we get a more complete list of contacts, so no
* need to get them here if that's the case */
if (opts & MU_MSG_OPTION_HEADERS_ONLY)
add_contacts (items, msg);
add_prop_nonempty (items, ":references", mu_msg_get_references (msg));
add_prop_nonempty (items, ":in-reply-to", mu_msg_get_header (msg, "In-Reply-To"));
add_prop_nonempty (items, ":in-reply-to", mu_msg_get_header (msg, "In-Reply-To"));
add_date_and_size (items, msg);
add_date_and_size (items, msg);
add_flags (items, msg);
add_tags (items, msg);
add_tags (items, msg);
/* headers are retrieved from the database, views from the
* message file file attr things can only be gotten from the
* file (ie., mu view), not from the database (mu find). */
if (!(opts & MU_MSG_OPTION_HEADERS_ONLY))
add_message_file_parts (items, msg, opts);
/* headers are retrieved from the database, views from the
* message file file attr things can only be gotten from the
* file (ie., mu view), not from the database (mu find). */
if (!(opts & MU_MSG_OPTION_HEADERS_ONLY))
add_message_file_parts (items, msg, opts);
return Sexp::make_list(std::move(items));
}
char*
mu_msg_to_sexp (MuMsg *msg, unsigned docid, const MuMsgIterThreadInfo *ti,
MuMsgOptions opts)
{
return g_strdup (Mu::msg_to_sexp (msg, docid, ti, opts)
.to_sexp_string().c_str());
}
char*
mu_msg_to_json (MuMsg *msg, unsigned docid, const MuMsgIterThreadInfo *ti,
MuMsgOptions opts)
{
return g_strdup (Mu::msg_to_sexp (msg, docid, ti, opts)
.to_json_string().c_str());
}

View File

@ -1,5 +1,4 @@
/*
**
** Copyright (C) 2008-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify
@ -28,11 +27,13 @@
#include <gmime/gmime.h>
#include "mu-msg-priv.h" /* include before mu-msg.h */
#include "mu-msg.h"
#include "mu-msg-priv.hh" /* include before mu-msg.h */
#include "mu-msg.hh"
#include "utils/mu-str.h"
#include "mu-maildir.h"
#include "mu-maildir.hh"
using namespace Mu;
/* note, we do the gmime initialization here rather than in
* mu-runtime, because this way we don't need mu-runtime for simple
@ -64,15 +65,15 @@ msg_new (void)
{
MuMsg *self;
self = g_slice_new0 (MuMsg);
self = g_new0 (MuMsg, 1);
self->_refcount = 1;
return self;
}
MuMsg*
mu_msg_new_from_file (const char *path, const char *mdir,
GError **err)
Mu::mu_msg_new_from_file (const char *path, const char *mdir,
GError **err)
{
MuMsg *self;
MuMsgFile *msgfile;
@ -101,7 +102,7 @@ mu_msg_new_from_file (const char *path, const char *mdir,
}
MuMsg*
mu_msg_new_from_doc (XapianDocument *doc, GError **err)
Mu::mu_msg_new_from_doc (XapianDocument *doc, GError **err)
{
MuMsg *self;
MuMsgDoc *msgdoc;
@ -139,11 +140,11 @@ mu_msg_destroy (MuMsg *self)
g_slist_free (self->_free_later_lst);
}
g_slice_free (MuMsg, self);
g_free (self);
}
MuMsg*
mu_msg_ref (MuMsg *self)
Mu::mu_msg_ref (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
@ -153,7 +154,7 @@ mu_msg_ref (MuMsg *self)
}
void
mu_msg_unref (MuMsg *self)
Mu::mu_msg_unref (MuMsg *self)
{
g_return_if_fail (self);
g_return_if_fail (self->_refcount >= 1);
@ -210,7 +211,7 @@ get_path (MuMsg *self)
/* for some data, we need to read the message file from disk */
gboolean
mu_msg_load_msg_file (MuMsg *self, GError **err)
Mu::mu_msg_load_msg_file (MuMsg *self, GError **err)
{
const char *path;
@ -231,7 +232,7 @@ mu_msg_load_msg_file (MuMsg *self, GError **err)
}
void
mu_msg_unload_msg_file (MuMsg *msg)
Mu::mu_msg_unload_msg_file (MuMsg *msg)
{
g_return_if_fail (msg);
@ -303,7 +304,7 @@ get_num_field (MuMsg *self, MuMsgFieldId mfid)
}
const char*
mu_msg_get_header (MuMsg *self, const char *header)
Mu::mu_msg_get_header (MuMsg *self, const char *header)
{
GError *err;
@ -324,7 +325,7 @@ mu_msg_get_header (MuMsg *self, const char *header)
}
time_t
mu_msg_get_timestamp (MuMsg *self)
Mu::mu_msg_get_timestamp (MuMsg *self)
{
const char *path;
struct stat statbuf;
@ -342,28 +343,28 @@ mu_msg_get_timestamp (MuMsg *self)
}
const char*
mu_msg_get_path (MuMsg *self)
Mu::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)
Mu::mu_msg_get_subject (MuMsg *self)
{
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)
Mu::mu_msg_get_msgid (MuMsg *self)
{
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_MSGID);
}
const char*
mu_msg_get_mailing_list (MuMsg *self)
Mu::mu_msg_get_mailing_list (MuMsg *self)
{
const char *ml;
char *decml;
@ -382,63 +383,63 @@ mu_msg_get_mailing_list (MuMsg *self)
}
const char*
mu_msg_get_maildir (MuMsg *self)
Mu::mu_msg_get_maildir (MuMsg *self)
{
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)
Mu::mu_msg_get_from (MuMsg *self)
{
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)
Mu::mu_msg_get_to (MuMsg *self)
{
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)
Mu::mu_msg_get_cc (MuMsg *self)
{
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)
Mu::mu_msg_get_bcc (MuMsg *self)
{
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)
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);
}
MuFlags
mu_msg_get_flags (MuMsg *self)
Mu::mu_msg_get_flags (MuMsg *self)
{
g_return_val_if_fail (self, MU_FLAG_NONE);
return (MuFlags)get_num_field (self, MU_MSG_FIELD_ID_FLAGS);
}
size_t
mu_msg_get_size (MuMsg *self)
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);
}
MuMsgPrio
mu_msg_get_prio (MuMsg *self)
Mu::mu_msg_get_prio (MuMsg *self)
{
g_return_val_if_fail (self, MU_MSG_PRIO_NORMAL);
return (MuMsgPrio)get_num_field (self, MU_MSG_FIELD_ID_PRIO);
@ -517,11 +518,11 @@ find_content_type (MuMsg *msg, MuMsgPart *mpart, ContentTypeData *cdata)
if (!cdata->want_html &&
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_PLAIN))
wanted = mpart->data;
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))
wanted = mpart->data;
wanted = (GMimePart*)mpart->data;
else
wanted = NULL;
@ -569,56 +570,56 @@ get_content_type_parameters (MuMsg *self, MuMsgOptions opts, gboolean want_html)
}
const GSList*
mu_msg_get_body_text_content_type_parameters (MuMsg *self, MuMsgOptions opts)
Mu::mu_msg_get_body_text_content_type_parameters (MuMsg *self, MuMsgOptions opts)
{
g_return_val_if_fail (self, NULL);
return get_content_type_parameters(self, opts, FALSE);
}
const char*
mu_msg_get_body_html (MuMsg *self, MuMsgOptions opts)
Mu::mu_msg_get_body_html (MuMsg *self, MuMsgOptions opts)
{
g_return_val_if_fail (self, NULL);
return free_later_str (self, get_body (self, opts, TRUE));
}
const char*
mu_msg_get_body_text (MuMsg *self, MuMsgOptions opts)
Mu::mu_msg_get_body_text (MuMsg *self, MuMsgOptions opts)
{
g_return_val_if_fail (self, NULL);
return free_later_str (self, get_body (self, opts, FALSE));
}
const GSList*
mu_msg_get_references (MuMsg *self)
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);
}
const GSList*
mu_msg_get_tags (MuMsg *self)
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);
}
const char*
mu_msg_get_field_string (MuMsg *self, MuMsgFieldId mfid)
Mu::mu_msg_get_field_string (MuMsg *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, NULL);
return get_str_field (self, mfid);
}
const GSList*
mu_msg_get_field_string_list (MuMsg *self, MuMsgFieldId mfid)
Mu::mu_msg_get_field_string_list (MuMsg *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, NULL);
return get_str_list_field (self, mfid);
}
gint64
mu_msg_get_field_numeric (MuMsg *self, MuMsgFieldId mfid)
Mu::mu_msg_get_field_numeric (MuMsg *self, MuMsgFieldId mfid)
{
g_return_val_if_fail (self, -1);
return get_num_field (self, mfid);
@ -744,7 +745,7 @@ msg_contact_foreach_doc (MuMsg *msg, MuMsgContactForeachFunc func,
}
void
mu_msg_contact_foreach (MuMsg *msg, MuMsgContactForeachFunc func,
Mu::mu_msg_contact_foreach (MuMsg *msg, MuMsgContactForeachFunc func,
gpointer user_data)
{
g_return_if_fail (msg);
@ -809,7 +810,7 @@ cmp_subject (const char* s1, const char *s2)
}
int
mu_msg_cmp (MuMsg *m1, MuMsg *m2, MuMsgFieldId mfid)
Mu::mu_msg_cmp (MuMsg *m1, MuMsg *m2, MuMsgFieldId mfid)
{
g_return_val_if_fail (m1, 0);
g_return_val_if_fail (m2, 0);
@ -834,7 +835,7 @@ mu_msg_cmp (MuMsg *m1, MuMsg *m2, MuMsgFieldId mfid)
}
gboolean
mu_msg_is_readable (MuMsg *self)
Mu::mu_msg_is_readable (MuMsg *self)
{
g_return_val_if_fail (self, FALSE);
@ -903,7 +904,7 @@ get_target_mdir (MuMsg *msg, const char *target_maildir, GError **err)
* super-paranoid here...
*/
gboolean
mu_msg_move_to_maildir (MuMsg *self, const char *maildir,
Mu::mu_msg_move_to_maildir (MuMsg *self, const char *maildir,
MuFlags flags, gboolean ignore_dups,
gboolean new_name, GError **err)
{
@ -947,7 +948,7 @@ mu_msg_move_to_maildir (MuMsg *self, const char *maildir,
* some 3rd party progs such as mbsync
*/
gboolean
mu_msg_tickle (MuMsg *self, GError **err)
Mu::mu_msg_tickle (MuMsg *self, GError **err)
{
g_return_val_if_fail (self, FALSE);
@ -958,13 +959,13 @@ mu_msg_tickle (MuMsg *self, GError **err)
}
const char*
mu_str_flags_s (MuFlags flags)
Mu::mu_str_flags_s (MuFlags flags)
{
return mu_flags_to_str_s (flags, MU_FLAG_TYPE_ANY);
}
char*
mu_str_flags (MuFlags flags)
Mu::mu_str_flags (MuFlags flags)
{
return g_strdup (mu_str_flags_s(flags));
}
@ -991,7 +992,7 @@ cleanup_contact (char *contact)
/* this is still somewhat simplistic... */
const char*
mu_str_display_contact_s (const char *str)
Mu::mu_str_display_contact_s (const char *str)
{
static gchar contact[255];
gchar *c, *c2;
@ -1017,7 +1018,7 @@ mu_str_display_contact_s (const char *str)
}
char*
mu_str_display_contact (const char *str)
Mu::mu_str_display_contact (const char *str)
{
g_return_val_if_fail (str, NULL);

View File

@ -1,7 +1,5 @@
/* -*- mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
**
** Copyright (C) 2010-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
/*
** Copyright (C) 2010-2020 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
@ -19,21 +17,23 @@
**
*/
#ifndef __MU_MSG_H__
#define __MU_MSG_H__
#ifndef MU_MSG_HH__
#define MU_MSG_HH__
#include <mu-flags.h>
#include <mu-flags.hh>
#include <mu-msg-fields.h>
#include <mu-msg-prio.h>
#include <utils/mu-util.h>
#include <utils/mu-utils.hh>
#include <utils/mu-option.hh>
#include <utils/mu-sexp.hh>
G_BEGIN_DECLS
namespace Mu {
struct _MuMsg;
typedef struct _MuMsg MuMsg;
struct MuMsg;
/* options for various functions */
typedef enum {
enum MuMsgOptions {
MU_MSG_OPTION_NONE = 0,
/* 1 << 0 is still free! */
@ -59,8 +59,8 @@ typedef enum {
/* recurse into submessages */
MU_MSG_OPTION_RECURSE_RFC822 = 1 << 11
} MuMsgOptions;
};
MU_ENABLE_BITOPS(MuMsgOptions);
/**
* create a new MuMsg* instance which parses a message and provides
@ -593,26 +593,7 @@ char* mu_str_flags (MuFlags flags)
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
struct _MuMsgIterThreadInfo;
/**
* convert the msg to json
*
* @param msg a valid message
* @param docid the docid for this message, or 0
* @param ti thread info for the current message, or NULL
* @param opts, bitwise OR'ed;
* - MU_MSG_OPTION_HEADERS_ONLY: only include message fields which can be
* obtained from the database (this is much faster if the MuMsg is
* database-backed, so no file needs to be opened)
* - MU_MSG_OPTION_EXTRACT_IMAGES: extract image attachments as temporary
* files and include links to those in the sexp
*
* @return a string with the json (free with g_free) or NULL in case of error
*/
char* mu_msg_to_json (MuMsg *msg, unsigned docid,
const struct _MuMsgIterThreadInfo *ti,
MuMsgOptions ops) G_GNUC_WARN_UNUSED_RESULT;
struct QueryMatch;
/**
* convert the msg to a Lisp symbolic expression (for further processing in
@ -620,44 +601,7 @@ char* mu_msg_to_json (MuMsg *msg, unsigned docid,
*
* @param msg a valid message
* @param docid the docid for this message, or 0
* @param ti thread info for the current message, or NULL
* @param opts, bitwise OR'ed;
* - MU_MSG_OPTION_HEADERS_ONLY: only include message fields which can be
* obtained from the database (this is much faster if the MuMsg is
* database-backed, so no file needs to be opened)
* - 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_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)
*
* @return a string with the sexp (free with g_free) or NULL in case of error
*/
char* mu_msg_to_sexp (MuMsg *msg, unsigned docid,
const struct _MuMsgIterThreadInfo *ti,
MuMsgOptions ops)
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
#ifdef __cplusplus
#include <utils/mu-sexp.hh>
namespace Mu {
/**
* convert the msg to a Lisp symbolic expression (for further processing in
* e.g. emacs)
*
* @param msg a valid message
* @param docid the docid for this message, or 0
* @param ti thread info for the current message, or NULL
* @param qm information about this match
* @param opts, bitwise OR'ed;
* - MU_MSG_OPTION_HEADERS_ONLY: only include message fields which can be
* obtained from the database (this is much faster if the MuMsg is
@ -673,11 +617,8 @@ namespace Mu {
* @return a Sexp::Node representing the message
*/
Mu::Sexp msg_to_sexp (MuMsg *msg, unsigned docid,
const struct _MuMsgIterThreadInfo *ti,
const Option<QueryMatch&> qm,
MuMsgOptions ops);
}
#endif /*__cplusplus*/
#endif /*__MU_MSG_H__*/
#endif /*MU_MSG_HH__*/

View File

@ -34,13 +34,12 @@
#include <glib.h>
#include <glib/gprintf.h>
#include "mu-msg.h"
#include "mu-runtime.hh"
#include "mu-maildir.h"
#include "mu-maildir.hh"
#include "mu-query.hh"
#include "index/mu-indexer.hh"
#include "mu-store.hh"
#include "mu-msg-part.h"
#include "mu-msg-part.hh"
#include "mu-contacts.hh"
#include "utils/mu-str.h"
@ -90,7 +89,7 @@ struct Server::Private {
void output_sexp(Sexp::List&& lst) const {
output_sexp(Sexp::make_list(std::move(lst)));
}
size_t output_sexp (MuMsgIter *iter, unsigned maxnum);
size_t output_sexp (const QueryResults& qres, unsigned maxnum);
//
// handlers for various commands.
@ -359,8 +358,7 @@ Server::Private::add_handler (const Parameters& params)
path.c_str(), docid);
Sexp::List update;
update.add_prop(":update", Mu::msg_to_sexp(msg, docid, NULL,
MU_MSG_OPTION_VERIFY));
update.add_prop(":update", Mu::msg_to_sexp(msg, docid, {}, MU_MSG_OPTION_VERIFY));
output_sexp(Sexp::make_list(std::move(update)));
mu_msg_unref(msg);
}
@ -617,18 +615,17 @@ docids_for_msgid (const Query& q, const std::string& msgid, size_t max=100)
g_free(tmp);
GError *gerr{};
auto iter{q.run(expr , MU_MSG_FIELD_ID_NONE, Query::Flags::None, max)};
const auto res{q.run(expr, MU_MSG_FIELD_ID_NONE, QueryFlags::None, max)};
g_free (expr);
if (!iter)
if (!res)
throw Error(Error::Code::Store, &gerr, "failed to run msgid-query");
if (mu_msg_iter_is_done (iter))
else if (res->empty())
throw Error(Error::Code::NotFound,
"could not find message(s) for msgid %s", msgid.c_str());
std::vector<DocId> docids;
do {
docids.emplace_back(mu_msg_iter_get_docid (iter));
} while (mu_msg_iter_next (iter));
mu_msg_iter_destroy (iter);
"could not find message(s) for msgid %s", msgid.c_str());
std::vector<DocId> docids{};
for(auto&& mi: *res)
docids.emplace_back(mi.doc_id());
return docids;
}
@ -676,24 +673,23 @@ determine_docids (const Query& q, const Parameters& params)
size_t
Server::Private::output_sexp (MuMsgIter *iter, unsigned maxnum)
Server::Private::output_sexp (const QueryResults& qres, unsigned maxnum)
{
size_t n{};
while (!mu_msg_iter_is_done (iter) && n < maxnum) {
for (auto&& mi: qres) {
MuMsg *msg;
msg = mu_msg_iter_get_msg_floating (iter);
if (n >= maxnum)
break;
++n;
auto msg{mi.floating_msg()};
if (!msg)
continue;
if (mu_msg_is_readable (msg)) {
const MuMsgIterThreadInfo* ti;
ti = mu_msg_iter_get_thread_info (iter);
output_sexp(Mu::msg_to_sexp(msg,
mu_msg_iter_get_docid (iter),
ti, MU_MSG_OPTION_HEADERS_ONLY));
++n;
}
mu_msg_iter_next (iter);
auto qm{mi.query_match()};
output_sexp(Mu::msg_to_sexp(msg, mi.doc_id(),
qm, MU_MSG_OPTION_HEADERS_ONLY));
}
return n;
}
@ -718,20 +714,19 @@ Server::Private::find_handler (const Parameters& params)
sortfieldstr.c_str()};
}
auto qflags{Query::Flags::None};
auto qflags{QueryFlags::None};
if (descending)
qflags |= Query::Flags::Descending;
qflags |= QueryFlags::Descending;
if (skip_dups)
qflags |= Query::Flags::SkipDups;
qflags |= QueryFlags::SkipDuplicates;
if (include_related)
qflags |= Query::Flags::IncludeRelated;
qflags |= QueryFlags::IncludeRelated;
if (threads)
qflags |= Query::Flags::Threading;
qflags |= QueryFlags::Threading;
GError *gerr{};
auto miter{query().run(q, sort_field, qflags, maxnum, &gerr)};
if (!miter)
throw Error(Error::Code::Query, &gerr, "failed to run query");
auto qres{query().run(q, sort_field, qflags, maxnum)};
if (!qres)
throw Error(Error::Code::Query, "failed to run query");
/* before sending new results, send an 'erase' message, so the frontend
* knows it should erase the headers buffer. this will ensure that the
@ -743,16 +738,13 @@ Server::Private::find_handler (const Parameters& params)
}
{
const auto foundnum{output_sexp (miter, maxnum)};
const auto foundnum{output_sexp (*qres, maxnum)};
Sexp::List lst;
lst.add_prop(":found", Sexp::make_number(foundnum));
output_sexp(std::move(lst));
}
//output_sexp ("(:found %u)", foundnum);
mu_msg_iter_destroy (miter);
}
void
Server::Private::help_handler (const Parameters& params)
{
@ -886,7 +878,7 @@ perform_move (Store& store, DocId docid, MuMsg *msg, const std::string& maildira
throw Error{Error::Code::Store, "failed to store updated message"};
Sexp::List seq;
seq.add_prop(":update", msg_to_sexp (msg, docid, NULL, MU_MSG_OPTION_VERIFY));
seq.add_prop(":update", msg_to_sexp (msg, docid, {}, MU_MSG_OPTION_VERIFY));
/* note, the :move t thing is a hint to the frontend that it
* could remove the particular header */
if (different_mdir)

View File

@ -38,7 +38,7 @@
#include "utils/mu-str.h"
#include "utils/mu-error.hh"
#include "mu-msg-part.h"
#include "mu-msg-part.hh"
#include "utils/mu-utils.hh"
using namespace Mu;
@ -425,7 +425,7 @@ Store::remove_message (const std::string& path)
try {
const std::string term{(get_uid_term(path.c_str()))};
priv()->writable_db().delete_document(term);
priv_->writable_db().delete_document(term);
} MU_XAPIAN_CATCH_BLOCK_RETURN (false);
@ -443,7 +443,7 @@ Store::remove_messages (const std::vector<Store::Id>& ids)
try {
for (auto&& id: ids) {
priv()->writable_db().delete_document(id);
priv_->writable_db().delete_document(id);
priv_->dirty();
}

View File

@ -20,7 +20,7 @@
#ifndef __MU_STORE_HH__
#define __MU_STORE_HH__
#include <mu-msg.h>
#include <mu-msg.hh>
#ifdef __cplusplus
@ -52,7 +52,6 @@ public:
*/
Store (const std::string& path, bool readonly=true);
struct Config {
size_t max_message_size{};
/**< maximum size (in bytes) for a message, or 0 for default */
@ -121,8 +120,8 @@ public:
/**
* Get the Indexer associated with this store. It is an error
* to call this on a read-only store.
* Get the Indexer associated with this store. It is an error to call
* this on a read-only store.
*
* @return the indexer.
*/
@ -143,7 +142,7 @@ public:
* @param msg a message
* @param id the id for this message
*
* @return false in case of failure; true ottherwise.
* @return false in case of failure; true otherwise.
*/
bool update_message (MuMsg *msg, Id id);

View File

@ -1,6 +1,5 @@
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
/*
** Copyright (C) 2008-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2020 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
@ -23,9 +22,10 @@
#endif /*HAVE_CONFIG_H*/
#include <glib.h>
#include "mu-flags.h"
#include "mu-flags.hh"
#include "test-mu-common.hh"
using namespace Mu;
static void
test_mu_flag_char (void)

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2008-2016 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2020 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
@ -29,9 +29,10 @@
#include <string.h>
#include "test-mu-common.hh"
#include "mu-maildir.h"
#include "mu-maildir.hh"
#include "utils/mu-util.h"
using namespace Mu;
static void
test_mu_maildir_mkdir_01 (void)

View File

@ -29,9 +29,11 @@
#include <locale.h>
#include "test-mu-common.hh"
#include "mu-msg.h"
#include "mu-msg.hh"
#include "utils/mu-str.h"
using namespace Mu;
static MuMsg*
get_msg (const char *path)

View File

@ -21,7 +21,6 @@
#ifndef MU_SEXP_HH__
#define MU_SEXP_HH__
#include <iterator>
#include <string>
#include <vector>
#include <type_traits>