~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to camel/providers/imapx/camel-imapx-store-summary.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
2
/*
 
3
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 
4
 *
 
5
 * Authors: Michael Zucchi <notzed@ximian.com>
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of version 2 of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this program; if not, write to the
 
18
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
19
 * Boston, MA 02110-1301, USA.
 
20
 */
 
21
 
 
22
#ifdef HAVE_CONFIG_H
 
23
#include <config.h>
 
24
#endif
 
25
 
 
26
#include <ctype.h>
 
27
#include <errno.h>
 
28
#include <stdlib.h>
 
29
#include <string.h>
 
30
#include <unistd.h>
 
31
 
 
32
#include "camel-file-utils.h"
 
33
#include "camel-private.h"
 
34
#include "camel-store.h"
 
35
#include "camel-utf8.h"
 
36
#include "camel-imapx-utils.h"
 
37
#include "camel-imapx-store-summary.h"
 
38
 
 
39
#define d(x)
 
40
#define io(x)                   /* io debug */
 
41
 
 
42
#define CAMEL_IMAPX_STORE_SUMMARY_VERSION_0 (0)
 
43
 
 
44
#define CAMEL_IMAPX_STORE_SUMMARY_VERSION (0)
 
45
 
 
46
#define _PRIVATE(o) (((CamelIMAPXStoreSummary *)(o))->priv)
 
47
 
 
48
static gint summary_header_load(CamelStoreSummary *, FILE *);
 
49
static gint summary_header_save(CamelStoreSummary *, FILE *);
 
50
 
 
51
/*static CamelStoreInfo * store_info_new(CamelStoreSummary *, const gchar *);*/
 
52
static CamelStoreInfo * store_info_load(CamelStoreSummary *, FILE *);
 
53
static gint              store_info_save(CamelStoreSummary *, FILE *, CamelStoreInfo *);
 
54
static void              store_info_free(CamelStoreSummary *, CamelStoreInfo *);
 
55
 
 
56
static const gchar *store_info_string(CamelStoreSummary *, const CamelStoreInfo *, gint);
 
57
static void store_info_set_string(CamelStoreSummary *, CamelStoreInfo *, int, const gchar *);
 
58
 
 
59
static void camel_imapx_store_summary_class_init (CamelIMAPXStoreSummaryClass *klass);
 
60
static void camel_imapx_store_summary_init       (CamelIMAPXStoreSummary *obj);
 
61
static void camel_imapx_store_summary_finalise   (CamelObject *obj);
 
62
 
 
63
static CamelStoreSummaryClass *camel_imapx_store_summary_parent;
 
64
 
 
65
static void
 
66
camel_imapx_store_summary_class_init (CamelIMAPXStoreSummaryClass *klass)
 
67
{
 
68
        CamelStoreSummaryClass *ssklass = (CamelStoreSummaryClass *)klass;
 
69
 
 
70
        ssklass->summary_header_load = summary_header_load;
 
71
        ssklass->summary_header_save = summary_header_save;
 
72
 
 
73
        /*ssklass->store_info_new  = store_info_new;*/
 
74
        ssklass->store_info_load = store_info_load;
 
75
        ssklass->store_info_save = store_info_save;
 
76
        ssklass->store_info_free = store_info_free;
 
77
 
 
78
        ssklass->store_info_string = store_info_string;
 
79
        ssklass->store_info_set_string = store_info_set_string;
 
80
}
 
81
 
 
82
static void
 
83
camel_imapx_store_summary_init (CamelIMAPXStoreSummary *s)
 
84
{
 
85
        /*struct _CamelImapStoreSummaryPrivate *p;
 
86
 
 
87
          p = _PRIVATE(s) = g_malloc0(sizeof(*p));*/
 
88
 
 
89
        ((CamelStoreSummary *)s)->store_info_size = sizeof(CamelIMAPXStoreInfo);
 
90
        s->version = CAMEL_IMAPX_STORE_SUMMARY_VERSION;
 
91
}
 
92
 
 
93
static void
 
94
camel_imapx_store_summary_finalise (CamelObject *obj)
 
