1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2000 Ximian Inc.
6 * Michael Zucchi <notzed@ximian.com>
7 * Dan Winship <danw@ximian.com>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
34 #include "camel-file-utils.h"
36 #include "camel-imap-summary.h"
37 #include "camel-imap-utils.h"
39 #define CAMEL_IMAP_SUMMARY_VERSION (3)
41 static int summary_header_load (CamelFolderSummary *, FILE *);
42 static int summary_header_save (CamelFolderSummary *, FILE *);
44 static CamelMessageInfo *message_info_load (CamelFolderSummary *s, FILE *in);
45 static int message_info_save (CamelFolderSummary *s, FILE *out,
46 CamelMessageInfo *info);
47 static gboolean info_set_user_tag(CamelMessageInfo *info, const char *name, const char *value);
48 static CamelMessageContentInfo *content_info_load (CamelFolderSummary *s, FILE *in);
49 static int content_info_save (CamelFolderSummary *s, FILE *out,
50 CamelMessageContentInfo *info);
52 static void camel_imap_summary_class_init (CamelImapSummaryClass *klass);
53 static void camel_imap_summary_init (CamelImapSummary *obj);
55 static CamelFolderSummaryClass *camel_imap_summary_parent;
58 camel_imap_summary_get_type (void)
60 static CamelType type = CAMEL_INVALID_TYPE;
62 if (type == CAMEL_INVALID_TYPE) {
63 type = camel_type_register(
64 camel_folder_summary_get_type(), "CamelImapSummary",
65 sizeof (CamelImapSummary),
66 sizeof (CamelImapSummaryClass),
67 (CamelObjectClassInitFunc) camel_imap_summary_class_init,
69 (CamelObjectInitFunc) camel_imap_summary_init,
76 static CamelMessageInfo *
77 imap_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
79 CamelImapMessageInfo *to;
80 const CamelImapMessageInfo *from = (const CamelImapMessageInfo *)mi;
82 to = (CamelImapMessageInfo *)camel_imap_summary_parent->message_info_clone(s, mi);
83 to->server_flags = from->server_flags;
85 /* FIXME: parent clone should do this */
86 to->info.content = camel_folder_summary_content_info_new(s);
88 return (CamelMessageInfo *)to;
92 camel_imap_summary_class_init (CamelImapSummaryClass *klass)
94 CamelFolderSummaryClass *cfs_class = (CamelFolderSummaryClass *) klass;
96 camel_imap_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs (camel_folder_summary_get_type()));
98 cfs_class->message_info_clone = imap_message_info_clone;
100 cfs_class->summary_header_load = summary_header_load;
101 cfs_class->summary_header_save = summary_header_save;
102 cfs_class->message_info_load = message_info_load;
103 cfs_class->message_info_save = message_info_save;
104 cfs_class->content_info_load = content_info_load;
105 cfs_class->content_info_save = content_info_save;
107 cfs_class->info_set_user_tag = info_set_user_tag;
111 camel_imap_summary_init (CamelImapSummary *obj)
113 CamelFolderSummary *s = (CamelFolderSummary *)obj;
115 /* subclasses need to set the right instance data sizes */
116 s->message_info_size = sizeof(CamelImapMessageInfo);
117 s->content_info_size = sizeof(CamelImapMessageContentInfo);
121 * camel_imap_summary_new:
122 * @folder: Parent folder.
123 * @filename: the file to store the summary in.
125 * This will create a new CamelImapSummary object and read in the
126 * summary data from disk, if it exists.
128 * Return value: A new CamelImapSummary object.
131 camel_imap_summary_new (struct _CamelFolder *folder, const char *filename)
133 CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (camel_object_new (camel_imap_summary_get_type ()));
135 summary->folder = folder;
137 camel_folder_summary_set_build_content (summary, TRUE);
138 camel_folder_summary_set_filename (summary, filename);
140 if (camel_folder_summary_load (summary) == -1) {
141 camel_folder_summary_clear (summary);
142 camel_folder_summary_touch (summary);
149 summary_header_load (CamelFolderSummary *s, FILE *in)
151 CamelImapSummary *ims = CAMEL_IMAP_SUMMARY (s);
153 if (camel_imap_summary_parent->summary_header_load (s, in) == -1)
157 if (s->version == 0x30c)
158 return camel_file_util_decode_uint32(in, &ims->validity);
161 if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1)
164 if (ims->version == 2) {
165 /* Version 2: for compat with version 2 of the imap4 summary files */
168 if (camel_file_util_decode_fixed_int32 (in, &have_mlist) == -1)
172 if (camel_file_util_decode_fixed_int32(in, &ims->validity) == -1)
175 if (ims->version > CAMEL_IMAP_SUMMARY_VERSION) {
176 g_warning("Unkown summary version\n");
185 summary_header_save (CamelFolderSummary *s, FILE *out)
187 CamelImapSummary *ims = CAMEL_IMAP_SUMMARY(s);
189 if (camel_imap_summary_parent->summary_header_save (s, out) == -1)
192 camel_file_util_encode_fixed_int32(out, CAMEL_IMAP_SUMMARY_VERSION);
194 return camel_file_util_encode_fixed_int32(out, ims->validity);
197 /* We snoop the setting of the 'label' tag, so we can store it on
198 the server, also in a mozilla compatiable way as a bonus */
200 label_to_flags(CamelImapMessageInfo *info)
204 flags = imap_label_to_flags((CamelMessageInfo *)info);
205 if ((info->info.flags & CAMEL_IMAP_MESSAGE_LABEL_MASK) != flags)
206 info->info.flags = (info->info.flags & ~CAMEL_IMAP_MESSAGE_LABEL_MASK) | flags | CAMEL_MESSAGE_FOLDER_FLAGGED;
209 static CamelMessageInfo *
210 message_info_load (CamelFolderSummary *s, FILE *in)
212 CamelMessageInfo *info;
213 CamelImapMessageInfo *iinfo;
215 info = camel_imap_summary_parent->message_info_load (s, in);
217 iinfo = (CamelImapMessageInfo *)info;
219 if (camel_file_util_decode_uint32 (in, &iinfo->server_flags) == -1)
222 label_to_flags(iinfo);
227 camel_message_info_free(info);
232 message_info_save (CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
234 CamelImapMessageInfo *iinfo = (CamelImapMessageInfo *)info;
236 if (camel_imap_summary_parent->message_info_save (s, out, info) == -1)
239 return camel_file_util_encode_uint32 (out, iinfo->server_flags);
243 info_set_user_tag(CamelMessageInfo *info, const char *name, const char *value)
247 res = camel_imap_summary_parent->info_set_user_tag(info, name, value);
249 if (!strcmp(name, "label"))
250 label_to_flags((CamelImapMessageInfo *)info);
255 static CamelMessageContentInfo *
256 content_info_load (CamelFolderSummary *s, FILE *in)
259 return camel_imap_summary_parent->content_info_load (s, in);
261 return camel_folder_summary_content_info_new (s);
265 content_info_save (CamelFolderSummary *s, FILE *out,
266 CamelMessageContentInfo *info)
270 return camel_imap_summary_parent->content_info_save (s, out, info);
272 return fputc (0, out);
276 camel_imap_summary_add_offline (CamelFolderSummary *summary, const char *uid,
277 CamelMimeMessage *message,
278 const CamelMessageInfo *info)
280 CamelImapMessageInfo *mi;
281 const CamelFlag *flag;
284 /* Create summary entry */
285 mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message);
287 /* Copy flags 'n' tags */
288 mi->info.flags = camel_message_info_flags(info);
290 flag = camel_message_info_user_flags(info);
292 camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE);
295 tag = camel_message_info_user_tags(info);
297 camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value);
301 mi->info.size = camel_message_info_size(info);
302 mi->info.uid = g_strdup (uid);
306 camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
310 camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, const char *uid,
311 const CamelMessageInfo *info)
313 CamelImapMessageInfo *mi;
315 mi = camel_message_info_clone(info);
316 mi->info.uid = g_strdup(uid);
320 camel_folder_summary_add (summary, (CamelMessageInfo *)mi);