Files
evolution/camel/camel-folder-summary.h
Not Zed 854f94bc20 Fixes for the summary messageid changes. Hash the messageid and store it.
2000-11-20  Not Zed  <NotZed@HelixCode.com>

	* providers/nntp/camel-nntp-utils.c (get_XOVER_headers): Fixes for
	the summary messageid changes.  Hash the messageid and store it.
	(get_XOVER_headers): Use camel_folder_summary_info_new() to create
	the summary item before adding it.

	* camel-folder-summary.h (CamelMessageInfo): Changed the
	messgae-id to be an 8 byte md5 hash, and the references list to be
	an array of these.

	* providers/local/camel-mh-summary.c (mh_summary_sync_message):
	New function, sync out the message info stuff.  Only updates the
	X-Ev header if it can get away with it, otherwise writes out a
	whole new message.
	(mh_summary_sync): Added more functionality.  All summary info is
	now written to the X-Ev header, etc, and new messages re-written
	if required during the sync process.

	* providers/local/camel-local-folder.c
	(local_set_message_user_flag): Set the XEVCHANGE flag.
	(local_set_message_user_tag): And here too.

	* providers/local/camel-local-summary.h: New flag
	CAMEL_MESSAGE_FOLDER_XEVCHANGE to indicate the XEV header has
	probably changed size and needs to be rewritten in whole.

	* camel-folder-summary.c (next_uid_string): Want this static, not
	const.
	(message_info_new): Store the references and message-id values as
	64 bit, binary hashes.
	(message_info_load): fix for message-id/references changes.
	(message_info_save): Likewise.
	(camel_message_info_dup_to): And here.
	(camel_message_info_free): And here too.  No longer free
	message_id, and simple free for references array.
	(CAMEL_FOLDER_SUMMARY_VERSION): Bumped file revision.
	(camel_folder_summary_init): Init memchunk allocators to empty.
	(camel_folder_summary_finalize): Free memchunk allocators if
	there.
	(message_info_new): Use the chunk allocator to allocate message
	info's.
	(camel_folder_summary_info_new): New helper to allocate the
	message info, and setup the memchunk if required.
	(content_info_alloc): Likewise for content info's.
	(message_info_load): Use summary_info_new_empty.
	(content_info_new): Use content_info_alloc.
	(content_info_load): "
	(content_info_free): Free the content info as a memchunk.
	(message_info_free): Free everything directly and the base as a
	memchunk, rather than calling camel_message_info_free(), which
	assumes a malloc'd array.

	* providers/local/camel-local-summary.c: Include ctype.h, kill a
	warning.
	(local_summary_decode_x_evolution): If we get a NULL message info,
	then dont try and set anything, just check for validity.
	(camel_local_summary_write_headers): New function to write a set
	of headers to an fd.
	(camel_local_summary_check): Added some statistic generation
	stuff for memory profiling.

	* providers/local/camel-mbox-summary.c (header_write): Changed to
	use stdoi functions to write out the header to a buffered stream,
	instead of using writev, which is apparently slow (and writing
	each line separately is slow anyway).
	(mbox_summary_sync_full): New implementation.  Does things
	differently, doesn't use or require the content info stuff.
	(summary_rebuild): Dont return an error if we start scanning at
	the end of file.
	(mbox_summary_sync_full): If we are not writing out new headers,
	make sure we copy the From line as we go, and update frompos
	appropriately.
	(mbox_summary_sync_full): Always copy the From line from the
	existing one, rather than trying to make one up ourselves.
	(mbox_summary_sync): If we can get by with a quick-sync, then try
	it, if that fails, then try a full sync anyway.
	(mbox_summary_sync_quick): Quick sync.  Only update system flags,
	etc.
	(mbox_summary_sync_full): Use the proper local summary encode_xev
	function.
	(header_evolution_decode): Removed, no longer needed.
	(header_evolution_encode): Same.
	(copy_block): No longer needed, removed.
	(header_write): Removed, replaced with
	camel_local_summary_write_headers.
	(mbox_summary_sync_full): Fixed for header_write change.

	* camel-mime-parser.c (folder_scan_step): Implement the new
	optional parser state HSCAN_PRE_FROM, that returns the (currently
	unfiltered) input data.
	(folder_scan_drop_step): Do the right thing for the PRE_FROM
	state.
	(camel_mime_parser_scan_from): Update the doco.
	(camel_mime_parser_scan_pre_from): Ok, make this behaviour
	optional, it simplifies a lot of loops that dont otherwise need to
	know about it.
	(folder_scan_step): Made the PRE_FROM state optional.
	(struct _header_scan_state): Made the bool vars 1 bit.
	(folder_pull_part): Free the from_line buffer if it is there.
	(folder_scan_skip_line): Added a new arg, can save the skpped data
	to a byte_array, as we go.
	(folder_scan_step): Fixed calls to skip_line approrpiately.  Now
	we save the from line as we parse it.
	(camel_mime_parser_read): New function to read from the mime
	parser buffer directly.  Useful if you use the parser to read the
	first/some headers, then need to scan the rest of the data,
	without needing to use a seek(), or allocate your own buffers.

	* camel-mime-parser.h (struct _header_state): Added a new parser state,
	pre-from which returns any data found before a from line during
	parsing (all other data can be retrieved by the caller except
	this).