95
{
 
96
        /*struct _CamelImapStoreSummaryPrivate *p;*/
 
97
        /*CamelImapStoreSummary *s = (CamelImapStoreSummary *)obj;*/
 
98
 
 
99
        /*p = _PRIVATE(obj);
 
100
          g_free(p);*/
 
101
}
 
102
 
 
103
CamelType
 
104
camel_imapx_store_summary_get_type (void)
 
105
{
 
106
        static CamelType type = CAMEL_INVALID_TYPE;
 
107
 
 
108
        if (type == CAMEL_INVALID_TYPE) {
 
109
                camel_imapx_store_summary_parent = (CamelStoreSummaryClass *)camel_store_summary_get_type();
 
110
                type = camel_type_register((CamelType)camel_imapx_store_summary_parent, "CamelIMAPXStoreSummary",
 
111
                                           sizeof (CamelIMAPXStoreSummary),
 
112
                                           sizeof (CamelIMAPXStoreSummaryClass),
 
113
                                           (CamelObjectClassInitFunc) camel_imapx_store_summary_class_init,
 
114
                                           NULL,
 
115
                                           (CamelObjectInitFunc) camel_imapx_store_summary_init,
 
116
                                           (CamelObjectFinalizeFunc) camel_imapx_store_summary_finalise);
 
117
        }
 
118
 
 
119
        return type;
 
120
}
 
121
 
 
122
/**
 
123
 * camel_imapx_store_summary_new:
 
124
 *
 
125
 * Create a new CamelIMAPXStoreSummary object.
 
126
 *
 
127
 * Returns: A new CamelIMAPXStoreSummary widget.
 
128
 **/
 
129
CamelIMAPXStoreSummary *
 
130
camel_imapx_store_summary_new (void)
 
131
{
 
132
        CamelIMAPXStoreSummary *new = CAMEL_IMAPX_STORE_SUMMARY ( camel_object_new (camel_imapx_store_summary_get_type ()));
 
133
 
 
134
        return new;
 
135
}
 
136
 
 
137
/**
 
138
 * camel_imapx_store_summary_full_name:
 
139
 * @s:
 
140
 * @full_name:
 
141
 *
 
142
 * Retrieve a summary item by full name.
 
143
 *
 
144
 * A referenced to the summary item is returned, which may be
 
145
 * ref'd or free'd as appropriate.
 
146
 *
 
147
 * Returns: The summary item, or NULL if the @full_name name
 
148
 * is not available.
 
149
 * It must be freed using camel_store_summary_info_free().
 
150
 **/
 
151
CamelIMAPXStoreInfo *
 
152
camel_imapx_store_summary_full_name(CamelIMAPXStoreSummary *s, const gchar *full_name)
 
153
{
 
154
        gint count, i;
 
155
        CamelIMAPXStoreInfo *info;
 
156
 
 
157
        count = camel_store_summary_count((CamelStoreSummary *)s);
 
158
        for (i=0;i<count;i++) {
 
159
                info = (CamelIMAPXStoreInfo *)camel_store_summary_index((CamelStoreSummary *)s, i);
 
160
                if (info) {
 
161
                        if (strcmp(info->full_name, full_name) == 0)
 
162
                                return info;
 
163
                        camel_store_summary_info_free((CamelStoreSummary *)s, (CamelStoreInfo *)info);
 
164
                }
 
165
        }
 
166
 
 
167
        return NULL;
 
168
}
 
169
 
 
170
gchar *
 
171
camel_imapx_store_summary_full_to_path(CamelIMAPXStoreSummary *s, const gchar *full_name, gchar dir_sep)
 
172
{
 
173
        gchar *path, *p;
 
174
        gint c;
 
175
        const gchar *f;
 
176
 
 
177
        if (dir_sep != '/') {
 
178
                p = path = alloca(strlen(full_name)*3+1);
 
179
                f = full_name;
 
180
                while ((c = *f++ & 0xff)) {
 
181
                        if (c == dir_sep)
 
182
                                *p++ = '/';
 
183
                        else if (c == '/' || c == '%')
 
184
                                p += sprintf(p, "%%%02X", c);
 
185
                        else
 
186
                                *p++ = c;
 
187
                }
 
188
                *p = 0;
 
189
        } else
 
190
                path = (gchar *)full_name;
 
191
 
 
192
        return g_strdup(path);
 
193
}
 
