[evolution-data-server] Bug 764065 - [Camel] Port more classes to GObject
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 764065 - [Camel] Port more classes to GObject
- Date: Tue, 8 Nov 2016 14:50:07 +0000 (UTC)
commit 9af0c834ea6094c651f7e82fc2f02afa0c6fd697
Author: Corentin Noël <corentin elementary io>
Date: Tue Nov 8 15:49:25 2016 +0100
Bug 764065 - [Camel] Port more classes to GObject
Some parts had been done by Milan Crha.
CMakeLists.txt | 2 +-
src/camel/CMakeLists.txt | 12 +
src/camel/camel-address.c | 42 +-
src/camel/camel-address.h | 6 +-
src/camel/camel-async-closure.c | 8 +-
src/camel/camel-block-file.c | 434 ++--
src/camel/camel-block-file.h | 32 +-
src/camel/camel-certdb.h | 3 +
src/camel/camel-charset-map.c | 12 +-
src/camel/camel-cipher-context.c | 23 +-
src/camel/camel-cipher-context.h | 4 +-
src/camel/camel-data-cache.h | 3 +
src/camel/camel-data-wrapper.c | 205 ++-
src/camel/camel-data-wrapper.h | 27 +-
src/camel/camel-db.c | 375 +--
src/camel/camel-db.h | 323 ++-
src/camel/camel-enums.h | 14 +
src/camel/camel-filter-driver.c | 31 +-
src/camel/camel-filter-driver.h | 5 +-
src/camel/camel-filter-input-stream.h | 3 +
src/camel/camel-filter-output-stream.h | 3 +
src/camel/camel-filter-search.c | 123 +-
src/camel/camel-folder-search.c | 485 ++--
src/camel/camel-folder-search.h | 33 +-
src/camel/camel-folder-summary.c | 2955 +++----------------
src/camel/camel-folder-summary.h | 438 +---
src/camel/camel-folder-thread.c | 68 +-
src/camel/camel-folder.c | 404 ++-
src/camel/camel-folder.h | 60 +-
src/camel/camel-gpg-context.c | 2 +-
src/camel/camel-gpg-context.h | 3 +
src/camel/camel-html-parser.h | 3 +
src/camel/camel-iconv.c | 28 +-
src/camel/camel-index.h | 5 +-
src/camel/camel-internet-address.c | 113 +-
src/camel/camel-internet-address.h | 3 +
src/camel/camel-junk-filter.h | 3 +
src/camel/camel-local-settings.h | 3 +
src/camel/camel-medium.c | 56 +-
src/camel/camel-medium.h | 35 +-
src/camel/camel-memchunk.c | 14 +-
src/camel/camel-mempool.c | 10 +-
src/camel/camel-message-info-base.c | 877 ++++++
src/camel/camel-message-info-base.h | 70 +
src/camel/camel-message-info.c | 2979 ++++++++++++++++++++
src/camel/camel-message-info.h | 328 +++
src/camel/camel-mime-filter-basic.h | 3 +
src/camel/camel-mime-filter-bestenc.h | 3 +
src/camel/camel-mime-filter-canon.h | 3 +
src/camel/camel-mime-filter-charset.h | 3 +
src/camel/camel-mime-filter-crlf.h | 3 +
src/camel/camel-mime-filter-enriched.h | 3 +
src/camel/camel-mime-filter-from.h | 3 +
src/camel/camel-mime-filter-gzip.h | 3 +
src/camel/camel-mime-filter-html.h | 3 +
src/camel/camel-mime-filter-index.h | 3 +
src/camel/camel-mime-filter-linewrap.h | 3 +
src/camel/camel-mime-filter-pgp.h | 3 +
src/camel/camel-mime-filter-progress.h | 3 +
src/camel/camel-mime-filter-tohtml.h | 3 +
src/camel/camel-mime-filter-windows.h | 3 +
src/camel/camel-mime-filter-yenc.c | 30 +-
src/camel/camel-mime-filter-yenc.h | 3 +
src/camel/camel-mime-filter.h | 3 +
src/camel/camel-mime-message.c | 194 +-
src/camel/camel-mime-message.h | 22 +-
src/camel/camel-mime-parser.c | 102 +-
src/camel/camel-mime-parser.h | 8 +-
src/camel/camel-mime-part-utils.c | 248 ++-
src/camel/camel-mime-part-utils.h | 39 +-
src/camel/camel-mime-part.c | 219 +-
src/camel/camel-mime-part.h | 7 +-
src/camel/camel-mime-utils.c | 358 +--
src/camel/camel-mime-utils.h | 30 +-
src/camel/camel-movemail.c | 24 +-
src/camel/camel-msgport.c | 20 +-
src/camel/camel-multipart-encrypted.h | 2 +
src/camel/camel-multipart-signed.h | 3 +
src/camel/camel-multipart.c | 8 +-
src/camel/camel-multipart.h | 3 +
src/camel/camel-name-value-array.c | 636 +++++
src/camel/camel-name-value-array.h | 97 +
src/camel/camel-named-flags.c | 319 +++
src/camel/camel-named-flags.h | 62 +
src/camel/camel-network-service.h | 3 +-
src/camel/camel-network-settings.h | 3 +
src/camel/camel-nntp-address.c | 92 +-
src/camel/camel-nntp-address.h | 7 +-
src/camel/camel-null-output-stream.h | 3 +
src/camel/camel-object-bag.c | 4 +-
src/camel/camel-object.h | 3 +
src/camel/camel-offline-folder.h | 4 +-
src/camel/camel-offline-settings.h | 3 +
src/camel/camel-offline-store.c | 9 +-
src/camel/camel-offline-store.h | 3 +
src/camel/camel-operation.h | 3 +
src/camel/camel-partition-table.c | 191 +-
src/camel/camel-partition-table.h | 22 +-
src/camel/camel-provider.c | 40 +-
src/camel/camel-provider.h | 3 +
src/camel/camel-sasl-anonymous.c | 30 +-
src/camel/camel-sasl-anonymous.h | 8 +-
src/camel/camel-sasl-cram-md5.h | 3 +
src/camel/camel-sasl-digest-md5.h | 3 +
src/camel/camel-sasl-gssapi.c | 4 +-
src/camel/camel-sasl-gssapi.h | 3 +
src/camel/camel-sasl-login.h | 3 +
src/camel/camel-sasl-ntlm.h | 3 +
src/camel/camel-sasl-plain.h | 3 +
src/camel/camel-sasl-popb4smtp.h | 3 +
src/camel/camel-sasl.c | 2 +-
src/camel/camel-sasl.h | 4 +-
src/camel/camel-search-private.c | 34 +-
src/camel/camel-service.c | 43 +-
src/camel/camel-service.h | 11 +-
src/camel/camel-session.c | 2 +-
src/camel/camel-session.h | 7 +-
src/camel/camel-settings.h | 3 +
src/camel/camel-sexp.c | 135 +-
src/camel/camel-sexp.h | 23 +-
src/camel/camel-smime-context.c | 6 +-
src/camel/camel-smime-context.h | 3 +
src/camel/camel-store-settings.h | 3 +
src/camel/camel-store-summary.c | 84 +-
src/camel/camel-store-summary.h | 13 +-
src/camel/camel-store.c | 317 ++-
src/camel/camel-store.h | 48 +-
src/camel/camel-stream-buffer.c | 2 +-
src/camel/camel-stream-buffer.h | 3 +
src/camel/camel-stream-filter.h | 3 +
src/camel/camel-stream-fs.c | 17 +-
src/camel/camel-stream-fs.h | 3 +
src/camel/camel-stream-mem.h | 3 +
src/camel/camel-stream-null.c | 30 +-
src/camel/camel-stream-null.h | 11 +-
src/camel/camel-stream-process.c | 54 +-
src/camel/camel-stream-process.h | 8 +-
src/camel/camel-stream.c | 15 +-
src/camel/camel-stream.h | 5 +-
src/camel/camel-subscribable.c | 47 +-
src/camel/camel-subscribable.h | 7 +-
src/camel/camel-text-index.c | 46 +-
src/camel/camel-text-index.h | 12 +
src/camel/camel-transport.h | 4 +-
src/camel/camel-trie.c | 14 +-
src/camel/camel-uid-cache.c | 2 +-
src/camel/camel-url-scanner.c | 29 +
src/camel/camel-url.c | 42 +-
src/camel/camel-url.h | 6 +-
src/camel/camel-utf8.c | 21 +-
src/camel/camel-utf8.h | 3 -
src/camel/camel-utils.c | 173 ++
src/camel/camel-utils.h | 40 +
src/camel/camel-vee-data-cache.h | 13 +-
src/camel/camel-vee-folder.c | 104 +-
src/camel/camel-vee-folder.h | 9 +-
src/camel/camel-vee-message-info.c | 532 ++++
src/camel/camel-vee-message-info.h | 80 +
src/camel/camel-vee-store.c | 38 +-
src/camel/camel-vee-store.h | 3 +
src/camel/camel-vee-summary.c | 335 +--
src/camel/camel-vee-summary.h | 17 +-
src/camel/camel-vtrash-folder.c | 50 +-
src/camel/camel-vtrash-folder.h | 11 +-
src/camel/camel.h | 6 +
src/camel/providers/imapx/CMakeLists.txt | 2 +
src/camel/providers/imapx/camel-imapx-command.c | 4 +-
.../providers/imapx/camel-imapx-conn-manager.c | 2 +-
.../providers/imapx/camel-imapx-conn-manager.h | 3 +
src/camel/providers/imapx/camel-imapx-folder.c | 92 +-
src/camel/providers/imapx/camel-imapx-folder.h | 3 +
.../providers/imapx/camel-imapx-input-stream.h | 3 +
src/camel/providers/imapx/camel-imapx-job.h | 1 -
.../providers/imapx/camel-imapx-list-response.h | 3 +
src/camel/providers/imapx/camel-imapx-logger.h | 3 +
src/camel/providers/imapx/camel-imapx-mailbox.h | 3 +
.../providers/imapx/camel-imapx-message-info.c | 435 +++
.../providers/imapx/camel-imapx-message-info.h | 90 +
.../imapx/camel-imapx-namespace-response.h | 3 +
src/camel/providers/imapx/camel-imapx-namespace.h | 3 +
src/camel/providers/imapx/camel-imapx-search.c | 49 +-
src/camel/providers/imapx/camel-imapx-search.h | 3 +
src/camel/providers/imapx/camel-imapx-server.c | 534 ++--
src/camel/providers/imapx/camel-imapx-server.h | 3 +
src/camel/providers/imapx/camel-imapx-settings.h | 3 +
.../providers/imapx/camel-imapx-status-response.h | 3 +
.../providers/imapx/camel-imapx-store-summary.h | 3 +
src/camel/providers/imapx/camel-imapx-store.c | 50 +-
src/camel/providers/imapx/camel-imapx-store.h | 3 +
src/camel/providers/imapx/camel-imapx-summary.c | 291 +--
src/camel/providers/imapx/camel-imapx-summary.h | 17 +-
src/camel/providers/imapx/camel-imapx-utils.c | 181 +-
src/camel/providers/imapx/camel-imapx-utils.h | 17 +-
src/camel/providers/local/CMakeLists.txt | 4 +
src/camel/providers/local/camel-local-folder.c | 42 +-
src/camel/providers/local/camel-local-folder.h | 3 +
src/camel/providers/local/camel-local-store.c | 2 +-
src/camel/providers/local/camel-local-store.h | 3 +
src/camel/providers/local/camel-local-summary.c | 207 +-
src/camel/providers/local/camel-local-summary.h | 19 +-
src/camel/providers/local/camel-maildir-folder.c | 70 +-
src/camel/providers/local/camel-maildir-folder.h | 3 +
.../providers/local/camel-maildir-message-info.c | 251 ++
.../providers/local/camel-maildir-message-info.h | 74 +
src/camel/providers/local/camel-maildir-store.c | 4 +-
src/camel/providers/local/camel-maildir-store.h | 3 +
src/camel/providers/local/camel-maildir-summary.c | 191 +-
src/camel/providers/local/camel-maildir-summary.h | 18 +-
src/camel/providers/local/camel-mbox-folder.c | 91 +-
src/camel/providers/local/camel-mbox-folder.h | 3 +
.../providers/local/camel-mbox-message-info.c | 255 ++
.../providers/local/camel-mbox-message-info.h | 70 +
src/camel/providers/local/camel-mbox-store.c | 6 +-
src/camel/providers/local/camel-mbox-store.h | 3 +
src/camel/providers/local/camel-mbox-summary.c | 415 +--
src/camel/providers/local/camel-mbox-summary.h | 9 +-
src/camel/providers/local/camel-mh-folder.c | 10 +-
src/camel/providers/local/camel-mh-folder.h | 3 +
src/camel/providers/local/camel-mh-settings.h | 3 +
src/camel/providers/local/camel-mh-store.c | 8 +-
src/camel/providers/local/camel-mh-store.h | 3 +
src/camel/providers/local/camel-mh-summary.c | 40 +-
src/camel/providers/local/camel-mh-summary.h | 3 +
src/camel/providers/local/camel-spool-folder.c | 5 +-
src/camel/providers/local/camel-spool-folder.h | 3 +
src/camel/providers/local/camel-spool-settings.h | 3 +
src/camel/providers/local/camel-spool-store.c | 5 +-
src/camel/providers/local/camel-spool-store.h | 3 +
src/camel/providers/local/camel-spool-summary.c | 24 +-
src/camel/providers/local/camel-spool-summary.h | 7 +-
src/camel/providers/nntp/camel-nntp-folder.c | 75 +-
src/camel/providers/nntp/camel-nntp-folder.h | 3 +
src/camel/providers/nntp/camel-nntp-settings.h | 3 +
.../providers/nntp/camel-nntp-store-summary.h | 3 +
src/camel/providers/nntp/camel-nntp-store.c | 12 +-
src/camel/providers/nntp/camel-nntp-store.h | 3 +
src/camel/providers/nntp/camel-nntp-stream.h | 3 +
src/camel/providers/nntp/camel-nntp-summary.c | 82 +-
src/camel/providers/nntp/camel-nntp-summary.h | 3 +
src/camel/providers/pop3/camel-pop3-engine.h | 3 +
src/camel/providers/pop3/camel-pop3-folder.c | 30 +-
src/camel/providers/pop3/camel-pop3-folder.h | 3 +
src/camel/providers/pop3/camel-pop3-settings.h | 3 +
src/camel/providers/pop3/camel-pop3-store.h | 3 +
src/camel/providers/pop3/camel-pop3-stream.h | 3 +
.../providers/sendmail/camel-sendmail-provider.c | 4 +-
.../providers/sendmail/camel-sendmail-settings.h | 3 +
.../providers/sendmail/camel-sendmail-transport.c | 55 +-
.../providers/sendmail/camel-sendmail-transport.h | 3 +
src/camel/providers/smtp/camel-smtp-settings.h | 3 +
src/camel/providers/smtp/camel-smtp-transport.c | 45 +-
src/camel/providers/smtp/camel-smtp-transport.h | 3 +
src/camel/tests/CMakeLists.txt | 3 +-
src/camel/tests/folder/test10.c | 3 +-
src/camel/tests/folder/test11.c | 27 +-
src/camel/tests/folder/test2.c | 2 +-
src/camel/tests/folder/test8.c | 3 +-
src/camel/tests/lib/folders.c | 12 +-
src/camel/tests/lib/messages.c | 8 +-
src/camel/tests/message/test2.c | 4 +-
src/camel/tests/mime-filter/test-charset.c | 3 +-
src/camel/tests/misc/split.c | 4 +-
src/camel/tests/misc/utf7.c | 2 +-
src/camel/tests/smime/pgp.c | 1 -
src/vala/Camel-1.2.metadata | 12 +
265 files changed, 13074 insertions(+), 7170 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5588f3a..06be584 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -44,7 +44,7 @@ set(USER_PROMPTER_DBUS_SERVICE_NAME "org.gnome.evolution.dataserver.UserPrompter
# ******************************
# Library versioning
# ******************************
-set(LIBCAMEL_CURRENT 59)
+set(LIBCAMEL_CURRENT 60)
set(LIBCAMEL_REVISION 0)
set(LIBCAMEL_AGE 0)
diff --git a/src/camel/CMakeLists.txt b/src/camel/CMakeLists.txt
index 923e674..481f102 100644
--- a/src/camel/CMakeLists.txt
+++ b/src/camel/CMakeLists.txt
@@ -38,6 +38,8 @@ set(SOURCES
camel-medium.c
camel-memchunk.c
camel-mempool.c
+ camel-message-info.c
+ camel-message-info-base.c
camel-mime-filter-basic.c
camel-mime-filter-bestenc.c
camel-mime-filter-canon.c
@@ -64,6 +66,8 @@ set(SOURCES
camel-multipart-encrypted.c
camel-multipart-signed.c
camel-multipart.c
+ camel-named-flags.c
+ camel-name-value-array.c
camel-net-utils.c
camel-network-service.c
camel-network-settings.c
@@ -111,8 +115,10 @@ set(SOURCES
camel-url-scanner.c
camel-url.c
camel-utf8.c
+ camel-utils.c
camel-vee-data-cache.c
camel-vee-folder.c
+ camel-vee-message-info.c
camel-vee-store.c
camel-vee-summary.c
camel-vtrash-folder.c
@@ -167,6 +173,8 @@ set(HEADERS
camel-medium.h
camel-memchunk.h
camel-mempool.h
+ camel-message-info.h
+ camel-message-info-base.h
camel-mime-filter-basic.h
camel-mime-filter-bestenc.h
camel-mime-filter-canon.h
@@ -194,6 +202,8 @@ set(HEADERS
camel-multipart-encrypted.h
camel-multipart-signed.h
camel-multipart.h
+ camel-named-flags.h
+ camel-name-value-array.h
camel-net-utils.h
camel-network-service.h
camel-network-settings.h
@@ -242,8 +252,10 @@ set(HEADERS
camel-url-scanner.h
camel-url.h
camel-utf8.h
+ camel-utils.h
camel-vee-data-cache.h
camel-vee-folder.h
+ camel-vee-message-info.h
camel-vee-store.h
camel-vee-summary.h
camel-vtrash-folder.h
diff --git a/src/camel/camel-address.c b/src/camel/camel-address.c
index 9b6e6d3..8897cd1 100644
--- a/src/camel/camel-address.c
+++ b/src/camel/camel-address.c
@@ -18,33 +18,22 @@
#include "camel-address.h"
-G_DEFINE_TYPE (CamelAddress, camel_address, G_TYPE_OBJECT)
-
-static void
-address_finalize (GObject *object)
-{
- CamelAddress *address = CAMEL_ADDRESS (object);
+struct _CamelAddressPrivate {
+ guint dummy;
+};
- camel_address_remove (address, -1);
- g_ptr_array_free (address->addresses, TRUE);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (camel_address_parent_class)->finalize (object);
-}
+G_DEFINE_TYPE (CamelAddress, camel_address, G_TYPE_OBJECT)
static void
camel_address_class_init (CamelAddressClass *class)
{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = address_finalize;
+ g_type_class_add_private (class, sizeof (CamelAddressPrivate));
}
static void
camel_address_init (CamelAddress *address)
{
- address->addresses = g_ptr_array_new ();
+ address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address, CAMEL_TYPE_ADDRESS, CamelAddressPrivate);
}
/**
@@ -90,7 +79,14 @@ camel_address_new_clone (CamelAddress *addr)
gint
camel_address_length (CamelAddress *addr)
{
- return addr->addresses->len;
+ CamelAddressClass *class;
+
+ g_return_val_if_fail (CAMEL_IS_ADDRESS (addr), -1);
+
+ class = CAMEL_ADDRESS_GET_CLASS (addr);
+ g_return_val_if_fail (class->length != NULL, -1);
+
+ return class->length (addr);
}
/**
@@ -236,7 +232,7 @@ camel_address_copy (CamelAddress *dest,
**/
void
camel_address_remove (CamelAddress *addr,
- gint index)
+ gint index)
{
CamelAddressClass *class;
@@ -246,8 +242,12 @@ camel_address_remove (CamelAddress *addr,
g_return_if_fail (class->remove != NULL);
if (index == -1) {
- for (index = addr->addresses->len; index>-1; index--)
+ gint len = camel_address_length (addr);
+
+ for (index = len - 1; index >= 0; index--) {
class->remove (addr, index);
- } else
+ }
+ } else {
class->remove (addr, index);
+ }
}
diff --git a/src/camel/camel-address.h b/src/camel/camel-address.h
index 186d6cd..6965eb2 100644
--- a/src/camel/camel-address.h
+++ b/src/camel/camel-address.h
@@ -54,14 +54,13 @@ typedef struct _CamelAddressPrivate CamelAddressPrivate;
struct _CamelAddress {
GObject parent;
- GPtrArray *addresses;
-
CamelAddressPrivate *priv;
};
struct _CamelAddressClass {
GObjectClass parent_class;
+ gint (*length) (CamelAddress *addr);
gint (*decode) (CamelAddress *addr,
const gchar *raw);
gchar * (*encode) (CamelAddress *addr);
@@ -72,6 +71,9 @@ struct _CamelAddressClass {
CamelAddress *source);
void (*remove) (CamelAddress *addr,
gint index);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_address_get_type (void);
diff --git a/src/camel/camel-async-closure.c b/src/camel/camel-async-closure.c
index f765571..970c363 100644
--- a/src/camel/camel-async-closure.c
+++ b/src/camel/camel-async-closure.c
@@ -59,7 +59,7 @@ struct _CamelAsyncClosure {
};
/**
- * camel_async_closure_new:
+ * camel_async_closure_new: (skip)
*
* Creates a new #CamelAsyncClosure for use with asynchronous functions.
*
@@ -96,7 +96,7 @@ camel_async_closure_unlock_mutex_cb (gpointer user_data)
}
/**
- * camel_async_closure_wait:
+ * camel_async_closure_wait: (skip)
* @closure: a #CamelAsyncClosure
*
* Call this function immediately after starting an asynchronous operation.
@@ -136,7 +136,7 @@ camel_async_closure_wait (CamelAsyncClosure *closure)
}
/**
- * camel_async_closure_free:
+ * camel_async_closure_free: (skip)
* @closure: a #CamelAsyncClosure
*
* Frees the @closure and the resources it holds.
@@ -162,7 +162,7 @@ camel_async_closure_free (CamelAsyncClosure *closure)
}
/**
- * camel_async_closure_callback:
+ * camel_async_closure_callback: (skip)
* @source_object: a #GObject or %NULL
* @result: a #GAsyncResult
* @closure: a #CamelAsyncClosure
diff --git a/src/camel/camel-block-file.c b/src/camel/camel-block-file.c
index 92ec24b..c0b333f 100644
--- a/src/camel/camel-block-file.c
+++ b/src/camel/camel-block-file.c
@@ -44,6 +44,22 @@ struct _CamelBlockFilePrivate {
GMutex io_lock; /* for all io ops */
guint deleted : 1;
+
+ gchar version[8];
+ gchar *path;
+ CamelBlockFileFlags flags;
+
+ gint fd;
+ gsize block_size;
+
+ CamelBlockRoot *root;
+ CamelBlock *root_block;
+
+ /* make private? */
+ gint block_cache_limit;
+ gint block_cache_count;
+ GQueue block_cache;
+ GHashTable *blocks;
};
#define CAMEL_BLOCK_FILE_LOCK(kf, lock) (g_mutex_lock(&(kf)->priv->lock))
@@ -74,39 +90,39 @@ block_file_validate_root (CamelBlockFile *bs)
struct stat st;
gint retval;
- br = bs->root;
+ br = bs->priv->root;
- retval = fstat (bs->fd, &st);
+ retval = fstat (bs->priv->fd, &st);
- d (printf ("Validate root: '%s'\n", bs->path));
- d (printf ("version: %.8s (%.8s)\n", bs->root->version, bs->version));
+ d (printf ("Validate root: '%s'\n", bs->priv->path));
+ d (printf ("version: %.8s (%.8s)\n", bs->priv->root->version, bs->priv->version));
d (printf (
"block size: %d (%d)%s\n",
- br->block_size, bs->block_size,
- br->block_size != bs->block_size ? " BAD":" OK"));
+ br->block_size, bs->priv->block_size,
+ br->block_size != bs->priv->block_size ? " BAD":" OK"));
d (printf (
"free: %ld (%d add size < %ld)%s\n",
(glong) br->free,
- br->free / bs->block_size * bs->block_size,
+ br->free / bs->priv->block_size * bs->priv->block_size,
(glong) st.st_size,
(br->free > st.st_size) ||
- (br->free % bs->block_size) != 0 ? " BAD":" OK"));
+ (br->free % bs->priv->block_size) != 0 ? " BAD":" OK"));
d (printf (
"last: %ld (%d and size: %ld)%s\n",
(glong) br->last,
- br->last / bs->block_size * bs->block_size,
+ br->last / bs->priv->block_size * bs->priv->block_size,
(glong) st.st_size,
(br->last != st.st_size) ||
- ((br->last % bs->block_size) != 0) ? " BAD": " OK"));
+ ((br->last % bs->priv->block_size) != 0) ? " BAD": " OK"));
d (printf (
"flags: %s\n",
- (br->flags & CAMEL_BLOCK_FILE_SYNC) ? "SYNC" : "unSYNC"));
+ (br->priv->flags & CAMEL_BLOCK_FILE_SYNC) ? "SYNC" : "unSYNC"));
if (br->last == 0
- || memcmp (bs->root->version, bs->version, 8) != 0
- || br->block_size != bs->block_size
- || (br->free % bs->block_size) != 0
- || (br->last % bs->block_size) != 0
+ || memcmp (bs->priv->root->version, bs->priv->version, 8) != 0
+ || br->block_size != bs->priv->block_size
+ || (br->free % bs->priv->block_size) != 0
+ || (br->last % bs->priv->block_size) != 0
|| retval == -1
|| st.st_size != br->last
|| br->free > st.st_size
@@ -120,14 +136,14 @@ block_file_validate_root (CamelBlockFile *bs)
static gint
block_file_init_root (CamelBlockFile *bs)
{
- CamelBlockRoot *br = bs->root;
+ CamelBlockRoot *br = bs->priv->root;
- memset (br, 0, bs->block_size);
- memcpy (br->version, bs->version, 8);
- br->last = bs->block_size;
+ memset (br, 0, bs->priv->block_size);
+ memcpy (br->version, bs->priv->version, 8);
+ br->last = bs->priv->block_size;
br->flags = CAMEL_BLOCK_FILE_SYNC;
br->free = 0;
- br->block_size = bs->block_size;
+ br->block_size = bs->priv->block_size;
return 0;
}
@@ -138,13 +154,13 @@ block_file_finalize (GObject *object)
CamelBlockFile *bs = CAMEL_BLOCK_FILE (object);
CamelBlock *bl;
- if (bs->root_block)
+ if (bs->priv->root_block)
camel_block_file_sync (bs);
/* remove from lru list */
LOCK (block_file_lock);
- if (bs->fd != -1)
+ if (bs->priv->fd != -1)
block_file_count--;
/* XXX This is only supposed to be in one block file list
@@ -155,26 +171,24 @@ block_file_finalize (GObject *object)
UNLOCK (block_file_lock);
- while ((bl = g_queue_pop_head (&bs->block_cache)) != NULL) {
+ while ((bl = g_queue_pop_head (&bs->priv->block_cache)) != NULL) {
if (bl->refcount != 0)
g_warning ("Block '%u' still referenced", bl->id);
g_free (bl);
}
- g_hash_table_destroy (bs->blocks);
+ g_hash_table_destroy (bs->priv->blocks);
- if (bs->root_block)
- camel_block_file_unref_block (bs, bs->root_block);
- g_free (bs->path);
- if (bs->fd != -1)
- close (bs->fd);
+ if (bs->priv->root_block)
+ camel_block_file_unref_block (bs, bs->priv->root_block);
+ g_free (bs->priv->path);
+ if (bs->priv->fd != -1)
+ close (bs->priv->fd);
g_mutex_clear (&bs->priv->io_lock);
g_mutex_clear (&bs->priv->cache_lock);
g_mutex_clear (&bs->priv->root_lock);
- g_free (bs->priv);
-
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_block_file_parent_class)->finalize (object);
}
@@ -184,6 +198,8 @@ camel_block_file_class_init (CamelBlockFileClass *class)
{
GObjectClass *object_class;
+ g_type_class_add_private (class, sizeof (CamelBlockFilePrivate));
+
object_class = G_OBJECT_CLASS (class);
object_class->finalize = block_file_finalize;
@@ -200,15 +216,16 @@ block_hash_func (gconstpointer v)
static void
camel_block_file_init (CamelBlockFile *bs)
{
- bs->fd = -1;
- bs->block_size = CAMEL_BLOCK_SIZE;
- g_queue_init (&bs->block_cache);
- bs->blocks = g_hash_table_new ((GHashFunc) block_hash_func, NULL);
+ bs->priv = G_TYPE_INSTANCE_GET_PRIVATE (bs, CAMEL_TYPE_BLOCK_FILE, CamelBlockFilePrivate);
+
+ bs->priv->fd = -1;
+ bs->priv->block_size = CAMEL_BLOCK_SIZE;
+ g_queue_init (&bs->priv->block_cache);
+ bs->priv->blocks = g_hash_table_new ((GHashFunc) block_hash_func, NULL);
/* this cache size and the text index size have been tuned for about the best
* with moderate memory usage. Doubling the memory usage barely affects performance. */
- bs->block_cache_limit = 256;
+ bs->priv->block_cache_limit = 256;
- bs->priv = g_malloc0 (sizeof (*bs->priv));
bs->priv->base = bs;
g_mutex_init (&bs->priv->root_lock);
@@ -240,17 +257,17 @@ block_file_use (CamelBlockFile *bs)
CAMEL_BLOCK_FILE_LOCK (bs, io_lock);
- if (bs->fd != -1)
+ if (bs->priv->fd != -1)
return 0;
else if (bs->priv->deleted) {
CAMEL_BLOCK_FILE_UNLOCK (bs, io_lock);
errno = ENOENT;
return -1;
} else {
- d (printf ("Turning block file online: %s\n", bs->path));
+ d (printf ("Turning block file online: %s\n", bs->priv->path));
}
- if ((bs->fd = g_open (bs->path, bs->flags | O_BINARY, 0600)) == -1) {
+ if ((bs->priv->fd = g_open (bs->priv->path, bs->priv->flags | O_BINARY, 0600)) == -1) {
err = errno;
CAMEL_BLOCK_FILE_UNLOCK (bs, io_lock);
errno = err;
@@ -274,16 +291,16 @@ block_file_use (CamelBlockFile *bs)
/* We never hit the current blockfile here, as its removed from the list first */
bf = nw->base;
- if (bf->fd != -1) {
+ if (bf->priv->fd != -1) {
/* Need to trylock, as any of these lock levels might be trying
* to lock the block_file_lock, so we need to check and abort if so */
if (CAMEL_BLOCK_FILE_TRYLOCK (bf, root_lock)) {
if (CAMEL_BLOCK_FILE_TRYLOCK (bf, cache_lock)) {
if (CAMEL_BLOCK_FILE_TRYLOCK (bf, io_lock)) {
- d (printf ("[%d] Turning block file offline: %s\n",
block_file_count - 1, bf->path));
+ d (printf ("[%d] Turning block file offline: %s\n",
block_file_count - 1, bf->priv->path));
sync_nolock (bf);
- close (bf->fd);
- bf->fd = -1;
+ close (bf->priv->fd);
+ bf->priv->fd = -1;
block_file_count--;
CAMEL_BLOCK_FILE_UNLOCK (bf, io_lock);
}
@@ -348,20 +365,20 @@ camel_block_file_new (const gchar *path,
CamelBlockFile *bs;
bs = g_object_new (CAMEL_TYPE_BLOCK_FILE, NULL);
- memcpy (bs->version, version, 8);
- bs->path = g_strdup (path);
- bs->flags = flags;
+ memcpy (bs->priv->version, version, 8);
+ bs->priv->path = g_strdup (path);
+ bs->priv->flags = flags;
- bs->root_block = camel_block_file_get_block (bs, 0);
- if (bs->root_block == NULL) {
+ bs->priv->root_block = camel_block_file_get_block (bs, 0);
+ if (bs->priv->root_block == NULL) {
g_object_unref (bs);
return NULL;
}
- camel_block_file_detach_block (bs, bs->root_block);
- bs->root = (CamelBlockRoot *) &bs->root_block->data;
+ camel_block_file_detach_block (bs, bs->priv->root_block);
+ bs->priv->root = (CamelBlockRoot *) &bs->priv->root_block->data;
/* we only need these flags on first open */
- bs->flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
+ bs->priv->flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
class = CAMEL_BLOCK_FILE_GET_CLASS (bs);
@@ -370,13 +387,13 @@ camel_block_file_new (const gchar *path,
d (printf ("Initialise root block: %.8s\n", version));
class->init_root (bs);
- camel_block_file_touch_block (bs, bs->root_block);
+ camel_block_file_touch_block (bs, bs->priv->root_block);
if (block_file_use (bs) == -1) {
g_object_unref (bs);
return NULL;
}
- if (sync_block_nolock (bs, bs->root_block) == -1
- || ftruncate (bs->fd, bs->root->last) == -1) {
+ if (sync_block_nolock (bs, bs->priv->root_block) == -1
+ || ftruncate (bs->priv->fd, bs->priv->root->last) == -1) {
block_file_unuse (bs);
g_object_unref (bs);
return NULL;
@@ -387,6 +404,72 @@ camel_block_file_new (const gchar *path,
return bs;
}
+/**
+ * camel_block_file_get_root:
+ * @bs: a #CamelBlockFile
+ *
+ * Returns: (transfer none): A #CamelBlockRoot of @bs.
+ *
+ * Since: 3.24
+ **/
+CamelBlockRoot *
+camel_block_file_get_root (CamelBlockFile *bs)
+{
+ g_return_val_if_fail (CAMEL_IS_BLOCK_FILE (bs), NULL);
+
+ return bs->priv->root;
+}
+
+/**
+ * camel_block_file_get_root_block:
+ * @bs: a #CamelBlockFile
+ *
+ * Returns: (transfer none): A root #CamelBlock of @bs.
+ *
+ * Since: 3.24
+ **/
+CamelBlock *
+camel_block_file_get_root_block (CamelBlockFile *bs)
+{
+ g_return_val_if_fail (CAMEL_IS_BLOCK_FILE (bs), NULL);
+
+ return bs->priv->root_block;
+}
+
+/**
+ * camel_block_file_get_cache_limit:
+ * @bs: a #CamelBlockFile
+ *
+ * Returns: Current block cache limit of @bs.
+ *
+ * Since: 3.24
+ **/
+gint
+camel_block_file_get_cache_limit (CamelBlockFile *bs)
+{
+ g_return_val_if_fail (CAMEL_IS_BLOCK_FILE (bs), -1);
+
+ return bs->priv->block_cache_limit;
+}
+
+/**
+ * camel_block_file_set_cache_limit:
+ * @bs: a #CamelBlockFile
+ * @block_cache_limit: a new block cache limit to set
+ *
+ * Sets a new block cache limit for @bs.
+ *
+ * Since: 3.24
+ **/
+void
+camel_block_file_set_cache_limit (CamelBlockFile *bs,
+ gint block_cache_limit)
+{
+ g_return_if_fail (CAMEL_IS_BLOCK_FILE (bs));
+
+ bs->priv->block_cache_limit = block_cache_limit;
+}
+
gint
camel_block_file_rename (CamelBlockFile *bs,
const gchar *path)
@@ -400,20 +483,20 @@ camel_block_file_rename (CamelBlockFile *bs,
CAMEL_BLOCK_FILE_LOCK (bs, io_lock);
- ret = g_rename (bs->path, path);
+ ret = g_rename (bs->priv->path, path);
if (ret == -1) {
/* Maybe the rename actually worked */
err = errno;
if (g_stat (path, &st) == 0
- && g_stat (bs->path, &st) == -1
+ && g_stat (bs->priv->path, &st) == -1
&& errno == ENOENT)
ret = 0;
errno = err;
}
if (ret != -1) {
- g_free (bs->path);
- bs->path = g_strdup (path);
+ g_free (bs->priv->path);
+ bs->priv->path = g_strdup (path);
}
CAMEL_BLOCK_FILE_UNLOCK (bs, io_lock);
@@ -430,16 +513,16 @@ camel_block_file_delete (CamelBlockFile *bs)
CAMEL_BLOCK_FILE_LOCK (bs, io_lock);
- if (bs->fd != -1) {
+ if (bs->priv->fd != -1) {
LOCK (block_file_lock);
block_file_count--;
UNLOCK (block_file_lock);
- close (bs->fd);
- bs->fd = -1;
+ close (bs->priv->fd);
+ bs->priv->fd = -1;
}
bs->priv->deleted = TRUE;
- ret = g_unlink (bs->path);
+ ret = g_unlink (bs->priv->path);
CAMEL_BLOCK_FILE_UNLOCK (bs, io_lock);
@@ -448,7 +531,7 @@ camel_block_file_delete (CamelBlockFile *bs)
}
/**
- * camel_block_file_new_block:
+ * camel_block_file_new_block: (skip)
* @bs:
*
* Allocate a new block, return a pointer to it. Old blocks
@@ -465,19 +548,19 @@ camel_block_file_new_block (CamelBlockFile *bs)
CAMEL_BLOCK_FILE_LOCK (bs, root_lock);
- if (bs->root->free) {
- bl = camel_block_file_get_block (bs, bs->root->free);
+ if (bs->priv->root->free) {
+ bl = camel_block_file_get_block (bs, bs->priv->root->free);
if (bl == NULL)
goto fail;
- bs->root->free = ((camel_block_t *) bl->data)[0];
+ bs->priv->root->free = ((camel_block_t *) bl->data)[0];
} else {
- bl = camel_block_file_get_block (bs, bs->root->last);
+ bl = camel_block_file_get_block (bs, bs->priv->root->last);
if (bl == NULL)
goto fail;
- bs->root->last += CAMEL_BLOCK_SIZE;
+ bs->priv->root->last += CAMEL_BLOCK_SIZE;
}
- bs->root_block->flags |= CAMEL_BLOCK_DIRTY;
+ bs->priv->root_block->flags |= CAMEL_BLOCK_DIRTY;
bl->flags |= CAMEL_BLOCK_DIRTY;
memset (bl->data, 0, CAMEL_BLOCK_SIZE);
@@ -508,9 +591,9 @@ camel_block_file_free_block (CamelBlockFile *bs,
CAMEL_BLOCK_FILE_LOCK (bs, root_lock);
- ((camel_block_t *) bl->data)[0] = bs->root->free;
- bs->root->free = bl->id;
- bs->root_block->flags |= CAMEL_BLOCK_DIRTY;
+ ((camel_block_t *) bl->data)[0] = bs->priv->root->free;
+ bs->priv->root->free = bl->id;
+ bs->priv->root_block->flags |= CAMEL_BLOCK_DIRTY;
bl->flags |= CAMEL_BLOCK_DIRTY;
camel_block_file_unref_block (bs, bl);
@@ -520,7 +603,7 @@ camel_block_file_free_block (CamelBlockFile *bs,
}
/**
- * camel_block_file_get_block:
+ * camel_block_file_get_block: (skip)
* @bs:
* @id:
*
@@ -539,16 +622,16 @@ camel_block_file_get_block (CamelBlockFile *bs,
/* Sanity check: Dont allow reading of root block (except before its been read)
* or blocks with invalid block id's */
- if ((bs->root == NULL && id != 0)
- || (bs->root != NULL && (id > bs->root->last || id == 0))
- || (id % bs->block_size) != 0) {
+ if ((bs->priv->root == NULL && id != 0)
+ || (bs->priv->root != NULL && (id > bs->priv->root->last || id == 0))
+ || (id % bs->priv->block_size) != 0) {
errno = EINVAL;
return NULL;
}
CAMEL_BLOCK_FILE_LOCK (bs, cache_lock);
- bl = g_hash_table_lookup (bs->blocks, GUINT_TO_POINTER (id));
+ bl = g_hash_table_lookup (bs->priv->blocks, GUINT_TO_POINTER (id));
d (printf ("Get block %08x: %s\n", id, bl?"cached":"must read"));
@@ -564,30 +647,30 @@ camel_block_file_get_block (CamelBlockFile *bs,
bl = g_malloc0 (sizeof (*bl));
bl->id = id;
- if (lseek (bs->fd, id, SEEK_SET) == -1 ||
- camel_read (bs->fd, (gchar *) bl->data, CAMEL_BLOCK_SIZE, NULL, NULL) == -1) {
+ if (lseek (bs->priv->fd, id, SEEK_SET) == -1 ||
+ camel_read (bs->priv->fd, (gchar *) bl->data, CAMEL_BLOCK_SIZE, NULL, NULL) == -1) {
block_file_unuse (bs);
CAMEL_BLOCK_FILE_UNLOCK (bs, cache_lock);
g_free (bl);
return NULL;
}
- bs->block_cache_count++;
- g_hash_table_insert (bs->blocks, GUINT_TO_POINTER (bl->id), bl);
+ bs->priv->block_cache_count++;
+ g_hash_table_insert (bs->priv->blocks, GUINT_TO_POINTER (bl->id), bl);
/* flush old blocks */
- link = g_queue_peek_tail_link (&bs->block_cache);
+ link = g_queue_peek_tail_link (&bs->priv->block_cache);
- while (link != NULL && bs->block_cache_count > bs->block_cache_limit) {
+ while (link != NULL && bs->priv->block_cache_count > bs->priv->block_cache_limit) {
CamelBlock *flush = link->data;
if (flush->refcount == 0) {
if (sync_block_nolock (bs, flush) != -1) {
- g_hash_table_remove (bs->blocks, GUINT_TO_POINTER (flush->id));
+ g_hash_table_remove (bs->priv->blocks, GUINT_TO_POINTER (flush->id));
g_queue_push_tail (&trash, link);
link->data = NULL;
g_free (flush);
- bs->block_cache_count--;
+ bs->priv->block_cache_count--;
}
}
@@ -596,15 +679,15 @@ camel_block_file_get_block (CamelBlockFile *bs,
/* Remove deleted blocks from the cache. */
while ((link = g_queue_pop_head (&trash)) != NULL)
- g_queue_delete_link (&bs->block_cache, link);
+ g_queue_delete_link (&bs->priv->block_cache, link);
/* UNLOCK io_lock */
block_file_unuse (bs);
} else {
- g_queue_remove (&bs->block_cache, bl);
+ g_queue_remove (&bs->priv->block_cache, bl);
}
- g_queue_push_head (&bs->block_cache, bl);
+ g_queue_push_head (&bs->priv->block_cache, bl);
bl->refcount++;
CAMEL_BLOCK_FILE_UNLOCK (bs, cache_lock);
@@ -633,8 +716,8 @@ camel_block_file_detach_block (CamelBlockFile *bs,
CAMEL_BLOCK_FILE_LOCK (bs, cache_lock);
- g_hash_table_remove (bs->blocks, GUINT_TO_POINTER (bl->id));
- g_queue_remove (&bs->block_cache, bl);
+ g_hash_table_remove (bs->priv->blocks, GUINT_TO_POINTER (bl->id));
+ g_queue_remove (&bs->priv->block_cache, bl);
bl->flags |= CAMEL_BLOCK_DETACHED;
CAMEL_BLOCK_FILE_UNLOCK (bs, cache_lock);
@@ -656,8 +739,8 @@ camel_block_file_attach_block (CamelBlockFile *bs,
CAMEL_BLOCK_FILE_LOCK (bs, cache_lock);
- g_hash_table_insert (bs->blocks, GUINT_TO_POINTER (bl->id), bl);
- g_queue_push_tail (&bs->block_cache, bl);
+ g_hash_table_insert (bs->priv->blocks, GUINT_TO_POINTER (bl->id), bl);
+ g_queue_push_tail (&bs->priv->block_cache, bl);
bl->flags &= ~CAMEL_BLOCK_DETACHED;
CAMEL_BLOCK_FILE_UNLOCK (bs, cache_lock);
@@ -683,11 +766,11 @@ camel_block_file_touch_block (CamelBlockFile *bs,
bl->flags |= CAMEL_BLOCK_DIRTY;
- if ((bs->root->flags & CAMEL_BLOCK_FILE_SYNC) && bl != bs->root_block) {
+ if ((bs->priv->root->flags & CAMEL_BLOCK_FILE_SYNC) && bl != bs->priv->root_block) {
d (printf ("turning off sync flag\n"));
- bs->root->flags &= ~CAMEL_BLOCK_FILE_SYNC;
- bs->root_block->flags |= CAMEL_BLOCK_DIRTY;
- camel_block_file_sync_block (bs, bs->root_block);
+ bs->priv->root->flags &= ~CAMEL_BLOCK_FILE_SYNC;
+ bs->priv->root_block->flags |= CAMEL_BLOCK_DIRTY;
+ camel_block_file_sync_block (bs, bs->priv->root_block);
}
CAMEL_BLOCK_FILE_UNLOCK (bs, cache_lock);
@@ -726,11 +809,11 @@ static gint
sync_block_nolock (CamelBlockFile *bs,
CamelBlock *bl)
{
- d (printf ("Sync block %08x: %s\n", bl->id, (bl->flags & CAMEL_BLOCK_DIRTY)?"dirty":"clean"));
+ d (printf ("Sync block %08x: %s\n", bl->id, (bl->priv->flags & CAMEL_BLOCK_DIRTY)?"dirty":"clean"));
if (bl->flags & CAMEL_BLOCK_DIRTY) {
- if (lseek (bs->fd, bl->id, SEEK_SET) == -1
- || write (bs->fd, bl->data, CAMEL_BLOCK_SIZE) != CAMEL_BLOCK_SIZE) {
+ if (lseek (bs->priv->fd, bl->id, SEEK_SET) == -1
+ || write (bs->priv->fd, bl->data, CAMEL_BLOCK_SIZE) != CAMEL_BLOCK_SIZE) {
return -1;
}
bl->flags &= ~CAMEL_BLOCK_DIRTY;
@@ -745,7 +828,7 @@ sync_nolock (CamelBlockFile *bs)
GList *head, *link;
gint work = FALSE;
- head = g_queue_peek_head_link (&bs->block_cache);
+ head = g_queue_peek_head_link (&bs->priv->block_cache);
for (link = head; link != NULL; link = g_list_next (link)) {
CamelBlock *bl = link->data;
@@ -758,16 +841,16 @@ sync_nolock (CamelBlockFile *bs)
}
if (!work
- && (bs->root_block->flags & CAMEL_BLOCK_DIRTY) == 0
- && (bs->root->flags & CAMEL_BLOCK_FILE_SYNC) != 0)
+ && (bs->priv->root_block->flags & CAMEL_BLOCK_DIRTY) == 0
+ && (bs->priv->root->flags & CAMEL_BLOCK_FILE_SYNC) != 0)
return 0;
d (printf ("turning on sync flag\n"));
- bs->root->flags |= CAMEL_BLOCK_FILE_SYNC;
- bs->root_block->flags |= CAMEL_BLOCK_DIRTY;
+ bs->priv->root->flags |= CAMEL_BLOCK_FILE_SYNC;
+ bs->priv->root_block->flags |= CAMEL_BLOCK_DIRTY;
- return sync_block_nolock (bs, bs->root_block);
+ return sync_block_nolock (bs, bs->priv->root_block);
}
/**
@@ -838,6 +921,11 @@ struct _CamelKeyFilePrivate {
struct _CamelKeyFile *base;
GMutex lock;
guint deleted : 1;
+
+ FILE *fp;
+ gchar *path;
+ gint flags;
+ goffset last;
};
#define CAMEL_KEY_FILE_LOCK(kf, lock) (g_mutex_lock(&(kf)->priv->lock))
@@ -857,28 +945,26 @@ G_DEFINE_TYPE (CamelKeyFile, camel_key_file, G_TYPE_OBJECT)
static void
key_file_finalize (GObject *object)
{
- CamelKeyFile *bs = CAMEL_KEY_FILE (object);
+ CamelKeyFile *kf = CAMEL_KEY_FILE (object);
LOCK (key_file_lock);
/* XXX This is only supposed to be in one key file list
* at a time, but not sure if we can guarantee which,
* so try removing from both lists. */
- g_queue_remove (&key_file_list, bs->priv);
- g_queue_remove (&key_file_active_list, bs->priv);
+ g_queue_remove (&key_file_list, kf->priv);
+ g_queue_remove (&key_file_active_list, kf->priv);
- if (bs-> fp) {
+ if (kf->priv->fp) {
key_file_count--;
- fclose (bs->fp);
+ fclose (kf->priv->fp);
}
UNLOCK (key_file_lock);
- g_free (bs->path);
-
- g_mutex_clear (&bs->priv->lock);
+ g_free (kf->priv->path);
- g_free (bs->priv);
+ g_mutex_clear (&kf->priv->lock);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_key_file_parent_class)->finalize (object);
@@ -889,28 +975,30 @@ camel_key_file_class_init (CamelKeyFileClass *class)
{
GObjectClass *object_class;
+ g_type_class_add_private (class, sizeof (CamelKeyFilePrivate));
+
object_class = G_OBJECT_CLASS (class);
object_class->finalize = key_file_finalize;
}
static void
-camel_key_file_init (CamelKeyFile *bs)
+camel_key_file_init (CamelKeyFile *kf)
{
- bs->priv = g_malloc0 (sizeof (*bs->priv));
- bs->priv->base = bs;
+ kf->priv = G_TYPE_INSTANCE_GET_PRIVATE (kf, CAMEL_TYPE_KEY_FILE, CamelKeyFilePrivate);
+ kf->priv->base = kf;
- g_mutex_init (&bs->priv->lock);
+ g_mutex_init (&kf->priv->lock);
LOCK (key_file_lock);
- g_queue_push_head (&key_file_list, bs->priv);
+ g_queue_push_head (&key_file_list, kf->priv);
UNLOCK (key_file_lock);
}
/* 'use' a key file for io */
static gint
-key_file_use (CamelKeyFile *bs)
+key_file_use (CamelKeyFile *ks)
{
- CamelKeyFile *bf;
+ CamelKeyFile *kf;
gint err, fd;
const gchar *flag;
GList *link;
@@ -926,36 +1014,36 @@ key_file_use (CamelKeyFile *bs)
/* TODO: Check header on reset? */
- CAMEL_KEY_FILE_LOCK (bs, lock);
+ CAMEL_KEY_FILE_LOCK (ks, lock);
- if (bs->fp != NULL)
+ if (ks->priv->fp != NULL)
return 0;
- else if (bs->priv->deleted) {
- CAMEL_KEY_FILE_UNLOCK (bs, lock);
+ else if (ks->priv->deleted) {
+ CAMEL_KEY_FILE_UNLOCK (ks, lock);
errno = ENOENT;
return -1;
} else {
- d (printf ("Turning key file online: '%s'\n", bs->path));
+ d (printf ("Turning key file online: '%s'\n", bs->priv->path));
}
- if ((bs->flags & O_ACCMODE) == O_RDONLY)
+ if ((ks->priv->flags & O_ACCMODE) == O_RDONLY)
flag = "rb";
else
flag = "a+b";
- if ((fd = g_open (bs->path, bs->flags | O_BINARY, 0600)) == -1
- || (bs->fp = fdopen (fd, flag)) == NULL) {
+ if ((fd = g_open (ks->priv->path, ks->priv->flags | O_BINARY, 0600)) == -1
+ || (ks->priv->fp = fdopen (fd, flag)) == NULL) {
err = errno;
if (fd != -1)
close (fd);
- CAMEL_KEY_FILE_UNLOCK (bs, lock);
+ CAMEL_KEY_FILE_UNLOCK (ks, lock);
errno = err;
return -1;
}
LOCK (key_file_lock);
- link = g_queue_find (&key_file_list, bs->priv);
+ link = g_queue_find (&key_file_list, ks->priv);
if (link != NULL) {
g_queue_unlink (&key_file_list, link);
g_queue_push_tail_link (&key_file_active_list, link);
@@ -968,16 +1056,16 @@ key_file_use (CamelKeyFile *bs)
struct _CamelKeyFilePrivate *nw = link->data;
/* We never hit the current keyfile here, as its removed from the list first */
- bf = nw->base;
- if (bf->fp != NULL) {
+ kf = nw->base;
+ if (kf->priv->fp != NULL) {
/* Need to trylock, as any of these lock levels might be trying
* to lock the key_file_lock, so we need to check and abort if so */
- if (CAMEL_BLOCK_FILE_TRYLOCK (bf, lock)) {
- d (printf ("Turning key file offline: %s\n", bf->path));
- fclose (bf->fp);
- bf->fp = NULL;
+ if (CAMEL_BLOCK_FILE_TRYLOCK (kf, lock)) {
+ d (printf ("Turning key file offline: %s\n", kf->priv->path));
+ fclose (kf->priv->fp);
+ kf->priv->fp = NULL;
key_file_count--;
- CAMEL_BLOCK_FILE_UNLOCK (bf, lock);
+ CAMEL_BLOCK_FILE_UNLOCK (kf, lock);
}
}
@@ -990,19 +1078,19 @@ key_file_use (CamelKeyFile *bs)
}
static void
-key_file_unuse (CamelKeyFile *bs)
+key_file_unuse (CamelKeyFile *kf)
{
GList *link;
LOCK (key_file_lock);
- link = g_queue_find (&key_file_active_list, bs->priv);
+ link = g_queue_find (&key_file_active_list, kf->priv);
if (link != NULL) {
g_queue_unlink (&key_file_active_list, link);
g_queue_push_tail_link (&key_file_list, link);
}
UNLOCK (key_file_lock);
- CAMEL_KEY_FILE_UNLOCK (bs, lock);
+ CAMEL_KEY_FILE_UNLOCK (kf, lock);
}
/**
@@ -1029,28 +1117,28 @@ camel_key_file_new (const gchar *path,
d (printf ("New key file '%s'\n", path));
kf = g_object_new (CAMEL_TYPE_KEY_FILE, NULL);
- kf->path = g_strdup (path);
- kf->fp = NULL;
- kf->flags = flags;
- kf->last = 8;
+ kf->priv->path = g_strdup (path);
+ kf->priv->fp = NULL;
+ kf->priv->flags = flags;
+ kf->priv->last = 8;
if (key_file_use (kf) == -1) {
g_object_unref (kf);
kf = NULL;
} else {
- fseek (kf->fp, 0, SEEK_END);
- last = ftell (kf->fp);
+ fseek (kf->priv->fp, 0, SEEK_END);
+ last = ftell (kf->priv->fp);
if (last == 0) {
- fwrite (version, sizeof (gchar), 8, kf->fp);
+ fwrite (version, sizeof (gchar), 8, kf->priv->fp);
last += 8;
}
- kf->last = last;
+ kf->priv->last = last;
- err = ferror (kf->fp);
+ err = ferror (kf->priv->fp);
key_file_unuse (kf);
/* we only need these flags on first open */
- kf->flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
+ kf->priv->flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
if (err) {
g_object_unref (kf);
@@ -1074,20 +1162,20 @@ camel_key_file_rename (CamelKeyFile *kf,
CAMEL_KEY_FILE_LOCK (kf, lock);
- ret = g_rename (kf->path, path);
+ ret = g_rename (kf->priv->path, path);
if (ret == -1) {
/* Maybe the rename actually worked */
err = errno;
if (g_stat (path, &st) == 0
- && g_stat (kf->path, &st) == -1
+ && g_stat (kf->priv->path, &st) == -1
&& errno == ENOENT)
ret = 0;
errno = err;
}
if (ret != -1) {
- g_free (kf->path);
- kf->path = g_strdup (path);
+ g_free (kf->priv->path);
+ kf->priv->path = g_strdup (path);
}
CAMEL_KEY_FILE_UNLOCK (kf, lock);
@@ -1104,16 +1192,16 @@ camel_key_file_delete (CamelKeyFile *kf)
CAMEL_KEY_FILE_LOCK (kf, lock);
- if (kf->fp) {
+ if (kf->priv->fp) {
LOCK (key_file_lock);
key_file_count--;
UNLOCK (key_file_lock);
- fclose (kf->fp);
- kf->fp = NULL;
+ fclose (kf->priv->fp);
+ kf->priv->fp = NULL;
}
kf->priv->deleted = TRUE;
- ret = g_unlink (kf->path);
+ ret = g_unlink (kf->priv->path);
CAMEL_KEY_FILE_UNLOCK (kf, lock);
@@ -1160,18 +1248,18 @@ camel_key_file_write (CamelKeyFile *kf,
size = len;
/* FIXME: Use io util functions? */
- next = kf->last;
- if (fseek (kf->fp, kf->last, SEEK_SET) == -1)
+ next = kf->priv->last;
+ if (fseek (kf->priv->fp, kf->priv->last, SEEK_SET) == -1)
return -1;
- fwrite (parent, sizeof (*parent), 1, kf->fp);
- fwrite (&size, sizeof (size), 1, kf->fp);
- fwrite (records, sizeof (records[0]), len, kf->fp);
+ fwrite (parent, sizeof (*parent), 1, kf->priv->fp);
+ fwrite (&size, sizeof (size), 1, kf->priv->fp);
+ fwrite (records, sizeof (records[0]), len, kf->priv->fp);
- if (ferror (kf->fp)) {
- clearerr (kf->fp);
+ if (ferror (kf->priv->fp)) {
+ clearerr (kf->priv->fp);
} else {
- kf->last = ftell (kf->fp);
+ kf->priv->last = ftell (kf->priv->fp);
*parent = next;
ret = len;
}
@@ -1218,11 +1306,11 @@ camel_key_file_read (CamelKeyFile *kf,
if (key_file_use (kf) == -1)
return -1;
- if (fseek (kf->fp, pos, SEEK_SET) == -1
- || fread (&next, sizeof (next), 1, kf->fp) != 1
- || fread (&size, sizeof (size), 1, kf->fp) != 1
+ if (fseek (kf->priv->fp, pos, SEEK_SET) == -1
+ || fread (&next, sizeof (next), 1, kf->priv->fp) != 1
+ || fread (&size, sizeof (size), 1, kf->priv->fp) != 1
|| size > 1024) {
- clearerr (kf->fp);
+ clearerr (kf->priv->fp);
goto fail;
}
@@ -1232,7 +1320,7 @@ camel_key_file_read (CamelKeyFile *kf,
if (records) {
camel_key_t *keys = g_malloc (size * sizeof (camel_key_t));
- if (fread (keys, sizeof (camel_key_t), size, kf->fp) != size) {
+ if (fread (keys, sizeof (camel_key_t), size, kf->priv->fp) != size) {
g_free (keys);
goto fail;
}
diff --git a/src/camel/camel-block-file.h b/src/camel/camel-block-file.h
index 9c02075..3a3e8da 100644
--- a/src/camel/camel-block-file.h
+++ b/src/camel/camel-block-file.h
@@ -112,22 +112,6 @@ struct _CamelBlock {
struct _CamelBlockFile {
GObject parent;
CamelBlockFilePrivate *priv;
-
- gchar version[8];
- gchar *path;
- CamelBlockFileFlags flags;
-
- gint fd;
- gsize block_size;
-
- CamelBlockRoot *root;
- CamelBlock *root_block;
-
- /* make private? */
- gint block_cache_limit;
- gint block_cache_count;
- GQueue block_cache;
- GHashTable *blocks;
};
struct _CamelBlockFileClass {
@@ -135,6 +119,9 @@ struct _CamelBlockFileClass {
gint (*validate_root)(CamelBlockFile *bs);
gint (*init_root)(CamelBlockFile *bs);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_block_file_get_type (void);
@@ -142,6 +129,11 @@ CamelBlockFile *camel_block_file_new (const gchar *path,
gint flags,
const gchar version[8],
gsize block_size);
+CamelBlockRoot *camel_block_file_get_root (CamelBlockFile *bs);
+CamelBlock * camel_block_file_get_root_block (CamelBlockFile *bs);
+gint camel_block_file_get_cache_limit(CamelBlockFile *bs);
+void camel_block_file_set_cache_limit(CamelBlockFile *bs,
+ gint block_cache_limit);
gint camel_block_file_rename (CamelBlockFile *bs,
const gchar *path);
gint camel_block_file_delete (CamelBlockFile *kf);
@@ -171,15 +163,13 @@ typedef struct _CamelKeyFilePrivate CamelKeyFilePrivate;
struct _CamelKeyFile {
GObject parent;
CamelKeyFilePrivate *priv;
-
- FILE *fp;
- gchar *path;
- gint flags;
- goffset last;
};
struct _CamelKeyFileClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_key_file_get_type (void);
diff --git a/src/camel/camel-certdb.h b/src/camel/camel-certdb.h
index 6f0b092..cf289f7 100644
--- a/src/camel/camel-certdb.h
+++ b/src/camel/camel-certdb.h
@@ -91,6 +91,9 @@ struct _CamelCertDBClass {
gint (*cert_save) (CamelCertDB *certdb,
CamelCert *cert,
FILE *ostream);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_cert_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-charset-map.c b/src/camel/camel-charset-map.c
index 38f4167..1e765c3 100644
--- a/src/camel/camel-charset-map.c
+++ b/src/camel/camel-charset-map.c
@@ -316,6 +316,10 @@ camel_charset_init (CamelCharset *c)
c->level = 0;
}
+/**
+ * camel_charset_step:
+ * @in: (array length=len) (type gchar):
+ **/
void
camel_charset_step (CamelCharset *cc,
const gchar *in,
@@ -381,7 +385,13 @@ camel_charset_best_name (CamelCharset *charset)
return NULL;
}
-/* finds the minimum charset for this string NULL means US-ASCII */
+/**
+ * camel_charset_best:
+ * @in: (array length=len) (type gchar):
+ *
+ * finds the minimum charset for this string NULL means US-ASCII
+ * Returns: (nullable): the minimum charset or NULL for US_ASCII.
+ **/
const gchar *
camel_charset_best (const gchar *in,
gint len)
diff --git a/src/camel/camel-cipher-context.c b/src/camel/camel-cipher-context.c
index 80bcc6c..d05a866 100644
--- a/src/camel/camel-cipher-context.c
+++ b/src/camel/camel-cipher-context.c
@@ -1179,6 +1179,13 @@ camel_cipher_validity_add_certinfo (CamelCipherValidity *vin,
/**
* camel_cipher_validity_add_certinfo_ex:
+ * @vin: a #CamelCipherValidity
+ * @mode: a #CamelCipherValidityMode, where to add the additional certificate information
+ * @name: a name to add
+ * @email: an e-mail address to add
+ * @cert_data: (nullable) (destroy cert_data_free): a certificate data, or %NULL
+ * @cert_data_free: (nullable): a destroy function for @cert_data; required, when @cert_data is not %NULL
+ * @cert_data_clone: (nullable) (scope call): a copy function for @cert_data, to copy the data; required,
when @cert_data is not %NULL
*
* Add a cert info to the signer or encrypter info, with extended data set.
*
@@ -1232,7 +1239,7 @@ camel_cipher_validity_add_certinfo_ex (CamelCipherValidity *vin,
*
* Gets a named property @name value for the given @info_index of the @mode validity part.
*
- * Returns: Value of a named property of a #CamelCipherCertInfo, or %NULL when no such
+ * Returns: (transfer none) (nullable): Value of a named property of a #CamelCipherCertInfo, or %NULL when
no such
* property exists. The returned value is owned by the associated #CamelCipherCertInfo
* and is valid until the cert info is freed.
*
@@ -1270,9 +1277,9 @@ camel_cipher_validity_get_certinfo_property (CamelCipherValidity *vin,
* @mode: which cipher validity part to use
* @info_index: a 0-based index of the requested #CamelCipherCertInfo
* @name: a property name
- * @value: (nullable): a property value, or %NULL
+ * @value: (nullable) (destroy value_free): a property value, or %NULL
* @value_free: (nullable): a free function for the @value
- * @value_clone: (nullable): a clone function for the @value
+ * @value_clone: (nullable) (scope call): a clone function for the @value
*
* Sets a named property @name value @value for the given @info_index
* of the @mode validity part. If the @value is %NULL, then the property
@@ -1399,9 +1406,9 @@ camel_cipher_validity_free (CamelCipherValidity *validity)
*
* Gets a named property @name value for the given @cert_info.
*
- * Returns: Value of a named property of the @cert_info, or %NULL when no such
- * property exists. The returned value is owned by the @cert_info
- * and is valid until the @cert_info is freed.
+ * Returns: (transfer none) (nullable): Value of a named property of the @cert_info,
+ * or %NULL when no such property exists. The returned value is owned by
+ * the @cert_info and is valid until the @cert_info is freed.
*
* Since: 3.22
**/
@@ -1428,9 +1435,9 @@ camel_cipher_certinfo_get_property (CamelCipherCertInfo *cert_info,
* camel_cipher_certinfo_set_property:
* @cert_info: a #CamelCipherCertInfo
* @name: a property name
- * @value: (nullable): a property value, or %NULL
+ * @value: (nullable) (destroy value_free): a property value, or %NULL
* @value_free: (nullable): a free function for the @value
- * @value_clone: (nullable): a clone function for the @value
+ * @value_clone: (nullable) (scope call): a clone function for the @value
*
* Sets a named property @name value @value for the given @cert_info.
* If the @value is %NULL, then the property is removed. With a non-%NULL
diff --git a/src/camel/camel-cipher-context.h b/src/camel/camel-cipher-context.h
index 191a24d..6ad74b6 100644
--- a/src/camel/camel-cipher-context.h
+++ b/src/camel/camel-cipher-context.h
@@ -182,8 +182,8 @@ struct _CamelCipherContextClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots. */
- gpointer reserved[8];
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_cipher_context_get_type (void);
diff --git a/src/camel/camel-data-cache.h b/src/camel/camel-data-cache.h
index 97a468e..3d616ee 100644
--- a/src/camel/camel-data-cache.h
+++ b/src/camel/camel-data-cache.h
@@ -59,6 +59,9 @@ struct _CamelDataCache {
struct _CamelDataCacheClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_data_cache_get_type (void);
diff --git a/src/camel/camel-data-wrapper.c b/src/camel/camel-data-wrapper.c
index 1da5026..68c6093 100644
--- a/src/camel/camel-data-wrapper.c
+++ b/src/camel/camel-data-wrapper.c
@@ -29,6 +29,7 @@
#include "camel-mime-filter-crlf.h"
#include "camel-stream-filter.h"
#include "camel-stream-mem.h"
+#include "camel-stream-null.h"
#define d(x)
@@ -41,6 +42,12 @@ typedef struct _AsyncContext AsyncContext;
struct _CamelDataWrapperPrivate {
GMutex stream_lock;
GByteArray *byte_array;
+
+ CamelTransferEncoding encoding;
+
+ CamelContentType *mime_type;
+
+ guint offline : 1;
};
struct _AsyncContext {
@@ -66,9 +73,9 @@ data_wrapper_dispose (GObject *object)
{
CamelDataWrapper *data_wrapper = CAMEL_DATA_WRAPPER (object);
- if (data_wrapper->mime_type != NULL) {
- camel_content_type_unref (data_wrapper->mime_type);
- data_wrapper->mime_type = NULL;
+ if (data_wrapper->priv->mime_type != NULL) {
+ camel_content_type_unref (data_wrapper->priv->mime_type);
+ data_wrapper->priv->mime_type = NULL;
}
/* Chain up to parent's dispose() method. */
@@ -93,21 +100,21 @@ static void
data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
const gchar *mime_type)
{
- if (data_wrapper->mime_type)
- camel_content_type_unref (data_wrapper->mime_type);
- data_wrapper->mime_type = camel_content_type_decode (mime_type);
+ if (data_wrapper->priv->mime_type)
+ camel_content_type_unref (data_wrapper->priv->mime_type);
+ data_wrapper->priv->mime_type = camel_content_type_decode (mime_type);
}
static gchar *
data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper)
{
- return camel_content_type_simple (data_wrapper->mime_type);
+ return camel_content_type_simple (data_wrapper->priv->mime_type);
}
static CamelContentType *
data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper)
{
- return data_wrapper->mime_type;
+ return data_wrapper->priv->mime_type;
}
static void
@@ -116,15 +123,15 @@ data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
{
if (mime_type)
camel_content_type_ref (mime_type);
- if (data_wrapper->mime_type)
- camel_content_type_unref (data_wrapper->mime_type);
- data_wrapper->mime_type = mime_type;
+ if (data_wrapper->priv->mime_type)
+ camel_content_type_unref (data_wrapper->priv->mime_type);
+ data_wrapper->priv->mime_type = mime_type;
}
static gboolean
data_wrapper_is_offline (CamelDataWrapper *data_wrapper)
{
- return data_wrapper->offline;
+ return data_wrapper->priv->offline;
}
static gssize
@@ -173,7 +180,7 @@ data_wrapper_decode_to_stream_sync (CamelDataWrapper *data_wrapper,
fstream = camel_stream_filter_new (stream);
- switch (data_wrapper->encoding) {
+ switch (data_wrapper->priv->encoding) {
case CAMEL_TRANSFER_ENCODING_BASE64:
filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
@@ -290,7 +297,7 @@ data_wrapper_decode_to_output_stream_sync (CamelDataWrapper *data_wrapper,
gboolean content_type_is_text;
gssize bytes_written;
- switch (data_wrapper->encoding) {
+ switch (data_wrapper->priv->encoding) {
case CAMEL_TRANSFER_ENCODING_BASE64:
filter = camel_mime_filter_basic_new (
CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
@@ -325,10 +332,8 @@ data_wrapper_decode_to_output_stream_sync (CamelDataWrapper *data_wrapper,
}
content_type_is_text =
- camel_content_type_is (
- data_wrapper->mime_type, "text", "*") &&
- !camel_content_type_is (
- data_wrapper->mime_type, "text", "pdf");
+ camel_content_type_is (data_wrapper->priv->mime_type, "text", "*") &&
+ !camel_content_type_is (data_wrapper->priv->mime_type, "text", "pdf");
if (content_type_is_text) {
GOutputStream *temp_stream;
@@ -444,10 +449,9 @@ camel_data_wrapper_init (CamelDataWrapper *data_wrapper)
g_mutex_init (&data_wrapper->priv->stream_lock);
data_wrapper->priv->byte_array = g_byte_array_new ();
- data_wrapper->mime_type = camel_content_type_new (
- "application", "octet-stream");
- data_wrapper->encoding = CAMEL_TRANSFER_ENCODING_DEFAULT;
- data_wrapper->offline = FALSE;
+ data_wrapper->priv->mime_type = camel_content_type_new ("application", "octet-stream");
+ data_wrapper->priv->encoding = CAMEL_TRANSFER_ENCODING_DEFAULT;
+ data_wrapper->priv->offline = FALSE;
}
/**
@@ -484,6 +488,41 @@ camel_data_wrapper_get_byte_array (CamelDataWrapper *data_wrapper)
}
/**
+ * camel_data_wrapper_get_encoding:
+ * @data_wrapper: a #CamelDataWrapper
+ *
+ * Returns: An encoding (#CamelTransferEncoding) of the @data_wrapper
+ *
+ * Since: 3.24
+ **/
+CamelTransferEncoding
+camel_data_wrapper_get_encoding (CamelDataWrapper *data_wrapper)
+{
+ g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), CAMEL_TRANSFER_ENCODING_DEFAULT);
+
+ return data_wrapper->priv->encoding;
+}
+
+/**
+ * camel_data_wrapper_set_encoding:
+ * @data_wrapper: a #CamelDataWrapper
+ * @encoding: an encoding to set
+ *
+ * Sets encoding (#CamelTransferEncoding) for the @data_wrapper.
+ * It doesn't re-encode the content, if the encoding changes.
+ *
+ * Since: 3.24
+ **/
+void
+camel_data_wrapper_set_encoding (CamelDataWrapper *data_wrapper,
+ CamelTransferEncoding encoding)
+{
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+
+ data_wrapper->priv->encoding = encoding;
+}
+
+/**
* camel_data_wrapper_set_mime_type:
* @data_wrapper: a #CamelDataWrapper
* @mime_type: a MIME type
@@ -552,10 +591,12 @@ camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper)
/**
* camel_data_wrapper_set_mime_type_field:
* @data_wrapper: a #CamelDataWrapper
- * @mime_type: a #CamelContentType
+ * @mime_type: (nullable): a #CamelContentType
+ *
+ * This sets the data wrapper's MIME type. It adds its own reference
+ * to @mime_type, if not %NULL.
*
- * This sets the data wrapper's MIME type. It suffers from the same
- * flaws as camel_data_wrapper_set_mime_type().
+ * It suffers from the same flaws as camel_data_wrapper_set_mime_type().
**/
void
camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
@@ -573,6 +614,32 @@ camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
}
/**
+ * camel_data_wrapper_take_mime_type_field:
+ * @data_wrapper: a #CamelDataWrapper
+ * @mime_type: (nullable) (transfer full): a #CamelContentType
+ *
+ * Sets mime-type filed to be @mime_type and consumes it, aka unlike
+ * camel_data_wrapper_set_mime_type_field(), this doesn't add its own
+ * reference to @mime_type.
+ *
+ * It suffers from the same flaws as camel_data_wrapper_set_mime_type().
+ *
+ * Since: 3.24
+ **/
+void
+camel_data_wrapper_take_mime_type_field (CamelDataWrapper *data_wrapper,
+ CamelContentType *mime_type)
+{
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+ g_return_if_fail (mime_type != NULL);
+
+ camel_data_wrapper_set_mime_type_field (data_wrapper, mime_type);
+
+ if (mime_type)
+ camel_content_type_unref (mime_type);
+}
+
+/**
* camel_data_wrapper_is_offline:
* @data_wrapper: a #CamelDataWrapper
*
@@ -594,6 +661,25 @@ camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper)
}
/**
+ * camel_data_wrapper_set_offline:
+ * @data_wrapper: a #CamelDataWrapper
+ * @offline: whether the @data_wrapper is "offline"
+ *
+ * Sets whether the @data_wrapper is "offline". It applies only to this
+ * concrete instance. See camel_data_wrapper_is_offline().
+ *
+ * Since: 3.24
+ **/
+void
+camel_data_wrapper_set_offline (CamelDataWrapper *data_wrapper,
+ gboolean offline)
+{
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+
+ data_wrapper->priv->offline = offline;
+}
+
+/**
* camel_data_wrapper_write_to_stream_sync:
* @data_wrapper: a #CamelDataWrapper
* @stream: a #CamelStream for output
@@ -1459,3 +1545,72 @@ camel_data_wrapper_construct_from_input_stream_finish (CamelDataWrapper *data_wr
return g_task_propagate_boolean (G_TASK (result), error);
}
+/**
+ * camel_data_wrapper_calculate_size_sync:
+ * @data_wrapper: a #CamelDataWrapper
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Calculates size of the @data_wrapper by saving it to a null-stream
+ * and returns how many bytes had been written. It's using
+ * camel_data_wrapper_write_to_stream_sync() internally.
+ *
+ * Returns: how many bytes the @data_wrapper would use when saved,
+ * or -1 on error.
+ *
+ * Since: 3.24
+ **/
+gsize
+camel_data_wrapper_calculate_size_sync (CamelDataWrapper *data_wrapper,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStream *stream;
+ gsize bytes_written = -1;
+
+ g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), -1);
+
+ stream = camel_stream_null_new ();
+
+ if (camel_data_wrapper_write_to_stream_sync (data_wrapper, stream, cancellable, error))
+ bytes_written = camel_stream_null_get_bytes_written (CAMEL_STREAM_NULL (stream));
+
+ g_object_unref (stream);
+
+ return bytes_written;
+}
+
+/**
+ * camel_data_wrapper_calculate_decoded_size_sync:
+ * @data_wrapper: a #CamelDataWrapper
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Calculates decoded size of the @data_wrapper by saving it to a null-stream
+ * and returns how many bytes had been written. It's using
+ * camel_data_wrapper_decode_to_stream_sync() internally.
+ *
+ * Returns: how many bytes the @data_wrapper would use when saved,
+ * or -1 on error.
+ *
+ * Since: 3.24
+ **/
+gsize
+camel_data_wrapper_calculate_decoded_size_sync (CamelDataWrapper *data_wrapper,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStream *stream;
+ gsize bytes_written = -1;
+
+ g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), -1);
+
+ stream = camel_stream_null_new ();
+
+ if (camel_data_wrapper_decode_to_stream_sync (data_wrapper, stream, cancellable, error))
+ bytes_written = camel_stream_null_get_bytes_written (CAMEL_STREAM_NULL (stream));
+
+ g_object_unref (stream);
+
+ return bytes_written;
+}
diff --git a/src/camel/camel-data-wrapper.h b/src/camel/camel-data-wrapper.h
index 0e70224..34376d9 100644
--- a/src/camel/camel-data-wrapper.h
+++ b/src/camel/camel-data-wrapper.h
@@ -59,12 +59,6 @@ typedef struct _CamelDataWrapperPrivate CamelDataWrapperPrivate;
struct _CamelDataWrapper {
GObject parent;
CamelDataWrapperPrivate *priv;
-
- CamelTransferEncoding encoding;
-
- CamelContentType *mime_type;
-
- guint offline : 1;
};
struct _CamelDataWrapperClass {
@@ -110,8 +104,8 @@ struct _CamelDataWrapperClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots. */
- gpointer reserved[3];
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_data_wrapper_get_type (void);
@@ -119,6 +113,10 @@ CamelDataWrapper *
camel_data_wrapper_new (void);
GByteArray * camel_data_wrapper_get_byte_array
(CamelDataWrapper *data_wrapper);
+CamelTransferEncoding
+ camel_data_wrapper_get_encoding (CamelDataWrapper *data_wrapper);
+void camel_data_wrapper_set_encoding (CamelDataWrapper *data_wrapper,
+ CamelTransferEncoding encoding);
void camel_data_wrapper_set_mime_type
(CamelDataWrapper *data_wrapper,
const gchar *mime_type);
@@ -130,7 +128,12 @@ CamelContentType *
void camel_data_wrapper_set_mime_type_field
(CamelDataWrapper *data_wrapper,
CamelContentType *mime_type);
+void camel_data_wrapper_take_mime_type_field
+ (CamelDataWrapper *data_wrapper,
+ CamelContentType *mime_type);
gboolean camel_data_wrapper_is_offline (CamelDataWrapper *data_wrapper);
+void camel_data_wrapper_set_offline (CamelDataWrapper *data_wrapper,
+ gboolean offline);
gssize camel_data_wrapper_write_to_stream_sync
(CamelDataWrapper *data_wrapper,
@@ -228,6 +231,14 @@ gboolean camel_data_wrapper_construct_from_input_stream_finish
(CamelDataWrapper *data_wrapper,
GAsyncResult *result,
GError **error);
+gsize camel_data_wrapper_calculate_size_sync
+ (CamelDataWrapper *data_wrapper,
+ GCancellable *cancellable,
+ GError **error);
+gsize camel_data_wrapper_calculate_decoded_size_sync
+ (CamelDataWrapper *data_wrapper,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
diff --git a/src/camel/camel-db.c b/src/camel/camel-db.c
index dffad32..4e585ef 100644
--- a/src/camel/camel-db.c
+++ b/src/camel/camel-db.c
@@ -29,6 +29,8 @@
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
+#include <sqlite3.h>
+
#include "camel-debug.h"
#include "camel-object.h"
#include "camel-string-utils.h"
@@ -437,6 +439,9 @@ init_sqlite_vfs (void)
sqlite3_vfs_register (&vfs, 1);
+ if (g_getenv ("CAMEL_SQLITE_SHARED_CACHE"))
+ sqlite3_enable_shared_cache (TRUE);
+
return NULL;
}
@@ -481,14 +486,56 @@ init_sqlite_vfs (void)
}
struct _CamelDBPrivate {
+ sqlite3 *db;
GTimer *timer;
GRWLock rwlock;
- gchar *file_name;
+ gchar *filename;
GMutex transaction_lock;
GThread *transaction_thread;
guint32 transaction_level;
};
+G_DEFINE_TYPE (CamelDB, camel_db, G_TYPE_OBJECT)
+
+static void
+camel_db_finalize (GObject *object)
+{
+ CamelDB *cdb = CAMEL_DB (object);
+
+ sqlite3_close (cdb->priv->db);
+ g_rw_lock_clear (&cdb->priv->rwlock);
+ g_mutex_clear (&cdb->priv->transaction_lock);
+ g_free (cdb->priv->filename);
+
+ d (g_print ("\nDatabase succesfully closed \n"));
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (camel_db_parent_class)->finalize (object);
+}
+
+static void
+camel_db_class_init (CamelDBClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelDBPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = camel_db_finalize;
+}
+
+static void
+camel_db_init (CamelDB *cdb)
+{
+ cdb->priv = G_TYPE_INSTANCE_GET_PRIVATE (cdb, CAMEL_TYPE_DB, CamelDBPrivate);
+
+ g_rw_lock_init (&cdb->priv->rwlock);
+ g_mutex_init (&cdb->priv->transaction_lock);
+ cdb->priv->transaction_thread = NULL;
+ cdb->priv->transaction_level = 0;
+ cdb->priv->timer = NULL;
+}
+
/**
* cdb_sql_exec
* @db:
@@ -713,7 +760,7 @@ camel_db_command_internal (CamelDB *cdb,
cdb_writer_lock (cdb);
START (stmt);
- ret = cdb_sql_exec (cdb->db, stmt, NULL, NULL, out_sqlite_error_code, error);
+ ret = cdb_sql_exec (cdb->priv->db, stmt, NULL, NULL, out_sqlite_error_code, error);
END;
cdb_writer_unlock (cdb);
@@ -722,13 +769,18 @@ camel_db_command_internal (CamelDB *cdb,
}
/**
- * camel_db_open:
+ * camel_db_new:
+ * @filename: A filename with the database to open/create
+ * @error: (out): a #GError for error messages
*
- * Since: 2.24
+ * Returns: (transfer full): A new #CamelDB with @filename as its database file.
+ * Free it with g_object_unref() when no longer needed.
+ *
+ * Since: 3.24
**/
CamelDB *
-camel_db_open (const gchar *path,
- GError **error)
+camel_db_new (const gchar *filename,
+ GError **error)
{
static GOnce vfs_once = G_ONCE_INIT;
CamelDB *cdb;
@@ -739,10 +791,8 @@ camel_db_open (const gchar *path,
g_once (&vfs_once, (GThreadFunc) init_sqlite_vfs, NULL);
- CAMEL_DB_USE_SHARED_CACHE;
-
reopen:
- ret = sqlite3_open (path, &db);
+ ret = sqlite3_open (filename, &db);
if (ret) {
if (!db) {
g_set_error (
@@ -752,7 +802,7 @@ camel_db_open (const gchar *path,
} else {
const gchar *errmsg;
errmsg = sqlite3_errmsg (db);
- d (g_print ("Can't open database %s: %s\n", path, errmsg));
+ d (g_print ("Can't open database %s: %s\n", filename, errmsg));
g_set_error (
error, CAMEL_ERROR,
CAMEL_ERROR_GENERIC, "%s", errmsg);
@@ -761,15 +811,9 @@ camel_db_open (const gchar *path,
return NULL;
}
- cdb = g_new (CamelDB, 1);
- cdb->db = db;
- cdb->priv = g_new0 (CamelDBPrivate, 1);
- cdb->priv->file_name = g_strdup (path);
- g_rw_lock_init (&cdb->priv->rwlock);
- g_mutex_init (&cdb->priv->transaction_lock);
- cdb->priv->transaction_thread = NULL;
- cdb->priv->transaction_level = 0;
- cdb->priv->timer = NULL;
+ cdb = g_object_new (CAMEL_TYPE_DB, NULL);
+ cdb->priv->db = db;
+ cdb->priv->filename = g_strdup (filename);
d (g_print ("\nDatabase succesfully opened \n"));
sqlite3_create_function (db, "MATCH", 2, SQLITE_UTF8, NULL, cdb_match_func, NULL, NULL);
@@ -799,16 +843,16 @@ camel_db_open (const gchar *path,
cdb_sqlite_error_code == SQLITE_NOTADB)) {
gchar *second_filename;
- camel_db_close (cdb);
+ g_clear_object (&cdb);
reopening = TRUE;
- second_filename = g_strconcat (path, ".corrupt", NULL);
- if (g_rename (path, second_filename) == -1) {
+ second_filename = g_strconcat (filename, ".corrupt", NULL);
+ if (g_rename (filename, second_filename) == -1) {
if (!local_error) {
g_set_error (&local_error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Could not rename '%s' to %s: %s"),
- path, second_filename, g_strerror (errno));
+ filename, second_filename, g_strerror (errno));
}
g_propagate_error (error, local_error);
@@ -820,7 +864,7 @@ camel_db_open (const gchar *path,
g_free (second_filename);
- g_warning ("%s: Failed to open '%s', renamed old file to .corrupt; code:%s (%d) error:%s",
G_STRFUNC, path,
+ g_warning ("%s: Failed to open '%s', renamed old file to .corrupt; code:%s (%d) error:%s",
G_STRFUNC, filename,
cdb_sqlite_error_code == SQLITE_CANTOPEN ? "SQLITE_CANTOPEN" :
cdb_sqlite_error_code == SQLITE_CORRUPT ? "SQLITE_CORRUPT" :
cdb_sqlite_error_code == SQLITE_NOTADB ? "SQLITE_NOTADB" : "???",
@@ -833,44 +877,29 @@ camel_db_open (const gchar *path,
if (local_error) {
g_propagate_error (error, local_error);
- camel_db_close (cdb);
+ g_clear_object (&cdb);
return NULL;
}
- sqlite3_busy_timeout (cdb->db, CAMEL_DB_SLEEP_INTERVAL);
+ sqlite3_busy_timeout (cdb->priv->db, CAMEL_DB_SLEEP_INTERVAL);
return cdb;
}
/**
- * camel_db_clone:
+ * camel_db_get_filename:
+ * @cdb: a #CamelDB
*
- * Since: 2.26
+ * Returns: (transfer none): A filename associated with @cdb.
+ *
+ * Since: 3.24
**/
-CamelDB *
-camel_db_clone (CamelDB *cdb,
- GError **error)
+const gchar *
+camel_db_get_filename (CamelDB *cdb)
{
- return camel_db_open (cdb->priv->file_name, error);
-}
+ g_return_val_if_fail (CAMEL_IS_DB (cdb), NULL);
-/**
- * camel_db_close:
- *
- * Since: 2.24
- **/
-void
-camel_db_close (CamelDB *cdb)
-{
- if (cdb) {
- sqlite3_close (cdb->db);
- g_rw_lock_clear (&cdb->priv->rwlock);
- g_mutex_clear (&cdb->priv->transaction_lock);
- g_free (cdb->priv->file_name);
- g_free (cdb->priv);
- g_free (cdb);
- d (g_print ("\nDatabase succesfully closed \n"));
- }
+ return cdb->priv->filename;
}
/**
@@ -885,18 +914,18 @@ camel_db_set_collate (CamelDB *cdb,
const gchar *collate,
CamelDBCollate func)
{
- gint ret = 0;
+ gint ret = 0;
- if (!cdb)
- return 0;
+ if (!cdb)
+ return 0;
- cdb_writer_lock (cdb);
- d (g_print ("Creating Collation %s on %s with %p\n", collate, col, (gpointer) func));
- if (collate && func)
- ret = sqlite3_create_collation (cdb->db, collate, SQLITE_UTF8, NULL, func);
- cdb_writer_unlock (cdb);
+ cdb_writer_lock (cdb);
+ d (g_print ("Creating Collation %s on %s with %p\n", collate, col, (gpointer) func));
+ if (collate && func)
+ ret = sqlite3_create_collation (cdb->priv->db, collate, SQLITE_UTF8, NULL, func);
+ cdb_writer_unlock (cdb);
- return ret;
+ return ret;
}
/**
@@ -932,7 +961,7 @@ camel_db_begin_transaction (CamelDB *cdb,
stmt = cdb_construct_transaction_stmt (cdb, "SAVEPOINT ");
STARTTS (stmt);
- res = cdb_sql_exec (cdb->db, stmt, NULL, NULL, NULL, error);
+ res = cdb_sql_exec (cdb->priv->db, stmt, NULL, NULL, NULL, error);
g_free (stmt);
return res;
@@ -954,12 +983,12 @@ camel_db_end_transaction (CamelDB *cdb,
return -1;
stmt = cdb_construct_transaction_stmt (cdb, "RELEASE SAVEPOINT ");
- ret = cdb_sql_exec (cdb->db, stmt, NULL, NULL, NULL, error);
+ ret = cdb_sql_exec (cdb->priv->db, stmt, NULL, NULL, NULL, error);
g_free (stmt);
ENDTS;
cdb_writer_unlock (cdb);
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
return ret;
}
@@ -977,11 +1006,11 @@ camel_db_abort_transaction (CamelDB *cdb,
gint ret;
stmt = cdb_construct_transaction_stmt (cdb, "ROLLBACK TO SAVEPOINT ");
- ret = cdb_sql_exec (cdb->db, stmt, NULL, NULL, NULL, error);
+ ret = cdb_sql_exec (cdb->priv->db, stmt, NULL, NULL, NULL, error);
g_free (stmt);
cdb_writer_unlock (cdb);
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
return ret;
}
@@ -1001,7 +1030,7 @@ camel_db_add_to_transaction (CamelDB *cdb,
g_return_val_if_fail (cdb_is_in_transaction (cdb), -1);
- return (cdb_sql_exec (cdb->db, stmt, NULL, NULL, NULL, error));
+ return (cdb_sql_exec (cdb->priv->db, stmt, NULL, NULL, NULL, error));
}
/**
@@ -1031,7 +1060,7 @@ camel_db_transaction_command (CamelDB *cdb,
while (qry_list) {
query = qry_list->data;
- ret = cdb_sql_exec (cdb->db, query, NULL, NULL, NULL, error);
+ ret = cdb_sql_exec (cdb->priv->db, query, NULL, NULL, NULL, error);
if (ret)
goto end;
qry_list = g_list_next (qry_list);
@@ -1079,12 +1108,12 @@ camel_db_count_message_info (CamelDB *cdb,
cdb_reader_lock (cdb);
START (query);
- ret = cdb_sql_exec (cdb->db, query, count_cb, count, NULL, error);
+ ret = cdb_sql_exec (cdb->priv->db, query, count_cb, count, NULL, error);
END;
cdb_reader_unlock (cdb);
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
return ret;
}
@@ -1287,11 +1316,11 @@ camel_db_select (CamelDB *cdb,
cdb_reader_lock (cdb);
START (stmt);
- ret = cdb_sql_exec (cdb->db, stmt, callback, user_data, NULL, error);
+ ret = cdb_sql_exec (cdb->priv->db, stmt, callback, user_data, NULL, error);
END;
cdb_reader_unlock (cdb);
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
return ret;
}
@@ -1369,7 +1398,7 @@ camel_db_get_folder_uids (CamelDB *db,
**/
GPtrArray *
camel_db_get_folder_junk_uids (CamelDB *db,
- gchar *folder_name,
+ const gchar *folder_name,
GError **error)
{
gchar *sel_query;
@@ -1418,104 +1447,6 @@ camel_db_get_folder_deleted_uids (CamelDB *db,
return array;
}
-struct ReadPreviewData
-{
- GHashTable *columns_hash;
- GHashTable *hash;
-};
-
-static gint
-read_preview_callback (gpointer ref,
- gint ncol,
- gchar **cols,
- gchar **name)
-{
- struct ReadPreviewData *rpd = ref;
- const gchar *uid = NULL;
- gchar *msg = NULL;
- gint i;
-
- for (i = 0; i < ncol; ++i) {
- if (!name[i] || !cols[i])
- continue;
-
- switch (camel_db_get_column_ident (&rpd->columns_hash, i, ncol, name)) {
- case CAMEL_DB_COLUMN_UID:
- uid = camel_pstring_strdup (cols[i]);
- break;
- case CAMEL_DB_COLUMN_PREVIEW:
- msg = g_strdup (cols[i]);
- break;
- default:
- g_warn_if_reached ();
- break;
- }
- }
-
- g_hash_table_insert (rpd->hash, (gchar *) uid, msg);
-
- return 0;
-}
-
-/**
- * camel_db_get_folder_preview:
- *
- * Returns: (element-type utf8 utf8) (transfer full):
- *
- * Since: 2.28
- **/
-GHashTable *
-camel_db_get_folder_preview (CamelDB *db,
- const gchar *folder_name,
- GError **error)
-{
- gchar *sel_query;
- gint ret;
- struct ReadPreviewData rpd;
- GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- sel_query = sqlite3_mprintf ("SELECT uid, preview FROM '%q_preview'", folder_name);
-
- rpd.columns_hash = NULL;
- rpd.hash = hash;
-
- ret = camel_db_select (db, sel_query, read_preview_callback, &rpd, error);
- sqlite3_free (sel_query);
-
- if (rpd.columns_hash)
- g_hash_table_destroy (rpd.columns_hash);
-
- if (!g_hash_table_size (hash) || ret != 0) {
- g_hash_table_destroy (hash);
- hash = NULL;
- }
-
- return hash;
-}
-
-/**
- * camel_db_write_preview_record:
- *
- * Since: 2.28
- **/
-gint
-camel_db_write_preview_record (CamelDB *db,
- const gchar *folder_name,
- const gchar *uid,
- const gchar *msg,
- GError **error)
-{
- gchar *query;
- gint ret;
-
- query = sqlite3_mprintf ("INSERT OR REPLACE INTO '%q_preview' VALUES(%Q,%Q)", folder_name, uid, msg);
-
- ret = camel_db_add_to_transaction (db, query, error);
- sqlite3_free (query);
-
- return ret;
-}
-
/**
* camel_db_create_folders_table:
*
@@ -1539,7 +1470,7 @@ camel_db_create_folders_table (CamelDB *cdb,
"visible_count INTEGER, "
"jnd_count INTEGER, "
"bdata TEXT )";
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
ret = camel_db_command (cdb, query, error);
@@ -1598,19 +1529,6 @@ camel_db_create_message_info_table (CamelDB *cdb,
ret = camel_db_add_to_transaction (cdb, table_creation_query, error);
sqlite3_free (table_creation_query);
- table_creation_query = sqlite3_mprintf (
- "CREATE TABLE IF NOT EXISTS '%q_bodystructure' ( "
- "uid TEXT PRIMARY KEY , "
- "bodystructure TEXT )",
- folder_name);
- ret = camel_db_add_to_transaction (cdb, table_creation_query, error);
- sqlite3_free (table_creation_query);
-
- /* Create message preview table. */
- table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%q_preview' ( uid TEXT PRIMARY
KEY , preview TEXT)", folder_name);
- ret = camel_db_add_to_transaction (cdb, table_creation_query, error);
- sqlite3_free (table_creation_query);
-
/* FIXME: sqlize folder_name before you create the index */
safe_index = g_strdup_printf ("SINDEX-%s", folder_name);
table_creation_query = sqlite3_mprintf ("DROP INDEX IF EXISTS %Q", safe_index);
@@ -1618,13 +1536,6 @@ camel_db_create_message_info_table (CamelDB *cdb,
g_free (safe_index);
sqlite3_free (table_creation_query);
- /* INDEX on preview */
- safe_index = g_strdup_printf ("SINDEX-%s-preview", folder_name);
- table_creation_query = sqlite3_mprintf ("CREATE INDEX IF NOT EXISTS %Q ON '%q_preview' (uid,
preview)", safe_index, folder_name);
- ret = camel_db_add_to_transaction (cdb, table_creation_query, error);
- g_free (safe_index);
- sqlite3_free (table_creation_query);
-
/* Index on deleted*/
safe_index = g_strdup_printf ("DELINDEX-%s", folder_name);
table_creation_query = sqlite3_mprintf ("CREATE INDEX IF NOT EXISTS %Q ON %Q (deleted)", safe_index,
folder_name);
@@ -1974,8 +1885,8 @@ write_mir (CamelDB *cdb,
record->attachment,
record->dirty,
record->size,
- (gint64) record->dsent,
- (gint64) record->dreceived,
+ record->dsent,
+ record->dreceived,
record->subject,
record->from,
record->to,
@@ -1994,15 +1905,6 @@ write_mir (CamelDB *cdb,
sqlite3_free (ins_query);
- if (ret == 0) {
- ins_query = sqlite3_mprintf (
- "INSERT OR REPLACE INTO "
- "'%q_bodystructure' VALUES (%Q, %Q )",
- folder_name, record->uid, record->bodystructure);
- ret = camel_db_add_to_transaction (cdb, ins_query, error);
- sqlite3_free (ins_query);
- }
-
return ret;
}
@@ -2051,12 +1953,12 @@ camel_db_write_folder_info_record (CamelDB *cdb,
ins_query = sqlite3_mprintf (
"INSERT INTO folders VALUES ("
- "%Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %Q ) ",
+ "%Q, %d, %d, %d, %lld, %d, %d, %d, %d, %d, %d, %Q ) ",
record->folder_name,
record->version,
record->flags,
record->nextuid,
- record->time,
+ record->timestamp,
record->saved_count,
record->unread_count,
record->deleted_count,
@@ -2112,7 +2014,7 @@ read_fir_callback (gpointer ref,
rfd->record->nextuid = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
break;
case CAMEL_DB_COLUMN_TIME:
- rfd->record->time = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ rfd->record->timestamp = cols[i] ? g_ascii_strtoll (cols[i], NULL, 10) : 0;
break;
case CAMEL_DB_COLUMN_SAVED_COUNT:
rfd->record->saved_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
@@ -2242,17 +2144,13 @@ camel_db_delete_uid (CamelDB *cdb,
camel_db_begin_transaction (cdb, error);
- tab = sqlite3_mprintf ("DELETE FROM '%q_bodystructure' WHERE uid = %Q", folder, uid);
- ret = camel_db_add_to_transaction (cdb, tab, error);
- sqlite3_free (tab);
-
tab = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder, uid);
ret = camel_db_add_to_transaction (cdb, tab, error);
sqlite3_free (tab);
ret = camel_db_end_transaction (cdb, error);
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
return ret;
}
@@ -2303,7 +2201,7 @@ cdb_delete_ids (CamelDB *cdb,
else
ret = camel_db_end_transaction (cdb, error);
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
g_string_free (str, TRUE);
@@ -2342,23 +2240,19 @@ camel_db_clear_folder_summary (CamelDB *cdb,
gint ret;
gchar *folders_del;
gchar *msginfo_del;
- gchar *bstruct_del;
folders_del = sqlite3_mprintf ("DELETE FROM folders WHERE folder_name = %Q", folder);
msginfo_del = sqlite3_mprintf ("DELETE FROM %Q ", folder);
- bstruct_del = sqlite3_mprintf ("DELETE FROM '%q_bodystructure' ", folder);
camel_db_begin_transaction (cdb, error);
camel_db_add_to_transaction (cdb, msginfo_del, error);
camel_db_add_to_transaction (cdb, folders_del, error);
- camel_db_add_to_transaction (cdb, bstruct_del, error);
ret = camel_db_end_transaction (cdb, error);
sqlite3_free (folders_del);
sqlite3_free (msginfo_del);
- sqlite3_free (bstruct_del);
return ret;
}
@@ -2386,13 +2280,9 @@ camel_db_delete_folder (CamelDB *cdb,
ret = camel_db_add_to_transaction (cdb, del, error);
sqlite3_free (del);
- del = sqlite3_mprintf ("DROP TABLE '%q_bodystructure' ", folder);
- ret = camel_db_add_to_transaction (cdb, del, error);
- sqlite3_free (del);
-
ret = camel_db_end_transaction (cdb, error);
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
return ret;
}
@@ -2430,7 +2320,7 @@ camel_db_rename_folder (CamelDB *cdb,
ret = camel_db_end_transaction (cdb, error);
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
return ret;
}
@@ -2444,20 +2334,19 @@ camel_db_camel_mir_free (CamelMIRecord *record)
{
if (record) {
camel_pstring_free (record->uid);
- camel_pstring_free (record->subject);
- camel_pstring_free (record->from);
- camel_pstring_free (record->to);
- camel_pstring_free (record->cc);
- camel_pstring_free (record->mlist);
- camel_pstring_free (record->followup_flag);
- camel_pstring_free (record->followup_completed_on);
- camel_pstring_free (record->followup_due_by);
+ g_free (record->subject);
+ g_free (record->from);
+ g_free (record->to);
+ g_free (record->cc);
+ g_free (record->mlist);
+ g_free (record->followup_flag);
+ g_free (record->followup_completed_on);
+ g_free (record->followup_due_by);
g_free (record->part);
g_free (record->labels);
g_free (record->usertags);
g_free (record->cinfo);
g_free (record->bdata);
- g_free (record->bodystructure);
g_free (record);
}
@@ -2624,7 +2513,6 @@ static struct _known_column_names {
} known_column_names[] = {
{ "attachment", CAMEL_DB_COLUMN_ATTACHMENT },
{ "bdata", CAMEL_DB_COLUMN_BDATA },
- { "bodystructure", CAMEL_DB_COLUMN_BODYSTRUCTURE },
{ "cinfo", CAMEL_DB_COLUMN_CINFO },
{ "deleted", CAMEL_DB_COLUMN_DELETED },
{ "deleted_count", CAMEL_DB_COLUMN_DELETED_COUNT },
@@ -2646,7 +2534,6 @@ static struct _known_column_names {
{ "mlist", CAMEL_DB_COLUMN_MLIST },
{ "nextuid", CAMEL_DB_COLUMN_NEXTUID },
{ "part", CAMEL_DB_COLUMN_PART },
- { "preview", CAMEL_DB_COLUMN_PREVIEW },
{ "read", CAMEL_DB_COLUMN_READ },
{ "replied", CAMEL_DB_COLUMN_REPLIED },
{ "saved_count", CAMEL_DB_COLUMN_SAVED_COUNT },
@@ -2760,11 +2647,11 @@ camel_db_maybe_run_maintenance (CamelDB *cdb,
cdb_writer_lock (cdb);
- if (cdb_sql_exec (cdb->db, "PRAGMA page_count;", get_number_cb, &page_count, NULL, &local_error) ==
SQLITE_OK &&
- cdb_sql_exec (cdb->db, "PRAGMA freelist_count;", get_number_cb, &freelist_count, NULL,
&local_error) == SQLITE_OK) {
+ if (cdb_sql_exec (cdb->priv->db, "PRAGMA page_count;", get_number_cb, &page_count, NULL,
&local_error) == SQLITE_OK &&
+ cdb_sql_exec (cdb->priv->db, "PRAGMA freelist_count;", get_number_cb, &freelist_count, NULL,
&local_error) == SQLITE_OK) {
/* Vacuum, if there's more than 5% of the free pages */
success = !page_count || !freelist_count || freelist_count * 1000 / page_count <= 50 ||
- cdb_sql_exec (cdb->db, "vacuum;", NULL, NULL, NULL, &local_error) == SQLITE_OK;
+ cdb_sql_exec (cdb->priv->db, "vacuum;", NULL, NULL, NULL, &local_error) == SQLITE_OK;
}
cdb_writer_unlock (cdb);
@@ -2776,3 +2663,23 @@ camel_db_maybe_run_maintenance (CamelDB *cdb,
return success;
}
+
+/**
+ * camel_db_release_cache_memory:
+ *
+ * Instructs sqlite to release its memory, if possible. This can be avoided
+ * when CAMEL_SQLITE_FREE_CACHE environment variable is set.
+ *
+ * Since: 3.24
+ **/
+void
+camel_db_release_cache_memory (void)
+{
+ static gint env_set = -1;
+
+ if (env_set == -1)
+ env_set = g_getenv("CAMEL_SQLITE_FREE_CACHE") ? 1 : 0;
+
+ if (!env_set)
+ sqlite3_release_memory (CAMEL_DB_FREE_CACHE_SIZE);
+}
diff --git a/src/camel/camel-db.h b/src/camel/camel-db.h
index b454af9..77a88b9 100644
--- a/src/camel/camel-db.h
+++ b/src/camel/camel-db.h
@@ -24,11 +24,58 @@
#ifndef CAMEL_DB_H
#define CAMEL_DB_H
-#include <sqlite3.h>
#include <glib.h>
+#include <glib-object.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_DB \
+ (camel_db_get_type ())
+#define CAMEL_DB(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_DB, CamelDB))
+#define CAMEL_DB_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_DB, CamelDBClass))
+#define CAMEL_IS_DB(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_DB))
+#define CAMEL_IS_DB_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_DB))
+#define CAMEL_DB_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_DB, CamelDBClass))
G_BEGIN_DECLS
+typedef struct _CamelDB CamelDB;
+typedef struct _CamelDBClass CamelDBClass;
+typedef struct _CamelDBPrivate CamelDBPrivate;
+
+/**
+ * CamelDB:
+ *
+ * Since: 2.24
+ **/
+struct _CamelDB {
+ GObject parent;
+ CamelDBPrivate *priv;
+};
+
+struct _CamelDBClass {
+ GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
+};
+
+/**
+ * CamelDBCollate:
+ *
+ * Since: 2.24
+ **/
+typedef gint (*CamelDBCollate)(gpointer enc, gint length1, gconstpointer data1, gint length2, gconstpointer
data2);
+
/**
* CAMEL_DB_FILE:
*
@@ -59,27 +106,6 @@ G_BEGIN_DECLS
**/
#define CAMEL_DB_IN_MEMORY_TABLE_LIMIT 100000
-typedef struct _CamelDBPrivate CamelDBPrivate;
-
-/**
- * CamelDBCollate:
- *
- * Since: 2.24
- **/
-typedef gint (*CamelDBCollate)(gpointer enc, gint length1, gconstpointer data1, gint length2, gconstpointer
data2);
-
-/**
- * CamelDB:
- *
- * Since: 2.24
- **/
-struct _CamelDB {
- sqlite3 *db;
- /* this lock has been replaced with a rw lock which sits inside priv.
- * This is currently unused. Keeping it, not to break the ABI */
- GMutex *lock;
- CamelDBPrivate *priv;
-};
/**
* CAMEL_DB_FREE_CACHE_SIZE:
@@ -96,20 +122,6 @@ struct _CamelDB {
#define CAMEL_DB_SLEEP_INTERVAL 1*10*10
/**
- * CAMEL_DB_RELEASE_SQLITE_MEMORY:
- *
- * Since: 2.24
- **/
-#define CAMEL_DB_RELEASE_SQLITE_MEMORY if(!g_getenv("CAMEL_SQLITE_FREE_CACHE"))
sqlite3_release_memory(CAMEL_DB_FREE_CACHE_SIZE);
-
-/**
- * CAMEL_DB_USE_SHARED_CACHE:
- *
- * Since: 2.24
- **/
-#define CAMEL_DB_USE_SHARED_CACHE if(g_getenv("CAMEL_SQLITE_SHARED_CACHE"))
sqlite3_enable_shared_cache(TRUE);
-
-/**
* CamelMIRecord:
* @uid:
* Message UID
@@ -161,7 +173,6 @@ struct _CamelDB {
* content info string - composite string
* @bdata:
* provider specific data
- * @bodystructure:
*
* The extensive DB format, supporting basic searching and sorting.
*
@@ -179,8 +190,8 @@ typedef struct _CamelMIRecord {
gboolean junk;
gboolean attachment;
guint32 size;
- time_t dsent;
- time_t dreceived;
+ gint64 dsent; /* time_t */
+ gint64 dreceived; /* time_t */
gchar *subject;
gchar *from;
gchar *to;
@@ -194,7 +205,6 @@ typedef struct _CamelMIRecord {
gchar *usertags;
gchar *cinfo;
gchar *bdata;
- gchar *bodystructure;
} CamelMIRecord;
/**
@@ -207,7 +217,7 @@ typedef struct _CamelFIRecord {
guint32 version;
guint32 flags;
guint32 nextuid;
- time_t time;
+ gint64 timestamp;
guint32 saved_count;
guint32 unread_count;
guint32 deleted_count;
@@ -217,8 +227,6 @@ typedef struct _CamelFIRecord {
gchar *bdata;
} CamelFIRecord;
-typedef struct _CamelDB CamelDB;
-
/**
* CamelDBKnownColumnNames:
*
@@ -228,7 +236,6 @@ typedef enum {
CAMEL_DB_COLUMN_UNKNOWN = -1,
CAMEL_DB_COLUMN_ATTACHMENT,
CAMEL_DB_COLUMN_BDATA,
- CAMEL_DB_COLUMN_BODYSTRUCTURE,
CAMEL_DB_COLUMN_CINFO,
CAMEL_DB_COLUMN_DELETED,
CAMEL_DB_COLUMN_DELETED_COUNT,
@@ -250,7 +257,6 @@ typedef enum {
CAMEL_DB_COLUMN_MLIST,
CAMEL_DB_COLUMN_NEXTUID,
CAMEL_DB_COLUMN_PART,
- CAMEL_DB_COLUMN_PREVIEW,
CAMEL_DB_COLUMN_READ,
CAMEL_DB_COLUMN_REPLIED,
CAMEL_DB_COLUMN_SAVED_COUNT,
@@ -272,74 +278,165 @@ CamelDBKnownColumnNames camel_db_get_column_ident (GHashTable **hash, gint index
*
* Since: 2.24
**/
-typedef gint (*CamelDBSelectCB) (gpointer data, gint ncol, gchar **colvalues, gchar **colnames);
-
-CamelDB * camel_db_open (const gchar *path, GError **error);
-CamelDB * camel_db_clone (CamelDB *cdb, GError **error);
-void camel_db_close (CamelDB *cdb);
-gint camel_db_command (CamelDB *cdb, const gchar *stmt, GError **error);
-
-gint camel_db_transaction_command (CamelDB *cdb, GList *qry_list, GError **error);
-
-gint camel_db_begin_transaction (CamelDB *cdb, GError **error);
-gint camel_db_add_to_transaction (CamelDB *cdb, const gchar *query, GError **error);
-gint camel_db_end_transaction (CamelDB *cdb, GError **error);
-gint camel_db_abort_transaction (CamelDB *cdb, GError **error);
-gint camel_db_clear_folder_summary (CamelDB *cdb, const gchar *folder, GError **error);
-gint camel_db_rename_folder (CamelDB *cdb, const gchar *old_folder, const gchar *new_folder, GError **error);
-
-gint camel_db_delete_folder (CamelDB *cdb, const gchar *folder, GError **error);
-gint camel_db_delete_uid (CamelDB *cdb, const gchar *folder, const gchar *uid, GError **error);
-/*int camel_db_delete_uids (CamelDB *cdb, GError **error, gint nargs, ... );*/
-gint camel_db_delete_uids (CamelDB *cdb, const gchar * folder_name, GList *uids, GError **error);
-
-gint camel_db_create_folders_table (CamelDB *cdb, GError **error);
-gint camel_db_select (CamelDB *cdb, const gchar * stmt, CamelDBSelectCB callback, gpointer user_data, GError
**error);
-
-gint camel_db_write_folder_info_record (CamelDB *cdb, CamelFIRecord *record, GError **error);
-gint camel_db_read_folder_info_record (CamelDB *cdb, const gchar *folder_name, CamelFIRecord *record, GError
**error);
-
-gint camel_db_prepare_message_info_table (CamelDB *cdb, const gchar *folder_name, GError **error);
-
-gint camel_db_write_message_info_record (CamelDB *cdb, const gchar *folder_name, CamelMIRecord *record,
GError **error);
-gint camel_db_write_fresh_message_info_record (CamelDB *cdb, const gchar *folder_name, CamelMIRecord
*record, GError **error);
-gint camel_db_read_message_info_records (CamelDB *cdb, const gchar *folder_name, gpointer user_data,
CamelDBSelectCB read_mir_callback, GError **error);
-gint camel_db_read_message_info_record_with_uid (CamelDB *cdb, const gchar *folder_name, const gchar *uid,
gpointer user_data, CamelDBSelectCB read_mir_callback, GError **error);
-
-gint camel_db_count_junk_message_info (CamelDB *cdb, const gchar *table_name, guint32 *count, GError
**error);
-gint camel_db_count_unread_message_info (CamelDB *cdb, const gchar *table_name, guint32 *count, GError
**error);
-gint camel_db_count_deleted_message_info (CamelDB *cdb, const gchar *table_name, guint32 *count, GError
**error);
-gint camel_db_count_total_message_info (CamelDB *cdb, const gchar *table_name, guint32 *count, GError
**error);
-
-gint camel_db_count_visible_message_info (CamelDB *cdb, const gchar *table_name, guint32 *count, GError
**error);
-gint camel_db_count_visible_unread_message_info (CamelDB *cdb, const gchar *table_name, guint32 *count,
GError **error);
-
-gint camel_db_count_junk_not_deleted_message_info (CamelDB *cdb, const gchar *table_name, guint32 *count,
GError **error);
-gint camel_db_count_message_info (CamelDB *cdb, const gchar *query, guint32 *count, GError **error);
-void camel_db_camel_mir_free (CamelMIRecord *record);
-
-gint camel_db_get_folder_uids (CamelDB *db, const gchar *folder_name, const gchar *sort_by, const gchar
*collate, GHashTable *hash, GError **error);
-
-GPtrArray * camel_db_get_folder_junk_uids (CamelDB *db, gchar *folder_name, GError **error);
-GPtrArray * camel_db_get_folder_deleted_uids (CamelDB *db, const gchar *folder_name, GError **error);
-
-gchar * camel_db_sqlize_string (const gchar *string);
-void camel_db_free_sqlized_string (gchar *string);
-
-gchar * camel_db_get_column_name (const gchar *raw_name);
-gint camel_db_set_collate (CamelDB *cdb, const gchar *col, const gchar *collate, CamelDBCollate func);
-
-gint camel_db_start_in_memory_transactions (CamelDB *cdb, GError **error);
-gint camel_db_flush_in_memory_transactions (CamelDB *cdb, const gchar * folder_name, GError **error);
-
-GHashTable *
-camel_db_get_folder_preview (CamelDB *db, const gchar *folder_name, GError **error);
-gint camel_db_write_preview_record (CamelDB *db, const gchar *folder_name, const gchar *uid, const gchar
*msg, GError **error);
-
-gint
-camel_db_reset_folder_version (CamelDB *cdb, const gchar *folder_name, gint reset_version, GError **error);
-
-gboolean camel_db_maybe_run_maintenance (CamelDB *cdb, GError **error);
+typedef gint (*CamelDBSelectCB) (gpointer user_data, gint ncol, gchar **colvalues, gchar **colnames);
+
+GType camel_db_get_type (void) G_GNUC_CONST;
+
+CamelDB * camel_db_new (const gchar *filename,
+ GError **error);
+const gchar * camel_db_get_filename (CamelDB *cdb);
+gint camel_db_command (CamelDB *cdb,
+ const gchar *stmt,
+ GError **error);
+gint camel_db_transaction_command (CamelDB *cdb,
+ GList *qry_list,
+ GError **error);
+gint camel_db_begin_transaction (CamelDB *cdb,
+ GError **error);
+gint camel_db_add_to_transaction (CamelDB *cdb,
+ const gchar *query,
+ GError **error);
+gint camel_db_end_transaction (CamelDB *cdb,
+ GError **error);
+gint camel_db_abort_transaction (CamelDB *cdb,
+ GError **error);
+gint camel_db_clear_folder_summary (CamelDB *cdb,
+ const gchar *folder,
+ GError **error);
+gint camel_db_rename_folder (CamelDB *cdb,
+ const gchar *old_folder,
+ const gchar *new_folder,
+ GError **error);
+gint camel_db_delete_folder (CamelDB *cdb,
+ const gchar *folder,
+ GError **error);
+gint camel_db_delete_uid (CamelDB *cdb,
+ const gchar *folder,
+ const gchar *uid,
+ GError **error);
+gint camel_db_delete_uids (CamelDB *cdb,
+ const gchar *folder_name,
+ GList *uids,
+ GError **error);
+gint camel_db_create_folders_table (CamelDB *cdb,
+ GError **error);
+gint camel_db_select (CamelDB *cdb,
+ const gchar *stmt,
+ CamelDBSelectCB callback,
+ gpointer user_data,
+ GError **error);
+gint camel_db_write_folder_info_record
+ (CamelDB *cdb,
+ CamelFIRecord *record,
+ GError **error);
+gint camel_db_read_folder_info_record
+ (CamelDB *cdb,
+ const gchar *folder_name,
+ CamelFIRecord *record,
+ GError **error);
+gint camel_db_prepare_message_info_table
+ (CamelDB *cdb,
+ const gchar *folder_name,
+ GError **error);
+gint camel_db_write_message_info_record
+ (CamelDB *cdb,
+ const gchar *folder_name,
+ CamelMIRecord *record,
+ GError **error);
+gint camel_db_write_fresh_message_info_record
+ (CamelDB *cdb,
+ const gchar *folder_name,
+ CamelMIRecord *record,
+ GError **error);
+gint camel_db_read_message_info_records
+ (CamelDB *cdb,
+ const gchar *folder_name,
+ gpointer user_data,
+ CamelDBSelectCB read_mir_callback,
+ GError **error);
+gint camel_db_read_message_info_record_with_uid
+ (CamelDB *cdb,
+ const gchar *folder_name,
+ const gchar *uid,
+ gpointer user_data,
+ CamelDBSelectCB read_mir_callback,
+ GError **error);
+gint camel_db_count_junk_message_info
+ (CamelDB *cdb,
+ const gchar *table_name,
+ guint32 *count,
+ GError **error);
+gint camel_db_count_unread_message_info
+ (CamelDB *cdb,
+ const gchar *table_name,
+ guint32 *count,
+ GError **error);
+gint camel_db_count_deleted_message_info
+ (CamelDB *cdb,
+ const gchar *table_name,
+ guint32 *count,
+ GError **error);
+gint camel_db_count_total_message_info
+ (CamelDB *cdb,
+ const gchar *table_name,
+ guint32 *count,
+ GError **error);
+gint camel_db_count_visible_message_info
+ (CamelDB *cdb,
+ const gchar *table_name,
+ guint32 *count,
+ GError **error);
+gint camel_db_count_visible_unread_message_info
+ (CamelDB *cdb,
+ const gchar *table_name,
+ guint32 *count,
+ GError **error);
+gint camel_db_count_junk_not_deleted_message_info
+ (CamelDB *cdb,
+ const gchar *table_name,
+ guint32 *count,
+ GError **error);
+gint camel_db_count_message_info (CamelDB *cdb,
+ const gchar *query,
+ guint32 *count,
+ GError **error);
+gint camel_db_get_folder_uids (CamelDB *db,
+ const gchar *folder_name,
+ const gchar *sort_by,
+ const gchar *collate,
+ GHashTable *hash,
+ GError **error);
+GPtrArray * camel_db_get_folder_junk_uids (CamelDB *db,
+ const gchar *folder_name,
+ GError **error);
+GPtrArray * camel_db_get_folder_deleted_uids
+ (CamelDB *db,
+ const gchar *folder_name,
+ GError **error);
+gint camel_db_set_collate (CamelDB *cdb,
+ const gchar *col,
+ const gchar *collate,
+ CamelDBCollate func);
+gint camel_db_start_in_memory_transactions
+ (CamelDB *cdb,
+ GError **error);
+gint camel_db_flush_in_memory_transactions
+ (CamelDB *cdb,
+ const gchar *folder_name,
+ GError **error);
+gint camel_db_reset_folder_version (CamelDB *cdb,
+ const gchar *folder_name,
+ gint reset_version,
+ GError **error);
+gboolean camel_db_maybe_run_maintenance (CamelDB *cdb,
+ GError **error);
+
+void camel_db_release_cache_memory (void);
+
+gchar * camel_db_sqlize_string (const gchar *string);
+void camel_db_free_sqlized_string (gchar *string);
+gchar * camel_db_get_column_name (const gchar *raw_name);
+void camel_db_camel_mir_free (CamelMIRecord *record);
G_END_DECLS
diff --git a/src/camel/camel-enums.h b/src/camel/camel-enums.h
index 13577db..e20578e 100644
--- a/src/camel/camel-enums.h
+++ b/src/camel/camel-enums.h
@@ -474,4 +474,18 @@ typedef enum {
CAMEL_THREE_STATE_INCONSISTENT
} CamelThreeState;
+/**
+ * CamelCompareType:
+ * @CAMEL_COMPARE_CASE_INSENSITIVE: compare case insensitively
+ * @CAMEL_COMPARE_CASE_SENSITIVE: compare case sensitively
+ *
+ * Declares the compare type to use.
+ *
+ * Since: 3.24
+ **/
+typedef enum {
+ CAMEL_COMPARE_CASE_INSENSITIVE,
+ CAMEL_COMPARE_CASE_SENSITIVE
+} CamelCompareType;
+
#endif /* CAMEL_ENUMS_H */
diff --git a/src/camel/camel-filter-driver.c b/src/camel/camel-filter-driver.c
index b0e73b4..eacab5d 100644
--- a/src/camel/camel-filter-driver.c
+++ b/src/camel/camel-filter-driver.c
@@ -1345,7 +1345,7 @@ camel_filter_driver_flush (CamelFilterDriver *driver,
static gint
decode_flags_from_xev (const gchar *xev,
- CamelMessageInfoBase *mi)
+ CamelMessageInfo *mi)
{
guint32 uid, flags = 0;
gchar *header;
@@ -1359,7 +1359,8 @@ decode_flags_from_xev (const gchar *xev,
}
g_free (header);
- mi->flags = flags;
+ camel_message_info_set_flags (mi, ~0, flags);
+
return 0;
}
@@ -1421,6 +1422,7 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
CamelMessageInfo *info;
CamelMimeMessage *message;
+ const CamelNameValueArray *headers;
CamelMimePart *mime_part;
gint pc = 0;
const gchar *xev;
@@ -1448,13 +1450,14 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
goto fail;
}
- info = camel_message_info_new_from_header (NULL, mime_part->headers);
+ headers = camel_medium_get_headers (CAMEL_MEDIUM (mime_part));
+ info = camel_message_info_new_from_headers (NULL, headers);
/* Try and see if it has X-Evolution headers */
- xev = camel_header_raw_find (&mime_part->headers, "X-Evolution", NULL);
+ xev = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE,
"X-Evolution");
if (xev)
- decode_flags_from_xev (xev, (CamelMessageInfoBase *) info);
+ decode_flags_from_xev (xev, info);
- ((CamelMessageInfoBase *) info)->size = camel_mime_parser_tell (mp) - last;
+ camel_message_info_set_size (info, camel_mime_parser_tell (mp) - last);
last = camel_mime_parser_tell (mp);
status = camel_filter_driver_filter_message (
@@ -1466,7 +1469,7 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
report_status (
driver, CAMEL_FILTER_STATUS_END,
100, _("Failed on message %d"), i);
- camel_message_info_unref (info);
+ g_clear_object (&info);
g_propagate_error (error, local_error);
goto fail;
}
@@ -1476,7 +1479,7 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
/* skip over the FROM_END state */
camel_mime_parser_step (mp, NULL, NULL);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
camel_operation_progress (cancellable, 100);
@@ -1565,7 +1568,7 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver,
store_uid, store_uid, cancellable, &local_error);
if (camel_folder_has_summary_capability (folder))
- camel_message_info_unref (info);
+ g_clear_object (&info);
if (local_error != NULL || status == -1) {
report_status (
@@ -1690,7 +1693,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
g_return_val_if_fail (message != NULL || (source != NULL && uid != NULL), -1);
if (info == NULL) {
- struct _camel_header_raw *h;
+ const CamelNameValueArray *headers;
if (message) {
g_object_ref (message);
@@ -1701,8 +1704,8 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
return -1;
}
- h = CAMEL_MIME_PART (message)->headers;
- info = camel_message_info_new_from_header (NULL, h);
+ headers = camel_medium_get_headers (CAMEL_MEDIUM (message));
+ info = camel_message_info_new_from_headers (NULL, headers);
freeinfo = TRUE;
} else {
if (camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED)
@@ -1865,7 +1868,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
g_object_unref (driver->priv->message);
if (freeinfo)
- camel_message_info_unref (info);
+ g_clear_object (&info);
return 0;
@@ -1877,7 +1880,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
g_object_unref (driver->priv->message);
if (freeinfo)
- camel_message_info_unref (info);
+ g_clear_object (&info);
g_propagate_error (error, driver->priv->error);
driver->priv->error = NULL;
diff --git a/src/camel/camel-filter-driver.h b/src/camel/camel-filter-driver.h
index d0b7eda..8425863 100644
--- a/src/camel/camel-filter-driver.h
+++ b/src/camel/camel-filter-driver.h
@@ -61,6 +61,9 @@ struct _CamelFilterDriver {
struct _CamelFilterDriverClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
/* FIXME: this maybe should change... */
@@ -74,7 +77,7 @@ enum camel_filter_status_t {
};
typedef CamelFolder * (*CamelFilterGetFolderFunc) (CamelFilterDriver *driver, const gchar *uri,
- gpointer data, GError **error);
+ gpointer user_data, GError **error);
/* report status */
typedef void (*CamelFilterStatusFunc) (CamelFilterDriver *driver, enum camel_filter_status_t status,
gint pc, const gchar *desc, gpointer user_data);
diff --git a/src/camel/camel-filter-input-stream.h b/src/camel/camel-filter-input-stream.h
index abc8f3d..1740a4d 100644
--- a/src/camel/camel-filter-input-stream.h
+++ b/src/camel/camel-filter-input-stream.h
@@ -57,6 +57,9 @@ struct _CamelFilterInputStream {
struct _CamelFilterInputStreamClass {
GFilterInputStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_filter_input_stream_get_type
diff --git a/src/camel/camel-filter-output-stream.h b/src/camel/camel-filter-output-stream.h
index 064f851..b089f80 100644
--- a/src/camel/camel-filter-output-stream.h
+++ b/src/camel/camel-filter-output-stream.h
@@ -57,6 +57,9 @@ struct _CamelFilterOutputStream {
struct _CamelFilterOutputStreamClass {
GFilterOutputStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_filter_output_stream_get_type
diff --git a/src/camel/camel-filter-search.c b/src/camel/camel-filter-search.c
index 68f0b63..1d85d59 100644
--- a/src/camel/camel-filter-search.c
+++ b/src/camel/camel-filter-search.c
@@ -148,16 +148,18 @@ check_header_in_message_info (CamelMessageInfo *info,
{
struct _KnownHeaders {
const gchar *header_name;
- guint info_key;
+ const gchar *info_name;
+ camel_search_t type;
} known_headers[] = {
- { "Subject", CAMEL_MESSAGE_INFO_SUBJECT },
- { "From", CAMEL_MESSAGE_INFO_FROM },
- { "To", CAMEL_MESSAGE_INFO_TO },
- { "Cc", CAMEL_MESSAGE_INFO_CC }
+ { "Subject", "subject", CAMEL_SEARCH_TYPE_ENCODED },
+ { "From", "from", CAMEL_SEARCH_TYPE_ADDRESS_ENCODED },
+ { "To", "to", CAMEL_SEARCH_TYPE_ADDRESS_ENCODED },
+ { "Cc", "cc", CAMEL_SEARCH_TYPE_ADDRESS_ENCODED }
};
- camel_search_t type = CAMEL_SEARCH_TYPE_ENCODED;
- const gchar *name, *value;
+ const gchar *name;
+ gchar *value;
gboolean found = FALSE;
+ camel_search_t use_type;
gint ii;
g_return_val_if_fail (argc > 1, FALSE);
@@ -175,20 +177,20 @@ check_header_in_message_info (CamelMessageInfo *info,
gint jj;
for (jj = 0; jj < G_N_ELEMENTS (known_headers); jj++) {
- value = camel_message_info_get_ptr (info, known_headers[jj].info_key);
+ value = NULL;
+
+ g_object_get (G_OBJECT (info), known_headers[jj].info_name, &value, NULL);
+
if (!value)
continue;
- if (known_headers[jj].info_key == CAMEL_MESSAGE_INFO_SUBJECT)
- type = CAMEL_SEARCH_TYPE_ENCODED;
- else
- type = CAMEL_SEARCH_TYPE_ADDRESS_ENCODED;
-
for (ii = 1; ii < argc && !*matched; ii++) {
if (argv[ii]->type == CAMEL_SEXP_RES_STRING)
- *matched = camel_search_header_match (value, argv[ii]->value.string,
how, type, NULL);
+ *matched = camel_search_header_match (value, argv[ii]->value.string,
how, known_headers[jj].type, NULL);
}
+ g_free (value);
+
if (*matched)
return TRUE;
}
@@ -201,21 +203,24 @@ check_header_in_message_info (CamelMessageInfo *info,
for (ii = 0; ii < G_N_ELEMENTS (known_headers); ii++) {
found = g_ascii_strcasecmp (name, known_headers[ii].header_name) == 0;
if (found) {
- value = camel_message_info_get_ptr (info, known_headers[ii].info_key);
- if (known_headers[ii].info_key != CAMEL_MESSAGE_INFO_SUBJECT)
- type = CAMEL_SEARCH_TYPE_ADDRESS_ENCODED;
+ g_object_get (G_OBJECT (info), known_headers[ii].info_name, &value, NULL);
+ use_type = known_headers[ii].type;
break;
}
}
- if (!found || !value)
+ if (!found || !value) {
+ g_free (value);
return FALSE;
+ }
for (ii = 1; ii < argc && !*matched; ii++) {
if (argv[ii]->type == CAMEL_SEXP_RES_STRING)
- *matched = camel_search_header_match (value, argv[ii]->value.string, how, type, NULL);
+ *matched = camel_search_header_match (value, argv[ii]->value.string, how, use_type,
NULL);
}
+ g_free (value);
+
return TRUE;
}
@@ -249,10 +254,12 @@ check_header (struct _CamelSExp *f,
} else if (fms->message || !check_header_in_message_info (fms->info, argc, argv, how,
&matched)) {
CamelMimeMessage *message;
CamelMimePart *mime_part;
- struct _camel_header_raw *header;
+ const CamelNameValueArray *headers;
const gchar *charset = NULL;
camel_search_t type = CAMEL_SEARCH_TYPE_ENCODED;
CamelContentType *ct;
+ guint ii;
+ const gchar *header_name = NULL, *header_value = NULL;
message = camel_filter_search_get_message (fms, f);
mime_part = CAMEL_MIME_PART (message);
@@ -267,12 +274,13 @@ check_header (struct _CamelSExp *f,
}
}
- for (header = mime_part->headers; header && !matched; header = header->next) {
+ headers = camel_medium_get_headers (CAMEL_MEDIUM (mime_part));
+ for (ii = 0; camel_name_value_array_get (headers, ii, &header_name, &header_value);
ii++) {
/* empty name means any header */
- if (!name || !*name || !g_ascii_strcasecmp (header->name, name)) {
+ if (!name || !*name || !g_ascii_strcasecmp (header_name, name)) {
for (i = 1; i < argc && !matched; i++) {
if (argv[i]->type == CAMEL_SEXP_RES_STRING)
- matched = camel_search_header_match (header->value,
argv[i]->value.string, how, type, charset);
+ matched = camel_search_header_match (header_value,
argv[i]->value.string, how, type, charset);
}
}
}
@@ -845,7 +853,7 @@ junk_test (struct _CamelSExp *f,
CamelMimeMessage *message;
CamelJunkStatus status;
const GHashTable *ht;
- const CamelHeaderParam *node;
+ const CamelNameValueArray *info_headers;
gboolean sender_is_known;
gboolean message_is_junk = FALSE;
GError *error = NULL;
@@ -887,52 +895,69 @@ junk_test (struct _CamelSExp *f,
/* Check the headers for a junk designation. */
ht = camel_session_get_junk_headers (fms->session);
- node = camel_message_info_get_headers (info);
- while (node != NULL) {
- const gchar *value = NULL;
+ camel_message_info_property_lock (info);
- if (node->name != NULL)
- value = g_hash_table_lookup (
- (GHashTable *) ht, node->name);
+ info_headers = camel_message_info_get_headers (info);
+ if (info_headers) {
+ guint len, ii;
- message_is_junk =
- (value != NULL) &&
- (camel_strstrcase (node->value, value) != NULL);
+ len = camel_name_value_array_get_length (info_headers);
+ for (ii = 0; ii < len; ii++) {
+ const gchar *hdr_name = NULL;
+ const gchar *hdr_value = NULL;
+ const gchar *junk_value = NULL;
- if (message_is_junk) {
- if (camel_debug ("junk"))
- printf (
- "Message contains \"%s: %s\"",
- node->name, value);
- goto done;
- }
+ if (!camel_name_value_array_get (info_headers, ii, &hdr_name, &hdr_value))
+ continue;
+
+ if (!hdr_name || !hdr_value)
+ continue;
- node = node->next;
+ junk_value = g_hash_table_lookup ((GHashTable *) ht, hdr_name);
+
+ message_is_junk =
+ (junk_value != NULL) &&
+ (camel_strstrcase (hdr_value, junk_value) != NULL);
+
+ if (message_is_junk) {
+ if (camel_debug ("junk"))
+ printf (
+ "Message contains \"%s: %s\"",
+ hdr_name, junk_value);
+ camel_message_info_property_unlock (info);
+ goto done;
+ }
+ }
}
+ camel_message_info_property_unlock (info);
+
/* Not every message info has headers available, thus try headers of the message itself */
message = camel_filter_search_get_message (fms, f);
if (message) {
- struct _camel_header_raw *h;
+ const CamelNameValueArray *headers;
+ const gchar *raw_name = NULL, *raw_value = NULL;
+ guint ii;
- for (h = CAMEL_MIME_PART (message)->headers; h; h = h->next) {
+ headers = camel_medium_get_headers (CAMEL_MEDIUM (message));
+ for (ii = 0; camel_name_value_array_get (headers, ii, &raw_name, &raw_value); ii++) {
const gchar *value;
-
- if (!h->name)
+ if (!raw_name)
continue;
- value = g_hash_table_lookup ((GHashTable *) ht, h->name);
+ value = g_hash_table_lookup ((GHashTable *) ht, raw_name);
if (!value)
continue;
- message_is_junk = camel_strstrcase (h->value, value) != NULL;
+ message_is_junk = camel_strstrcase (raw_value, value) != NULL;
if (message_is_junk) {
- if (camel_debug ("junk"))
+ if (camel_debug ("junk")) {
printf (
"Message contains \"%s: %s\"",
- h->name, value);
+ raw_name, value);
+ }
goto done;
}
}
diff --git a/src/camel/camel-folder-search.c b/src/camel/camel-folder-search.c
index ffb4add..850d27d 100644
--- a/src/camel/camel-folder-search.c
+++ b/src/camel/camel-folder-search.c
@@ -57,6 +57,17 @@
((obj), CAMEL_TYPE_FOLDER_SEARCH, CamelFolderSearchPrivate))
struct _CamelFolderSearchPrivate {
+ CamelSExp *sexp; /* s-exp evaluator */
+ gchar *last_search; /* last searched expression */
+
+ /* these are only valid during the search, and are reset afterwards */
+ CamelFolder *folder; /* folder for current search */
+ GPtrArray *summary; /* summary array for current search */
+ GPtrArray *summary_set; /* subset of summary to actually include in search */
+ CamelMessageInfo *current; /* current message info, when searching one by one */
+ CamelMimeMessage *current_message; /* cache of current message, if required */
+ CamelIndex *body_index;
+
GCancellable *cancellable;
GError **error;
@@ -269,11 +280,10 @@ fill_thread_table (CamelFolderThreadNode *root,
static CamelMimeMessage *
get_current_message (CamelFolderSearch *search)
{
- if (!search || !search->folder || !search->current)
+ if (!search || !search->priv->folder || !search->priv->current)
return NULL;
- return camel_folder_get_message_sync (
- search->folder, search->current->uid, search->priv->cancellable, NULL);
+ return camel_folder_get_message_sync (search->priv->folder, camel_message_info_get_uid
(search->priv->current), search->priv->cancellable, NULL);
}
static CamelSExpResult *
@@ -289,7 +299,7 @@ check_header (CamelSExp *sexp,
r (printf ("executing check-header %d\n", how));
/* are we inside a match-all? */
- if (search->current && argc > 1
+ if (search->priv->current && argc > 1
&& argv[0]->type == CAMEL_SEXP_RES_STRING
&& !g_cancellable_is_cancelled (search->priv->cancellable)) {
gchar *headername;
@@ -299,29 +309,28 @@ check_header (CamelSExp *sexp,
camel_search_t type = CAMEL_SEARCH_TYPE_ASIS;
struct _camel_search_words *words;
CamelMimeMessage *message = NULL;
- struct _camel_header_raw *raw_header;
/* only a subset of headers are supported .. */
headername = argv[0]->value.string;
if (!g_ascii_strcasecmp (headername, "subject")) {
- header = camel_message_info_get_subject (search->current);
+ header = camel_message_info_get_subject (search->priv->current);
} else if (!g_ascii_strcasecmp (headername, "date")) {
/* FIXME: not a very useful form of the date */
g_snprintf (
strbuf, sizeof (strbuf), "%d",
- (gint) camel_message_info_get_date_sent (search->current));
+ (gint) camel_message_info_get_date_sent (search->priv->current));
header = strbuf;
} else if (!g_ascii_strcasecmp (headername, "from")) {
- header = camel_message_info_get_from (search->current);
+ header = camel_message_info_get_from (search->priv->current);
type = CAMEL_SEARCH_TYPE_ADDRESS;
} else if (!g_ascii_strcasecmp (headername, "to")) {
- header = camel_message_info_get_to (search->current);
+ header = camel_message_info_get_to (search->priv->current);
type = CAMEL_SEARCH_TYPE_ADDRESS;
} else if (!g_ascii_strcasecmp (headername, "cc")) {
- header = camel_message_info_get_cc (search->current);
+ header = camel_message_info_get_cc (search->priv->current);
type = CAMEL_SEARCH_TYPE_ADDRESS;
} else if (!g_ascii_strcasecmp (headername, "x-camel-mlist")) {
- header = camel_message_info_get_mlist (search->current);
+ header = camel_message_info_get_mlist (search->priv->current);
type = CAMEL_SEARCH_TYPE_MLIST;
} else {
message = get_current_message (search);
@@ -351,15 +360,20 @@ check_header (CamelSExp *sexp,
truth = TRUE;
for (j = 0; j < words->len && truth; j++) {
if (message) {
- for (raw_header = ((CamelMimePart *)
message)->headers; raw_header; raw_header = raw_header->next) {
+ const CamelNameValueArray *headers = NULL;
+ const gchar *raw_name = NULL, *raw_value = NULL;
+ guint ii;
+
+ headers = camel_medium_get_headers (CAMEL_MEDIUM
(message));
+ for (ii = 0; camel_name_value_array_get (headers, ii,
&raw_name, &raw_value); ii++) {
/* empty name means any header */
- if (!headername || !*headername ||
!g_ascii_strcasecmp (raw_header->name, headername)) {
- if (camel_search_header_match
(raw_header->value, words->words[j]->word, how, type, charset))
+ if (!headername || !*headername ||
!g_ascii_strcasecmp (raw_name, headername)) {
+ if (camel_search_header_match
(raw_value, words->words[j]->word, how, type, charset))
break;
}
}
- truth = raw_header != NULL;
+ truth = ii < camel_name_value_array_get_length
(headers);
} else
truth = camel_search_header_match (
header,
@@ -369,11 +383,16 @@ check_header (CamelSExp *sexp,
camel_search_words_free (words);
} else {
if (message) {
- for (raw_header = ((CamelMimePart *) message)->headers;
raw_header && !truth; raw_header = raw_header->next) {
+ const CamelNameValueArray *headers = NULL;
+ const gchar *raw_name = NULL, *raw_value = NULL;
+ guint ii;
+
+ headers = camel_medium_get_headers (CAMEL_MEDIUM (message));
+ for (ii = 0; camel_name_value_array_get (headers, ii,
&raw_name, &raw_value); ii++) {
/* empty name means any header */
- if (!headername || !*headername ||
!g_ascii_strcasecmp (raw_header->name, headername)) {
+ if (!headername || !*headername ||
!g_ascii_strcasecmp (raw_name, headername)) {
truth = camel_search_header_match (
- raw_header->value,
+ raw_value,
argv[i]->value.string,
how, type, charset);
}
@@ -460,7 +479,7 @@ match_words_index (CamelFolderSearch *search,
/* we can have a maximum of 32 words, as we use it as the AND mask */
- wc = camel_index_words (search->body_index);
+ wc = camel_index_words (search->priv->body_index);
if (wc) {
GHashTable *ht = g_hash_table_new (g_str_hash, g_str_equal);
@@ -468,7 +487,7 @@ match_words_index (CamelFolderSearch *search,
for (i = 0; i < words->len; i++) {
if (camel_ustrstrcase (word, words->words[i]->word) != NULL) {
/* perf: could have the wc cursor return the name cursor */
- nc = camel_index_find (search->body_index, word);
+ nc = camel_index_find (search->priv->body_index, word);
if (nc) {
while ((name = camel_index_cursor_next (nc))) {
gchar *name_owned;
@@ -528,7 +547,7 @@ match_words_1message (CamelDataWrapper *object,
} else if (CAMEL_IS_MIME_MESSAGE (containee)) {
/* for messages we only look at its contents */
truth = match_words_1message ((CamelDataWrapper *) containee, words, mask, cancellable);
- } else if (camel_content_type_is (CAMEL_DATA_WRAPPER (containee)->mime_type, "text", "*")) {
+ } else if (camel_content_type_is (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER
(containee)), "text", "*")) {
/* for all other text parts, we look inside, otherwise we dont care */
CamelStream *stream;
GByteArray *byte_array;
@@ -537,7 +556,7 @@ match_words_1message (CamelDataWrapper *object,
byte_array = g_byte_array_new ();
stream = camel_stream_mem_new_with_byte_array (byte_array);
- charset = camel_content_type_param (CAMEL_DATA_WRAPPER (containee)->mime_type, "charset");
+ charset = camel_content_type_param (camel_data_wrapper_get_mime_type_field
(CAMEL_DATA_WRAPPER (containee)), "charset");
if (charset && *charset) {
CamelMimeFilter *filter = camel_mime_filter_charset_new (charset, "UTF-8");
if (filter) {
@@ -609,7 +628,7 @@ match_words_messages (CamelFolderSearch *search,
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return matches;
- if (search->body_index) {
+ if (search->priv->body_index) {
GPtrArray *indexed;
struct _camel_search_words *simple;
@@ -621,20 +640,20 @@ match_words_messages (CamelFolderSearch *search,
const gchar *uid = g_ptr_array_index (indexed, i);
if (match_words_message (
- search->folder, uid, words,
+ search->priv->folder, uid, words,
cancellable, error))
g_ptr_array_add (matches, (gchar *) uid);
}
g_ptr_array_free (indexed, TRUE);
} else {
- GPtrArray *v = search->summary_set ? search->summary_set : search->summary;
+ GPtrArray *v = camel_folder_search_get_current_summary (search);
for (i = 0; i < v->len && !g_cancellable_is_cancelled (cancellable); i++) {
gchar *uid = g_ptr_array_index (v, i);
if (match_words_message (
- search->folder, uid, words,
+ search->priv->folder, uid, words,
cancellable, error))
g_ptr_array_add (matches, (gchar *) uid);
}
@@ -666,7 +685,7 @@ folder_search_dummy (CamelSExp *sexp,
{
CamelSExpResult *r;
- if (search->current == NULL) {
+ if (search->priv->current == NULL) {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
r->value.boolean = FALSE;
} else {
@@ -691,10 +710,7 @@ folder_search_dispose (GObject *object)
{
CamelFolderSearch *search = CAMEL_FOLDER_SEARCH (object);
- if (search->sexp != NULL) {
- g_object_unref (search->sexp);
- search->sexp = NULL;
- }
+ g_clear_object (&search->priv->sexp);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (camel_folder_search_parent_class)->dispose (object);
@@ -705,7 +721,7 @@ folder_search_finalize (GObject *object)
{
CamelFolderSearch *search = CAMEL_FOLDER_SEARCH (object);
- g_free (search->last_search);
+ g_free (search->priv->last_search);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_folder_search_parent_class)->finalize (object);
@@ -747,18 +763,18 @@ folder_search_constructed (GObject *object)
if (func != NULL) {
if (flags & CAMEL_FOLDER_SEARCH_IMMEDIATE) {
camel_sexp_add_ifunction (
- search->sexp, 0, name,
+ search->priv->sexp, 0, name,
(CamelSExpIFunc) func, search);
} else {
camel_sexp_add_function (
- search->sexp, 0, name,
+ search->priv->sexp, 0, name,
(CamelSExpFunc) func, search);
}
}
}
camel_sexp_add_function (
- search->sexp, 0, "header-has-words",
+ search->priv->sexp, 0, "header-has-words",
(CamelSExpFunc) folder_search_header_has_words, search);
}
@@ -781,10 +797,10 @@ folder_search_not (CamelSExp *sexp,
r->value.ptrarray = g_ptr_array_new ();
/* not against a single message?*/
- if (search->current) {
+ if (search->priv->current) {
gint found = FALSE;
- uid = camel_message_info_get_uid (search->current);
+ uid = camel_message_info_get_uid (search->priv->current);
for (i = 0; !found && i < v->len; i++) {
if (strcmp (uid, v->pdata[i]) == 0)
found = TRUE;
@@ -792,7 +808,7 @@ folder_search_not (CamelSExp *sexp,
if (!found)
g_ptr_array_add (r->value.ptrarray, (gchar *) uid);
- } else if (search->summary == NULL) {
+ } else if (search->priv->summary == NULL) {
g_warning ("No summary set, 'not' against an array requires a summary");
} else {
/* 'not' against the whole summary */
@@ -804,7 +820,7 @@ folder_search_not (CamelSExp *sexp,
for (i = 0; i < v->len; i++)
g_hash_table_insert (have, s[i], s[i]);
- v = search->summary_set ? search->summary_set : search->summary;
+ v = camel_folder_search_get_current_summary (search);
m = (gchar **) v->pdata;
for (i = 0; i < v->len; i++) {
gchar *uid = m[i];
@@ -847,8 +863,8 @@ folder_search_match_all (CamelSExp *sexp,
}
/* we are only matching a single message? or already inside a match-all? */
- if (search->current) {
- d (printf ("matching against 1 message: %s\n", camel_message_info_get_subject
(search->current)));
+ if (search->priv->current) {
+ d (printf ("matching against 1 message: %s\n", camel_message_info_get_subject
(search->priv->current)));
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
r->value.boolean = FALSE;
@@ -874,25 +890,25 @@ folder_search_match_all (CamelSExp *sexp,
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_ARRAY_PTR);
r->value.ptrarray = g_ptr_array_new ();
- if (search->summary == NULL) {
+ if (search->priv->summary == NULL) {
/* TODO: make it work - e.g. use the folder and so forth for a slower search */
g_warning ("No summary supplied, match-all doesn't work with no summary");
return r;
}
- v = search->summary_set ? search->summary_set : search->summary;
+ v = camel_folder_search_get_current_summary (search);
- if (!CAMEL_IS_VEE_FOLDER (search->folder)) {
- camel_folder_summary_prepare_fetch_all (search->folder->summary, search->priv->error);
+ if (!CAMEL_IS_VEE_FOLDER (search->priv->folder)) {
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary
(search->priv->folder), search->priv->error);
}
for (i = 0; i < v->len && !g_cancellable_is_cancelled (search->priv->cancellable); i++) {
const gchar *uid;
- search->current = camel_folder_summary_get (search->folder->summary, v->pdata[i]);
- if (!search->current)
+ search->priv->current = camel_folder_summary_get (camel_folder_get_folder_summary
(search->priv->folder), v->pdata[i]);
+ if (!search->priv->current)
continue;
- uid = camel_message_info_get_uid (search->current);
+ uid = camel_message_info_get_uid (search->priv->current);
if (argc > 0) {
r1 = camel_sexp_term_eval (sexp, argv[0]);
@@ -910,9 +926,9 @@ folder_search_match_all (CamelSExp *sexp,
} else {
g_ptr_array_add (r->value.ptrarray, (gchar *) uid);
}
- camel_message_info_unref (search->current);
+ g_clear_object (&search->priv->current);
}
- search->current = NULL;
+ search->priv->current = NULL;
return r;
}
@@ -935,7 +951,7 @@ folder_search_match_threads (CamelSExp *sexp,
}
/* not supported in match-all */
- if (search->current) {
+ if (search->priv->current) {
/* Translators: Each '%s' is an element type name, part of an expressing language */
error_msg = g_strdup_printf (_("(%s) not allowed inside %s"), "match-threads", "match-all");
camel_sexp_fatal_error (sexp, error_msg);
@@ -988,7 +1004,7 @@ folder_search_match_threads (CamelSExp *sexp,
if (type == 0)
return r;
- if (search->folder == NULL) {
+ if (search->priv->folder == NULL) {
/* Translators: The '%s' is an element type name, part of an expressing language */
error_msg = g_strdup_printf (_("(%s) requires the folder set"), "match-threads");
camel_sexp_fatal_error (sexp, error_msg);
@@ -997,7 +1013,7 @@ folder_search_match_threads (CamelSExp *sexp,
/* cache this, so we only have to re-calculate once per search at most */
if (p->threads == NULL) {
- p->threads = camel_folder_thread_messages_new (search->folder, NULL, TRUE);
+ p->threads = camel_folder_thread_messages_new (search->priv->folder, NULL, TRUE);
p->threads_hash = g_hash_table_new (g_str_hash, g_str_equal);
fill_thread_table (p->threads->tree, p->threads_hash);
@@ -1058,7 +1074,7 @@ folder_search_body_contains (CamelSExp *sexp,
CamelSExpResult *r;
struct IterData lambdafoo;
- if (search->current) {
+ if (search->priv->current) {
gint truth = FALSE;
if (argc == 1 && argv[0]->value.string[0] == 0) {
@@ -1068,18 +1084,18 @@ folder_search_body_contains (CamelSExp *sexp,
if (argv[i]->type == CAMEL_SEXP_RES_STRING) {
words = camel_search_words_split ((const guchar *)
argv[i]->value.string);
truth = TRUE;
- if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 &&
search->body_index) {
+ if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 &&
search->priv->body_index) {
for (j = 0; j < words->len && truth; j++)
truth = match_message_index (
- search->body_index,
- camel_message_info_get_uid (search->current),
+ search->priv->body_index,
+ camel_message_info_get_uid
(search->priv->current),
words->words[j]->word,
error);
} else {
/* TODO: cache current message incase of multiple body search
terms */
truth = match_words_message (
- search->folder,
- camel_message_info_get_uid (search->current),
+ search->priv->folder,
+ camel_message_info_get_uid (search->priv->current),
words,
search->priv->cancellable,
error);
@@ -1095,7 +1111,7 @@ folder_search_body_contains (CamelSExp *sexp,
r->value.ptrarray = g_ptr_array_new ();
if (argc == 1 && argv[0]->value.string[0] == 0) {
- GPtrArray *v = search->summary_set ? search->summary_set : search->summary;
+ GPtrArray *v = camel_folder_search_get_current_summary (search);
for (i = 0; i < v->len && !g_cancellable_is_cancelled (search->priv->cancellable);
i++) {
gchar *uid = g_ptr_array_index (v, i);
@@ -1109,7 +1125,7 @@ folder_search_body_contains (CamelSExp *sexp,
for (i = 0; i < argc && !g_cancellable_is_cancelled (search->priv->cancellable); i++)
{
if (argv[i]->type == CAMEL_SEXP_RES_STRING) {
words = camel_search_words_split ((const guchar *)
argv[i]->value.string);
- if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 &&
search->body_index) {
+ if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 &&
search->priv->body_index) {
matches = match_words_index (search, words,
search->priv->cancellable, error);
} else {
matches = match_words_messages (search, words,
search->priv->cancellable, error);
@@ -1173,14 +1189,14 @@ folder_search_body_regex (CamelSExp *sexp,
argc, argv,
search->priv->error) == 0) {
gint i;
- GPtrArray *v = search->summary_set ? search->summary_set : search->summary;
+ GPtrArray *v = camel_folder_search_get_current_summary (search);
CamelMimeMessage *message;
for (i = 0; i < v->len && !g_cancellable_is_cancelled (search->priv->cancellable);
i++) {
gchar *uid = g_ptr_array_index (v, i);
message = camel_folder_get_message_sync (
- search->folder, uid, search->priv->cancellable, NULL);
+ search->priv->folder, uid, search->priv->cancellable, NULL);
if (message) {
if (camel_search_message_body_contains ((CamelDataWrapper *) message,
&pattern)) {
g_ptr_array_add (r->value.ptrarray, uid);
@@ -1243,10 +1259,10 @@ folder_search_header_exists (CamelSExp *sexp,
r (printf ("executing header-exists\n"));
- if (search->current) {
+ if (search->priv->current) {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
if (argc == 1 && argv[0]->type == CAMEL_SEXP_RES_STRING)
- r->value.boolean = camel_medium_get_header (CAMEL_MEDIUM (search->current),
argv[0]->value.string) != NULL;
+ r->value.boolean = camel_medium_get_header (CAMEL_MEDIUM (search->priv->current),
argv[0]->value.string) != NULL;
} else {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_ARRAY_PTR);
@@ -1366,8 +1382,8 @@ folder_search_user_tag (CamelSExp *sexp,
r (printf ("executing user-tag\n"));
- if (search->current && argc == 1)
- value = camel_message_info_get_user_tag (search->current, argv[0]->value.string);
+ if (search->priv->current && argc == 1)
+ value = camel_message_info_get_user_tag (search->priv->current, argv[0]->value.string);
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_STRING);
r->value.string = g_strdup (value ? value : "");
@@ -1387,12 +1403,12 @@ folder_search_user_flag (CamelSExp *sexp,
r (printf ("executing user-flag\n"));
/* are we inside a match-all? */
- if (search->current) {
+ if (search->priv->current) {
gint truth = FALSE;
/* performs an OR of all words */
for (i = 0; i < argc && !truth; i++) {
if (argv[i]->type == CAMEL_SEXP_RES_STRING
- && camel_message_info_get_user_flag (search->current, argv[i]->value.string)) {
+ && camel_message_info_get_user_flag (search->priv->current,
argv[i]->value.string)) {
truth = TRUE;
break;
}
@@ -1417,11 +1433,11 @@ folder_search_system_flag (CamelSExp *sexp,
r (printf ("executing system-flag\n"));
- if (search->current) {
+ if (search->priv->current) {
gboolean truth = FALSE;
if (argc == 1)
- truth = camel_system_flag_get (camel_message_info_get_flags (search->current),
argv[0]->value.string);
+ truth = camel_system_flag_get (camel_message_info_get_flags (search->priv->current),
argv[0]->value.string);
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
r->value.boolean = truth;
@@ -1444,10 +1460,10 @@ folder_search_get_sent_date (CamelSExp *sexp,
r (printf ("executing get-sent-date\n"));
/* are we inside a match-all? */
- if (search->current) {
+ if (search->priv->current) {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_INT);
- r->value.number = camel_message_info_get_date_sent (search->current);
+ r->value.number = camel_message_info_get_date_sent (search->priv->current);
} else {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_ARRAY_PTR);
r->value.ptrarray = g_ptr_array_new ();
@@ -1467,10 +1483,10 @@ folder_search_get_received_date (CamelSExp *sexp,
r (printf ("executing get-received-date\n"));
/* are we inside a match-all? */
- if (search->current) {
+ if (search->priv->current) {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_INT);
- r->value.number = camel_message_info_get_date_received (search->current);
+ r->value.number = camel_message_info_get_date_received (search->priv->current);
} else {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_ARRAY_PTR);
r->value.ptrarray = g_ptr_array_new ();
@@ -1528,9 +1544,9 @@ folder_search_get_size (CamelSExp *sexp,
r (printf ("executing get-size\n"));
/* are we inside a match-all? */
- if (search->current) {
+ if (search->priv->current) {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_INT);
- r->value.number = camel_message_info_get_size (search->current) / 1024;
+ r->value.number = camel_message_info_get_size (search->priv->current) / 1024;
} else {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_ARRAY_PTR);
r->value.ptrarray = g_ptr_array_new ();
@@ -1551,9 +1567,9 @@ folder_search_uid (CamelSExp *sexp,
r (printf ("executing uid\n"));
/* are we inside a match-all? */
- if (search->current) {
+ if (search->priv->current) {
gint truth = FALSE;
- const gchar *uid = camel_message_info_get_uid (search->current);
+ const gchar *uid = camel_message_info_get_uid (search->priv->current);
/* performs an OR of all words */
for (i = 0; i < argc && !truth; i++) {
@@ -1617,13 +1633,13 @@ folder_search_message_location (CamelSExp *sexp,
gboolean same = FALSE;
if (argc == 1 && argv[0]->type == CAMEL_SEXP_RES_STRING) {
- if (argv[0]->value.string && search->folder) {
+ if (argv[0]->value.string && search->priv->folder) {
CamelStore *store;
const gchar *name;
gchar *uri;
- store = camel_folder_get_parent_store (search->folder);
- name = camel_folder_get_full_name (search->folder);
+ store = camel_folder_get_parent_store (search->priv->folder);
+ name = camel_folder_get_full_name (search->priv->folder);
uri = mail_folder_uri_build (store, name);
same = g_str_equal (uri, argv[0]->value.string);
@@ -1632,7 +1648,7 @@ folder_search_message_location (CamelSExp *sexp,
}
}
- if (search->current) {
+ if (search->priv->current) {
r = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
r->value.boolean = same ? TRUE : FALSE;
} else {
@@ -1642,7 +1658,7 @@ folder_search_message_location (CamelSExp *sexp,
if (same) {
/* all matches */
gint i;
- GPtrArray *v = search->summary_set ? search->summary_set : search->summary;
+ GPtrArray *v = camel_folder_search_get_current_summary (search);
for (i = 0; i < v->len; i++) {
gchar *uid = g_ptr_array_index (v, i);
@@ -1696,22 +1712,7 @@ static void
camel_folder_search_init (CamelFolderSearch *search)
{
search->priv = CAMEL_FOLDER_SEARCH_GET_PRIVATE (search);
- search->sexp = camel_sexp_new ();
-}
-
-/**
- * camel_folder_search_construct:
- * @search: a #CamelFolderSearch
- *
- * This function used to register callbacks with @search's internal
- * #CamelSExp, but this now happens during instance initialization.
- *
- * Deprecated: 3.8: The function no longer does anything.
- **/
-void
-camel_folder_search_construct (CamelFolderSearch *search)
-{
- /* XXX constructed() method handles what used to be here. */
+ search->priv->sexp = camel_sexp_new ();
}
/**
@@ -1733,13 +1734,97 @@ camel_folder_search_new (void)
}
/**
+ * camel_folder_search_set_current_message_info:
+ * @search: a #CamelFolderSearch
+ * @info: (nullable): a #CamelMessageInfo
+ *
+ * Sets, or unsets, the @info as the currently processing #CamelMessageInfo.
+ * The function adds its own reference to @info, if not %NULL.
+ *
+ * Since: 3.24
+ **/
+void
+camel_folder_search_set_current_message_info (CamelFolderSearch *search,
+ CamelMessageInfo *info)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER_SEARCH (search));
+ if (info)
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (info));
+
+ if (info != search->priv->current) {
+ if (info)
+ g_object_ref (info);
+
+ g_clear_object (&search->priv->current);
+ search->priv->current = info;
+ }
+}
+
+/**
+ * camel_folder_search_take_current_message_info:
+ * @search: a #CamelFolderSearch
+ * @info: (nullable): a #CamelMessageInfo
+ *
+ * Sets, or unsets, the @info as the currently processing #CamelMessageInfo.
+ * Unlike camel_folder_search_set_current_message_info(), this function
+ * assumes ownership of the @info, if not %NULL.
+ *
+ * Since: 3.24
+ **/
+void
+camel_folder_search_take_current_message_info (CamelFolderSearch *search,
+ CamelMessageInfo *info)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER_SEARCH (search));
+ if (info)
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (info));
+
+ camel_folder_search_set_current_message_info (search, info);
+
+ /* Remove the reference added by camel_folder_search_set_current_message_info() */
+ g_clear_object (&info);
+}
+
+/**
+ * camel_folder_search_get_current_message_info:
+ * @search: a #CamelFolderSearch
+ *
+ * Returns: (nullable) (transfer none): the currently processing #CamelMessageInfo
+ *
+ * Since: 3.24
+ **/
+CamelMessageInfo *
+camel_folder_search_get_current_message_info (CamelFolderSearch *search)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SEARCH (search), NULL);
+
+ return search->priv->current;
+}
+
+/**
+ * camel_folder_search_get_current_summary:
+ * @search: a #CamelFolderSearch
+ *
+ * Returns: (transfer none) (element-type utf8): the current summary, and array
+ * of message info UID-s to use.
+ *
+ * Since: 3.24
+ **/
+GPtrArray *
+camel_folder_search_get_current_summary (CamelFolderSearch *search)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SEARCH (search), NULL);
+
+ return search->priv->summary_set ? search->priv->summary_set : search->priv->summary;
+}
+
+/**
* camel_folder_search_set_folder:
- * @search:
- * @folder: A folder.
+ * @search: a #CamelFolderSearch
+ * @folder: a #CamelFolder
*
- * Set the folder attribute of the search. This is currently unused, but
- * could be used to perform a slow-search when indexes and so forth are not
- * available. Or for use by subclasses.
+ * Set the folder attribute of the search. This can be used to perform a slow-search
+ * when indexes and so forth are not available. Or for use by subclasses.
**/
void
camel_folder_search_set_folder (CamelFolderSearch *search,
@@ -1748,13 +1833,29 @@ camel_folder_search_set_folder (CamelFolderSearch *search,
g_return_if_fail (CAMEL_IS_FOLDER_SEARCH (search));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
- search->folder = folder;
+ search->priv->folder = folder;
+}
+
+/**
+ * camel_folder_search_get_folder:
+ * @search: a #CamelFolderSearch
+ *
+ * Returns: (transfer none): a #CamelFolder for which the @search is currently running.
+ *
+ * Since: 3.24
+ **/
+CamelFolder *
+camel_folder_search_get_folder (CamelFolderSearch *search)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SEARCH (search), NULL);
+
+ return search->priv->folder;
}
/**
* camel_folder_search_set_summary:
- * @search:
- * @summary: (element-type CamelMessageInfo): An array of CamelMessageInfo pointers.
+ * @search: a #CamelFolderSearch
+ * @summary: (element-type utf8): An array of UID-s of #CamelMessageInfo.
*
* Set the array of summary objects representing the span of the search.
*
@@ -1767,7 +1868,39 @@ camel_folder_search_set_summary (CamelFolderSearch *search,
{
g_return_if_fail (CAMEL_IS_FOLDER_SEARCH (search));
- search->summary = summary;
+ search->priv->summary = summary;
+}
+
+/**
+ * camel_folder_search_get_summary:
+ * @search: a #CamelFolderSearch
+ *
+ * Returns: (element-type utf8) (transfer none): A summary of UID-s of #CamelMessageInfo
+ * previously set by camel_folder_search_set_summary().
+ *
+ * Since: 3.24
+ **/
+GPtrArray *
+camel_folder_search_get_summary (CamelFolderSearch *search)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SEARCH (search), NULL);
+
+ return search->priv->summary;
+}
+
+/**
+ * camel_folder_search_get_summary_empty:
+ * @search: a #CamelFolderSearch
+ *
+ * Returns: Whether the summary (as returned by camel_folder_search_get_summary()) is empty.
+ * It returns %FALSE when the summary is set and contains at least one item.
+ **/
+gboolean
+camel_folder_search_get_summary_empty (CamelFolderSearch *search)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SEARCH (search), TRUE);
+
+ return !search->priv->summary || !search->priv->summary->len;
}
/**
@@ -1791,10 +1924,10 @@ camel_folder_search_set_body_index (CamelFolderSearch *search,
g_object_ref (body_index);
}
- if (search->body_index != NULL)
- g_object_unref (search->body_index);
+ if (search->priv->body_index != NULL)
+ g_object_unref (search->priv->body_index);
- search->body_index = body_index;
+ search->priv->body_index = body_index;
}
static gboolean
@@ -1818,8 +1951,8 @@ do_search_in_memory (CamelFolder *search_in_folder,
gint i;
if (search_in_folder &&
- search_in_folder->summary &&
- (search_in_folder->summary->flags & CAMEL_FOLDER_SUMMARY_IN_MEMORY_ONLY) != 0)
+ camel_folder_get_folder_summary (search_in_folder) &&
+ (camel_folder_summary_get_flags (camel_folder_get_folder_summary (search_in_folder)) &
CAMEL_FOLDER_SUMMARY_IN_MEMORY_ONLY) != 0)
return TRUE;
if (!expr)
@@ -1888,7 +2021,7 @@ camel_folder_search_count (CamelFolderSearch *search,
if (!expr || !*expr)
expr = "(match-all)";
- if (!search->folder) {
+ if (!search->priv->folder) {
g_warn_if_reached ();
goto fail;
}
@@ -1898,35 +2031,35 @@ camel_folder_search_count (CamelFolderSearch *search,
p->error = error;
/* We route body-contains search and thread based search through memory and not via db. */
- if (do_search_in_memory (search->folder, expr, &sql_query)) {
+ if (do_search_in_memory (search->priv->folder, expr, &sql_query)) {
/* setup our search list only contains those we're interested in */
- search->summary = camel_folder_get_summary (search->folder);
- if (search->folder->summary)
- camel_folder_summary_prepare_fetch_all (search->folder->summary, NULL);
+ search->priv->summary = camel_folder_get_summary (search->priv->folder);
+ if (camel_folder_get_folder_summary (search->priv->folder))
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary
(search->priv->folder), NULL);
- summary_set = search->summary;
+ summary_set = search->priv->summary;
/* only re-parse if the search has changed */
- if (search->last_search == NULL
- || strcmp (search->last_search, expr)) {
- camel_sexp_input_text (search->sexp, expr, strlen (expr));
- if (camel_sexp_parse (search->sexp) == -1) {
+ if (search->priv->last_search == NULL
+ || strcmp (search->priv->last_search, expr)) {
+ camel_sexp_input_text (search->priv->sexp, expr, strlen (expr));
+ if (camel_sexp_parse (search->priv->sexp) == -1) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Cannot parse search expression: %s:\n%s"),
- camel_sexp_error (search->sexp), expr);
+ camel_sexp_error (search->priv->sexp), expr);
goto fail;
}
- g_free (search->last_search);
- search->last_search = g_strdup (expr);
+ g_free (search->priv->last_search);
+ search->priv->last_search = g_strdup (expr);
}
- r = camel_sexp_eval (search->sexp);
+ r = camel_sexp_eval (search->priv->sexp);
if (r == NULL) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Error executing search expression: %s:\n%s"),
- camel_sexp_error (search->sexp), expr);
+ camel_sexp_error (search->priv->sexp), expr);
goto fail;
}
@@ -1949,18 +2082,18 @@ camel_folder_search_count (CamelFolderSearch *search,
g_hash_table_destroy (results);
}
- camel_sexp_result_free (search->sexp, r);
+ camel_sexp_result_free (search->priv->sexp, r);
} else {
CamelStore *parent_store;
const gchar *full_name;
GError *local_error = NULL;
- full_name = camel_folder_get_full_name (search->folder);
- parent_store = camel_folder_get_parent_store (search->folder);
+ full_name = camel_folder_get_full_name (search->priv->folder);
+ parent_store = camel_folder_get_parent_store (search->priv->folder);
/* Sync the db, so that we search the db for changes */
- camel_folder_summary_save_to_db (search->folder->summary, error);
+ camel_folder_summary_save (camel_folder_get_folder_summary (search->priv->folder), error);
dd (printf ("sexp is : [%s]\n", expr));
tmp1 = camel_db_sqlize_string (full_name);
@@ -1969,7 +2102,7 @@ camel_folder_search_count (CamelFolderSearch *search,
g_free (sql_query);
dd (printf ("Equivalent sql %s\n", tmp));
- cdb = (CamelDB *) (parent_store->cdb_r);
+ cdb = camel_store_get_db (parent_store);
camel_db_count_message_info (cdb, tmp, &count, &local_error);
if (local_error != NULL) {
const gchar *message = local_error->message;
@@ -1989,10 +2122,10 @@ fail:
camel_folder_thread_messages_unref (p->threads);
if (p->threads_hash)
g_hash_table_destroy (p->threads_hash);
- if (search->summary_set)
- g_ptr_array_free (search->summary_set, TRUE);
- if (search->summary)
- camel_folder_free_summary (search->folder, search->summary);
+ if (search->priv->summary_set)
+ g_ptr_array_free (search->priv->summary_set, TRUE);
+ if (search->priv->summary)
+ camel_folder_free_summary (search->priv->folder, search->priv->summary);
free_pstring_array (p->owned_pstrings);
p->owned_pstrings = NULL;
@@ -2000,11 +2133,11 @@ fail:
p->error = NULL;
p->threads = NULL;
p->threads_hash = NULL;
- search->folder = NULL;
- search->summary = NULL;
- search->summary_set = NULL;
- search->current = NULL;
- search->body_index = NULL;
+ search->priv->folder = NULL;
+ search->priv->summary = NULL;
+ search->priv->summary_set = NULL;
+ search->priv->current = NULL;
+ search->priv->body_index = NULL;
return count;
}
@@ -2048,7 +2181,7 @@ camel_folder_search_search (CamelFolderSearch *search,
if (!expr || !*expr)
expr = "(match-all)";
- if (!search->folder) {
+ if (!search->priv->folder) {
g_warn_if_reached ();
goto fail;
}
@@ -2058,47 +2191,47 @@ camel_folder_search_search (CamelFolderSearch *search,
p->error = error;
/* We route body-contains / thread based search and uid search through memory and not via db. */
- if (uids || do_search_in_memory (search->folder, expr, &sql_query)) {
+ if (uids || do_search_in_memory (search->priv->folder, expr, &sql_query)) {
/* setup our search list only contains those we're interested in */
- search->summary = camel_folder_get_summary (search->folder);
+ search->priv->summary = camel_folder_get_summary (search->priv->folder);
if (uids) {
GHashTable *uids_hash = g_hash_table_new (g_str_hash, g_str_equal);
- summary_set = search->summary_set = g_ptr_array_new ();
+ summary_set = search->priv->summary_set = g_ptr_array_new ();
for (i = 0; i < uids->len; i++)
g_hash_table_insert (uids_hash, uids->pdata[i], uids->pdata[i]);
- for (i = 0; i < search->summary->len; i++)
- if (g_hash_table_lookup (uids_hash, search->summary->pdata[i]))
- g_ptr_array_add (search->summary_set, search->summary->pdata[i]);
+ for (i = 0; i < search->priv->summary->len; i++)
+ if (g_hash_table_lookup (uids_hash, search->priv->summary->pdata[i]))
+ g_ptr_array_add (search->priv->summary_set,
search->priv->summary->pdata[i]);
g_hash_table_destroy (uids_hash);
} else {
- if (search->folder->summary)
- camel_folder_summary_prepare_fetch_all (search->folder->summary, NULL);
- summary_set = search->summary;
+ if (camel_folder_get_folder_summary (search->priv->folder))
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary
(search->priv->folder), NULL);
+ summary_set = search->priv->summary;
}
/* only re-parse if the search has changed */
- if (search->last_search == NULL
- || strcmp (search->last_search, expr)) {
- camel_sexp_input_text (search->sexp, expr, strlen (expr));
- if (camel_sexp_parse (search->sexp) == -1) {
+ if (search->priv->last_search == NULL
+ || strcmp (search->priv->last_search, expr)) {
+ camel_sexp_input_text (search->priv->sexp, expr, strlen (expr));
+ if (camel_sexp_parse (search->priv->sexp) == -1) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Cannot parse search expression: %s:\n%s"),
- camel_sexp_error (search->sexp), expr);
+ camel_sexp_error (search->priv->sexp), expr);
goto fail;
}
- g_free (search->last_search);
- search->last_search = g_strdup (expr);
+ g_free (search->priv->last_search);
+ search->priv->last_search = g_strdup (expr);
}
- r = camel_sexp_eval (search->sexp);
+ r = camel_sexp_eval (search->priv->sexp);
if (r == NULL) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Error executing search expression: %s:\n%s"),
- camel_sexp_error (search->sexp), expr);
+ camel_sexp_error (search->priv->sexp), expr);
goto fail;
}
@@ -2123,18 +2256,18 @@ camel_folder_search_search (CamelFolderSearch *search,
g_hash_table_destroy (results);
}
- camel_sexp_result_free (search->sexp, r);
+ camel_sexp_result_free (search->priv->sexp, r);
} else {
CamelStore *parent_store;
const gchar *full_name;
GError *local_error = NULL;
- full_name = camel_folder_get_full_name (search->folder);
- parent_store = camel_folder_get_parent_store (search->folder);
+ full_name = camel_folder_get_full_name (search->priv->folder);
+ parent_store = camel_folder_get_parent_store (search->priv->folder);
/* Sync the db, so that we search the db for changes */
- camel_folder_summary_save_to_db (search->folder->summary, error);
+ camel_folder_summary_save (camel_folder_get_folder_summary (search->priv->folder), error);
dd (printf ("sexp is : [%s]\n", expr));
tmp1 = camel_db_sqlize_string (full_name);
@@ -2144,7 +2277,7 @@ camel_folder_search_search (CamelFolderSearch *search,
dd (printf ("Equivalent sql %s\n", tmp));
matches = g_ptr_array_new ();
- cdb = (CamelDB *) (parent_store->cdb_r);
+ cdb = camel_store_get_db (parent_store);
camel_db_select (
cdb, tmp, (CamelDBSelectCB)
read_uid_callback, matches, &local_error);
@@ -2167,10 +2300,10 @@ fail:
camel_folder_thread_messages_unref (p->threads);
if (p->threads_hash)
g_hash_table_destroy (p->threads_hash);
- if (search->summary_set)
- g_ptr_array_free (search->summary_set, TRUE);
- if (search->summary)
- camel_folder_free_summary (search->folder, search->summary);
+ if (search->priv->summary_set)
+ g_ptr_array_free (search->priv->summary_set, TRUE);
+ if (search->priv->summary)
+ camel_folder_free_summary (search->priv->folder, search->priv->summary);
free_pstring_array (p->owned_pstrings);
p->owned_pstrings = NULL;
@@ -2178,11 +2311,11 @@ fail:
p->error = NULL;
p->threads = NULL;
p->threads_hash = NULL;
- search->folder = NULL;
- search->summary = NULL;
- search->summary_set = NULL;
- search->current = NULL;
- search->body_index = NULL;
+ search->priv->folder = NULL;
+ search->priv->summary = NULL;
+ search->priv->summary_set = NULL;
+ search->priv->current = NULL;
+ search->priv->body_index = NULL;
if (error && *error) {
camel_folder_search_free_result (search, matches);
diff --git a/src/camel/camel-folder-search.h b/src/camel/camel-folder-search.h
index 7c88f68..fe86b8b 100644
--- a/src/camel/camel-folder-search.h
+++ b/src/camel/camel-folder-search.h
@@ -56,17 +56,6 @@ typedef struct _CamelFolderSearchPrivate CamelFolderSearchPrivate;
struct _CamelFolderSearch {
GObject parent;
CamelFolderSearchPrivate *priv;
-
- CamelSExp *sexp; /* s-exp evaluator */
- gchar *last_search; /* last searched expression */
-
- /* these are only valid during the search, and are reset afterwards */
- CamelFolder *folder; /* folder for current search */
- GPtrArray *summary; /* summary array for current search */
- GPtrArray *summary_set; /* subset of summary to actually include in search */
- CamelMessageInfo *current; /* current message info, when searching one by one */
- CamelMimeMessage *current_message; /* cache of current message, if required */
- CamelIndex *body_index;
};
struct _CamelFolderSearchClass {
@@ -263,18 +252,36 @@ struct _CamelFolderSearchClass {
gint argc,
CamelSExpResult **argv,
CamelFolderSearch *search);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_folder_search_get_type (void) G_GNUC_CONST;
CamelFolderSearch *
camel_folder_search_new (void);
+void camel_folder_search_set_current_message_info
+ (CamelFolderSearch *search,
+ CamelMessageInfo *info);
+void camel_folder_search_take_current_message_info
+ (CamelFolderSearch *search,
+ CamelMessageInfo *info);
+CamelMessageInfo *
+ camel_folder_search_get_current_message_info
+ (CamelFolderSearch *search);
+GPtrArray * camel_folder_search_get_current_summary
+ (CamelFolderSearch *search);
/* XXX This stuff currently gets cleared when you run a search.
* What on earth was i thinking ... */
void camel_folder_search_set_folder (CamelFolderSearch *search,
CamelFolder *folder);
+CamelFolder * camel_folder_search_get_folder (CamelFolderSearch *search);
void camel_folder_search_set_summary (CamelFolderSearch *search,
GPtrArray *summary);
+GPtrArray * camel_folder_search_get_summary (CamelFolderSearch *search);
+gboolean camel_folder_search_get_summary_empty
+ (CamelFolderSearch *search);
void camel_folder_search_set_body_index
(CamelFolderSearch *search,
CamelIndex *body_index);
@@ -296,10 +303,6 @@ time_t camel_folder_search_util_add_months
(time_t t,
gint months);
-#ifndef CAMEL_DISABLE_DEPRECATED
-void camel_folder_search_construct (CamelFolderSearch *search);
-#endif /* CAMEL_DISABLE_DEPRECATED */
-
G_END_DECLS
#endif /* CAMEL_FOLDER_SEARCH_H */
diff --git a/src/camel/camel-folder-summary.c b/src/camel/camel-folder-summary.c
index aec35e3..e7f0234 100644
--- a/src/camel/camel-folder-summary.c
+++ b/src/camel/camel-folder-summary.c
@@ -37,6 +37,8 @@
#include "camel-folder-summary.h"
#include "camel-folder.h"
#include "camel-iconv.h"
+#include "camel-message-info.h"
+#include "camel-message-info-base.h"
#include "camel-mime-filter-basic.h"
#include "camel-mime-filter-charset.h"
#include "camel-mime-filter-html.h"
@@ -63,6 +65,11 @@
#define dd(x) if (camel_debug("sync")) x
struct _CamelFolderSummaryPrivate {
+ /* header info */
+ guint32 version; /* version of file loaded/loading */
+ gint64 timestamp; /* timestamp for this summary (for implementors to use) */
+ CamelFolderSummaryFlags flags;
+
GHashTable *filter_charset; /* CamelMimeFilterCharset's indexed by source charset */
struct _CamelMimeFilter *filter_index;
@@ -79,9 +86,6 @@ struct _CamelFolderSummaryPrivate {
GRecMutex summary_lock; /* for the summary hashtable/array */
GRecMutex filter_lock; /* for accessing any of the filtering/indexing stuff, since we share them */
- gboolean need_preview;
- GHashTable *preview_updates;
-
guint32 nextuid; /* next uid? */
guint32 saved_count; /* how many were saved/loaded */
guint32 unread_count; /* handy totals */
@@ -90,8 +94,6 @@ struct _CamelFolderSummaryPrivate {
guint32 junk_not_deleted_count;
guint32 visible_count;
- gboolean build_content; /* do we try and parse/index the content, or not? */
-
GHashTable *uids; /* uids of all known message infos; the 'value' are used flags for the message info
*/
GHashTable *loaded_infos; /* uid->CamelMessageInfo *, those currently in memory */
@@ -116,27 +118,18 @@ struct _node {
static void cfs_schedule_info_release_timer (CamelFolderSummary *summary);
-static struct _node *my_list_append (struct _node **list, struct _node *n);
-static gint my_list_size (struct _node **list);
+static void summary_traverse_content_with_parser (CamelFolderSummary *summary, CamelMessageInfo *msginfo,
CamelMimeParser *mp);
+static void summary_traverse_content_with_part (CamelFolderSummary *summary, CamelMessageInfo *msginfo,
CamelMimePart *object);
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_headers (CamelFolderSummary *, const CamelNameValueArray *);
static CamelMessageInfo * message_info_new_from_parser (CamelFolderSummary *, CamelMimeParser *);
-static CamelMessageInfo * message_info_new_from_message (CamelFolderSummary *summary, CamelMimeMessage *msg,
const gchar *bodystructure);
-static void message_info_free (CamelFolderSummary *, CamelMessageInfo *);
-
-static CamelMessageContentInfo * content_info_new_from_header (CamelFolderSummary *, struct
_camel_header_raw *);
-static CamelMessageContentInfo * content_info_new_from_parser (CamelFolderSummary *, CamelMimeParser *);
-static CamelMessageContentInfo * content_info_new_from_message (CamelFolderSummary *summary, CamelMimePart
*mp);
-static void content_info_free (CamelFolderSummary *, CamelMessageContentInfo *);
+static CamelMessageInfo * message_info_new_from_message (CamelFolderSummary *summary, CamelMimeMessage *msg);
static gint save_message_infos_to_db (CamelFolderSummary *summary, GError **error);
static gint camel_read_mir_callback (gpointer ref, gint ncol, gchar ** cols, gchar ** name);
static gchar *next_uid_string (CamelFolderSummary *summary);
-static CamelMessageContentInfo * summary_build_content_info (CamelFolderSummary *summary, CamelMessageInfo
*msginfo, CamelMimeParser *mp);
-static CamelMessageContentInfo * summary_build_content_info_message (CamelFolderSummary *summary,
CamelMessageInfo *msginfo, CamelMimePart *object);
-
static CamelMessageInfo * message_info_from_uid (CamelFolderSummary *summary, const gchar *uid);
enum {
@@ -147,18 +140,11 @@ enum {
PROP_DELETED_COUNT,
PROP_JUNK_COUNT,
PROP_JUNK_NOT_DELETED_COUNT,
- PROP_VISIBLE_COUNT,
- PROP_BUILD_CONTENT,
- PROP_NEED_PREVIEW
+ PROP_VISIBLE_COUNT
};
G_DEFINE_TYPE (CamelFolderSummary, camel_folder_summary, G_TYPE_OBJECT)
-G_DEFINE_BOXED_TYPE (CamelMessageInfo,
- camel_message_info,
- camel_message_info_ref,
- camel_message_info_unref)
-
static gboolean
remove_each_item (gpointer uid,
gpointer mi,
@@ -182,8 +168,7 @@ remove_all_loaded (CamelFolderSummary *summary)
g_hash_table_foreach_remove (summary->priv->loaded_infos, remove_each_item, &to_remove_infos);
- g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_unref, NULL);
- g_slist_free (to_remove_infos);
+ g_slist_free_full (to_remove_infos, g_object_unref);
camel_folder_summary_unlock (summary);
}
@@ -242,8 +227,6 @@ folder_summary_finalize (GObject *object)
g_hash_table_foreach (priv->filter_charset, free_o_name, NULL);
g_hash_table_destroy (priv->filter_charset);
- g_hash_table_destroy (priv->preview_updates);
-
g_rec_mutex_clear (&priv->summary_lock);
g_rec_mutex_clear (&priv->filter_lock);
@@ -275,18 +258,6 @@ folder_summary_set_property (GObject *object,
CAMEL_FOLDER_SUMMARY (object),
CAMEL_FOLDER (g_value_get_object (value)));
return;
-
- case PROP_BUILD_CONTENT:
- camel_folder_summary_set_build_content (
- CAMEL_FOLDER_SUMMARY (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_NEED_PREVIEW:
- camel_folder_summary_set_need_preview (
- CAMEL_FOLDER_SUMMARY (object),
- g_value_get_boolean (value));
- return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -347,20 +318,6 @@ folder_summary_get_property (GObject *object,
camel_folder_summary_get_visible_count (
CAMEL_FOLDER_SUMMARY (object)));
return;
-
- case PROP_BUILD_CONTENT:
- g_value_set_boolean (
- value,
- camel_folder_summary_get_build_content (
- CAMEL_FOLDER_SUMMARY (object)));
- return;
-
- case PROP_NEED_PREVIEW:
- g_value_set_boolean (
- value,
- camel_folder_summary_get_need_preview (
- CAMEL_FOLDER_SUMMARY (object)));
- return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -371,7 +328,7 @@ is_in_memory_summary (CamelFolderSummary *summary)
{
g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
- return (summary->flags & CAMEL_FOLDER_SUMMARY_IN_MEMORY_ONLY) != 0;
+ return (summary->priv->flags & CAMEL_FOLDER_SUMMARY_IN_MEMORY_ONLY) != 0;
}
#define UPDATE_COUNTS_ADD (1)
@@ -398,8 +355,8 @@ folder_summary_update_counts_by_flags (CamelFolderSummary *summary,
if (summary->priv->folder && CAMEL_IS_VTRASH_FOLDER (summary->priv->folder)) {
CamelVTrashFolder *vtrash = CAMEL_VTRASH_FOLDER (summary->priv->folder);
- is_junk_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_JUNK;
- is_trash_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_TRASH;
+ is_junk_folder = vtrash && camel_vtrash_folder_get_folder_type (vtrash) ==
CAMEL_VTRASH_FOLDER_JUNK;
+ is_trash_folder = vtrash && camel_vtrash_folder_get_folder_type (vtrash) ==
CAMEL_VTRASH_FOLDER_TRASH;
}
if (!(flags & CAMEL_MESSAGE_SEEN))
@@ -467,31 +424,31 @@ folder_summary_update_counts_by_flags (CamelFolderSummary *summary,
}
static gboolean
-summary_header_from_db (CamelFolderSummary *summary,
- CamelFIRecord *record)
+summary_header_load (CamelFolderSummary *summary,
+ CamelFIRecord *record)
{
io (printf ("Loading header from db \n"));
- summary->version = record->version;
+ summary->priv->version = record->version;
/* We may not worry, as we are setting a new standard here */
#if 0
/* Legacy version check, before version 12 we have no upgrade knowledge */
- if ((summary->version > 0xff) && (summary->version & 0xff) < 12) {
+ if ((summary->priv->version > 0xff) && (summary->priv->version & 0xff) < 12) {
io (printf ("Summary header version mismatch"));
errno = EINVAL;
return FALSE;
}
- if (!(summary->version < 0x100 && summary->version >= 13))
+ if (!(summary->priv->version < 0x100 && summary->priv->version >= 13))
io (printf ("Loading legacy summary\n"));
else
io (printf ("loading new-format summary\n"));
#endif
- summary->flags = record->flags;
+ summary->priv->flags = record->flags;
summary->priv->nextuid = record->nextuid;
- summary->time = record->time;
+ summary->priv->timestamp = record->timestamp;
summary->priv->saved_count = record->saved_count;
summary->priv->unread_count = record->unread_count;
@@ -504,19 +461,19 @@ summary_header_from_db (CamelFolderSummary *summary,
}
static CamelFIRecord *
-summary_header_to_db (CamelFolderSummary *summary,
- GError **error)
+summary_header_save (CamelFolderSummary *summary,
+ GError **error)
{
CamelFIRecord *record = g_new0 (CamelFIRecord, 1);
CamelStore *parent_store;
- CamelDB *db;
+ CamelDB *cdb;
const gchar *table_name;
/* Though we are going to read, we do this during write,
* so lets use it that way. */
table_name = camel_folder_get_full_name (summary->priv->folder);
parent_store = camel_folder_get_parent_store (summary->priv->folder);
- db = parent_store ? parent_store->cdb_w : NULL;
+ cdb = parent_store ? camel_store_get_db (parent_store) : NULL;
io (printf ("Savining header to db\n"));
@@ -524,23 +481,23 @@ summary_header_to_db (CamelFolderSummary *summary,
/* we always write out the current version */
record->version = CAMEL_FOLDER_SUMMARY_VERSION;
- record->flags = summary->flags;
+ record->flags = summary->priv->flags;
record->nextuid = summary->priv->nextuid;
- record->time = summary->time;
+ record->timestamp = summary->priv->timestamp;
- if (db && !is_in_memory_summary (summary)) {
+ if (cdb && !is_in_memory_summary (summary)) {
/* FIXME: Ever heard of Constructors and initializing ? */
- if (camel_db_count_total_message_info (db, table_name, &(record->saved_count), NULL))
+ if (camel_db_count_total_message_info (cdb, table_name, &(record->saved_count), NULL))
record->saved_count = 0;
- if (camel_db_count_junk_message_info (db, table_name, &(record->junk_count), NULL))
+ if (camel_db_count_junk_message_info (cdb, table_name, &(record->junk_count), NULL))
record->junk_count = 0;
- if (camel_db_count_deleted_message_info (db, table_name, &(record->deleted_count), NULL))
+ if (camel_db_count_deleted_message_info (cdb, table_name, &(record->deleted_count), NULL))
record->deleted_count = 0;
- if (camel_db_count_unread_message_info (db, table_name, &(record->unread_count), NULL))
+ if (camel_db_count_unread_message_info (cdb, table_name, &(record->unread_count), NULL))
record->unread_count = 0;
- if (camel_db_count_visible_message_info (db, table_name, &(record->visible_count), NULL))
+ if (camel_db_count_visible_message_info (cdb, table_name, &(record->visible_count), NULL))
record->visible_count = 0;
- if (camel_db_count_junk_not_deleted_message_info (db, table_name, &(record->jnd_count), NULL))
+ if (camel_db_count_junk_not_deleted_message_info (cdb, table_name, &(record->jnd_count),
NULL))
record->jnd_count = 0;
}
@@ -553,282 +510,6 @@ summary_header_to_db (CamelFolderSummary *summary,
return record;
}
-static CamelMessageInfo *
-message_info_from_db (CamelFolderSummary *summary,
- CamelMIRecord *record)
-{
- CamelMessageInfoBase *mi;
- gint i;
- gint count;
- gchar *part, *label;
-
- mi = (CamelMessageInfoBase *) camel_message_info_new (summary);
-
- io (printf ("Loading message info from db\n"));
-
- mi->flags = record->flags;
- mi->size = record->size;
- mi->date_sent = record->dsent;
- mi->date_received = record->dreceived;
-
- mi->uid = (gchar *) camel_pstring_strdup (record->uid);
- mi->subject = (gchar *) camel_pstring_add (record->subject, FALSE);
- mi->from = (gchar *) camel_pstring_add (record->from, FALSE);
- mi->to = (gchar *) camel_pstring_add (record->to, FALSE);
- mi->cc = (gchar *) camel_pstring_add (record->cc, FALSE);
- mi->mlist = (gchar *) camel_pstring_add (record->mlist, FALSE);
-
- /* Evolution itself doesn't yet use this, so we ignore it (saving some memory) */
- mi->bodystructure = NULL;
-
- /* Extract Message id & References */
- mi->content = NULL;
- part = record->part;
- if (part) {
- mi->message_id.id.part.hi = bdata_extract_digit (&part);
- mi->message_id.id.part.lo = bdata_extract_digit (&part);
- count = bdata_extract_digit (&part);
-
- if (count > 0) {
- mi->references = g_malloc (sizeof (*mi->references) + ((count - 1) * sizeof
(mi->references->references[0])));
- mi->references->size = count;
- for (i = 0; i < count; i++) {
- mi->references->references[i].id.part.hi = bdata_extract_digit (&part);
- mi->references->references[i].id.part.lo = bdata_extract_digit (&part);
- }
- } else
- mi->references = NULL;
-
- }
-
- /* Extract User flags/labels */
- part = record->labels;
- if (part) {
- label = part;
- for (i = 0; part[i]; i++) {
-
- if (part[i] == ' ') {
- part[i] = 0;
- camel_flag_set (&mi->user_flags, label, TRUE);
- label = &(part[i + 1]);
- }
- }
- camel_flag_set (&mi->user_flags, label, TRUE);
- }
-
- /* Extract User tags */
- part = record->usertags;
- count = bdata_extract_digit (&part);
- for (i = 0; i < count; i++) {
- gchar *name, *value;
-
- name = bdata_extract_string (&part);
- value = bdata_extract_string (&part);
- camel_tag_set (&mi->user_tags, name, value);
-
- g_free (name);
- g_free (value);
- }
-
- return (CamelMessageInfo *) mi;
-}
-
-static CamelMIRecord *
-message_info_to_db (CamelFolderSummary *summary,
- CamelMessageInfo *info)
-{
- CamelMIRecord *record = g_new0 (CamelMIRecord, 1);
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
- GString *tmp;
- CamelFlag *flag;
- CamelTag *tag;
- gint count, i;
-
- /* Assume that we dont have to take care of DB Safeness. It will be done while doing the DB
transaction */
- record->uid = (gchar *) camel_pstring_strdup (camel_message_info_get_uid (info));
- record->flags = mi->flags;
-
- record->read = ((mi->flags & (CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_JUNK))) ? 1
: 0;
- record->deleted = mi->flags & CAMEL_MESSAGE_DELETED ? 1 : 0;
- record->replied = mi->flags & CAMEL_MESSAGE_ANSWERED ? 1 : 0;
- record->important = mi->flags & CAMEL_MESSAGE_FLAGGED ? 1 : 0;
- record->junk = mi->flags & CAMEL_MESSAGE_JUNK ? 1 : 0;
- record->dirty = mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED ? 1 : 0;
- record->attachment = mi->flags & CAMEL_MESSAGE_ATTACHMENTS ? 1 : 0;
-
- record->size = mi->size;
- record->dsent = mi->date_sent;
- record->dreceived = mi->date_received;
-
- record->subject = (gchar *) camel_pstring_strdup (camel_message_info_get_subject (info));
- record->from = (gchar *) camel_pstring_strdup (camel_message_info_get_from (info));
- record->to = (gchar *) camel_pstring_strdup (camel_message_info_get_to (info));
- record->cc = (gchar *) camel_pstring_strdup (camel_message_info_get_cc (info));
- record->mlist = (gchar *) camel_pstring_strdup (camel_message_info_get_mlist (info));
-
- record->followup_flag = (gchar *) camel_pstring_strdup (camel_message_info_get_user_tag (info,
"follow-up"));
- record->followup_completed_on = (gchar *) camel_pstring_strdup (camel_message_info_get_user_tag
(info, "completed-on"));
- record->followup_due_by = (gchar *) camel_pstring_strdup (camel_message_info_get_user_tag (info,
"due-by"));
-
- record->bodystructure = mi->bodystructure ? g_strdup (mi->bodystructure) : NULL;
-
- tmp = g_string_new (NULL);
- if (mi->references) {
- g_string_append_printf (tmp, "%lu %lu %lu", (gulong) mi->message_id.id.part.hi, (gulong)
mi->message_id.id.part.lo, (gulong) mi->references->size);
- for (i = 0; i < mi->references->size; i++)
- g_string_append_printf (tmp, " %lu %lu", (gulong)
mi->references->references[i].id.part.hi, (gulong) mi->references->references[i].id.part.lo);
- } else {
- g_string_append_printf (tmp, "%lu %lu %lu", (gulong) mi->message_id.id.part.hi, (gulong)
mi->message_id.id.part.lo, (gulong) 0);
- }
- record->part = tmp->str;
- g_string_free (tmp, FALSE);
-
- tmp = g_string_new (NULL);
- flag = mi->user_flags;
- while (flag) {
- g_string_append_printf (tmp, "%s ", flag->name);
- flag = flag->next;
- }
-
- /* Strip off the last space */
- if (tmp->len)
- tmp->len--;
-
- record->labels = tmp->str;
- g_string_free (tmp, FALSE);
-
- tmp = g_string_new (NULL);
- count = camel_tag_list_size (&mi->user_tags);
- g_string_append_printf (tmp, "%lu", (gulong) count);
- tag = mi->user_tags;
- while (tag) {
- /* FIXME: Should we handle empty tags? Can it be empty? If it potential crasher ahead*/
- g_string_append_printf (tmp, " %lu-%s %lu-%s", (gulong) strlen (tag->name), tag->name,
(gulong) strlen (tag->value), tag->value);
- tag = tag->next;
- }
- record->usertags = tmp->str;
- g_string_free (tmp, FALSE);
-
- return record;
-}
-
-static CamelMessageContentInfo *
-content_info_from_db (CamelFolderSummary *summary,
- CamelMIRecord *record)
-{
- CamelMessageContentInfo *ci;
- gchar *type, *subtype;
- guint32 count, i;
- CamelContentType *ct;
- gchar *part = record->cinfo;
-
- io (printf ("Loading content info from db\n"));
-
- if (!part)
- return NULL;
-
- ci = camel_folder_summary_content_info_new (summary);
- if (*part == ' ') part++; /* Move off the space in the record */
-
- type = bdata_extract_string (&part);
- subtype = bdata_extract_string (&part);
- ct = camel_content_type_new (type, subtype);
- g_free (type); /* can this be removed? */
- g_free (subtype);
- count = bdata_extract_digit (&part);
-
- for (i = 0; i < count; i++) {
- gchar *name, *value;
- name = bdata_extract_string (&part);
- value = bdata_extract_string (&part);
-
- camel_content_type_set_param (ct, name, value);
- /* TODO: do this so we dont have to double alloc/free */
- g_free (name);
- g_free (value);
- }
- ci->type = ct;
-
- /* FIXME[disk-summary] move all these to camel pstring */
- ci->id = bdata_extract_string (&part);
- ci->description = bdata_extract_string (&part);
- ci->encoding = bdata_extract_string (&part);
- ci->size = bdata_extract_digit (&part);
-
- record->cinfo = part; /* Keep moving the cursor in the record */
-
- ci->childs = NULL;
-
- return ci;
-}
-
-static gboolean
-content_info_to_db (CamelFolderSummary *summary,
- CamelMessageContentInfo *ci,
- CamelMIRecord *record)
-{
- CamelContentType *ct;
- struct _camel_header_param *hp;
- GString *str = g_string_new (NULL);
- gchar *oldr;
-
- io (printf ("Saving content info to db\n"));
-
- ct = ci->type;
- if (ct) {
- if (ct->type)
- g_string_append_printf (str, " %d-%s", (gint) strlen (ct->type), ct->type);
- else
- g_string_append_printf (str, " 0-");
- if (ct->subtype)
- g_string_append_printf (str, " %d-%s", (gint) strlen (ct->subtype), ct->subtype);
- else
- g_string_append_printf (str, " 0-");
- g_string_append_printf (str, " %d", my_list_size ((struct _node **) &ct->params));
- hp = ct->params;
- while (hp) {
- if (hp->name)
- g_string_append_printf (str, " %d-%s", (gint) strlen (hp->name), hp->name);
- else
- g_string_append_printf (str, " 0-");
- if (hp->value)
- g_string_append_printf (str, " %d-%s", (gint) strlen (hp->value), hp->value);
- else
- g_string_append_printf (str, " 0-");
- hp = hp->next;
- }
- } else {
- g_string_append_printf (str, " %d-", 0);
- g_string_append_printf (str, " %d-", 0);
- g_string_append_printf (str, " %d", 0);
- }
-
- if (ci->id)
- g_string_append_printf (str, " %d-%s", (gint) strlen (ci->id), ci->id);
- else
- g_string_append_printf (str, " 0-");
- if (ci->description)
- g_string_append_printf (str, " %d-%s", (gint) strlen (ci->description), ci->description);
- else
- g_string_append_printf (str, " 0-");
- if (ci->encoding)
- g_string_append_printf (str, " %d-%s", (gint) strlen (ci->encoding), ci->encoding);
- else
- g_string_append_printf (str, " 0-");
- g_string_append_printf (str, " %u", ci->size);
-
- if (record->cinfo) {
- oldr = record->cinfo;
- record->cinfo = g_strconcat (oldr, str->str, NULL);
- g_free (oldr); g_string_free (str, TRUE);
- } else {
- record->cinfo = str->str;
- g_string_free (str, FALSE);
- }
-
- return TRUE;
-}
-
/**
* camel_folder_summary_replace_flags:
* @summary: a #CamelFolderSummary
@@ -873,8 +554,8 @@ camel_folder_summary_replace_flags (CamelFolderSummary *summary,
if (summary->priv->folder && CAMEL_IS_VTRASH_FOLDER (summary->priv->folder)) {
CamelVTrashFolder *vtrash = CAMEL_VTRASH_FOLDER (summary->priv->folder);
- is_junk_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_JUNK;
- is_trash_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_TRASH;
+ is_junk_folder = vtrash && camel_vtrash_folder_get_folder_type (vtrash) ==
CAMEL_VTRASH_FOLDER_JUNK;
+ is_trash_folder = vtrash && camel_vtrash_folder_get_folder_type (vtrash) ==
CAMEL_VTRASH_FOLDER_TRASH;
}
added_flags = new_flags & (~(old_flags & new_flags));
@@ -915,231 +596,6 @@ camel_folder_summary_replace_flags (CamelFolderSummary *summary,
return changed;
}
-static CamelMessageInfo *
-message_info_clone (CamelFolderSummary *summary,
- const CamelMessageInfo *mi)
-{
- CamelMessageInfoBase *to, *from = (CamelMessageInfoBase *) mi;
- CamelFlag *flag;
- CamelTag *tag;
-
- to = (CamelMessageInfoBase *) camel_message_info_new (summary);
-
- to->flags = from->flags;
- to->size = from->size;
- to->date_sent = from->date_sent;
- to->date_received = from->date_received;
- to->refcount = 1;
-
- /* NB: We don't clone the uid */
-
- to->subject = camel_pstring_strdup (from->subject);
- to->from = camel_pstring_strdup (from->from);
- to->to = camel_pstring_strdup (from->to);
- to->cc = camel_pstring_strdup (from->cc);
- to->mlist = camel_pstring_strdup (from->mlist);
- memcpy (&to->message_id, &from->message_id, sizeof (to->message_id));
- to->preview = g_strdup (from->preview);
- if (from->references) {
- gint len = sizeof (*from->references) + ((from->references->size - 1) * sizeof
(from->references->references[0]));
-
- to->references = g_malloc (len);
- memcpy (to->references, from->references, len);
- }
-
- flag = from->user_flags;
- while (flag) {
- camel_flag_set (&to->user_flags, flag->name, TRUE);
- flag = flag->next;
- }
-
- tag = from->user_tags;
- while (tag) {
- camel_tag_set (&to->user_tags, tag->name, tag->value);
- tag = tag->next;
- }
-
- if (from->content) {
- /* FIXME: copy content-infos */
- }
-
- return (CamelMessageInfo *) to;
-}
-
-static gconstpointer
-info_ptr (const CamelMessageInfo *mi,
- gint id)
-{
- switch (id) {
- case CAMEL_MESSAGE_INFO_SUBJECT:
- return ((const CamelMessageInfoBase *) mi)->subject;
- case CAMEL_MESSAGE_INFO_FROM:
- return ((const CamelMessageInfoBase *) mi)->from;
- case CAMEL_MESSAGE_INFO_TO:
- return ((const CamelMessageInfoBase *) mi)->to;
- case CAMEL_MESSAGE_INFO_CC:
- return ((const CamelMessageInfoBase *) mi)->cc;
- case CAMEL_MESSAGE_INFO_MLIST:
- return ((const CamelMessageInfoBase *) mi)->mlist;
- case CAMEL_MESSAGE_INFO_MESSAGE_ID:
- return &((const CamelMessageInfoBase *) mi)->message_id;
- case CAMEL_MESSAGE_INFO_REFERENCES:
- return ((const CamelMessageInfoBase *) mi)->references;
- case CAMEL_MESSAGE_INFO_USER_FLAGS:
- return ((const CamelMessageInfoBase *) mi)->user_flags;
- case CAMEL_MESSAGE_INFO_USER_TAGS:
- return ((const CamelMessageInfoBase *) mi)->user_tags;
- case CAMEL_MESSAGE_INFO_HEADERS:
- return ((const CamelMessageInfoBase *) mi)->headers;
- case CAMEL_MESSAGE_INFO_CONTENT:
- return ((const CamelMessageInfoBase *) mi)->content;
- case CAMEL_MESSAGE_INFO_PREVIEW:
- return ((const CamelMessageInfoBase *) mi)->preview;
- default:
- g_return_val_if_reached (NULL);
- }
-}
-
-static guint32
-info_uint32 (const CamelMessageInfo *mi,
- gint id)
-{
- switch (id) {
- case CAMEL_MESSAGE_INFO_FLAGS:
- return ((const CamelMessageInfoBase *) mi)->flags;
- case CAMEL_MESSAGE_INFO_SIZE:
- return ((const CamelMessageInfoBase *) mi)->size;
- default:
- g_return_val_if_reached (0);
- }
-}
-
-static time_t
-info_time (const CamelMessageInfo *mi,
- gint id)
-{
- switch (id) {
- case CAMEL_MESSAGE_INFO_DATE_SENT:
- return ((const CamelMessageInfoBase *) mi)->date_sent;
- case CAMEL_MESSAGE_INFO_DATE_RECEIVED:
- return ((const CamelMessageInfoBase *) mi)->date_received;
- default:
- g_return_val_if_reached (0);
- }
-}
-
-static gboolean
-info_user_flag (const CamelMessageInfo *mi,
- const gchar *id)
-{
- return camel_flag_get (&((CamelMessageInfoBase *) mi)->user_flags, id);
-}
-
-static const gchar *
-info_user_tag (const CamelMessageInfo *mi,
- const gchar *id)
-{
- return camel_tag_get (&((CamelMessageInfoBase *) mi)->user_tags, id);
-}
-
-static gboolean
-info_set_user_flag (CamelMessageInfo *info,
- const gchar *name,
- gboolean value)
-{
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
- gint res;
-
- res = camel_flag_set (&mi->user_flags, name, value);
-
- if (mi->summary && res && mi->summary->priv->folder && mi->uid
- && camel_folder_summary_check_uid (mi->summary, mi->uid)) {
- CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
-
- mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- mi->dirty = TRUE;
- camel_folder_summary_touch (mi->summary);
- camel_folder_change_info_change_uid (changes, camel_message_info_get_uid (info));
- camel_folder_changed (mi->summary->priv->folder, changes);
- camel_folder_change_info_free (changes);
- }
-
- return res;
-}
-
-static gboolean
-info_set_user_tag (CamelMessageInfo *info,
- const gchar *name,
- const gchar *value)
-{
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
- gint res;
-
- res = camel_tag_set (&mi->user_tags, name, value);
-
- if (mi->summary && res && mi->summary->priv->folder && mi->uid
- && camel_folder_summary_check_uid (mi->summary, mi->uid)) {
- CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
-
- mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- mi->dirty = TRUE;
- camel_folder_summary_touch (mi->summary);
- camel_folder_change_info_change_uid (changes, camel_message_info_get_uid (info));
- camel_folder_changed (mi->summary->priv->folder, changes);
- camel_folder_change_info_free (changes);
- }
-
- return res;
-}
-
-static gboolean
-info_set_flags (CamelMessageInfo *info,
- guint32 flags,
- guint32 set)
-{
- guint32 old;
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
- gboolean counts_changed = FALSE;
-
- old = camel_message_info_get_flags (info);
- mi->flags = (old & ~flags) | (set & flags);
- if (old != mi->flags) {
- mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- mi->dirty = TRUE;
- if (mi->summary)
- camel_folder_summary_touch (mi->summary);
- }
-
- if (mi->summary) {
- camel_folder_summary_lock (mi->summary);
- g_object_freeze_notify (G_OBJECT (mi->summary));
- counts_changed = camel_folder_summary_replace_flags (mi->summary, info);
- }
-
- if (!counts_changed && ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags &
~CAMEL_MESSAGE_SYSTEM_MASK)) && !((set & CAMEL_MESSAGE_JUNK_LEARN) && !(set & CAMEL_MESSAGE_JUNK))) {
- if (mi->summary) {
- g_object_thaw_notify (G_OBJECT (mi->summary));
- camel_folder_summary_unlock (mi->summary);
- }
- return FALSE;
- }
-
- if (mi->summary) {
- g_object_thaw_notify (G_OBJECT (mi->summary));
- camel_folder_summary_unlock (mi->summary);
- }
-
- if (mi->summary && mi->summary->priv->folder && mi->uid) {
- CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
-
- camel_folder_change_info_change_uid (changes, camel_message_info_get_uid (info));
- camel_folder_changed (mi->summary->priv->folder, changes);
- camel_folder_change_info_free (changes);
- }
-
- return TRUE;
-}
-
static void
camel_folder_summary_class_init (CamelFolderSummaryClass *class)
{
@@ -1153,41 +609,18 @@ camel_folder_summary_class_init (CamelFolderSummaryClass *class)
object_class->dispose = folder_summary_dispose;
object_class->finalize = folder_summary_finalize;
- class->message_info_size = sizeof (CamelMessageInfoBase);
- class->content_info_size = sizeof (CamelMessageContentInfo);
+ class->message_info_type = CAMEL_TYPE_MESSAGE_INFO_BASE;
- class->summary_header_from_db = summary_header_from_db;
- class->summary_header_to_db = summary_header_to_db;
- class->message_info_from_db = message_info_from_db;
- class->message_info_to_db = message_info_to_db;
- class->content_info_from_db = content_info_from_db;
- class->content_info_to_db = content_info_to_db;
+ class->summary_header_load = summary_header_load;
+ class->summary_header_save = summary_header_save;
- class->message_info_new_from_header = message_info_new_from_header;
+ class->message_info_new_from_headers = message_info_new_from_headers;
class->message_info_new_from_parser = message_info_new_from_parser;
class->message_info_new_from_message = message_info_new_from_message;
- class->message_info_free = message_info_free;
- class->message_info_clone = message_info_clone;
class->message_info_from_uid = message_info_from_uid;
- class->content_info_new_from_header = content_info_new_from_header;
- class->content_info_new_from_parser = content_info_new_from_parser;
- class->content_info_new_from_message = content_info_new_from_message;
- class->content_info_free = content_info_free;
-
class->next_uid_string = next_uid_string;
- class->info_ptr = info_ptr;
- class->info_uint32 = info_uint32;
- class->info_time = info_time;
- class->info_user_flag = info_user_flag;
- class->info_user_tag = info_user_tag;
-
- class->info_set_user_flag = info_set_user_flag;
- class->info_set_user_tag = info_set_user_tag;
-
- class->info_set_flags = info_set_flags;
-
/**
* CamelFolderSummary:folder
*
@@ -1293,35 +726,6 @@ camel_folder_summary_class_init (CamelFolderSummaryClass *class)
"How many visible (not deleted and not junk) infos is saved in a summary",
0, G_MAXUINT32,
0, G_PARAM_READABLE));
-
- /**
- * CamelFolderSummary:build-content
- *
- * Whether to build CamelMessageInfo.content.
- **/
- g_object_class_install_property (
- object_class,
- PROP_BUILD_CONTENT,
- g_param_spec_boolean (
- "build-content",
- "Build content",
- "Whether to build CamelMessageInfo.content",
- FALSE,
- G_PARAM_READWRITE));
-
- /**
- * CamelFolderSummary:need-preview
- *
- **/
- g_object_class_install_property (
- object_class,
- PROP_NEED_PREVIEW,
- g_param_spec_boolean (
- "need-preview",
- "Need preview",
- "",
- FALSE,
- G_PARAM_READWRITE));
}
static void
@@ -1329,16 +733,13 @@ camel_folder_summary_init (CamelFolderSummary *summary)
{
summary->priv = CAMEL_FOLDER_SUMMARY_GET_PRIVATE (summary);
- summary->version = CAMEL_FOLDER_SUMMARY_VERSION;
- summary->flags = 0;
- summary->time = 0;
+ summary->priv->version = CAMEL_FOLDER_SUMMARY_VERSION;
+ summary->priv->flags = 0;
+ summary->priv->timestamp = 0;
summary->priv->filter_charset = g_hash_table_new (
camel_strcase_hash, camel_strcase_equal);
- summary->priv->need_preview = FALSE;
- summary->priv->preview_updates = g_hash_table_new (g_str_hash, g_str_equal);
-
summary->priv->nextuid = 1;
summary->priv->uids = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)
camel_pstring_free, NULL);
summary->priv->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
@@ -1352,7 +753,7 @@ camel_folder_summary_init (CamelFolderSummary *summary)
/**
* camel_folder_summary_new:
- * @folder: parent #CamelFolder object
+ * @folder: (type CamelFolder): parent #CamelFolder object
*
* Create a new #CamelFolderSummary object.
*
@@ -1381,6 +782,109 @@ camel_folder_summary_get_folder (CamelFolderSummary *summary)
}
/**
+ * camel_folder_summary_get_flags:
+ * @summary: a #CamelFolderSummary
+ *
+ * Returns: flags of the @summary, a bit-or of #CamelFolderSummaryFlags
+ *
+ * Since: 3.24
+ **/
+guint32
+camel_folder_summary_get_flags (CamelFolderSummary *summary)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), 0);
+
+ return summary->priv->flags;
+}
+
+/**
+ * camel_folder_summary_set_flags:
+ * @summary: a #CamelFolderSummary
+ * @flags: flags to set
+ *
+ * Sets flags of the @summary, a bit-or of #CamelFolderSummaryFlags.
+ *
+ * Since: 3.24
+ **/
+void
+camel_folder_summary_set_flags (CamelFolderSummary *summary,
+ guint32 flags)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
+
+ summary->priv->flags = flags;
+}
+
+/**
+ * camel_folder_summary_get_timestamp:
+ * @summary: a #CamelFolderSummary
+ *
+ * Returns: timestamp of the @summary, as set by the descendants
+ *
+ * Since: 3.24
+ **/
+gint64
+camel_folder_summary_get_timestamp (CamelFolderSummary *summary)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), 0);
+
+ return summary->priv->timestamp;
+}
+
+/**
+ * camel_folder_summary_set_timestamp:
+ * @summary: a #CamelFolderSummary
+ * @timestamp: a timestamp to set
+ *
+ * Sets timestamp of the @summary, provided by the descendants. This doesn't
+ * change the 'dirty' flag of the @summary.
+ *
+ * Since: 3.24
+ **/
+void
+camel_folder_summary_set_timestamp (CamelFolderSummary *summary,
+ gint64 timestamp)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
+
+ summary->priv->timestamp = timestamp;
+}
+
+/**
+ * camel_folder_summary_get_version:
+ * @summary: a #CamelFolderSummary
+ *
+ * Returns: version of the @summary
+ *
+ * Since: 3.24
+ **/
+guint32
+camel_folder_summary_get_version (CamelFolderSummary *summary)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), 0);
+
+ return summary->priv->version;
+}
+
+/**
+ * camel_folder_summary_set_version:
+ * @summary: a #CamelFolderSummary
+ * @version: version to set
+ *
+ * Sets version of the @summary.
+ *
+ * Since: 3.24
+ **/
+void
+camel_folder_summary_set_version (CamelFolderSummary *summary,
+ guint32 version)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
+
+ summary->priv->version = version;
+}
+
+/**
* camel_folder_summary_get_saved_count:
* @summary: a #CamelFolderSummary object
*
@@ -1483,8 +987,6 @@ camel_folder_summary_get_visible_count (CamelFolderSummary *summary)
*
* Set the index used to index body content. If the index is %NULL, or
* not set (the default), no indexing of body content will take place.
- *
- * Unlike earlier behaviour, build_content need not be set to perform indexing.
**/
void
camel_folder_summary_set_index (CamelFolderSummary *summary,
@@ -1518,72 +1020,6 @@ camel_folder_summary_get_index (CamelFolderSummary *summary)
}
/**
- * camel_folder_summary_set_build_content:
- * @summary: a #CamelFolderSummary object
- * @state: to build or not to build the content
- *
- * Set a flag to tell the summary to build the content info summary
- * (#CamelMessageInfo.content). The default is not to build content
- * info summaries.
- **/
-void
-camel_folder_summary_set_build_content (CamelFolderSummary *summary,
- gboolean state)
-{
- g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
-
- if (summary->priv->build_content == state)
- return;
-
- summary->priv->build_content = state;
-
- g_object_notify (G_OBJECT (summary), "build-content");
-}
-
-/**
- * camel_folder_summary_get_build_content:
- * @summary: a #CamelFolderSummary object
- *
- * Returns: Whether to build #CamelMessageInfo.content.
- *
- * Since: 3.4
- **/
-gboolean
-camel_folder_summary_get_build_content (CamelFolderSummary *summary)
-{
- g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
-
- return summary->priv->build_content;
-}
-
-/**
- * camel_folder_summary_set_need_preview:
- *
- * Since: 2.28
- **/
-void
-camel_folder_summary_set_need_preview (CamelFolderSummary *summary,
- gboolean preview)
-{
- g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
-
- summary->priv->need_preview = preview;
-}
-
-/**
- * camel_folder_summary_get_need_preview:
- *
- * Since: 2.28
- **/
-gboolean
-camel_folder_summary_get_need_preview (CamelFolderSummary *summary)
-{
- g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
-
- return summary->priv->need_preview;
-}
-
-/**
* camel_folder_summary_next_uid:
* @summary: a #CamelFolderSummary object
*
@@ -1824,6 +1260,7 @@ camel_folder_summary_get_hash (CamelFolderSummary *summary)
/**
* camel_folder_summary_peek_loaded:
*
+ * Returns: (nullable) (transfer full):
* Since: 2.26
**/
CamelMessageInfo *
@@ -1837,7 +1274,7 @@ camel_folder_summary_peek_loaded (CamelFolderSummary *summary,
info = g_hash_table_lookup (summary->priv->loaded_infos, uid);
if (info)
- camel_message_info_ref (info);
+ g_object_ref (info);
return info;
}
@@ -1882,7 +1319,7 @@ message_info_from_uid (CamelFolderSummary *summary,
return NULL;
}
- cdb = parent_store->cdb_r;
+ cdb = camel_store_get_db (parent_store);
data.columns_hash = NULL;
data.summary = summary;
@@ -1906,7 +1343,7 @@ message_info_from_uid (CamelFolderSummary *summary,
}
if (info)
- camel_message_info_ref (info);
+ g_object_ref (info);
camel_folder_summary_unlock (summary);
@@ -1923,7 +1360,7 @@ message_info_from_uid (CamelFolderSummary *summary,
* A referenced to the summary item is returned, which may be
* ref'd or free'd as appropriate.
*
- * Returns: the summary item, or %NULL if the uid @uid is not available
+ * Returns: (nullable) (transfer full): the summary item, or %NULL if the uid @uid is not available
*
* See camel_folder_summary_get_info_flags().
*
@@ -1978,49 +1415,16 @@ camel_folder_summary_get_info_flags (CamelFolderSummary *summary,
return GPOINTER_TO_UINT (ptr_flags);
}
-static CamelMessageContentInfo *
-perform_content_info_load_from_db (CamelFolderSummary *summary,
- CamelMIRecord *mir)
-{
- gint i;
- guint32 count;
- CamelMessageContentInfo *ci, *pci;
- gchar *part;
-
- ci = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->content_info_from_db (summary, mir);
- if (ci == NULL)
- return NULL;
- part = mir->cinfo;
- if (!part)
- return ci;
- if (*part == ' ') part++;
- count = bdata_extract_digit (&part);
-
- mir->cinfo = part;
- for (i = 0; i < count; i++) {
- pci = perform_content_info_load_from_db (summary, mir);
- if (pci ) {
- my_list_append ((struct _node **) &ci->childs, (struct _node *) pci);
- pci->parent = ci;
- } else {
- d (fprintf (stderr, "Summary file format messed up?"));
- camel_folder_summary_content_info_free (summary, ci);
- return NULL;
- }
- }
- return ci;
-}
-
static void
gather_dirty_or_flagged_uids (gpointer key,
gpointer value,
gpointer user_data)
{
const gchar *uid = key;
- CamelMessageInfoBase *info = value;
+ CamelMessageInfo *info = value;
GHashTable *hash = user_data;
- if (info->dirty || (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0)
+ if (camel_message_info_get_dirty (info) || (camel_message_info_get_flags (info) &
CAMEL_MESSAGE_FOLDER_FLAGGED) != 0)
g_hash_table_insert (hash, (gpointer) camel_pstring_strdup (uid), GINT_TO_POINTER (1));
}
@@ -2067,10 +1471,10 @@ camel_folder_summary_get_changed (CamelFolderSummary *summary)
static void
count_changed_uids (gchar *key,
- CamelMessageInfoBase *info,
+ CamelMessageInfo *info,
gint *count)
{
- if (info->dirty)
+ if (camel_message_info_get_dirty (info))
(*count)++;
}
@@ -2088,10 +1492,10 @@ cfs_count_dirty (CamelFolderSummary *summary)
static gboolean
remove_item (gchar *uid,
- CamelMessageInfoBase *info,
+ CamelMessageInfo *info,
GSList **to_remove_infos)
{
- if (info->refcount == 1 && !info->dirty && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
+ if (G_OBJECT (info)->ref_count == 1 && !camel_message_info_get_dirty (info) &&
(camel_message_info_get_flags (info) & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
*to_remove_infos = g_slist_prepend (*to_remove_infos, info);
return TRUE;
}
@@ -2107,7 +1511,7 @@ remove_cache (CamelSession *session,
{
GSList *to_remove_infos = NULL;
- CAMEL_DB_RELEASE_SQLITE_MEMORY;
+ camel_db_release_cache_memory ();
if (time (NULL) - summary->priv->cache_load_time < SUMMARY_CACHE_DROP)
return;
@@ -2116,8 +1520,7 @@ remove_cache (CamelSession *session,
g_hash_table_foreach_remove (summary->priv->loaded_infos, (GHRFunc) remove_item, &to_remove_infos);
- g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_unref, NULL);
- g_slist_free (to_remove_infos);
+ g_slist_free_full (to_remove_infos, g_object_unref);
camel_folder_summary_unlock (summary);
@@ -2254,115 +1657,6 @@ cfs_cache_size (CamelFolderSummary *summary)
return g_hash_table_size (summary->priv->uids);
}
-/* Update preview of cached messages */
-
-static void
-msg_update_preview (const gchar *uid,
- gpointer value,
- CamelFolder *folder)
-{
- CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (folder->summary, uid);
- CamelMimeMessage *msg;
- CamelStore *parent_store;
- const gchar *full_name;
-
- full_name = camel_folder_get_full_name (folder);
- parent_store = camel_folder_get_parent_store (folder);
-
- /* FIXME Pass a GCancellable */
- msg = camel_folder_get_message_sync (folder, uid, NULL, NULL);
- if (msg != NULL) {
- if (camel_mime_message_build_preview ((CamelMimePart *) msg, (CamelMessageInfo *) info) &&
info->preview) {
- if (parent_store && !is_in_memory_summary (folder->summary))
- camel_db_write_preview_record (parent_store->cdb_w, full_name, info->uid,
info->preview, NULL);
- }
- }
- camel_message_info_unref (info);
-}
-
-static void
-pick_uids (const gchar *uid,
- CamelMessageInfoBase *mi,
- GPtrArray *array)
-{
- if (mi->preview)
- g_ptr_array_add (array, (gchar *) camel_pstring_strdup (uid));
-}
-
-static void
-copy_all_uids_to_hash (gpointer uid,
- gpointer hash)
-{
- g_return_if_fail (uid != NULL);
-
- g_hash_table_insert (hash, (gchar *) camel_pstring_strdup (uid), GINT_TO_POINTER (1));
-}
-
-static gboolean
-fill_mi (const gchar *uid,
- const gchar *msg,
- CamelFolder *folder)
-{
- CamelMessageInfoBase *info;
-
- info = g_hash_table_lookup (folder->summary->priv->loaded_infos, uid);
- if (info) /* We re assign the memory of msg */
- info->preview = (gchar *) msg;
- camel_pstring_free (uid); /* unref the uid */
-
- return TRUE;
-}
-
-static void
-preview_update (CamelSession *session,
- GCancellable *cancellable,
- CamelFolder *folder,
- GError **error)
-{
- /* FIXME: Either lock & use or copy & use.*/
- GPtrArray *uids_uncached, *uids_array;
- GHashTable *preview_data, *uids_hash;
- CamelStore *parent_store;
- const gchar *full_name;
- gboolean is_in_memory = is_in_memory_summary (folder->summary);
- gint i;
-
- uids_array = camel_folder_summary_get_array (folder->summary);
- uids_hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free,
NULL);
- g_ptr_array_foreach (uids_array, copy_all_uids_to_hash, uids_hash);
- uids_uncached = camel_folder_get_uncached_uids (folder, uids_array, NULL);
- camel_folder_summary_free_array (uids_array);
- uids_array = NULL;
-
- full_name = camel_folder_get_full_name (folder);
- parent_store = camel_folder_get_parent_store (folder);
- preview_data = (!parent_store || is_in_memory) ? NULL : camel_db_get_folder_preview
(parent_store->cdb_r, full_name, NULL);
- if (preview_data) {
- g_hash_table_foreach_remove (preview_data, (GHRFunc) fill_mi, folder);
- g_hash_table_destroy (preview_data);
- }
-
- camel_folder_summary_lock (folder->summary);
- g_hash_table_foreach (folder->summary->priv->loaded_infos, (GHFunc) pick_uids, uids_uncached);
- camel_folder_summary_unlock (folder->summary);
-
- for (i = 0; i < uids_uncached->len; i++) {
- g_hash_table_remove (uids_hash, uids_uncached->pdata[i]);
- }
-
- camel_folder_lock (folder);
- if (parent_store && !is_in_memory)
- camel_db_begin_transaction (parent_store->cdb_w, NULL);
- g_hash_table_foreach (uids_hash, (GHFunc) msg_update_preview, folder);
- if (parent_store && !is_in_memory)
- camel_db_end_transaction (parent_store->cdb_w, NULL);
- camel_folder_unlock (folder);
- camel_folder_free_uids (folder, uids_uncached);
- g_hash_table_destroy (uids_hash);
-}
-
-/* end */
-
static void
cfs_reload_from_db (CamelFolderSummary *summary,
GError **error)
@@ -2384,7 +1678,7 @@ cfs_reload_from_db (CamelFolderSummary *summary,
return;
folder_name = camel_folder_get_full_name (summary->priv->folder);
- cdb = parent_store->cdb_r;
+ cdb = camel_store_get_db (parent_store);
data.columns_hash = NULL;
data.summary = summary;
@@ -2398,54 +1692,6 @@ cfs_reload_from_db (CamelFolderSummary *summary,
g_hash_table_destroy (data.columns_hash);
cfs_schedule_info_release_timer (summary);
-
- /* FIXME Convert this to a GTask, submitted through
- * camel_service_queue_task(). Then it won't
- * have to call camel_folder_lock/unlock(). */
- if (summary->priv->need_preview) {
- CamelSession *session;
-
- /* This may not be available in a case of this being called as part
- of CamelSession's dispose, because the CamelService uses GWeakRef
- object which is invalidates its content when it reaches the dispose. */
- session = camel_service_ref_session (CAMEL_SERVICE (parent_store));
- if (session) {
- gchar *description;
-
- /* Translators: The first '%s' is replaced with an account name and the second '%s'
- is replaced with a full path name. The spaces around ':' are intentional, as
- the whole '%s : %s' is meant as an absolute identification of the folder. */
- description = g_strdup_printf (_("Update preview data for folder '%s : %s'"),
- camel_service_get_display_name (CAMEL_SERVICE (parent_store)),
- camel_folder_get_full_name (summary->priv->folder));
-
- camel_session_submit_job (
- session, description,
- (CamelSessionCallback) preview_update,
- g_object_ref (summary->priv->folder),
- (GDestroyNotify) g_object_unref);
-
- g_object_unref (session);
- g_free (description);
- }
- }
-
- return;
-}
-
-/**
- * camel_folder_summary_add_preview:
- *
- * Since: 2.28
- **/
-void
-camel_folder_summary_add_preview (CamelFolderSummary *summary,
- CamelMessageInfo *info)
-{
- camel_folder_summary_lock (summary);
- g_hash_table_insert (summary->priv->preview_updates, (gchar *) info->uid, ((CamelMessageInfoBase *)
info)->preview);
- camel_folder_summary_touch (summary);
- camel_folder_summary_unlock (summary);
}
/**
@@ -2482,14 +1728,15 @@ camel_folder_summary_prepare_fetch_all (CamelFolderSummary *summary,
}
/**
- * camel_folder_summary_load_from_db:
+ * camel_folder_summary_load:
*
- * Since: 2.24
+ * Since: 3.24
**/
gboolean
-camel_folder_summary_load_from_db (CamelFolderSummary *summary,
- GError **error)
+camel_folder_summary_load (CamelFolderSummary *summary,
+ GError **error)
{
+ CamelFolderSummaryClass *klass;
CamelDB *cdb;
CamelStore *parent_store;
const gchar *full_name;
@@ -2498,18 +1745,21 @@ camel_folder_summary_load_from_db (CamelFolderSummary *summary,
g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
+ klass = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
+ g_return_val_if_fail (klass != NULL, FALSE);
+
if (is_in_memory_summary (summary))
return TRUE;
camel_folder_summary_lock (summary);
- camel_folder_summary_save_to_db (summary, NULL);
+ camel_folder_summary_save (summary, NULL);
/* struct _db_pass_data data; */
- d (printf ("\ncamel_folder_summary_load_from_db called \n"));
+ d (printf ("\ncamel_folder_summary_load called \n"));
full_name = camel_folder_get_full_name (summary->priv->folder);
parent_store = camel_folder_get_parent_store (summary->priv->folder);
- if (!camel_folder_summary_header_load_from_db (summary, parent_store, full_name, error)) {
+ if (!camel_folder_summary_header_load (summary, parent_store, full_name, error)) {
camel_folder_summary_unlock (summary);
return FALSE;
}
@@ -2519,10 +1769,10 @@ camel_folder_summary_load_from_db (CamelFolderSummary *summary,
return FALSE;
}
- cdb = parent_store->cdb_r;
+ cdb = camel_store_get_db (parent_store);
ret = camel_db_get_folder_uids (
- cdb, full_name, summary->sort_by, summary->collate,
+ cdb, full_name, klass->sort_by, klass->collate,
summary->priv->uids, &local_error);
if (local_error != NULL && local_error->message != NULL &&
@@ -2539,6 +1789,7 @@ camel_folder_summary_load_from_db (CamelFolderSummary *summary,
return ret == 0;
}
+/* Beware, it only borrows pointers from 'cols' here */
static void
mir_from_cols (CamelMIRecord *mir,
CamelFolderSummary *summary,
@@ -2555,80 +1806,76 @@ mir_from_cols (CamelMIRecord *mir,
switch (camel_db_get_column_ident (columns_hash, i, ncol, name)) {
case CAMEL_DB_COLUMN_UID:
- mir->uid = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->uid = cols[i];
break;
case CAMEL_DB_COLUMN_FLAGS:
- mir->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ mir->flags = cols[i] ? g_ascii_strtoull (cols[i], NULL, 10) : 0;
break;
case CAMEL_DB_COLUMN_READ:
- mir->read = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) :
FALSE;
+ mir->read = (cols[i]) ? ( ((g_ascii_strtoull (cols[i], NULL, 10)) ? TRUE :
FALSE)) : FALSE;
break;
case CAMEL_DB_COLUMN_DELETED:
- mir->deleted = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE))
: FALSE;
+ mir->deleted = (cols[i]) ? ( ((g_ascii_strtoull (cols[i], NULL, 10)) ? TRUE :
FALSE)) : FALSE;
break;
case CAMEL_DB_COLUMN_REPLIED:
- mir->replied = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE))
: FALSE;
+ mir->replied = (cols[i]) ? ( ((g_ascii_strtoull (cols[i], NULL, 10)) ? TRUE :
FALSE)) : FALSE;
break;
case CAMEL_DB_COLUMN_IMPORTANT:
- mir->important = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE :
FALSE)) : FALSE;
+ mir->important = (cols[i]) ? ( ((g_ascii_strtoull (cols[i], NULL, 10)) ? TRUE
: FALSE)) : FALSE;
break;
case CAMEL_DB_COLUMN_JUNK:
- mir->junk = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) :
FALSE;
+ mir->junk = (cols[i]) ? ( ((g_ascii_strtoull (cols[i], NULL, 10)) ? TRUE :
FALSE)) : FALSE;
break;
case CAMEL_DB_COLUMN_ATTACHMENT:
- mir->attachment = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE :
FALSE)) : FALSE;
+ mir->attachment = (cols[i]) ? ( ((g_ascii_strtoull (cols[i], NULL, 10)) ?
TRUE : FALSE)) : FALSE;
break;
case CAMEL_DB_COLUMN_SIZE:
- mir->size = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+ mir->size = cols[i] ? g_ascii_strtoull (cols[i], NULL, 10) : 0;
break;
case CAMEL_DB_COLUMN_DSENT:
- mir->dsent = cols[i] ? strtol (cols[i], NULL, 10) : 0;
+ mir->dsent = cols[i] ? g_ascii_strtoll (cols[i], NULL, 10) : 0;
break;
case CAMEL_DB_COLUMN_DRECEIVED:
- mir->dreceived = cols[i] ? strtol (cols[i], NULL, 10) : 0;
+ mir->dreceived = cols[i] ? g_ascii_strtoll (cols[i], NULL, 10) : 0;
break;
case CAMEL_DB_COLUMN_SUBJECT:
- mir->subject = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->subject = cols[i];
break;
case CAMEL_DB_COLUMN_MAIL_FROM:
- mir->from = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->from = cols[i];
break;
case CAMEL_DB_COLUMN_MAIL_TO:
- mir->to = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->to = cols[i];
break;
case CAMEL_DB_COLUMN_MAIL_CC:
- mir->cc = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->cc = cols[i];
break;
case CAMEL_DB_COLUMN_MLIST:
- mir->mlist = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->mlist = cols[i];
break;
case CAMEL_DB_COLUMN_FOLLOWUP_FLAG:
- mir->followup_flag = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->followup_flag = cols[i];
break;
case CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON:
- mir->followup_completed_on = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->followup_completed_on = cols[i];
break;
case CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY:
- mir->followup_due_by = (gchar *) camel_pstring_strdup (cols[i]);
+ mir->followup_due_by = cols[i];
break;
case CAMEL_DB_COLUMN_PART:
- mir->part = g_strdup (cols[i]);
+ mir->part = cols[i];
break;
case CAMEL_DB_COLUMN_LABELS:
- mir->labels = g_strdup (cols[i]);
+ mir->labels = cols[i];
break;
case CAMEL_DB_COLUMN_USERTAGS:
- mir->usertags = g_strdup (cols[i]);
+ mir->usertags = cols[i];
break;
case CAMEL_DB_COLUMN_CINFO:
- mir->cinfo = g_strdup (cols[i]);
+ mir->cinfo = cols[i];
break;
case CAMEL_DB_COLUMN_BDATA:
- mir->bdata = g_strdup (cols[i]);
- break;
- case CAMEL_DB_COLUMN_BODYSTRUCTURE:
- /* Evolution itself doesn't yet use this, ignoring */
- /* mir->bodystructure = g_strdup (cols[i]); */
+ mir->bdata = cols[i];
break;
default:
g_warn_if_reached ();
@@ -2645,133 +1892,105 @@ camel_read_mir_callback (gpointer ref,
{
struct _db_pass_data *data = (struct _db_pass_data *) ref;
CamelFolderSummary *summary = data->summary;
- CamelMIRecord *mir;
+ CamelMIRecord mir;
CamelMessageInfo *info;
+ gchar *bdata_ptr;
gint ret = 0;
- mir = g_new0 (CamelMIRecord , 1);
- mir_from_cols (mir, summary, &data->columns_hash, ncol, cols, name);
+ memset (&mir, 0, sizeof (CamelMIRecord));
+
+ /* As mir_from_cols() only borrows data from cols, no need to free mir */
+ mir_from_cols (&mir, summary, &data->columns_hash, ncol, cols, name);
camel_folder_summary_lock (summary);
- if (!mir->uid || g_hash_table_lookup (summary->priv->loaded_infos, mir->uid)) {
+ if (!mir.uid || g_hash_table_lookup (summary->priv->loaded_infos, mir.uid)) {
/* Unlock and better return */
camel_folder_summary_unlock (summary);
- camel_db_camel_mir_free (mir);
return ret;
}
camel_folder_summary_unlock (summary);
- info = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_from_db (summary, mir);
-
- if (info) {
-
- if (summary->priv->build_content) {
- gchar *tmp;
- tmp = mir->cinfo;
- /* FIXME: this should be done differently, how i don't know */
- ((CamelMessageInfoBase *) info)->content = perform_content_info_load_from_db
(summary, mir);
- if (((CamelMessageInfoBase *) info)->content == NULL) {
- camel_message_info_unref (info);
- info = NULL;
- }
- mir->cinfo = tmp;
-
- if (!info) {
- camel_db_camel_mir_free (mir);
- return -1;
- }
- }
-
+ info = camel_message_info_new (summary);
+ bdata_ptr = mir.bdata;
+ if (camel_message_info_load (info, &mir, &bdata_ptr)) {
/* Just now we are reading from the DB, it can't be dirty. */
- ((CamelMessageInfoBase *) info)->dirty = FALSE;
- if (data->add)
- camel_folder_summary_add (summary, info);
- else
- camel_folder_summary_insert (summary, info, TRUE);
-
+ camel_message_info_set_dirty (info, FALSE);
+ if (data->add) {
+ camel_folder_summary_add (summary, info, FALSE);
+ g_clear_object (&info);
+ } else {
+ camel_folder_summary_lock (summary);
+ /* Summary always holds a ref for the loaded infos; this consumes it */
+ g_hash_table_insert (summary->priv->loaded_infos, (gchar *)
camel_message_info_get_uid (info), info);
+ camel_folder_summary_unlock (summary);
+ }
} else {
+ g_clear_object (&info);
g_warning ("Loading messageinfo from db failed");
ret = -1;
}
- camel_db_camel_mir_free (mir);
-
return ret;
}
-/* saves the content descriptions, recursively */
-static gboolean
-perform_content_info_save_to_db (CamelFolderSummary *summary,
- CamelMessageContentInfo *ci,
- CamelMIRecord *record)
-{
- CamelMessageContentInfo *part;
- gchar *oldr;
-
- if (!CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->content_info_to_db (summary, ci, record))
- return FALSE;
-
- oldr = record->cinfo;
- record->cinfo = g_strdup_printf ("%s %d", oldr, my_list_size ((struct _node **) &ci->childs));
- g_free (oldr);
-
- part = ci->childs;
- while (part) {
- if (perform_content_info_save_to_db (summary, part, record) == -1)
- return FALSE;
- part = part->next;
- }
-
- return TRUE;
-}
-
static void
save_to_db_cb (gpointer key,
gpointer value,
gpointer data)
{
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *) value;
- CamelFolderSummary *summary = (CamelFolderSummary *) mi->summary;
+ CamelMessageInfo *mi = value;
+ CamelFolderSummary *summary;
CamelStore *parent_store;
const gchar *full_name;
CamelDB *cdb;
CamelMIRecord *mir;
+ GString *bdata_str;
GError **error = data;
- full_name = camel_folder_get_full_name (summary->priv->folder);
- parent_store = camel_folder_get_parent_store (summary->priv->folder);
- if (!parent_store)
+ if (!camel_message_info_get_dirty (mi))
return;
- cdb = parent_store->cdb_w;
+ summary = camel_message_info_ref_summary (mi);
+ if (!summary)
+ return;
- if (!mi->dirty)
+ full_name = camel_folder_get_full_name (summary->priv->folder);
+ parent_store = camel_folder_get_parent_store (summary->priv->folder);
+ if (!parent_store) {
+ g_clear_object (&summary);
return;
+ }
- mir = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_to_db (summary, (CamelMessageInfo *) mi);
+ cdb = camel_store_get_db (parent_store);
- if (mir && summary->priv->build_content) {
- if (!perform_content_info_save_to_db (summary, ((CamelMessageInfoBase *) mi)->content, mir)) {
- g_warning ("unable to save mir+cinfo for uid: %s\n", mir->uid);
- camel_db_camel_mir_free (mir);
- /* FIXME: Add exception here */
- return;
- }
+ mir = g_new0 (CamelMIRecord, 1);
+ bdata_str = g_string_new (NULL);
+
+ if (!camel_message_info_save (mi, mir, bdata_str)) {
+ g_warning ("Failed to save message info: %s\n", camel_message_info_get_uid (mi));
+ g_string_free (bdata_str, TRUE);
+ camel_db_camel_mir_free (mir);
+ g_clear_object (&summary);
+ return;
}
- g_return_if_fail (mir != NULL);
+ g_warn_if_fail (mir->bdata == NULL);
+ mir->bdata = g_string_free (bdata_str, FALSE);
+ bdata_str = NULL;
if (camel_db_write_message_info_record (cdb, full_name, mir, error) != 0) {
camel_db_camel_mir_free (mir);
+ g_clear_object (&summary);
return;
}
/* Reset the dirty flag which decides if the changes are synced to the DB or not.
The FOLDER_FLAGGED should be used to check if the changes are synced to the server.
So, dont unset the FOLDER_FLAGGED flag */
- mi->dirty = FALSE;
+ camel_message_info_set_dirty (mi, FALSE);
camel_db_camel_mir_free (mir);
+ g_clear_object (&summary);
}
static gint
@@ -2790,7 +2009,7 @@ save_message_infos_to_db (CamelFolderSummary *summary,
if (!parent_store)
return 0;
- cdb = parent_store->cdb_w;
+ cdb = camel_store_get_db (parent_store);
if (camel_db_prepare_message_info_table (cdb, full_name, error) != 0)
return -1;
@@ -2808,31 +2027,14 @@ save_message_infos_to_db (CamelFolderSummary *summary,
return 0;
}
-static void
-msg_save_preview (const gchar *uid,
- gpointer value,
- CamelFolder *folder)
-{
- CamelStore *parent_store;
- const gchar *full_name;
-
- full_name = camel_folder_get_full_name (folder);
- parent_store = camel_folder_get_parent_store (folder);
-
- if (parent_store) {
- camel_db_write_preview_record (
- parent_store->cdb_w, full_name, uid, (gchar *) value, NULL);
- }
-}
-
/**
- * camel_folder_summary_save_to_db:
+ * camel_folder_summary_save:
*
- * Since: 2.24
+ * Since: 3.24
**/
gboolean
-camel_folder_summary_save_to_db (CamelFolderSummary *summary,
- GError **error)
+camel_folder_summary_save (CamelFolderSummary *summary,
+ GError **error)
{
CamelStore *parent_store;
CamelDB *cdb;
@@ -2841,7 +2043,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *summary,
g_return_val_if_fail (summary != NULL, FALSE);
- if (!(summary->flags & CAMEL_FOLDER_SUMMARY_DIRTY) ||
+ if (!(summary->priv->flags & CAMEL_FOLDER_SUMMARY_DIRTY) ||
is_in_memory_summary (summary))
return TRUE;
@@ -2849,23 +2051,17 @@ camel_folder_summary_save_to_db (CamelFolderSummary *summary,
if (!parent_store)
return FALSE;
- cdb = parent_store->cdb_w;
+ cdb = camel_store_get_db (parent_store);
camel_folder_summary_lock (summary);
- d (printf ("\ncamel_folder_summary_save_to_db called \n"));
- if (summary->priv->need_preview && g_hash_table_size (summary->priv->preview_updates)) {
- camel_db_begin_transaction (parent_store->cdb_w, NULL);
- g_hash_table_foreach (summary->priv->preview_updates, (GHFunc) msg_save_preview,
summary->priv->folder);
- g_hash_table_remove_all (summary->priv->preview_updates);
- camel_db_end_transaction (parent_store->cdb_w, NULL);
- }
+ d (printf ("\ncamel_folder_summary_save called \n"));
- summary->flags &= ~CAMEL_FOLDER_SUMMARY_DIRTY;
+ summary->priv->flags &= ~CAMEL_FOLDER_SUMMARY_DIRTY;
count = cfs_count_dirty (summary);
if (!count) {
- gboolean res = camel_folder_summary_header_save_to_db (summary, error);
+ gboolean res = camel_folder_summary_header_save (summary, error);
camel_folder_summary_unlock (summary);
return res;
}
@@ -2873,7 +2069,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *summary,
ret = save_message_infos_to_db (summary, error);
if (ret != 0) {
/* Failed, so lets reset the flag */
- summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
+ summary->priv->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
camel_folder_summary_unlock (summary);
return FALSE;
}
@@ -2895,15 +2091,15 @@ camel_folder_summary_save_to_db (CamelFolderSummary *summary,
ret = save_message_infos_to_db (summary, error);
if (ret != 0) {
- summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
+ summary->priv->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
camel_folder_summary_unlock (summary);
return FALSE;
}
}
- record = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_to_db (summary, error);
+ record = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_save (summary, error);
if (!record) {
- summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
+ summary->priv->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
camel_folder_summary_unlock (summary);
return FALSE;
}
@@ -2916,7 +2112,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *summary,
if (ret != 0) {
camel_db_abort_transaction (cdb, NULL);
- summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
+ summary->priv->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
camel_folder_summary_unlock (summary);
return FALSE;
}
@@ -2928,13 +2124,13 @@ camel_folder_summary_save_to_db (CamelFolderSummary *summary,
}
/**
- * camel_folder_summary_header_save_to_db:
+ * camel_folder_summary_header_save:
*
- * Since: 2.24
+ * Since: 3.24
**/
gboolean
-camel_folder_summary_header_save_to_db (CamelFolderSummary *summary,
- GError **error)
+camel_folder_summary_header_save (CamelFolderSummary *summary,
+ GError **error)
{
CamelStore *parent_store;
CamelFIRecord *record;
@@ -2948,12 +2144,12 @@ camel_folder_summary_header_save_to_db (CamelFolderSummary *summary,
if (!parent_store)
return FALSE;
- cdb = parent_store->cdb_w;
+ cdb = camel_store_get_db (parent_store);
camel_folder_summary_lock (summary);
- d (printf ("\ncamel_folder_summary_header_save_to_db called \n"));
+ d (printf ("\ncamel_folder_summary_header_save called \n"));
- record = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_to_db (summary, error);
+ record = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_save (summary, error);
if (!record) {
camel_folder_summary_unlock (summary);
return FALSE;
@@ -2978,34 +2174,34 @@ camel_folder_summary_header_save_to_db (CamelFolderSummary *summary,
}
/**
- * camel_folder_summary_header_load_from_db:
+ * camel_folder_summary_header_load:
*
- * Since: 2.24
+ * Since: 3.24
**/
gboolean
-camel_folder_summary_header_load_from_db (CamelFolderSummary *summary,
- CamelStore *store,
- const gchar *folder_name,
- GError **error)
+camel_folder_summary_header_load (CamelFolderSummary *summary,
+ CamelStore *store,
+ const gchar *folder_name,
+ GError **error)
{
CamelDB *cdb;
CamelFIRecord *record;
gboolean ret = FALSE;
- d (printf ("\ncamel_folder_summary_header_load_from_db called \n"));
+ d (printf ("\ncamel_folder_summary_header_load called \n"));
if (is_in_memory_summary (summary))
return TRUE;
camel_folder_summary_lock (summary);
- camel_folder_summary_save_to_db (summary, NULL);
+ camel_folder_summary_save (summary, NULL);
- cdb = store->cdb_r;
+ cdb = camel_store_get_db (store);
record = g_new0 (CamelFIRecord, 1);
camel_db_read_folder_info_record (cdb, folder_name, record, error);
- ret = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_from_db (summary, record);
+ ret = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->summary_header_load (summary, record);
camel_folder_summary_unlock (summary);
@@ -3020,35 +2216,51 @@ static gboolean
summary_assign_uid (CamelFolderSummary *summary,
CamelMessageInfo *info)
{
- const gchar *uid;
+ const gchar *info_uid;
+ gchar *new_uid;
CamelMessageInfo *mi;
- uid = camel_message_info_get_uid (info);
+ camel_message_info_set_abort_notifications (info, TRUE);
+ camel_message_info_property_lock (info);
- if (uid == NULL || uid[0] == 0) {
- camel_pstring_free (info->uid);
- uid = info->uid = (gchar *) camel_pstring_add (camel_folder_summary_next_uid_string
(summary), TRUE);
+ info_uid = camel_message_info_get_uid (info);
+
+ if (!info_uid || !*info_uid) {
+ new_uid = camel_folder_summary_next_uid_string (summary);
+
+ camel_message_info_set_uid (info, new_uid);
+ } else {
+ new_uid = g_strdup (info_uid);
}
camel_folder_summary_lock (summary);
- while ((mi = g_hash_table_lookup (summary->priv->loaded_infos, uid))) {
+ while ((mi = g_hash_table_lookup (summary->priv->loaded_infos, new_uid))) {
camel_folder_summary_unlock (summary);
- if (mi == info)
+ g_free (new_uid);
+
+ if (mi == info) {
+ camel_message_info_property_unlock (info);
return FALSE;
+ }
d (printf ("Trying to insert message with clashing uid (%s). new uid re-assigned",
camel_message_info_get_uid (info)));
- camel_pstring_free (info->uid);
- uid = info->uid = camel_pstring_add (camel_folder_summary_next_uid_string (summary), TRUE);
- camel_message_info_set_flags (info, CAMEL_MESSAGE_FOLDER_FLAGGED,
CAMEL_MESSAGE_FOLDER_FLAGGED);
+ new_uid = camel_folder_summary_next_uid_string (summary);
+ camel_message_info_set_uid (info, new_uid);
+ camel_message_info_set_folder_flagged (info, TRUE);
camel_folder_summary_lock (summary);
}
+ g_free (new_uid);
+
camel_folder_summary_unlock (summary);
+ camel_message_info_property_unlock (info);
+ camel_message_info_set_abort_notifications (info, FALSE);
+
return TRUE;
}
@@ -3056,36 +2268,47 @@ summary_assign_uid (CamelFolderSummary *summary,
* camel_folder_summary_add:
* @summary: a #CamelFolderSummary object
* @info: a #CamelMessageInfo
+ * @force_keep_uid: whether to keep set UID of the @info
*
- * Adds a new @info record to the summary. If @info->uid is %NULL,
+ * Adds a new @info record to the summary. If the @force_keep_uid is %FALSE,
* then a new uid is automatically re-assigned by calling
- * camel_folder_summary_next_uid_string().
+ * camel_folder_summary_next_uid_string(). It's an error to to use
+ * @force_keep_uid whe nthe @info has none set.
*
- * The @info record should have been generated by calling one of the
- * info_new_*() functions, as it will be free'd based on the summary
- * class. And MUST NOT be allocated directly using malloc.
+ * The @summary adds its own reference to @info, if needed.
**/
void
camel_folder_summary_add (CamelFolderSummary *summary,
- CamelMessageInfo *info)
+ CamelMessageInfo *info,
+ gboolean force_keep_uid)
{
- CamelMessageInfoBase *base_info;
-
g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
- if (info == NULL)
+ if (!info)
return;
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (info));
+
camel_folder_summary_lock (summary);
- if (!summary_assign_uid (summary, info)) {
+ if (!force_keep_uid && !summary_assign_uid (summary, info)) {
camel_folder_summary_unlock (summary);
return;
}
- base_info = (CamelMessageInfoBase *) info;
+ if (force_keep_uid) {
+ const gchar *uid;
+
+ uid = camel_message_info_get_uid (info);
+ if (!uid || !*uid) {
+ g_warning ("%s: Cannot add message info without UID, when disabled to assign new UID;
skipping it", G_STRFUNC);
+ camel_folder_summary_unlock (summary);
+ return;
+ }
+ }
+
folder_summary_update_counts_by_flags (summary, camel_message_info_get_flags (info),
UPDATE_COUNTS_ADD);
- base_info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- base_info->dirty = TRUE;
+ camel_message_info_set_folder_flagged (info, TRUE);
+ camel_message_info_set_dirty (info, TRUE);
g_hash_table_insert (
summary->priv->uids,
@@ -3093,7 +2316,7 @@ camel_folder_summary_add (CamelFolderSummary *summary,
GUINT_TO_POINTER (camel_message_info_get_flags (info)));
/* Summary always holds a ref for the loaded infos */
- g_hash_table_insert (summary->priv->loaded_infos, (gpointer) camel_message_info_get_uid (info), info);
+ g_hash_table_insert (summary->priv->loaded_infos, (gpointer) camel_message_info_get_uid (info),
g_object_ref (info));
camel_folder_summary_touch (summary);
@@ -3101,65 +2324,29 @@ camel_folder_summary_add (CamelFolderSummary *summary,
}
/**
- * camel_folder_summary_insert:
- *
- * Since: 2.24
- **/
-void
-camel_folder_summary_insert (CamelFolderSummary *summary,
- CamelMessageInfo *info,
- gboolean load)
-{
- g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
-
- if (info == NULL)
- return;
-
- camel_folder_summary_lock (summary);
-
- if (!load) {
- CamelMessageInfoBase *base_info = (CamelMessageInfoBase *) info;
-
- folder_summary_update_counts_by_flags (summary, camel_message_info_get_flags (info),
UPDATE_COUNTS_ADD);
- base_info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- base_info->dirty = TRUE;
-
- g_hash_table_insert (
- summary->priv->uids,
- (gpointer) camel_pstring_strdup (camel_message_info_get_uid (info)),
- GUINT_TO_POINTER (camel_message_info_get_flags (info)));
-
- camel_folder_summary_touch (summary);
- }
-
- /* Summary always holds a ref for the loaded infos */
- g_hash_table_insert (summary->priv->loaded_infos, (gchar *) camel_message_info_get_uid (info), info);
-
- camel_folder_summary_unlock (summary);
-}
-
-/**
- * camel_folder_summary_info_new_from_header:
+ * camel_folder_summary_info_new_from_headers:
* @summary: a #CamelFolderSummary object
- * @headers: rfc822 headers
+ * @headers: rfc822 headers as #CamelNameValueArray
*
* Create a new info record from a header.
*
- * Returns: the newly allocated record which must be unreferenced with
- * camel_message_info_unref()
+ * Returns: (transfer full): a newly created #CamelMessageInfo. Unref it
+ * with g_object_unref(), when done with it.
+ *
+ * Since: 3.24
**/
CamelMessageInfo *
-camel_folder_summary_info_new_from_header (CamelFolderSummary *summary,
- struct _camel_header_raw *h)
+camel_folder_summary_info_new_from_headers (CamelFolderSummary *summary,
+ const CamelNameValueArray *headers)
{
CamelFolderSummaryClass *class;
g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
- g_return_val_if_fail (class->message_info_new_from_header != NULL, NULL);
+ g_return_val_if_fail (class->message_info_new_from_headers != NULL, NULL);
- return class->message_info_new_from_header (summary, h);
+ return class->message_info_new_from_headers (summary, headers);
}
/**
@@ -3180,8 +2367,8 @@ camel_folder_summary_info_new_from_header (CamelFolderSummary *summary,
* Once complete, the parser will be positioned at the end of
* the message.
*
- * Returns: the newly allocated record which must be unreferenced with
- * camel_message_info_unref()
+ * Returns: (transfer full): a newly created #CamelMessageInfo. Unref it
+ * with g_object_unref(), when done with it.
**/
CamelMessageInfo *
camel_folder_summary_info_new_from_parser (CamelFolderSummary *summary,
@@ -3218,7 +2405,7 @@ camel_folder_summary_info_new_from_parser (CamelFolderSummary *summary,
}
/* always scan the content info, even if we dont save it */
- ((CamelMessageInfoBase *) info)->content = summary_build_content_info (summary, info, mp);
+ summary_traverse_content_with_parser (summary, info, mp);
if (name && p->index) {
camel_index_write_name (p->index, name);
@@ -3229,7 +2416,7 @@ camel_folder_summary_info_new_from_parser (CamelFolderSummary *summary,
g_rec_mutex_unlock (&summary->priv->filter_lock);
- ((CamelMessageInfoBase *) info)->size = camel_mime_parser_tell (mp) - start;
+ camel_message_info_set_size (info, camel_mime_parser_tell (mp) - start);
}
return info;
}
@@ -3238,23 +2425,21 @@ camel_folder_summary_info_new_from_parser (CamelFolderSummary *summary,
* camel_folder_summary_info_new_from_message:
* @summary: a #CamelFolderSummary object
* @message: a #CamelMimeMessage object
- * @bodystructure: a bodystructure or NULL
*
* Create a summary item from a message.
*
- * Returns: the newly allocated record which must be unreferenced with
- * camel_message_info_unref()
+ * Returns: (transfer full): a newly created #CamelMessageInfo. Unref it
+ * with g_object_unref(), when done with it.
**/
CamelMessageInfo *
camel_folder_summary_info_new_from_message (CamelFolderSummary *summary,
- CamelMimeMessage *msg,
- const gchar *bodystructure)
+ CamelMimeMessage *msg)
{
CamelMessageInfo *info;
CamelFolderSummaryPrivate *p = summary->priv;
CamelIndexName *name = NULL;
- info = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_message (summary, msg,
bodystructure);
+ info = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_message (summary, msg);
/* assign a unique uid, this is slightly 'wrong' as we do not really
* know if we are going to store this in the summary, but we need it set for indexing */
@@ -3279,7 +2464,7 @@ camel_folder_summary_info_new_from_message (CamelFolderSummary *summary,
}
}
- ((CamelMessageInfoBase *) info)->content = summary_build_content_info_message (summary, info,
(CamelMimePart *) msg);
+ summary_traverse_content_with_part (summary, info, (CamelMimePart *) msg);
if (name) {
camel_index_write_name (p->index, name);
@@ -3294,28 +2479,6 @@ camel_folder_summary_info_new_from_message (CamelFolderSummary *summary,
}
/**
- * camel_folder_summary_content_info_free:
- * @summary: a #CamelFolderSummary object
- * @ci: a #CamelMessageContentInfo
- *
- * Free the content info @ci, and all associated memory.
- **/
-void
-camel_folder_summary_content_info_free (CamelFolderSummary *summary,
- CamelMessageContentInfo *ci)
-{
- CamelMessageContentInfo *pw, *pn;
-
- pw = ci->childs;
- CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->content_info_free (summary, ci);
- while (pw) {
- pn = pw->next;
- camel_folder_summary_content_info_free (summary, pw);
- pw = pn;
- }
-}
-
-/**
* camel_folder_summary_touch:
* @summary: a #CamelFolderSummary object
*
@@ -3326,7 +2489,7 @@ void
camel_folder_summary_touch (CamelFolderSummary *summary)
{
camel_folder_summary_lock (summary);
- summary->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
+ summary->priv->flags |= CAMEL_FOLDER_SUMMARY_DIRTY;
camel_folder_summary_unlock (summary);
}
@@ -3374,7 +2537,7 @@ camel_folder_summary_clear (CamelFolderSummary *summary,
return FALSE;
}
- cdb = parent_store->cdb_w;
+ cdb = camel_store_get_db (parent_store);
if (!is_in_memory_summary (summary))
res = camel_db_clear_folder_summary (cdb, folder_name, error) == 0;
@@ -3413,7 +2576,7 @@ camel_folder_summary_remove (CamelFolderSummary *summary,
g_return_val_if_fail (info != NULL, FALSE);
if (camel_folder_summary_remove_uid (summary, camel_message_info_get_uid (info))) {
- camel_message_info_unref (info);
+ g_clear_object (&info);
return TRUE;
}
@@ -3457,7 +2620,7 @@ camel_folder_summary_remove_uid (CamelFolderSummary *summary,
if (!is_in_memory_summary (summary)) {
full_name = camel_folder_get_full_name (summary->priv->folder);
parent_store = camel_folder_get_parent_store (summary->priv->folder);
- if (!parent_store || camel_db_delete_uid (parent_store->cdb_w, full_name, uid_copy, NULL) !=
0)
+ if (!parent_store || camel_db_delete_uid (camel_store_get_db (parent_store), full_name,
uid_copy, NULL) != 0)
res = FALSE;
}
@@ -3508,7 +2671,7 @@ camel_folder_summary_remove_uids (CamelFolderSummary *summary,
g_hash_table_remove (summary->priv->loaded_infos, uid_copy);
if (mi)
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
camel_pstring_free (uid_copy);
}
}
@@ -3516,7 +2679,7 @@ camel_folder_summary_remove_uids (CamelFolderSummary *summary,
if (!is_in_memory_summary (summary)) {
full_name = camel_folder_get_full_name (summary->priv->folder);
parent_store = camel_folder_get_parent_store (summary->priv->folder);
- if (!parent_store || camel_db_delete_uids (parent_store->cdb_w, full_name, uids, NULL) != 0)
+ if (!parent_store || camel_db_delete_uids (camel_store_get_db (parent_store), full_name,
uids, NULL) != 0)
res = FALSE;
}
@@ -3527,42 +2690,13 @@ camel_folder_summary_remove_uids (CamelFolderSummary *summary,
return res;
}
-static struct _node *
-my_list_append (struct _node **list,
- struct _node *n)
-{
- struct _node *ln = *list;
- n->next = NULL;
-
- if (!ln) {
- *list = n;
- return n;
- }
-
- while (ln->next)
- ln = ln->next;
- ln->next = n;
- return n;
-}
-
-static gint
-my_list_size (struct _node **list)
-{
- gint len = 0;
- struct _node *ln = (struct _node *) list;
- while (ln->next) {
- ln = ln->next;
- len++;
- }
- return len;
-}
-
/* are these even useful for anything??? */
static CamelMessageInfo *
message_info_new_from_parser (CamelFolderSummary *summary,
CamelMimeParser *mp)
{
CamelMessageInfo *mi = NULL;
+ CamelNameValueArray *headers;
gint state;
state = camel_mime_parser_state (mp);
@@ -3570,7 +2704,9 @@ message_info_new_from_parser (CamelFolderSummary *summary,
case CAMEL_MIME_PARSER_STATE_HEADER:
case CAMEL_MIME_PARSER_STATE_MESSAGE:
case CAMEL_MIME_PARSER_STATE_MULTIPART:
- mi = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_header (summary,
camel_mime_parser_headers_raw (mp));
+ headers = camel_mime_parser_dup_headers (mp);
+ mi = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_headers (summary,
headers);
+ camel_name_value_array_free (headers);
break;
default:
g_error ("Invalid parser state");
@@ -3579,70 +2715,30 @@ message_info_new_from_parser (CamelFolderSummary *summary,
return mi;
}
-static CamelMessageContentInfo *
-content_info_new_from_parser (CamelFolderSummary *summary,
- CamelMimeParser *mp)
-{
- CamelMessageContentInfo *ci = NULL;
-
- switch (camel_mime_parser_state (mp)) {
- case CAMEL_MIME_PARSER_STATE_HEADER:
- case CAMEL_MIME_PARSER_STATE_MESSAGE:
- case CAMEL_MIME_PARSER_STATE_MULTIPART:
- ci = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->content_info_new_from_header (summary,
camel_mime_parser_headers_raw (mp));
- if (ci) {
- if (ci->type)
- camel_content_type_unref (ci->type);
- ci->type = camel_mime_parser_content_type (mp);
- camel_content_type_ref (ci->type);
- }
- break;
- default:
- g_error ("Invalid parser state");
- }
-
- return ci;
-}
-
static CamelMessageInfo *
message_info_new_from_message (CamelFolderSummary *summary,
- CamelMimeMessage *msg,
- const gchar *bodystructure)
-{
- CamelMessageInfo *mi;
-
- mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS (summary)))->message_info_new_from_header
(summary, ((CamelMimePart *) msg)->headers);
- ((CamelMessageInfoBase *) mi)->bodystructure = g_strdup (bodystructure);
-
- return mi;
-}
-
-static CamelMessageContentInfo *
-content_info_new_from_message (CamelFolderSummary *summary,
- CamelMimePart *mp)
+ CamelMimeMessage *msg)
{
- CamelMessageContentInfo *ci;
-
- ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS (summary)))->content_info_new_from_header
(summary, mp->headers);
-
- return ci;
+ return CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_headers (summary,
camel_medium_get_headers (CAMEL_MEDIUM (msg)));
}
static gchar *
-summary_format_address (struct _camel_header_raw *h,
+summary_format_address (const CamelNameValueArray *headers,
const gchar *name,
const gchar *charset)
{
- CamelHeaderAddress *addr;
- gchar *text, *str;
+ CamelHeaderAddress *addr = NULL;
+ gchar *text = NULL, *str = NULL;
+ const gchar *value;
- if (!(text = (gchar *) camel_header_raw_find (&h, name, NULL)))
+ value = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, name);
+ if (!value)
return NULL;
- while (isspace ((unsigned) *text))
- text++;
+ while (*value && g_ascii_isspace (*value))
+ value++;
- text = camel_header_unfold (text);
+ text = camel_header_unfold (value);
if ((addr = camel_header_address_decode (text, charset))) {
str = camel_header_address_list_format (addr);
@@ -3656,54 +2752,36 @@ summary_format_address (struct _camel_header_raw *h,
}
static gchar *
-summary_format_string (struct _camel_header_raw *h,
+summary_format_string (const CamelNameValueArray *headers,
const gchar *name,
const gchar *charset)
{
gchar *text, *str;
+ const gchar *value;
- if (!(text = (gchar *) camel_header_raw_find (&h, name, NULL)))
+ value = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, name);
+ if (!value)
return NULL;
- while (isspace ((unsigned) *text))
- text++;
+ while (*value && g_ascii_isspace (*value))
+ value++;
- text = camel_header_unfold (text);
+ text = camel_header_unfold (value);
str = camel_header_decode_string (text, charset);
g_free (text);
return str;
}
-/**
- * camel_folder_summary_content_info_new:
- * @summary: a #CamelFolderSummary object
- *
- * Allocate a new #CamelMessageContentInfo, suitable for adding
- * to this summary.
- *
- * Returns: a newly allocated #CamelMessageContentInfo
- **/
-CamelMessageContentInfo *
-camel_folder_summary_content_info_new (CamelFolderSummary *summary)
-{
- CamelFolderSummaryClass *class;
-
- class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
- g_return_val_if_fail (class->content_info_size > 0, NULL);
-
- return g_slice_alloc0 (class->content_info_size);
-}
-
static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *summary,
- struct _camel_header_raw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+ const CamelNameValueArray *headers)
{
const gchar *received, *date, *content, *charset = NULL;
GSList *refs, *irt, *scan;
gchar *subject, *from, *to, *cc, *mlist;
CamelContentType *ct = NULL;
- CamelMessageInfoBase *mi;
+ CamelMessageInfo *mi;
guint8 *digest;
gsize length;
gchar *msgid;
@@ -3712,9 +2790,11 @@ message_info_new_from_header (CamelFolderSummary *summary,
length = g_checksum_type_get_length (G_CHECKSUM_MD5);
digest = g_alloca (length);
- mi = (CamelMessageInfoBase *) camel_message_info_new (summary);
+ mi = camel_message_info_new (summary);
+
+ camel_message_info_set_abort_notifications (mi, TRUE);
- if ((content = camel_header_raw_find (&h, "Content-Type", NULL))
+ if ((content = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE,
"Content-Type"))
&& (ct = camel_content_type_decode (content))
&& (charset = camel_content_type_param (ct, "charset"))
&& (g_ascii_strcasecmp (charset, "us-ascii") == 0))
@@ -3722,62 +2802,71 @@ message_info_new_from_header (CamelFolderSummary *summary,
charset = charset ? camel_iconv_charset_name (charset) : NULL;
- subject = summary_format_string (h, "subject", charset);
- from = summary_format_address (h, "from", charset);
- to = summary_format_address (h, "to", charset);
- cc = summary_format_address (h, "cc", charset);
- mlist = camel_header_raw_check_mailing_list (&h);
+ subject = summary_format_string (headers, "subject", charset);
+ from = summary_format_address (headers, "from", charset);
+ to = summary_format_address (headers, "to", charset);
+ cc = summary_format_address (headers, "cc", charset);
+ mlist = camel_headers_dup_mailing_list (headers);
if (ct)
camel_content_type_unref (ct);
- mi->subject = camel_pstring_add (subject, TRUE);
- mi->from = camel_pstring_add (from, TRUE);
- mi->to = camel_pstring_add (to, TRUE);
- mi->cc = camel_pstring_add (cc, TRUE);
- mi->mlist = camel_pstring_add (mlist, TRUE);
+ camel_message_info_set_subject (mi, subject);
+ camel_message_info_set_from (mi, from);
+ camel_message_info_set_to (mi, to);
+ camel_message_info_set_cc (mi, cc);
+ camel_message_info_set_mlist (mi, mlist);
- mi->user_flags = NULL;
- mi->user_tags = NULL;
+ g_free (subject);
+ g_free (from);
+ g_free (to);
+ g_free (cc);
+ g_free (mlist);
- if ((date = camel_header_raw_find (&h, "date", NULL)))
- mi->date_sent = camel_header_decode_date (date, NULL);
+ if ((date = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Date")))
+ camel_message_info_set_date_sent (mi, camel_header_decode_date (date, NULL));
else
- mi->date_sent = 0;
+ camel_message_info_set_date_sent (mi, 0);
- received = camel_header_raw_find (&h, "received", NULL);
+ received = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Received");
if (received)
received = strrchr (received, ';');
if (received)
- mi->date_received = camel_header_decode_date (received + 1, NULL);
+ camel_message_info_set_date_received (mi, camel_header_decode_date (received + 1, NULL));
else
- mi->date_received = 0;
+ camel_message_info_set_date_received (mi, 0);
/* Fallback to Received date, when the Date header is missing */
- if (!mi->date_sent)
- mi->date_sent = mi->date_received;
+ if (!camel_message_info_get_date_sent (mi))
+ camel_message_info_set_date_sent (mi, camel_message_info_get_date_received (mi));
/* If neither Received is available, then use the current time. */
- if (!mi->date_sent)
- mi->date_sent = time (NULL);
+ if (!camel_message_info_get_date_sent (mi))
+ camel_message_info_set_date_sent (mi, (gint64) time (NULL));
- msgid = camel_header_msgid_decode (camel_header_raw_find (&h, "message-id", NULL));
+ msgid = camel_header_msgid_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "Message-ID"));
if (msgid) {
GChecksum *checksum;
+ CamelSummaryMessageID message_id;
checksum = g_checksum_new (G_CHECKSUM_MD5);
g_checksum_update (checksum, (guchar *) msgid, -1);
g_checksum_get_digest (checksum, digest, &length);
g_checksum_free (checksum);
- memcpy (mi->message_id.id.hash, digest, sizeof (mi->message_id.id.hash));
+ memcpy (message_id.id.hash, digest, sizeof (message_id.id.hash));
g_free (msgid);
+
+ camel_message_info_set_message_id (mi, message_id.id.id);
}
/* decode our references and in-reply-to headers */
- refs = camel_header_references_decode (camel_header_raw_find (&h, "references", NULL));
- irt = camel_header_references_decode (camel_header_raw_find (&h, "in-reply-to", NULL));
+ refs = camel_header_references_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "References"));
+ irt = camel_header_references_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "In-Reply-To"));
if (refs || irt) {
+ GArray *references;
+ CamelSummaryMessageID message_id;
+
if (irt) {
/* The References field is populated from the "References" and/or "In-Reply-To"
* headers. If both headers exist, take the first thing in the In-Reply-To header
@@ -3790,8 +2879,8 @@ message_info_new_from_header (CamelFolderSummary *summary,
}
count = g_slist_length (refs);
- mi->references = g_malloc (sizeof (*mi->references) + ((count - 1) * sizeof
(mi->references->references[0])));
- count = 0;
+ references = g_array_sized_new (FALSE, FALSE, sizeof (guint64), count);
+
for (scan = refs; scan != NULL; scan = g_slist_next (scan)) {
GChecksum *checksum;
@@ -3800,84 +2889,18 @@ message_info_new_from_header (CamelFolderSummary *summary,
g_checksum_get_digest (checksum, digest, &length);
g_checksum_free (checksum);
- memcpy (mi->references->references[count].id.hash, digest, sizeof
(mi->message_id.id.hash));
- count++;
+ memcpy (message_id.id.hash, digest, sizeof (message_id.id.hash));
+
+ g_array_append_val (references, message_id.id.id);
}
- mi->references->size = count;
g_slist_free_full (refs, g_free);
- }
-
- return (CamelMessageInfo *) mi;
-}
-
-static void
-message_info_free (CamelFolderSummary *summary,
- CamelMessageInfo *info)
-{
- CamelFolderSummaryClass *class;
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
- if (mi->uid) {
- if (summary) {
- camel_folder_summary_lock (summary);
- if (g_hash_table_lookup (summary->priv->loaded_infos, mi->uid) == mi) {
- g_hash_table_remove (summary->priv->loaded_infos, mi->uid);
- }
- camel_folder_summary_unlock (summary);
- }
- camel_pstring_free (mi->uid);
+ camel_message_info_take_references (mi, references);
}
- camel_pstring_free (mi->subject);
- camel_pstring_free (mi->from);
- camel_pstring_free (mi->to);
- camel_pstring_free (mi->cc);
- camel_pstring_free (mi->mlist);
- g_free (mi->bodystructure);
- g_free (mi->references);
- g_free (mi->preview);
- camel_flag_list_free (&mi->user_flags);
- camel_tag_list_free (&mi->user_tags);
- if (mi->headers)
- camel_header_param_list_free (mi->headers);
-
- if (summary) {
- class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
- g_slice_free1 (class->message_info_size, mi);
- } else
- g_slice_free (CamelMessageInfoBase, mi);
-}
-static CamelMessageContentInfo *
-content_info_new_from_header (CamelFolderSummary *summary,
- struct _camel_header_raw *h)
-{
- CamelMessageContentInfo *ci;
- const gchar *charset;
-
- ci = camel_folder_summary_content_info_new (summary);
-
- charset = camel_iconv_locale_charset ();
- ci->id = camel_header_msgid_decode (camel_header_raw_find (&h, "content-id", NULL));
- ci->description = camel_header_decode_string (camel_header_raw_find (&h, "content-description",
NULL), charset);
- ci->encoding = camel_content_transfer_encoding_decode (camel_header_raw_find (&h,
"content-transfer-encoding", NULL));
- ci->type = camel_content_type_decode (camel_header_raw_find (&h, "content-type", NULL));
-
- return ci;
-}
-
-static void
-content_info_free (CamelFolderSummary *summary,
- CamelMessageContentInfo *ci)
-{
- CamelFolderSummaryClass *class;
-
- class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
+ camel_message_info_set_abort_notifications (mi, FALSE);
- camel_content_type_unref (ci->type);
- g_free (ci->id);
- g_free (ci->description);
- g_free (ci->encoding);
- g_slice_free1 (class->content_info_size, ci);
+ return mi;
}
static gchar *
@@ -3893,30 +2916,25 @@ next_uid_string (CamelFolderSummary *summary)
*/
/* must have filter_lock before calling this function */
-static CamelMessageContentInfo *
-summary_build_content_info (CamelFolderSummary *summary,
- CamelMessageInfo *msginfo,
- CamelMimeParser *mp)
+static void
+summary_traverse_content_with_parser (CamelFolderSummary *summary,
+ CamelMessageInfo *msginfo,
+ CamelMimeParser *mp)
{
gint state;
gsize len;
gchar *buffer;
- CamelMessageContentInfo *info = NULL;
CamelContentType *ct;
gint enc_id = -1, chr_id = -1, html_id = -1, idx_id = -1;
CamelFolderSummaryPrivate *p = summary->priv;
CamelMimeFilter *mfc;
- CamelMessageContentInfo *part;
const gchar *calendar_header;
- d (printf ("building content info\n"));
+ d (printf ("traversing content\n"));
/* start of this part */
state = camel_mime_parser_step (mp, &buffer, &len);
- if (summary->priv->build_content)
- info = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->content_info_new_from_parser (summary, mp);
-
switch (state) {
case CAMEL_MIME_PARSER_STATE_HEADER:
/* check content type for indexing, then read body */
@@ -4032,11 +3050,7 @@ summary_build_content_info (CamelFolderSummary *summary,
while (camel_mime_parser_step (mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) {
camel_mime_parser_unstep (mp);
- part = summary_build_content_info (summary, msginfo, mp);
- if (part) {
- part->parent = info;
- my_list_append ((struct _node **) &info->childs, (struct _node *) part);
- }
+ summary_traverse_content_with_parser (summary, msginfo, mp);
}
break;
case CAMEL_MIME_PARSER_STATE_MESSAGE:
@@ -4044,11 +3058,7 @@ summary_build_content_info (CamelFolderSummary *summary,
/* update attachments flag as we go */
camel_message_info_set_flags (msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);
- part = summary_build_content_info (summary, msginfo, mp);
- if (part) {
- part->parent = info;
- my_list_append ((struct _node **) &info->childs, (struct _node *) part);
- }
+ summary_traverse_content_with_parser (summary, msginfo, mp);
state = camel_mime_parser_step (mp, &buffer, &len);
if (state != CAMEL_MIME_PARSER_STATE_MESSAGE_END) {
g_error ("Bad parser state: Expecing MESSAGE_END or MESSAGE_EOF, got: %d", state);
@@ -4057,39 +3067,34 @@ summary_build_content_info (CamelFolderSummary *summary,
break;
}
- d (printf ("finished building content info\n"));
-
- return info;
+ d (printf ("finished traversion content info\n"));
}
/* build the content-info, from a message */
/* this needs the filter lock since it uses filters to perform indexing */
-static CamelMessageContentInfo *
-summary_build_content_info_message (CamelFolderSummary *summary,
+static void
+summary_traverse_content_with_part (CamelFolderSummary *summary,
CamelMessageInfo *msginfo,
CamelMimePart *object)
{
CamelDataWrapper *containee;
gint parts, i;
CamelFolderSummaryPrivate *p = summary->priv;
- CamelMessageContentInfo *info = NULL, *child;
CamelContentType *ct;
- const struct _camel_header_raw *header;
+ const CamelNameValueArray *headers;
gboolean is_calendar = FALSE, is_note = FALSE;
-
- if (summary->priv->build_content)
- info = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->content_info_new_from_message (summary,
object);
+ const gchar *header_name, *header_value;
containee = camel_medium_get_content (CAMEL_MEDIUM (object));
if (containee == NULL)
- return info;
+ return;
/* TODO: I find it odd that get_part and get_content do not
* add a reference, probably need fixing for multithreading */
/* check for attachments */
- ct = ((CamelDataWrapper *) containee)->mime_type;
+ ct = camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (containee));
if (camel_content_type_is (ct, "multipart", "*")) {
if (camel_content_type_is (ct, "multipart", "mixed"))
camel_message_info_set_flags (msginfo, CAMEL_MESSAGE_ATTACHMENTS,
CAMEL_MESSAGE_ATTACHMENTS);
@@ -4105,22 +3110,22 @@ summary_build_content_info_message (CamelFolderSummary *summary,
camel_message_info_set_flags (msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
}
- for (header = object->headers; header; header = header->next) {
- const gchar *value = header->value;
+ headers = camel_medium_get_headers (CAMEL_MEDIUM (object));
+ for (i = 0; camel_name_value_array_get (headers, i, &header_name, &header_value); i++) {
+ const gchar *value = header_value;
- /* skip preceding spaces in the value */
- while (value && *value && isspace (*value))
+ while (value && *value && g_ascii_isspace (*value))
value++;
- if (header->name && value && (
- (g_ascii_strcasecmp (header->name, "Content-class") == 0 && g_ascii_strcasecmp (value,
"urn:content-classes:calendarmessage") == 0) ||
- (g_ascii_strcasecmp (header->name, "X-Calendar-Attachment") == 0))) {
+ if (header_name && value && (
+ (g_ascii_strcasecmp (header_name, "Content-class") == 0 && g_ascii_strcasecmp (value,
"urn:content-classes:calendarmessage") == 0) ||
+ (g_ascii_strcasecmp (header_name, "X-Calendar-Attachment") == 0))) {
is_calendar = TRUE;
if (is_note)
break;
}
- if (header->name && value && g_ascii_strcasecmp (header->name, "X-Evolution-Note") == 0) {
+ if (header_name && value && g_ascii_strcasecmp (header_name, "X-Evolution-Note") == 0) {
is_note = TRUE;
if (is_calendar)
break;
@@ -4139,20 +3144,12 @@ summary_build_content_info_message (CamelFolderSummary *summary,
for (i = 0; i < parts; i++) {
CamelMimePart *part = camel_multipart_get_part (CAMEL_MULTIPART (containee), i);
- g_return_val_if_fail (part, info);
- child = summary_build_content_info_message (summary, msginfo, part);
- if (child) {
- child->parent = info;
- my_list_append ((struct _node **) &info->childs, (struct _node *) child);
- }
+ g_return_if_fail (part);
+ summary_traverse_content_with_part (summary, msginfo, part);
}
} else if (CAMEL_IS_MIME_MESSAGE (containee)) {
/* for messages we only look at its contents */
- child = summary_build_content_info_message (summary, msginfo, (CamelMimePart *) containee);
- if (child) {
- child->parent = info;
- my_list_append ((struct _node **) &info->childs, (struct _node *) child);
- }
+ summary_traverse_content_with_part (summary, msginfo, (CamelMimePart *) containee);
} else if (p->filter_stream
&& camel_content_type_is (ct, "text", "*")) {
gint html_id = -1, idx_id = -1;
@@ -4181,327 +3178,6 @@ summary_build_content_info_message (CamelFolderSummary *summary,
camel_stream_filter_remove (
CAMEL_STREAM_FILTER (p->filter_stream), html_id);
}
-
- return info;
-}
-
-/**
- * camel_flag_get:
- * @list: the address of a #CamelFlag list
- * @name: name of the flag to get
- *
- * Find the state of the flag @name in @list.
- *
- * Returns: the state of the flag (%TRUE or %FALSE)
- **/
-gboolean
-camel_flag_get (CamelFlag **list,
- const gchar *name)
-{
- CamelFlag *flag;
- flag = *list;
- while (flag) {
- if (!strcmp (flag->name, name))
- return TRUE;
- flag = flag->next;
- }
- return FALSE;
-}
-
-/**
- * camel_flag_set:
- * @list: the address of a #CamelFlag list
- * @name: name of the flag to set or change
- * @value: the value to set on the flag
- *
- * Set the state of a flag @name in the list @list to @value.
- *
- * Returns: %TRUE if the value of the flag has been changed or %FALSE
- * otherwise
- **/
-gboolean
-camel_flag_set (CamelFlag **list,
- const gchar *name,
- gboolean value)
-{
- CamelFlag *flag, *tmp;
- gsize tmp_len = 0;
-
- if (!name)
- return TRUE;
-
- /* this 'trick' works because flag->next is the first element */
- flag = (CamelFlag *) list;
- while (flag->next) {
- tmp = flag->next;
- if (!strcmp (flag->next->name, name)) {
- if (!value) {
- flag->next = tmp->next;
- g_free (tmp);
- }
- return !value;
- }
- flag = tmp;
- }
-
- if (value) {
- tmp_len = sizeof (*tmp) + strlen (name);
- tmp = g_malloc (tmp_len);
- g_strlcpy (tmp->name, name, strlen (name) + 1);
- tmp->next = NULL;
- flag->next = tmp;
- }
- return value;
-}
-
-/**
- * camel_flag_list_size:
- * @list: the address of a #CamelFlag list
- *
- * Get the length of the flag list.
- *
- * Returns: the number of flags in the list
- **/
-gint
-camel_flag_list_size (CamelFlag **list)
-{
- gint count = 0;
- CamelFlag *flag;
-
- flag = *list;
- while (flag) {
- count++;
- flag = flag->next;
- }
- return count;
-}
-
-/**
- * camel_flag_list_free:
- * @list: the address of a #CamelFlag list
- *
- * Free the memory associated with the flag list @list.
- **/
-void
-camel_flag_list_free (CamelFlag **list)
-{
- CamelFlag *flag, *tmp;
- flag = *list;
- while (flag) {
- tmp = flag->next;
- g_free (flag);
- flag = tmp;
- }
- *list = NULL;
-}
-
-/**
- * camel_flag_list_copy:
- * @to: the address of the #CamelFlag list to copy to
- * @from: the address of the #CamelFlag list to copy from
- *
- * Copy a flag list.
- *
- * Returns: %TRUE if @to is changed or %FALSE otherwise
- **/
-gboolean
-camel_flag_list_copy (CamelFlag **to,
- CamelFlag **from)
-{
- CamelFlag *flag, *tmp;
- gboolean changed = FALSE;
-
- if (*to == NULL && from == NULL)
- return FALSE;
-
- /* Remove any now-missing flags */
- flag = (CamelFlag *) to;
- while (flag->next) {
- tmp = flag->next;
- if (!camel_flag_get (from, tmp->name)) {
- if (*tmp->name)
- changed = TRUE;
- flag->next = tmp->next;
- g_free (tmp);
- } else {
- flag = tmp;
- }
- }
-
- /* Add any new non-empty flags */
- flag = *from;
- while (flag) {
- if (*flag->name)
- changed |= camel_flag_set (to, flag->name, TRUE);
- flag = flag->next;
- }
-
- return changed;
-}
-
-/**
- * camel_tag_get:
- * @list: the address of a #CamelTag list
- * @name: name of the tag to get
- *
- * Find the flag @name in @list and get the value.
- *
- * Returns: the value of the flag or %NULL if unset
- **/
-const gchar *
-camel_tag_get (CamelTag **list,
- const gchar *name)
-{
- CamelTag *tag;
-
- tag = *list;
- while (tag) {
- if (!strcmp (tag->name, name))
- return (const gchar *) tag->value;
- tag = tag->next;
- }
- return NULL;
-}
-
-/**
- * camel_tag_set:
- * @list: the address of a #CamelTag list
- * @name: name of the tag to set
- * @value: value to set on the tag
- *
- * Set the tag @name in the tag list @list to @value.
- *
- * Returns: %TRUE if the value on the tag changed or %FALSE otherwise
- **/
-gboolean
-camel_tag_set (CamelTag **list,
- const gchar *name,
- const gchar *value)
-{
- CamelTag *tag, *tmp;
-
- /* this 'trick' works because tag->next is the first element */
- tag = (CamelTag *) list;
- while (tag->next) {
- tmp = tag->next;
- if (!strcmp (tmp->name, name)) {
- if (value == NULL) { /* clear it? */
- tag->next = tmp->next;
- g_free (tmp->value);
- g_free (tmp);
- return TRUE;
- } else if (strcmp (tmp->value, value)) { /* has it changed? */
- g_free (tmp->value);
- tmp->value = g_strdup (value);
- return TRUE;
- }
- return FALSE;
- }
- tag = tmp;
- }
-
- if (value) {
- tmp = g_malloc (sizeof (*tmp) + strlen (name));
- g_strlcpy (tmp->name, name, strlen (name) + 1);
- tmp->value = g_strdup (value);
- tmp->next = NULL;
- tag->next = tmp;
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * camel_tag_list_size:
- * @list: the address of a #CamelTag list
- *
- * Get the number of tags present in the tag list @list.
- *
- * Returns: the number of tags
- **/
-gint
-camel_tag_list_size (CamelTag **list)
-{
- gint count = 0;
- CamelTag *tag;
-
- tag = *list;
- while (tag) {
- count++;
- tag = tag->next;
- }
- return count;
-}
-
-static void
-rem_tag (gchar *key,
- gchar *value,
- CamelTag **to)
-{
- camel_tag_set (to, key, NULL);
-}
-
-/**
- * camel_tag_list_copy:
- * @to: the address of the #CamelTag list to copy to
- * @from: the address of the #CamelTag list to copy from
- *
- * Copy a tag list.
- *
- * Returns: %TRUE if @to is changed or %FALSE otherwise
- **/
-gboolean
-camel_tag_list_copy (CamelTag **to,
- CamelTag **from)
-{
- gint changed = FALSE;
- CamelTag *tag;
- GHashTable *left;
-
- if (*to == NULL && from == NULL)
- return FALSE;
-
- left = g_hash_table_new (g_str_hash, g_str_equal);
- tag = *to;
- while (tag) {
- g_hash_table_insert (left, tag->name, tag);
- tag = tag->next;
- }
-
- tag = *from;
- while (tag) {
- changed |= camel_tag_set (to, tag->name, tag->value);
- g_hash_table_remove (left, tag->name);
- tag = tag->next;
- }
-
- if (g_hash_table_size (left) > 0) {
- g_hash_table_foreach (left, (GHFunc) rem_tag, to);
- changed = TRUE;
- }
- g_hash_table_destroy (left);
-
- return changed;
-}
-
-/**
- * camel_tag_list_free:
- * @list: the address of a #CamelTag list
- *
- * Free the tag list @list.
- **/
-void
-camel_tag_list_free (CamelTag **list)
-{
- CamelTag *tag, *tmp;
- tag = *list;
- while (tag) {
- tmp = tag->next;
- g_free (tag->value);
- g_free (tag);
- tag = tmp;
- }
- *list = NULL;
}
static struct flag_names_t {
@@ -4559,684 +3235,25 @@ camel_system_flag_get (CamelMessageFlags flags,
}
/**
- * camel_message_info_new:
- * @summary: (nullable): a #CamelFolderSummary object or %NULL
- *
- * Create a new #CamelMessageInfo.
- *
- * Returns: (transfer full) (type CamelMessageInfo): a new #CamelMessageInfo
- **/
-gpointer
-camel_message_info_new (CamelFolderSummary *summary)
-{
- CamelFolderSummaryClass *class;
- CamelMessageInfo *info;
- gsize message_info_size;
-
- if (summary != NULL) {
- class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
- g_return_val_if_fail (class->message_info_size > 0, NULL);
- message_info_size = class->message_info_size;
- } else {
- message_info_size = sizeof (CamelMessageInfoBase);
- }
-
- info = g_slice_alloc0 (message_info_size);
- info->refcount = 1;
- info->summary = summary;
-
- /* We assume that mi is always dirty unless freshly read or just saved*/
- ((CamelMessageInfoBase *) info)->dirty = TRUE;
-
- return info;
-}
-
-/**
- * camel_message_info_ref:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Reference an info.
- * Returns: (transfer full) (type CamelMessageInfo):
- **/
-gpointer
-camel_message_info_ref (gpointer o)
-{
- CamelMessageInfo *mi = o;
-
- g_return_val_if_fail (mi != NULL, NULL);
- g_return_val_if_fail (mi->refcount > 0, NULL);
-
- g_atomic_int_inc (&mi->refcount);
-
- return o;
-}
-
-/**
- * camel_message_info_new_from_header:
+ * camel_message_info_new_from_headers:
* @summary: a #CamelFolderSummary object or %NULL
- * @header: raw header
+ * @headers: a #CamelNameValueArray
*
* Create a new #CamelMessageInfo pre-populated with info from
- * @header.
+ * @headers.
*
* Returns: (transfer full): a new #CamelMessageInfo
+ *
+ * Since: 3.24
**/
CamelMessageInfo *
-camel_message_info_new_from_header (CamelFolderSummary *summary,
- struct _camel_header_raw *header)
+camel_message_info_new_from_headers (CamelFolderSummary *summary,
+ const CamelNameValueArray *headers)
{
if (summary != NULL)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->
- message_info_new_from_header (summary, header);
- else
- return message_info_new_from_header (NULL, header);
-}
-
-/**
- * camel_message_info_unref:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Unref's and potentially frees a #CamelMessageInfo and its contents.
- **/
-void
-camel_message_info_unref (gpointer o)
-{
- CamelMessageInfo *mi = o;
-
- g_return_if_fail (mi != NULL);
- g_return_if_fail (mi->refcount > 0);
-
- if (g_atomic_int_dec_and_test (&mi->refcount)) {
- if (mi->summary != NULL) {
- CamelFolderSummaryClass *class;
-
- /* FIXME This is kinda busted, should really
- * be handled by message_info_free(). */
- if (mi->summary->priv->build_content
- && ((CamelMessageInfoBase *) mi)->content) {
- camel_folder_summary_content_info_free (
- mi->summary,
- ((CamelMessageInfoBase *) mi)->content);
- ((CamelMessageInfoBase *) mi)->content = NULL;
- }
-
- class = CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary);
- g_return_if_fail (class->message_info_free != NULL);
-
- class->message_info_free (mi->summary, mi);
- } else {
- message_info_free (NULL, mi);
- }
- }
-}
-
-/**
- * camel_message_info_clone:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Duplicate a #CamelMessageInfo.
- *
- * Returns: (transfer full) (type CamelMessageInfo): the duplicated #CamelMessageInfo
- **/
-gpointer
-camel_message_info_clone (gconstpointer o)
-{
- const CamelMessageInfo *mi = o;
-
- if (mi->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (mi->summary)->message_info_clone (mi->summary, mi);
+ return CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->message_info_new_from_headers (summary,
headers);
else
- return message_info_clone (NULL, mi);
-}
-
-/**
- * camel_message_info_get_ptr:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- * @id: info to get
- *
- * Generic accessor method for getting pointer data.
- *
- * Returns: (transfer none): the pointer data
- *
- * Since: 3.22
- **/
-gconstpointer
-camel_message_info_get_ptr (gconstpointer info,
- gint id)
-{
- const CamelMessageInfo *nfo = info;
-
- g_return_val_if_fail (info != NULL, NULL);
-
- if (nfo->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (nfo->summary)->info_ptr (nfo, id);
- else
- return info_ptr (nfo, id);
-}
-
-/**
- * camel_message_info_get_uint32:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- * @id: info to get
- *
- * Generic accessor method for getting 32bit unsigned integer data.
- *
- * Returns: the guint32 data
- *
- * Since: 3.22
- **/
-guint32
-camel_message_info_get_uint32 (gconstpointer info,
- gint id)
-{
- const CamelMessageInfo *nfo = info;
-
- g_return_val_if_fail (info != NULL, 0);
-
- if (nfo->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (nfo->summary)->info_uint32 (nfo, id);
- else
- return info_uint32 (nfo, id);
-}
-
-/**
- * camel_message_info_get_time:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- * @id: info to get
- *
- * Generic accessor method for getting time_t data.
- *
- * Returns: the time_t data
- *
- * Since: 3.22
- **/
-time_t
-camel_message_info_get_time (gconstpointer info,
- gint id)
-{
- const CamelMessageInfo *nfo = info;
-
- g_return_val_if_fail (info != NULL, (time_t) 0);
-
- if (nfo->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (nfo->summary)->info_time (nfo, id);
- else
- return info_time (nfo, id);
-}
-
-/**
- * camel_message_info_get_uid:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the uid of the #CamelMessageInfo
- *
- * Returns: the uid
- *
- * Since: 3.22
- **/
-const gchar *
-camel_message_info_get_uid (gconstpointer info)
-{
- const CamelMessageInfo *nfo = info;
-
- g_return_val_if_fail (info != NULL, NULL);
-
- return nfo->uid;
-}
-
-/**
- * camel_message_info_get_subject:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the subject of the #CamelMessageInfo
- *
- * Returns: the subject
- *
- * Since: 3.22
- **/
-const gchar *
-camel_message_info_get_subject (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_SUBJECT);
-}
-
-/**
- * camel_message_info_get_preview:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the preview of the #CamelMessageInfo
- *
- * Returns: the preview
- *
- * Since: 3.22
- **/
-const gchar *
-camel_message_info_get_preview (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_PREVIEW);
-}
-
-/**
- * camel_message_info_get_from:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the from field of the #CamelMessageInfo
- *
- * Returns: the from field
- *
- * Since: 3.22
- **/
-const gchar *
-camel_message_info_get_from (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_FROM);
-}
-
-/**
- * camel_message_info_get_to:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the to field of the #CamelMessageInfo
- *
- * Returns: the to field
- *
- * Since: 3.22
- **/
-const gchar *
-camel_message_info_get_to (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_TO);
-}
-
-/**
- * camel_message_info_get_cc:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the cc field of the #CamelMessageInfo
- *
- * Returns: the cc field
- *
- * Since: 3.22
- **/
-const gchar *
-camel_message_info_get_cc (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_CC);
-}
-
-/**
- * camel_message_info_get_mlist:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the mlist of the #CamelMessageInfo
- *
- * Returns: the mlist
- *
- * Since: 3.22
- **/
-const gchar *
-camel_message_info_get_mlist (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_MLIST);
-}
-
-/**
- * camel_message_info_get_flags:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the flags of the #CamelMessageInfo
- *
- * Returns: the flags
- *
- * Since: 3.22
- **/
-guint32
-camel_message_info_get_flags (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, 0);
-
- return camel_message_info_get_uint32 (info, CAMEL_MESSAGE_INFO_FLAGS);
-}
-
-/**
- * camel_message_info_get_size:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the size of the #CamelMessageInfo
- *
- * Returns: the size
- *
- * Since: 3.22
- **/
-guint32
-camel_message_info_get_size (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, 0);
-
- return camel_message_info_get_uint32 (info, CAMEL_MESSAGE_INFO_SIZE);
-}
-
-/**
- * camel_message_info_get_date_sent:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the sent date of the #CamelMessageInfo
- *
- * Returns: the sent date
- *
- * Since: 3.22
- **/
-time_t
-camel_message_info_get_date_sent (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, (time_t) 0);
-
- return camel_message_info_get_time (info, CAMEL_MESSAGE_INFO_DATE_SENT);
-}
-
-/**
- * camel_message_info_get_date_received:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the received date of the #CamelMessageInfo
- *
- * Returns: the received date
- *
- * Since: 3.22
- **/
-time_t
-camel_message_info_get_date_received (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, (time_t) 0);
-
- return camel_message_info_get_time (info, CAMEL_MESSAGE_INFO_DATE_RECEIVED);
-}
-
-/**
- * camel_message_info_get_user_flag:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- * @id: user flag to get
- *
- * Get the state of a user flag named @id.
- *
- * Returns: the state of the user flag
- *
- * Since: 3.22
- **/
-gboolean
-camel_message_info_get_user_flag (gconstpointer info,
- const gchar *id)
-{
- const CamelMessageInfo *nfo = info;
-
- g_return_val_if_fail (info != NULL, FALSE);
-
- if (nfo->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (nfo->summary)->info_user_flag (nfo, id);
- else
- return info_user_flag (nfo, id);
-}
-
-/**
- * camel_message_info_get_user_tag:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- * @id: user tag to get
- *
- * Get the value of a user tag named @id.
- *
- * Returns: the value of the user tag
- *
- * Since: 3.22
- **/
-const gchar *
-camel_message_info_get_user_tag (gconstpointer info,
- const gchar *id)
-{
- const CamelMessageInfo *nfo = info;
-
- g_return_val_if_fail (info != NULL, NULL);
-
- if (nfo->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (nfo->summary)->info_user_tag (nfo, id);
- else
- return info_user_tag (nfo, id);
-}
-
-/**
- * camel_message_info_get_message_id:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the #CamelSummaryMessageID of the #CamelMessageInfo
- *
- * Returns: the id of the message
- *
- * Since: 3.22
- **/
-const CamelSummaryMessageID *
-camel_message_info_get_message_id (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_MESSAGE_ID);
-}
-
-/**
- * camel_message_info_get_references:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the #CamelSummaryReferences of the #CamelMessageInfo
- *
- * Returns: the references of the message
- *
- * Since: 3.22
- **/
-const CamelSummaryReferences *
-camel_message_info_get_references (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_REFERENCES);
-}
-
-/**
- * camel_message_info_get_user_flags:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the #CamelFlag of the #CamelMessageInfo
- *
- * Returns: the flags of the message
- *
- * Since: 3.22
- **/
-const CamelFlag *
-camel_message_info_get_user_flags (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_USER_FLAGS);
-}
-
-/**
- * camel_message_info_get_user_tags:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the #CamelTag of the #CamelMessageInfo
- *
- * Returns: the tags of the message
- *
- * Since: 3.22
- **/
-const CamelTag *
-camel_message_info_get_user_tags (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_USER_TAGS);
-}
-
-/**
- * camel_message_info_get_headers:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the #CamelHeaderParam of the #CamelMessageInfo
- *
- * Returns: the headers of the message
- *
- * Since: 3.22
- **/
-const CamelHeaderParam *
-camel_message_info_get_headers (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_HEADERS);
-}
-
-/**
- * camel_message_info_get_content:
- * @info: (type CamelMessageInfo): a #CamelMessageInfo
- *
- * Get the #CamelMessageContentInfo of the #CamelMessageInfo
- *
- * Returns: the content of the message
- *
- * Since: 3.22
- **/
-const CamelMessageContentInfo *
-camel_message_info_get_content (gconstpointer info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return camel_message_info_get_ptr (info, CAMEL_MESSAGE_INFO_CONTENT);
-}
-
-/**
- * camel_message_info_set_flags:
- * @info: a #CamelMessageInfo
- * @flags: mask of flags to change
- * @set: state the flags should be changed to
- *
- * Change the state of the system flags on the #CamelMessageInfo
- *
- * Returns: %TRUE if any of the flags changed or %FALSE otherwise
- **/
-gboolean
-camel_message_info_set_flags (CamelMessageInfo *info,
- CamelMessageFlags flags,
- guint32 set)
-{
- if (info->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_set_flags (info, flags, set);
- else
- return info_set_flags (info, flags, set);
-}
-
-/**
- * camel_message_info_set_user_flag:
- * @info: a #CamelMessageInfo
- * @id: name of the user flag to set
- * @state: state to set the flag to
- *
- * Set the state of a user flag on a #CamelMessageInfo.
- *
- * Returns: %TRUE if the state changed or %FALSE otherwise
- **/
-gboolean
-camel_message_info_set_user_flag (CamelMessageInfo *info,
- const gchar *id,
- gboolean state)
-{
- if (info->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_set_user_flag (info, id, state);
- else
- return info_set_user_flag (info, id, state);
-}
-
-/**
- * camel_message_info_set_user_tag:
- * @info: a #CamelMessageInfo
- * @id: name of the user tag to set
- * @val: value to set
- *
- * Set the value of a user tag on a #CamelMessageInfo.
- *
- * Returns: %TRUE if the value changed or %FALSE otherwise
- **/
-gboolean
-camel_message_info_set_user_tag (CamelMessageInfo *info,
- const gchar *id,
- const gchar *val)
-{
- if (info->summary)
- return CAMEL_FOLDER_SUMMARY_GET_CLASS (info->summary)->info_set_user_tag (info, id, val);
- else
- return info_set_user_tag (info, id, val);
-}
-
-void
-camel_content_info_dump (CamelMessageContentInfo *ci,
- gint depth)
-{
- gchar *p;
-
- p = alloca (depth * 4 + 1);
- memset (p, ' ', depth * 4);
- p[depth * 4] = 0;
-
- if (ci == NULL) {
- printf ("%s<empty>\n", p);
- return;
- }
-
- if (ci->type)
- printf (
- "%scontent-type: %s/%s\n",
- p, ci->type->type ? ci->type->type : "(null)",
- ci->type->subtype ? ci->type->subtype : "(null)");
- else
- printf ("%scontent-type: <unset>\n", p);
- printf (
- "%scontent-transfer-encoding: %s\n",
- p, ci->encoding ? ci->encoding : "(null)");
- printf (
- "%scontent-description: %s\n",
- p, ci->description ? ci->description : "(null)");
- printf ("%ssize: %lu\n", p, (gulong) ci->size);
- ci = ci->childs;
- while (ci) {
- camel_content_info_dump (ci, depth + 1);
- ci = ci->next;
- }
-}
-
-void
-camel_message_info_dump (CamelMessageInfo *info)
-{
- if (info == NULL) {
- printf ("No message?\n");
- return;
- }
-
- printf ("Subject: %s\n", camel_message_info_get_subject (info));
- printf ("To: %s\n", camel_message_info_get_to (info));
- printf ("Cc: %s\n", camel_message_info_get_cc (info));
- printf ("mailing list: %s\n", camel_message_info_get_mlist (info));
- printf ("From: %s\n", camel_message_info_get_from (info));
- printf ("UID: %s\n", camel_message_info_get_uid (info));
- printf ("Flags: %04x\n", camel_message_info_get_flags (info));
- camel_content_info_dump (((CamelMessageInfoBase *) info)->content, 0);
+ return message_info_new_from_headers (NULL, headers);
}
/**
@@ -5270,47 +3287,3 @@ camel_folder_summary_unlock (CamelFolderSummary *summary)
g_rec_mutex_unlock (&summary->priv->summary_lock);
}
-
-gint
-bdata_extract_digit (/* const */ gchar **part)
-{
- if (!part || !*part || !**part)
- return 0;
-
- if (**part == ' ')
- *part += 1;
-
- if (!**part)
- return 0;
-
- return strtoul (*part, part, 10);
-}
-
-/* expecting "digit-value", where digit is length of the value */
-gchar *
-bdata_extract_string (/* const */ gchar **part)
-{
- gint len, has_len;
- gchar *val;
-
- len = bdata_extract_digit (part);
-
- /* might be a '-' sign */
- if (part && *part && **part)
- *part += 1;
-
- if (len <= 0 || !part || !*part || !**part)
- return g_strdup ("");
-
- if (!**part)
- return g_strdup ("");
-
- has_len = strlen (*part);
- if (has_len < len)
- len = has_len;
-
- val = g_strndup (*part, len);
- *part += len;
-
- return val;
-}
diff --git a/src/camel/camel-folder-summary.h b/src/camel/camel-folder-summary.h
index d6dfff0..8fb53bb 100644
--- a/src/camel/camel-folder-summary.h
+++ b/src/camel/camel-folder-summary.h
@@ -28,7 +28,7 @@
#include <time.h>
#include <camel/camel-index.h>
-#include <camel/camel-memchunk.h>
+#include <camel/camel-message-info.h>
#include <camel/camel-mime-message.h>
#include <camel/camel-mime-parser.h>
@@ -60,156 +60,6 @@ typedef struct _CamelFolderSummary CamelFolderSummary;
typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass;
typedef struct _CamelFolderSummaryPrivate CamelFolderSummaryPrivate;
-typedef struct _CamelMessageInfo CamelMessageInfo;
-typedef struct _CamelMessageInfoBase CamelMessageInfoBase;
-
-typedef struct _CamelMessageContentInfo CamelMessageContentInfo;
-
-/* A tree of message content info structures
- * describe the content structure of the message (if it has any) */
-struct _CamelMessageContentInfo {
- CamelMessageContentInfo *next;
-
- CamelMessageContentInfo *childs;
- CamelMessageContentInfo *parent;
-
- CamelContentType *type;
- gchar *id;
- gchar *description;
- gchar *encoding; /* this should be an enum?? */
- guint32 size;
-};
-
-/* system flag bits */
-typedef enum _CamelMessageFlags {
- CAMEL_MESSAGE_ANSWERED = 1 << 0,
- CAMEL_MESSAGE_DELETED = 1 << 1,
- CAMEL_MESSAGE_DRAFT = 1 << 2,
- CAMEL_MESSAGE_FLAGGED = 1 << 3,
- CAMEL_MESSAGE_SEEN = 1 << 4,
-
- /* these aren't really system flag bits, but are convenience flags */
- CAMEL_MESSAGE_ATTACHMENTS = 1 << 5,
- CAMEL_MESSAGE_ANSWERED_ALL = 1 << 6,
- CAMEL_MESSAGE_JUNK = 1 << 7,
- CAMEL_MESSAGE_SECURE = 1 << 8,
- CAMEL_MESSAGE_NOTJUNK = 1 << 9,
- CAMEL_MESSAGE_FORWARDED = 1 << 10,
-
- /* following flags are for the folder, and are not really permanent flags */
- CAMEL_MESSAGE_FOLDER_FLAGGED = 1 << 16, /* for use by the folder implementation */
- /* flags after 1 << 16 are used by camel providers,
- * if adding non permanent flags, add them to the end */
-
- CAMEL_MESSAGE_JUNK_LEARN = 1 << 30, /* used when setting CAMEL_MESSAGE_JUNK flag
- * to say that we request junk plugin
- * to learn that message as junk/non junk */
- CAMEL_MESSAGE_USER = 1 << 31 /* supports user flags */
-} CamelMessageFlags;
-
-/* Changes to system flags will NOT trigger a folder changed event */
-#define CAMEL_MESSAGE_SYSTEM_MASK (0xffff << 16)
-
-typedef struct _CamelFlag {
- struct _CamelFlag *next;
- gchar name[1]; /* name allocated as part of the structure */
-} CamelFlag;
-
-typedef struct _CamelTag {
- struct _CamelTag *next;
- gchar *value;
- gchar name[1]; /* name allocated as part of the structure */
-} CamelTag;
-
-/* a summary messageid is a 64 bit identifier (partial md5 hash) */
-typedef struct _CamelSummaryMessageID {
- union {
- guint64 id;
- guchar hash[8];
- struct {
- guint32 hi;
- guint32 lo;
- } part;
- } id;
-} CamelSummaryMessageID;
-
-/* summary references is a fixed size array of references */
-typedef struct _CamelSummaryReferences {
- gint size;
- CamelSummaryMessageID references[1];
-} CamelSummaryReferences;
-
-/* accessor id's */
-enum {
- CAMEL_MESSAGE_INFO_SUBJECT,
- CAMEL_MESSAGE_INFO_FROM,
- CAMEL_MESSAGE_INFO_TO,
- CAMEL_MESSAGE_INFO_CC,
- CAMEL_MESSAGE_INFO_MLIST,
-
- CAMEL_MESSAGE_INFO_FLAGS,
- CAMEL_MESSAGE_INFO_SIZE,
-
- CAMEL_MESSAGE_INFO_DATE_SENT,
- CAMEL_MESSAGE_INFO_DATE_RECEIVED,
-
- CAMEL_MESSAGE_INFO_MESSAGE_ID,
- CAMEL_MESSAGE_INFO_REFERENCES,
- CAMEL_MESSAGE_INFO_USER_FLAGS,
- CAMEL_MESSAGE_INFO_USER_TAGS,
-
- CAMEL_MESSAGE_INFO_HEADERS,
- CAMEL_MESSAGE_INFO_PREVIEW,
- CAMEL_MESSAGE_INFO_CONTENT,
- CAMEL_MESSAGE_INFO_LAST
-};
-
-/* information about a given message, use accessors */
-struct _CamelMessageInfo {
- CamelFolderSummary *summary;
-
- volatile gint refcount;
- const gchar *uid;
- /*FIXME: Make it work with the CAMEL_MESSADE_DB_DIRTY flag instead of another 4 bytes*/
- guint dirty : 1;
-};
-
-/* For classes wishing to do the provided i/o, or for anonymous users,
- * they must subclass or use this messageinfo structure */
-/* Otherwise they can do their own thing entirely */
-struct _CamelMessageInfoBase {
- CamelFolderSummary *summary;
-
- volatile gint refcount;
- const gchar *uid;
- /*FIXME: Make it work with the CAMEL_MESSADE_DB_DIRTY flag instead of another 4 bytes*/
- guint dirty : 1;
-
- const gchar *subject;
- const gchar *from;
- const gchar *to;
- const gchar *cc;
- const gchar *mlist;
-
- CamelMessageFlags flags;
- guint32 size;
-
- time_t date_sent;
- time_t date_received;
-
- CamelSummaryMessageID message_id;
- CamelSummaryReferences *references;/* from parent to root */
-
- struct _CamelFlag *user_flags;
- struct _CamelTag *user_tags;
-
- /* tree of content description - NULL if it is not available */
- CamelMessageContentInfo *content;
- struct _camel_header_param *headers;
- gchar *preview;
- gchar *bodystructure;
-};
-
/**
* CamelFolderSummaryFlags:
* @CAMEL_FOLDER_SUMMARY_DIRTY:
@@ -226,17 +76,6 @@ typedef enum {
struct _CamelFolderSummary {
GObject parent;
CamelFolderSummaryPrivate *priv;
-
- /* header info */
- guint32 version; /* version of file loaded/loading */
- time_t time; /* timestamp for this summary (for implementors to use) */
- CamelFolderSummaryFlags flags;
-
- const gchar *collate;
- const gchar *sort_by;
-
- /* Future ABI expansion */
- gpointer later[4];
};
struct _CamelMIRecord;
@@ -245,40 +84,24 @@ struct _CamelFIRecord;
struct _CamelFolderSummaryClass {
GObjectClass parent_class;
- /* sizes of memory objects */
- gsize message_info_size;
- gsize content_info_size;
+ GType message_info_type;
+ const gchar *collate;
+ const gchar *sort_by;
- /* Load/Save folder summary from DB*/
- gboolean (*summary_header_from_db)
+ /* Load/Save folder summary*/
+ gboolean (*summary_header_load)
(CamelFolderSummary *summary,
struct _CamelFIRecord *fir);
struct _CamelFIRecord *
- (*summary_header_to_db)
+ (*summary_header_save)
(CamelFolderSummary *summary,
GError **error);
- CamelMessageInfo *
- (*message_info_from_db)
- (CamelFolderSummary *summary,
- struct _CamelMIRecord *mir);
- struct _CamelMIRecord *
- (*message_info_to_db)
- (CamelFolderSummary *summary,
- CamelMessageInfo *info);
- CamelMessageContentInfo *
- (*content_info_from_db)
- (CamelFolderSummary *summary,
- struct _CamelMIRecord *mir);
- gboolean (*content_info_to_db)
- (CamelFolderSummary *summary,
- CamelMessageContentInfo *info,
- struct _CamelMIRecord *mir);
- /* create/save/load an individual message info */
+ /* create an individual message info */
CamelMessageInfo *
- (*message_info_new_from_header)
+ (*message_info_new_from_headers)
(CamelFolderSummary *summary,
- struct _camel_header_raw *header);
+ const CamelNameValueArray *headers);
CamelMessageInfo *
(*message_info_new_from_parser)
(CamelFolderSummary *summary,
@@ -286,32 +109,8 @@ struct _CamelFolderSummaryClass {
CamelMessageInfo *
(*message_info_new_from_message)
(CamelFolderSummary *summary,
- CamelMimeMessage *message,
- const gchar *bodystructure);
- void (*message_info_free)
- (CamelFolderSummary *summary,
- CamelMessageInfo *ci);
- CamelMessageInfo *
- (*message_info_clone)
- (CamelFolderSummary *summary,
- const CamelMessageInfo *info);
+ CamelMimeMessage *message);
- /* save/load individual content info's */
- CamelMessageContentInfo *
- (*content_info_new_from_header)
- (CamelFolderSummary *summary,
- struct _camel_header_raw *header);
- CamelMessageContentInfo *
- (*content_info_new_from_parser)
- (CamelFolderSummary *summary,
- CamelMimeParser *parser);
- CamelMessageContentInfo *
- (*content_info_new_from_message)
- (CamelFolderSummary *summary,
- CamelMimePart *mime_part);
- void (*content_info_free)
- (CamelFolderSummary *summary,
- CamelMessageContentInfo *ci);
CamelMessageInfo *
(*message_info_from_uid)
(CamelFolderSummary *summary,
@@ -321,34 +120,8 @@ struct _CamelFolderSummaryClass {
gchar * (*next_uid_string)
(CamelFolderSummary *summary);
- /* virtual accessors on messageinfo's */
- gconstpointer (*info_ptr) (const CamelMessageInfo *info,
- gint id);
- guint32 (*info_uint32) (const CamelMessageInfo *info,
- gint id);
- time_t (*info_time) (const CamelMessageInfo *info,
- gint id);
-
- gboolean (*info_user_flag)
- (const CamelMessageInfo *info,
- const gchar *id);
- const gchar * (*info_user_tag)
- (const CamelMessageInfo *info,
- const gchar *id);
-
- /* set accessors for the modifyable bits */
- gboolean (*info_set_user_flag)
- (CamelMessageInfo *info,
- const gchar *id,
- gboolean state);
- gboolean (*info_set_user_tag)
- (CamelMessageInfo *info,
- const gchar *id,
- const gchar *val);
- gboolean (*info_set_flags)
- (CamelMessageInfo *info,
- guint32 mask,
- guint32 set);
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_folder_summary_get_type (void);
@@ -357,7 +130,19 @@ CamelFolderSummary *
struct _CamelFolder *
camel_folder_summary_get_folder (CamelFolderSummary *summary);
-
+guint32 camel_folder_summary_get_flags (CamelFolderSummary *summary);
+void camel_folder_summary_set_flags (CamelFolderSummary *summary,
+ guint32 flags);
+gint64 camel_folder_summary_get_timestamp
+ (CamelFolderSummary *summary);
+void camel_folder_summary_set_timestamp
+ (CamelFolderSummary *summary,
+ gint64 timestamp);
+guint32 camel_folder_summary_get_version
+ (CamelFolderSummary *summary);
+void camel_folder_summary_set_version
+ (CamelFolderSummary *summary,
+ guint32 version);
guint32 camel_folder_summary_get_saved_count
(CamelFolderSummary *summary);
guint32 camel_folder_summary_get_unread_count
@@ -374,16 +159,6 @@ guint32 camel_folder_summary_get_visible_count
void camel_folder_summary_set_index (CamelFolderSummary *summary,
CamelIndex *index);
CamelIndex * camel_folder_summary_get_index (CamelFolderSummary *summary);
-void camel_folder_summary_set_build_content
- (CamelFolderSummary *summary,
- gboolean state);
-gboolean camel_folder_summary_get_build_content
- (CamelFolderSummary *summary);
-void camel_folder_summary_set_need_preview
- (CamelFolderSummary *summary,
- gboolean preview);
-gboolean camel_folder_summary_get_need_preview
- (CamelFolderSummary *summary);
guint32 camel_folder_summary_next_uid (CamelFolderSummary *summary);
void camel_folder_summary_set_next_uid
(CamelFolderSummary *summary,
@@ -393,20 +168,19 @@ guint32 camel_folder_summary_get_next_uid
gchar * camel_folder_summary_next_uid_string
(CamelFolderSummary *summary);
-/* load/save the full summary from/to the db */
-gboolean camel_folder_summary_save_to_db (CamelFolderSummary *summary,
+/* load/save the full summary */
+gboolean camel_folder_summary_save (CamelFolderSummary *summary,
GError **error);
-gboolean camel_folder_summary_load_from_db
- (CamelFolderSummary *summary,
+gboolean camel_folder_summary_load (CamelFolderSummary *summary,
GError **error);
/* only load the header */
-gboolean camel_folder_summary_header_load_from_db
+gboolean camel_folder_summary_header_load
(CamelFolderSummary *summary,
struct _CamelStore *store,
const gchar *folder_name,
GError **error);
-gboolean camel_folder_summary_header_save_to_db
+gboolean camel_folder_summary_header_save
(CamelFolderSummary *summary,
GError **error);
@@ -415,9 +189,9 @@ void camel_folder_summary_touch (CamelFolderSummary *summary);
/* Just build raw summary items */
CamelMessageInfo *
- camel_folder_summary_info_new_from_header
+ camel_folder_summary_info_new_from_headers
(CamelFolderSummary *summary,
- struct _camel_header_raw *headers);
+ const CamelNameValueArray *headers);
CamelMessageInfo *
camel_folder_summary_info_new_from_parser
(CamelFolderSummary *summary,
@@ -425,35 +199,20 @@ CamelMessageInfo *
CamelMessageInfo *
camel_folder_summary_info_new_from_message
(CamelFolderSummary *summary,
- CamelMimeMessage *message,
- const gchar *bodystructure);
-
-CamelMessageContentInfo *
- camel_folder_summary_content_info_new
- (CamelFolderSummary *summary);
-void camel_folder_summary_content_info_free
- (CamelFolderSummary *summary,
- CamelMessageContentInfo *ci);
-
-void camel_folder_summary_add_preview
- (CamelFolderSummary *summary,
- CamelMessageInfo *info);
+ CamelMimeMessage *message);
/* add a new raw summary item */
void camel_folder_summary_add (CamelFolderSummary *summary,
- CamelMessageInfo *info);
-
-/* insert mi to summary */
-void camel_folder_summary_insert (CamelFolderSummary *summary,
CamelMessageInfo *info,
- gboolean load);
+ gboolean force_keep_uid);
gboolean camel_folder_summary_remove (CamelFolderSummary *summary,
CamelMessageInfo *info);
gboolean camel_folder_summary_remove_uid (CamelFolderSummary *summary,
const gchar *uid);
-gboolean camel_folder_summary_remove_uids (CamelFolderSummary *summary,
+gboolean camel_folder_summary_remove_uids
+ (CamelFolderSummary *summary,
GList *uids);
/* remove all items */
@@ -499,134 +258,15 @@ void camel_folder_summary_prepare_fetch_all
void camel_folder_summary_lock (CamelFolderSummary *summary);
void camel_folder_summary_unlock (CamelFolderSummary *summary);
-/* message flag operations */
-gboolean camel_flag_get (CamelFlag **list,
- const gchar *name);
-gboolean camel_flag_set (CamelFlag **list,
- const gchar *name,
- gboolean value);
-gboolean camel_flag_list_copy (CamelFlag **to,
- CamelFlag **from);
-gint camel_flag_list_size (CamelFlag **list);
-void camel_flag_list_free (CamelFlag **list);
-
CamelMessageFlags
camel_system_flag (const gchar *name);
gboolean camel_system_flag_get (CamelMessageFlags flags,
const gchar *name);
-/* message tag operations */
-const gchar * camel_tag_get (CamelTag **list,
- const gchar *name);
-gboolean camel_tag_set (CamelTag **list,
- const gchar *name,
- const gchar *value);
-gboolean camel_tag_list_copy (CamelTag **to,
- CamelTag **from);
-gint camel_tag_list_size (CamelTag **list);
-void camel_tag_list_free (CamelTag **list);
-
-/* Summary may be null */
-/* Use anonymous pointers to avoid tons of cast crap */
-GType camel_message_info_get_type (void) G_GNUC_CONST;
-gpointer camel_message_info_new (CamelFolderSummary *summary);
-gpointer camel_message_info_ref (gpointer info);
CamelMessageInfo *
- camel_message_info_new_from_header
+ camel_message_info_new_from_headers
(CamelFolderSummary *summary,
- struct _camel_header_raw *header);
-void camel_message_info_unref (gpointer info);
-gpointer camel_message_info_clone (gconstpointer info);
-
-/* These will be fully removed soon, left only for a backward compatibility */
-#define camel_message_info_ptr camel_message_info_get_ptr
-#define camel_message_info_uint32 camel_message_info_get_uint32
-#define camel_message_info_time camel_message_info_get_time
-#define camel_message_info_uid camel_message_info_get_uid
-#define camel_message_info_subject camel_message_info_get_subject
-#define camel_message_info_preview camel_message_info_get_preview
-#define camel_message_info_from camel_message_info_get_from
-#define camel_message_info_to camel_message_info_get_to
-#define camel_message_info_cc camel_message_info_get_cc
-#define camel_message_info_mlist camel_message_info_get_mlist
-#define camel_message_info_flags camel_message_info_get_flags
-#define camel_message_info_size camel_message_info_get_size
-#define camel_message_info_date_sent camel_message_info_get_date_sent
-#define camel_message_info_date_received camel_message_info_get_date_received
-#define camel_message_info_message_id camel_message_info_get_message_id
-#define camel_message_info_references camel_message_info_get_references
-#define camel_message_info_user_flags camel_message_info_get_user_flags
-#define camel_message_info_user_tags camel_message_info_get_user_tags
-#define camel_message_info_headers camel_message_info_get_headers
-#define camel_message_info_content camel_message_info_get_content
-#define camel_message_info_user_flag camel_message_info_get_user_flag
-#define camel_message_info_user_tag camel_message_info_get_user_tag
-
-/* accessors */
-gconstpointer camel_message_info_get_ptr (gconstpointer info,
- gint id);
-guint32 camel_message_info_get_uint32 (gconstpointer info,
- gint id);
-time_t camel_message_info_get_time (gconstpointer info,
- gint id);
-
-const gchar * camel_message_info_get_uid (gconstpointer info);
-const gchar * camel_message_info_get_subject (gconstpointer info);
-const gchar * camel_message_info_get_preview (gconstpointer info);
-const gchar * camel_message_info_get_from (gconstpointer info);
-const gchar * camel_message_info_get_to (gconstpointer info);
-
-const gchar * camel_message_info_get_cc (gconstpointer info);
-const gchar * camel_message_info_get_mlist (gconstpointer info);
-guint32 camel_message_info_get_flags (gconstpointer info);
-guint32 camel_message_info_get_size (gconstpointer info);
-
-time_t camel_message_info_get_date_sent
- (gconstpointer info);
-time_t camel_message_info_get_date_received
- (gconstpointer info);
-
-const CamelSummaryMessageID *
- camel_message_info_get_message_id
- (gconstpointer info);
-const CamelSummaryReferences *
- camel_message_info_get_references
- (gconstpointer info);
-const CamelFlag *
- camel_message_info_get_user_flags
- (gconstpointer info);
-const CamelTag *
- camel_message_info_get_user_tags
- (gconstpointer info);
-const CamelHeaderParam *
- camel_message_info_get_headers (gconstpointer info);
-const CamelMessageContentInfo *
- camel_message_info_get_content (gconstpointer info);
-gboolean camel_message_info_get_user_flag(gconstpointer info,
- const gchar *id);
-const gchar * camel_message_info_get_user_tag (gconstpointer info,
- const gchar *id);
-
-gboolean camel_message_info_set_flags (CamelMessageInfo *info,
- CamelMessageFlags flags,
- guint32 set);
-gboolean camel_message_info_set_user_flag
- (CamelMessageInfo *info,
- const gchar *id,
- gboolean state);
-gboolean camel_message_info_set_user_tag (CamelMessageInfo *info,
- const gchar *id,
- const gchar *val);
-
-/* debugging functions */
-void camel_content_info_dump (CamelMessageContentInfo *ci,
- gint depth);
-void camel_message_info_dump (CamelMessageInfo *info);
-
-/* utility functions for bdata string decomposition */
-gint bdata_extract_digit (gchar **part);
-gchar * bdata_extract_string (gchar **part);
-
+ const CamelNameValueArray *headers);
G_END_DECLS
#endif /* CAMEL_FOLDER_SUMMARY_H */
diff --git a/src/camel/camel-folder-thread.c b/src/camel/camel-folder-thread.c
index 9ff205d..1d6c53d 100644
--- a/src/camel/camel-folder-thread.c
+++ b/src/camel/camel-folder-thread.c
@@ -367,12 +367,16 @@ dump_tree_rec (struct _tree_info *info,
g_hash_table_insert (info->visited, c, c);
}
if (c->message) {
+ CamelSummaryMessageID message_id;
+
+ message_id.id.id = camel_message_info_get_message_id (c->message);
+
printf (
"%*s %p Subject: %s <%08x%08x>\n",
indent, "", (gpointer) c,
camel_message_info_get_subject (c->message),
- camel_message_info_get_message_id (c->message)->id.part.hi,
- camel_message_info_get_message_id (c->message)->id.part.lo);
+ message_id.id.part.hi,
+ message_id.id.part.lo);
count += 1;
} else {
printf ("%*s %p <empty>\n", indent, "", (gpointer) c);
@@ -461,18 +465,18 @@ sort_thread (CamelFolderThreadNode **cp)
}
static guint
-id_hash (gpointer key)
+id_hash (gconstpointer key)
{
- CamelSummaryMessageID *id = (CamelSummaryMessageID *) key;
+ const CamelSummaryMessageID *id = key;
return id->id.part.lo;
}
-static gint
-id_equal (gpointer a,
- gpointer b)
+static gboolean
+id_equal (gconstpointer a,
+ gconstpointer b)
{
- return ((CamelSummaryMessageID *) a)->id.id == ((CamelSummaryMessageID *) b)->id.id;
+ return ((const CamelSummaryMessageID *) a)->id.id == ((const CamelSummaryMessageID *) b)->id.id;
}
/* perform actual threading */
@@ -490,15 +494,20 @@ thread_summary (CamelFolderThread *thread,
gettimeofday (&start, NULL);
#endif
- id_table = g_hash_table_new ((GHashFunc) id_hash, (GCompareFunc) id_equal);
+ id_table = g_hash_table_new_full (id_hash, id_equal, g_free, NULL);
no_id_table = g_hash_table_new (NULL, NULL);
for (i = 0; i < summary->len; i++) {
CamelMessageInfo *mi = summary->pdata[i];
- const CamelSummaryMessageID *mid = camel_message_info_get_message_id (mi);
- const CamelSummaryReferences *references = camel_message_info_get_references (mi);
+ CamelSummaryMessageID *message_id_copy, message_id;
+ const GArray *references;
+
+ camel_message_info_property_lock (mi);
- if (mid != NULL && mid->id.id) {
- c = g_hash_table_lookup (id_table, mid);
+ message_id.id.id = camel_message_info_get_message_id (mi);
+ references = camel_message_info_get_references (mi);
+
+ if (message_id.id.id) {
+ c = g_hash_table_lookup (id_table, &message_id);
/* check for duplicate messages */
if (c && c->order) {
/* if duplicate, just make out it is a no-id message, but try and insert it
@@ -507,9 +516,11 @@ thread_summary (CamelFolderThread *thread,
c = camel_memchunk_alloc0 (thread->node_chunks);
g_hash_table_insert (no_id_table, (gpointer) mi, c);
} else if (!c) {
- d (printf ("doing : %08x%08x (%s)\n", mid->id.part.hi, mid->id.part.lo,
camel_message_info_get_subject (mi)));
+ d (printf ("doing : %08x%08x (%s)\n", message_id.id.part.hi,
message_id.id.part.lo, camel_message_info_get_subject (mi)));
c = camel_memchunk_alloc0 (thread->node_chunks);
- g_hash_table_insert (id_table, (gpointer) mid, c);
+ message_id_copy = g_new0 (CamelSummaryMessageID, 1);
+ message_id_copy->id.id = message_id.id.id;
+ g_hash_table_insert (id_table, message_id_copy, c);
}
} else {
d (printf ("doing : (no message id)\n"));
@@ -521,21 +532,26 @@ thread_summary (CamelFolderThread *thread,
c->order = i + 1;
child = c;
if (references) {
- gint j;
+ guint jj;
d (printf ("%s (%s) references:\n", G_STRLOC, G_STRFUNC); )
- for (j = 0; j < references->size; j++) {
+
+ for (jj = 0; jj < references->len; jj++) {
gboolean found = FALSE;
+ message_id.id.id = g_array_index (references, guint64, jj);
+
/* should never be empty, but just incase */
- if (references->references[j].id.id == 0)
+ if (!message_id.id.id)
continue;
- c = g_hash_table_lookup (id_table, &references->references[j]);
+ c = g_hash_table_lookup (id_table, &message_id);
if (c == NULL) {
d (printf ("%s (%s) not found\n", G_STRLOC, G_STRFUNC));
c = camel_memchunk_alloc0 (thread->node_chunks);
- g_hash_table_insert (id_table, (gpointer) &references->references[j],
c);
+ message_id_copy = g_new0 (CamelSummaryMessageID, 1);
+ message_id_copy->id.id = message_id.id.id;
+ g_hash_table_insert (id_table, message_id_copy, c);
} else
found = TRUE;
if (c != child) {
@@ -549,6 +565,8 @@ thread_summary (CamelFolderThread *thread,
child = c;
}
}
+
+ camel_message_info_property_unlock (mi);
}
d (printf ("\n\n"));
@@ -631,7 +649,7 @@ thread_summary (CamelFolderThread *thread,
}
/**
- * camel_folder_thread_messages_new:
+ * camel_folder_thread_messages_new: (skip)
* @folder:
* @uids: (element-type utf8): The subset of uid's to thread. If NULL. then thread all
* uid's in @folder.
@@ -666,12 +684,12 @@ camel_folder_thread_messages_new (CamelFolder *folder,
thread->node_chunks = camel_memchunk_new (32, sizeof (CamelFolderThreadNode));
thread->folder = g_object_ref (folder);
- camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary (folder), NULL);
thread->summary = summary = g_ptr_array_new ();
/* prefer given order from the summary order */
if (!uids) {
- fsummary = camel_folder_summary_get_array (folder->summary);
+ fsummary = camel_folder_summary_get_array (camel_folder_get_folder_summary (folder));
uids = fsummary;
}
@@ -712,7 +730,7 @@ add_present_rec (CamelFolderThread *thread,
g_hash_table_remove (have, uid);
g_ptr_array_add (summary, info);
} else {
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
if (node->child)
@@ -781,7 +799,7 @@ camel_folder_thread_messages_unref (CamelFolderThread *thread)
gint i;
for (i = 0; i < thread->summary->len; i++)
- camel_message_info_unref (thread->summary->pdata[i]);
+ g_clear_object (&thread->summary->pdata[i]);
g_ptr_array_free (thread->summary, TRUE);
g_object_unref (thread->folder);
}
diff --git a/src/camel/camel-folder.c b/src/camel/camel-folder.c
index 2b08478..460da61 100644
--- a/src/camel/camel-folder.c
+++ b/src/camel/camel-folder.c
@@ -50,6 +50,9 @@ typedef struct _SignalClosure SignalClosure;
typedef struct _FolderFilterData FolderFilterData;
struct _CamelFolderPrivate {
+ CamelFolderSummary *summary;
+ CamelFolderFlags folder_flags;
+
GRecMutex lock;
GMutex change_lock;
/* must require the 'change_lock' to access this */
@@ -135,7 +138,7 @@ async_context_free (AsyncContext *async_context)
g_object_unref (async_context->message);
if (async_context->info != NULL)
- camel_message_info_unref (async_context->info);
+ g_clear_object (&async_context->info);
if (async_context->destination != NULL)
g_object_unref (async_context->destination);
@@ -247,7 +250,7 @@ folder_filter_data_free_thread (gpointer user_data)
camel_folder_free_deep (data->folder, data->notjunk);
/* XXX Too late to pass a GError here. */
- camel_folder_summary_save_to_db (data->folder->summary, NULL);
+ camel_folder_summary_save (camel_folder_get_folder_summary (data->folder), NULL);
camel_folder_thaw (data->folder);
g_object_unref (data->folder);
@@ -294,23 +297,23 @@ folder_filter (CamelSession *session,
/* Reset junk learn flag so that we don't process it again */
if (data->junk) {
for (i = 0; i < data->junk->len; i++) {
- info = camel_folder_summary_get (data->folder->summary, data->junk->pdata[i]);
+ info = camel_folder_summary_get (camel_folder_get_folder_summary (data->folder),
data->junk->pdata[i]);
if (!info)
continue;
camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK_LEARN, 0);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
}
if (data->notjunk) {
for (i = 0; i < data->notjunk->len; i++) {
- info = camel_folder_summary_get (data->folder->summary, data->notjunk->pdata[i]);
+ info = camel_folder_summary_get (camel_folder_get_folder_summary (data->folder),
data->notjunk->pdata[i]);
if (!info)
continue;
camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK_LEARN, 0);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
}
@@ -444,7 +447,7 @@ folder_filter (CamelSession *session,
data->driver, NULL, info, uid, data->folder,
store_uid, store_uid, cancellable, error);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
camel_operation_pop_message (cancellable);
@@ -482,6 +485,7 @@ folder_transfer_message_to (CamelFolder *source,
{
CamelMimeMessage *msg;
CamelMessageInfo *minfo, *info;
+ guint32 source_folder_flags;
GError *local_error = NULL;
/* Default implementation. */
@@ -490,19 +494,24 @@ folder_transfer_message_to (CamelFolder *source,
if (!msg)
return;
+ source_folder_flags = camel_folder_get_flags (source);
+
/* if its deleted we poke the flags, so we need to copy the messageinfo */
- if ((source->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY)
- && (minfo = camel_folder_get_message_info (source, uid))) {
- info = camel_message_info_clone (minfo);
- camel_message_info_unref (minfo);
- } else
- info = camel_message_info_new_from_header (NULL, ((CamelMimePart *) msg)->headers);
+ if ((source_folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY)
+ && (minfo = camel_folder_get_message_info (source, uid))) {
+ info = camel_message_info_clone (minfo, NULL);
+ g_clear_object (&minfo);
+ } else {
+ const CamelNameValueArray *headers = camel_medium_get_headers (CAMEL_MEDIUM (msg));
+
+ info = camel_message_info_new_from_headers (NULL, headers);
+ }
/* unset deleted flag when transferring from trash folder */
- if ((source->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0)
+ if ((source_folder_flags & CAMEL_FOLDER_IS_TRASH) != 0)
camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0);
/* unset junk flag when transferring from junk folder */
- if ((source->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0)
+ if ((source_folder_flags & CAMEL_FOLDER_IS_JUNK) != 0)
camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK, 0);
camel_folder_append_message_sync (
@@ -517,7 +526,7 @@ folder_transfer_message_to (CamelFolder *source,
source, uid, CAMEL_MESSAGE_DELETED |
CAMEL_MESSAGE_SEEN, ~0);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
static gboolean
@@ -664,10 +673,7 @@ folder_dispose (GObject *object)
folder->priv->parent_store = NULL;
}
- if (folder->summary) {
- g_object_unref (folder->summary);
- folder->summary = NULL;
- }
+ g_clear_object (&folder->priv->summary);
/* Chain up to parent's dispose () method. */
G_OBJECT_CLASS (camel_folder_parent_class)->dispose (object);
@@ -701,32 +707,32 @@ folder_finalize (GObject *object)
static gint
folder_get_message_count (CamelFolder *folder)
{
- g_return_val_if_fail (folder->summary != NULL, -1);
+ g_return_val_if_fail (folder->priv->summary != NULL, -1);
- return camel_folder_summary_count (folder->summary);
+ return camel_folder_summary_count (folder->priv->summary);
}
-static CamelMessageFlags
+static guint32
folder_get_permanent_flags (CamelFolder *folder)
{
- return folder->permanent_flags;
+ return 0;
}
-static CamelMessageFlags
+static guint32
folder_get_message_flags (CamelFolder *folder,
const gchar *uid)
{
CamelMessageInfo *info;
- CamelMessageFlags flags;
+ guint32 flags;
- g_return_val_if_fail (folder->summary != NULL, 0);
+ g_return_val_if_fail (folder->priv->summary != NULL, 0);
- info = camel_folder_summary_get (folder->summary, uid);
+ info = camel_folder_summary_get (folder->priv->summary, uid);
if (info == NULL)
return 0;
flags = camel_message_info_get_flags (info);
- camel_message_info_unref (info);
+ g_clear_object (&info);
return flags;
}
@@ -734,20 +740,20 @@ folder_get_message_flags (CamelFolder *folder,
static gboolean
folder_set_message_flags (CamelFolder *folder,
const gchar *uid,
- CamelMessageFlags flags,
- CamelMessageFlags set)
+ guint32 mask,
+ guint32 set)
{
CamelMessageInfo *info;
gint res;
- g_return_val_if_fail (folder->summary != NULL, FALSE);
+ g_return_val_if_fail (folder->priv->summary != NULL, FALSE);
- info = camel_folder_summary_get (folder->summary, uid);
+ info = camel_folder_summary_get (folder->priv->summary, uid);
if (info == NULL)
return FALSE;
- res = camel_message_info_set_flags (info, flags, set);
- camel_message_info_unref (info);
+ res = camel_message_info_set_flags (info, mask, set);
+ g_clear_object (&info);
return res;
}
@@ -760,14 +766,14 @@ folder_get_message_user_flag (CamelFolder *folder,
CamelMessageInfo *info;
gboolean ret;
- g_return_val_if_fail (folder->summary != NULL, FALSE);
+ g_return_val_if_fail (folder->priv->summary != NULL, FALSE);
- info = camel_folder_summary_get (folder->summary, uid);
+ info = camel_folder_summary_get (folder->priv->summary, uid);
if (info == NULL)
return FALSE;
ret = camel_message_info_get_user_flag (info, name);
- camel_message_info_unref (info);
+ g_clear_object (&info);
return ret;
}
@@ -780,14 +786,14 @@ folder_set_message_user_flag (CamelFolder *folder,
{
CamelMessageInfo *info;
- g_return_if_fail (folder->summary != NULL);
+ g_return_if_fail (folder->priv->summary != NULL);
- info = camel_folder_summary_get (folder->summary, uid);
+ info = camel_folder_summary_get (folder->priv->summary, uid);
if (info == NULL)
return;
camel_message_info_set_user_flag (info, name, value);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
static const gchar *
@@ -798,14 +804,14 @@ folder_get_message_user_tag (CamelFolder *folder,
CamelMessageInfo *info;
const gchar *ret;
- g_return_val_if_fail (folder->summary != NULL, NULL);
+ g_return_val_if_fail (folder->priv->summary != NULL, NULL);
- info = camel_folder_summary_get (folder->summary, uid);
+ info = camel_folder_summary_get (folder->priv->summary, uid);
if (info == NULL)
return NULL;
ret = camel_message_info_get_user_tag (info, name);
- camel_message_info_unref (info);
+ g_clear_object (&info);
return ret;
}
@@ -818,22 +824,22 @@ folder_set_message_user_tag (CamelFolder *folder,
{
CamelMessageInfo *info;
- g_return_if_fail (folder->summary != NULL);
+ g_return_if_fail (folder->priv->summary != NULL);
- info = camel_folder_summary_get (folder->summary, uid);
+ info = camel_folder_summary_get (folder->priv->summary, uid);
if (info == NULL)
return;
camel_message_info_set_user_tag (info, name, value);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
static GPtrArray *
folder_get_uids (CamelFolder *folder)
{
- g_return_val_if_fail (folder->summary != NULL, NULL);
+ g_return_val_if_fail (folder->priv->summary != NULL, NULL);
- return camel_folder_summary_get_array (folder->summary);
+ return camel_folder_summary_get_array (folder->priv->summary);
}
static GPtrArray *
@@ -884,9 +890,9 @@ folder_sort_uids (CamelFolder *folder,
static GPtrArray *
folder_get_summary (CamelFolder *folder)
{
- g_return_val_if_fail (folder->summary != NULL, NULL);
+ g_return_val_if_fail (folder->priv->summary != NULL, NULL);
- return camel_folder_summary_get_array (folder->summary);
+ return camel_folder_summary_get_array (folder->priv->summary);
}
static void
@@ -911,16 +917,16 @@ static CamelMessageInfo *
folder_get_message_info (CamelFolder *folder,
const gchar *uid)
{
- g_return_val_if_fail (folder->summary != NULL, NULL);
+ g_return_val_if_fail (folder->priv->summary != NULL, NULL);
- return camel_folder_summary_get (folder->summary, uid);
+ return camel_folder_summary_get (folder->priv->summary, uid);
}
static void
folder_delete (CamelFolder *folder)
{
- if (folder->summary)
- camel_folder_summary_clear (folder->summary, NULL);
+ if (folder->priv->summary)
+ camel_folder_summary_clear (folder->priv->summary, NULL);
}
static void
@@ -945,8 +951,8 @@ folder_freeze (CamelFolder *folder)
g_mutex_lock (&folder->priv->change_lock);
folder->priv->frozen++;
- if (folder->summary)
- g_object_freeze_notify (G_OBJECT (folder->summary));
+ if (folder->priv->summary)
+ g_object_freeze_notify (G_OBJECT (folder->priv->summary));
d (printf ("freeze (%p '%s') = %d\n", folder, folder->full_name, folder->priv->frozen));
g_mutex_unlock (&folder->priv->change_lock);
@@ -962,8 +968,8 @@ folder_thaw (CamelFolder *folder)
g_mutex_lock (&folder->priv->change_lock);
folder->priv->frozen--;
- if (folder->summary)
- g_object_thaw_notify (G_OBJECT (folder->summary));
+ if (folder->priv->summary)
+ g_object_thaw_notify (G_OBJECT (folder->priv->summary));
d (printf ("thaw (%p '%s') = %d\n", folder, folder->full_name, folder->priv->frozen));
@@ -979,8 +985,8 @@ folder_thaw (CamelFolder *folder)
camel_folder_changed (folder, info);
camel_folder_change_info_free (info);
- if (folder->summary)
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ if (folder->priv->summary)
+ camel_folder_summary_save (folder->priv->summary, NULL);
}
}
@@ -1113,10 +1119,10 @@ folder_changed (CamelFolder *folder,
junk_filter = camel_session_get_junk_filter (session);
if (junk_filter != NULL && info->uid_changed->len) {
- CamelMessageFlags flags;
+ guint32 flags;
for (i = 0; i < info->uid_changed->len; i++) {
- flags = camel_folder_summary_get_info_flags (folder->summary,
info->uid_changed->pdata[i]);
+ flags = camel_folder_summary_get_info_flags (folder->priv->summary,
info->uid_changed->pdata[i]);
if (flags != (~0) && (flags & CAMEL_MESSAGE_JUNK_LEARN) != 0) {
if (flags & CAMEL_MESSAGE_JUNK) {
if (!junk)
@@ -1133,11 +1139,11 @@ folder_changed (CamelFolder *folder,
}
}
- if ((folder->folder_flags & (CAMEL_FOLDER_FILTER_RECENT | CAMEL_FOLDER_FILTER_JUNK))
+ if ((camel_folder_get_flags (folder) & (CAMEL_FOLDER_FILTER_RECENT | CAMEL_FOLDER_FILTER_JUNK))
&& p->uid_filter->len > 0)
driver = camel_session_get_filter_driver (
session,
- (folder->folder_flags & CAMEL_FOLDER_FILTER_RECENT)
+ (camel_folder_get_flags (folder) & CAMEL_FOLDER_FILTER_RECENT)
? "incoming" : "junktest", NULL);
if (driver) {
@@ -1294,6 +1300,7 @@ camel_folder_class_init (CamelFolderClass *class)
/**
* CamelFolder::changed
* @folder: the #CamelFolder which emitted the signal
+ * @changes: the #CamelFolderChangeInfo with the list of changes
**/
signals[CHANGED] = g_signal_new (
"changed",
@@ -1302,7 +1309,7 @@ camel_folder_class_init (CamelFolderClass *class)
G_STRUCT_OFFSET (CamelFolderClass, changed),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+ CAMEL_TYPE_FOLDER_CHANGE_INFO);
/**
* CamelFolder::deleted
@@ -1644,6 +1651,46 @@ camel_folder_get_parent_store (CamelFolder *folder)
}
/**
+ * camel_folder_get_folder_summary:
+ * @folder: a #CamelFolder
+ *
+ * Returns: (transfer none): a #CamelFolderSummary of the folder
+ *
+ * Since: 3.24
+ **/
+CamelFolderSummary *
+camel_folder_get_folder_summary (CamelFolder *folder)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+
+ return folder->priv->summary;
+}
+
+/**
+ * camel_folder_take_folder_summary:
+ * @folder: a #CamelFolder
+ * @summary: (transfer full): a #CamelFolderSummary
+ *
+ * Sets a #CamelFolderSummary of the folder. It consumes the @summary.
+ *
+ * This is supposed to be called only by the descendants of
+ * the #CamelFolder and only at the construction time. Calling
+ * this function twice yeilds to an error.
+ *
+ * Since: 3.24
+ **/
+void
+camel_folder_take_folder_summary (CamelFolder *folder,
+ CamelFolderSummary *summary)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
+ g_return_if_fail (folder->priv->summary == NULL);
+
+ folder->priv->summary = summary;
+}
+
+/**
* camel_folder_get_message_count:
* @folder: a #CamelFolder
*
@@ -1675,9 +1722,9 @@ gint
camel_folder_get_unread_message_count (CamelFolder *folder)
{
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
- g_return_val_if_fail (folder->summary != NULL, -1);
+ g_return_val_if_fail (folder->priv->summary != NULL, -1);
- return camel_folder_summary_get_unread_count (folder->summary);
+ return camel_folder_summary_get_unread_count (folder->priv->summary);
}
/**
@@ -1691,9 +1738,43 @@ gint
camel_folder_get_deleted_message_count (CamelFolder *folder)
{
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
- g_return_val_if_fail (folder->summary != NULL, -1);
+ g_return_val_if_fail (folder->priv->summary != NULL, -1);
+
+ return camel_folder_summary_get_deleted_count (folder->priv->summary);
+}
- return camel_folder_summary_get_deleted_count (folder->summary);
+/**
+ * camel_folder_get_flags:
+ * @folder: a #CamelFolder
+ *
+ * Returns: Folder flags (bit-or of #CamelFolderFlags) of the @folder
+ *
+ * Since: 3.24
+ **/
+guint32
+camel_folder_get_flags (CamelFolder *folder)
+{
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0);
+
+ return folder->priv->folder_flags;
+}
+
+/**
+ * camel_folder_set_flags:
+ * @folder: a #CamelFolder
+ * @folder_flags: flags (bit-or of #CamelFolderFlags) to set
+ *
+ * Sets folder flags (bit-or of #CamelFolderFlags) for the @folder.
+ *
+ * Since: 3.24
+ **/
+void
+camel_folder_set_flags (CamelFolder *folder,
+ guint32 folder_flags)
+{
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+ folder->priv->folder_flags = folder_flags;
}
/**
@@ -1704,7 +1785,7 @@ camel_folder_get_deleted_message_count (CamelFolder *folder)
* stored on a message between sessions. If it includes
* #CAMEL_FLAG_USER, then user-defined flags will be remembered.
**/
-CamelMessageFlags
+guint32
camel_folder_get_permanent_flags (CamelFolder *folder)
{
CamelFolderClass *class;
@@ -1727,7 +1808,7 @@ camel_folder_get_permanent_flags (CamelFolder *folder)
* Returns: the #CamelMessageFlags that are set on the indicated
* message.
**/
-CamelMessageFlags
+guint32
camel_folder_get_message_flags (CamelFolder *folder,
const gchar *uid)
{
@@ -1746,10 +1827,10 @@ camel_folder_get_message_flags (CamelFolder *folder,
* camel_folder_set_message_flags:
* @folder: a #CamelFolder
* @uid: the UID of a message in @folder
- * @flags: a set of #CamelMessageFlag values to set
- * @set: the mask of values in @flags to use.
+ * @mask: a mask of #CamelMessageFlag bit-or values to use
+ * @set: the flags to ser, also bit-or of #CamelMessageFlag
*
- * Sets those flags specified by @flags to the values specified by @set
+ * Sets those flags specified by @mask to the values specified by @set
* on the indicated message. (This may or may not persist after the
* folder or store is closed. See camel_folder_get_permanent_flags())
*
@@ -1764,8 +1845,8 @@ camel_folder_get_message_flags (CamelFolder *folder,
gboolean
camel_folder_set_message_flags (CamelFolder *folder,
const gchar *uid,
- CamelMessageFlags flags,
- CamelMessageFlags set)
+ guint32 mask,
+ guint32 set)
{
CamelFolderClass *class;
@@ -1775,12 +1856,7 @@ camel_folder_set_message_flags (CamelFolder *folder,
class = CAMEL_FOLDER_GET_CLASS (folder);
g_return_val_if_fail (class->set_message_flags != NULL, FALSE);
- if ((flags & (CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_JUNK_LEARN)) == CAMEL_MESSAGE_JUNK) {
- flags |= CAMEL_MESSAGE_JUNK_LEARN;
- set &= ~CAMEL_MESSAGE_JUNK_LEARN;
- }
-
- return class->set_message_flags (folder, uid, flags, set);
+ return class->set_message_flags (folder, uid, mask, set);
}
/**
@@ -1910,11 +1986,11 @@ camel_folder_set_message_user_tag (CamelFolder *folder,
* @folder: a #CamelFolder
* @uid: the uid of a message
*
- * Retrieve the #CamelMessageInfo for the specified @uid. This return
- * must be freed using camel_message_info_unref().
+ * Retrieve the #CamelMessageInfo for the specified @uid.
*
- * Returns: the summary information for the indicated message, or %NULL
- * if the uid does not exist
+ * Returns: (transfer full): The summary information for the indicated message, or %NULL
+ * if the uid does not exist. Free the returned object with g_object_unref(),
+ * when done with it.
**/
CamelMessageInfo *
camel_folder_get_message_info (CamelFolder *folder,
@@ -1945,7 +2021,7 @@ camel_folder_has_summary_capability (CamelFolder *folder)
{
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
- return folder->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY;
+ return (camel_folder_get_flags (folder) & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY) != 0;
}
/* UIDs stuff */
@@ -2093,7 +2169,7 @@ camel_folder_sort_uids (CamelFolder *folder,
* should not be modified, and must be freed with
* camel_folder_free_summary().
*
- * Returns: (element-type CamelMessageInfo) (transfer none): an array of #CamelMessageInfo
+ * Returns: (element-type utf8) (transfer none): an array of UID-s of #CamelMessageInfo
**/
GPtrArray *
camel_folder_get_summary (CamelFolder *folder)
@@ -2283,12 +2359,12 @@ camel_folder_delete (CamelFolder *folder)
g_return_if_fail (class->delete_ != NULL);
camel_folder_lock (folder);
- if (folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
+ if (camel_folder_get_flags (folder) & CAMEL_FOLDER_HAS_BEEN_DELETED) {
camel_folder_unlock (folder);
return;
}
- folder->folder_flags |= CAMEL_FOLDER_HAS_BEEN_DELETED;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) | CAMEL_FOLDER_HAS_BEEN_DELETED);
class->delete_ (folder);
@@ -2297,7 +2373,7 @@ camel_folder_delete (CamelFolder *folder)
/* Delete the references of the folder from the DB.*/
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
- camel_db_delete_folder (parent_store->cdb_w, full_name, NULL);
+ camel_db_delete_folder (camel_store_get_db (parent_store), full_name, NULL);
service = CAMEL_SERVICE (parent_store);
session = camel_service_ref_session (service);
@@ -2352,7 +2428,7 @@ camel_folder_rename (CamelFolder *folder,
class->rename (folder, new_name);
parent_store = camel_folder_get_parent_store (folder);
- camel_db_rename_folder (parent_store->cdb_w, old_name, new_name, NULL);
+ camel_db_rename_folder (camel_store_get_db (parent_store), old_name, new_name, NULL);
service = CAMEL_SERVICE (parent_store);
session = camel_service_ref_session (service);
@@ -2598,22 +2674,6 @@ camel_folder_quota_info_free (CamelFolderQuotaInfo *info)
}
/**
- * camel_folder_free_nop:
- * @folder: a #CamelFolder
- * @array: an array of uids or #CamelMessageInfo
- *
- * "Frees" the provided array by doing nothing. Used by #CamelFolder
- * subclasses as an implementation for free_uids, or free_summary when
- * the returned array is "static" information and should not be freed.
- **/
-void
-camel_folder_free_nop (CamelFolder *folder,
- GPtrArray *array)
-{
- ;
-}
-
-/**
* camel_folder_free_shallow:
* @folder: a #CamelFolder
* @array: (element-type utf8): an array of uids or #CamelMessageInfo
@@ -2807,7 +2867,7 @@ camel_folder_append_message (CamelFolder *folder,
async_context = g_slice_new0 (AsyncContext);
async_context->message = g_object_ref (message);
- async_context->info = camel_message_info_ref (info);
+ async_context->info = g_object_ref (info);
task = g_task_new (folder, cancellable, callback, user_data);
g_task_set_source_tag (task, camel_folder_append_message);
@@ -2915,7 +2975,7 @@ camel_folder_expunge_sync (CamelFolder *folder,
camel_service_get_display_name (CAMEL_SERVICE (camel_folder_get_parent_store (folder))),
camel_folder_get_full_name (folder));
- if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
+ if (!(camel_folder_get_flags (folder) & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
success = class->expunge_sync (folder, cancellable, error);
CAMEL_CHECK_GERROR (folder, expunge_sync, success, error);
@@ -3674,7 +3734,7 @@ camel_folder_synchronize_sync (CamelFolder *folder,
return FALSE;
}
- if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
+ if (!(camel_folder_get_flags (folder) & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
success = class->synchronize_sync (
folder, expunge, cancellable, error);
CAMEL_CHECK_GERROR (folder, synchronize_sync, success, error);
@@ -4175,6 +4235,8 @@ camel_folder_prepare_content_refresh (CamelFolder *folder)
klass->prepare_content_refresh (folder);
}
+G_DEFINE_BOXED_TYPE (CamelFolderChangeInfo, camel_folder_change_info, camel_folder_change_info_copy,
camel_folder_change_info_free)
+
/**
* camel_folder_change_info_new:
*
@@ -4183,7 +4245,7 @@ camel_folder_prepare_content_refresh (CamelFolder *folder)
* Change info structures are not MT-SAFE and must be
* locked for exclusive access externally.
*
- * Returns: a new #CamelFolderChangeInfo
+ * Returns: (transfer full): a new #CamelFolderChangeInfo
**/
CamelFolderChangeInfo *
camel_folder_change_info_new (void)
@@ -4205,6 +4267,30 @@ camel_folder_change_info_new (void)
}
/**
+ * camel_folder_change_info_copy:
+ * @src: a #CamelFolderChangeInfo to make copy of
+ *
+ * Creates a copy of the @src.
+ *
+ * Returns: (transfer full): Copy of the @src.
+ *
+ * Since: 3.24
+ **/
+CamelFolderChangeInfo *
+camel_folder_change_info_copy (CamelFolderChangeInfo *src)
+{
+ CamelFolderChangeInfo *copy;
+
+ if (!src)
+ return NULL;
+
+ copy = camel_folder_change_info_new ();
+ camel_folder_change_info_cat (copy, src);
+
+ return copy;
+}
+
+/**
* camel_folder_change_info_add_source:
* @info: a #CamelFolderChangeInfo
* @uid: a uid
@@ -4409,21 +4495,21 @@ change_info_cat (CamelFolderChangeInfo *info,
* @info: a #CamelFolderChangeInfo to append to
* @src: a #CamelFolderChangeInfo to append from
*
- * Concatenate one change info onto antoher. Can be used to copy them
+ * Concatenate one change info onto antoher. Can be used to copy them
* too.
**/
void
camel_folder_change_info_cat (CamelFolderChangeInfo *info,
- CamelFolderChangeInfo *source)
+ CamelFolderChangeInfo *src)
{
g_return_if_fail (info != NULL);
- g_return_if_fail (source != NULL);
+ g_return_if_fail (src != NULL);
- change_info_cat (info, source->uid_added, camel_folder_change_info_add_uid);
- change_info_cat (info, source->uid_removed, camel_folder_change_info_remove_uid);
- change_info_cat (info, source->uid_changed, camel_folder_change_info_change_uid);
- change_info_cat (info, source->uid_recent, change_info_recent_uid);
- change_info_cat (info, source->priv->uid_filter, change_info_filter_uid);
+ change_info_cat (info, src->uid_added, camel_folder_change_info_add_uid);
+ change_info_cat (info, src->uid_removed, camel_folder_change_info_remove_uid);
+ change_info_cat (info, src->uid_changed, camel_folder_change_info_change_uid);
+ change_info_cat (info, src->uid_recent, change_info_recent_uid);
+ change_info_cat (info, src->priv->uid_filter, change_info_filter_uid);
}
/**
@@ -4565,6 +4651,82 @@ camel_folder_change_info_changed (CamelFolderChangeInfo *info)
}
/**
+ * camel_folder_change_info_get_added_uids:
+ * @info: a #CamelFolderChangeInfo
+ *
+ * Returns an array of added messages UIDs. The returned array, the same as its content,
+ * is owned by the @info.
+ *
+ * Returns: (element-type utf8) (transfer none): An array of added UIDs.
+ *
+ * Since: 3.24
+ **/
+GPtrArray *
+camel_folder_change_info_get_added_uids (CamelFolderChangeInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->uid_added;
+}
+
+/**
+ * camel_folder_change_info_get_removed_uids:
+ * @info: a #CamelFolderChangeInfo
+ *
+ * Returns an array of removed messages UIDs. The returned array, the same as its content,
+ * is owned by the @info.
+ *
+ * Returns: (element-type utf8) (transfer none): An array of removed UIDs.
+ *
+ * Since: 3.24
+ **/
+GPtrArray *
+camel_folder_change_info_get_removed_uids (CamelFolderChangeInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->uid_removed;
+}
+
+/**
+ * camel_folder_change_info_get_changed_uids:
+ * @info: a #CamelFolderChangeInfo
+ *
+ * Returns an array of changed messages UIDs. The returned array, the same as its content,
+ * is owned by the @info.
+ *
+ * Returns: (element-type utf8) (transfer none): An array of changed UIDs.
+ *
+ * Since: 3.24
+ **/
+GPtrArray *
+camel_folder_change_info_get_changed_uids (CamelFolderChangeInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->uid_changed;
+}
+
+/**
+ * camel_folder_change_info_get_recent_uids:
+ * @info: a #CamelFolderChangeInfo
+ *
+ * Returns an array of recent messages UIDs. The returned array, the same as its content,
+ * is owned by the @info.
+ *
+ * Returns: (element-type utf8) (transfer none): An array of recent UIDs.
+ *
+ * Since: 3.24
+ **/
+GPtrArray *
+camel_folder_change_info_get_recent_uids (CamelFolderChangeInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->uid_recent;
+}
+
+/**
* camel_folder_change_info_clear:
* @info: a #CamelFolderChangeInfo
*
diff --git a/src/camel/camel-folder.h b/src/camel/camel-folder.h
index df2cdbb..f68a192 100644
--- a/src/camel/camel-folder.h
+++ b/src/camel/camel-folder.h
@@ -49,6 +49,8 @@
(G_TYPE_INSTANCE_GET_CLASS \
((obj), CAMEL_TYPE_FOLDER, CamelFolderClass))
+#define CAMEL_TYPE_FOLDER_CHANGE_INFO (camel_folder_change_info_get_type ())
+
/**
* CAMEL_FOLDER_ERROR:
*
@@ -100,6 +102,7 @@ struct _CamelFolderChangeInfo {
GPtrArray *uid_changed;
GPtrArray *uid_recent;
+ /*< private >*/
CamelFolderChangeInfoPrivate *priv;
};
@@ -121,14 +124,6 @@ struct _CamelFolderQuotaInfo {
struct _CamelFolder {
CamelObject parent;
CamelFolderPrivate *priv;
-
- CamelFolderSummary *summary;
-
- CamelFolderFlags folder_flags;
- CamelMessageFlags permanent_flags;
-
- /* Future ABI expansion */
- gpointer later[4];
};
struct _CamelFolderClass {
@@ -136,15 +131,13 @@ struct _CamelFolderClass {
/* Non-Blocking Methods */
gint (*get_message_count) (CamelFolder *folder);
- CamelMessageFlags
- (*get_permanent_flags) (CamelFolder *folder);
- CamelMessageFlags
- (*get_message_flags) (CamelFolder *folder,
+ guint32 (*get_permanent_flags) (CamelFolder *folder);
+ guint32 (*get_message_flags) (CamelFolder *folder,
const gchar *uid);
gboolean (*set_message_flags) (CamelFolder *folder,
const gchar *uid,
- CamelMessageFlags flags,
- CamelMessageFlags set);
+ guint32 mask,
+ guint32 set);
gboolean (*get_message_user_flag)(CamelFolder *folder,
const gchar *uid,
const gchar *name);
@@ -254,8 +247,8 @@ struct _CamelFolderClass {
void (*prepare_content_refresh)
(CamelFolder *folder);
- /* Reserved slots for methods. */
- gpointer reserved_for_methods[19];
+ /* Padding for future expansion */
+ gpointer reserved_methods[20];
/* Signals */
void (*changed) (CamelFolder *folder,
@@ -263,6 +256,9 @@ struct _CamelFolderClass {
void (*deleted) (CamelFolder *folder);
void (*renamed) (CamelFolder *folder,
const gchar *old_name);
+
+ /* Padding for future expansion */
+ gpointer reserved_signals[20];
};
GType camel_folder_get_type (void);
@@ -271,6 +267,11 @@ void camel_folder_set_lock_async (CamelFolder *folder,
gboolean skip_folder_lock);
struct _CamelStore *
camel_folder_get_parent_store (CamelFolder *folder);
+CamelFolderSummary *
+ camel_folder_get_folder_summary (CamelFolder *folder);
+void camel_folder_take_folder_summary
+ (CamelFolder *folder,
+ CamelFolderSummary *summary);
const gchar * camel_folder_get_full_name (CamelFolder *folder);
gchar * camel_folder_dup_full_name (CamelFolder *folder);
void camel_folder_set_full_name (CamelFolder *folder,
@@ -283,17 +284,18 @@ const gchar * camel_folder_get_description (CamelFolder *folder);
gchar * camel_folder_dup_description (CamelFolder *folder);
void camel_folder_set_description (CamelFolder *folder,
const gchar *description);
-CamelMessageFlags
- camel_folder_get_permanent_flags
+guint32 camel_folder_get_flags (CamelFolder *folder);
+void camel_folder_set_flags (CamelFolder *folder,
+ guint32 folder_flags);
+guint32 camel_folder_get_permanent_flags
(CamelFolder *folder);
#ifndef CAMEL_DISABLE_DEPRECATED
-CamelMessageFlags
- camel_folder_get_message_flags (CamelFolder *folder,
+guint32 camel_folder_get_message_flags (CamelFolder *folder,
const gchar *uid);
gboolean camel_folder_set_message_flags (CamelFolder *folder,
const gchar *uid,
- CamelMessageFlags flags,
- CamelMessageFlags set);
+ guint32 mask,
+ guint32 set);
gboolean camel_folder_get_message_user_flag
(CamelFolder *folder,
const gchar *uid,
@@ -380,8 +382,6 @@ CamelFolderQuotaInfo *
CamelFolderQuotaInfo *
camel_folder_quota_info_clone (const CamelFolderQuotaInfo *info);
void camel_folder_quota_info_free (CamelFolderQuotaInfo *info);
-void camel_folder_free_nop (CamelFolder *folder,
- GPtrArray *array);
void camel_folder_free_shallow (CamelFolder *folder,
GPtrArray *array);
void camel_folder_free_deep (CamelFolder *folder,
@@ -537,11 +537,23 @@ void camel_folder_prepare_content_refresh
(CamelFolder *folder);
/* update functions for change info */
+GType camel_folder_change_info_get_type
+ (void) G_GNUC_CONST;
CamelFolderChangeInfo *
camel_folder_change_info_new (void);
+CamelFolderChangeInfo *
+ camel_folder_change_info_copy (CamelFolderChangeInfo *src);
void camel_folder_change_info_clear (CamelFolderChangeInfo *info);
void camel_folder_change_info_free (CamelFolderChangeInfo *info);
gboolean camel_folder_change_info_changed (CamelFolderChangeInfo *info);
+GPtrArray * camel_folder_change_info_get_added_uids
+ (CamelFolderChangeInfo *info);
+GPtrArray * camel_folder_change_info_get_removed_uids
+ (CamelFolderChangeInfo *info);
+GPtrArray * camel_folder_change_info_get_changed_uids
+ (CamelFolderChangeInfo *info);
+GPtrArray * camel_folder_change_info_get_recent_uids
+ (CamelFolderChangeInfo *info);
/* for building diff's automatically */
void camel_folder_change_info_add_source
diff --git a/src/camel/camel-gpg-context.c b/src/camel/camel-gpg-context.c
index b539272..4194637 100644
--- a/src/camel/camel-gpg-context.c
+++ b/src/camel/camel-gpg-context.c
@@ -2082,7 +2082,7 @@ gpg_verify_sync (CamelCipherContext *context,
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
mps = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) ipart);
- ct = ((CamelDataWrapper *) mps)->mime_type;
+ ct = camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (mps));
/* Inline signature (using our fake mime type) or PGP/Mime signature */
if (camel_content_type_is (ct, "multipart", "signed")) {
diff --git a/src/camel/camel-gpg-context.h b/src/camel/camel-gpg-context.h
index 763bc23..667f74e 100644
--- a/src/camel/camel-gpg-context.h
+++ b/src/camel/camel-gpg-context.h
@@ -59,6 +59,9 @@ struct _CamelGpgContext {
struct _CamelGpgContextClass {
CamelCipherContextClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_gpg_context_get_type (void);
diff --git a/src/camel/camel-html-parser.h b/src/camel/camel-html-parser.h
index b299a4d..06d8d82 100644
--- a/src/camel/camel-html-parser.h
+++ b/src/camel/camel-html-parser.h
@@ -82,6 +82,9 @@ struct _CamelHTMLParser {
struct _CamelHTMLParserClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_html_parser_get_type (void);
diff --git a/src/camel/camel-iconv.c b/src/camel/camel-iconv.c
index ed5b2fe..723707f 100644
--- a/src/camel/camel-iconv.c
+++ b/src/camel/camel-iconv.c
@@ -369,12 +369,18 @@ flush_entry (struct _iconv_cache *ic)
g_free (ic);
}
-/* This should run pretty quick, its called a lot */
+/**
+ * camel_iconv_open: (skip)
+ * @to: charset to convert to
+ * @from: charset to covert from
+ *
+ * Returns: a #GIConv for the conversion from charset @from to charset @to, or (GIConv) -1 on error.
+ **/
GIConv
-camel_iconv_open (const gchar *oto,
- const gchar *ofrom)
+camel_iconv_open (const gchar *to,
+ const gchar *from)
{
- const gchar *to, *from;
+ const gchar *nto, *nfrom;
gchar *tofrom;
gsize tofrom_len;
struct _iconv_cache *ic;
@@ -382,16 +388,16 @@ camel_iconv_open (const gchar *oto,
gint errnosav;
GIConv ip;
- if (oto == NULL || ofrom == NULL) {
+ if (to == NULL || from == NULL) {
errno = EINVAL;
return (GIConv) -1;
}
- to = camel_iconv_charset_name (oto);
- from = camel_iconv_charset_name (ofrom);
- tofrom_len = strlen (to) + strlen (from) + 2;
+ nto = camel_iconv_charset_name (to);
+ nfrom = camel_iconv_charset_name (from);
+ tofrom_len = strlen (nto) + strlen (nfrom) + 2;
tofrom = g_alloca (tofrom_len);
- g_snprintf (tofrom, tofrom_len, "%s%%%s", to, from);
+ g_snprintf (tofrom, tofrom_len, "%s%%%s", nto, nfrom);
G_LOCK (iconv);
@@ -449,7 +455,7 @@ camel_iconv_open (const gchar *oto,
}
} else {
cd (printf ("creating new iconv converter '%s'\n", ic->conv));
- ip = g_iconv_open (to, from);
+ ip = g_iconv_open (nto, nfrom);
in = g_malloc (sizeof (*in));
in->ip = ip;
in->parent = ic;
@@ -459,7 +465,7 @@ camel_iconv_open (const gchar *oto,
in->busy = TRUE;
} else {
errnosav = errno;
- g_warning ("Could not open converter for '%s' to '%s' charset", from, to);
+ g_warning ("Could not open converter for '%s' to '%s' charset", nfrom, nto);
in->busy = FALSE;
errno = errnosav;
}
diff --git a/src/camel/camel-index.h b/src/camel/camel-index.h
index 5bec6cf..fa49ddc 100644
--- a/src/camel/camel-index.h
+++ b/src/camel/camel-index.h
@@ -94,7 +94,7 @@ typedef struct _CamelIndexCursor CamelIndexCursor;
typedef struct _CamelIndexCursorClass CamelIndexCursorClass;
typedef struct _CamelIndexCursorPrivate CamelIndexCursorPrivate;
-typedef gchar * (*CamelIndexNorm)(CamelIndex *index, const gchar *word, gpointer data);
+typedef gchar * (*CamelIndexNorm)(CamelIndex *index, const gchar *word, gpointer user_data);
/* ********************************************************************** */
@@ -109,6 +109,9 @@ struct _CamelIndexCursorClass {
GObjectClass parent;
const gchar * (*next) (CamelIndexCursor *idc);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_index_cursor_get_type (void);
diff --git a/src/camel/camel-internet-address.c b/src/camel/camel-internet-address.c
index 42f87ca..ef7ee51 100644
--- a/src/camel/camel-internet-address.c
+++ b/src/camel/camel-internet-address.c
@@ -25,6 +25,10 @@
#define d(x)
+struct _CamelInternetAddressPrivate {
+ GPtrArray *addresses;
+};
+
struct _address {
gchar *name;
gchar *address;
@@ -33,11 +37,21 @@ struct _address {
G_DEFINE_TYPE (CamelInternetAddress, camel_internet_address, CAMEL_TYPE_ADDRESS)
static gint
-internet_address_decode (CamelAddress *a,
+internet_address_length (CamelAddress *paddr)
+{
+ CamelInternetAddress *inet_addr = CAMEL_INTERNET_ADDRESS (paddr);
+
+ g_return_val_if_fail (inet_addr != NULL, -1);
+
+ return inet_addr->priv->addresses->len;
+}
+
+static gint
+internet_address_decode (CamelAddress *addr,
const gchar *raw)
{
CamelHeaderAddress *ha, *n;
- gint count = a->addresses->len;
+ gint count = camel_address_length (addr);
/* Should probably use its own decoder or something */
ha = camel_header_address_decode (raw, NULL);
@@ -45,12 +59,12 @@ internet_address_decode (CamelAddress *a,
n = ha;
while (n) {
if (n->type == CAMEL_HEADER_ADDRESS_NAME) {
- camel_internet_address_add ((CamelInternetAddress *) a, n->name, n->v.addr);
+ camel_internet_address_add ((CamelInternetAddress *) addr, n->name,
n->v.addr);
} else if (n->type == CAMEL_HEADER_ADDRESS_GROUP) {
CamelHeaderAddress *g = n->v.members;
while (g) {
if (g->type == CAMEL_HEADER_ADDRESS_NAME)
- camel_internet_address_add ((CamelInternetAddress *) a,
g->name, g->v.addr);
+ camel_internet_address_add ((CamelInternetAddress *) addr,
g->name, g->v.addr);
/* otherwise, it's an error, infact */
g = g->next;
}
@@ -60,24 +74,25 @@ internet_address_decode (CamelAddress *a,
camel_header_address_list_clear (&ha);
}
- return a->addresses->len - count;
+ return camel_address_length (addr) - count;
}
static gchar *
-internet_address_encode (CamelAddress *a)
+internet_address_encode (CamelAddress *paddr)
{
+ CamelInternetAddress *inet_addr = CAMEL_INTERNET_ADDRESS (paddr);
gint i;
GString *out;
gchar *ret;
gint len = 6; /* "From: ", assume longer of the address headers */
- if (a->addresses->len == 0)
+ if (inet_addr->priv->addresses->len == 0)
return NULL;
out = g_string_new ("");
- for (i = 0; i < a->addresses->len; i++) {
- struct _address *addr = g_ptr_array_index (a->addresses, i);
+ for (i = 0; i < inet_addr->priv->addresses->len; i++) {
+ struct _address *addr = g_ptr_array_index (inet_addr->priv->addresses, i);
gchar *enc;
if (i != 0)
@@ -95,12 +110,13 @@ internet_address_encode (CamelAddress *a)
}
static gint
-internet_address_unformat (CamelAddress *a,
+internet_address_unformat (CamelAddress *paddr,
const gchar *raw)
{
+ CamelInternetAddress *inet_addr = CAMEL_INTERNET_ADDRESS (paddr);
gchar *buffer, *p, *name, *addr;
gint c;
- gint count = a->addresses->len;
+ gint count = inet_addr->priv->addresses->len;
if (raw == NULL)
return 0;
@@ -148,7 +164,7 @@ internet_address_unformat (CamelAddress *a,
addr = g_strstrip (addr);
if (addr[0]) {
d (printf ("found address: '%s' <%s>\n", name, addr));
- camel_internet_address_add ((CamelInternetAddress *) a, name, addr);
+ camel_internet_address_add (inet_addr, name, addr);
}
name = NULL;
addr = p;
@@ -158,23 +174,24 @@ internet_address_unformat (CamelAddress *a,
g_free (buffer);
- return a->addresses->len - count;
+ return inet_addr->priv->addresses->len - count;
}
static gchar *
-internet_address_format (CamelAddress *a)
+internet_address_format (CamelAddress *paddr)
{
+ CamelInternetAddress *inet_addr = CAMEL_INTERNET_ADDRESS (paddr);
gint i;
GString *out;
gchar *ret;
- if (a->addresses->len == 0)
+ if (inet_addr->priv->addresses->len == 0)
return NULL;
out = g_string_new ("");
- for (i = 0; i < a->addresses->len; i++) {
- struct _address *addr = g_ptr_array_index (a->addresses, i);
+ for (i = 0; i < inet_addr->priv->addresses->len; i++) {
+ struct _address *addr = g_ptr_array_index (inet_addr->priv->addresses, i);
gchar *enc;
if (i != 0)
@@ -192,43 +209,69 @@ internet_address_format (CamelAddress *a)
}
static void
-internet_address_remove (CamelAddress *a,
+internet_address_remove (CamelAddress *paddr,
gint index)
{
+ CamelInternetAddress *inet_addr = CAMEL_INTERNET_ADDRESS (paddr);
struct _address *addr;
- if (index < 0 || index >= a->addresses->len)
+ if (index < 0 || index >= inet_addr->priv->addresses->len)
return;
- addr = g_ptr_array_index (a->addresses, index);
+ addr = g_ptr_array_index (inet_addr->priv->addresses, index);
g_free (addr->name);
g_free (addr->address);
g_free (addr);
- g_ptr_array_remove_index (a->addresses, index);
+ g_ptr_array_remove_index (inet_addr->priv->addresses, index);
}
static gint
internet_address_cat (CamelAddress *dest,
CamelAddress *source)
{
+ CamelInternetAddress *dest_inet_addr;
+ CamelInternetAddress *source_inet_addr;
gint i;
+ g_return_val_if_fail (CAMEL_IS_INTERNET_ADDRESS (dest), -1);
g_return_val_if_fail (CAMEL_IS_INTERNET_ADDRESS (source), -1);
- for (i = 0; i < source->addresses->len; i++) {
- struct _address *addr = g_ptr_array_index (source->addresses, i);
- camel_internet_address_add ((CamelInternetAddress *) dest, addr->name, addr->address);
+ dest_inet_addr = CAMEL_INTERNET_ADDRESS (dest);
+ source_inet_addr = CAMEL_INTERNET_ADDRESS (source);
+
+ for (i = 0; i < source_inet_addr->priv->addresses->len; i++) {
+ struct _address *addr = g_ptr_array_index (source_inet_addr->priv->addresses, i);
+ camel_internet_address_add (dest_inet_addr, addr->name, addr->address);
}
return i;
}
static void
+internet_address_finalize (GObject *object)
+{
+ CamelInternetAddress *inet_addr = CAMEL_INTERNET_ADDRESS (object);
+
+ camel_address_remove (CAMEL_ADDRESS (inet_addr), -1);
+ g_ptr_array_free (inet_addr->priv->addresses, TRUE);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (camel_internet_address_parent_class)->finalize (object);
+}
+
+static void
camel_internet_address_class_init (CamelInternetAddressClass *class)
{
CamelAddressClass *address_class;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelInternetAddressPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = internet_address_finalize;
address_class = CAMEL_ADDRESS_CLASS (class);
+ address_class->length = internet_address_length;
address_class->decode = internet_address_decode;
address_class->encode = internet_address_encode;
address_class->unformat = internet_address_unformat;
@@ -240,6 +283,8 @@ camel_internet_address_class_init (CamelInternetAddressClass *class)
static void
camel_internet_address_init (CamelInternetAddress *internet_address)
{
+ internet_address->priv = G_TYPE_INSTANCE_GET_PRIVATE (internet_address, CAMEL_TYPE_INTERNET_ADDRESS,
CamelInternetAddressPrivate);
+ internet_address->priv->addresses = g_ptr_array_new ();
}
/**
@@ -278,8 +323,8 @@ camel_internet_address_add (CamelInternetAddress *addr,
new = g_malloc (sizeof (*new));
new->name = g_strdup (name);
new->address = g_strdup (address);
- index = ((CamelAddress *) addr)->addresses->len;
- g_ptr_array_add (((CamelAddress *) addr)->addresses, new);
+ index = addr->priv->addresses->len;
+ g_ptr_array_add (addr->priv->addresses, new);
return index;
}
@@ -305,10 +350,10 @@ camel_internet_address_get (CamelInternetAddress *addr,
g_return_val_if_fail (CAMEL_IS_INTERNET_ADDRESS (addr), FALSE);
- if (index < 0 || index >= ((CamelAddress *) addr)->addresses->len)
+ if (index < 0 || index >= addr->priv->addresses->len)
return FALSE;
- a = g_ptr_array_index (((CamelAddress *) addr)->addresses, index);
+ a = g_ptr_array_index (addr->priv->addresses, index);
if (namep)
*namep = a->name;
if (addressp)
@@ -337,9 +382,9 @@ camel_internet_address_find_name (CamelInternetAddress *addr,
g_return_val_if_fail (CAMEL_IS_INTERNET_ADDRESS (addr), -1);
- len = ((CamelAddress *) addr)->addresses->len;
+ len = addr->priv->addresses->len;
for (i = 0; i < len; i++) {
- a = g_ptr_array_index (((CamelAddress *) addr)->addresses, i);
+ a = g_ptr_array_index (addr->priv->addresses, i);
if (a->name && !strcmp (a->name, name)) {
if (addressp)
*addressp = a->address;
@@ -391,10 +436,10 @@ camel_internet_address_ensure_ascii_domains (CamelInternetAddress *addr)
g_return_if_fail (CAMEL_IS_INTERNET_ADDRESS (addr));
- len = ((CamelAddress *) addr)->addresses->len;
+ len = addr->priv->addresses->len;
for (i = 0; i < len; i++) {
gint at_pos = -1;
- a = g_ptr_array_index (((CamelAddress *) addr)->addresses, i);
+ a = g_ptr_array_index (addr->priv->addresses, i);
if (a->address && !domain_contains_only_ascii (a->address, &at_pos)) {
gchar *address, *domain;
@@ -434,9 +479,9 @@ camel_internet_address_find_address (CamelInternetAddress *addr,
g_return_val_if_fail (CAMEL_IS_INTERNET_ADDRESS (addr), -1);
- len = ((CamelAddress *) addr)->addresses->len;
+ len = addr->priv->addresses->len;
for (i = 0; i < len; i++) {
- a = g_ptr_array_index (((CamelAddress *) addr)->addresses, i);
+ a = g_ptr_array_index (addr->priv->addresses, i);
if (!strcmp (a->address, address)) {
if (namep)
*namep = a->name;
diff --git a/src/camel/camel-internet-address.h b/src/camel/camel-internet-address.h
index 4253abb..9562460 100644
--- a/src/camel/camel-internet-address.h
+++ b/src/camel/camel-internet-address.h
@@ -58,6 +58,9 @@ struct _CamelInternetAddress {
struct _CamelInternetAddressClass {
CamelAddressClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_internet_address_get_type (void);
diff --git a/src/camel/camel-junk-filter.h b/src/camel/camel-junk-filter.h
index b27064f..b36abe7 100644
--- a/src/camel/camel-junk-filter.h
+++ b/src/camel/camel-junk-filter.h
@@ -75,6 +75,9 @@ struct _CamelJunkFilterInterface {
gboolean (*synchronize) (CamelJunkFilter *junk_filter,
GCancellable *cancellable,
GError **error);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_junk_filter_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-local-settings.h b/src/camel/camel-local-settings.h
index 6ae5d1d..eedb42b 100644
--- a/src/camel/camel-local-settings.h
+++ b/src/camel/camel-local-settings.h
@@ -64,6 +64,9 @@ struct _CamelLocalSettings {
struct _CamelLocalSettingsClass {
CamelStoreSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_local_settings_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-medium.c b/src/camel/camel-medium.c
index dc0d5d0..2165881 100644
--- a/src/camel/camel-medium.c
+++ b/src/camel/camel-medium.c
@@ -178,7 +178,7 @@ camel_medium_init (CamelMedium *medium)
void
camel_medium_add_header (CamelMedium *medium,
const gchar *name,
- gconstpointer value)
+ const gchar *value)
{
CamelMediumClass *class;
@@ -205,7 +205,7 @@ camel_medium_add_header (CamelMedium *medium,
void
camel_medium_set_header (CamelMedium *medium,
const gchar *name,
- gconstpointer value)
+ const gchar *value)
{
CamelMediumClass *class;
@@ -256,11 +256,11 @@ camel_medium_remove_header (CamelMedium *medium,
*
* If the header occurs more than once, only retrieve the first
* instance of the header. For multi-occuring headers, use
- * :get_headers().
+ * camel_medium_dup_headers() or camel_medium_get_headers().
*
- * Returns: (transfer none) (nullable): the value of the named header, or %NULL
+ * Returns: (nullable): the value of the named header, or %NULL
**/
-gconstpointer
+const gchar *
camel_medium_get_header (CamelMedium *medium,
const gchar *name)
{
@@ -276,51 +276,53 @@ camel_medium_get_header (CamelMedium *medium,
}
/**
- * camel_medium_get_headers:
+ * camel_medium_dup_headers:
* @medium: a #CamelMedium object
*
- * Gets an array of all header name/value pairs (as
- * CamelMediumHeader structures). The values will be decoded
- * to UTF-8 for any headers that are recognized by Camel. The
- * caller should not modify the returned data.
+ * Gets an array of all header name/value pairs. The values will be
+ * decoded to UTF-8 for any headers that are recognized by Camel.
+ * See also camel_medium_get_headers().
+ *
+ * Returns: (transfer full): the array of headers, which must be freed with camel_name_value_array_free().
*
- * Returns: (element-type CamelMediumHeader) (transfer full): the array of
- * headers, which must be freed with camel_medium_free_headers().
+ * Since: 3.24
**/
-GArray *
-camel_medium_get_headers (CamelMedium *medium)
+CamelNameValueArray *
+camel_medium_dup_headers (CamelMedium *medium)
{
CamelMediumClass *class;
g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
class = CAMEL_MEDIUM_GET_CLASS (medium);
- g_return_val_if_fail (class->get_headers != NULL, NULL);
+ g_return_val_if_fail (class->dup_headers != NULL, NULL);
- return class->get_headers (medium);
+ return class->dup_headers (medium);
}
/**
- * camel_medium_free_headers:
+ * camel_medium_get_headers:
* @medium: a #CamelMedium object
- * @headers: (element-type CamelMediumHeader): an array of headers returned
- * from camel_medium_get_headers()
*
- * Frees @headers.
+ * Gets an array of all header name/value pairs. The values will be
+ * decoded to UTF-8 for any headers that are recognized by Camel.
+ * See also camel_medium_dup_headers().
+ *
+ * Returns: (transfer none): the array of headers, owned by @medium.
+ *
+ * Since: 3.24
**/
-void
-camel_medium_free_headers (CamelMedium *medium,
- GArray *headers)
+const CamelNameValueArray *
+camel_medium_get_headers (CamelMedium *medium)
{
CamelMediumClass *class;
- g_return_if_fail (CAMEL_IS_MEDIUM (medium));
- g_return_if_fail (headers != NULL);
+ g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), NULL);
class = CAMEL_MEDIUM_GET_CLASS (medium);
- g_return_if_fail (class->free_headers != NULL);
+ g_return_val_if_fail (class->get_headers != NULL, NULL);
- class->free_headers (medium, headers);
+ return class->get_headers (medium);
}
/**
diff --git a/src/camel/camel-medium.h b/src/camel/camel-medium.h
index 3d83723..9872cc6 100644
--- a/src/camel/camel-medium.h
+++ b/src/camel/camel-medium.h
@@ -27,6 +27,7 @@
#define CAMEL_MEDIUM_H
#include <camel/camel-data-wrapper.h>
+#include <camel/camel-name-value-array.h>
/* Standard GObject macros */
#define CAMEL_TYPE_MEDIUM \
@@ -53,11 +54,6 @@ typedef struct _CamelMedium CamelMedium;
typedef struct _CamelMediumClass CamelMediumClass;
typedef struct _CamelMediumPrivate CamelMediumPrivate;
-typedef struct {
- const gchar *name;
- const gchar *value;
-} CamelMediumHeader;
-
struct _CamelMedium {
CamelDataWrapper parent;
CamelMediumPrivate *priv;
@@ -68,37 +64,42 @@ struct _CamelMediumClass {
void (*add_header) (CamelMedium *medium,
const gchar *name,
- gconstpointer value);
+ const gchar *value);
void (*set_header) (CamelMedium *medium,
const gchar *name,
- gconstpointer value);
+ const gchar *value);
void (*remove_header) (CamelMedium *medium,
const gchar *name);
- gconstpointer (*get_header) (CamelMedium *medium,
+ const gchar * (*get_header) (CamelMedium *medium,
const gchar *name);
- GArray * (*get_headers) (CamelMedium *medium);
- void (*free_headers) (CamelMedium *medium,
- GArray *headers);
+ CamelNameValueArray *
+ (*dup_headers) (CamelMedium *medium);
+ const CamelNameValueArray *
+ (*get_headers) (CamelMedium *medium);
CamelDataWrapper *
(*get_content) (CamelMedium *medium);
void (*set_content) (CamelMedium *medium,
CamelDataWrapper *content);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_medium_get_type (void);
void camel_medium_add_header (CamelMedium *medium,
const gchar *name,
- gconstpointer value);
+ const gchar *value);
void camel_medium_set_header (CamelMedium *medium,
const gchar *name,
- gconstpointer value);
+ const gchar *value);
void camel_medium_remove_header (CamelMedium *medium,
const gchar *name);
-gconstpointer camel_medium_get_header (CamelMedium *medium,
+const gchar * camel_medium_get_header (CamelMedium *medium,
const gchar *name);
-GArray * camel_medium_get_headers (CamelMedium *medium);
-void camel_medium_free_headers (CamelMedium *medium,
- GArray *headers);
+CamelNameValueArray *
+ camel_medium_dup_headers (CamelMedium *medium);
+const CamelNameValueArray *
+ camel_medium_get_headers (CamelMedium *medium);
CamelDataWrapper *
camel_medium_get_content (CamelMedium *medium);
void camel_medium_set_content (CamelMedium *medium,
diff --git a/src/camel/camel-memchunk.c b/src/camel/camel-memchunk.c
index d99f3de..8f3991b 100644
--- a/src/camel/camel-memchunk.c
+++ b/src/camel/camel-memchunk.c
@@ -72,7 +72,7 @@ struct _CamelMemChunk {
};
/**
- * camel_memchunk_new:
+ * camel_memchunk_new: (skip)
* @atomcount: the number of atoms stored in a single malloc'd block of memory
* @atomsize: the size of each allocation
*
@@ -102,7 +102,7 @@ camel_memchunk_new (gint atomcount,
}
/**
- * camel_memchunk_alloc:
+ * camel_memchunk_alloc: (skip)
* @memchunk: an #CamelMemChunk
*
* Allocate a new atom size block of memory from an #CamelMemChunk.
@@ -141,7 +141,7 @@ camel_memchunk_alloc (CamelMemChunk *memchunk)
}
/**
- * camel_memchunk_alloc0:
+ * camel_memchunk_alloc0: (skip)
* @memchunk: an #CamelMemChunk
*
* Allocate a new atom size block of memory from an #CamelMemChunk,
@@ -164,7 +164,7 @@ camel_memchunk_alloc0 (CamelMemChunk *memchunk)
}
/**
- * camel_memchunk_free:
+ * camel_memchunk_free: (skip)
* @memchunk: an #CamelMemChunk
* @mem: address of atom to free
*
@@ -194,7 +194,7 @@ camel_memchunk_free (CamelMemChunk *memchunk,
}
/**
- * camel_memchunk_empty:
+ * camel_memchunk_empty: (skip)
* @memchunk: an #CamelMemChunk
*
* Clean out the memchunk buffers. Marks all allocated memory as free blocks,
@@ -250,7 +250,7 @@ tree_search (struct _cleaninfo *a,
}
/**
- * camel_memchunk_clean:
+ * camel_memchunk_clean: (skip)
* @memchunk: an #CamelMemChunk
*
* Scan all empty blocks and check for blocks which can be free'd
@@ -328,7 +328,7 @@ camel_memchunk_clean (CamelMemChunk *memchunk)
}
/**
- * camel_memchunk_destroy:
+ * camel_memchunk_destroy: (skip)
* @memchunk: an #CamelMemChunk
*
* Free the memchunk header, and all associated memory.
diff --git a/src/camel/camel-mempool.c b/src/camel/camel-mempool.c
index bc2fade..2c9bc2b 100644
--- a/src/camel/camel-mempool.c
+++ b/src/camel/camel-mempool.c
@@ -41,7 +41,7 @@ struct _CamelMemPool {
};
/**
- * camel_mempool_new:
+ * camel_mempool_new: (skip)
* @blocksize: The base blocksize to use for all system alocations.
* @threshold: If the allocation exceeds the threshold, then it is
* allocated separately and stored in a separate list.
@@ -94,7 +94,7 @@ camel_mempool_new (gint blocksize,
}
/**
- * camel_mempool_alloc:
+ * camel_mempool_alloc: (skip)
* @pool: a #CamelMemPool
* @size:
*
@@ -137,7 +137,7 @@ camel_mempool_alloc (CamelMemPool *pool,
}
/**
- * camel_mempool_strdup:
+ * camel_mempool_strdup: (skip)
* @pool: a #CamelMemPool
* @str:
*
@@ -158,7 +158,7 @@ camel_mempool_strdup (CamelMemPool *pool,
}
/**
- * camel_mempool_flush:
+ * camel_mempool_flush: (skip)
* @pool: a #CamelMemPool
* @freeall: free all system allocated blocks as well
*
@@ -203,7 +203,7 @@ camel_mempool_flush (CamelMemPool *pool,
}
/**
- * camel_mempool_destroy:
+ * camel_mempool_destroy: (skip)
* @pool: a #CamelMemPool
*
* Free all memory associated with a mempool.
diff --git a/src/camel/camel-message-info-base.c b/src/camel/camel-message-info-base.c
new file mode 100644
index 0000000..71b1b70
--- /dev/null
+++ b/src/camel/camel-message-info-base.c
@@ -0,0 +1,877 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "camel-folder-summary.h"
+#include "camel-message-info.h"
+
+#include "camel-message-info-base.h"
+
+struct _CamelMessageInfoBasePrivate {
+ guint32 flags; /* bit-or of CamelMessageFlags */
+ CamelNamedFlags *user_flags;
+ CamelNameValueArray *user_tags;
+ gchar *subject;
+ gchar *from;
+ gchar *to;
+ gchar *cc;
+ gchar *mlist;
+ guint32 size;
+ gint64 date_sent; /* aka time_t */
+ gint64 date_received; /* aka time_t */
+ guint64 message_id;
+ GArray *references; /* guint64, aka CamelSummaryMessageID */
+ CamelNameValueArray *headers;
+};
+
+G_DEFINE_TYPE (CamelMessageInfoBase, camel_message_info_base, CAMEL_TYPE_MESSAGE_INFO)
+
+static guint32
+message_info_base_get_flags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ guint32 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), 0);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->flags;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_flags (CamelMessageInfo *mi,
+ guint32 mask,
+ guint32 set)
+{
+ CamelMessageInfoBase *bmi;
+ guint32 old_flags;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ old_flags = bmi->priv->flags;
+ bmi->priv->flags = (old_flags & ~mask) | (set & mask);
+ changed = old_flags != bmi->priv->flags;
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static gboolean
+message_info_base_get_user_flag (const CamelMessageInfo *mi,
+ const gchar *name)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ if (bmi->priv->user_flags)
+ result = camel_named_flags_contains (bmi->priv->user_flags, name);
+ else
+ result = FALSE;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_user_flag (CamelMessageInfo *mi,
+ const gchar *name,
+ gboolean state)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ if (!bmi->priv->user_flags)
+ bmi->priv->user_flags = camel_named_flags_new ();
+
+ if (state)
+ changed = camel_named_flags_insert (bmi->priv->user_flags, name);
+ else
+ changed = camel_named_flags_remove (bmi->priv->user_flags, name);
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const CamelNamedFlags *
+message_info_base_get_user_flags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const CamelNamedFlags *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->user_flags;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static CamelNamedFlags *
+message_info_base_dup_user_flags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ CamelNamedFlags *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ if (bmi->priv->user_flags)
+ result = camel_named_flags_copy (bmi->priv->user_flags);
+ else
+ result = NULL;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_take_user_flags (CamelMessageInfo *mi,
+ CamelNamedFlags *user_flags)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = !camel_named_flags_equal (bmi->priv->user_flags, user_flags);
+
+ if (changed) {
+ camel_named_flags_free (bmi->priv->user_flags);
+ bmi->priv->user_flags = user_flags;
+ } else {
+ camel_named_flags_free (user_flags);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const gchar *
+message_info_base_get_user_tag (const CamelMessageInfo *mi,
+ const gchar *name)
+{
+ CamelMessageInfoBase *bmi;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ if (bmi->priv->user_tags)
+ result = camel_name_value_array_get_named (bmi->priv->user_tags,
CAMEL_COMPARE_CASE_SENSITIVE, name);
+ else
+ result = NULL;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_user_tag (CamelMessageInfo *mi,
+ const gchar *name,
+ const gchar *value)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ if (!bmi->priv->user_tags)
+ bmi->priv->user_tags = camel_name_value_array_new ();
+
+ if (value)
+ changed = camel_name_value_array_set_named (bmi->priv->user_tags,
CAMEL_COMPARE_CASE_SENSITIVE, name, value);
+ else
+ changed = camel_name_value_array_remove_named (bmi->priv->user_tags,
CAMEL_COMPARE_CASE_SENSITIVE, name, FALSE);
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const CamelNameValueArray *
+message_info_base_get_user_tags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->user_tags;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static CamelNameValueArray *
+message_info_base_dup_user_tags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = camel_name_value_array_copy (bmi->priv->user_tags);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_take_user_tags (CamelMessageInfo *mi,
+ CamelNameValueArray *user_tags)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = !camel_name_value_array_equal (bmi->priv->user_tags, user_tags,
CAMEL_COMPARE_CASE_SENSITIVE);
+
+ if (changed) {
+ camel_name_value_array_free (bmi->priv->user_tags);
+ bmi->priv->user_tags = user_tags;
+ } else {
+ camel_name_value_array_free (user_tags);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const gchar *
+message_info_base_get_subject (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->subject;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_subject (CamelMessageInfo *mi,
+ const gchar *subject)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = g_strcmp0 (bmi->priv->subject, subject) != 0;
+
+ if (changed) {
+ g_free (bmi->priv->subject);
+ bmi->priv->subject = g_strdup (subject);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const gchar *
+message_info_base_get_from (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->from;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_from (CamelMessageInfo *mi,
+ const gchar *from)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = g_strcmp0 (bmi->priv->from, from) != 0;
+
+ if (changed) {
+ g_free (bmi->priv->from);
+ bmi->priv->from = g_strdup (from);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const gchar *
+message_info_base_get_to (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->to;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_to (CamelMessageInfo *mi,
+ const gchar *to)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = g_strcmp0 (bmi->priv->to, to) != 0;
+
+ if (changed) {
+ g_free (bmi->priv->to);
+ bmi->priv->to = g_strdup (to);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const gchar *
+message_info_base_get_cc (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->cc;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_cc (CamelMessageInfo *mi,
+ const gchar *cc)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = g_strcmp0 (bmi->priv->cc, cc) != 0;
+
+ if (changed) {
+ g_free (bmi->priv->cc);
+ bmi->priv->cc = g_strdup (cc);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const gchar *
+message_info_base_get_mlist (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->mlist;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_mlist (CamelMessageInfo *mi,
+ const gchar *mlist)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = g_strcmp0 (bmi->priv->mlist, mlist) != 0;
+
+ if (changed) {
+ g_free (bmi->priv->mlist);
+ bmi->priv->mlist = g_strdup (mlist);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static guint32
+message_info_base_get_size (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ guint32 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), 0);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->size;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_size (CamelMessageInfo *mi,
+ guint32 size)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = bmi->priv->size != size;
+
+ if (changed)
+ bmi->priv->size = size;
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static gint64
+message_info_base_get_date_sent (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ gint64 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), 0);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->date_sent;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_date_sent (CamelMessageInfo *mi,
+ gint64 date_sent)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = bmi->priv->date_sent != date_sent;
+
+ if (changed)
+ bmi->priv->date_sent = date_sent;
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static gint64
+message_info_base_get_date_received (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ gint64 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), 0);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->date_received;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_date_received (CamelMessageInfo *mi,
+ gint64 date_received)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = bmi->priv->date_received != date_received;
+
+ if (changed)
+ bmi->priv->date_received = date_received;
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static guint64
+message_info_base_get_message_id (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ guint64 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), 0);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->message_id;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_set_message_id (CamelMessageInfo *mi,
+ guint64 message_id)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = bmi->priv->message_id != message_id;
+
+ if (changed)
+ bmi->priv->message_id = message_id;
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const GArray *
+message_info_base_get_references (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const GArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->references;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_references_equal (const GArray *references_a,
+ const GArray *references_b)
+{
+ guint ii, len;
+
+ if (references_a == references_b)
+ return TRUE;
+
+ if (!references_a || !references_b)
+ return FALSE;
+
+ len = references_a->len;
+ if (len != references_b->len)
+ return FALSE;
+
+ /* They can be still the same, only having the items on different indexes,
+ but that's too expensive to compare precisely. */
+ for (ii = 0; ii < len; ii++) {
+ if (g_array_index (references_a, guint64, ii) != g_array_index (references_b, guint64, ii))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+message_info_base_take_references (CamelMessageInfo *mi,
+ GArray *references)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = !message_info_base_references_equal (bmi->priv->references, references);
+
+ if (changed) {
+ if (bmi->priv->references)
+ g_array_unref (bmi->priv->references);
+ bmi->priv->references = references;
+ } else if (references) {
+ g_array_unref (references);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static const CamelNameValueArray *
+message_info_base_get_headers (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoBase *bmi;
+ const CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), NULL);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+ result = bmi->priv->headers;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+static gboolean
+message_info_base_take_headers (CamelMessageInfo *mi,
+ CamelNameValueArray *headers)
+{
+ CamelMessageInfoBase *bmi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO_BASE (mi), FALSE);
+
+ bmi = CAMEL_MESSAGE_INFO_BASE (mi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = !camel_name_value_array_equal (bmi->priv->headers, headers, CAMEL_COMPARE_CASE_SENSITIVE);
+
+ if (changed) {
+ camel_name_value_array_free (bmi->priv->headers);
+ bmi->priv->headers = headers;
+ } else {
+ camel_name_value_array_free (headers);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ return changed;
+}
+
+static void
+message_info_base_dispose (GObject *object)
+{
+ CamelMessageInfoBase *bmi = CAMEL_MESSAGE_INFO_BASE (object);
+
+ camel_named_flags_free (bmi->priv->user_flags);
+ bmi->priv->user_flags = NULL;
+
+ camel_name_value_array_free (bmi->priv->user_tags);
+ bmi->priv->user_tags = NULL;
+
+ #define free_ptr(x) G_STMT_START { g_free (x); x = NULL; } G_STMT_END
+
+ free_ptr (bmi->priv->subject);
+ free_ptr (bmi->priv->from);
+ free_ptr (bmi->priv->to);
+ free_ptr (bmi->priv->cc);
+ free_ptr (bmi->priv->mlist);
+
+ #undef free_ptr
+
+ if (bmi->priv->references) {
+ g_array_unref (bmi->priv->references);
+ bmi->priv->references = NULL;
+ }
+
+ camel_name_value_array_free (bmi->priv->headers);
+ bmi->priv->headers = NULL;
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_message_info_base_parent_class)->dispose (object);
+}
+
+static void
+camel_message_info_base_class_init (CamelMessageInfoBaseClass *class)
+{
+ CamelMessageInfoClass *mi_class;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelMessageInfoBasePrivate));
+
+ mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
+ mi_class->get_flags = message_info_base_get_flags;
+ mi_class->set_flags = message_info_base_set_flags;
+ mi_class->get_user_flag = message_info_base_get_user_flag;
+ mi_class->set_user_flag = message_info_base_set_user_flag;
+ mi_class->get_user_flags = message_info_base_get_user_flags;
+ mi_class->dup_user_flags = message_info_base_dup_user_flags;
+ mi_class->take_user_flags = message_info_base_take_user_flags;
+ mi_class->get_user_tag = message_info_base_get_user_tag;
+ mi_class->set_user_tag = message_info_base_set_user_tag;
+ mi_class->get_user_tags = message_info_base_get_user_tags;
+ mi_class->dup_user_tags = message_info_base_dup_user_tags;
+ mi_class->take_user_tags = message_info_base_take_user_tags;
+ mi_class->get_subject = message_info_base_get_subject;
+ mi_class->set_subject = message_info_base_set_subject;
+ mi_class->get_from = message_info_base_get_from;
+ mi_class->set_from = message_info_base_set_from;
+ mi_class->get_to = message_info_base_get_to;
+ mi_class->set_to = message_info_base_set_to;
+ mi_class->get_cc = message_info_base_get_cc;
+ mi_class->set_cc = message_info_base_set_cc;
+ mi_class->get_mlist = message_info_base_get_mlist;
+ mi_class->set_mlist = message_info_base_set_mlist;
+ mi_class->get_size = message_info_base_get_size;
+ mi_class->set_size = message_info_base_set_size;
+ mi_class->get_date_sent = message_info_base_get_date_sent;
+ mi_class->set_date_sent = message_info_base_set_date_sent;
+ mi_class->get_date_received = message_info_base_get_date_received;
+ mi_class->set_date_received = message_info_base_set_date_received;
+ mi_class->get_message_id = message_info_base_get_message_id;
+ mi_class->set_message_id = message_info_base_set_message_id;
+ mi_class->get_references = message_info_base_get_references;
+ mi_class->take_references = message_info_base_take_references;
+ mi_class->get_headers = message_info_base_get_headers;
+ mi_class->take_headers = message_info_base_take_headers;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = message_info_base_dispose;
+}
+
+static void
+camel_message_info_base_init (CamelMessageInfoBase *bmi)
+{
+ bmi->priv = G_TYPE_INSTANCE_GET_PRIVATE (bmi, CAMEL_TYPE_MESSAGE_INFO_BASE,
CamelMessageInfoBasePrivate);
+}
diff --git a/src/camel/camel-message-info-base.h b/src/camel/camel-message-info-base.h
new file mode 100644
index 0000000..4343467
--- /dev/null
+++ b/src/camel/camel-message-info-base.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_MESSAGE_INFO_BASE_H
+#define CAMEL_MESSAGE_INFO_BASE_H
+
+#include <glib-object.h>
+
+#include <camel/camel-message-info.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_MESSAGE_INFO_BASE \
+ (camel_message_info_base_get_type ())
+#define CAMEL_MESSAGE_INFO_BASE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_MESSAGE_INFO_BASE, CamelMessageInfoBase))
+#define CAMEL_MESSAGE_INFO_BASE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_MESSAGE_INFO_BASE, CamelMessageInfoBaseClass))
+#define CAMEL_IS_MESSAGE_INFO_BASE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_MESSAGE_INFO_BASE))
+#define CAMEL_IS_MESSAGE_INFO_BASE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_MESSAGE_INFO_BASE))
+#define CAMEL_MESSAGE_INFO_BASE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_MESSAGE_INFO_BASE, CamelMessageInfoBaseClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelMessageInfoBase CamelMessageInfoBase;
+typedef struct _CamelMessageInfoBaseClass CamelMessageInfoBaseClass;
+typedef struct _CamelMessageInfoBasePrivate CamelMessageInfoBasePrivate;
+
+struct _CamelMessageInfoBase {
+ CamelMessageInfo parent;
+ CamelMessageInfoBasePrivate *priv;
+};
+
+struct _CamelMessageInfoBaseClass {
+ CamelMessageInfoClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
+};
+
+GType camel_message_info_base_get_type (void);
+
+G_END_DECLS
+
+#endif /* CAMEL_MESSAGE_INFO_BASE_H */
diff --git a/src/camel/camel-message-info.c b/src/camel/camel-message-info.c
new file mode 100644
index 0000000..01664e3
--- /dev/null
+++ b/src/camel/camel-message-info.c
@@ -0,0 +1,2979 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "camel-db.h"
+#include "camel-folder.h"
+#include "camel-folder-summary.h"
+#include "camel-message-info-base.h"
+#include "camel-string-utils.h"
+
+#include "camel-message-info.h"
+
+struct _CamelMessageInfoPrivate {
+ GRecMutex property_lock;
+
+ GWeakRef summary; /* CamelFolderSummary * */
+ gboolean dirty; /* whether requires save to local disk/summary */
+ const gchar *uid; /* allocated in the string pool */
+ gboolean abort_notifications;
+ gboolean thaw_notify_folder;
+ gboolean thaw_notify_folder_with_counts;
+ guint freeze_notifications;
+ guint folder_flagged_stamp;
+};
+
+enum {
+ PROP_0,
+ PROP_SUMMARY,
+ PROP_DIRTY,
+ PROP_FOLDER_FLAGGED,
+ PROP_FOLDER_FLAGGED_STAMP,
+ PROP_ABORT_NOTIFICATIONS,
+ PROP_UID,
+ PROP_FLAGS,
+ PROP_USER_FLAGS,
+ PROP_USER_TAGS,
+ PROP_SUBJECT,
+ PROP_FROM,
+ PROP_TO,
+ PROP_CC,
+ PROP_MLIST,
+ PROP_SIZE,
+ PROP_DATE_SENT,
+ PROP_DATE_RECEIVED,
+ PROP_MESSAGE_ID,
+ PROP_REFERENCES,
+ PROP_HEADERS
+};
+
+G_DEFINE_ABSTRACT_TYPE (CamelMessageInfo, camel_message_info, G_TYPE_OBJECT)
+
+static CamelMessageInfo *
+message_info_clone (const CamelMessageInfo *mi,
+ CamelFolderSummary *assign_summary)
+{
+ CamelMessageInfo *result;
+ const gchar *uid;
+ const GArray *references;
+ const CamelNameValueArray *headers;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+ if (assign_summary)
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (assign_summary), NULL);
+
+ /* Make sure the 'mi' doesn't change while copying the values. */
+ camel_message_info_property_lock (mi);
+
+ if (!assign_summary) {
+ CamelFolderSummary *mi_summary;
+
+ mi_summary = camel_message_info_ref_summary (mi);
+ result = camel_message_info_new (mi_summary);
+ g_clear_object (&mi_summary);
+ } else {
+ result = camel_message_info_new (assign_summary);
+ }
+
+ g_object_freeze_notify (G_OBJECT (result));
+ camel_message_info_set_abort_notifications (result, TRUE);
+
+ uid = camel_message_info_pooldup_uid (mi);
+ camel_message_info_set_uid (result, uid);
+ camel_pstring_free (uid);
+
+ camel_message_info_take_user_flags (result, camel_message_info_dup_user_flags (mi));
+ camel_message_info_take_user_tags (result, camel_message_info_dup_user_tags (mi));
+ camel_message_info_set_subject (result, camel_message_info_get_subject (mi));
+ camel_message_info_set_from (result, camel_message_info_get_from (mi));
+ camel_message_info_set_to (result, camel_message_info_get_to (mi));
+ camel_message_info_set_cc (result, camel_message_info_get_cc (mi));
+ camel_message_info_set_mlist (result, camel_message_info_get_mlist (mi));
+ camel_message_info_set_size (result, camel_message_info_get_size (mi));
+ camel_message_info_set_date_sent (result, camel_message_info_get_date_sent (mi));
+ camel_message_info_set_date_received (result, camel_message_info_get_date_received (mi));
+ camel_message_info_set_message_id (result, camel_message_info_get_message_id (mi));
+
+ references = camel_message_info_get_references (mi);
+ if (references && references->len) {
+ GArray *copy;
+ guint ii;
+
+ copy = g_array_sized_new (FALSE, FALSE, references->len, sizeof (guint64));
+
+ for (ii = 0; ii < references->len; ii++) {
+ g_array_append_val (copy, g_array_index (references, guint64, ii));
+ }
+
+ camel_message_info_take_references (result, copy);
+ }
+
+ headers = camel_message_info_get_headers (mi);
+ if (headers) {
+ camel_message_info_take_headers (result,
+ camel_name_value_array_copy (headers));
+ }
+
+ /* Set flags as the last, to not overwrite 'folder-flagged' flag by
+ the "changes" when copying fields. */
+ camel_message_info_set_flags (result, ~0, camel_message_info_get_flags (mi));
+
+ camel_message_info_property_unlock (mi);
+
+ /* Also ensure 'dirty' flag, thus it can be eventually saved. */
+ camel_message_info_set_dirty (result, TRUE);
+
+ camel_message_info_set_abort_notifications (result, FALSE);
+ g_object_thaw_notify (G_OBJECT (result));
+
+ return result;
+}
+
+static gboolean
+message_info_load (CamelMessageInfo *mi,
+ const CamelMIRecord *record,
+ /* const */ gchar **bdata_ptr)
+{
+ gint ii, count;
+ gchar *part, *label;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_ptr != NULL, FALSE);
+
+ camel_message_info_set_uid (mi, record->uid);
+ camel_message_info_set_flags (mi, ~0, record->flags);
+ camel_message_info_set_size (mi, record->size);
+ camel_message_info_set_date_sent (mi, record->dsent);
+ camel_message_info_set_date_received (mi, record->dreceived);
+
+ camel_message_info_set_subject (mi, record->subject);
+ camel_message_info_set_from (mi, record->from);
+ camel_message_info_set_to (mi, record->to);
+ camel_message_info_set_cc (mi, record->cc);
+ camel_message_info_set_mlist (mi, record->mlist);
+
+ /* Extract Message id & References */
+ part = record->part;
+ if (part) {
+ CamelSummaryMessageID message_id;
+
+ message_id.id.part.hi = camel_util_bdata_get_number (&part, 0);
+ message_id.id.part.lo = camel_util_bdata_get_number (&part, 0);
+
+ camel_message_info_set_message_id (mi, message_id.id.id);
+
+ count = camel_util_bdata_get_number (&part, 0);
+
+ if (count > 0) {
+ GArray *references = g_array_sized_new (FALSE, FALSE, sizeof (guint64), count);
+
+ for (ii = 0; ii < count; ii++) {
+ message_id.id.part.hi = camel_util_bdata_get_number (&part, 0);
+ message_id.id.part.lo = camel_util_bdata_get_number (&part, 0);
+
+ g_array_append_val (references, message_id.id.id);
+ }
+
+ camel_message_info_take_references (mi, references);
+ }
+ }
+
+ /* Extract User flags/labels */
+ part = record->labels;
+ if (part) {
+ CamelNamedFlags *user_flags;
+
+ user_flags = camel_named_flags_new ();
+
+ label = part;
+ for (ii = 0; part[ii]; ii++) {
+ if (part[ii] == ' ') {
+ part[ii] = 0;
+ if (label && *label)
+ camel_named_flags_insert (user_flags, label);
+ label = &(part[ii + 1]);
+ part[ii] = ' ';
+ }
+ }
+ if (label && *label)
+ camel_named_flags_insert (user_flags, label);
+
+ camel_message_info_take_user_flags (mi, user_flags);
+ }
+
+ /* Extract User tags */
+ part = record->usertags;
+ if (part) {
+ CamelNameValueArray *user_tags;
+
+ count = camel_util_bdata_get_number (&part, 0);
+
+ user_tags = camel_name_value_array_new_sized (count);
+
+ for (ii = 0; ii < count; ii++) {
+ gchar *name, *value;
+
+ name = camel_util_bdata_get_string (&part, NULL);
+ value = camel_util_bdata_get_string (&part, NULL);
+
+ if (name)
+ camel_name_value_array_set_named (user_tags, CAMEL_COMPARE_CASE_SENSITIVE,
name, value ? value : "");
+
+ g_free (name);
+ g_free (value);
+ }
+
+ camel_message_info_take_user_tags (mi, user_tags);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+message_info_save (const CamelMessageInfo *mi,
+ CamelMIRecord *record,
+ GString *bdata_str)
+{
+ GString *tmp;
+ CamelSummaryMessageID message_id;
+ const CamelNamedFlags *user_flags;
+ const CamelNameValueArray *user_tags;
+ const GArray *references;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_str != NULL, FALSE);
+
+ record->uid = (gchar *) camel_pstring_strdup (camel_message_info_get_uid (mi));
+ record->flags = camel_message_info_get_flags (mi);
+
+ record->read = ((record->flags & (CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_JUNK)))
? 1 : 0;
+ record->deleted = (record->flags & CAMEL_MESSAGE_DELETED) != 0 ? 1 : 0;
+ record->replied = (record->flags & CAMEL_MESSAGE_ANSWERED) != 0 ? 1 : 0;
+ record->important = (record->flags & CAMEL_MESSAGE_FLAGGED) != 0 ? 1 : 0;
+ record->junk = (record->flags & CAMEL_MESSAGE_JUNK) != 0 ? 1 : 0;
+ record->dirty = (record->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0 ? 1 : 0;
+ record->attachment = (record->flags & CAMEL_MESSAGE_ATTACHMENTS) != 0 ? 1 : 0;
+
+ record->size = camel_message_info_get_size (mi);
+ record->dsent = camel_message_info_get_date_sent (mi);
+ record->dreceived = camel_message_info_get_date_received (mi);
+
+ record->subject = g_strdup (camel_message_info_get_subject (mi));
+ record->from = g_strdup (camel_message_info_get_from (mi));
+ record->to = g_strdup (camel_message_info_get_to (mi));
+ record->cc = g_strdup (camel_message_info_get_cc (mi));
+ record->mlist = g_strdup (camel_message_info_get_mlist (mi));
+
+ record->followup_flag = g_strdup (camel_message_info_get_user_tag (mi, "follow-up"));
+ record->followup_completed_on = g_strdup (camel_message_info_get_user_tag (mi, "completed-on"));
+ record->followup_due_by = g_strdup (camel_message_info_get_user_tag (mi, "due-by"));
+
+ tmp = g_string_new (NULL);
+ message_id.id.id = camel_message_info_get_message_id (mi);
+ g_string_append_printf (tmp, "%lu %lu ", (gulong) message_id.id.part.hi, (gulong)
message_id.id.part.lo);
+ references = camel_message_info_get_references (mi);
+ if (references) {
+ guint ii;
+
+ g_string_append_printf (tmp, "%lu", (gulong) references->len);
+ for (ii = 0; ii < references->len; ii++) {
+ message_id.id.id = g_array_index (references, guint64, ii);
+
+ g_string_append_printf (tmp, " %lu %lu", (gulong) message_id.id.part.hi, (gulong)
message_id.id.part.lo);
+ }
+ } else {
+ g_string_append (tmp, "0");
+ }
+ record->part = g_string_free (tmp, FALSE);
+
+ tmp = g_string_new (NULL);
+ user_flags = camel_message_info_get_user_flags (mi);
+ if (user_flags) {
+ guint ii, count;
+
+ count = camel_named_flags_get_length (user_flags);
+ for (ii = 0; ii < count; ii++) {
+ const gchar *name = camel_named_flags_get (user_flags, ii);
+
+ if (name && *name) {
+ if (tmp->len)
+ g_string_append (tmp, " ");
+ g_string_append (tmp, name);
+ }
+ }
+ }
+ record->labels = g_string_free (tmp, FALSE);
+
+ tmp = g_string_new (NULL);
+ user_tags = camel_message_info_get_user_tags (mi);
+ if (user_tags) {
+ guint ii, count;
+
+ count = camel_name_value_array_get_length (user_tags);
+ g_string_append_printf (tmp, "%lu", (gulong) count);
+
+ for (ii = 0; ii < count; ii++) {
+ const gchar *name = NULL, *value = NULL;
+
+ if (camel_name_value_array_get (user_tags, ii, &name, &value)) {
+ if (!name)
+ name = "";
+ if (!value)
+ value = "";
+
+ g_string_append_printf (tmp, " %lu-%s %lu-%s", (gulong) strlen (name), name,
(gulong) strlen (value), value);
+ }
+ }
+ } else {
+ g_string_append (tmp, "0");
+ }
+ record->usertags = g_string_free (tmp, FALSE);
+
+ return TRUE;
+}
+
+static void
+message_info_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CamelMessageInfo *mi = CAMEL_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_SUMMARY:
+ g_weak_ref_set (&mi->priv->summary, g_value_get_object (value));
+ return;
+
+ case PROP_DIRTY:
+ camel_message_info_set_dirty (mi, g_value_get_boolean (value));
+ return;
+
+ case PROP_FOLDER_FLAGGED:
+ camel_message_info_set_folder_flagged (mi, g_value_get_boolean (value));
+ return;
+
+ case PROP_ABORT_NOTIFICATIONS:
+ camel_message_info_set_abort_notifications (mi, g_value_get_boolean (value));
+ return;
+
+ case PROP_UID:
+ camel_message_info_set_uid (mi, g_value_get_string (value));
+ return;
+
+ case PROP_FLAGS:
+ camel_message_info_set_flags (mi, ~0, g_value_get_uint (value));
+ return;
+
+ case PROP_USER_FLAGS:
+ camel_message_info_take_user_flags (mi, g_value_dup_boxed (value));
+ return;
+
+ case PROP_USER_TAGS:
+ camel_message_info_take_user_tags (mi, g_value_dup_boxed (value));
+ return;
+
+ case PROP_SUBJECT:
+ camel_message_info_set_subject (mi, g_value_get_string (value));
+ return;
+
+ case PROP_FROM:
+ camel_message_info_set_from (mi, g_value_get_string (value));
+ return;
+
+ case PROP_TO:
+ camel_message_info_set_to (mi, g_value_get_string (value));
+ return;
+
+ case PROP_CC:
+ camel_message_info_set_cc (mi, g_value_get_string (value));
+ return;
+
+ case PROP_MLIST:
+ camel_message_info_set_mlist (mi, g_value_get_string (value));
+ return;
+
+ case PROP_SIZE:
+ camel_message_info_set_size (mi, g_value_get_uint (value));
+ return;
+
+ case PROP_DATE_SENT:
+ camel_message_info_set_date_sent (mi, g_value_get_int64 (value));
+ return;
+
+ case PROP_DATE_RECEIVED:
+ camel_message_info_set_date_received (mi, g_value_get_int64 (value));
+ return;
+
+ case PROP_MESSAGE_ID:
+ camel_message_info_set_message_id (mi, g_value_get_uint64 (value));
+ return;
+
+ case PROP_REFERENCES:
+ camel_message_info_take_references (mi, g_value_dup_boxed (value));
+ return;
+
+ case PROP_HEADERS:
+ camel_message_info_take_headers (mi, g_value_dup_boxed (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+message_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CamelMessageInfo *mi = CAMEL_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_SUMMARY:
+ g_value_take_object (value, camel_message_info_ref_summary (mi));
+ return;
+
+ case PROP_DIRTY:
+ g_value_set_boolean (value, camel_message_info_get_dirty (mi));
+ return;
+
+ case PROP_FOLDER_FLAGGED:
+ g_value_set_boolean (value, camel_message_info_get_folder_flagged (mi));
+ return;
+
+ case PROP_FOLDER_FLAGGED_STAMP:
+ g_value_set_uint (value, camel_message_info_get_folder_flagged_stamp (mi));
+ return;
+
+ case PROP_ABORT_NOTIFICATIONS:
+ g_value_set_boolean (value, camel_message_info_get_abort_notifications (mi));
+ return;
+
+ case PROP_UID:
+ g_value_set_string (value, camel_message_info_get_uid (mi));
+ return;
+
+ case PROP_FLAGS:
+ g_value_set_uint (value, camel_message_info_get_flags (mi));
+ return;
+
+ case PROP_USER_FLAGS:
+ g_value_take_boxed (value, camel_message_info_dup_user_flags (mi));
+ return;
+
+ case PROP_USER_TAGS:
+ g_value_take_boxed (value, camel_message_info_dup_user_tags (mi));
+ return;
+
+ case PROP_SUBJECT:
+ g_value_set_string (value, camel_message_info_get_subject (mi));
+ return;
+
+ case PROP_FROM:
+ g_value_set_string (value, camel_message_info_get_from (mi));
+ return;
+
+ case PROP_TO:
+ g_value_set_string (value, camel_message_info_get_to (mi));
+ return;
+
+ case PROP_CC:
+ g_value_set_string (value, camel_message_info_get_cc (mi));
+ return;
+
+ case PROP_MLIST:
+ g_value_set_string (value, camel_message_info_get_mlist (mi));
+ return;
+
+ case PROP_SIZE:
+ g_value_set_uint (value, camel_message_info_get_size (mi));
+ return;
+
+ case PROP_DATE_SENT:
+ g_value_set_int64 (value, camel_message_info_get_date_sent (mi));
+ return;
+
+ case PROP_DATE_RECEIVED:
+ g_value_set_int64 (value, camel_message_info_get_date_received (mi));
+ return;
+
+ case PROP_MESSAGE_ID:
+ g_value_set_uint64 (value, camel_message_info_get_message_id (mi));
+ return;
+
+ case PROP_REFERENCES:
+ g_value_take_boxed (value, camel_message_info_dup_references (mi));
+ return;
+
+ case PROP_HEADERS:
+ g_value_take_boxed (value, camel_message_info_dup_headers (mi));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+message_info_dispose (GObject *object)
+{
+ CamelMessageInfo *mi = CAMEL_MESSAGE_INFO (object);
+
+ g_weak_ref_set (&mi->priv->summary, NULL);
+ camel_pstring_free (mi->priv->uid);
+ mi->priv->uid = NULL;
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_message_info_parent_class)->dispose (object);
+}
+
+static void
+message_info_finalize (GObject *object)
+{
+ CamelMessageInfo *mi = CAMEL_MESSAGE_INFO (object);
+
+ g_weak_ref_clear (&mi->priv->summary);
+ g_rec_mutex_clear (&mi->priv->property_lock);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_message_info_parent_class)->finalize (object);
+}
+
+static void
+camel_message_info_class_init (CamelMessageInfoClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelMessageInfoPrivate));
+
+ class->clone = message_info_clone;
+ class->load = message_info_load;
+ class->save = message_info_save;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = message_info_set_property;
+ object_class->get_property = message_info_get_property;
+ object_class->dispose = message_info_dispose;
+ object_class->finalize = message_info_finalize;
+
+ /**
+ * CamelMessageInfo:summary
+ *
+ * The #CamelFolderSummary to which the message info belongs, or %NULL.
+ * It can be set only during construction of the object.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SUMMARY,
+ g_param_spec_object (
+ "summary",
+ "Summary",
+ NULL,
+ CAMEL_TYPE_FOLDER_SUMMARY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * CamelMessageInfo:uid
+ *
+ * A unique ID of the message in its folder.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_UID,
+ g_param_spec_string (
+ "uid",
+ "UID",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:dirty
+ *
+ * Flag, whether the info is changed and requires save to disk.
+ * Compare with CamelMessageInfo:folder-flagged
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_DIRTY,
+ g_param_spec_boolean (
+ "dirty",
+ "Dirty",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:folder-flagged
+ *
+ * Flag, whether the info is changed and requires save to
+ * the destination store/server. This is different from
+ * the CamelMessageInfo:dirty, which takes care of the local
+ * information only.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FOLDER_FLAGGED,
+ g_param_spec_boolean (
+ "folder-flagged",
+ "Folder Flagged",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:folder-flagged-stamp
+ *
+ * The 'folder-flagged-stamp' is a stamp of the 'folder-flagged' flag. This stamp
+ * changes whenever anything would mark the @mi 'folder-flagged', regardless the @mi
+ * being already 'folder-flagged'. It can be used to recognize changes
+ * on the 'folder-flagged' flag during the time.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FOLDER_FLAGGED_STAMP,
+ g_param_spec_uint (
+ "folder-flagged-stamp",
+ "Folder Flagged Stamp",
+ NULL,
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE));
+
+ /**
+ * CamelMessageInfo:abort-notifications
+ *
+ * Flag, whether the info is currently aborting notifications. It is used to avoid
+ * unnecessary 'folder-flagged' and 'dirty' flags changes and also to avoid
+ * associated folder's "changed" signal.
+ *f
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_ABORT_NOTIFICATIONS,
+ g_param_spec_boolean (
+ "abort-notifications",
+ "Abort Notifications",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:flags
+ *
+ * Bit-or of #CamelMessageFlags.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FLAGS,
+ g_param_spec_uint (
+ "flags",
+ "Flags",
+ NULL,
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:user-flags
+ *
+ * User flags for the associated message. Can be %NULL.
+ * Unlike user-tags, which can contain various values, the user-flags
+ * can only be set or not.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_USER_FLAGS,
+ g_param_spec_boxed (
+ "user-flags",
+ "User Flags",
+ NULL,
+ CAMEL_TYPE_NAMED_FLAGS,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:user-tags
+ *
+ * User tags for the associated message. Can be %NULL.
+ * Unlike user-flags, which can be set or not, the user-tags
+ * can contain various values.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_USER_TAGS,
+ g_param_spec_boxed (
+ "user-tags",
+ "User tags",
+ NULL,
+ CAMEL_TYPE_NAME_VALUE_ARRAY,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:subject
+ *
+ * Subject of the associated message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SUBJECT,
+ g_param_spec_string (
+ "subject",
+ "Subject",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:from
+ *
+ * From address of the associated message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FROM,
+ g_param_spec_string (
+ "from",
+ "From",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:to
+ *
+ * To address of the associated message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_TO,
+ g_param_spec_string (
+ "to",
+ "To",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:cc
+ *
+ * CC address of the associated message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_CC,
+ g_param_spec_string (
+ "cc",
+ "CC",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:mlist
+ *
+ * Mailing list address of the associated message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_MLIST,
+ g_param_spec_string (
+ "mlist",
+ "mlist",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:size
+ *
+ * Size of the associated message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SIZE,
+ g_param_spec_uint (
+ "size",
+ "Size",
+ NULL,
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:date-sent
+ *
+ * Sent Date of the associated message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_DATE_SENT,
+ g_param_spec_int64 (
+ "date-sent",
+ "Date Sent",
+ NULL,
+ G_MININT64, G_MAXINT64, 0,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:date-received
+ *
+ * Received date of the associated message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_DATE_RECEIVED,
+ g_param_spec_int64 (
+ "date-received",
+ "Date Received",
+ NULL,
+ G_MININT64, G_MAXINT64, 0,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:message-id
+ *
+ * Encoded Message-ID of the associated message as a guint64 number,
+ * partial MD5 sum. The value can be cast to #CamelSummaryMessageID.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_MESSAGE_ID,
+ g_param_spec_uint64 (
+ "message-id",
+ "Message ID",
+ NULL,
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:references
+ *
+ * Encoded In-Reply-To and References headers of the associated message
+ * as an array of guint64 numbers, partial MD5 sums. Each value can be
+ * cast to #CamelSummaryMessageID.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_REFERENCES,
+ g_param_spec_boxed (
+ "references",
+ "References",
+ NULL,
+ G_TYPE_ARRAY,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelMessageInfo:headers
+ *
+ * Headers of the associated message. Can be %NULL.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_HEADERS,
+ g_param_spec_boxed (
+ "headers",
+ "Headers",
+ NULL,
+ CAMEL_TYPE_NAME_VALUE_ARRAY,
+ G_PARAM_READWRITE));
+}
+
+static void
+camel_message_info_init (CamelMessageInfo *mi)
+{
+ mi->priv = G_TYPE_INSTANCE_GET_PRIVATE (mi, CAMEL_TYPE_MESSAGE_INFO, CamelMessageInfoPrivate);
+
+ g_rec_mutex_init (&mi->priv->property_lock);
+ g_weak_ref_init (&mi->priv->summary, NULL);
+}
+
+/**
+ * camel_message_info_new:
+ * @summary: (nullable): parent #CamelFolderSummary object, or %NULL
+ *
+ * Create a new #CamelMessageInfo object, optionally for given @summary.
+ *
+ * Returns: (transfer full): a new #CamelMessageInfo object
+ *
+ * Since: 3.24
+ **/
+CamelMessageInfo *
+camel_message_info_new (CamelFolderSummary *summary)
+{
+ GType type = CAMEL_TYPE_MESSAGE_INFO_BASE;
+
+ if (summary) {
+ CamelFolderSummaryClass *klass;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
+
+ klass = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
+ g_return_val_if_fail (klass != NULL, NULL);
+
+ type = klass->message_info_type;
+ }
+
+ return g_object_new (type, "summary", summary, NULL);
+}
+
+/**
+ * camel_message_info_clone:
+ * @mi: a #CamelMessageInfo to clone
+ * @assign_summary: (nullable): parent #CamelFolderSummary object, or %NULL, to set on the clone
+ *
+ * Clones the @mi as a new #CamelMessageInfo and eventually assigns
+ * a new #CamelFolderSummary to it. If it's not set, then the same
+ * summary as the one with @mi is used.
+ *
+ * Returns: (transfer full): a new #CamelMessageInfo object, clone of the @mi
+ *
+ * Since: 3.24
+ **/
+CamelMessageInfo *
+camel_message_info_clone (const CamelMessageInfo *mi,
+ CamelFolderSummary *assign_summary)
+{
+ CamelMessageInfoClass *klass;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+ if (assign_summary)
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (assign_summary), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->clone != NULL, NULL);
+
+ return klass->clone (mi, assign_summary);
+}
+
+/**
+ * camel_message_info_load:
+ * @mi: a #CamelMessageInfo to load
+ * @record: a #CamelMIRecord to load the @mi from
+ * @bdata_ptr: a backend specific data (bdata) pointer
+ *
+ * Load content of @mi from the data stored in @record. The @bdata_ptr points
+ * to the current position of the record->bdata, where the read can continue.
+ * Use helper functions camel_util_bdata_get_number() and camel_util_bdata_get_string()
+ * to read data from it and also move forward the *bdata_ptr.
+ *
+ * After successful load of the @mi, the 'dirty' flag is unset.
+ *
+ * Returns: Whether the load was successful.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_load (CamelMessageInfo *mi,
+ const CamelMIRecord *record,
+ /* const */ gchar **bdata_ptr)
+{
+ CamelMessageInfoClass *klass;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_ptr != NULL, FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->load != NULL, FALSE);
+
+ g_object_freeze_notify (G_OBJECT (mi));
+ camel_message_info_property_lock (mi);
+ camel_message_info_set_abort_notifications (mi, TRUE);
+
+ success = klass->load (mi, record, bdata_ptr);
+
+ if (success)
+ camel_message_info_set_dirty (mi, FALSE);
+
+ camel_message_info_set_abort_notifications (mi, FALSE);
+ camel_message_info_property_unlock (mi);
+ g_object_thaw_notify (G_OBJECT (mi));
+
+ return success;
+}
+
+/**
+ * camel_message_info_save:
+ * @mi: a #CamelMessageInfo
+ * @record: a #CamelMIRecord to populate
+ * @bdata_str: a #GString with a string to save as backend specific data (bdata)
+ *
+ * Save the @mi content to the message info record @record. It can populate all
+ * but the record->bdata value, which is set fro mthe @bdata_str. Use helper functions
+ * camel_util_bdata_put_number() and camel_util_bdata_put_string() to put data into the @bdata_str.
+ *
+ * Returns: Whether the save succeeded.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_save (const CamelMessageInfo *mi,
+ CamelMIRecord *record,
+ GString *bdata_str)
+{
+ CamelMessageInfoClass *klass;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_str != NULL, FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->save != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+
+ success = klass->save (mi, record, bdata_str);
+
+ camel_message_info_property_unlock (mi);
+
+ return success;
+}
+
+/**
+ * camel_message_info_ref_summary:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer full): Referenced #CamelFolderSummary to which the @mi belongs, or %NULL,
+ * if there is none. Use g_object_unref() for non-NULL returned values when done with it.
+ *
+ * Since: 3.24
+ **/
+CamelFolderSummary *
+camel_message_info_ref_summary (const CamelMessageInfo *mi)
+{
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ return g_weak_ref_get (&mi->priv->summary);
+}
+
+/**
+ * camel_message_info_property_lock:
+ * @mi: a #CamelMessageInfo
+ *
+ * Acquires a property lock, which is used to ensure thread safety
+ * when properties are changing. Release the lock with
+ * camel_message_info_property_unlock().
+ *
+ * Since: 3.24
+ **/
+void
+camel_message_info_property_lock (const CamelMessageInfo *mi)
+{
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (mi));
+
+ g_rec_mutex_lock (&mi->priv->property_lock);
+}
+
+/**
+ * camel_message_info_property_unlock:
+ * @mi: a #CamelMessageInfo
+ *
+ * Releases a property lock, previously acquired with
+ * camel_message_info_property_lock().
+ *
+ * Since: 3.24
+ **/
+void
+camel_message_info_property_unlock (const CamelMessageInfo *mi)
+{
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (mi));
+
+ g_rec_mutex_unlock (&mi->priv->property_lock);
+}
+
+static void
+camel_message_info_update_summary_and_folder (CamelMessageInfo *mi,
+ gboolean update_counts)
+{
+ CamelFolderSummary *summary;
+
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (mi));
+
+ camel_message_info_property_lock (mi);
+ if (camel_message_info_get_notifications_frozen (mi)) {
+ mi->priv->thaw_notify_folder = TRUE;
+ mi->priv->thaw_notify_folder_with_counts |= update_counts;
+ camel_message_info_property_unlock (mi);
+
+ return;
+ }
+ camel_message_info_property_unlock (mi);
+
+ summary = camel_message_info_ref_summary (mi);
+ if (summary) {
+ CamelFolder *folder;
+ const gchar *uid;
+
+ uid = camel_message_info_pooldup_uid (mi);
+
+ /* This is for cases when a new message info had been created,
+ but not added into the summary yet. */
+ if (uid && camel_folder_summary_check_uid (summary, uid) &&
+ camel_folder_summary_peek_loaded (summary, uid) == mi) {
+ if (update_counts) {
+ camel_folder_summary_lock (summary);
+ g_object_freeze_notify (G_OBJECT (summary));
+
+ camel_folder_summary_replace_flags (summary, mi);
+
+ g_object_thaw_notify (G_OBJECT (summary));
+ camel_folder_summary_unlock (summary);
+ }
+
+ folder = camel_folder_summary_get_folder (summary);
+ if (folder) {
+ CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
+
+ camel_folder_change_info_change_uid (changes, uid);
+ camel_folder_changed (folder, changes);
+ camel_folder_change_info_free (changes);
+ }
+ }
+
+ g_clear_object (&summary);
+ camel_pstring_free (uid);
+ }
+}
+
+/**
+ * camel_message_info_get_dirty:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: Whether the @mi is dirty, which means that it had been
+ * changed and a save to the local summary is required.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_get_dirty (const CamelMessageInfo *mi)
+{
+ gboolean result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ camel_message_info_property_lock (mi);
+ result = mi->priv->dirty;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_dirty:
+ * @mi: a #CamelMessageInfo
+ * @dirty: a dirty state to set
+ *
+ * Marks the @mi as dirty, which means a save to the local summary
+ * is required. In case the @dirty is %TRUE and the @mi is not aborting notifications,
+ * the 'dirty-stamp' changes too.
+ *
+ * Since: 3.24
+ **/
+void
+camel_message_info_set_dirty (const CamelMessageInfo *mi,
+ gboolean dirty)
+{
+ gboolean changed, abort_notifications;
+
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (mi));
+
+ camel_message_info_property_lock (mi);
+
+ changed = (!mi->priv->dirty) != (!dirty);
+ if (changed)
+ mi->priv->dirty = dirty;
+ abort_notifications = mi->priv->abort_notifications;
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "dirty");
+
+ if (dirty) {
+ CamelFolderSummary *summary;
+
+ summary = camel_message_info_ref_summary (mi);
+ if (summary)
+ camel_folder_summary_touch (summary);
+
+ g_clear_object (&summary);
+ }
+ }
+}
+
+/**
+ * camel_message_info_get_folder_flagged:
+ * @mi: a #CamelMessageInfo
+ *
+ * The folder flagged flag is used to mark the message infor as being changed
+ * and this change should be propagated to the remote store (server). This is
+ * different from the 'dirty' flag, which is set for local changes only. It
+ * can happen that the 'folder-flagged' flag is set, but the 'dirty' flag not.
+ *
+ * This is only a convenient wrapper around CAMEL_MESSAGE_FOLDER_FLAGGED flag,
+ * for better readiness of the code.
+ *
+ * Returns: Whether requires save of the local changes into the remote store.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_get_folder_flagged (const CamelMessageInfo *mi)
+{
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ return (camel_message_info_get_flags (mi) & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0;
+}
+
+/**
+ * camel_message_info_set_folder_flagged:
+ * @mi: a #CamelMessageInfo
+ * folder_flagged: a value to set to
+ *
+ * Changes the folder-flagged flag to the @folder_flagged value. See
+ * camel_message_info_get_folder_flagged() for more information about
+ * the use of this flag.
+ *
+ * This is only a convenient wrapper around CAMEL_MESSAGE_FOLDER_FLAGGED flag,
+ * for better readiness of the code.
+ *
+ * Returns: Whether the flag had been changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_folder_flagged (CamelMessageInfo *mi,
+ gboolean folder_flagged)
+{
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ /* g_object_notify (G_OBJECT (mi), "folder-flagged");
+ is called as part of the set_flags function */
+
+ return camel_message_info_set_flags (mi, CAMEL_MESSAGE_FOLDER_FLAGGED,
+ folder_flagged ? CAMEL_MESSAGE_FOLDER_FLAGGED : 0);
+}
+
+/**
+ * camel_message_info_get_folder_flagged_stamp:
+ * @mi: a #CamelMessageInfo
+ *
+ * The 'folder-flagged-stamp' is a stamp of the 'folder-flagged' flag. This stamp
+ * changes whenever anything would mark the @mi as 'folder-flagged', regardless
+ * the @mi being already 'folder-flagged'. It can be used to recognize changes
+ * on the 'folder-flagged' flag during the time.
+ *
+ * Returns: Stamp of the 'folder-flagged' flag.
+ *
+ * Since: 3.24
+ **/
+guint
+camel_message_info_get_folder_flagged_stamp (const CamelMessageInfo *mi)
+{
+ guint result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), ~0);
+
+ camel_message_info_property_lock (mi);
+ result = mi->priv->folder_flagged_stamp;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_get_abort_notifications:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: Whether the @mi is aborting notifications, which means
+ * that it will not influence 'dirty' and 'folder-flagged' flags
+ * in the set/take functions, neither it will emit any GObject::notify
+ * signals on change, nor associated folder's "changed" signal.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_get_abort_notifications (const CamelMessageInfo *mi)
+{
+ gboolean result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ camel_message_info_property_lock (mi);
+ result = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_abort_notifications:
+ * @mi: a #CamelMessageInfo
+ * @abort_notifications: a state to set
+ *
+ * Marks the @mi to abort any notifications, which means that it
+ * will not influence 'dirty' and 'folder-flagged' flags in
+ * the set/take functions, neither it will emit any GObject::notify
+ * signals on change, nor associated folder's "changed" signal.
+ *
+ * Since: 3.24
+ **/
+void
+camel_message_info_set_abort_notifications (CamelMessageInfo *mi,
+ gboolean abort_notifications)
+{
+ gboolean changed;
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (mi));
+
+ camel_message_info_property_lock (mi);
+ changed = (!mi->priv->abort_notifications) != (!abort_notifications);
+ if (changed)
+ mi->priv->abort_notifications = abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed)
+ g_object_notify (G_OBJECT (mi), "abort-notifications");
+}
+
+/**
+ * camel_message_info_freeze_notifications:
+ * @mi: a #CamelMessageInfo
+ *
+ * Freezes all the notifications until the camel_message_info_thaw_notifications() is called.
+ * This function can be called multiple times, where the last thaw will do the notifications.
+ *
+ * Since: 3.24
+ **/
+void
+camel_message_info_freeze_notifications (CamelMessageInfo *mi)
+{
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (mi));
+
+ camel_message_info_property_lock (mi);
+ mi->priv->freeze_notifications++;
+ if (mi->priv->freeze_notifications == 1) {
+ mi->priv->thaw_notify_folder = FALSE;
+ mi->priv->thaw_notify_folder_with_counts = FALSE;
+ g_object_freeze_notify (G_OBJECT (mi));
+ }
+ camel_message_info_property_unlock (mi);
+}
+
+/**
+ * camel_message_info_thaw_notifications:
+ * @mi: a #CamelMessageInfo
+ *
+ * Reverses the call of the camel_message_info_freeze_notifications().
+ * If this is the last freeze, then the associated folder is also notified
+ * about the change, if any happened during the freeze.
+ *
+ * Since: 3.24
+ **/
+void
+camel_message_info_thaw_notifications (CamelMessageInfo *mi)
+{
+ g_return_if_fail (CAMEL_IS_MESSAGE_INFO (mi));
+
+ camel_message_info_property_lock (mi);
+ if (!mi->priv->freeze_notifications) {
+ camel_message_info_property_unlock (mi);
+
+ g_warn_if_reached ();
+ return;
+ }
+
+ mi->priv->freeze_notifications--;
+ if (!mi->priv->freeze_notifications) {
+ gboolean notify_folder, notify_folder_with_counts;
+
+ notify_folder = mi->priv->thaw_notify_folder;
+ notify_folder_with_counts = mi->priv->thaw_notify_folder_with_counts;
+
+ camel_message_info_property_unlock (mi);
+
+ g_object_thaw_notify (G_OBJECT (mi));
+
+ if (notify_folder)
+ camel_message_info_update_summary_and_folder (mi, notify_folder_with_counts);
+ } else {
+ camel_message_info_property_unlock (mi);
+ }
+}
+
+/**
+ * camel_message_info_get_notifications_frozen:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: Whether the notifications are frozen.
+ *
+ * See: camel_message_info_freeze_notifications()
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_get_notifications_frozen (const CamelMessageInfo *mi)
+{
+ gboolean result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ camel_message_info_property_lock (mi);
+ result = mi->priv->freeze_notifications > 0;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_get_uid:
+ * @mi: a #CamelMessageInfo
+ *
+ * Get the UID of the #mi.
+ *
+ * Returns: (transfer none): The UID of the @mi.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_message_info_get_uid (const CamelMessageInfo *mi)
+{
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ camel_message_info_property_lock (mi);
+ result = mi->priv->uid;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_pooldup_uid:
+ * @mi: a #CamelMessageInfo
+ *
+ * Get the UID of the #mi, duplicated on the Camel's string pool.
+ * This is good for thread safety, though the UID should not change once set.
+ *
+ * Returns: A newly references string in the string pool, the #mi UID.
+ * Free it with camel_pstring_free() when no longer needed.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_message_info_pooldup_uid (const CamelMessageInfo *mi)
+{
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ camel_message_info_property_lock (mi);
+ result = camel_pstring_strdup (mi->priv->uid);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_uid:
+ * @mi: a #CamelMessageInfo
+ * @uid: a UID to set
+ *
+ * Changes UID of the @mi to @uid. If it changes, the 'dirty' flag
+ * of the @mi is set too, unless the @mi is aborting notifications. This change
+ * does not influence the 'folder-flagged' flag.
+ *
+ * Returns: Whether the UID changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_uid (CamelMessageInfo *mi,
+ const gchar *uid)
+{
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = mi->priv->uid != uid && g_strcmp0 (mi->priv->uid, uid) != 0;
+ if (changed) {
+ camel_pstring_free (mi->priv->uid);
+ mi->priv->uid = camel_pstring_strdup (uid);
+ }
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "uid");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_flags:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: Bit-or of #CamelMessageFlags set on the @mi.
+ *
+ * Since: 3.24
+ **/
+guint32
+camel_message_info_get_flags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ guint32 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), 0);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, 0);
+ g_return_val_if_fail (klass->get_flags != NULL, 0);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_flags (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_flags:
+ * @mi: a #CamelMessageInfo
+ * @mask: mask of flags to change
+ * @set: state the flags should be changed to
+ *
+ * Change the state of the flags on the @mi. Both @mask and @set are bit-or
+ * of #CamelMessageFlags.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is also emitted
+ * folder's "changed" signal for this @mi, if necessary. In case
+ * the CAMEL_MESSAGE_FOLDER_FLAGGED flag would be set and the @mi is
+ * not aborting notifications, the 'folder-flagged-stamp' changes too.
+ *
+ * Returns: Whether the flags changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_flags (CamelMessageInfo *mi,
+ guint32 mask,
+ guint32 set)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_flags != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+
+ changed = klass->set_flags (mi, mask, set);
+ abort_notifications = mi->priv->abort_notifications;
+
+ if (!abort_notifications &&
+ (mask & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0 &&
+ (set & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0)
+ mi->priv->folder_flagged_stamp++;
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "flags");
+ camel_message_info_set_dirty (mi, TRUE);
+
+ /* Only if the folder-flagged was not part of the change */
+ if (!(mask & CAMEL_MESSAGE_FOLDER_FLAGGED))
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ else
+ g_object_notify (G_OBJECT (mi), "folder-flagged");
+
+ camel_message_info_update_summary_and_folder (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_user_flag:
+ * @mi: a #CamelMessageInfo
+ * @name: user flag name
+ *
+ * Returns: Whther the user flag named @name is set.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_get_user_flag (const CamelMessageInfo *mi,
+ const gchar *name)
+{
+ CamelMessageInfoClass *klass;
+ gboolean result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->get_user_flag != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_user_flag (mi, name);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_user_flag:
+ * @mi: a #CamelMessageInfo
+ * @name: user flag name
+ * @state: state to set for the flag
+ *
+ * Change @state of the flag named @name. Unlike user tags, user flags
+ * can only be set or unset, while the user tags can contain certain values.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is also emitted
+ * folder's "changed" signal for this @mi, if necessary.
+ *
+ * Returns: Whether the message info changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_user_flag (CamelMessageInfo *mi,
+ const gchar *name,
+ gboolean state)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_user_flag != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_user_flag (mi, name, state);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "user-flags");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+
+ camel_message_info_update_summary_and_folder (mi, FALSE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_user_flags:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer none) (nullable): A #CamelNamedFlags with all the currently set
+ * user flags on the @mi. Do not modify it.
+ *
+ * Since: 3.24
+ **/
+const CamelNamedFlags *
+camel_message_info_get_user_flags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const CamelNamedFlags *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_user_flags != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_user_flags (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_dup_user_flags:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer full): A newly allocated #CamelNamedFlags with all the currently set
+ * user flags on the @mi. Free the returned structure with camel_named_flags_free()
+ * when no londer needed.
+ *
+ * Since: 3.24
+ **/
+CamelNamedFlags *
+camel_message_info_dup_user_flags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ CamelNamedFlags *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->dup_user_flags != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->dup_user_flags (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_take_user_flags:
+ * @mi: a #CamelMessageInfo
+ * @user_flags: (transfer full) (nullable): user flags to set
+ *
+ * Takes all the @user_flags, which replaces any current user flags on the @mi.
+ * The passed-in @user_flags is consumed by the @mi, which becomes an owner
+ * of it. The caller should not change @user_flags afterwards.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is also emitted
+ * folder's "changed" signal for this @mi, if necessary.
+ *
+ * Note that it's not safe to use the @user_flags after the call to this function,
+ * because it can be freed due to no change.
+ *
+ * Returns: Whether the message info changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_take_user_flags (CamelMessageInfo *mi,
+ CamelNamedFlags *user_flags)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->take_user_flags != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->take_user_flags (mi, user_flags);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "user-flags");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+
+ camel_message_info_update_summary_and_folder (mi, FALSE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_user_tag:
+ * @mi: a #CamelMessageInfo
+ * @name: user tag name
+ *
+ * Returns: (transfer none) (nullable): Value of the user tag, or %NULL when
+ * it is not set.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_message_info_get_user_tag (const CamelMessageInfo *mi,
+ const gchar *name)
+{
+ CamelMessageInfoClass *klass;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_user_tag != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_user_tag (mi, name);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_dup_user_tag:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer full) (nullable): Value of the user tag as newly allocated
+ * string, or %NULL when it is not set. Free it with g_free() when no longer needed.
+ *
+ * Since: 3.24
+ **/
+gchar *
+camel_message_info_dup_user_tag (const CamelMessageInfo *mi,
+ const gchar *name)
+{
+ gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = g_strdup (camel_message_info_get_user_tag (mi, name));
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_user_tag:
+ * @mi: a #CamelMessageInfo
+ * @name: user tag name
+ * @value: (nullable): user tag value, or %NULL to remove the user tag
+ *
+ * Set user tag @name to @value, or remove it, if @value is %NULL.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is also emitted
+ * folder's "changed" signal for this @mi, if necessary.
+ *
+ * Returns: Whether the @mi changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_user_tag (CamelMessageInfo *mi,
+ const gchar *name,
+ const gchar *value)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_user_tag != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_user_tag (mi, name, value);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "user-tags");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+
+ camel_message_info_update_summary_and_folder (mi, FALSE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_user_tags:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer none) (nullable): a #CamelNameValueArray containing all set
+ * user tags of the @mi. Do not modify it.
+ *
+ * Since: 3.24
+ **/
+const CamelNameValueArray *
+camel_message_info_get_user_tags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_user_tags != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_user_tags (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_dup_user_tags:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer full) (nullable): a newly allocated #CamelNameValueArray containing all set
+ * user tags of the @mi. Free it with camel_name_value_array_free() when no longer needed.
+ *
+ * Since: 3.24
+ **/
+CamelNameValueArray *
+camel_message_info_dup_user_tags (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->dup_user_tags != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->dup_user_tags (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_take_user_tags:
+ * @mi: a #CamelMessageInfo
+ * @user_tags: (transfer full) (nullable): user tags to set
+ *
+ * Takes all the @user_tags, which replaces any current user tags on the @mi.
+ * The passed-in @user_tags is consumed by the @mi, which becomes an owner
+ * of it. The caller should not change @user_tags afterwards.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is also emitted
+ * folder's "changed" signal for this @mi, if necessary.
+ *
+ * Note that it's not safe to use the @user_tags after the call to this function,
+ * because it can be freed due to no change.
+ *
+ * Returns: Whether the @mi changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_take_user_tags (CamelMessageInfo *mi,
+ CamelNameValueArray *user_tags)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->take_user_tags != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->take_user_tags (mi, user_tags);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "user-tags");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+
+ camel_message_info_update_summary_and_folder (mi, FALSE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_subject:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer none): Subject of the #mi.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_message_info_get_subject (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_subject != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_subject (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_subject:
+ * @mi: a #CamelMessageInfo
+ * @subject: (nullable): a Subject to set
+ *
+ * Sets Subject from the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_subject (CamelMessageInfo *mi,
+ const gchar *subject)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_subject != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_subject (mi, subject);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "subject");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_from:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer none): From address of the @mi.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_message_info_get_from (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_from != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_from (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_from:
+ * @mi: a #CamelMessageInfo
+ * @from: (nullable): a From to set
+ *
+ * Sets From from the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_from (CamelMessageInfo *mi,
+ const gchar *from)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_from != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_from (mi, from);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "from");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_to:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer none): To address of the @mi.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_message_info_get_to (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_to != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_to (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_to:
+ * @mi: a #CamelMessageInfo
+ * @to: (nullable): a To to set
+ *
+ * Sets To from the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_to (CamelMessageInfo *mi,
+ const gchar *to)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_to != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_to (mi, to);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "to");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_cc:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer none): CC address of the @mi.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_message_info_get_cc (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_cc != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_cc (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_cc:
+ * @mi: a #CamelMessageInfo
+ * @cc: (nullable): a CC to set
+ *
+ * Sets CC from the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_cc (CamelMessageInfo *mi,
+ const gchar *cc)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_cc != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_cc (mi, cc);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "cc");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_mlist:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer none): Mailing list address of the @mi.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_message_info_get_mlist (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_mlist != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_mlist (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_mlist:
+ * @mi: a #CamelMessageInfo
+ * @mlist: (nullable): a message list address to set
+ *
+ * Sets mesage list address from the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_mlist (CamelMessageInfo *mi,
+ const gchar *mlist)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_mlist != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_mlist (mi, mlist);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "mlist");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_size:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: Size of the associated message.
+ *
+ * Since: 3.24
+ **/
+guint32
+camel_message_info_get_size (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ guint32 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), 0);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, 0);
+ g_return_val_if_fail (klass->get_size != NULL, 0);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_size (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_size:
+ * @mi: a #CamelMessageInfo
+ * @size: a size to set
+ *
+ * Sets size of the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_size (CamelMessageInfo *mi,
+ guint32 size)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_size != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_size (mi, size);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "size");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_date_sent:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: time_t of the Date header of the message, encoded as gint64.
+ *
+ * Since: 3.24
+ **/
+gint64
+camel_message_info_get_date_sent (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ gint64 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), 0);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, 0);
+ g_return_val_if_fail (klass->get_date_sent != NULL, 0);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_date_sent (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_date_sent:
+ * @mi: a #CamelMessageInfo
+ * @date_sent: a sent date to set
+ *
+ * Sets sent date (the Date header) of the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_date_sent (CamelMessageInfo *mi,
+ gint64 date_sent)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_date_sent != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_date_sent (mi, date_sent);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "date-sent");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_date_received:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: time_t of the Received header of the message, encoded as gint64.
+ *
+ * Since: 3.24
+ **/
+gint64
+camel_message_info_get_date_received (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ gint64 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), 0);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, 0);
+ g_return_val_if_fail (klass->get_date_received != NULL, 0);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_date_received (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_date_received:
+ * @mi: a #CamelMessageInfo
+ * @date_received: a received date to set
+ *
+ * Sets received date (the Received header) of the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_date_received (CamelMessageInfo *mi,
+ gint64 date_received)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_date_received != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_date_received (mi, date_received);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "date-received");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_message_id:
+ * @mi: a #CamelMessageInfo
+ *
+ * Encoded Message-ID of the associated message as a guint64 number,
+ * partial MD5 sum. The value can be cast to #CamelSummaryMessageID.
+ *
+ * Returns: Partial MD5 hash of the Message-ID header of the associated message.
+ *
+ * Since: 3.24
+ **/
+guint64
+camel_message_info_get_message_id (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ guint64 result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), 0);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, 0);
+ g_return_val_if_fail (klass->get_message_id != NULL, 0);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_message_id (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_set_message_id:
+ * @mi: a #CamelMessageInfo
+ * @message_id: a message id to set
+ *
+ * Sets encoded Message-ID of the associated message as a guint64 number,
+ * partial MD5 sum. The value can be cast to #CamelSummaryMessageID.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_set_message_id (CamelMessageInfo *mi,
+ guint64 message_id)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->set_message_id != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->set_message_id (mi, message_id);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "message-id");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_references:
+ * @mi: a #CamelMessageInfo
+ *
+ * Gets encoded In-Reply-To and References headers of the associated
+ * message as an array of guint64 numbers, partial MD5 sums. Each value
+ * can be cast to #CamelSummaryMessageID.
+ *
+ * Returns: (transfer none) (nullable) (element-type guint64): A #GArray of
+ * guint64 encoded Message-ID-s; or %NULL when none are available.
+ *
+ * Since: 3.24
+ **/
+const GArray *
+camel_message_info_get_references (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const GArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_references != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_references (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_dup_references:
+ * @mi: a #CamelMessageInfo
+ *
+ * Duplicates encoded In-Reply-To and References headers of the associated
+ * message as an array of guint64 numbers, partial MD5 sums. Each value
+ * can be cast to #CamelSummaryMessageID.
+ *
+ * Returns: (transfer full) (nullable) (element-type guint64): A #GArray of
+ * guint64 encoded Message-ID-s; or %NULL when none are available. Free returned
+ * array with g_array_unref() when no longer needed.
+ *
+ * Since: 3.24
+ **/
+GArray *
+camel_message_info_dup_references (const CamelMessageInfo *mi)
+{
+ const GArray *arr;
+ GArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ camel_message_info_property_lock (mi);
+ arr = camel_message_info_get_references (mi);
+ if (arr) {
+ guint ii;
+
+ result = g_array_sized_new (FALSE, FALSE, sizeof (guint64), arr->len);
+ for (ii = 0; ii < arr->len; ii++) {
+ g_array_append_val (result, g_array_index (arr, guint64, ii));
+ }
+ } else {
+ result = NULL;
+ }
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_take_references:
+ * @mi: a #CamelMessageInfo
+ * @references: (element-type guint64) (transfer full) (nullable): a references to set
+ *
+ * Takes encoded In-Reply-To and References headers of the associated message
+ * as an array of guint64 numbers, partial MD5 sums. Each value can be
+ * cast to #CamelSummaryMessageID.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Note that it's not safe to use the @references after the call to this function,
+ * because it can be freed due to no change.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_take_references (CamelMessageInfo *mi,
+ GArray *references)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->take_references != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->take_references (mi, references);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "references");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_get_headers:
+ * @mi: a #CamelMessageInfo
+ *
+ * Returns: (transfer none) (nullable): All the message headers of the associated
+ * message, or %NULL, when none are available.
+ *
+ * Since: 3.24
+ **/
+const CamelNameValueArray *
+camel_message_info_get_headers (const CamelMessageInfo *mi)
+{
+ CamelMessageInfoClass *klass;
+ const CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_headers != NULL, NULL);
+
+ camel_message_info_property_lock (mi);
+ result = klass->get_headers (mi);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_dup_headers:
+ * @mi: a #CamelMessageInfo
+ *
+ * Duplicates array of headers for the @mi.
+ *
+ * Returns: (transfer full) (nullable): All the message headers of the associated
+ * message, or %NULL, when none are available. Free returned array with
+ * camel_name_value_array_free() when no longer needed.
+ *
+ * Since: 3.24
+ **/
+CamelNameValueArray *
+camel_message_info_dup_headers (const CamelMessageInfo *mi)
+{
+ const CamelNameValueArray *arr;
+ CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), NULL);
+
+ camel_message_info_property_lock (mi);
+ arr = camel_message_info_get_headers (mi);
+ if (arr) {
+ result = camel_name_value_array_copy (arr);
+ } else {
+ result = NULL;
+ }
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+/**
+ * camel_message_info_take_headers:
+ * @mi: a #CamelMessageInfo
+ * @headers: (transfer full) (nullable): headers to set, as #CamelNameValueArray, or %NULL
+ *
+ * Takes headers of the associated message.
+ *
+ * This property is considered static, in a meaning that it should
+ * not change during the life-time of the @mi, the same as it doesn't
+ * change in the associated message.
+ *
+ * If the @mi changed, the 'dirty' flag and the 'folder-flagged' flag are
+ * set automatically, unless the @mi is aborting notifications. There is not emitted
+ * folder's "changed" signal for this @mi.
+ *
+ * Note that it's not safe to use the @headers after the call to this function,
+ * because it can be freed due to no change.
+ *
+ * Returns: Whether the value changed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_message_info_take_headers (CamelMessageInfo *mi,
+ CamelNameValueArray *headers)
+{
+ CamelMessageInfoClass *klass;
+ gboolean changed, abort_notifications;
+
+ g_return_val_if_fail (CAMEL_IS_MESSAGE_INFO (mi), FALSE);
+
+ klass = CAMEL_MESSAGE_INFO_GET_CLASS (mi);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->take_headers != NULL, FALSE);
+
+ camel_message_info_property_lock (mi);
+ changed = klass->take_headers (mi, headers);
+ abort_notifications = mi->priv->abort_notifications;
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !abort_notifications) {
+ g_object_notify (G_OBJECT (mi), "headers");
+ camel_message_info_set_dirty (mi, TRUE);
+ camel_message_info_set_folder_flagged (mi, TRUE);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_message_info_dump:
+ * @mi: a #CamelMessageInfo
+ *
+ * Dumps the mesasge info @mi to stdout. This is meand for debugging
+ * purposes only.
+ *
+ * Since: 3.24
+ **/
+void
+camel_message_info_dump (CamelMessageInfo *mi)
+{
+ if (!mi) {
+ printf ("No message info\n");
+ return;
+ }
+
+ camel_message_info_property_lock (mi);
+
+ printf ("Message info %s:\n", G_OBJECT_TYPE_NAME (mi));
+ printf (" UID: %s\n", camel_message_info_get_uid (mi));
+ printf (" Flags: %04x\n", camel_message_info_get_flags (mi));
+ printf (" From: %s\n", camel_message_info_get_from (mi));
+ printf (" To: %s\n", camel_message_info_get_to (mi));
+ printf (" Cc: %s\n", camel_message_info_get_cc (mi));
+ printf (" Mailing list: %s\n", camel_message_info_get_mlist (mi));
+ printf (" Subject: %s\n", camel_message_info_get_subject (mi));
+
+ camel_message_info_property_unlock (mi);
+}
diff --git a/src/camel/camel-message-info.h b/src/camel/camel-message-info.h
new file mode 100644
index 0000000..7b355cb
--- /dev/null
+++ b/src/camel/camel-message-info.h
@@ -0,0 +1,328 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_MESSAGE_INFO_H
+#define CAMEL_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel-named-flags.h>
+#include <camel/camel-name-value-array.h>
+#include <camel/camel-utils.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_MESSAGE_INFO \
+ (camel_message_info_get_type ())
+#define CAMEL_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_MESSAGE_INFO, CamelMessageInfo))
+#define CAMEL_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_MESSAGE_INFO, CamelMessageInfoClass))
+#define CAMEL_IS_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_MESSAGE_INFO))
+#define CAMEL_IS_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_MESSAGE_INFO))
+#define CAMEL_MESSAGE_INFO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_MESSAGE_INFO, CamelMessageInfoClass))
+
+G_BEGIN_DECLS
+
+/* Forward declarations */
+struct _CamelFolderSummary;
+struct _CamelMIRecord;
+
+/* A summary messageid is a 64 bit identifier (partial md5 hash) */
+typedef struct _CamelSummaryMessageID {
+ union {
+ guint64 id;
+ guchar hash[8];
+ struct {
+ guint32 hi;
+ guint32 lo;
+ } part;
+ } id;
+} CamelSummaryMessageID;
+
+/* system flag bits */
+typedef enum _CamelMessageFlags {
+ CAMEL_MESSAGE_ANSWERED = 1 << 0,
+ CAMEL_MESSAGE_DELETED = 1 << 1,
+ CAMEL_MESSAGE_DRAFT = 1 << 2,
+ CAMEL_MESSAGE_FLAGGED = 1 << 3,
+ CAMEL_MESSAGE_SEEN = 1 << 4,
+
+ /* these aren't really system flag bits, but are convenience flags */
+ CAMEL_MESSAGE_ATTACHMENTS = 1 << 5,
+ CAMEL_MESSAGE_ANSWERED_ALL = 1 << 6,
+ CAMEL_MESSAGE_JUNK = 1 << 7,
+ CAMEL_MESSAGE_SECURE = 1 << 8,
+ CAMEL_MESSAGE_NOTJUNK = 1 << 9,
+ CAMEL_MESSAGE_FORWARDED = 1 << 10,
+
+ /* following flags are for the folder, and are not really permanent flags */
+ CAMEL_MESSAGE_FOLDER_FLAGGED = 1 << 16, /* for use by the folder implementation */
+ /* flags after 1 << 16 are used by camel providers,
+ * if adding non permanent flags, add them to the end */
+
+ CAMEL_MESSAGE_JUNK_LEARN = 1 << 30, /* used when setting CAMEL_MESSAGE_JUNK flag
+ * to say that we request junk plugin
+ * to learn that message as junk/non junk */
+ CAMEL_MESSAGE_USER = 1 << 31 /* supports user flags */
+} CamelMessageFlags;
+
+/* Changes to system flags will NOT trigger a folder changed event */
+#define CAMEL_MESSAGE_SYSTEM_MASK (0xffff << 16)
+
+typedef struct _CamelMessageInfo CamelMessageInfo;
+typedef struct _CamelMessageInfoClass CamelMessageInfoClass;
+typedef struct _CamelMessageInfoPrivate CamelMessageInfoPrivate;
+
+struct _CamelMessageInfo {
+ GObject parent;
+ CamelMessageInfoPrivate *priv;
+};
+
+struct _CamelMessageInfoClass {
+ GObjectClass parent_class;
+
+ CamelMessageInfo * (* clone) (const CamelMessageInfo *mi,
+ struct _CamelFolderSummary *assign_summary);
+ gboolean (* load) (CamelMessageInfo *mi,
+ const struct _CamelMIRecord *record,
+ /* const */ gchar **bdata_ptr);
+ gboolean (* save) (const CamelMessageInfo *mi,
+ struct _CamelMIRecord *record,
+ GString *bdata_str);
+ guint32 (* get_flags) (const CamelMessageInfo *mi);
+ gboolean (* set_flags) (CamelMessageInfo *mi,
+ guint32 mask,
+ guint32 set);
+ gboolean (* get_user_flag)
+ (const CamelMessageInfo *mi,
+ const gchar *name);
+ gboolean (* set_user_flag)
+ (CamelMessageInfo *mi,
+ const gchar *name,
+ gboolean state);
+ const CamelNamedFlags * (* get_user_flags)
+ (const CamelMessageInfo *mi);
+ CamelNamedFlags * (* dup_user_flags)
+ (const CamelMessageInfo *mi);
+ gboolean (* take_user_flags)
+ (CamelMessageInfo *mi,
+ CamelNamedFlags *user_flags);
+ const gchar * (* get_user_tag)(const CamelMessageInfo *mi,
+ const gchar *name);
+ gboolean (* set_user_tag)(CamelMessageInfo *mi,
+ const gchar *name,
+ const gchar *value);
+ const CamelNameValueArray *
+ (* get_user_tags)
+ (const CamelMessageInfo *mi);
+ CamelNameValueArray * (* dup_user_tags)
+ (const CamelMessageInfo *mi);
+ gboolean (* take_user_tags)
+ (CamelMessageInfo *mi,
+ CamelNameValueArray *user_tags);
+ const gchar * (* get_subject) (const CamelMessageInfo *mi);
+ gboolean (* set_subject) (CamelMessageInfo *mi,
+ const gchar *subject);
+ const gchar * (* get_from) (const CamelMessageInfo *mi);
+ gboolean (* set_from) (CamelMessageInfo *mi,
+ const gchar *from);
+ const gchar * (* get_to) (const CamelMessageInfo *mi);
+ gboolean (* set_to) (CamelMessageInfo *mi,
+ const gchar *to);
+ const gchar * (* get_cc) (const CamelMessageInfo *mi);
+ gboolean (* set_cc) (CamelMessageInfo *mi,
+ const gchar *cc);
+ const gchar * (* get_mlist) (const CamelMessageInfo *mi);
+ gboolean (* set_mlist) (CamelMessageInfo *mi,
+ const gchar *mlist);
+ guint32 (* get_size) (const CamelMessageInfo *mi);
+ gboolean (* set_size) (CamelMessageInfo *mi,
+ guint32 size);
+ gint64 (* get_date_sent)
+ (const CamelMessageInfo *mi);
+ gboolean (* set_date_sent)
+ (CamelMessageInfo *mi,
+ gint64 date_sent);
+ gint64 (* get_date_received)
+ (const CamelMessageInfo *mi);
+ gboolean (* set_date_received)
+ (CamelMessageInfo *mi,
+ gint64 date_received);
+ guint64 (* get_message_id)
+ (const CamelMessageInfo *mi);
+ gboolean (* set_message_id)
+ (CamelMessageInfo *mi,
+ guint64 message_id);
+ const GArray * (* get_references)
+ (const CamelMessageInfo *mi);
+ gboolean (* take_references)
+ (CamelMessageInfo *mi,
+ GArray *references);
+ const CamelNameValueArray *
+ (* get_headers) (const CamelMessageInfo *mi);
+ gboolean (* take_headers)(CamelMessageInfo *mi,
+ CamelNameValueArray *headers);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
+};
+
+GType camel_message_info_get_type (void);
+CamelMessageInfo *
+ camel_message_info_new (struct _CamelFolderSummary *summary);
+CamelMessageInfo *
+ camel_message_info_clone (const CamelMessageInfo *mi,
+ struct _CamelFolderSummary *assign_summary);
+gboolean camel_message_info_load (CamelMessageInfo *mi,
+ const struct _CamelMIRecord *record,
+ /* const */ gchar **bdata_ptr);
+gboolean camel_message_info_save (const CamelMessageInfo *mi,
+ struct _CamelMIRecord *record,
+ GString *bdata_str);
+struct _CamelFolderSummary *
+ camel_message_info_ref_summary (const CamelMessageInfo *mi);
+void camel_message_info_property_lock
+ (const CamelMessageInfo *mi);
+void camel_message_info_property_unlock
+ (const CamelMessageInfo *mi);
+gboolean camel_message_info_get_dirty (const CamelMessageInfo *mi);
+void camel_message_info_set_dirty (const CamelMessageInfo *mi,
+ gboolean dirty);
+gboolean camel_message_info_get_folder_flagged
+ (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_folder_flagged
+ (CamelMessageInfo *mi,
+ gboolean folder_flagged);
+guint camel_message_info_get_folder_flagged_stamp
+ (const CamelMessageInfo *mi);
+gboolean camel_message_info_get_abort_notifications
+ (const CamelMessageInfo *mi);
+void camel_message_info_set_abort_notifications
+ (CamelMessageInfo *mi,
+ gboolean abort_notifications);
+void camel_message_info_freeze_notifications
+ (CamelMessageInfo *mi);
+void camel_message_info_thaw_notifications
+ (CamelMessageInfo *mi);
+gboolean camel_message_info_get_notifications_frozen
+ (const CamelMessageInfo *mi);
+const gchar * camel_message_info_get_uid (const CamelMessageInfo *mi);
+const gchar * camel_message_info_pooldup_uid (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_uid (CamelMessageInfo *mi,
+ const gchar *uid);
+guint32 camel_message_info_get_flags (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_flags (CamelMessageInfo *mi,
+ guint32 mask,
+ guint32 set);
+gboolean camel_message_info_get_user_flag
+ (const CamelMessageInfo *mi,
+ const gchar *name);
+gboolean camel_message_info_set_user_flag
+ (CamelMessageInfo *mi,
+ const gchar *name,
+ gboolean state);
+const CamelNamedFlags *
+ camel_message_info_get_user_flags
+ (const CamelMessageInfo *mi);
+CamelNamedFlags *
+ camel_message_info_dup_user_flags
+ (const CamelMessageInfo *mi);
+gboolean
+ camel_message_info_take_user_flags
+ (CamelMessageInfo *mi,
+ CamelNamedFlags *user_flags);
+const gchar * camel_message_info_get_user_tag (const CamelMessageInfo *mi,
+ const gchar *name);
+gchar * camel_message_info_dup_user_tag (const CamelMessageInfo *mi,
+ const gchar *name);
+gboolean camel_message_info_set_user_tag (CamelMessageInfo *mi,
+ const gchar *name,
+ const gchar *value);
+const CamelNameValueArray *
+ camel_message_info_get_user_tags
+ (const CamelMessageInfo *mi);
+CamelNameValueArray *
+ camel_message_info_dup_user_tags
+ (const CamelMessageInfo *mi);
+gboolean camel_message_info_take_user_tags
+ (CamelMessageInfo *mi,
+ CamelNameValueArray *user_tags);
+const gchar * camel_message_info_get_subject (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_subject (CamelMessageInfo *mi,
+ const gchar *subject);
+const gchar * camel_message_info_get_from (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_from (CamelMessageInfo *mi,
+ const gchar *from);
+const gchar * camel_message_info_get_to (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_to (CamelMessageInfo *mi,
+ const gchar *to);
+const gchar * camel_message_info_get_cc (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_cc (CamelMessageInfo *mi,
+ const gchar *cc);
+const gchar * camel_message_info_get_mlist (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_mlist (CamelMessageInfo *mi,
+ const gchar *mlist);
+guint32 camel_message_info_get_size (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_size (CamelMessageInfo *mi,
+ guint32 size);
+gint64 camel_message_info_get_date_sent
+ (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_date_sent
+ (CamelMessageInfo *mi,
+ gint64 date_sent);
+gint64 camel_message_info_get_date_received
+ (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_date_received
+ (CamelMessageInfo *mi,
+ gint64 date_received);
+guint64 camel_message_info_get_message_id
+ (const CamelMessageInfo *mi);
+gboolean camel_message_info_set_message_id
+ (CamelMessageInfo *mi,
+ guint64 message_id);
+const GArray * camel_message_info_get_references
+ (const CamelMessageInfo *mi);
+GArray * camel_message_info_dup_references
+ (const CamelMessageInfo *mi);
+gboolean camel_message_info_take_references
+ (CamelMessageInfo *mi,
+ GArray *references);
+const CamelNameValueArray *
+ camel_message_info_get_headers (const CamelMessageInfo *mi);
+CamelNameValueArray *
+ camel_message_info_dup_headers (const CamelMessageInfo *mi);
+gboolean camel_message_info_take_headers (CamelMessageInfo *mi,
+ CamelNameValueArray *headers);
+
+/* Debugging functions */
+void camel_message_info_dump (CamelMessageInfo *mi);
+
+G_END_DECLS
+
+#endif /* CAMEL_MESSAGE_INFO_H */
diff --git a/src/camel/camel-mime-filter-basic.h b/src/camel/camel-mime-filter-basic.h
index a393632..8ad4f29 100644
--- a/src/camel/camel-mime-filter-basic.h
+++ b/src/camel/camel-mime-filter-basic.h
@@ -59,6 +59,9 @@ struct _CamelMimeFilterBasic {
struct _CamelMimeFilterBasicClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_basic_get_type (void);
diff --git a/src/camel/camel-mime-filter-bestenc.h b/src/camel/camel-mime-filter-bestenc.h
index 9d5f95b..ff4a190 100644
--- a/src/camel/camel-mime-filter-bestenc.h
+++ b/src/camel/camel-mime-filter-bestenc.h
@@ -79,6 +79,9 @@ struct _CamelMimeFilterBestenc {
struct _CamelMimeFilterBestencClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_bestenc_get_type (void);
diff --git a/src/camel/camel-mime-filter-canon.h b/src/camel/camel-mime-filter-canon.h
index 7a725d0..495a065 100644
--- a/src/camel/camel-mime-filter-canon.h
+++ b/src/camel/camel-mime-filter-canon.h
@@ -65,6 +65,9 @@ struct _CamelMimeFilterCanon {
struct _CamelMimeFilterCanonClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_canon_get_type (void);
diff --git a/src/camel/camel-mime-filter-charset.h b/src/camel/camel-mime-filter-charset.h
index a3336dd..27d743c 100644
--- a/src/camel/camel-mime-filter-charset.h
+++ b/src/camel/camel-mime-filter-charset.h
@@ -59,6 +59,9 @@ struct _CamelMimeFilterCharset {
struct _CamelMimeFilterCharsetClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_charset_get_type (void);
diff --git a/src/camel/camel-mime-filter-crlf.h b/src/camel/camel-mime-filter-crlf.h
index 3c2ae69..47dc502 100644
--- a/src/camel/camel-mime-filter-crlf.h
+++ b/src/camel/camel-mime-filter-crlf.h
@@ -60,6 +60,9 @@ struct _CamelMimeFilterCRLF {
struct _CamelMimeFilterCRLFClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_crlf_get_type (void);
diff --git a/src/camel/camel-mime-filter-enriched.h b/src/camel/camel-mime-filter-enriched.h
index 0ffad8e..fbdf797 100644
--- a/src/camel/camel-mime-filter-enriched.h
+++ b/src/camel/camel-mime-filter-enriched.h
@@ -60,6 +60,9 @@ struct _CamelMimeFilterEnriched {
struct _CamelMimeFilterEnrichedClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_enriched_get_type (void);
diff --git a/src/camel/camel-mime-filter-from.h b/src/camel/camel-mime-filter-from.h
index 86b3d20..93f6aef 100644
--- a/src/camel/camel-mime-filter-from.h
+++ b/src/camel/camel-mime-filter-from.h
@@ -58,6 +58,9 @@ struct _CamelMimeFilterFrom {
struct _CamelMimeFilterFromClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_from_get_type (void);
diff --git a/src/camel/camel-mime-filter-gzip.h b/src/camel/camel-mime-filter-gzip.h
index ac2ca5f..0b92411 100644
--- a/src/camel/camel-mime-filter-gzip.h
+++ b/src/camel/camel-mime-filter-gzip.h
@@ -59,6 +59,9 @@ struct _CamelMimeFilterGZip {
struct _CamelMimeFilterGZipClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_gzip_get_type (void);
diff --git a/src/camel/camel-mime-filter-html.h b/src/camel/camel-mime-filter-html.h
index 71e9a9e..664b897 100644
--- a/src/camel/camel-mime-filter-html.h
+++ b/src/camel/camel-mime-filter-html.h
@@ -58,6 +58,9 @@ struct _CamelMimeFilterHTML {
struct _CamelMimeFilterHTMLClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_html_get_type (void);
diff --git a/src/camel/camel-mime-filter-index.h b/src/camel/camel-mime-filter-index.h
index 3ca3881..80a425f 100644
--- a/src/camel/camel-mime-filter-index.h
+++ b/src/camel/camel-mime-filter-index.h
@@ -59,6 +59,9 @@ struct _CamelMimeFilterIndex {
struct _CamelMimeFilterIndexClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_index_get_type (void);
diff --git a/src/camel/camel-mime-filter-linewrap.h b/src/camel/camel-mime-filter-linewrap.h
index 51bf6b7..a1229d1 100644
--- a/src/camel/camel-mime-filter-linewrap.h
+++ b/src/camel/camel-mime-filter-linewrap.h
@@ -63,6 +63,9 @@ struct _CamelMimeFilterLinewrap {
struct _CamelMimeFilterLinewrapClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_linewrap_get_type (void);
diff --git a/src/camel/camel-mime-filter-pgp.h b/src/camel/camel-mime-filter-pgp.h
index a2b9155..11ab23b 100644
--- a/src/camel/camel-mime-filter-pgp.h
+++ b/src/camel/camel-mime-filter-pgp.h
@@ -58,6 +58,9 @@ struct _CamelMimeFilterPgp {
struct _CamelMimeFilterPgpClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_pgp_get_type (void);
diff --git a/src/camel/camel-mime-filter-progress.h b/src/camel/camel-mime-filter-progress.h
index 9f8a19c..e76f5b8 100644
--- a/src/camel/camel-mime-filter-progress.h
+++ b/src/camel/camel-mime-filter-progress.h
@@ -65,6 +65,9 @@ struct _CamelMimeFilterProgress {
struct _CamelMimeFilterProgressClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_progress_get_type (void);
diff --git a/src/camel/camel-mime-filter-tohtml.h b/src/camel/camel-mime-filter-tohtml.h
index a0b9d2a..ef6d384 100644
--- a/src/camel/camel-mime-filter-tohtml.h
+++ b/src/camel/camel-mime-filter-tohtml.h
@@ -59,6 +59,9 @@ struct _CamelMimeFilterToHTML {
struct _CamelMimeFilterToHTMLClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_tohtml_get_type (void);
diff --git a/src/camel/camel-mime-filter-windows.h b/src/camel/camel-mime-filter-windows.h
index 17a3d2a..99fcd0a 100644
--- a/src/camel/camel-mime-filter-windows.h
+++ b/src/camel/camel-mime-filter-windows.h
@@ -58,6 +58,9 @@ struct _CamelMimeFilterWindows {
struct _CamelMimeFilterWindowsClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_windows_get_type (void);
diff --git a/src/camel/camel-mime-filter-yenc.c b/src/camel/camel-mime-filter-yenc.c
index ba87c9e..8f75192 100644
--- a/src/camel/camel-mime-filter-yenc.c
+++ b/src/camel/camel-mime-filter-yenc.c
@@ -380,12 +380,12 @@ static const gint yenc_crc_table[256] = {
/**
* camel_ydecode_step:
- * @in: input buffer
+ * @in: (type guchar) (array length=inlen): input buffer
* @inlen: input buffer length
- * @out: output buffer
- * @state: ydecode state
- * @pcrc: part crc state
- * @crc: crc state
+ * @out: (out) (array): output buffer
+ * @state: (out): ydecode state
+ * @pcrc: (out): part crc state
+ * @crc: (out): crc state
*
* Performs a 'decode step' on a chunk of yEncoded data of length
* @inlen pointed to by @in and writes to @out. Assumes the =ybegin
@@ -463,12 +463,12 @@ camel_ydecode_step (const guchar *in,
/**
* camel_yencode_step:
- * @in: input buffer
+ * @in: (type guchar) (array length=inlen): input buffer
* @inlen: input buffer length
- * @out: output buffer
- * @state: yencode state
- * @pcrc: part crc state
- * @crc: crc state
+ * @out: (array) (out): output buffer
+ * @state: (out): yencode state
+ * @pcrc: (out): part crc state
+ * @crc: (out): crc state
*
* Performs an yEncode 'encode step' on a chunk of raw data of length
* @inlen pointed to by @in and writes to @out.
@@ -532,12 +532,12 @@ camel_yencode_step (const guchar *in,
/**
* camel_yencode_close:
- * @in: input buffer
+ * @in: (type guchar) (array length=inlen): input buffer
* @inlen: input buffer length
- * @out: output buffer
- * @state: yencode state
- * @pcrc: part crc state
- * @crc: crc state
+ * @out: (array) (out): output buffer
+ * @state: (out): yencode state
+ * @pcrc: (out): part crc state
+ * @crc: (out): crc state
*
* Call this function when finished encoding data with
* camel_yencode_step() to flush off the remaining state.
diff --git a/src/camel/camel-mime-filter-yenc.h b/src/camel/camel-mime-filter-yenc.h
index fa9d6d7..8fce654 100644
--- a/src/camel/camel-mime-filter-yenc.h
+++ b/src/camel/camel-mime-filter-yenc.h
@@ -78,6 +78,9 @@ struct _CamelMimeFilterYenc {
struct _CamelMimeFilterYencClass {
CamelMimeFilterClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_yenc_get_type (void);
diff --git a/src/camel/camel-mime-filter.h b/src/camel/camel-mime-filter.h
index a064aed..45dfc0d 100644
--- a/src/camel/camel-mime-filter.h
+++ b/src/camel/camel-mime-filter.h
@@ -88,6 +88,9 @@ struct _CamelMimeFilterClass {
gsize *outlen,
gsize *outprespace);
void (*reset) (CamelMimeFilter *filter);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_filter_get_type (void);
diff --git a/src/camel/camel-mime-message.c b/src/camel/camel-mime-message.c
index 8f32c67..195b1f2 100644
--- a/src/camel/camel-mime-message.c
+++ b/src/camel/camel-mime-message.c
@@ -48,7 +48,24 @@
#endif
#define d(x)
-extern gint camel_verbose_debug;
+struct _CamelMimeMessagePrivate {
+ /* header fields */
+ time_t date;
+ gint date_offset; /* GMT offset */
+
+ /* cached internal copy */
+ time_t date_received;
+ gint date_received_offset; /* GMT offset */
+
+ gchar *subject;
+
+ gchar *message_id;
+
+ CamelInternetAddress *reply_to;
+ CamelInternetAddress *from;
+
+ GHashTable *recipients; /* hash table of CamelInternetAddress's */
+};
/* these 2 below should be kept in sync */
typedef enum {
@@ -100,9 +117,9 @@ process_header (CamelMedium *medium,
if (camel_address_decode ((CamelAddress *) addr, unfolded) <= 0) {
g_object_unref (addr);
} else {
- if (message->from)
- g_object_unref (message->from);
- message->from = addr;
+ if (message->priv->from)
+ g_object_unref (message->priv->from);
+ message->priv->from = addr;
}
g_free (unfolded);
break;
@@ -112,22 +129,22 @@ process_header (CamelMedium *medium,
if (camel_address_decode ((CamelAddress *) addr, unfolded) <= 0) {
g_object_unref (addr);
} else {
- if (message->reply_to)
- g_object_unref (message->reply_to);
- message->reply_to = addr;
+ if (message->priv->reply_to)
+ g_object_unref (message->priv->reply_to);
+ message->priv->reply_to = addr;
}
g_free (unfolded);
break;
case HEADER_SUBJECT:
- g_free (message->subject);
- if (((CamelDataWrapper *) message)->mime_type) {
- charset = camel_content_type_param (((CamelDataWrapper *) message)->mime_type,
"charset");
+ g_free (message->priv->subject);
+ if (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (message))) {
+ charset = camel_content_type_param (camel_data_wrapper_get_mime_type_field
(CAMEL_DATA_WRAPPER (message)), "charset");
charset = camel_iconv_charset_name (charset);
} else
charset = NULL;
unfolded = camel_header_unfold (value);
- message->subject = g_strstrip (camel_header_decode_string (unfolded, charset));
+ message->priv->subject = g_strstrip (camel_header_decode_string (unfolded, charset));
g_free (unfolded);
break;
case HEADER_TO:
@@ -136,7 +153,7 @@ process_header (CamelMedium *medium,
case HEADER_RESENT_TO:
case HEADER_RESENT_CC:
case HEADER_RESENT_BCC:
- addr = g_hash_table_lookup (message->recipients, name);
+ addr = g_hash_table_lookup (message->priv->recipients, name);
if (value) {
unfolded = camel_header_unfold (value);
camel_address_decode (CAMEL_ADDRESS (addr), unfolded);
@@ -147,18 +164,18 @@ process_header (CamelMedium *medium,
return FALSE;
case HEADER_DATE:
if (value) {
- message->date = camel_header_decode_date (value, &message->date_offset);
+ message->priv->date = camel_header_decode_date (value, &message->priv->date_offset);
} else {
- message->date = CAMEL_MESSAGE_DATE_CURRENT;
- message->date_offset = 0;
+ message->priv->date = CAMEL_MESSAGE_DATE_CURRENT;
+ message->priv->date_offset = 0;
}
break;
case HEADER_MESSAGE_ID:
- g_free (message->message_id);
+ g_free (message->priv->message_id);
if (value)
- message->message_id = camel_header_msgid_decode (value);
+ message->priv->message_id = camel_header_msgid_decode (value);
else
- message->message_id = NULL;
+ message->priv->message_id = NULL;
break;
default:
return FALSE;
@@ -180,17 +197,17 @@ mime_message_ensure_required_headers (CamelMimeMessage *message)
{
CamelMedium *medium = CAMEL_MEDIUM (message);
- if (message->from == NULL) {
+ if (message->priv->from == NULL) {
camel_medium_set_header (medium, "From", "");
}
if (!camel_medium_get_header (medium, "Date"))
camel_mime_message_set_date (
message, CAMEL_MESSAGE_DATE_CURRENT, 0);
- if (message->subject == NULL)
+ if (message->priv->subject == NULL)
camel_mime_message_set_subject (message, "No Subject");
- if (message->message_id == NULL)
+ if (message->priv->message_id == NULL)
camel_mime_message_set_message_id (message, NULL);
/* FIXME: "To" header needs to be set explicitly as well ... */
@@ -204,15 +221,8 @@ mime_message_dispose (GObject *object)
{
CamelMimeMessage *message = CAMEL_MIME_MESSAGE (object);
- if (message->reply_to != NULL) {
- g_object_unref (message->reply_to);
- message->reply_to = NULL;
- }
-
- if (message->from != NULL) {
- g_object_unref (message->from);
- message->from = NULL;
- }
+ g_clear_object (&message->priv->reply_to);
+ g_clear_object (&message->priv->from);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (camel_mime_message_parent_class)->dispose (object);
@@ -223,12 +233,11 @@ mime_message_finalize (GObject *object)
{
CamelMimeMessage *message = CAMEL_MIME_MESSAGE (object);
- g_free (message->subject);
+ g_free (message->priv->subject);
+ g_free (message->priv->message_id);
- g_free (message->message_id);
-
- g_hash_table_foreach (message->recipients, unref_recipient, NULL);
- g_hash_table_destroy (message->recipients);
+ g_hash_table_foreach (message->priv->recipients, unref_recipient, NULL);
+ g_hash_table_destroy (message->priv->recipients);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_mime_message_parent_class)->finalize (object);
@@ -271,7 +280,7 @@ mime_message_write_to_output_stream_sync (CamelDataWrapper *data_wrapper,
static void
mime_message_add_header (CamelMedium *medium,
const gchar *name,
- gconstpointer value)
+ const gchar *value)
{
CamelMediumClass *medium_class;
@@ -287,7 +296,7 @@ mime_message_add_header (CamelMedium *medium,
static void
mime_message_set_header (CamelMedium *medium,
const gchar *name,
- gconstpointer value)
+ const gchar *value)
{
process_header (medium, name, value);
@@ -363,6 +372,8 @@ camel_mime_message_class_init (CamelMimeMessageClass *class)
CamelMediumClass *medium_class;
gint ii;
+ g_type_class_add_private (class, sizeof (CamelMimeMessagePrivate));
+
object_class = G_OBJECT_CLASS (class);
object_class->dispose = mime_message_dispose;
object_class->finalize = mime_message_finalize;
@@ -395,23 +406,25 @@ camel_mime_message_init (CamelMimeMessage *mime_message)
{
gint ii;
- mime_message->recipients = g_hash_table_new (
+ mime_message->priv = G_TYPE_INSTANCE_GET_PRIVATE (mime_message, CAMEL_TYPE_MIME_MESSAGE,
CamelMimeMessagePrivate);
+
+ mime_message->priv->recipients = g_hash_table_new (
camel_strcase_hash, camel_strcase_equal);
for (ii = 0; recipient_names[ii] != NULL; ii++) {
g_hash_table_insert (
- mime_message->recipients,
+ mime_message->priv->recipients,
(gpointer) recipient_names[ii],
camel_internet_address_new ());
}
- mime_message->subject = NULL;
- mime_message->reply_to = NULL;
- mime_message->from = NULL;
- mime_message->date = CAMEL_MESSAGE_DATE_CURRENT;
- mime_message->date_offset = 0;
- mime_message->date_received = CAMEL_MESSAGE_DATE_CURRENT;
- mime_message->date_received_offset = 0;
- mime_message->message_id = NULL;
+ mime_message->priv->subject = NULL;
+ mime_message->priv->reply_to = NULL;
+ mime_message->priv->from = NULL;
+ mime_message->priv->date = CAMEL_MESSAGE_DATE_CURRENT;
+ mime_message->priv->date_offset = 0;
+ mime_message->priv->date_received = CAMEL_MESSAGE_DATE_CURRENT;
+ mime_message->priv->date_received_offset = 0;
+ mime_message->priv->message_id = NULL;
}
/**
@@ -454,8 +467,8 @@ camel_mime_message_set_date (CamelMimeMessage *message,
camel_localtime_with_offset (date, &local, &tz);
offset = (((tz / 60 / 60) * 100) + (tz / 60 % 60));
}
- message->date = date;
- message->date_offset = offset;
+ message->priv->date = date;
+ message->priv->date_offset = offset;
datestr = camel_header_format_date (date, offset);
CAMEL_MEDIUM_CLASS (camel_mime_message_parent_class)->set_header ((CamelMedium *) message, "Date",
datestr);
@@ -476,9 +489,9 @@ camel_mime_message_get_date (CamelMimeMessage *msg,
gint *offset)
{
if (offset)
- *offset = msg->date_offset;
+ *offset = msg->priv->date_offset;
- return msg->date;
+ return msg->priv->date;
}
/**
@@ -494,20 +507,20 @@ time_t
camel_mime_message_get_date_received (CamelMimeMessage *msg,
gint *offset)
{
- if (msg->date_received == CAMEL_MESSAGE_DATE_CURRENT) {
+ if (msg->priv->date_received == CAMEL_MESSAGE_DATE_CURRENT) {
const gchar *received;
received = camel_medium_get_header ((CamelMedium *) msg, "received");
if (received)
received = strrchr (received, ';');
if (received)
- msg->date_received = camel_header_decode_date (received + 1,
&msg->date_received_offset);
+ msg->priv->date_received = camel_header_decode_date (received + 1,
&msg->priv->date_received_offset);
}
if (offset)
- *offset = msg->date_received_offset;
+ *offset = msg->priv->date_received_offset;
- return msg->date_received;
+ return msg->priv->date_received;
}
/* **** Message-ID: */
@@ -527,7 +540,7 @@ camel_mime_message_set_message_id (CamelMimeMessage *mime_message,
g_return_if_fail (mime_message);
- g_free (mime_message->message_id);
+ g_free (mime_message->priv->message_id);
if (message_id) {
id = g_strstrip (g_strdup (message_id));
@@ -547,8 +560,8 @@ camel_mime_message_set_message_id (CamelMimeMessage *mime_message,
id = camel_header_msgid_generate (domain);
}
- mime_message->message_id = id;
- id = g_strdup_printf ("<%s>", mime_message->message_id);
+ mime_message->priv->message_id = id;
+ id = g_strdup_printf ("<%s>", mime_message->priv->message_id);
CAMEL_MEDIUM_CLASS (camel_mime_message_parent_class)->set_header (CAMEL_MEDIUM (mime_message),
"Message-ID", id);
g_free (id);
}
@@ -566,7 +579,7 @@ camel_mime_message_get_message_id (CamelMimeMessage *mime_message)
{
g_return_val_if_fail (mime_message, NULL);
- return mime_message->message_id;
+ return mime_message->priv->message_id;
}
/* **** Reply-To: */
@@ -586,18 +599,15 @@ camel_mime_message_set_reply_to (CamelMimeMessage *msg,
g_return_if_fail (msg);
- if (msg->reply_to) {
- g_object_unref (msg->reply_to);
- msg->reply_to = NULL;
- }
+ g_clear_object (&msg->priv->reply_to);
if (reply_to == NULL) {
CAMEL_MEDIUM_CLASS (camel_mime_message_parent_class)->remove_header (CAMEL_MEDIUM (msg),
"Reply-To");
return;
}
- msg->reply_to = (CamelInternetAddress *) camel_address_new_clone ((CamelAddress *) reply_to);
- addr = camel_address_encode ((CamelAddress *) msg->reply_to);
+ msg->priv->reply_to = (CamelInternetAddress *) camel_address_new_clone ((CamelAddress *) reply_to);
+ addr = camel_address_encode ((CamelAddress *) msg->priv->reply_to);
CAMEL_MEDIUM_CLASS (camel_mime_message_parent_class)->set_header (CAMEL_MEDIUM (msg), "Reply-To",
addr);
g_free (addr);
}
@@ -617,7 +627,7 @@ camel_mime_message_get_reply_to (CamelMimeMessage *mime_message)
/* TODO: ref for threading? */
- return mime_message->reply_to;
+ return mime_message->priv->reply_to;
}
/* **** Subject: */
@@ -637,13 +647,13 @@ camel_mime_message_set_subject (CamelMimeMessage *message,
g_return_if_fail (message);
- g_free (message->subject);
+ g_free (message->priv->subject);
if (subject) {
- message->subject = g_strstrip (g_strdup (subject));
- text = camel_header_encode_string ((guchar *) message->subject);
+ message->priv->subject = g_strstrip (g_strdup (subject));
+ text = camel_header_encode_string ((guchar *) message->priv->subject);
} else {
- message->subject = NULL;
+ message->priv->subject = NULL;
text = NULL;
}
@@ -664,7 +674,7 @@ camel_mime_message_get_subject (CamelMimeMessage *mime_message)
{
g_return_val_if_fail (mime_message, NULL);
- return mime_message->subject;
+ return mime_message->priv->subject;
}
/* *** From: */
@@ -688,18 +698,15 @@ camel_mime_message_set_from (CamelMimeMessage *msg,
g_return_if_fail (msg);
- if (msg->from) {
- g_object_unref (msg->from);
- msg->from = NULL;
- }
+ g_clear_object (&msg->priv->from);
if (from == NULL || camel_address_length ((CamelAddress *) from) == 0) {
CAMEL_MEDIUM_CLASS (camel_mime_message_parent_class)->remove_header (CAMEL_MEDIUM (msg),
"From");
return;
}
- msg->from = (CamelInternetAddress *) camel_address_new_clone ((CamelAddress *) from);
- addr = camel_address_encode ((CamelAddress *) msg->from);
+ msg->priv->from = (CamelInternetAddress *) camel_address_new_clone ((CamelAddress *) from);
+ addr = camel_address_encode ((CamelAddress *) msg->priv->from);
CAMEL_MEDIUM_CLASS (camel_mime_message_parent_class)->set_header (CAMEL_MEDIUM (msg), "From", addr);
g_free (addr);
}
@@ -719,7 +726,7 @@ camel_mime_message_get_from (CamelMimeMessage *mime_message)
/* TODO: we should really ref this for multi-threading to work */
- return mime_message->from;
+ return mime_message->priv->from;
}
/* **** To: Cc: Bcc: */
@@ -742,7 +749,7 @@ camel_mime_message_set_recipients (CamelMimeMessage *mime_message,
g_return_if_fail (mime_message);
- addr = g_hash_table_lookup (mime_message->recipients, type);
+ addr = g_hash_table_lookup (mime_message->priv->recipients, type);
if (addr == NULL) {
g_warning ("trying to set a non-valid receipient type: %s", type);
return;
@@ -778,7 +785,7 @@ camel_mime_message_get_recipients (CamelMimeMessage *mime_message,
{
g_return_val_if_fail (mime_message, NULL);
- return g_hash_table_lookup (mime_message->recipients, type);
+ return g_hash_table_lookup (mime_message->priv->recipients, type);
}
void
@@ -951,7 +958,7 @@ find_best_encoding (CamelMimePart *part,
return CAMEL_TRANSFER_ENCODING_DEFAULT;
}
- istext = camel_content_type_is (((CamelDataWrapper *) part)->mime_type, "text", "*");
+ istext = camel_content_type_is (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (part)),
"text", "*");
if (istext) {
flags = CAMEL_BESTENC_GET_CHARSET | CAMEL_BESTENC_GET_ENCODING;
enctype |= CAMEL_BESTENC_TEXT;
@@ -971,7 +978,7 @@ find_best_encoding (CamelMimePart *part,
/* if we're looking for the best charset, then we need to convert to UTF-8 */
if (istext && (required & CAMEL_BESTENC_GET_CHARSET) != 0
- && (charsetin = camel_content_type_param (content->mime_type, "charset"))) {
+ && (charsetin = camel_content_type_param (camel_data_wrapper_get_mime_type_field (content),
"charset"))) {
charenc = camel_mime_filter_charset_new (charsetin, "UTF-8");
if (charenc != NULL)
idc = camel_stream_filter_add (
@@ -997,7 +1004,7 @@ find_best_encoding (CamelMimePart *part,
d (printf ("best charset = %s\n", charsetin ? charsetin : "(null)"));
charset = g_strdup (charsetin);
- charsetin = camel_content_type_param (content->mime_type, "charset");
+ charsetin = camel_content_type_param (camel_data_wrapper_get_mime_type_field (content),
"charset");
} else {
charset = NULL;
}
@@ -1081,14 +1088,14 @@ best_encoding (CamelMimeMessage *msg,
camel_mime_part_set_encoding (part, encoding);
if ((data->required & CAMEL_BESTENC_GET_CHARSET) != 0) {
- if (camel_content_type_is (((CamelDataWrapper *) part)->mime_type, "text", "*")) {
+ if (camel_content_type_is (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER
(part)), "text", "*")) {
gchar *newct;
/* FIXME: ick, the part content_type interface needs fixing bigtime */
camel_content_type_set_param (
- ((CamelDataWrapper *) part)->mime_type, "charset",
+ camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (part)),
"charset",
charset ? charset : "us-ascii");
- newct = camel_content_type_format (((CamelDataWrapper *) part)->mime_type);
+ newct = camel_content_type_format (camel_data_wrapper_get_mime_type_field
(CAMEL_DATA_WRAPPER (part)));
if (newct) {
d (printf ("Setting content-type to %s\n", newct));
@@ -1217,7 +1224,7 @@ static const gchar tz_days[][4] = {
gchar *
camel_mime_message_build_mbox_from (CamelMimeMessage *message)
{
- struct _camel_header_raw *header = ((CamelMimePart *) message)->headers;
+ const CamelNameValueArray *headers;
GString *out = g_string_new ("From ");
gchar *ret;
const gchar *tmp;
@@ -1225,9 +1232,10 @@ camel_mime_message_build_mbox_from (CamelMimeMessage *message)
gint offset;
struct tm tm;
- tmp = camel_header_raw_find (&header, "Sender", NULL);
+ headers = camel_medium_get_headers (CAMEL_MEDIUM (message));
+ tmp = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Sender");
if (tmp == NULL)
- tmp = camel_header_raw_find (&header, "From", NULL);
+ tmp = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "From");
if (tmp != NULL) {
CamelHeaderAddress *addr = camel_header_address_decode (tmp, NULL);
@@ -1245,7 +1253,7 @@ camel_mime_message_build_mbox_from (CamelMimeMessage *message)
g_string_append (out, "unknown nodomain now au");
/* try use the received header to get the date */
- tmp = camel_header_raw_find (&header, "Received", NULL);
+ tmp = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Received");
if (tmp) {
tmp = strrchr (tmp, ';');
if (tmp)
@@ -1254,7 +1262,7 @@ camel_mime_message_build_mbox_from (CamelMimeMessage *message)
/* if there isn't one, try the Date field */
if (tmp == NULL)
- tmp = camel_header_raw_find (&header, "Date", NULL);
+ tmp = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE, "Date");
thetime = camel_header_decode_date (tmp, &offset);
thetime += ((offset / 100) * (60 * 60)) + (offset % 100) * 60;
@@ -1393,7 +1401,7 @@ cmm_dump_rec (CamelMimeMessage *msg,
s[depth] = 0;
/* yes this leaks, so what its only debug stuff */
printf ("%sclass: %s\n", s, G_OBJECT_TYPE_NAME (part));
- printf ("%smime-type: %s\n", s, camel_content_type_format (((CamelDataWrapper *) part)->mime_type));
+ printf ("%smime-type: %s\n", s, camel_content_type_format (camel_data_wrapper_get_mime_type_field
(CAMEL_DATA_WRAPPER (part))));
containee = camel_medium_get_content ((CamelMedium *) part);
@@ -1401,7 +1409,7 @@ cmm_dump_rec (CamelMimeMessage *msg,
return;
printf ("%scontent class: %s\n", s, G_OBJECT_TYPE_NAME (containee));
- printf ("%scontent mime-type: %s\n", s, camel_content_type_format (((CamelDataWrapper *)
containee)->mime_type));
+ printf ("%scontent mime-type: %s\n", s, camel_content_type_format
(camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (containee))));
data = camel_data_wrapper_get_byte_array (containee);
if (body && data) {
diff --git a/src/camel/camel-mime-message.h b/src/camel/camel-mime-message.h
index 026de17..d10f9c2 100644
--- a/src/camel/camel-mime-message.h
+++ b/src/camel/camel-mime-message.h
@@ -65,30 +65,18 @@ G_BEGIN_DECLS
typedef struct _CamelMimeMessage CamelMimeMessage;
typedef struct _CamelMimeMessageClass CamelMimeMessageClass;
+typedef struct _CamelMimeMessagePrivate CamelMimeMessagePrivate;
struct _CamelMimeMessage {
CamelMimePart parent;
-
- /* header fields */
- time_t date;
- gint date_offset; /* GMT offset */
-
- /* cached internal copy */
- time_t date_received;
- gint date_received_offset; /* GMT offset */
-
- gchar *subject;
-
- gchar *message_id;
-
- CamelInternetAddress *reply_to;
- CamelInternetAddress *from;
-
- GHashTable *recipients; /* hash table of CamelInternetAddress's */
+ CamelMimeMessagePrivate *priv;
};
struct _CamelMimeMessageClass {
CamelMimePartClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_message_get_type (void);
diff --git a/src/camel/camel-mime-parser.c b/src/camel/camel-mime-parser.c
index dccf063..cfbb4c5 100644
--- a/src/camel/camel-mime-parser.c
+++ b/src/camel/camel-mime-parser.c
@@ -60,6 +60,15 @@ gint inend_id = -1,
#define _header_scan_state _CamelMimeParserPrivate
#define _PRIVATE(obj) (((CamelMimeParser *)(obj))->priv)
+/* a raw rfc822 header */
+/* the value MUST be US-ASCII */
+typedef struct _camel_header_raw {
+ struct _camel_header_raw *next;
+ gchar *name;
+ gchar *value;
+ gint offset; /* in file, if known */
+} CamelHeaderRaw;
+
struct _header_scan_state {
/* global state */
@@ -116,7 +125,7 @@ struct _header_scan_stack {
#ifdef MEMPOOL
CamelMemPool *pool; /* memory pool to keep track of headers/etc at this level */
#endif
- struct _camel_header_raw *headers; /* headers for this part */
+ CamelHeaderRaw *headers; /* headers for this part */
CamelContentType *content_type;
@@ -154,8 +163,13 @@ static goffset folder_tell (struct _header_scan_state *s);
static gint folder_read (struct _header_scan_state *s);
static void folder_push_part (struct _header_scan_state *s, struct _header_scan_stack *h);
+static const gchar * header_raw_find (CamelHeaderRaw **list, const gchar *name, gint *offset);
+
#ifdef MEMPOOL
static void header_append_mempool (struct _header_scan_state *s, struct _header_scan_stack *h, gchar
*header, gint offset);
+#else
+static void header_raw_free (CamelHeaderRaw *l);
+static void header_raw_clear (CamelHeaderRaw *l);
#endif
#if d(!)0
@@ -317,7 +331,7 @@ camel_mime_parser_header (CamelMimeParser *m,
struct _header_scan_state *s = _PRIVATE (m);
if (s->parts && s->parts->headers)
- return camel_header_raw_find (&s->parts->headers, name, offset);
+ return header_raw_find (&s->parts->headers, name, offset);
return NULL;
}
@@ -330,18 +344,26 @@ camel_mime_parser_header (CamelMimeParser *m,
* current state of the parser. These headers are valid
* until the next call to parser_step(), or parser_drop_step().
*
- * Returns: (transfer none): The raw headers, or NULL if there are no headers
- * defined for the current part or state. These are READ ONLY.
+ * Returns: (transfer full): The headers, or %NULL, if there are no headers
+ * defined for the current part or state. Free it with camel_name_value_array_free().
*
- * Since: 2.22
+ * Since: 3.24
**/
-struct _camel_header_raw *
-camel_mime_parser_headers_raw (CamelMimeParser *m)
+CamelNameValueArray *
+camel_mime_parser_dup_headers (CamelMimeParser *m)
{
struct _header_scan_state *s = _PRIVATE (m);
- if (s->parts)
- return s->parts->headers;
+ if (s->parts) {
+ CamelHeaderRaw *header = s->parts->headers;
+ CamelNameValueArray *header_copy = camel_name_value_array_new ();
+ while (header) {
+ camel_name_value_array_append (header_copy, header->name, header->value);
+ header = header->next;
+ }
+
+ return header_copy;
+ }
return NULL;
}
@@ -1180,7 +1202,7 @@ header_append_mempool (struct _header_scan_state *s,
gchar *header,
gint offset)
{
- struct _camel_header_raw *l, *n;
+ CamelHeaderRaw *l, *n;
gchar *content;
content = strchr (header, ':');
@@ -1203,7 +1225,7 @@ header_append_mempool (struct _header_scan_state *s,
n->offset = offset;
- l = (struct _camel_header_raw *) &h->headers;
+ l = (CamelHeaderRaw *) &h->headers;
while (l->next) {
l = l->next;
}
@@ -1688,7 +1710,7 @@ tail_recurse:
/* FIXME: should this check for MIME-Version: 1.0 as well? */
type = CAMEL_MIME_PARSER_STATE_HEADER;
- if ((content = camel_header_raw_find (&h->headers, "Content-Type", NULL))
+ if ((content = header_raw_find (&h->headers, "Content-Type", NULL))
&& (ct = camel_content_type_decode (content))) {
if (!g_ascii_strcasecmp (ct->type, "multipart")) {
if (!camel_content_type_is (ct, "multipart", "signed")
@@ -1892,6 +1914,60 @@ folder_scan_drop_step (struct _header_scan_state *s)
}
}
+static CamelHeaderRaw *
+header_raw_find_node (CamelHeaderRaw **list,
+ const gchar *name)
+{
+ CamelHeaderRaw *l;
+
+ l = *list;
+ while (l) {
+ if (!g_ascii_strcasecmp (l->name, name))
+ break;
+ l = l->next;
+ }
+ return l;
+}
+
+static const gchar *
+header_raw_find (CamelHeaderRaw **list,
+ const gchar *name,
+ gint *offset)
+{
+ CamelHeaderRaw *l;
+
+ l = header_raw_find_node (list, name);
+ if (l) {
+ if (offset)
+ *offset = l->offset;
+ return l->value;
+ } else
+ return NULL;
+}
+
+#ifndef MEMPOOL
+static void
+header_raw_free (CamelHeaderRaw *l)
+{
+ g_free (l->name);
+ g_free (l->value);
+ g_free (l);
+}
+
+static void
+header_raw_clear (CamelHeaderRaw **list)
+{
+ CamelHeaderRaw *l, *n;
+ l = *list;
+ while (l) {
+ n = l->next;
+ header_raw_free (l);
+ l = n;
+ }
+ *list = NULL;
+}
+#endif
+
#ifdef STANDALONE
gint main (gint argc, gchar **argv)
{
@@ -1948,7 +2024,7 @@ gint main (gint argc, gchar **argv)
charset = NULL;
}
- encoding = camel_header_raw_find (&s->parts->headers,
"Content-transfer-encoding", 0);
+ encoding = header_raw_find (&s->parts->headers, "Content-transfer-encoding",
NULL);
printf ("encoding = '%s'\n", encoding);
if (encoding && !g_ascii_strncasecmp (encoding, " base64", 7)) {
printf ("adding base64 filter\n");
diff --git a/src/camel/camel-mime-parser.h b/src/camel/camel-mime-parser.h
index ce5c098..17cbaaf 100644
--- a/src/camel/camel-mime-parser.h
+++ b/src/camel/camel-mime-parser.h
@@ -27,6 +27,7 @@
#include <camel/camel-mime-utils.h>
#include <camel/camel-mime-filter.h>
#include <camel/camel-stream.h>
+#include <camel/camel-name-value-array.h>
/* Stardard GObject macros */
#define CAMEL_TYPE_MIME_PARSER \
@@ -89,6 +90,9 @@ struct _CamelMimeParserClass {
void (*message) (CamelMimeParser *parser, gpointer headers);
void (*part) (CamelMimeParser *parser);
void (*content) (CamelMimeParser *parser);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_parser_get_type (void);
@@ -128,8 +132,8 @@ CamelContentType *camel_mime_parser_content_type (CamelMimeParser *parser);
/* get/change raw header by name */
const gchar *camel_mime_parser_header (CamelMimeParser *m, const gchar *name, gint *offset);
-/* get all raw headers. READ ONLY! */
-struct _camel_header_raw *camel_mime_parser_headers_raw (CamelMimeParser *m);
+/* get all raw headers */
+CamelNameValueArray *camel_mime_parser_dup_headers (CamelMimeParser *m);
/* get multipart pre/postface */
const gchar *camel_mime_parser_preface (CamelMimeParser *m);
diff --git a/src/camel/camel-mime-part-utils.c b/src/camel/camel-mime-part-utils.c
index 9fe0f9e..77ab61b 100644
--- a/src/camel/camel-mime-part-utils.c
+++ b/src/camel/camel-mime-part-utils.c
@@ -30,6 +30,7 @@
#include "camel-charset-map.h"
#include "camel-html-parser.h"
+#include "camel-iconv.h"
#include "camel-mime-filter-basic.h"
#include "camel-mime-filter-charset.h"
#include "camel-mime-filter-crlf.h"
@@ -137,7 +138,7 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw,
if (content) {
if (encoding)
- content->encoding = camel_transfer_encoding_from_string (encoding);
+ camel_data_wrapper_set_encoding (content, camel_transfer_encoding_from_string
(encoding));
/* would you believe you have to set this BEFORE you set the content object??? oh my god
!!!! */
camel_data_wrapper_set_mime_type_field (content, camel_mime_part_get_content_type (dw));
@@ -150,91 +151,188 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw,
return success;
}
+G_DEFINE_BOXED_TYPE (CamelMessageContentInfo,
+ camel_message_content_info,
+ camel_message_content_info_copy,
+ camel_message_content_info_free)
+
/**
- * camel_mime_message_build_preview:
+ * camel_message_content_info_new:
*
- * <note>
- * <para>
- * This function blocks like crazy.
- * </para>
- * </note>
+ * Allocate a new #CamelMessageContentInfo.
*
- * Since: 2.28
+ * Returns: (transfer full): a newly allocated #CamelMessageContentInfo
**/
-gboolean
-camel_mime_message_build_preview (CamelMimePart *msg,
- CamelMessageInfo *info)
+CamelMessageContentInfo *
+camel_message_content_info_new (void)
{
- CamelDataWrapper *dw;
- gboolean got_plain = FALSE;
+ return g_slice_alloc0 (sizeof (CamelMessageContentInfo));
+}
+
+/**
+ * camel_message_content_info_copy:
+ * @src: (nullable): a source #CamelMessageContentInfo to copy
+ *
+ * Returns: a copy of @src, or %NULL, if @src was %NULL
+ *
+ * Since: 3.24
+ **/
+CamelMessageContentInfo *
+camel_message_content_info_copy (const CamelMessageContentInfo *src)
+{
+ CamelMessageContentInfo *res;
+
+ if (!src)
+ return NULL;
+
+ res = camel_message_content_info_new ();
+
+ if (src->type) {
+ gchar *content_type;
+
+ content_type = camel_content_type_format (src->type);
+ res->type = camel_content_type_decode (content_type);
+
+ g_free (content_type);
+ }
- dw = camel_medium_get_content ((CamelMedium *) msg);
- if (camel_content_type_is (dw->mime_type, "multipart", "*")) {
- gint i, nparts;
- CamelMultipart *mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) msg);
+ res->id = g_strdup (src->id);
+ res->description = g_strdup (src->description);
+ res->encoding = g_strdup (src->encoding);
+ res->size = src->size;
- g_warn_if_fail (CAMEL_IS_MULTIPART (mp));
+ res->next = camel_message_content_info_copy (src->next);
+ res->childs = camel_message_content_info_copy (src->childs);
- nparts = camel_multipart_get_number (mp);
- for (i = 0; i < nparts && !got_plain; i++) {
- CamelMimePart *part = camel_multipart_get_part (mp, i);
- got_plain = camel_mime_message_build_preview (part, info);
+ if (res->childs) {
+ CamelMessageContentInfo *child;
+
+ for (child = res->childs; child; child = child->next) {
+ child->parent = res;
}
+ }
+
+ return res;
+}
+
+/**
+ * camel_message_content_info_free:
+ * @ci: a #CamelMessageContentInfo
+ *
+ * Recursively frees the content info @ci, and all associated memory.
+ **/
+void
+camel_message_content_info_free (CamelMessageContentInfo *ci)
+{
+ CamelMessageContentInfo *pw, *pn;
+
+ pw = ci->childs;
+
+ camel_content_type_unref (ci->type);
+ g_free (ci->id);
+ g_free (ci->description);
+ g_free (ci->encoding);
+ g_slice_free1 (sizeof (CamelMessageContentInfo), ci);
+
+ while (pw) {
+ pn = pw->next;
+ camel_message_content_info_free (pw);
+ pw = pn;
+ }
+}
- } else if (camel_content_type_is (dw->mime_type, "text", "*") &&
- /* !camel_content_type_is (dw->mime_type, "text", "html") && */
- !camel_content_type_is (dw->mime_type, "text", "calendar")) {
- CamelStream *mstream, *bstream;
-
- /* FIXME Pass a GCancellable and GError here. */
- mstream = camel_stream_mem_new ();
- if (camel_data_wrapper_decode_to_stream_sync (dw, mstream, NULL, NULL) > 0) {
- gchar *line = NULL;
- GString *str = g_string_new (NULL);
-
- g_seekable_seek (
- G_SEEKABLE (mstream), 0,
- G_SEEK_SET, NULL, NULL);
-
- bstream = camel_stream_buffer_new (mstream, CAMEL_STREAM_BUFFER_READ |
CAMEL_STREAM_BUFFER_BUFFER);
-
- /* We should fetch just 200 unquoted lines. */
- while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *) bstream, NULL,
NULL)) && str->len < 200) {
- gchar *tmp = line;
-
- if (*line == '>' || strstr (line, "wrote:")) {
- g_free (tmp);
- continue;
- }
- if (g_str_has_prefix (line, "--")) {
- g_free (tmp);
- line = NULL;
- break;
- }
- while (*line && ((*line == ' ') || *line == '\t'))
- line++;
- if (*line == '\0' || *line == '\n') {
- g_free (tmp);
- continue;
- }
-
- g_string_append (str, " ");
- g_string_append (str, line);
- g_free (tmp);
- line = NULL;
- }
- if (str->len > 100) {
- g_string_insert (str, 100, "\n");
- }
- /* We don't mark dirty, as we don't store these */
- ((CamelMessageInfoBase *) info)->preview = camel_utf8_make_valid (str->str);
- g_string_free (str, TRUE);
-
- g_object_unref (bstream);
+CamelMessageContentInfo *
+camel_message_content_info_new_from_parser (CamelMimeParser *mp)
+{
+ CamelMessageContentInfo *ci = NULL;
+ CamelNameValueArray *headers = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_MIME_PARSER (mp), NULL);
+
+ switch (camel_mime_parser_state (mp)) {
+ case CAMEL_MIME_PARSER_STATE_HEADER:
+ case CAMEL_MIME_PARSER_STATE_MESSAGE:
+ case CAMEL_MIME_PARSER_STATE_MULTIPART:
+ headers = camel_mime_parser_dup_headers (mp);
+ ci = camel_message_content_info_new_from_headers (headers);
+ camel_name_value_array_free (headers);
+ if (ci) {
+ if (ci->type)
+ camel_content_type_unref (ci->type);
+ ci->type = camel_mime_parser_content_type (mp);
+ camel_content_type_ref (ci->type);
}
- g_object_unref (mstream);
- return TRUE;
+ break;
+ default:
+ g_error ("Invalid parser state");
}
- return got_plain;
+ return ci;
+}
+
+CamelMessageContentInfo *
+camel_message_content_info_new_from_message (CamelMimePart *mp)
+{
+ CamelMessageContentInfo *ci = NULL;
+ const CamelNameValueArray *headers = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (mp), NULL);
+
+ headers = camel_medium_get_headers (CAMEL_MEDIUM (mp));
+ ci = camel_message_content_info_new_from_headers (headers);
+
+ return ci;
+}
+
+CamelMessageContentInfo *
+camel_message_content_info_new_from_headers (const CamelNameValueArray *headers)
+{
+ CamelMessageContentInfo *ci;
+ const gchar *charset;
+
+ ci = camel_message_content_info_new ();
+
+ charset = camel_iconv_locale_charset ();
+ ci->id = camel_header_msgid_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "Content-ID"));
+ ci->description = camel_header_decode_string (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "Content-Description"), charset);
+ ci->encoding = camel_content_transfer_encoding_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "Content-Transfer-Encoding"));
+ ci->type = camel_content_type_decode (camel_name_value_array_get_named (headers,
CAMEL_COMPARE_CASE_INSENSITIVE, "Content-Type"));
+
+ return ci;
+}
+
+void
+camel_message_content_info_dump (CamelMessageContentInfo *ci,
+ gint depth)
+{
+ gchar *p;
+
+ p = alloca (depth * 4 + 1);
+ memset (p, ' ', depth * 4);
+ p[depth * 4] = 0;
+
+ if (ci == NULL) {
+ printf ("%s<empty>\n", p);
+ return;
+ }
+
+ if (ci->type)
+ printf (
+ "%scontent-type: %s/%s\n",
+ p, ci->type->type ? ci->type->type : "(null)",
+ ci->type->subtype ? ci->type->subtype : "(null)");
+ else
+ printf ("%scontent-type: <unset>\n", p);
+ printf (
+ "%scontent-transfer-encoding: %s\n",
+ p, ci->encoding ? ci->encoding : "(null)");
+ printf (
+ "%scontent-description: %s\n",
+ p, ci->description ? ci->description : "(null)");
+ printf ("%ssize: %lu\n", p, (gulong) ci->size);
+ ci = ci->childs;
+ while (ci) {
+ camel_message_content_info_dump (ci, depth + 1);
+ ci = ci->next;
+ }
}
diff --git a/src/camel/camel-mime-part-utils.h b/src/camel/camel-mime-part-utils.h
index 916cc33..a31f2be 100644
--- a/src/camel/camel-mime-part-utils.h
+++ b/src/camel/camel-mime-part-utils.h
@@ -35,8 +35,43 @@ gboolean camel_mime_part_construct_content_from_parser
CamelMimeParser *mp,
GCancellable *cancellable,
GError **error);
-gboolean camel_mime_message_build_preview (CamelMimePart *mime_part,
- CamelMessageInfo *info);
+
+typedef struct _CamelMessageContentInfo CamelMessageContentInfo;
+
+/* A tree of message content info structures
+ * describe the content structure of the message (if it has any) */
+struct _CamelMessageContentInfo {
+ CamelMessageContentInfo *next;
+
+ CamelMessageContentInfo *childs;
+ CamelMessageContentInfo *parent;
+
+ CamelContentType *type;
+ gchar *id;
+ gchar *description;
+ gchar *encoding;
+ guint32 size;
+};
+
+GType camel_message_content_info_get_type
+ (void) G_GNUC_CONST;
+CamelMessageContentInfo *
+ camel_message_content_info_new (void);
+CamelMessageContentInfo *
+ camel_message_content_info_copy (const CamelMessageContentInfo *src);
+void camel_message_content_info_free (CamelMessageContentInfo *ci);
+CamelMessageContentInfo *
+ camel_message_content_info_new_from_headers
+ (const CamelNameValueArray *headers);
+CamelMessageContentInfo *
+ camel_message_content_info_new_from_parser
+ (CamelMimeParser *parser);
+CamelMessageContentInfo *
+ camel_message_content_info_new_from_message
+ (CamelMimePart *mime_part);
+/* debugging functions */
+void camel_message_content_info_dump (CamelMessageContentInfo *ci,
+ gint depth);
G_END_DECLS
diff --git a/src/camel/camel-mime-part.c b/src/camel/camel-mime-part.c
index 70b842b..beabf46 100644
--- a/src/camel/camel-mime-part.c
+++ b/src/camel/camel-mime-part.c
@@ -59,6 +59,8 @@ struct _CamelMimePartPrivate {
gchar *content_location;
GList *content_languages;
CamelTransferEncoding encoding;
+ /* mime headers */
+ CamelNameValueArray *headers;
};
struct _AsyncContext {
@@ -318,8 +320,8 @@ mime_part_process_header (CamelMedium *medium,
switch (header_type) {
case HEADER_DESCRIPTION: /* raw header->utf8 conversion */
g_free (mime_part->priv->description);
- if (((CamelDataWrapper *) mime_part)->mime_type) {
- charset = camel_content_type_param (((CamelDataWrapper *) mime_part)->mime_type,
"charset");
+ if (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (mime_part))) {
+ charset = camel_content_type_param (camel_data_wrapper_get_mime_type_field
(CAMEL_DATA_WRAPPER (mime_part)), "charset");
charset = camel_iconv_charset_name (charset);
} else
charset = NULL;
@@ -346,9 +348,7 @@ mime_part_process_header (CamelMedium *medium,
mime_part->priv->content_location = camel_header_location_decode (value);
break;
case HEADER_CONTENT_TYPE:
- if (((CamelDataWrapper *) mime_part)->mime_type)
- camel_content_type_unref (((CamelDataWrapper *) mime_part)->mime_type);
- ((CamelDataWrapper *) mime_part)->mime_type = camel_content_type_decode (value);
+ camel_data_wrapper_take_mime_type_field (CAMEL_DATA_WRAPPER (mime_part),
camel_content_type_decode (value));
break;
default:
return FALSE;
@@ -452,8 +452,7 @@ mime_part_finalize (GObject *object)
g_list_free_full (priv->content_languages, (GDestroyNotify) g_free);
camel_content_disposition_unref (priv->disposition);
-
- camel_header_raw_clear (&CAMEL_MIME_PART (object)->headers);
+ camel_name_value_array_free (priv->headers);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_mime_part_parent_class)->finalize (object);
@@ -462,7 +461,7 @@ mime_part_finalize (GObject *object)
static void
mime_part_add_header (CamelMedium *medium,
const gchar *name,
- gconstpointer value)
+ const gchar *value)
{
CamelMimePart *part = CAMEL_MIME_PART (medium);
@@ -472,40 +471,42 @@ mime_part_add_header (CamelMedium *medium,
/* If it was one of the headers we handled, it must be unique, set it instead of add */
if (mime_part_process_header (medium, name, value))
- camel_header_raw_replace (&part->headers, name, value, -1);
- else
- camel_header_raw_append (&part->headers, name, value, -1);
+ camel_name_value_array_remove_named (part->priv->headers, CAMEL_COMPARE_CASE_INSENSITIVE,
name, TRUE);
+
+ camel_name_value_array_append (part->priv->headers, name, value);
}
static void
mime_part_set_header (CamelMedium *medium,
const gchar *name,
- gconstpointer value)
+ const gchar *value)
{
CamelMimePart *part = CAMEL_MIME_PART (medium);
mime_part_process_header (medium, name, value);
- camel_header_raw_replace (&part->headers, name, value, -1);
+ camel_name_value_array_remove_named (part->priv->headers, CAMEL_COMPARE_CASE_INSENSITIVE, name, TRUE);
+
+ camel_name_value_array_append (part->priv->headers, name, value);
}
static void
mime_part_remove_header (CamelMedium *medium,
const gchar *name)
{
- CamelMimePart *part = (CamelMimePart *) medium;
+ CamelMimePart *part = CAMEL_MIME_PART (medium);
mime_part_process_header (medium, name, NULL);
- camel_header_raw_remove (&part->headers, name);
+ camel_name_value_array_remove_named (part->priv->headers, CAMEL_COMPARE_CASE_INSENSITIVE, name, TRUE);
}
-static gconstpointer
+static const gchar *
mime_part_get_header (CamelMedium *medium,
const gchar *name)
{
- CamelMimePart *part = (CamelMimePart *) medium;
+ CamelMimePart *part = CAMEL_MIME_PART (medium);
const gchar *value;
- value = camel_header_raw_find (&part->headers, name, NULL);
+ value = camel_name_value_array_get_named (part->priv->headers, CAMEL_COMPARE_CASE_INSENSITIVE, name);
/* Skip leading whitespace. */
while (value != NULL && g_ascii_isspace (*value))
@@ -514,29 +515,20 @@ mime_part_get_header (CamelMedium *medium,
return value;
}
-static GArray *
-mime_part_get_headers (CamelMedium *medium)
+static CamelNameValueArray *
+mime_part_dup_headers (CamelMedium *medium)
{
- CamelMimePart *part = (CamelMimePart *) medium;
- GArray *headers;
- CamelMediumHeader header;
- struct _camel_header_raw *h;
-
- headers = g_array_new (FALSE, FALSE, sizeof (CamelMediumHeader));
- for (h = part->headers; h; h = h->next) {
- header.name = h->name;
- header.value = h->value;
- g_array_append_val (headers, header);
- }
+ CamelMimePart *part = CAMEL_MIME_PART (medium);
- return headers;
+ return camel_name_value_array_copy (part->priv->headers);
}
-static void
-mime_part_free_headers (CamelMedium *medium,
- GArray *headers)
+static const CamelNameValueArray *
+mime_part_get_headers (CamelMedium *medium)
{
- g_array_free (headers, TRUE);
+ CamelMimePart *part = CAMEL_MIME_PART (medium);
+
+ return part->priv->headers;
}
static void
@@ -552,7 +544,7 @@ mime_part_set_content (CamelMedium *medium,
medium_class->set_content (medium, content);
content_type = camel_data_wrapper_get_mime_type_field (content);
- if (mime_part->mime_type != content_type) {
+ if (camel_data_wrapper_get_mime_type_field (mime_part) != content_type) {
gchar *txt;
txt = camel_content_type_format (content_type);
@@ -574,45 +566,38 @@ mime_part_write_to_stream_sync (CamelDataWrapper *dw,
gssize total = 0;
gssize count;
gint errnosav;
+ guint ii;
+ const gchar *header_name = NULL, *header_value = NULL;
d (printf ("mime_part::write_to_stream\n"));
/* FIXME: something needs to be done about this ... */
/* TODO: content-languages header? */
- if (mp->headers) {
- struct _camel_header_raw *h = mp->headers;
- gchar *val;
+ for (ii = 0; camel_name_value_array_get (mp->priv->headers, ii, &header_name, &header_value); ii++) {
gssize (*writefn) (
gpointer stream,
const gchar *name,
const gchar *value,
GCancellable *cancellable,
GError **error);
-
- /* fold/write the headers. But dont fold headers that are already formatted
- * (e.g. ones with parameter-lists, that we know about, and have created) */
- while (h) {
- val = h->value;
- if (val == NULL) {
- g_warning ("h->value is NULL here for %s", h->name);
- count = 0;
- } else if ((writefn = g_hash_table_lookup (header_formatted_table, h->name)) == NULL)
{
- val = camel_header_fold (val, strlen (h->name));
- count = write_header (
- stream, h->name, val,
- cancellable, error);
- g_free (val);
- } else {
- count = writefn (
- stream, h->name, h->value,
- cancellable, error);
- }
- if (count == -1)
- return -1;
- total += count;
- h = h->next;
+ if (header_value == NULL) {
+ g_warning ("header_value is NULL here for %s", header_name);
+ count = 0;
+ } else if ((writefn = g_hash_table_lookup (header_formatted_table, header_name)) == NULL) {
+ gchar *val = camel_header_fold (header_value, strlen (header_name));
+ count = write_header (
+ stream, header_name, val,
+ cancellable, error);
+ g_free (val);
+ } else {
+ count = writefn (
+ stream, header_name, header_value,
+ cancellable, error);
}
+ if (count == -1)
+ return -1;
+ total += count;
}
count = camel_stream_write (stream, "\n", 1, cancellable, error);
@@ -630,9 +615,9 @@ mime_part_write_to_stream_sync (CamelDataWrapper *dw,
gboolean reencode = FALSE;
const gchar *filename;
- if (camel_content_type_is (dw->mime_type, "text", "*")) {
- content_charset = camel_content_type_param (content->mime_type, "charset");
- part_charset = camel_content_type_param (dw->mime_type, "charset");
+ if (camel_content_type_is (camel_data_wrapper_get_mime_type_field (dw), "text", "*")) {
+ content_charset = camel_content_type_param (camel_data_wrapper_get_mime_type_field
(content), "charset");
+ part_charset = camel_content_type_param (camel_data_wrapper_get_mime_type_field (dw),
"charset");
if (content_charset && part_charset) {
content_charset = camel_iconv_charset_name (content_charset);
@@ -640,7 +625,7 @@ mime_part_write_to_stream_sync (CamelDataWrapper *dw,
}
}
- if (mp->priv->encoding != content->encoding) {
+ if (mp->priv->encoding != camel_data_wrapper_get_encoding (content)) {
gchar *content;
switch (mp->priv->encoding) {
@@ -767,46 +752,39 @@ mime_part_write_to_output_stream_sync (CamelDataWrapper *dw,
gssize total = 0;
gssize result;
gboolean success;
+ guint ii;
+ const gchar *header_name = NULL, *header_value = NULL;
d (printf ("mime_part::write_to_stream\n"));
/* FIXME: something needs to be done about this ... */
/* TODO: content-languages header? */
- if (mp->headers) {
- struct _camel_header_raw *h = mp->headers;
- gchar *val;
+ for (ii = 0; camel_name_value_array_get (mp->priv->headers, ii, &header_name, &header_value); ii++) {
gssize (*writefn) (
gpointer stream,
const gchar *name,
const gchar *value,
GCancellable *cancellable,
GError **error);
-
- /* fold/write the headers. But dont fold headers that are already formatted
- * (e.g. ones with parameter-lists, that we know about, and have created) */
- while (h) {
- val = h->value;
- if (val == NULL) {
- g_warning ("h->value is NULL here for %s", h->name);
- bytes_written = 0;
- result = 0;
- } else if ((writefn = g_hash_table_lookup (header_formatted_table, h->name)) == NULL)
{
- val = camel_header_fold (val, strlen (h->name));
- result = write_header (
- output_stream, h->name, val,
- cancellable, error);
- g_free (val);
- } else {
- result = writefn (
- output_stream, h->name, h->value,
- cancellable, error);
- }
- if (result == -1)
- return -1;
- total += result;
- h = h->next;
+ if (header_value == NULL) {
+ g_warning ("header_value is NULL here for %s", header_name);
+ bytes_written = 0;
+ result = 0;
+ } else if ((writefn = g_hash_table_lookup (header_formatted_table, header_name)) == NULL) {
+ gchar *val = camel_header_fold (header_value, strlen (header_name));
+ result = write_header (
+ output_stream, header_name, val,
+ cancellable, error);
+ g_free (val);
+ } else {
+ result = writefn (
+ output_stream, header_name, header_value,
+ cancellable, error);
}
+ if (result == -1)
+ return -1;
+ total += result;
}
success = g_output_stream_write_all (
@@ -828,11 +806,11 @@ mime_part_write_to_output_stream_sync (CamelDataWrapper *dw,
const gchar *filename;
content_type_is_text =
- camel_content_type_is (dw->mime_type, "text", "*");
+ camel_content_type_is (camel_data_wrapper_get_mime_type_field (dw), "text", "*");
if (content_type_is_text) {
- content_charset = camel_content_type_param (content->mime_type, "charset");
- part_charset = camel_content_type_param (dw->mime_type, "charset");
+ content_charset = camel_content_type_param (camel_data_wrapper_get_mime_type_field
(content), "charset");
+ part_charset = camel_content_type_param (camel_data_wrapper_get_mime_type_field (dw),
"charset");
if (content_charset && part_charset) {
content_charset = camel_iconv_charset_name (content_charset);
@@ -840,7 +818,7 @@ mime_part_write_to_output_stream_sync (CamelDataWrapper *dw,
}
}
- if (mp->priv->encoding != content->encoding) {
+ if (mp->priv->encoding != camel_data_wrapper_get_encoding (content)) {
gchar *content;
switch (mp->priv->encoding) {
@@ -972,40 +950,40 @@ mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
GError **error)
{
CamelDataWrapper *dw = (CamelDataWrapper *) mime_part;
- struct _camel_header_raw *headers;
+ CamelNameValueArray *headers;
const gchar *content;
gchar *buf;
gsize len;
gint err;
+ guint ii;
gboolean success = TRUE;
+ const gchar *header_name = NULL, *header_value = NULL;
switch (camel_mime_parser_step (parser, &buf, &len)) {
case CAMEL_MIME_PARSER_STATE_MESSAGE:
/* set the default type of a message always */
- if (dw->mime_type)
- camel_content_type_unref (dw->mime_type);
- dw->mime_type = camel_content_type_decode ("message/rfc822");
+ camel_data_wrapper_take_mime_type_field (dw, camel_content_type_decode ("message/rfc822"));
/* coverity[fallthrough] */
case CAMEL_MIME_PARSER_STATE_HEADER:
case CAMEL_MIME_PARSER_STATE_MULTIPART:
/* we have the headers, build them into 'us' */
- headers = camel_mime_parser_headers_raw (parser);
+ headers = camel_mime_parser_dup_headers (parser);
/* if content-type exists, process it first, set for fallback charset in headers */
- content = camel_header_raw_find (&headers, "content-type", NULL);
+ content = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE,
"Content-Type");
if (content)
- mime_part_process_header ((CamelMedium *) dw, "content-type", content);
+ mime_part_process_header (CAMEL_MEDIUM (dw), "content-type", content);
- while (headers) {
- if (g_ascii_strcasecmp (headers->name, "content-type") == 0
- && headers->value != content)
- camel_medium_add_header ((CamelMedium *) dw, "X-Invalid-Content-Type",
headers->value);
+ for (ii = 0; camel_name_value_array_get (headers, ii, &header_name, &header_value); ii++) {
+ if (g_ascii_strcasecmp (header_name, "content-type") == 0 && header_value != content)
+ camel_medium_add_header (CAMEL_MEDIUM (dw), "X-Invalid-Content-Type",
header_value);
else
- camel_medium_add_header ((CamelMedium *) dw, headers->name, headers->value);
- headers = headers->next;
+ camel_medium_add_header (CAMEL_MEDIUM (dw), header_name, header_value);
}
+ camel_name_value_array_free (headers);
+
success = camel_mime_part_construct_content_from_parser (
mime_part, parser, cancellable, error);
break;
@@ -1045,8 +1023,8 @@ camel_mime_part_class_init (CamelMimePartClass *class)
medium_class->set_header = mime_part_set_header;
medium_class->remove_header = mime_part_remove_header;
medium_class->get_header = mime_part_get_header;
+ medium_class->dup_headers = mime_part_dup_headers;
medium_class->get_headers = mime_part_get_headers;
- medium_class->free_headers = mime_part_free_headers;
medium_class->set_content = mime_part_set_content;
data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
@@ -1107,13 +1085,11 @@ camel_mime_part_init (CamelMimePart *mime_part)
mime_part->priv = CAMEL_MIME_PART_GET_PRIVATE (mime_part);
mime_part->priv->encoding = CAMEL_TRANSFER_ENCODING_DEFAULT;
+ mime_part->priv->headers = camel_name_value_array_new ();
data_wrapper = CAMEL_DATA_WRAPPER (mime_part);
- if (data_wrapper->mime_type != NULL)
- camel_content_type_unref (data_wrapper->mime_type);
-
- data_wrapper->mime_type = camel_content_type_new ("text", "plain");
+ camel_data_wrapper_take_mime_type_field (data_wrapper, camel_content_type_new ("text", "plain"));
}
/**
@@ -1538,8 +1514,7 @@ camel_mime_part_get_filename (CamelMimePart *mime_part)
return name;
}
- return camel_content_type_param (
- ((CamelDataWrapper *) mime_part)->mime_type, "name");
+ return camel_content_type_param (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER
(mime_part)), "name");
}
/**
@@ -1571,10 +1546,10 @@ camel_mime_part_set_filename (CamelMimePart *mime_part,
g_free (str);
dw = (CamelDataWrapper *) mime_part;
- if (!dw->mime_type)
- dw->mime_type = camel_content_type_new ("application", "octet-stream");
- camel_content_type_set_param (dw->mime_type, "name", filename);
- str = camel_content_type_format (dw->mime_type);
+ if (!camel_data_wrapper_get_mime_type_field (dw))
+ camel_data_wrapper_take_mime_type_field (dw, camel_content_type_new ("application",
"octet-stream"));
+ camel_content_type_set_param (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (dw)),
"name", filename);
+ str = camel_content_type_format (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (dw)));
camel_medium_set_header (medium, "Content-Type", str);
g_free (str);
}
diff --git a/src/camel/camel-mime-part.h b/src/camel/camel-mime-part.h
index bcacdcb..b21a486 100644
--- a/src/camel/camel-mime-part.h
+++ b/src/camel/camel-mime-part.h
@@ -29,6 +29,7 @@
#include <camel/camel-medium.h>
#include <camel/camel-mime-utils.h>
#include <camel/camel-mime-parser.h>
+#include <camel/camel-name-value-array.h>
/* Standard GObject macros */
#define CAMEL_TYPE_MIME_PART \
@@ -58,8 +59,6 @@ typedef struct _CamelMimePartPrivate CamelMimePartPrivate;
struct _CamelMimePart {
CamelMedium parent;
CamelMimePartPrivate *priv;
-
- struct _camel_header_raw *headers; /* mime headers */
};
struct _CamelMimePartClass {
@@ -72,8 +71,8 @@ struct _CamelMimePartClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots. */
- gpointer reserved[2];
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mime_part_get_type (void);
diff --git a/src/camel/camel-mime-utils.c b/src/camel/camel-mime-utils.c
index 7c33fb8..c49d9a1 100644
--- a/src/camel/camel-mime-utils.c
+++ b/src/camel/camel-mime-utils.c
@@ -41,6 +41,7 @@
#include "camel-iconv.h"
#include "camel-mime-utils.h"
#include "camel-net-utils.h"
+#include "camel-string-utils.h"
#ifdef G_OS_WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
@@ -4464,191 +4465,6 @@ camel_header_location_decode (const gchar *in)
return res;
}
-/* extra rfc checks */
-#define CHECKS
-
-#ifdef CHECKS
-static void
-check_header (struct _camel_header_raw *header)
-{
- guchar *cp;
-
- cp = (guchar *) header->value;
- while (cp && *cp) {
- if (!isascii (*cp)) {
- w (g_warning ("Appending header violates rfc: %s: %s", header->name, header->value));
- return;
- }
- cp++;
- }
-}
-#endif
-
-void
-camel_header_raw_append_parse (struct _camel_header_raw **list,
- const gchar *header,
- gint offset)
-{
- register const gchar *in;
- gsize fieldlen;
- gchar *name;
-
- in = header;
- while (camel_mime_is_fieldname (*in) || *in == ':')
- in++;
- fieldlen = in - header - 1;
- while (camel_mime_is_lwsp (*in))
- in++;
- if (fieldlen == 0 || header[fieldlen] != ':') {
- printf ("Invalid header line: '%s'\n", header);
- return;
- }
- name = g_alloca (fieldlen + 1);
- memcpy (name, header, fieldlen);
- name[fieldlen] = 0;
-
- camel_header_raw_append (list, name, in, offset);
-}
-
-void
-camel_header_raw_append (struct _camel_header_raw **list,
- const gchar *name,
- const gchar *value,
- gint offset)
-{
- struct _camel_header_raw *l, *n;
-
- d (printf ("Header: %s: %s\n", name, value));
-
- n = g_malloc (sizeof (*n));
- n->next = NULL;
- n->name = g_strdup (name);
- n->value = g_strdup (value);
- n->offset = offset;
-#ifdef CHECKS
- check_header (n);
-#endif
- l = (struct _camel_header_raw *) list;
- while (l->next) {
- l = l->next;
- }
- l->next = n;
-
- /* debug */
-#if 0
- if (!g_ascii_strcasecmp (name, "To")) {
- printf ("- Decoding To\n");
- camel_header_to_decode (value);
- } else if (!g_ascii_strcasecmp (name, "Content-type")) {
- printf ("- Decoding content-type\n");
- camel_content_type_dump (camel_content_type_decode (value));
- } else if (!g_ascii_strcasecmp (name, "MIME-Version")) {
- printf ("- Decoding mime version\n");
- camel_header_mime_decode (value);
- }
-#endif
-}
-
-static struct _camel_header_raw *
-header_raw_find_node (struct _camel_header_raw **list,
- const gchar *name)
-{
- struct _camel_header_raw *l;
-
- l = *list;
- while (l) {
- if (!g_ascii_strcasecmp (l->name, name))
- break;
- l = l->next;
- }
- return l;
-}
-
-const gchar *
-camel_header_raw_find (struct _camel_header_raw **list,
- const gchar *name,
- gint *offset)
-{
- struct _camel_header_raw *l;
-
- l = header_raw_find_node (list, name);
- if (l) {
- if (offset)
- *offset = l->offset;
- return l->value;
- } else
- return NULL;
-}
-
-const gchar *
-camel_header_raw_find_next (struct _camel_header_raw **list,
- const gchar *name,
- gint *offset,
- const gchar *last)
-{
- struct _camel_header_raw *l;
-
- if (last == NULL || name == NULL)
- return NULL;
-
- l = *list;
- while (l && l->value != last)
- l = l->next;
- return camel_header_raw_find (&l, name, offset);
-}
-
-static void
-header_raw_free (struct _camel_header_raw *l)
-{
- g_free (l->name);
- g_free (l->value);
- g_free (l);
-}
-
-void
-camel_header_raw_remove (struct _camel_header_raw **list,
- const gchar *name)
-{
- struct _camel_header_raw *l, *p;
-
- /* the next pointer is at the head of the structure, so this is safe */
- p = (struct _camel_header_raw *) list;
- l = *list;
- while (l) {
- if (!g_ascii_strcasecmp (l->name, name)) {
- p->next = l->next;
- header_raw_free (l);
- l = p->next;
- } else {
- p = l;
- l = l->next;
- }
- }
-}
-
-void
-camel_header_raw_replace (struct _camel_header_raw **list,
- const gchar *name,
- const gchar *value,
- gint offset)
-{
- camel_header_raw_remove (list, name);
- camel_header_raw_append (list, name, value, offset);
-}
-
-void
-camel_header_raw_clear (struct _camel_header_raw **list)
-{
- struct _camel_header_raw *l, *n;
- l = *list;
- while (l) {
- n = l->next;
- header_raw_free (l);
- l = n;
- }
- *list = NULL;
-}
-
/**
* camel_header_msgid_generate:
* @domain: domain to use (like "example.com") for the ID suffix; can be NULL
@@ -4775,8 +4591,17 @@ mailing_list_init (gpointer param)
return NULL;
}
+/**
+ * camel_headers_dup_mailing_list:
+ * @headers: a #CamelNameValueArray with headers
+ *
+ * Searches for a mailing list information among known headers and returns
+ * a newly allocated string with its value.
+ *
+ * Returns: (nullable) (transfer full): The mailing list header, or %NULL, if none is found
+ **/
gchar *
-camel_header_raw_check_mailing_list (struct _camel_header_raw **list)
+camel_headers_dup_mailing_list (const CamelNameValueArray *headers)
{
static GOnce once = G_ONCE_INIT;
const gchar *v;
@@ -4786,7 +4611,7 @@ camel_header_raw_check_mailing_list (struct _camel_header_raw **list)
g_once (&once, mailing_list_init, NULL);
for (i = 0; i < G_N_ELEMENTS (mail_list_magic); i++) {
- v = camel_header_raw_find (list, mail_list_magic[i].name, NULL);
+ v = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE,
mail_list_magic[i].name);
for (j = 0; j < 3; j++) {
match[j].rm_so = -1;
match[j].rm_eo = -1;
@@ -4850,69 +4675,77 @@ camel_header_address_new_group (const gchar *name)
}
CamelHeaderAddress *
-camel_header_address_ref (CamelHeaderAddress *h)
+camel_header_address_ref (CamelHeaderAddress *addrlist)
{
- if (h)
- h->refcount++;
+ if (addrlist)
+ addrlist->refcount++;
- return h;
+ return addrlist;
}
void
-camel_header_address_unref (CamelHeaderAddress *h)
+camel_header_address_unref (CamelHeaderAddress *addrlist)
{
- if (h) {
- if (h->refcount <= 1) {
- if (h->type == CAMEL_HEADER_ADDRESS_GROUP) {
- camel_header_address_list_clear (&h->v.members);
- } else if (h->type == CAMEL_HEADER_ADDRESS_NAME) {
- g_free (h->v.addr);
+ if (addrlist) {
+ if (addrlist->refcount <= 1) {
+ if (addrlist->type == CAMEL_HEADER_ADDRESS_GROUP) {
+ camel_header_address_list_clear (&addrlist->v.members);
+ } else if (addrlist->type == CAMEL_HEADER_ADDRESS_NAME) {
+ g_free (addrlist->v.addr);
}
- g_free (h->name);
- g_free (h);
+ g_free (addrlist->name);
+ g_free (addrlist);
} else {
- h->refcount--;
+ addrlist->refcount--;
}
}
}
void
-camel_header_address_set_name (CamelHeaderAddress *h,
+camel_header_address_set_name (CamelHeaderAddress *addrlist,
const gchar *name)
{
- if (h) {
- g_free (h->name);
- h->name = g_strdup (name);
+ if (addrlist) {
+ g_free (addrlist->name);
+ addrlist->name = g_strdup (name);
}
}
void
-camel_header_address_set_addr (CamelHeaderAddress *h,
+camel_header_address_set_addr (CamelHeaderAddress *addrlist,
const gchar *addr)
{
- if (h) {
- if (h->type == CAMEL_HEADER_ADDRESS_NAME
- || h->type == CAMEL_HEADER_ADDRESS_NONE) {
- h->type = CAMEL_HEADER_ADDRESS_NAME;
- g_free (h->v.addr);
- h->v.addr = g_strdup (addr);
+ if (addrlist) {
+ if (addrlist->type == CAMEL_HEADER_ADDRESS_NAME
+ || addrlist->type == CAMEL_HEADER_ADDRESS_NONE) {
+ addrlist->type = CAMEL_HEADER_ADDRESS_NAME;
+ g_free (addrlist->v.addr);
+ addrlist->v.addr = g_strdup (addr);
} else {
g_warning ("Trying to set the address on a group");
}
}
}
+/**
+ * camel_header_address_set_members:
+ * @addrlist: a #CamelHeaderAddress object
+ * @group: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress
+ *
+ * TODO: Document me.
+ *
+ **/
void
-camel_header_address_set_members (CamelHeaderAddress *h,
+camel_header_address_set_members (CamelHeaderAddress *addrlist,
CamelHeaderAddress *group)
{
- if (h) {
- if (h->type == CAMEL_HEADER_ADDRESS_GROUP
- || h->type == CAMEL_HEADER_ADDRESS_NONE) {
- h->type = CAMEL_HEADER_ADDRESS_GROUP;
- camel_header_address_list_clear (&h->v.members);
+ if (addrlist) {
+ if (addrlist->type == CAMEL_HEADER_ADDRESS_GROUP
+ || addrlist->type == CAMEL_HEADER_ADDRESS_NONE) {
+ addrlist->type = CAMEL_HEADER_ADDRESS_GROUP;
+ camel_header_address_list_clear (&addrlist->v.members);
/* should this ref them? */
- h->v.members = group;
+ addrlist->v.members = group;
} else {
g_warning ("Trying to set the members on a name, not group");
}
@@ -4920,52 +4753,75 @@ camel_header_address_set_members (CamelHeaderAddress *h,
}
void
-camel_header_address_add_member (CamelHeaderAddress *h,
+camel_header_address_add_member (CamelHeaderAddress *addrlist,
CamelHeaderAddress *member)
{
- if (h) {
- if (h->type == CAMEL_HEADER_ADDRESS_GROUP
- || h->type == CAMEL_HEADER_ADDRESS_NONE) {
- h->type = CAMEL_HEADER_ADDRESS_GROUP;
- camel_header_address_list_append (&h->v.members, member);
+ if (addrlist) {
+ if (addrlist->type == CAMEL_HEADER_ADDRESS_GROUP
+ || addrlist->type == CAMEL_HEADER_ADDRESS_NONE) {
+ addrlist->type = CAMEL_HEADER_ADDRESS_GROUP;
+ camel_header_address_list_append (&addrlist->v.members, member);
}
}
}
+/**
+ * camel_header_address_list_append_list:
+ * @addrlistp: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ * @addrs: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress to add
+ *
+ * TODO: Document me.
+ *
+ **/
void
-camel_header_address_list_append_list (CamelHeaderAddress **l,
- CamelHeaderAddress **h)
+camel_header_address_list_append_list (CamelHeaderAddress **addrlistp,
+ CamelHeaderAddress **addrs)
{
- if (l) {
- CamelHeaderAddress *n = (CamelHeaderAddress *) l;
+ if (addrlistp) {
+ CamelHeaderAddress *n = (CamelHeaderAddress *) addrlistp;
while (n->next)
n = n->next;
- n->next = *h;
+ n->next = *addrs;
}
}
+/**
+ * camel_header_address_list_append:
+ * @addrlistp: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ * @addr: the #CamelHeaderAddress to add
+ *
+ * TODO: Document me.
+ *
+ **/
void
-camel_header_address_list_append (CamelHeaderAddress **l,
- CamelHeaderAddress *h)
+camel_header_address_list_append (CamelHeaderAddress **addrlistp,
+ CamelHeaderAddress *addr)
{
- if (h) {
- camel_header_address_list_append_list (l, &h);
- h->next = NULL;
+ if (addr) {
+ camel_header_address_list_append_list (addrlistp, &addr);
+ addr->next = NULL;
}
}
+/**
+ * camel_header_address_list_clear:
+ * @addrlistp: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ *
+ * TODO: Document me.
+ *
+ **/
void
-camel_header_address_list_clear (CamelHeaderAddress **l)
+camel_header_address_list_clear (CamelHeaderAddress **addrlistp)
{
CamelHeaderAddress *a, *n;
- a = *l;
+ a = *addrlistp;
while (a) {
n = a->next;
camel_header_address_unref (a);
a = n;
}
- *l = NULL;
+ *addrlistp = NULL;
}
/* if encode is true, then the result is suitable for mailing, otherwise
@@ -5012,35 +4868,49 @@ header_address_list_encode_append (GString *out,
}
}
+/**
+ * camel_header_address_list_encode:
+ * @addrlist: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ *
+ * TODO: Document me.
+ *
+ **/
gchar *
-camel_header_address_list_encode (CamelHeaderAddress *a)
+camel_header_address_list_encode (CamelHeaderAddress *addrlist)
{
GString *out;
gchar *ret;
- if (a == NULL)
+ if (!addrlist)
return NULL;
out = g_string_new ("");
- header_address_list_encode_append (out, TRUE, a);
+ header_address_list_encode_append (out, TRUE, addrlist);
ret = out->str;
g_string_free (out, FALSE);
return ret;
}
+/**
+ * camel_header_address_list_format:
+ * @addrlist: (array zero-terminated=1): a NULL-terminated list of #CamelHeaderAddress objects
+ *
+ * TODO: Document me.
+ *
+ **/
gchar *
-camel_header_address_list_format (CamelHeaderAddress *a)
+camel_header_address_list_format (CamelHeaderAddress *addrlist)
{
GString *out;
gchar *ret;
- if (a == NULL)
+ if (!addrlist)
return NULL;
out = g_string_new ("");
- header_address_list_encode_append (out, FALSE, a);
+ header_address_list_encode_append (out, FALSE, addrlist);
ret = out->str;
g_string_free (out, FALSE);
diff --git a/src/camel/camel-mime-utils.h b/src/camel/camel-mime-utils.h
index 2a51044..0e42793 100644
--- a/src/camel/camel-mime-utils.h
+++ b/src/camel/camel-mime-utils.h
@@ -29,6 +29,10 @@
#include <glib.h>
#include <glib-object.h>
#include <camel/camel-enums.h>
+#include <camel/camel-utils.h>
+#include <camel/camel-name-value-array.h>
+
+G_BEGIN_DECLS
/* maximum recommended size of a line from camel_header_fold() */
#define CAMEL_FOLD_SIZE (77)
@@ -43,8 +47,6 @@ typedef enum {
#define CAMEL_UUDECODE_STATE_MASK (CAMEL_UUDECODE_STATE_BEGIN | CAMEL_UUDECODE_STATE_END)
-G_BEGIN_DECLS
-
typedef struct _camel_header_param {
struct _camel_header_param *next;
gchar *name;
@@ -59,15 +61,6 @@ typedef struct {
guint refcount;
} CamelContentType;
-/* a raw rfc822 header */
-/* the value MUST be US-ASCII */
-struct _camel_header_raw {
- struct _camel_header_raw *next;
- gchar *name;
- gchar *value;
- gint offset; /* in file, if known */
-};
-
typedef struct _CamelContentDisposition {
gchar *disposition;
struct _camel_header_param *params;
@@ -81,6 +74,7 @@ typedef enum _camel_header_address_t {
} CamelHeaderAddressType;
typedef struct _camel_header_address {
+ /* < private > */
struct _camel_header_address *next;
CamelHeaderAddressType type;
gchar *name;
@@ -152,23 +146,13 @@ gchar *camel_content_disposition_format (CamelContentDisposition *disposition);
/* decode the contents of a content-encoding header */
gchar *camel_content_transfer_encoding_decode (const gchar *in);
-/* raw headers */
-void camel_header_raw_append (struct _camel_header_raw **list, const gchar *name, const gchar *value, gint
offset);
-void camel_header_raw_append_parse (struct _camel_header_raw **list, const gchar *header, gint offset);
-const gchar *camel_header_raw_find (struct _camel_header_raw **list, const gchar *name, gint *offset);
-const gchar *camel_header_raw_find_next (struct _camel_header_raw **list, const gchar *name, gint *offset,
const gchar *last);
-void camel_header_raw_replace (struct _camel_header_raw **list, const gchar *name, const gchar *value, gint
offset);
-void camel_header_raw_remove (struct _camel_header_raw **list, const gchar *name);
-void camel_header_raw_fold (struct _camel_header_raw **list);
-void camel_header_raw_clear (struct _camel_header_raw **list);
-
-gchar *camel_header_raw_check_mailing_list (struct _camel_header_raw **list);
-
/* fold a header */
gchar *camel_header_address_fold (const gchar *in, gsize headerlen);
gchar *camel_header_fold (const gchar *in, gsize headerlen);
gchar *camel_header_unfold (const gchar *in);
+gchar *camel_headers_dup_mailing_list (const CamelNameValueArray *headers);
+
/* decode a header which is a simple token */
gchar *camel_header_token_decode (const gchar *in);
diff --git a/src/camel/camel-movemail.c b/src/camel/camel-movemail.c
index 4e00e2e..3bda653 100644
--- a/src/camel/camel-movemail.c
+++ b/src/camel/camel-movemail.c
@@ -431,22 +431,24 @@ camel_movemail_copy_filter (gint fromfd,
* want to maintain it! */
static gint
solaris_header_write (gint fd,
- struct _camel_header_raw *header)
+ CamelNameValueArray *headers)
{
struct iovec iv[4];
gint outlen = 0, len;
+ guint ii;
+ const gchar *header_name = NULL, *header_value = NULL;
iv[1].iov_base = ":";
iv[1].iov_len = 1;
iv[3].iov_base = "\n";
iv[3].iov_len = 1;
- while (header) {
- if (g_ascii_strcasecmp (header->name, "Content-Length")) {
- iv[0].iov_base = header->name;
- iv[0].iov_len = strlen (header->name);
- iv[2].iov_base = header->value;
- iv[2].iov_len = strlen (header->value);
+ for (ii = 0; camel_name_value_array_get (headers, ii, &header_name, &header_value); ii++) {
+ if (g_ascii_strcasecmp (header_name, "Content-Length")) {
+ iv[0].iov_base = header_name;
+ iv[0].iov_len = strlen (header_name);
+ iv[2].iov_base = header_value;
+ iv[2].iov_len = strlen (header_value);
do {
len = writev (fd, iv, 4);
@@ -456,7 +458,6 @@ solaris_header_write (gint fd,
return -1;
outlen += len;
}
- header = header->next;
}
do {
@@ -510,6 +511,7 @@ camel_movemail_solaris (gint oldsfd,
g_return_val_if_fail (camel_mime_parser_from_line (mp), -1);
from = g_strdup (camel_mime_parser_from_line (mp));
if (camel_mime_parser_step (mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_FROM_END) {
+ CamelNameValueArray *headers;
const gchar *cl;
gint length;
gint start, body;
@@ -524,9 +526,13 @@ camel_movemail_solaris (gint oldsfd,
goto fail;
/* write out headers, but NOT content-length header */
- if (solaris_header_write (dfd, camel_mime_parser_headers_raw (mp)) == -1)
+ headers = camel_mime_parser_dup_headers (mp);
+ if (solaris_header_write (dfd, headers) == -1) {
+ camel_name_value_array_free (headers);
goto fail;
+ }
+ camel_name_value_array_free (headers);
cl = camel_mime_parser_header (mp, "content-length", NULL);
if (cl == NULL) {
g_warning ("Required Content-Length header is missing from solaris mail box @
%d", (gint) camel_mime_parser_tell (mp));
diff --git a/src/camel/camel-msgport.c b/src/camel/camel-msgport.c
index 26a9cd0..75ee41f 100644
--- a/src/camel/camel-msgport.c
+++ b/src/camel/camel-msgport.c
@@ -238,7 +238,7 @@ msgport_sync_with_prpipe (PRFileDesc *prfd)
}
/**
- * camel_msgport_new:
+ * camel_msgport_new: (skip)
*
* Since: 2.24
**/
@@ -258,7 +258,7 @@ camel_msgport_new (void)
}
/**
- * camel_msgport_destroy:
+ * camel_msgport_destroy: (skip)
*
* Since: 2.24
**/
@@ -281,7 +281,7 @@ camel_msgport_destroy (CamelMsgPort *msgport)
}
/**
- * camel_msgport_fd:
+ * camel_msgport_fd: (skip)
*
* Since: 2.24
**/
@@ -302,7 +302,9 @@ camel_msgport_fd (CamelMsgPort *msgport)
}
/**
- * camel_msgport_prfd:
+ * camel_msgport_prfd: (skip)
+ *
+ * Returns: (transfer none):
*
* Since: 2.24
**/
@@ -323,7 +325,7 @@ camel_msgport_prfd (CamelMsgPort *msgport)
}
/**
- * camel_msgport_push:
+ * camel_msgport_push: (skip)
*
* Since: 2.24
**/
@@ -374,7 +376,7 @@ camel_msgport_push (CamelMsgPort *msgport,
}
/**
- * camel_msgport_pop:
+ * camel_msgport_pop: (skip)
*
* Since: 2.24
**/
@@ -402,7 +404,7 @@ camel_msgport_pop (CamelMsgPort *msgport)
}
/**
- * camel_msgport_try_pop:
+ * camel_msgport_try_pop: (skip)
*
* Since: 2.24
**/
@@ -428,7 +430,7 @@ camel_msgport_try_pop (CamelMsgPort *msgport)
}
/**
- * camel_msgport_timeout_pop:
+ * camel_msgport_timeout_pop: (skip)
* @msgport: a #CamelMsgPort
* @timeout: number of microseconds to wait
*
@@ -457,7 +459,7 @@ camel_msgport_timeout_pop (CamelMsgPort *msgport,
}
/**
- * camel_msgport_reply:
+ * camel_msgport_reply: (skip)
*
* Since: 2.24
**/
diff --git a/src/camel/camel-multipart-encrypted.h b/src/camel/camel-multipart-encrypted.h
index dedb469..2566538 100644
--- a/src/camel/camel-multipart-encrypted.h
+++ b/src/camel/camel-multipart-encrypted.h
@@ -65,6 +65,8 @@ struct _CamelMultipartEncrypted {
struct _CamelMultipartEncryptedClass {
CamelMultipartClass parent_class;
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_multipart_encrypted_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-multipart-signed.h b/src/camel/camel-multipart-signed.h
index 6d84d0f..aef7d5f 100644
--- a/src/camel/camel-multipart-signed.h
+++ b/src/camel/camel-multipart-signed.h
@@ -69,6 +69,9 @@ struct _CamelMultipartSigned {
struct _CamelMultipartSignedClass {
CamelMultipartClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_multipart_signed_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-multipart.c b/src/camel/camel-multipart.c
index 0836b5e..ea51717 100644
--- a/src/camel/camel-multipart.c
+++ b/src/camel/camel-multipart.c
@@ -297,7 +297,7 @@ multipart_set_boundary (CamelMultipart *multipart,
gsize length;
gint state, save;
- g_return_if_fail (cdw->mime_type != NULL);
+ g_return_if_fail (camel_data_wrapper_get_mime_type_field (cdw) != NULL);
length = g_checksum_type_get_length (G_CHECKSUM_MD5);
digest = g_alloca (length);
@@ -328,7 +328,7 @@ multipart_set_boundary (CamelMultipart *multipart,
boundary = bbuf;
}
- camel_content_type_set_param (cdw->mime_type, "boundary", boundary);
+ camel_content_type_set_param (camel_data_wrapper_get_mime_type_field (cdw), "boundary", boundary);
}
static const gchar *
@@ -336,8 +336,8 @@ multipart_get_boundary (CamelMultipart *multipart)
{
CamelDataWrapper *cdw = CAMEL_DATA_WRAPPER (multipart);
- g_return_val_if_fail (cdw->mime_type != NULL, NULL);
- return camel_content_type_param (cdw->mime_type, "boundary");
+ g_return_val_if_fail (camel_data_wrapper_get_mime_type_field (cdw) != NULL, NULL);
+ return camel_content_type_param (camel_data_wrapper_get_mime_type_field (cdw), "boundary");
}
static gint
diff --git a/src/camel/camel-multipart.h b/src/camel/camel-multipart.h
index 171b0eb..8284edc 100644
--- a/src/camel/camel-multipart.h
+++ b/src/camel/camel-multipart.h
@@ -73,6 +73,9 @@ struct _CamelMultipartClass {
gint (*construct_from_parser)
(CamelMultipart *multipart,
CamelMimeParser *parser);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_multipart_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-name-value-array.c b/src/camel/camel-name-value-array.c
new file mode 100644
index 0000000..0a90e02
--- /dev/null
+++ b/src/camel/camel-name-value-array.c
@@ -0,0 +1,636 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "camel-string-utils.h"
+
+#include "camel-name-value-array.h"
+
+G_DEFINE_BOXED_TYPE (CamelNameValueArray,
+ camel_name_value_array,
+ camel_name_value_array_copy,
+ camel_name_value_array_free)
+
+typedef struct _CamelNameValuePair {
+ gchar *name;
+ gchar *value;
+} CamelNameValuePair;
+
+static void
+free_name_value_content (gpointer ptr)
+{
+ CamelNameValuePair *pair = ptr;
+
+ if (pair) {
+ g_free (pair->name);
+ g_free (pair->value);
+
+ pair->name = NULL;
+ pair->value = NULL;
+ }
+}
+
+/**
+ * camel_name_value_array_new:
+ *
+ * Creates a new #CamelNameValueArray. The returned pointer should be freed
+ * with camel_name_value_array_free() when no longer needed.
+ *
+ * Returns: (transfer full): A new #CamelNameValueArray.
+ *
+ * See: camel_name_value_array_new_sized, camel_name_value_array_copy
+ *
+ * Since: 3.24
+ **/
+CamelNameValueArray *
+camel_name_value_array_new (void)
+{
+ GArray *arr;
+
+ arr = g_array_new (FALSE, FALSE, sizeof (CamelNameValuePair));
+ g_array_set_clear_func (arr, free_name_value_content);
+
+ return (CamelNameValueArray *) arr;
+}
+
+/**
+ * camel_name_value_array_new_sized:
+ * @reserve_size: an array size to reserve
+ *
+ * Creates a new #CamelNameValueArray, which has reserved @reserve_size
+ * elements. This value doesn't influence the camel_name_value_array_get_length(),
+ * which returns zero on the array returned from this function. The returned
+ * pointer should be freed with camel_name_value_array_free() when no longer needed.
+ *
+ * Returns: (transfer full): A new #CamelNameValueArray.
+ *
+ * See: camel_name_value_array_new, camel_name_value_array_copy
+ *
+ * Since: 3.24
+ **/
+CamelNameValueArray *
+camel_name_value_array_new_sized (guint reserve_size)
+{
+ GArray *arr;
+
+ arr = g_array_sized_new (FALSE, FALSE, sizeof (CamelNameValuePair), reserve_size);
+ g_array_set_clear_func (arr, free_name_value_content);
+
+ return (CamelNameValueArray *) arr;
+}
+
+/**
+ * camel_name_value_array_copy:
+ * @array: (nullable): a #CamelNameValueArray
+ *
+ * Creates a new copy of the @array. The returned pointer should be freed
+ * with camel_name_value_array_free() when no longer needed.
+ *
+ * Returns: (transfer full): A new copy of the @array.
+ *
+ * See: camel_name_value_array_new, camel_name_value_array_new_sized
+ *
+ * Since: 3.24
+ **/
+CamelNameValueArray *
+camel_name_value_array_copy (const CamelNameValueArray *array)
+{
+ CamelNameValueArray *copy;
+ guint ii, len;
+
+ if (!array)
+ return NULL;
+
+ len = camel_name_value_array_get_length (array);
+ copy = camel_name_value_array_new_sized (len);
+
+ for (ii = 0; ii < len; ii++) {
+ const gchar *name = NULL, *value = NULL;
+
+ if (camel_name_value_array_get (array, ii, &name, &value))
+ camel_name_value_array_append (copy, name, value);
+ }
+
+ return copy;
+}
+
+/**
+ * camel_name_value_array_free:
+ * @array: (nullable): a #CamelNameValueArray, or %NULL
+ *
+ * Frees the @array, previously allocated by camel_name_value_array_new(),
+ * camel_name_value_array_new_sized() or camel_name_value_array_copy().
+ * If the @array is %NULL, then does nothing.
+ *
+ * Since: 3.24
+ **/
+void
+camel_name_value_array_free (CamelNameValueArray *array)
+{
+ if (array)
+ g_array_free ((GArray *) array, TRUE);
+}
+
+/**
+ * camel_name_value_array_get_length:
+ * @array: (nullable): a #CamelNameValueArray
+ *
+ * Returns: Length of the @array, aka how many elements are stored in the @array.
+ *
+ * Since: 3.24
+ **/
+guint
+camel_name_value_array_get_length (const CamelNameValueArray *array)
+{
+ GArray *arr = (GArray *) array;
+
+ if (!array)
+ return 0;
+
+ return arr->len;
+}
+
+/**
+ * camel_name_value_array_get:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ * @out_name: (out) (nullable): A place to store the name of the element, or %NULL
+ * @out_value: (out) (nullable): A place to store the value of the element, or %NULL
+ *
+ * Returns the name and the value of the element at index @index. Either
+ * of the @out_name and @out_value can be %NULL, to not return that part.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise.
+ *
+ * See: camel_name_value_array_get_name, camel_name_value_array_get_value, camel_name_value_array_get_named
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_get (const CamelNameValueArray *array,
+ guint index,
+ const gchar **out_name,
+ const gchar **out_value)
+{
+ GArray *arr = (GArray *) array;
+ CamelNameValuePair *pair;
+
+ g_return_val_if_fail (array != NULL, FALSE);
+
+ if (index >= camel_name_value_array_get_length (array))
+ return FALSE;
+
+ pair = &g_array_index (arr, CamelNameValuePair, index);
+
+ if (out_name)
+ *out_name = pair->name;
+ if (out_value)
+ *out_value= pair->value;
+
+ return TRUE;
+}
+
+static guint
+camel_name_value_array_find_named (const CamelNameValueArray *array,
+ CamelCompareType compare_type,
+ const gchar *name)
+{
+ GArray *arr = (GArray *) array;
+ gboolean case_sensitive;
+ gint ii;
+
+ g_return_val_if_fail (array != NULL, (guint) -1);
+ g_return_val_if_fail (name != NULL, (guint) -1);
+
+ case_sensitive = compare_type == CAMEL_COMPARE_CASE_SENSITIVE;
+
+ for (ii = 0; ii < arr->len; ii++) {
+ CamelNameValuePair *pair = &g_array_index (arr, CamelNameValuePair, ii);
+
+ if ((case_sensitive && g_strcmp0 (name, pair->name) == 0) ||
+ (!case_sensitive && pair->name && camel_strcase_equal (name, pair->name))) {
+ return ii;
+ }
+ }
+
+ return (guint) -1;
+}
+
+/**
+ * camel_name_value_array_get_named:
+ * @array: a #CamelNameValueArray
+ * @compare_type: a compare type, one of #CamelCompareType
+ * @name: a name
+ *
+ * Returns the value of the first element named @name, or %NULL when there
+ * is no element of such @name in the @array. The @compare_type determines
+ * how to compare the names.
+ *
+ * Returns: (transfer none) (nullable): Value of the first element named @name, or %NULL.
+ *
+ * See: camel_name_value_array_get, camel_name_value_array_get_name
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_name_value_array_get_named (const CamelNameValueArray *array,
+ CamelCompareType compare_type,
+ const gchar *name)
+{
+ guint index;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ index = camel_name_value_array_find_named (array, compare_type, name);
+ if (index == (guint) -1)
+ return NULL;
+
+ return camel_name_value_array_get_value (array, index);
+}
+
+/**
+ * camel_name_value_array_get_name:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ *
+ * Returns the name of the element at index @index.
+ *
+ * Returns: (transfer none) (nullable): Name of the element at the given @index,
+ * or %NULL on error.
+ *
+ * See: camel_name_value_array_get, camel_name_value_array_get_value
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_name_value_array_get_name (const CamelNameValueArray *array,
+ guint index)
+{
+ const gchar *name = NULL;
+
+ g_return_val_if_fail (array != NULL, NULL);
+
+ if (!camel_name_value_array_get (array, index, &name, NULL))
+ return NULL;
+
+ return name;
+}
+
+/**
+ * camel_name_value_array_get_value:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ *
+ * Returns the value of the element at index @index.
+ *
+ * Returns: (transfer none) (nullable): Value of the element at the given @index,
+ * or %NULL on error.
+ *
+ * See: camel_name_value_array_get, camel_name_value_array_get_name
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_name_value_array_get_value (const CamelNameValueArray *array,
+ guint index)
+{
+ const gchar *value = NULL;
+
+ g_return_val_if_fail (array != NULL, NULL);
+
+ if (!camel_name_value_array_get (array, index, NULL, &value))
+ return NULL;
+
+ return value;
+}
+
+/**
+ * camel_name_value_array_append:
+ * @array: a #CamelNameValueArray
+ * @name: a name
+ * @value: a value
+ *
+ * Appends a new element of the name @name and the value @value
+ * at the end of @array.
+ *
+ * See: camel_name_value_array_set_named
+ *
+ * Since: 3.24
+ **/
+void
+camel_name_value_array_append (CamelNameValueArray *array,
+ const gchar *name,
+ const gchar *value)
+{
+ GArray *arr = (GArray *) array;
+ CamelNameValuePair pair;
+
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (value != NULL);
+
+ pair.name = g_strdup (name);
+ pair.value = g_strdup (value);
+
+ g_array_append_val (arr, pair);
+}
+
+static gboolean
+camel_name_value_array_set_internal (CamelNameValueArray *array,
+ guint index,
+ const gchar *name,
+ const gchar *value)
+{
+ GArray *arr = (GArray *) array;
+ CamelNameValuePair *pair;
+ gboolean changed = FALSE;
+
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+
+ pair = &g_array_index (arr, CamelNameValuePair, index);
+
+ if (name && g_strcmp0 (pair->name, name) != 0) {
+ g_free (pair->name);
+ pair->name = g_strdup (name);
+ changed = TRUE;
+ }
+
+ if (value && g_strcmp0 (pair->value, value) != 0) {
+ g_free (pair->value);
+ pair->value = g_strdup (value);
+ changed = TRUE;
+ }
+
+ return changed;
+}
+
+/**
+ * camel_name_value_array_set:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ * @name: a name
+ * @value: a value
+ *
+ * Sets both the @name and the @value of the element at index @index.
+ *
+ * Returns: Whether the @array changed.
+ *
+ * See: camel_name_value_array_append, camel_name_value_array_set_name, camel_name_value_array_set_value
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_set (CamelNameValueArray *array,
+ guint index,
+ const gchar *name,
+ const gchar *value)
+{
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ return camel_name_value_array_set_internal (array, index, name, value);
+}
+
+/**
+ * camel_name_value_array_set_name:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ * @name: a name
+ *
+ * Sets the @name of the element at index @index.
+ *
+ * Returns: Whether the @array changed.
+ *
+ * See: camel_name_value_array_set, camel_name_value_array_set_value
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_set_name (CamelNameValueArray *array,
+ guint index,
+ const gchar *name)
+{
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return camel_name_value_array_set_internal (array, index, name, NULL);
+}
+
+/**
+ * camel_name_value_array_set_value:
+ * @array: a #CamelNameValueArray
+ * @index: an index
+ * @value: a value
+ *
+ * Sets the @value of the element at index @index.
+ *
+ * Returns: Whether the @array changed.
+ *
+ * See: camel_name_value_array_set, camel_name_value_array_set_name
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_set_value (CamelNameValueArray *array,
+ guint index,
+ const gchar *value)
+{
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ return camel_name_value_array_set_internal (array, index, NULL, value);
+}
+
+/**
+ * camel_name_value_array_set_named:
+ * @array: a #CamelNameValueArray
+ * @compare_type: a compare type, one of #CamelCompareType
+ * @name: a name
+ * @value: a value
+ *
+ * Finds an element named @name and sets its value to @value, or appends
+ * a new element, in case no such named element exists in the @array yet.
+ * In case there are more elements named with @name only the first
+ * occurrence is changed. The @compare_type determines how to compare
+ * the names.
+ *
+ * Returns: Whether the @array changed.
+ *
+ * See: camel_name_value_array_append, camel_name_value_array_set
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_set_named (CamelNameValueArray *array,
+ CamelCompareType compare_type,
+ const gchar *name,
+ const gchar *value)
+{
+ gboolean changed = FALSE;
+ guint index;
+
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ index = camel_name_value_array_find_named (array, compare_type, name);
+ if (index == (guint) -1) {
+ camel_name_value_array_append (array, name, value);
+ changed = TRUE;
+ } else {
+ changed = camel_name_value_array_set_value (array, index, value);
+ }
+
+ return changed;
+}
+
+/**
+ * camel_name_value_array_remove:
+ * @array: a #CamelNameValueArray
+ * @index: an index to remove
+ *
+ * Removes element at index @index.
+ *
+ * Returns: Whether the element was removed.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_remove (CamelNameValueArray *array,
+ guint index)
+{
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index < camel_name_value_array_get_length (array), FALSE);
+
+ g_array_remove_index ((GArray *) array, index);
+
+ return TRUE;
+}
+
+/**
+ * camel_name_value_array_remove_named:
+ * @array: a #CamelNameValueArray
+ * @compare_type: a compare type, one of #CamelCompareType
+ * @name: a name to remove
+ * @all_occurrences: whether to remove all occurrences of the @name
+ *
+ * Removes elements of the @array with the given @name.
+ * The @compare_type determines hot to compare the names.
+ * If the @all_occurrences is set to %TRUE, then every elements with the @name
+ * are removed, otherwise only the first occurrence is removed.
+ *
+ * Returns: How many elements had been removed.
+ *
+ * Since: 3.24
+ **/
+guint
+camel_name_value_array_remove_named (CamelNameValueArray *array,
+ CamelCompareType compare_type,
+ const gchar *name,
+ gboolean all_occurrences)
+{
+ guint index, removed = 0;
+
+ g_return_val_if_fail (array != NULL, 0);
+ g_return_val_if_fail (name != NULL, 0);
+
+ while (index = camel_name_value_array_find_named (array, compare_type, name), index != (guint) -1) {
+ if (!camel_name_value_array_remove (array, index))
+ break;
+
+ removed++;
+
+ if (!all_occurrences)
+ break;
+ }
+
+ return removed;
+}
+
+/**
+ * camel_name_value_array_clear:
+ * @array: a #CamelNameValueArray
+ *
+ * Removes all elements of the @array.
+ *
+ * Since: 3.24
+ **/
+void
+camel_name_value_array_clear (CamelNameValueArray *array)
+{
+ GArray *arr = (GArray *) array;
+
+ g_return_if_fail (array != NULL);
+
+ g_array_remove_range (arr, 0, arr->len);
+}
+
+/**
+ * camel_name_value_array_equal:
+ * @array_a: (nullable): the first #CamelNameValueArray
+ * @array_b: (nullable): the second #CamelNameValueArray
+ * @compare_type: a compare type, one of #CamelCompareType
+ *
+ * Compares content of the two #CamelNameValueArray and returns whether
+ * they equal. Note this is an expensive operation for large arrays.
+ *
+ * Returns: Whether the two #CamelNameValueArray have the same content.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_equal (const CamelNameValueArray *array_a,
+ const CamelNameValueArray *array_b,
+ CamelCompareType compare_type)
+{
+ guint ii, len;
+
+ if (array_a == array_b)
+ return TRUE;
+
+ if (!array_a || !array_b)
+ return FALSE;
+
+ len = camel_name_value_array_get_length (array_a);
+ if (len != camel_name_value_array_get_length (array_b))
+ return FALSE;
+
+ for (ii = 0; ii < len; ii++) {
+ const gchar *value1, *value2;
+
+ value1 = camel_name_value_array_get_value (array_a, ii);
+ value2 = camel_name_value_array_get_named (array_b, compare_type,
+ camel_name_value_array_get_name (array_a, ii));
+
+ if (g_strcmp0 (value1, value2) != 0)
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/camel/camel-name-value-array.h b/src/camel/camel-name-value-array.h
new file mode 100644
index 0000000..b3886b7
--- /dev/null
+++ b/src/camel/camel-name-value-array.h
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_NAME_VALUE_ARRAY_H
+#define CAMEL_NAME_VALUE_ARRAY_H
+
+#include <glib-object.h>
+#include <camel/camel-enums.h>
+
+G_BEGIN_DECLS
+
+/**
+ * CamelNameValueArray:
+ *
+ * Since: 3.24
+ **/
+struct _CamelNameValueArray;
+typedef struct _CamelNameValueArray CamelNameValueArray;
+
+#define CAMEL_TYPE_NAME_VALUE_ARRAY (camel_name_value_array_get_type ())
+
+GType camel_name_value_array_get_type (void) G_GNUC_CONST;
+CamelNameValueArray *
+ camel_name_value_array_new (void);
+CamelNameValueArray *
+ camel_name_value_array_new_sized
+ (guint reserve_size);
+CamelNameValueArray *
+ camel_name_value_array_copy (const CamelNameValueArray *array);
+void camel_name_value_array_free (CamelNameValueArray *array);
+guint camel_name_value_array_get_length
+ (const CamelNameValueArray *array);
+gboolean camel_name_value_array_get (const CamelNameValueArray *array,
+ guint index,
+ const gchar **out_name,
+ const gchar **out_value);
+const gchar * camel_name_value_array_get_named
+ (const CamelNameValueArray *array,
+ CamelCompareType compare_type,
+ const gchar *name);
+const gchar * camel_name_value_array_get_name (const CamelNameValueArray *array,
+ guint index);
+const gchar * camel_name_value_array_get_value
+ (const CamelNameValueArray *array,
+ guint index);
+void camel_name_value_array_append (CamelNameValueArray *array,
+ const gchar *name,
+ const gchar *value);
+gboolean camel_name_value_array_set (CamelNameValueArray *array,
+ guint index,
+ const gchar *name,
+ const gchar *value);
+gboolean camel_name_value_array_set_name (CamelNameValueArray *array,
+ guint index,
+ const gchar *name);
+gboolean camel_name_value_array_set_value
+ (CamelNameValueArray *array,
+ guint index,
+ const gchar *value);
+gboolean camel_name_value_array_set_named
+ (CamelNameValueArray *array,
+ CamelCompareType compare_type,
+ const gchar *name,
+ const gchar *value);
+gboolean camel_name_value_array_remove (CamelNameValueArray *array,
+ guint index);
+guint camel_name_value_array_remove_named
+ (CamelNameValueArray *array,
+ CamelCompareType compare_type,
+ const gchar *name,
+ gboolean all_occurrences);
+void camel_name_value_array_clear (CamelNameValueArray *array);
+gboolean camel_name_value_array_equal (const CamelNameValueArray *array_a,
+ const CamelNameValueArray *array_b,
+ CamelCompareType compare_type);
+
+G_END_DECLS
+
+#endif /* CAMEL_NAME_VALUE_ARRAY_H */
diff --git a/src/camel/camel-named-flags.c b/src/camel/camel-named-flags.c
new file mode 100644
index 0000000..04d9d30
--- /dev/null
+++ b/src/camel/camel-named-flags.c
@@ -0,0 +1,319 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "camel-named-flags.h"
+
+G_DEFINE_BOXED_TYPE (CamelNamedFlags,
+ camel_named_flags,
+ camel_named_flags_copy,
+ camel_named_flags_free)
+
+/**
+ * camel_named_flags_new:
+ *
+ * Creates a new #CamelNamedFlags.
+ *
+ * Returns: (transfer full): A newly allocated #CamelNamedFlags.
+ * Free it with camel_named_flags_free() when done with it.
+ *
+ * Since: 3.24
+ **/
+CamelNamedFlags *
+camel_named_flags_new (void)
+{
+ return (CamelNamedFlags *) g_ptr_array_new_with_free_func (g_free);
+}
+
+/**
+ * camel_named_flags_new_sized:
+ * @reserve_size: an array size to reserve
+ *
+ * Created a new #CamelNamedFlags, which has reserved @reserve_size
+ * elements. This value doesn't influence the camel_named_flags_get_length(),
+ * which returns zero on the array returned from this function.
+ *
+ * Returns: (transfer full): A newly allocated #CamelNameValueArray.
+ * Free it with camel_named_flags_free() when done with it.
+ *
+ * See: camel_name_value_array_new, camel_name_value_array_copy
+ *
+ * Since: 3.24
+ **/
+CamelNamedFlags *
+camel_named_flags_new_sized (guint reserve_size)
+{
+ return (CamelNamedFlags *) g_ptr_array_new_full (reserve_size, g_free);
+}
+
+/**
+ * camel_named_flags_copy:
+ * @named_flags: (nullable): a #CamelNamedFlags
+ *
+ * Creates a copy of the @named_flags and returns it.
+ *
+ * Returns: (transfer full): A newly allocated #CamelNamedFlags.
+ * Free it with camel_named_flags_free() when done with it.
+ *
+ * Since: 3.24
+ **/
+CamelNamedFlags *
+camel_named_flags_copy (const CamelNamedFlags *named_flags)
+{
+ const GPtrArray *src = (const GPtrArray *) named_flags;
+ GPtrArray *arr;
+ guint ii;
+
+ if (!src)
+ return NULL;
+
+ arr = (GPtrArray *) camel_named_flags_new_sized (src->len);
+ for (ii = 0; ii < src->len; ii++) {
+ const gchar *name = g_ptr_array_index (src, ii);
+
+ if (name && *name)
+ g_ptr_array_add (arr, g_strdup (name));
+ }
+
+ return (CamelNamedFlags *) arr;
+}
+
+/**
+ * camel_named_flags_free:
+ * @named_flags: (nullable): a #CamelNamedFlags, or %NULL
+ *
+ * Frees memory associated iwth the @named_flags. Does nothing,
+ * if @named_flags is %NULL.
+ *
+ * Since: 3.24
+ **/
+void
+camel_named_flags_free (CamelNamedFlags *named_flags)
+{
+ if (named_flags)
+ g_ptr_array_unref ((GPtrArray *) named_flags);
+}
+
+static guint
+camel_named_flags_find (const CamelNamedFlags *named_flags,
+ const gchar *name)
+{
+ GPtrArray *arr = (GPtrArray *) named_flags;
+ guint ii;
+
+ g_return_val_if_fail (named_flags != NULL, (guint) -1);
+ g_return_val_if_fail (name != NULL, (guint) -1);
+
+ for (ii = 0; ii < arr->len; ii++) {
+ const gchar *nm = g_ptr_array_index (arr, ii);
+
+ if (g_strcmp0 (nm, name) == 0)
+ return ii;
+ }
+
+ return (guint) -1;
+}
+
+/**
+ * camel_named_flags_insert:
+ * @named_flags: a #CamelNamedFlags
+ * @name: name of the flag
+ *
+ * Inserts a flag named @name into the @named_flags, if it is not included
+ * already (comparing case sensitively), or does nothing otherwise.
+ *
+ * Returns: %TRUE the flag named @name was inserted; %FALSE otherwise.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_insert (CamelNamedFlags *named_flags,
+ const gchar *name)
+{
+ GPtrArray *arr = (GPtrArray *) named_flags;
+ guint index;
+
+ g_return_val_if_fail (named_flags != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ index = camel_named_flags_find (named_flags, name);
+
+ /* already there */
+ if (index != (guint) -1)
+ return FALSE;
+
+ g_ptr_array_add (arr, g_strdup (name));
+
+ return TRUE;
+}
+
+/**
+ * camel_named_flags_remove:
+ * @named_flags: a #CamelNamedFlags
+ * @name: name of the flag
+ *
+ * Removes a flag named @name from the @named_flags.
+ *
+ * Returns: %TRUE when the @named_flags contained a flag named @name,
+ * comparing case sensitively, and it was removed; %FALSE otherwise.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_remove (CamelNamedFlags *named_flags,
+ const gchar *name)
+{
+ GPtrArray *arr = (GPtrArray *) named_flags;
+ guint index;
+
+ g_return_val_if_fail (named_flags != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ index = camel_named_flags_find (named_flags, name);
+
+ /* not there */
+ if (index == (guint) -1)
+ return FALSE;
+
+ g_ptr_array_remove_index (arr, index);
+
+ return TRUE;
+}
+
+/**
+ * camel_named_flags_contains:
+ * @named_flags: a #CamelNamedFlags
+ * @name: name of the flag
+ *
+ * Returns: Whether the @named_flags contains a flag named @name,
+ * comparing case sensitively.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_contains (const CamelNamedFlags *named_flags,
+ const gchar *name)
+{
+ g_return_val_if_fail (named_flags != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return camel_named_flags_find (named_flags, name) != (guint) -1;
+}
+
+/**
+ * camel_named_flags_clear:
+ * @named_flags: a #CamelNamedFlags
+ *
+ * Removes all the elements of the array.
+ *
+ * Since: 3.24
+ **/
+void
+camel_named_flags_clear (CamelNamedFlags *named_flags)
+{
+ GPtrArray *arr = (GPtrArray *) named_flags;
+
+ g_return_if_fail (named_flags != NULL);
+
+ if (arr->len)
+ g_ptr_array_remove_range (arr, 0, arr->len);
+}
+
+/**
+ * camel_named_flags_get_length:
+ * @named_flags: (nullable): a #CamelNamedFlags
+ *
+ * Returns: Length of the array, aka how many named flags are stored there.
+ *
+ * Since: 3.24
+ **/
+guint
+camel_named_flags_get_length (const CamelNamedFlags *named_flags)
+{
+ const GPtrArray *arr = (const GPtrArray *) named_flags;
+
+ if (!named_flags)
+ return 0;
+
+ return arr->len;
+}
+
+/**
+ * camel_named_flags_get:
+ * @named_flags: a #CamelNamedFlags
+ * @index: an index of an element
+ *
+ * Returns: (transfer none) (nullable): Name of the flag in at the given @index,
+ * or %NULL on error.
+ *
+ * Since: 3.24
+ **/
+const gchar *
+camel_named_flags_get (const CamelNamedFlags *named_flags,
+ guint index)
+{
+ const GPtrArray *arr = (const GPtrArray *) named_flags;
+
+ g_return_val_if_fail (named_flags != NULL, NULL);
+
+ if (index >= camel_named_flags_get_length (named_flags))
+ return NULL;
+
+ return g_ptr_array_index (arr, index);
+}
+
+/**
+ * camel_named_flags_equal:
+ * @named_flags_a: (nullable): the first #CamelNamedFlags
+ * @named_flags_b: (nullable): the second #CamelNamedFlags
+ *
+ * Compares content of the two #CamelNamedFlags and returns whether
+ * they equal. Note this is an expensive operation for large sets.
+ *
+ * Returns: Whether the two #CamelNamedFlags have the same content.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_equal (const CamelNamedFlags *named_flags_a,
+ const CamelNamedFlags *named_flags_b)
+{
+ guint ii, len;
+
+ if (named_flags_a == named_flags_b)
+ return TRUE;
+
+ if (!named_flags_a || !named_flags_b)
+ return FALSE;
+
+ len = camel_named_flags_get_length (named_flags_a);
+ if (len != camel_named_flags_get_length (named_flags_b))
+ return FALSE;
+
+ for (ii = 0; ii < len; ii++) {
+ if (!camel_named_flags_contains (named_flags_a, camel_named_flags_get (named_flags_b, ii)))
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/camel/camel-named-flags.h b/src/camel/camel-named-flags.h
new file mode 100644
index 0000000..e5e7ca5
--- /dev/null
+++ b/src/camel/camel-named-flags.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_NAMED_FLAGS_H
+#define CAMEL_NAMED_FLAGS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * CamelNamedFlags:
+ *
+ * Since: 3.24
+ **/
+struct _CamelNamedFlags;
+typedef struct _CamelNamedFlags CamelNamedFlags;
+
+#define CAMEL_TYPE_NAMED_FLAGS (camel_named_flags_get_type ())
+
+GType camel_named_flags_get_type (void) G_GNUC_CONST;
+CamelNamedFlags *
+ camel_named_flags_new (void);
+CamelNamedFlags *
+ camel_named_flags_new_sized (guint reserve_size);
+CamelNamedFlags *
+ camel_named_flags_copy (const CamelNamedFlags *named_flags);
+void camel_named_flags_free (CamelNamedFlags *named_flags);
+gboolean camel_named_flags_insert (CamelNamedFlags *named_flags,
+ const gchar *name);
+gboolean camel_named_flags_remove (CamelNamedFlags *named_flags,
+ const gchar *name);
+gboolean camel_named_flags_contains (const CamelNamedFlags *named_flags,
+ const gchar *name);
+void camel_named_flags_clear (CamelNamedFlags *named_flags);
+guint camel_named_flags_get_length (const CamelNamedFlags *named_flags);
+const gchar * camel_named_flags_get (const CamelNamedFlags *named_flags,
+ guint index);
+gboolean camel_named_flags_equal (const CamelNamedFlags *named_flags_a,
+ const CamelNamedFlags *named_flags_b);
+
+G_END_DECLS
+
+#endif /* CAMEL_NAMED_FLAGS_H */
diff --git a/src/camel/camel-network-service.h b/src/camel/camel-network-service.h
index 4795e9b..92e75a8 100644
--- a/src/camel/camel-network-service.h
+++ b/src/camel/camel-network-service.h
@@ -73,7 +73,8 @@ struct _CamelNetworkServiceInterface {
(*new_connectable)
(CamelNetworkService *service);
- gpointer reserved[15];
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_network_service_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-network-settings.h b/src/camel/camel-network-settings.h
index db79485..9158bf1 100644
--- a/src/camel/camel-network-settings.h
+++ b/src/camel/camel-network-settings.h
@@ -56,6 +56,9 @@ typedef struct _CamelNetworkSettingsInterface CamelNetworkSettingsInterface;
struct _CamelNetworkSettingsInterface {
GTypeInterface parent_interface;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_network_settings_get_type
diff --git a/src/camel/camel-nntp-address.c b/src/camel/camel-nntp-address.c
index 3e16a29..60729dc 100644
--- a/src/camel/camel-nntp-address.c
+++ b/src/camel/camel-nntp-address.c
@@ -24,20 +24,30 @@
#define d(x)
-struct _address {
- gchar *name;
- gchar *address;
+struct _CamelNNTPAddressPrivate {
+ GPtrArray *addresses;
};
G_DEFINE_TYPE (CamelNNTPAddress, camel_nntp_address, CAMEL_TYPE_ADDRESS)
+static gint
+nntp_address_length (CamelAddress *paddr)
+{
+ CamelNNTPAddress *nntp_addr = CAMEL_NNTP_ADDRESS (paddr);
+
+ g_return_val_if_fail (nntp_addr != NULL, -1);
+
+ return nntp_addr->priv->addresses->len;
+}
+
/* since newsgropus are 7bit ascii, decode/unformat are the same */
static gint
nntp_address_decode (CamelAddress *address,
const gchar *raw)
{
+ CamelNNTPAddress *nntp_addr = CAMEL_NNTP_ADDRESS (address);
GSList *ha, *n;
- gint count = address->addresses->len;
+ gint count = nntp_addr->priv->addresses->len;
ha = camel_header_newsgroups_decode (raw);
for (n = ha; n != NULL; n = n->next) {
@@ -45,27 +55,28 @@ nntp_address_decode (CamelAddress *address,
}
g_slist_free_full (ha, g_free);
- return address->addresses->len - count;
+ return nntp_addr->priv->addresses->len - count;
}
/* since newsgropus are 7bit ascii, encode/format are the same */
static gchar *
nntp_address_encode (CamelAddress *address)
{
+ CamelNNTPAddress *nntp_addr = CAMEL_NNTP_ADDRESS (address);
gint i;
GString *out;
gchar *ret;
- if (address->addresses->len == 0)
+ if (nntp_addr->priv->addresses->len == 0)
return NULL;
out = g_string_new ("");
- for (i = 0; i < address->addresses->len; i++) {
+ for (i = 0; i < nntp_addr->priv->addresses->len; i++) {
if (i != 0)
g_string_append (out, ", ");
- g_string_append (out, g_ptr_array_index (address->addresses, i));
+ g_string_append (out, g_ptr_array_index (nntp_addr->priv->addresses, i));
}
ret = out->str;
@@ -78,14 +89,19 @@ static gint
nntp_address_cat (CamelAddress *dest,
CamelAddress *source)
{
+ CamelNNTPAddress *dest_nntp_addr;
+ CamelNNTPAddress *source_nntp_addr;
gint ii;
+ g_return_val_if_fail (CAMEL_IS_NNTP_ADDRESS (dest), -1);
g_return_val_if_fail (CAMEL_IS_NNTP_ADDRESS (source), -1);
- for (ii = 0; ii < source->addresses->len; ii++)
- camel_nntp_address_add (
- CAMEL_NNTP_ADDRESS (dest),
- g_ptr_array_index (source->addresses, ii));
+ dest_nntp_addr = CAMEL_NNTP_ADDRESS (dest);
+ source_nntp_addr = CAMEL_NNTP_ADDRESS (source);
+
+ for (ii = 0; ii < source_nntp_addr->priv->addresses->len; ii++) {
+ camel_nntp_address_add (dest_nntp_addr, g_ptr_array_index (source_nntp_addr->priv->addresses,
ii));
+ }
return ii;
}
@@ -94,19 +110,41 @@ static void
nntp_address_remove (CamelAddress *address,
gint index)
{
- if (index < 0 || index >= address->addresses->len)
+ CamelNNTPAddress *nntp_addr = CAMEL_NNTP_ADDRESS (address);
+
+ if (index < 0 || index >= nntp_addr->priv->addresses->len)
return;
- g_free (g_ptr_array_index (address->addresses, index));
- g_ptr_array_remove_index (address->addresses, index);
+ g_free (g_ptr_array_index (nntp_addr->priv->addresses, index));
+ g_ptr_array_remove_index (nntp_addr->priv->addresses, index);
+}
+
+
+static void
+nntp_address_finalize (GObject *object)
+{
+ CamelNNTPAddress *nntp_addr = CAMEL_NNTP_ADDRESS (object);
+
+ camel_address_remove (CAMEL_ADDRESS (nntp_addr), -1);
+ g_ptr_array_free (nntp_addr->priv->addresses, TRUE);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (camel_nntp_address_parent_class)->finalize (object);
}
static void
camel_nntp_address_class_init (CamelNNTPAddressClass *class)
{
CamelAddressClass *address_class;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelNNTPAddressPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = nntp_address_finalize;
address_class = CAMEL_ADDRESS_CLASS (class);
+ address_class->length = nntp_address_length;
address_class->decode = nntp_address_decode;
address_class->encode = nntp_address_encode;
address_class->unformat = nntp_address_decode;
@@ -118,6 +156,8 @@ camel_nntp_address_class_init (CamelNNTPAddressClass *class)
static void
camel_nntp_address_init (CamelNNTPAddress *nntp_address)
{
+ nntp_address->priv = G_TYPE_INSTANCE_GET_PRIVATE (nntp_address, CAMEL_TYPE_NNTP_ADDRESS,
CamelNNTPAddressPrivate);
+ nntp_address->priv->addresses = g_ptr_array_new ();
}
/**
@@ -135,7 +175,7 @@ camel_nntp_address_new (void)
/**
* camel_nntp_address_add:
- * @a: nntp address object
+ * @addr: nntp address object
* @name:
*
* Add a new nntp address to the address object. Duplicates are not added twice.
@@ -143,26 +183,26 @@ camel_nntp_address_new (void)
* Returns: Index of added entry, or existing matching entry.
**/
gint
-camel_nntp_address_add (CamelNNTPAddress *a,
+camel_nntp_address_add (CamelNNTPAddress *addr,
const gchar *name)
{
gint index, i;
- g_return_val_if_fail (CAMEL_IS_NNTP_ADDRESS (a), -1);
+ g_return_val_if_fail (CAMEL_IS_NNTP_ADDRESS (addr), -1);
- index = ((CamelAddress *) a)->addresses->len;
+ index = addr->priv->addresses->len;
for (i = 0; i < index; i++)
- if (!strcmp (g_ptr_array_index (((CamelAddress *) a)->addresses, i), name))
+ if (!strcmp (g_ptr_array_index (addr->priv->addresses, i), name))
return i;
- g_ptr_array_add (((CamelAddress *) a)->addresses, g_strdup (name));
+ g_ptr_array_add (addr->priv->addresses, g_strdup (name));
return index;
}
/**
* camel_nntp_address_get:
- * @a: nntp address object
+ * @addr: nntp address object
* @index: address's array index
* @namep: Holder for the returned address, or NULL, if not required.
*
@@ -171,17 +211,17 @@ camel_nntp_address_add (CamelNNTPAddress *a,
* Returns: TRUE if such an address exists, or FALSE otherwise.
**/
gboolean
-camel_nntp_address_get (CamelNNTPAddress *a,
+camel_nntp_address_get (CamelNNTPAddress *addr,
gint index,
const gchar **namep)
{
- g_return_val_if_fail (CAMEL_IS_NNTP_ADDRESS (a), FALSE);
+ g_return_val_if_fail (CAMEL_IS_NNTP_ADDRESS (addr), FALSE);
- if (index < 0 || index >= ((CamelAddress *) a)->addresses->len)
+ if (index < 0 || index >= addr->priv->addresses->len)
return FALSE;
if (namep)
- *namep = g_ptr_array_index( ((CamelAddress *)a)->addresses, index);
+ *namep = g_ptr_array_index (addr->priv->addresses, index);
return TRUE;
}
diff --git a/src/camel/camel-nntp-address.h b/src/camel/camel-nntp-address.h
index 096fcf2..4831aa7 100644
--- a/src/camel/camel-nntp-address.h
+++ b/src/camel/camel-nntp-address.h
@@ -58,14 +58,17 @@ struct _CamelNNTPAddress {
struct _CamelNNTPAddressClass {
CamelAddressClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_nntp_address_get_type (void);
CamelNNTPAddress *
camel_nntp_address_new (void);
-gint camel_nntp_address_add (CamelNNTPAddress *a,
+gint camel_nntp_address_add (CamelNNTPAddress *addr,
const gchar *name);
-gboolean camel_nntp_address_get (CamelNNTPAddress *a,
+gboolean camel_nntp_address_get (CamelNNTPAddress *addr,
gint index,
const gchar **namep);
diff --git a/src/camel/camel-null-output-stream.h b/src/camel/camel-null-output-stream.h
index f113ae4..978763d 100644
--- a/src/camel/camel-null-output-stream.h
+++ b/src/camel/camel-null-output-stream.h
@@ -56,6 +56,9 @@ struct _CamelNullOutputStream {
struct _CamelNullOutputStreamClass {
GOutputStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_null_output_stream_get_type
diff --git a/src/camel/camel-object-bag.c b/src/camel/camel-object-bag.c
index 79c3cec..b489014 100644
--- a/src/camel/camel-object-bag.c
+++ b/src/camel/camel-object-bag.c
@@ -151,7 +151,7 @@ wref_free_func (gpointer p)
}
/**
- * camel_object_bag_new:
+ * camel_object_bag_new: (skip)
* @key_hash_func: (scope call): a hashing function for keys
* @key_equal_func: (scope call): a comparison function for keys
* @key_copy_func: (scope call): a function to copy keys
@@ -530,7 +530,7 @@ camel_object_bag_rekey (CamelObjectBag *bag,
*
* <informalexample>
* <programlisting>
- * g_ptr_array_foreach (array, g_object_unref, NULL);
+ * g_ptr_array_foreach (array, (GFunc) g_object_unref, NULL);
* g_ptr_array_free (array, TRUE);
* </programlisting>
* </informalexample>
diff --git a/src/camel/camel-object.h b/src/camel/camel-object.h
index 1d96f82..5e76c01 100644
--- a/src/camel/camel-object.h
+++ b/src/camel/camel-object.h
@@ -101,6 +101,9 @@ struct _CamelObjectClass {
FILE *fp);
gint (*state_write) (CamelObject *object,
FILE *fp);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_object_get_type (void);
diff --git a/src/camel/camel-offline-folder.h b/src/camel/camel-offline-folder.h
index 0182cb3..4d04344 100644
--- a/src/camel/camel-offline-folder.h
+++ b/src/camel/camel-offline-folder.h
@@ -66,8 +66,8 @@ struct _CamelOfflineFolderClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots. */
- gpointer reserved[2];
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_offline_folder_get_type (void);
diff --git a/src/camel/camel-offline-settings.h b/src/camel/camel-offline-settings.h
index b336a62..c0a562e 100644
--- a/src/camel/camel-offline-settings.h
+++ b/src/camel/camel-offline-settings.h
@@ -64,6 +64,9 @@ struct _CamelOfflineSettings {
struct _CamelOfflineSettingsClass {
CamelStoreSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_offline_settings_get_type
diff --git a/src/camel/camel-offline-store.c b/src/camel/camel-offline-store.c
index b49b786..3ca0db6 100644
--- a/src/camel/camel-offline-store.c
+++ b/src/camel/camel-offline-store.c
@@ -223,8 +223,7 @@ camel_offline_store_set_online_sync (CamelOfflineStore *store,
GPtrArray *folders;
guint ii;
- folders = camel_object_bag_list (
- CAMEL_STORE (store)->folders);
+ folders = camel_store_dup_opened_folders (CAMEL_STORE (store));
for (ii = 0; ii < folders->len; ii++) {
CamelFolder *folder = folders->pdata[ii];
@@ -288,8 +287,7 @@ camel_offline_store_prepare_for_offline_sync (CamelOfflineStore *store,
GPtrArray *folders;
guint ii;
- folders = camel_object_bag_list (
- CAMEL_STORE (store)->folders);
+ folders = camel_store_dup_opened_folders (CAMEL_STORE (store));
for (ii = 0; ii < folders->len; ii++) {
CamelFolder *folder = folders->pdata[ii];
@@ -359,8 +357,7 @@ camel_offline_store_requires_downsync (CamelOfflineStore *store)
GPtrArray *folders;
guint ii;
- folders = camel_object_bag_list (
- CAMEL_STORE (store)->folders);
+ folders = camel_store_dup_opened_folders (CAMEL_STORE (store));
for (ii = 0; ii < folders->len && !sync_any_folder; ii++) {
CamelFolder *folder = folders->pdata[ii];
diff --git a/src/camel/camel-offline-store.h b/src/camel/camel-offline-store.h
index 35e5ddc..3ca4400 100644
--- a/src/camel/camel-offline-store.h
+++ b/src/camel/camel-offline-store.h
@@ -58,6 +58,9 @@ struct _CamelOfflineStore {
struct _CamelOfflineStoreClass {
CamelStoreClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_offline_store_get_type (void);
diff --git a/src/camel/camel-operation.h b/src/camel/camel-operation.h
index d8cbd9f..1452470 100644
--- a/src/camel/camel-operation.h
+++ b/src/camel/camel-operation.h
@@ -61,6 +61,9 @@ struct _CamelOperationClass {
void (*status) (CamelOperation *operation,
const gchar *what,
gint pc);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_operation_get_type (void);
diff --git a/src/camel/camel-partition-table.c b/src/camel/camel-partition-table.c
index e51c16b..1e5659b 100644
--- a/src/camel/camel-partition-table.c
+++ b/src/camel/camel-partition-table.c
@@ -49,6 +49,12 @@
struct _CamelPartitionTablePrivate {
GMutex lock; /* for locking partition */
+
+ CamelBlockFile *blocks;
+ camel_block_t rootid;
+
+ /* we keep a list of partition blocks active at all times */
+ GQueue partition;
};
G_DEFINE_TYPE (CamelPartitionTable, camel_partition_table, G_TYPE_OBJECT)
@@ -59,14 +65,14 @@ partition_table_finalize (GObject *object)
CamelPartitionTable *table = CAMEL_PARTITION_TABLE (object);
CamelBlock *bl;
- if (table->blocks != NULL) {
- while ((bl = g_queue_pop_head (&table->partition)) != NULL) {
- camel_block_file_sync_block (table->blocks, bl);
- camel_block_file_unref_block (table->blocks, bl);
+ if (table->priv->blocks != NULL) {
+ while ((bl = g_queue_pop_head (&table->priv->partition)) != NULL) {
+ camel_block_file_sync_block (table->priv->blocks, bl);
+ camel_block_file_unref_block (table->priv->blocks, bl);
}
- camel_block_file_sync (table->blocks);
+ camel_block_file_sync (table->priv->blocks);
- g_object_unref (table->blocks);
+ g_object_unref (table->priv->blocks);
}
g_mutex_clear (&table->priv->lock);
@@ -91,7 +97,7 @@ camel_partition_table_init (CamelPartitionTable *cpi)
{
cpi->priv = CAMEL_PARTITION_TABLE_GET_PRIVATE (cpi);
- g_queue_init (&cpi->partition);
+ g_queue_init (&cpi->priv->partition);
g_mutex_init (&cpi->priv->lock);
}
@@ -138,7 +144,7 @@ find_partition (CamelPartitionTable *cpi,
GList *head, *link;
/* first, find the block this key might be in, then binary search the block */
- head = g_queue_peek_head_link (&cpi->partition);
+ head = g_queue_peek_head_link (&cpi->priv->partition);
for (link = head; link != NULL; link = g_list_next (link)) {
CamelBlock *bl = link->data;
@@ -191,8 +197,8 @@ camel_partition_table_new (CamelBlockFile *bs,
g_return_val_if_fail (CAMEL_IS_BLOCK_FILE (bs), NULL);
cpi = g_object_new (CAMEL_TYPE_PARTITION_TABLE, NULL);
- cpi->rootid = root;
- cpi->blocks = g_object_ref (bs);
+ cpi->priv->rootid = root;
+ cpi->priv->blocks = g_object_ref (bs);
/* read the partition table into memory */
do {
@@ -205,7 +211,7 @@ camel_partition_table_new (CamelBlockFile *bs,
d (printf ("Adding partition block, used = %d, hashid = %08x\n", ptb->used,
ptb->partition[0].hashid));
/* if we have no data, prime initial block */
- if (ptb->used == 0 && g_queue_is_empty (&cpi->partition) && ptb->next == 0) {
+ if (ptb->used == 0 && g_queue_is_empty (&cpi->priv->partition) && ptb->next == 0) {
pblock = camel_block_file_new_block (bs);
if (pblock == NULL) {
camel_block_file_unref_block (bs, block);
@@ -226,7 +232,7 @@ camel_partition_table_new (CamelBlockFile *bs,
root = ptb->next;
camel_block_file_detach_block (bs, block);
- g_queue_push_tail (&cpi->partition, block);
+ g_queue_push_tail (&cpi->priv->partition, block);
} while (root);
return cpi;
@@ -246,15 +252,15 @@ camel_partition_table_sync (CamelPartitionTable *cpi)
CAMEL_PARTITION_TABLE_LOCK (cpi, lock);
- if (cpi->blocks) {
+ if (cpi->priv->blocks) {
GList *head, *link;
- head = g_queue_peek_head_link (&cpi->partition);
+ head = g_queue_peek_head_link (&cpi->priv->partition);
for (link = head; link != NULL; link = g_list_next (link)) {
CamelBlock *bl = link->data;
- ret = camel_block_file_sync_block (cpi->blocks, bl);
+ ret = camel_block_file_sync_block (cpi->priv->blocks, bl);
if (ret == -1)
goto fail;
}
@@ -294,7 +300,7 @@ camel_partition_table_lookup (CamelPartitionTable *cpi,
ptblock = (CamelBlock *) ptblock_link->data;
ptb = (CamelPartitionMapBlock *) &ptblock->data;
block = camel_block_file_get_block (
- cpi->blocks, ptb->partition[index].blockid);
+ cpi->priv->blocks, ptb->partition[index].blockid);
if (block == NULL) {
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
return 0;
@@ -314,7 +320,7 @@ camel_partition_table_lookup (CamelPartitionTable *cpi,
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
- camel_block_file_unref_block (cpi->blocks, block);
+ camel_block_file_unref_block (cpi->priv->blocks, block);
return keyid;
}
@@ -346,7 +352,7 @@ camel_partition_table_remove (CamelPartitionTable *cpi,
ptblock = (CamelBlock *) ptblock_link->data;
ptb = (CamelPartitionMapBlock *) &ptblock->data;
block = camel_block_file_get_block (
- cpi->blocks, ptb->partition[index].blockid);
+ cpi->priv->blocks, ptb->partition[index].blockid);
if (block == NULL) {
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
return FALSE;
@@ -365,14 +371,14 @@ camel_partition_table_remove (CamelPartitionTable *cpi,
pkb->keys[i].keyid = pkb->keys[i + 1].keyid;
pkb->keys[i].hashid = pkb->keys[i + 1].hashid;
}
- camel_block_file_touch_block (cpi->blocks, block);
+ camel_block_file_touch_block (cpi->priv->blocks, block);
break;
}
}
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
- camel_block_file_unref_block (cpi->blocks, block);
+ camel_block_file_unref_block (cpi->priv->blocks, block);
return TRUE;
}
@@ -422,7 +428,7 @@ camel_partition_table_add (CamelPartitionTable *cpi,
ptblock = (CamelBlock *) ptblock_link->data;
ptb = (CamelPartitionMapBlock *) &ptblock->data;
block = camel_block_file_get_block (
- cpi->blocks, ptb->partition[index].blockid);
+ cpi->priv->blocks, ptb->partition[index].blockid);
if (block == NULL) {
CAMEL_PARTITION_TABLE_UNLOCK (cpi, lock);
return -1;
@@ -445,17 +451,17 @@ camel_partition_table_add (CamelPartitionTable *cpi,
if (index > 0) {
pblock = camel_block_file_get_block (
- cpi->blocks, ptb->partition[index - 1].blockid);
+ cpi->priv->blocks, ptb->partition[index - 1].blockid);
if (pblock == NULL)
goto fail;
pkb = (CamelPartitionKeyBlock *) &pblock->data;
}
if (index < (ptb->used - 1)) {
nblock = camel_block_file_get_block (
- cpi->blocks, ptb->partition[index + 1].blockid);
+ cpi->priv->blocks, ptb->partition[index + 1].blockid);
if (nblock == NULL) {
if (pblock)
- camel_block_file_unref_block (cpi->blocks, pblock);
+ camel_block_file_unref_block (cpi->priv->blocks, pblock);
goto fail;
}
nkb = (CamelPartitionKeyBlock *) &nblock->data;
@@ -486,15 +492,15 @@ camel_partition_table_add (CamelPartitionTable *cpi,
/* See if we have room in the partition table for this block or need to split that
too */
if (ptb->used >= G_N_ELEMENTS (ptb->partition)) {
/* TODO: Could check next block to see if it'll fit there first */
- ptnblock = camel_block_file_new_block (cpi->blocks);
+ ptnblock = camel_block_file_new_block (cpi->priv->blocks);
if (ptnblock == NULL) {
if (nblock)
- camel_block_file_unref_block (cpi->blocks, nblock);
+ camel_block_file_unref_block (cpi->priv->blocks, nblock);
if (pblock)
- camel_block_file_unref_block (cpi->blocks, pblock);
+ camel_block_file_unref_block (cpi->priv->blocks, pblock);
goto fail;
}
- camel_block_file_detach_block (cpi->blocks, ptnblock);
+ camel_block_file_detach_block (cpi->priv->blocks, ptnblock);
/* split block and link on-disk, always sorted */
ptn = (CamelPartitionMapBlock *) &ptnblock->data;
@@ -507,18 +513,18 @@ camel_partition_table_add (CamelPartitionTable *cpi,
/* link in-memory */
g_queue_insert_after (
- &cpi->partition,
+ &cpi->priv->partition,
ptblock_link, ptnblock);
/* write in right order to ensure structure */
- camel_block_file_touch_block (cpi->blocks, ptnblock);
+ camel_block_file_touch_block (cpi->priv->blocks, ptnblock);
#ifdef SYNC_UPDATES
- camel_block_file_sync_block (cpi->blocks, ptnblock);
+ camel_block_file_sync_block (cpi->priv->blocks, ptnblock);
#endif
if (index > len) {
- camel_block_file_touch_block (cpi->blocks, ptblock);
+ camel_block_file_touch_block (cpi->priv->blocks, ptblock);
#ifdef SYNC_UPDATES
- camel_block_file_sync_block (cpi->blocks, ptblock);
+ camel_block_file_sync_block (cpi->priv->blocks, ptblock);
#endif
index -= len;
ptb = ptn;
@@ -527,12 +533,12 @@ camel_partition_table_add (CamelPartitionTable *cpi,
}
/* try get newblock before modifying existing */
- newblock = camel_block_file_new_block (cpi->blocks);
+ newblock = camel_block_file_new_block (cpi->priv->blocks);
if (newblock == NULL) {
if (nblock)
- camel_block_file_unref_block (cpi->blocks, nblock);
+ camel_block_file_unref_block (cpi->priv->blocks, nblock);
if (pblock)
- camel_block_file_unref_block (cpi->blocks, pblock);
+ camel_block_file_unref_block (cpi->priv->blocks, pblock);
goto fail;
}
@@ -550,18 +556,18 @@ camel_partition_table_add (CamelPartitionTable *cpi,
ptb->partition[newindex].blockid = newblock->id;
if (nblock)
- camel_block_file_unref_block (cpi->blocks, nblock);
+ camel_block_file_unref_block (cpi->priv->blocks, nblock);
if (pblock)
- camel_block_file_unref_block (cpi->blocks, pblock);
+ camel_block_file_unref_block (cpi->priv->blocks, pblock);
} else {
newkb = (CamelPartitionKeyBlock *) &newblock->data;
if (newblock == pblock) {
if (nblock)
- camel_block_file_unref_block (cpi->blocks, nblock);
+ camel_block_file_unref_block (cpi->priv->blocks, nblock);
} else {
if (pblock)
- camel_block_file_unref_block (cpi->blocks, pblock);
+ camel_block_file_unref_block (cpi->priv->blocks, pblock);
}
}
@@ -593,16 +599,16 @@ camel_partition_table_add (CamelPartitionTable *cpi,
ptb->partition[newindex].hashid = partid;
}
- camel_block_file_touch_block (cpi->blocks, ptblock);
+ camel_block_file_touch_block (cpi->priv->blocks, ptblock);
#ifdef SYNC_UPDATES
- camel_block_file_sync_block (cpi->blocks, ptblock);
+ camel_block_file_sync_block (cpi->priv->blocks, ptblock);
#endif
- camel_block_file_touch_block (cpi->blocks, newblock);
- camel_block_file_unref_block (cpi->blocks, newblock);
+ camel_block_file_touch_block (cpi->priv->blocks, newblock);
+ camel_block_file_unref_block (cpi->priv->blocks, newblock);
}
- camel_block_file_touch_block (cpi->blocks, block);
- camel_block_file_unref_block (cpi->blocks, block);
+ camel_block_file_touch_block (cpi->priv->blocks, block);
+ camel_block_file_unref_block (cpi->priv->blocks, block);
ret = 0;
fail:
@@ -624,6 +630,13 @@ fail:
struct _CamelKeyTablePrivate {
GMutex lock; /* for locking key */
+
+ CamelBlockFile *blocks;
+
+ camel_block_t rootid;
+
+ CamelKeyRootBlock *root;
+ CamelBlock *root_block;
};
G_DEFINE_TYPE (CamelKeyTable, camel_key_table, G_TYPE_OBJECT)
@@ -633,13 +646,13 @@ key_table_finalize (GObject *object)
{
CamelKeyTable *table = CAMEL_KEY_TABLE (object);
- if (table->blocks) {
- if (table->root_block) {
- camel_block_file_sync_block (table->blocks, table->root_block);
- camel_block_file_unref_block (table->blocks, table->root_block);
+ if (table->priv->blocks) {
+ if (table->priv->root_block) {
+ camel_block_file_sync_block (table->priv->blocks, table->priv->root_block);
+ camel_block_file_unref_block (table->priv->blocks, table->priv->root_block);
}
- camel_block_file_sync (table->blocks);
- g_object_unref (table->blocks);
+ camel_block_file_sync (table->priv->blocks);
+ g_object_unref (table->priv->blocks);
}
g_mutex_clear (&table->priv->lock);
@@ -676,19 +689,19 @@ camel_key_table_new (CamelBlockFile *bs,
ki = g_object_new (CAMEL_TYPE_KEY_TABLE, NULL);
- ki->blocks = g_object_ref (bs);
- ki->rootid = root;
+ ki->priv->blocks = g_object_ref (bs);
+ ki->priv->rootid = root;
- ki->root_block = camel_block_file_get_block (bs, ki->rootid);
- if (ki->root_block == NULL) {
+ ki->priv->root_block = camel_block_file_get_block (bs, ki->priv->rootid);
+ if (ki->priv->root_block == NULL) {
g_object_unref (ki);
ki = NULL;
} else {
- camel_block_file_detach_block (bs, ki->root_block);
- ki->root = (CamelKeyRootBlock *) &ki->root_block->data;
+ camel_block_file_detach_block (bs, ki->priv->root_block);
+ ki->priv->root = (CamelKeyRootBlock *) &ki->priv->root_block->data;
k (printf ("Opening key index\n"));
- k (printf (" first %u\n last %u\n free %u\n", ki->root->first, ki->root->last,
ki->root->free));
+ k (printf (" first %u\n last %u\n free %u\n", ki->priv->root->first, ki->priv->root->last,
ki->priv->root->free));
}
return ki;
@@ -702,7 +715,7 @@ camel_key_table_sync (CamelKeyTable *ki)
#ifdef SYNC_UPDATES
return 0;
#else
- return camel_block_file_sync_block (ki->blocks, ki->root_block);
+ return camel_block_file_sync_block (ki->priv->blocks, ki->priv->root_block);
#endif
}
@@ -728,16 +741,16 @@ camel_key_table_add (CamelKeyTable *ki,
CAMEL_KEY_TABLE_LOCK (ki, lock);
- if (ki->root->last == 0) {
- last = camel_block_file_new_block (ki->blocks);
+ if (ki->priv->root->last == 0) {
+ last = camel_block_file_new_block (ki->priv->blocks);
if (last == NULL)
goto fail;
- ki->root->last = ki->root->first = last->id;
- camel_block_file_touch_block (ki->blocks, ki->root_block);
- k (printf ("adding first block, first = %u\n", ki->root->first));
+ ki->priv->root->last = ki->priv->root->first = last->id;
+ camel_block_file_touch_block (ki->priv->blocks, ki->priv->root_block);
+ k (printf ("adding first block, first = %u\n", ki->priv->root->first));
} else {
last = camel_block_file_get_block (
- ki->blocks, ki->root->last);
+ ki->priv->blocks, ki->priv->root->last);
if (last == NULL)
goto fail;
}
@@ -756,18 +769,18 @@ camel_key_table_add (CamelKeyTable *ki,
sizeof (kblast->u.keydata) - kblast->u.keys[kblast->used - 1].offset,
left, len));
if (left < len) {
- next = camel_block_file_new_block (ki->blocks);
+ next = camel_block_file_new_block (ki->priv->blocks);
if (next == NULL) {
- camel_block_file_unref_block (ki->blocks, last);
+ camel_block_file_unref_block (ki->priv->blocks, last);
goto fail;
}
kbnext = (CamelKeyBlock *) &next->data;
kblast->next = next->id;
- ki->root->last = next->id;
- d (printf ("adding new block, first = %u, last = %u\n", ki->root->first,
ki->root->last));
- camel_block_file_touch_block (ki->blocks, ki->root_block);
- camel_block_file_touch_block (ki->blocks, last);
- camel_block_file_unref_block (ki->blocks, last);
+ ki->priv->root->last = next->id;
+ d (printf ("adding new block, first = %u, last = %u\n", ki->priv->root->first,
ki->priv->root->last));
+ camel_block_file_touch_block (ki->priv->blocks, ki->priv->root_block);
+ camel_block_file_touch_block (ki->priv->blocks, last);
+ camel_block_file_unref_block (ki->priv->blocks, last);
kblast = kbnext;
last = next;
}
@@ -793,11 +806,11 @@ camel_key_table_add (CamelKeyTable *ki,
goto fail;
}
- camel_block_file_touch_block (ki->blocks, last);
- camel_block_file_unref_block (ki->blocks, last);
+ camel_block_file_touch_block (ki->priv->blocks, last);
+ camel_block_file_unref_block (ki->priv->blocks, last);
#ifdef SYNC_UPDATES
- camel_block_file_sync_block (ki->blocks, ki->root_block);
+ camel_block_file_sync_block (ki->priv->blocks, ki->priv->root_block);
#endif
fail:
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
@@ -821,7 +834,7 @@ camel_key_table_set_data (CamelKeyTable *ki,
blockid = keyid & (~(CAMEL_BLOCK_SIZE - 1));
index = keyid & (CAMEL_BLOCK_SIZE - 1);
- bl = camel_block_file_get_block (ki->blocks, blockid);
+ bl = camel_block_file_get_block (ki->priv->blocks, blockid);
if (bl == NULL)
return FALSE;
kb = (CamelKeyBlock *) &bl->data;
@@ -830,12 +843,12 @@ camel_key_table_set_data (CamelKeyTable *ki,
if (kb->u.keys[index].data != data) {
kb->u.keys[index].data = data;
- camel_block_file_touch_block (ki->blocks, bl);
+ camel_block_file_touch_block (ki->priv->blocks, bl);
}
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
- camel_block_file_unref_block (ki->blocks, bl);
+ camel_block_file_unref_block (ki->priv->blocks, bl);
return TRUE;
}
@@ -858,7 +871,7 @@ camel_key_table_set_flags (CamelKeyTable *ki,
blockid = keyid & (~(CAMEL_BLOCK_SIZE - 1));
index = keyid & (CAMEL_BLOCK_SIZE - 1);
- bl = camel_block_file_get_block (ki->blocks, blockid);
+ bl = camel_block_file_get_block (ki->priv->blocks, blockid);
if (bl == NULL)
return FALSE;
kb = (CamelKeyBlock *) &bl->data;
@@ -873,12 +886,12 @@ camel_key_table_set_flags (CamelKeyTable *ki,
old = kb->u.keys[index].flags;
if ((old & set) != (flags & set)) {
kb->u.keys[index].flags = (old & (~set)) | (flags & set);
- camel_block_file_touch_block (ki->blocks, bl);
+ camel_block_file_touch_block (ki->priv->blocks, bl);
}
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
- camel_block_file_unref_block (ki->blocks, bl);
+ camel_block_file_unref_block (ki->priv->blocks, bl);
return TRUE;
}
@@ -906,7 +919,7 @@ camel_key_table_lookup (CamelKeyTable *ki,
blockid = keyid & (~(CAMEL_BLOCK_SIZE - 1));
index = keyid & (CAMEL_BLOCK_SIZE - 1);
- bl = camel_block_file_get_block (ki->blocks, blockid);
+ bl = camel_block_file_get_block (ki->priv->blocks, blockid);
if (bl == NULL)
return 0;
@@ -936,7 +949,7 @@ camel_key_table_lookup (CamelKeyTable *ki,
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
- camel_block_file_unref_block (ki->blocks, bl);
+ camel_block_file_unref_block (ki->priv->blocks, bl);
return blockid;
}
@@ -966,7 +979,7 @@ camel_key_table_next (CamelKeyTable *ki,
CAMEL_KEY_TABLE_LOCK (ki, lock);
if (next == 0) {
- next = ki->root->first;
+ next = ki->priv->root->first;
if (next == 0) {
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
return 0;
@@ -978,7 +991,7 @@ camel_key_table_next (CamelKeyTable *ki,
blockid = next & (~(CAMEL_BLOCK_SIZE - 1));
index = next & (CAMEL_BLOCK_SIZE - 1);
- bl = camel_block_file_get_block (ki->blocks, blockid);
+ bl = camel_block_file_get_block (ki->priv->blocks, blockid);
if (bl == NULL) {
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
return 0;
@@ -990,7 +1003,7 @@ camel_key_table_next (CamelKeyTable *ki,
if (index >= kb->used) {
/* FIXME: check for loops */
next = kb->next;
- camel_block_file_unref_block (ki->blocks, bl);
+ camel_block_file_unref_block (ki->priv->blocks, bl);
bl = NULL;
}
} while (bl == NULL);
@@ -1004,7 +1017,7 @@ camel_key_table_next (CamelKeyTable *ki,
/*|| kb->u.keys[index-1].offset < kb->u.keydata - (gchar *)&kb->u.keys[kb->used]))) {*/
|| kb->u.keys[index - 1].offset < sizeof (kb->u.keys[0]) * kb->used)))) {
g_warning ("Block %u invalid scanning keys", bl->id);
- camel_block_file_unref_block (ki->blocks, bl);
+ camel_block_file_unref_block (ki->priv->blocks, bl);
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
return 0;
}
@@ -1030,7 +1043,7 @@ camel_key_table_next (CamelKeyTable *ki,
CAMEL_KEY_TABLE_UNLOCK (ki, lock);
- camel_block_file_unref_block (ki->blocks, bl);
+ camel_block_file_unref_block (ki->priv->blocks, bl);
return next;
}
diff --git a/src/camel/camel-partition-table.h b/src/camel/camel-partition-table.h
index 8689d4b..50571fa 100644
--- a/src/camel/camel-partition-table.h
+++ b/src/camel/camel-partition-table.h
@@ -103,19 +103,13 @@ struct _CamelPartitionMapBlock {
struct _CamelPartitionTable {
GObject parent;
CamelPartitionTablePrivate *priv;
-
- CamelBlockFile *blocks;
- camel_block_t rootid;
-
- gint (*is_key)(CamelPartitionTable *cpi, const gchar *key, camel_key_t keyid, gpointer data);
- gpointer is_key_data;
-
- /* we keep a list of partition blocks active at all times */
- GQueue partition;
};
struct _CamelPartitionTableClass {
GObjectClass parent;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_partition_table_get_type (void);
@@ -168,17 +162,13 @@ struct _CamelKeyBlock {
struct _CamelKeyTable {
GObject parent;
CamelKeyTablePrivate *priv;
-
- CamelBlockFile *blocks;
-
- camel_block_t rootid;
-
- CamelKeyRootBlock *root;
- CamelBlock *root_block;
};
struct _CamelKeyTableClass {
GObjectClass parent;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_key_table_get_type (void);
diff --git a/src/camel/camel-provider.c b/src/camel/camel-provider.c
index 45d2611..c9c3bd1 100644
--- a/src/camel/camel-provider.c
+++ b/src/camel/camel-provider.c
@@ -47,6 +47,42 @@ static GRecMutex provider_lock;
#define LOCK() (g_rec_mutex_lock(&provider_lock))
#define UNLOCK() (g_rec_mutex_unlock(&provider_lock))
+CamelProvider * camel_provider_copy (CamelProvider *provider);
+void camel_provider_free (CamelProvider *provider);
+
+G_DEFINE_BOXED_TYPE (CamelProvider, camel_provider, camel_provider_copy, camel_provider_free)
+
+/*
+ * camel_provider_copy:
+ * @provider: a #CamelProvider to copy
+ *
+ * The function returns @provider, because providers are not allocated
+ * on heap. It's defined only for the introspection purposes.
+ *
+ * Returns: (transfer full): the @provider
+ *
+ * Since: 3.24
+ */
+CamelProvider *
+camel_provider_copy (CamelProvider *provider)
+{
+ return provider;
+}
+
+/*
+ * camel_provider_free:
+ * @provider: a #CamelProvider to copy
+ *
+ * The function does nothing, because providers are not allocated
+ * on heap. It's defined only for the introspection purposes.
+ *
+ * Since: 3.24
+ */
+void
+camel_provider_free (CamelProvider *provider)
+{
+}
+
/* The vfolder provider is always available */
static CamelProvider vee_provider = {
"vfolder",
@@ -138,8 +174,8 @@ provider_setup (gpointer param)
(GEqualFunc) camel_strcase_equal);
vee_provider.object_types[CAMEL_PROVIDER_STORE] = CAMEL_TYPE_VEE_STORE;
- vee_provider.url_hash = camel_url_hash;
- vee_provider.url_equal = camel_url_equal;
+ vee_provider.url_hash = (GHashFunc) camel_url_hash;
+ vee_provider.url_equal = (GEqualFunc) camel_url_equal;
provider_register_internal (&vee_provider);
return NULL;
diff --git a/src/camel/camel-provider.h b/src/camel/camel-provider.h
index 0f09117..1a1d642 100644
--- a/src/camel/camel-provider.h
+++ b/src/camel/camel-provider.h
@@ -196,6 +196,9 @@ struct _CamelProviderModule {
guint loaded : 1;
};
+/* Introspection function */
+GType camel_provider_get_type (void) G_GNUC_CONST;
+
void camel_provider_init (void);
gboolean camel_provider_load (const gchar *path,
GError **error);
diff --git a/src/camel/camel-sasl-anonymous.c b/src/camel/camel-sasl-anonymous.c
index 62c1fe0..90ff488 100644
--- a/src/camel/camel-sasl-anonymous.c
+++ b/src/camel/camel-sasl-anonymous.c
@@ -26,6 +26,11 @@
#include "camel-internet-address.h"
#include "camel-sasl-anonymous.h"
+struct _CamelSaslAnonymousPrivate {
+ gchar *trace_info;
+ CamelSaslAnonTraceType type;
+};
+
static CamelServiceAuthType sasl_anonymous_auth_type = {
N_("Anonymous"),
@@ -42,7 +47,7 @@ sasl_anonymous_finalize (GObject *object)
{
CamelSaslAnonymous *sasl = CAMEL_SASL_ANONYMOUS (object);
- g_free (sasl->trace_info);
+ g_free (sasl->priv->trace_info);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_sasl_anonymous_parent_class)->finalize (object);
@@ -66,33 +71,33 @@ sasl_anonymous_challenge_sync (CamelSasl *sasl,
return NULL;
}
- switch (sasl_anon->type) {
+ switch (sasl_anon->priv->type) {
case CAMEL_SASL_ANON_TRACE_EMAIL:
cia = camel_internet_address_new ();
- if (camel_internet_address_add (cia, NULL, sasl_anon->trace_info) != 1) {
+ if (camel_internet_address_add (cia, NULL, sasl_anon->priv->trace_info) != 1) {
g_set_error (
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
_("Invalid email address trace information:\n%s"),
- sasl_anon->trace_info);
+ sasl_anon->priv->trace_info);
g_object_unref (cia);
return NULL;
}
g_object_unref (cia);
ret = g_byte_array_new ();
- g_byte_array_append (ret, (guint8 *) sasl_anon->trace_info, strlen (sasl_anon->trace_info));
+ g_byte_array_append (ret, (guint8 *) sasl_anon->priv->trace_info, strlen
(sasl_anon->priv->trace_info));
break;
case CAMEL_SASL_ANON_TRACE_OPAQUE:
- if (strchr (sasl_anon->trace_info, '@')) {
+ if (strchr (sasl_anon->priv->trace_info, '@')) {
g_set_error (
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
_("Invalid opaque trace information:\n%s"),
- sasl_anon->trace_info);
+ sasl_anon->priv->trace_info);
return NULL;
}
ret = g_byte_array_new ();
- g_byte_array_append (ret, (guint8 *) sasl_anon->trace_info, strlen (sasl_anon->trace_info));
+ g_byte_array_append (ret, (guint8 *) sasl_anon->priv->trace_info, strlen
(sasl_anon->priv->trace_info));
break;
case CAMEL_SASL_ANON_TRACE_EMPTY:
ret = g_byte_array_new ();
@@ -102,7 +107,7 @@ sasl_anonymous_challenge_sync (CamelSasl *sasl,
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
_("Invalid trace information:\n%s"),
- sasl_anon->trace_info);
+ sasl_anon->priv->trace_info);
return NULL;
}
@@ -116,6 +121,8 @@ camel_sasl_anonymous_class_init (CamelSaslAnonymousClass *class)
GObjectClass *object_class;
CamelSaslClass *sasl_class;
+ g_type_class_add_private (class, sizeof (CamelSaslAnonymousPrivate));
+
object_class = G_OBJECT_CLASS (class);
object_class->finalize = sasl_anonymous_finalize;
@@ -127,6 +134,7 @@ camel_sasl_anonymous_class_init (CamelSaslAnonymousClass *class)
static void
camel_sasl_anonymous_init (CamelSaslAnonymous *sasl_anonymous)
{
+ sasl_anonymous->priv = G_TYPE_INSTANCE_GET_PRIVATE (sasl_anonymous, CAMEL_TYPE_SASL_ANONYMOUS,
CamelSaslAnonymousPrivate);
}
/**
@@ -148,8 +156,8 @@ camel_sasl_anonymous_new (CamelSaslAnonTraceType type,
return NULL;
sasl_anon = g_object_new (CAMEL_TYPE_SASL_ANONYMOUS, NULL);
- sasl_anon->trace_info = g_strdup (trace_info);
- sasl_anon->type = type;
+ sasl_anon->priv->trace_info = g_strdup (trace_info);
+ sasl_anon->priv->type = type;
return CAMEL_SASL (sasl_anon);
}
diff --git a/src/camel/camel-sasl-anonymous.h b/src/camel/camel-sasl-anonymous.h
index 56c570e..43041d3 100644
--- a/src/camel/camel-sasl-anonymous.h
+++ b/src/camel/camel-sasl-anonymous.h
@@ -50,16 +50,18 @@ G_BEGIN_DECLS
typedef struct _CamelSaslAnonymous CamelSaslAnonymous;
typedef struct _CamelSaslAnonymousClass CamelSaslAnonymousClass;
+typedef struct _CamelSaslAnonymousPrivate CamelSaslAnonymousPrivate;
struct _CamelSaslAnonymous {
CamelSasl parent;
-
- gchar *trace_info;
- CamelSaslAnonTraceType type;
+ CamelSaslAnonymousPrivate *priv;
};
struct _CamelSaslAnonymousClass {
CamelSaslClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_anonymous_get_type (void);
diff --git a/src/camel/camel-sasl-cram-md5.h b/src/camel/camel-sasl-cram-md5.h
index 352c6f3..d885796 100644
--- a/src/camel/camel-sasl-cram-md5.h
+++ b/src/camel/camel-sasl-cram-md5.h
@@ -58,6 +58,9 @@ struct _CamelSaslCramMd5 {
struct _CamelSaslCramMd5Class {
CamelSaslClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_cram_md5_get_type (void);
diff --git a/src/camel/camel-sasl-digest-md5.h b/src/camel/camel-sasl-digest-md5.h
index 9e30fa4..1b5da6d 100644
--- a/src/camel/camel-sasl-digest-md5.h
+++ b/src/camel/camel-sasl-digest-md5.h
@@ -59,6 +59,9 @@ struct _CamelSaslDigestMd5 {
struct _CamelSaslDigestMd5Class {
CamelSaslClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_digest_md5_get_type (void);
diff --git a/src/camel/camel-sasl-gssapi.c b/src/camel/camel-sasl-gssapi.c
index 08d429d..536fea9 100644
--- a/src/camel/camel-sasl-gssapi.c
+++ b/src/camel/camel-sasl-gssapi.c
@@ -578,8 +578,8 @@ camel_sasl_gssapi_is_available (void)
/**
* camel_sasl_gssapi_override_host_and_user:
- * @override_host: Host name to use during challenge processing; can be %NULL
- * @override_user: User name to use during challenge processing; can be %NULL
+ * @override_host: (nullable): Host name to use during challenge processing; can be %NULL
+ * @override_user: (nullable): User name to use during challenge processing; can be %NULL
*
* Set host and user to use, instead of those in CamelService's settings.
* It's both or none, aka either set both, or the settings values are used.
diff --git a/src/camel/camel-sasl-gssapi.h b/src/camel/camel-sasl-gssapi.h
index 7629fb3..4e87ba9 100644
--- a/src/camel/camel-sasl-gssapi.h
+++ b/src/camel/camel-sasl-gssapi.h
@@ -59,6 +59,9 @@ struct _CamelSaslGssapi {
struct _CamelSaslGssapiClass {
CamelSaslClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_gssapi_get_type (void);
diff --git a/src/camel/camel-sasl-login.h b/src/camel/camel-sasl-login.h
index 41a53cf..6fab83b 100644
--- a/src/camel/camel-sasl-login.h
+++ b/src/camel/camel-sasl-login.h
@@ -58,6 +58,9 @@ struct _CamelSaslLogin {
struct _CamelSaslLoginClass {
CamelSaslClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_login_get_type (void);
diff --git a/src/camel/camel-sasl-ntlm.h b/src/camel/camel-sasl-ntlm.h
index 31d0630..095250f 100644
--- a/src/camel/camel-sasl-ntlm.h
+++ b/src/camel/camel-sasl-ntlm.h
@@ -57,6 +57,9 @@ struct _CamelSaslNTLM {
struct _CamelSaslNTLMClass {
CamelSaslClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_ntlm_get_type (void);
diff --git a/src/camel/camel-sasl-plain.h b/src/camel/camel-sasl-plain.h
index 8bdf7f1..f21c9d3 100644
--- a/src/camel/camel-sasl-plain.h
+++ b/src/camel/camel-sasl-plain.h
@@ -58,6 +58,9 @@ struct _CamelSaslPlain {
struct _CamelSaslPlainClass {
CamelSaslClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_plain_get_type (void);
diff --git a/src/camel/camel-sasl-popb4smtp.h b/src/camel/camel-sasl-popb4smtp.h
index a079d39..1fa6731 100644
--- a/src/camel/camel-sasl-popb4smtp.h
+++ b/src/camel/camel-sasl-popb4smtp.h
@@ -58,6 +58,9 @@ struct _CamelSaslPOPB4SMTP {
struct _CamelSaslPOPB4SMTPClass {
CamelSaslClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_popb4smtp_get_type (void);
diff --git a/src/camel/camel-sasl.c b/src/camel/camel-sasl.c
index 38a55ce..c903545 100644
--- a/src/camel/camel-sasl.c
+++ b/src/camel/camel-sasl.c
@@ -341,7 +341,7 @@ camel_sasl_init (CamelSasl *sasl)
* @mechanism: the SASL mechanism
* @service: the CamelService that will be using this SASL
*
- * Returns: a new #CamelSasl object for the given @service_name,
+ * Returns: (nullable): a new #CamelSasl object for the given @service_name,
* @mechanism, and @service, or %NULL if the mechanism is not
* supported.
**/
diff --git a/src/camel/camel-sasl.h b/src/camel/camel-sasl.h
index e167199..befc009 100644
--- a/src/camel/camel-sasl.h
+++ b/src/camel/camel-sasl.h
@@ -72,8 +72,8 @@ struct _CamelSaslClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots. */
- gpointer reserved[4];
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sasl_get_type (void);
diff --git a/src/camel/camel-search-private.c b/src/camel/camel-search-private.c
index ced34e9..8a38f0f 100644
--- a/src/camel/camel-search-private.c
+++ b/src/camel/camel-search-private.c
@@ -46,6 +46,9 @@
*
* A small issue is that case-insenstivity won't work entirely correct
* for utf8 strings. */
+/**
+ * camel_search_build_match_regex: (skip)
+ **/
gint
camel_search_build_match_regex (regex_t *pattern,
camel_search_flags_t type,
@@ -500,6 +503,9 @@ camel_search_header_match (const gchar *value,
/* Performs a 'slow' content-based match. */
/* There is also an identical copy of this in camel-filter-search.c. */
+/**
+ * camel_search_message_body_contains: (skip)
+ **/
gboolean
camel_search_message_body_contains (CamelDataWrapper *object,
regex_t *pattern)
@@ -524,8 +530,8 @@ camel_search_message_body_contains (CamelDataWrapper *object,
} else if (CAMEL_IS_MIME_MESSAGE (containee)) {
/* For messages we only look at its contents. */
truth = camel_search_message_body_contains ((CamelDataWrapper *) containee, pattern);
- } else if (camel_content_type_is (CAMEL_DATA_WRAPPER (containee)->mime_type, "text", "*")
- || camel_content_type_is (CAMEL_DATA_WRAPPER (containee)->mime_type, "x-evolution",
"evolution-rss-feed")) {
+ } else if (camel_content_type_is (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER
(containee)), "text", "*")
+ || camel_content_type_is (camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER
(containee)), "x-evolution", "evolution-rss-feed")) {
/* For all other text parts we look
* inside, otherwise we don't care. */
CamelStream *stream;
@@ -535,7 +541,7 @@ camel_search_message_body_contains (CamelDataWrapper *object,
byte_array = g_byte_array_new ();
stream = camel_stream_mem_new_with_byte_array (byte_array);
- charset = camel_content_type_param (CAMEL_DATA_WRAPPER (containee)->mime_type, "charset");
+ charset = camel_content_type_param (camel_data_wrapper_get_mime_type_field
(CAMEL_DATA_WRAPPER (containee)), "charset");
if (charset && *charset) {
CamelMimeFilter *filter = camel_mime_filter_charset_new (charset, "UTF-8");
if (filter) {
@@ -831,9 +837,9 @@ camel_search_get_all_headers_decoded (CamelMimeMessage *message)
{
CamelMedium *medium;
GString *str;
- GArray *headers;
+ const CamelNameValueArray *headers;
const gchar *default_charset;
- guint ii;
+ guint ii, length;
g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
@@ -845,19 +851,23 @@ camel_search_get_all_headers_decoded (CamelMimeMessage *message)
default_charset = camel_search_get_default_charset_from_message (message);
str = g_string_new ("");
- for (ii = 0; ii < headers->len; ii++) {
- CamelMediumHeader *header;
+ length = camel_name_value_array_get_length (headers);
+ for (ii = 0; ii < length; ii++) {
gchar *content;
+ const gchar *header_name = NULL;
+ const gchar *header_value = NULL;
- header = &g_array_index (headers, CamelMediumHeader, ii);
- if (!header->value)
+ if (!camel_name_value_array_get (headers, ii, &header_name, &header_value))
continue;
- content = camel_search_get_header_decoded (header->name, header->value, default_charset);
+ if (!header_name || !header_value)
+ continue;
+
+ content = camel_search_get_header_decoded (header_name, header_value, default_charset);
if (!content)
continue;
- g_string_append (str, header->name);
+ g_string_append (str, header_name);
if (isspace (content[0]))
g_string_append (str, ":");
else
@@ -868,7 +878,5 @@ camel_search_get_all_headers_decoded (CamelMimeMessage *message)
g_free (content);
}
- camel_medium_free_headers (medium, headers);
-
return g_string_free (str, FALSE);
}
diff --git a/src/camel/camel-service.c b/src/camel/camel-service.c
index cc4cac9..e53f7d1 100644
--- a/src/camel/camel-service.c
+++ b/src/camel/camel-service.c
@@ -35,8 +35,8 @@
#include "camel-network-service.h"
#include "camel-network-settings.h"
#include "camel-operation.h"
-#include "camel-service.h"
#include "camel-session.h"
+#include "camel-service.h"
#define d(x)
#define w(x)
@@ -121,6 +121,7 @@ static void service_task_dispatch (CamelService *service,
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (
CamelService, camel_service, CAMEL_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, camel_service_initable_init))
+G_DEFINE_BOXED_TYPE (CamelServiceAuthType, camel_service_auth_type, camel_service_auth_type_copy,
camel_service_auth_type_free);
static void
async_context_free (AsyncContext *async_context)
@@ -1560,14 +1561,14 @@ camel_service_set_proxy_resolver (CamelService *service,
/**
* camel_service_ref_session:
- * @service: (type CamelService): a #CamelService
+ * @service: a #CamelService
*
* Returns the #CamelSession associated with the service.
*
* The returned #CamelSession is referenced for thread-safety. Unreference
* the #CamelSession with g_object_unref() when finished with it.
*
- * Returns: (transfer full): the #CamelSession
+ * Returns: (transfer full) (type CamelSession): the #CamelSession
*
* Since: 3.8
**/
@@ -2378,3 +2379,39 @@ camel_service_query_auth_types_finish (CamelService *service,
return g_task_propagate_pointer (G_TASK (result), error);
}
+/**
+ * camel_service_auth_type_copy:
+ * @service_auth_type: an #CamelServiceAuthType
+ *
+ * Copies the @service_auth_type struct.
+ * Does nothing and returns the given object in reality, needed for the introspection.
+ *
+ * Returns: (transfer full): the copy of @service_auth_type
+ *
+ * Since: 3.24
+ **/
+CamelServiceAuthType *
+camel_service_auth_type_copy (const CamelServiceAuthType *service_auth_type)
+{
+ /* This is needed for the introspection.
+ * In the reality, each CamelSasl subclass has a static reference of it.
+ */
+ return (CamelServiceAuthType *) service_auth_type;
+}
+
+/**
+ * camel_service_auth_type_free:
+ * @service_auth_type: an #CamelServiceAuthType
+ *
+ * Frees the @service_auth_type struct.
+ * Does nothing in reality, needed for the introspection.
+ *
+ * Since: 3.24
+ **/
+void
+camel_service_auth_type_free (CamelServiceAuthType *service_auth_type)
+{
+ /* This is needed for the introspection.
+ * In the reality, each CamelSasl subclass has a static reference of it.
+ */
+}
diff --git a/src/camel/camel-service.h b/src/camel/camel-service.h
index 5dd70f7..fe04223 100644
--- a/src/camel/camel-service.h
+++ b/src/camel/camel-service.h
@@ -51,6 +51,8 @@
#define CAMEL_SERVICE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS \
((obj), CAMEL_TYPE_SERVICE, CamelServiceClass))
+#define CAMEL_TYPE_SERVICE_AUTH_TYPE \
+ (camel_service_auth_type_get_type ())
/**
* CAMEL_SERVICE_ERROR:
@@ -113,8 +115,8 @@ struct _CamelServiceClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots. */
- gpointer reserved[8];
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
/* query_auth_types returns a GList of these */
@@ -216,6 +218,11 @@ GList * camel_service_query_auth_types_finish
GAsyncResult *result,
GError **error);
+GType camel_service_auth_type_get_type(void);
+CamelServiceAuthType *
+ camel_service_auth_type_copy (const CamelServiceAuthType *service_auth_type);
+void camel_service_auth_type_free (CamelServiceAuthType *service_auth_type);
+
G_END_DECLS
#endif /* CAMEL_SERVICE_H */
diff --git a/src/camel/camel-session.c b/src/camel/camel-session.c
index 1c4fcc5..c7d76b9 100644
--- a/src/camel/camel-session.c
+++ b/src/camel/camel-session.c
@@ -704,7 +704,7 @@ camel_session_class_init (CamelSessionClass *class)
NULL, NULL, NULL,
G_TYPE_NONE, 2,
G_TYPE_CANCELLABLE,
- G_TYPE_POINTER);
+ G_TYPE_ERROR);
/**
* CamelSession::user-alert:
diff --git a/src/camel/camel-session.h b/src/camel/camel-session.h
index e837e0f..1745ac6 100644
--- a/src/camel/camel-session.h
+++ b/src/camel/camel-session.h
@@ -132,8 +132,8 @@ struct _CamelSessionClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots for methods. */
- gpointer reserved_for_methods[4];
+ /* Padding for future expansion */
+ gpointer reserved_methods[20];
/* Signals */
void (*job_started) (CamelSession *session,
@@ -145,6 +145,9 @@ struct _CamelSessionClass {
CamelService *service,
CamelSessionAlertType type,
const gchar *message);
+
+ /* Padding for future expansion */
+ gpointer reserved_signals[20];
};
GType camel_session_get_type (void);
diff --git a/src/camel/camel-settings.h b/src/camel/camel-settings.h
index 3781b82..c8dcd89 100644
--- a/src/camel/camel-settings.h
+++ b/src/camel/camel-settings.h
@@ -72,6 +72,9 @@ struct _CamelSettingsClass {
CamelSettings * (*clone) (CamelSettings *settings);
gboolean (*equal) (CamelSettings *settings_a,
CamelSettings *settings_b);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_settings_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-sexp.c b/src/camel/camel-sexp.c
index 41664c4..5487d79 100644
--- a/src/camel/camel-sexp.c
+++ b/src/camel/camel-sexp.c
@@ -91,6 +91,21 @@
#define r(x) /* run debug */
#define d(x) /* general debug */
+struct _CamelSExpPrivate {
+ GScanner *scanner; /* for parsing text version */
+ CamelSExpTerm *tree; /* root of expression tree */
+
+ /* private stuff */
+ jmp_buf failenv;
+ gchar *error;
+ GSList *operators;
+
+ /* TODO: may also need a pool allocator for term strings,
+ * so we dont lose them in error conditions? */
+ CamelMemChunk *term_chunks;
+ CamelMemChunk *result_chunks;
+};
+
G_DEFINE_TYPE (CamelSExp, camel_sexp, G_TYPE_OBJECT)
static CamelSExpTerm * parse_list (CamelSExp *sexp, gint gotbrace);
@@ -159,17 +174,17 @@ camel_sexp_fatal_error (CamelSExp *sexp,
{
va_list args;
- /* jumps back to the caller of sexp->failenv,
+ /* jumps back to the caller of sexp->priv->failenv,
* only to be called from inside a callback */
- if (sexp->error)
- g_free (sexp->error);
+ if (sexp->priv->error)
+ g_free (sexp->priv->error);
va_start (args, why);
- sexp->error = g_strdup_vprintf (why, args);
+ sexp->priv->error = g_strdup_vprintf (why, args);
va_end (args);
- longjmp (sexp->failenv, 1);
+ longjmp (sexp->priv->failenv, 1);
}
/**
@@ -180,11 +195,11 @@ camel_sexp_fatal_error (CamelSExp *sexp,
const gchar *
camel_sexp_error (CamelSExp *sexp)
{
- return sexp->error;
+ return sexp->priv->error;
}
/**
- * camel_sexp_result_new:
+ * camel_sexp_result_new: (skip)
*
* Since: 3.4
**/
@@ -194,7 +209,7 @@ camel_sexp_result_new (CamelSExp *sexp,
{
CamelSExpResult *result;
- result = camel_memchunk_alloc0 (sexp->result_chunks);
+ result = camel_memchunk_alloc0 (sexp->priv->result_chunks);
result->type = type;
result->occuring_start = 0;
result->occuring_end = _TIME_MAX;
@@ -231,7 +246,7 @@ camel_sexp_result_free (CamelSExp *sexp,
default:
g_return_if_reached ();
}
- camel_memchunk_free (sexp->result_chunks, term);
+ camel_memchunk_free (sexp->priv->result_chunks, term);
}
/**
@@ -301,7 +316,7 @@ term_eval_and (CamelSExp *sexp,
result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_UNDEFINED);
oper = "AND";
- sexp->operators = g_slist_prepend (sexp->operators, (gpointer) oper);
+ sexp->priv->operators = g_slist_prepend (sexp->priv->operators, (gpointer) oper);
for (i = 0; bool && i < argc; i++) {
r1 = camel_sexp_term_eval (sexp, argv[i]);
@@ -343,7 +358,7 @@ term_eval_and (CamelSExp *sexp,
}
g_hash_table_destroy (ht);
- sexp->operators = g_slist_remove (sexp->operators, oper);
+ sexp->priv->operators = g_slist_remove (sexp->priv->operators, oper);
return result;
}
@@ -365,7 +380,7 @@ term_eval_or (CamelSExp *sexp,
r (printf ("(or \n"));
oper = "OR";
- sexp->operators = g_slist_prepend (sexp->operators, (gpointer) oper);
+ sexp->priv->operators = g_slist_prepend (sexp->priv->operators, (gpointer) oper);
result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_UNDEFINED);
@@ -405,7 +420,7 @@ term_eval_or (CamelSExp *sexp,
}
g_hash_table_destroy (ht);
- sexp->operators = g_slist_remove (sexp->operators, oper);
+ sexp->priv->operators = g_slist_remove (sexp->priv->operators, oper);
return result;
}
@@ -753,7 +768,7 @@ term_eval_begin (CamelSExp *sexp,
}
/**
- * camel_sexp_term_eval:
+ * camel_sexp_term_eval: (skip)
*
* Since: 3.4
**/
@@ -1195,7 +1210,7 @@ parse_term_new (CamelSExp *sexp,
{
CamelSExpTerm *term;
- term = camel_memchunk_alloc0 (sexp->term_chunks);
+ term = camel_memchunk_alloc0 (sexp->priv->term_chunks);
term->type = type;
return term;
@@ -1233,7 +1248,7 @@ parse_term_free (CamelSExp *sexp,
default:
printf ("parse_term_free: unknown type: %d\n", term->type);
}
- camel_memchunk_free (sexp->term_chunks, term);
+ camel_memchunk_free (sexp->priv->term_chunks, term);
}
static CamelSExpTerm **
@@ -1243,7 +1258,7 @@ parse_values (CamelSExp *sexp,
gint token;
CamelSExpTerm **terms;
gint i, size = 0;
- GScanner *gs = sexp->scanner;
+ GScanner *gs = sexp->priv->scanner;
GSList *list = NULL, *l;
p (printf ("parsing values\n"));
@@ -1273,7 +1288,7 @@ parse_values (CamelSExp *sexp,
}
/**
- * camel_sexp_parse_value:
+ * camel_sexp_parse_value: (skip)
*
* Since: 3.4
**/
@@ -1288,7 +1303,7 @@ parse_value (CamelSExp *sexp)
{
gint token, negative = FALSE;
CamelSExpTerm *term = NULL;
- GScanner *gs = sexp->scanner;
+ GScanner *gs = sexp->priv->scanner;
CamelSExpSymbol *sym;
p (printf ("parsing value\n"));
@@ -1382,7 +1397,7 @@ parse_list (CamelSExp *sexp,
{
gint token;
CamelSExpTerm *term = NULL;
- GScanner *gs = sexp->scanner;
+ GScanner *gs = sexp->priv->scanner;
p (printf ("parsing list\n"));
if (gotbrace)
@@ -1449,19 +1464,19 @@ camel_sexp_finalize (GObject *object)
{
CamelSExp *sexp = (CamelSExp *) object;
- if (sexp->tree) {
- parse_term_free (sexp, sexp->tree);
- sexp->tree = NULL;
+ if (sexp->priv->tree) {
+ parse_term_free (sexp, sexp->priv->tree);
+ sexp->priv->tree = NULL;
}
- camel_memchunk_destroy (sexp->term_chunks);
- camel_memchunk_destroy (sexp->result_chunks);
+ camel_memchunk_destroy (sexp->priv->term_chunks);
+ camel_memchunk_destroy (sexp->priv->result_chunks);
- g_scanner_scope_foreach_symbol (sexp->scanner, 0, free_symbol, NULL);
- g_scanner_destroy (sexp->scanner);
+ g_scanner_scope_foreach_symbol (sexp->priv->scanner, 0, free_symbol, NULL);
+ g_scanner_destroy (sexp->priv->scanner);
- g_free (sexp->error);
- sexp->error = NULL;
+ g_free (sexp->priv->error);
+ sexp->priv->error = NULL;
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_sexp_parent_class)->finalize (object);
@@ -1472,6 +1487,8 @@ camel_sexp_class_init (CamelSExpClass *class)
{
GObjectClass *object_class;
+ g_type_class_add_private (class, sizeof (CamelSExpPrivate));
+
object_class = G_OBJECT_CLASS (class);
object_class->finalize = camel_sexp_finalize;
}
@@ -1503,9 +1520,11 @@ camel_sexp_init (CamelSExp *sexp)
{
gint i;
- sexp->scanner = g_scanner_new (&scanner_config);
- sexp->term_chunks = camel_memchunk_new (16, sizeof (CamelSExpTerm));
- sexp->result_chunks = camel_memchunk_new (16, sizeof (CamelSExpResult));
+ sexp->priv = G_TYPE_INSTANCE_GET_PRIVATE (sexp, CAMEL_TYPE_SEXP, CamelSExpPrivate);
+
+ sexp->priv->scanner = g_scanner_new (&scanner_config);
+ sexp->priv->term_chunks = camel_memchunk_new (16, sizeof (CamelSExpTerm));
+ sexp->priv->result_chunks = camel_memchunk_new (16, sizeof (CamelSExpResult));
/* load in builtin symbols? */
for (i = 0; i < G_N_ELEMENTS (symbols); i++) {
@@ -1560,7 +1579,7 @@ camel_sexp_add_function (CamelSExp *sexp,
sym->type = CAMEL_SEXP_TERM_FUNC;
sym->data = user_data;
- g_scanner_scope_add_symbol (sexp->scanner, scope, sym->name, sym);
+ g_scanner_scope_add_symbol (sexp->priv->scanner, scope, sym->name, sym);
}
/**
@@ -1589,7 +1608,7 @@ camel_sexp_add_ifunction (CamelSExp *sexp,
sym->type = CAMEL_SEXP_TERM_IFUNC;
sym->data = user_data;
- g_scanner_scope_add_symbol (sexp->scanner, scope, sym->name, sym);
+ g_scanner_scope_add_symbol (sexp->priv->scanner, scope, sym->name, sym);
}
/**
@@ -1613,7 +1632,7 @@ camel_sexp_add_variable (CamelSExp *sexp,
sym->type = CAMEL_SEXP_TERM_VAR;
sym->data = value;
- g_scanner_scope_add_symbol (sexp->scanner, scope, sym->name, sym);
+ g_scanner_scope_add_symbol (sexp->priv->scanner, scope, sym->name, sym);
}
/**
@@ -1632,10 +1651,10 @@ camel_sexp_remove_symbol (CamelSExp *sexp,
g_return_if_fail (CAMEL_IS_SEXP (sexp));
g_return_if_fail (name != NULL);
- oldscope = g_scanner_set_scope (sexp->scanner, scope);
- sym = g_scanner_lookup_symbol (sexp->scanner, name);
- g_scanner_scope_remove_symbol (sexp->scanner, scope, name);
- g_scanner_set_scope (sexp->scanner, oldscope);
+ oldscope = g_scanner_set_scope (sexp->priv->scanner, scope);
+ sym = g_scanner_lookup_symbol (sexp->priv->scanner, name);
+ g_scanner_scope_remove_symbol (sexp->priv->scanner, scope, name);
+ g_scanner_set_scope (sexp->priv->scanner, oldscope);
if (sym != NULL) {
g_free (sym->name);
g_free (sym);
@@ -1653,7 +1672,7 @@ camel_sexp_set_scope (CamelSExp *sexp,
{
g_return_val_if_fail (CAMEL_IS_SEXP (sexp), 0);
- return g_scanner_set_scope (sexp->scanner, scope);
+ return g_scanner_set_scope (sexp->priv->scanner, scope);
}
/**
@@ -1669,7 +1688,7 @@ camel_sexp_input_text (CamelSExp *sexp,
g_return_if_fail (CAMEL_IS_SEXP (sexp));
g_return_if_fail (text != NULL);
- g_scanner_input_text (sexp->scanner, text, len);
+ g_scanner_input_text (sexp->priv->scanner, text, len);
}
/**
@@ -1683,7 +1702,7 @@ camel_sexp_input_file (CamelSExp *sexp,
{
g_return_if_fail (CAMEL_IS_SEXP (sexp));
- g_scanner_input_file (sexp->scanner, fd);
+ g_scanner_input_file (sexp->priv->scanner, fd);
}
/**
@@ -1696,21 +1715,21 @@ camel_sexp_parse (CamelSExp *sexp)
{
g_return_val_if_fail (CAMEL_IS_SEXP (sexp), -1);
- if (setjmp (sexp->failenv)) {
- g_warning ("Error in parsing: %s", sexp->error);
+ if (setjmp (sexp->priv->failenv)) {
+ g_warning ("Error in parsing: %s", sexp->priv->error);
return -1;
}
- if (sexp->tree)
- parse_term_free (sexp, sexp->tree);
+ if (sexp->priv->tree)
+ parse_term_free (sexp, sexp->priv->tree);
- sexp->tree = parse_value (sexp);
+ sexp->priv->tree = parse_value (sexp);
return 0;
}
/**
- * camel_sexp_eval:
+ * camel_sexp_eval: (skip)
*
* Since: 3.4
**/
@@ -1718,14 +1737,14 @@ CamelSExpResult *
camel_sexp_eval (CamelSExp *sexp)
{
g_return_val_if_fail (CAMEL_IS_SEXP (sexp), NULL);
- g_return_val_if_fail (sexp->tree != NULL, NULL);
+ g_return_val_if_fail (sexp->priv->tree != NULL, NULL);
- if (setjmp (sexp->failenv)) {
- g_warning ("Error in execution: %s", sexp->error);
+ if (setjmp (sexp->priv->failenv)) {
+ g_warning ("Error in execution: %s", sexp->priv->error);
return NULL;
}
- return camel_sexp_term_eval (sexp, sexp->tree);
+ return camel_sexp_term_eval (sexp, sexp->priv->tree);
}
/**
@@ -1746,19 +1765,19 @@ camel_sexp_evaluate_occur_times (CamelSExp *sexp,
CamelSExpResult *result;
gboolean generator;
g_return_val_if_fail (CAMEL_IS_SEXP (sexp), FALSE);
- g_return_val_if_fail (sexp->tree != NULL, FALSE);
+ g_return_val_if_fail (sexp->priv->tree != NULL, FALSE);
g_return_val_if_fail (start != NULL, FALSE);
g_return_val_if_fail (end != NULL, FALSE);
*start = *end = -1;
- if (setjmp (sexp->failenv)) {
- g_warning ("Error in execution: %s", sexp->error);
+ if (setjmp (sexp->priv->failenv)) {
+ g_warning ("Error in execution: %s", sexp->priv->error);
return FALSE;
}
result = camel_sexp_term_evaluate_occur_times (
- sexp, sexp->tree, start, end);
+ sexp, sexp->priv->tree, start, end);
generator = result->time_generator;
if (generator) {
@@ -1841,8 +1860,8 @@ main (gint argc,
camel_sexp_input_text (sexp, t, t);
camel_sexp_parse (sexp);
- if (sexp->tree)
- parse_dump_term (sexp->tree, 0);
+ if (sexp->priv->tree)
+ parse_dump_term (sexp->priv->tree, 0);
result = camel_sexp_eval (sexp);
if (result) {
diff --git a/src/camel/camel-sexp.h b/src/camel/camel-sexp.h
index e0d824a..f300568 100644
--- a/src/camel/camel-sexp.h
+++ b/src/camel/camel-sexp.h
@@ -51,6 +51,7 @@ G_BEGIN_DECLS
typedef struct _CamelSExp CamelSExp;
typedef struct _CamelSExpClass CamelSExpClass;
+typedef struct _CamelSExpPrivate CamelSExpPrivate;
typedef struct _CamelSExpSymbol CamelSExpSymbol;
typedef struct _CamelSExpResult CamelSExpResult;
@@ -91,6 +92,7 @@ struct _CamelSExpResult {
/**
* CamelSExpFunc:
+ * @argv: (inout) (array length=argc):
*
* Since: 3.4
**/
@@ -98,17 +100,18 @@ typedef CamelSExpResult *
(*CamelSExpFunc) (CamelSExp *sexp,
gint argc,
CamelSExpResult **argv,
- gpointer data);
+ gpointer user_data);
/**
* CamelSExpIFunc:
+ * @argv: (inout) (array length=argc):
*
* Since: 3.4
**/
typedef CamelSExpResult *
(*CamelSExpIFunc) (CamelSExp *sexp, gint argc,
CamelSExpTerm **argv,
- gpointer data);
+ gpointer user_data);
/**
* CamelSExpTermType:
@@ -168,22 +171,14 @@ struct _CamelSExpTerm {
**/
struct _CamelSExp {
GObject parent;
- GScanner *scanner; /* for parsing text version */
- CamelSExpTerm *tree; /* root of expression tree */
-
- /* private stuff */
- jmp_buf failenv;
- gchar *error;
- GSList *operators;
-
- /* TODO: may also need a pool allocator for term strings,
- * so we dont lose them in error conditions? */
- CamelMemChunk *term_chunks;
- CamelMemChunk *result_chunks;
+ CamelSExpPrivate *priv;
};
struct _CamelSExpClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sexp_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-smime-context.c b/src/camel/camel-smime-context.c
index 1e18a1d..adc1689 100644
--- a/src/camel/camel-smime-context.c
+++ b/src/camel/camel-smime-context.c
@@ -871,7 +871,7 @@ smime_context_sign_sync (CamelCipherContext *context,
g_seekable_seek (G_SEEKABLE (ostream), 0, G_SEEK_SET, NULL, NULL);
camel_data_wrapper_construct_from_stream_sync (
dw, ostream, cancellable, NULL);
- dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;
+ camel_data_wrapper_set_encoding (dw, CAMEL_TRANSFER_ENCODING_BINARY);
if (((CamelSMIMEContext *) context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN) {
CamelMultipartSigned *mps;
@@ -951,7 +951,7 @@ smime_context_verify_sync (CamelCipherContext *context,
class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
dw = camel_medium_get_content ((CamelMedium *) ipart);
- ct = dw->mime_type;
+ ct = camel_data_wrapper_get_mime_type_field (dw);
/* FIXME: we should stream this to the decoder */
buffer = g_byte_array_new ();
@@ -1175,7 +1175,7 @@ smime_context_encrypt_sync (CamelCipherContext *context,
camel_data_wrapper_construct_from_stream_sync (
dw, ostream, NULL, NULL);
g_object_unref (ostream);
- dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;
+ camel_data_wrapper_set_encoding (dw, CAMEL_TRANSFER_ENCODING_BINARY);
ct = camel_content_type_new ("application", "x-pkcs7-mime");
camel_content_type_set_param (ct, "name", "smime.p7m");
diff --git a/src/camel/camel-smime-context.h b/src/camel/camel-smime-context.h
index b1dd0e9..a24e8c2 100644
--- a/src/camel/camel-smime-context.h
+++ b/src/camel/camel-smime-context.h
@@ -71,6 +71,9 @@ struct _CamelSMIMEContext {
struct _CamelSMIMEContextClass {
CamelCipherContextClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_smime_context_get_type (void);
diff --git a/src/camel/camel-store-settings.h b/src/camel/camel-store-settings.h
index a743cb1..be1b32a 100644
--- a/src/camel/camel-store-settings.h
+++ b/src/camel/camel-store-settings.h
@@ -64,6 +64,9 @@ struct _CamelStoreSettings {
struct _CamelStoreSettingsClass {
CamelSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_store_settings_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/camel-store-summary.c b/src/camel/camel-store-summary.c
index 23527bc..85fda17 100644
--- a/src/camel/camel-store-summary.c
+++ b/src/camel/camel-store-summary.c
@@ -31,8 +31,8 @@
#include <glib/gstdio.h>
#include "camel-file-utils.h"
-#include "camel-store-summary.h"
#include "camel-folder-summary.h"
+#include "camel-store-summary.h"
#include "camel-url.h"
#include "camel-win32.h"
@@ -66,6 +66,9 @@ struct _CamelStoreSummaryPrivate {
GHashTable *folder_summaries; /* CamelFolderSummary->path; doesn't add reference to
CamelFolderSummary */
guint scheduled_save_id;
+
+ GPtrArray *folders; /* CamelStoreInfo's */
+ GHashTable *folders_path; /* CamelStoreInfo's by path name */
};
G_DEFINE_TYPE (CamelStoreSummary, camel_store_summary, G_TYPE_OBJECT)
@@ -76,15 +79,15 @@ store_summary_finalize (GObject *object)
CamelStoreSummary *summary = CAMEL_STORE_SUMMARY (object);
guint ii;
- for (ii = 0; ii < summary->folders->len; ii++) {
+ for (ii = 0; ii < summary->priv->folders->len; ii++) {
CamelStoreInfo *info;
- info = g_ptr_array_index (summary->folders, ii);
+ info = g_ptr_array_index (summary->priv->folders, ii);
camel_store_summary_info_unref (summary, info);
}
- g_ptr_array_free (summary->folders, TRUE);
- g_hash_table_destroy (summary->folders_path);
+ g_ptr_array_free (summary->priv->folders, TRUE);
+ g_hash_table_destroy (summary->priv->folders_path);
g_hash_table_destroy (summary->priv->folder_summaries);
g_free (summary->priv->summary_path);
@@ -240,10 +243,10 @@ store_summary_store_info_set_string (CamelStoreSummary *summary,
{
switch (type) {
case CAMEL_STORE_INFO_PATH:
- g_hash_table_remove (summary->folders_path, (gchar *) camel_store_info_path (summary, info));
+ g_hash_table_remove (summary->priv->folders_path, (gchar *) camel_store_info_path (summary,
info));
g_free (info->path);
info->path = g_strdup (str);
- g_hash_table_insert (summary->folders_path, (gchar *) camel_store_info_path (summary, info),
info);
+ g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_path (summary,
info), info);
summary->priv->dirty = TRUE;
break;
}
@@ -277,8 +280,8 @@ camel_store_summary_init (CamelStoreSummary *summary)
summary->priv->version = CAMEL_STORE_SUMMARY_VERSION;
- summary->folders = g_ptr_array_new ();
- summary->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
+ summary->priv->folders = g_ptr_array_new ();
+ summary->priv->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
summary->priv->folder_summaries = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
summary->priv->scheduled_save_id = 0;
@@ -333,7 +336,7 @@ camel_store_summary_count (CamelStoreSummary *summary)
{
g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), -1);
- return summary->folders->len;
+ return summary->priv->folders->len;
}
/**
@@ -358,9 +361,9 @@ camel_store_summary_array (CamelStoreSummary *summary)
g_rec_mutex_lock (&summary->priv->summary_lock);
- res = g_ptr_array_sized_new (summary->folders->len);
- for (i = 0; i < summary->folders->len; i++) {
- info = g_ptr_array_index (summary->folders, i);
+ res = g_ptr_array_sized_new (summary->priv->folders->len);
+ for (i = 0; i < summary->priv->folders->len; i++) {
+ info = g_ptr_array_index (summary->priv->folders, i);
camel_store_summary_info_ref (summary, info);
g_ptr_array_add (res, info);
}
@@ -393,7 +396,7 @@ camel_store_summary_array_free (CamelStoreSummary *summary,
}
/**
- * camel_store_summary_path:
+ * camel_store_summary_path: (skip)
* @summary: a #CamelStoreSummary object
* @path: path to the item
*
@@ -416,7 +419,7 @@ camel_store_summary_path (CamelStoreSummary *summary,
g_rec_mutex_lock (&summary->priv->summary_lock);
- info = g_hash_table_lookup (summary->folders_path, path);
+ info = g_hash_table_lookup (summary->priv->folders_path, path);
if (info != NULL)
camel_store_summary_info_ref (summary, info);
@@ -552,9 +555,9 @@ camel_store_summary_save (CamelStoreSummary *summary)
/* FIXME: Locking? */
- count = summary->folders->len;
+ count = summary->priv->folders->len;
for (i = 0; i < count; i++) {
- info = summary->folders->pdata[i];
+ info = summary->priv->folders->pdata[i];
class->store_info_save (summary, out, info);
}
@@ -604,21 +607,21 @@ camel_store_summary_add (CamelStoreSummary *summary,
g_rec_mutex_lock (&summary->priv->summary_lock);
- g_ptr_array_add (summary->folders, info);
- g_hash_table_insert (summary->folders_path, (gchar *) camel_store_info_path (summary, info), info);
+ g_ptr_array_add (summary->priv->folders, info);
+ g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_path (summary, info),
info);
summary->priv->dirty = TRUE;
g_rec_mutex_unlock (&summary->priv->summary_lock);
}
/**
- * camel_store_summary_add_from_path:
+ * camel_store_summary_add_from_path: (skip)
* @summary: a #CamelStoreSummary object
* @path: item path
*
* Build a new info record based on the name, and add it to the summary.
*
- * Returns: the newly added record
+ * Returns: (transfer none): the newly added record
**/
CamelStoreInfo *
camel_store_summary_add_from_path (CamelStoreSummary *summary,
@@ -631,7 +634,7 @@ camel_store_summary_add_from_path (CamelStoreSummary *summary,
g_rec_mutex_lock (&summary->priv->summary_lock);
- info = g_hash_table_lookup (summary->folders_path, path);
+ info = g_hash_table_lookup (summary->priv->folders_path, path);
if (info != NULL) {
g_warning ("Trying to add folder '%s' to summary that already has it", path);
info = NULL;
@@ -643,8 +646,8 @@ camel_store_summary_add_from_path (CamelStoreSummary *summary,
info = class->store_info_new (summary, path);
- g_ptr_array_add (summary->folders, info);
- g_hash_table_insert (summary->folders_path, (gchar *) camel_store_info_path (summary, info),
info);
+ g_ptr_array_add (summary->priv->folders, info);
+ g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_path (summary,
info), info);
summary->priv->dirty = TRUE;
}
@@ -654,13 +657,13 @@ camel_store_summary_add_from_path (CamelStoreSummary *summary,
}
/**
- * camel_store_summary_info_ref:
+ * camel_store_summary_info_ref: (skip)
* @summary: a #CamelStoreSummary object
* @info: a #CamelStoreInfo
*
* Add an extra reference to @info.
*
- * Returns: the @info argument
+ * Returns: (transfer full): the @info argument
**/
CamelStoreInfo *
camel_store_summary_info_ref (CamelStoreSummary *summary,
@@ -731,8 +734,8 @@ camel_store_summary_remove (CamelStoreSummary *summary,
g_return_if_fail (info != NULL);
g_rec_mutex_lock (&summary->priv->summary_lock);
- g_hash_table_remove (summary->folders_path, camel_store_info_path (summary, info));
- g_ptr_array_remove (summary->folders, info);
+ g_hash_table_remove (summary->priv->folders_path, camel_store_info_path (summary, info));
+ g_ptr_array_remove (summary->priv->folders, info);
summary->priv->dirty = TRUE;
g_rec_mutex_unlock (&summary->priv->summary_lock);
@@ -757,7 +760,7 @@ camel_store_summary_remove_path (CamelStoreSummary *summary,
g_return_if_fail (path != NULL);
g_rec_mutex_lock (&summary->priv->summary_lock);
- if (g_hash_table_lookup_extended (summary->folders_path, path, (gpointer) &oldpath, (gpointer)
&oldinfo)) {
+ if (g_hash_table_lookup_extended (summary->priv->folders_path, path, (gpointer) &oldpath, (gpointer)
&oldinfo)) {
/* make sure it doesn't vanish while we're removing it */
camel_store_summary_info_ref (summary, oldinfo);
g_rec_mutex_unlock (&summary->priv->summary_lock);
@@ -769,7 +772,7 @@ camel_store_summary_remove_path (CamelStoreSummary *summary,
}
/**
- * camel_store_summary_info_new:
+ * camel_store_summary_info_new: (skip)
* @summary: a #CamelStoreSummary object
*
* Allocate a new #CamelStoreInfo, suitable for adding to this
@@ -868,6 +871,27 @@ camel_store_info_name (CamelStoreSummary *summary,
return (cp != NULL) ? cp + 1 : info->path;
}
+/**
+ * camel_store_summary_sort:
+ * @summary: a #CamelStoreSummary
+ * @compare_func: (scope call) (closure user_data): a compare function
+ * @user_data: user data passed to the @compare_func
+ *
+ * Sorts the array of the folders using the @compare_func.
+ *
+ * Since: 3.24
+ **/
+void
+camel_store_summary_sort (CamelStoreSummary *summary,
+ GCompareDataFunc compare_func,
+ gpointer user_data)
+{
+ g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
+ g_return_if_fail (compare_func != NULL);
+
+ g_ptr_array_sort_with_data (summary->priv->folders, compare_func, user_data);
+}
+
static gboolean
store_summary_save_timeout (gpointer user_data)
{
diff --git a/src/camel/camel-store-summary.h b/src/camel/camel-store-summary.h
index 68e1557..247439e 100644
--- a/src/camel/camel-store-summary.h
+++ b/src/camel/camel-store-summary.h
@@ -76,9 +76,6 @@ struct _CamelStoreInfo {
struct _CamelStoreSummary {
GObject parent;
CamelStoreSummaryPrivate *priv;
-
- GPtrArray *folders; /* CamelStoreInfo's */
- GHashTable *folders_path; /* CamelStoreInfo's by path name */
};
struct _CamelStoreSummaryClass {
@@ -112,6 +109,9 @@ struct _CamelStoreSummaryClass {
CamelStoreInfo *info,
gint type,
const gchar *value);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_store_summary_get_type (void) G_GNUC_CONST;
@@ -171,14 +171,17 @@ const gchar * camel_store_info_path (CamelStoreSummary *summary,
CamelStoreInfo *info);
const gchar * camel_store_info_name (CamelStoreSummary *summary,
CamelStoreInfo *info);
+void camel_store_summary_sort (CamelStoreSummary *summary,
+ GCompareDataFunc compare_func,
+ gpointer user_data);
gboolean camel_store_summary_connect_folder_summary
(CamelStoreSummary *summary,
const gchar *path,
- struct _CamelFolderSummary *folder_summary);
+ CamelFolderSummary *folder_summary);
gboolean camel_store_summary_disconnect_folder_summary
(CamelStoreSummary *summary,
- struct _CamelFolderSummary *folder_summary);
+ CamelFolderSummary *folder_summary);
G_END_DECLS
diff --git a/src/camel/camel-store.c b/src/camel/camel-store.c
index 4d4f112..98e470a 100644
--- a/src/camel/camel-store.c
+++ b/src/camel/camel-store.c
@@ -51,6 +51,11 @@ typedef struct _AsyncContext AsyncContext;
typedef struct _SignalClosure SignalClosure;
struct _CamelStorePrivate {
+ CamelDB *cdb;
+ CamelObjectBag *folders;
+ guint32 flags; /* bit-or of CamelStoreFlags */
+ guint32 permissions; /* bit-or of CamelStorePermissionFlags */
+
GMutex signal_emission_lock;
gboolean folder_info_stale_scheduled;
volatile gint maintenance_lock;
@@ -238,45 +243,6 @@ ignore_no_such_table_exception (GError **error)
g_clear_error (error);
}
-/* deletes folder/removes it from the folder cache, if it's there */
-static void
-cs_delete_cached_folder (CamelStore *store,
- const gchar *folder_name)
-{
- CamelFolder *folder;
- CamelVeeFolder *vfolder;
-
- if (store->folders == NULL)
- return;
-
- folder = camel_object_bag_get (store->folders, folder_name);
- if (folder == NULL)
- return;
-
- if (store->flags & CAMEL_STORE_VTRASH) {
- vfolder = camel_object_bag_get (
- store->folders, CAMEL_VTRASH_NAME);
- if (vfolder != NULL) {
- camel_vee_folder_remove_folder (vfolder, folder, NULL);
- g_object_unref (vfolder);
- }
- }
-
- if (store->flags & CAMEL_STORE_VJUNK) {
- vfolder = camel_object_bag_get (
- store->folders, CAMEL_VJUNK_NAME);
- if (vfolder != NULL) {
- camel_vee_folder_remove_folder (vfolder, folder, NULL);
- g_object_unref (vfolder);
- }
- }
-
- camel_folder_delete (folder);
-
- camel_object_bag_remove (store->folders, folder);
- g_object_unref (folder);
-}
-
static CamelFolder *
store_get_special (CamelStore *store,
CamelVTrashFolderType type)
@@ -286,7 +252,7 @@ store_get_special (CamelStore *store,
gint i;
folder = camel_vtrash_folder_new (store, type);
- folders = camel_object_bag_list (store->folders);
+ folders = camel_object_bag_list (store->priv->folders);
for (i = 0; i < folders->len; i++) {
if (!CAMEL_IS_VTRASH_FOLDER (folders->pdata[i]))
camel_vee_folder_add_folder ((CamelVeeFolder *) folder, (CamelFolder *)
folders->pdata[i], NULL);
@@ -345,14 +311,10 @@ store_finalize (GObject *object)
{
CamelStore *store = CAMEL_STORE (object);
- if (store->folders != NULL)
- camel_object_bag_destroy (store->folders);
+ if (store->priv->folders != NULL)
+ camel_object_bag_destroy (store->priv->folders);
- if (store->cdb_r != NULL) {
- camel_db_close (store->cdb_r);
- store->cdb_r = NULL;
- store->cdb_w = NULL;
- }
+ g_clear_object (&store->priv->cdb);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_store_parent_class)->finalize (object);
@@ -373,7 +335,7 @@ store_constructed (GObject *object)
g_return_if_fail (class->hash_folder_name != NULL);
g_return_if_fail (class->equal_folder_name != NULL);
- store->folders = camel_object_bag_new (
+ store->priv->folders = camel_object_bag_new (
class->hash_folder_name,
class->equal_folder_name,
(CamelCopyFunc) g_strdup, g_free);
@@ -480,7 +442,7 @@ store_synchronize_sync (CamelStore *store,
camel_folder_info_free (root);
} else {
/* sync only folders opened until now */
- folders = camel_object_bag_list (store->folders);
+ folders = camel_object_bag_list (store->priv->folders);
}
/* We don't sync any vFolders, that is used to update certain
@@ -489,8 +451,8 @@ store_synchronize_sync (CamelStore *store,
for (ii = 0; ii < folders->len; ii++) {
CamelFolder *folder = folders->pdata[ii];
- if (folder->summary)
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ if (camel_folder_get_folder_summary (folder))
+ camel_folder_summary_save (camel_folder_get_folder_summary (folder), NULL);
if (!CAMEL_IS_VEE_FOLDER (folder) && local_error == NULL) {
camel_folder_synchronize_sync (
@@ -544,7 +506,7 @@ store_initable_init (GInitable *initable,
return FALSE;
service = CAMEL_SERVICE (initable);
- if ((store->flags & CAMEL_STORE_USE_CACHE_DIR) != 0)
+ if ((store->priv->flags & CAMEL_STORE_USE_CACHE_DIR) != 0)
user_dir = camel_service_get_user_cache_dir (service);
else
user_dir = camel_service_get_user_data_dir (service);
@@ -559,18 +521,15 @@ store_initable_init (GInitable *initable,
/* This is for reading from the store */
filename = g_build_filename (user_dir, CAMEL_DB_FILE, NULL);
- store->cdb_r = camel_db_open (filename, error);
+ store->priv->cdb = camel_db_new (filename, error);
g_free (filename);
- if (store->cdb_r == NULL)
+ if (store->priv->cdb == NULL)
return FALSE;
- if (camel_db_create_folders_table (store->cdb_r, error))
+ if (camel_db_create_folders_table (store->priv->cdb, error))
return FALSE;
- /* keep cb_w to not break the ABI */
- store->cdb_w = store->cdb_r;
-
return TRUE;
}
@@ -606,7 +565,7 @@ camel_store_class_init (CamelStoreClass *class)
G_STRUCT_OFFSET (CamelStoreClass, folder_created),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+ CAMEL_TYPE_FOLDER_INFO);
signals[FOLDER_DELETED] = g_signal_new (
"folder-deleted",
@@ -615,7 +574,7 @@ camel_store_class_init (CamelStoreClass *class)
G_STRUCT_OFFSET (CamelStoreClass, folder_deleted),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+ CAMEL_TYPE_FOLDER_INFO);
/**
* CamelStore::folder-info-stale:
@@ -660,7 +619,7 @@ camel_store_class_init (CamelStoreClass *class)
NULL, NULL, NULL,
G_TYPE_NONE, 2,
G_TYPE_STRING,
- G_TYPE_POINTER);
+ CAMEL_TYPE_FOLDER_INFO);
}
static void
@@ -682,18 +641,146 @@ camel_store_init (CamelStore *store)
* - Include a virtual Trash folder.
* - Allow creating/deleting/renaming folders.
*/
- store->flags =
+ store->priv->flags =
CAMEL_STORE_VJUNK |
CAMEL_STORE_VTRASH |
CAMEL_STORE_CAN_EDIT_FOLDERS;
- store->mode = CAMEL_STORE_READ | CAMEL_STORE_WRITE;
+ store->priv->permissions = CAMEL_STORE_READ | CAMEL_STORE_WRITE;
store->priv->maintenance_lock = 0;
}
G_DEFINE_QUARK (camel-store-error-quark, camel_store_error)
/**
+ * camel_store_get_db:
+ * @store: a #CamelStore
+ *
+ * Returns: (transfer none): A #CamelDB instance associated with this @store.
+ *
+ * Since: 3.24
+ **/
+CamelDB *
+camel_store_get_db (CamelStore *store)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ return store->priv->cdb;
+}
+
+/**
+ * camel_store_get_folders_bag:
+ * @store: a #CamelStore
+ *
+ * Returns: (transfer none): a #CamelObjectBag of opened #CamelFolder<!-- -->s
+ *
+ * Since: 3.24
+ **/
+CamelObjectBag *
+camel_store_get_folders_bag (CamelStore *store)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ return store->priv->folders;
+}
+
+/**
+ * camel_store_dup_opened_folders:
+ * @store: a #CamelStore
+ *
+ * Returns a #GPtrArray of all the opened folders for the @store. The caller owns
+ * both the array and the folder references, so to free the array use:
+ *
+ * <informalexample>
+ * <programlisting>
+ * g_ptr_array_foreach (array, (GFunc) g_object_unref, NULL);
+ * g_ptr_array_free (array, TRUE);
+ * </programlisting>
+ * </informalexample>
+ *
+ * Returns: (element-type CamelFolder) (transfer full): an array with all currently
+ * opened folders for the @store.
+ *
+ * Since: 3.24
+ **/
+GPtrArray *
+camel_store_dup_opened_folders (CamelStore *store)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+ g_return_val_if_fail (store->priv->folders != NULL, NULL);
+
+ return camel_object_bag_list (store->priv->folders);
+}
+
+/**
+ * camel_store_get_flags:
+ * @store: a #CamelStore
+ *
+ * Returns: bit-or of #CamelStoreFlags set for the @store
+ *
+ * Since: 3.24
+ **/
+guint32
+camel_store_get_flags (CamelStore *store)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (store), 0);
+
+ return store->priv->flags;
+}
+
+/**
+ * camel_store_set_flags:
+ * @store: a #CamelStore
+ * @flags: bit-or of #CamelStoreFlags
+ *
+ * Sets flags for the @store, a bit-or of #CamelStoreFlags.
+ *
+ * Since: 3.24
+ **/
+void
+camel_store_set_flags (CamelStore *store,
+ guint32 flags)
+{
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ store->priv->flags = flags;
+}
+
+/**
+ * camel_store_get_permissions:
+ * @store: a #CamelStore
+ *
+ * Returns: Permissions of the @store, a bit-or of #CamelStorePermissionFlags
+ *
+ * Since: 3.24
+ **/
+guint32
+camel_store_get_permissions (CamelStore *store)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (store), 0);
+
+ return store->priv->permissions;
+}
+
+/**
+ * camel_store_set_permissions:
+ * @store: a #CamelStore
+ * @permissions: permissions of the @store, a bit-or of #CamelStorePermissionFlags
+ *
+ * Sets permissions for the @store, a bit-or of #CamelStorePermissionFlags
+ *
+ * Since: 3.24
+ **/
+void
+camel_store_set_permissions (CamelStore *store,
+ guint32 permissions)
+{
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
+ store->priv->permissions = permissions;
+}
+
+/**
* camel_store_folder_created:
* @store: a #CamelStore
* @folder_info: information about the created folder
@@ -1243,7 +1330,7 @@ camel_store_get_folder_sync (CamelStore *store,
try_again:
/* Try cache first. */
- folder = camel_object_bag_reserve (store->folders, folder_name);
+ folder = camel_object_bag_reserve (store->priv->folders, folder_name);
if (folder != NULL) {
if ((flags & CAMEL_STORE_FOLDER_INFO_REFRESH) != 0)
camel_folder_prepare_content_refresh (folder);
@@ -1252,9 +1339,9 @@ try_again:
}
store_uses_vjunk =
- ((store->flags & CAMEL_STORE_VJUNK) != 0);
+ ((store->priv->flags & CAMEL_STORE_VJUNK) != 0);
store_uses_vtrash =
- ((store->flags & CAMEL_STORE_VTRASH) != 0);
+ ((store->priv->flags & CAMEL_STORE_VTRASH) != 0);
folder_name_is_vjunk =
store_uses_vjunk &&
(strcmp (folder_name, CAMEL_VJUNK_NAME) == 0);
@@ -1264,16 +1351,16 @@ try_again:
if (flags & CAMEL_STORE_IS_MIGRATING) {
if (folder_name_is_vtrash) {
- if (store->folders != NULL)
+ if (store->priv->folders != NULL)
camel_object_bag_abort (
- store->folders, folder_name);
+ store->priv->folders, folder_name);
return NULL;
}
if (folder_name_is_vjunk) {
- if (store->folders != NULL)
+ if (store->priv->folders != NULL)
camel_object_bag_abort (
- store->folders, folder_name);
+ store->priv->folders, folder_name);
return NULL;
}
}
@@ -1324,11 +1411,11 @@ try_again:
if (folder != NULL && store_uses_vjunk)
vjunk = camel_object_bag_get (
- store->folders, CAMEL_VJUNK_NAME);
+ store->priv->folders, CAMEL_VJUNK_NAME);
if (folder != NULL && store_uses_vtrash)
vtrash = camel_object_bag_get (
- store->folders, CAMEL_VTRASH_NAME);
+ store->priv->folders, CAMEL_VTRASH_NAME);
}
/* Release the folder name reservation before adding the
@@ -1336,10 +1423,10 @@ try_again:
* reduce the chance of deadlock. */
if (folder != NULL)
camel_object_bag_add (
- store->folders, folder_name, folder);
+ store->priv->folders, folder_name, folder);
else
camel_object_bag_abort (
- store->folders, folder_name);
+ store->priv->folders, folder_name);
/* If this is a normal folder and the store uses a
* virtual Junk folder, let the virtual Junk folder
@@ -1591,8 +1678,8 @@ camel_store_get_folder_info_sync (CamelStore *store,
/* For readability. */
allow_virtual = ((flags & CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL) == 0);
start_at_root = (top == NULL || *top == '\0');
- store_has_vtrash = ((store->flags & CAMEL_STORE_VTRASH) != 0);
- store_has_vjunk = ((store->flags & CAMEL_STORE_VJUNK) != 0);
+ store_has_vtrash = ((store->priv->flags & CAMEL_STORE_VTRASH) != 0);
+ store_has_vjunk = ((store->priv->flags & CAMEL_STORE_VJUNK) != 0);
if (info != NULL && start_at_root && allow_virtual) {
if (store_has_vtrash) {
@@ -1947,7 +2034,7 @@ camel_store_get_junk_folder_sync (CamelStore *store,
{
g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
- if ((store->flags & CAMEL_STORE_VJUNK) == 0) {
+ if ((store->priv->flags & CAMEL_STORE_VJUNK) == 0) {
CamelStoreClass *class;
CamelFolder *folder;
@@ -2073,7 +2160,7 @@ camel_store_get_trash_folder_sync (CamelStore *store,
{
g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
- if ((store->flags & CAMEL_STORE_VTRASH) == 0) {
+ if ((store->priv->flags & CAMEL_STORE_VTRASH) == 0) {
CamelStoreClass *class;
CamelFolder *folder;
@@ -2255,9 +2342,9 @@ store_create_folder_thread (GTask *task,
gboolean reserved_vfolder_name;
reserved_vfolder_name =
- ((store->flags & CAMEL_STORE_VJUNK) &&
+ ((store->priv->flags & CAMEL_STORE_VJUNK) &&
g_str_equal (folder_name, CAMEL_VJUNK_NAME)) ||
- ((store->flags & CAMEL_STORE_VTRASH) &&
+ ((store->priv->flags & CAMEL_STORE_VTRASH) &&
g_str_equal (folder_name, CAMEL_VTRASH_NAME));
if (reserved_vfolder_name) {
@@ -2439,9 +2526,9 @@ store_delete_folder_thread (GTask *task,
g_return_if_fail (class->delete_folder_sync != NULL);
reserved_vfolder_name =
- ((store->flags & CAMEL_STORE_VJUNK) &&
+ ((store->priv->flags & CAMEL_STORE_VJUNK) &&
g_str_equal (folder_name, CAMEL_VJUNK_NAME)) ||
- ((store->flags & CAMEL_STORE_VTRASH) &&
+ ((store->priv->flags & CAMEL_STORE_VTRASH) &&
g_str_equal (folder_name, CAMEL_VTRASH_NAME));
if (reserved_vfolder_name) {
@@ -2466,7 +2553,7 @@ store_delete_folder_thread (GTask *task,
if (local_error != NULL) {
g_task_return_error (task, local_error);
} else {
- cs_delete_cached_folder (store, folder_name);
+ camel_store_delete_cached_folder (store, folder_name);
g_task_return_boolean (task, success);
}
}
@@ -2629,9 +2716,9 @@ store_rename_folder_thread (GTask *task,
}
reserved_vfolder_name =
- ((store->flags & CAMEL_STORE_VJUNK) &&
+ ((store->priv->flags & CAMEL_STORE_VJUNK) &&
g_str_equal (old_name, CAMEL_VJUNK_NAME)) ||
- ((store->flags & CAMEL_STORE_VTRASH) &&
+ ((store->priv->flags & CAMEL_STORE_VTRASH) &&
g_str_equal (old_name, CAMEL_VTRASH_NAME));
if (reserved_vfolder_name) {
@@ -2648,7 +2735,7 @@ store_rename_folder_thread (GTask *task,
/* If the folder is open (or any subfolders of the open folder)
* We need to rename them atomically with renaming the actual
* folder path. */
- folders = camel_object_bag_list (store->folders);
+ folders = camel_object_bag_list (store->priv->folders);
for (ii = 0; ii < folders->len; ii++) {
const gchar *full_name;
gsize full_name_len;
@@ -2691,7 +2778,7 @@ store_rename_folder_thread (GTask *task,
full_name = camel_folder_get_full_name (folder);
new = g_strdup_printf ("%s%s", new_name, full_name + strlen (old_name));
- camel_object_bag_rekey (store->folders, folder, new);
+ camel_object_bag_rekey (store->priv->folders, folder, new);
camel_folder_rename (folder, new);
g_free (new);
@@ -3134,8 +3221,60 @@ camel_store_maybe_run_db_maintenance (CamelStore *store,
if (g_atomic_int_get (&store->priv->maintenance_lock) > 0)
return TRUE;
- if (!store->cdb_w)
+ if (!store->priv->cdb)
return TRUE;
- return camel_db_maybe_run_maintenance (store->cdb_w, error);
+ return camel_db_maybe_run_maintenance (store->priv->cdb, error);
+}
+
+/**
+ * camel_store_delete_cached_folder:
+ * @store: a #CamelStore
+ * @folder_name: a folder full name to delete from the cache
+ *
+ * Deletes local data for the given @folder_name. The folder should
+ * be part of the opened folders.
+ *
+ * It doesn't delete the folder in the store (server) as such.
+ * Use camel_store_delete_folder(), or its synchronous variant,
+ * if you want to do that instead.
+ *
+ * Since: 3.24
+ **/
+void
+camel_store_delete_cached_folder (CamelStore *store,
+ const gchar *folder_name)
+{
+ CamelFolder *folder;
+ CamelVeeFolder *vfolder;
+
+ if (store->priv->folders == NULL)
+ return;
+
+ folder = camel_object_bag_get (store->priv->folders, folder_name);
+ if (folder == NULL)
+ return;
+
+ if (store->priv->flags & CAMEL_STORE_VTRASH) {
+ vfolder = camel_object_bag_get (
+ store->priv->folders, CAMEL_VTRASH_NAME);
+ if (vfolder != NULL) {
+ camel_vee_folder_remove_folder (vfolder, folder, NULL);
+ g_object_unref (vfolder);
+ }
+ }
+
+ if (store->priv->flags & CAMEL_STORE_VJUNK) {
+ vfolder = camel_object_bag_get (
+ store->priv->folders, CAMEL_VJUNK_NAME);
+ if (vfolder != NULL) {
+ camel_vee_folder_remove_folder (vfolder, folder, NULL);
+ g_object_unref (vfolder);
+ }
+ }
+
+ camel_folder_delete (folder);
+
+ camel_object_bag_remove (store->priv->folders, folder);
+ g_object_unref (folder);
}
diff --git a/src/camel/camel-store.h b/src/camel/camel-store.h
index 19d930e..5c0c88b 100644
--- a/src/camel/camel-store.h
+++ b/src/camel/camel-store.h
@@ -27,9 +27,7 @@
#ifndef CAMEL_STORE_H
#define CAMEL_STORE_H
-/* for mode_t */
-#include <sys/types.h>
-
+#include <camel/camel-db.h>
#include <camel/camel-enums.h>
#include <camel/camel-folder.h>
#include <camel/camel-service.h>
@@ -53,6 +51,14 @@
(G_TYPE_INSTANCE_GET_CLASS \
((obj), CAMEL_TYPE_STORE, CamelStoreClass))
+#define CAMEL_TYPE_FOLDER_INFO \
+ (camel_folder_info_get_type ())
+#define CAMEL_FOLDER_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_FOLDER_INFO, CamelFolderInfo))
+#define CAMEL_IS_FOLDER_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_FOLDER_INFO))
/**
* CAMEL_STORE_ERROR:
*
@@ -113,8 +119,6 @@ typedef struct _CamelFolderInfo {
gint32 total;
} CamelFolderInfo;
-struct _CamelDB;
-
typedef struct _CamelStore CamelStore;
typedef struct _CamelStoreClass CamelStoreClass;
typedef struct _CamelStorePrivate CamelStorePrivate;
@@ -133,21 +137,6 @@ typedef enum {
struct _CamelStore {
CamelService parent;
CamelStorePrivate *priv;
-
- CamelObjectBag *folders;
- struct _CamelDB *cdb_r;
- struct _CamelDB *cdb_w;
-
- CamelStoreFlags flags;
-
- /* XXX The default "mode" (read/write) is changed only by
- * evolution-groupwise for non-writable proxy accounts.
- * The mode is only checked by the account combo box in
- * Evolution's composer window. */
- CamelStorePermissionFlags mode;
-
- /* Future ABI expansion */
- gpointer later[4];
};
struct _CamelStoreClass {
@@ -208,8 +197,8 @@ struct _CamelStoreClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots for methods. */
- gpointer reserved_for_methods[20];
+ /* Padding for future expansion */
+ gpointer reserved_methods[20];
/* Signals */
void (*folder_created) (CamelStore *store,
@@ -222,10 +211,22 @@ struct _CamelStoreClass {
const gchar *old_name,
CamelFolderInfo *folder_info);
void (*folder_info_stale) (CamelStore *store);
+
+ /* Padding for future expansion */
+ gpointer reserved_signals[20];
};
GType camel_store_get_type (void);
GQuark camel_store_error_quark (void) G_GNUC_CONST;
+CamelDB * camel_store_get_db (CamelStore *store);
+CamelObjectBag *camel_store_get_folders_bag (CamelStore *store);
+GPtrArray * camel_store_dup_opened_folders (CamelStore *store);
+guint32 camel_store_get_flags (CamelStore *store);
+void camel_store_set_flags (CamelStore *store,
+ guint32 flags);
+guint32 camel_store_get_permissions (CamelStore *store);
+void camel_store_set_permissions (CamelStore *store,
+ guint32 permissions);
void camel_store_folder_created (CamelStore *store,
CamelFolderInfo *folder_info);
void camel_store_folder_deleted (CamelStore *store,
@@ -404,6 +405,9 @@ gboolean camel_store_initial_setup_finish
gboolean camel_store_maybe_run_db_maintenance
(CamelStore *store,
GError **error);
+void camel_store_delete_cached_folder
+ (CamelStore *store,
+ const gchar *folder_name);
G_END_DECLS
diff --git a/src/camel/camel-stream-buffer.c b/src/camel/camel-stream-buffer.c
index 7ad8c62..c490b52 100644
--- a/src/camel/camel-stream-buffer.c
+++ b/src/camel/camel-stream-buffer.c
@@ -400,7 +400,7 @@ camel_stream_buffer_new (CamelStream *stream,
/**
* camel_stream_buffer_gets:
* @sbf: a #CamelStreamBuffer object
- * @buf: (out) (array): Memory to write the string to.
+ * @buf: (array length=max) (type gchar): Memory to write the string to.
* @max: Maxmimum number of characters to store.
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
diff --git a/src/camel/camel-stream-buffer.h b/src/camel/camel-stream-buffer.h
index d7a014b..ef92cfd 100644
--- a/src/camel/camel-stream-buffer.h
+++ b/src/camel/camel-stream-buffer.h
@@ -77,6 +77,9 @@ struct _CamelStreamBufferClass {
CamelStreamBufferMode mode,
gchar *buf,
guint32 size);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_stream_buffer_get_type (void);
diff --git a/src/camel/camel-stream-filter.h b/src/camel/camel-stream-filter.h
index 853ae17..c954a8d 100644
--- a/src/camel/camel-stream-filter.h
+++ b/src/camel/camel-stream-filter.h
@@ -59,6 +59,9 @@ struct _CamelStreamFilter {
struct _CamelStreamFilterClass {
CamelStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_stream_filter_get_type (void);
diff --git a/src/camel/camel-stream-fs.c b/src/camel/camel-stream-fs.c
index 78045df..beceb3d 100644
--- a/src/camel/camel-stream-fs.c
+++ b/src/camel/camel-stream-fs.c
@@ -39,6 +39,7 @@
((obj), CAMEL_TYPE_STREAM_FS, CamelStreamFsPrivate))
struct _CamelStreamFsPrivate {
+ gboolean eos;
gint fd; /* file descriptor on the underlying file */
};
@@ -78,7 +79,7 @@ stream_fs_read (CamelStream *stream,
nread = camel_read (priv->fd, buffer, n, cancellable, error);
if (nread == 0)
- stream->eos = TRUE;
+ priv->eos = TRUE;
return nread;
}
@@ -145,6 +146,14 @@ stream_fs_close (CamelStream *stream,
return 0;
}
+static gboolean
+stream_fs_eos (CamelStream *stream)
+{
+ CamelStreamFs *fs = CAMEL_STREAM_FS (stream);
+
+ return fs->priv->eos;
+}
+
static goffset
stream_fs_tell (GSeekable *seekable)
{
@@ -201,7 +210,7 @@ stream_fs_seek (GSeekable *seekable,
return FALSE;
}
- CAMEL_STREAM (seekable)->eos = FALSE;
+ priv->eos = FALSE;
return TRUE;
}
@@ -242,6 +251,7 @@ camel_stream_fs_class_init (CamelStreamFsClass *class)
stream_class->write = stream_fs_write;
stream_class->flush = stream_fs_flush;
stream_class->close = stream_fs_close;
+ stream_class->eos = stream_fs_eos;
}
static void
@@ -259,6 +269,7 @@ camel_stream_fs_init (CamelStreamFs *stream)
{
stream->priv = CAMEL_STREAM_FS_GET_PRIVATE (stream);
stream->priv->fd = -1;
+ stream->priv->eos = FALSE;
}
/**
@@ -292,7 +303,7 @@ camel_stream_fs_new_with_fd (gint fd)
* camel_stream_fs_new_with_name:
* @name: a local filename
* @flags: flags as in open(2)
- * @mode: a file mode
+ * @mode: (type guint32): a file mode
* @error: return location for a #GError, or %NULL
*
* Creates a new #CamelStreamFs corresponding to the named file, flags,
diff --git a/src/camel/camel-stream-fs.h b/src/camel/camel-stream-fs.h
index 31cfe8c..7c0547b 100644
--- a/src/camel/camel-stream-fs.h
+++ b/src/camel/camel-stream-fs.h
@@ -64,6 +64,9 @@ struct _CamelStreamFs {
struct _CamelStreamFsClass {
CamelStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_stream_fs_get_type (void);
diff --git a/src/camel/camel-stream-mem.h b/src/camel/camel-stream-mem.h
index 385ce86..02fcbd4 100644
--- a/src/camel/camel-stream-mem.h
+++ b/src/camel/camel-stream-mem.h
@@ -61,6 +61,9 @@ struct _CamelStreamMem {
struct _CamelStreamMemClass {
CamelStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_stream_mem_get_type (void);
diff --git a/src/camel/camel-stream-null.c b/src/camel/camel-stream-null.c
index db75989..72aa617 100644
--- a/src/camel/camel-stream-null.c
+++ b/src/camel/camel-stream-null.c
@@ -24,6 +24,10 @@
#include "camel-stream-null.h"
+struct _CamelStreamNullPrivate {
+ gsize written;
+};
+
static void camel_stream_null_seekable_init (GSeekableIface *iface);
G_DEFINE_TYPE_WITH_CODE (CamelStreamNull, camel_stream_null, CAMEL_TYPE_STREAM,
@@ -36,7 +40,7 @@ stream_null_write (CamelStream *stream,
GCancellable *cancellable,
GError **error)
{
- CAMEL_STREAM_NULL (stream)->written += n;
+ CAMEL_STREAM_NULL (stream)->priv->written += n;
return n;
}
@@ -73,7 +77,7 @@ stream_null_seek (GSeekable *seekable,
return FALSE;
}
- CAMEL_STREAM_NULL (seekable)->written = 0;
+ CAMEL_STREAM_NULL (seekable)->priv->written = 0;
return TRUE;
}
@@ -103,6 +107,8 @@ camel_stream_null_class_init (CamelStreamNullClass *class)
{
CamelStreamClass *stream_class;
+ g_type_class_add_private (class, sizeof (CamelStreamNullPrivate));
+
stream_class = CAMEL_STREAM_CLASS (class);
stream_class->write = stream_null_write;
stream_class->eos = stream_null_eos;
@@ -121,6 +127,7 @@ camel_stream_null_seekable_init (GSeekableIface *iface)
static void
camel_stream_null_init (CamelStreamNull *stream_null)
{
+ stream_null->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream_null, CAMEL_TYPE_STREAM_NULL,
CamelStreamNullPrivate);
}
/**
@@ -129,10 +136,27 @@ camel_stream_null_init (CamelStreamNull *stream_null)
* Returns a null stream. A null stream is always at eof, and
* always returns success for all reads and writes.
*
- * Returns: a new #CamelStreamNull
+ * Returns: (transfer full): a new #CamelStreamNull
**/
CamelStream *
camel_stream_null_new (void)
{
return g_object_new (CAMEL_TYPE_STREAM_NULL, NULL);
}
+
+/**
+ * camel_stream_null_get_bytes_written:
+ * @stream_null: a #CamelStreamNull
+ *
+ * Returns: how many bytes had been written to the @stream_null since
+ * it was created or rewind to the beginning.
+ *
+ * Since: 3.24
+ **/
+gsize
+camel_stream_null_get_bytes_written (CamelStreamNull *stream_null)
+{
+ g_return_val_if_fail (CAMEL_IS_STREAM_NULL (stream_null), -1);
+
+ return stream_null->priv->written;
+}
diff --git a/src/camel/camel-stream-null.h b/src/camel/camel-stream-null.h
index d0d96d5..51b3da5 100644
--- a/src/camel/camel-stream-null.h
+++ b/src/camel/camel-stream-null.h
@@ -49,20 +49,25 @@ G_BEGIN_DECLS
typedef struct _CamelStreamNull CamelStreamNull;
typedef struct _CamelStreamNullClass CamelStreamNullClass;
+typedef struct _CamelStreamNullPrivate CamelStreamNullPrivate;
struct _CamelStreamNull {
CamelStream parent;
-
- gsize written;
+ CamelStreamNullPrivate *priv;
};
struct _CamelStreamNullClass {
CamelStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_stream_null_get_type (void);
-CamelStream *camel_stream_null_new (void);
+CamelStream * camel_stream_null_new (void);
+gsize camel_stream_null_get_bytes_written
+ (CamelStreamNull *stream_null);
G_END_DECLS
diff --git a/src/camel/camel-stream-process.c b/src/camel/camel-stream-process.c
index c8ab3ac..1f6fa29 100644
--- a/src/camel/camel-stream-process.c
+++ b/src/camel/camel-stream-process.c
@@ -46,6 +46,11 @@
extern gint camel_verbose_debug;
+struct _CamelStreamProcessPrivate {
+ gint sockfd;
+ pid_t childpid;
+};
+
G_DEFINE_TYPE (CamelStreamProcess, camel_stream_process, CAMEL_TYPE_STREAM)
static void
@@ -67,7 +72,7 @@ stream_process_read (CamelStream *stream,
GError **error)
{
CamelStreamProcess *stream_process = CAMEL_STREAM_PROCESS (stream);
- gint fd = stream_process->sockfd;
+ gint fd = stream_process->priv->sockfd;
return camel_read (fd, buffer, n, cancellable, error);
}
@@ -80,7 +85,7 @@ stream_process_write (CamelStream *stream,
GError **error)
{
CamelStreamProcess *stream_process = CAMEL_STREAM_PROCESS (stream);
- gint fd = stream_process->sockfd;
+ gint fd = stream_process->priv->sockfd;
return camel_write (fd, buffer, n, cancellable, error);
}
@@ -96,23 +101,23 @@ stream_process_close (CamelStream *object,
fprintf (
stderr,
"Process stream close. sockfd %d, childpid %d\n",
- stream->sockfd, stream->childpid);
+ stream->priv->sockfd, stream->priv->childpid);
- if (stream->sockfd != -1) {
- close (stream->sockfd);
- stream->sockfd = -1;
+ if (stream->priv->sockfd != -1) {
+ close (stream->priv->sockfd);
+ stream->priv->sockfd = -1;
}
- if (stream->childpid) {
+ if (stream->priv->childpid) {
gint ret, i;
for (i = 0; i < 4; i++) {
- ret = waitpid (stream->childpid, NULL, WNOHANG);
+ ret = waitpid (stream->priv->childpid, NULL, WNOHANG);
if (camel_verbose_debug)
fprintf (
stderr,
"waitpid() for pid %d returned %d (errno %d)\n",
- stream->childpid, ret, ret == -1 ? errno : 0);
- if (ret == stream->childpid || errno == ECHILD)
+ stream->priv->childpid, ret, ret == -1 ? errno : 0);
+ if (ret == stream->priv->childpid || errno == ECHILD)
break;
switch (i) {
case 0:
@@ -120,16 +125,16 @@ stream_process_close (CamelStream *object,
fprintf (
stderr,
"Sending SIGTERM to pid %d\n",
- stream->childpid);
- kill (stream->childpid, SIGTERM);
+ stream->priv->childpid);
+ kill (stream->priv->childpid, SIGTERM);
break;
case 2:
if (camel_verbose_debug)
fprintf (
stderr,
"Sending SIGKILL to pid %d\n",
- stream->childpid);
- kill (stream->childpid, SIGKILL);
+ stream->priv->childpid);
+ kill (stream->priv->childpid, SIGKILL);
break;
case 1:
case 3:
@@ -138,7 +143,7 @@ stream_process_close (CamelStream *object,
}
}
- stream->childpid = 0;
+ stream->priv->childpid = 0;
}
return 0;
@@ -158,6 +163,8 @@ camel_stream_process_class_init (CamelStreamProcessClass *class)
GObjectClass *object_class;
CamelStreamClass *stream_class;
+ g_type_class_add_private (class, sizeof (CamelStreamProcessPrivate));
+
object_class = G_OBJECT_CLASS (class);
object_class->finalize = stream_process_finalize;
@@ -171,8 +178,9 @@ camel_stream_process_class_init (CamelStreamProcessClass *class)
static void
camel_stream_process_init (CamelStreamProcess *stream)
{
- stream->sockfd = -1;
- stream->childpid = 0;
+ stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, CAMEL_TYPE_STREAM_PROCESS,
CamelStreamProcessPrivate);
+ stream->priv->sockfd = -1;
+ stream->priv->childpid = 0;
}
/**
@@ -247,24 +255,24 @@ camel_stream_process_connect (CamelStreamProcess *stream,
g_return_val_if_fail (CAMEL_IS_STREAM_PROCESS (stream), -1);
g_return_val_if_fail (command != NULL, -1);
- if (stream->sockfd != -1 || stream->childpid)
+ if (stream->priv->sockfd != -1 || stream->priv->childpid)
camel_stream_close (CAMEL_STREAM (stream), NULL, NULL);
if (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfds))
goto fail;
- stream->childpid = fork ();
- if (!stream->childpid) {
+ stream->priv->childpid = fork ();
+ if (!stream->priv->childpid) {
do_exec_command (sockfds[1], command, (gchar **) env);
- } else if (stream->childpid == -1) {
+ } else if (stream->priv->childpid == -1) {
close (sockfds[0]);
close (sockfds[1]);
- stream->sockfd = -1;
+ stream->priv->sockfd = -1;
goto fail;
}
close (sockfds[1]);
- stream->sockfd = sockfds[0];
+ stream->priv->sockfd = sockfds[0];
return 0;
diff --git a/src/camel/camel-stream-process.h b/src/camel/camel-stream-process.h
index 1c48645..b0de6fb 100644
--- a/src/camel/camel-stream-process.h
+++ b/src/camel/camel-stream-process.h
@@ -49,16 +49,18 @@ G_BEGIN_DECLS
typedef struct _CamelStreamProcess CamelStreamProcess;
typedef struct _CamelStreamProcessClass CamelStreamProcessClass;
+typedef struct _CamelStreamProcessPrivate CamelStreamProcessPrivate;
struct _CamelStreamProcess {
CamelStream parent;
-
- gint sockfd;
- pid_t childpid;
+ CamelStreamProcessPrivate *priv;
};
struct _CamelStreamProcessClass {
CamelStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_stream_process_get_type (void);
diff --git a/src/camel/camel-stream.c b/src/camel/camel-stream.c
index 3841819..5d43f02 100644
--- a/src/camel/camel-stream.c
+++ b/src/camel/camel-stream.c
@@ -33,6 +33,7 @@
struct _CamelStreamPrivate {
GIOStream *base_stream;
GMutex base_stream_lock;
+ gboolean eos;
};
enum {
@@ -135,7 +136,7 @@ stream_read (CamelStream *stream,
g_object_unref (base_stream);
}
- stream->eos = n_bytes_read <= 0;
+ stream->priv->eos = n_bytes_read <= 0;
return n_bytes_read;
}
@@ -157,7 +158,7 @@ stream_write (CamelStream *stream,
gsize n_written = 0;
output_stream = g_io_stream_get_output_stream (base_stream);
- stream->eos = FALSE;
+ stream->priv->eos = FALSE;
if (g_output_stream_write_all (output_stream, buffer, n, &n_written, cancellable, error))
n_bytes_written = (gssize) n_written;
@@ -219,7 +220,7 @@ stream_flush (CamelStream *stream,
static gboolean
stream_eos (CamelStream *stream)
{
- return stream->eos;
+ return stream->priv->eos;
}
static goffset
@@ -278,7 +279,7 @@ stream_seek (GSeekable *seekable,
base_stream = camel_stream_ref_base_stream (stream);
if (G_IS_SEEKABLE (base_stream)) {
- stream->eos = FALSE;
+ stream->priv->eos = FALSE;
success = g_seekable_seek (
G_SEEKABLE (base_stream),
offset, type, cancellable, error);
@@ -479,12 +480,12 @@ camel_stream_set_base_stream (CamelStream *stream,
/**
* camel_stream_read:
* @stream: a #CamelStream object.
- * @buffer: output buffer
+ * @buffer: (array length=n) (type gchar): output buffer
* @n: max number of bytes to read.
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
*
- * Attempts to read up to @len bytes from @stream into @buf.
+ * Attempts to read up to @n bytes from @stream into @buffer.
*
* Returns: the number of bytes actually read, or %-1 on error and set
* errno.
@@ -514,7 +515,7 @@ camel_stream_read (CamelStream *stream,
/**
* camel_stream_write:
* @stream: a #CamelStream object
- * @buffer: buffer to write.
+ * @buffer: (array length=n) (type gchar): buffer to write.
* @n: number of bytes to write
* @cancellable: optional #GCancellable object, or %NULL
* @error: return location for a #GError, or %NULL
diff --git a/src/camel/camel-stream.h b/src/camel/camel-stream.h
index 4e7571e..1bfdbeb 100644
--- a/src/camel/camel-stream.h
+++ b/src/camel/camel-stream.h
@@ -58,8 +58,6 @@ typedef struct _CamelStreamPrivate CamelStreamPrivate;
struct _CamelStream {
GObject parent;
CamelStreamPrivate *priv;
-
- gboolean eos;
};
struct _CamelStreamClass {
@@ -82,6 +80,9 @@ struct _CamelStreamClass {
GCancellable *cancellable,
GError **error);
gboolean (*eos) (CamelStream *stream);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_stream_get_type (void);
diff --git a/src/camel/camel-subscribable.c b/src/camel/camel-subscribable.c
index 3ec4f58..a8f3fa8 100644
--- a/src/camel/camel-subscribable.c
+++ b/src/camel/camel-subscribable.c
@@ -106,46 +106,6 @@ subscribable_emit_folder_unsubscribed_cb (gpointer user_data)
}
static void
-subscribable_delete_cached_folder (CamelStore *store,
- const gchar *folder_name)
-{
- CamelFolder *folder;
- CamelVeeFolder *vfolder;
-
- /* XXX Copied from camel-store.c. Should this be public? */
-
- if (store->folders == NULL)
- return;
-
- folder = camel_object_bag_get (store->folders, folder_name);
- if (folder == NULL)
- return;
-
- if (store->flags & CAMEL_STORE_VTRASH) {
- folder_name = CAMEL_VTRASH_NAME;
- vfolder = camel_object_bag_get (store->folders, folder_name);
- if (vfolder != NULL) {
- camel_vee_folder_remove_folder (vfolder, folder, NULL);
- g_object_unref (vfolder);
- }
- }
-
- if (store->flags & CAMEL_STORE_VJUNK) {
- folder_name = CAMEL_VJUNK_NAME;
- vfolder = camel_object_bag_get (store->folders, folder_name);
- if (vfolder != NULL) {
- camel_vee_folder_remove_folder (vfolder, folder, NULL);
- g_object_unref (vfolder);
- }
- }
-
- camel_folder_delete (folder);
-
- camel_object_bag_remove (store->folders, folder);
- g_object_unref (folder);
-}
-
-static void
camel_subscribable_default_init (CamelSubscribableInterface *iface)
{
signals[FOLDER_SUBSCRIBED] = g_signal_new (
@@ -157,7 +117,7 @@ camel_subscribable_default_init (CamelSubscribableInterface *iface)
folder_subscribed),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+ CAMEL_TYPE_FOLDER_INFO);
signals[FOLDER_UNSUBSCRIBED] = g_signal_new (
"folder-unsubscribed",
@@ -168,7 +128,7 @@ camel_subscribable_default_init (CamelSubscribableInterface *iface)
folder_unsubscribed),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
- G_TYPE_POINTER);
+ CAMEL_TYPE_FOLDER_INFO);
}
/**
@@ -449,8 +409,7 @@ subscribable_unsubscribe_folder_thread (GTask *task,
subscribable, unsubscribe_folder_sync, success, local_error);
if (success)
- subscribable_delete_cached_folder (
- CAMEL_STORE (subscribable), folder_name);
+ camel_store_delete_cached_folder (CAMEL_STORE (subscribable), folder_name);
camel_operation_pop_message (cancellable);
diff --git a/src/camel/camel-subscribable.h b/src/camel/camel-subscribable.h
index 6d53492..c0aafda 100644
--- a/src/camel/camel-subscribable.h
+++ b/src/camel/camel-subscribable.h
@@ -73,8 +73,8 @@ struct _CamelSubscribableInterface {
GCancellable *cancellable,
GError **error);
- /* Reserved slots for methods. */
- gpointer reserved_for_methods[4];
+ /* Padding for future expansion */
+ gpointer reserved_methods[20];
/* Signals */
void (*folder_subscribed)
@@ -83,6 +83,9 @@ struct _CamelSubscribableInterface {
void (*folder_unsubscribed)
(CamelSubscribable *subscribable,
CamelFolderInfo *folder_info);
+
+ /* Padding for future expansion */
+ gpointer reserved_signals[20];
};
GType camel_subscribable_get_type
diff --git a/src/camel/camel-text-index.c b/src/camel/camel-text-index.c
index 7807753..ba64718 100644
--- a/src/camel/camel-text-index.c
+++ b/src/camel/camel-text-index.c
@@ -234,7 +234,7 @@ text_index_add_name_to_word (CamelIndex *idx,
CamelTextIndexPrivate *p = CAMEL_TEXT_INDEX (idx)->priv;
camel_key_t wordid;
camel_block_t data;
- struct _CamelTextIndexRoot *rb = (struct _CamelTextIndexRoot *) p->blocks->root;
+ struct _CamelTextIndexRoot *rb = (struct _CamelTextIndexRoot *) camel_block_file_get_root (p->blocks);
w = g_hash_table_lookup (p->words, word);
if (w == NULL) {
@@ -259,7 +259,7 @@ text_index_add_name_to_word (CamelIndex *idx,
return;
}
rb->words++;
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block (p->blocks));
} else {
data = camel_key_table_lookup (p->word_index, wordid, NULL, NULL);
if (data == 0) {
@@ -290,7 +290,7 @@ text_index_add_name_to_word (CamelIndex *idx,
if (camel_key_file_write (p->links, &ww->data, ww->used, ww->names) != -1) {
io (printf (" new data [%x]\n", ww->data));
rb->keys++;
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block
(p->blocks));
/* if this call fails - we still point to the old data - not fatal */
camel_key_table_set_data (
p->word_index, ww->wordid, ww->data);
@@ -318,7 +318,7 @@ text_index_add_name_to_word (CamelIndex *idx,
io (printf ("writing key file entry '%s' [%x]\n", w->word, w->data));
if (camel_key_file_write (p->links, &w->data, w->used, w->names) != -1) {
rb->keys++;
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block
(p->blocks));
/* if this call fails - we still point to the old data - not fatal */
camel_key_table_set_data (
p->word_index, w->wordid, w->data);
@@ -344,14 +344,14 @@ text_index_sync (CamelIndex *idx)
|| p->name_index == NULL || p->name_hash == NULL)
return 0;
- rb = (struct _CamelTextIndexRoot *) p->blocks->root;
+ rb = (struct _CamelTextIndexRoot *) camel_block_file_get_root (p->blocks);
/* sync/flush word cache */
CAMEL_TEXT_INDEX_LOCK (idx, lock);
/* we sync, bump down the cache limits since we dont need them for reading */
- p->blocks->block_cache_limit = 128;
+ camel_block_file_set_cache_limit (p->blocks, 128);
/* this doesn't really need to be dropped, its only used in updates anyway */
p->word_cache_limit = 1024;
@@ -361,7 +361,7 @@ text_index_sync (CamelIndex *idx)
if (camel_key_file_write (p->links, &ww->data, ww->used, ww->names) != -1) {
io (printf (" new data [%x]\n", ww->data));
rb->keys++;
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block
(p->blocks));
camel_key_table_set_data (
p->word_index, ww->wordid, ww->data);
} else {
@@ -473,7 +473,7 @@ text_index_compress_nosync (CamelIndex *idx)
CAMEL_TEXT_INDEX_LOCK (idx, lock);
- rb = (struct _CamelTextIndexRoot *) newp->blocks->root;
+ rb = (struct _CamelTextIndexRoot *) camel_block_file_get_root (newp->blocks);
rb->words = 0;
rb->names = 0;
@@ -562,7 +562,7 @@ text_index_compress_nosync (CamelIndex *idx)
name = NULL;
}
- camel_block_file_touch_block (newp->blocks, newp->blocks->root_block);
+ camel_block_file_touch_block (newp->blocks, camel_block_file_get_root_block (newp->blocks));
if (camel_index_sync (CAMEL_INDEX (newidx)) == -1)
goto fail;
@@ -677,13 +677,13 @@ text_index_add_name (CamelIndex *idx,
CamelTextIndexPrivate *p = CAMEL_TEXT_INDEX_GET_PRIVATE (idx);
camel_key_t keyid;
CamelIndexName *idn;
- struct _CamelTextIndexRoot *rb = (struct _CamelTextIndexRoot *) p->blocks->root;
+ struct _CamelTextIndexRoot *rb = (struct _CamelTextIndexRoot *) camel_block_file_get_root (p->blocks);
CAMEL_TEXT_INDEX_LOCK (idx, lock);
/* if we're adding words, up the cache limits a lot */
if (p->word_cache_limit < 8192) {
- p->blocks->block_cache_limit = 1024;
+ camel_block_file_set_cache_limit (p->blocks, 1024);
p->word_cache_limit = 8192;
}
@@ -703,7 +703,7 @@ text_index_add_name (CamelIndex *idx,
rb->names++;
}
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block (p->blocks));
/* TODO: if keyid == 0, we had a failure, we should somehow flag that, but for
* now just return a valid object but discard its results, see text_index_write_name */
@@ -759,7 +759,7 @@ text_index_delete_name (CamelIndex *idx,
{
CamelTextIndexPrivate *p = CAMEL_TEXT_INDEX_GET_PRIVATE (idx);
camel_key_t keyid;
- struct _CamelTextIndexRoot *rb = (struct _CamelTextIndexRoot *) p->blocks->root;
+ struct _CamelTextIndexRoot *rb = (struct _CamelTextIndexRoot *) camel_block_file_get_root (p->blocks);
d (printf ("Delete name: %s\n", name));
@@ -770,7 +770,7 @@ text_index_delete_name (CamelIndex *idx,
keyid = camel_partition_table_lookup (p->name_hash, name);
if (keyid != 0) {
rb->deleted++;
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block (p->blocks));
camel_key_table_set_flags (p->name_index, keyid, 1, 1);
camel_partition_table_remove (p->name_hash, name);
}
@@ -896,7 +896,7 @@ camel_text_index_new (const gchar *path,
if (p->links == NULL)
goto fail;
- rb = (struct _CamelTextIndexRoot *) p->blocks->root;
+ rb = (struct _CamelTextIndexRoot *) camel_block_file_get_root (p->blocks);
if (rb->word_index_root == 0) {
bl = camel_block_file_new_block (p->blocks);
@@ -906,7 +906,7 @@ camel_text_index_new (const gchar *path,
rb->word_index_root = bl->id;
camel_block_file_unref_block (p->blocks, bl);
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block (p->blocks));
}
if (rb->word_hash_root == 0) {
@@ -917,7 +917,7 @@ camel_text_index_new (const gchar *path,
rb->word_hash_root = bl->id;
camel_block_file_unref_block (p->blocks, bl);
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block (p->blocks));
}
if (rb->name_index_root == 0) {
@@ -928,7 +928,7 @@ camel_text_index_new (const gchar *path,
rb->name_index_root = bl->id;
camel_block_file_unref_block (p->blocks, bl);
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block (p->blocks));
}
if (rb->name_hash_root == 0) {
@@ -939,7 +939,7 @@ camel_text_index_new (const gchar *path,
rb->name_hash_root = bl->id;
camel_block_file_unref_block (p->blocks, bl);
- camel_block_file_touch_block (p->blocks, p->blocks->root_block);
+ camel_block_file_touch_block (p->blocks, camel_block_file_get_root_block (p->blocks));
}
p->word_index = camel_key_table_new (p->blocks, rb->word_index_root);
@@ -1064,7 +1064,7 @@ void
camel_text_index_info (CamelTextIndex *idx)
{
CamelTextIndexPrivate *p = idx->priv;
- struct _CamelTextIndexRoot *rb = (struct _CamelTextIndexRoot *) p->blocks->root;
+ struct _CamelTextIndexRoot *rb = (struct _CamelTextIndexRoot *) camel_block_file_get_root (p->blocks);
gint frag;
printf ("Path: '%s'\n", idx->parent.path);
@@ -1918,16 +1918,16 @@ main (gint argc,
#if 0
bs = camel_block_file_new ("blocks", "TESTINDX", CAMEL_BLOCK_SIZE);
- root = (struct _CamelIndexRoot *) bs->root;
+ root = (struct _CamelIndexRoot *) camel_block_file_get_root (bs);
if (root->word_root == 0) {
keyroot = camel_block_file_new_block (bs);
root->word_root = keyroot->id;
- camel_block_file_touch_block (bs, bs->root_block);
+ camel_block_file_touch_block (bs, camel_block_file_get_root_block (bs));
}
if (root->word_hash_root == 0) {
partroot = camel_block_file_new_block (bs);
root->word_hash_root = partroot->id;
- camel_block_file_touch_block (bs, bs->root_block);
+ camel_block_file_touch_block (bs, camel_block_file_get_root_block (bs));
}
ki = camel_key_table_new (bs, root->word_root);
diff --git a/src/camel/camel-text-index.h b/src/camel/camel-text-index.h
index c4e2750..9162cc8 100644
--- a/src/camel/camel-text-index.h
+++ b/src/camel/camel-text-index.h
@@ -127,6 +127,9 @@ struct _CamelTextIndexCursor {
struct _CamelTextIndexCursorClass {
CamelIndexCursorClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_text_index_cursor_get_type (void);
@@ -140,6 +143,9 @@ struct _CamelTextIndexKeyCursor {
struct _CamelTextIndexKeyCursorClass {
CamelIndexCursorClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_text_index_key_cursor_get_type (void);
@@ -153,6 +159,9 @@ struct _CamelTextIndexName {
struct _CamelTextIndexNameClass {
CamelIndexNameClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_text_index_name_get_type (void);
@@ -166,6 +175,9 @@ struct _CamelTextIndex {
struct _CamelTextIndexClass {
CamelIndexClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_text_index_get_type (void);
diff --git a/src/camel/camel-transport.h b/src/camel/camel-transport.h
index df51094..92e845c 100644
--- a/src/camel/camel-transport.h
+++ b/src/camel/camel-transport.h
@@ -71,8 +71,8 @@ struct _CamelTransportClass {
GCancellable *cancellable,
GError **error);
- /* Reserved slots. */
- gpointer reserved[2];
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_transport_get_type (void);
diff --git a/src/camel/camel-trie.c b/src/camel/camel-trie.c
index 4d9ea9f..e2f4c33 100644
--- a/src/camel/camel-trie.c
+++ b/src/camel/camel-trie.c
@@ -101,7 +101,7 @@ trie_utf8_getc (const guchar **in,
}
/**
- * camel_trie_new:
+ * camel_trie_new: (skip)
* @icase: Case sensitivity for the #CamelTrie.
*
* Creates a new #CamelTrie. If @icase is %TRUE, then pattern matching
@@ -132,7 +132,7 @@ camel_trie_new (gboolean icase)
}
/**
- * camel_trie_free:
+ * camel_trie_free: (skip)
* @trie: The #CamelTrie to free.
*
* Frees the memory associated with the #CamelTrie @trie.
@@ -232,7 +232,7 @@ dump_trie (struct _trie_state *s,
*/
/**
- * camel_trie_add:
+ * camel_trie_add: (skip)
* @trie: The #CamelTrie to add a pattern to.
* @pattern: The pattern to add.
* @pattern_id: The id to use for the pattern.
@@ -329,15 +329,15 @@ camel_trie_add (CamelTrie *trie,
*/
/**
- * camel_trie_search:
+ * camel_trie_search: (skip)
* @trie: The #CamelTrie to search in.
- * @buffer: The string to match against a pattern in @trie.
+ * @buffer: (array length=buflen) (type gchar): The string to match against a pattern in @trie.
* @buflen: The length of @buffer.
- * @matched_id: An integer address to store the matched pattern id in.
+ * @matched_id: (out): An integer address to store the matched pattern id in.
*
* Try to match the string @buffer with a pattern in @trie.
*
- * Returns: The matched pattern, or %NULL if no pattern is matched.
+ * Returns: (nullable): The matched pattern, or %NULL if no pattern is matched.
*
* Since: 2.24
**/
diff --git a/src/camel/camel-uid-cache.c b/src/camel/camel-uid-cache.c
index e6fbc28..23237f5 100644
--- a/src/camel/camel-uid-cache.c
+++ b/src/camel/camel-uid-cache.c
@@ -38,7 +38,7 @@ struct _uid_state {
};
/**
- * camel_uid_cache_new:
+ * camel_uid_cache_new: (skip)
* @filename: path to load the cache from
*
* Creates a new UID cache, initialized from @filename. If @filename
diff --git a/src/camel/camel-url-scanner.c b/src/camel/camel-url-scanner.c
index c977e14..d86a9bc 100644
--- a/src/camel/camel-url-scanner.c
+++ b/src/camel/camel-url-scanner.c
@@ -32,6 +32,11 @@ struct _CamelUrlScanner {
CamelTrie *trie;
};
+/**
+ * camel_url_scanner_new: (skip)
+ *
+ * Returns: (transfer full): Creates a new #CamelUrlScanner
+ **/
CamelUrlScanner *
camel_url_scanner_new (void)
{
@@ -44,6 +49,12 @@ camel_url_scanner_new (void)
return scanner;
}
+/**
+ * camel_url_scanner_free: (skip)
+ * @scanner: a #CamelUrlScanner
+ *
+ * Frees the @scanner.
+ **/
void
camel_url_scanner_free (CamelUrlScanner *scanner)
{
@@ -54,6 +65,13 @@ camel_url_scanner_free (CamelUrlScanner *scanner)
g_free (scanner);
}
+/**
+ * camel_url_scanner_add: (skip)
+ * @scanner: a #CamelUrlScanner
+ * @pattern: a #CamelUrlPattern to add
+ *
+ * Adds a new @pattern into the scanner
+ **/
void
camel_url_scanner_add (CamelUrlScanner *scanner,
CamelUrlPattern *pattern)
@@ -64,6 +82,17 @@ camel_url_scanner_add (CamelUrlScanner *scanner,
g_ptr_array_add (scanner->patterns, pattern);
}
+/**
+ * camel_url_scanner_scan: (skip)
+ * @scanner: a #CamelUrlScanner object.
+ * @in: (array length=inlen) (type gchar): the url to scan.
+ * @inlen: length of the in array.
+ * @match: the #CamelUrlMatch structure containing the criterias.
+ *
+ * Scan the @in string with the @match criterias.
+ *
+ * Returns: %TRUE if there is a result.
+ **/
gboolean
camel_url_scanner_scan (CamelUrlScanner *scanner,
const gchar *in,
diff --git a/src/camel/camel-url.c b/src/camel/camel-url.c
index b51ed09..c089b15 100644
--- a/src/camel/camel-url.c
+++ b/src/camel/camel-url.c
@@ -703,10 +703,15 @@ camel_url_decode (gchar *part)
} while (*s++);
}
+/**
+ * camel_url_hash:
+ * @u: the base URL
+ *
+ * Returns: the url hash
+ */
guint
-camel_url_hash (gconstpointer v)
+camel_url_hash (const CamelURL *u)
{
- const CamelURL *u = v;
guint hash = 0;
#define ADD_HASH(s) if (s) hash ^= g_str_hash (s);
@@ -722,7 +727,7 @@ camel_url_hash (gconstpointer v)
return hash;
}
-static gint
+static gboolean
check_equal (gchar *s1,
gchar *s2)
{
@@ -739,19 +744,24 @@ check_equal (gchar *s1,
return strcmp (s1, s2) == 0;
}
-gint
-camel_url_equal (gconstpointer v,
- gconstpointer v2)
+/**
+ * camel_url_equal:
+ * @u: the base URL
+ * @u2: the URL to compare
+ *
+ * Returns: return %TRUE if the two urls are equal
+ */
+gboolean
+camel_url_equal (const CamelURL *u,
+ const CamelURL *u2)
{
- const CamelURL *u1 = v, *u2 = v2;
-
- return check_equal (u1->protocol, u2->protocol)
- && check_equal (u1->user, u2->user)
- && check_equal (u1->authmech, u2->authmech)
- && check_equal (u1->host, u2->host)
- && check_equal (u1->path, u2->path)
- && check_equal (u1->query, u2->query)
- && u1->port == u2->port;
+ return check_equal (u->protocol, u2->protocol)
+ && check_equal (u->user, u2->user)
+ && check_equal (u->authmech, u2->authmech)
+ && check_equal (u->host, u2->host)
+ && check_equal (u->path, u2->path)
+ && check_equal (u->query, u2->query)
+ && u->port == u2->port;
}
/**
@@ -760,7 +770,7 @@ camel_url_equal (gconstpointer v,
*
* Copy a #CamelURL.
*
- * Returns: a duplicate copy of @in
+ * Returns:(transfer full): a duplicate copy of @in
**/
CamelURL *
camel_url_copy (CamelURL *in)
diff --git a/src/camel/camel-url.h b/src/camel/camel-url.h
index db3a26e..951a52a 100644
--- a/src/camel/camel-url.h
+++ b/src/camel/camel-url.h
@@ -62,9 +62,9 @@ CamelURL * camel_url_new (const gchar *url_string,
GError **error);
gchar * camel_url_to_string (CamelURL *url,
CamelURLFlags flags);
-guint camel_url_hash (gconstpointer v);
-gint camel_url_equal (gconstpointer v,
- gconstpointer v2);
+guint camel_url_hash (const CamelURL *u);
+gboolean camel_url_equal (const CamelURL *u,
+ const CamelURL *u2);
CamelURL * camel_url_copy (CamelURL *in);
void camel_url_free (CamelURL *url);
diff --git a/src/camel/camel-utf8.c b/src/camel/camel-utf8.c
index b2c7420..d682b80 100644
--- a/src/camel/camel-utf8.c
+++ b/src/camel/camel-utf8.c
@@ -163,18 +163,6 @@ loop:
return 0xffff;
}
-void
-g_string_append_u (GString *out,
- guint32 c)
-{
- guchar buffer[8];
- guchar *p = buffer;
-
- camel_utf8_putc (&p, c);
- *p = 0;
- g_string_append (out, (const gchar *) buffer);
-}
-
static const gchar utf7_alphabet[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
@@ -251,11 +239,11 @@ camel_utf7_utf8 (const gchar *ptr)
i+=6;
if (i >= 16) {
x = (v >> (i - 16)) & 0xffff;
- g_string_append_u (out, x);
+ g_string_append_unichar (out, x);
i-=16;
}
} else {
- g_string_append_u (out, c);
+ g_string_append_unichar (out, c);
state = 0;
}
break;
@@ -379,7 +367,8 @@ camel_utf8_ucs2 (const gchar *pptr)
*
* Returns:
**/
-gchar *camel_ucs2_utf8 (const gchar *ptr)
+gchar *
+camel_ucs2_utf8 (const gchar *ptr)
{
guint16 *ucs = (guint16 *) ptr;
guint32 c;
@@ -387,7 +376,7 @@ gchar *camel_ucs2_utf8 (const gchar *ptr)
gchar *out;
while ((c = *ucs++))
- g_string_append_u (work, g_ntohs (c));
+ g_string_append_unichar (work, g_ntohs (c));
out = g_strdup (work->str);
g_string_free (work, TRUE);
diff --git a/src/camel/camel-utf8.h b/src/camel/camel-utf8.h
index d509f06..48c5e86 100644
--- a/src/camel/camel-utf8.h
+++ b/src/camel/camel-utf8.h
@@ -32,9 +32,6 @@ void camel_utf8_putc (guchar **ptr, guint32 c);
guint32 camel_utf8_getc (const guchar **ptr);
guint32 camel_utf8_getc_limit (const guchar **ptr, const guchar *end);
-/* utility func for utf8 gstrings */
-void g_string_append_u (GString *out, guint32 c);
-
/* convert utf7 to/from utf8, actually this is modified IMAP utf7 */
gchar *camel_utf7_utf8 (const gchar *ptr);
gchar *camel_utf8_utf7 (const gchar *ptr);
diff --git a/src/camel/camel-utils.c b/src/camel/camel-utils.c
new file mode 100644
index 0000000..b7a0f5d
--- /dev/null
+++ b/src/camel/camel-utils.c
@@ -0,0 +1,173 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "camel-utils.h"
+
+/**
+ * camel_util_bdata_get_number:
+ * @bdata_ptr: a backend specific data (bdata) pointer
+ * @default_value: a value to return, when no data can be read
+ *
+ * Reads a numeric data from the @bdata_ptr and moves the @bdata_ptr
+ * after that number. If the number cannot be read, then the @default_value
+ * is returned instead and the @bdata_ptr is left unchanged. The number
+ * might be previously stored with the camel_util_bdata_put_number().
+ *
+ * Returns: The read number, or the @default_value, if the @bdata_ptr doesn't
+ * point to a number.
+ *
+ * Since: 3.24
+ **/
+gint64
+camel_util_bdata_get_number (/* const */ gchar **bdata_ptr,
+ gint64 default_value)
+{
+ gint64 result;
+ gchar *endptr;
+
+ g_return_val_if_fail (bdata_ptr != NULL, default_value);
+
+ if (!bdata_ptr || !*bdata_ptr || !**bdata_ptr)
+ return default_value;
+
+ if (**bdata_ptr == ' ')
+ *bdata_ptr += 1;
+
+ if (!**bdata_ptr)
+ return default_value;
+
+ endptr = *bdata_ptr;
+
+ result = g_ascii_strtoll (*bdata_ptr, &endptr, 10);
+
+ if (endptr == *bdata_ptr)
+ result = default_value;
+ else
+ *bdata_ptr = endptr;
+
+ return result;
+}
+
+/**
+ * camel_util_bdata_put_number:
+ * @bdata_str: a #GString to store a backend specific data (bdata)
+ * @value: a value to store
+ *
+ * Puts the number @value at the end of the @bdata_str. In case the @bdata_str
+ * is not empty a space is added before the numeric @value. The stored value
+ * can be read back with the camel_util_bdata_get_number().
+ *
+ * Since: 3.24
+ **/
+void
+camel_util_bdata_put_number (GString *bdata_str,
+ gint64 value)
+{
+ g_return_if_fail (bdata_str != NULL);
+
+ if (bdata_str->len && bdata_str->str[bdata_str->len - 1] != ' ')
+ g_string_append_c (bdata_str, ' ');
+
+ g_string_append_printf (bdata_str, "%" G_GINT64_FORMAT, value);
+}
+
+/**
+ * camel_util_bdata_get_string:
+ * @bdata_ptr: a backend specific data (bdata) pointer
+ * @default_value: a value to return, when no data can be read
+ *
+ * Reads a string data from the @bdata_ptr and moves the @bdata_ptr
+ * after that string. If the string cannot be read, then the @default_value
+ * is returned instead and the @bdata_ptr is left unchanged. The string
+ * might be previously stored with the camel_util_bdata_put_string().
+ *
+ * Returns: (transfer full): Newly allocated string, which was read, or
+ * dupped the @default_value, if the @bdata_ptr doesn't point to a string.
+ * Free returned pointer with g_free() when done with it.
+ *
+ * Since: 3.24
+ **/
+gchar *
+camel_util_bdata_get_string (/* const */ gchar **bdata_ptr,
+ const gchar *default_value)
+{
+ gint64 length, has_length;
+ gchar *orig_bdata_ptr;
+ gchar *result;
+
+ g_return_val_if_fail (bdata_ptr != NULL, NULL);
+
+ orig_bdata_ptr = *bdata_ptr;
+
+ length = camel_util_bdata_get_number (bdata_ptr, -1);
+
+ /* might be a '-' sign */
+ if (*bdata_ptr && **bdata_ptr == '-')
+ *bdata_ptr += 1;
+ else
+ length = -1;
+
+ if (length < 0 || !*bdata_ptr || !**bdata_ptr || *bdata_ptr == orig_bdata_ptr) {
+ *bdata_ptr = orig_bdata_ptr;
+
+ return g_strdup (default_value);
+ }
+
+ if (!length)
+ return g_strdup ("");
+
+ has_length = strlen (*bdata_ptr);
+ if (has_length < length)
+ length = has_length;
+
+ result = g_strndup (*bdata_ptr, length);
+ *bdata_ptr += length;
+
+ return result;
+}
+
+/**
+ * camel_util_bdata_put_string:
+ * @bdata_str: a #GString to store a backend specific data (bdata)
+ * @value: a value to store
+ *
+ * Puts the string @value at the end of the @bdata_str. In case the @bdata_str
+ * is not empty a space is added before the string @value. The stored value
+ * can be read back with the camel_util_bdata_get_string().
+ *
+ * The strings are encoded as "length-value", quotes for clarity only.
+ *
+ * Since: 3.24
+ **/
+void
+camel_util_bdata_put_string (GString *bdata_str,
+ const gchar *value)
+{
+ g_return_if_fail (bdata_str != NULL);
+ g_return_if_fail (value != NULL);
+
+ camel_util_bdata_put_number (bdata_str, strlen (value));
+
+ g_string_append_printf (bdata_str, "-%s", value);
+}
diff --git a/src/camel/camel-utils.h b/src/camel/camel-utils.h
new file mode 100644
index 0000000..25c2864
--- /dev/null
+++ b/src/camel/camel-utils.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_UTILS_H
+#define CAMEL_UTILS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+gint64 camel_util_bdata_get_number (/* const */ gchar **bdata_ptr,
+ gint64 default_value);
+void camel_util_bdata_put_number (GString *bdata_str,
+ gint64 value);
+gchar * camel_util_bdata_get_string (/* const */ gchar **bdata_ptr,
+ const gchar *default_value);
+void camel_util_bdata_put_string (GString *bdata_str,
+ const gchar *value);
+
+G_END_DECLS
+
+#endif /* CAMEL_UTILS_H */
diff --git a/src/camel/camel-vee-data-cache.h b/src/camel/camel-vee-data-cache.h
index 9c42cc4..4220500 100644
--- a/src/camel/camel-vee-data-cache.h
+++ b/src/camel/camel-vee-data-cache.h
@@ -113,6 +113,9 @@ struct _CamelVeeSubfolderData {
struct _CamelVeeSubfolderDataClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_vee_subfolder_data_get_type
@@ -138,6 +141,9 @@ struct _CamelVeeMessageInfoData {
struct _CamelVeeMessageInfoDataClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_vee_message_info_data_get_type
@@ -168,6 +174,9 @@ struct _CamelVeeDataCache {
struct _CamelVeeDataCacheClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_vee_data_cache_get_type (void) G_GNUC_CONST;
@@ -199,9 +208,7 @@ CamelVeeMessageInfoData *
void camel_vee_data_cache_foreach_message_info_data
(CamelVeeDataCache *data_cache,
CamelFolder *fromfolder,
- void (* func) (CamelVeeMessageInfoData *mi_data,
- CamelFolder *subfolder,
- gpointer user_data),
+ CamelForeachInfoData func,
gpointer user_data);
void camel_vee_data_cache_remove_message_info_data
(CamelVeeDataCache *data_cache,
diff --git a/src/camel/camel-vee-folder.c b/src/camel/camel-vee-folder.c
index a6355ad..91af03d 100644
--- a/src/camel/camel-vee-folder.c
+++ b/src/camel/camel-vee-folder.c
@@ -46,6 +46,7 @@ typedef struct _FolderChangedData FolderChangedData;
((obj), CAMEL_TYPE_VEE_FOLDER, CamelVeeFolderPrivate))
struct _CamelVeeFolderPrivate {
+ guint32 flags; /* folder open flags */
gboolean destroyed;
GList *subfolders; /* lock using subfolder_lock before changing/accessing */
GHashTable *ignore_changed; /* hash of subfolder pointers to ignore the next folder's 'changed'
signal */
@@ -137,7 +138,7 @@ vee_folder_note_added_uid (CamelVeeFolder *vfolder,
const gchar *vuid;
vuid = camel_vee_message_info_data_get_vee_message_uid (added_mi_data);
- if (!camel_folder_summary_check_uid (&vsummary->summary, vuid)) {
+ if (!camel_folder_summary_check_uid (CAMEL_FOLDER_SUMMARY (vsummary), vuid)) {
/* add it only if it wasn't in yet */
CamelVeeMessageInfo *vmi;
@@ -145,7 +146,7 @@ vee_folder_note_added_uid (CamelVeeFolder *vfolder,
if (vmi) {
if (changes)
camel_folder_change_info_add_uid (changes, vuid);
- camel_message_info_unref (vmi);
+ g_clear_object (&vmi);
if (vfolder->priv->parent_vee_store)
camel_vee_store_note_vuid_used (vfolder->priv->parent_vee_store,
added_mi_data, vfolder);
@@ -168,7 +169,7 @@ vee_folder_note_unmatch_uid (CamelVeeFolder *vfolder,
const gchar *vuid;
vuid = camel_vee_message_info_data_get_vee_message_uid (unmatched_mi_data);
- if (camel_folder_summary_check_uid (&vsummary->summary, vuid)) {
+ if (camel_folder_summary_check_uid (CAMEL_FOLDER_SUMMARY (vsummary), vuid)) {
g_object_ref (unmatched_mi_data);
/* this one doesn't belong to us anymore */
@@ -263,7 +264,7 @@ vee_folder_merge_matching (CamelVeeFolder *vfolder,
folder = CAMEL_FOLDER (vfolder);
g_return_if_fail (folder != NULL);
- vsummary = CAMEL_VEE_SUMMARY (folder->summary);
+ vsummary = CAMEL_VEE_SUMMARY (camel_folder_get_folder_summary (folder));
g_return_if_fail (vsummary != NULL);
data_cache = vee_folder_get_data_cache (vfolder);
@@ -323,7 +324,7 @@ vee_folder_rebuild_folder_with_changes (CamelVeeFolder *vfolder,
if (!g_cancellable_is_cancelled (cancellable)) {
GHashTable *all_uids;
- all_uids = camel_folder_summary_get_hash (subfolder->summary);
+ all_uids = camel_folder_summary_get_hash (camel_folder_get_folder_summary (subfolder));
vee_folder_merge_matching (vfolder, subfolder, all_uids, match, changes, FALSE);
g_hash_table_destroy (all_uids);
}
@@ -394,7 +395,7 @@ vee_folder_subfolder_changed (CamelVeeFolder *vfolder,
changes = camel_folder_change_info_new ();
v_folder = CAMEL_FOLDER (vfolder);
- vsummary = CAMEL_VEE_SUMMARY (v_folder->summary);
+ vsummary = CAMEL_VEE_SUMMARY (camel_folder_get_folder_summary (v_folder));
camel_folder_freeze (v_folder);
@@ -434,7 +435,7 @@ vee_folder_subfolder_changed (CamelVeeFolder *vfolder,
continue;
vuid = camel_vee_message_info_data_get_vee_message_uid (mi_data);
- if (camel_folder_summary_check_uid (v_folder->summary, vuid))
+ if (camel_folder_summary_check_uid (camel_folder_get_folder_summary
(v_folder), vuid))
g_ptr_array_add (match, (gpointer) camel_pstring_strdup
(test_uids->pdata[ii]));
g_object_unref (mi_data);
}
@@ -557,7 +558,7 @@ vee_folder_dispose (GObject *object)
folder = CAMEL_FOLDER (object);
/* parent's class frees summary on dispose, thus depend on it */
- if (folder->summary) {
+ if (camel_folder_get_folder_summary (folder)) {
CamelVeeFolder *vfolder;
vfolder = CAMEL_VEE_FOLDER (object);
@@ -679,7 +680,7 @@ vee_folder_propagate_skipped_changes (CamelVeeFolder *vf)
changes = camel_folder_change_info_new ();
v_folder = CAMEL_FOLDER (vf);
- vsummary = CAMEL_VEE_SUMMARY (v_folder->summary);
+ vsummary = CAMEL_VEE_SUMMARY (camel_folder_get_folder_summary (v_folder));
/* first remove ... */
g_hash_table_iter_init (&iter, vf->priv->unmatched_remove_changed);
@@ -727,6 +728,17 @@ vee_folder_propagate_skipped_changes (CamelVeeFolder *vf)
}
}
+static guint32
+vee_folder_get_permanent_flags (CamelFolder *folder)
+{
+ /* FIXME: what to do about user flags if the subfolder doesn't support them? */
+ return CAMEL_MESSAGE_ANSWERED |
+ CAMEL_MESSAGE_DELETED |
+ CAMEL_MESSAGE_DRAFT |
+ CAMEL_MESSAGE_FLAGGED |
+ CAMEL_MESSAGE_SEEN;
+}
+
static GPtrArray *
vee_folder_search_by_expression (CamelFolder *folder,
const gchar *expression,
@@ -902,12 +914,12 @@ vee_folder_get_message_sync (CamelFolder *folder,
CamelVeeMessageInfo *mi;
CamelMimeMessage *msg = NULL;
- mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, uid);
+ mi = (CamelVeeMessageInfo *) camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid);
if (mi) {
msg = camel_folder_get_message_sync (
- camel_folder_summary_get_folder (mi->orig_summary), camel_message_info_get_uid (mi) +
8,
+ camel_vee_message_info_get_original_folder (mi), camel_message_info_get_uid
(CAMEL_MESSAGE_INFO (mi)) + 8,
cancellable, error);
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
} else {
g_set_error (
error, CAMEL_FOLDER_ERROR,
@@ -1081,12 +1093,12 @@ vee_folder_remove_folder (CamelVeeFolder *vfolder,
camel_folder_freeze (v_folder);
- uids = camel_vee_summary_get_uids_for_subfolder (CAMEL_VEE_SUMMARY (v_folder->summary), subfolder);
+ uids = camel_vee_summary_get_uids_for_subfolder (CAMEL_VEE_SUMMARY (camel_folder_get_folder_summary
(v_folder)), subfolder);
if (uids) {
struct RemoveUnmatchedData rud;
rud.vfolder = vfolder;
- rud.vsummary = CAMEL_VEE_SUMMARY (v_folder->summary);
+ rud.vsummary = CAMEL_VEE_SUMMARY (camel_folder_get_folder_summary (v_folder));
rud.subfolder = subfolder;
rud.data_cache = vee_folder_get_data_cache (vfolder);
rud.changes = changes;
@@ -1190,6 +1202,7 @@ camel_vee_folder_class_init (CamelVeeFolderClass *class)
object_class->set_property = vee_folder_set_property;
folder_class = CAMEL_FOLDER_CLASS (class);
+ folder_class->get_permanent_flags = vee_folder_get_permanent_flags;
folder_class->search_by_expression = vee_folder_search_by_expression;
folder_class->search_by_uids = vee_folder_search_by_uids;
folder_class->count_by_expression = vee_folder_count_by_expression;
@@ -1229,14 +1242,7 @@ camel_vee_folder_init (CamelVeeFolder *vee_folder)
vee_folder->priv = CAMEL_VEE_FOLDER_GET_PRIVATE (vee_folder);
- folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY;
-
- /* FIXME: what to do about user flags if the subfolder doesn't support them? */
- folder->permanent_flags = CAMEL_MESSAGE_ANSWERED |
- CAMEL_MESSAGE_DELETED |
- CAMEL_MESSAGE_DRAFT |
- CAMEL_MESSAGE_FLAGGED |
- CAMEL_MESSAGE_SEEN;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) |
CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY);
g_rec_mutex_init (&vee_folder->priv->subfolder_lock);
g_rec_mutex_init (&vee_folder->priv->changed_lock);
@@ -1253,6 +1259,14 @@ camel_vee_folder_init (CamelVeeFolder *vee_folder)
(GDestroyNotify) vee_folder_changed_data_free);
}
+/**
+ * camel_vee_folder_construct:
+ * @vf: a #CamelVeeFolder
+ * @flags: flags for the @vf
+ *
+ * Initializes internal structures of the @vf. This is meant to be
+ * called by the descendants of #CamelVeeFolder.
+ **/
void
camel_vee_folder_construct (CamelVeeFolder *vf,
guint32 flags)
@@ -1260,7 +1274,7 @@ camel_vee_folder_construct (CamelVeeFolder *vf,
CamelFolder *folder = (CamelFolder *) vf;
CamelStore *parent_store;
- vf->flags = flags;
+ vf->priv->flags = flags;
parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (vf));
if (CAMEL_IS_VEE_STORE (parent_store))
@@ -1268,7 +1282,7 @@ camel_vee_folder_construct (CamelVeeFolder *vf,
else
vf->priv->vee_data_cache = camel_vee_data_cache_new ();
- folder->summary = camel_vee_summary_new (folder);
+ camel_folder_take_folder_summary (folder, camel_vee_summary_new (folder));
/* only for subfolders of vee-store */
if (vf->priv->parent_vee_store) {
@@ -1293,6 +1307,22 @@ camel_vee_folder_construct (CamelVeeFolder *vf,
}
/**
+ * camel_vee_folder_get_flags:
+ * @vf: a #CamelVeeFolder
+ *
+ * Returns: flags of @vf, as set by camel_vee_folder_construct()
+ *
+ * Since: 3.24
+ **/
+guint32
+camel_vee_folder_get_flags (CamelVeeFolder *vf)
+{
+ g_return_val_if_fail (CAMEL_IS_VEE_FOLDER (vf), 0);
+
+ return vf->priv->flags;
+}
+
+/**
* camel_vee_folder_new:
* @parent_store: the parent CamelVeeStore
* @full: the full path to the vfolder.
@@ -1531,6 +1561,9 @@ camel_vee_folder_set_folders (CamelVeeFolder *vf,
/**
* camel_vee_folder_add_vuid:
+ * @vfolder:
+ * @mi_data: (type CamelVeeMessageInfoData):
+ * @changes:
*
* FIXME Document me!
*
@@ -1576,12 +1609,15 @@ camel_vee_folder_add_vuid (CamelVeeFolder *vfolder,
g_rec_mutex_unlock (&vfolder->priv->changed_lock);
- vsummary = CAMEL_VEE_SUMMARY (CAMEL_FOLDER (vfolder)->summary);
+ vsummary = CAMEL_VEE_SUMMARY (camel_folder_get_folder_summary (CAMEL_FOLDER (vfolder)));
vee_folder_note_added_uid (vfolder, vsummary, mi_data, changes, FALSE);
}
/**
* camel_vee_folder_remove_vuid:
+ * @vfolder:
+ * @mi_data: (type CamelVeeMessageInfoData):
+ * @changes:
*
* FIXME Document me!
*
@@ -1628,7 +1664,7 @@ camel_vee_folder_remove_vuid (CamelVeeFolder *vfolder,
g_rec_mutex_unlock (&vfolder->priv->changed_lock);
- vsummary = CAMEL_VEE_SUMMARY (CAMEL_FOLDER (vfolder)->summary);
+ vsummary = CAMEL_VEE_SUMMARY (camel_folder_get_folder_summary (CAMEL_FOLDER (vfolder)));
data_cache = vee_folder_get_data_cache (vfolder);
/* It can be NULL on dispose of the CamelVeeStore */
@@ -1653,25 +1689,29 @@ camel_vee_folder_get_location (CamelVeeFolder *vf,
gchar **realuid)
{
CamelFolder *folder;
+ const gchar *uid;
g_return_val_if_fail (CAMEL_IS_VEE_FOLDER (vf), NULL);
g_return_val_if_fail (vinfo != NULL, NULL);
- folder = camel_folder_summary_get_folder (vinfo->orig_summary);
+ folder = camel_vee_message_info_get_original_folder (vinfo);
+ uid = camel_message_info_get_uid (CAMEL_MESSAGE_INFO (vinfo));
+
+ g_return_val_if_fail (uid != NULL && strlen (uid) > 8, NULL);
/* locking? yes? no? although the vfolderinfo is valid when obtained
* the folder in it might not necessarily be so ...? */
if (CAMEL_IS_VEE_FOLDER (folder)) {
CamelFolder *res;
- const CamelVeeMessageInfo *vfinfo;
+ CamelMessageInfo *vfinfo;
- vfinfo = (CamelVeeMessageInfo *) camel_folder_get_message_info (folder,
camel_message_info_get_uid (vinfo) + 8);
- res = camel_vee_folder_get_location ((CamelVeeFolder *) folder, vfinfo, realuid);
- camel_message_info_unref ((CamelMessageInfo *) vfinfo);
+ vfinfo = camel_folder_get_message_info (folder, uid + 8);
+ res = camel_vee_folder_get_location ((CamelVeeFolder *) folder, CAMEL_VEE_MESSAGE_INFO
(vfinfo), realuid);
+ g_clear_object (&vfinfo);
return res;
} else {
if (realuid)
- *realuid = g_strdup (camel_message_info_get_uid (vinfo)+8);
+ *realuid = g_strdup (uid + 8);
return folder;
}
diff --git a/src/camel/camel-vee-folder.h b/src/camel/camel-vee-folder.h
index c1854bc..bee2eed 100644
--- a/src/camel/camel-vee-folder.h
+++ b/src/camel/camel-vee-folder.h
@@ -57,8 +57,6 @@ typedef struct _CamelVeeFolderPrivate CamelVeeFolderPrivate;
struct _CamelVeeFolder {
CamelFolder parent;
CamelVeeFolderPrivate *priv;
-
- guint32 flags; /* folder open flags */
};
struct _CamelVeeFolderClass {
@@ -83,6 +81,9 @@ struct _CamelVeeFolderClass {
void (*folder_changed) (CamelVeeFolder *vfolder,
CamelFolder *subfolder,
CamelFolderChangeInfo *changes);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
#define CAMEL_UNMATCHED_NAME "UNMATCHED"
@@ -93,9 +94,9 @@ CamelFolder * camel_vee_folder_new (CamelStore *parent_store,
guint32 flags);
void camel_vee_folder_construct (CamelVeeFolder *vf,
guint32 flags);
-
+guint32 camel_vee_folder_get_flags (CamelVeeFolder *vf);
CamelFolder * camel_vee_folder_get_location (CamelVeeFolder *vf,
- const struct _CamelVeeMessageInfo *vinfo,
+ const CamelVeeMessageInfo *vinfo,
gchar **realuid);
CamelFolder * camel_vee_folder_get_vee_uid_folder (CamelVeeFolder *vf,
const gchar *vee_message_uid);
diff --git a/src/camel/camel-vee-message-info.c b/src/camel/camel-vee-message-info.c
new file mode 100644
index 0000000..b0b3e0d
--- /dev/null
+++ b/src/camel/camel-vee-message-info.c
@@ -0,0 +1,532 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "camel-folder.h"
+#include "camel-folder-summary.h"
+#include "camel-message-info.h"
+#include "camel-string-utils.h"
+#include "camel-vee-folder.h"
+#include "camel-vee-summary.h"
+#include "camel-vtrash-folder.h"
+
+#include "camel-vee-message-info.h"
+
+struct _CamelVeeMessageInfoPrivate {
+ CamelFolderSummary *orig_summary;
+};
+
+G_DEFINE_TYPE (CamelVeeMessageInfo, camel_vee_message_info, CAMEL_TYPE_MESSAGE_INFO)
+
+static CamelMessageInfo *
+vee_message_info_clone (const CamelMessageInfo *mi,
+ CamelFolderSummary *assign_summary)
+{
+ CamelMessageInfo *result;
+
+ g_return_val_if_fail (CAMEL_IS_VEE_MESSAGE_INFO (mi), NULL);
+
+ result = CAMEL_MESSAGE_INFO_CLASS (camel_vee_message_info_parent_class)->clone (mi, assign_summary);
+ if (!result)
+ return NULL;
+
+ if (CAMEL_IS_VEE_MESSAGE_INFO (result)) {
+ CamelVeeMessageInfo *vmi, *vmi_result;
+
+ vmi = CAMEL_VEE_MESSAGE_INFO (mi);
+ vmi_result = CAMEL_VEE_MESSAGE_INFO (result);
+
+ if (vmi->priv->orig_summary)
+ vmi_result->priv->orig_summary = g_object_ref (vmi->priv->orig_summary);
+ }
+
+ return result;
+}
+
+static void
+vee_message_info_notify_mi_changed (CamelFolder *folder,
+ const gchar *mi_uid)
+{
+ CamelFolderChangeInfo *changes;
+
+ g_return_if_fail (CAMEL_IS_VEE_FOLDER (folder));
+ g_return_if_fail (mi_uid != NULL);
+
+ changes = camel_folder_change_info_new ();
+ camel_folder_change_info_change_uid (changes, mi_uid);
+ camel_folder_changed (folder, changes);
+ camel_folder_change_info_free (changes);
+}
+
+#define vee_call_from_parent_mi(_err_ret, _ret_type, _call_what, _call_args, _is_set) G_STMT_START { \
+ CamelVeeMessageInfo *vmi; \
+ CamelMessageInfo *orig_mi; \
+ CamelFolderSummary *this_summary, *sub_summary; \
+ CamelFolder *this_folder, *sub_folder; \
+ gboolean ignore_changes; \
+ const gchar *uid; \
+ _ret_type result; \
+ \
+ g_return_val_if_fail (CAMEL_IS_VEE_MESSAGE_INFO (mi), _err_ret); \
+ \
+ vmi = CAMEL_VEE_MESSAGE_INFO (mi); \
+ g_return_val_if_fail (vmi->priv->orig_summary != NULL, _err_ret); \
+ \
+ uid = camel_message_info_pooldup_uid (mi); \
+ g_return_val_if_fail (uid != NULL, _err_ret); \
+ \
+ if (!uid[0] || !uid[1] || !uid[2] || !uid[3] || !uid[4] || \
+ !uid[5] || !uid[6] || !uid[7] || !uid[8]) { \
+ camel_pstring_free (uid); \
+ g_warn_if_reached (); \
+ return _err_ret; \
+ } \
+ \
+ orig_mi = (CamelMessageInfo *) camel_folder_summary_get (vmi->priv->orig_summary, uid + 8);
\
+ if (!orig_mi) { \
+ g_warning ("%s: Failed to get orig uid '%s'\n", G_STRFUNC, uid); \
+ camel_pstring_free (uid); \
+ return _err_ret; \
+ } \
+ \
+ this_summary = camel_message_info_ref_summary (mi); \
+ this_folder = this_summary ? camel_folder_summary_get_folder (this_summary) : NULL; \
+ sub_summary = camel_message_info_ref_summary (orig_mi); \
+ sub_folder = sub_summary ? camel_folder_summary_get_folder (sub_summary) : NULL; \
+ \
+ ignore_changes = _is_set && !CAMEL_IS_VTRASH_FOLDER (this_folder); \
+ \
+ /* ignore changes done in the folder itself, \
+ * unless it's a vTrash or vJunk folder */ \
+ if (ignore_changes) \
+ camel_vee_folder_ignore_next_changed_event (CAMEL_VEE_FOLDER (this_folder),
sub_folder); \
+ \
+ result = _call_what _call_args; \
+ \
+ if (ignore_changes) { \
+ if (result) \
+ vee_message_info_notify_mi_changed (this_folder, uid); \
+ else \
+ camel_vee_folder_remove_from_ignore_changed_event ( \
+ CAMEL_VEE_FOLDER (this_folder), sub_folder); \
+ } \
+ \
+ g_clear_object (&this_summary); \
+ g_clear_object (&sub_summary); \
+ g_clear_object (&orig_mi); \
+ camel_pstring_free (uid); \
+ \
+ return result; \
+ } G_STMT_END
+
+static guint32
+vee_message_info_get_flags (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (0, guint32, camel_message_info_get_flags, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_flags_real (CamelMessageInfo *mi,
+ guint32 mask,
+ guint32 set)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_flags, (orig_mi, mask, set), TRUE);
+}
+
+static gboolean
+vee_message_info_set_flags (CamelMessageInfo *mi,
+ guint32 mask,
+ guint32 set)
+{
+ gboolean result;
+
+ result = vee_message_info_set_flags_real (mi, mask, set);
+
+ if (result) {
+ CamelFolderSummary *summary;
+
+ summary = camel_message_info_ref_summary (mi);
+ if (summary)
+ camel_folder_summary_replace_flags (summary, mi);
+ g_clear_object (&summary);
+ }
+
+ return result;
+}
+
+static gboolean
+vee_message_info_get_user_flag (const CamelMessageInfo *mi,
+ const gchar *name)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_get_user_flag, (orig_mi, name), FALSE);
+}
+
+static gboolean
+vee_message_info_set_user_flag (CamelMessageInfo *mi,
+ const gchar *name,
+ gboolean state)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_user_flag, (orig_mi, name, state),
TRUE);
+}
+
+static const CamelNamedFlags *
+vee_message_info_get_user_flags (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const CamelNamedFlags *, camel_message_info_get_user_flags, (orig_mi),
FALSE);
+}
+
+static CamelNamedFlags *
+vee_message_info_dup_user_flags (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, CamelNamedFlags *, camel_message_info_dup_user_flags, (orig_mi),
FALSE);
+}
+
+static gboolean
+vee_message_info_take_user_flags (CamelMessageInfo *mi,
+ CamelNamedFlags *user_flags)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_take_user_flags, (orig_mi, user_flags),
TRUE);
+}
+
+static const gchar *
+vee_message_info_get_user_tag (const CamelMessageInfo *mi,
+ const gchar *name)
+{
+ vee_call_from_parent_mi (NULL, const gchar *, camel_message_info_get_user_tag, (orig_mi, name),
FALSE);
+}
+
+static gboolean
+vee_message_info_set_user_tag (CamelMessageInfo *mi,
+ const gchar *name,
+ const gchar *value)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_user_tag, (orig_mi, name, value),
TRUE);
+}
+
+static CamelNameValueArray *
+vee_message_info_dup_user_tags (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, CamelNameValueArray *, camel_message_info_dup_user_tags, (orig_mi),
FALSE);
+}
+
+static const CamelNameValueArray *
+vee_message_info_get_user_tags (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const CamelNameValueArray *, camel_message_info_get_user_tags,
(orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_take_user_tags (CamelMessageInfo *mi,
+ CamelNameValueArray *user_tags)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_take_user_tags, (orig_mi, user_tags),
TRUE);
+}
+
+static const gchar *
+vee_message_info_get_subject (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const gchar *, camel_message_info_get_subject, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_subject (CamelMessageInfo *mi,
+ const gchar *subject)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_subject, (orig_mi, subject), TRUE);
+}
+
+static const gchar *
+vee_message_info_get_from (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const gchar *, camel_message_info_get_from, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_from (CamelMessageInfo *mi,
+ const gchar *from)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_from, (orig_mi, from), TRUE);
+}
+
+static const gchar *
+vee_message_info_get_to (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const gchar *, camel_message_info_get_to, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_to (CamelMessageInfo *mi,
+ const gchar *to)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_to, (orig_mi, to), TRUE);
+}
+
+static const gchar *
+vee_message_info_get_cc (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const gchar *, camel_message_info_get_cc, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_cc (CamelMessageInfo *mi,
+ const gchar *cc)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_cc, (orig_mi, cc), TRUE);
+}
+
+static const gchar *
+vee_message_info_get_mlist (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const gchar *, camel_message_info_get_mlist, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_mlist (CamelMessageInfo *mi,
+ const gchar *mlist)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_mlist, (orig_mi, mlist), TRUE);
+}
+
+static guint32
+vee_message_info_get_size (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (0, guint32, camel_message_info_get_size, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_size (CamelMessageInfo *mi,
+ guint32 size)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_size, (orig_mi, size), TRUE);
+}
+
+static gint64
+vee_message_info_get_date_sent (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (0, gint64, camel_message_info_get_date_sent, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_date_sent (CamelMessageInfo *mi,
+ gint64 date_sent)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_date_sent, (orig_mi, date_sent),
TRUE);
+}
+
+static gint64
+vee_message_info_get_date_received (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (0, gint64, camel_message_info_get_date_received, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_date_received (CamelMessageInfo *mi,
+ gint64 date_received)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_date_received, (orig_mi,
date_received), TRUE);
+}
+
+static guint64
+vee_message_info_get_message_id (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (0, guint64, camel_message_info_get_message_id, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_set_message_id (CamelMessageInfo *mi,
+ guint64 message_id)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_set_message_id, (orig_mi, message_id),
TRUE);
+}
+
+static const GArray *
+vee_message_info_get_references (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const GArray *, camel_message_info_get_references, (orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_take_references (CamelMessageInfo *mi,
+ GArray *references)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_take_references, (orig_mi, references),
TRUE);
+}
+
+static const CamelNameValueArray *
+vee_message_info_get_headers (const CamelMessageInfo *mi)
+{
+ vee_call_from_parent_mi (NULL, const CamelNameValueArray *, camel_message_info_get_headers,
(orig_mi), FALSE);
+}
+
+static gboolean
+vee_message_info_take_headers (CamelMessageInfo *mi,
+ CamelNameValueArray *headers)
+{
+ vee_call_from_parent_mi (FALSE, gboolean, camel_message_info_take_headers, (orig_mi, headers), TRUE);
+}
+
+#undef vee_call_from_parent_mi
+
+static void
+vee_message_info_dispose (GObject *object)
+{
+ CamelVeeMessageInfo *vmi = CAMEL_VEE_MESSAGE_INFO (object);
+
+ g_clear_object (&vmi->priv->orig_summary);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_vee_message_info_parent_class)->dispose (object);
+}
+
+static void
+camel_vee_message_info_class_init (CamelVeeMessageInfoClass *class)
+{
+ CamelMessageInfoClass *mi_class;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelVeeMessageInfoPrivate));
+
+ mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
+ mi_class->clone = vee_message_info_clone;
+ mi_class->get_flags = vee_message_info_get_flags;
+ mi_class->set_flags = vee_message_info_set_flags;
+ mi_class->get_user_flag = vee_message_info_get_user_flag;
+ mi_class->set_user_flag = vee_message_info_set_user_flag;
+ mi_class->get_user_flags = vee_message_info_get_user_flags;
+ mi_class->dup_user_flags = vee_message_info_dup_user_flags;
+ mi_class->take_user_flags = vee_message_info_take_user_flags;
+ mi_class->get_user_tag = vee_message_info_get_user_tag;
+ mi_class->set_user_tag = vee_message_info_set_user_tag;
+ mi_class->get_user_tags = vee_message_info_get_user_tags;
+ mi_class->dup_user_tags = vee_message_info_dup_user_tags;
+ mi_class->take_user_tags = vee_message_info_take_user_tags;
+ mi_class->get_subject = vee_message_info_get_subject;
+ mi_class->set_subject = vee_message_info_set_subject;
+ mi_class->get_from = vee_message_info_get_from;
+ mi_class->set_from = vee_message_info_set_from;
+ mi_class->get_to = vee_message_info_get_to;
+ mi_class->set_to = vee_message_info_set_to;
+ mi_class->get_cc = vee_message_info_get_cc;
+ mi_class->set_cc = vee_message_info_set_cc;
+ mi_class->get_mlist = vee_message_info_get_mlist;
+ mi_class->set_mlist = vee_message_info_set_mlist;
+ mi_class->get_size = vee_message_info_get_size;
+ mi_class->set_size = vee_message_info_set_size;
+ mi_class->get_date_sent = vee_message_info_get_date_sent;
+ mi_class->set_date_sent = vee_message_info_set_date_sent;
+ mi_class->get_date_received = vee_message_info_get_date_received;
+ mi_class->set_date_received = vee_message_info_set_date_received;
+ mi_class->get_message_id = vee_message_info_get_message_id;
+ mi_class->set_message_id = vee_message_info_set_message_id;
+ mi_class->get_references = vee_message_info_get_references;
+ mi_class->take_references = vee_message_info_take_references;
+ mi_class->get_headers = vee_message_info_get_headers;
+ mi_class->take_headers = vee_message_info_take_headers;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = vee_message_info_dispose;
+}
+
+static void
+camel_vee_message_info_init (CamelVeeMessageInfo *vmi)
+{
+ vmi->priv = G_TYPE_INSTANCE_GET_PRIVATE (vmi, CAMEL_TYPE_VEE_MESSAGE_INFO,
CamelVeeMessageInfoPrivate);
+}
+
+/**
+ * camel_vee_message_info_new:
+ * @summary: a #CamelVeeSummary, the "owner" of the created message info
+ * @original_summary: an original #CamelFolderSummary to reference to
+ * @vuid: what UID to set on the resulting message info
+ *
+ * Creates a new instance of #CamelVeeMessageInfo which references
+ * a message from the @original_summary internally.
+ *
+ * The @vuid should be encoded in a way which the vFolder understands,
+ * which is like the one returned by camel_vee_message_info_data_get_vee_message_uid().
+ *
+ * Returns: (transfer full): a newly created #CamelVeeMessageInfo
+ * which references @orig_mi. Free with g_object_unref() when done
+ * with it.
+ *
+ * Since: 3.24
+ **/
+CamelMessageInfo *
+camel_vee_message_info_new (CamelFolderSummary *summary,
+ CamelFolderSummary *original_summary,
+ const gchar *vuid)
+{
+ CamelMessageInfo *mi;
+ CamelVeeMessageInfo *vmi;
+
+ g_return_val_if_fail (CAMEL_IS_VEE_SUMMARY (summary), NULL);
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (original_summary), NULL);
+ g_return_val_if_fail (vuid != NULL, NULL);
+ g_return_val_if_fail (vuid[0] && vuid[1] && vuid[2] && vuid[3] && vuid[4] && vuid[5] && vuid[6] &&
vuid[7] && vuid[8], NULL);
+
+ mi = camel_message_info_new (summary);
+ g_return_val_if_fail (CAMEL_IS_VEE_MESSAGE_INFO (mi), NULL);
+
+ vmi = CAMEL_VEE_MESSAGE_INFO (mi);
+ vmi->priv->orig_summary = g_object_ref (original_summary);
+
+ camel_message_info_set_uid (mi, vuid);
+
+ return mi;
+}
+
+/**
+ * camel_vee_message_info_get_original_summary:
+ * @vmi: a #CamelVeeMessageInfo
+ *
+ * Returns: (transfer none): A #CamelFolderSummary of the original
+ * message info, which this @vmi is proxying.
+ *
+ * Since: 3.24
+ **/
+CamelFolderSummary *
+camel_vee_message_info_get_original_summary (const CamelVeeMessageInfo *vmi)
+{
+ g_return_val_if_fail (CAMEL_IS_VEE_MESSAGE_INFO (vmi), NULL);
+
+ return vmi->priv->orig_summary;
+}
+
+/**
+ * camel_vee_message_info_get_original_folder:
+ * @vmi: a #CamelVeeMessageInfo
+ *
+ * Returns: (transfer none): A #CamelFolder of the original
+ * message info, which this @vmi is proxying.
+ *
+ * Since: 3.24
+ **/
+CamelFolder *
+camel_vee_message_info_get_original_folder (const CamelVeeMessageInfo *vmi)
+{
+ g_return_val_if_fail (CAMEL_IS_VEE_MESSAGE_INFO (vmi), NULL);
+
+ if (!vmi->priv->orig_summary)
+ return NULL;
+
+ return camel_folder_summary_get_folder (vmi->priv->orig_summary);
+}
diff --git a/src/camel/camel-vee-message-info.h b/src/camel/camel-vee-message-info.h
new file mode 100644
index 0000000..3ba0b72
--- /dev/null
+++ b/src/camel/camel-vee-message-info.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_VEE_MESSAGE_INFO_H
+#define CAMEL_VEE_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel-message-info.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_VEE_MESSAGE_INFO \
+ (camel_vee_message_info_get_type ())
+#define CAMEL_VEE_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_VEE_MESSAGE_INFO, CamelVeeMessageInfo))
+#define CAMEL_VEE_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_VEE_MESSAGE_INFO, CamelVeeMessageInfoClass))
+#define CAMEL_IS_VEE_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_VEE_MESSAGE_INFO))
+#define CAMEL_IS_VEE_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_VEE_MESSAGE_INFO))
+#define CAMEL_VEE_MESSAGE_INFO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_VEE_MESSAGE_INFO, CamelVeeMessageInfoClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelVeeMessageInfo CamelVeeMessageInfo;
+typedef struct _CamelVeeMessageInfoClass CamelVeeMessageInfoClass;
+typedef struct _CamelVeeMessageInfoPrivate CamelVeeMessageInfoPrivate;
+
+struct _CamelVeeMessageInfo {
+ CamelMessageInfo parent;
+ CamelVeeMessageInfoPrivate *priv;
+};
+
+struct _CamelVeeMessageInfoClass {
+ CamelMessageInfoClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
+};
+
+GType camel_vee_message_info_get_type (void);
+CamelMessageInfo *
+ camel_vee_message_info_new (CamelFolderSummary *summary,
+ CamelFolderSummary *original_summary,
+ const gchar *vuid);
+CamelFolderSummary *
+ camel_vee_message_info_get_original_summary
+ (const CamelVeeMessageInfo *vmi);
+CamelFolder *
+ camel_vee_message_info_get_original_folder
+ (const CamelVeeMessageInfo *vmi);
+
+G_END_DECLS
+
+#endif /* CAMEL_VEE_MESSAGE_INFO_H */
diff --git a/src/camel/camel-vee-store.c b/src/camel/camel-vee-store.c
index 393207c..0b5d31a 100644
--- a/src/camel/camel-vee-store.c
+++ b/src/camel/camel-vee-store.c
@@ -220,7 +220,7 @@ vee_store_get_folder_sync (CamelStore *store,
gsize name_len;
vf = (CamelVeeFolder *) camel_vee_folder_new (store, folder_name, flags);
- if (vf && ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0)) {
+ if (vf && ((camel_vee_folder_get_flags (vf) & CAMEL_STORE_FOLDER_PRIVATE) == 0)) {
const gchar *full_name;
full_name = camel_folder_get_full_name (CAMEL_FOLDER (vf));
@@ -233,11 +233,11 @@ vee_store_get_folder_sync (CamelStore *store,
while ( (p = strchr (p, '/'))) {
*p = 0;
- folder = camel_object_bag_reserve (store->folders, name);
+ folder = camel_object_bag_reserve (camel_store_get_folders_bag (store), name);
if (folder == NULL) {
/* create a dummy vFolder for this, makes get_folder_info simpler */
folder = camel_vee_folder_new (store, name, flags);
- camel_object_bag_add (store->folders, name, folder);
+ camel_object_bag_add (camel_store_get_folders_bag (store), name, folder);
change_folder (store, name, CHANGE_ADD | CHANGE_NOSELECT, 0);
/* FIXME: this sort of leaks folder, nobody owns a ref to it but us */
} else {
@@ -285,7 +285,7 @@ vee_store_get_folder_info_sync (CamelStore *store,
d (printf ("Get folder info '%s'\n", top ? top:"<null>"));
infos_hash = g_hash_table_new (g_str_hash, g_str_equal);
- folders = camel_object_bag_list (store->folders);
+ folders = camel_store_dup_opened_folders (store);
qsort (folders->pdata, folders->len, sizeof (folders->pdata[0]), vee_folder_cmp);
for (i = 0; i < folders->len; i++) {
CamelVeeFolder *folder = folders->pdata[i];
@@ -366,8 +366,8 @@ vee_store_get_folder_info_sync (CamelStore *store,
}
g_free (pname);
- g_object_unref (folder);
}
+ g_ptr_array_foreach (folders, (GFunc) g_object_unref, NULL);
g_ptr_array_free (folders, TRUE);
g_hash_table_destroy (infos_hash);
@@ -422,7 +422,7 @@ vee_store_delete_folder_sync (CamelStore *store,
return FALSE;
}
- folder = camel_object_bag_get (store->folders, folder_name);
+ folder = camel_object_bag_get (camel_store_get_folders_bag (store), folder_name);
if (folder) {
CamelObject *object = CAMEL_OBJECT (folder);
const gchar *state_filename;
@@ -433,7 +433,7 @@ vee_store_delete_folder_sync (CamelStore *store,
camel_object_set_state_filename (object, NULL);
}
- if ((((CamelVeeFolder *) folder)->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
+ if ((camel_vee_folder_get_flags (CAMEL_VEE_FOLDER (folder)) & CAMEL_STORE_FOLDER_PRIVATE) ==
0) {
/* what about now-empty parents? ignore? */
change_folder (store, folder_name, CHANGE_DELETE, -1);
}
@@ -473,7 +473,7 @@ vee_store_rename_folder_sync (CamelStore *store,
}
/* See if it exists, for vfolders, all folders are in the folders hash */
- oldfolder = camel_object_bag_get (store->folders, old);
+ oldfolder = camel_object_bag_get (camel_store_get_folders_bag (store), old);
if (oldfolder == NULL) {
g_set_error (
error, CAMEL_STORE_ERROR,
@@ -490,11 +490,11 @@ vee_store_rename_folder_sync (CamelStore *store,
while ( (p = strchr (p, '/'))) {
*p = 0;
- folder = camel_object_bag_reserve (store->folders, name);
+ folder = camel_object_bag_reserve (camel_store_get_folders_bag (store), name);
if (folder == NULL) {
/* create a dummy vFolder for this, makes get_folder_info simpler */
- folder = camel_vee_folder_new (store, name, ((CamelVeeFolder *) oldfolder)->flags);
- camel_object_bag_add (store->folders, name, folder);
+ folder = camel_vee_folder_new (store, name, camel_vee_folder_get_flags
(CAMEL_VEE_FOLDER (oldfolder)));
+ camel_object_bag_add (camel_store_get_folders_bag (store), name, folder);
change_folder (store, name, CHANGE_ADD | CHANGE_NOSELECT, 0);
/* FIXME: this sort of leaks folder, nobody owns a ref to it but us */
} else {
@@ -556,7 +556,7 @@ camel_vee_store_init (CamelVeeStore *vee_store)
vee_store->priv->unmatched_enabled = TRUE;
/* we dont want a vtrash/vjunk on this one */
- store->flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK);
+ camel_store_set_flags (store, camel_store_get_flags (store) & ~(CAMEL_STORE_VTRASH |
CAMEL_STORE_VJUNK));
}
/**
@@ -577,7 +577,7 @@ camel_vee_store_new (void)
*
* FIXME Document me!
*
- * Returns: (transfer none):
+ * Returns: (type CamelVeeFolder) (transfer none):
*
* Since: 3.6
**/
@@ -686,6 +686,9 @@ add_to_unmatched_folder_cb (CamelVeeMessageInfoData *mi_data,
/**
* camel_vee_store_note_subfolder_used:
+ * @vstore:
+ * @subfolder:
+ * @used_by: (type CamelVeeFolder):
*
* FIXME Document me!
*
@@ -765,6 +768,9 @@ remove_vuid_count_record_cb (CamelVeeMessageInfoData *mi_data,
/**
* camel_vee_store_note_subfolder_unused:
+ * @vstore:
+ * @subfolder:
+ * @unused_by: (type CamelVeeFolder):
*
* FIXME Document me!
*
@@ -814,6 +820,9 @@ camel_vee_store_note_subfolder_unused (CamelVeeStore *vstore,
/**
* camel_vee_store_note_vuid_used:
+ * @vstore:
+ * @mi_data:
+ * @used_by: (type CamelVeeFolder):
*
* FIXME Document me!
*
@@ -871,6 +880,9 @@ camel_vee_store_note_vuid_used (CamelVeeStore *vstore,
/**
* camel_vee_store_note_vuid_unused:
+ * @vstore:
+ * @mi_data:
+ * @unused_by: (type CamelVeeFolder):
*
* FIXME Document me!
*
diff --git a/src/camel/camel-vee-store.h b/src/camel/camel-vee-store.h
index d0fde35..3857323 100644
--- a/src/camel/camel-vee-store.h
+++ b/src/camel/camel-vee-store.h
@@ -60,6 +60,9 @@ struct _CamelVeeStore {
struct _CamelVeeStoreClass {
CamelStoreClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_vee_store_get_type (void);
diff --git a/src/camel/camel-vee-summary.c b/src/camel/camel-vee-summary.c
index ddd527d..11e6a4e 100644
--- a/src/camel/camel-vee-summary.c
+++ b/src/camel/camel-vee-summary.c
@@ -29,12 +29,14 @@
#include "camel-debug.h"
#include "camel-folder.h"
#include "camel-store.h"
-#include "camel-vee-summary.h"
#include "camel-vee-folder.h"
+#include "camel-vee-message-info.h"
#include "camel-vee-store.h"
#include "camel-vtrash-folder.h"
#include "camel-string-utils.h"
+#include "camel-vee-summary.h"
+
#define d(x)
#define CAMEL_VEE_SUMMARY_GET_PRIVATE(obj) \
@@ -48,240 +50,6 @@ struct _CamelVeeSummaryPrivate {
G_DEFINE_TYPE (CamelVeeSummary, camel_vee_summary, CAMEL_TYPE_FOLDER_SUMMARY)
-static void
-vee_message_info_free (CamelFolderSummary *s,
- CamelMessageInfo *info)
-{
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) info;
-
- g_object_unref (mi->orig_summary);
-
- CAMEL_FOLDER_SUMMARY_CLASS (camel_vee_summary_parent_class)->message_info_free (s, info);
-}
-
-static CamelMessageInfo *
-vee_message_info_clone (CamelFolderSummary *s,
- const CamelMessageInfo *mi)
-{
- CamelVeeMessageInfo *to;
- const CamelVeeMessageInfo *from = (const CamelVeeMessageInfo *) mi;
-
- to = (CamelVeeMessageInfo *) camel_message_info_new (s);
-
- to->orig_summary = g_object_ref (from->orig_summary);
- to->info.summary = s;
- to->info.uid = camel_pstring_strdup (from->info.uid);
-
- return (CamelMessageInfo *) to;
-}
-
-#define HANDLE_NULL_INFO(value) if (!rmi) { d(g_warning (G_STRLOC ": real info is NULL for %s,
safeguarding\n", mi->uid)); return value; }
-
-static gconstpointer
-vee_info_ptr (const CamelMessageInfo *mi,
- gint id)
-{
- CamelVeeMessageInfo *vmi = (CamelVeeMessageInfo *) mi;
- CamelMessageInfo *rmi;
- gpointer p;
-
- rmi = camel_folder_summary_get (vmi->orig_summary, mi->uid + 8);
- HANDLE_NULL_INFO (NULL);
- p = (gpointer) camel_message_info_get_ptr (rmi, id);
- camel_message_info_unref (rmi);
-
- return p;
-}
-
-static guint32
-vee_info_uint32 (const CamelMessageInfo *mi,
- gint id)
-{
- CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid
+ 8);
- guint32 ret;
-
- HANDLE_NULL_INFO (0);
- ret = camel_message_info_get_uint32 (rmi, id);
- camel_message_info_unref (rmi);
-
- return ret;
-
-}
-
-static time_t
-vee_info_time (const CamelMessageInfo *mi,
- gint id)
-{
- CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid
+ 8);
- time_t ret;
-
- HANDLE_NULL_INFO (0);
- ret = camel_message_info_get_time (rmi, id);
- camel_message_info_unref (rmi);
-
- return ret;
-}
-
-static gboolean
-vee_info_user_flag (const CamelMessageInfo *mi,
- const gchar *id)
-{
- CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid
+ 8);
- gboolean ret;
-
- HANDLE_NULL_INFO (FALSE);
- ret = camel_message_info_get_user_flag (rmi, id);
- camel_message_info_unref (rmi);
-
- return ret;
-}
-
-static const gchar *
-vee_info_user_tag (const CamelMessageInfo *mi,
- const gchar *id)
-{
- CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid
+ 8);
- const gchar *ret;
-
- HANDLE_NULL_INFO ("");
- ret = camel_message_info_get_user_tag (rmi, id);
- camel_message_info_unref (rmi);
-
- return ret;
-}
-
-static void
-vee_summary_notify_mi_changed (CamelVeeFolder *vfolder,
- CamelMessageInfo *mi)
-{
- CamelFolderChangeInfo *changes;
-
- g_return_if_fail (vfolder != NULL);
- g_return_if_fail (mi != NULL);
-
- changes = camel_folder_change_info_new ();
-
- camel_folder_change_info_change_uid (changes, camel_message_info_get_uid (mi));
- camel_folder_changed (CAMEL_FOLDER (vfolder), changes);
- camel_folder_change_info_free (changes);
-}
-
-static gboolean
-vee_info_set_user_flag (CamelMessageInfo *mi,
- const gchar *name,
- gboolean value)
-{
- gint res = FALSE;
- CamelVeeFolder *vf = (CamelVeeFolder *) camel_folder_summary_get_folder (mi->summary);
-
- if (mi->uid) {
- CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary,
mi->uid + 8);
- gboolean ignore_changes = !CAMEL_IS_VTRASH_FOLDER (vf);
-
- HANDLE_NULL_INFO (FALSE);
-
- /* ignore changes done in the folder itself,
- * unless it's a vTrash or vJunk folder */
- if (ignore_changes)
- camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder
(rmi->summary));
-
- res = camel_message_info_set_user_flag (rmi, name, value);
-
- if (ignore_changes) {
- if (res)
- vee_summary_notify_mi_changed (vf, mi);
- else
- camel_vee_folder_remove_from_ignore_changed_event (vf,
camel_folder_summary_get_folder (rmi->summary));
- }
-
- camel_message_info_unref (rmi);
- }
-
- return res;
-}
-
-static gboolean
-vee_info_set_user_tag (CamelMessageInfo *mi,
- const gchar *name,
- const gchar *value)
-{
- gint res = FALSE;
-
- if (mi->uid) {
- CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary,
mi->uid + 8);
- CamelVeeFolder *vf = (CamelVeeFolder *) camel_folder_summary_get_folder (mi->summary);
- gboolean ignore_changes = !CAMEL_IS_VTRASH_FOLDER (vf);
-
- HANDLE_NULL_INFO (FALSE);
-
- /* ignore changes done in the folder itself,
- * unless it's a vTrash or vJunk folder */
- if (ignore_changes)
- camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder
(rmi->summary));
-
- res = camel_message_info_set_user_tag (rmi, name, value);
-
- if (ignore_changes) {
- if (res)
- vee_summary_notify_mi_changed (vf, mi);
- else
- camel_vee_folder_remove_from_ignore_changed_event (vf,
camel_folder_summary_get_folder (rmi->summary));
- }
-
- camel_message_info_unref (rmi);
- }
-
- return res;
-}
-
-static gboolean
-vee_info_set_flags (CamelMessageInfo *mi,
- guint32 flags,
- guint32 set)
-{
- gint res = FALSE;
- CamelVeeFolder *vf = CAMEL_VEE_FOLDER (camel_folder_summary_get_folder (mi->summary));
-
- /* first update original message info... */
- if (mi->uid) {
- CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary,
mi->uid + 8);
- gboolean ignore_changes = !CAMEL_IS_VTRASH_FOLDER (vf);
-
- HANDLE_NULL_INFO (FALSE);
-
- /* ignore changes done in the folder itself,
- * unless it's a vTrash or vJunk folder */
- if (ignore_changes)
- camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder
(rmi->summary));
-
- res = camel_message_info_set_flags (rmi, flags, set);
-
- if (res) {
- /* update flags on itself too */
- camel_folder_summary_replace_flags (mi->summary, mi);
- }
-
- if (ignore_changes) {
- if (res)
- vee_summary_notify_mi_changed (vf, mi);
- else
- camel_vee_folder_remove_from_ignore_changed_event (vf,
camel_folder_summary_get_folder (rmi->summary));
- }
-
- camel_message_info_unref (rmi);
- }
-
- /* Do not call parent class' info_set_flags, to not do flood
- * of change notifications, rather wait for a notification
- * from original folder, and propagate the change in counts
- * through camel_vee_summary_replace_flags().
- */
- /*if (res)
- CAMEL_FOLDER_SUMMARY_CLASS (camel_vee_summary_parent_class)->info_set_flags (mi, flags,
set);*/
-
- return res;
-}
-
static CamelMessageInfo *
message_info_from_uid (CamelFolderSummary *s,
const gchar *uid)
@@ -290,7 +58,6 @@ message_info_from_uid (CamelFolderSummary *s,
info = camel_folder_summary_peek_loaded (s, uid);
if (!info) {
- CamelVeeMessageInfo *vinfo;
CamelFolder *orig_folder;
/* This function isn't really nice. But no great way
@@ -305,22 +72,16 @@ message_info_from_uid (CamelFolderSummary *s,
return NULL;
}
- /* Create the info and load it, its so easy. */
- info = camel_message_info_new (s);
- info->dirty = FALSE;
- info->uid = camel_pstring_strdup (uid);
-
orig_folder = camel_vee_folder_get_vee_uid_folder (
(CamelVeeFolder *) camel_folder_summary_get_folder (s), uid);
g_return_val_if_fail (orig_folder != NULL, NULL);
- vinfo = (CamelVeeMessageInfo *) info;
- vinfo->orig_summary = orig_folder->summary;
+ /* Create the info and load it, its so easy. */
+ info = camel_vee_message_info_new (s, camel_folder_get_folder_summary (orig_folder), uid);
- g_object_ref (vinfo->orig_summary);
- camel_message_info_ref (info);
+ camel_message_info_set_dirty (info, FALSE);
- camel_folder_summary_insert (s, info, FALSE);
+ camel_folder_summary_add (s, info, TRUE);
}
return info;
@@ -351,18 +112,7 @@ camel_vee_summary_class_init (CamelVeeSummaryClass *class)
object_class->finalize = vee_summary_finalize;
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
- folder_summary_class->message_info_size = sizeof (CamelVeeMessageInfo);
- folder_summary_class->content_info_size = 0;
- folder_summary_class->message_info_clone = vee_message_info_clone;
- folder_summary_class->message_info_free = vee_message_info_free;
- folder_summary_class->info_ptr = vee_info_ptr;
- folder_summary_class->info_uint32 = vee_info_uint32;
- folder_summary_class->info_time = vee_info_time;
- folder_summary_class->info_user_flag = vee_info_user_flag;
- folder_summary_class->info_user_tag = vee_info_user_tag;
- folder_summary_class->info_set_user_flag = vee_info_set_user_flag;
- folder_summary_class->info_set_user_tag = vee_info_set_user_tag;
- folder_summary_class->info_set_flags = vee_info_set_flags;
+ folder_summary_class->message_info_type = CAMEL_TYPE_VEE_MESSAGE_INFO;
folder_summary_class->message_info_from_uid = message_info_from_uid;
}
@@ -395,12 +145,12 @@ camel_vee_summary_new (CamelFolder *parent)
const gchar *full_name;
summary = g_object_new (CAMEL_TYPE_VEE_SUMMARY, "folder", parent, NULL);
- summary->flags |= CAMEL_FOLDER_SUMMARY_IN_MEMORY_ONLY;
+ camel_folder_summary_set_flags (summary, camel_folder_summary_get_flags (summary) |
CAMEL_FOLDER_SUMMARY_IN_MEMORY_ONLY);
/* not using DB for vee folder summaries, drop the table */
full_name = camel_folder_get_full_name (parent);
parent_store = camel_folder_get_parent_store (parent);
- camel_db_delete_folder (parent_store->cdb_w, full_name, NULL);
+ camel_db_delete_folder (camel_store_get_db (parent_store), full_name, NULL);
return summary;
}
@@ -431,7 +181,7 @@ camel_vee_summary_get_uids_for_subfolder (CamelVeeSummary *summary,
g_return_val_if_fail (CAMEL_IS_VEE_SUMMARY (summary), NULL);
g_return_val_if_fail (CAMEL_IS_FOLDER (subfolder), NULL);
- camel_folder_summary_lock (&summary->summary);
+ camel_folder_summary_lock (CAMEL_FOLDER_SUMMARY (summary));
/* uses direct hash, because strings are supposed to be from the string pool */
known_uids = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify)
camel_pstring_free, NULL);
@@ -441,14 +191,22 @@ camel_vee_summary_get_uids_for_subfolder (CamelVeeSummary *summary,
g_hash_table_foreach (vuids, get_uids_for_subfolder, known_uids);
}
- camel_folder_summary_unlock (&summary->summary);
+ camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (summary));
return known_uids;
}
-/* unref returned pointer with camel_message_info_unref() */
+/**
+ * camel_vee_summary_add:
+ * @summary: the CamelVeeSummary
+ * @mi_data: (type CamelVeeMessageInfoData): the #CamelVeeMessageInfoData to add
+ *
+ * Unref returned pointer with g_object_unref()
+ *
+ * Returns: (transfer full): A new #CamelVeeMessageInfo object.
+ **/
CamelVeeMessageInfo *
-camel_vee_summary_add (CamelVeeSummary *s,
+camel_vee_summary_add (CamelVeeSummary *summary,
CamelVeeMessageInfoData *mi_data)
{
CamelVeeMessageInfo *vmi;
@@ -457,44 +215,39 @@ camel_vee_summary_add (CamelVeeSummary *s,
CamelFolder *orig_folder;
GHashTable *vuids;
- g_return_val_if_fail (CAMEL_IS_VEE_SUMMARY (s), NULL);
+ g_return_val_if_fail (CAMEL_IS_VEE_SUMMARY (summary), NULL);
g_return_val_if_fail (CAMEL_IS_VEE_MESSAGE_INFO_DATA (mi_data), NULL);
- camel_folder_summary_lock (&s->summary);
+ camel_folder_summary_lock (CAMEL_FOLDER_SUMMARY (summary));
sf_data = camel_vee_message_info_data_get_subfolder_data (mi_data);
vuid = camel_vee_message_info_data_get_vee_message_uid (mi_data);
orig_folder = camel_vee_subfolder_data_get_folder (sf_data);
- vmi = (CamelVeeMessageInfo *) camel_folder_summary_peek_loaded (&s->summary, vuid);
+ vmi = (CamelVeeMessageInfo *) camel_folder_summary_peek_loaded (CAMEL_FOLDER_SUMMARY (summary), vuid);
if (vmi) {
/* Possible that the entry is loaded, see if it has the summary */
d (g_message ("%s - already there\n", vuid));
- if (!vmi->orig_summary)
- vmi->orig_summary = g_object_ref (orig_folder->summary);
+ g_warn_if_fail (camel_vee_message_info_get_original_summary (vmi) != NULL);
- camel_folder_summary_unlock (&s->summary);
+ camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (summary));
return vmi;
}
- vmi = (CamelVeeMessageInfo *) camel_message_info_new (&s->summary);
- vmi->orig_summary = g_object_ref (orig_folder->summary);
- vmi->info.uid = (gchar *) camel_pstring_strdup (vuid);
-
- camel_message_info_ref (vmi);
+ vmi = (CamelVeeMessageInfo *) camel_vee_message_info_new (CAMEL_FOLDER_SUMMARY (summary),
camel_folder_get_folder_summary (orig_folder), vuid);
- vuids = g_hash_table_lookup (s->priv->vuids_by_subfolder, orig_folder);
+ vuids = g_hash_table_lookup (summary->priv->vuids_by_subfolder, orig_folder);
if (vuids) {
g_hash_table_insert (vuids, (gpointer) camel_pstring_strdup (vuid), GINT_TO_POINTER (1));
} else {
vuids = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify)
camel_pstring_free, NULL);
g_hash_table_insert (vuids, (gpointer) camel_pstring_strdup (vuid), GINT_TO_POINTER (1));
- g_hash_table_insert (s->priv->vuids_by_subfolder, orig_folder, vuids);
+ g_hash_table_insert (summary->priv->vuids_by_subfolder, orig_folder, vuids);
}
- camel_folder_summary_insert (&s->summary, (CamelMessageInfo *) vmi, FALSE);
- camel_folder_summary_unlock (&s->summary);
+ camel_folder_summary_add (CAMEL_FOLDER_SUMMARY (summary), (CamelMessageInfo *) vmi, TRUE);
+ camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (summary));
return vmi;
}
@@ -518,7 +271,7 @@ camel_vee_summary_remove (CamelVeeSummary *summary,
g_return_if_fail (vuid != NULL);
g_return_if_fail (subfolder != NULL);
- camel_folder_summary_lock (&summary->summary);
+ camel_folder_summary_lock (CAMEL_FOLDER_SUMMARY (summary));
vuids = g_hash_table_lookup (summary->priv->vuids_by_subfolder, subfolder);
if (vuids) {
@@ -527,18 +280,18 @@ camel_vee_summary_remove (CamelVeeSummary *summary,
g_hash_table_remove (summary->priv->vuids_by_subfolder, subfolder);
}
- mi = camel_folder_summary_peek_loaded (&summary->summary, vuid);
+ mi = camel_folder_summary_peek_loaded (CAMEL_FOLDER_SUMMARY (summary), vuid);
- camel_folder_summary_remove_uid (&summary->summary, vuid);
+ camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (summary), vuid);
if (mi) {
/* under twice, the first for camel_folder_summary_peek_loaded(),
* the second to actually free the mi */
- camel_message_info_unref (mi);
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
+ g_clear_object (&mi);
}
- camel_folder_summary_unlock (&summary->summary);
+ camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (summary));
}
/**
@@ -561,16 +314,16 @@ camel_vee_summary_replace_flags (CamelVeeSummary *summary,
g_return_if_fail (CAMEL_IS_VEE_SUMMARY (summary));
g_return_if_fail (uid != NULL);
- camel_folder_summary_lock (&summary->summary);
+ camel_folder_summary_lock (CAMEL_FOLDER_SUMMARY (summary));
- mi = camel_folder_summary_get (&summary->summary, uid);
+ mi = camel_folder_summary_get (CAMEL_FOLDER_SUMMARY (summary), uid);
if (!mi) {
- camel_folder_summary_unlock (&summary->summary);
+ camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (summary));
return;
}
- camel_folder_summary_replace_flags (&summary->summary, mi);
- camel_message_info_unref (mi);
+ camel_folder_summary_replace_flags (CAMEL_FOLDER_SUMMARY (summary), mi);
+ g_clear_object (&mi);
- camel_folder_summary_unlock (&summary->summary);
+ camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (summary));
}
diff --git a/src/camel/camel-vee-summary.h b/src/camel/camel-vee-summary.h
index 94a95dc..5bdfdac 100644
--- a/src/camel/camel-vee-summary.h
+++ b/src/camel/camel-vee-summary.h
@@ -25,6 +25,7 @@
#define CAMEL_VEE_SUMMARY_H
#include <camel/camel-folder-summary.h>
+#include <camel/camel-vee-message-info.h>
/* Standard GObject macros */
#define CAMEL_TYPE_VEE_SUMMARY \
@@ -55,28 +56,24 @@ typedef struct _CamelVeeSummary CamelVeeSummary;
typedef struct _CamelVeeSummaryClass CamelVeeSummaryClass;
typedef struct _CamelVeeSummaryPrivate CamelVeeSummaryPrivate;
-typedef struct _CamelVeeMessageInfo CamelVeeMessageInfo;
-
-struct _CamelVeeMessageInfo {
- CamelMessageInfoBase info;
- CamelFolderSummary *orig_summary;
-};
-
struct _CamelVeeSummary {
- CamelFolderSummary summary;
+ CamelFolderSummary parent;
CamelVeeSummaryPrivate *priv;
};
struct _CamelVeeSummaryClass {
CamelFolderSummaryClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_vee_summary_get_type (void);
CamelFolderSummary *
- camel_vee_summary_new (struct _CamelFolder *parent);
+ camel_vee_summary_new (CamelFolder *parent);
CamelVeeMessageInfo *
- camel_vee_summary_add (CamelVeeSummary *s,
+ camel_vee_summary_add (CamelVeeSummary *summary,
struct _CamelVeeMessageInfoData *mi_data);
void camel_vee_summary_remove (CamelVeeSummary *summary,
const gchar *vuid,
diff --git a/src/camel/camel-vtrash-folder.c b/src/camel/camel-vtrash-folder.c
index b8eef41..79198e8 100644
--- a/src/camel/camel-vtrash-folder.c
+++ b/src/camel/camel-vtrash-folder.c
@@ -31,6 +31,11 @@
#include "camel-vtrash-folder.h"
#include "camel-string-utils.h"
+struct _CamelVTrashFolderPrivate {
+ CamelVTrashFolderType type;
+ guint32 bit;
+};
+
static struct {
const gchar *full_name;
const gchar *name;
@@ -79,7 +84,7 @@ transfer_messages (CamelFolder *folder,
CamelMessageInfo *mi = camel_folder_get_message_info (md->source_folder,
md->source_uids->pdata[i]);
if (mi) {
camel_message_info_set_flags (mi, md->sbit, md->sbit);
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
}
}
@@ -104,7 +109,7 @@ vtrash_folder_append_message_sync (CamelFolder *folder,
{
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, "%s",
- _(vdata[((CamelVTrashFolder *) folder)->type].error_copy));
+ _(vdata[((CamelVTrashFolder *) folder)->priv->type].error_copy));
return FALSE;
}
@@ -123,7 +128,7 @@ vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
GHashTable *batch = NULL;
const gchar *tuid;
struct _transfer_data *md;
- guint32 sbit = ((CamelVTrashFolder *) source)->bit;
+ guint32 sbit = ((CamelVTrashFolder *) source)->priv->bit;
/* This is a special case of transfer_messages_to: Either the
* source or the destination is a vtrash folder (but not both
@@ -138,7 +143,7 @@ vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
if (!delete_originals) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, "%s",
- _(vdata[((CamelVTrashFolder *) dest)->type].error_copy));
+ _(vdata[((CamelVTrashFolder *) dest)->priv->type].error_copy));
return FALSE;
}
@@ -146,7 +151,7 @@ vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
for (i = 0; i < uids->len; i++)
camel_folder_set_message_flags (
source, uids->pdata[i],
- ((CamelVTrashFolder *) dest)->bit, ~0);
+ ((CamelVTrashFolder *) dest)->priv->bit, ~0);
return TRUE;
}
@@ -166,18 +171,18 @@ vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
continue;
}
- if (dest == camel_folder_summary_get_folder (mi->orig_summary)) {
+ if (dest == camel_vee_message_info_get_original_folder (mi)) {
/* Just unset the flag on the original message */
camel_folder_set_message_flags (
source, uids->pdata[i], sbit, 0);
} else {
if (batch == NULL)
batch = g_hash_table_new (NULL, NULL);
- md = g_hash_table_lookup (batch, camel_folder_summary_get_folder (mi->orig_summary));
+ md = g_hash_table_lookup (batch, camel_vee_message_info_get_original_folder (mi));
if (md == NULL) {
md = g_malloc0 (sizeof (*md));
md->cancellable = cancellable;
- md->folder = g_object_ref (camel_folder_summary_get_folder
(mi->orig_summary));
+ md->folder = g_object_ref (camel_vee_message_info_get_original_folder (mi));
md->uids = g_ptr_array_new ();
md->dest = dest;
md->delete = delete_originals;
@@ -187,7 +192,7 @@ vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
if (cancellable != NULL)
g_object_ref (cancellable);
camel_folder_freeze (md->folder);
- g_hash_table_insert (batch, camel_folder_summary_get_folder
(mi->orig_summary), md);
+ g_hash_table_insert (batch, camel_vee_message_info_get_original_folder (mi),
md);
}
/* unset the bit temporarily */
@@ -199,7 +204,7 @@ vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
g_ptr_array_add (md->uids, g_strdup (tuid));
g_ptr_array_add (md->source_uids, uids->pdata[i]);
}
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
}
if (batch) {
@@ -218,6 +223,8 @@ camel_vtrash_folder_class_init (CamelVTrashFolderClass *class)
{
CamelFolderClass *folder_class;
+ g_type_class_add_private (class, sizeof (CamelVTrashFolderPrivate));
+
folder_class = CAMEL_FOLDER_CLASS (class);
folder_class->append_message_sync = vtrash_folder_append_message_sync;
folder_class->transfer_messages_to_sync = vtrash_folder_transfer_messages_to_sync;
@@ -226,6 +233,7 @@ camel_vtrash_folder_class_init (CamelVTrashFolderClass *class)
static void
camel_vtrash_folder_init (CamelVTrashFolder *vtrash_folder)
{
+ vtrash_folder->priv = G_TYPE_INSTANCE_GET_PRIVATE (vtrash_folder, CAMEL_TYPE_VTRASH_FOLDER,
CamelVTrashFolderPrivate);
}
/**
@@ -257,10 +265,26 @@ camel_vtrash_folder_new (CamelStore *parent_store,
CAMEL_STORE_FOLDER_PRIVATE |
CAMEL_STORE_FOLDER_CREATE);
- ((CamelFolder *) vtrash)->folder_flags |= vdata[type].flags;
+ camel_folder_set_flags (CAMEL_FOLDER (vtrash), camel_folder_get_flags (CAMEL_FOLDER (vtrash)) |
vdata[type].flags);
camel_vee_folder_set_expression ((CamelVeeFolder *) vtrash, vdata[type].expr);
- vtrash->bit = vdata[type].bit;
- vtrash->type = type;
+ vtrash->priv->bit = vdata[type].bit;
+ vtrash->priv->type = type;
return (CamelFolder *) vtrash;
}
+
+/**
+ * camel_vtrash_folder_get_folder_type:
+ * @vtrash_folder: a #CamelVTrashFolder
+ *
+ * Returns: a @vtrash_folder folder type (#CamelVTrashFolderType)
+ *
+ * Since: 3.24
+ **/
+CamelVTrashFolderType
+camel_vtrash_folder_get_folder_type (CamelVTrashFolder *vtrash_folder)
+{
+ g_return_val_if_fail (CAMEL_IS_VTRASH_FOLDER (vtrash_folder), CAMEL_VTRASH_FOLDER_LAST);
+
+ return vtrash_folder->priv->type;
+}
diff --git a/src/camel/camel-vtrash-folder.h b/src/camel/camel-vtrash-folder.h
index bf0c6d4..94bd73b 100644
--- a/src/camel/camel-vtrash-folder.h
+++ b/src/camel/camel-vtrash-folder.h
@@ -53,6 +53,7 @@ G_BEGIN_DECLS
typedef struct _CamelVTrashFolder CamelVTrashFolder;
typedef struct _CamelVTrashFolderClass CamelVTrashFolderClass;
+typedef struct _CamelVTrashFolderPrivate CamelVTrashFolderPrivate;
typedef enum {
CAMEL_VTRASH_FOLDER_TRASH,
@@ -62,18 +63,22 @@ typedef enum {
struct _CamelVTrashFolder {
CamelVeeFolder parent;
-
- CamelVTrashFolderType type;
- guint32 bit;
+ CamelVTrashFolderPrivate *priv;
};
struct _CamelVTrashFolderClass {
CamelVeeFolderClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_vtrash_folder_get_type (void);
CamelFolder * camel_vtrash_folder_new (CamelStore *parent_store,
CamelVTrashFolderType type);
+CamelVTrashFolderType
+ camel_vtrash_folder_get_folder_type
+ (CamelVTrashFolder *vtrash_folder);
G_END_DECLS
diff --git a/src/camel/camel.h b/src/camel/camel.h
index 5710717..b405baf 100644
--- a/src/camel/camel.h
+++ b/src/camel/camel.h
@@ -56,6 +56,8 @@
#include <camel/camel-medium.h>
#include <camel/camel-memchunk.h>
#include <camel/camel-mempool.h>
+#include <camel/camel-message-info.h>
+#include <camel/camel-message-info-base.h>
#include <camel/camel-mime-filter.h>
#include <camel/camel-mime-filter-basic.h>
#include <camel/camel-mime-filter-bestenc.h>
@@ -83,6 +85,8 @@
#include <camel/camel-multipart.h>
#include <camel/camel-multipart-encrypted.h>
#include <camel/camel-multipart-signed.h>
+#include <camel/camel-named-flags.h>
+#include <camel/camel-name-value-array.h>
#include <camel/camel-net-utils.h>
#include <camel/camel-network-service.h>
#include <camel/camel-nntp-address.h>
@@ -128,8 +132,10 @@
#include <camel/camel-url.h>
#include <camel/camel-url-scanner.h>
#include <camel/camel-utf8.h>
+#include <camel/camel-utils.h>
#include <camel/camel-vee-data-cache.h>
#include <camel/camel-vee-folder.h>
+#include <camel/camel-vee-message-info.h>
#include <camel/camel-vee-store.h>
#include <camel/camel-vee-summary.h>
#include <camel/camel-vtrash-folder.h>
diff --git a/src/camel/providers/imapx/CMakeLists.txt b/src/camel/providers/imapx/CMakeLists.txt
index 5395f24..dcdf24b 100644
--- a/src/camel/providers/imapx/CMakeLists.txt
+++ b/src/camel/providers/imapx/CMakeLists.txt
@@ -16,6 +16,8 @@ set(SOURCES
camel-imapx-logger.h
camel-imapx-mailbox.c
camel-imapx-mailbox.h
+ camel-imapx-message-info.c
+ camel-imapx-message-info.h
camel-imapx-namespace.c
camel-imapx-namespace.h
camel-imapx-namespace-response.c
diff --git a/src/camel/providers/imapx/camel-imapx-command.c b/src/camel/providers/imapx/camel-imapx-command.c
index cf54416..7e9ec7f 100644
--- a/src/camel/providers/imapx/camel-imapx-command.c
+++ b/src/camel/providers/imapx/camel-imapx-command.c
@@ -188,7 +188,7 @@ camel_imapx_command_addv (CamelIMAPXCommand *ic,
gint d;
glong l;
guint32 f;
- CamelFlag *F;
+ const CamelNamedFlags *F;
CamelDataWrapper *D;
CamelSasl *A;
gchar literal_format[16];
@@ -307,7 +307,7 @@ camel_imapx_command_addv (CamelIMAPXCommand *ic,
goto output_string;
case 'F': /* IMAP flags set */
f = va_arg (ap, guint32);
- F = va_arg (ap, CamelFlag *);
+ F = va_arg (ap, const CamelNamedFlags *);
imapx_write_flags (buffer, f, F);
break;
case 'c':
diff --git a/src/camel/providers/imapx/camel-imapx-conn-manager.c
b/src/camel/providers/imapx/camel-imapx-conn-manager.c
index 983c69b..e82de56 100644
--- a/src/camel/providers/imapx/camel-imapx-conn-manager.c
+++ b/src/camel/providers/imapx/camel-imapx-conn-manager.c
@@ -1654,7 +1654,7 @@ imapx_conn_manager_move_to_real_trash_sync (CamelIMAPXConnManager *conn_man,
destination = camel_imapx_folder_list_mailbox (
CAMEL_IMAPX_FOLDER (folder),
cancellable, error);
- folder_deleted_count = camel_folder_summary_get_deleted_count (folder->summary);
+ folder_deleted_count = camel_folder_summary_get_deleted_count
(camel_folder_get_folder_summary (folder));
g_object_unref (folder);
}
diff --git a/src/camel/providers/imapx/camel-imapx-conn-manager.h
b/src/camel/providers/imapx/camel-imapx-conn-manager.h
index f0edd54..eac6db2 100644
--- a/src/camel/providers/imapx/camel-imapx-conn-manager.h
+++ b/src/camel/providers/imapx/camel-imapx-conn-manager.h
@@ -64,6 +64,9 @@ struct _CamelIMAPXConnManagerClass {
/* Signals */
void (* connection_created) (CamelIMAPXConnManager *conn_man,
CamelIMAPXServer *server);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_conn_manager_get_type (void);
diff --git a/src/camel/providers/imapx/camel-imapx-folder.c b/src/camel/providers/imapx/camel-imapx-folder.c
index 0d73287..2d1080e 100644
--- a/src/camel/providers/imapx/camel-imapx-folder.c
+++ b/src/camel/providers/imapx/camel-imapx-folder.c
@@ -207,7 +207,7 @@ imapx_folder_dispose (GObject *object)
if (store != NULL) {
camel_store_summary_disconnect_folder_summary (
CAMEL_IMAPX_STORE (store)->summary,
- CAMEL_FOLDER (folder)->summary);
+ camel_folder_get_folder_summary (CAMEL_FOLDER (folder)));
}
g_weak_ref_set (&folder->priv->mailbox, NULL);
@@ -442,7 +442,7 @@ imapx_append_message_sync (CamelFolder *folder,
goto exit;
success = camel_imapx_conn_manager_append_message_sync (
- conn_man, mailbox, folder->summary,
+ conn_man, mailbox, camel_folder_get_folder_summary (folder),
CAMEL_IMAPX_FOLDER (folder)->cache, message,
info, appended_uid, cancellable, error);
@@ -475,7 +475,7 @@ imapx_expunge_sync (CamelFolder *folder,
if (mailbox == NULL)
goto exit;
- if ((store->flags & CAMEL_STORE_VTRASH) == 0) {
+ if ((camel_store_get_flags (store) & CAMEL_STORE_VTRASH) == 0) {
CamelFolder *trash;
const gchar *full_name;
@@ -484,25 +484,27 @@ imapx_expunge_sync (CamelFolder *folder,
trash = camel_store_get_trash_folder_sync (store, cancellable, &local_error);
if (local_error == NULL && trash && (folder == trash || g_ascii_strcasecmp (full_name,
camel_folder_get_full_name (trash)) == 0)) {
+ CamelFolderSummary *folder_summary;
CamelMessageInfo *info;
GPtrArray *known_uids;
gint ii;
- camel_folder_summary_lock (folder->summary);
+ folder_summary = camel_folder_get_folder_summary (folder);
+ camel_folder_summary_lock (folder_summary);
- camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
- known_uids = camel_folder_summary_get_array (folder->summary);
+ camel_folder_summary_prepare_fetch_all (folder_summary, NULL);
+ known_uids = camel_folder_summary_get_array (folder_summary);
/* it's a real trash folder, thus delete all mails from there */
for (ii = 0; known_uids && ii < known_uids->len; ii++) {
- info = camel_folder_summary_get (folder->summary, g_ptr_array_index
(known_uids, ii));
+ info = camel_folder_summary_get (camel_folder_get_folder_summary (folder),
g_ptr_array_index (known_uids, ii));
if (info) {
camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED,
CAMEL_MESSAGE_DELETED);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
}
- camel_folder_summary_unlock (folder->summary);
+ camel_folder_summary_unlock (folder_summary);
camel_folder_summary_free_array (known_uids);
}
@@ -609,7 +611,7 @@ imapx_get_message_sync (CamelFolder *folder,
return NULL;
stream = camel_imapx_conn_manager_get_message_sync (
- conn_man, mailbox, folder->summary,
+ conn_man, mailbox, camel_folder_get_folder_summary (folder),
CAMEL_IMAPX_FOLDER (folder)->cache, uid,
cancellable, error);
@@ -635,7 +637,7 @@ imapx_get_message_sync (CamelFolder *folder,
if (msg != NULL) {
CamelMessageInfo *mi;
- mi = camel_folder_summary_get (folder->summary, uid);
+ mi = camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid);
if (mi != NULL) {
CamelMessageFlags flags;
gboolean has_attachment;
@@ -649,7 +651,7 @@ imapx_get_message_sync (CamelFolder *folder,
has_attachment ? CAMEL_MESSAGE_ATTACHMENTS : 0);
}
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
}
}
@@ -781,7 +783,7 @@ imapx_synchronize_sync (CamelFolder *folder,
success = mailbox != NULL;
} else {
success = camel_imapx_conn_manager_sync_changes_sync (conn_man, mailbox, cancellable, error);
- if (success && expunge && camel_folder_summary_get_deleted_count (folder->summary) > 0) {
+ if (success && expunge && camel_folder_summary_get_deleted_count
(camel_folder_get_folder_summary (folder)) > 0) {
success = camel_imapx_conn_manager_expunge_sync (conn_man, mailbox, cancellable,
error);
}
}
@@ -815,7 +817,7 @@ imapx_synchronize_message_sync (CamelFolder *folder,
goto exit;
success = camel_imapx_conn_manager_sync_message_sync (
- conn_man, mailbox, folder->summary,
+ conn_man, mailbox, camel_folder_get_folder_summary (folder),
CAMEL_IMAPX_FOLDER (folder)->cache, uid,
cancellable, error);
@@ -900,6 +902,17 @@ imapx_folder_changed (CamelFolder *folder,
CAMEL_FOLDER_CLASS (camel_imapx_folder_parent_class)->changed (folder, info);
}
+static guint32
+imapx_get_permanent_flags (CamelFolder *folder)
+{
+ return CAMEL_MESSAGE_ANSWERED |
+ CAMEL_MESSAGE_DELETED |
+ CAMEL_MESSAGE_DRAFT |
+ CAMEL_MESSAGE_FLAGGED |
+ CAMEL_MESSAGE_SEEN |
+ CAMEL_MESSAGE_USER;
+}
+
static void
imapx_rename (CamelFolder *folder,
const gchar *new_name)
@@ -912,7 +925,7 @@ imapx_rename (CamelFolder *folder,
imapx_store = CAMEL_IMAPX_STORE (store);
camel_store_summary_disconnect_folder_summary (
- imapx_store->summary, folder->summary);
+ imapx_store->summary, camel_folder_get_folder_summary (folder));
/* Chain up to parent's rename() method. */
CAMEL_FOLDER_CLASS (camel_imapx_folder_parent_class)->
@@ -921,7 +934,7 @@ imapx_rename (CamelFolder *folder,
folder_name = camel_folder_get_full_name (folder);
camel_store_summary_connect_folder_summary (
- imapx_store->summary, folder_name, folder->summary);
+ imapx_store->summary, folder_name, camel_folder_get_folder_summary (folder));
}
static void
@@ -939,6 +952,7 @@ camel_imapx_folder_class_init (CamelIMAPXFolderClass *class)
object_class->finalize = imapx_folder_finalize;
folder_class = CAMEL_FOLDER_CLASS (class);
+ folder_class->get_permanent_flags = imapx_get_permanent_flags;
folder_class->rename = imapx_rename;
folder_class->search_by_expression = imapx_search_by_expression;
folder_class->search_by_uids = imapx_search_by_uids;
@@ -1012,15 +1026,7 @@ camel_imapx_folder_init (CamelIMAPXFolder *imapx_folder)
imapx_folder->priv = CAMEL_IMAPX_FOLDER_GET_PRIVATE (imapx_folder);
- folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY;
-
- folder->permanent_flags =
- CAMEL_MESSAGE_ANSWERED |
- CAMEL_MESSAGE_DELETED |
- CAMEL_MESSAGE_DRAFT |
- CAMEL_MESSAGE_FLAGGED |
- CAMEL_MESSAGE_SEEN |
- CAMEL_MESSAGE_USER;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) |
CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY);
camel_folder_set_lock_async (folder, TRUE);
@@ -1043,6 +1049,7 @@ camel_imapx_folder_new (CamelStore *store,
GError **error)
{
CamelFolder *folder;
+ CamelFolderSummary *folder_summary;
CamelService *service;
CamelSettings *settings;
CamelIMAPXFolder *imapx_folder;
@@ -1052,6 +1059,7 @@ camel_imapx_folder_new (CamelStore *store,
gboolean filter_inbox;
gboolean filter_junk;
gboolean filter_junk_inbox;
+ guint32 add_folder_flags = 0;
d ("opening imap folder '%s'\n", folder_dir);
@@ -1081,21 +1089,25 @@ camel_imapx_folder_new (CamelStore *store,
"full_name", folder_name,
"parent-store", store, NULL);
- folder->summary = camel_imapx_summary_new (folder);
- if (folder->summary == NULL) {
+ folder_summary = camel_imapx_summary_new (folder);
+ if (!folder_summary) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Could not create folder summary for %s"),
short_name);
+ g_object_unref (folder);
return NULL;
}
+ camel_folder_take_folder_summary (folder, folder_summary);
+
imapx_folder = CAMEL_IMAPX_FOLDER (folder);
imapx_folder->cache = camel_data_cache_new (folder_dir, error);
if (imapx_folder->cache == NULL) {
g_prefix_error (
error, _("Could not create cache for %s: "),
short_name);
+ g_object_unref (folder);
return NULL;
}
@@ -1118,25 +1130,27 @@ camel_imapx_folder_new (CamelStore *store,
imapx_folder->search = camel_imapx_search_new (CAMEL_IMAPX_STORE (store));
if (filter_all)
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+ add_folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
if (camel_imapx_mailbox_is_inbox (folder_name)) {
if (filter_inbox)
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+ add_folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
if (filter_junk)
- folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
+ add_folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
} else {
if (filter_junk && !filter_junk_inbox)
- folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
+ add_folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
if (imapx_folder_get_apply_filters (imapx_folder))
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+ add_folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
}
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) | add_folder_flags);
+
camel_store_summary_connect_folder_summary (
CAMEL_IMAPX_STORE (store)->summary,
- folder_name, folder->summary);
+ folder_name, camel_folder_get_folder_summary (folder));
return folder;
}
@@ -1188,7 +1202,7 @@ camel_imapx_folder_set_mailbox (CamelIMAPXFolder *folder,
g_weak_ref_set (&folder->priv->mailbox, mailbox);
- imapx_summary = CAMEL_IMAPX_SUMMARY (CAMEL_FOLDER (folder)->summary);
+ imapx_summary = CAMEL_IMAPX_SUMMARY (camel_folder_get_folder_summary (CAMEL_FOLDER (folder)));
uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
if (uidvalidity > 0 && uidvalidity != imapx_summary->validity)
@@ -1330,7 +1344,7 @@ camel_imapx_folder_copy_message_map (CamelIMAPXFolder *folder)
g_return_val_if_fail (CAMEL_IS_IMAPX_FOLDER (folder), NULL);
- summary = CAMEL_FOLDER (folder)->summary;
+ summary = camel_folder_get_folder_summary (CAMEL_FOLDER (folder));
array = camel_folder_summary_get_array (summary);
camel_folder_sort_uids (CAMEL_FOLDER (folder), array);
@@ -1366,7 +1380,7 @@ camel_imapx_folder_add_move_to_real_junk (CamelIMAPXFolder *folder,
{
g_return_if_fail (CAMEL_IS_IMAPX_FOLDER (folder));
g_return_if_fail (message_uid != NULL);
- g_return_if_fail (camel_folder_summary_check_uid (CAMEL_FOLDER (folder)->summary, message_uid));
+ g_return_if_fail (camel_folder_summary_check_uid (camel_folder_get_folder_summary (CAMEL_FOLDER
(folder)), message_uid));
g_mutex_lock (&folder->priv->move_to_hash_table_lock);
@@ -1397,7 +1411,7 @@ camel_imapx_folder_add_move_to_real_trash (CamelIMAPXFolder *folder,
{
g_return_if_fail (CAMEL_IS_IMAPX_FOLDER (folder));
g_return_if_fail (message_uid != NULL);
- g_return_if_fail (camel_folder_summary_check_uid (CAMEL_FOLDER (folder)->summary, message_uid));
+ g_return_if_fail (camel_folder_summary_check_uid (camel_folder_get_folder_summary (CAMEL_FOLDER
(folder)), message_uid));
g_mutex_lock (&folder->priv->move_to_hash_table_lock);
@@ -1434,7 +1448,7 @@ camel_imapx_folder_invalidate_local_cache (CamelIMAPXFolder *folder,
g_return_if_fail (CAMEL_IS_IMAPX_FOLDER (folder));
g_return_if_fail (new_uidvalidity > 0);
- summary = CAMEL_FOLDER (folder)->summary;
+ summary = camel_folder_get_folder_summary (CAMEL_FOLDER (folder));
changes = camel_folder_change_info_new ();
array = camel_folder_summary_get_array (summary);
@@ -1446,7 +1460,7 @@ camel_imapx_folder_invalidate_local_cache (CamelIMAPXFolder *folder,
CAMEL_IMAPX_SUMMARY (summary)->validity = new_uidvalidity;
camel_folder_summary_touch (summary);
- camel_folder_summary_save_to_db (summary, NULL);
+ camel_folder_summary_save (summary, NULL);
camel_data_cache_clear (folder->cache, "cache");
camel_data_cache_clear (folder->cache, "cur");
diff --git a/src/camel/providers/imapx/camel-imapx-folder.h b/src/camel/providers/imapx/camel-imapx-folder.h
index 12c3d9b..98d4bc0 100644
--- a/src/camel/providers/imapx/camel-imapx-folder.h
+++ b/src/camel/providers/imapx/camel-imapx-folder.h
@@ -65,6 +65,9 @@ struct _CamelIMAPXFolder {
struct _CamelIMAPXFolderClass {
CamelOfflineFolderClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_folder_get_type (void);
diff --git a/src/camel/providers/imapx/camel-imapx-input-stream.h
b/src/camel/providers/imapx/camel-imapx-input-stream.h
index e379a3a..f2a7cc4 100644
--- a/src/camel/providers/imapx/camel-imapx-input-stream.h
+++ b/src/camel/providers/imapx/camel-imapx-input-stream.h
@@ -68,6 +68,9 @@ struct _CamelIMAPXInputStream {
struct _CamelIMAPXInputStreamClass {
GFilterInputStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GQuark camel_imapx_error_quark (void) G_GNUC_CONST;
diff --git a/src/camel/providers/imapx/camel-imapx-job.h b/src/camel/providers/imapx/camel-imapx-job.h
index de0c5d1..b27de5f 100644
--- a/src/camel/providers/imapx/camel-imapx-job.h
+++ b/src/camel/providers/imapx/camel-imapx-job.h
@@ -121,4 +121,3 @@ void camel_imapx_job_wait_sync (CamelIMAPXJob *job,
G_END_DECLS
#endif /* CAMEL_IMAPX_JOB_H */
-
diff --git a/src/camel/providers/imapx/camel-imapx-list-response.h
b/src/camel/providers/imapx/camel-imapx-list-response.h
index b0419bf..3fdb38d 100644
--- a/src/camel/providers/imapx/camel-imapx-list-response.h
+++ b/src/camel/providers/imapx/camel-imapx-list-response.h
@@ -84,6 +84,9 @@ struct _CamelIMAPXListResponse {
struct _CamelIMAPXListResponseClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_list_response_get_type
diff --git a/src/camel/providers/imapx/camel-imapx-logger.h b/src/camel/providers/imapx/camel-imapx-logger.h
index cdf9231..d697ad4 100644
--- a/src/camel/providers/imapx/camel-imapx-logger.h
+++ b/src/camel/providers/imapx/camel-imapx-logger.h
@@ -60,6 +60,9 @@ struct _CamelIMAPXLogger {
struct _CamelIMAPXLoggerClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_logger_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/providers/imapx/camel-imapx-mailbox.h b/src/camel/providers/imapx/camel-imapx-mailbox.h
index 9ec86df..9421457 100644
--- a/src/camel/providers/imapx/camel-imapx-mailbox.h
+++ b/src/camel/providers/imapx/camel-imapx-mailbox.h
@@ -69,6 +69,9 @@ struct _CamelIMAPXMailbox {
struct _CamelIMAPXMailboxClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_mailbox_get_type
diff --git a/src/camel/providers/imapx/camel-imapx-message-info.c
b/src/camel/providers/imapx/camel-imapx-message-info.c
new file mode 100644
index 0000000..c7d7fe4
--- /dev/null
+++ b/src/camel/providers/imapx/camel-imapx-message-info.c
@@ -0,0 +1,435 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "camel/camel.h"
+#include "camel-imapx-summary.h"
+
+#include "camel-imapx-message-info.h"
+
+struct _CamelIMAPXMessageInfoPrivate {
+ guint32 server_flags;
+ CamelNamedFlags *server_user_flags;
+ CamelNameValueArray *server_user_tags;
+};
+
+enum {
+ PROP_0,
+ PROP_SERVER_FLAGS,
+ PROP_SERVER_USER_FLAGS,
+ PROP_SERVER_USER_TAGS
+};
+
+G_DEFINE_TYPE (CamelIMAPXMessageInfo, camel_imapx_message_info, CAMEL_TYPE_MESSAGE_INFO_BASE)
+
+static CamelMessageInfo *
+imapx_message_info_clone (const CamelMessageInfo *mi,
+ CamelFolderSummary *assign_summary)
+{
+ CamelMessageInfo *result;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (mi), NULL);
+
+ result = CAMEL_MESSAGE_INFO_CLASS (camel_imapx_message_info_parent_class)->clone (mi, assign_summary);
+ if (!result)
+ return NULL;
+
+ if (CAMEL_IS_IMAPX_MESSAGE_INFO (result)) {
+ CamelIMAPXMessageInfo *imi, *imi_result;
+
+ imi = CAMEL_IMAPX_MESSAGE_INFO (mi);
+ imi_result = CAMEL_IMAPX_MESSAGE_INFO (result);
+
+ camel_imapx_message_info_set_server_flags (imi_result,
camel_imapx_message_info_get_server_flags (imi));
+ camel_imapx_message_info_take_server_user_flags (imi_result,
camel_imapx_message_info_dup_server_user_flags (imi));
+ camel_imapx_message_info_take_server_user_tags (imi_result,
camel_imapx_message_info_dup_server_user_tags (imi));
+ }
+
+ return result;
+}
+
+static gboolean
+imapx_message_info_load (CamelMessageInfo *mi,
+ const CamelMIRecord *record,
+ /* const */ gchar **bdata_ptr)
+{
+ CamelIMAPXMessageInfo *imi;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_ptr != NULL, FALSE);
+
+ if (!CAMEL_MESSAGE_INFO_CLASS (camel_imapx_message_info_parent_class)->load ||
+ !CAMEL_MESSAGE_INFO_CLASS (camel_imapx_message_info_parent_class)->load (mi, record, bdata_ptr))
+ return FALSE;
+
+ imi = CAMEL_IMAPX_MESSAGE_INFO (mi);
+
+ camel_imapx_message_info_set_server_flags (imi, camel_util_bdata_get_number (bdata_ptr, 0));
+
+ /* Reset server-side information, which is not saved into the summary. */
+ camel_imapx_message_info_take_server_user_flags (imi, NULL);
+ camel_imapx_message_info_take_server_user_tags (imi, NULL);
+
+ return TRUE;
+}
+
+static gboolean
+imapx_message_info_save (const CamelMessageInfo *mi,
+ CamelMIRecord *record,
+ GString *bdata_str)
+{
+ CamelIMAPXMessageInfo *imi;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_str != NULL, FALSE);
+
+ if (!CAMEL_MESSAGE_INFO_CLASS (camel_imapx_message_info_parent_class)->save ||
+ !CAMEL_MESSAGE_INFO_CLASS (camel_imapx_message_info_parent_class)->save (mi, record, bdata_str))
+ return FALSE;
+
+ imi = CAMEL_IMAPX_MESSAGE_INFO (mi);
+
+ camel_util_bdata_put_number (bdata_str, camel_imapx_message_info_get_server_flags (imi));
+
+ return TRUE;
+}
+
+static void
+imapx_message_info_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CamelIMAPXMessageInfo *imi = CAMEL_IMAPX_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_SERVER_FLAGS:
+ camel_imapx_message_info_set_server_flags (imi, g_value_get_uint (value));
+ return;
+
+ case PROP_SERVER_USER_FLAGS:
+ camel_imapx_message_info_take_server_user_flags (imi, g_value_dup_boxed (value));
+ return;
+
+ case PROP_SERVER_USER_TAGS:
+ camel_imapx_message_info_take_server_user_tags (imi, g_value_dup_boxed (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+imapx_message_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CamelIMAPXMessageInfo *imi = CAMEL_IMAPX_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_SERVER_FLAGS:
+ g_value_set_uint (value, camel_imapx_message_info_get_server_flags (imi));
+ return;
+
+ case PROP_SERVER_USER_FLAGS:
+ g_value_take_boxed (value, camel_imapx_message_info_dup_server_user_flags (imi));
+ return;
+
+ case PROP_SERVER_USER_TAGS:
+ g_value_take_boxed (value, camel_imapx_message_info_dup_server_user_tags (imi));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+imapx_message_info_dispose (GObject *object)
+{
+ CamelIMAPXMessageInfo *imi = CAMEL_IMAPX_MESSAGE_INFO (object);
+
+ camel_named_flags_free (imi->priv->server_user_flags);
+ imi->priv->server_user_flags = NULL;
+
+ camel_name_value_array_free (imi->priv->server_user_tags);
+ imi->priv->server_user_tags = NULL;
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_imapx_message_info_parent_class)->dispose (object);
+}
+
+static void
+camel_imapx_message_info_class_init (CamelIMAPXMessageInfoClass *class)
+{
+ CamelMessageInfoClass *mi_class;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelIMAPXMessageInfoPrivate));
+
+ mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
+ mi_class->clone = imapx_message_info_clone;
+ mi_class->load = imapx_message_info_load;
+ mi_class->save = imapx_message_info_save;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = imapx_message_info_set_property;
+ object_class->get_property = imapx_message_info_get_property;
+ object_class->dispose = imapx_message_info_dispose;
+
+ /**
+ * CamelIMAPXMessageInfo:server-flags
+ *
+ * Bit-or of #CamelMessageFlags of the flags stored on the server.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SERVER_FLAGS,
+ g_param_spec_uint (
+ "server-flags",
+ "Server Flags",
+ NULL,
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelIMAPXMessageInfo:server-user-flags
+ *
+ * User flags for the associated message, as stored on the server.
+ * Can be %NULL.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SERVER_USER_FLAGS,
+ g_param_spec_boxed (
+ "server-user-flags",
+ "Server User Flags",
+ NULL,
+ CAMEL_TYPE_NAMED_FLAGS,
+ G_PARAM_READWRITE));
+
+ /**
+ * CamelIMAPXMessageInfo:server-user-tags
+ *
+ * User tags for the associated message, as stored on the server.
+ * Can be %NULL.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SERVER_USER_TAGS,
+ g_param_spec_boxed (
+ "server-user-tags",
+ "Server User tags",
+ NULL,
+ CAMEL_TYPE_NAME_VALUE_ARRAY,
+ G_PARAM_READWRITE));
+}
+
+static void
+camel_imapx_message_info_init (CamelIMAPXMessageInfo *imi)
+{
+ imi->priv = G_TYPE_INSTANCE_GET_PRIVATE (imi, CAMEL_TYPE_IMAPX_MESSAGE_INFO,
CamelIMAPXMessageInfoPrivate);
+}
+
+guint32
+camel_imapx_message_info_get_server_flags (const CamelIMAPXMessageInfo *imi)
+{
+ CamelMessageInfo *mi;
+ guint32 result;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (imi), 0);
+
+ mi = CAMEL_MESSAGE_INFO (imi);
+
+ camel_message_info_property_lock (mi);
+ result = imi->priv->server_flags;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gboolean
+camel_imapx_message_info_set_server_flags (CamelIMAPXMessageInfo *imi,
+ guint32 server_flags)
+{
+ CamelMessageInfo *mi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (imi), FALSE);
+
+ mi = CAMEL_MESSAGE_INFO (imi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = imi->priv->server_flags != server_flags;
+ if (changed)
+ imi->priv->server_flags = server_flags;
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !camel_message_info_get_abort_notifications (mi)) {
+ g_object_notify (G_OBJECT (imi), "server-flags");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
+
+const CamelNamedFlags *
+camel_imapx_message_info_get_server_user_flags (const CamelIMAPXMessageInfo *imi)
+{
+ CamelMessageInfo *mi;
+ const CamelNamedFlags *result;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (imi), NULL);
+
+ mi = CAMEL_MESSAGE_INFO (imi);
+
+ camel_message_info_property_lock (mi);
+ result = imi->priv->server_user_flags;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+CamelNamedFlags *
+camel_imapx_message_info_dup_server_user_flags (const CamelIMAPXMessageInfo *imi)
+{
+ CamelMessageInfo *mi;
+ CamelNamedFlags *result;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (imi), NULL);
+
+ mi = CAMEL_MESSAGE_INFO (imi);
+
+ camel_message_info_property_lock (mi);
+ result = camel_named_flags_copy (imi->priv->server_user_flags);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gboolean
+camel_imapx_message_info_take_server_user_flags (CamelIMAPXMessageInfo *imi,
+ CamelNamedFlags *server_user_flags)
+{
+ CamelMessageInfo *mi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (imi), FALSE);
+
+ mi = CAMEL_MESSAGE_INFO (imi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = !camel_named_flags_equal (imi->priv->server_user_flags, server_user_flags);
+
+ if (changed) {
+ camel_named_flags_free (imi->priv->server_user_flags);
+ imi->priv->server_user_flags = server_user_flags;
+ } else {
+ camel_named_flags_free (server_user_flags);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !camel_message_info_get_abort_notifications (mi)) {
+ g_object_notify (G_OBJECT (imi), "server-user-flags");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
+
+const CamelNameValueArray *
+camel_imapx_message_info_get_server_user_tags (const CamelIMAPXMessageInfo *imi)
+{
+ CamelMessageInfo *mi;
+ const CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (imi), NULL);
+
+ mi = CAMEL_MESSAGE_INFO (imi);
+
+ camel_message_info_property_lock (mi);
+ result = imi->priv->server_user_tags;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+CamelNameValueArray *
+camel_imapx_message_info_dup_server_user_tags (const CamelIMAPXMessageInfo *imi)
+{
+ CamelMessageInfo *mi;
+ CamelNameValueArray *result;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (imi), NULL);
+
+ mi = CAMEL_MESSAGE_INFO (imi);
+
+ camel_message_info_property_lock (mi);
+ result = camel_name_value_array_copy (imi->priv->server_user_tags);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gboolean
+camel_imapx_message_info_take_server_user_tags (CamelIMAPXMessageInfo *imi,
+ CamelNameValueArray *server_user_tags)
+{
+ CamelMessageInfo *mi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_IMAPX_MESSAGE_INFO (imi), FALSE);
+
+ mi = CAMEL_MESSAGE_INFO (imi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = !camel_name_value_array_equal (imi->priv->server_user_tags, server_user_tags,
CAMEL_COMPARE_CASE_SENSITIVE);
+
+ if (changed) {
+ camel_name_value_array_free (imi->priv->server_user_tags);
+ imi->priv->server_user_tags = server_user_tags;
+ } else {
+ camel_name_value_array_free (server_user_tags);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !camel_message_info_get_abort_notifications (mi)) {
+ g_object_notify (G_OBJECT (imi), "server-user-tags");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
diff --git a/src/camel/providers/imapx/camel-imapx-message-info.h
b/src/camel/providers/imapx/camel-imapx-message-info.h
new file mode 100644
index 0000000..f553559
--- /dev/null
+++ b/src/camel/providers/imapx/camel-imapx-message-info.h
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAMEL_IMAPX_MESSAGE_INFO_H
+#define CAMEL_IMAPX_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_IMAPX_MESSAGE_INFO \
+ (camel_imapx_message_info_get_type ())
+#define CAMEL_IMAPX_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_IMAPX_MESSAGE_INFO, CamelIMAPXMessageInfo))
+#define CAMEL_IMAPX_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_IMAPX_MESSAGE_INFO, CamelIMAPXMessageInfoClass))
+#define CAMEL_IS_IMAPX_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_IMAPX_MESSAGE_INFO))
+#define CAMEL_IS_IMAPX_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_IMAPX_MESSAGE_INFO))
+#define CAMEL_IMAPX_MESSAGE_INFO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_IMAPX_MESSAGE_INFO, CamelIMAPXMessageInfoClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelIMAPXMessageInfo CamelIMAPXMessageInfo;
+typedef struct _CamelIMAPXMessageInfoClass CamelIMAPXMessageInfoClass;
+typedef struct _CamelIMAPXMessageInfoPrivate CamelIMAPXMessageInfoPrivate;
+
+struct _CamelIMAPXMessageInfo {
+ CamelMessageInfoBase parent;
+ CamelIMAPXMessageInfoPrivate *priv;
+};
+
+struct _CamelIMAPXMessageInfoClass {
+ CamelMessageInfoBaseClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
+};
+
+GType camel_imapx_message_info_get_type (void);
+
+guint32 camel_imapx_message_info_get_server_flags
+ (const CamelIMAPXMessageInfo *imi);
+gboolean camel_imapx_message_info_set_server_flags
+ (CamelIMAPXMessageInfo *imi,
+ guint32 server_flags);
+const CamelNamedFlags *
+ camel_imapx_message_info_get_server_user_flags
+ (const CamelIMAPXMessageInfo *imi);
+CamelNamedFlags *
+ camel_imapx_message_info_dup_server_user_flags
+ (const CamelIMAPXMessageInfo *imi);
+gboolean camel_imapx_message_info_take_server_user_flags
+ (CamelIMAPXMessageInfo *imi,
+ CamelNamedFlags *server_user_flags);
+const CamelNameValueArray *
+ camel_imapx_message_info_get_server_user_tags
+ (const CamelIMAPXMessageInfo *imi);
+CamelNameValueArray *
+ camel_imapx_message_info_dup_server_user_tags
+ (const CamelIMAPXMessageInfo *imi);
+gboolean camel_imapx_message_info_take_server_user_tags
+ (CamelIMAPXMessageInfo *imi,
+ CamelNameValueArray *server_user_tags);
+
+G_END_DECLS
+
+#endif /* CAMEL_IMAPX_MESSAGE_INFO_H */
diff --git a/src/camel/providers/imapx/camel-imapx-namespace-response.h
b/src/camel/providers/imapx/camel-imapx-namespace-response.h
index 0321dd3..af71b8a 100644
--- a/src/camel/providers/imapx/camel-imapx-namespace-response.h
+++ b/src/camel/providers/imapx/camel-imapx-namespace-response.h
@@ -61,6 +61,9 @@ struct _CamelIMAPXNamespaceResponse {
struct _CamelIMAPXNamespaceResponseClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_namespace_response_get_type
diff --git a/src/camel/providers/imapx/camel-imapx-namespace.h
b/src/camel/providers/imapx/camel-imapx-namespace.h
index d6fdb5f..5d42cf2 100644
--- a/src/camel/providers/imapx/camel-imapx-namespace.h
+++ b/src/camel/providers/imapx/camel-imapx-namespace.h
@@ -78,6 +78,9 @@ struct _CamelIMAPXNamespace {
struct _CamelIMAPXNamespaceClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_namespace_get_type
diff --git a/src/camel/providers/imapx/camel-imapx-search.c b/src/camel/providers/imapx/camel-imapx-search.c
index b4e0a80..f06215b 100644
--- a/src/camel/providers/imapx/camel-imapx-search.c
+++ b/src/camel/providers/imapx/camel-imapx-search.c
@@ -116,19 +116,23 @@ imapx_search_result_match_all (CamelSExp *sexp,
g_return_val_if_fail (search != NULL, NULL);
- if (search->current != NULL) {
+ if (camel_folder_search_get_current_message_info (search)) {
result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
result->value.boolean = TRUE;
} else {
+ GPtrArray *summary;
gint ii;
+ summary = camel_folder_search_get_summary (search);
+
result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_ARRAY_PTR);
result->value.ptrarray = g_ptr_array_new ();
- for (ii = 0; ii < search->summary->len; ii++)
+ for (ii = 0; summary && ii < summary->len; ii++) {
g_ptr_array_add (
result->value.ptrarray,
- (gpointer) search->summary->pdata[ii]);
+ (gpointer) summary->pdata[ii]);
+ }
}
return result;
@@ -142,7 +146,7 @@ imapx_search_result_match_none (CamelSExp *sexp,
g_return_val_if_fail (search != NULL, NULL);
- if (search->current != NULL) {
+ if (camel_folder_search_get_current_message_info (search)) {
result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
result->value.boolean = FALSE;
} else {
@@ -169,7 +173,7 @@ imapx_search_process_criteria (CamelSExp *sexp,
GError *local_error = NULL;
mailbox = camel_imapx_folder_list_mailbox (
- CAMEL_IMAPX_FOLDER (search->folder), imapx_search->priv->cancellable, &local_error);
+ CAMEL_IMAPX_FOLDER (camel_folder_search_get_folder (search)),
imapx_search->priv->cancellable, &local_error);
/* Sanity check. */
g_return_val_if_fail (
@@ -205,7 +209,7 @@ imapx_search_process_criteria (CamelSExp *sexp,
uids = g_ptr_array_new ();
}
- if (search->current != NULL) {
+ if (camel_folder_search_get_current_message_info (search)) {
result = camel_sexp_result_new (sexp, CAMEL_SEXP_RES_BOOL);
result->value.boolean = (uids && uids->len > 0);
} else {
@@ -234,7 +238,7 @@ imapx_search_match_all (CamelSExp *sexp,
return imapx_search_result_match_none (sexp, search);
imapx_store = camel_imapx_search_ref_store (CAMEL_IMAPX_SEARCH (search));
- if (!imapx_store || search->current || !search->summary) {
+ if (!imapx_store || camel_folder_search_get_current_message_info (search) ||
!camel_folder_search_get_summary (search)) {
g_clear_object (&imapx_store);
/* Chain up to parent's method. */
@@ -247,19 +251,18 @@ imapx_search_match_all (CamelSExp *sexp,
prev_local_data_search = imapx_search->priv->local_data_search;
imapx_search->priv->local_data_search = &local_data_search;
- summary = search->summary_set ? search->summary_set : search->summary;
+ summary = camel_folder_search_get_current_summary (search);
- if (!CAMEL_IS_VEE_FOLDER (search->folder)) {
- camel_folder_summary_prepare_fetch_all (search->folder->summary, NULL);
+ if (!CAMEL_IS_VEE_FOLDER (camel_folder_search_get_folder (search))) {
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary
(camel_folder_search_get_folder (search)), NULL);
}
for (ii = 0; ii < summary->len; ii++) {
- search->current = camel_folder_summary_get (search->folder->summary, summary->pdata[ii]);
- if (search->current) {
+ camel_folder_search_take_current_message_info (search, camel_folder_summary_get
(camel_folder_get_folder_summary (camel_folder_search_get_folder (search)), summary->pdata[ii]));
+ if (camel_folder_search_get_current_message_info (search)) {
result = camel_sexp_term_eval (sexp, argv[0]);
camel_sexp_result_free (sexp, result);
- camel_message_info_unref (search->current);
- search->current = NULL;
+ camel_folder_search_set_current_message_info (search, NULL);
break;
}
}
@@ -360,7 +363,7 @@ imapx_search_body_contains (CamelSExp *sexp,
return imapx_search_result_match_all (sexp, search);
/* Match nothing if empty argv or empty summary. */
- if (argc == 0 || search->summary->len == 0)
+ if (argc == 0 || camel_folder_search_get_summary_empty (search))
return imapx_search_result_match_none (sexp, search);
imapx_store = camel_imapx_search_ref_store (CAMEL_IMAPX_SEARCH (search));
@@ -376,11 +379,11 @@ imapx_search_body_contains (CamelSExp *sexp,
criteria = g_string_sized_new (128);
- if (search->current != NULL) {
+ if (camel_folder_search_get_current_message_info (search)) {
const gchar *uid;
/* Limit the search to a single UID. */
- uid = camel_message_info_get_uid (search->current);
+ uid = camel_message_info_get_uid (camel_folder_search_get_current_message_info (search));
g_string_append_printf (criteria, "UID %s", uid);
}
@@ -421,7 +424,7 @@ imapx_search_header_contains (CamelSExp *sexp,
/* Match nothing if empty argv or empty summary. */
if (argc <= 1 ||
argv[0]->type != CAMEL_SEXP_RES_STRING ||
- search->summary->len == 0)
+ camel_folder_search_get_summary_empty (search))
return imapx_search_result_match_none (sexp, search);
headername = argv[0]->value.string;
@@ -454,11 +457,11 @@ imapx_search_header_contains (CamelSExp *sexp,
criteria = g_string_sized_new (128);
- if (search->current != NULL) {
+ if (camel_folder_search_get_current_message_info (search)) {
const gchar *uid;
/* Limit the search to a single UID. */
- uid = camel_message_info_get_uid (search->current);
+ uid = camel_message_info_get_uid (camel_folder_search_get_current_message_info (search));
g_string_append_printf (criteria, "UID %s", uid);
}
@@ -501,7 +504,7 @@ imapx_search_header_exists (CamelSExp *sexp,
gint ii;
/* Match nothing if empty argv or empty summary. */
- if (argc == 0 || search->summary->len == 0)
+ if (argc == 0 || camel_folder_search_get_summary_empty (search))
return imapx_search_result_match_none (sexp, search);
/* Check if asking for locally stored headers only */
@@ -543,11 +546,11 @@ imapx_search_header_exists (CamelSExp *sexp,
criteria = g_string_sized_new (128);
- if (search->current != NULL) {
+ if (camel_folder_search_get_current_message_info (search)) {
const gchar *uid;
/* Limit the search to a single UID. */
- uid = camel_message_info_get_uid (search->current);
+ uid = camel_message_info_get_uid (camel_folder_search_get_current_message_info (search));
g_string_append_printf (criteria, "UID %s", uid);
}
diff --git a/src/camel/providers/imapx/camel-imapx-search.h b/src/camel/providers/imapx/camel-imapx-search.h
index acdba79..93b8daa 100644
--- a/src/camel/providers/imapx/camel-imapx-search.h
+++ b/src/camel/providers/imapx/camel-imapx-search.h
@@ -62,6 +62,9 @@ struct _CamelIMAPXSearch {
struct _CamelIMAPXSearchClass {
CamelFolderSearchClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_search_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c
index 5665ad7..1c91744 100644
--- a/src/camel/providers/imapx/camel-imapx-server.c
+++ b/src/camel/providers/imapx/camel-imapx-server.c
@@ -41,6 +41,7 @@
#include "camel-imapx-input-stream.h"
#include "camel-imapx-job.h"
#include "camel-imapx-logger.h"
+#include "camel-imapx-message-info.h"
#include "camel-imapx-settings.h"
#include "camel-imapx-store.h"
#include "camel-imapx-summary.h"
@@ -362,7 +363,7 @@ G_DEFINE_TYPE (CamelIMAPXServer, camel_imapx_server, G_TYPE_OBJECT)
typedef struct _FetchChangesInfo {
guint32 server_flags;
- CamelFlag *server_user_flags;
+ CamelNamedFlags *server_user_flags;
} FetchChangesInfo;
static void
@@ -371,7 +372,7 @@ fetch_changes_info_free (gpointer ptr)
FetchChangesInfo *nfo = ptr;
if (nfo) {
- camel_flag_list_free (&nfo->server_user_flags);
+ camel_named_flags_free (nfo->server_user_flags);
g_free (nfo);
}
}
@@ -760,7 +761,7 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *is,
g_return_if_fail (is->priv->changes != NULL);
- camel_folder_summary_remove_uid (folder->summary, uid);
+ camel_folder_summary_remove_uid (camel_folder_get_folder_summary (folder), uid);
g_mutex_lock (&is->priv->changes_lock);
@@ -774,7 +775,7 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *is,
g_mutex_unlock (&is->priv->changes_lock);
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ camel_folder_summary_save (camel_folder_get_folder_summary (folder), NULL);
imapx_update_store_summary (folder);
camel_folder_changed (folder, changes);
@@ -969,7 +970,7 @@ imapx_untagged_vanished (CamelIMAPXServer *is,
g_mutex_unlock (&is->priv->changes_lock);
uid_list = g_list_reverse (uid_list);
- camel_folder_summary_remove_uids (folder->summary, uid_list);
+ camel_folder_summary_remove_uids (camel_folder_get_folder_summary (folder), uid_list);
/* If the response is truly unsolicited (e.g. via NOTIFY)
* then go ahead and emit the change notification now. */
@@ -987,7 +988,7 @@ imapx_untagged_vanished (CamelIMAPXServer *is,
g_mutex_unlock (&is->priv->changes_lock);
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ camel_folder_summary_save (camel_folder_get_folder_summary (folder), NULL);
imapx_update_store_summary (folder);
camel_folder_changed (folder, changes);
@@ -1069,7 +1070,7 @@ imapx_untagged_exists (CamelIMAPXServer *is,
if (camel_imapx_server_is_in_idle (is)) {
guint count;
- count = camel_folder_summary_count (folder->summary);
+ count = camel_folder_summary_count (camel_folder_get_folder_summary (folder));
if (count < exists)
g_signal_emit (is, signals[REFRESH_MAILBOX], 0, mailbox);
}
@@ -1243,7 +1244,7 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
}
if (uid) {
- mi = camel_folder_summary_get (select_folder->summary, uid);
+ mi = camel_folder_summary_get (camel_folder_get_folder_summary
(select_folder), uid);
if (mi) {
/* It's unsolicited _unless_ select_pending (i.e. during
* a QRESYNC SELECT */
@@ -1271,7 +1272,7 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
g_free (uid);
if (changed && camel_imapx_server_is_in_idle (is)) {
- camel_folder_summary_save_to_db (select_folder->summary, NULL);
+ camel_folder_summary_save (camel_folder_get_folder_summary (select_folder),
NULL);
imapx_update_store_summary (select_folder);
g_mutex_lock (&is->priv->changes_lock);
@@ -1282,8 +1283,7 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
g_mutex_unlock (&is->priv->changes_lock);
}
- if (mi)
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
g_object_unref (select_folder);
}
@@ -1332,16 +1332,17 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
mp = camel_mime_parser_new ();
camel_mime_parser_init_with_bytes (mp, finfo->header);
- mi = camel_folder_summary_info_new_from_parser (folder->summary, mp);
+ mi = camel_folder_summary_info_new_from_parser (camel_folder_get_folder_summary (folder), mp);
g_object_unref (mp);
if (mi != NULL) {
guint32 server_flags;
- CamelFlag *server_user_flags;
- CamelMessageInfoBase *binfo;
+ CamelNamedFlags *server_user_flags;
gboolean free_user_flags = FALSE;
- mi->uid = camel_pstring_strdup (finfo->uid);
+ camel_message_info_set_abort_notifications (mi, TRUE);
+
+ camel_message_info_set_uid (mi, finfo->uid);
if (!(finfo->got & FETCH_FLAGS) && is->priv->fetch_changes_infos) {
FetchChangesInfo *nfo;
@@ -1367,45 +1368,44 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
if (!(server_flags & CAMEL_MESSAGE_SEEN)) {
guint64 uidl;
- uidl = strtoull (mi->uid, NULL, 10);
+ uidl = strtoull (finfo->uid, NULL, 10);
if (uidl >= uidnext) {
- c (is->priv->tagprefix, "Updating unseen count for new message %s\n",
mi->uid);
+ c (is->priv->tagprefix, "Updating unseen count for new message %s\n",
finfo->uid);
camel_imapx_mailbox_set_unseen (mailbox, unseen + 1);
} else {
- c (is->priv->tagprefix, "Not updating unseen count for new message
%s\n", mi->uid);
+ c (is->priv->tagprefix, "Not updating unseen count for new message
%s\n", finfo->uid);
}
}
- binfo = (CamelMessageInfoBase *) mi;
- binfo->size = finfo->size;
+ camel_message_info_set_size (mi, finfo->size);
+ camel_message_info_set_abort_notifications (mi, FALSE);
- camel_folder_summary_lock (folder->summary);
+ camel_folder_summary_lock (camel_folder_get_folder_summary (folder));
- if (!camel_folder_summary_check_uid (folder->summary, mi->uid)) {
+ if (!camel_folder_summary_check_uid (camel_folder_get_folder_summary (folder),
finfo->uid)) {
imapx_set_message_info_flags_for_new_message (mi, server_flags,
server_user_flags, FALSE, NULL, camel_imapx_mailbox_get_permanentflags (mailbox));
- camel_folder_summary_add (folder->summary, mi);
+ camel_folder_summary_add (camel_folder_get_folder_summary (folder), mi,
FALSE);
g_mutex_lock (&is->priv->changes_lock);
- camel_folder_change_info_add_uid (is->priv->changes, mi->uid);
- camel_folder_change_info_recent_uid (is->priv->changes, mi->uid);
+ camel_folder_change_info_add_uid (is->priv->changes, finfo->uid);
+ camel_folder_change_info_recent_uid (is->priv->changes, finfo->uid);
g_mutex_unlock (&is->priv->changes_lock);
if (messages > 0) {
- gint cnt = (camel_folder_summary_count (folder->summary) * 100) /
messages;
+ gint cnt = (camel_folder_summary_count
(camel_folder_get_folder_summary (folder)) * 100) / messages;
camel_operation_progress (cancellable, cnt ? cnt : 1);
}
- } else {
- camel_message_info_unref (mi);
}
- camel_folder_summary_unlock (folder->summary);
+ g_clear_object (&mi);
+ camel_folder_summary_unlock (camel_folder_get_folder_summary (folder));
- if (free_user_flags && server_user_flags)
- camel_flag_list_free (&server_user_flags);
+ if (free_user_flags)
+ camel_named_flags_free (server_user_flags);
}
g_clear_object (&mailbox);
@@ -2332,7 +2332,7 @@ imapx_completion (CamelIMAPXServer *is,
folder = imapx_server_ref_folder (is, mailbox);
g_return_val_if_fail (folder != NULL, FALSE);
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ camel_folder_summary_save (camel_folder_get_folder_summary (folder), NULL);
imapx_update_store_summary (folder);
camel_folder_changed (folder, changes);
@@ -4082,12 +4082,12 @@ camel_imapx_server_get_message_sync (CamelIMAPXServer *is,
cache_stream = camel_data_cache_add (message_cache, "tmp", message_uid, error);
if (cache_stream == NULL) {
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
return NULL;
}
settings = camel_imapx_server_ref_settings (is);
- data_size = ((CamelMessageInfoBase *) mi)->size;
+ data_size = camel_message_info_get_size (mi);
use_multi_fetch = data_size > MULTI_SIZE && camel_imapx_settings_get_use_multi_fetch (settings);
g_object_unref (settings);
@@ -4303,8 +4303,8 @@ camel_imapx_server_copy_message_sync (CamelIMAPXServer *is,
folder = imapx_server_ref_folder (is, mailbox);
g_return_val_if_fail (folder != NULL, FALSE);
- remove_deleted_flags = remove_deleted_flags || (folder->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0;
- remove_junk_flags = (folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
+ remove_deleted_flags = remove_deleted_flags || (camel_folder_get_flags (folder) &
CAMEL_FOLDER_IS_TRASH) != 0;
+ remove_junk_flags = (camel_folder_get_flags (folder) & CAMEL_FOLDER_IS_JUNK) != 0;
/* If we're moving messages, prefer "UID MOVE" if supported. */
if (delete_originals) {
@@ -4318,14 +4318,14 @@ camel_imapx_server_copy_message_sync (CamelIMAPXServer *is,
g_mutex_unlock (&is->priv->stream_lock);
}
- source_infos = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, camel_message_info_unref);
+ source_infos = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
data_uids = g_ptr_array_new ();
for (ii = 0; ii < uids->len; ii++) {
gchar *uid = (gchar *) camel_pstring_strdup (uids->pdata[ii]);
g_ptr_array_add (data_uids, uid);
- g_hash_table_insert (source_infos, uid, camel_folder_summary_get (folder->summary, uid));
+ g_hash_table_insert (source_infos, uid, camel_folder_summary_get
(camel_folder_get_folder_summary (folder), uid));
}
g_ptr_array_sort (data_uids, (GCompareFunc) imapx_uids_array_cmp);
@@ -4393,40 +4393,41 @@ camel_imapx_server_copy_message_sync (CamelIMAPXServer *is,
continue;
uid = g_strdup_printf ("%d", g_array_index
(copyuid_status->u.copyuid.copied_uids, guint32, ii));
- destination_info = camel_folder_summary_get (folder->summary,
uid);
+ destination_info = camel_folder_summary_get
(camel_folder_get_folder_summary (folder), uid);
if (!destination_info) {
is_new = TRUE;
- destination_info = camel_message_info_clone
(source_info);
- destination_info->summary =
destination_folder->summary;
- camel_pstring_free (destination_info->uid);
- destination_info->uid = camel_pstring_strdup (uid);
+ destination_info = camel_message_info_clone
(source_info, camel_folder_get_folder_summary (destination_folder));
+ camel_message_info_set_uid (destination_info, uid);
}
g_free (uid);
+ camel_message_info_property_lock (source_info);
+
imapx_set_message_info_flags_for_new_message (
destination_info,
- ((CamelMessageInfoBase *) source_info)->flags,
- ((CamelMessageInfoBase *) source_info)->user_flags,
+ camel_message_info_get_flags (source_info),
+ camel_message_info_get_user_flags (source_info),
TRUE,
- ((CamelMessageInfoBase *) source_info)->user_tags,
+ camel_message_info_get_user_tags (source_info),
camel_imapx_mailbox_get_permanentflags (destination));
if (remove_deleted_flags)
camel_message_info_set_flags (destination_info,
CAMEL_MESSAGE_DELETED, 0);
if (remove_junk_flags)
camel_message_info_set_flags (destination_info,
CAMEL_MESSAGE_JUNK, 0);
if (is_new)
- camel_folder_summary_add
(destination_folder->summary, destination_info);
- camel_folder_change_info_add_uid (changes,
destination_info->uid);
+ camel_folder_summary_add
(camel_folder_get_folder_summary (destination_folder), destination_info, FALSE);
+ camel_folder_change_info_add_uid (changes,
camel_message_info_get_uid (destination_info));
+
+ camel_message_info_property_unlock (source_info);
- if (!is_new)
- camel_message_info_unref (destination_info);
+ g_clear_object (&destination_info);
}
if (camel_folder_change_info_changed (changes)) {
- camel_folder_summary_touch (destination_folder->summary);
- camel_folder_summary_save_to_db (destination_folder->summary,
NULL);
+ camel_folder_summary_touch (camel_folder_get_folder_summary
(destination_folder));
+ camel_folder_summary_save (camel_folder_get_folder_summary
(destination_folder), NULL);
camel_folder_changed (destination_folder, changes);
}
@@ -4447,7 +4448,7 @@ camel_imapx_server_copy_message_sync (CamelIMAPXServer *is,
if (delete_originals) {
camel_folder_delete_message (folder, uid);
} else {
- if (camel_folder_summary_remove_uid (folder->summary, uid)) {
+ if (camel_folder_summary_remove_uid
(camel_folder_get_folder_summary (folder), uid)) {
if (!changes)
changes = camel_folder_change_info_new ();
@@ -4457,8 +4458,8 @@ camel_imapx_server_copy_message_sync (CamelIMAPXServer *is,
}
if (changes && camel_folder_change_info_changed (changes)) {
- camel_folder_summary_touch (folder->summary);
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ camel_folder_summary_touch (camel_folder_get_folder_summary (folder));
+ camel_folder_summary_save (camel_folder_get_folder_summary (folder),
NULL);
camel_folder_changed (folder, changes);
}
@@ -4572,35 +4573,22 @@ camel_imapx_server_append_message_sync (CamelIMAPXServer *is,
date_time = camel_mime_message_get_date (message, NULL);
path = camel_data_cache_get_filename (message_cache, "new", uid);
- info = camel_folder_summary_info_new_from_message (summary, message, NULL);
- info->uid = camel_pstring_strdup (uid);
+ info = camel_folder_summary_info_new_from_message (summary, message);
+
+ camel_message_info_set_abort_notifications (info, TRUE);
+ camel_message_info_set_uid (info, uid);
if (mi != NULL) {
struct icaltimetype icaltime;
- CamelMessageInfoBase *base_info = (CamelMessageInfoBase *) info;
- const CamelFlag *flag;
- const CamelTag *tag;
-
- base_info->flags = camel_message_info_get_flags (mi);
- base_info->size = camel_message_info_get_size (mi);
-
- flag = camel_message_info_get_user_flags (mi);
- while (flag != NULL) {
- if (*flag->name != '\0')
- camel_flag_set (
- &base_info->user_flags,
- flag->name, TRUE);
- flag = flag->next;
- }
- tag = camel_message_info_get_user_tags (mi);
- while (tag != NULL) {
- if (*tag->name != '\0')
- camel_tag_set (
- &base_info->user_tags,
- tag->name, tag->value);
- tag = tag->next;
- }
+ camel_message_info_property_lock (mi);
+
+ camel_message_info_set_flags (info, ~0, camel_message_info_get_flags (mi));
+ camel_message_info_set_size (info, camel_message_info_get_size (mi));
+ camel_message_info_take_user_flags (info,
+ camel_named_flags_copy (camel_message_info_get_user_flags (mi)));
+ camel_message_info_take_user_tags (info,
+ camel_name_value_array_copy (camel_message_info_get_user_tags (mi)));
if (date_time > 0) {
icaltime = icaltime_from_timet (date_time, FALSE);
@@ -4616,22 +4604,18 @@ camel_imapx_server_append_message_sync (CamelIMAPXServer *is,
if (!icaltime_is_valid_time (icaltime))
date_time = -1;
}
+
+ camel_message_info_property_unlock (mi);
}
if (!camel_message_info_get_size (info)) {
- CamelStreamNull *sn = (CamelStreamNull *) camel_stream_null_new ();
-
- camel_data_wrapper_write_to_stream_sync (
- CAMEL_DATA_WRAPPER (message),
- CAMEL_STREAM (sn), NULL, NULL);
- ((CamelMessageInfoBase *) info)->size = sn->written;
- g_object_unref (sn);
+ camel_message_info_set_size (info, camel_data_wrapper_calculate_size_sync (CAMEL_DATA_WRAPPER
(message), NULL, NULL));
}
g_free (uid);
if (camel_mime_message_has_attachment (message))
- ((CamelMessageInfoBase *) info)->flags |= CAMEL_MESSAGE_ATTACHMENTS;
+ camel_message_info_set_flags (info, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);
if (date_time > 0) {
gchar *date_time_str;
@@ -4651,8 +4635,8 @@ camel_imapx_server_append_message_sync (CamelIMAPXServer *is,
ic = camel_imapx_command_new (is, CAMEL_IMAPX_JOB_APPEND_MESSAGE, "APPEND %M %F %t %P",
mailbox,
- ((CamelMessageInfoBase *) info)->flags,
- ((CamelMessageInfoBase *) info)->user_flags,
+ camel_message_info_get_flags (info),
+ camel_message_info_get_user_flags (info),
date_time_str,
path);
@@ -4660,11 +4644,13 @@ camel_imapx_server_append_message_sync (CamelIMAPXServer *is,
} else {
ic = camel_imapx_command_new (is, CAMEL_IMAPX_JOB_APPEND_MESSAGE, "APPEND %M %F %P",
mailbox,
- ((CamelMessageInfoBase *) info)->flags,
- ((CamelMessageInfoBase *) info)->user_flags,
+ camel_message_info_get_flags (info),
+ camel_message_info_get_user_flags (info),
path);
}
+ camel_message_info_set_abort_notifications (info, FALSE);
+
success = camel_imapx_server_process_command_sync (is, ic, _("Error appending message"), cancellable,
error);
if (success) {
@@ -4687,36 +4673,42 @@ camel_imapx_server_append_message_sync (CamelIMAPXServer *is,
* numbered MessageInfo, without losing any information. Otherwise
* we have to wait for the server to let us know it was appended. */
- mi = camel_message_info_clone (info);
- old_uid = g_strdup (info->uid);
+ mi = camel_message_info_clone (info, NULL);
+ old_uid = g_strdup (camel_message_info_get_uid (info));
if (ic->status && ic->status->condition == IMAPX_APPENDUID) {
c (is->priv->tagprefix, "Got appenduid %d %d\n", (gint)
ic->status->u.appenduid.uidvalidity, (gint) ic->status->u.appenduid.uid);
if (ic->status->u.appenduid.uidvalidity == uidvalidity) {
- if (appended_uid)
- *appended_uid = g_strdup_printf ("%u", (guint)
ic->status->u.appenduid.uid);
- mi->uid = camel_pstring_add (g_strdup_printf ("%u", (guint)
ic->status->u.appenduid.uid), TRUE);
+ gchar *uid;
+
+ uid = g_strdup_printf ("%u", (guint) ic->status->u.appenduid.uid);
+ camel_message_info_set_uid (mi, uid);
- cur = camel_data_cache_get_filename (imapx_folder->cache, "cur", mi->uid);
+ cur = camel_data_cache_get_filename (imapx_folder->cache, "cur", uid);
if (g_rename (path, cur) == -1 && errno != ENOENT) {
g_warning ("%s: Failed to rename '%s' to '%s': %s", G_STRFUNC, path,
cur, g_strerror (errno));
}
imapx_set_message_info_flags_for_new_message (
mi,
- ((CamelMessageInfoBase *) info)->flags,
- ((CamelMessageInfoBase *) info)->user_flags,
+ camel_message_info_get_flags (info),
+ camel_message_info_get_user_flags (info),
TRUE,
- ((CamelMessageInfoBase *) info)->user_tags,
+ camel_message_info_get_user_tags (info),
camel_imapx_mailbox_get_permanentflags (mailbox));
- camel_folder_summary_add (folder->summary, mi);
+ camel_folder_summary_add (camel_folder_get_folder_summary (folder), mi,
FALSE);
g_mutex_lock (&is->priv->changes_lock);
- camel_folder_change_info_add_uid (is->priv->changes, mi->uid);
+ camel_folder_change_info_add_uid (is->priv->changes,
camel_message_info_get_uid (mi));
g_mutex_unlock (&is->priv->changes_lock);
- mi = NULL;
+ if (appended_uid)
+ *appended_uid = uid;
+ else
+ g_free (uid);
+
+ g_clear_object (&mi);
g_free (cur);
} else {
@@ -4728,8 +4720,7 @@ camel_imapx_server_append_message_sync (CamelIMAPXServer *is,
g_free (old_uid);
camel_imapx_command_unref (ic);
- if (mi)
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
g_object_unref (folder);
}
@@ -4827,7 +4818,7 @@ imapx_server_process_fetch_changes_infos (CamelIMAPXServer *is,
if (out_fetch_summary_uids)
g_return_if_fail (*out_fetch_summary_uids == NULL);
- summary = folder->summary;
+ summary = camel_folder_get_folder_summary (folder);
g_hash_table_iter_init (&iter, infos);
while (g_hash_table_iter_next (&iter, &key, &value)) {
@@ -4862,7 +4853,7 @@ imapx_server_process_fetch_changes_infos (CamelIMAPXServer *is,
g_mutex_unlock (&is->priv->changes_lock);
}
- camel_message_info_unref (minfo);
+ g_clear_object (&minfo);
}
}
@@ -5027,20 +5018,20 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
folder = imapx_server_ref_folder (is, mailbox);
g_return_val_if_fail (folder != NULL, FALSE);
- imapx_summary = CAMEL_IMAPX_SUMMARY (folder->summary);
+ imapx_summary = CAMEL_IMAPX_SUMMARY (camel_folder_get_folder_summary (folder));
messages = camel_imapx_mailbox_get_messages (mailbox);
unseen = camel_imapx_mailbox_get_unseen (mailbox);
uidnext = camel_imapx_mailbox_get_uidnext (mailbox);
uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
highestmodseq = camel_imapx_mailbox_get_highestmodseq (mailbox);
- total = camel_folder_summary_count (folder->summary);
+ total = camel_folder_summary_count (camel_folder_get_folder_summary (folder));
need_rescan =
(uidvalidity > 0 && uidvalidity != imapx_summary->validity) ||
total != messages ||
imapx_summary->uidnext != uidnext ||
- camel_folder_summary_get_unread_count (folder->summary) != unseen ||
+ camel_folder_summary_get_unread_count (camel_folder_get_folder_summary (folder)) != unseen ||
imapx_summary->modseq != highestmodseq;
if (!need_rescan) {
@@ -5056,7 +5047,7 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
if (is->priv->use_qresync && imapx_summary->modseq > 0 && uidvalidity > 0) {
imapx_summary->modseq = highestmodseq;
if (total != messages ||
- camel_folder_summary_get_unread_count (folder->summary) != unseen ||
+ camel_folder_summary_get_unread_count (camel_folder_get_folder_summary (folder)) !=
unseen ||
imapx_summary->modseq != highestmodseq) {
c (
is->priv->tagprefix,
@@ -5064,7 +5055,7 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
"total %u / %u, unread %u / %u, modseq %"
G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "\n",
total, messages,
- camel_folder_summary_get_unread_count (folder->summary),
+ camel_folder_summary_get_unread_count (camel_folder_get_folder_summary
(folder)),
unseen,
imapx_summary->modseq,
highestmodseq);
@@ -5075,7 +5066,7 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
"total %u / %u, unread %u / %u, modseq %"
G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "\n",
total, messages,
- camel_folder_summary_get_unread_count (folder->summary),
+ camel_folder_summary_get_unread_count (camel_folder_get_folder_summary
(folder)),
unseen,
imapx_summary->modseq,
highestmodseq);
@@ -5097,7 +5088,7 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
uidl = 1;
}
- camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary (folder), NULL);
known_uids = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free,
NULL);
@@ -5111,11 +5102,11 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
GPtrArray *array;
gint ii;
- camel_folder_summary_lock (folder->summary);
+ camel_folder_summary_lock (camel_folder_get_folder_summary (folder));
changes = camel_folder_change_info_new ();
- array = camel_folder_summary_get_array (folder->summary);
+ array = camel_folder_summary_get_array (camel_folder_get_folder_summary (folder));
for (ii = 0; array && ii < array->len; ii++) {
const gchar *uid = array->pdata[ii];
@@ -5128,18 +5119,18 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
}
}
- camel_folder_summary_unlock (folder->summary);
+ camel_folder_summary_unlock (camel_folder_get_folder_summary (folder));
if (removed != NULL) {
- camel_folder_summary_remove_uids (folder->summary, removed);
- camel_folder_summary_touch (folder->summary);
+ camel_folder_summary_remove_uids (camel_folder_get_folder_summary (folder), removed);
+ camel_folder_summary_touch (camel_folder_get_folder_summary (folder));
/* Shares UIDs with the 'array'. */
g_list_free (removed);
}
if (camel_folder_change_info_changed (changes)) {
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ camel_folder_summary_save (camel_folder_get_folder_summary (folder), NULL);
imapx_update_store_summary (folder);
camel_folder_changed (folder, changes);
}
@@ -5169,7 +5160,7 @@ imapx_sync_free_user (GArray *user_set)
for (j = 0; j < infos->len; j++) {
CamelMessageInfo *info = g_ptr_array_index (infos, j);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
g_ptr_array_free (infos, TRUE);
@@ -5194,42 +5185,20 @@ imapx_unset_folder_flagged_flag (CamelFolderSummary *summary,
info = camel_folder_summary_get (summary, changed_uids->pdata[ii]);
if (info) {
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
-
/* some infos could be only 'dirty' (needed to save into summary) */
- if ((mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0 &&
- (!except_deleted_messages || (mi->flags & CAMEL_MESSAGE_DELETED) == 0)) {
- mi->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- mi->dirty = TRUE;
+ if (camel_message_info_get_folder_flagged (info) &&
+ (!except_deleted_messages || (camel_message_info_get_flags (info) &
CAMEL_MESSAGE_DELETED) == 0)) {
+ camel_message_info_set_folder_flagged (info, FALSE);
changed = TRUE;
}
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
}
if (changed) {
camel_folder_summary_touch (summary);
- camel_folder_summary_save_to_db (summary, NULL);
- }
-}
-
-static void
-imapx_server_info_changed_cb (CamelIMAPXSummary *summary,
- CamelMessageInfo *info,
- gpointer user_data)
-{
- GHashTable *changed_meanwhile = user_data;
-
- g_return_if_fail (info != NULL);
- g_return_if_fail (changed_meanwhile != NULL);
-
- /* The UID can be NULL in case of a newly fetched message, for example when creating
- the message info in imapx_untagged_fetch() by camel_folder_summary_info_new_from_parser() */
- if (camel_message_info_get_uid (info)) {
- g_hash_table_insert (changed_meanwhile,
- (gpointer) camel_pstring_strdup (camel_message_info_get_uid (info)),
- GINT_TO_POINTER (1));
+ camel_folder_summary_save (summary, NULL);
}
}
@@ -5244,9 +5213,8 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
GPtrArray *changed_uids;
GArray *on_user = NULL, *off_user = NULL;
CamelFolder *folder;
- CamelIMAPXMessageInfo *info;
- GHashTable *changed_meanwhile;
- gulong changed_meanwhile_handler_id;
+ CamelMessageInfo *info;
+ GHashTable *stamps;
guint32 permanentflags;
struct _uidset_state uidset;
gint unread_change = 0;
@@ -5272,7 +5240,7 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
* one for each flag being turned off, including each
* info being turned off, and one for each flag being turned on.
*/
- changed_uids = camel_folder_summary_get_changed (folder->summary);
+ changed_uids = camel_folder_summary_get_changed (camel_folder_get_folder_summary (folder));
if (changed_uids->len == 0) {
camel_folder_free_uids (folder, changed_uids);
@@ -5280,9 +5248,7 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
return TRUE;
}
- changed_meanwhile = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)
camel_pstring_free, NULL);
- changed_meanwhile_handler_id = g_signal_connect (folder->summary, "info-changed",
- G_CALLBACK (imapx_server_info_changed_cb), changed_meanwhile);
+ stamps = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
if (can_influence_flags) {
CamelIMAPXSettings *settings;
@@ -5312,30 +5278,38 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
}
if (changed_uids->len > 20)
- camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary (folder), NULL);
off_orset = on_orset = 0;
for (i = 0; i < changed_uids->len; i++) {
+ CamelIMAPXMessageInfo *xinfo;
guint32 flags, sflags;
- CamelFlag *uflags, *suflags;
+ const CamelNamedFlags *local_uflags, *server_uflags;
const gchar *uid;
guint j = 0;
uid = g_ptr_array_index (changed_uids, i);
- info = (CamelIMAPXMessageInfo *)
- camel_folder_summary_get (folder->summary, uid);
+ info = camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid);
+ xinfo = info ? CAMEL_IMAPX_MESSAGE_INFO (info) : NULL;
- if (info == NULL)
+ if (!info || !xinfo) {
+ g_clear_object (&info);
continue;
+ }
- if (!(info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- camel_message_info_unref (info);
+ if (!camel_message_info_get_folder_flagged (info)) {
+ g_clear_object (&info);
continue;
}
- flags = info->info.flags & CAMEL_IMAPX_SERVER_FLAGS;
- sflags = info->server_flags & CAMEL_IMAPX_SERVER_FLAGS;
+ camel_message_info_property_lock (info);
+
+ g_hash_table_insert (stamps, (gpointer) camel_message_info_pooldup_uid (info),
+ GUINT_TO_POINTER (camel_message_info_get_folder_flagged_stamp (info)));
+
+ flags = camel_message_info_get_flags (info) & CAMEL_IMAPX_SERVER_FLAGS;
+ sflags = camel_imapx_message_info_get_server_flags (xinfo) & CAMEL_IMAPX_SERVER_FLAGS;
if (can_influence_flags) {
gboolean move_to_real_junk;
@@ -5363,63 +5337,76 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
on_orset |= (flags ^ sflags) & flags;
}
- uflags = info->info.user_flags;
- suflags = info->server_user_flags;
- while (uflags || suflags) {
- gint res;
-
- if (uflags) {
- if (suflags)
- res = strcmp (uflags->name, suflags->name);
- else if (*uflags->name)
- res = -1;
- else {
- uflags = uflags->next;
- continue;
- }
- } else {
- res = 1;
- }
+ local_uflags = camel_message_info_get_user_flags (info);
+ server_uflags = camel_imapx_message_info_get_server_user_flags (xinfo);
- if (res == 0) {
- uflags = uflags->next;
- suflags = suflags->next;
- } else {
- GArray *user_set;
- CamelFlag *user_flag;
- struct _imapx_flag_change *change = NULL, add = { 0 };
-
- if (res < 0) {
- if (on_user == NULL)
- on_user = g_array_new (FALSE, FALSE, sizeof (struct
_imapx_flag_change));
- user_set = on_user;
- user_flag = uflags;
- uflags = uflags->next;
+ if (!camel_named_flags_equal (local_uflags, server_uflags)) {
+ guint ii, jj, llen, slen;
+
+ llen = local_uflags ? camel_named_flags_get_length (local_uflags) : 0;
+ slen = server_uflags ? camel_named_flags_get_length (server_uflags) : 0;
+ for (ii = 0, jj = 0; ii < llen || jj < slen;) {
+ gint res;
+
+ if (ii < llen) {
+ const gchar *local_name = camel_named_flags_get (local_uflags, ii);
+
+ if (jj < slen) {
+ const gchar *server_name = camel_named_flags_get
(server_uflags, jj);
+
+ res = g_strcmp0 (local_name, server_name);
+ } else if (local_name && *local_name)
+ res = -1;
+ else {
+ ii++;
+ continue;
+ }
} else {
- if (off_user == NULL)
- off_user = g_array_new (FALSE, FALSE, sizeof (struct
_imapx_flag_change));
- user_set = off_user;
- user_flag = suflags;
- suflags = suflags->next;
+ res = 1;
}
- /* Could sort this and binary search */
- for (j = 0; j < user_set->len; j++) {
- change = &g_array_index (user_set, struct _imapx_flag_change, j);
- if (strcmp (change->name, user_flag->name) == 0)
- goto found;
+ if (res == 0) {
+ ii++;
+ jj++;
+ } else {
+ GArray *user_set;
+ const gchar *user_flag_name;
+ struct _imapx_flag_change *change = NULL, add = { 0 };
+
+ if (res < 0) {
+ if (on_user == NULL)
+ on_user = g_array_new (FALSE, FALSE, sizeof (struct
_imapx_flag_change));
+ user_set = on_user;
+ user_flag_name = camel_named_flags_get (local_uflags, ii);
+ ii++;
+ } else {
+ if (off_user == NULL)
+ off_user = g_array_new (FALSE, FALSE, sizeof (struct
_imapx_flag_change));
+ user_set = off_user;
+ user_flag_name = camel_named_flags_get (server_uflags, jj);
+ jj++;
+ }
+
+ /* Could sort this and binary search */
+ for (j = 0; j < user_set->len; j++) {
+ change = &g_array_index (user_set, struct _imapx_flag_change,
j);
+ if (g_strcmp0 (change->name, user_flag_name) == 0)
+ goto found;
+ }
+ add.name = g_strdup (user_flag_name);
+ add.infos = g_ptr_array_new ();
+ g_array_append_val (user_set, add);
+ change = &add;
+ found:
+ g_object_ref (info);
+ g_ptr_array_add (change->infos, info);
}
- add.name = g_strdup (user_flag->name);
- add.infos = g_ptr_array_new ();
- g_array_append_val (user_set, add);
- change = &add;
- found:
- camel_message_info_ref (info);
- g_ptr_array_add (change->infos, info);
}
}
- camel_message_info_unref (info);
+ camel_message_info_property_unlock (info);
+
+ g_clear_object (&info);
}
nothing_to_do =
@@ -5429,24 +5416,20 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
(off_user == NULL);
if (nothing_to_do) {
- g_signal_handler_disconnect (folder->summary, changed_meanwhile_handler_id);
-
imapx_sync_free_user (on_user);
imapx_sync_free_user (off_user);
- imapx_unset_folder_flagged_flag (folder->summary, changed_uids, remove_deleted_flags);
+ imapx_unset_folder_flagged_flag (camel_folder_get_folder_summary (folder), changed_uids,
remove_deleted_flags);
camel_folder_free_uids (folder, changed_uids);
- g_hash_table_destroy (changed_meanwhile);
+ g_hash_table_destroy (stamps);
g_object_unref (folder);
return TRUE;
}
if (!camel_imapx_server_ensure_selected_sync (is, mailbox, cancellable, error)) {
- g_signal_handler_disconnect (folder->summary, changed_meanwhile_handler_id);
-
imapx_sync_free_user (on_user);
imapx_sync_free_user (off_user);
camel_folder_free_uids (folder, changed_uids);
- g_hash_table_destroy (changed_meanwhile);
+ g_hash_table_destroy (stamps);
g_object_unref (folder);
return FALSE;
}
@@ -5468,22 +5451,23 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
c (is->priv->tagprefix, "checking/storing %s flags '%s'\n", on ? "on" : "off",
flags_table[jj].name);
imapx_uidset_init (&uidset, 0, 100);
for (i = 0; i < changed_uids->len && success; i++) {
- CamelIMAPXMessageInfo *info;
+ CamelMessageInfo *info;
+ CamelIMAPXMessageInfo *xinfo;
gboolean remove_deleted_flag;
guint32 flags;
guint32 sflags;
gint send;
- info = (CamelIMAPXMessageInfo *)
- camel_folder_summary_get (
- folder->summary,
- changed_uids->pdata[i]);
+ info = camel_folder_summary_get (camel_folder_get_folder_summary (folder),
changed_uids->pdata[i]);
+ xinfo = info ? CAMEL_IMAPX_MESSAGE_INFO (info) : NULL;
- if (info == NULL)
+ if (!info || !xinfo) {
+ g_clear_object (&info);
continue;
+ }
- flags = (info->info.flags & CAMEL_IMAPX_SERVER_FLAGS) & permanentflags;
- sflags = (info->server_flags & CAMEL_IMAPX_SERVER_FLAGS) & permanentflags;
+ flags = (camel_message_info_get_flags (info) & CAMEL_IMAPX_SERVER_FLAGS) &
permanentflags;
+ sflags = (camel_imapx_message_info_get_server_flags (xinfo) &
CAMEL_IMAPX_SERVER_FLAGS) & permanentflags;
send = 0;
remove_deleted_flag =
@@ -5527,10 +5511,11 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
/* The second round and the server doesn't support saving user flags,
thus store them at least locally */
if (on && (permanentflags & CAMEL_MESSAGE_USER) == 0) {
- camel_flag_list_copy (&info->server_user_flags,
&info->info.user_flags);
+ camel_imapx_message_info_take_server_user_flags (xinfo,
+ camel_message_info_dup_user_flags (info));
}
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
g_warn_if_fail (ic == NULL);
@@ -5544,7 +5529,7 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
imapx_uidset_init (&uidset, 0, 100);
for (i = 0; i < c->infos->len; i++) {
- CamelIMAPXMessageInfo *info = c->infos->pdata[i];
+ CamelMessageInfo *info = c->infos->pdata[i];
if (ic == NULL)
ic = camel_imapx_command_new (is,
CAMEL_IMAPX_JOB_SYNC_CHANGES, "UID STORE ");
@@ -5572,45 +5557,64 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
}
}
- g_signal_handler_disconnect (folder->summary, changed_meanwhile_handler_id);
-
if (success) {
+ CamelFolderSummary *folder_summary;
CamelStore *parent_store;
guint32 unseen;
parent_store = camel_folder_get_parent_store (folder);
+ folder_summary = camel_folder_get_folder_summary (folder);
- camel_folder_summary_lock (folder->summary);
+ camel_folder_summary_lock (folder_summary);
for (i = 0; i < changed_uids->len; i++) {
- CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) camel_folder_summary_get
(folder->summary,
- changed_uids->pdata[i]);
+ CamelMessageInfo *info;
+ CamelIMAPXMessageInfo *xinfo;
+ gboolean set_folder_flagged;
+ guint32 has_flags, set_server_flags;
+ gboolean changed_meanwhile;
+
+ info = camel_folder_summary_get (folder_summary, changed_uids->pdata[i]);
+ xinfo = info ? CAMEL_IMAPX_MESSAGE_INFO (info) : NULL;
- if (!xinfo)
+ if (!info || !xinfo) {
+ g_clear_object (&info);
continue;
+ }
+
+ camel_message_info_property_lock (info);
+
+ changed_meanwhile = camel_message_info_get_folder_flagged_stamp (info) !=
+ GPOINTER_TO_UINT (g_hash_table_lookup (stamps, changed_uids->pdata[i]));
- xinfo->server_flags = xinfo->info.flags & CAMEL_IMAPX_SERVER_FLAGS;
+ has_flags = camel_message_info_get_flags (info);
+ set_server_flags = has_flags & CAMEL_IMAPX_SERVER_FLAGS;
if (!remove_deleted_flags ||
- !(xinfo->info.flags & CAMEL_MESSAGE_DELETED)) {
- xinfo->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+ !(has_flags & CAMEL_MESSAGE_DELETED)) {
+ set_folder_flagged = FALSE;
} else {
/* to stare back the \Deleted flag */
- xinfo->server_flags &= ~CAMEL_MESSAGE_DELETED;
- xinfo->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+ set_server_flags &= ~CAMEL_MESSAGE_DELETED;
+ set_folder_flagged = TRUE;
}
- xinfo->info.dirty = TRUE;
+
if ((permanentflags & CAMEL_MESSAGE_USER) != 0 ||
- camel_flag_list_size (&xinfo->server_user_flags) == 0)
- camel_flag_list_copy (&xinfo->server_user_flags, &xinfo->info.user_flags);
+ !camel_named_flags_get_length (camel_imapx_message_info_get_server_user_flags
(xinfo))) {
+ camel_imapx_message_info_take_server_user_flags (xinfo,
camel_message_info_dup_user_flags (info));
+ }
+
+ if (changed_meanwhile)
+ set_folder_flagged = TRUE;
- if (g_hash_table_lookup (changed_meanwhile, changed_uids->pdata[i]))
- xinfo->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+ camel_imapx_message_info_set_server_flags (xinfo, set_server_flags);
+ camel_message_info_set_folder_flagged (info, set_folder_flagged);
- camel_folder_summary_touch (folder->summary);
- camel_message_info_unref (xinfo);
+ camel_message_info_property_unlock (info);
+ camel_folder_summary_touch (folder_summary);
+ g_clear_object (&info);
}
- camel_folder_summary_unlock (folder->summary);
+ camel_folder_summary_unlock (folder_summary);
/* Apply the changes to server-side unread count; it won't tell
* us of these changes, of course. */
@@ -5618,16 +5622,16 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
unseen += unread_change;
camel_imapx_mailbox_set_unseen (mailbox, unseen);
- if (folder->summary && (folder->summary->flags & CAMEL_FOLDER_SUMMARY_DIRTY) != 0) {
+ if ((camel_folder_summary_get_flags (folder_summary) & CAMEL_FOLDER_SUMMARY_DIRTY) != 0) {
CamelStoreInfo *si;
/* ... and store's summary when folder's summary is dirty */
si = camel_store_summary_path (CAMEL_IMAPX_STORE (parent_store)->summary,
camel_folder_get_full_name (folder));
if (si) {
- if (si->total != camel_folder_summary_get_saved_count (folder->summary) ||
- si->unread != camel_folder_summary_get_unread_count (folder->summary)) {
- si->total = camel_folder_summary_get_saved_count (folder->summary);
- si->unread = camel_folder_summary_get_unread_count (folder->summary);
+ if (si->total != camel_folder_summary_get_saved_count (folder_summary) ||
+ si->unread != camel_folder_summary_get_unread_count (folder_summary)) {
+ si->total = camel_folder_summary_get_saved_count (folder_summary);
+ si->unread = camel_folder_summary_get_unread_count (folder_summary);
camel_store_summary_touch (CAMEL_IMAPX_STORE (parent_store)->summary);
}
@@ -5635,14 +5639,14 @@ camel_imapx_server_sync_changes_sync (CamelIMAPXServer *is,
}
}
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ camel_folder_summary_save (folder_summary, NULL);
camel_store_summary_save (CAMEL_IMAPX_STORE (parent_store)->summary);
}
imapx_sync_free_user (on_user);
imapx_sync_free_user (off_user);
camel_folder_free_uids (folder, changed_uids);
- g_hash_table_destroy (changed_meanwhile);
+ g_hash_table_destroy (stamps);
g_object_unref (folder);
return success;
@@ -5674,15 +5678,17 @@ camel_imapx_server_expunge_sync (CamelIMAPXServer *is,
if (success) {
GPtrArray *uids;
CamelStore *parent_store;
+ CamelFolderSummary *folder_summary;
const gchar *full_name;
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
+ folder_summary = camel_folder_get_folder_summary (folder);
- camel_folder_summary_lock (folder->summary);
+ camel_folder_summary_lock (folder_summary);
- camel_folder_summary_save_to_db (folder->summary, NULL);
- uids = camel_db_get_folder_deleted_uids (parent_store->cdb_r, full_name, NULL);
+ camel_folder_summary_save (folder_summary, NULL);
+ uids = camel_db_get_folder_deleted_uids (camel_store_get_db (parent_store),
full_name, NULL);
if (uids && uids->len) {
CamelFolderChangeInfo *changes;
@@ -5695,8 +5701,8 @@ camel_imapx_server_expunge_sync (CamelIMAPXServer *is,
removed = g_list_prepend (removed, (gpointer) uids->pdata[i]);
}
- camel_folder_summary_remove_uids (folder->summary, removed);
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ camel_folder_summary_remove_uids (folder_summary, removed);
+ camel_folder_summary_save (folder_summary, NULL);
camel_folder_changed (folder, changes);
camel_folder_change_info_free (changes);
@@ -5708,7 +5714,7 @@ camel_imapx_server_expunge_sync (CamelIMAPXServer *is,
if (uids)
g_ptr_array_free (uids, TRUE);
- camel_folder_summary_unlock (folder->summary);
+ camel_folder_summary_unlock (folder_summary);
}
camel_imapx_command_unref (ic);
diff --git a/src/camel/providers/imapx/camel-imapx-server.h b/src/camel/providers/imapx/camel-imapx-server.h
index 16d5090..c51e005 100644
--- a/src/camel/providers/imapx/camel-imapx-server.h
+++ b/src/camel/providers/imapx/camel-imapx-server.h
@@ -114,6 +114,9 @@ struct _CamelIMAPXServerClass {
/* Signals */
void (*refresh_mailbox) (CamelIMAPXServer *is,
CamelIMAPXMailbox *mailbox);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_server_get_type (void);
diff --git a/src/camel/providers/imapx/camel-imapx-settings.h
b/src/camel/providers/imapx/camel-imapx-settings.h
index f1e402e..4de7306 100644
--- a/src/camel/providers/imapx/camel-imapx-settings.h
+++ b/src/camel/providers/imapx/camel-imapx-settings.h
@@ -52,6 +52,9 @@ struct _CamelIMAPXSettings {
struct _CamelIMAPXSettingsClass {
CamelOfflineSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_settings_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/providers/imapx/camel-imapx-status-response.h
b/src/camel/providers/imapx/camel-imapx-status-response.h
index 49af19a..47ce8cd 100644
--- a/src/camel/providers/imapx/camel-imapx-status-response.h
+++ b/src/camel/providers/imapx/camel-imapx-status-response.h
@@ -62,6 +62,9 @@ struct _CamelIMAPXStatusResponse {
struct _CamelIMAPXStatusResponseClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_status_response_get_type
diff --git a/src/camel/providers/imapx/camel-imapx-store-summary.h
b/src/camel/providers/imapx/camel-imapx-store-summary.h
index 2d919d1..390bb74 100644
--- a/src/camel/providers/imapx/camel-imapx-store-summary.h
+++ b/src/camel/providers/imapx/camel-imapx-store-summary.h
@@ -60,6 +60,9 @@ struct _CamelIMAPXStoreSummary {
struct _CamelIMAPXStoreSummaryClass {
CamelStoreSummaryClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_store_summary_get_type
diff --git a/src/camel/providers/imapx/camel-imapx-store.c b/src/camel/providers/imapx/camel-imapx-store.c
index 96bbb84..9a8282e 100644
--- a/src/camel/providers/imapx/camel-imapx-store.c
+++ b/src/camel/providers/imapx/camel-imapx-store.c
@@ -153,23 +153,27 @@ imapx_store_update_store_flags (CamelStore *store)
CamelService *service;
CamelSettings *settings;
CamelIMAPXSettings *imapx_settings;
+ guint32 store_flags;
service = CAMEL_SERVICE (store);
settings = camel_service_ref_settings (service);
imapx_settings = CAMEL_IMAPX_SETTINGS (settings);
+ store_flags = camel_store_get_flags (store);
if (camel_imapx_settings_get_use_real_junk_path (imapx_settings)) {
- store->flags &= ~CAMEL_STORE_VJUNK;
- store->flags |= CAMEL_STORE_REAL_JUNK_FOLDER;
+ store_flags &= ~CAMEL_STORE_VJUNK;
+ store_flags |= CAMEL_STORE_REAL_JUNK_FOLDER;
} else {
- store->flags |= CAMEL_STORE_VJUNK;
- store->flags &= ~CAMEL_STORE_REAL_JUNK_FOLDER;
+ store_flags |= CAMEL_STORE_VJUNK;
+ store_flags &= ~CAMEL_STORE_REAL_JUNK_FOLDER;
}
if (camel_imapx_settings_get_use_real_trash_path (imapx_settings))
- store->flags &= ~CAMEL_STORE_VTRASH;
+ store_flags &= ~CAMEL_STORE_VTRASH;
else
- store->flags |= CAMEL_STORE_VTRASH;
+ store_flags |= CAMEL_STORE_VTRASH;
+
+ camel_store_set_flags (store, store_flags);
g_object_unref (settings);
}
@@ -226,7 +230,7 @@ imapx_store_build_folder_info (CamelIMAPXStore *imapx_store,
fi->display_name = g_strdup (name);
}
- if ((store->flags & CAMEL_STORE_VTRASH) == 0) {
+ if ((camel_store_get_flags (store) & CAMEL_STORE_VTRASH) == 0) {
const gchar *trash_path;
trash_path = camel_imapx_settings_get_real_trash_path (
@@ -235,7 +239,7 @@ imapx_store_build_folder_info (CamelIMAPXStore *imapx_store,
fi->flags |= CAMEL_FOLDER_TYPE_TRASH;
}
- if ((store->flags & CAMEL_STORE_REAL_JUNK_FOLDER) != 0) {
+ if ((camel_store_get_flags (store) & CAMEL_STORE_REAL_JUNK_FOLDER) != 0) {
const gchar *junk_path;
junk_path = camel_imapx_settings_get_real_junk_path (
@@ -351,8 +355,7 @@ imapx_store_add_mailbox_to_folder (CamelIMAPXStore *store,
folder_path = camel_imapx_mailbox_dup_folder_path (mailbox);
- folder = camel_object_bag_get (
- CAMEL_STORE (store)->folders, folder_path);
+ folder = camel_object_bag_get (camel_store_get_folders_bag (CAMEL_STORE (store)), folder_path);
if (folder != NULL) {
camel_imapx_folder_set_mailbox (folder, mailbox);
@@ -557,14 +560,14 @@ imapx_store_process_mailbox_status (CamelIMAPXStore *imapx_store,
store = CAMEL_STORE (imapx_store);
/* Update only already opened folders */
- folder = camel_object_bag_reserve (store->folders, folder_path);
+ folder = camel_object_bag_reserve (camel_store_get_folders_bag (store), folder_path);
if (folder != NULL) {
CamelIMAPXFolder *imapx_folder;
CamelIMAPXSummary *imapx_summary;
guint32 uidvalidity;
imapx_folder = CAMEL_IMAPX_FOLDER (folder);
- imapx_summary = CAMEL_IMAPX_SUMMARY (folder->summary);
+ imapx_summary = CAMEL_IMAPX_SUMMARY (camel_folder_get_folder_summary (folder));
uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
@@ -574,7 +577,7 @@ imapx_store_process_mailbox_status (CamelIMAPXStore *imapx_store,
g_object_unref (folder);
} else {
- camel_object_bag_abort (store->folders, folder_path);
+ camel_object_bag_abort (camel_store_get_folders_bag (store), folder_path);
}
g_free (folder_path);
@@ -945,14 +948,14 @@ fill_fi (CamelStore *store,
{
CamelFolder *folder;
- folder = camel_object_bag_peek (store->folders, fi->full_name);
+ folder = camel_object_bag_peek (camel_store_get_folders_bag (store), fi->full_name);
if (folder) {
CamelIMAPXFolder *imapx_folder;
CamelIMAPXSummary *ims;
CamelIMAPXMailbox *mailbox;
- if (folder->summary)
- ims = (CamelIMAPXSummary *) folder->summary;
+ if (camel_folder_get_folder_summary (folder))
+ ims = CAMEL_IMAPX_SUMMARY (camel_folder_get_folder_summary (folder));
else
ims = (CamelIMAPXSummary *) camel_imapx_summary_new (folder);
@@ -964,7 +967,7 @@ fill_fi (CamelStore *store,
g_clear_object (&mailbox);
- if (!folder->summary)
+ if (!camel_folder_get_folder_summary (folder))
g_object_unref (ims);
g_object_unref (folder);
}
@@ -997,8 +1000,7 @@ imapx_delete_folder_from_cache (CamelIMAPXStore *imapx_store,
g_unlink (state_file);
g_free (state_file);
- camel_db_delete_folder (
- CAMEL_STORE (imapx_store)->cdb_w, folder_path, NULL);
+ camel_db_delete_folder (camel_store_get_db (CAMEL_STORE (imapx_store)), folder_path, NULL);
g_rmdir (folder_dir);
state_file = g_build_filename (folder_dir, "subfolders", NULL);
@@ -1046,8 +1048,8 @@ get_folder_info_offline (CamelStore *store,
return NULL;
fi = imapx_store_build_folder_info (imapx_store, top, 0);
- fi->unread = camel_folder_summary_get_unread_count (vfolder->summary);
- fi->total = camel_folder_summary_get_saved_count (vfolder->summary);
+ fi->unread = camel_folder_summary_get_unread_count (camel_folder_get_folder_summary
(vfolder));
+ fi->total = camel_folder_summary_get_saved_count (camel_folder_get_folder_summary (vfolder));
if (g_strcmp0 (top, CAMEL_VTRASH_NAME) == 0)
fi->flags = (fi->flags & ~CAMEL_FOLDER_TYPE_MASK) |
@@ -1790,7 +1792,7 @@ imapx_store_get_folder_sync (CamelStore *store,
real_junk_path = g_strdup ("");
if (g_ascii_strcasecmp (real_junk_path, folder_name) == 0)
- folder->folder_flags |= CAMEL_FOLDER_IS_JUNK;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) |
CAMEL_FOLDER_IS_JUNK);
g_free (real_junk_path);
}
@@ -1807,7 +1809,7 @@ imapx_store_get_folder_sync (CamelStore *store,
real_trash_path = g_strdup ("");
if (g_ascii_strcasecmp (real_trash_path, folder_name) == 0)
- folder->folder_flags |= CAMEL_FOLDER_IS_TRASH;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) |
CAMEL_FOLDER_IS_TRASH);
g_free (real_trash_path);
}
@@ -2603,7 +2605,7 @@ imapx_store_initable_init (GInitable *initable,
store = CAMEL_STORE (initable);
service = CAMEL_SERVICE (initable);
- store->flags |= CAMEL_STORE_USE_CACHE_DIR | CAMEL_STORE_SUPPORTS_INITIAL_SETUP;
+ camel_store_set_flags (store, camel_store_get_flags (store) | CAMEL_STORE_USE_CACHE_DIR |
CAMEL_STORE_SUPPORTS_INITIAL_SETUP);
imapx_migrate_to_user_cache_dir (service);
/* Chain up to parent interface's init() method. */
diff --git a/src/camel/providers/imapx/camel-imapx-store.h b/src/camel/providers/imapx/camel-imapx-store.h
index e25eccd..c9f5d2f 100644
--- a/src/camel/providers/imapx/camel-imapx-store.h
+++ b/src/camel/providers/imapx/camel-imapx-store.h
@@ -72,6 +72,9 @@ struct _CamelIMAPXStoreClass {
const gchar *oldname);
void (*mailbox_updated) (CamelIMAPXStore *imapx_store,
CamelIMAPXMailbox *mailbox);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_store_get_type (void);
diff --git a/src/camel/providers/imapx/camel-imapx-summary.c b/src/camel/providers/imapx/camel-imapx-summary.c
index 6e3a2d2..b1af6bf 100644
--- a/src/camel/providers/imapx/camel-imapx-summary.c
+++ b/src/camel/providers/imapx/camel-imapx-summary.c
@@ -28,16 +28,13 @@
#include <camel/camel.h>
+#include "camel-imapx-message-info.h"
#include "camel-imapx-summary.h"
-#define CAMEL_IMAPX_SUMMARY_VERSION (4)
-
-enum {
- INFO_CHANGED,
- LAST_SIGNAL
-};
+/* Don't do DB sort. Its pretty slow to load */
+/* #define SORT_DB 1 */
-static guint signals[LAST_SIGNAL];
+#define CAMEL_IMAPX_SUMMARY_VERSION (4)
G_DEFINE_TYPE (
CamelIMAPXSummary,
@@ -45,15 +42,13 @@ G_DEFINE_TYPE (
CAMEL_TYPE_FOLDER_SUMMARY)
static gboolean
-imapx_summary_summary_header_from_db (CamelFolderSummary *s,
- CamelFIRecord *mir)
+imapx_summary_summary_header_load (CamelFolderSummary *s,
+ CamelFIRecord *mir)
{
gboolean success;
- /* Chain up to parent's summary_header_from_db() method. */
- success = CAMEL_FOLDER_SUMMARY_CLASS (
- camel_imapx_summary_parent_class)->
- summary_header_from_db (s, mir);
+ /* Chain up to parent's summary_header_load() method. */
+ success = CAMEL_FOLDER_SUMMARY_CLASS (camel_imapx_summary_parent_class)->summary_header_load (s, mir);
if (success) {
CamelIMAPXSummary *ims;
@@ -61,12 +56,12 @@ imapx_summary_summary_header_from_db (CamelFolderSummary *s,
ims = CAMEL_IMAPX_SUMMARY (s);
- ims->version = bdata_extract_digit (&part);
- ims->validity = bdata_extract_digit (&part);
+ ims->version = camel_util_bdata_get_number (&part, 0);
+ ims->validity = camel_util_bdata_get_number (&part, 0);
if (ims->version >= 4) {
- ims->uidnext = bdata_extract_digit (&part);
- ims->modseq = bdata_extract_digit (&part);
+ ims->uidnext = camel_util_bdata_get_number (&part, 0);
+ ims->modseq = camel_util_bdata_get_number (&part, 0);
}
if (ims->version > CAMEL_IMAPX_SUMMARY_VERSION) {
@@ -80,15 +75,13 @@ imapx_summary_summary_header_from_db (CamelFolderSummary *s,
}
static CamelFIRecord *
-imapx_summary_summary_header_to_db (CamelFolderSummary *s,
- GError **error)
+imapx_summary_summary_header_save (CamelFolderSummary *s,
+ GError **error)
{
struct _CamelFIRecord *fir;
- /* Chain up to parent's summary_header_to_db() method. */
- fir = CAMEL_FOLDER_SUMMARY_CLASS (
- camel_imapx_summary_parent_class)->
- summary_header_to_db (s, error);
+ /* Chain up to parent's summary_header_save() method. */
+ fir = CAMEL_FOLDER_SUMMARY_CLASS (camel_imapx_summary_parent_class)->summary_header_save (s, error);
if (fir != NULL) {
CamelIMAPXSummary *ims;
@@ -109,236 +102,19 @@ imapx_summary_summary_header_to_db (CamelFolderSummary *s,
return fir;
}
-static CamelMessageInfo *
-imapx_summary_message_info_from_db (CamelFolderSummary *s,
- CamelMIRecord *mir)
-{
- CamelMessageInfo *info;
-
- /* Chain up parent's message_info_from_db() method. */
- info = CAMEL_FOLDER_SUMMARY_CLASS (
- camel_imapx_summary_parent_class)->
- message_info_from_db (s, mir);
-
- if (info != NULL) {
- CamelIMAPXMessageInfo *imapx_info;
- gchar *part = mir->bdata;
-
- imapx_info = (CamelIMAPXMessageInfo *) info;
- imapx_info->server_flags = bdata_extract_digit (&part);
- }
-
- return info;
-}
-
-static CamelMIRecord *
-imapx_summary_message_info_to_db (CamelFolderSummary *s,
- CamelMessageInfo *info)
-{
- struct _CamelMIRecord *mir;
-
- /* Chain up to parent's message_info_to_db() method. */
- mir = CAMEL_FOLDER_SUMMARY_CLASS (
- camel_imapx_summary_parent_class)->
- message_info_to_db (s, info);
-
- if (mir != NULL) {
- CamelIMAPXMessageInfo *imapx_info;
-
- imapx_info = (CamelIMAPXMessageInfo *) info;
- mir->bdata = g_strdup_printf ("%u", imapx_info->server_flags);
- }
-
- return mir;
-}
-
-static CamelMessageContentInfo *
-imapx_summary_content_info_from_db (CamelFolderSummary *summary,
- CamelMIRecord *mir)
-{
- gchar *part = mir->cinfo;
- guint32 type = 0;
-
- if (part != NULL) {
- if (*part == ' ')
- part++;
- if (part != NULL)
- type = bdata_extract_digit (&part);
- }
- mir->cinfo = part;
-
- if (type) {
- /* Chain up to parent's content_info_from_db() method. */
- return CAMEL_FOLDER_SUMMARY_CLASS (
- camel_imapx_summary_parent_class)->
- content_info_from_db (summary, mir);
- } else {
- return camel_folder_summary_content_info_new (summary);
- }
-}
-
-static gboolean
-imapx_summary_content_info_to_db (CamelFolderSummary *summary,
- CamelMessageContentInfo *info,
- CamelMIRecord *mir)
-{
- gchar *oldr;
-
- if (info->type) {
- oldr = mir->cinfo;
- if (oldr != NULL)
- mir->cinfo = g_strdup_printf ("%s 1", oldr);
- else
- mir->cinfo = g_strdup ("1");
- g_free (oldr);
-
- /* Chain up to parent's content_info_to_db() method. */
- return CAMEL_FOLDER_SUMMARY_CLASS (
- camel_imapx_summary_parent_class)->
- content_info_to_db (summary, info, mir);
-
- } else {
- oldr = mir->cinfo;
- if (oldr != NULL)
- mir->cinfo = g_strdup_printf ("%s 0", oldr);
- else
- mir->cinfo = g_strdup ("0");
- g_free (oldr);
-
- return TRUE;
- }
-}
-
-static void
-imapx_summary_message_info_free (CamelFolderSummary *summary,
- CamelMessageInfo *info)
-{
- CamelIMAPXMessageInfo *imapx_info;
-
- imapx_info = (CamelIMAPXMessageInfo *) info;
- camel_flag_list_free (&imapx_info->server_user_flags);
-
- /* Chain up to parent's message_info_free() method. */
- CAMEL_FOLDER_SUMMARY_CLASS (camel_imapx_summary_parent_class)->
- message_info_free (summary, info);
-}
-
-static CamelMessageInfo *
-imapx_summary_message_info_clone (CamelFolderSummary *summary,
- const CamelMessageInfo *info)
-{
- CamelMessageInfo *copy;
- CamelIMAPXMessageInfo *imapx_copy;
- CamelIMAPXMessageInfo *imapx_info;
-
- /* Chain up to parent's message_info_clone() method. */
- copy = CAMEL_FOLDER_SUMMARY_CLASS (
- camel_imapx_summary_parent_class)->
- message_info_clone (summary, info);
-
- imapx_info = (CamelIMAPXMessageInfo *) info;
- imapx_copy = (CamelIMAPXMessageInfo *) copy;
-
- if (imapx_info->server_user_flags) {
- camel_flag_list_copy (
- &imapx_copy->server_user_flags,
- &imapx_info->server_user_flags);
- }
-
- imapx_copy->server_flags = imapx_info->server_flags;
-
- /* FIXME: parent clone should do this */
- imapx_copy->info.content =
- camel_folder_summary_content_info_new (summary);
-
- return copy;
-}
-
-static void
-imapx_summary_emit_info_changed (CamelMessageInfo *info)
-{
- g_return_if_fail (info != NULL);
- g_return_if_fail (CAMEL_IS_IMAPX_SUMMARY (info->summary));
-
- g_signal_emit (info->summary, signals[INFO_CHANGED], 0, info);
-}
-
-static gboolean
-imapx_summary_info_set_user_flag (CamelMessageInfo *info,
- const gchar *id,
- gboolean state)
-{
- gboolean changed;
-
- /* Chain up to parent's method. */
- changed = CAMEL_FOLDER_SUMMARY_CLASS (camel_imapx_summary_parent_class)->info_set_user_flag (info,
id, state);
-
- if (changed)
- imapx_summary_emit_info_changed (info);
-
- return changed;
-}
-
-static gboolean
-imapx_summary_info_set_user_tag (CamelMessageInfo *info,
- const gchar *name,
- const gchar *value)
-{
- gboolean changed;
-
- /* Chain up to parent's method. */
- changed = CAMEL_FOLDER_SUMMARY_CLASS (camel_imapx_summary_parent_class)->info_set_user_tag (info,
name, value);
-
- if (changed)
- imapx_summary_emit_info_changed (info);
-
- return changed;
-}
-
-static gboolean
-imapx_summary_info_set_flags (CamelMessageInfo *info,
- guint32 flags,
- guint32 set)
-{
- gboolean changed;
-
- /* Chain up to parent's method. */
- changed = CAMEL_FOLDER_SUMMARY_CLASS (camel_imapx_summary_parent_class)->info_set_flags (info, flags,
set);
-
- if (changed)
- imapx_summary_emit_info_changed (info);
-
- return changed;
-}
-
static void
camel_imapx_summary_class_init (CamelIMAPXSummaryClass *class)
{
CamelFolderSummaryClass *folder_summary_class;
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
- folder_summary_class->message_info_size = sizeof (CamelIMAPXMessageInfo);
- folder_summary_class->content_info_size = sizeof (CamelIMAPXMessageContentInfo);
- folder_summary_class->summary_header_from_db = imapx_summary_summary_header_from_db;
- folder_summary_class->summary_header_to_db = imapx_summary_summary_header_to_db;
- folder_summary_class->message_info_from_db = imapx_summary_message_info_from_db;
- folder_summary_class->message_info_to_db = imapx_summary_message_info_to_db;
- folder_summary_class->content_info_from_db = imapx_summary_content_info_from_db;
- folder_summary_class->content_info_to_db = imapx_summary_content_info_to_db;
- folder_summary_class->message_info_free = imapx_summary_message_info_free;
- folder_summary_class->message_info_clone = imapx_summary_message_info_clone;
- folder_summary_class->info_set_user_flag = imapx_summary_info_set_user_flag;
- folder_summary_class->info_set_user_tag = imapx_summary_info_set_user_tag;
- folder_summary_class->info_set_flags = imapx_summary_info_set_flags;
-
- signals[INFO_CHANGED] = g_signal_new (
- "info-changed",
- G_OBJECT_CLASS_TYPE (class),
- G_SIGNAL_RUN_LAST,
- 0 /* G_STRUCT_OFFSET (CamelIMAPXSummaryClass, info_changed) */,
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER /* CamelMessageInfo * */);
+ folder_summary_class->message_info_type = CAMEL_TYPE_IMAPX_MESSAGE_INFO;
+#ifdef SORT_DB
+ folder_summary_class->sort_by = "uid";
+ folder_summary_class->collate = "imapx_uid_sort";
+#endif
+ folder_summary_class->summary_header_load = imapx_summary_summary_header_load;
+ folder_summary_class->summary_header_save = imapx_summary_summary_header_save;
}
static void
@@ -346,6 +122,7 @@ camel_imapx_summary_init (CamelIMAPXSummary *obj)
{
}
+#ifdef SORT_DB
static gint
sort_uid_cmp (gpointer enc,
gint len1,
@@ -373,6 +150,7 @@ sort_uid_cmp (gpointer enc,
return (a1 < a2) ? -1 : (a1 > a2) ? 1 : 0;
}
+#endif
/**
* camel_imapx_summary_new:
@@ -386,24 +164,20 @@ sort_uid_cmp (gpointer enc,
CamelFolderSummary *
camel_imapx_summary_new (CamelFolder *folder)
{
+#ifdef SORT_DB
CamelStore *parent_store;
+#endif
CamelFolderSummary *summary;
GError *local_error = NULL;
- parent_store = camel_folder_get_parent_store (folder);
-
summary = g_object_new (CAMEL_TYPE_IMAPX_SUMMARY, "folder", folder, NULL);
- /* Don't do DB sort. Its pretty slow to load */
- if (folder && 0) {
- camel_db_set_collate (parent_store->cdb_r, "uid", "imapx_uid_sort", (CamelDBCollate)
sort_uid_cmp);
- summary->sort_by = "uid";
- summary->collate = "imapx_uid_sort";
- }
-
- camel_folder_summary_set_build_content (summary, TRUE);
+#ifdef SORT_DB
+ parent_store = camel_folder_get_parent_store (folder);
+ camel_db_set_collate (camel_store_get_db (parent_store), "uid", "imapx_uid_sort", (CamelDBCollate)
sort_uid_cmp);
+#endif
- if (!camel_folder_summary_load_from_db (summary, &local_error)) {
+ if (!camel_folder_summary_load (summary, &local_error)) {
/* FIXME: Isn't this dangerous ? We clear the summary
if it cannot be loaded, for some random reason.
We need to pass the error and find out why it is not loaded etc. ? */
@@ -414,4 +188,3 @@ camel_imapx_summary_new (CamelFolder *folder)
return summary;
}
-
diff --git a/src/camel/providers/imapx/camel-imapx-summary.h b/src/camel/providers/imapx/camel-imapx-summary.h
index c515c19..3f4d989 100644
--- a/src/camel/providers/imapx/camel-imapx-summary.h
+++ b/src/camel/providers/imapx/camel-imapx-summary.h
@@ -55,20 +55,6 @@ G_BEGIN_DECLS
typedef struct _CamelIMAPXSummary CamelIMAPXSummary;
typedef struct _CamelIMAPXSummaryClass CamelIMAPXSummaryClass;
-typedef struct _CamelIMAPXMessageInfo CamelIMAPXMessageInfo;
-typedef struct _CamelIMAPXMessageContentInfo CamelIMAPXMessageContentInfo;
-
-struct _CamelIMAPXMessageContentInfo {
- CamelMessageContentInfo info;
-};
-
-struct _CamelIMAPXMessageInfo {
- CamelMessageInfoBase info;
-
- guint32 server_flags;
- CamelFlag *server_user_flags;
-};
-
struct _CamelIMAPXSummary {
CamelFolderSummary parent;
@@ -80,6 +66,9 @@ struct _CamelIMAPXSummary {
struct _CamelIMAPXSummaryClass {
CamelFolderSummaryClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_imapx_summary_get_type (void);
diff --git a/src/camel/providers/imapx/camel-imapx-utils.c b/src/camel/providers/imapx/camel-imapx-utils.c
index c60666d..3d981f4 100644
--- a/src/camel/providers/imapx/camel-imapx-utils.c
+++ b/src/camel/providers/imapx/camel-imapx-utils.c
@@ -24,6 +24,7 @@
#include "camel-imapx-command.h"
#include "camel-imapx-folder.h"
+#include "camel-imapx-message-info.h"
#include "camel-imapx-settings.h"
#include "camel-imapx-summary.h"
#include "camel-imapx-store.h"
@@ -101,7 +102,7 @@ static struct {
gboolean
imapx_parse_flags (CamelIMAPXInputStream *stream,
guint32 *flagsp,
- CamelFlag **user_flagsp,
+ CamelNamedFlags *user_flags,
GCancellable *cancellable,
GError **error)
{
@@ -149,7 +150,7 @@ imapx_parse_flags (CamelIMAPXInputStream *stream,
}
}
- if (!match_found && user_flagsp != NULL) {
+ if (!match_found && user_flags) {
const gchar *flag_name;
gchar *utf8;
@@ -163,7 +164,7 @@ imapx_parse_flags (CamelIMAPXInputStream *stream,
utf8 = NULL;
}
- camel_flag_set (user_flagsp, utf8 ? utf8 : flag_name, TRUE);
+ camel_named_flags_insert (user_flags, utf8 ? utf8 : flag_name);
g_free (utf8);
}
@@ -225,44 +226,50 @@ rename_label_flag (const gchar *flag,
void
imapx_write_flags (GString *string,
guint32 flags,
- CamelFlag *user_flags)
+ const CamelNamedFlags *user_flags)
{
- gint i;
+ guint ii;
gboolean first = TRUE;
g_string_append_c (string, '(');
- for (i = 0; flags != 0 && i< G_N_ELEMENTS (flag_table); i++) {
- if (flag_table[i].flag & flags) {
- if (flag_table[i].flag & CAMEL_IMAPX_MESSAGE_RECENT)
+ for (ii = 0; flags != 0 && ii < G_N_ELEMENTS (flag_table); ii++) {
+ if (flag_table[ii].flag & flags) {
+ if (flag_table[ii].flag & CAMEL_IMAPX_MESSAGE_RECENT)
continue;
if (!first)
g_string_append_c (string, ' ');
first = FALSE;
- g_string_append (string, flag_table[i].name);
+ g_string_append (string, flag_table[ii].name);
- flags &= ~flag_table[i].flag;
+ flags &= ~flag_table[ii].flag;
}
}
- while (user_flags) {
- const gchar *flag_name;
- gchar *utf7;
+ if (user_flags) {
+ guint len = camel_named_flags_get_length (user_flags);
+
+ for (ii = 0; ii < len; ii++) {
+ const gchar *name = camel_named_flags_get (user_flags, ii);
+ const gchar *flag_name;
+ gchar *utf7;
- flag_name = rename_label_flag (
- user_flags->name, strlen (user_flags->name), FALSE);
+ if (!name || !*name)
+ continue;
- if (!first)
- g_string_append_c (string, ' ');
- first = FALSE;
- utf7 = camel_utf8_utf7 (flag_name);
+ flag_name = rename_label_flag (name, strlen (name), FALSE);
+
+ if (!first)
+ g_string_append_c (string, ' ');
+ first = FALSE;
- g_string_append (string, utf7 ? utf7 : flag_name);
+ utf7 = camel_utf8_utf7 (flag_name);
- g_free (utf7);
+ g_string_append (string, utf7 ? utf7 : flag_name);
- user_flags = user_flags->next;
+ g_free (utf7);
+ }
}
g_string_append_c (string, ')');
@@ -270,26 +277,38 @@ imapx_write_flags (GString *string,
static gboolean
imapx_update_user_flags (CamelMessageInfo *info,
- CamelFlag *server_user_flags)
+ const CamelNamedFlags *server_user_flags)
{
gboolean changed = FALSE;
- CamelMessageInfoBase *binfo = (CamelMessageInfoBase *) info;
- CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) info;
+ const CamelNamedFlags *mi_user_flags;
gboolean set_cal = FALSE, set_note = FALSE;
- if (camel_flag_get (&binfo->user_flags, "$has_cal"))
+ mi_user_flags = camel_message_info_get_user_flags (info);
+ if (camel_named_flags_equal (mi_user_flags, server_user_flags)) {
+ mi_user_flags = camel_imapx_message_info_get_server_user_flags (CAMEL_IMAPX_MESSAGE_INFO
(info));
+
+ if (!camel_named_flags_equal (mi_user_flags, server_user_flags)) {
+ camel_imapx_message_info_take_server_user_flags (CAMEL_IMAPX_MESSAGE_INFO (info),
+ camel_named_flags_copy (server_user_flags));
+ }
+
+ return FALSE;
+ }
+
+ if (mi_user_flags && camel_named_flags_contains (mi_user_flags, "$has_cal"))
set_cal = TRUE;
- if (camel_flag_get (&binfo->user_flags, "$has_note"))
+ if (mi_user_flags && camel_named_flags_contains (mi_user_flags, "$has_note"))
set_note = TRUE;
- changed = camel_flag_list_copy (&binfo->user_flags, &server_user_flags);
- camel_flag_list_copy (&xinfo->server_user_flags, &server_user_flags);
+ changed = camel_message_info_take_user_flags (info, camel_named_flags_copy (server_user_flags));
+ camel_imapx_message_info_take_server_user_flags (CAMEL_IMAPX_MESSAGE_INFO (info),
+ camel_named_flags_copy (server_user_flags));
/* reset the flags as they were set in messageinfo before */
if (set_cal)
- camel_flag_set (&binfo->user_flags, "$has_cal", TRUE);
+ camel_message_info_set_user_flag (info, "$has_cal", TRUE);
if (set_note)
- camel_flag_set (&binfo->user_flags, "$has_note", TRUE);
+ camel_message_info_set_user_flag (info, "$has_note", TRUE);
return changed;
}
@@ -297,16 +316,16 @@ imapx_update_user_flags (CamelMessageInfo *info,
gboolean
imapx_update_message_info_flags (CamelMessageInfo *info,
guint32 server_flags,
- CamelFlag *server_user_flags,
+ const CamelNamedFlags *server_user_flags,
guint32 permanent_flags,
CamelFolder *folder,
gboolean unsolicited)
{
gboolean changed = FALSE;
- CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) info;
+ CamelIMAPXMessageInfo *xinfo = CAMEL_IMAPX_MESSAGE_INFO (info);
/* Locally made changes should not be overwritten, it'll be (re)saved later */
- if ((camel_message_info_get_flags (info) & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
+ if (camel_message_info_get_folder_flagged (info)) {
d ('?', "Skipping update of locally changed uid:'%s'\n", camel_message_info_get_uid (info));
return FALSE;
}
@@ -314,15 +333,21 @@ imapx_update_message_info_flags (CamelMessageInfo *info,
/* This makes sure that server flags has precedence from locally stored flags,
* thus a user actually sees what is stored on the server */
if ((camel_message_info_get_flags (info) & CAMEL_IMAPX_SERVER_FLAGS) != (server_flags &
CAMEL_IMAPX_SERVER_FLAGS)) {
- xinfo->server_flags = (xinfo->server_flags & ~CAMEL_IMAPX_SERVER_FLAGS) |
- (camel_message_info_get_flags (info) & CAMEL_IMAPX_SERVER_FLAGS);
+ guint32 old_server_flags;
+
+ old_server_flags = camel_imapx_message_info_get_server_flags (xinfo);
+
+ camel_imapx_message_info_set_server_flags (xinfo,
+ (old_server_flags & ~CAMEL_IMAPX_SERVER_FLAGS) |
+ (camel_message_info_get_flags (info) & CAMEL_IMAPX_SERVER_FLAGS));
}
- if (server_flags != xinfo->server_flags) {
- guint32 server_set, server_cleared;
+ if (server_flags != camel_imapx_message_info_get_server_flags (xinfo)) {
+ guint32 server_set, server_cleared, old_server_flags;
- server_set = server_flags & ~xinfo->server_flags;
- server_cleared = xinfo->server_flags & ~server_flags;
+ old_server_flags = camel_imapx_message_info_get_server_flags (xinfo);
+ server_set = server_flags & ~old_server_flags;
+ server_cleared = old_server_flags & ~server_flags;
/* Don't clear non-permanent server-side flags.
* This avoids overwriting local flags that we
@@ -330,13 +355,11 @@ imapx_update_message_info_flags (CamelMessageInfo *info,
if (permanent_flags > 0)
server_cleared &= permanent_flags;
- changed = camel_message_info_set_flags ((
- CamelMessageInfo *) xinfo,
+ changed = camel_message_info_set_flags (info,
server_set | server_cleared,
- (xinfo->info.flags | server_set) & ~server_cleared);
+ (camel_message_info_get_flags (info) | server_set) & ~server_cleared);
- xinfo->server_flags = server_flags;
- xinfo->info.dirty = TRUE;
+ camel_imapx_message_info_set_server_flags (xinfo, server_flags);
}
if ((permanent_flags & CAMEL_MESSAGE_USER) != 0 && imapx_update_user_flags (info, server_user_flags))
@@ -348,29 +371,22 @@ imapx_update_message_info_flags (CamelMessageInfo *info,
void
imapx_set_message_info_flags_for_new_message (CamelMessageInfo *info,
guint32 server_flags,
- CamelFlag *server_user_flags,
+ const CamelNamedFlags *server_user_flags,
gboolean force_user_flags,
- CamelTag *user_tags,
+ const CamelNameValueArray *user_tags,
guint32 permanent_flags)
{
- CamelMessageInfoBase *binfo = (CamelMessageInfoBase *) info;
- CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) info;
-
- binfo->flags |= server_flags;
- camel_message_info_set_flags (info, server_flags, binfo->flags | server_flags);
+ CamelIMAPXMessageInfo *xinfo = CAMEL_IMAPX_MESSAGE_INFO (info);
- xinfo->server_flags = server_flags;
+ camel_message_info_set_flags (info, server_flags, camel_message_info_get_flags (info) | server_flags);
+ camel_imapx_message_info_set_server_flags (xinfo, server_flags);
if (force_user_flags || (permanent_flags & CAMEL_MESSAGE_USER) != 0)
imapx_update_user_flags (info, server_user_flags);
- while (user_tags) {
- camel_message_info_set_user_tag (info, user_tags->name, user_tags->value);
- user_tags = user_tags->next;
- }
+ camel_message_info_take_user_tags (info, camel_name_value_array_copy (user_tags));
- binfo->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- binfo->dirty = TRUE;
+ camel_message_info_set_folder_flagged (info, FALSE);
}
void
@@ -394,8 +410,8 @@ imapx_update_store_summary (CamelFolder *folder)
if (si == NULL)
return;
- total = camel_folder_summary_count (folder->summary);
- unread = camel_folder_summary_get_unread_count (folder->summary);
+ total = camel_folder_summary_count (camel_folder_get_folder_summary (folder));
+ unread = camel_folder_summary_get_unread_count (camel_folder_get_folder_summary (folder));
if (si->unread != unread || si->total != total) {
si->unread = unread;
@@ -416,7 +432,7 @@ camel_imapx_dup_uid_from_summary_index (CamelFolder *folder,
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
- summary = folder->summary;
+ summary = camel_folder_get_folder_summary (folder);
g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
array = camel_folder_summary_get_array (summary);
@@ -1150,7 +1166,7 @@ imapx_parse_address_list (CamelIMAPXInputStream *stream,
return list;
}
-struct _CamelMessageInfo *
+CamelMessageInfo *
imapx_parse_envelope (CamelIMAPXInputStream *stream,
GCancellable *cancellable,
GError **error)
@@ -1160,7 +1176,7 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
guchar *token;
CamelHeaderAddress *addr, *addr_from;
gchar *addrstr;
- struct _CamelMessageInfoBase *minfo = NULL;
+ CamelMessageInfo *info;
GError *local_error = NULL;
/* envelope ::= "(" env_date SPACE env_subject SPACE env_from
@@ -1168,7 +1184,7 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
* SPACE env_cc SPACE env_bcc SPACE env_in_reply_to
* SPACE env_message_id ")" */
- minfo = (CamelMessageInfoBase *) camel_message_info_new (NULL);
+ info = camel_message_info_new (NULL);
tok = camel_imapx_input_stream_token (
stream, &token, &len, cancellable, &local_error);
@@ -1178,7 +1194,7 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
if (tok != '(') {
g_clear_error (&local_error);
- camel_message_info_unref (minfo);
+ g_clear_object (&info);
g_set_error (error, CAMEL_IMAPX_ERROR, CAMEL_IMAPX_ERROR_SERVER_RESPONSE_MALFORMED,
"envelope: expecting '('");
return NULL;
}
@@ -1188,14 +1204,14 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
if (local_error)
goto error;
- minfo->date_sent = camel_header_decode_date ((gchar *) token, NULL);
+ camel_message_info_set_date_sent (info, camel_header_decode_date ((gchar *) token, NULL));
/* env_subject ::= nstring */
camel_imapx_input_stream_nstring (stream, &token, cancellable, &local_error);
if (local_error)
goto error;
- minfo->subject = camel_pstring_strdup ((gchar *) token);
+ camel_message_info_set_subject (info, (const gchar *) token);
/* we merge from/sender into from, append should probably merge more smartly? */
@@ -1218,7 +1234,7 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
if (addr_from) {
addrstr = camel_header_address_list_format (addr_from);
- minfo->from = camel_pstring_strdup (addrstr);
+ camel_message_info_set_from (info, addrstr);
g_free (addrstr);
camel_header_address_list_clear (&addr_from);
}
@@ -1236,7 +1252,7 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
addr = imapx_parse_address_list (stream, cancellable, &local_error);
if (addr) {
addrstr = camel_header_address_list_format (addr);
- minfo->to = camel_pstring_strdup (addrstr);
+ camel_message_info_set_to (info, addrstr);
g_free (addrstr);
camel_header_address_list_clear (&addr);
}
@@ -1248,7 +1264,7 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
addr = imapx_parse_address_list (stream, cancellable, &local_error);
if (addr) {
addrstr = camel_header_address_list_format (addr);
- minfo->cc = camel_pstring_strdup (addrstr);
+ camel_message_info_set_cc (info, addrstr);
g_free (addrstr);
camel_header_address_list_clear (&addr);
}
@@ -1285,7 +1301,7 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
if (tok != ')') {
g_clear_error (&local_error);
- camel_message_info_unref (minfo);
+ g_clear_object (&info);
g_set_error (error, CAMEL_IMAPX_ERROR, CAMEL_IMAPX_ERROR_SERVER_RESPONSE_MALFORMED,
"expecting ')'");
return NULL;
}
@@ -1294,15 +1310,14 @@ imapx_parse_envelope (CamelIMAPXInputStream *stream,
/* CHEN TODO handle exceptions better */
if (local_error != NULL) {
g_propagate_error (error, local_error);
- if (minfo)
- camel_message_info_unref (minfo);
+ g_clear_object (&info);
return NULL;
}
- return (CamelMessageInfo *) minfo;
+ return info;
}
-struct _CamelMessageContentInfo *
+CamelMessageContentInfo *
imapx_parse_body (CamelIMAPXInputStream *stream,
GCancellable *cancellable,
GError **error)
@@ -1449,7 +1464,7 @@ imapx_parse_body (CamelIMAPXInputStream *stream,
/* what do we do with the message content info?? */
//((CamelMessageInfoBase *) minfo)->content = imapx_parse_body (stream);
- camel_message_info_unref (minfo);
+ g_clear_object (&minfo);
minfo = NULL;
}
@@ -1673,11 +1688,10 @@ imapx_free_fetch (struct _fetch_info *finfo)
g_bytes_unref (finfo->text);
if (finfo->header)
g_bytes_unref (finfo->header);
- if (finfo->minfo)
- camel_message_info_unref (finfo->minfo);
if (finfo->cinfo)
imapx_free_body (finfo->cinfo);
- camel_flag_list_free (&finfo->user_flags);
+ camel_named_flags_free (finfo->user_flags);
+ g_clear_object (&finfo->minfo);
g_free (finfo->date);
g_free (finfo->section);
g_free (finfo->uid);
@@ -1853,7 +1867,7 @@ imapx_parse_fetch_flags (CamelIMAPXInputStream *stream,
gboolean success;
success = imapx_parse_flags (
- stream, &finfo->flags, &finfo->user_flags,
+ stream, &finfo->flags, finfo->user_flags,
cancellable, error);
if (success)
@@ -2003,6 +2017,7 @@ imapx_parse_fetch (CamelIMAPXInputStream *stream,
struct _fetch_info *finfo;
finfo = g_malloc0 (sizeof (*finfo));
+ finfo->user_flags = camel_named_flags_new ();
tok = camel_imapx_input_stream_token (
stream, &token, &len, cancellable, error);
@@ -2632,7 +2647,7 @@ camel_imapx_command_add_qresync_parameter (CamelIMAPXCommand *ic,
g_return_val_if_fail (CAMEL_IS_IMAPX_FOLDER (folder), FALSE);
imapx_folder = CAMEL_IMAPX_FOLDER (folder);
- imapx_summary = CAMEL_IMAPX_SUMMARY (folder->summary);
+ imapx_summary = CAMEL_IMAPX_SUMMARY (camel_folder_get_folder_summary (folder));
mailbox = camel_imapx_folder_ref_mailbox (imapx_folder);
if (!mailbox)
@@ -2644,7 +2659,7 @@ camel_imapx_command_add_qresync_parameter (CamelIMAPXCommand *ic,
/* XXX This should return an unsigned integer to
* avoid the possibility of a negative count. */
- summary_total = camel_folder_summary_count (folder->summary);
+ summary_total = camel_folder_summary_count (camel_folder_get_folder_summary (folder));
g_return_val_if_fail (summary_total >= 0, FALSE);
if (summary_total > 0) {
diff --git a/src/camel/providers/imapx/camel-imapx-utils.h b/src/camel/providers/imapx/camel-imapx-utils.h
index 7fc055b..d9d7e34 100644
--- a/src/camel/providers/imapx/camel-imapx-utils.h
+++ b/src/camel/providers/imapx/camel-imapx-utils.h
@@ -30,7 +30,6 @@ G_BEGIN_DECLS
* enum/struct definitions and helper macros, so we don't
* have these conflicting header dependencies. */
struct _CamelIMAPXCommand;
-struct _CamelFlag;
struct _CamelIMAPXStore;
/* list of strings we know about that can be *quickly* tokenised */
@@ -136,24 +135,24 @@ GArray * imapx_parse_uids (CamelIMAPXInputStream *stream,
GError **error);
gboolean imapx_parse_flags (CamelIMAPXInputStream *stream,
guint32 *flagsp,
- struct _CamelFlag **user_flagsp,
+ CamelNamedFlags *user_flags,
GCancellable *cancellable,
GError **error);
void imapx_write_flags (GString *string,
guint32 flags,
- struct _CamelFlag *user_flags);
+ const CamelNamedFlags *user_flags);
gboolean imapx_update_message_info_flags (CamelMessageInfo *info,
guint32 server_flags,
- CamelFlag *server_user_flags,
+ const CamelNamedFlags *server_user_flags,
guint32 permanent_flags,
CamelFolder *folder,
gboolean unsolicited);
void imapx_set_message_info_flags_for_new_message
(CamelMessageInfo *info,
guint32 server_flags,
- CamelFlag *server_user_flags,
+ const CamelNamedFlags *server_user_flags,
gboolean force_user_flags,
- CamelTag *user_tags,
+ const CamelNameValueArray *user_tags,
guint32 permanent_flags);
void imapx_update_store_summary (CamelFolder *folder);
@@ -218,11 +217,11 @@ CamelHeaderAddress *
imapx_parse_address_list (CamelIMAPXInputStream *stream,
GCancellable *cancellable,
GError **error);
-struct _CamelMessageInfo *
+CamelMessageInfo *
imapx_parse_envelope (CamelIMAPXInputStream *stream,
GCancellable *cancellable,
GError **error);
-struct _CamelMessageContentInfo *
+CamelMessageContentInfo *
imapx_parse_body (CamelIMAPXInputStream *stream,
GCancellable *cancellable,
GError **error);
@@ -245,7 +244,7 @@ struct _fetch_info {
guint32 offset; /* start offset of a BODY[]<offset.length> request */
guint32 flags; /* FLAGS */
guint64 modseq; /* MODSEQ */
- CamelFlag *user_flags;
+ CamelNamedFlags *user_flags;
gchar *date; /* INTERNALDATE */
gchar *section; /* section for a BODY[section] request */
gchar *uid; /* UID */
diff --git a/src/camel/providers/local/CMakeLists.txt b/src/camel/providers/local/CMakeLists.txt
index 169e489..24afeb4 100644
--- a/src/camel/providers/local/CMakeLists.txt
+++ b/src/camel/providers/local/CMakeLists.txt
@@ -10,12 +10,16 @@ set(SOURCES
camel-local-provider.c
camel-maildir-folder.c
camel-maildir-folder.h
+ camel-maildir-message-info.c
+ camel-maildir-message-info.h
camel-maildir-store.c
camel-maildir-store.h
camel-maildir-summary.c
camel-maildir-summary.h
camel-mbox-folder.c
camel-mbox-folder.h
+ camel-mbox-message-info.c
+ camel-mbox-message-info.h
camel-mbox-store.c
camel-mbox-store.h
camel-mbox-summary.c
diff --git a/src/camel/providers/local/camel-local-folder.c b/src/camel/providers/local/camel-local-folder.c
index 47ba761..1b451aa 100644
--- a/src/camel/providers/local/camel-local-folder.c
+++ b/src/camel/providers/local/camel-local-folder.c
@@ -102,17 +102,16 @@ local_folder_dispose (GObject *object)
folder = CAMEL_FOLDER (object);
local_folder = CAMEL_LOCAL_FOLDER (object);
- if (folder->summary) {
+ if (camel_folder_get_folder_summary (folder)) {
/* Something can hold the reference to the folder longer than
the parent store is alive, thus count with it. */
if (camel_folder_get_parent_store (folder)) {
camel_local_summary_sync (
- CAMEL_LOCAL_SUMMARY (folder->summary),
+ CAMEL_LOCAL_SUMMARY (camel_folder_get_folder_summary (folder)),
FALSE, local_folder->changes, NULL, NULL);
}
}
- g_clear_object (&folder->summary);
g_clear_object (&local_folder->search);
g_clear_object (&local_folder->index);
@@ -223,6 +222,18 @@ local_folder_constructed (GObject *object)
g_free (path);
}
+static guint32
+local_folder_get_permanent_flags (CamelFolder *folder)
+{
+ return CAMEL_MESSAGE_ANSWERED |
+ CAMEL_MESSAGE_DELETED |
+ CAMEL_MESSAGE_DRAFT |
+ CAMEL_MESSAGE_FLAGGED |
+ CAMEL_MESSAGE_SEEN |
+ CAMEL_MESSAGE_ANSWERED_ALL |
+ CAMEL_MESSAGE_USER;
+}
+
static GPtrArray *
local_folder_search_by_expression (CamelFolder *folder,
const gchar *expression,
@@ -331,8 +342,8 @@ local_folder_rename (CamelFolder *folder,
g_free (statepath);
/* FIXME: Poke some internals, sigh */
- g_free (((CamelLocalSummary *) folder->summary)->folder_path);
- ((CamelLocalSummary *) folder->summary)->folder_path = g_strdup (lf->folder_path);
+ g_free (((CamelLocalSummary *) camel_folder_get_folder_summary (folder))->folder_path);
+ ((CamelLocalSummary *) camel_folder_get_folder_summary (folder))->folder_path = g_strdup
(lf->folder_path);
CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->rename (folder, newname);
}
@@ -399,7 +410,7 @@ local_folder_refresh_info_sync (CamelFolder *folder,
CAMEL_LOCAL_STORE (parent_store));
if (need_summary_check &&
- camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable,
error) == -1)
+ camel_local_summary_check ((CamelLocalSummary *) camel_folder_get_folder_summary (folder),
lf->changes, cancellable, error) == -1)
return FALSE;
if (camel_folder_change_info_changed (lf->changes)) {
@@ -428,7 +439,7 @@ local_folder_synchronize_sync (CamelFolder *folder,
/* if sync fails, we'll pass it up on exit through ex */
success = (camel_local_summary_sync (
- (CamelLocalSummary *) folder->summary,
+ (CamelLocalSummary *) camel_folder_get_folder_summary (folder),
expunge, lf->changes, cancellable, error) == 0);
camel_local_folder_unlock (lf);
@@ -470,6 +481,7 @@ camel_local_folder_class_init (CamelLocalFolderClass *class)
object_class->constructed = local_folder_constructed;
folder_class = CAMEL_FOLDER_CLASS (class);
+ folder_class->get_permanent_flags = local_folder_get_permanent_flags;
folder_class->search_by_expression = local_folder_search_by_expression;
folder_class->search_by_uids = local_folder_search_by_uids;
folder_class->search_free = local_folder_search_free;
@@ -504,14 +516,8 @@ camel_local_folder_init (CamelLocalFolder *local_folder)
local_folder->priv = CAMEL_LOCAL_FOLDER_GET_PRIVATE (local_folder);
g_mutex_init (&local_folder->priv->search_lock);
- folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY;
-
- folder->permanent_flags = CAMEL_MESSAGE_ANSWERED |
- CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT |
- CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN |
- CAMEL_MESSAGE_ANSWERED_ALL | CAMEL_MESSAGE_USER;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) |
CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY);
- folder->summary = NULL;
local_folder->search = NULL;
}
@@ -622,13 +628,13 @@ camel_local_folder_construct (CamelLocalFolder *lf,
forceindex = FALSE;
}
- folder->summary = (CamelFolderSummary *) CAMEL_LOCAL_FOLDER_GET_CLASS (lf)->create_summary (lf,
lf->folder_path, lf->index);
- if (!(flags & CAMEL_STORE_IS_MIGRATING) && !camel_local_summary_load ((CamelLocalSummary *)
folder->summary, forceindex, NULL)) {
+ camel_folder_take_folder_summary (folder, CAMEL_FOLDER_SUMMARY (CAMEL_LOCAL_FOLDER_GET_CLASS
(lf)->create_summary (lf, lf->folder_path, lf->index)));
+ if (!(flags & CAMEL_STORE_IS_MIGRATING) && !camel_local_summary_load ((CamelLocalSummary *)
camel_folder_get_folder_summary (folder), forceindex, NULL)) {
/* ? */
if (need_summary_check &&
- camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes,
cancellable, error) == 0) {
+ camel_local_summary_check ((CamelLocalSummary *) camel_folder_get_folder_summary
(folder), lf->changes, cancellable, error) == 0) {
/* we sync here so that any hard work setting up the folder isn't lost */
- if (camel_local_summary_sync ((CamelLocalSummary *) folder->summary, FALSE,
lf->changes, cancellable, error) == -1) {
+ if (camel_local_summary_sync ((CamelLocalSummary *) camel_folder_get_folder_summary
(folder), FALSE, lf->changes, cancellable, error) == -1) {
g_object_unref (folder);
return NULL;
}
diff --git a/src/camel/providers/local/camel-local-folder.h b/src/camel/providers/local/camel-local-folder.h
index 00bcb8e..e09c410 100644
--- a/src/camel/providers/local/camel-local-folder.h
+++ b/src/camel/providers/local/camel-local-folder.h
@@ -89,6 +89,9 @@ struct _CamelLocalFolderClass {
/* Unlock the folder for my operations */
void (*unlock) (CamelLocalFolder *);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_local_folder_get_type (void);
diff --git a/src/camel/providers/local/camel-local-store.c b/src/camel/providers/local/camel-local-store.c
index 324a44e..6790b95 100644
--- a/src/camel/providers/local/camel-local-store.c
+++ b/src/camel/providers/local/camel-local-store.c
@@ -532,7 +532,7 @@ local_store_rename_folder_sync (CamelStore *store,
d (printf ("local rename folder '%s' '%s'\n", old, new));
- folder = camel_object_bag_get (store->folders, old);
+ folder = camel_object_bag_get (camel_store_get_folders_bag (store), old);
if (folder && folder->index) {
if (camel_index_rename (folder->index, newibex) == -1)
goto ibex_failed;
diff --git a/src/camel/providers/local/camel-local-store.h b/src/camel/providers/local/camel-local-store.h
index 32e492f..a71d920 100644
--- a/src/camel/providers/local/camel-local-store.h
+++ b/src/camel/providers/local/camel-local-store.h
@@ -62,6 +62,9 @@ struct _CamelLocalStoreClass {
gchar * (*get_meta_path) (CamelLocalStore *ls,
const gchar *full_name,
const gchar *ext);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_local_store_get_type (void);
diff --git a/src/camel/providers/local/camel-local-summary.c b/src/camel/providers/local/camel-local-summary.c
index 9fee506..1d0a2c3 100644
--- a/src/camel/providers/local/camel-local-summary.c
+++ b/src/camel/providers/local/camel-local-summary.c
@@ -37,25 +37,23 @@
#define CAMEL_LOCAL_SUMMARY_VERSION (1)
-#define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
-
static CamelFIRecord *
- summary_header_to_db (CamelFolderSummary *,
+ summary_header_save (CamelFolderSummary *,
GError **error);
-static gboolean summary_header_from_db (CamelFolderSummary *,
+static gboolean summary_header_load (CamelFolderSummary *,
CamelFIRecord *);
static CamelMessageInfo *
- message_info_new_from_header (CamelFolderSummary *,
- struct _camel_header_raw *);
+ message_info_new_from_headers (CamelFolderSummary *,
+ const CamelNameValueArray *);
static gint local_summary_decode_x_evolution
(CamelLocalSummary *cls,
const gchar *xev,
- CamelLocalMessageInfo *mi);
+ CamelMessageInfo *mi);
static gchar * local_summary_encode_x_evolution
(CamelLocalSummary *cls,
- const CamelLocalMessageInfo *mi);
+ const CamelMessageInfo *mi);
static gint local_summary_load (CamelLocalSummary *cls,
gint forceindex,
@@ -119,11 +117,9 @@ camel_local_summary_class_init (CamelLocalSummaryClass *class)
object_class->finalize = local_summary_finalize;
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
- folder_summary_class->message_info_size = sizeof (CamelLocalMessageInfo);
- folder_summary_class->content_info_size = sizeof (CamelMessageContentInfo);
- folder_summary_class->summary_header_from_db = summary_header_from_db;
- folder_summary_class->summary_header_to_db = summary_header_to_db;
- folder_summary_class->message_info_new_from_header = message_info_new_from_header;
+ folder_summary_class->summary_header_load = summary_header_load;
+ folder_summary_class->summary_header_save = summary_header_save;
+ folder_summary_class->message_info_new_from_headers = message_info_new_from_headers;
class->load = local_summary_load;
class->check = local_summary_check;
@@ -142,7 +138,7 @@ camel_local_summary_init (CamelLocalSummary *local_summary)
folder_summary = CAMEL_FOLDER_SUMMARY (local_summary);
/* and a unique file version */
- folder_summary->version += CAMEL_LOCAL_SUMMARY_VERSION;
+ camel_folder_summary_set_version (folder_summary, camel_folder_summary_get_version (folder_summary) +
CAMEL_LOCAL_SUMMARY_VERSION);
}
void
@@ -150,7 +146,6 @@ camel_local_summary_construct (CamelLocalSummary *new,
const gchar *local_name,
CamelIndex *index)
{
- camel_folder_summary_set_build_content (CAMEL_FOLDER_SUMMARY (new), FALSE);
new->folder_path = g_strdup (local_name);
new->index = index;
if (index)
@@ -163,7 +158,7 @@ local_summary_load (CamelLocalSummary *cls,
GError **error)
{
d (g_print ("\nlocal_summary_load called \n"));
- return camel_folder_summary_load_from_db ((CamelFolderSummary *) cls, error);
+ return camel_folder_summary_load ((CamelFolderSummary *) cls, error);
}
/* load/check the summary */
@@ -195,7 +190,7 @@ void camel_local_summary_check_force (CamelLocalSummary *cls)
gchar *
camel_local_summary_encode_x_evolution (CamelLocalSummary *cls,
- const CamelLocalMessageInfo *info)
+ const CamelMessageInfo *info)
{
return CAMEL_LOCAL_SUMMARY_GET_CLASS (cls)->encode_x_evolution (cls, info);
}
@@ -203,7 +198,7 @@ camel_local_summary_encode_x_evolution (CamelLocalSummary *cls,
gint
camel_local_summary_decode_x_evolution (CamelLocalSummary *cls,
const gchar *xev,
- CamelLocalMessageInfo *info)
+ CamelMessageInfo *info)
{
return CAMEL_LOCAL_SUMMARY_GET_CLASS (cls)->decode_x_evolution (cls, xev, info);
}
@@ -315,7 +310,7 @@ camel_local_summary_check (CamelLocalSummary *cls,
for (i = 0; i < camel_folder_summary_count (s); i++) {
CamelMessageInfo *info = camel_folder_summary_get (s, g_ptr_array_index (known_uids,
i));
do_stat_mi (cls, &stats, info);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
camel_folder_summary_free_array (known_uids);
@@ -378,7 +373,7 @@ camel_local_summary_add (CamelLocalSummary *cls,
/**
* camel_local_summary_write_headers:
* @fd:
- * @header:
+ * @headers:
* @xevline:
* @status:
* @xstatus:
@@ -392,13 +387,15 @@ camel_local_summary_add (CamelLocalSummary *cls,
**/
gint
camel_local_summary_write_headers (gint fd,
- struct _camel_header_raw *header,
+ CamelNameValueArray *headers,
const gchar *xevline,
const gchar *status,
const gchar *xstatus)
{
gint outlen = 0, len;
gint newfd;
+ guint ii;
+ const gchar *header_name = NULL, *header_value = NULL;
FILE *out;
/* dum de dum, maybe the whole sync function should just use stdio for output */
@@ -413,18 +410,17 @@ camel_local_summary_write_headers (gint fd,
return -1;
}
- while (header) {
- if (strcmp (header->name, "X-Evolution") != 0
- && (status == NULL || strcmp (header->name, "Status") != 0)
- && (xstatus == NULL || strcmp (header->name, "X-Status") != 0)) {
- len = fprintf (out, "%s:%s\n", header->name, header->value);
+ for (ii = 0; camel_name_value_array_get (headers, ii, &header_name, &header_value); ii++) {
+ if (strcmp (header_name, "X-Evolution") != 0
+ && (status == NULL || strcmp (header_name, "Status") != 0)
+ && (xstatus == NULL || strcmp (header_name, "X-Status") != 0)) {
+ len = fprintf (out, "%s:%s\n", header_name, header_value);
if (len == -1) {
fclose (out);
return -1;
}
outlen += len;
}
- header = header->next;
}
if (status) {
@@ -488,7 +484,7 @@ local_summary_sync (CamelLocalSummary *cls,
folder_summary = CAMEL_FOLDER_SUMMARY (cls);
- if (!camel_folder_summary_save_to_db (folder_summary, error)) {
+ if (!camel_folder_summary_save (folder_summary, error)) {
g_warning ("Could not save summary for local providers");
return -1;
}
@@ -516,52 +512,34 @@ local_summary_add (CamelLocalSummary *cls,
{
CamelFolderSummary *summary;
CamelMessageInfo *mi;
- CamelMessageInfoBase *mi_base;
gchar *xev;
d (printf ("Adding message to summary\n"));
summary = CAMEL_FOLDER_SUMMARY (cls);
- mi = camel_folder_summary_info_new_from_message (summary, msg, NULL);
- camel_folder_summary_add (summary, mi);
-
- mi_base = (CamelMessageInfoBase *) mi;
+ mi = camel_folder_summary_info_new_from_message (summary, msg);
+ camel_message_info_set_abort_notifications (mi, TRUE);
if (info) {
- const CamelTag *tag = camel_message_info_get_user_tags (info);
- const CamelFlag *flag = camel_message_info_get_user_flags (info);
-
- while (flag) {
- camel_message_info_set_user_flag (mi, flag->name, TRUE);
- flag = flag->next;
- }
-
- while (tag) {
- camel_message_info_set_user_tag (mi, tag->name, tag->value);
- tag = tag->next;
- }
-
- camel_message_info_set_flags (mi, 0xffff, camel_message_info_get_flags (info));
- mi_base->size = camel_message_info_get_size (info);
+ camel_message_info_take_user_flags (mi, camel_message_info_dup_user_flags (info));
+ camel_message_info_take_user_tags (mi, camel_message_info_dup_user_tags (info));
+ camel_message_info_set_flags (mi, ~0, camel_message_info_get_flags (info));
+ camel_message_info_set_size (mi, camel_message_info_get_size (info));
}
/* we need to calculate the size ourselves */
if (camel_message_info_get_size (mi) == 0) {
- CamelStreamNull *sn = (CamelStreamNull *) camel_stream_null_new ();
-
- camel_data_wrapper_write_to_stream_sync (
- (CamelDataWrapper *) msg,
- (CamelStream *) sn, NULL, NULL);
- mi_base->size = sn->written;
- g_object_unref (sn);
+ camel_message_info_set_size (mi, camel_data_wrapper_calculate_size_sync (CAMEL_DATA_WRAPPER
(msg), NULL, NULL));
}
- mi_base->flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV);
- xev = camel_local_summary_encode_x_evolution (
- cls, (CamelLocalMessageInfo *) mi);
+ camel_message_info_set_flags (mi, CAMEL_MESSAGE_FOLDER_NOXEV, 0);
+ xev = camel_local_summary_encode_x_evolution (cls, mi);
camel_medium_set_header ((CamelMedium *) msg, "X-Evolution", xev);
g_free (xev);
+
+ camel_message_info_set_abort_notifications (mi, FALSE);
+ camel_folder_summary_add (summary, mi, FALSE);
camel_folder_change_info_add_uid (ci, camel_message_info_get_uid (mi));
return mi;
@@ -569,65 +547,86 @@ local_summary_add (CamelLocalSummary *cls,
static gchar *
local_summary_encode_x_evolution (CamelLocalSummary *cls,
- const CamelLocalMessageInfo *mi)
+ const CamelMessageInfo *mi)
{
GString *out = g_string_new ("");
struct _camel_header_param *params = NULL;
- CamelFlag *flag = mi->info.user_flags;
- CamelTag *tag = mi->info.user_tags;
+ guint32 flags;
+ const CamelNamedFlags *user_flags;
+ const CamelNameValueArray *user_tags;
gchar *ret;
const gchar *p, *uidstr;
guint32 uid;
+ camel_message_info_property_lock (mi);
+
/* FIXME: work out what to do with uid's that aren't stored here? */
/* FIXME: perhaps make that a mbox folder only issue?? */
p = uidstr = camel_message_info_get_uid (mi);
+ flags = camel_message_info_get_flags (mi);
while (*p && isdigit (*p))
p++;
if (*p == 0 && sscanf (uidstr, "%u", &uid) == 1) {
- g_string_printf (out, "%08x-%04x", uid, mi->info.flags & 0xffff);
+ g_string_printf (out, "%08x-%04x", uid, flags & 0xffff);
} else {
- g_string_printf (out, "%s-%04x", uidstr, mi->info.flags & 0xffff);
+ g_string_printf (out, "%s-%04x", uidstr, flags & 0xffff);
}
- if (flag || tag) {
+ user_flags = camel_message_info_get_user_flags (mi);
+ user_tags = camel_message_info_get_user_tags (mi);
+
+ if (user_flags || user_tags) {
GString *val = g_string_new ("");
+ const gchar *name, *value;
+ guint ii, len;
+
+ len = camel_named_flags_get_length (user_flags);
+ if (len) {
+ for (ii = 0; ii < len; ii++) {
+ name = camel_named_flags_get (user_flags, ii);
+ if (!name)
+ continue;
- if (flag) {
- while (flag) {
- g_string_append (val, flag->name);
- if (flag->next)
+ if (val->len)
g_string_append_c (val, ',');
- flag = flag->next;
+ g_string_append (val, name);
}
camel_header_set_param (¶ms, "flags", val->str);
g_string_truncate (val, 0);
}
- if (tag) {
- while (tag) {
- g_string_append (val, tag->name);
- g_string_append_c (val, '=');
- g_string_append (val, tag->value);
- if (tag->next)
+
+ len = camel_name_value_array_get_length (user_tags);
+ if (len) {
+ for (ii = 0; ii < len; ii++) {
+ if (!camel_name_value_array_get (user_tags, ii, &name, &value))
+ continue;
+
+ if (val->len)
g_string_append_c (val, ',');
- tag = tag->next;
+
+ g_string_append (val, name);
+ g_string_append_c (val, '=');
+ g_string_append (val, value);
}
camel_header_set_param (¶ms, "tags", val->str);
}
g_string_free (val, TRUE);
+
camel_header_param_list_format_append (out, params);
camel_header_param_list_free (params);
}
ret = out->str;
g_string_free (out, FALSE);
+ camel_message_info_property_unlock (mi);
+
return ret;
}
static gint
local_summary_decode_x_evolution (CamelLocalSummary *cls,
const gchar *xev,
- CamelLocalMessageInfo *mi)
+ CamelMessageInfo *mi)
{
struct _camel_header_param *params, *scan;
guint32 uid, flags;
@@ -662,7 +661,7 @@ local_summary_decode_x_evolution (CamelLocalSummary *cls,
gchar **flagv = g_strsplit (scan->value, ",", 1000);
for (i = 0; flagv[i]; i++)
- camel_message_info_set_user_flag ((CamelMessageInfo *) mi, flagv[i],
TRUE);
+ camel_message_info_set_user_flag (mi, flagv[i], TRUE);
g_strfreev (flagv);
} else if (!g_ascii_strcasecmp (scan->name, "tags")) {
gchar **tagv = g_strsplit (scan->value, ",", 10000);
@@ -672,7 +671,7 @@ local_summary_decode_x_evolution (CamelLocalSummary *cls,
val = strchr (tagv[i], '=');
if (val) {
*val++ = 0;
- camel_message_info_set_user_tag ((CamelMessageInfo *) mi,
tagv[i], val);
+ camel_message_info_set_user_tag (mi, tagv[i], val);
val[-1]='=';
}
}
@@ -683,27 +682,27 @@ local_summary_decode_x_evolution (CamelLocalSummary *cls,
camel_header_param_list_free (params);
}
- mi->info.uid = camel_pstring_strdup (uidstr);
- mi->info.flags = flags;
+ camel_message_info_set_uid (mi, uidstr);
+ camel_message_info_set_flags (mi, ~0, flags);
return 0;
}
static gboolean
-summary_header_from_db (CamelFolderSummary *s,
- CamelFIRecord *fir)
+summary_header_load (CamelFolderSummary *s,
+ CamelFIRecord *fir)
{
CamelLocalSummary *cls = (CamelLocalSummary *) s;
gchar *part, *tmp;
/* We dont actually add our own headers, but version that we don't anyway */
- if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->summary_header_from_db (s, fir))
+ if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->summary_header_load (s, fir))
return FALSE;
part = fir->bdata;
if (part) {
- EXTRACT_FIRST_DIGIT (cls->version)
+ cls->version = camel_util_bdata_get_number (&part, 0);
}
/* keep only the rest of the bdata there (strip our version digit) */
@@ -715,15 +714,15 @@ summary_header_from_db (CamelFolderSummary *s,
}
static struct _CamelFIRecord *
-summary_header_to_db (CamelFolderSummary *s,
- GError **error)
+summary_header_save (CamelFolderSummary *s,
+ GError **error)
{
CamelFolderSummaryClass *folder_summary_class;
struct _CamelFIRecord *fir;
- /* Chain up to parent's summary_header_to_db() method. */
+ /* Chain up to parent's summary_header_save() method. */
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class);
- fir = folder_summary_class->summary_header_to_db (s, NULL);
+ fir = folder_summary_class->summary_header_save (s, NULL);
if (fir)
fir->bdata = g_strdup_printf ("%d", CAMEL_LOCAL_SUMMARY_VERSION);
@@ -731,24 +730,28 @@ summary_header_to_db (CamelFolderSummary *s,
}
static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s,
- struct _camel_header_raw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+ const CamelNameValueArray *headers)
{
- CamelLocalMessageInfo *mi;
- CamelLocalSummary *cls = (CamelLocalSummary *) s;
+ CamelMessageInfo *mi;
+ CamelLocalSummary *cls = (CamelLocalSummary *) summary;
- mi = (CamelLocalMessageInfo *) CAMEL_FOLDER_SUMMARY_CLASS
(camel_local_summary_parent_class)->message_info_new_from_header (s, h);
+ mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->message_info_new_from_headers
(summary, headers);
if (mi) {
const gchar *xev;
gint doindex = FALSE;
- xev = camel_header_raw_find (&h, "X-Evolution", NULL);
+ xev = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE,
"X-Evolution");
if (xev == NULL || camel_local_summary_decode_x_evolution (cls, xev, mi) == -1) {
+ gchar *uid;
+
+ uid = camel_folder_summary_next_uid_string (summary);
+
/* to indicate it has no xev header */
- mi->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
- mi->info.dirty = TRUE;
- camel_pstring_free (mi->info.uid);
- mi->info.uid = camel_pstring_add (camel_folder_summary_next_uid_string (s), TRUE);
+ camel_message_info_set_flags (mi, CAMEL_MESSAGE_FOLDER_FLAGGED |
CAMEL_MESSAGE_FOLDER_NOXEV, CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV);
+ camel_message_info_set_uid (mi, uid);
+
+ g_free (uid);
/* shortcut, no need to look it up in the index library */
doindex = TRUE;
@@ -759,12 +762,12 @@ message_info_new_from_header (CamelFolderSummary *s,
|| cls->index_force
|| !camel_index_has_name (cls->index, camel_message_info_get_uid (mi)))) {
d (printf ("Am indexing message %s\n", camel_message_info_get_uid (mi)));
- camel_folder_summary_set_index (s, cls->index);
+ camel_folder_summary_set_index (summary, cls->index);
} else {
d (printf ("Not indexing message %s\n", camel_message_info_get_uid (mi)));
- camel_folder_summary_set_index (s, NULL);
+ camel_folder_summary_set_index (summary, NULL);
}
}
- return (CamelMessageInfo *) mi;
+ return mi;
}
diff --git a/src/camel/providers/local/camel-local-summary.h b/src/camel/providers/local/camel-local-summary.h
index 496b787..284aca2 100644
--- a/src/camel/providers/local/camel-local-summary.h
+++ b/src/camel/providers/local/camel-local-summary.h
@@ -52,12 +52,6 @@ enum {
CAMEL_MESSAGE_FOLDER_NOTSEEN = 1 << 19 /* have we seen this in processing this loop? */
};
-typedef struct _CamelLocalMessageInfo CamelLocalMessageInfo;
-
-struct _CamelLocalMessageInfo {
- CamelMessageInfoBase info;
-};
-
struct _CamelLocalSummary {
CamelFolderSummary parent;
@@ -78,9 +72,12 @@ struct _CamelLocalSummaryClass {
gint (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo,
GCancellable *cancellable, GError **error);
CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info,
CamelFolderChangeInfo *, GError **error);
- gchar *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelLocalMessageInfo *info);
- gint (*decode_x_evolution)(CamelLocalSummary *cls, const gchar *xev, CamelLocalMessageInfo *info);
+ gchar *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelMessageInfo *info);
+ gint (*decode_x_evolution)(CamelLocalSummary *cls, const gchar *xev, CamelMessageInfo *info);
gint (*need_index)(void);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_local_summary_get_type (void);
@@ -99,11 +96,11 @@ CamelMessageInfo *camel_local_summary_add (CamelLocalSummary *cls, CamelMimeMess
void camel_local_summary_check_force (CamelLocalSummary *cls);
/* generate an X-Evolution header line */
-gchar *camel_local_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *info);
-gint camel_local_summary_decode_x_evolution (CamelLocalSummary *cls, const gchar *xev, CamelLocalMessageInfo
*info);
+gchar *camel_local_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelMessageInfo *info);
+gint camel_local_summary_decode_x_evolution (CamelLocalSummary *cls, const gchar *xev, CamelMessageInfo
*info);
/* utility functions - write headers to a file with optional X-Evolution header and/or status header */
-gint camel_local_summary_write_headers (gint fd, struct _camel_header_raw *header, const gchar *xevline,
const gchar *status, const gchar *xstatus);
+gint camel_local_summary_write_headers (gint fd, CamelNameValueArray *headers, const gchar *xevline, const
gchar *status, const gchar *xstatus);
G_END_DECLS
diff --git a/src/camel/providers/local/camel-maildir-folder.c
b/src/camel/providers/local/camel-maildir-folder.c
index 7ec56fd..494b6fb 100644
--- a/src/camel/providers/local/camel-maildir-folder.c
+++ b/src/camel/providers/local/camel-maildir-folder.c
@@ -48,17 +48,17 @@ maildir_folder_cmp_uids (CamelFolder *folder,
time_t tma, tmb;
g_return_val_if_fail (folder != NULL, 0);
- g_return_val_if_fail (folder->summary != NULL, 0);
+ g_return_val_if_fail (camel_folder_get_folder_summary (folder) != NULL, 0);
- a = camel_folder_summary_get (folder->summary, uid1);
- b = camel_folder_summary_get (folder->summary, uid2);
+ a = camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid1);
+ b = camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid2);
if (!a || !b) {
/* It's not a problem when one of the messages is not in the summary */
if (a)
- camel_message_info_unref (a);
+ g_object_unref (a);
if (b)
- camel_message_info_unref (b);
+ g_object_unref (b);
if (a == b)
return 0;
@@ -70,8 +70,8 @@ maildir_folder_cmp_uids (CamelFolder *folder,
tma = camel_message_info_get_date_received (a);
tmb = camel_message_info_get_date_received (b);
- camel_message_info_unref (a);
- camel_message_info_unref (b);
+ g_clear_object (&a);
+ g_clear_object (&b);
return tma < tmb ? -1 : tma == tmb ? 0 : 1;
}
@@ -84,7 +84,7 @@ maildir_folder_sort_uids (CamelFolder *folder,
g_return_if_fail (folder != NULL);
if (uids && uids->len > 1)
- camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary (folder), NULL);
/* Chain up to parent's sort_uids() method. */
CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class)->sort_uids (folder, uids);
@@ -101,20 +101,20 @@ maildir_folder_get_filename (CamelFolder *folder,
gchar *res;
/* get the message summary info */
- if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) {
+ if ((info = camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid)) == NULL) {
set_cannot_get_message_ex (
error, CAMEL_FOLDER_ERROR_INVALID_UID,
uid, lf->folder_path, _("No such message"));
return NULL;
}
- mdi = (CamelMaildirMessageInfo *) info;
+ mdi = CAMEL_MAILDIR_MESSAGE_INFO (info);
/* If filename is NULL, it means folder_summary_check is not yet executed.
* Try to find the file in the folder and use it, otherwise construct its
* name based on actual flags.
*/
- if (!camel_maildir_info_filename (mdi)) {
+ if (!camel_maildir_message_info_get_filename (mdi)) {
const gchar *uid = camel_message_info_get_uid (info);
if (uid) {
@@ -131,7 +131,7 @@ maildir_folder_get_filename (CamelFolder *folder,
while (filename = g_dir_read_name (dir), filename) {
if (g_str_has_prefix (filename, uid) && (filename[uid_len] == '\0' ||
filename[uid_len] == CAMEL_MAILDIR_FLAG_SEP)) {
- camel_maildir_info_set_filename (mdi, g_strdup (filename));
+ camel_maildir_message_info_take_filename (mdi, g_strdup
(filename));
break;
}
}
@@ -140,14 +140,14 @@ maildir_folder_get_filename (CamelFolder *folder,
}
}
- if (!camel_maildir_info_filename (mdi)) {
- camel_maildir_info_set_filename (mdi, camel_maildir_summary_info_to_name (mdi));
+ if (!camel_maildir_message_info_get_filename (mdi)) {
+ camel_maildir_message_info_take_filename (mdi, camel_maildir_summary_info_to_name
(info));
}
}
- res = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));
+ res = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_message_info_get_filename (mdi));
- camel_message_info_unref (info);
+ g_clear_object (&info);
return res;
}
@@ -175,7 +175,7 @@ maildir_folder_append_message_sync (CamelFolder *folder,
/* add it to the summary/assign the uid, etc */
mi = camel_local_summary_add (
- CAMEL_LOCAL_SUMMARY (folder->summary),
+ CAMEL_LOCAL_SUMMARY (camel_folder_get_folder_summary (folder)),
message, info, lf->changes, error);
if (mi == NULL)
goto check_changed;
@@ -203,7 +203,7 @@ maildir_folder_append_message_sync (CamelFolder *folder,
goto fail_write;
/* now move from tmp to cur (bypass new, does it matter?) */
- dest = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));
+ dest = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_message_info_get_filename (mdi));
if (g_rename (name, dest) == -1) {
g_set_error (
error, G_IO_ERROR,
@@ -226,7 +226,7 @@ maildir_folder_append_message_sync (CamelFolder *folder,
fail_write:
/* remove the summary info so we are not out-of-sync with the mh folder */
- camel_folder_summary_remove (CAMEL_FOLDER_SUMMARY (folder->summary), mi);
+ camel_folder_summary_remove (CAMEL_FOLDER_SUMMARY (camel_folder_get_folder_summary (folder)), mi);
g_prefix_error (
error, _("Cannot append message to maildir folder: %s: "),
@@ -250,6 +250,8 @@ maildir_folder_append_message_sync (CamelFolder *folder,
camel_folder_change_info_clear (lf->changes);
}
+ g_clear_object (&mi);
+
return success;
}
@@ -336,7 +338,7 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
CamelMaildirMessageInfo *mdi;
CamelMessageInfo *info;
- if ((info = camel_folder_summary_get (source->summary, uid)) == NULL) {
+ if ((info = camel_folder_summary_get (camel_folder_get_folder_summary (source), uid))
== NULL) {
set_cannot_get_message_ex (
error, CAMEL_FOLDER_ERROR_INVALID_UID,
uid, lf->folder_path, _("No such message"));
@@ -344,10 +346,10 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
}
mdi = (CamelMaildirMessageInfo *) info;
- new_filename = camel_maildir_summary_info_to_name (mdi);
+ new_filename = camel_maildir_summary_info_to_name (info);
d_filename = g_strdup_printf ("%s/cur/%s", df->folder_path, new_filename);
- s_filename = g_strdup_printf ("%s/cur/%s", lf->folder_path,
camel_maildir_info_filename (mdi));
+ s_filename = g_strdup_printf ("%s/cur/%s", lf->folder_path,
camel_maildir_message_info_get_filename (mdi));
if (g_rename (s_filename, d_filename) != 0) {
if (errno == EXDEV) {
@@ -359,7 +361,7 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
g_io_error_from_errno (errno),
_("Cannot transfer message to destination folder: %s"),
g_strerror (errno));
- camel_message_info_unref (info);
+ g_clear_object (&info);
g_free (s_filename);
g_free (d_filename);
g_free (new_filename);
@@ -367,22 +369,17 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
}
} else {
CamelMessageInfo *clone;
- CamelMaildirMessageInfo *mclone;
- clone = camel_message_info_clone (info);
- clone->summary = dest->summary;
+ clone = camel_message_info_clone (info, camel_folder_get_folder_summary
(dest));
- mclone = (CamelMaildirMessageInfo *) clone;
- /* preserve also UID, as it matches the file name */
- mclone->info.info.uid = camel_pstring_strdup (camel_message_info_get_uid
(info));
- camel_maildir_info_set_filename (clone, g_strdup (new_filename));
+ camel_maildir_message_info_set_filename (CAMEL_MAILDIR_MESSAGE_INFO (clone),
new_filename);
/* unset deleted flag when transferring from trash folder */
- if ((source->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0)
+ if ((camel_folder_get_flags (source) & CAMEL_FOLDER_IS_TRASH) != 0)
camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0);
/* unset junk flag when transferring from junk folder */
- if ((source->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0)
+ if ((camel_folder_get_flags (source) & CAMEL_FOLDER_IS_JUNK) != 0)
camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK, 0);
- camel_folder_summary_add (dest->summary, clone);
+ camel_folder_summary_add (camel_folder_get_folder_summary (dest), clone,
FALSE);
camel_folder_change_info_add_uid (df->changes, camel_message_info_get_uid
(clone));
@@ -390,10 +387,11 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
source, uid, CAMEL_MESSAGE_DELETED |
CAMEL_MESSAGE_SEEN, ~0);
camel_folder_change_info_remove_uid (lf->changes, camel_message_info_get_uid
(info));
- camel_folder_summary_remove (source->summary, info);
+ camel_folder_summary_remove (camel_folder_get_folder_summary (source), info);
+ g_clear_object (&clone);
}
- camel_message_info_unref (info);
+ g_clear_object (&info);
g_free (s_filename);
g_free (d_filename);
g_free (new_filename);
@@ -498,7 +496,7 @@ camel_maildir_folder_new (CamelStore *parent_store,
g_object_unref (settings);
if (filter_inbox && (g_str_equal (full_name, ".") || g_ascii_strcasecmp (full_name, "Inbox") == 0))
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) | CAMEL_FOLDER_FILTER_RECENT);
folder = (CamelFolder *) camel_local_folder_construct (
CAMEL_LOCAL_FOLDER (folder), flags, cancellable, error);
diff --git a/src/camel/providers/local/camel-maildir-folder.h
b/src/camel/providers/local/camel-maildir-folder.h
index 08a08de..cbafc03 100644
--- a/src/camel/providers/local/camel-maildir-folder.h
+++ b/src/camel/providers/local/camel-maildir-folder.h
@@ -52,6 +52,9 @@ struct _CamelMaildirFolder {
struct _CamelMaildirFolderClass {
CamelLocalFolderClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_maildir_folder_get_type (void);
diff --git a/src/camel/providers/local/camel-maildir-message-info.c
b/src/camel/providers/local/camel-maildir-message-info.c
new file mode 100644
index 0000000..7d85cc9
--- /dev/null
+++ b/src/camel/providers/local/camel-maildir-message-info.c
@@ -0,0 +1,251 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "camel/camel.h"
+#include "camel-maildir-summary.h"
+
+#include "camel-maildir-message-info.h"
+
+struct _CamelMaildirMessageInfoPrivate {
+ gchar *filename;
+};
+
+enum {
+ PROP_0,
+ PROP_FILENAME
+};
+
+G_DEFINE_TYPE (CamelMaildirMessageInfo, camel_maildir_message_info, CAMEL_TYPE_MESSAGE_INFO_BASE)
+
+static CamelMessageInfo *
+maildir_message_info_clone (const CamelMessageInfo *mi,
+ CamelFolderSummary *assign_summary)
+{
+ CamelMessageInfo *result;
+
+ g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mi), NULL);
+
+ result = CAMEL_MESSAGE_INFO_CLASS (camel_maildir_message_info_parent_class)->clone (mi,
assign_summary);
+ if (!result)
+ return NULL;
+
+ if (CAMEL_IS_MAILDIR_MESSAGE_INFO (result)) {
+ CamelMaildirMessageInfo *mmi, *mmi_result;
+
+ mmi = CAMEL_MAILDIR_MESSAGE_INFO (mi);
+ mmi_result = CAMEL_MAILDIR_MESSAGE_INFO (result);
+
+ /* safe-guard that the mmi's filename doesn't change before it's copied to mmi_result */
+ camel_message_info_property_lock (mi);
+
+ camel_maildir_message_info_set_filename (mmi_result, camel_maildir_message_info_get_filename
(mmi));
+
+ camel_message_info_property_unlock (mi);
+ }
+
+ return result;
+}
+
+static gboolean
+maildir_message_info_load (CamelMessageInfo *mi,
+ const CamelMIRecord *record,
+ /* const */ gchar **bdata_ptr)
+{
+ CamelMaildirMessageInfo *mmi;
+
+ g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_ptr != NULL, FALSE);
+
+ if (!CAMEL_MESSAGE_INFO_CLASS (camel_maildir_message_info_parent_class)->load ||
+ !CAMEL_MESSAGE_INFO_CLASS (camel_maildir_message_info_parent_class)->load (mi, record, bdata_ptr))
+ return FALSE;
+
+ mmi = CAMEL_MAILDIR_MESSAGE_INFO (mi);
+
+ camel_maildir_message_info_take_filename (mmi, camel_maildir_summary_info_to_name (mi));
+
+ return TRUE;
+}
+
+static void
+maildir_message_info_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CamelMaildirMessageInfo *mmi = CAMEL_MAILDIR_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_FILENAME:
+ camel_maildir_message_info_set_filename (mmi, g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+maildir_message_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CamelMaildirMessageInfo *mmi = CAMEL_MAILDIR_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_FILENAME:
+ g_value_set_string (value, camel_maildir_message_info_get_filename (mmi));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+maildir_message_info_dispose (GObject *object)
+{
+ CamelMaildirMessageInfo *mmi = CAMEL_MAILDIR_MESSAGE_INFO (object);
+
+ g_free (mmi->priv->filename);
+ mmi->priv->filename = NULL;
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_maildir_message_info_parent_class)->dispose (object);
+}
+
+static void
+camel_maildir_message_info_class_init (CamelMaildirMessageInfoClass *class)
+{
+ CamelMessageInfoClass *mi_class;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelMaildirMessageInfoPrivate));
+
+ mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
+ mi_class->clone = maildir_message_info_clone;
+ mi_class->load = maildir_message_info_load;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = maildir_message_info_set_property;
+ object_class->get_property = maildir_message_info_get_property;
+ object_class->dispose = maildir_message_info_dispose;
+
+ /**
+ * CamelMaildirMessageInfo:filename
+ *
+ * File name of the message on the disk.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FILENAME,
+ g_param_spec_string (
+ "filename",
+ "Filename",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+}
+
+static void
+camel_maildir_message_info_init (CamelMaildirMessageInfo *mmi)
+{
+ mmi->priv = G_TYPE_INSTANCE_GET_PRIVATE (mmi, CAMEL_TYPE_MAILDIR_MESSAGE_INFO,
CamelMaildirMessageInfoPrivate);
+}
+
+const gchar *
+camel_maildir_message_info_get_filename (const CamelMaildirMessageInfo *mmi)
+{
+ CamelMessageInfo *mi;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mmi), NULL);
+
+ mi = CAMEL_MESSAGE_INFO (mmi);
+
+ camel_message_info_property_lock (mi);
+ result = mmi->priv->filename;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gchar *
+camel_maildir_message_info_dup_filename (const CamelMaildirMessageInfo *mmi)
+{
+ CamelMessageInfo *mi;
+ gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mmi), NULL);
+
+ mi = CAMEL_MESSAGE_INFO (mmi);
+
+ camel_message_info_property_lock (mi);
+ result = g_strdup (mmi->priv->filename);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gboolean
+camel_maildir_message_info_set_filename (CamelMaildirMessageInfo *mmi,
+ const gchar *filename)
+{
+ g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mmi), FALSE);
+
+ return camel_maildir_message_info_take_filename (mmi, g_strdup (filename));
+}
+
+gboolean
+camel_maildir_message_info_take_filename (CamelMaildirMessageInfo *mmi,
+ gchar *filename)
+{
+ CamelMessageInfo *mi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mmi), FALSE);
+
+ mi = CAMEL_MESSAGE_INFO (mmi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = g_strcmp0 (mmi->priv->filename, filename) != 0;
+
+ if (changed) {
+ g_free (mmi->priv->filename);
+ mmi->priv->filename = filename;
+ } else if (filename != mmi->priv->filename) {
+ g_free (filename);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !camel_message_info_get_abort_notifications (mi)) {
+ g_object_notify (G_OBJECT (mmi), "filename");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
diff --git a/src/camel/providers/local/camel-maildir-message-info.h
b/src/camel/providers/local/camel-maildir-message-info.h
new file mode 100644
index 0000000..5264762
--- /dev/null
+++ b/src/camel/providers/local/camel-maildir-message-info.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAMEL_MAILDIR_MESSAGE_INFO_H
+#define CAMEL_MAILDIR_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_MAILDIR_MESSAGE_INFO \
+ (camel_maildir_message_info_get_type ())
+#define CAMEL_MAILDIR_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_MAILDIR_MESSAGE_INFO, CamelMaildirMessageInfo))
+#define CAMEL_MAILDIR_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_MAILDIR_MESSAGE_INFO, CamelMaildirMessageInfoClass))
+#define CAMEL_IS_MAILDIR_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_MAILDIR_MESSAGE_INFO))
+#define CAMEL_IS_MAILDIR_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_MAILDIR_MESSAGE_INFO))
+#define CAMEL_MAILDIR_MESSAGE_INFO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_MAILDIR_MESSAGE_INFO, CamelMaildirMessageInfoClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelMaildirMessageInfo CamelMaildirMessageInfo;
+typedef struct _CamelMaildirMessageInfoClass CamelMaildirMessageInfoClass;
+typedef struct _CamelMaildirMessageInfoPrivate CamelMaildirMessageInfoPrivate;
+
+struct _CamelMaildirMessageInfo {
+ CamelMessageInfoBase parent;
+ CamelMaildirMessageInfoPrivate *priv;
+};
+
+struct _CamelMaildirMessageInfoClass {
+ CamelMessageInfoBaseClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
+};
+
+GType camel_maildir_message_info_get_type (void);
+
+const gchar * camel_maildir_message_info_get_filename (const CamelMaildirMessageInfo *mmi);
+gchar * camel_maildir_message_info_dup_filename (const CamelMaildirMessageInfo *mmi);
+gboolean camel_maildir_message_info_set_filename (CamelMaildirMessageInfo *mmi,
+ const gchar *filename);
+gboolean camel_maildir_message_info_take_filename
+ (CamelMaildirMessageInfo *mmi,
+ gchar *filename);
+
+G_END_DECLS
+
+#endif /* CAMEL_MAILDIR_MESSAGE_INFO_H */
diff --git a/src/camel/providers/local/camel-maildir-store.c b/src/camel/providers/local/camel-maildir-store.c
index be483b1..8b070fc 100644
--- a/src/camel/providers/local/camel-maildir-store.c
+++ b/src/camel/providers/local/camel-maildir-store.c
@@ -441,7 +441,7 @@ fill_fi (CamelStore *store,
{
CamelFolder *folder;
- folder = camel_object_bag_peek (store->folders, fi->full_name);
+ folder = camel_object_bag_peek (camel_store_get_folders_bag (store), fi->full_name);
if (folder) {
if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
camel_folder_refresh_info_sync (folder, cancellable, NULL);
@@ -476,7 +476,7 @@ fill_fi (CamelStore *store,
g_free (root);
s = (CamelFolderSummary *) camel_maildir_summary_new (NULL, folderpath, NULL);
- if (camel_folder_summary_header_load_from_db (s, store, fi->full_name, NULL)) {
+ if (camel_folder_summary_header_load (s, store, fi->full_name, NULL)) {
fi->unread = camel_folder_summary_get_unread_count (s);
fi->total = camel_folder_summary_get_saved_count (s);
}
diff --git a/src/camel/providers/local/camel-maildir-store.h b/src/camel/providers/local/camel-maildir-store.h
index d949597..dbae0da 100644
--- a/src/camel/providers/local/camel-maildir-store.h
+++ b/src/camel/providers/local/camel-maildir-store.h
@@ -54,6 +54,9 @@ struct _CamelMaildirStore {
struct _CamelMaildirStoreClass {
CamelLocalStoreClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_maildir_store_get_type (void);
diff --git a/src/camel/providers/local/camel-maildir-summary.c
b/src/camel/providers/local/camel-maildir-summary.c
index 2c5a56b..7b240f6 100644
--- a/src/camel/providers/local/camel-maildir-summary.c
+++ b/src/camel/providers/local/camel-maildir-summary.c
@@ -36,6 +36,7 @@
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
+#include "camel-maildir-message-info.h"
#include "camel-maildir-summary.h"
#define CAMEL_MAILDIR_SUMMARY_GET_PRIVATE(obj) \
@@ -47,14 +48,8 @@
#define CAMEL_MAILDIR_SUMMARY_VERSION (0x2000)
static CamelMessageInfo *
- message_info_new_from_header (CamelFolderSummary *,
- struct _camel_header_raw *);
-static CamelMessageInfo *
- maildir_message_info_from_db (CamelFolderSummary *summary,
- CamelMIRecord *record);
-static void message_info_free (CamelFolderSummary *,
- CamelMessageInfo *mi);
-
+ message_info_new_from_headers (CamelFolderSummary *,
+ const CamelNameValueArray *);
static gint maildir_summary_load (CamelLocalSummary *cls,
gint forceindex,
GError **error);
@@ -78,10 +73,10 @@ static gchar * maildir_summary_next_uid_string (CamelFolderSummary *s);
static gint maildir_summary_decode_x_evolution
(CamelLocalSummary *cls,
const gchar *xev,
- CamelLocalMessageInfo *mi);
+ CamelMessageInfo *mi);
static gchar * maildir_summary_encode_x_evolution
(CamelLocalSummary *cls,
- const CamelLocalMessageInfo *mi);
+ const CamelMessageInfo *mi);
typedef struct _CamelMaildirMessageContentInfo CamelMaildirMessageContentInfo;
@@ -129,11 +124,10 @@ camel_maildir_summary_class_init (CamelMaildirSummaryClass *class)
object_class->finalize = maildir_summary_finalize;
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
- folder_summary_class->message_info_size = sizeof (CamelMaildirMessageInfo);
- folder_summary_class->content_info_size = sizeof (CamelMaildirMessageContentInfo);
- folder_summary_class->message_info_new_from_header = message_info_new_from_header;
- folder_summary_class->message_info_from_db = maildir_message_info_from_db;
- folder_summary_class->message_info_free = message_info_free;
+ folder_summary_class->message_info_type = CAMEL_TYPE_MAILDIR_MESSAGE_INFO;
+ folder_summary_class->sort_by = "dreceived";
+ folder_summary_class->collate = NULL;
+ folder_summary_class->message_info_new_from_headers = message_info_new_from_headers;
folder_summary_class->next_uid_string = maildir_summary_next_uid_string;
local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (class);
@@ -157,7 +151,7 @@ camel_maildir_summary_init (CamelMaildirSummary *maildir_summary)
CAMEL_MAILDIR_SUMMARY_GET_PRIVATE (maildir_summary);
/* set unique file version */
- folder_summary->version += CAMEL_MAILDIR_SUMMARY_VERSION;
+ camel_folder_summary_set_version (folder_summary, camel_folder_summary_get_version (folder_summary) +
CAMEL_MAILDIR_SUMMARY_VERSION);
if (gethostname (hostname, 256) == 0) {
maildir_summary->priv->hostname = g_strdup (hostname);
@@ -186,9 +180,7 @@ CamelMaildirSummary
CamelStore *parent_store;
parent_store = camel_folder_get_parent_store (folder);
- camel_db_set_collate (parent_store->cdb_r, "dreceived", NULL, NULL);
- ((CamelFolderSummary *) o)->sort_by = "dreceived";
- ((CamelFolderSummary *) o)->collate = NULL;
+ camel_db_set_collate (camel_store_get_db (parent_store), "dreceived", NULL, NULL);
}
camel_local_summary_construct ((CamelLocalSummary *) o, maildirdir, index);
return o;
@@ -208,17 +200,20 @@ static struct {
};
/* convert the uid + flags into a unique:info maildir format */
-gchar *camel_maildir_summary_info_to_name (const CamelMaildirMessageInfo *info)
+gchar *
+camel_maildir_summary_info_to_name (const CamelMessageInfo *info)
{
const gchar *uid;
+ guint32 flags;
gchar *p, *buf;
gint i;
uid = camel_message_info_get_uid (info);
buf = g_alloca (strlen (uid) + strlen (CAMEL_MAILDIR_FLAG_SEP_S "2,") + G_N_ELEMENTS (flagbits) + 1);
p = buf + sprintf (buf, "%s" CAMEL_MAILDIR_FLAG_SEP_S "2,", uid);
+ flags = camel_message_info_get_flags (info);
for (i = 0; i < G_N_ELEMENTS (flagbits); i++) {
- if (info->info.info.flags & flagbits[i].flagbit)
+ if ((flags & flagbits[i].flagbit) != 0)
*p++ = flagbits[i].flag;
}
@@ -227,48 +222,48 @@ gchar *camel_maildir_summary_info_to_name (const CamelMaildirMessageInfo *info)
return g_strdup (buf);
}
-/* returns 0 if the info matches (or there was none), otherwise we changed it */
-gint camel_maildir_summary_name_to_info (CamelMaildirMessageInfo *info, const gchar *name)
+/* returns whether the @info changed */
+gboolean
+camel_maildir_summary_name_to_info (CamelMessageInfo *info,
+ const gchar *name)
{
gchar *p, c;
guint32 set = 0; /* what we set */
- /*guint32 all = 0;*/ /* all flags */
gint i;
p = strstr (name, CAMEL_MAILDIR_FLAG_SEP_S "2,");
if (p) {
- p+=3;
+ guint32 flags;
+
+ flags = camel_message_info_get_flags (info);
+
+ p += 3;
while ((c = *p++)) {
/* we could assume that the flags are in order, but its just as easy not to require */
for (i = 0; i < G_N_ELEMENTS (flagbits); i++) {
- if (flagbits[i].flag == c && (info->info.info.flags & flagbits[i].flagbit) ==
0) {
+ if (flagbits[i].flag == c && (flags & flagbits[i].flagbit) == 0) {
set |= flagbits[i].flagbit;
}
- /*all |= flagbits[i].flagbit;*/
}
}
/* changed? */
- /*if ((info->flags & all) != set) {*/
- if ((info->info.info.flags & set) != set) {
- /* ok, they did change, only add the new flags ('merge flags'?) */
- /*info->flags &= all; if we wanted to set only the new flags, which we probably dont
*/
- info->info.info.flags |= set;
- return 1;
+ if ((flags & set) != set) {
+ return camel_message_info_set_flags (info, set, set);
}
}
- return 0;
+ return FALSE;
}
/* for maildir, x-evolution isn't used, so dont try and get anything out of it */
-static gint maildir_summary_decode_x_evolution (CamelLocalSummary *cls, const gchar *xev,
CamelLocalMessageInfo *mi)
+static gint maildir_summary_decode_x_evolution (CamelLocalSummary *cls, const gchar *xev, CamelMessageInfo
*mi)
{
return -1;
}
-static gchar *maildir_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi)
+static gchar *maildir_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelMessageInfo *mi)
{
return NULL;
}
@@ -284,16 +279,17 @@ maildir_summary_add (CamelLocalSummary *cls,
GError **error)
{
CamelLocalSummaryClass *local_summary_class;
- CamelMaildirMessageInfo *mi;
+ CamelMessageInfo *mi;
/* Chain up to parent's add() method. */
local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (camel_maildir_summary_parent_class);
- mi = (CamelMaildirMessageInfo *) local_summary_class->add (
- cls, msg, info, changes, error);
+ mi = local_summary_class->add (cls, msg, info, changes, error);
if (mi) {
if (info) {
- camel_maildir_info_set_filename (mi, camel_maildir_summary_info_to_name (mi));
- d (printf ("Setting filename to %s\n", camel_maildir_info_filename (mi)));
+ CamelMaildirMessageInfo *mdi = CAMEL_MAILDIR_MESSAGE_INFO (mi);
+
+ camel_maildir_message_info_take_filename (mdi, camel_maildir_summary_info_to_name
(mi));
+ d (printf ("Setting filename to %s\n", camel_maildir_message_info_get_filename
(mdi)));
/* Inherit the Received date from the passed-in info only if it is set and
the new message info doesn't have it set or it's set to the default
@@ -302,42 +298,43 @@ maildir_summary_add (CamelLocalSummary *cls,
(camel_message_info_get_date_received (mi) <= 0 ||
(camel_message_info_get_uid (mi) &&
camel_message_info_get_date_received (mi) == strtoul (camel_message_info_get_uid
(mi), NULL, 10))))
- mi->info.info.date_received = camel_message_info_get_date_received (info);
+ camel_message_info_set_date_received (mi,
camel_message_info_get_date_received (info));
}
}
- return (CamelMessageInfo *) mi;
+ return mi;
}
static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s,
- struct _camel_header_raw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+ const CamelNameValueArray *headers)
{
CamelMessageInfo *mi, *info;
- CamelMaildirSummary *mds = (CamelMaildirSummary *) s;
- CamelMaildirMessageInfo *mdi;
+ CamelMaildirSummary *mds = (CamelMaildirSummary *) summary;
const gchar *uid;
- mi = ((CamelFolderSummaryClass *) camel_maildir_summary_parent_class)->message_info_new_from_header
(s, h);
+ mi = ((CamelFolderSummaryClass *) camel_maildir_summary_parent_class)->message_info_new_from_headers
(summary, headers);
/* assign the uid and new filename */
if (mi) {
- mdi = (CamelMaildirMessageInfo *) mi;
-
uid = camel_message_info_get_uid (mi);
- if (uid == NULL || uid[0] == 0)
- mdi->info.info.uid = camel_pstring_add (camel_folder_summary_next_uid_string (s),
TRUE);
+ if (uid == NULL || uid[0] == 0) {
+ gchar *new_uid = camel_folder_summary_next_uid_string (summary);
+
+ camel_message_info_set_uid (mi, new_uid);
+ g_free (new_uid);
+ }
/* handle 'duplicates' */
- info = camel_folder_summary_peek_loaded (s, uid);
+ info = (uid && *uid) ? camel_folder_summary_peek_loaded (summary, uid) : NULL;
if (info) {
d (printf ("already seen uid '%s', just summarising instead\n", uid));
- camel_message_info_unref (mi);
- mdi = (CamelMaildirMessageInfo *)(mi = info);
+ g_clear_object (&mi);
+ mi = info;
}
- if (mdi->info.info.date_received <= 0) {
+ if (camel_message_info_get_date_received (mi) <= 0) {
/* with maildir we know the real received date, from the filename */
- mdi->info.info.date_received = strtoul (camel_message_info_get_uid (mi), NULL, 10);
+ camel_message_info_set_date_received (mi, strtoul (camel_message_info_get_uid (mi),
NULL, 10));
}
if (mds->priv->current_file) {
@@ -346,8 +343,8 @@ message_info_new_from_header (CamelFolderSummary *s,
gulong uid;
#endif
/* if setting from a file, grab the flags from it */
- camel_maildir_info_set_filename (mi, g_strdup (mds->priv->current_file));
- camel_maildir_summary_name_to_info (mdi, mds->priv->current_file);
+ camel_maildir_message_info_take_filename (CAMEL_MAILDIR_MESSAGE_INFO (mi), g_strdup
(mds->priv->current_file));
+ camel_maildir_summary_name_to_info (mi, mds->priv->current_file);
#if 0
/* Actually, I dont think all this effort is worth it at all ... */
@@ -367,42 +364,16 @@ message_info_new_from_header (CamelFolderSummary *s,
#endif
} else {
/* if creating a file, set its name from the flags we have */
- camel_maildir_info_set_filename (mdi, camel_maildir_summary_info_to_name (mdi));
- d (printf ("Setting filename to %s\n", camel_maildir_info_filename (mi)));
+ camel_maildir_message_info_take_filename (CAMEL_MAILDIR_MESSAGE_INFO (mi),
camel_maildir_summary_info_to_name (mi));
+ d (printf ("Setting filename to %s\n", camel_maildir_message_info_get_filename
(CAMEL_MAILDIR_MESSAGE_INFO (mi))));
}
}
return mi;
}
-static CamelMessageInfo *
-maildir_message_info_from_db (CamelFolderSummary *summary,
- CamelMIRecord *record)
-{
- CamelMessageInfo *mi;
-
- mi = ((CamelFolderSummaryClass *) camel_maildir_summary_parent_class)->message_info_from_db (summary,
record);
- if (mi) {
- CamelMaildirMessageInfo *mdi = (CamelMaildirMessageInfo *) mi;
-
- camel_maildir_info_set_filename (mdi, camel_maildir_summary_info_to_name (mdi));
- }
-
- return mi;
-}
-
-static void
-message_info_free (CamelFolderSummary *s,
- CamelMessageInfo *mi)
-{
- CamelMaildirMessageInfo *mdi = (CamelMaildirMessageInfo *) mi;
-
- g_free (mdi->filename);
-
- ((CamelFolderSummaryClass *) camel_maildir_summary_parent_class)->message_info_free (s, mi);
-}
-
-static gchar *maildir_summary_next_uid_string (CamelFolderSummary *s)
+static gchar *
+maildir_summary_next_uid_string (CamelFolderSummary *s)
{
CamelMaildirSummary *mds = (CamelMaildirSummary *) s;
@@ -546,7 +517,8 @@ camel_maildir_summary_add (CamelLocalSummary *cls,
maildirs->priv->current_file = (gchar *) name;
info = camel_folder_summary_info_new_from_parser (summary, mp);
- camel_folder_summary_add (summary, info);
+ camel_folder_summary_add (summary, info, FALSE);
+ g_clear_object (&info);
g_object_unref (mp);
maildirs->priv->current_file = NULL;
@@ -571,7 +543,7 @@ remove_summary (gchar *key,
if (rd->changes)
camel_folder_change_info_remove_uid (rd->changes, key);
camel_folder_summary_remove ((CamelFolderSummary *) rd->cls, info);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
static gint
@@ -667,7 +639,7 @@ maildir_summary_check (CamelLocalSummary *cls,
info = g_hash_table_lookup (left, uid);
if (info) {
g_hash_table_remove (left, uid);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
info = camel_folder_summary_get ((CamelFolderSummary *) cls, uid);
@@ -685,13 +657,12 @@ maildir_summary_check (CamelLocalSummary *cls,
}
mdi = (CamelMaildirMessageInfo *) info;
- filename = camel_maildir_info_filename (mdi);
+ filename = camel_maildir_message_info_get_filename (mdi);
/* TODO: only store the extension in the mdi->filename struct, not the whole lot */
if (filename == NULL || strcmp (filename, d->d_name) != 0) {
- g_free (mdi->filename);
- mdi->filename = g_strdup (d->d_name);
+ camel_maildir_message_info_set_filename (mdi, d->d_name);
}
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
g_free (uid);
}
@@ -734,7 +705,7 @@ maildir_summary_check (CamelLocalSummary *cls,
/* already in summary? shouldn't happen, but just incase ... */
if ((info = camel_folder_summary_get ((CamelFolderSummary *) cls, name))) {
- camel_message_info_unref (info);
+ g_clear_object (&info);
newname = destname = camel_folder_summary_next_uid_string (s);
} else {
gchar *nm;
@@ -813,9 +784,9 @@ maildir_summary_sync (CamelLocalSummary *cls,
camel_operation_progress (cancellable, (known_uids->len - i) * 100 / known_uids->len);
info = camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids,
i));
- mdi = (CamelMaildirMessageInfo *) info;
- if (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_DELETED) && expunge) {
- name = g_strdup_printf ("%s/cur/%s", cls->folder_path, camel_maildir_info_filename
(mdi));
+ mdi = CAMEL_MAILDIR_MESSAGE_INFO (info);
+ if (mdi && (camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED) != 0 && expunge) {
+ name = g_strdup_printf ("%s/cur/%s", cls->folder_path,
camel_maildir_message_info_get_filename (mdi));
d (printf ("deleting %s\n", name));
if (unlink (name) == 0 || errno == ENOENT) {
@@ -827,16 +798,16 @@ maildir_summary_sync (CamelLocalSummary *cls,
removed_uids = g_list_prepend (removed_uids, (gpointer) camel_pstring_strdup
(camel_message_info_get_uid (info)));
}
g_free (name);
- } else if (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- gchar *newname = camel_maildir_summary_info_to_name (mdi);
+ } else if (mdi && camel_message_info_get_folder_flagged (info)) {
+ gchar *newname = camel_maildir_summary_info_to_name (info);
gchar *dest;
/* do we care about additional metainfo stored inside the message? */
/* probably should all go in the filename? */
/* have our flags/ i.e. name changed? */
- if (strcmp (newname, camel_maildir_info_filename (mdi))) {
- name = g_strdup_printf ("%s/cur/%s", cls->folder_path,
camel_maildir_info_filename (mdi));
+ if (strcmp (newname, camel_maildir_message_info_get_filename (mdi))) {
+ name = g_strdup_printf ("%s/cur/%s", cls->folder_path,
camel_maildir_message_info_get_filename (mdi));
dest = g_strdup_printf ("%s/cur/%s", cls->folder_path, newname);
if (g_rename (name, dest) == -1) {
g_warning ("%s: Failed to rename '%s' to '%s': %s", G_STRFUNC, name,
dest, g_strerror (errno));
@@ -848,19 +819,18 @@ maildir_summary_sync (CamelLocalSummary *cls,
/* TODO: If this is made mt-safe, then this code could be a problem,
since
* the estrv is being modified.
* Sigh, this may mean the maildir name has to be cached another way
*/
- g_free (mdi->filename);
- mdi->filename = newname;
+ camel_maildir_message_info_set_filename (mdi, newname);
}
g_free (name);
g_free (dest);
- } else {
- g_free (newname);
}
+ g_free (newname);
+
/* strip FOLDER_MESSAGE_FLAGED, etc */
- mdi->info.info.flags &= 0xffff;
+ camel_message_info_set_flags (info, 0xffff, camel_message_info_get_flags (info));
}
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
if (removed_uids) {
@@ -875,4 +845,3 @@ maildir_summary_sync (CamelLocalSummary *cls,
local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (camel_maildir_summary_parent_class);
return local_summary_class->sync (cls, expunge, changes, cancellable, error);
}
-
diff --git a/src/camel/providers/local/camel-maildir-summary.h
b/src/camel/providers/local/camel-maildir-summary.h
index 77cbdd3..e188b54 100644
--- a/src/camel/providers/local/camel-maildir-summary.h
+++ b/src/camel/providers/local/camel-maildir-summary.h
@@ -19,6 +19,7 @@
#ifndef CAMEL_MAILDIR_SUMMARY_H
#define CAMEL_MAILDIR_SUMMARY_H
+#include "camel-maildir-message-info.h"
#include "camel-local-summary.h"
/* Standard GObject macros */
@@ -54,12 +55,6 @@ typedef struct _CamelMaildirSummary CamelMaildirSummary;
typedef struct _CamelMaildirSummaryClass CamelMaildirSummaryClass;
typedef struct _CamelMaildirSummaryPrivate CamelMaildirSummaryPrivate;
-typedef struct _CamelMaildirMessageInfo {
- CamelLocalMessageInfo info;
-
- gchar *filename; /* maildir has this annoying status on the end of the filename, use
this to get the real message id */
-} CamelMaildirMessageInfo;
-
struct _CamelMaildirSummary {
CamelLocalSummary parent;
CamelMaildirSummaryPrivate *priv;
@@ -67,18 +62,17 @@ struct _CamelMaildirSummary {
struct _CamelMaildirSummaryClass {
CamelLocalSummaryClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_maildir_summary_get_type (void);
CamelMaildirSummary *camel_maildir_summary_new (struct _CamelFolder *folder, const gchar
*maildirdir, CamelIndex *index);
/* convert some info->flags to/from the messageinfo */
-gchar *camel_maildir_summary_info_to_name (const CamelMaildirMessageInfo *info);
-gint camel_maildir_summary_name_to_info (CamelMaildirMessageInfo *info, const gchar *name);
-
-/* TODO: could proably use get_string stuff */
-#define camel_maildir_info_filename(x) (((CamelMaildirMessageInfo *)x)->filename)
-#define camel_maildir_info_set_filename(x, s) (g_free(((CamelMaildirMessageInfo
*)x)->filename),((CamelMaildirMessageInfo *)x)->filename = s)
+gchar *camel_maildir_summary_info_to_name (const CamelMessageInfo *info);
+gboolean camel_maildir_summary_name_to_info (CamelMessageInfo *info, const gchar *name);
G_END_DECLS
diff --git a/src/camel/providers/local/camel-mbox-folder.c b/src/camel/providers/local/camel-mbox-folder.c
index 56ca428..094772c 100644
--- a/src/camel/providers/local/camel-mbox-folder.c
+++ b/src/camel/providers/local/camel-mbox-folder.c
@@ -33,6 +33,7 @@
#include <glib/gstdio.h>
#include "camel-mbox-folder.h"
+#include "camel-mbox-message-info.h"
#include "camel-mbox-store.h"
#include "camel-mbox-summary.h"
@@ -50,20 +51,21 @@ mbox_folder_cmp_uids (CamelFolder *folder,
const gchar *uid2)
{
CamelMboxMessageInfo *a, *b;
+ goffset aoffset, boffset;
gint res;
g_return_val_if_fail (folder != NULL, 0);
- g_return_val_if_fail (folder->summary != NULL, 0);
+ g_return_val_if_fail (camel_folder_get_folder_summary (folder) != NULL, 0);
- a = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid1);
- b = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid2);
+ a = (CamelMboxMessageInfo *) camel_folder_summary_get (camel_folder_get_folder_summary (folder),
uid1);
+ b = (CamelMboxMessageInfo *) camel_folder_summary_get (camel_folder_get_folder_summary (folder),
uid2);
if (!a || !b) {
/* It's not a problem when one of the messages is not in the summary */
if (a)
- camel_message_info_unref (a);
+ g_object_unref (a);
if (b)
- camel_message_info_unref (b);
+ g_object_unref (b);
if (a == b)
return 0;
@@ -72,10 +74,13 @@ mbox_folder_cmp_uids (CamelFolder *folder,
return 1;
}
- res = a->frompos < b->frompos ? -1 : a->frompos == b->frompos ? 0 : 1;
+ aoffset = camel_mbox_message_info_get_offset (a);
+ boffset = camel_mbox_message_info_get_offset (b);
- camel_message_info_unref (a);
- camel_message_info_unref (b);
+ res = aoffset < boffset ? -1 : aoffset == boffset ? 0 : 1;
+
+ g_clear_object (&a);
+ g_clear_object (&b);
return res;
}
@@ -88,7 +93,7 @@ mbox_folder_sort_uids (CamelFolder *folder,
g_return_if_fail (folder != NULL);
if (uids && uids->len > 1)
- camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
+ camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary (folder), NULL);
CAMEL_FOLDER_CLASS (camel_mbox_folder_parent_class)->sort_uids (folder, uids);
}
@@ -100,7 +105,6 @@ mbox_folder_get_filename (CamelFolder *folder,
{
CamelLocalFolder *lf = (CamelLocalFolder *) folder;
CamelMboxMessageInfo *info;
- goffset frompos;
gchar *filename = NULL;
d (printf ("Getting message %s\n", uid));
@@ -110,32 +114,28 @@ mbox_folder_get_filename (CamelFolder *folder,
return NULL;
/* check for new messages always */
- if (camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, NULL, error) ==
-1) {
+ if (camel_local_summary_check ((CamelLocalSummary *) camel_folder_get_folder_summary (folder),
lf->changes, NULL, error) == -1) {
camel_local_folder_unlock (lf);
return NULL;
}
/* get the message summary info */
- info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid);
+ info = (CamelMboxMessageInfo *) camel_folder_summary_get (camel_folder_get_folder_summary (folder),
uid);
if (info == NULL) {
set_cannot_get_message_ex (
error, CAMEL_FOLDER_ERROR_INVALID_UID,
uid, lf->folder_path, _("No such message"));
- goto fail;
- }
+ } else {
+ goffset frompos;
- if (info->frompos == -1) {
- camel_message_info_unref (info);
- goto fail;
- }
+ frompos = camel_mbox_message_info_get_offset (info);
+ g_clear_object (&info);
- frompos = info->frompos;
- camel_message_info_unref (info);
-
- filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (gint64) frompos);
+ if (frompos != -1)
+ filename = g_strdup_printf ("%s%s!%" G_GINT64_FORMAT, lf->folder_path,
G_DIR_SEPARATOR_S, (gint64) frompos);
+ }
-fail:
/* and unlock now we're finished with it */
camel_local_folder_unlock (lf);
@@ -153,8 +153,8 @@ mbox_folder_append_message_sync (CamelFolder *folder,
CamelLocalFolder *lf = (CamelLocalFolder *) folder;
CamelStream *output_stream = NULL, *filter_stream = NULL;
CamelMimeFilter *filter_from;
- CamelMboxSummary *mbs = (CamelMboxSummary *) folder->summary;
- CamelMessageInfo *mi;
+ CamelMboxSummary *mbs = (CamelMboxSummary *) camel_folder_get_folder_summary (folder);
+ CamelMessageInfo *mi = NULL;
gchar *fromline = NULL;
struct stat st;
gint retval;
@@ -169,12 +169,12 @@ mbox_folder_append_message_sync (CamelFolder *folder,
d (printf ("Appending message\n"));
/* first, check the summary is correct (updates folder_size too) */
- retval = camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable,
error);
+ retval = camel_local_summary_check ((CamelLocalSummary *) camel_folder_get_folder_summary (folder),
lf->changes, cancellable, error);
if (retval == -1)
goto fail;
/* add it to the summary/assign the uid, etc */
- mi = camel_local_summary_add ((CamelLocalSummary *) folder->summary, message, info, lf->changes,
error);
+ mi = camel_local_summary_add ((CamelLocalSummary *) camel_folder_get_folder_summary (folder),
message, info, lf->changes, error);
if (mi == NULL)
goto fail;
@@ -197,13 +197,13 @@ mbox_folder_append_message_sync (CamelFolder *folder,
}
/* and we need to set the frompos/XEV explicitly */
- ((CamelMboxMessageInfo *) mi)->frompos = mbs->folder_size;
+ camel_mbox_message_info_set_offset (CAMEL_MBOX_MESSAGE_INFO (mi), mbs->folder_size);
#if 0
- xev = camel_local_summary_encode_x_evolution ((CamelLocalSummary *) folder->summary, mi);
+ xev = camel_local_summary_encode_x_evolution ((CamelLocalSummary *) camel_folder_get_folder_summary
(folder), mi);
if (xev) {
/* the x-ev header should match the 'current' flags, no problem, so store as much */
camel_medium_set_header ((CamelMedium *) message, "X-Evolution", xev);
- mi->flags &= ~ CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED;
+ camel_mesage_info_set_flags (mi, CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED,
0);
g_free (xev);
}
#endif
@@ -230,15 +230,10 @@ mbox_folder_append_message_sync (CamelFolder *folder,
g_object_unref (output_stream);
g_free (fromline);
- if (!((CamelMessageInfoBase *) mi)->preview && camel_folder_summary_get_need_preview
(folder->summary)) {
- if (camel_mime_message_build_preview ((CamelMimePart *) message, mi) &&
((CamelMessageInfoBase *) mi)->preview)
- camel_folder_summary_add_preview (folder->summary, mi);
- }
-
/* now we 'fudge' the summary to tell it its uptodate, because its idea of uptodate has just changed
*/
/* the stat really shouldn't fail, we just wrote to it */
if (g_stat (lf->folder_path, &st) == 0) {
- ((CamelFolderSummary *) mbs)->time = st.st_mtime;
+ camel_folder_summary_set_timestamp (CAMEL_FOLDER_SUMMARY (mbs), st.st_mtime);
mbs->folder_size = st.st_size;
}
@@ -253,6 +248,8 @@ mbox_folder_append_message_sync (CamelFolder *folder,
if (appended_uid)
*appended_uid = g_strdup(camel_message_info_get_uid(mi));
+ g_clear_object (&mi);
+
return TRUE;
fail_write:
@@ -284,7 +281,7 @@ fail_write:
/* and tell the summary it's up-to-date */
if (g_stat (lf->folder_path, &st) == 0) {
- ((CamelFolderSummary *) mbs)->time = st.st_mtime;
+ camel_folder_summary_set_timestamp (CAMEL_FOLDER_SUMMARY (mbs), st.st_mtime);
mbs->folder_size = st.st_size;
}
@@ -298,6 +295,8 @@ fail:
camel_folder_change_info_clear (lf->changes);
}
+ g_clear_object (&mi);
+
return FALSE;
}
@@ -322,14 +321,14 @@ mbox_folder_get_message_sync (CamelFolder *folder,
return NULL;
/* check for new messages always */
- if (camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable,
error) == -1) {
+ if (camel_local_summary_check ((CamelLocalSummary *) camel_folder_get_folder_summary (folder),
lf->changes, cancellable, error) == -1) {
camel_local_folder_unlock (lf);
return NULL;
}
retry:
/* get the message summary info */
- info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid);
+ info = (CamelMboxMessageInfo *) camel_folder_summary_get (camel_folder_get_folder_summary (folder),
uid);
if (info == NULL) {
set_cannot_get_message_ex (
@@ -338,13 +337,11 @@ retry:
goto fail;
}
- if (info->frompos == -1) {
- camel_message_info_unref (info);
- goto fail;
- }
+ frompos = camel_mbox_message_info_get_offset (CAMEL_MBOX_MESSAGE_INFO (info));
+ g_clear_object (&info);
- frompos = info->frompos;
- camel_message_info_unref (info);
+ if (frompos == -1)
+ goto fail;
/* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache
* the whole message in memory if the stream is non-seekable (which it is when built from a parser
@@ -378,8 +375,8 @@ retry:
if (!retried) {
retried = TRUE;
- camel_local_summary_check_force ((CamelLocalSummary *) folder->summary);
- retval = camel_local_summary_check ((CamelLocalSummary *) folder->summary,
lf->changes, cancellable, error);
+ camel_local_summary_check_force ((CamelLocalSummary *)
camel_folder_get_folder_summary (folder));
+ retval = camel_local_summary_check ((CamelLocalSummary *)
camel_folder_get_folder_summary (folder), lf->changes, cancellable, error);
if (retval != -1)
goto retry;
}
diff --git a/src/camel/providers/local/camel-mbox-folder.h b/src/camel/providers/local/camel-mbox-folder.h
index f309d02..1e72efa 100644
--- a/src/camel/providers/local/camel-mbox-folder.h
+++ b/src/camel/providers/local/camel-mbox-folder.h
@@ -55,6 +55,9 @@ struct _CamelMboxFolder {
struct _CamelMboxFolderClass {
CamelLocalFolderClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mbox_folder_get_type (void);
diff --git a/src/camel/providers/local/camel-mbox-message-info.c
b/src/camel/providers/local/camel-mbox-message-info.c
new file mode 100644
index 0000000..9a278e4
--- /dev/null
+++ b/src/camel/providers/local/camel-mbox-message-info.c
@@ -0,0 +1,255 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "camel/camel.h"
+#include "camel-mbox-summary.h"
+
+#include "camel-mbox-message-info.h"
+
+struct _CamelMboxMessageInfoPrivate {
+ goffset offset;
+};
+
+enum {
+ PROP_0,
+ PROP_OFFSET
+};
+
+G_DEFINE_TYPE (CamelMboxMessageInfo, camel_mbox_message_info, CAMEL_TYPE_MESSAGE_INFO_BASE)
+
+static CamelMessageInfo *
+mbox_message_info_clone (const CamelMessageInfo *mi,
+ CamelFolderSummary *assign_summary)
+{
+ CamelMessageInfo *result;
+
+ g_return_val_if_fail (CAMEL_IS_MBOX_MESSAGE_INFO (mi), NULL);
+
+ result = CAMEL_MESSAGE_INFO_CLASS (camel_mbox_message_info_parent_class)->clone (mi, assign_summary);
+ if (!result)
+ return NULL;
+
+ if (CAMEL_IS_MBOX_MESSAGE_INFO (result)) {
+ CamelMboxMessageInfo *mmi, *mmi_result;
+
+ mmi = CAMEL_MBOX_MESSAGE_INFO (mi);
+ mmi_result = CAMEL_MBOX_MESSAGE_INFO (result);
+
+ camel_mbox_message_info_set_offset (mmi_result, camel_mbox_message_info_get_offset (mmi));
+ }
+
+ return result;
+}
+
+static gboolean
+mbox_message_info_load (CamelMessageInfo *mi,
+ const CamelMIRecord *record,
+ /* const */ gchar **bdata_ptr)
+{
+ CamelMboxMessageInfo *mmi;
+ gint64 offset;
+
+ g_return_val_if_fail (CAMEL_IS_MBOX_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_ptr != NULL, FALSE);
+
+ if (!CAMEL_MESSAGE_INFO_CLASS (camel_mbox_message_info_parent_class)->load ||
+ !CAMEL_MESSAGE_INFO_CLASS (camel_mbox_message_info_parent_class)->load (mi, record, bdata_ptr))
+ return FALSE;
+
+ mmi = CAMEL_MBOX_MESSAGE_INFO (mi);
+
+ offset = camel_util_bdata_get_number (bdata_ptr, -1);
+ if (offset < 0)
+ return FALSE;
+
+ camel_mbox_message_info_set_offset (mmi, offset);
+
+ return TRUE;
+}
+
+static gboolean
+mbox_message_info_save (const CamelMessageInfo *mi,
+ CamelMIRecord *record,
+ GString *bdata_str)
+{
+ CamelMboxMessageInfo *mmi;
+
+ g_return_val_if_fail (CAMEL_IS_MBOX_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_str != NULL, FALSE);
+
+ if (!CAMEL_MESSAGE_INFO_CLASS (camel_mbox_message_info_parent_class)->save ||
+ !CAMEL_MESSAGE_INFO_CLASS (camel_mbox_message_info_parent_class)->save (mi, record, bdata_str))
+ return FALSE;
+
+ mmi = CAMEL_MBOX_MESSAGE_INFO (mi);
+
+ camel_util_bdata_put_number (bdata_str, camel_mbox_message_info_get_offset (mmi));
+
+ return TRUE;
+}
+
+static gboolean
+mbox_message_info_set_flags (CamelMessageInfo *mi,
+ guint32 mask,
+ guint32 set)
+{
+ CamelFolderSummary *summary;
+ CamelMboxSummary *mbox_summary;
+
+ summary = camel_message_info_ref_summary (mi);
+ mbox_summary = summary ? CAMEL_MBOX_SUMMARY (summary) : NULL;
+
+ /* Basically, if anything could change the Status line, presume it does */
+ if (mbox_summary && mbox_summary->xstatus
+ && (mask & (CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_ANSWERED |
CAMEL_MESSAGE_DELETED))) {
+ mask |= CAMEL_MESSAGE_FOLDER_XEVCHANGE | CAMEL_MESSAGE_FOLDER_FLAGGED;
+ set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE | CAMEL_MESSAGE_FOLDER_FLAGGED;
+ }
+
+ g_clear_object (&summary);
+
+ return CAMEL_MESSAGE_INFO_CLASS (camel_mbox_message_info_parent_class)->set_flags (mi, mask, set);
+}
+
+static void
+mbox_message_info_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CamelMboxMessageInfo *mmi = CAMEL_MBOX_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_OFFSET:
+ camel_mbox_message_info_set_offset (mmi, g_value_get_int64 (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mbox_message_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CamelMboxMessageInfo *mmi = CAMEL_MBOX_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_OFFSET:
+ g_value_set_int64 (value, camel_mbox_message_info_get_offset (mmi));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+camel_mbox_message_info_class_init (CamelMboxMessageInfoClass *class)
+{
+ CamelMessageInfoClass *mi_class;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelMboxMessageInfoPrivate));
+
+ mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
+ mi_class->clone = mbox_message_info_clone;
+ mi_class->load = mbox_message_info_load;
+ mi_class->save = mbox_message_info_save;
+ mi_class->set_flags = mbox_message_info_set_flags;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mbox_message_info_set_property;
+ object_class->get_property = mbox_message_info_get_property;
+
+ /**
+ * CamelMboxMessageInfo:offset
+ *
+ * Offset in the file to the related message.
+ *
+ * Since: 3.24
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_OFFSET,
+ g_param_spec_int64 (
+ "offset",
+ "Offset",
+ NULL,
+ 0, G_MAXINT64, 0,
+ G_PARAM_READWRITE));
+}
+
+static void
+camel_mbox_message_info_init (CamelMboxMessageInfo *mmi)
+{
+ mmi->priv = G_TYPE_INSTANCE_GET_PRIVATE (mmi, CAMEL_TYPE_MBOX_MESSAGE_INFO,
CamelMboxMessageInfoPrivate);
+}
+
+goffset
+camel_mbox_message_info_get_offset (const CamelMboxMessageInfo *mmi)
+{
+ CamelMessageInfo *mi;
+ goffset result;
+
+ g_return_val_if_fail (CAMEL_IS_MBOX_MESSAGE_INFO (mmi), 0);
+
+ mi = CAMEL_MESSAGE_INFO (mmi);
+
+ camel_message_info_property_lock (mi);
+ result = mmi->priv->offset;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gboolean
+camel_mbox_message_info_set_offset (CamelMboxMessageInfo *mmi,
+ goffset offset)
+{
+ CamelMessageInfo *mi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_MBOX_MESSAGE_INFO (mmi), FALSE);
+
+ mi = CAMEL_MESSAGE_INFO (mmi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = mmi->priv->offset != offset;
+
+ if (changed)
+ mmi->priv->offset = offset;
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !camel_message_info_get_abort_notifications (mi)) {
+ g_object_notify (G_OBJECT (mmi), "offset");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
diff --git a/src/camel/providers/local/camel-mbox-message-info.h
b/src/camel/providers/local/camel-mbox-message-info.h
new file mode 100644
index 0000000..c493d8d
--- /dev/null
+++ b/src/camel/providers/local/camel-mbox-message-info.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAMEL_MBOX_MESSAGE_INFO_H
+#define CAMEL_MBOX_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_MBOX_MESSAGE_INFO \
+ (camel_mbox_message_info_get_type ())
+#define CAMEL_MBOX_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_MBOX_MESSAGE_INFO, CamelMboxMessageInfo))
+#define CAMEL_MBOX_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_MBOX_MESSAGE_INFO, CamelMboxMessageInfoClass))
+#define CAMEL_IS_MBOX_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_MBOX_MESSAGE_INFO))
+#define CAMEL_IS_MBOX_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_MBOX_MESSAGE_INFO))
+#define CAMEL_MBOX_MESSAGE_INFO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_MBOX_MESSAGE_INFO, CamelMboxMessageInfoClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelMboxMessageInfo CamelMboxMessageInfo;
+typedef struct _CamelMboxMessageInfoClass CamelMboxMessageInfoClass;
+typedef struct _CamelMboxMessageInfoPrivate CamelMboxMessageInfoPrivate;
+
+struct _CamelMboxMessageInfo {
+ CamelMessageInfoBase parent;
+ CamelMboxMessageInfoPrivate *priv;
+};
+
+struct _CamelMboxMessageInfoClass {
+ CamelMessageInfoBaseClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
+};
+
+GType camel_mbox_message_info_get_type (void);
+
+goffset camel_mbox_message_info_get_offset (const CamelMboxMessageInfo *mmi);
+gboolean camel_mbox_message_info_set_offset (CamelMboxMessageInfo *mmi,
+ goffset offset);
+
+G_END_DECLS
+
+#endif /* CAMEL_MBOX_MESSAGE_INFO_H */
diff --git a/src/camel/providers/local/camel-mbox-store.c b/src/camel/providers/local/camel-mbox-store.c
index cff6ff1..01ec20d 100644
--- a/src/camel/providers/local/camel-mbox-store.c
+++ b/src/camel/providers/local/camel-mbox-store.c
@@ -112,7 +112,7 @@ fill_fi (CamelStore *store,
fi->unread = -1;
fi->total = -1;
- folder = camel_object_bag_peek (store->folders, fi->full_name);
+ folder = camel_object_bag_peek (camel_store_get_folders_bag (store), fi->full_name);
if (folder) {
if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
camel_folder_refresh_info_sync (folder, NULL, NULL);
@@ -134,7 +134,7 @@ fill_fi (CamelStore *store,
mbs = (CamelMboxSummary *) camel_mbox_summary_new (
NULL, folderpath, NULL);
/* FIXME[disk-summary] track exception */
- if (camel_folder_summary_header_load_from_db ((CamelFolderSummary *) mbs, store,
fi->full_name, NULL)) {
+ if (camel_folder_summary_header_load ((CamelFolderSummary *) mbs, store, fi->full_name,
NULL)) {
fi->unread = camel_folder_summary_get_unread_count (
(CamelFolderSummary *) mbs);
fi->total = camel_folder_summary_get_saved_count (
@@ -830,7 +830,7 @@ mbox_store_rename_folder_sync (CamelStore *store,
newdir = NULL;
}
- folder = camel_object_bag_get (store->folders, old);
+ folder = camel_object_bag_get (camel_store_get_folders_bag (store), old);
if (folder && folder->index) {
if (camel_index_rename (folder->index, newibex) == -1 && errno != ENOENT) {
errnosav = errno;
diff --git a/src/camel/providers/local/camel-mbox-store.h b/src/camel/providers/local/camel-mbox-store.h
index be38efd..82b8a56 100644
--- a/src/camel/providers/local/camel-mbox-store.h
+++ b/src/camel/providers/local/camel-mbox-store.h
@@ -52,6 +52,9 @@ struct _CamelMboxStore {
struct _CamelMboxStoreClass {
CamelLocalStoreClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mbox_store_get_type (void);
diff --git a/src/camel/providers/local/camel-mbox-summary.c b/src/camel/providers/local/camel-mbox-summary.c
index 4e82fdc..f7c0765 100644
--- a/src/camel/providers/local/camel-mbox-summary.c
+++ b/src/camel/providers/local/camel-mbox-summary.c
@@ -31,14 +31,14 @@
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
+#include "camel-mbox-message-info.h"
#include "camel-mbox-summary.h"
#include "camel-local-private.h"
#define io(x)
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
-/* Enable the use of elm/pine style "Status" & "X-Status" headers */
-#define STATUS_PINE
+/* This uses elm/pine style "Status" & "X-Status" headers */
#define CAMEL_MBOX_SUMMARY_VERSION (1)
@@ -55,26 +55,19 @@ struct _CamelMboxMessageContentInfo {
};
static CamelFIRecord *
- summary_header_to_db (CamelFolderSummary *,
+ summary_header_save (CamelFolderSummary *,
GError **error);
-static gboolean summary_header_from_db (CamelFolderSummary *,
+static gboolean summary_header_load (CamelFolderSummary *,
CamelFIRecord *);
static CamelMessageInfo *
- message_info_from_db (CamelFolderSummary *s,
- CamelMIRecord *record);
-static CamelMIRecord *
- message_info_to_db (CamelFolderSummary *s,
- CamelMessageInfo *info);
-
-static CamelMessageInfo *
- message_info_new_from_header (CamelFolderSummary *,
- struct _camel_header_raw *);
+ message_info_new_from_headers (CamelFolderSummary *,
+ const CamelNameValueArray *);
static CamelMessageInfo *
message_info_new_from_parser (CamelFolderSummary *,
CamelMimeParser *);
static gchar * mbox_summary_encode_x_evolution (CamelLocalSummary *cls,
- const CamelLocalMessageInfo *mi);
+ const CamelMessageInfo *mi);
static gint mbox_summary_check (CamelLocalSummary *cls,
CamelFolderChangeInfo *changeinfo,
@@ -85,15 +78,12 @@ static gint mbox_summary_sync (CamelLocalSummary *cls,
CamelFolderChangeInfo *changeinfo,
GCancellable *cancellable,
GError **error);
-#ifdef STATUS_PINE
static CamelMessageInfo *
mbox_summary_add (CamelLocalSummary *cls,
CamelMimeMessage *msg,
const CamelMessageInfo *info,
CamelFolderChangeInfo *ci,
GError **error);
-#endif
-
static gint mbox_summary_sync_quick (CamelMboxSummary *cls,
gboolean expunge,
CamelFolderChangeInfo *changeinfo,
@@ -105,7 +95,6 @@ static gint mbox_summary_sync_full (CamelMboxSummary *cls,
GCancellable *cancellable,
GError **error);
-#ifdef STATUS_PINE
/* Which status flags are stored in each separate header */
#define STATUS_XSTATUS \
(CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED)
@@ -113,59 +102,12 @@ static gint mbox_summary_sync_full (CamelMboxSummary *cls,
static void encode_status (guint32 flags, gchar status[8]);
static guint32 decode_status (const gchar *status);
-#endif
G_DEFINE_TYPE (
CamelMboxSummary,
camel_mbox_summary,
CAMEL_TYPE_LOCAL_SUMMARY)
-static gboolean
-mbox_info_set_user_flag (CamelMessageInfo *mi,
- const gchar *name,
- gboolean value)
-{
- gint res;
-
- res = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->info_set_user_flag (mi, name,
value);
- if (res)
- ((CamelLocalMessageInfo *) mi)->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
-
- return res;
-}
-
-static gboolean
-mbox_info_set_user_tag (CamelMessageInfo *mi,
- const gchar *name,
- const gchar *value)
-{
- gint res;
-
- res = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->info_set_user_tag (mi, name,
value);
- if (res)
- ((CamelLocalMessageInfo *) mi)->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
-
- return res;
-}
-
-#ifdef STATUS_PINE
-static gboolean
-mbox_info_set_flags (CamelMessageInfo *mi,
- guint32 flags,
- guint32 set)
-{
- /* Basically, if anything could change the Status line, presume it does */
- if (((CamelMboxSummary *) mi->summary)->xstatus
- && (flags & (CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_ANSWERED |
CAMEL_MESSAGE_DELETED))) {
- flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE | CAMEL_MESSAGE_FOLDER_FLAGGED;
- set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE | CAMEL_MESSAGE_FOLDER_FLAGGED;
- }
-
- return CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->
- info_set_flags (mi, flags, set);
-}
-#endif
-
static void
camel_mbox_summary_class_init (CamelMboxSummaryClass *class)
{
@@ -173,27 +115,19 @@ camel_mbox_summary_class_init (CamelMboxSummaryClass *class)
CamelLocalSummaryClass *local_summary_class;
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
- folder_summary_class->message_info_size = sizeof (CamelMboxMessageInfo);
- folder_summary_class->content_info_size = sizeof (CamelMboxMessageContentInfo);
- folder_summary_class->summary_header_from_db = summary_header_from_db;
- folder_summary_class->summary_header_to_db = summary_header_to_db;
- folder_summary_class->message_info_from_db = message_info_from_db;
- folder_summary_class->message_info_to_db = message_info_to_db;
- folder_summary_class->message_info_new_from_header = message_info_new_from_header;
+ folder_summary_class->message_info_type = CAMEL_TYPE_MBOX_MESSAGE_INFO;
+ folder_summary_class->sort_by = "bdata";
+ folder_summary_class->collate = "mbox_frompos_sort";
+ folder_summary_class->summary_header_load = summary_header_load;
+ folder_summary_class->summary_header_save = summary_header_save;
+ folder_summary_class->message_info_new_from_headers = message_info_new_from_headers;
folder_summary_class->message_info_new_from_parser = message_info_new_from_parser;
- folder_summary_class->info_set_user_flag = mbox_info_set_user_flag;
- folder_summary_class->info_set_user_tag = mbox_info_set_user_tag;
-#ifdef STATUS_PINE
- folder_summary_class->info_set_flags = mbox_info_set_flags;
-#endif
local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (class);
local_summary_class->encode_x_evolution = mbox_summary_encode_x_evolution;
local_summary_class->check = mbox_summary_check;
local_summary_class->sync = mbox_summary_sync;
-#ifdef STATUS_PINE
local_summary_class->add = mbox_summary_add;
-#endif
class->sync_quick = mbox_summary_sync_quick;
class->sync_full = mbox_summary_sync_full;
@@ -207,7 +141,7 @@ camel_mbox_summary_init (CamelMboxSummary *mbox_summary)
folder_summary = CAMEL_FOLDER_SUMMARY (mbox_summary);
/* and a unique file version */
- folder_summary->version += CAMEL_MBOX_SUMMARY_VERSION;
+ camel_folder_summary_set_version (folder_summary, camel_folder_summary_get_version (folder_summary) +
CAMEL_MBOX_SUMMARY_VERSION);
}
/**
@@ -226,16 +160,12 @@ camel_mbox_summary_new (CamelFolder *folder,
new = g_object_new (CAMEL_TYPE_MBOX_SUMMARY, "folder", folder, NULL);
if (folder) {
- CamelFolderSummary *summary = (CamelFolderSummary *) new;
CamelStore *parent_store;
parent_store = camel_folder_get_parent_store (folder);
/* Set the functions for db sorting */
- camel_db_set_collate (parent_store->cdb_r, "bdata", "mbox_frompos_sort", (CamelDBCollate)
camel_local_frompos_sort);
- summary->sort_by = "bdata";
- summary->collate = "mbox_frompos_sort";
-
+ camel_db_set_collate (camel_store_get_db (parent_store), "bdata", "mbox_frompos_sort",
(CamelDBCollate) camel_local_frompos_sort);
}
camel_local_summary_construct ((CamelLocalSummary *) new, mbox_name, index);
return new;
@@ -248,54 +178,56 @@ void camel_mbox_summary_xstatus (CamelMboxSummary *mbs, gint state)
static gchar *
mbox_summary_encode_x_evolution (CamelLocalSummary *cls,
- const CamelLocalMessageInfo *mi)
+ const CamelMessageInfo *mi)
{
const gchar *p, *uidstr;
- guint32 uid;
+ guint32 uid, flags;
/* This is busted, it is supposed to encode ALL DATA */
p = uidstr = camel_message_info_get_uid (mi);
while (*p && isdigit (*p))
p++;
+ flags = camel_message_info_get_flags (mi);
+
if (*p == 0 && sscanf (uidstr, "%u", &uid) == 1) {
- return g_strdup_printf ("%08x-%04x", uid, mi->info.flags & 0xffff);
+ return g_strdup_printf ("%08x-%04x", uid, flags & 0xffff);
} else {
- return g_strdup_printf ("%s-%04x", uidstr, mi->info.flags & 0xffff);
+ return g_strdup_printf ("%s-%04x", uidstr, flags & 0xffff);
}
}
static gboolean
-summary_header_from_db (CamelFolderSummary *s,
- struct _CamelFIRecord *fir)
+summary_header_load (CamelFolderSummary *s,
+ struct _CamelFIRecord *fir)
{
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY (s);
gchar *part;
- if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->summary_header_from_db (s, fir))
+ if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->summary_header_load (s, fir))
return FALSE;
part = fir->bdata;
if (part) {
- mbs->version = bdata_extract_digit (&part);
- mbs->folder_size = bdata_extract_digit (&part);
+ mbs->version = camel_util_bdata_get_number (&part, 0);
+ mbs->folder_size = camel_util_bdata_get_number (&part, 0);
}
return TRUE;
}
static CamelFIRecord *
-summary_header_to_db (CamelFolderSummary *s,
- GError **error)
+summary_header_save (CamelFolderSummary *s,
+ GError **error)
{
CamelFolderSummaryClass *folder_summary_class;
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY (s);
struct _CamelFIRecord *fir;
gchar *tmp;
- /* Chain up to parent's summary_header_to_db() method. */
+ /* Chain up to parent's summary_header_save() method. */
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class);
- fir = folder_summary_class->summary_header_to_db (s, error);
+ fir = folder_summary_class->summary_header_save (s, error);
if (fir) {
tmp = fir->bdata;
fir->bdata = g_strdup_printf ("%s %d %d", tmp ? tmp : "", CAMEL_MBOX_SUMMARY_VERSION, (gint)
mbs->folder_size);
@@ -306,48 +238,47 @@ summary_header_to_db (CamelFolderSummary *s,
}
static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s,
- struct _camel_header_raw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+ const CamelNameValueArray *headers)
{
- CamelMboxMessageInfo *mi;
- CamelMboxSummary *mbs = (CamelMboxSummary *) s;
+ CamelMessageInfo *mi;
+ CamelMboxSummary *mbs = (CamelMboxSummary *) summary;
- mi = (CamelMboxMessageInfo *) CAMEL_FOLDER_SUMMARY_CLASS
(camel_mbox_summary_parent_class)->message_info_new_from_header (s, h);
+ mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->message_info_new_from_headers
(summary, headers);
if (mi) {
const gchar *xev, *uid;
- CamelMboxMessageInfo *info = NULL;
+ CamelMessageInfo *info = NULL;
gint add = 0; /* bitmask of things to add, 1 assign uid, 2, just add as new, 4 = recent */
-#ifdef STATUS_PINE
const gchar *status = NULL, *xstatus = NULL;
guint32 flags = 0;
if (mbs->xstatus) {
/* check for existance of status & x-status headers */
- status = camel_header_raw_find (&h, "Status", NULL);
+ status = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE,
"Status");
if (status)
flags = decode_status (status);
- xstatus = camel_header_raw_find (&h, "X-Status", NULL);
+ xstatus = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE,
"X-Status");
if (xstatus)
flags |= decode_status (xstatus);
}
-#endif
+
/* if we have an xev header, use it, else assign a new one */
- xev = camel_header_raw_find (&h, "X-Evolution", NULL);
+ xev = camel_name_value_array_get_named (headers, CAMEL_COMPARE_CASE_INSENSITIVE,
"X-Evolution");
if (xev != NULL
- && camel_local_summary_decode_x_evolution ((CamelLocalSummary *) s, xev, &mi->info) == 0)
{
+ && camel_local_summary_decode_x_evolution ((CamelLocalSummary *) summary, xev, mi) == 0) {
uid = camel_message_info_get_uid (mi);
d (printf ("found valid x-evolution: %s\n", uid));
/* If one is there, it should be there already */
- info = (CamelMboxMessageInfo *) camel_folder_summary_peek_loaded (s, uid);
+ info = camel_folder_summary_peek_loaded (summary, uid);
if (info) {
- if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
- info->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
- camel_message_info_unref (mi);
+ if ((camel_message_info_get_flags (info) & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
+ camel_message_info_set_flags (info, CAMEL_MESSAGE_FOLDER_NOTSEEN, 0);
+ g_clear_object (&mi);
mi = info;
} else {
add = 7;
d (printf ("seen '%s' before, adding anew\n", uid));
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
} else {
add = 2;
@@ -358,22 +289,25 @@ message_info_new_from_header (CamelFolderSummary *s,
add = 7;
}
- if (add&1) {
- mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
- camel_pstring_free (mi->info.info.uid);
- mi->info.info.uid = camel_pstring_add (camel_folder_summary_next_uid_string (s),
TRUE);
+ if ((add & 1) != 0) {
+ gchar *new_uid = camel_folder_summary_next_uid_string (summary);
+
+ camel_message_info_set_flags (mi, CAMEL_MESSAGE_FOLDER_FLAGGED |
CAMEL_MESSAGE_FOLDER_NOXEV, CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV);
+ camel_message_info_set_uid (mi, new_uid);
+
+ g_free (new_uid);
} else {
- camel_folder_summary_set_next_uid (s, strtoul (camel_message_info_get_uid (mi), NULL,
10));
+ camel_folder_summary_set_next_uid (summary, strtoul (camel_message_info_get_uid (mi),
NULL, 10));
}
-#ifdef STATUS_PINE
- if (mbs->xstatus && add&2) {
+
+ if (mbs->xstatus && (add & 2) != 0) {
/* use the status as the flags when we read it the first time */
if (status)
- mi->info.info.flags = (mi->info.info.flags & ~(STATUS_STATUS)) | (flags &
STATUS_STATUS);
+ camel_message_info_set_flags (mi, STATUS_STATUS, flags);
if (xstatus)
- mi->info.info.flags = (mi->info.info.flags & ~(STATUS_XSTATUS)) | (flags &
STATUS_XSTATUS);
+ camel_message_info_set_flags (mi, STATUS_XSTATUS, flags);
}
-#endif
+
if (mbs->changes) {
if (add&2)
camel_folder_change_info_add_uid (mbs->changes, camel_message_info_get_uid
(mi));
@@ -381,7 +315,7 @@ message_info_new_from_header (CamelFolderSummary *s,
camel_folder_change_info_recent_uid (mbs->changes, camel_message_info_get_uid
(mi));
}
- mi->frompos = -1;
+ camel_mbox_message_info_set_offset (CAMEL_MBOX_MESSAGE_INFO (mi), -1);
}
return (CamelMessageInfo *) mi;
@@ -395,46 +329,12 @@ message_info_new_from_parser (CamelFolderSummary *s,
mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->message_info_new_from_parser (s,
mp);
if (mi) {
- CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *) mi;
-
- mbi->frompos = camel_mime_parser_tell_start_from (mp);
+ camel_mbox_message_info_set_offset (CAMEL_MBOX_MESSAGE_INFO (mi),
camel_mime_parser_tell_start_from (mp));
}
return mi;
}
-static CamelMessageInfo *
-message_info_from_db (CamelFolderSummary *s,
- struct _CamelMIRecord *mir)
-{
- CamelMessageInfo *mi;
-
- mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->message_info_from_db (s, mir);
-
- if (mi) {
- CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *) mi;
- gchar *part = mir->bdata;
- if (part) {
- mbi->frompos = bdata_extract_digit (&part);
- }
- }
-
- return mi;
-}
-
-static struct _CamelMIRecord *
-message_info_to_db (CamelFolderSummary *s,
- CamelMessageInfo *info)
-{
- CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *) info;
- struct _CamelMIRecord *mir;
-
- mir = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->message_info_to_db (s, info);
- mir->bdata = g_strdup_printf ("%" G_GOFFSET_FORMAT, mbi->frompos);
-
- return mir;
-}
-
/* like summary_rebuild, but also do changeinfo stuff (if supplied) */
static gint
summary_update (CamelLocalSummary *cls,
@@ -447,7 +347,7 @@ summary_update (CamelLocalSummary *cls,
CamelFolderSummary *s = (CamelFolderSummary *) cls;
CamelMboxSummary *mbs = (CamelMboxSummary *) cls;
CamelMimeParser *mp;
- CamelMboxMessageInfo *mi;
+ CamelMessageInfo *mi;
CamelStore *parent_store;
const gchar *full_name;
gint fd;
@@ -503,12 +403,9 @@ summary_update (CamelLocalSummary *cls,
camel_folder_summary_prepare_fetch_all (s, NULL);
known_uids = camel_folder_summary_get_array (s);
for (i = 0; known_uids && i < known_uids->len; i++) {
- mi = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
- if (offset == 0)
- mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN;
- else
- mi->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
- camel_message_info_unref (mi);
+ mi = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
+ camel_message_info_set_flags (mi, CAMEL_MESSAGE_FOLDER_NOTSEEN, offset == 0 ?
CAMEL_MESSAGE_FOLDER_NOTSEEN : 0);
+ g_clear_object (&mi);
}
camel_folder_summary_free_array (known_uids);
mbs->changes = changeinfo;
@@ -526,7 +423,8 @@ summary_update (CamelLocalSummary *cls,
camel_operation_progress (cancellable, progress);
info = camel_folder_summary_info_new_from_parser (s, mp);
- camel_folder_summary_add (s, info);
+ camel_folder_summary_add (s, info, FALSE);
+ g_clear_object (&info);
g_warn_if_fail (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM_END);
}
@@ -541,19 +439,18 @@ summary_update (CamelLocalSummary *cls,
if (!uid)
continue;
- mi = (CamelMboxMessageInfo *) camel_folder_summary_get (s, uid);
+ mi = camel_folder_summary_get (s, uid);
/* must've dissapeared from the file? */
- if (!mi || mi->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) {
+ if (!mi || (camel_message_info_get_flags (mi) & CAMEL_MESSAGE_FOLDER_NOTSEEN) != 0) {
d (printf ("uid '%s' vanished, removing", uid));
if (changeinfo)
camel_folder_change_info_remove_uid (changeinfo, uid);
del = g_list_prepend (del, (gpointer) camel_pstring_strdup (uid));
if (mi)
- camel_folder_summary_remove (s, (CamelMessageInfo *) mi);
+ camel_folder_summary_remove (s, mi);
}
- if (mi)
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
}
if (known_uids)
@@ -562,7 +459,7 @@ summary_update (CamelLocalSummary *cls,
/* Delete all in one transaction */
full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
- camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
+ camel_db_delete_uids (camel_store_get_db (parent_store), full_name, del, NULL);
g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
g_list_free (del);
@@ -573,7 +470,7 @@ summary_update (CamelLocalSummary *cls,
if (g_stat (cls->folder_path, &st) == 0) {
camel_folder_summary_touch (s);
mbs->folder_size = st.st_size;
- s->time = st.st_mtime;
+ camel_folder_summary_set_timestamp (s, st.st_mtime);
}
}
@@ -627,7 +524,7 @@ mbox_summary_check (CamelLocalSummary *cls,
if (info) {
camel_folder_change_info_remove_uid (changes, camel_message_info_get_uid
(info));
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
}
camel_folder_summary_free_array (known_uids);
@@ -635,7 +532,7 @@ mbox_summary_check (CamelLocalSummary *cls,
ret = 0;
} else {
/* is the summary uptodate? */
- if (st.st_size != mbs->folder_size || st.st_mtime != s->time) {
+ if (st.st_size != mbs->folder_size || st.st_mtime != camel_folder_summary_get_timestamp (s)) {
if (mbs->folder_size < st.st_size) {
/* this will automatically rescan from 0 if there is a problem */
d (printf ("folder grew, attempting to rebuild from %d\n", mbs->folder_size));
@@ -652,9 +549,9 @@ mbox_summary_check (CamelLocalSummary *cls,
/* FIXME: move upstream? */
if (ret != -1) {
- if (mbs->folder_size != st.st_size || s->time != st.st_mtime) {
+ if (mbs->folder_size != st.st_size || camel_folder_summary_get_timestamp (s) != st.st_mtime) {
mbs->folder_size = st.st_size;
- s->time = st.st_mtime;
+ camel_folder_summary_set_timestamp (s, st.st_mtime);
camel_folder_summary_touch (s);
}
}
@@ -790,20 +687,25 @@ cms_sort_frompos (gconstpointer a,
{
CamelFolderSummary *summary = (CamelFolderSummary *) data;
CamelMboxMessageInfo *info1, *info2;
+ goffset afrompos, bfrompos;
gint ret = 0;
/* Things are in memory already. Sorting speeds up syncing, if things are sorted by from pos. */
info1 = (CamelMboxMessageInfo *) camel_folder_summary_get (summary, *(gchar **) a);
info2 = (CamelMboxMessageInfo *) camel_folder_summary_get (summary, *(gchar **) b);
- if (info1->frompos > info2->frompos)
+ afrompos = camel_mbox_message_info_get_offset (info1);
+ bfrompos = camel_mbox_message_info_get_offset (info2);
+
+ if (afrompos > bfrompos)
ret = 1;
- else if (info1->frompos < info2->frompos)
+ else if (afrompos < bfrompos)
ret = -1;
else
ret = 0;
- camel_message_info_unref (info1);
- camel_message_info_unref (info2);
+
+ g_clear_object (&info1);
+ g_clear_object (&info2);
return ret;
@@ -821,7 +723,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
CamelFolderSummary *s = (CamelFolderSummary *) mbs;
CamelMimeParser *mp = NULL;
gint i;
- CamelMboxMessageInfo *info = NULL;
+ CamelMessageInfo *info = NULL;
gint fd = -1, pfd;
gchar *xevnew, *xevtmp;
const gchar *xev;
@@ -871,24 +773,26 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
g_ptr_array_sort_with_data (summary, cms_sort_frompos, mbs);
for (i = 0; i < summary->len; i++) {
+ goffset frompos;
gint xevoffset;
gint pc = (i + 1) * 100 / summary->len;
camel_operation_progress (cancellable, pc);
- info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, summary->pdata[i]);
+ info = camel_folder_summary_get (s, summary->pdata[i]);
- d (printf ("Checking message %s %08x\n", camel_message_info_get_uid (info),
((CamelMessageInfoBase *) info)->flags));
+ d (printf ("Checking message %s %08x\n", camel_message_info_get_uid (info),
camel_message_info_get_flags (info)));
- if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
- camel_message_info_unref (info);
- info = NULL;
+ if (!camel_message_info_get_folder_flagged (info)) {
+ g_clear_object (&info);
continue;
}
- d (printf ("Updating message %s: %d\n", camel_message_info_get_uid (info), (gint)
info->frompos));
+ frompos = camel_mbox_message_info_get_offset (CAMEL_MBOX_MESSAGE_INFO (info));
- camel_mime_parser_seek (mp, info->frompos, SEEK_SET);
+ d (printf ("Updating message %s: %d\n", camel_message_info_get_uid (info), (gint) frompos));
+
+ camel_mime_parser_seek (mp, frompos, SEEK_SET);
if (camel_mime_parser_step (mp, NULL, NULL) != CAMEL_MIME_PARSER_STATE_FROM) {
g_set_error (
@@ -897,10 +801,10 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
goto error;
}
- if (camel_mime_parser_tell_start_from (mp) != info->frompos) {
+ if (camel_mime_parser_tell_start_from (mp) != frompos) {
g_warning (
"Didn't get the next message where I expected (%d) got %d instead",
- (gint) info->frompos, (gint) camel_mime_parser_tell_start_from (mp));
+ (gint) frompos, (gint) camel_mime_parser_tell_start_from (mp));
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Summary and folder mismatch, even after a sync"));
@@ -917,7 +821,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
g_warning ("We're supposed to have a valid x-ev header, but we dont");
goto error;
}
- xevnew = camel_local_summary_encode_x_evolution (cls, &info->info);
+ xevnew = camel_local_summary_encode_x_evolution (cls, info);
/* SIGH: encode_param_list is about the only function which folds headers by itself.
* This should be fixed somehow differently (either parser doesn't fold headers,
* or param_list doesn't, or something */
@@ -949,10 +853,8 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
camel_mime_parser_drop_step (mp);
camel_mime_parser_drop_step (mp);
- info->info.info.flags &= 0xffff;
- info->info.info.dirty = TRUE;
- camel_message_info_unref (info);
- info = NULL;
+ camel_message_info_set_flags (info, 0xffff, camel_message_info_get_flags (info));
+ g_clear_object (&info);
}
d (printf ("Closing folders\n"));
@@ -983,7 +885,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
if (fd != -1)
close (fd);
if (info)
- camel_message_info_unref (info);
+ g_clear_object (&info);
camel_operation_pop_message (cancellable);
camel_folder_summary_unlock (s);
@@ -1023,14 +925,14 @@ mbox_summary_sync (CamelLocalSummary *cls,
summary = camel_folder_summary_get_changed ((CamelFolderSummary *) mbs);
for (i = 0; i < summary->len; i++) {
- CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_get (s,
summary->pdata[i]);
+ CamelMessageInfo *info = camel_folder_summary_get (s, summary->pdata[i]);
- if ((expunge && (info->info.info.flags & CAMEL_MESSAGE_DELETED)) ||
- (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_XEVCHANGE)))
+ if ((expunge && (camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED) != 0) ||
+ (camel_message_info_get_flags (info) & (CAMEL_MESSAGE_FOLDER_NOXEV |
CAMEL_MESSAGE_FOLDER_XEVCHANGE)) != 0)
quick = FALSE;
else
- work |= (info->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0;
- camel_message_info_unref (info);
+ work |= camel_message_info_get_folder_flagged (info);
+ g_clear_object (&info);
}
g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
@@ -1039,7 +941,7 @@ mbox_summary_sync (CamelLocalSummary *cls,
if (quick && expunge) {
guint32 dcount =0;
- if (camel_db_count_deleted_message_info (parent_store->cdb_w, full_name, &dcount, error) ==
-1) {
+ if (camel_db_count_deleted_message_info (camel_store_get_db (parent_store), full_name,
&dcount, error) == -1) {
camel_folder_summary_unlock (s);
return -1;
}
@@ -1077,8 +979,8 @@ mbox_summary_sync (CamelLocalSummary *cls,
return -1;
}
- if (mbs->folder_size != st.st_size || s->time != st.st_mtime) {
- s->time = st.st_mtime;
+ if (mbs->folder_size != st.st_size || camel_folder_summary_get_timestamp (s) != st.st_mtime) {
+ camel_folder_summary_set_timestamp (s, st.st_mtime);
mbs->folder_size = st.st_size;
camel_folder_summary_touch (s);
}
@@ -1104,7 +1006,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
CamelStore *parent_store;
const gchar *full_name;
gint i;
- CamelMboxMessageInfo *info = NULL;
+ CamelMessageInfo *info = NULL;
gchar *buffer, *xevnew = NULL;
gsize len;
const gchar *fromline;
@@ -1112,9 +1014,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
gboolean touched = FALSE;
GList *del = NULL;
GPtrArray *known_uids = NULL;
-#ifdef STATUS_PINE
gchar statnew[8], xstatnew[8];
-#endif
d (printf ("performing full summary/sync\n"));
@@ -1144,10 +1044,11 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
g_ptr_array_sort_with_data (known_uids, cms_sort_frompos, mbs);
for (i = 0; known_uids && i < known_uids->len; i++) {
gint pc = (i + 1) * 100 / known_uids->len;
+ goffset frompos;
camel_operation_progress (cancellable, pc);
- info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids,
i));
+ info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
if (!info)
continue;
@@ -1156,13 +1057,15 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
"Looking at message %s\n",
camel_message_info_get_uid (info)));
+ frompos = camel_mbox_message_info_get_offset (CAMEL_MBOX_MESSAGE_INFO (info));
+
d (printf (
"seeking (%s) to %d\n",
- ((CamelMessageInfo *) info)->uid,
- (gint) info->frompos));
+ camel_message_info_get_uid (info),
+ (gint) frompos));
if (lastdel)
- camel_mime_parser_seek (mp, info->frompos, SEEK_SET);
+ camel_mime_parser_seek (mp, frompos, SEEK_SET);
if (camel_mime_parser_step (mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_FROM) {
g_set_error (
@@ -1172,10 +1075,10 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
goto error;
}
- if (camel_mime_parser_tell_start_from (mp) != info->frompos) {
+ if (camel_mime_parser_tell_start_from (mp) != frompos) {
g_warning (
"Didn't get the next message where I expected (%d) got %d instead",
- (gint) info->frompos,
+ (gint) frompos,
(gint) camel_mime_parser_tell_start_from (mp));
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
@@ -1184,7 +1087,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
}
lastdel = FALSE;
- if ((flags&1) && info->info.info.flags & CAMEL_MESSAGE_DELETED) {
+ if ((flags & 1) && (camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED) != 0) {
const gchar *uid = camel_message_info_get_uid (info);
d (printf ("Deleting %s\n", uid));
@@ -1195,8 +1098,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
camel_folder_change_info_remove_uid (changeinfo, uid);
camel_folder_summary_remove (s, (CamelMessageInfo *) info);
del = g_list_prepend (del, (gpointer) camel_pstring_strdup (uid));
- camel_message_info_unref (info);
- info = NULL;
+ g_clear_object (&info);
lastdel = TRUE;
touched = TRUE;
} else {
@@ -1205,33 +1107,37 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
if (i > 0)
write (fdout, "\n", 1);
#endif
- info->frompos = lseek (fdout, 0, SEEK_CUR);
- ((CamelMessageInfo *) info)->dirty = TRUE;
+ frompos = lseek (fdout, 0, SEEK_CUR);
+ camel_mbox_message_info_set_offset (CAMEL_MBOX_MESSAGE_INFO (info), frompos);
+ camel_message_info_set_dirty (info, TRUE);
fromline = camel_mime_parser_from_line (mp);
- d (printf ("Saving %s:%d\n", camel_message_info_get_uid (info), info->frompos));
+ d (printf ("Saving %s:%d\n", camel_message_info_get_uid (info), frompos));
g_warn_if_fail (write (fdout, fromline, strlen (fromline)) != -1);
}
- if (info && info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV |
CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- d (printf ("Updating header for %s flags = %08x\n", camel_message_info_get_uid
(info), info->info.flags));
+ if (info && (camel_message_info_get_flags (info) & (CAMEL_MESSAGE_FOLDER_NOXEV |
CAMEL_MESSAGE_FOLDER_FLAGGED)) != 0) {
+ CamelNameValueArray *header = NULL;
+ d (printf ("Updating header for %s flags = %08x\n", camel_message_info_get_uid
(info), camel_message_info_get_flags (info)));
if (camel_mime_parser_step (mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_FROM_END) {
g_warning ("camel_mime_parser_step failed (2)");
goto error;
}
- xevnew = camel_local_summary_encode_x_evolution ((CamelLocalSummary *) cls,
&info->info);
-#ifdef STATUS_PINE
+ header = camel_mime_parser_dup_headers (mp);
+ xevnew = camel_local_summary_encode_x_evolution ((CamelLocalSummary *) cls, info);
if (mbs->xstatus) {
- encode_status (info->info.info.flags & STATUS_STATUS, statnew);
- encode_status (info->info.info.flags & STATUS_XSTATUS, xstatnew);
- len = camel_local_summary_write_headers (fdout, camel_mime_parser_headers_raw
(mp), xevnew, statnew, xstatnew);
+ guint32 flags = camel_message_info_get_flags (info);
+
+ encode_status (flags & STATUS_STATUS, statnew);
+ encode_status (flags & STATUS_XSTATUS, xstatnew);
+
+ len = camel_local_summary_write_headers (fdout, header, xevnew, statnew,
xstatnew);
} else {
-#endif
- len = camel_local_summary_write_headers (fdout, camel_mime_parser_headers_raw
(mp), xevnew, NULL, NULL);
-#ifdef STATUS_PINE
+ len = camel_local_summary_write_headers (fdout, header, xevnew, NULL, NULL);
}
-#endif
+
+ camel_name_value_array_free (header);
if (len == -1) {
d (printf ("Error writing to temporary mailbox\n"));
g_set_error (
@@ -1241,7 +1147,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
g_strerror (errno));
goto error;
}
- info->info.info.flags &= 0xffff;
+ camel_message_info_set_flags (info, 0xffff, camel_message_info_get_flags (info));
g_free (xevnew);
xevnew = NULL;
camel_mime_parser_drop_step (mp);
@@ -1277,14 +1183,13 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
(gint) camel_mime_parser_tell (mp),
(gint) camel_mime_parser_tell_start_from (mp)));
camel_mime_parser_unstep (mp);
- camel_message_info_unref (info);
- info = NULL;
+ g_clear_object (&info);
}
}
full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
- camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
+ camel_db_delete_uids (camel_store_get_db (parent_store), full_name, del, NULL);
g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
g_list_free (del);
@@ -1298,24 +1203,17 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
/* clear working flags */
for (i = 0; known_uids && i < known_uids->len; i++) {
- info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids,
i));
+ info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
if (info) {
- if (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV |
CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_XEVCHANGE)) {
- info->info.info.flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV
- |CAMEL_MESSAGE_FOLDER_FLAGGED
- |CAMEL_MESSAGE_FOLDER_XEVCHANGE);
- ((CamelMessageInfo *) info)->dirty = TRUE;
- camel_folder_summary_touch (s);
- }
- camel_message_info_unref (info);
- info = NULL;
+ camel_message_info_set_flags (info, CAMEL_MESSAGE_FOLDER_NOXEV |
CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_XEVCHANGE, 0);
+ g_clear_object (&info);
}
}
camel_folder_summary_free_array (known_uids);
if (touched)
- camel_folder_summary_header_save_to_db (s, NULL);
+ camel_folder_summary_header_save (s, NULL);
camel_folder_summary_unlock (s);
@@ -1323,9 +1221,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
error:
g_free (xevnew);
g_object_unref (mp);
-
- if (info)
- camel_message_info_unref (info);
+ g_clear_object (&info);
camel_folder_summary_free_array (known_uids);
camel_folder_summary_unlock (s);
@@ -1333,7 +1229,6 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
return -1;
}
-#ifdef STATUS_PINE
static CamelMessageInfo *
mbox_summary_add (CamelLocalSummary *cls,
CamelMimeMessage *msg,
@@ -1342,23 +1237,23 @@ mbox_summary_add (CamelLocalSummary *cls,
GError **error)
{
CamelLocalSummaryClass *local_summary_class;
- CamelMboxMessageInfo *mi;
+ CamelMessageInfo *mi;
/* Chain up to parent's add() method. */
local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (camel_mbox_summary_parent_class);
- mi = (CamelMboxMessageInfo *) local_summary_class->add (
- cls, msg, info, ci, error);
+ mi = local_summary_class->add (cls, msg, info, ci, error);
if (mi && ((CamelMboxSummary *) cls)->xstatus) {
gchar status[8];
+ guint32 flags = camel_message_info_get_flags (mi);
/* we snoop and add status/x-status headers to suit */
- encode_status (mi->info.info.flags & STATUS_STATUS, status);
+ encode_status (flags & STATUS_STATUS, status);
camel_medium_set_header ((CamelMedium *) msg, "Status", status);
- encode_status (mi->info.info.flags & STATUS_XSTATUS, status);
+ encode_status (flags & STATUS_XSTATUS, status);
camel_medium_set_header ((CamelMedium *) msg, "X-Status", status);
}
- return (CamelMessageInfo *) mi;
+ return mi;
}
static struct {
@@ -1403,5 +1298,3 @@ decode_status (const gchar *status)
return flags;
}
-
-#endif /* STATUS_PINE */
diff --git a/src/camel/providers/local/camel-mbox-summary.h b/src/camel/providers/local/camel-mbox-summary.h
index 37f6bad..1c610c2 100644
--- a/src/camel/providers/local/camel-mbox-summary.h
+++ b/src/camel/providers/local/camel-mbox-summary.h
@@ -45,12 +45,6 @@ G_BEGIN_DECLS
typedef struct _CamelMboxSummary CamelMboxSummary;
typedef struct _CamelMboxSummaryClass CamelMboxSummaryClass;
-typedef struct _CamelMboxMessageInfo {
- CamelLocalMessageInfo info;
-
- goffset frompos;
-} CamelMboxMessageInfo;
-
struct _CamelMboxSummary {
CamelLocalSummary parent;
@@ -78,6 +72,9 @@ struct _CamelMboxSummaryClass {
CamelFolderChangeInfo *changeinfo,
GCancellable *cancellable,
GError **error);
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mbox_summary_get_type (void);
diff --git a/src/camel/providers/local/camel-mh-folder.c b/src/camel/providers/local/camel-mh-folder.c
index 7eaafe9..f3cc140 100644
--- a/src/camel/providers/local/camel-mh-folder.c
+++ b/src/camel/providers/local/camel-mh-folder.c
@@ -71,7 +71,7 @@ mh_folder_append_message_sync (CamelFolder *folder,
return FALSE;
/* add it to the summary/assign the uid, etc */
- mi = camel_local_summary_add ((CamelLocalSummary *) folder->summary, message, info, lf->changes,
error);
+ mi = camel_local_summary_add ((CamelLocalSummary *) camel_folder_get_folder_summary (folder),
message, info, lf->changes, error);
if (mi == NULL)
goto check_changed;
@@ -108,7 +108,7 @@ mh_folder_append_message_sync (CamelFolder *folder,
fail_write:
/* remove the summary info so we are not out-of-sync with the mh folder */
- camel_folder_summary_remove (CAMEL_FOLDER_SUMMARY (folder->summary), mi);
+ camel_folder_summary_remove (camel_folder_get_folder_summary (folder), mi);
g_prefix_error (
error, _("Cannot append message to mh folder: %s: "), name);
@@ -128,6 +128,8 @@ mh_folder_append_message_sync (CamelFolder *folder,
camel_folder_change_info_clear (lf->changes);
}
+ g_clear_object (&mi);
+
return TRUE;
}
@@ -149,7 +151,7 @@ mh_folder_get_message_sync (CamelFolder *folder,
return NULL;
/* get the message summary info */
- if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) {
+ if ((info = camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid)) == NULL) {
set_cannot_get_message_ex (
error, CAMEL_FOLDER_ERROR_INVALID_UID,
uid, lf->folder_path, _("No such message"));
@@ -157,7 +159,7 @@ mh_folder_get_message_sync (CamelFolder *folder,
}
/* we only need it to check the message exists */
- camel_message_info_unref (info);
+ g_clear_object (&info);
name = g_strdup_printf ("%s/%s", lf->folder_path, uid);
message_stream = camel_stream_fs_new_with_name (
diff --git a/src/camel/providers/local/camel-mh-folder.h b/src/camel/providers/local/camel-mh-folder.h
index c905c2e..169abc1 100644
--- a/src/camel/providers/local/camel-mh-folder.h
+++ b/src/camel/providers/local/camel-mh-folder.h
@@ -51,6 +51,9 @@ struct _CamelMhFolder {
struct _CamelMhFolderClass {
CamelLocalFolderClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mh_folder_get_type (void);
diff --git a/src/camel/providers/local/camel-mh-settings.h b/src/camel/providers/local/camel-mh-settings.h
index 0ec8561..a9b633c 100644
--- a/src/camel/providers/local/camel-mh-settings.h
+++ b/src/camel/providers/local/camel-mh-settings.h
@@ -52,6 +52,9 @@ struct _CamelMhSettings {
struct _CamelMhSettingsClass {
CamelLocalSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mh_settings_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/providers/local/camel-mh-store.c b/src/camel/providers/local/camel-mh-store.c
index 7f771ec..9dc7752 100644
--- a/src/camel/providers/local/camel-mh-store.c
+++ b/src/camel/providers/local/camel-mh-store.c
@@ -189,7 +189,7 @@ fill_fi (CamelStore *store,
CamelFolder *folder;
local_store = CAMEL_LOCAL_STORE (store);
- folder = camel_object_bag_peek (store->folders, fi->full_name);
+ folder = camel_object_bag_peek (camel_store_get_folders_bag (store), fi->full_name);
if (folder != NULL) {
fi->unread = camel_folder_get_unread_message_count (folder);
@@ -220,10 +220,8 @@ fill_fi (CamelStore *store,
* every file, i.e. very very slow */
folderpath = g_strdup_printf ("%s/%s", path, fi->full_name);
- s = (CamelFolderSummary *) camel_mh_summary_new (
- NULL, folderpath, NULL);
- if (camel_folder_summary_header_load_from_db (
- s, store, fi->full_name, NULL)) {
+ s = (CamelFolderSummary *) camel_mh_summary_new (NULL, folderpath, NULL);
+ if (camel_folder_summary_header_load (s, store, fi->full_name, NULL)) {
fi->unread = camel_folder_summary_get_unread_count (s);
fi->total = camel_folder_summary_get_saved_count (s);
}
diff --git a/src/camel/providers/local/camel-mh-store.h b/src/camel/providers/local/camel-mh-store.h
index c478d48..fd78f39 100644
--- a/src/camel/providers/local/camel-mh-store.h
+++ b/src/camel/providers/local/camel-mh-store.h
@@ -54,6 +54,9 @@ struct _CamelMhStore {
struct _CamelMhStoreClass {
CamelLocalStoreClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mh_store_get_type (void);
diff --git a/src/camel/providers/local/camel-mh-summary.c b/src/camel/providers/local/camel-mh-summary.c
index b653192..6c33a58 100644
--- a/src/camel/providers/local/camel-mh-summary.c
+++ b/src/camel/providers/local/camel-mh-summary.c
@@ -43,7 +43,7 @@
static gint mh_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable
*cancellable, GError **error);
static gint mh_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo,
GCancellable *cancellable, GError **error);
-static gint mh_summary_decode_x_evolution (CamelLocalSummary *cls, const gchar *xev, CamelLocalMessageInfo
*info);
+static gint mh_summary_decode_x_evolution (CamelLocalSummary *cls, const gchar *xev, CamelMessageInfo *info);
/*static gint mh_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, CamelMessageInfo *info,
CamelFolderChangeInfo *, GError **error);*/
static gchar *mh_summary_next_uid_string (CamelFolderSummary *s);
@@ -63,6 +63,8 @@ camel_mh_summary_class_init (CamelMhSummaryClass *class)
g_type_class_add_private (class, sizeof (CamelMhSummaryPrivate));
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
+ folder_summary_class->sort_by = "uid";
+ folder_summary_class->collate = "mh_uid_sort";
folder_summary_class->next_uid_string = mh_summary_next_uid_string;
local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (class);
@@ -81,7 +83,7 @@ camel_mh_summary_init (CamelMhSummary *mh_summary)
folder_summary = CAMEL_FOLDER_SUMMARY (mh_summary);
/* set unique file version */
- folder_summary->version += CAMEL_MH_SUMMARY_VERSION;
+ camel_folder_summary_set_version (folder_summary, camel_folder_summary_get_version (folder_summary) +
CAMEL_MH_SUMMARY_VERSION);
}
/**
@@ -103,9 +105,7 @@ camel_mh_summary_new (CamelFolder *folder,
CamelStore *parent_store;
parent_store = camel_folder_get_parent_store (folder);
- camel_db_set_collate (parent_store->cdb_r, "uid", "mh_uid_sort", (CamelDBCollate)
camel_local_frompos_sort);
- ((CamelFolderSummary *) o)->sort_by = "uid";
- ((CamelFolderSummary *) o)->collate = "mh_uid_sort";
+ camel_db_set_collate (camel_store_get_db (parent_store), "uid", "mh_uid_sort",
(CamelDBCollate) camel_local_frompos_sort);
}
camel_local_summary_construct ((CamelLocalSummary *) o, mhdir, index);
@@ -183,7 +183,8 @@ camel_mh_summary_add (CamelLocalSummary *cls,
mhs->priv->current_uid = (gchar *) name;
info = camel_folder_summary_info_new_from_parser (summary, mp);
- camel_folder_summary_add (summary, info);
+ camel_folder_summary_add (summary, info, FALSE);
+ g_clear_object (&info);
g_object_unref (mp);
mhs->priv->current_uid = NULL;
@@ -202,7 +203,7 @@ remove_summary (gchar *key,
if (cls->index)
camel_index_delete_name (cls->index, camel_message_info_get_uid (info));
camel_folder_summary_remove ((CamelFolderSummary *) cls, info);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
static gint
@@ -265,11 +266,11 @@ mh_summary_check (CamelLocalSummary *cls,
if (old) {
g_hash_table_remove (left, camel_message_info_get_uid (info));
- camel_message_info_unref (old);
+ g_clear_object (&old);
}
camel_folder_summary_remove ((CamelFolderSummary *) cls, info);
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
camel_mh_summary_add (cls, d->d_name, forceindex, cancellable);
} else {
@@ -278,9 +279,9 @@ mh_summary_check (CamelLocalSummary *cls,
if (old) {
g_hash_table_remove (left, uid);
- camel_message_info_unref (old);
+ g_clear_object (&old);
}
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
}
}
@@ -302,7 +303,7 @@ mh_summary_sync (CamelLocalSummary *cls,
CamelLocalSummaryClass *local_summary_class;
gint i;
GPtrArray *known_uids;
- CamelLocalMessageInfo *info;
+ CamelMessageInfo *info;
gchar *name;
const gchar *uid;
@@ -318,9 +319,9 @@ mh_summary_sync (CamelLocalSummary *cls,
camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *) cls, error);
known_uids = camel_folder_summary_get_array ((CamelFolderSummary *) cls);
for (i = (known_uids ? known_uids->len : 0) - 1; i >= 0; i--) {
- info = (CamelLocalMessageInfo *) camel_folder_summary_get ((CamelFolderSummary *) cls,
g_ptr_array_index (known_uids, i));
+ info = camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids,
i));
g_return_val_if_fail (info, -1);
- if (expunge && (info->info.flags & CAMEL_MESSAGE_DELETED)) {
+ if (expunge && (camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED) != 0) {
uid = camel_message_info_get_uid (info);
name = g_strdup_printf ("%s/%s", cls->folder_path, uid);
d (printf ("deleting %s\n", name));
@@ -334,10 +335,10 @@ mh_summary_sync (CamelLocalSummary *cls,
camel_folder_summary_remove ((CamelFolderSummary *) cls, (CamelMessageInfo *)
info);
}
g_free (name);
- } else if (info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- info->info.flags &= 0xffff;
+ } else if ((camel_message_info_get_flags (info) & (CAMEL_MESSAGE_FOLDER_NOXEV |
CAMEL_MESSAGE_FOLDER_FLAGGED)) != 0) {
+ camel_message_info_set_flags (info, 0xffff, camel_message_info_get_flags (info));
}
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
camel_folder_summary_free_array (known_uids);
@@ -350,7 +351,7 @@ mh_summary_sync (CamelLocalSummary *cls,
static gint
mh_summary_decode_x_evolution (CamelLocalSummary *cls,
const gchar *xev,
- CamelLocalMessageInfo *info)
+ CamelMessageInfo *info)
{
CamelLocalSummaryClass *local_summary_class;
CamelMhSummary *mh_summary;
@@ -365,8 +366,7 @@ mh_summary_decode_x_evolution (CamelLocalSummary *cls,
/* do not use UID from the header, rather use the one provided, if any */
mh_summary = CAMEL_MH_SUMMARY (cls);
if (mh_summary->priv->current_uid) {
- camel_pstring_free (info->info.uid);
- info->info.uid = camel_pstring_strdup (mh_summary->priv->current_uid);
+ camel_message_info_set_uid (info, mh_summary->priv->current_uid);
}
return ret;
diff --git a/src/camel/providers/local/camel-mh-summary.h b/src/camel/providers/local/camel-mh-summary.h
index 3c3ef20..e99ab8a 100644
--- a/src/camel/providers/local/camel-mh-summary.h
+++ b/src/camel/providers/local/camel-mh-summary.h
@@ -53,6 +53,9 @@ struct _CamelMhSummary {
struct _CamelMhSummaryClass {
CamelLocalSummaryClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_mh_summary_get_type (void);
diff --git a/src/camel/providers/local/camel-spool-folder.c b/src/camel/providers/local/camel-spool-folder.c
index af8c064..d98d3b2 100644
--- a/src/camel/providers/local/camel-spool-folder.c
+++ b/src/camel/providers/local/camel-spool-folder.c
@@ -159,15 +159,14 @@ camel_spool_folder_new (CamelStore *parent_store,
"parent-store", parent_store, NULL);
if (filter_inbox && strcmp (full_name, "INBOX") == 0)
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) | CAMEL_FOLDER_FILTER_RECENT);
flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX;
folder = (CamelFolder *) camel_local_folder_construct (
(CamelLocalFolder *) folder, flags, cancellable, error);
if (folder != NULL && use_xstatus_headers)
- camel_mbox_summary_xstatus (
- CAMEL_MBOX_SUMMARY (folder->summary), TRUE);
+ camel_mbox_summary_xstatus (CAMEL_MBOX_SUMMARY (camel_folder_get_folder_summary (folder)),
TRUE);
g_free (basename);
diff --git a/src/camel/providers/local/camel-spool-folder.h b/src/camel/providers/local/camel-spool-folder.h
index 1de8e2d..88e1e6d 100644
--- a/src/camel/providers/local/camel-spool-folder.h
+++ b/src/camel/providers/local/camel-spool-folder.h
@@ -57,6 +57,9 @@ struct _CamelSpoolFolder {
struct _CamelSpoolFolderClass {
CamelMboxFolderClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_spool_folder_get_type (void);
diff --git a/src/camel/providers/local/camel-spool-settings.h
b/src/camel/providers/local/camel-spool-settings.h
index 5ee0ecc..53d8d5a 100644
--- a/src/camel/providers/local/camel-spool-settings.h
+++ b/src/camel/providers/local/camel-spool-settings.h
@@ -52,6 +52,9 @@ struct _CamelSpoolSettings {
struct _CamelSpoolSettingsClass {
CamelLocalSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_spool_settings_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/providers/local/camel-spool-store.c b/src/camel/providers/local/camel-spool-store.c
index b97810d..3478091 100644
--- a/src/camel/providers/local/camel-spool-store.c
+++ b/src/camel/providers/local/camel-spool-store.c
@@ -125,7 +125,7 @@ spool_fill_fi (CamelStore *store,
fi->unread = -1;
fi->total = -1;
- folder = camel_object_bag_peek (store->folders, fi->full_name);
+ folder = camel_object_bag_peek (camel_store_get_folders_bag (store), fi->full_name);
if (folder) {
if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
camel_folder_refresh_info_sync (folder, cancellable, NULL);
@@ -256,8 +256,7 @@ scan_dir (CamelStore *store,
gint isfolder = FALSE;
/* first, see if we already have it open */
- folder = camel_object_bag_peek (
- store->folders, fname);
+ folder = camel_object_bag_peek (camel_store_get_folders_bag (store), fname);
if (folder == NULL) {
fp = fopen (tmp, "r");
if (fp != NULL) {
diff --git a/src/camel/providers/local/camel-spool-store.h b/src/camel/providers/local/camel-spool-store.h
index d6974d1..d2e6e33 100644
--- a/src/camel/providers/local/camel-spool-store.h
+++ b/src/camel/providers/local/camel-spool-store.h
@@ -54,6 +54,9 @@ struct _CamelSpoolStore {
struct _CamelSpoolStoreClass {
CamelMboxStoreClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_spool_store_get_type (void);
diff --git a/src/camel/providers/local/camel-spool-summary.c b/src/camel/providers/local/camel-spool-summary.c
index 44e3719..a0992d3 100644
--- a/src/camel/providers/local/camel-spool-summary.c
+++ b/src/camel/providers/local/camel-spool-summary.c
@@ -31,10 +31,11 @@
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
-#include "camel-spool-summary.h"
#include "camel-local-private.h"
#include "camel-win32.h"
+#include "camel-spool-summary.h"
+
#define io(x)
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -60,9 +61,14 @@ G_DEFINE_TYPE (CamelSpoolSummary, camel_spool_summary, CAMEL_TYPE_MBOX_SUMMARY)
static void
camel_spool_summary_class_init (CamelSpoolSummaryClass *class)
{
+ CamelFolderSummaryClass *folder_summary_class;
CamelLocalSummaryClass *local_summary_class;
CamelMboxSummaryClass *mbox_summary_class;
+ folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
+ folder_summary_class->sort_by = "bdata";
+ folder_summary_class->collate = "spool_frompos_sort";
+
local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (class);
local_summary_class->load = spool_summary_load;
local_summary_class->check = spool_summary_check;
@@ -82,7 +88,7 @@ camel_spool_summary_init (CamelSpoolSummary *spool_summary)
/* message info size is from mbox parent */
/* and a unique file version */
- folder_summary->version += CAMEL_SPOOL_SUMMARY_VERSION;
+ camel_folder_summary_set_version (folder_summary, camel_folder_summary_get_version (folder_summary) +
CAMEL_SPOOL_SUMMARY_VERSION);
}
CamelSpoolSummary *
@@ -96,12 +102,10 @@ camel_spool_summary_new (CamelFolder *folder,
CamelStore *parent_store;
parent_store = camel_folder_get_parent_store (folder);
- camel_db_set_collate (parent_store->cdb_r, "bdata", "spool_frompos_sort", (CamelDBCollate)
camel_local_frompos_sort);
- ((CamelFolderSummary *) new)->sort_by = "bdata";
- ((CamelFolderSummary *) new)->collate = "spool_frompos_sort";
+ camel_db_set_collate (camel_store_get_db (parent_store), "bdata", "spool_frompos_sort",
(CamelDBCollate) camel_local_frompos_sort);
}
camel_local_summary_construct ((CamelLocalSummary *) new, mbox_name, NULL);
- camel_folder_summary_load_from_db ((CamelFolderSummary *) new, NULL);
+ camel_folder_summary_load ((CamelFolderSummary *) new, NULL);
return new;
}
@@ -332,10 +336,10 @@ spool_summary_check (CamelLocalSummary *cls,
camel_folder_summary_prepare_fetch_all (s, error);
known_uids = camel_folder_summary_get_array (s);
for (i = 0; !work && known_uids && i < known_uids->len; i++) {
- CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_get (s,
g_ptr_array_index (known_uids, i));
+ CamelMessageInfo *info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
g_return_val_if_fail (info, -1);
- work = (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0;
- camel_message_info_unref (info);
+ work = (camel_message_info_get_flags (info) & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0;
+ g_clear_object (&info);
}
camel_folder_summary_free_array (known_uids);
@@ -357,7 +361,7 @@ spool_summary_check (CamelLocalSummary *cls,
}
((CamelMboxSummary *) cls)->folder_size = st.st_size;
- ((CamelFolderSummary *) cls)->time = st.st_mtime;
+ camel_folder_summary_set_timestamp (CAMEL_FOLDER_SUMMARY (cls), st.st_mtime);
}
return 0;
diff --git a/src/camel/providers/local/camel-spool-summary.h b/src/camel/providers/local/camel-spool-summary.h
index b08adfb..74e49e3 100644
--- a/src/camel/providers/local/camel-spool-summary.h
+++ b/src/camel/providers/local/camel-spool-summary.h
@@ -49,11 +49,13 @@ typedef struct _CamelSpoolSummaryClass CamelSpoolSummaryClass;
struct _CamelSpoolSummary {
CamelMboxSummary parent;
-
};
struct _CamelSpoolSummaryClass {
CamelMboxSummaryClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_spool_summary_get_type (void);
@@ -75,9 +77,6 @@ CamelMessageInfo *camel_spool_summary_add (CamelSpoolSummary *cls, CamelMimeMess
gchar *camel_spool_summary_encode_x_evolution (CamelSpoolSummary *cls, const CamelMessageInfo *info);
gint camel_spool_summary_decode_x_evolution (CamelSpoolSummary *cls, const gchar *xev, CamelMessageInfo
*info);
-/* utility functions - write headers to a file with optional X-Evolution header */
-gint camel_spool_summary_write_headers (gint fd, struct _camel_header_raw *header, gchar *xevline);
-
G_END_DECLS
#endif /* CAMEL_SPOOL_SUMMARY_H */
diff --git a/src/camel/providers/nntp/camel-nntp-folder.c b/src/camel/providers/nntp/camel-nntp-folder.c
index 8e45b11..8ff03a1 100644
--- a/src/camel/providers/nntp/camel-nntp-folder.c
+++ b/src/camel/providers/nntp/camel-nntp-folder.c
@@ -114,7 +114,7 @@ nntp_folder_dispose (GObject *object)
CamelStore *store;
folder = CAMEL_FOLDER (object);
- camel_folder_summary_save_to_db (folder->summary, NULL);
+ camel_folder_summary_save (camel_folder_get_folder_summary (folder), NULL);
store = camel_folder_get_parent_store (folder);
if (store != NULL) {
@@ -124,7 +124,7 @@ nntp_folder_dispose (GObject *object)
CAMEL_NNTP_STORE (store));
camel_store_summary_disconnect_folder_summary (
CAMEL_STORE_SUMMARY (nntp_store_summary),
- folder->summary);
+ camel_folder_get_folder_summary (folder));
g_clear_object (&nntp_store_summary);
}
@@ -163,7 +163,7 @@ camel_nntp_folder_selected (CamelNNTPFolder *nntp_folder,
parent_store = camel_folder_get_parent_store (folder);
res = camel_nntp_summary_check (
- CAMEL_NNTP_SUMMARY (folder->summary),
+ CAMEL_NNTP_SUMMARY (camel_folder_get_folder_summary (folder)),
CAMEL_NNTP_STORE (parent_store),
line, nntp_folder->changes,
cancellable, error);
@@ -189,14 +189,8 @@ unset_flagged_flag (const gchar *uid,
info = camel_folder_summary_get (summary, uid);
if (info) {
- CamelMessageInfoBase *base = (CamelMessageInfoBase *) info;
-
- if ((base->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
- base->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- base->dirty = TRUE;
- }
-
- camel_message_info_unref (info);
+ camel_message_info_set_folder_flagged (info, FALSE);
+ g_clear_object (&info);
}
}
@@ -410,8 +404,9 @@ nntp_folder_append_message_sync (CamelFolder *folder,
CamelStream *filtered_stream;
CamelMimeFilter *crlffilter;
gint ret;
- guint u;
- struct _camel_header_raw *header, *savedhdrs, *n, *tail;
+ guint u, ii;
+ CamelNameValueArray *previous_headers = NULL;
+ const gchar *header_name = NULL, *header_value = NULL;
const gchar *full_name;
gchar *group, *line;
gboolean success = TRUE;
@@ -445,24 +440,11 @@ nntp_folder_append_message_sync (CamelFolder *folder,
/* the 'Newsgroups: ' header */
group = g_strdup_printf ("Newsgroups: %s\r\n", full_name);
- /* remove mail 'To', 'CC', and 'BCC' headers */
- savedhdrs = NULL;
- tail = (struct _camel_header_raw *) &savedhdrs;
-
- header = (struct _camel_header_raw *) &CAMEL_MIME_PART (message)->headers;
- n = header->next;
- while (n != NULL) {
- if (!g_ascii_strcasecmp (n->name, "To") || !g_ascii_strcasecmp (n->name, "Cc") ||
!g_ascii_strcasecmp (n->name, "Bcc")) {
- header->next = n->next;
- tail->next = n;
- n->next = NULL;
- tail = n;
- } else {
- header = n;
- }
-
- n = header->next;
- }
+ /* remove mail 'To', 'Cc', and 'Bcc' headers */
+ previous_headers = camel_medium_dup_headers (CAMEL_MEDIUM (message));
+ camel_medium_remove_header (CAMEL_MEDIUM (message), "To");
+ camel_medium_remove_header (CAMEL_MEDIUM (message), "Cc");
+ camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");
nntp_stream = camel_nntp_store_ref_stream (nntp_store);
@@ -509,7 +491,16 @@ nntp_folder_append_message_sync (CamelFolder *folder,
g_object_unref (filtered_stream);
g_free (group);
- header->next = savedhdrs;
+ /* restore the bcc headers */
+ for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); ii++) {
+ if (!g_ascii_strcasecmp (header_name, "To") ||
+ !g_ascii_strcasecmp (header_name, "Cc") ||
+ !g_ascii_strcasecmp (header_name, "Bcc")) {
+ camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+ }
+ }
+
+ camel_name_value_array_free (previous_headers);
exit:
g_clear_object (&nntp_stream);
@@ -527,7 +518,7 @@ nntp_folder_expunge_sync (CamelFolder *folder,
GPtrArray *known_uids;
guint ii;
- summary = folder->summary;
+ summary = camel_folder_get_folder_summary (folder);
camel_folder_summary_prepare_fetch_all (summary, NULL);
known_uids = camel_folder_summary_get_array (summary);
@@ -549,10 +540,10 @@ nntp_folder_expunge_sync (CamelFolder *folder,
camel_folder_summary_remove (summary, info);
}
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
- camel_folder_summary_save_to_db (summary, NULL);
+ camel_folder_summary_save (summary, NULL);
camel_folder_changed (folder, changes);
camel_folder_change_info_free (changes);
@@ -695,7 +686,7 @@ nntp_folder_synchronize_sync (CamelFolder *folder,
return FALSE;
}
- summary = folder->summary;
+ summary = camel_folder_get_folder_summary (folder);
changed = camel_folder_summary_get_changed (summary);
if (changed != NULL) {
@@ -707,7 +698,7 @@ nntp_folder_synchronize_sync (CamelFolder *folder,
g_ptr_array_free (changed, TRUE);
}
- return camel_folder_summary_save_to_db (summary, error);
+ return camel_folder_summary_save (summary, error);
}
static gboolean
@@ -813,7 +804,7 @@ camel_nntp_folder_new (CamelStore *parent,
"parent-store", parent, NULL);
nntp_folder = (CamelNNTPFolder *) folder;
- folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) |
CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY);
storage_path = g_build_filename (user_cache_dir, folder_name, NULL);
root = g_strdup_printf ("%s.cmeta", storage_path);
@@ -822,12 +813,12 @@ camel_nntp_folder_new (CamelStore *parent,
g_free (root);
g_free (storage_path);
- folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (folder);
+ camel_folder_take_folder_summary (folder, (CamelFolderSummary *) camel_nntp_summary_new (folder));
if (filter_all || nntp_folder_get_apply_filters (nntp_folder))
- folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) | CAMEL_FOLDER_FILTER_RECENT);
- camel_folder_summary_load_from_db (folder->summary, NULL);
+ camel_folder_summary_load (camel_folder_get_folder_summary (folder), NULL);
nntp_store = CAMEL_NNTP_STORE (parent);
nntp_store_summary = camel_nntp_store_ref_summary (nntp_store);
@@ -843,7 +834,7 @@ camel_nntp_folder_new (CamelStore *parent,
camel_store_summary_connect_folder_summary (
CAMEL_STORE_SUMMARY (nntp_store_summary),
- folder_name, folder->summary);
+ folder_name, camel_folder_get_folder_summary (folder));
g_clear_object (&nntp_store_summary);
diff --git a/src/camel/providers/nntp/camel-nntp-folder.h b/src/camel/providers/nntp/camel-nntp-folder.h
index 7f8308d..b3ba625 100644
--- a/src/camel/providers/nntp/camel-nntp-folder.h
+++ b/src/camel/providers/nntp/camel-nntp-folder.h
@@ -58,6 +58,9 @@ struct _CamelNNTPFolder {
struct _CamelNNTPFolderClass {
CamelOfflineFolderClass parent;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_nntp_folder_get_type (void);
diff --git a/src/camel/providers/nntp/camel-nntp-settings.h b/src/camel/providers/nntp/camel-nntp-settings.h
index c934456..74b198e 100644
--- a/src/camel/providers/nntp/camel-nntp-settings.h
+++ b/src/camel/providers/nntp/camel-nntp-settings.h
@@ -52,6 +52,9 @@ struct _CamelNNTPSettings {
struct _CamelNNTPSettingsClass {
CamelOfflineSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_nntp_settings_get_type
diff --git a/src/camel/providers/nntp/camel-nntp-store-summary.h
b/src/camel/providers/nntp/camel-nntp-store-summary.h
index c7cd5a5..40abc42 100644
--- a/src/camel/providers/nntp/camel-nntp-store-summary.h
+++ b/src/camel/providers/nntp/camel-nntp-store-summary.h
@@ -76,6 +76,9 @@ struct _CamelNNTPStoreSummary {
struct _CamelNNTPStoreSummaryClass {
CamelStoreSummaryClass summary_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_nntp_store_summary_get_type
diff --git a/src/camel/providers/nntp/camel-nntp-store.c b/src/camel/providers/nntp/camel-nntp-store.c
index 100dd09..8d0586e 100644
--- a/src/camel/providers/nntp/camel-nntp-store.c
+++ b/src/camel/providers/nntp/camel-nntp-store.c
@@ -1140,7 +1140,8 @@ store_info_remove (gpointer key,
static gint
store_info_sort (gconstpointer a,
- gconstpointer b)
+ gconstpointer b,
+ gpointer user_data)
{
return strcmp ((*(CamelNNTPStoreInfo **) a)->full_name, (*(CamelNNTPStoreInfo **) b)->full_name);
}
@@ -1276,9 +1277,8 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
}
/* sort the list */
- g_ptr_array_sort (
- CAMEL_STORE_SUMMARY (nntp_store_summary)->folders,
- store_info_sort);
+ camel_store_summary_sort (CAMEL_STORE_SUMMARY (nntp_store_summary), store_info_sort, NULL);
+
if (ret < 0)
goto error;
@@ -1471,7 +1471,7 @@ nntp_store_initable_init (GInitable *initable,
store = CAMEL_STORE (initable);
service = CAMEL_SERVICE (initable);
- store->flags |= CAMEL_STORE_USE_CACHE_DIR;
+ camel_store_set_flags (store, camel_store_get_flags (store) | CAMEL_STORE_USE_CACHE_DIR);
nntp_migrate_to_user_cache_dir (service);
/* Chain up to parent interface's init() method. */
@@ -1783,7 +1783,7 @@ camel_nntp_store_init (CamelNNTPStore *nntp_store)
/* Clear the default flags. We don't want a virtual Junk or Trash
* folder and the user can't create/delete/rename newsgroup folders. */
- CAMEL_STORE (nntp_store)->flags = 0;
+ camel_store_set_flags (CAMEL_STORE (nntp_store), 0);
}
/**
diff --git a/src/camel/providers/nntp/camel-nntp-store.h b/src/camel/providers/nntp/camel-nntp-store.h
index 8050b96..69f1832 100644
--- a/src/camel/providers/nntp/camel-nntp-store.h
+++ b/src/camel/providers/nntp/camel-nntp-store.h
@@ -81,6 +81,9 @@ struct _CamelNNTPStore {
struct _CamelNNTPStoreClass {
CamelOfflineStoreClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_nntp_store_get_type (void);
diff --git a/src/camel/providers/nntp/camel-nntp-stream.h b/src/camel/providers/nntp/camel-nntp-stream.h
index a54ca16..cb33405 100644
--- a/src/camel/providers/nntp/camel-nntp-stream.h
+++ b/src/camel/providers/nntp/camel-nntp-stream.h
@@ -65,6 +65,9 @@ struct _CamelNNTPStream {
struct _CamelNNTPStreamClass {
CamelStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_nntp_stream_get_type (void);
diff --git a/src/camel/providers/nntp/camel-nntp-summary.c b/src/camel/providers/nntp/camel-nntp-summary.c
index d4c47aa..bae3279 100644
--- a/src/camel/providers/nntp/camel-nntp-summary.c
+++ b/src/camel/providers/nntp/camel-nntp-summary.c
@@ -51,9 +51,9 @@ struct _CamelNNTPSummaryPrivate {
gint xover_setup;
};
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
-static gboolean summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
-static CamelFIRecord * summary_header_to_db (CamelFolderSummary *s, GError **error);
+static CamelMessageInfo * message_info_new_from_headers (CamelFolderSummary *, const CamelNameValueArray *);
+static gboolean summary_header_load (CamelFolderSummary *s, CamelFIRecord *mir);
+static CamelFIRecord * summary_header_save (CamelFolderSummary *s, GError **error);
G_DEFINE_TYPE (CamelNNTPSummary, camel_nntp_summary, CAMEL_TYPE_FOLDER_SUMMARY)
@@ -65,11 +65,9 @@ camel_nntp_summary_class_init (CamelNNTPSummaryClass *class)
g_type_class_add_private (class, sizeof (CamelNNTPSummaryPrivate));
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
- folder_summary_class->message_info_size = sizeof (CamelMessageInfoBase);
- folder_summary_class->content_info_size = sizeof (CamelMessageContentInfo);
- folder_summary_class->message_info_new_from_header = message_info_new_from_header;
- folder_summary_class->summary_header_from_db = summary_header_from_db;
- folder_summary_class->summary_header_to_db = summary_header_to_db;
+ folder_summary_class->message_info_new_from_headers = message_info_new_from_headers;
+ folder_summary_class->summary_header_load = summary_header_load;
+ folder_summary_class->summary_header_save = summary_header_save;
}
static void
@@ -80,7 +78,7 @@ camel_nntp_summary_init (CamelNNTPSummary *nntp_summary)
nntp_summary->priv = CAMEL_NNTP_SUMMARY_GET_PRIVATE (nntp_summary);
/* and a unique file version */
- summary->version += CAMEL_NNTP_SUMMARY_VERSION;
+ camel_folder_summary_set_version (summary, camel_folder_summary_get_version (summary) +
CAMEL_NNTP_SUMMARY_VERSION);
}
CamelNNTPSummary *
@@ -90,60 +88,57 @@ camel_nntp_summary_new (CamelFolder *folder)
cns = g_object_new (CAMEL_TYPE_NNTP_SUMMARY, "folder", folder, NULL);
- camel_folder_summary_set_build_content ((CamelFolderSummary *) cns, FALSE);
-
return cns;
}
static CamelMessageInfo *
-message_info_new_from_header (CamelFolderSummary *s,
- struct _camel_header_raw *h)
+message_info_new_from_headers (CamelFolderSummary *summary,
+ const CamelNameValueArray *headers)
{
- CamelMessageInfoBase *mi;
- CamelNNTPSummary *cns = (CamelNNTPSummary *) s;
+ CamelMessageInfo *mi;
+ CamelNNTPSummary *cns = (CamelNNTPSummary *) summary;
/* error to call without this setup */
if (cns->priv->uid == NULL)
return NULL;
- mi = (CamelMessageInfoBase *) CAMEL_FOLDER_SUMMARY_CLASS
(camel_nntp_summary_parent_class)->message_info_new_from_header (s, h);
+ mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->message_info_new_from_headers
(summary, headers);
if (mi) {
- camel_pstring_free (mi->uid);
- mi->uid = camel_pstring_strdup (cns->priv->uid);
+ camel_message_info_set_uid (mi, cns->priv->uid);
g_free (cns->priv->uid);
cns->priv->uid = NULL;
}
- return (CamelMessageInfo *) mi;
+ return mi;
}
static gboolean
-summary_header_from_db (CamelFolderSummary *s,
- CamelFIRecord *mir)
+summary_header_load (CamelFolderSummary *s,
+ CamelFIRecord *mir)
{
CamelNNTPSummary *cns = CAMEL_NNTP_SUMMARY (s);
gchar *part;
- if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->summary_header_from_db (s, mir))
+ if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->summary_header_load (s, mir))
return FALSE;
part = mir->bdata;
- cns->version = bdata_extract_digit (&part);
- cns->high = bdata_extract_digit (&part);
- cns->low = bdata_extract_digit (&part);
+ cns->version = camel_util_bdata_get_number (&part, 0);
+ cns->high = camel_util_bdata_get_number (&part, 0);
+ cns->low = camel_util_bdata_get_number (&part, 0);
return TRUE;
}
static CamelFIRecord *
-summary_header_to_db (CamelFolderSummary *s,
- GError **error)
+summary_header_save (CamelFolderSummary *s,
+ GError **error)
{
CamelNNTPSummary *cns = CAMEL_NNTP_SUMMARY (s);
struct _CamelFIRecord *fir;
- fir = CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->summary_header_to_db (s, error);
+ fir = CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->summary_header_save (s, error);
if (!fir)
return NULL;
fir->bdata = g_strdup_printf ("%d %d %d", CAMEL_NNTP_SUMMARY_VERSION, cns->high, cns->low);
@@ -169,7 +164,7 @@ add_range_xover (CamelNNTPSummary *cns,
CamelSettings *settings;
CamelService *service;
CamelFolderSummary *s;
- struct _camel_header_raw *headers = NULL;
+ CamelNameValueArray *headers = NULL;
gchar *line, *tab;
gchar *host;
guint len;
@@ -180,7 +175,7 @@ add_range_xover (CamelNNTPSummary *cns,
s = (CamelFolderSummary *) cns;
folder_filter_recent = camel_folder_summary_get_folder (s) &&
- (camel_folder_summary_get_folder (s)->folder_flags & CAMEL_FOLDER_FILTER_RECENT) != 0;
+ (camel_folder_get_flags (camel_folder_summary_get_folder (s)) & CAMEL_FOLDER_FILTER_RECENT)
!= 0;
service = CAMEL_SERVICE (nntp_store);
@@ -222,6 +217,7 @@ add_range_xover (CamelNNTPSummary *cns,
count = 0;
total = high - low + 1;
+ headers = camel_name_value_array_new ();
while ((ret = camel_nntp_stream_line (nntp_stream, (guchar **) &line, &len, cancellable, error)) > 0)
{
camel_operation_progress (cancellable, (count * 100) / total);
count++;
@@ -243,7 +239,7 @@ add_range_xover (CamelNNTPSummary *cns,
if (xover->name) {
line += xover->skip;
if (line < tab) {
- camel_header_raw_append (&headers, xover->name, line, -1);
+ camel_name_value_array_append (headers, xover->name, line);
switch (xover->type) {
case XOVER_STRING:
break;
@@ -267,14 +263,15 @@ add_range_xover (CamelNNTPSummary *cns,
if (!camel_folder_summary_check_uid (s, cns->priv->uid)) {
CamelMessageInfo *mi;
- mi = camel_folder_summary_info_new_from_header (s, headers);
- ((CamelMessageInfoBase *) mi)->size = size;
- camel_folder_summary_add (s, mi);
+ mi = camel_folder_summary_info_new_from_headers (s, headers);
+ camel_message_info_set_size (mi, size);
+ camel_folder_summary_add (s, mi, FALSE);
cns->high = n;
camel_folder_change_info_add_uid (changes, camel_message_info_get_uid (mi));
if (folder_filter_recent)
camel_folder_change_info_recent_uid (changes,
camel_message_info_get_uid (mi));
+ g_clear_object (&mi);
}
}
@@ -283,9 +280,10 @@ add_range_xover (CamelNNTPSummary *cns,
cns->priv->uid = NULL;
}
- camel_header_raw_clear (&headers);
+ camel_name_value_array_clear (headers);
}
+ camel_name_value_array_free (headers);
g_clear_object (&nntp_stream);
camel_operation_pop_message (cancellable);
@@ -318,7 +316,7 @@ add_range_head (CamelNNTPSummary *cns,
s = (CamelFolderSummary *) cns;
folder_filter_recent = camel_folder_summary_get_folder (s) &&
- (camel_folder_summary_get_folder (s)->folder_flags & CAMEL_FOLDER_FILTER_RECENT) != 0;
+ (camel_folder_get_flags (camel_folder_summary_get_folder (s)) & CAMEL_FOLDER_FILTER_RECENT)
!= 0;
mp = camel_mime_parser_new ();
@@ -370,7 +368,7 @@ add_range_head (CamelNNTPSummary *cns,
if (camel_mime_parser_init_with_stream (mp, CAMEL_STREAM (nntp_stream),
error) == -1)
goto error;
mi = camel_folder_summary_info_new_from_parser (s, mp);
- camel_folder_summary_add (s, mi);
+ camel_folder_summary_add (s, mi, FALSE);
while (camel_mime_parser_step (mp, NULL, NULL) != CAMEL_MIME_PARSER_STATE_EOF)
;
if (mi == NULL) {
@@ -380,6 +378,7 @@ add_range_head (CamelNNTPSummary *cns,
camel_folder_change_info_add_uid (changes, camel_message_info_get_uid (mi));
if (folder_filter_recent)
camel_folder_change_info_recent_uid (changes,
camel_message_info_get_uid (mi));
+ g_clear_object (&mi);
}
if (cns->priv->uid) {
g_free (cns->priv->uid);
@@ -504,7 +503,7 @@ camel_nntp_summary_check (CamelNNTPSummary *cns,
mi = camel_folder_summary_peek_loaded (s, uid);
if (mi) {
camel_folder_summary_remove (s, mi);
- camel_message_info_unref (mi);
+ g_clear_object (&mi);
} else {
camel_folder_summary_remove_uid (s, uid);
}
@@ -517,7 +516,7 @@ camel_nntp_summary_check (CamelNNTPSummary *cns,
g_clear_object (&nntp_cache);
}
- camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
+ camel_db_delete_uids (camel_store_get_db (parent_store), full_name, del, NULL);
g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
g_list_free (del);
@@ -537,7 +536,7 @@ camel_nntp_summary_check (CamelNNTPSummary *cns,
/* TODO: not from here */
camel_folder_summary_touch (s);
- camel_folder_summary_save_to_db (s, NULL);
+ camel_folder_summary_save (s, NULL);
update:
/* update store summary if we have it */
@@ -554,8 +553,7 @@ update:
guint32 unread = 0;
count = camel_folder_summary_count (s);
- camel_db_count_unread_message_info (
- parent_store->cdb_r, full_name, &unread, NULL);
+ camel_db_count_unread_message_info (camel_store_get_db (parent_store), full_name, &unread,
NULL);
if (si->info.unread != unread
|| si->info.total != count
diff --git a/src/camel/providers/nntp/camel-nntp-summary.h b/src/camel/providers/nntp/camel-nntp-summary.h
index 941721a..f8a2c36 100644
--- a/src/camel/providers/nntp/camel-nntp-summary.h
+++ b/src/camel/providers/nntp/camel-nntp-summary.h
@@ -59,6 +59,9 @@ struct _CamelNNTPSummary {
struct _CamelNNTPSummaryClass {
CamelFolderSummaryClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_nntp_summary_get_type (void);
diff --git a/src/camel/providers/pop3/camel-pop3-engine.h b/src/camel/providers/pop3/camel-pop3-engine.h
index c71a464..768fd6f 100644
--- a/src/camel/providers/pop3/camel-pop3-engine.h
+++ b/src/camel/providers/pop3/camel-pop3-engine.h
@@ -139,6 +139,9 @@ struct _CamelPOP3Engine {
struct _CamelPOP3EngineClass {
GObjectClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_pop3_engine_get_type (void);
diff --git a/src/camel/providers/pop3/camel-pop3-folder.c b/src/camel/providers/pop3/camel-pop3-folder.c
index bb7042e..2beb51e 100644
--- a/src/camel/providers/pop3/camel-pop3-folder.c
+++ b/src/camel/providers/pop3/camel-pop3-folder.c
@@ -90,10 +90,12 @@ cmd_builduid (CamelPOP3Engine *pe,
{
GChecksum *checksum;
CamelPOP3FolderInfo *fi = data;
- struct _camel_header_raw *h;
+ CamelNameValueArray *h;
CamelMimeParser *mp;
guint8 *digest;
gsize length;
+ guint ii;
+ const gchar *header_name = NULL, *header_value = NULL;
length = g_checksum_type_get_length (G_CHECKSUM_MD5);
digest = g_alloca (length);
@@ -109,15 +111,16 @@ cmd_builduid (CamelPOP3Engine *pe,
case CAMEL_MIME_PARSER_STATE_HEADER:
case CAMEL_MIME_PARSER_STATE_MESSAGE:
case CAMEL_MIME_PARSER_STATE_MULTIPART:
- h = camel_mime_parser_headers_raw (mp);
- while (h) {
- if (g_ascii_strcasecmp (h->name, "status") != 0
- && g_ascii_strcasecmp (h->name, "x-status") != 0) {
- g_checksum_update (checksum, (guchar *) h->name, -1);
- g_checksum_update (checksum, (guchar *) h->value, -1);
+ h = camel_mime_parser_dup_headers (mp);
+ for (ii = 0; camel_name_value_array_get (h, ii, &header_name, &header_value); ii++) {
+ if (g_ascii_strcasecmp (header_name, "status") != 0
+ && g_ascii_strcasecmp (header_name, "x-status") != 0) {
+ g_checksum_update (checksum, (guchar *) header_name, -1);
+ g_checksum_update (checksum, (guchar *) header_value, -1);
}
- h = h->next;
}
+
+ camel_name_value_array_free (h);
default:
break;
}
@@ -372,8 +375,8 @@ pop3_folder_get_filename (CamelFolder *folder,
static gboolean
pop3_folder_set_message_flags (CamelFolder *folder,
const gchar *uid,
- CamelMessageFlags flags,
- CamelMessageFlags set)
+ guint32 flags,
+ guint32 set)
{
CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
CamelPOP3FolderInfo *fi;
@@ -1005,8 +1008,10 @@ pop3_get_message_time_from_cache (CamelFolder *folder,
}
if (message) {
+ gint date_offset = 0;
+
res = TRUE;
- *message_time = message->date + message->date_offset;
+ *message_time = camel_mime_message_get_date (message, &date_offset) + date_offset;
g_object_unref (message);
}
@@ -1092,7 +1097,8 @@ camel_pop3_folder_delete_old (CamelFolder *folder,
message = pop3_folder_get_message_internal_sync (
folder, fi->uid, TRUE, cancellable, error);
if (message) {
- message_time = message->date + message->date_offset;
+ gint date_offset = 0;
+ message_time = camel_mime_message_get_date (message, &date_offset) +
date_offset;
g_object_unref (message);
}
}
diff --git a/src/camel/providers/pop3/camel-pop3-folder.h b/src/camel/providers/pop3/camel-pop3-folder.h
index 2cd2ab1..67a25d1 100644
--- a/src/camel/providers/pop3/camel-pop3-folder.h
+++ b/src/camel/providers/pop3/camel-pop3-folder.h
@@ -69,6 +69,9 @@ struct _CamelPOP3Folder {
struct _CamelPOP3FolderClass {
CamelFolderClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_pop3_folder_get_type (void);
diff --git a/src/camel/providers/pop3/camel-pop3-settings.h b/src/camel/providers/pop3/camel-pop3-settings.h
index 2f5d2f3..d69b71b 100644
--- a/src/camel/providers/pop3/camel-pop3-settings.h
+++ b/src/camel/providers/pop3/camel-pop3-settings.h
@@ -52,6 +52,9 @@ struct _CamelPOP3Settings {
struct _CamelPOP3SettingsClass {
CamelStoreSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_pop3_settings_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/providers/pop3/camel-pop3-store.h b/src/camel/providers/pop3/camel-pop3-store.h
index 58432d6..63e559e 100644
--- a/src/camel/providers/pop3/camel-pop3-store.h
+++ b/src/camel/providers/pop3/camel-pop3-store.h
@@ -58,6 +58,9 @@ struct _CamelPOP3Store {
struct _CamelPOP3StoreClass {
CamelStoreClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_pop3_store_get_type (void);
diff --git a/src/camel/providers/pop3/camel-pop3-stream.h b/src/camel/providers/pop3/camel-pop3-stream.h
index 2c4a51a..bb6dbb9 100644
--- a/src/camel/providers/pop3/camel-pop3-stream.h
+++ b/src/camel/providers/pop3/camel-pop3-stream.h
@@ -68,6 +68,9 @@ struct _CamelPOP3Stream {
struct _CamelPOP3StreamClass {
CamelStreamClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_pop3_stream_get_type (void);
diff --git a/src/camel/providers/sendmail/camel-sendmail-provider.c
b/src/camel/providers/sendmail/camel-sendmail-provider.c
index 7a8124a..a79afc7 100644
--- a/src/camel/providers/sendmail/camel-sendmail-provider.c
+++ b/src/camel/providers/sendmail/camel-sendmail-provider.c
@@ -52,8 +52,8 @@ camel_provider_module_init (void)
sendmail_provider.object_types[CAMEL_PROVIDER_TRANSPORT] =
CAMEL_TYPE_SENDMAIL_TRANSPORT;
- sendmail_provider.url_hash = camel_url_hash;
- sendmail_provider.url_equal = camel_url_equal;
+ sendmail_provider.url_hash = (GHashFunc) camel_url_hash;
+ sendmail_provider.url_equal = (GEqualFunc) camel_url_equal;
sendmail_provider.translation_domain = GETTEXT_PACKAGE;
camel_provider_register (&sendmail_provider);
diff --git a/src/camel/providers/sendmail/camel-sendmail-settings.h
b/src/camel/providers/sendmail/camel-sendmail-settings.h
index 5c3d152..4afa013 100644
--- a/src/camel/providers/sendmail/camel-sendmail-settings.h
+++ b/src/camel/providers/sendmail/camel-sendmail-settings.h
@@ -52,6 +52,9 @@ struct _CamelSendmailSettings {
struct _CamelSendmailSettingsClass {
CamelSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sendmail_settings_get_type
diff --git a/src/camel/providers/sendmail/camel-sendmail-transport.c
b/src/camel/providers/sendmail/camel-sendmail-transport.c
index 7767945..ca1edf6 100644
--- a/src/camel/providers/sendmail/camel-sendmail-transport.c
+++ b/src/camel/providers/sendmail/camel-sendmail-transport.c
@@ -112,7 +112,8 @@ sendmail_send_to_sync (CamelTransport *transport,
GCancellable *cancellable,
GError **error)
{
- struct _camel_header_raw *header, *savedbcc, *n, *tail;
+ CamelNameValueArray *previous_headers = NULL;
+ const gchar *header_name = NULL, *header_value = NULL;
const gchar *from_addr, *addr;
GPtrArray *argv_arr;
gint i, len, fd[2], nullfd, wstat;
@@ -125,6 +126,7 @@ sendmail_send_to_sync (CamelTransport *transport,
gchar *custom_binary = NULL, *custom_args = NULL;
gboolean success;
pid_t pid;
+ guint ii;
success = camel_internet_address_get (
CAMEL_INTERNET_ADDRESS (from), 0, NULL, &from_addr);
@@ -203,23 +205,8 @@ sendmail_send_to_sync (CamelTransport *transport,
}
/* unlink the bcc headers */
- savedbcc = NULL;
- tail = (struct _camel_header_raw *) &savedbcc;
-
- header = (struct _camel_header_raw *) &CAMEL_MIME_PART (message)->headers;
- n = header->next;
- while (n != NULL) {
- if (!g_ascii_strcasecmp (n->name, "Bcc")) {
- header->next = n->next;
- tail->next = n;
- n->next = NULL;
- tail = n;
- } else {
- header = n;
- }
-
- n = header->next;
- }
+ previous_headers = camel_medium_dup_headers (CAMEL_MEDIUM (message));
+ camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");
if (pipe (fd) == -1) {
g_set_error (
@@ -229,7 +216,13 @@ sendmail_send_to_sync (CamelTransport *transport,
"mail not sent"), binary, g_strerror (errno));
/* restore the bcc headers */
- header->next = savedbcc;
+ for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value);
ii++) {
+ if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+ camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+ }
+ }
+
+ camel_name_value_array_free (previous_headers);
g_free (custom_binary);
g_free (custom_args);
g_ptr_array_free (argv_arr, TRUE);
@@ -257,7 +250,13 @@ sendmail_send_to_sync (CamelTransport *transport,
sigprocmask (SIG_SETMASK, &omask, NULL);
/* restore the bcc headers */
- header->next = savedbcc;
+ for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value);
ii++) {
+ if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+ camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+ }
+ }
+
+ camel_name_value_array_free (previous_headers);
g_free (custom_binary);
g_free (custom_args);
g_ptr_array_free (argv_arr, TRUE);
@@ -308,7 +307,13 @@ sendmail_send_to_sync (CamelTransport *transport,
sigprocmask (SIG_SETMASK, &omask, NULL);
/* restore the bcc headers */
- header->next = savedbcc;
+ for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value);
ii++) {
+ if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+ camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+ }
+ }
+
+ camel_name_value_array_free (previous_headers);
g_free (custom_binary);
g_free (custom_args);
@@ -324,7 +329,13 @@ sendmail_send_to_sync (CamelTransport *transport,
sigprocmask (SIG_SETMASK, &omask, NULL);
/* restore the bcc headers */
- header->next = savedbcc;
+ for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); ii++) {
+ if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+ camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+ }
+ }
+
+ camel_name_value_array_free (previous_headers);
if (!WIFEXITED (wstat)) {
g_set_error (
diff --git a/src/camel/providers/sendmail/camel-sendmail-transport.h
b/src/camel/providers/sendmail/camel-sendmail-transport.h
index 77171cb..cb548ed 100644
--- a/src/camel/providers/sendmail/camel-sendmail-transport.h
+++ b/src/camel/providers/sendmail/camel-sendmail-transport.h
@@ -53,6 +53,9 @@ struct _CamelSendmailTransport {
struct _CamelSendmailTransportClass {
CamelTransportClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_sendmail_transport_get_type (void);
diff --git a/src/camel/providers/smtp/camel-smtp-settings.h b/src/camel/providers/smtp/camel-smtp-settings.h
index b37739a..e2dd454 100644
--- a/src/camel/providers/smtp/camel-smtp-settings.h
+++ b/src/camel/providers/smtp/camel-smtp-settings.h
@@ -52,6 +52,9 @@ struct _CamelSmtpSettings {
struct _CamelSmtpSettingsClass {
CamelSettingsClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_smtp_settings_get_type (void) G_GNUC_CONST;
diff --git a/src/camel/providers/smtp/camel-smtp-transport.c b/src/camel/providers/smtp/camel-smtp-transport.c
index 44e96bf..dc39930 100644
--- a/src/camel/providers/smtp/camel-smtp-transport.c
+++ b/src/camel/providers/smtp/camel-smtp-transport.c
@@ -1639,13 +1639,15 @@ smtp_data (CamelSmtpTransport *transport,
GCancellable *cancellable,
GError **error)
{
- struct _camel_header_raw *header, *savedbcc, *n, *tail;
+ CamelNameValueArray *previous_headers;
+ const gchar *header_name = NULL, *header_value = NULL;
CamelBestencEncoding enctype = CAMEL_BESTENC_8BIT;
CamelStream *filtered_stream;
gchar *cmdbuf, *respbuf = NULL;
CamelMimeFilter *filter;
- CamelStreamNull *null;
+ gsize bytes_written;
gint ret;
+ guint ii;
/* If the server doesn't support 8BITMIME, set our required encoding to be 7bit */
if (!(transport->flags & CAMEL_SMTP_TRANSPORT_8BITMIME))
@@ -1694,42 +1696,23 @@ smtp_data (CamelSmtpTransport *transport,
g_free (respbuf);
respbuf = NULL;
- /* unlink the bcc headers */
- savedbcc = NULL;
- tail = (struct _camel_header_raw *) &savedbcc;
-
- header = (struct _camel_header_raw *) &CAMEL_MIME_PART (message)->headers;
- n = header->next;
- while (n != NULL) {
- if (!g_ascii_strcasecmp (n->name, "Bcc")) {
- header->next = n->next;
- tail->next = n;
- n->next = NULL;
- tail = n;
- } else {
- header = n;
- }
-
- n = header->next;
- }
+ /* unlink the bcc headers and keep a copy of them */
+ previous_headers = camel_medium_dup_headers (CAMEL_MEDIUM (message));
+ camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");
/* find out how large the message is... */
- null = CAMEL_STREAM_NULL (camel_stream_null_new ());
- camel_data_wrapper_write_to_stream_sync (
- CAMEL_DATA_WRAPPER (message),
- CAMEL_STREAM (null), NULL, NULL);
+ bytes_written = camel_data_wrapper_calculate_size_sync (CAMEL_DATA_WRAPPER (message), NULL, NULL);
/* Set the upload timeout to an equal of 512 bytes per second */
- smtp_maybe_update_socket_timeout (ostream, null->written / 512);
+ smtp_maybe_update_socket_timeout (ostream, bytes_written / 512);
filtered_stream = camel_stream_filter_new (ostream);
/* setup progress reporting for message sending... */
- filter = camel_mime_filter_progress_new (cancellable, null->written);
+ filter = camel_mime_filter_progress_new (cancellable, bytes_written);
camel_stream_filter_add (
CAMEL_STREAM_FILTER (filtered_stream), filter);
g_object_unref (filter);
- g_object_unref (null);
/* setup LF->CRLF conversion */
filter = camel_mime_filter_crlf_new (
@@ -1745,7 +1728,13 @@ smtp_data (CamelSmtpTransport *transport,
filtered_stream, cancellable, error);
/* restore the bcc headers */
- header->next = savedbcc;
+ for (ii = 0; camel_name_value_array_get (previous_headers, ii, &header_name, &header_value); ii++) {
+ if (!g_ascii_strcasecmp (header_name, "Bcc")) {
+ camel_medium_add_header (CAMEL_MEDIUM (message), header_name, header_value);
+ }
+ }
+
+ camel_name_value_array_free (previous_headers);
if (ret == -1) {
g_prefix_error (error, _("DATA command failed: "));
diff --git a/src/camel/providers/smtp/camel-smtp-transport.h b/src/camel/providers/smtp/camel-smtp-transport.h
index c5a20de..f513639 100644
--- a/src/camel/providers/smtp/camel-smtp-transport.h
+++ b/src/camel/providers/smtp/camel-smtp-transport.h
@@ -65,6 +65,9 @@ struct _CamelSmtpTransport {
struct _CamelSmtpTransportClass {
CamelTransportClass parent_class;
+
+ /* Padding for future expansion */
+ gpointer reserved[20];
};
GType camel_smtp_transport_get_type (void);
diff --git a/src/camel/tests/CMakeLists.txt b/src/camel/tests/CMakeLists.txt
index c1b1063..e12ab64 100644
--- a/src/camel/tests/CMakeLists.txt
+++ b/src/camel/tests/CMakeLists.txt
@@ -1,7 +1,8 @@
macro(add_camel_test_one _part _name _src_file)
set(_test_ident cameltest-${_part}-${_name})
- add_executable(${_test_ident} EXCLUDE_FROM_ALL ${_src_file})
+ # Not using EXCLUDE_FROM_ALL here, to have these built always
+ add_executable(${_test_ident} ${_src_file})
target_compile_definitions(${_test_ident} PRIVATE
-DG_LOG_DOMAIN=\"${_test_ident}\"
diff --git a/src/camel/tests/folder/test10.c b/src/camel/tests/folder/test10.c
index 5331df9..4d23126 100644
--- a/src/camel/tests/folder/test10.c
+++ b/src/camel/tests/folder/test10.c
@@ -101,7 +101,8 @@ main (gint argc,
for (i = 0; i < MAX_THREADS; i++) {
GError *error = NULL;
- threads[i] = g_thread_new (NULL, worker, NULL);
+ threads[i] = g_thread_try_new (NULL, worker, NULL, &error);
+ check_msg (error == NULL, "g_thread_try_new() failed: %s", error->message);
}
for (i = 0; i < MAX_THREADS; i++) {
diff --git a/src/camel/tests/folder/test11.c b/src/camel/tests/folder/test11.c
index 3727720..6fd7c6f 100644
--- a/src/camel/tests/folder/test11.c
+++ b/src/camel/tests/folder/test11.c
@@ -22,6 +22,7 @@
#define MAX_LOOP (10000)
#define MAX_THREADS (5)
+#define GC(x) ((gchar *) (x))
static const gchar *local_drivers[] = { "local" };
@@ -30,25 +31,25 @@ static CamelSession *session;
/* FIXME: flags aren't really right yet */
/* ASCII sorted on full_name */
static CamelFolderInfo fi_list_1[] = {
- { NULL, NULL, NULL, ".", "Inbox", CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOCHILDREN, -1, -1 },
- { NULL, NULL, NULL, ".#evolution/Junk", "Junk", CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOCHILDREN, -1, -1
},
- { NULL, NULL, NULL, ".#evolution/Trash", "Trash", CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOCHILDREN, -1,
-1 },
- { NULL, NULL, NULL, "testbox", "testbox", CAMEL_FOLDER_CHILDREN, -1, -1 },
- { NULL, NULL, NULL, "testbox/foo", "foo", CAMEL_FOLDER_NOCHILDREN, -1, -1 },
- { NULL, NULL, NULL, "testbox2", "testbox2", CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("."), GC ("Inbox"), CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC (".#evolution/Junk"), GC ("Junk"), CAMEL_FOLDER_SYSTEM |
CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC (".#evolution/Trash"), GC ("Trash"), CAMEL_FOLDER_SYSTEM |
CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("testbox"), GC ("testbox"), CAMEL_FOLDER_CHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("testbox/foo"), GC ("foo"), CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("testbox2"), GC ("testbox2"), CAMEL_FOLDER_NOCHILDREN, -1, -1 },
};
static CamelFolderInfo fi_list_2[] = {
- { NULL, NULL, NULL, ".", "Inbox", CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOCHILDREN, -1, -1 },
- { NULL, NULL, NULL, ".#evolution/Junk", "Junk", CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOCHILDREN, -1, -1
},
- { NULL, NULL, NULL, ".#evolution/Trash", "Trash", CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOCHILDREN, -1,
-1 },
- { NULL, NULL, NULL, "testbox", "testbox", CAMEL_FOLDER_NOCHILDREN, -1, -1 },
- { NULL, NULL, NULL, "testbox2", "testbox2", CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("."), GC ("Inbox"), CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC (".#evolution/Junk"), GC ("Junk"), CAMEL_FOLDER_SYSTEM |
CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC (".#evolution/Trash"), GC ("Trash"), CAMEL_FOLDER_SYSTEM |
CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("testbox"), GC ("testbox"), CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("testbox2"), GC ("testbox2"), CAMEL_FOLDER_NOCHILDREN, -1, -1 },
};
static CamelFolderInfo fi_list_3[] = {
- { NULL, NULL, NULL, "testbox", "testbox", CAMEL_FOLDER_CHILDREN, -1, -1 },
- { NULL, NULL, NULL, "testbox/foo", "foo", CAMEL_FOLDER_NOCHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("testbox"), GC ("testbox"), CAMEL_FOLDER_CHILDREN, -1, -1 },
+ { NULL, NULL, NULL, GC ("testbox/foo"), GC ("foo"), CAMEL_FOLDER_NOCHILDREN, -1, -1 },
};
static gint
diff --git a/src/camel/tests/folder/test2.c b/src/camel/tests/folder/test2.c
index 85b66ff..b43bb0e 100644
--- a/src/camel/tests/folder/test2.c
+++ b/src/camel/tests/folder/test2.c
@@ -47,7 +47,7 @@ gint main (gint argc, gchar **argv)
/* we iterate over all stores we want to test, with indexing or indexing turned on or off */
for (i = 0; i < G_N_ELEMENTS (stores); i++) {
- gchar *name = stores[i];
+ const gchar *name = stores[i];
test_folder_message_ops (session, name, TRUE, "testbox");
}
diff --git a/src/camel/tests/folder/test8.c b/src/camel/tests/folder/test8.c
index 1a56706..1c5ee94 100644
--- a/src/camel/tests/folder/test8.c
+++ b/src/camel/tests/folder/test8.c
@@ -193,7 +193,8 @@ gint main (gint argc, gchar **argv)
info->id = i * MAX_MESSAGES;
info->folder = folder;
- threads[i] = g_thread_new (NULL, worker, info);
+ threads[i] = g_thread_try_new (NULL, worker, info, &error);
+ check_msg (error == NULL, "g_thread_try_new() failed: %s", error->message);
}
for (i = 0; i < MAX_THREADS; i++) {
diff --git a/src/camel/tests/lib/folders.c b/src/camel/tests/lib/folders.c
index 4db8c89..a2edadb 100644
--- a/src/camel/tests/lib/folders.c
+++ b/src/camel/tests/lib/folders.c
@@ -52,7 +52,7 @@ test_folder_counts (CamelFolder *folder,
info = camel_folder_get_message_info (folder, s->pdata[i]);
if (camel_message_info_get_flags (info) & CAMEL_MESSAGE_SEEN)
myunread--;
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
check (unread == myunread);
camel_folder_free_uids (folder, s);
@@ -109,7 +109,7 @@ test_folder_message (CamelFolder *folder,
info = camel_folder_get_message_info (folder, uid);
check (info != NULL);
check (strcmp (camel_message_info_get_uid (info), uid) == 0);
- camel_message_info_unref (info);
+ g_clear_object (&info);
/* then, getting message */
msg = camel_folder_get_message_sync (folder, uid, NULL, &error);
@@ -462,7 +462,7 @@ test_folder_message_ops (CamelSession *session,
check_msg (
strcmp (camel_message_info_get_subject (info), subject) == 0,
"info->subject %s", camel_message_info_get_subject (info));
- camel_message_info_unref (info);
+ g_clear_object (&info);
}
camel_folder_free_uids (folder, uids);
pull ();
@@ -515,7 +515,7 @@ test_folder_message_ops (CamelSession *session,
strcmp (camel_message_info_get_subject (info), subject) == 0,
"info->subject %s", camel_message_info_get_subject (info));
test_free (subject);
- camel_message_info_unref (info);
+ g_clear_object (&info);
pull ();
}
@@ -544,7 +544,7 @@ test_folder_message_ops (CamelSession *session,
strcmp (camel_message_info_get_subject (info), subject) == 0,
"info->subject %s", camel_message_info_get_subject (info));
test_free (subject);
- camel_message_info_unref (info);
+ g_clear_object (&info);
pull ();
}
pull ();
@@ -575,7 +575,7 @@ test_folder_message_ops (CamelSession *session,
strcmp (camel_message_info_get_subject (info), subject) == 0,
"info->subject %s", camel_message_info_get_subject (info));
test_free (subject);
- camel_message_info_unref (info);
+ g_clear_object (&info);
pull ();
}
pull ();
diff --git a/src/camel/tests/lib/messages.c b/src/camel/tests/lib/messages.c
index dbe674b..ea7b0a0 100644
--- a/src/camel/tests/lib/messages.c
+++ b/src/camel/tests/lib/messages.c
@@ -238,8 +238,6 @@ test_message_compare (CamelMimeMessage *msg)
g_seekable_seek (G_SEEKABLE (stream2), 0, G_SEEK_SET, NULL, NULL);
if (byte_array1->len != byte_array2->len) {
- CamelDataWrapper *content;
-
printf ("stream1 stream:\n%.*s\n", byte_array1->len, byte_array1->data);
printf ("stream2 stream:\n%.*s\n\n", byte_array2->len, byte_array2->data);
@@ -247,8 +245,6 @@ test_message_compare (CamelMimeMessage *msg)
test_message_dump_structure (msg);
printf ("msg2:\n");
test_message_dump_structure (msg2);
-
- content = camel_medium_get_content ((CamelMedium *) msg);
}
check_unref (msg2, 1);
@@ -298,7 +294,7 @@ message_dump_rec (CamelMimeMessage *msg,
printf ("%sPart <%s>\n", s, G_OBJECT_TYPE_NAME (part));
printf ("%sContent-Type: %s\n", s, mime_type);
g_free (mime_type);
- printf ("%s encoding: %s\n", s, camel_transfer_encoding_to_string (((CamelDataWrapper *)
part)->encoding));
+ printf ("%s encoding: %s\n", s, camel_transfer_encoding_to_string (camel_data_wrapper_get_encoding
((CamelDataWrapper *) part)));
printf ("%s part encoding: %s\n", s, camel_transfer_encoding_to_string (camel_mime_part_get_encoding
(part)));
containee = camel_medium_get_content (CAMEL_MEDIUM (part));
@@ -310,7 +306,7 @@ message_dump_rec (CamelMimeMessage *msg,
printf ("%sContent <%s>\n", s, G_OBJECT_TYPE_NAME (containee));
printf ("%sContent-Type: %s\n", s, mime_type);
g_free (mime_type);
- printf ("%s encoding: %s\n", s, camel_transfer_encoding_to_string (((CamelDataWrapper *)
containee)->encoding));
+ printf ("%s encoding: %s\n", s, camel_transfer_encoding_to_string (camel_data_wrapper_get_encoding
((CamelDataWrapper *) containee)));
/* using the object types is more accurate than using the mime/types */
if (CAMEL_IS_MULTIPART (containee)) {
diff --git a/src/camel/tests/message/test2.c b/src/camel/tests/message/test2.c
index ada3c1d..f00e23a 100644
--- a/src/camel/tests/message/test2.c
+++ b/src/camel/tests/message/test2.c
@@ -41,13 +41,13 @@ static gchar *convert (const gchar *in, const gchar *from, const gchar *to)
outp = out = g_malloc (outlen);
inp = in;
- if (iconv (ic, &inp, &inlen, &outp, &outlen) == -1) {
+ if (camel_iconv (ic, &inp, &inlen, &outp, &outlen) == -1) {
test_free (out);
g_iconv_close (ic);
return g_strdup (in);
}
- if (iconv (ic, NULL, 0, &outp, &outlen) == -1) {
+ if (camel_iconv (ic, NULL, 0, &outp, &outlen) == -1) {
test_free (out);
g_iconv_close (ic);
return g_strdup (in);
diff --git a/src/camel/tests/mime-filter/test-charset.c b/src/camel/tests/mime-filter/test-charset.c
index c490396..c68e688 100644
--- a/src/camel/tests/mime-filter/test-charset.c
+++ b/src/camel/tests/mime-filter/test-charset.c
@@ -80,8 +80,7 @@ test_case (const gchar *basename)
}
g_free (filename);
- filename = g_strdup_printf (
- "%s/%.*s.out", SOURCEDIR, ext - basename, basename);
+ filename = g_strdup_printf ("%s/%.*s.out", SOURCEDIR, (gint) (ext - basename), basename);
file = g_file_new_for_path (filename);
correct_stream = g_file_read (file, NULL, &local_error);
diff --git a/src/camel/tests/misc/split.c b/src/camel/tests/misc/split.c
index eac9548..9f7f418 100644
--- a/src/camel/tests/misc/split.c
+++ b/src/camel/tests/misc/split.c
@@ -78,7 +78,7 @@ main (gint argc,
for (i = 0; i < G_N_ELEMENTS (split_tests); i++) {
camel_test_push ("split %d '%s'", i, split_tests[i].word);
- words = camel_search_words_split (split_tests[i].word);
+ words = camel_search_words_split ((const guchar *) split_tests[i].word);
check (words != NULL);
check_msg (words->len == split_tests[i].count, "words->len = %d, count = %d", words->len,
split_tests[i].count);
@@ -100,7 +100,7 @@ main (gint argc,
for (i = 0; i < G_N_ELEMENTS (simple_tests); i++) {
camel_test_push ("simple split %d '%s'", i, simple_tests[i].word);
- tmp = camel_search_words_split (simple_tests[i].word);
+ tmp = camel_search_words_split ((const guchar *) simple_tests[i].word);
check (tmp != NULL);
words = camel_search_words_simple (tmp);
diff --git a/src/camel/tests/misc/utf7.c b/src/camel/tests/misc/utf7.c
index b79cf10..567de2f 100644
--- a/src/camel/tests/misc/utf7.c
+++ b/src/camel/tests/misc/utf7.c
@@ -103,7 +103,7 @@ main (gint argc,
do {
u = tests[i].unicode[j++];
camel_utf8_putc ((guchar **) &p, u);
- g_string_append_u (out, u);
+ g_string_append_unichar (out, u);
} while (u);
check (strcmp (utf8enc, out->str) == 0);
diff --git a/src/camel/tests/smime/pgp.c b/src/camel/tests/smime/pgp.c
index 05f7771..139aa3c 100644
--- a/src/camel/tests/smime/pgp.c
+++ b/src/camel/tests/smime/pgp.c
@@ -49,7 +49,6 @@ G_DEFINE_TYPE (CamelPgpSession, camel_pgp_session, camel_test_session_get_type (
static gchar *
pgp_session_get_password (CamelSession *session,
CamelService *service,
- const gchar *domain,
const gchar *prompt,
const gchar *item,
guint32 flags,
diff --git a/src/vala/Camel-1.2.metadata b/src/vala/Camel-1.2.metadata
index eb66385..74aded7 100644
--- a/src/vala/Camel-1.2.metadata
+++ b/src/vala/Camel-1.2.metadata
@@ -6,7 +6,9 @@ FilterDriver.set* skip=false
// We need to skip the methods because the signals and virtual methods have the same name
Object.state_read#method skip
+Object.state_read.fp type="GLib.FileStream"
Object.state_write#method skip
+Object.state_write.fp type="GLib.FileStream"
Operation.pop_message skip
Operation.progress skip
@@ -23,3 +25,13 @@ localtime_with_offset.tm type="Posix.tm"
mktime_utc.tm type="Posix.tm"
HeaderAddress.new_name#constructor name="with_name"
+
+// FILE* are supported by Vala
+StoreSummary.store_info_save.file type="GLib.FileStream"
+StoreSummary.summary_header_load.file type="GLib.FileStream"
+StoreSummary.summary_header_save.file type="GLib.FileStream"
+CertDB.cert_load.istream type="GLib.FileStream"
+CertDB.cert_save.ostream type="GLib.FileStream"
+CertDB.header_load.istream type="GLib.FileStream"
+CertDB.header_save.ostream type="GLib.FileStream"
+FilterDriver.set_logfile.logfile type="GLib.FileStream"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]