svn path=/trunk/; revision=6618
2000-11-20 23:54:48 +00:00

305 lines
12 KiB
C

/*
* Copyright (C) 2000 Helix Code Inc.
*
* Authors: Michael Zucchi <notzed@helixcode.com>
*
* 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 of the
* License, 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
*/
#ifndef _CAMEL_FOLDER_SUMMARY_H
#define _CAMEL_FOLDER_SUMMARY_H
#include <camel/camel-object.h>
#include <stdio.h>
#include <time.h>
#include <camel/camel-mime-parser.h>
#include <libibex/ibex.h>
#define CAMEL_FOLDER_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_folder_summary_get_type (), CamelFolderSummary)
#define CAMEL_FOLDER_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_folder_summary_get_type (), CamelFolderSummaryClass)
#define IS_CAMEL_FOLDER_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_folder_summary_get_type ())
/*typedef struct _CamelFolderSummary CamelFolderSummary;*/
typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass;
/* A tree of message content info structures
describe the content structure of the message (if it has any) */
typedef struct _CamelMessageContentInfo {
struct _CamelMessageContentInfo *next;
struct _CamelMessageContentInfo *childs;
struct _CamelMessageContentInfo *parent;
struct _header_content_type *type;
char *id;
char *description;
char *encoding;
/* NOTE: The fields below are to be deprecated, and eventually removed */
/* information about where this object lives in the stream.
if pos is -1 these are all invalid */
off_t pos;
off_t bodypos;
off_t endpos;
} CamelMessageContentInfo;
/* system flag bits */
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,
/* following flags are for the folder, and are not really permanent flags */
CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<16, /* for use by the folder implementation */
CAMEL_MESSAGE_USER = 1<<31 /* supports user flags */
};
typedef struct _CamelFlag {
struct _CamelFlag *next;
char name[1]; /* name allocated as part of the structure */
} CamelFlag;
typedef struct _CamelTag {
struct _CamelTag *next;
char *value;
char 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;
unsigned char hash[8];
struct {
guint32 hi;
guint32 lo;
} part;
} id;
} CamelSummaryMessageID;
/* summary references is a fixed size array of references */
typedef struct _CamelSummaryReferences {
int size;
CamelSummaryMessageID references[1];
} CamelSummaryReferences;
#ifdef DOESTRV
/* string array indices */
enum {
CAMEL_MESSAGE_INFO_SUBJECT,
CAMEL_MESSAGE_INFO_FROM,
CAMEL_MESSAGE_INFO_TO,
CAMEL_MESSAGE_INFO_CC,
CAMEL_MESSAGE_INFO_UID,
CAMEL_MESSAGE_INFO_STRING_COUNT,
};
#endif
/* information about a given object */
typedef struct {
/* public fields */
#ifdef DOESTRV
EStrv *strings; /* all strings packed into a single compact array */
#else
gchar *subject;
gchar *from;
gchar *to;
gchar *cc;
gchar *uid;
#endif
guint32 flags;
guint32 size;
time_t date_sent;
time_t date_received;
CamelSummaryMessageID message_id;/* for this message */
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;
} CamelMessageInfo;
enum _CamelFolderSummaryFlags {
CAMEL_SUMMARY_DIRTY = 1<<0,
};
struct _CamelFolderSummary {
CamelObject parent;
struct _CamelFolderSummaryPrivate *priv;
/* header info */
guint32 version; /* version of file required, should be set by implementors */
guint32 flags; /* flags */
guint32 nextuid; /* next uid? */
guint32 saved_count; /* how many were saved/loaded */
time_t time; /* timestamp for this summary (for implementors to use) */
/* sizes of memory objects */
guint32 message_info_size;
guint32 content_info_size;
/* memory allocators (setup automatically) */
struct _EMemChunk *message_info_chunks;
struct _EMemChunk *content_info_chunks;
char *summary_path;
gboolean build_content; /* do we try and parse/index the content, or not? */
GPtrArray *messages; /* CamelMessageInfo's */
GHashTable *messages_uid; /* CamelMessageInfo's by uid */
};
struct _CamelFolderSummaryClass {
CamelObjectClass parent_class;
/* load/save the global info */
int (*summary_header_load)(CamelFolderSummary *, FILE *);
int (*summary_header_save)(CamelFolderSummary *, FILE *);
/* create/save/load an individual message info */
CamelMessageInfo * (*message_info_new)(CamelFolderSummary *, struct _header_raw *);
CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
CamelMessageInfo * (*message_info_new_from_message)(CamelFolderSummary *, CamelMimeMessage *);
CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, FILE *);
int (*message_info_save)(CamelFolderSummary *, FILE *, CamelMessageInfo *);
void (*message_info_free)(CamelFolderSummary *, CamelMessageInfo *);
/* save/load individual content info's */
CamelMessageContentInfo * (*content_info_new)(CamelFolderSummary *, struct _header_raw *);
CamelMessageContentInfo * (*content_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
CamelMessageContentInfo * (*content_info_new_from_message)(CamelFolderSummary *, CamelMimePart *);
CamelMessageContentInfo * (*content_info_load)(CamelFolderSummary *, FILE *);
int (*content_info_save)(CamelFolderSummary *, FILE *, CamelMessageContentInfo *);
void (*content_info_free)(CamelFolderSummary *, CamelMessageContentInfo *);
/* get the next uid */
char *(*next_uid_string)(CamelFolderSummary *);
};
guint camel_folder_summary_get_type (void);
CamelFolderSummary *camel_folder_summary_new (void);
void camel_folder_summary_set_filename(CamelFolderSummary *, const char *);
void camel_folder_summary_set_index(CamelFolderSummary *, ibex *);
void camel_folder_summary_set_build_content(CamelFolderSummary *, gboolean state);
guint32 camel_folder_summary_next_uid (CamelFolderSummary *s);
char *camel_folder_summary_next_uid_string (CamelFolderSummary *s);
void camel_folder_summary_set_uid (CamelFolderSummary *s, guint32 uid);
/* load/save the summary in its entirety */
int camel_folder_summary_load(CamelFolderSummary *);
int camel_folder_summary_save(CamelFolderSummary *);
/* set the dirty bit on the summary */
void camel_folder_summary_touch(CamelFolderSummary *s);
/* add a new raw summary item */
void camel_folder_summary_add(CamelFolderSummary *, CamelMessageInfo *info);
/* build/add raw summary items */
CamelMessageInfo *camel_folder_summary_add_from_header(CamelFolderSummary *, struct _header_raw *);
CamelMessageInfo *camel_folder_summary_add_from_parser(CamelFolderSummary *, CamelMimeParser *);
CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *, CamelMimeMessage *);
/* Just build raw summary items */
CamelMessageInfo *camel_folder_summary_info_new(CamelFolderSummary *s);
CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *, struct _header_raw *);
CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary *, CamelMimeMessage *);
void camel_folder_summary_info_free(CamelFolderSummary *, CamelMessageInfo *);
/* removes a summary item, doesn't fix content offsets */
void camel_folder_summary_remove(CamelFolderSummary *s, CamelMessageInfo *info);
void camel_folder_summary_remove_uid(CamelFolderSummary *s, const char *uid);
void camel_folder_summary_remove_index(CamelFolderSummary *s, int);
/* remove all items */
void camel_folder_summary_clear(CamelFolderSummary *s);
/* lookup functions */
int camel_folder_summary_count(CamelFolderSummary *);
CamelMessageInfo *camel_folder_summary_index(CamelFolderSummary *, int);
CamelMessageInfo *camel_folder_summary_uid(CamelFolderSummary *, const char *uid);
/* shift content ... */
void camel_folder_summary_offset_content(CamelMessageContentInfo *content, off_t offset);
/* summary formatting utils */
char *camel_folder_summary_format_address(struct _header_raw *h, const char *name);
char *camel_folder_summary_format_string(struct _header_raw *h, const char *name);
/* summary file loading/saving helper functions */
int camel_folder_summary_encode_fixed_int32(FILE *, gint32);
int camel_folder_summary_decode_fixed_int32(FILE *, gint32 *);
int camel_folder_summary_encode_uint32(FILE *, guint32);
int camel_folder_summary_decode_uint32(FILE *, guint32 *);
int camel_folder_summary_encode_time_t(FILE *out, time_t value);
int camel_folder_summary_decode_time_t(FILE *in, time_t *dest);
int camel_folder_summary_encode_off_t(FILE *out, off_t value);
int camel_folder_summary_decode_off_t(FILE *in, off_t *dest);
int camel_folder_summary_encode_string(FILE *, char *);
int camel_folder_summary_decode_string(FILE *, char **);
/* basically like strings, but certain keywords can be compressed and de-cased */
int camel_folder_summary_encode_token(FILE *, char *);
int camel_folder_summary_decode_token(FILE *, char **);
/* message flag operations */
gboolean camel_flag_get(CamelFlag **list, const char *name);
void camel_flag_set(CamelFlag **list, const char *name, gboolean state);
int camel_flag_list_size(CamelFlag **list);
void camel_flag_list_free(CamelFlag **list);
/* message tag operations */
const char *camel_tag_get(CamelTag **list, const char *name);
void camel_tag_set(CamelTag **list, const char *name, const char *value);
int camel_tag_list_size(CamelTag **list);
void camel_tag_list_free(CamelTag **list);
/* message info utils for working with pseudo-messageinfo structures
NOTE: These cannot be added to a real summary object, but suffice for all
other external interfaces that use message info's */
void camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to);
void camel_message_info_free(CamelMessageInfo *mi);
/* accessors */
#ifdef DOESTRV
const char *camel_message_info_string(CamelMessageInfo *mi, int type);
#define camel_message_info_subject(x) camel_message_info_string(m, CAMEL_MESSAGE_INFO_SUBJECT)
#define camel_message_info_from(x) camel_message_info_string(m, CAMEL_MESSAGE_INFO_FROM)
#define camel_message_info_to(x) camel_message_info_string(m, CAMEL_MESSAGE_INFO_TO)
#define camel_message_info_cc(x) camel_message_info_string(m, CAMEL_MESSAGE_INFO_CC)
#define camel_message_info_uid(x) camel_message_info_string(m, CAMEL_MESSAGE_INFO_UID)
void camel_message_info_set_string(CamelMessageInfo *mi, int type, const char *str);
#define camel_message_info_set_subject(x, s) camel_message_info_string(m, CAMEL_MESSAGE_INFO_SUBJECT, s)
#define camel_message_info_set_from(x, s) camel_message_info_string(m, CAMEL_MESSAGE_INFO_FROM, s)
#define camel_message_info_set_to(x, s) camel_message_info_string(m, CAMEL_MESSAGE_INFO_TO, s)
#define camel_message_info_set_cc(x, s) camel_message_info_string(m, CAMEL_MESSAGE_INFO_CC, s)
#define camel_message_info_set_uid(x, s) camel_message_info_string(m, CAMEL_MESSAGE_INFO_UID, s)
#endif
#endif /* ! _CAMEL_FOLDER_SUMMARY_H */