194
 
 
195
static guint32 hexnib(guint32 c)
 
196
{
 
197
        if (c >= '0' && c <= '9')
 
198
                return c-'0';
 
199
        else if (c>='A' && c <= 'Z')
 
200
                return c-'A'+10;
 
201
        else
 
202
                return 0;
 
203
}
 
204
 
 
205
gchar *
 
206
camel_imapx_store_summary_path_to_full(CamelIMAPXStoreSummary *s, const gchar *path, gchar dir_sep)
 
207
{
 
208
        gchar *full, *f;
 
209
        guint32 c, v = 0;
 
210
        const gchar *p;
 
211
        gint state=0;
 
212
        gchar *subpath, *last = NULL;
 
213
        CamelStoreInfo *si;
 
214
        CamelIMAPXStoreNamespace *ns;
 
215
 
 
216
        /* check to see if we have a subpath of path already defined */
 
217
        subpath = alloca(strlen(path)+1);
 
218
        strcpy(subpath, path);
 
219
        do {
 
220
                si = camel_store_summary_path((CamelStoreSummary *)s, subpath);
 
221
                if (si == NULL) {
 
222
                        last = strrchr(subpath, '/');
 
223
                        if (last)
 
224
                                *last = 0;
 
225
                }
 
226
        } while (si == NULL && last);
 
227
 
 
228
        /* path is already present, use the raw version we have */
 
229
        if (si && strlen(subpath) == strlen(path)) {
 
230
                f = g_strdup(camel_imapx_store_info_full_name(s, si));
 
231
                camel_store_summary_info_free((CamelStoreSummary *)s, si);
 
232
                return f;
 
233
        }
 
234
 
 
235
        ns = camel_imapx_store_summary_namespace_find_path(s, path);
 
236
 
 
237
        f = full = alloca(strlen(path)*2+1);
 
238
        if (si)
 
239
                p = path + strlen(subpath);
 
240
        else if (ns)
 
241
                p = path + strlen(ns->path);
 
242
        else
 
243
                p = path;
 
244
 
 
245
        while ((c = camel_utf8_getc((const guchar **)&p))) {
 
246
                switch (state) {
 
247
                case 0:
 
248
                        if (c == '%')
 
249
                                state = 1;
 
250
                        else {
 
251
                                if (c == '/')
 
252
                                        c = dir_sep;
 
253
                                camel_utf8_putc((guchar **) &f, c);
 
254
                        }
 
255
                        break;
 
256
                case 1:
 
257
                        state = 2;
 
258
                        v = hexnib(c)<<4;
 
259
                        break;
 
260
                case 2:
 
261
                        state = 0;
 
262
                        v |= hexnib(c);
 
263
                        camel_utf8_putc((guchar **) &f, v);
 
264
                        break;
 
265
                }
 
266
        }
 
267
        camel_utf8_putc((guchar **) &f, c);
 
268
 
 
269
        /* merge old path part if required */
 
270
        f = g_strdup(full);
 
271
        if (si) {
 
272
                full = g_strdup_printf("%s%s", camel_imapx_store_info_full_name(s, si), f);
 
273
                g_free(f);
 
274
                camel_store_summary_info_free((CamelStoreSummary *)s, si);
 
275
                f = full;
 
276
        } else if (ns) {
 
277
                full = g_strdup_printf("%s%s", ns->full_name, f);
 
278
                g_free(f);
 
279
                f = full;
 
280
        }
 
281
 
 
282
        return f;
 
283
}
 
284
 
 
285
CamelIMAPXStoreInfo *
 
286
camel_imapx_store_summary_add_from_full(CamelIMAPXStoreSummary *s, const gchar *full, gchar dir_sep)
 
