aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap/camel-imap-utils.c
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2001-05-01 22:51:36 +0800
committerDan Winship <danw@src.gnome.org>2001-05-01 22:51:36 +0800
commiteb7438182ab5fd969aac96795f67034e21937e35 (patch)
treeaa136f16d6be288b7623cb66a16d260944e61557 /camel/providers/imap/camel-imap-utils.c
parentc757cacd08d3650309783172c2dedc0d20092634 (diff)
downloadgsoc2013-evolution-eb7438182ab5fd969aac96795f67034e21937e35.tar
gsoc2013-evolution-eb7438182ab5fd969aac96795f67034e21937e35.tar.gz
gsoc2013-evolution-eb7438182ab5fd969aac96795f67034e21937e35.tar.bz2
gsoc2013-evolution-eb7438182ab5fd969aac96795f67034e21937e35.tar.lz
gsoc2013-evolution-eb7438182ab5fd969aac96795f67034e21937e35.tar.xz
gsoc2013-evolution-eb7438182ab5fd969aac96795f67034e21937e35.tar.zst
gsoc2013-evolution-eb7438182ab5fd969aac96795f67034e21937e35.zip
Support the IMAP UIDPLUS extension (RFC 2359), which lets you
resync after disconnected operation more efficiently, but also makes it possible to do appends and moves/copies more efficiently now. * providers/imap/camel-imap-folder.c (imap_append_message): If the server supports UIDPLUS, grab the APPENDUID response and cache the message into the folder's message cache. (imap_copy_messages_to): Likewise, for COPYUID, copy any message parts we have cached between the source and destination folder caches. (imap_get_message): If the entire message is already in the cache, just return that rather than building it from parts. (imap_update_summary): Fetch just the "UID FLAGS RFC822.SIZE" of the new messages first, then only fetch the headers for messages where we don't already have the headers cached. * providers/imap/camel-imap-message-cache.c: Add gtk-doc comments. (cache_put): Fix refcounting stuff here. (camel_imap_message_cache_insert_stream, camel_imap_message_cache_insert_wrapper): New. (camel_imap_message_cache_get): Fix a bug here so the memory caching actually works. (camel_imap_message_cache_copy): New routine, used by imap_copy_messages_to. * providers/imap/camel-imap-utils.c (imap_uid_set_to_array): Inverse operation of imap_uid_array_to_set. Used to parse COPYUID response. svn path=/trunk/; revision=9635
Diffstat (limited to 'camel/providers/imap/camel-imap-utils.c')
-rw-r--r--camel/providers/imap/camel-imap-utils.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c
index 22f3c95b50..59d6ac5ea8 100644
--- a/camel/providers/imap/camel-imap-utils.c
+++ b/camel/providers/imap/camel-imap-utils.c
@@ -611,7 +611,7 @@ imap_uid_array_to_set (CamelFolderSummary *summary, GPtrArray *uids)
if (++si < scount)
next_summary_uid = get_summary_uid_numeric (summary, si);
else
- next_summary_uid = (guint32) -1;
+ next_summary_uid = (unsigned long) -1;
/* Now get the next UID from @uids */
this_uid = strtoul (uids->pdata[ui], NULL, 10);
@@ -620,7 +620,7 @@ imap_uid_array_to_set (CamelFolderSummary *summary, GPtrArray *uids)
if (++si < scount)
next_summary_uid = get_summary_uid_numeric (summary, si);
else
- next_summary_uid = (guint32) -1;
+ next_summary_uid = (unsigned long) -1;
} else {
if (range) {
g_string_sprintfa (gset, ":%lu", last_uid);
@@ -640,3 +640,92 @@ imap_uid_array_to_set (CamelFolderSummary *summary, GPtrArray *uids)
return set;
}
+
+/**
+ * imap_uid_set_to_array:
+ * @summary: summary for the folder the UIDs come from
+ * @uids: a pointer to the start of an IMAP "set" of UIDs
+ *
+ * Fills an array with the UIDs corresponding to @uids and @summary.
+ * There can be text after the uid set in @uids, which will be
+ * ignored.
+ *
+ * If @uids specifies a range of UIDs that extends outside the range
+ * of @summary, the function will assume that all of the "missing" UIDs
+ * do exist.
+ *
+ * Return value: the array of uids, which the caller must free with
+ * imap_uid_array_free(). (Or %NULL if the uid set can't be parsed.)
+ **/
+GPtrArray *
+imap_uid_set_to_array (CamelFolderSummary *summary, const char *uids)
+{
+ GPtrArray *arr;
+ char *p, *q;
+ unsigned long uid, suid;
+ int si, scount;
+
+ arr = g_ptr_array_new ();
+ scount = camel_folder_summary_count (summary);
+
+ p = (char *)uids;
+ si = 0;
+ do {
+ uid = strtoul (p, &q, 10);
+ if (p == q)
+ goto lose;
+ g_ptr_array_add (arr, g_strndup (p, q - p));
+
+ if (*q == ':') {
+ /* Find the summary entry for the UID after the one
+ * we just saw.
+ */
+ while (++si < scount) {
+ suid = get_summary_uid_numeric (summary, si);
+ if (suid > uid)
+ break;
+ }
+ if (si >= scount)
+ suid = uid + 1;
+
+ uid = strtoul (q + 1, &p, 10);
+ if (p == q + 1)
+ goto lose;
+
+ /* Add each summary UID until we find one
+ * larger than the end of the range
+ */
+ while (suid <= uid) {
+ g_ptr_array_add (arr, g_strdup_printf ("%lu", suid));
+ if (++si < scount)
+ suid = get_summary_uid_numeric (summary, si);
+ else
+ suid++;
+ }
+ } else
+ p = q;
+ } while (*p++ == ',');
+
+ return arr;
+
+ lose:
+ g_warning ("Invalid uid set %s", uids);
+ imap_uid_array_free (arr);
+ return NULL;
+}
+
+/**
+ * imap_uid_array_free:
+ * @arr: an array returned from imap_uid_set_to_array()
+ *
+ * Frees @arr
+ **/
+void
+imap_uid_array_free (GPtrArray *arr)
+{
+ int i;
+
+ for (i = 0; i < arr->len; i++)
+ g_free (arr->pdata[i]);
+ g_ptr_array_free (arr, TRUE);
+}