imap-message-cache.c revision 468bb8fbe53f28a18a47b8dc6761171d5d8ce706
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
#include "iobuffer.h"
#include "temp-string.h"
#include "mmap-util.h"
#include "message-parser.h"
#include "message-size.h"
#include "imap-bodystructure.h"
#include "imap-envelope.h"
#include "imap-message-cache.h"
#include <unistd.h>
/* It's not very useful to cache lots of messages, as they're mostly wanted
just once. The biggest reason for this cache to exist is to get just the
latest message. */
#define MAX_CACHED_MESSAGES 16
#define DEFAULT_MESSAGE_POOL_SIZE 4096
typedef struct _CachedMessage CachedMessage;
struct _CachedMessage {
unsigned int uid;
char *cached_body;
char *cached_bodystructure;
char *cached_envelope;
};
struct _ImapMessageCache {
int messages_count;
void *context;
};
{
}
{
}
{
}
}
{
}
{
cache->messages_count++;
else {
/* remove the last message from cache */
}
return msg;
}
unsigned int uid)
{
break;
}
/* not found, add it */
/* move it to first in list */
} else {
}
return msg;
}
void *context)
{
/* parse envelope headers if we're at the root message part */
}
}
{
return msg;
}
return NULL;
}
{
/* need to rewind */
i_fatal("Can't rewind message buffer");
}
}
{
return TRUE;
/* not open, see if the wanted fields are cached */
return FALSE;
return FALSE;
if ((fields & IMAP_CACHE_BODYSTRUCTURE) &&
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
}
/* Caches the fields for given message if possible */
{
const char *value;
t_push();
}
if ((fields & IMAP_CACHE_BODYSTRUCTURE) &&
}
/* envelope isn't parsed yet, do it. header size
is calculated anyway so save it */
MessageSize, 1);
}
}
}
}
/* we need to parse the message */
if ((fields & IMAP_CACHE_ENVELOPE) &&
/* we need envelope too, fill the info
while parsing headers */
} else {
}
}
if ((fields & IMAP_CACHE_MESSAGE_BODY_SIZE) &&
/* fill the body size, and while at it fill the header size
as well */
/* easy, get it from root part */
} else {
/* first get the header's size, then calculate the
body size from it and the total virtual size */
}
}
/* easy, get it from root part */
} else {
/* need to do some light parsing */
}
}
t_pop();
}
void *context),
void *context)
{
}
/* physical size == virtual size */
}
/* physical size == virtual size */
}
}
{
}
cache->open_virtual_size = 0;
}
{
switch (field) {
case IMAP_CACHE_BODY:
break;
case IMAP_CACHE_BODYSTRUCTURE:
break;
case IMAP_CACHE_ENVELOPE:
break;
default:
i_assert(0);
}
}
{
return NULL;
switch (field) {
case IMAP_CACHE_BODY:
return msg->cached_body;
case IMAP_CACHE_BODYSTRUCTURE:
return msg->cached_bodystructure;
case IMAP_CACHE_ENVELOPE:
return msg->cached_envelope;
default:
i_assert(0);
}
return NULL;
}
{
return NULL;
}
{
return FALSE;
} else {
return FALSE;
}
return FALSE;
}
return FALSE;
}
return TRUE;
}
{
unsigned char *msg;
unsigned int size;
int cr_skipped;
/* see if we can use the existing partial */
else {
}
if (!cr_skipped) {
/* see if we need to add virtual CR */
if (size > 0) {
if (msg[0] == '\n')
dest->virtual_size++;
break;
}
}
}
}
{
int size_got;
return FALSE;
}
/* see if we can do this easily */
if (virtual_skip == 0) {
}
(max_virtual_size < 0 ||
}
}
if (!size_got) {
}
if (get_header)
/* seek to wanted position */
return TRUE;
}
{
return FALSE;
return TRUE;
}