287
{
 
288
        CamelIMAPXStoreInfo *info;
 
289
        gchar *pathu8, *prefix;
 
290
        gint len;
 
291
        gchar *full_name;
 
292
        CamelIMAPXStoreNamespace *ns;
 
293
 
 
294
        d(printf("adding full name '%s' '%c'\n", full, dir_sep));
 
295
 
 
296
        len = strlen(full);
 
297
        full_name = alloca(len+1);
 
298
        strcpy(full_name, full);
 
299
        if (full_name[len-1] == dir_sep)
 
300
                full_name[len-1] = 0;
 
301
 
 
302
        info = camel_imapx_store_summary_full_name(s, full_name);
 
303
        if (info) {
 
304
                camel_store_summary_info_free((CamelStoreSummary *)s, (CamelStoreInfo *)info);
 
305
                d(printf("  already there\n"));
 
306
                return info;
 
307
        }
 
308
 
 
309
        ns = camel_imapx_store_summary_namespace_find_full(s, full_name);
 
310
        if (ns) {
 
311
                d(printf("(found namespace for '%s' ns '%s') ", full_name, ns->path));
 
312
                len = strlen(ns->full_name);
 
313
                if (len >= strlen(full_name)) {
 
314
                        pathu8 = g_strdup(ns->path);
 
315
                } else {
 
316
                        if (full_name[len] == ns->sep)
 
317
                                len++;
 
318
 
 
319
                        prefix = camel_imapx_store_summary_full_to_path(s, full_name+len, ns->sep);
 
320
                        if (*ns->path) {
 
321
                                pathu8 = g_strdup_printf ("%s/%s", ns->path, prefix);
 
322
                                g_free (prefix);
 
323
                        } else {
 
324
                                pathu8 = prefix;
 
325
                        }
 
326
                }
 
327
                d(printf(" (pathu8 = '%s')", pathu8));
 
328
        } else {
 
329
                d(printf("(Cannot find namespace for '%s')\n", full_name));
 
330
                pathu8 = camel_imapx_store_summary_full_to_path(s, full_name, dir_sep);
 
331
        }
 
332
 
 
333
        info = (CamelIMAPXStoreInfo *)camel_store_summary_add_from_path((CamelStoreSummary *)s, pathu8);
 
334
        if (info) {
 
335
                d(printf("  '%s' -> '%s'\n", pathu8, full_name));
 
336
                camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_IMAPX_STORE_INFO_FULL_NAME, full_name);
 
337
 
 
338
                if (!g_ascii_strcasecmp(full_name, "inbox"))
 
339
                        info->info.flags |= CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_TYPE_INBOX;
 
340
        } else {
 
341
                d(printf("  failed\n"));
 
342
        }
 
343
 
 
344
        return info;
 
345
}
 
346
 
 
347
/* should this be const? */
 
348
/* TODO: deprecate/merge this function with path_to_full */
 
349
gchar *
 
350
camel_imapx_store_summary_full_from_path(CamelIMAPXStoreSummary *s, const gchar *path)
 
351
{
 
352
        CamelIMAPXStoreNamespace *ns;
 
353
        gchar *name = NULL;
 
354
 
 
355
        ns = camel_imapx_store_summary_namespace_find_path(s, path);
 
356
        if (ns)
 
357
                name = camel_imapx_store_summary_path_to_full(s, path, ns->sep);
 
358
 
 
359
        d(printf("looking up path %s -> %s\n", path, name?name:"not found"));
 
360
 
 
361
        return name;
 
362
}
 
363
 
 
364
/* TODO: this api needs some more work */
 
365
CamelIMAPXStoreNamespace *camel_imapx_store_summary_namespace_new(CamelIMAPXStoreSummary *s, const gchar *full_name, gchar dir_sep)
 
366
{
 
367
        CamelIMAPXStoreNamespace *ns;
 
368
        gchar *p, *o, c;
 
369
        gint len;
 
370
 
 
371
        ns = g_malloc0(sizeof(*ns));
 
372
        ns->full_name = g_strdup(full_name);
 
373
        len = strlen(ns->full_name)-1;
 
374
        if (len >= 0 && ns->full_name[len] == dir_sep)
 
375
                ns->full_name[len] = 0;
 
376
        ns->sep = dir_sep;
 
377
 
 
378
        o = p = ns->path = camel_imapx_store_summary_full_to_path(s, ns->full_name, dir_sep);
 
379
        while ((c = *p++)) {
 
380
                if (c != '#') {
 
381
                        if (c == '/')
 
382
                                c = '.';
 
383
                        *o++ = c;
 
384
                }
 
385
        }
 
386
        *o = 0;
 
387
 
 
388
        return ns;
 
389
}
 
