Mercurial > dovecot > core-2.2
view src/lib-storage/index/index-sort.c @ 792:d573c53946ac HEAD
Full not-too-well-tested support for SORT extension. Required a few
library interface changes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 17 Dec 2002 06:28:40 +0200 |
parents | f57c52738f90 |
children | 35abd7a5d381 |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "ostream.h" #include "rfc822-date.h" #include "imap-envelope.h" #include "imap-message-cache.h" #include "mail-index.h" #include "index-storage.h" #include "index-sort.h" static ImapMessageCache *search_open_cache(IndexSortContext *ctx, unsigned int uid) { if (ctx->last_uid != uid) { ctx->cached = FALSE; ctx->last_uid = uid; ctx->rec = ctx->ibox->index->lookup_uid_range(ctx->ibox->index, uid, uid, NULL); if (ctx->rec == NULL) { ctx->last_uid = 0; return NULL; } } if (!ctx->cached) { ctx->cached = TRUE; (void)index_msgcache_open(ctx->ibox->cache, ctx->ibox->index, ctx->rec, IMAP_CACHE_ENVELOPE); } return ctx->ibox->cache; } static uoff_t _input_uofft(MailSortType type, unsigned int id, void *context) { IndexSortContext *ctx = context; ImapMessageCache *cache; if (type != MAIL_SORT_SIZE) { i_unreached(); return 0; } cache = search_open_cache(ctx, id); return cache == NULL ? 0 : imap_msgcache_get_virtual_size(cache); } static const char *_input_mailbox(MailSortType type, unsigned int id, void *context) { IndexSortContext *ctx = context; ImapEnvelopeField env_field; const char *envelope; switch (type) { case MAIL_SORT_CC: env_field = IMAP_ENVELOPE_CC; break; case MAIL_SORT_FROM: env_field = IMAP_ENVELOPE_FROM; break; case MAIL_SORT_TO: env_field = IMAP_ENVELOPE_TO; break; default: i_unreached(); return NULL; } /* get field from hopefully cached envelope */ envelope = imap_msgcache_get(search_open_cache(ctx, id), IMAP_CACHE_ENVELOPE); return envelope == NULL ? NULL : imap_envelope_parse(envelope, env_field, IMAP_ENVELOPE_RESULT_FIRST_MAILBOX); } static const char *_input_str(MailSortType type, unsigned int id, void *context) { IndexSortContext *ctx = context; ImapEnvelopeField env_field; const char *envelope; switch (type) { case MAIL_SORT_DATE: env_field = IMAP_ENVELOPE_DATE; break; case MAIL_SORT_SUBJECT: env_field = IMAP_ENVELOPE_SUBJECT; break; default: i_unreached(); return NULL; } /* get field from hopefully cached envelope */ envelope = imap_msgcache_get(search_open_cache(ctx, id), IMAP_CACHE_ENVELOPE); return envelope == NULL ? NULL : imap_envelope_parse(envelope, env_field, IMAP_ENVELOPE_RESULT_STRING); } static time_t _input_time(MailSortType type, unsigned int id, void *context) { IndexSortContext *ctx = context; ImapMessageCache *cache; const char *str; time_t time; int timezone_offset; switch (type) { case MAIL_SORT_ARRIVAL: cache = search_open_cache(ctx, id); return cache == NULL ? 0 : imap_msgcache_get_internal_date(cache); case MAIL_SORT_DATE: str = _input_str(type, id, context); if (str == NULL) return 0; if (!rfc822_parse_date(str, &time, &timezone_offset)) return 0; return time - timezone_offset*60; default: i_unreached(); return 0; } } static void _input_reset(void *context) { IndexSortContext *ctx = context; ctx->cached = FALSE; } static void _output(unsigned int *data, size_t count, void *context) { IndexSortContext *ctx = context; char num[MAX_INT_STRLEN+1]; size_t i, len; for (i = 0; i < count; i++) { len = i_snprintf(num, sizeof(num), " %u", data[i]); o_stream_send(ctx->output, num, len); } } MailSortFuncs index_sort_funcs = { _input_time, _input_uofft, _input_mailbox, _input_str, _input_reset, _output };