balsa r7895 - in trunk: . libbalsa/imap
- From: pawels svn gnome org
- To: svn-commits-list gnome org
- Subject: balsa r7895 - in trunk: . libbalsa/imap
- Date: Thu, 20 Mar 2008 22:55:13 +0000 (GMT)
Author: pawels
Date: Thu Mar 20 22:55:12 2008
New Revision: 7895
URL: http://svn.gnome.org/viewvc/balsa?rev=7895&view=rev
Log:
* libbalsa/imap/imap_search.[ch]: make it easier to explicitly
select message sets for searching.
* libbalsa/imap/imap-handle.c: put coalesce routines back here.
* libbalsa/imap/imap-handle.h: move search functions to imap_search.h
* libbalsa/imap/imap_private.h: declare coalesce routines here.
* libbalsa/imap/imap-commands.c: remove coalesce routines.
Added:
trunk/libbalsa/imap/imap_search.c
- copied, changed from r7892, /trunk/libbalsa/imap/imap-search.c
trunk/libbalsa/imap/imap_search.h
Removed:
trunk/libbalsa/imap/imap-search.c
Modified:
trunk/ChangeLog
trunk/libbalsa/imap/Makefile.am
trunk/libbalsa/imap/imap-commands.c
trunk/libbalsa/imap/imap-commands.h
trunk/libbalsa/imap/imap-handle.c
trunk/libbalsa/imap/imap-handle.h
trunk/libbalsa/imap/imap_private.h
Modified: trunk/libbalsa/imap/Makefile.am
==============================================================================
--- trunk/libbalsa/imap/Makefile.am (original)
+++ trunk/libbalsa/imap/Makefile.am Thu Mar 20 22:55:12 2008
@@ -23,7 +23,8 @@
imap-commands.h \
imap-handle.c \
imap-handle.h \
- imap-search.c \
+ imap_search.c \
+ imap_search.h \
imap-tls.c \
imap_private.h \
libimap-marshal.c \
Modified: trunk/libbalsa/imap/imap-commands.c
==============================================================================
--- trunk/libbalsa/imap/imap-commands.c (original)
+++ trunk/libbalsa/imap/imap-commands.c Thu Mar 20 22:55:12 2008
@@ -30,59 +30,6 @@
#define ELEMENTS(x) (sizeof (x) / sizeof(x[0]))
-typedef unsigned (*CoalesceFunc)(int, void*);
-static gchar*
-coalesce_seq_range(int lo, int hi, CoalesceFunc incl, void *data)
-{
- GString * res = g_string_sized_new(16);
- enum { BEGIN, LASTOUT, LASTIN, RANGE } mode = BEGIN;
- int seq;
- unsigned prev =0, num = 0;
-
- for(seq=lo; seq<=hi+1; seq++) {
- if(seq<=hi && (num=incl(seq, data)) != 0) {
- switch(mode) {
- case BEGIN:
- g_string_append_printf(res, "%u", num);
- mode = LASTIN; break;
- case RANGE:
- if(num!=prev+1) {
- g_string_append_printf(res, ":%u,%u", prev, num);
- mode = LASTIN;
- }
- break;
- case LASTIN:
- if(num==prev+1) {
- mode = RANGE;
- break;
- } /* else fall through */
- case LASTOUT:
- g_string_append_printf(res, ",%u", num);
- mode = LASTIN; break;
- }
- } else {
- switch(mode) {
- case BEGIN:
- case LASTOUT: break;
- case LASTIN: mode = LASTOUT; break;
- case RANGE:
- g_string_append_printf(res, ":%u", prev);
- mode = LASTOUT;
- break;
- }
- }
- prev = num;
- }
- return g_string_free(res, mode == BEGIN);
-}
-
-static unsigned
-simple_coealesce_func(int i, unsigned msgno[])
-{
- return msgno[i];
-}
-
-
struct fetch_data {
ImapMboxHandle* h;
ImapFetchType ift;
@@ -845,8 +792,8 @@
if( (f->known_flags & fnd.flag) ==0)
f->flag_values |= fnd.flag;
}
- seqno = coalesce_seq_range(1, h->exists,
- (CoalesceFunc)flag_unknown, &fnd);
+ seqno = imap_coalesce_seq_range(1, h->exists,
+ (ImapCoalesceFunc)flag_unknown, &fnd);
if(!seqno) /* oops, why were we called in the first place!? */
continue;
switch(fnd.flag) {
@@ -978,8 +925,9 @@
gchar * seq;
ImapResponse rc;
unsigned exists = imap_mbox_handle_get_exists(handle);
- CoalesceFunc cf = (CoalesceFunc)(mbox_view_is_active(&handle->mbox_view)
- ? need_fetch_view : need_fetch);
+ ImapCoalesceFunc cf =
+ (ImapCoalesceFunc)(mbox_view_is_active(&handle->mbox_view)
+ ? need_fetch_view : need_fetch);
struct fetch_data fd;
IMAP_REQUIRED_STATE1(handle, IMHS_SELECTED, IMR_BAD);
@@ -988,7 +936,7 @@
if(lo>hi) return IMR_OK;
if(lo<1) lo = 1;
if(hi>exists) hi = exists;
- seq = coalesce_seq_range(lo, hi, cf, &fd);
+ seq = imap_coalesce_seq_range(lo, hi, cf, &fd);
if(seq) {
const char* hdr[13];
ic_construct_header_list(hdr, fd.req_fetch_type);
@@ -1007,7 +955,7 @@
{
gchar * seq;
ImapResponse rc;
- CoalesceFunc cf;
+ ImapCoalesceFunc cf;
struct fetch_data_set fd;
IMAP_REQUIRED_STATE1(handle, IMHS_SELECTED, IMR_BAD);
@@ -1015,9 +963,9 @@
fd.fd.h = handle; fd.fd.ift = fd.fd.req_fetch_type = ift;
fd.set = set;
- cf = (CoalesceFunc)(mbox_view_is_active(&handle->mbox_view)
- ? need_fetch_view_set : need_fetch_set);
- seq = coalesce_seq_range(1, cnt, cf, &fd);
+ cf = (ImapCoalesceFunc)(mbox_view_is_active(&handle->mbox_view)
+ ? need_fetch_view_set : need_fetch_set);
+ seq = imap_coalesce_seq_range(1, cnt, cf, &fd);
if(seq) {
const char* hdr[13];
ic_construct_header_list(hdr, fd.fd.req_fetch_type);
@@ -1049,7 +997,7 @@
IMAP_REQUIRED_STATE1(handle, IMHS_SELECTED, IMR_BAD);
HANDLE_LOCK(handle);
- seq = coalesce_seq_range(0, cnt-1, (CoalesceFunc)simple_coealesce_func, set);
+ seq = imap_coalesce_set(cnt, set);
if(seq) {
ImapFetchBodyCb cb = handle->body_cb;
@@ -1218,7 +1166,7 @@
csd.handle = h; csd.msgcnt = msgcnt; csd.seqno = seqno;
csd.flag = flg; csd.state = state;
if(msgcnt == 0) return NULL;
- seq = coalesce_seq_range(0, msgcnt-1, (CoalesceFunc)cf_flag, &csd);
+ seq = imap_coalesce_seq_range(0, msgcnt-1, (ImapCoalesceFunc)cf_flag, &csd);
if(!seq) return NULL;
str = enum_flag_to_str(flg);
for(i=0; i<msgcnt; i++) {
@@ -1290,8 +1238,7 @@
IMAP_REQUIRED_STATE1(handle, IMHS_SELECTED, IMR_BAD);
{
gchar *mbx7 = imap_utf8_to_mailbox(dest);
- char *seq =
- coalesce_seq_range(0, cnt-1,(CoalesceFunc)simple_coealesce_func, seqno);
+ char *seq = imap_coalesce_set(cnt, seqno);
gchar *cmd = g_strdup_printf("COPY %s \"%s\"", seq, mbx7);
ImapResponse rc = imap_cmd_exec(handle, cmd);
g_free(seq); g_free(mbx7); g_free(cmd);
@@ -1420,8 +1367,7 @@
/* seq can be pretty long and g_strdup_printf has a limit on
* string length so we create the command string in two steps. */
keystr = sort_code_to_string(key);
- seq = coalesce_seq_range(0, cnt-1,(CoalesceFunc)simple_coealesce_func,
- msgno);
+ seq = imap_coalesce_set(cnt, msgno);
cmd= g_strdup_printf("SORT (%s%s) UTF-8 ",
ascending ? "" : "REVERSE ",
keystr);
@@ -1768,8 +1714,8 @@
void *arg;
IMAP_REQUIRED_STATE1(h, IMHS_SELECTED, IMR_BAD);
- seq = coalesce_seq_range(first_seqno_to_fetch, msgids->len,
- (CoalesceFunc)need_msgid, msgids);
+ seq = imap_coalesce_seq_range(first_seqno_to_fetch, msgids->len,
+ (ImapCoalesceFunc)need_msgid, msgids);
if(seq) {
cmd = g_strdup_printf("FETCH %s BODY.PEEK[HEADER.FIELDS (message-id)]",
seq);
Modified: trunk/libbalsa/imap/imap-commands.h
==============================================================================
--- trunk/libbalsa/imap/imap-commands.h (original)
+++ trunk/libbalsa/imap/imap-commands.h Thu Mar 20 22:55:12 2008
@@ -21,6 +21,7 @@
#include <gmime/gmime.h>
#include "imap-handle.h"
+#include "imap_search.h"
/* Any-State */
int imap_mbox_handle_can_do(ImapMboxHandle* handle, ImapCapability cap);
Modified: trunk/libbalsa/imap/imap-handle.c
==============================================================================
--- trunk/libbalsa/imap/imap-handle.c (original)
+++ trunk/libbalsa/imap/imap-handle.c Thu Mar 20 22:55:12 2008
@@ -3825,6 +3825,65 @@
return handle->thread_root;
}
+gchar*
+imap_coalesce_seq_range(int lo, int hi, ImapCoalesceFunc incl, void *data)
+{
+ GString * res = g_string_sized_new(16);
+ enum { BEGIN, LASTOUT, LASTIN, RANGE } mode = BEGIN;
+ int seq;
+ unsigned prev =0, num = 0;
+
+ for(seq=lo; seq<=hi+1; seq++) {
+ if(seq<=hi && (num=incl(seq, data)) != 0) {
+ switch(mode) {
+ case BEGIN:
+ g_string_append_printf(res, "%u", num);
+ mode = LASTIN; break;
+ case RANGE:
+ if(num!=prev+1) {
+ g_string_append_printf(res, ":%u,%u", prev, num);
+ mode = LASTIN;
+ }
+ break;
+ case LASTIN:
+ if(num==prev+1) {
+ mode = RANGE;
+ break;
+ } /* else fall through */
+ case LASTOUT:
+ g_string_append_printf(res, ",%u", num);
+ mode = LASTIN; break;
+ }
+ } else {
+ switch(mode) {
+ case BEGIN:
+ case LASTOUT: break;
+ case LASTIN: mode = LASTOUT; break;
+ case RANGE:
+ g_string_append_printf(res, ":%u", prev);
+ mode = LASTOUT;
+ break;
+ }
+ }
+ prev = num;
+ }
+ return g_string_free(res, mode == BEGIN);
+}
+
+unsigned
+imap_coalesce_func_simple(int i, unsigned msgno[])
+{
+ return msgno[i];
+}
+
+gchar*
+imap_coalesce_set(int cnt, unsigned *seqnos)
+{
+ return imap_coalesce_seq_range(0, cnt-1,
+ (ImapCoalesceFunc)imap_coalesce_func_simple,
+ seqnos);
+}
+
/* =================================================================== */
/* MboxView routines */
Modified: trunk/libbalsa/imap/imap-handle.h
==============================================================================
--- trunk/libbalsa/imap/imap-handle.h (original)
+++ trunk/libbalsa/imap/imap-handle.h Thu Mar 20 22:55:12 2008
@@ -180,36 +180,6 @@
const char *section);
/* ================ END OF BODY STRUCTURE FUNCTIONS ==================== */
-/* ================ BEGIN OF SEARCH FUNCTIONS ========================== */
-typedef enum { IMSE_S_BCC, IMSE_S_BODY, IMSE_S_CC, IMSE_S_FROM,
- IMSE_S_SUBJECT, IMSE_S_TEXT, IMSE_S_TO,
- IMSE_S_HEADER } ImapSearchHeader;
-
-typedef enum { IMSE_D_BEFORE = -1, IMSE_D_ON = 0,
- IMSE_D_SINCE = 1 } ImapSearchDateRange;
-
-typedef struct ImapSearchKey_ ImapSearchKey;
-
-ImapSearchKey *imap_search_key_new_not(unsigned negated,
- ImapSearchKey *list);
-ImapSearchKey *imap_search_key_new_or(unsigned negated,
- ImapSearchKey *a, ImapSearchKey *b);
-ImapSearchKey *imap_search_key_new_flag(unsigned negated, ImapMsgFlag flg);
-ImapSearchKey *imap_search_key_new_string(unsigned negated,
- ImapSearchHeader hdr,
- const char *string,
- const char *user_header);
-ImapSearchKey* imap_search_key_new_size_greater(unsigned negated, size_t sz);
-ImapSearchKey* imap_search_key_new_date(ImapSearchDateRange range,
- int internal, time_t tm);
-ImapSearchKey* imap_search_key_new_range(unsigned negated, int uid,
- unsigned lo, unsigned hi);
-
-void imap_search_key_free(ImapSearchKey *s);
-void imap_search_key_set_next(ImapSearchKey *list, ImapSearchKey *next);
-ImapResponse imap_search_exec(ImapMboxHandle *h, gboolean uid,
- ImapSearchKey *s, ImapSearchCb cb, void *cb_arg);
-/* ================ END OF SEARCH FUNCTIONS ============================ */
/* ================ BEGIN OF MBOX_VIEW FUNCTIONS ======================= */
typedef struct _MboxView MboxView;
Modified: trunk/libbalsa/imap/imap_private.h
==============================================================================
--- trunk/libbalsa/imap/imap_private.h (original)
+++ trunk/libbalsa/imap/imap_private.h Thu Mar 20 22:55:12 2008
@@ -167,6 +167,12 @@
#define imap_mbox_handle_set_msg(h,s) \
do{g_free((h)->last_msg); (h)->last_msg = g_strdup(s); }while(0)
+typedef unsigned (*ImapCoalesceFunc)(int, void*);
+gchar* imap_coalesce_seq_range(int lo, int hi,
+ ImapCoalesceFunc fun, void *data);
+unsigned imap_coalesce_func_simple(int i, unsigned msgno[]);
+gchar *imap_coalesce_set(int cnt, unsigned *seqnos);
+
/* even more private functions */
int imap_cmd_start(ImapMboxHandle* handle, const char* cmd, unsigned* cmdno);
ImapResponse imap_cmd_step(ImapMboxHandle* handle, unsigned cmdno);
Copied: trunk/libbalsa/imap/imap_search.c (from r7892, /trunk/libbalsa/imap/imap-search.c)
==============================================================================
--- /trunk/libbalsa/imap/imap-search.c (original)
+++ trunk/libbalsa/imap/imap_search.c Thu Mar 20 22:55:12 2008
@@ -1,5 +1,5 @@
/* libimap library.
- * Copyright (C) 2003-2004 Pawel Salek.
+ * Copyright (C) 2003-2008 Pawel Salek.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,16 +24,18 @@
#include <time.h>
#include "siobuf.h"
-#include "imap-handle.h"
+#include "imap_search.h"
#include "imap_private.h"
+typedef enum {
+ IMSE_NOT, IMSE_OR, IMSE_FLAG, IMSE_STRING, IMSE_DATE, IMSE_SIZE,
+ IMSE_SEQUENCE
+} ImapSearchKeyType;
+
struct ImapSearchKey_ {
struct ImapSearchKey_ *next; /* message must match all the conditions
* on the list. */
- enum {
- IMSE_NOT, IMSE_OR, IMSE_FLAG, IMSE_STRING, IMSE_DATE, IMSE_SIZE,
- IMSE_SEQUENCE
- } type;
+ ImapSearchKeyType type;
union {
/* IMSE_NOT */
struct ImapSearchKey_ *not;
@@ -161,6 +163,23 @@
}
}
+ImapSearchKey*
+imap_search_key_new_set(unsigned negated, int uid, int cnt, unsigned *seqnos)
+
+{
+ if(cnt>0) {
+ ImapSearchKey *s = g_new(ImapSearchKey,1);
+ s->next = NULL;
+ s->type = IMSE_SEQUENCE;
+ s->negated = negated;
+ s->d.seq.uid = uid;
+ s->d.seq.string = imap_coalesce_set(cnt, seqnos);
+ return s;
+ } else { /* always false */
+ return NULL;
+ }
+}
+
void
imap_search_key_free(ImapSearchKey *s)
{
@@ -216,22 +235,19 @@
}
static gboolean
-imap_search_checks_headers(const ImapSearchKey *s)
+imap_search_checks(const ImapSearchKey *s, ImapSearchKeyType s_type)
{
while(s) {
switch(s->type) {
case IMSE_NOT: /* NOOP */ break;
case IMSE_OR:
- if(imap_search_checks_headers(s->d.or.l) ||
- imap_search_checks_headers(s->d.or.r))
+ if(imap_search_checks(s->d.or.l, s_type) ||
+ imap_search_checks(s->d.or.r, s_type))
return TRUE;
break;
- case IMSE_FLAG: break;
- case IMSE_STRING:
- return TRUE;
- case IMSE_DATE:
- case IMSE_SIZE:
- case IMSE_SEQUENCE:
+ default:
+ if(s->type == s_type)
+ return TRUE;
break;
}
s = s->next;
@@ -239,7 +255,6 @@
return FALSE;
}
-
void
imap_search_key_set_next(ImapSearchKey *list, ImapSearchKey *next)
{
@@ -441,10 +456,10 @@
(flags) and immutable terms (anything else).
*/
ImapResponse
-imap_search_exec(ImapMboxHandle *h, gboolean uid, ImapSearchKey *s,
- ImapSearchCb cb, void *cb_arg)
+imap_search_exec(ImapMboxHandle *h, gboolean uid,
+ ImapSearchKey *s, ImapSearchCb cb, void *cb_arg)
{
- static const unsigned BODY_TO_SEARCH_AT_ONCE = 500;
+ static const unsigned BODY_TO_SEARCH_AT_ONCE = 500000;
static const unsigned HEADER_TO_SEARCH_AT_ONCE = 2000;
static const unsigned UIDS_TO_SEARCH_AT_ONCE = 100000;
int can_do_literals =
@@ -461,6 +476,7 @@
void *oarg;
unsigned cmdno, lo, delta;
const gchar *cmd_string;
+ gboolean split;
IMAP_REQUIRED_STATE1(h, IMHS_SELECTED, IMR_BAD);
@@ -480,32 +496,44 @@
imap_handle_idle_disable(h);
- if(imap_search_checks_body(s)) {
- delta = BODY_TO_SEARCH_AT_ONCE;
- } else if(imap_search_checks_headers(s)) {
- delta = HEADER_TO_SEARCH_AT_ONCE;
- } else {
- delta = UIDS_TO_SEARCH_AT_ONCE;
- }
+ split = imap_search_checks(s, IMSE_SEQUENCE);
+ if(split) {
+ if(imap_search_checks_body(s)) {
+ delta = BODY_TO_SEARCH_AT_ONCE;
+ } else if(imap_search_checks(s, IMSE_STRING)) {
+ delta = HEADER_TO_SEARCH_AT_ONCE;
+ } else {
+ delta = UIDS_TO_SEARCH_AT_ONCE;
+ }
- /* This loop may take long time to execute. Consider providing some
- feedback to the user... */
- for(lo = 1; ir == IMR_OK && lo<=h->exists; lo += delta) {
- unsigned hi = lo + delta-1;
- if(hi>h->exists)
- hi = h->exists;
- cmdno = imap_make_tag(tag);
- sio_printf(h->sio, "%s%s %s %u:%u ", tag, uid ? " UID" : "", cmd_string,
+ /* This loop may take long time to execute. Consider providing some
+ feedback to the user... */
+ for(lo = 1; ir == IMR_OK && lo<=h->exists; lo += delta) {
+ unsigned hi = lo + delta-1;
+ if(hi>h->exists)
+ hi = h->exists;
+ cmdno = imap_make_tag(tag);
+ sio_printf(h->sio, "%s%s %s %u:%u ", tag, uid ? " UID" : "", cmd_string,
lo, hi);
+ if( (ir=imap_write_key(h, s, cmdno, can_do_literals)) == IMR_OK) {
+ sio_write(h->sio, "\r\n", 2);
+ imap_handle_flush(h);
+ do {
+ ir = imap_cmd_step(h, cmdno);
+ } while(ir == IMR_UNTAGGED);
+ } else break;
+ }
+ } else { /* no split */
+ cmdno = imap_make_tag(tag);
+ sio_printf(h->sio, "%s%s %s ", tag, uid ? " UID" : "", cmd_string);
if( (ir=imap_write_key(h, s, cmdno, can_do_literals)) == IMR_OK) {
sio_write(h->sio, "\r\n", 2);
imap_handle_flush(h);
do {
- ir = imap_cmd_step(h, cmdno);
+ ir = imap_cmd_step(h, cmdno);
} while(ir == IMR_UNTAGGED);
- } else break;
+ }
}
-
h->search_cb = ocb;
h->search_arg = oarg;
imap_handle_idle_enable(h, 30);
Added: trunk/libbalsa/imap/imap_search.h
==============================================================================
--- (empty file)
+++ trunk/libbalsa/imap/imap_search.h Thu Mar 20 22:55:12 2008
@@ -0,0 +1,56 @@
+#ifndef __IMAP_SEARCH_H__
+#define __IMAP_SEARCH_H__ 1
+
+/* libimap library.
+ * Copyright (C) 2003-2008 Pawel Salek.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "imap-handle.h"
+
+typedef enum { IMSE_S_BCC, IMSE_S_BODY, IMSE_S_CC, IMSE_S_FROM,
+ IMSE_S_SUBJECT, IMSE_S_TEXT, IMSE_S_TO,
+ IMSE_S_HEADER } ImapSearchHeader;
+
+typedef enum { IMSE_D_BEFORE = -1, IMSE_D_ON = 0,
+ IMSE_D_SINCE = 1 } ImapSearchDateRange;
+
+typedef struct ImapSearchKey_ ImapSearchKey;
+
+ImapSearchKey *imap_search_key_new_not(unsigned negated,
+ ImapSearchKey *list);
+ImapSearchKey *imap_search_key_new_or(unsigned negated,
+ ImapSearchKey *a, ImapSearchKey *b);
+ImapSearchKey *imap_search_key_new_flag(unsigned negated, ImapMsgFlag flg);
+ImapSearchKey *imap_search_key_new_string(unsigned negated,
+ ImapSearchHeader hdr,
+ const char *string,
+ const char *user_header);
+ImapSearchKey* imap_search_key_new_size_greater(unsigned negated, size_t sz);
+ImapSearchKey* imap_search_key_new_date(ImapSearchDateRange range,
+ int internal, time_t tm);
+ImapSearchKey* imap_search_key_new_range(unsigned negated, int uid,
+ unsigned lo, unsigned hi);
+ImapSearchKey* imap_search_key_new_set(unsigned negated, int uid,
+ int cnt, unsigned *seqnos);
+
+void imap_search_key_free(ImapSearchKey *s);
+void imap_search_key_set_next(ImapSearchKey *list, ImapSearchKey *next);
+ImapResponse imap_search_exec(ImapMboxHandle *h, gboolean uid,
+ ImapSearchKey *s, ImapSearchCb cb, void *cb_arg);
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]