390
 
 
391
void camel_imapx_store_summary_namespace_set(CamelIMAPXStoreSummary *s, CamelIMAPXStoreNamespace *ns)
 
392
{
 
393
        d(printf("Setting namesapce to '%s' '%c' -> '%s'\n", ns->full_name, ns->sep, ns->path));
 
394
 
 
395
        /* CHEN not needed  */
 
396
        camel_store_summary_touch((CamelStoreSummary *)s);
 
397
}
 
398
 
 
399
CamelIMAPXStoreNamespace *
 
400
camel_imapx_store_summary_namespace_find_path(CamelIMAPXStoreSummary *s, const gchar *path)
 
401
{
 
402
        gint len;
 
403
        CamelIMAPXStoreNamespace *ns;
 
404
 
 
405
        /* NB: this currently only compares against 1 namespace, in future compare against others */
 
406
        /* CHEN TODO */
 
407
        ns = s->namespaces->personal;
 
408
        while (ns) {
 
409
                len = strlen(ns->path);
 
410
                if (len == 0
 
411
                    || (strncmp(ns->path, path, len) == 0
 
412
                        && (path[len] == '/' || path[len] == 0)))
 
413
                        break;
 
414
                ns = NULL;
 
415
        }
 
416
 
 
417
        /* have a default? */
 
418
        return ns;
 
419
}
 
420
 
 
421
CamelIMAPXStoreNamespace *
 
422
camel_imapx_store_summary_namespace_find_full(CamelIMAPXStoreSummary *s, const gchar *full)
 
423
{
 
424
        gint len = 0;
 
425
        CamelIMAPXStoreNamespace *ns;
 
426
 
 
427
        /* NB: this currently only compares against 1 namespace, in future compare against others */
 
428
        /* CHEN TODO */
 
429
        ns = s->namespaces->personal;
 
430
        while (ns) {
 
431
                if (ns->full_name)
 
432
                        len = strlen(ns->full_name);
 
433
                d(printf("find_full: comparing namespace '%s' to name '%s'\n", ns->full_name, full));
 
434
                if (len == 0
 
435
                    || (strncmp(ns->full_name, full, len) == 0
 
436
                        && (full[len] == ns->sep || full[len] == 0)))
 
437
                        break;
 
438
                ns = NULL;
 
439
        }
 
440
 
 
441
        /* have a default? */
 
442
        return ns;
 
443
}
 
444
 
 
445
static CamelIMAPXNamespaceList *
 
446
namespace_load(CamelStoreSummary *s, FILE *in)
 
447
{
 
448
        CamelIMAPXStoreNamespace *ns, *tail;
 
449
        CamelIMAPXNamespaceList *nsl;
 
450
        guint32 i, j;
 
451
        gint32 n;
 
452
 
 
453
        nsl = g_malloc0(sizeof(CamelIMAPXNamespaceList));
 
454
        nsl->personal = NULL;
 
455
        nsl->shared = NULL;
 
456
        nsl->other = NULL;
 
457
 
 
458
        for (j = 0; j < 3; j++) {
 
459
                switch (j) {
 
460
                case 0:
 
461
                        tail = (CamelIMAPXStoreNamespace *) &nsl->personal;
 
462
                        break;
 
463
                case 1:
 
464
                        tail = (CamelIMAPXStoreNamespace *) &nsl->shared;
 
465
                        break;
 
466
                case 2:
 
467
                        tail = (CamelIMAPXStoreNamespace *) &nsl->other;
 
468
                        break;
 
469
                }
 
470
 
 
471
                if (camel_file_util_decode_fixed_int32 (in, &n) == -1)
 
472
                        goto exception;
 
473
 
 
474
                for (i = 0; i < n; i++) {
 
475
                        guint32 sep;
 
476
                        gchar *path;
 
477
                        gchar *full_name;
 
478
 
 
479
                        if (camel_file_util_decode_string (in, &path) == -1)
 
480
                                goto exception;
 
481
 
 
482
                        if (camel_file_util_decode_string (in, &full_name) == -1) {
 
483
                                g_free (path);
 
484
                                goto exception;
 
485
                        }
 
486
 
 
487
                        if (camel_file_util_decode_uint32 (in, &sep) == -1) {
 
488
                                g_free (path);
 
489
                                g_free (full_name);
 
490
                                goto exception;
 
491
                        }
 
492
 
 
493
                        tail->next = ns = g_malloc (sizeof (CamelIMAPXStoreNamespace));
 
494
                        ns->sep = sep;
 
495
                        ns->path = path;
 
496
                        ns->full_name = full_name;
 
497
                        ns->next = NULL;
 
498
                        tail = ns;
 
499
                }
 
500
        }
 
501
 
 
502
        return nsl;
 
503
exception:
 
504
        camel_imapx_namespace_list_clear (nsl);
 
505
 
 
506
        return NULL;
 
507
}
 
