Extending test-client-custom-summary to try e_book_client_get_contacts_uids()
[platform/upstream/evolution-data-server.git] / camel / camel-index.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */
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 #include <sys/stat.h>
32
33 #include "camel-index.h"
34 #include "camel-object.h"
35
36 #define w(x)
37 #define io(x)
38 #define d(x) /*(printf ("%s (%d): ", __FILE__, __LINE__),(x))*/
39
40 #define CAMEL_INDEX_VERSION (0x01)
41
42 #define CAMEL_INDEX_GET_PRIVATE(obj) \
43         (G_TYPE_INSTANCE_GET_PRIVATE \
44         ((obj), CAMEL_TYPE_INDEX, CamelIndexPrivate))
45
46 struct _CamelIndexPrivate {
47         gpointer dummy;
48 };
49
50 /* ********************************************************************** */
51 /* CamelIndex */
52 /* ********************************************************************** */
53
54 G_DEFINE_TYPE (CamelIndex, camel_index, CAMEL_TYPE_OBJECT)
55
56 static void
57 index_finalize (GObject *object)
58 {
59         CamelIndex *index = CAMEL_INDEX (object);
60
61         g_free (index->path);
62
63         /* Chain up to parent's finalize () method. */
64         G_OBJECT_CLASS (camel_index_parent_class)->finalize (object);
65 }
66
67 static void
68 camel_index_class_init (CamelIndexClass *class)
69 {
70         GObjectClass *object_class;
71
72         g_type_class_add_private (class, sizeof (CamelIndexPrivate));
73
74         object_class = G_OBJECT_CLASS (class);
75         object_class->finalize = index_finalize;
76 }
77
78 static void
79 camel_index_init (CamelIndex *index)
80 {
81         index->priv = CAMEL_INDEX_GET_PRIVATE (index);
82         index->version = CAMEL_INDEX_VERSION;
83 }
84
85 CamelIndex *
86 camel_index_new (const gchar *path,
87                  gint flags)
88 {
89         CamelIndex *idx;
90
91         idx = g_object_new (CAMEL_TYPE_INDEX, NULL);
92         camel_index_construct (idx, path, flags);
93
94         return idx;
95 }
96
97 void
98 camel_index_construct (CamelIndex *idx,
99                        const gchar *path,
100                        gint flags)
101 {
102         g_free (idx->path);
103         idx->path = g_strdup_printf ("%s.index", path);
104         idx->flags = flags;
105 }
106
107 gint
108 camel_index_rename (CamelIndex *idx,
109                     const gchar *path)
110 {
111         CamelIndexClass *class;
112
113         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
114
115         class = CAMEL_INDEX_GET_CLASS (idx);
116         g_return_val_if_fail (class->rename != NULL, -1);
117
118         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
119                 return class->rename (idx, path);
120         else {
121                 errno = ENOENT;
122                 return -1;
123         }
124 }
125
126 /**
127  * camel_index_set_normalize:
128  * @index: a #CamelIndex
129  * @func: normalization function
130  * @data: user data for @func
131  *
132  * Since: 2.32
133  **/
134 void
135 camel_index_set_normalize (CamelIndex *index,
136                            CamelIndexNorm func,
137                            gpointer data)
138 {
139         g_return_if_fail (CAMEL_IS_INDEX (index));
140
141         index->normalize = func;
142         index->normalize_data = data;
143 }
144
145 gint
146 camel_index_sync (CamelIndex *idx)
147 {
148         CamelIndexClass *class;
149
150         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
151
152         class = CAMEL_INDEX_GET_CLASS (idx);
153         g_return_val_if_fail (class->sync != NULL, -1);
154
155         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
156                 return class->sync (idx);
157         else {
158                 errno = ENOENT;
159                 return -1;
160         }
161 }
162
163 gint
164 camel_index_compress (CamelIndex *idx)
165 {
166         CamelIndexClass *class;
167
168         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
169
170         class = CAMEL_INDEX_GET_CLASS (idx);
171         g_return_val_if_fail (class->compress != NULL, -1);
172
173         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
174                 return class->compress (idx);
175         else {
176                 errno = ENOENT;
177                 return -1;
178         }
179 }
180
181 gint
182 camel_index_delete (CamelIndex *idx)
183 {
184         CamelIndexClass *class;
185         gint ret;
186
187         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
188
189         class = CAMEL_INDEX_GET_CLASS (idx);
190         g_return_val_if_fail (class->delete_ != NULL, -1);
191
192         if ((idx->state & CAMEL_INDEX_DELETED) == 0) {
193                 ret = class->delete_ (idx);
194                 idx->state |= CAMEL_INDEX_DELETED;
195         } else {
196                 errno = ENOENT;
197                 ret = -1;
198         }
199
200         return ret;
201 }
202
203 gint
204 camel_index_has_name (CamelIndex *idx,
205                       const gchar *name)
206 {
207         CamelIndexClass *class;
208
209         g_return_val_if_fail (CAMEL_IS_INDEX (idx), FALSE);
210
211         class = CAMEL_INDEX_GET_CLASS (idx);
212         g_return_val_if_fail (class->has_name != NULL, FALSE);
213
214         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
215                 return class->has_name (idx, name);
216         else
217                 return FALSE;
218 }
219
220 CamelIndexName *
221 camel_index_add_name (CamelIndex *idx,
222                       const gchar *name)
223 {
224         CamelIndexClass *class;
225
226         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
227
228         class = CAMEL_INDEX_GET_CLASS (idx);
229         g_return_val_if_fail (class->add_name != NULL, NULL);
230
231         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
232                 return class->add_name (idx, name);
233         else
234                 return NULL;
235 }
236
237 gint
238 camel_index_write_name (CamelIndex *idx,
239                         CamelIndexName *idn)
240 {
241         CamelIndexClass *class;
242
243         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
244
245         class = CAMEL_INDEX_GET_CLASS (idx);
246         g_return_val_if_fail (class->write_name != NULL, -1);
247
248         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
249                 return class->write_name (idx, idn);
250         else {
251                 errno = ENOENT;
252                 return -1;
253         }
254 }
255
256 CamelIndexCursor *
257 camel_index_find_name (CamelIndex *idx,
258                        const gchar *name)
259 {
260         CamelIndexClass *class;
261
262         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
263
264         class = CAMEL_INDEX_GET_CLASS (idx);
265         g_return_val_if_fail (class->find_name != NULL, NULL);
266
267         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
268                 return class->find_name (idx, name);
269         else
270                 return NULL;
271 }
272
273 void
274 camel_index_delete_name (CamelIndex *idx,
275                          const gchar *name)
276 {
277         CamelIndexClass *class;
278
279         g_return_if_fail (CAMEL_IS_INDEX (idx));
280
281         class = CAMEL_INDEX_GET_CLASS (idx);
282         g_return_if_fail (class->delete_name != NULL);
283
284         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
285                 class->delete_name (idx, name);
286 }
287
288 CamelIndexCursor *
289 camel_index_find (CamelIndex *idx,
290                   const gchar *word)
291 {
292         CamelIndexClass *class;
293         CamelIndexCursor *ret;
294         gchar *b = (gchar *) word;
295
296         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
297
298         class = CAMEL_INDEX_GET_CLASS (idx);
299         g_return_val_if_fail (class->find != NULL, NULL);
300
301         if ((idx->state & CAMEL_INDEX_DELETED) != 0)
302                 return NULL;
303
304         if (idx->normalize)
305                 b = idx->normalize (idx, word, idx->normalize_data);
306
307         ret = class->find (idx, b);
308
309         if (b != word)
310                 g_free (b);
311
312         return ret;
313 }
314
315 CamelIndexCursor *
316 camel_index_words (CamelIndex *idx)
317 {
318         CamelIndexClass *class;
319
320         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
321
322         class = CAMEL_INDEX_GET_CLASS (idx);
323         g_return_val_if_fail (class->words != NULL, NULL);
324
325         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
326                 return class->words (idx);
327         else
328                 return NULL;
329 }
330
331 CamelIndexCursor *
332 camel_index_names (CamelIndex *idx)
333 {
334         CamelIndexClass *class;
335
336         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
337
338         class = CAMEL_INDEX_GET_CLASS (idx);
339         g_return_val_if_fail (class->names != NULL, NULL);
340
341         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
342                 return class->names (idx);
343         else
344                 return NULL;
345 }
346
347 /* ********************************************************************** */
348 /* CamelIndexName */
349 /* ********************************************************************** */
350
351 G_DEFINE_TYPE (CamelIndexName, camel_index_name, CAMEL_TYPE_OBJECT)
352
353 static void
354 index_name_dispose (GObject *object)
355 {
356         CamelIndexName *index_name = CAMEL_INDEX_NAME (object);
357
358         if (index_name->index != NULL) {
359                 g_object_unref (index_name->index);
360                 index_name->index = NULL;
361         }
362
363         /* Chain up to parent's dispose () method. */
364         G_OBJECT_CLASS (camel_index_name_parent_class)->dispose (object);
365 }
366
367 static void
368 camel_index_name_class_init (CamelIndexNameClass *class)
369 {
370         GObjectClass *object_class;
371
372         object_class = G_OBJECT_CLASS (class);
373         object_class->dispose = index_name_dispose;
374 }
375
376 static void
377 camel_index_name_init (CamelIndexName *index_name)
378 {
379 }
380
381 CamelIndexName *
382 camel_index_name_new (CamelIndex *idx,
383                       const gchar *name)
384 {
385         CamelIndexName *idn;
386
387         idn = g_object_new (CAMEL_TYPE_INDEX_NAME, NULL);
388         idn->index = g_object_ref (idx);
389
390         return idn;
391 }
392
393 void
394 camel_index_name_add_word (CamelIndexName *idn,
395                            const gchar *word)
396 {
397         CamelIndexNameClass *class;
398         gchar *b = (gchar *) word;
399
400         g_return_if_fail (CAMEL_IS_INDEX_NAME (idn));
401
402         class = CAMEL_INDEX_NAME_GET_CLASS (idn);
403         g_return_if_fail (class->add_word != NULL);
404
405         if (idn->index->normalize)
406                 b = idn->index->normalize (idn->index, word, idn->index->normalize_data);
407
408         class->add_word (idn, b);
409
410         if (b != word)
411                 g_free (b);
412 }
413
414 gsize
415 camel_index_name_add_buffer (CamelIndexName *idn,
416                              const gchar *buffer,
417                              gsize len)
418 {
419         CamelIndexNameClass *class;
420
421         g_return_val_if_fail (CAMEL_IS_INDEX_NAME (idn), 0);
422
423         class = CAMEL_INDEX_NAME_GET_CLASS (idn);
424         g_return_val_if_fail (class->add_buffer != NULL, 0);
425
426         return class->add_buffer (idn, buffer, len);
427 }
428
429 /* ********************************************************************** */
430 /* CamelIndexCursor */
431 /* ********************************************************************** */
432
433 G_DEFINE_TYPE (CamelIndexCursor, camel_index_cursor, CAMEL_TYPE_OBJECT)
434
435 static void
436 index_cursor_dispose (GObject *object)
437 {
438         CamelIndexCursor *index_cursor = CAMEL_INDEX_CURSOR (object);
439
440         if (index_cursor->index != NULL) {
441                 g_object_unref (index_cursor->index);
442                 index_cursor->index = NULL;
443         }
444
445         /* Chain up to parent's dispose () method. */
446         G_OBJECT_CLASS (camel_index_cursor_parent_class)->dispose (object);
447 }
448
449 static void
450 camel_index_cursor_class_init (CamelIndexCursorClass *class)
451 {
452         GObjectClass *object_class;
453
454         object_class = G_OBJECT_CLASS (class);
455         object_class->dispose = index_cursor_dispose;
456 }
457
458 static void
459 camel_index_cursor_init (CamelIndexCursor *index_cursor)
460 {
461 }
462
463 CamelIndexCursor *
464 camel_index_cursor_new (CamelIndex *idx,
465                         const gchar *name)
466 {
467         CamelIndexCursor *idc;
468
469         idc = g_object_new (CAMEL_TYPE_INDEX_CURSOR, NULL);
470         idc->index = g_object_ref (idx);
471
472         return idc;
473 }
474
475 const gchar *
476 camel_index_cursor_next (CamelIndexCursor *idc)
477 {
478         CamelIndexCursorClass *class;
479
480         g_return_val_if_fail (CAMEL_IS_INDEX_CURSOR (idc), NULL);
481
482         class = CAMEL_INDEX_CURSOR_GET_CLASS (idc);
483         g_return_val_if_fail (class->next != NULL, NULL);
484
485         return class->next (idc);
486 }
487
488 void
489 camel_index_cursor_reset (CamelIndexCursor *idc)
490 {
491         CamelIndexCursorClass *class;
492
493         g_return_if_fail (CAMEL_IS_INDEX_CURSOR (idc));
494
495         class = CAMEL_INDEX_CURSOR_GET_CLASS (idc);
496         g_return_if_fail (class->reset != NULL);
497
498         class->reset (idc);
499 }