2 /*======================================================================
4 CREATOR: eric 17 Jul 2000
7 Icalset is the "base class" for representations of a collection of
8 iCal components. Derived classes (actually delegates) include:
10 icalfileset Store components in a single file
11 icaldirset Store components in multiple files in a directory
12 icalheapset Store components on the heap
13 icalmysqlset Store components in a mysql database.
15 $Id: icalset.c,v 1.18 2008-01-02 20:07:41 dothebart Exp $
18 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of either:
23 The LGPL as published by the Free Software Foundation, version
24 2.1, available at: http://www.fsf.org/copyleft/lesser.html
28 The Mozilla Public License Version 1.0. You may obtain a copy of
29 the License at http://www.mozilla.org/MPL/
31 The Original Code is eric. The Initial Developer of the Original
35 ======================================================================*/
41 #include <libical/ical.h>
43 #include "icalfileset.h"
44 #include "icalfilesetimpl.h"
45 #include "icaldirset.h"
46 #include "icaldirsetimpl.h"
52 #include "icalbdbset.h"
53 #include "icalbdbsetimpl.h"
56 /* #define _DLOPEN_TEST */
58 #include <sys/types.h>
63 static icalset icalset_dirset_init = {
72 icaldirset_add_component,
73 icaldirset_remove_component,
74 icaldirset_count_components,
78 icaldirset_fetch_match,
81 icaldirset_get_current_component,
82 icaldirset_get_first_component,
83 icaldirset_get_next_component,
84 icaldirset_begin_component,
85 icaldirsetiter_to_next,
86 icaldirsetiter_to_prior
90 static icalset icalset_fileset_init = {
99 icalfileset_add_component,
100 icalfileset_remove_component,
101 icalfileset_count_components,
105 icalfileset_fetch_match,
108 icalfileset_get_current_component,
109 icalfileset_get_first_component,
110 icalfileset_get_next_component,
111 icalfileset_begin_component,
112 icalfilesetiter_to_next,
117 static icalset icalset_bdbset_init = {
126 icalbdbset_add_component,
127 icalbdbset_remove_component,
128 icalbdbset_count_components,
132 icalbdbset_fetch_match,
135 icalbdbset_get_current_component,
136 icalbdbset_get_first_component,
137 icalbdbset_get_next_component,
138 icalbdbset_begin_component,
139 icalbdbsetiter_to_next,
145 static int icalset_init_done = 0;
146 static pvl_list icalset_kinds = 0;
148 typedef icalset *(*fptr)(void);
151 * Try to load the file and register any icalset found within.
153 static int load(const char *file) {
157 icalset *icalset_init_ptr;
159 if ((modh = dlopen(file, RTLD_NOW)) == 0) {
164 if ((inith = (fptr)dlsym(modh, "InitModule")) == 0) {
169 while ((icalset_init_ptr = ((inith)())) != 0) {
170 pvl_push(icalset_kinds, &icalset_init_ptr);
177 * Look in the given directory for files called mod_*.o and try to
180 int icalset_loaddir(const char *path) {
188 bufptr = buf + strlen(buf);
190 if (*(bufptr-1) != '/')
193 if ((d = opendir(path)) == 0) {
198 while ((dp = readdir(d)) != 0) {
199 if (strncmp(dp->d_name, "mod_", 4)) continue;
201 strcpy(bufptr, dp->d_name);
211 int icalset_register_class(icalset *set);
213 static void icalset_init(void) {
214 assert(icalset_kinds == 0);
215 icalset_kinds = pvl_newlist();
217 pvl_push(icalset_kinds, &icalset_fileset_init);
218 pvl_push(icalset_kinds, &icalset_dirset_init);
220 pvl_push(icalset_kinds, &icalset_bdb4set_init);
224 icalset_loaddir(EXT_PATH);
230 int icalset_register_class(icalset *set) {
232 if (!icalset_init_done)
235 pvl_push(icalset_kinds, set);
241 icalset* icalset_new(icalset_kind kind, const char* dsn, void* options) {
242 icalset *data = NULL;
249 if (!icalset_init_done)
252 for(e = pvl_head(icalset_kinds); e!=0; e = pvl_next(e)) {
253 impl = (icalset*)pvl_data(e);
254 if (impl->kind == kind)
258 icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR);
262 data = (icalset*)malloc(impl->size);
264 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
269 /* The first member of the derived class must be an icalset. */
270 memset(data,0,impl->size);
272 memcpy(data, impl, sizeof(icalset));
274 data->dsn = strdup(dsn);
278 data = (icalset*) malloc(sizeof(icalfileset));
280 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
284 memset(data,0,sizeof(icalfileset));
285 *data = icalset_fileset_init;
288 data = (icalset*) malloc(sizeof(icaldirset));
290 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
294 memset(data,0,sizeof(icaldirset));
295 *data = icalset_dirset_init;
299 data = (icalset*) malloc(sizeof(icalbdbset));
301 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
305 memset(data,0,sizeof(icalbdbset));
306 *data = icalset_bdbset_init;
311 icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR);
312 /** unimplemented **/
317 data->dsn = strdup(dsn);
320 /** call the implementation specific initializer **/
321 if ((ret = data->init(data, dsn, options)) == NULL)
327 icalset* icalset_new_file(const char* path)
329 return icalset_new(ICAL_FILE_SET, path, NULL);
332 icalset* icalset_new_file_writer(const char* path)
334 return icalfileset_new_writer(path);
337 icalset* icalset_new_file_reader(const char* path)
339 return icalfileset_new_reader(path);
343 icalset* icalset_new_dir(const char* path)
345 return icalset_new(ICAL_DIR_SET, path, NULL);
348 icalset* icalset_new_dir_writer(const char* path)
350 return icaldirset_new_writer(path);
353 icalset* icalset_new_dir_reader(const char* path)
355 return icaldirset_new_reader(path);
360 /* Functions for built-in methods */
363 * free memory associated with this icalset
364 * automatically calls the implementation specific free routine
367 void icalset_free(icalset* set)
379 const char* icalset_path(icalset* set) {
380 return set->path(set);
383 void icalset_mark(icalset* set) {
387 icalerrorenum icalset_commit(icalset* set) {
388 return set->commit(set);
391 icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp) {
392 return set->add_component(set,comp);
395 icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp) {
396 return set->remove_component(set,comp);
399 int icalset_count_components(icalset* set,icalcomponent_kind kind) {
400 return set->count_components(set,kind);
403 icalerrorenum icalset_select(icalset* set, icalgauge* gauge) {
404 return set->select(set, gauge);
407 void icalset_clear(icalset* set) {
411 icalcomponent* icalset_fetch(icalset* set, const char* uid) {
412 return set->fetch(set, uid);
415 icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *comp) {
416 return set->fetch_match(set, comp);
419 int icalset_has_uid(icalset* set, const char* uid) {
420 return set->has_uid(set, uid);
423 icalerrorenum icalset_modify(icalset* set, icalcomponent *old,
424 icalcomponent *new) {
425 return set->modify(set, old, new);
428 icalcomponent* icalset_get_current_component(icalset* set) {
429 return set->get_current_component(set);
432 icalcomponent* icalset_get_first_component(icalset* set) {
433 return set->get_first_component(set);
436 icalcomponent* icalset_get_next_component(icalset* set) {
437 return set->get_next_component(set);
440 icalsetiter icalsetiter_null = {{ICAL_NO_COMPONENT, 0}, 0};
442 icalsetiter icalset_begin_component(icalset* set,
443 icalcomponent_kind kind, icalgauge* gauge) {
444 return set->icalset_begin_component(set, kind, gauge);
447 icalcomponent* icalsetiter_next(icalsetiter* itr) {
449 icalcomponent* c = 0;
450 icalerror_check_arg_rz( (itr != NULL), "i");
453 c = icalcompiter_next(&(itr->iter));
454 if(c != 0 && (itr->gauge == 0 ||
455 icalgauge_compare(itr->gauge, c) == 1)){
463 icalcomponent* icalsetiter_prior(icalsetiter* i) {
465 icalcomponent* c = 0;
466 icalerror_check_arg_rz( (i != NULL), "i" );
469 c = icalcompiter_prior(&(i->iter));
470 if(c != 0 && (i->gauge == 0 ||
471 icalgauge_compare(i->gauge, c) == 1)){
479 icalcomponent* icalsetiter_deref(icalsetiter* i) {
480 icalerror_check_arg_rz( (i != NULL), "i" );
481 return (icalcompiter_deref(&(i->iter)));
484 /* for subclasses that use multiple clusters that require specialized cluster traversal */
485 icalcomponent* icalsetiter_to_next(icalset* set, icalsetiter* i)
487 return set->icalsetiter_to_next(set, i);
490 icalcomponent* icalsetiter_to_prior(icalset* set, icalsetiter* i)
492 return set->icalsetiter_to_prior(set, i);