508
 
 
509
static gint
 
510
namespace_save(CamelStoreSummary *s, FILE *out, CamelIMAPXNamespaceList *nsl)
 
511
{
 
512
        CamelIMAPXStoreNamespace *ns, *cur = NULL;
 
513
        guint32 i, n;
 
514
 
 
515
        for (i = 0; i < 3; i++) {
 
516
                switch (i) {
 
517
                case 0:
 
518
                        cur = nsl->personal;
 
519
                        break;
 
520
                case 1:
 
521
                        cur = nsl->shared;
 
522
                        break;
 
523
                case 2:
 
524
                        cur = nsl->other;
 
525
                        break;
 
526
                }
 
527
 
 
528
                for (ns = cur, n = 0; ns; n++)
 
529
                        ns = ns->next;
 
530
 
 
531
                if (camel_file_util_encode_fixed_int32 (out, n) == -1)
 
532
                        return -1;
 
533
 
 
534
                ns = cur;
 
535
                while (ns != NULL) {
 
536
                        if (camel_file_util_encode_string (out, ns->path) == -1)
 
537
                                return -1;
 
538
 
 
539
                        if (camel_file_util_encode_string (out, ns->full_name) == -1)
 
540
                                return -1;
 
541
 
 
542
                        if (camel_file_util_encode_uint32 (out, ns->sep) == -1)
 
543
                                return -1;
 
544
 
 
545
                        ns = ns->next;
 
546
                }
 
547
        }
 
548
 
 
549
        return 0;
 
550
}
 
551
 
 
552
static gint
 
553
summary_header_load(CamelStoreSummary *s, FILE *in)
 
554
{
 
555
        CamelIMAPXStoreSummary *is = (CamelIMAPXStoreSummary *)s;
 
556
        gint32 version, capabilities;
 
557
 
 
558
        camel_imapx_namespace_list_clear (is->namespaces);
 
559
 
 
560
        if (camel_imapx_store_summary_parent->summary_header_load((CamelStoreSummary *)s, in) == -1
 
561
            || camel_file_util_decode_fixed_int32(in, &version) == -1)
 
562
                return -1;
 
563
 
 
564
        is->version = version;
 
565
 
 
566
        if (version < CAMEL_IMAPX_STORE_SUMMARY_VERSION_0) {
 
567
                g_warning("Store summary header version too low");
 
568
                return -1;
 
569
        }
 
570
 
 
571
        /* note file format can be expanded to contain more namespaces, but only 1 at the moment */
 
572
        if (camel_file_util_decode_fixed_int32(in, &capabilities) == -1)
 
573
                return -1;
 
574
 
 
575
        is->capabilities = capabilities;
 
576
 
 
577
        /* namespaces */
 
578
        if ((is->namespaces = namespace_load(s, in)) == NULL)
 
579
                return -1;
 
580
 
 
581
        return 0;
 
582
}
 
583
 
 
584
static gint
 
585
summary_header_save(CamelStoreSummary *s, FILE *out)
 
586
{
 
587
        CamelIMAPXStoreSummary *is = (CamelIMAPXStoreSummary *)s;
 
588
 
 
589
        /* always write as latest version */
 
590
        if (camel_imapx_store_summary_parent->summary_header_save((CamelStoreSummary *)s, out) == -1
 
591
            || camel_file_util_encode_fixed_int32(out, CAMEL_IMAPX_STORE_SUMMARY_VERSION) == -1
 
592
            || camel_file_util_encode_fixed_int32(out, is->capabilities) == -1)
 
593
                return -1;
 
594
 
 
595
        if (is->namespaces && namespace_save(s, out, is->namespaces) == -1)
 
596
                return -1;
 
597
 
 
598
        return 0;
 
599
}
 
