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-threader
/lib/test-mu-tokenizer /lib/test-mu-tokenizer
/lib/test-mu-parser /lib/test-mu-parser
/lib/test-mu-query-threader

View File

@ -63,13 +63,16 @@ libmu_la_SOURCES= \
mu-bookmarks.hh \ mu-bookmarks.hh \
mu-contacts.cc \ mu-contacts.cc \
mu-contacts.hh \ mu-contacts.hh \
mu-container.cc \
mu-container.hh \
mu-data.hh \ mu-data.hh \
mu-parser.cc \ mu-parser.cc \
mu-parser.hh \ mu-parser.hh \
mu-query.cc \ mu-query.cc \
mu-query.hh \ 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.cc \
mu-runtime.hh \ mu-runtime.hh \
mu-script.cc \ mu-script.cc \
@ -78,34 +81,30 @@ libmu_la_SOURCES= \
mu-server.hh \ mu-server.hh \
mu-store.cc \ mu-store.cc \
mu-store.hh \ mu-store.hh \
mu-threader.cc \
mu-threader.hh \
mu-tokenizer.cc \ mu-tokenizer.cc \
mu-tokenizer.hh \ mu-tokenizer.hh \
mu-tree.hh \ mu-tree.hh \
mu-xapian.cc \ mu-xapian.cc \
mu-xapian.hh \ mu-xapian.hh \
mu-flags.c \ mu-maildir.cc \
mu-maildir.c \ mu-maildir.hh \
mu-maildir.h \ mu-flags.cc \
mu-flags.h \ mu-flags.hh \
mu-msg-crypto.c \ mu-msg-crypto.cc \
mu-msg-doc.cc \ mu-msg-doc.cc \
mu-msg-doc.h \ mu-msg-doc.hh \
mu-msg-fields.c \ mu-msg-fields.c \
mu-msg-fields.h \ mu-msg-fields.h \
mu-msg-file.c \ mu-msg-file.cc \
mu-msg-file.h \ mu-msg-file.hh \
mu-msg-iter.cc \ mu-msg-part.cc \
mu-msg-iter.h \ mu-msg-part.hh \
mu-msg-part.c \
mu-msg-part.h \
mu-msg-prio.c \ mu-msg-prio.c \
mu-msg-prio.h \ mu-msg-prio.h \
mu-msg-priv.h \ mu-msg-priv.hh \
mu-msg-sexp.cc \ mu-msg-sexp.cc \
mu-msg.c \ mu-msg.cc \
mu-msg.h mu-msg.hh
libmu_la_LIBADD= \ libmu_la_LIBADD= \
$(XAPIAN_LIBS) \ $(XAPIAN_LIBS) \
@ -130,7 +129,6 @@ tokenize_LDADD= \
utils/libmu-utils.la utils/libmu-utils.la
EXTRA_DIST= \ EXTRA_DIST= \
mu-msg-crypto.c \
doxyfile.in doxyfile.in
noinst_PROGRAMS+=$(TEST_PROGS) noinst_PROGRAMS+=$(TEST_PROGS)
@ -154,14 +152,14 @@ TEST_PROGS += test-mu-store
test_mu_store_SOURCES= test-mu-store.cc test_mu_store_SOURCES= test-mu-store.cc
test_mu_store_LDADD= libtestmucommon.la 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_PROGS += test-mu-flags
test_mu_flags_SOURCES= test-mu-flags.cc test_mu_flags_SOURCES= test-mu-flags.cc
test_mu_flags_LDADD= libtestmucommon.la 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_PROGS += test-mu-contacts
test_mu_contacts_SOURCES= test-mu-contacts.cc test_mu_contacts_SOURCES= test-mu-contacts.cc
test_mu_contacts_LDADD= libtestmucommon.la 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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -18,15 +18,16 @@
*/ */
#include <string.h> #include <string.h>
#include "mu-flags.h" #include "mu-flags.hh"
struct _FlagInfo { using namespace Mu;
struct FlagInfo {
MuFlags flag; MuFlags flag;
char kar; char kar;
const char *name; const char *name;
MuFlagType flag_type; MuFlagType flag_type;
}; };
typedef struct _FlagInfo FlagInfo;
static const FlagInfo FLAG_INFO[] = { static const FlagInfo FLAG_INFO[] = {
@ -53,7 +54,7 @@ static const FlagInfo FLAG_INFO[] = {
MuFlagType MuFlagType
mu_flag_type (MuFlags flag) Mu::mu_flag_type (MuFlags flag)
{ {
unsigned u; unsigned u;
@ -66,7 +67,7 @@ mu_flag_type (MuFlags flag)
char char
mu_flag_char (MuFlags flag) Mu::mu_flag_char (MuFlags flag)
{ {
unsigned u; unsigned u;
@ -78,7 +79,7 @@ mu_flag_char (MuFlags flag)
MuFlags MuFlags
mu_flag_char_from_name (const char *str) Mu::mu_flag_char_from_name (const char *str)
{ {
unsigned u; unsigned u;
@ -86,9 +87,9 @@ mu_flag_char_from_name (const char *str)
for (u = 0; u != G_N_ELEMENTS (FLAG_INFO); ++u) for (u = 0; u != G_N_ELEMENTS (FLAG_INFO); ++u)
if (g_strcmp0(FLAG_INFO[u].name, str) == 0) 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* const char*
mu_flag_name (MuFlags flag) Mu::mu_flag_name (MuFlags flag)
{ {
unsigned u; unsigned u;
@ -119,7 +120,7 @@ mu_flag_name (MuFlags flag)
const char* const char*
mu_flags_to_str_s (MuFlags flags, MuFlagType types) Mu::mu_flags_to_str_s (MuFlags flags, MuFlagType types)
{ {
unsigned u,v; unsigned u,v;
static char str[sizeof(FLAG_INFO) + 1]; static char str[sizeof(FLAG_INFO) + 1];
@ -135,7 +136,7 @@ mu_flags_to_str_s (MuFlags flags, MuFlagType types)
MuFlags MuFlags
mu_flags_from_str (const char *str, MuFlagType types, Mu::mu_flags_from_str (const char *str, MuFlagType types,
gboolean ignore_invalid) gboolean ignore_invalid)
{ {
const char *cur; const char *cur;
@ -165,7 +166,7 @@ mu_flags_from_str (const char *str, MuFlagType types,
char* char*
mu_flags_custom_from_str (const char *str) Mu::mu_flags_custom_from_str (const char *str)
{ {
char *custom; char *custom;
const char* cur; const char* cur;
@ -195,7 +196,7 @@ mu_flags_custom_from_str (const char *str)
void void
mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data) Mu::mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data)
{ {
unsigned u; unsigned u;
@ -207,7 +208,7 @@ mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data)
MuFlags MuFlags
mu_flags_from_str_delta (const char *str, MuFlags oldflags, Mu::mu_flags_from_str_delta (const char *str, MuFlags oldflags,
MuFlagType types) MuFlagType types)
{ {
const char *cur; 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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -18,14 +18,15 @@
*/ */
#ifndef __MU_FLAGS_H__ #ifndef MU_FLAGS_HH__
#define __MU_FLAGS_H__ #define MU_FLAGS_HH__
#include <glib.h> #include <glib.h>
#include <utils/mu-utils.hh>
G_BEGIN_DECLS namespace Mu {
enum _MuFlags { enum MuFlags {
MU_FLAG_NONE = 0, MU_FLAG_NONE = 0,
/* next 6 are seen in the file-info part of maildir message /* next 6 are seen in the file-info part of maildir message
@ -56,17 +57,18 @@ enum _MuFlags {
/* other content flags */ /* other content flags */
MU_FLAG_LIST = 1 << 11 MU_FLAG_LIST = 1 << 11
}; };
typedef enum _MuFlags MuFlags; MU_ENABLE_BITOPS(MuFlags);
#define MU_FLAG_INVALID ((MuFlags)-1) #define MU_FLAG_INVALID ((MuFlags)-1)
enum _MuFlagType { enum MuFlagType {
MU_FLAG_TYPE_MAILFILE = 1 << 0, MU_FLAG_TYPE_MAILFILE = 1 << 0,
MU_FLAG_TYPE_MAILDIR = 1 << 1, MU_FLAG_TYPE_MAILDIR = 1 << 1,
MU_FLAG_TYPE_CONTENT = 1 << 2, MU_FLAG_TYPE_CONTENT = 1 << 2,
MU_FLAG_TYPE_PSEUDO = 1 << 3 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_ANY ((MuFlagType)-1)
#define MU_FLAG_TYPE_INVALID ((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); void mu_flags_foreach (MuFlagsForeachFunc func, gpointer user_data);
G_END_DECLS } // namespace Mu
#endif /*__MU_FLAGS_H__*/ #endif /*__MU_FLAGS_H__*/

View File

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

View File

@ -17,18 +17,16 @@
** **
*/ */
#ifndef __MU_MAILDIR_H__ #ifndef MU_MAILDIR_HH__
#define __MU_MAILDIR_H__ #define MU_MAILDIR_HH__
#include <glib.h> #include <glib.h>
#include <time.h> #include <time.h>
#include <sys/types.h> /* for mode_t */ #include <sys/types.h> /* for mode_t */
#include <utils/mu-util.h> #include <utils/mu-util.h>
#include <mu-flags.h> #include <mu-flags.hh>
G_BEGIN_DECLS
namespace Mu {
/** /**
* create a new maildir. if parts of the maildir already exists, those * 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 * 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) gboolean new_name, GError **err)
G_GNUC_WARN_UNUSED_RESULT; 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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -17,24 +17,25 @@
** **
*/ */
#if HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <string.h> #include <string.h>
#include "mu-msg.h" #include "mu-msg.hh"
#include "mu-msg-priv.h" #include "mu-msg-priv.hh"
#include "mu-msg-part.h" #include "mu-msg-part.hh"
#include "utils/mu-date.h" #include "utils/mu-date.h"
#include <gmime/gmime.h> #include <gmime/gmime.h>
#include <gmime/gmime-multipart-signed.h> #include <gmime/gmime-multipart-signed.h>
using namespace Mu;
static const char* static const char*
get_pubkey_algo_name (GMimePubKeyAlgo algo) get_pubkey_algo_name (GMimePubKeyAlgo algo)
{ {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
switch (algo) { switch (algo) {
case GMIME_PUBKEY_ALGO_DEFAULT: case GMIME_PUBKEY_ALGO_DEFAULT:
return "default"; return "default";
@ -53,11 +54,15 @@ get_pubkey_algo_name (GMimePubKeyAlgo algo)
default: default:
return "unknown pubkey algorithm"; return "unknown pubkey algorithm";
} }
#pragma GCC diagnostic pop
} }
static const gchar* static const gchar*
get_digestkey_algo_name (GMimeDigestAlgo algo) get_digestkey_algo_name (GMimeDigestAlgo algo)
{ {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
switch (algo) { switch (algo) {
case GMIME_DIGEST_ALGO_DEFAULT: case GMIME_DIGEST_ALGO_DEFAULT:
return "default"; return "default";
@ -86,6 +91,7 @@ get_digestkey_algo_name (GMimeDigestAlgo algo)
default: default:
return "unknown digest algorithm"; return "unknown digest algorithm";
} }
#pragma GCC diagnostic pop
} }
@ -196,16 +202,17 @@ get_verdict_report (GMimeSignature *msig)
static char* static char*
get_signers (GHashTable *signerhash) get_signers (GHashTable *signerhash)
{ {
GString *gstr; GString *gstr;
GHashTableIter iter; GHashTableIter iter;
const char *name; char *name;
if (!signerhash || g_hash_table_size(signerhash) == 0) if (!signerhash || g_hash_table_size(signerhash) == 0)
return NULL; return NULL;
gstr = g_string_new (NULL); gstr = g_string_new (NULL);
g_hash_table_iter_init (&iter, signerhash); 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) if (gstr->len != 0)
g_string_append_c (gstr, ','); g_string_append_c (gstr, ',');
gstr = g_string_append (gstr, name); gstr = g_string_append (gstr, name);
@ -272,7 +279,7 @@ get_status_report (GMimeSignatureList *sigs)
} }
void void
mu_msg_part_sig_status_report_destroy (MuMsgPartSigStatusReport *report) Mu::mu_msg_part_sig_status_report_destroy (MuMsgPartSigStatusReport *report)
{ {
if (!report) if (!report)
return; return;
@ -295,7 +302,7 @@ tag_with_sig_status(GObject *part,
void void
mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts, Mu::mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts,
GError **err) GError **err)
{ {
/* the signature status */ /* the signature status */
@ -349,7 +356,7 @@ check_decrypt_result(GMimeMultipartEncrypted *part, GMimeDecryptResult *res,
GMimeObject* /* this is declared in mu-msg-priv.h */ 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, MuMsgPartPasswordFunc func, gpointer user_data,
GError **err) 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 ** 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 ** it under the terms of the GNU General Public License as published by
@ -24,17 +24,18 @@
#include <xapian.h> #include <xapian.h>
#include "mu-msg-fields.h" #include "mu-msg-fields.h"
#include "mu-msg-doc.h" #include "mu-msg-doc.hh"
#include "utils/mu-util.h" #include "utils/mu-util.h"
#include "utils/mu-str.h" #include "utils/mu-str.h"
#include "utils/mu-date.h" #include "utils/mu-date.h"
#include "utils/mu-utils.hh" #include "utils/mu-utils.hh"
struct _MuMsgDoc { using namespace Mu;
_MuMsgDoc (Xapian::Document *doc): _doc (doc) { } struct Mu::MuMsgDoc {
~_MuMsgDoc () { delete _doc; } MuMsgDoc (Xapian::Document *doc): _doc (doc) { }
~MuMsgDoc () { delete _doc; }
const Xapian::Document doc() const { return *_doc; } const Xapian::Document doc() const { return *_doc; }
private: private:
Xapian::Document *_doc; Xapian::Document *_doc;
@ -42,7 +43,7 @@ private:
MuMsgDoc* 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); g_return_val_if_fail (doc, NULL);
@ -55,7 +56,7 @@ mu_msg_doc_new (XapianDocument *doc, GError **err)
} }
void void
mu_msg_doc_destroy (MuMsgDoc *self) Mu::mu_msg_doc_destroy (MuMsgDoc *self)
{ {
try { try {
delete self; delete self;
@ -65,7 +66,7 @@ mu_msg_doc_destroy (MuMsgDoc *self)
gchar* 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 (self, NULL);
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), 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* 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 (self, NULL);
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), 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 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 (self, -1);
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), -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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -17,16 +17,16 @@
** **
*/ */
#ifndef __MU_MSG_DOC_H__ #ifndef MU_MSG_DOC_HH__
#define __MU_MSG_DOC_H__ #define MU_MSG_DOC_HH__
#include <glib.h> #include <glib.h>
#include <utils/mu-util.h> #include <utils/mu-util.h>
G_BEGIN_DECLS
struct _MuMsgDoc; namespace Mu {
typedef struct _MuMsgDoc MuMsgDoc;
struct MuMsgDoc;
/** /**
* create a new MuMsgDoc instance * 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); gint64 mu_msg_doc_get_num_field (MuMsgDoc *self, MuMsgFieldId mfid);
} // namespace Mu
G_END_DECLS #endif /*MU_MSG_DOC_HH__*/
#endif /*__MU_MSG_DOC_H__*/

View File

@ -27,25 +27,27 @@
#include <inttypes.h> #include <inttypes.h>
#include <gmime/gmime.h> #include <gmime/gmime.h>
#include "mu-maildir.h" #include "mu-maildir.hh"
#include "mu-store.hh" #include "mu-store.hh"
#include "mu-msg-priv.h" #include "mu-msg-priv.hh"
#include "utils/mu-util.h" #include "utils/mu-util.h"
#include "utils/mu-str.h" #include "utils/mu-str.h"
using namespace Mu;
static gboolean init_file_metadata (MuMsgFile *self, const char* path, static gboolean init_file_metadata (MuMsgFile *self, const char* path,
const char *mdir, GError **err); const char *mdir, GError **err);
static gboolean init_mime_msg (MuMsgFile *msg, const char *path, GError **err); static gboolean init_mime_msg (MuMsgFile *msg, const char *path, GError **err);
MuMsgFile* 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; MuMsgFile *self;
g_return_val_if_fail (filepath, NULL); 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)) { if (!init_file_metadata (self, filepath, mdir, err)) {
mu_msg_file_destroy (self); mu_msg_file_destroy (self);
@ -61,18 +63,17 @@ mu_msg_file_new (const char* filepath, const char *mdir, GError **err)
} }
void void
mu_msg_file_destroy (MuMsgFile *self) Mu::mu_msg_file_destroy (MuMsgFile *self)
{ {
if (!self) if (!self)
return; return;
if (self->_mime_msg) g_clear_object(&self->_mime_msg);
g_object_unref (self->_mime_msg);
g_free(self->_path); g_free(self->_path);
g_free(self->_maildir); g_free(self->_maildir);
g_slice_free (MuMsgFile, self); g_free (self);
} }
static gboolean static gboolean
@ -477,7 +478,7 @@ stream_to_string (GMimeStream *stream, size_t buflen)
} }
gchar* gchar*
mu_msg_mime_part_to_string (GMimePart *part, gboolean *err) Mu::mu_msg_mime_part_to_string (GMimePart *part, gboolean *err)
{ {
GMimeDataWrapper *wrapper; GMimeDataWrapper *wrapper;
GMimeStream *stream; 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_CC : return GMIME_ADDRESS_TYPE_CC;
case MU_MSG_FIELD_ID_TO : return GMIME_ADDRESS_TYPE_TO; case MU_MSG_FIELD_ID_TO : return GMIME_ADDRESS_TYPE_TO;
case MU_MSG_FIELD_ID_FROM: return GMIME_ADDRESS_TYPE_FROM; 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* 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) gboolean *do_free)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
@ -705,7 +706,7 @@ mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid,
} }
GSList* 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 (self, NULL);
g_return_val_if_fail (mu_msg_field_is_string_list(mfid), 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 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 (self, -1);
g_return_val_if_fail (mu_msg_field_is_numeric(mfid), -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* 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; const gchar *hdr;
@ -797,8 +798,8 @@ foreach_cb (GMimeObject *parent, GMimeObject *part, ForeachData *fdata)
} }
void void
mu_mime_message_foreach (GMimeMessage *msg, gboolean decrypt, Mu::mu_mime_message_foreach (GMimeMessage *msg, gboolean decrypt,
GMimeObjectForeachFunc func, gpointer user_data) GMimeObjectForeachFunc func, gpointer user_data)
{ {
ForeachData fdata; 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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -19,11 +17,12 @@
** **
*/ */
#ifndef __MU_MSG_FILE_H__ #ifndef MU_MSG_FILE_HH__
#define __MU_MSG_FILE_H__ #define MU_MSG_FILE_HH__
struct _MuMsgFile; namespace Mu {
typedef struct _MuMsgFile MuMsgFile;
struct MuMsgFile;
/** /**
* create a new message from a file * 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); 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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -18,17 +17,18 @@
** **
*/ */
#if HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "mu-msg.hh"
#include "utils/mu-util.h" #include "utils/mu-util.h"
#include "utils/mu-str.h" #include "utils/mu-str.h"
#include "mu-msg-priv.h" #include "mu-msg-priv.hh"
#include "mu-msg-part.h" #include "mu-msg-part.hh"
using namespace Mu;
struct _DoData { struct _DoData {
GMimeObject *mime_obj; GMimeObject *mime_obj;
@ -60,7 +60,7 @@ get_mime_object_at_index (MuMsg *msg, MuMsgOptions opts, unsigned index)
ddata.index = index; ddata.index = index;
/* wipe out some irrelevant options */ /* wipe out some irrelevant options */
opts &= ~MU_MSG_OPTION_VERIFY; opts &= (MuMsgOptions)~MU_MSG_OPTION_VERIFY;
opts &= ~MU_MSG_OPTION_EXTRACT_IMAGES; opts &= ~MU_MSG_OPTION_EXTRACT_IMAGES;
mu_msg_part_foreach (msg, opts, mu_msg_part_foreach (msg, opts,
@ -192,7 +192,7 @@ get_text_from_mime_msg (MuMsg *msg, GMimeMessage *mmsg, MuMsgOptions opts)
char* 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; GMimeObject *mobj;
GMimeMessage *mime_msg; GMimeMessage *mime_msg;
@ -336,7 +336,7 @@ mime_part_get_filename (GMimeObject *mobj, unsigned index,
char* 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 (mpart, NULL);
g_return_val_if_fail (GMIME_IS_OBJECT(mpart->data), 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* 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 (mpart, NULL);
g_return_val_if_fail (GMIME_IS_OBJECT(mpart->data), 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; MuMsgPartSigStatusReport *report, *copy;
report = g_object_get_data (obj, SIG_STATUS_REPORT); report = (MuMsgPartSigStatusReport*)
g_object_get_data (obj, SIG_STATUS_REPORT);
if (!report) if (!report)
return NULL; /* nothing to copy */ return NULL; /* nothing to copy */
@ -661,7 +662,7 @@ handle_mime_object (MuMsg *msg, GMimeObject *mobj, GMimeObject *parent,
gboolean gboolean
mu_msg_part_foreach (MuMsg *msg, MuMsgOptions opts, Mu::mu_msg_part_foreach (MuMsg *msg, MuMsgOptions opts,
MuMsgPartForeachFunc func, gpointer user_data) MuMsgPartForeachFunc func, gpointer user_data)
{ {
unsigned index; unsigned index;
@ -788,8 +789,8 @@ save_object (GMimeObject *obj, MuMsgOptions opts, const char *fullpath,
gchar* gchar*
mu_msg_part_get_path (MuMsg *msg, MuMsgOptions opts, Mu::mu_msg_part_get_path (MuMsg *msg, MuMsgOptions opts,
const char* targetdir, unsigned index, GError **err) const char* targetdir, unsigned index, GError **err)
{ {
char *fname, *filepath; char *fname, *filepath;
GMimeObject* mobj; GMimeObject* mobj;
@ -821,7 +822,7 @@ mu_msg_part_get_path (MuMsg *msg, MuMsgOptions opts,
gchar* 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) GError **err)
{ {
char *dirname, *filepath; char *dirname, *filepath;
@ -856,7 +857,7 @@ mu_msg_part_get_cache_path (MuMsg *msg, MuMsgOptions opts, guint partid,
gboolean 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) const char *fullpath, guint partidx, GError **err)
{ {
gboolean rv; gboolean rv;
@ -897,7 +898,7 @@ mu_msg_part_save (MuMsg *msg, MuMsgOptions opts,
gchar* 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) GError **err)
{ {
gchar *filepath; gchar *filepath;
@ -925,7 +926,7 @@ match_cid (MuMsgPart *mpart, const char *cid)
} }
int 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 *sought_cid)
{ {
const char* cid; const char* cid;
@ -961,7 +962,7 @@ match_filename_rx (MuMsg *msg, MuMsgPart *mpart, RxMatchData *mdata)
if (!fname) if (!fname)
return; 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, mdata->_lst = g_slist_prepend (mdata->_lst,
GUINT_TO_POINTER(mpart->index)); GUINT_TO_POINTER(mpart->index));
g_free (fname); g_free (fname);
@ -969,7 +970,7 @@ match_filename_rx (MuMsg *msg, MuMsgPart *mpart, RxMatchData *mdata)
GSList* 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; RxMatchData mdata;
@ -991,7 +992,7 @@ mu_msg_find_files (MuMsg *msg, MuMsgOptions opts, const GRegex *pattern)
gboolean gboolean
mu_msg_part_maybe_attachment (MuMsgPart *part) Mu::mu_msg_part_maybe_attachment (MuMsgPart *part)
{ {
g_return_val_if_fail (part, FALSE); 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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -19,17 +17,18 @@
** **
*/ */
#ifndef __MU_MSG_PART_H__ #ifndef MU_MSG_PART_HH__
#define __MU_MSG_PART_H__ #define MU_MSG_PART_HH__
#include "utils/mu-utils.hh"
#include <glib.h> #include <glib.h>
#include <unistd.h> /* for ssize_t */ #include <unistd.h> /* for ssize_t */
namespace Mu {
#define SIG_STATUS_REPORT "sig-status-report" #define SIG_STATUS_REPORT "sig-status-report"
G_BEGIN_DECLS enum MuMsgPartType {
enum _MuMsgPartType {
MU_MSG_PART_TYPE_NONE = 0, MU_MSG_PART_TYPE_NONE = 0,
/* MIME part without children */ /* MIME part without children */
@ -51,8 +50,7 @@ enum _MuMsgPartType {
/* a text/html part? */ /* a text/html part? */
MU_MSG_PART_TYPE_TEXT_HTML = 1 << 9 MU_MSG_PART_TYPE_TEXT_HTML = 1 << 9
}; };
typedef enum _MuMsgPartType MuMsgPartType; MU_ENABLE_BITOPS(MuMsgPartType);
/* the signature status */ /* the signature status */
enum _MuMsgPartSigStatus { enum _MuMsgPartSigStatus {
@ -113,7 +111,6 @@ typedef struct _MuMsgPart MuMsgPart;
char *mu_msg_part_get_filename (MuMsgPart *mpart, gboolean construct_if_needed) char *mu_msg_part_get_filename (MuMsgPart *mpart, gboolean construct_if_needed)
G_GNUC_WARN_UNUSED_RESULT; G_GNUC_WARN_UNUSED_RESULT;
/** /**
* get appropriate content id for the mime-part * 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, gboolean mu_msg_part_foreach (MuMsg *msg, MuMsgOptions opts,
MuMsgPartForeachFunc func, gpointer user_data); 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 ** 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 ** it under the terms of the GNU General Public License as published by
@ -19,24 +17,20 @@
** **
*/ */
#ifndef __MU_MSG_PRIV_H__ #ifndef MU_MSG_PRIV_HH__
#define __MU_MSG_PRIV_H__ #define MU_MSG_PRIV_HH__
#if HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <gmime/gmime.h> #include <gmime/gmime.h>
#include <stdlib.h> #include <stdlib.h>
#include <mu-msg.h> #include <mu-msg.hh>
#include <mu-msg-file.h> #include <mu-msg-file.hh>
#include <mu-msg-doc.h> #include <mu-msg-doc.hh>
#include "mu-msg-part.h" #include "mu-msg-part.hh"
G_BEGIN_DECLS namespace Mu {
struct _MuMsgFile { struct MuMsgFile {
GMimeMessage *_mime_msg; GMimeMessage *_mime_msg;
time_t _timestamp; time_t _timestamp;
size_t _size; size_t _size;
@ -47,7 +41,7 @@ struct _MuMsgFile {
/* we put the the MuMsg definition in this separate -priv file, so we /* we put the the MuMsg definition in this separate -priv file, so we
* can split the mu_msg implementations over separate files */ * can split the mu_msg implementations over separate files */
struct _MuMsg { struct MuMsg {
guint _refcount; guint _refcount;
@ -135,6 +129,6 @@ GMimeObject* mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOpti
GError **err) GError **err)
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; 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 <string.h>
#include <ctype.h> #include <ctype.h>
#include "mu-query-results.hh"
#include "utils/mu-str.h" #include "utils/mu-str.h"
#include "mu-msg.h" #include "mu-msg.hh"
#include "mu-msg-iter.h" #include "mu-msg-part.hh"
#include "mu-msg-part.h" #include "mu-maildir.hh"
#include "mu-maildir.h"
using namespace Mu; using namespace Mu;
@ -31,7 +31,7 @@ static void
add_prop_nonempty (Sexp::List& list, const char* elm, const GSList *str_lst) add_prop_nonempty (Sexp::List& list, const char* elm, const GSList *str_lst)
{ {
Sexp::List elms; Sexp::List elms;
while (str_lst) { while (str_lst) {
elms.add(Sexp::make_string((const char*)str_lst->data)); elms.add(Sexp::make_string((const char*)str_lst->data));
str_lst = g_slist_next(str_lst); 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 static void
add_prop_nonempty (Sexp::List& list, const char* name, const char *str) 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)); list.add_prop(name, Sexp::make_string(str));
} }
@ -68,22 +68,22 @@ make_contact_sexp (MuMsgContact *c)
static void static void
add_list_post (Sexp::List& list, MuMsg *msg) add_list_post (Sexp::List& list, MuMsg *msg)
{ {
/* some mailing lists do not set the reply-to; see pull #1278. So for /* 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 */ * those cases, check the List-Post address and use that instead */
GMatchInfo *minfo; GMatchInfo *minfo;
GRegex *rx; GRegex *rx;
const char* list_post; const char* list_post;
list_post = mu_msg_get_header (msg, "List-Post"); list_post = mu_msg_get_header (msg, "List-Post");
if (!list_post) if (!list_post)
return; 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); (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); auto address = (char*)g_match_info_fetch (minfo, 1);
MuMsgContact contact{NULL, address}; MuMsgContact contact{NULL, address};
list.add_prop(":list-post", list.add_prop(":list-post",
@ -91,8 +91,8 @@ add_list_post (Sexp::List& list, MuMsg *msg)
g_free(address); g_free(address);
} }
g_match_info_free (minfo); g_match_info_free (minfo);
g_regex_unref (rx); g_regex_unref (rx);
} }
@ -105,28 +105,28 @@ typedef struct _ContactData ContactData;
static gboolean static gboolean
each_contact (MuMsgContact *c, ContactData *cdata) 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)); cdata->from.add(make_contact_sexp(c));
break; break;
case MU_MSG_CONTACT_TYPE_TO: case MU_MSG_CONTACT_TYPE_TO:
cdata->to.add(make_contact_sexp(c)); cdata->to.add(make_contact_sexp(c));
break; break;
case MU_MSG_CONTACT_TYPE_CC: case MU_MSG_CONTACT_TYPE_CC:
cdata->cc.add(make_contact_sexp(c)); cdata->cc.add(make_contact_sexp(c));
break; break;
case MU_MSG_CONTACT_TYPE_BCC: case MU_MSG_CONTACT_TYPE_BCC:
cdata->bcc.add(make_contact_sexp(c)); cdata->bcc.add(make_contact_sexp(c));
break; break;
case MU_MSG_CONTACT_TYPE_REPLY_TO: case MU_MSG_CONTACT_TYPE_REPLY_TO:
cdata->reply_to.add(make_contact_sexp(c)); cdata->reply_to.add(make_contact_sexp(c));
break; break;
default: default:
g_return_val_if_reached (FALSE); g_return_val_if_reached (FALSE);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static void static void
@ -144,9 +144,9 @@ add_prop_nonempty_list(Sexp::List& list, std::string&& name,
static void static void
add_contacts (Sexp::List& list, MuMsg *msg) add_contacts (Sexp::List& list, MuMsg *msg)
{ {
ContactData cdata{}; ContactData cdata{};
mu_msg_contact_foreach (msg, (MuMsgContactForeachFunc)each_contact, mu_msg_contact_foreach (msg, (MuMsgContactForeachFunc)each_contact,
&cdata); &cdata);
add_prop_nonempty_list (list, ":from", std::move(cdata.from)); add_prop_nonempty_list (list, ":from", std::move(cdata.from));
add_prop_nonempty_list (list, ":to", std::move(cdata.to)); add_prop_nonempty_list (list, ":to", std::move(cdata.to));
@ -159,23 +159,23 @@ add_contacts (Sexp::List& list, MuMsg *msg)
typedef struct { typedef struct {
Sexp::List flaglist; Sexp::List flaglist;
MuFlags msgflags; MuFlags msgflags;
} FlagData; } FlagData;
static void static void
each_flag (MuFlags flag, FlagData *fdata) each_flag (MuFlags flag, FlagData *fdata)
{ {
if (flag & fdata->msgflags) if (flag & fdata->msgflags)
fdata->flaglist.add(Sexp::make_symbol(mu_flag_name(flag))); fdata->flaglist.add(Sexp::make_symbol(mu_flag_name(flag)));
} }
static void static void
add_flags (Sexp::List& list, MuMsg *msg) add_flags (Sexp::List& list, MuMsg *msg)
{ {
FlagData fdata{}; FlagData fdata{};
fdata.msgflags = mu_msg_get_flags (msg); 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()) if (!fdata.flaglist.empty())
list.add_prop(":flags", list.add_prop(":flags",
Sexp::make_list(std::move(fdata.flaglist))); Sexp::make_list(std::move(fdata.flaglist)));
@ -184,24 +184,24 @@ add_flags (Sexp::List& list, MuMsg *msg)
static char* static char*
get_temp_file (MuMsg *msg, MuMsgOptions opts, unsigned index) get_temp_file (MuMsg *msg, MuMsgOptions opts, unsigned index)
{ {
char *path; char *path;
GError *err; GError *err;
err = NULL; err = NULL;
path = mu_msg_part_get_cache_path (msg, opts, index, &err); path = mu_msg_part_get_cache_path (msg, opts, index, &err);
if (!path) if (!path)
goto errexit; goto errexit;
if (!mu_msg_part_save (msg, opts, path, index, &err)) if (!mu_msg_part_save (msg, opts, path, index, &err))
goto errexit; goto errexit;
return path; return path;
errexit: errexit:
g_warning ("failed to save mime part: %s", g_warning ("failed to save mime part: %s",
err->message ? err->message : "something went wrong"); err->message ? err->message : "something went wrong");
g_clear_error (&err); g_clear_error (&err);
g_free (path); g_free (path);
return NULL; return NULL;
} }
@ -209,41 +209,41 @@ errexit:
static gchar* static gchar*
get_temp_file_maybe (MuMsg *msg, MuMsgPart *part, MuMsgOptions opts) get_temp_file_maybe (MuMsg *msg, MuMsgPart *part, MuMsgOptions opts)
{ {
opts = (MuMsgOptions)((int)opts | (int)MU_MSG_OPTION_USE_EXISTING); opts = (MuMsgOptions)((int)opts | (int)MU_MSG_OPTION_USE_EXISTING);
if (!(opts & MU_MSG_OPTION_EXTRACT_IMAGES) || if (!(opts & MU_MSG_OPTION_EXTRACT_IMAGES) ||
g_ascii_strcasecmp (part->type, "image") != 0) g_ascii_strcasecmp (part->type, "image") != 0)
return NULL; return NULL;
else else
return get_temp_file (msg, opts, part->index); return get_temp_file (msg, opts, part->index);
} }
struct PartInfo { struct PartInfo {
Sexp::List parts; Sexp::List parts;
MuMsgOptions opts; MuMsgOptions opts;
}; };
static void static void
sig_verdict (Sexp::List& partlist, MuMsgPart *mpart) sig_verdict (Sexp::List& partlist, MuMsgPart *mpart)
{ {
MuMsgPartSigStatusReport *report = mpart->sig_status_report; MuMsgPartSigStatusReport *report = mpart->sig_status_report;
if (!report) if (!report)
return; return;
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum" #pragma GCC diagnostic ignored "-Wswitch-enum"
switch (report->verdict) { switch (report->verdict) {
case MU_MSG_PART_SIG_STATUS_GOOD: case MU_MSG_PART_SIG_STATUS_GOOD:
partlist.add_prop(":signature", Sexp::make_symbol("verified")); partlist.add_prop(":signature", Sexp::make_symbol("verified"));
break; break;
case MU_MSG_PART_SIG_STATUS_BAD: case MU_MSG_PART_SIG_STATUS_BAD:
partlist.add_prop(":signature", Sexp::make_symbol("bad")); partlist.add_prop(":signature", Sexp::make_symbol("bad"));
break; break;
case MU_MSG_PART_SIG_STATUS_ERROR: case MU_MSG_PART_SIG_STATUS_ERROR:
partlist.add_prop(":signature", Sexp::make_symbol("unverified")); partlist.add_prop(":signature", Sexp::make_symbol("unverified"));
break; break;
default: default:
break; break;
} }
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
if (report->signers) if (report->signers)
@ -253,7 +253,7 @@ sig_verdict (Sexp::List& partlist, MuMsgPart *mpart)
static void static void
dec_verdict (Sexp::List& partlist, MuMsgPart *mpart) 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")); partlist.add_prop(":decryption", Sexp::make_symbol("succeeded"));
else if (mpart->part_type & MU_MSG_PART_TYPE_ENCRYPTED) else if (mpart->part_type & MU_MSG_PART_TYPE_ENCRYPTED)
partlist.add_prop(":decryption", Sexp::make_symbol("failed")); partlist.add_prop(":decryption", Sexp::make_symbol("failed"));
@ -263,21 +263,21 @@ dec_verdict (Sexp::List& partlist, MuMsgPart *mpart)
static Sexp static Sexp
make_part_types (MuMsgPartType ptype) make_part_types (MuMsgPartType ptype)
{ {
struct PartTypes { struct PartTypes {
MuMsgPartType ptype; MuMsgPartType ptype;
const char* name; const char* name;
} ptypes[] = { } ptypes[] = {
{ MU_MSG_PART_TYPE_LEAF, "leaf" }, { MU_MSG_PART_TYPE_LEAF, "leaf" },
{ MU_MSG_PART_TYPE_MESSAGE, "message" }, { MU_MSG_PART_TYPE_MESSAGE, "message" },
{ MU_MSG_PART_TYPE_INLINE, "inline" }, { MU_MSG_PART_TYPE_INLINE, "inline" },
{ MU_MSG_PART_TYPE_ATTACHMENT, "attachment" }, { MU_MSG_PART_TYPE_ATTACHMENT, "attachment" },
{ MU_MSG_PART_TYPE_SIGNED, "signed" }, { MU_MSG_PART_TYPE_SIGNED, "signed" },
{ MU_MSG_PART_TYPE_ENCRYPTED, "encrypted" } { MU_MSG_PART_TYPE_ENCRYPTED, "encrypted" }
}; };
Sexp::List list; Sexp::List list;
for (auto u = 0U; u!= G_N_ELEMENTS(ptypes); ++u) for (auto u = 0U; u!= G_N_ELEMENTS(ptypes); ++u)
if (ptype & ptypes[u].ptype) if (ptype & ptypes[u].ptype)
list.add(Sexp::make_symbol(ptypes[u].name)); list.add(Sexp::make_symbol(ptypes[u].name));
return Sexp::make_list(std::move(list)); 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"); part->subtype ? part->subtype : "octet-stream");
auto maybe_attach = Sexp::make_symbol(mu_msg_part_maybe_attachment (part) ? auto maybe_attach = Sexp::make_symbol(mu_msg_part_maybe_attachment (part) ?
"t" : "nil"); "t" : "nil");
Sexp::List partlist; Sexp::List partlist;
partlist.add_prop(":index", Sexp::make_number(part->index)); partlist.add_prop(":index", Sexp::make_number(part->index));
@ -334,31 +333,35 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
static void static void
add_parts (Sexp::List& items, MuMsg *msg, MuMsgOptions opts) add_parts (Sexp::List& items, MuMsg *msg, MuMsgOptions opts)
{ {
PartInfo pinfo; PartInfo pinfo;
pinfo.opts = opts; 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()) !pinfo.parts.empty())
items.add_prop(":parts", Sexp::make_list(std::move(pinfo.parts))); items.add_prop(":parts", Sexp::make_list(std::move(pinfo.parts)));
} }
static void static void
add_thread_info (Sexp::List& items, const MuMsgIterThreadInfo *ti) add_thread_info (Sexp::List& items, const QueryMatch& qmatch)
{ {
Sexp::List info; Sexp::List info;
info.add_prop( ":path", Sexp::make_string(ti->threadpath)); info.add_prop(":path", Sexp::make_string(qmatch.thread_path));
info.add_prop( ":level", Sexp::make_number(ti->level)); 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()); 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()); 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()); 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()); 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()); info.add_prop( ":has-child", symbol_t());
items.add_prop(":thread", Sexp::make_list(std::move(info))); 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) add_message_file_parts (Sexp::List& items, MuMsg *msg, MuMsgOptions opts)
{ {
GError *err{NULL}; GError *err{NULL};
if (!mu_msg_load_msg_file (msg, &err)) { if (!mu_msg_load_msg_file (msg, &err)) {
g_warning ("failed to load message file: %s", g_warning ("failed to load message file: %s",
err ? err->message : "some error occurred"); err ? err->message : "some error occurred");
g_clear_error (&err); g_clear_error (&err);
return; return;
} }
add_parts (items, msg, opts); add_parts (items, msg, opts);
add_contacts (items, msg); add_contacts (items, msg);
/* add the user-agent / x-mailer */ /* add the user-agent / x-mailer */
auto str = mu_msg_get_header (msg, "User-Agent"); auto str = mu_msg_get_header (msg, "User-Agent");
if (!str) if (!str)
str = mu_msg_get_header (msg, "X-Mailer"); str = mu_msg_get_header (msg, "X-Mailer");
@ -396,8 +399,8 @@ static void
add_date_and_size (Sexp::List& items, MuMsg *msg) add_date_and_size (Sexp::List& items, MuMsg *msg)
{ {
auto t = mu_msg_get_date (msg); auto t = mu_msg_get_date (msg);
if (t == (time_t)-1) /* invalid date? */ if (t == (time_t)-1) /* invalid date? */
t = 0; t = 0;
Sexp::List dlist; Sexp::List dlist;
dlist.add(Sexp::make_number((unsigned)(t >> 16))); 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))); items.add_prop(":date", Sexp::make_list(std::move(dlist)));
auto s = mu_msg_get_size (msg); auto s = mu_msg_get_size (msg);
if (s == (size_t)-1) /* invalid size? */ if (s == (size_t)-1) /* invalid size? */
s = 0; s = 0;
items.add_prop(":size", Sexp::make_number(s)); items.add_prop(":size", Sexp::make_number(s));
} }
@ -428,64 +431,45 @@ add_tags (Sexp::List& items, MuMsg *msg)
Mu::Sexp Mu::Sexp
Mu::msg_to_sexp (MuMsg *msg, unsigned docid, Mu::msg_to_sexp (MuMsg *msg, unsigned docid,
const struct _MuMsgIterThreadInfo *ti, const Option<QueryMatch&> qm, MuMsgOptions opts)
MuMsgOptions opts)
{ {
g_return_val_if_fail (msg, Sexp::make_symbol("error")); g_return_val_if_fail (msg, Sexp::make_symbol("error"));
g_return_val_if_fail (!((opts & MU_MSG_OPTION_HEADERS_ONLY) && g_return_val_if_fail (!((opts & MU_MSG_OPTION_HEADERS_ONLY) &&
(opts & MU_MSG_OPTION_EXTRACT_IMAGES)), (opts & MU_MSG_OPTION_EXTRACT_IMAGES)),
Sexp::make_symbol("error")); Sexp::make_symbol("error"));
Sexp::List items; Sexp::List items;
if (docid != 0) if (docid != 0)
items.add_prop(":docid", Sexp::make_number(docid)); items.add_prop(":docid", Sexp::make_number(docid));
if (ti) if (qm)
add_thread_info (items, ti); add_thread_info (items, *qm);
add_prop_nonempty (items, ":subject", mu_msg_get_subject (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, ":message-id", mu_msg_get_msgid (msg));
add_prop_nonempty (items, ":mailing-list", mu_msg_get_mailing_list (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, ":path", mu_msg_get_path (msg));
add_prop_nonempty (items, ":maildir", mu_msg_get_maildir (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)))); 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 /* 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 */ * need to get them here if that's the case */
if (opts & MU_MSG_OPTION_HEADERS_ONLY) if (opts & MU_MSG_OPTION_HEADERS_ONLY)
add_contacts (items, msg); add_contacts (items, msg);
add_prop_nonempty (items, ":references", mu_msg_get_references (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_flags (items, msg);
add_tags (items, msg); add_tags (items, msg);
/* headers are retrieved from the database, views from the /* headers are retrieved from the database, views from the
* message file file attr things can only be gotten from the * message file file attr things can only be gotten from the
* file (ie., mu view), not from the database (mu find). */ * file (ie., mu view), not from the database (mu find). */
if (!(opts & MU_MSG_OPTION_HEADERS_ONLY)) if (!(opts & MU_MSG_OPTION_HEADERS_ONLY))
add_message_file_parts (items, msg, opts); add_message_file_parts (items, msg, opts);
return Sexp::make_list(std::move(items)); 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> ** Copyright (C) 2008-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify ** This program is free software; you can redistribute it and/or modify
@ -28,11 +27,13 @@
#include <gmime/gmime.h> #include <gmime/gmime.h>
#include "mu-msg-priv.h" /* include before mu-msg.h */ #include "mu-msg-priv.hh" /* include before mu-msg.h */
#include "mu-msg.h" #include "mu-msg.hh"
#include "utils/mu-str.h" #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 /* note, we do the gmime initialization here rather than in
* mu-runtime, because this way we don't need mu-runtime for simple * mu-runtime, because this way we don't need mu-runtime for simple
@ -64,15 +65,15 @@ msg_new (void)
{ {
MuMsg *self; MuMsg *self;
self = g_slice_new0 (MuMsg); self = g_new0 (MuMsg, 1);
self->_refcount = 1; self->_refcount = 1;
return self; return self;
} }
MuMsg* MuMsg*
mu_msg_new_from_file (const char *path, const char *mdir, Mu::mu_msg_new_from_file (const char *path, const char *mdir,
GError **err) GError **err)
{ {
MuMsg *self; MuMsg *self;
MuMsgFile *msgfile; MuMsgFile *msgfile;
@ -101,7 +102,7 @@ mu_msg_new_from_file (const char *path, const char *mdir,
} }
MuMsg* MuMsg*
mu_msg_new_from_doc (XapianDocument *doc, GError **err) Mu::mu_msg_new_from_doc (XapianDocument *doc, GError **err)
{ {
MuMsg *self; MuMsg *self;
MuMsgDoc *msgdoc; MuMsgDoc *msgdoc;
@ -139,11 +140,11 @@ mu_msg_destroy (MuMsg *self)
g_slist_free (self->_free_later_lst); g_slist_free (self->_free_later_lst);
} }
g_slice_free (MuMsg, self); g_free (self);
} }
MuMsg* MuMsg*
mu_msg_ref (MuMsg *self) Mu::mu_msg_ref (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
@ -153,7 +154,7 @@ mu_msg_ref (MuMsg *self)
} }
void void
mu_msg_unref (MuMsg *self) Mu::mu_msg_unref (MuMsg *self)
{ {
g_return_if_fail (self); g_return_if_fail (self);
g_return_if_fail (self->_refcount >= 1); 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 */ /* for some data, we need to read the message file from disk */
gboolean gboolean
mu_msg_load_msg_file (MuMsg *self, GError **err) Mu::mu_msg_load_msg_file (MuMsg *self, GError **err)
{ {
const char *path; const char *path;
@ -231,7 +232,7 @@ mu_msg_load_msg_file (MuMsg *self, GError **err)
} }
void void
mu_msg_unload_msg_file (MuMsg *msg) Mu::mu_msg_unload_msg_file (MuMsg *msg)
{ {
g_return_if_fail (msg); g_return_if_fail (msg);
@ -303,7 +304,7 @@ get_num_field (MuMsg *self, MuMsgFieldId mfid)
} }
const char* const char*
mu_msg_get_header (MuMsg *self, const char *header) Mu::mu_msg_get_header (MuMsg *self, const char *header)
{ {
GError *err; GError *err;
@ -324,7 +325,7 @@ mu_msg_get_header (MuMsg *self, const char *header)
} }
time_t time_t
mu_msg_get_timestamp (MuMsg *self) Mu::mu_msg_get_timestamp (MuMsg *self)
{ {
const char *path; const char *path;
struct stat statbuf; struct stat statbuf;
@ -342,28 +343,28 @@ mu_msg_get_timestamp (MuMsg *self)
} }
const char* const char*
mu_msg_get_path (MuMsg *self) Mu::mu_msg_get_path (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_PATH); return get_str_field (self, MU_MSG_FIELD_ID_PATH);
} }
const char* const char*
mu_msg_get_subject (MuMsg *self) Mu::mu_msg_get_subject (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_SUBJECT); return get_str_field (self, MU_MSG_FIELD_ID_SUBJECT);
} }
const char* const char*
mu_msg_get_msgid (MuMsg *self) Mu::mu_msg_get_msgid (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_MSGID); return get_str_field (self, MU_MSG_FIELD_ID_MSGID);
} }
const char* const char*
mu_msg_get_mailing_list (MuMsg *self) Mu::mu_msg_get_mailing_list (MuMsg *self)
{ {
const char *ml; const char *ml;
char *decml; char *decml;
@ -382,63 +383,63 @@ mu_msg_get_mailing_list (MuMsg *self)
} }
const char* const char*
mu_msg_get_maildir (MuMsg *self) Mu::mu_msg_get_maildir (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_MAILDIR); return get_str_field (self, MU_MSG_FIELD_ID_MAILDIR);
} }
const char* const char*
mu_msg_get_from (MuMsg *self) Mu::mu_msg_get_from (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_FROM); return get_str_field (self, MU_MSG_FIELD_ID_FROM);
} }
const char* const char*
mu_msg_get_to (MuMsg *self) Mu::mu_msg_get_to (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_TO); return get_str_field (self, MU_MSG_FIELD_ID_TO);
} }
const char* const char*
mu_msg_get_cc (MuMsg *self) Mu::mu_msg_get_cc (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_CC); return get_str_field (self, MU_MSG_FIELD_ID_CC);
} }
const char* const char*
mu_msg_get_bcc (MuMsg *self) Mu::mu_msg_get_bcc (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_BCC); return get_str_field (self, MU_MSG_FIELD_ID_BCC);
} }
time_t time_t
mu_msg_get_date (MuMsg *self) Mu::mu_msg_get_date (MuMsg *self)
{ {
g_return_val_if_fail (self, (time_t)-1); 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, MU_MSG_FIELD_ID_DATE);
} }
MuFlags MuFlags
mu_msg_get_flags (MuMsg *self) Mu::mu_msg_get_flags (MuMsg *self)
{ {
g_return_val_if_fail (self, MU_FLAG_NONE); g_return_val_if_fail (self, MU_FLAG_NONE);
return (MuFlags)get_num_field (self, MU_MSG_FIELD_ID_FLAGS); return (MuFlags)get_num_field (self, MU_MSG_FIELD_ID_FLAGS);
} }
size_t size_t
mu_msg_get_size (MuMsg *self) Mu::mu_msg_get_size (MuMsg *self)
{ {
g_return_val_if_fail (self, (size_t)-1); 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, MU_MSG_FIELD_ID_SIZE);
} }
MuMsgPrio MuMsgPrio
mu_msg_get_prio (MuMsg *self) Mu::mu_msg_get_prio (MuMsg *self)
{ {
g_return_val_if_fail (self, MU_MSG_PRIO_NORMAL); g_return_val_if_fail (self, MU_MSG_PRIO_NORMAL);
return (MuMsgPrio)get_num_field (self, MU_MSG_FIELD_ID_PRIO); 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 && if (!cdata->want_html &&
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_PLAIN)) (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) && else if (!(mpart->part_type & MU_MSG_PART_TYPE_ATTACHMENT) &&
cdata->want_html && cdata->want_html &&
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_HTML)) (mpart->part_type & MU_MSG_PART_TYPE_TEXT_HTML))
wanted = mpart->data; wanted = (GMimePart*)mpart->data;
else else
wanted = NULL; wanted = NULL;
@ -569,56 +570,56 @@ get_content_type_parameters (MuMsg *self, MuMsgOptions opts, gboolean want_html)
} }
const GSList* 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); g_return_val_if_fail (self, NULL);
return get_content_type_parameters(self, opts, FALSE); return get_content_type_parameters(self, opts, FALSE);
} }
const char* 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); g_return_val_if_fail (self, NULL);
return free_later_str (self, get_body (self, opts, TRUE)); return free_later_str (self, get_body (self, opts, TRUE));
} }
const char* 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); g_return_val_if_fail (self, NULL);
return free_later_str (self, get_body (self, opts, FALSE)); return free_later_str (self, get_body (self, opts, FALSE));
} }
const GSList* const GSList*
mu_msg_get_references (MuMsg *self) Mu::mu_msg_get_references (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_list_field (self, MU_MSG_FIELD_ID_REFS); return get_str_list_field (self, MU_MSG_FIELD_ID_REFS);
} }
const GSList* const GSList*
mu_msg_get_tags (MuMsg *self) Mu::mu_msg_get_tags (MuMsg *self)
{ {
g_return_val_if_fail (self, NULL); g_return_val_if_fail (self, NULL);
return get_str_list_field (self, MU_MSG_FIELD_ID_TAGS); return get_str_list_field (self, MU_MSG_FIELD_ID_TAGS);
} }
const char* 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); g_return_val_if_fail (self, NULL);
return get_str_field (self, mfid); return get_str_field (self, mfid);
} }
const GSList* 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); g_return_val_if_fail (self, NULL);
return get_str_list_field (self, mfid); return get_str_list_field (self, mfid);
} }
gint64 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); g_return_val_if_fail (self, -1);
return get_num_field (self, mfid); return get_num_field (self, mfid);
@ -744,7 +745,7 @@ msg_contact_foreach_doc (MuMsg *msg, MuMsgContactForeachFunc func,
} }
void void
mu_msg_contact_foreach (MuMsg *msg, MuMsgContactForeachFunc func, Mu::mu_msg_contact_foreach (MuMsg *msg, MuMsgContactForeachFunc func,
gpointer user_data) gpointer user_data)
{ {
g_return_if_fail (msg); g_return_if_fail (msg);
@ -809,7 +810,7 @@ cmp_subject (const char* s1, const char *s2)
} }
int 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 (m1, 0);
g_return_val_if_fail (m2, 0); g_return_val_if_fail (m2, 0);
@ -834,7 +835,7 @@ mu_msg_cmp (MuMsg *m1, MuMsg *m2, MuMsgFieldId mfid)
} }
gboolean gboolean
mu_msg_is_readable (MuMsg *self) Mu::mu_msg_is_readable (MuMsg *self)
{ {
g_return_val_if_fail (self, FALSE); 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... * super-paranoid here...
*/ */
gboolean 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, MuFlags flags, gboolean ignore_dups,
gboolean new_name, GError **err) 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 * some 3rd party progs such as mbsync
*/ */
gboolean gboolean
mu_msg_tickle (MuMsg *self, GError **err) Mu::mu_msg_tickle (MuMsg *self, GError **err)
{ {
g_return_val_if_fail (self, FALSE); g_return_val_if_fail (self, FALSE);
@ -958,13 +959,13 @@ mu_msg_tickle (MuMsg *self, GError **err)
} }
const char* 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); return mu_flags_to_str_s (flags, MU_FLAG_TYPE_ANY);
} }
char* char*
mu_str_flags (MuFlags flags) Mu::mu_str_flags (MuFlags flags)
{ {
return g_strdup (mu_str_flags_s(flags)); return g_strdup (mu_str_flags_s(flags));
} }
@ -991,7 +992,7 @@ cleanup_contact (char *contact)
/* this is still somewhat simplistic... */ /* this is still somewhat simplistic... */
const char* const char*
mu_str_display_contact_s (const char *str) Mu::mu_str_display_contact_s (const char *str)
{ {
static gchar contact[255]; static gchar contact[255];
gchar *c, *c2; gchar *c, *c2;
@ -1017,7 +1018,7 @@ mu_str_display_contact_s (const char *str)
} }
char* char*
mu_str_display_contact (const char *str) Mu::mu_str_display_contact (const char *str)
{ {
g_return_val_if_fail (str, NULL); 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-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** Copyright (C) 2010-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify ** 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 ** it under the terms of the GNU General Public License as published by
@ -19,21 +17,23 @@
** **
*/ */
#ifndef __MU_MSG_H__ #ifndef MU_MSG_HH__
#define __MU_MSG_H__ #define MU_MSG_HH__
#include <mu-flags.h> #include <mu-flags.hh>
#include <mu-msg-fields.h> #include <mu-msg-fields.h>
#include <mu-msg-prio.h> #include <mu-msg-prio.h>
#include <utils/mu-util.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; struct MuMsg;
typedef struct _MuMsg MuMsg;
/* options for various functions */ /* options for various functions */
typedef enum { enum MuMsgOptions {
MU_MSG_OPTION_NONE = 0, MU_MSG_OPTION_NONE = 0,
/* 1 << 0 is still free! */ /* 1 << 0 is still free! */
@ -59,8 +59,8 @@ typedef enum {
/* recurse into submessages */ /* recurse into submessages */
MU_MSG_OPTION_RECURSE_RFC822 = 1 << 11 MU_MSG_OPTION_RECURSE_RFC822 = 1 << 11
};
} MuMsgOptions; MU_ENABLE_BITOPS(MuMsgOptions);
/** /**
* create a new MuMsg* instance which parses a message and provides * 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; G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
struct _MuMsgIterThreadInfo; struct QueryMatch;
/**
* 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;
/** /**
* convert the msg to a Lisp symbolic expression (for further processing in * 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 msg a valid message
* @param docid the docid for this message, or 0 * @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
* 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 opts, bitwise OR'ed; * @param opts, bitwise OR'ed;
* - MU_MSG_OPTION_HEADERS_ONLY: only include message fields which can be * - MU_MSG_OPTION_HEADERS_ONLY: only include message fields which can be
* obtained from the database (this is much faster if the MuMsg is * 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 * @return a Sexp::Node representing the message
*/ */
Mu::Sexp msg_to_sexp (MuMsg *msg, unsigned docid, Mu::Sexp msg_to_sexp (MuMsg *msg, unsigned docid,
const struct _MuMsgIterThreadInfo *ti, const Option<QueryMatch&> qm,
MuMsgOptions ops); MuMsgOptions ops);
} }
#endif /*__cplusplus*/ #endif /*MU_MSG_HH__*/
#endif /*__MU_MSG_H__*/

View File

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

View File

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

View File

@ -20,7 +20,7 @@
#ifndef __MU_STORE_HH__ #ifndef __MU_STORE_HH__
#define __MU_STORE_HH__ #define __MU_STORE_HH__
#include <mu-msg.h> #include <mu-msg.hh>
#ifdef __cplusplus #ifdef __cplusplus
@ -52,7 +52,6 @@ public:
*/ */
Store (const std::string& path, bool readonly=true); Store (const std::string& path, bool readonly=true);
struct Config { struct Config {
size_t max_message_size{}; size_t max_message_size{};
/**< maximum size (in bytes) for a message, or 0 for default */ /**< 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 * Get the Indexer associated with this store. It is an error to call
* to call this on a read-only store. * this on a read-only store.
* *
* @return the indexer. * @return the indexer.
*/ */
@ -143,7 +142,7 @@ public:
* @param msg a message * @param msg a message
* @param id the id for this 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); 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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -23,9 +22,10 @@
#endif /*HAVE_CONFIG_H*/ #endif /*HAVE_CONFIG_H*/
#include <glib.h> #include <glib.h>
#include "mu-flags.h" #include "mu-flags.hh"
#include "test-mu-common.hh" #include "test-mu-common.hh"
using namespace Mu;
static void static void
test_mu_flag_char (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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -29,9 +29,10 @@
#include <string.h> #include <string.h>
#include "test-mu-common.hh" #include "test-mu-common.hh"
#include "mu-maildir.h" #include "mu-maildir.hh"
#include "utils/mu-util.h" #include "utils/mu-util.h"
using namespace Mu;
static void static void
test_mu_maildir_mkdir_01 (void) test_mu_maildir_mkdir_01 (void)

View File

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

View File

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