Fix FSF address (Tobias Mueller, #470445)
[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) 2001 Ximian Inc.
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 struct _CamelIndexPrivate {
43         void *dummy;
44 };
45
46 #define _PRIVATE(o) (((CamelIndex *)(o))->priv)
47
48 #define CI_CLASS(o) ((CamelIndexClass *)(((CamelObject *)o)->klass))
49
50 /* ********************************************************************** */
51 /* CamelIndex */
52 /* ********************************************************************** */
53
54 static CamelObjectClass *camel_index_parent;
55
56 static void
57 camel_index_class_init(CamelIndexClass *klass)
58 {
59         camel_index_parent = CAMEL_OBJECT_CLASS(camel_type_get_global_classfuncs(camel_object_get_type()));
60 }
61
62 static void
63 camel_index_init(CamelIndex *idx)
64 {
65         struct _CamelIndexPrivate *p;
66
67         p = _PRIVATE(idx) = g_malloc0(sizeof(*p));
68
69         idx->version = CAMEL_INDEX_VERSION;
70 }
71
72 static void
73 camel_index_finalise(CamelIndex *idx)
74 {
75         g_free(idx->path);
76         g_free(idx->priv);
77 }
78
79 CamelType
80 camel_index_get_type(void)
81 {
82         static CamelType type = CAMEL_INVALID_TYPE;
83         
84         if (type == CAMEL_INVALID_TYPE) {
85                 type = camel_type_register(camel_object_get_type(), "CamelIndex",
86                                            sizeof (CamelIndex),
87                                            sizeof (CamelIndexClass),
88                                            (CamelObjectClassInitFunc) camel_index_class_init,
89                                            NULL,
90                                            (CamelObjectInitFunc) camel_index_init,
91                                            (CamelObjectFinalizeFunc) camel_index_finalise);
92         }
93         
94         return type;
95 }
96
97 CamelIndex *
98 camel_index_new(const char *path, int flags)
99 {
100         CamelIndex *idx = (CamelIndex *)camel_object_new(camel_index_get_type());
101
102         camel_index_construct(idx, path, flags);
103
104         return idx;
105 }
106
107 void
108 camel_index_construct(CamelIndex *idx, const char *path, int flags)
109 {
110         g_free(idx->path);
111         idx->path = g_strdup_printf("%s.index", path);
112         idx->flags = flags;
113 }
114
115 int
116 camel_index_rename(CamelIndex *idx, const char *path)
117 {
118         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
119         
120         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
121                 return CI_CLASS(idx)->rename(idx, path);
122         else {
123                 errno = ENOENT;
124                 return -1;
125         }
126 }
127
128 void
129 camel_index_set_normalise(CamelIndex *idx, CamelIndexNorm func, void *data)
130 {
131         g_return_if_fail (CAMEL_IS_INDEX (idx));
132         
133         idx->normalise = func;
134         idx->normalise_data = data;
135 }
136
137 int
138 camel_index_sync(CamelIndex *idx)
139 {
140         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
141         
142         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
143                 return CI_CLASS(idx)->sync(idx);
144         else {
145                 errno = ENOENT;
146                 return -1;
147         }
148 }
149
150 int
151 camel_index_compress(CamelIndex *idx)
152 {
153         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
154         
155         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
156                 return CI_CLASS(idx)->compress(idx);
157         else {
158                 errno = ENOENT;
159                 return -1;
160         }
161 }
162
163 int
164 camel_index_delete(CamelIndex *idx)
165 {
166         int ret;
167
168         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
169         
170         if ((idx->state & CAMEL_INDEX_DELETED) == 0) {
171                 ret = CI_CLASS(idx)->delete(idx);
172                 idx->state |= CAMEL_INDEX_DELETED;
173         } else {
174                 errno = ENOENT;
175                 ret = -1;
176         }
177
178         return ret;
179 }
180
181 int
182 camel_index_has_name(CamelIndex *idx, const char *name)
183 {
184         g_return_val_if_fail (CAMEL_IS_INDEX (idx), FALSE);
185         
186         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
187                 return CI_CLASS(idx)->has_name(idx, name);
188         else
189                 return FALSE;
190 }
191
192 CamelIndexName *
193 camel_index_add_name(CamelIndex *idx, const char *name)
194 {
195         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
196         
197         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
198                 return CI_CLASS(idx)->add_name(idx, name);
199         else
200                 return NULL;
201 }
202
203 int
204 camel_index_write_name(CamelIndex *idx, CamelIndexName *idn)
205 {
206         g_return_val_if_fail (CAMEL_IS_INDEX (idx), -1);
207         
208         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
209                 return CI_CLASS(idx)->write_name(idx, idn);
210         else {
211                 errno = ENOENT;
212                 return -1;
213         }
214 }
215
216 CamelIndexCursor *
217 camel_index_find_name(CamelIndex *idx, const char *name)
218 {
219         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
220         
221         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
222                 return CI_CLASS(idx)->find_name(idx, name);
223         else
224                 return NULL;
225 }
226
227 void
228 camel_index_delete_name(CamelIndex *idx, const char *name)
229 {
230         g_return_if_fail (CAMEL_IS_INDEX (idx));
231         
232         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
233                 CI_CLASS(idx)->delete_name(idx, name);
234 }
235
236 CamelIndexCursor *
237 camel_index_find(CamelIndex *idx, const char *word)
238 {
239         char *b = (char *)word;
240         CamelIndexCursor *ret;
241
242         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
243         
244         if ((idx->state & CAMEL_INDEX_DELETED) != 0)
245                 return NULL;
246
247         if (idx->normalise)
248                 b = idx->normalise(idx, word, idx->normalise_data);
249
250         ret = CI_CLASS(idx)->find(idx, b);
251
252         if (b != word)
253                 g_free(b);
254
255         return ret;
256 }
257
258 CamelIndexCursor *
259 camel_index_words(CamelIndex *idx)
260 {
261         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
262         
263         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
264                 return CI_CLASS(idx)->words(idx);
265         else
266                 return NULL;
267 }
268
269 CamelIndexCursor *
270 camel_index_names(CamelIndex *idx)
271 {
272         g_return_val_if_fail (CAMEL_IS_INDEX (idx), NULL);
273         
274         if ((idx->state & CAMEL_INDEX_DELETED) == 0)
275                 return CI_CLASS(idx)->names(idx);
276         else
277                 return NULL;
278 }
279
280 /* ********************************************************************** */
281 /* CamelIndexName */
282 /* ********************************************************************** */
283
284 static CamelObjectClass *camel_index_name_parent;
285
286 #define CIN_CLASS(o) ((CamelIndexNameClass *)(((CamelObject *)o)->klass))
287
288 static void
289 camel_index_name_class_init(CamelIndexNameClass *klass)
290 {
291         camel_index_name_parent = CAMEL_OBJECT_CLASS(camel_type_get_global_classfuncs(camel_object_get_type()));
292 }
293
294 static void
295 camel_index_name_init(CamelIndexName *idn)
296 {
297 }
298
299 static void
300 camel_index_name_finalise(CamelIndexName *idn)
301 {
302         if (idn->index)
303                 camel_object_unref((CamelObject *)idn->index);
304 }
305
306 CamelType
307 camel_index_name_get_type(void)
308 {
309         static CamelType type = CAMEL_INVALID_TYPE;
310         
311         if (type == CAMEL_INVALID_TYPE) {
312                 type = camel_type_register(camel_object_get_type(), "CamelIndexName",
313                                            sizeof (CamelIndexName),
314                                            sizeof (CamelIndexNameClass),
315                                            (CamelObjectClassInitFunc) camel_index_name_class_init,
316                                            NULL,
317                                            (CamelObjectInitFunc) camel_index_name_init,
318                                            (CamelObjectFinalizeFunc) camel_index_name_finalise);
319         }
320         
321         return type;
322 }
323
324 CamelIndexName *
325 camel_index_name_new(CamelIndex *idx, const char *name)
326 {
327         CamelIndexName *idn = (CamelIndexName *)camel_object_new(camel_index_name_get_type());
328
329         idn->index = idx;
330         camel_object_ref((CamelObject *)idx);
331
332         return idn;
333 }
334
335 void
336 camel_index_name_add_word(CamelIndexName *idn, const char *word)
337 {
338         char *b = (char *)word;
339
340         if (idn->index->normalise)
341                 b = idn->index->normalise(idn->index, word, idn->index->normalise_data);
342
343         CIN_CLASS(idn)->add_word(idn, b);
344
345         if (b != word)
346                 g_free(b);
347 }
348
349 size_t
350 camel_index_name_add_buffer(CamelIndexName *idn, const char *buffer, size_t len)
351 {
352         return CIN_CLASS(idn)->add_buffer(idn, buffer, len);
353 }
354
355 /* ********************************************************************** */
356 /* CamelIndexCursor */
357 /* ********************************************************************** */
358
359 static CamelObjectClass *camel_index_cursor_parent;
360
361 #define CIC_CLASS(o) ((CamelIndexCursorClass *)(((CamelObject *)o)->klass))
362
363 static void
364 camel_index_cursor_class_init(CamelIndexCursorClass *klass)
365 {
366         camel_index_cursor_parent = CAMEL_OBJECT_CLASS(camel_type_get_global_classfuncs(camel_object_get_type()));
367 }
368
369 static void
370 camel_index_cursor_init(CamelIndexCursor *idc)
371 {
372 }
373
374 static void
375 camel_index_cursor_finalise(CamelIndexCursor *idc)
376 {
377         if (idc->index)
378                 camel_object_unref((CamelObject *)idc->index);
379 }
380
381 CamelType
382 camel_index_cursor_get_type(void)
383 {
384         static CamelType type = CAMEL_INVALID_TYPE;
385         
386         if (type == CAMEL_INVALID_TYPE) {
387                 type = camel_type_register(camel_object_get_type(), "CamelIndexCursor",
388                                            sizeof (CamelIndexCursor),
389                                            sizeof (CamelIndexCursorClass),
390                                            (CamelObjectClassInitFunc) camel_index_cursor_class_init,
391                                            NULL,
392                                            (CamelObjectInitFunc) camel_index_cursor_init,
393                                            (CamelObjectFinalizeFunc) camel_index_cursor_finalise);
394         }
395         
396         return type;
397 }
398
399 CamelIndexCursor *
400 camel_index_cursor_new(CamelIndex *idx, const char *name)
401 {
402         CamelIndexCursor *idc = (CamelIndexCursor *)camel_object_new(camel_index_cursor_get_type());
403
404         idc->index = idx;
405         camel_object_ref((CamelObject *)idx);
406
407         return idc;
408 }
409
410 const char *
411 camel_index_cursor_next(CamelIndexCursor *idc)
412 {
413         return CIC_CLASS(idc)->next(idc);
414 }
415
416 void
417 camel_index_cursor_reset(CamelIndexCursor *idc)
418 {
419         CIC_CLASS(idc)->reset(idc);
420 }
421