600
 
 
601
static CamelStoreInfo *
 
602
store_info_load(CamelStoreSummary *s, FILE *in)
 
603
{
 
604
        CamelIMAPXStoreInfo *mi;
 
605
 
 
606
        mi = (CamelIMAPXStoreInfo *)camel_imapx_store_summary_parent->store_info_load(s, in);
 
607
        if (mi) {
 
608
                if (camel_file_util_decode_string(in, &mi->full_name) == -1) {
 
609
                        camel_store_summary_info_free(s, (CamelStoreInfo *)mi);
 
610
                        mi = NULL;
 
611
                } else {
 
612
                        /* NB: this is done again for compatability */
 
613
                        if (g_ascii_strcasecmp(mi->full_name, "inbox") == 0)
 
614
                                mi->info.flags |= CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_TYPE_INBOX;
 
615
                }
 
616
        }
 
617
 
 
618
        return (CamelStoreInfo *)mi;
 
619
}
 
620
 
 
621
static gint
 
622
store_info_save(CamelStoreSummary *s, FILE *out, CamelStoreInfo *mi)
 
623
{
 
624
        CamelIMAPXStoreInfo *isi = (CamelIMAPXStoreInfo *)mi;
 
625
 
 
626
        if (camel_imapx_store_summary_parent->store_info_save(s, out, mi) == -1
 
627
            || camel_file_util_encode_string(out, isi->full_name) == -1)
 
628
                return -1;
 
629
 
 
630
        return 0;
 
631
}
 
632
 
 
633
static void
 
634
store_info_free(CamelStoreSummary *s, CamelStoreInfo *mi)
 
635
{
 
636
        CamelIMAPXStoreInfo *isi = (CamelIMAPXStoreInfo *)mi;
 
637
 
 
638
        g_free(isi->full_name);
 
639
        camel_imapx_store_summary_parent->store_info_free(s, mi);
 
640
}
 
641
 
 
642
static const gchar *
 
643
store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, gint type)
 
644
{
 
645
        CamelIMAPXStoreInfo *isi = (CamelIMAPXStoreInfo *)mi;
 
646
 
 
647
        /* FIXME: Locks? */
 
648
 
 
649
        g_assert (mi != NULL);
 
650
 
 
651
        switch (type) {
 
652
        case CAMEL_IMAPX_STORE_INFO_FULL_NAME:
 
653
                return isi->full_name;
 
654
        default:
 
655
                return camel_imapx_store_summary_parent->store_info_string(s, mi, type);
 
656
        }
 
657
}
 
658
 
 
659
static void
 
660
store_info_set_string(CamelStoreSummary *s, CamelStoreInfo *mi, gint type, const gchar *str)
 
661
{
 
662
        CamelIMAPXStoreInfo *isi = (CamelIMAPXStoreInfo *)mi;
 
663
 
 
664
        g_assert(mi != NULL);
 
665
 
 
666
        switch (type) {
 
667
        case CAMEL_IMAPX_STORE_INFO_FULL_NAME:
 
668
                d(printf("Set full name %s -> %s\n", isi->full_name, str));
 
669
                CAMEL_STORE_SUMMARY_LOCK(s, summary_lock);
 
670
                g_free(isi->full_name);
 
671
                isi->full_name = g_strdup(str);
 
672
                CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock);
 
673
                break;
 
674
        default:
 
675
                camel_imapx_store_summary_parent->store_info_set_string(s, mi, type, str);
 
676
                break;
 
677
        }
 
678
}
 
679
 
 
680
void
 
681
camel_imapx_store_summary_set_namespaces (CamelIMAPXStoreSummary *summary, const CamelIMAPXNamespaceList *nsl)
 
682
{
 
683
        if (summary->namespaces)
 
684
                camel_imapx_namespace_list_clear (summary->namespaces);
 
685
        summary->namespaces = camel_imapx_namespace_list_copy (summary->namespaces);
 
686
}