diff options
Diffstat (limited to 'src/libicalss/icalset.c')
-rw-r--r-- | src/libicalss/icalset.c | 493 |
1 files changed, 493 insertions, 0 deletions
diff --git a/src/libicalss/icalset.c b/src/libicalss/icalset.c new file mode 100644 index 00000000..cd38033b --- /dev/null +++ b/src/libicalss/icalset.c @@ -0,0 +1,493 @@ +/* -*- Mode: C -*- */ +/*====================================================================== + FILE: icalset.c + CREATOR: eric 17 Jul 2000 + + + Icalset is the "base class" for representations of a collection of + iCal components. Derived classes (actually delegates) include: + + icalfileset Store components in a single file + icaldirset Store components in multiple files in a directory + icalheapset Store components on the heap + icalmysqlset Store components in a mysql database. + + $Id: icalset.c,v 1.18 2008-01-02 20:07:41 dothebart Exp $ + $Locker: $ + + (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org + + This program is free software; you can redistribute it and/or modify + it under the terms of either: + + The LGPL as published by the Free Software Foundation, version + 2.1, available at: http://www.fsf.org/copyleft/lesser.html + + Or: + + The Mozilla Public License Version 1.0. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + The Original Code is eric. The Initial Developer of the Original + Code is Eric Busboom + + +======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <libical/ical.h> +#include "icalset.h" +#include "icalfileset.h" +#include "icalfilesetimpl.h" +#include "icaldirset.h" +#include "icaldirsetimpl.h" +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#ifdef WITH_BDB4 +#include "icalbdbset.h" +#include "icalbdbsetimpl.h" +#endif + +/* #define _DLOPEN_TEST */ +#ifdef _DLOPEN_TEST +#include <sys/types.h> +#include <dlfcn.h> +#include <dirent.h> +#endif + +static icalset icalset_dirset_init = { + ICAL_DIR_SET, + sizeof(icaldirset), + NULL, + icaldirset_init, + icaldirset_free, + icaldirset_path, + icaldirset_mark, + icaldirset_commit, + icaldirset_add_component, + icaldirset_remove_component, + icaldirset_count_components, + icaldirset_select, + icaldirset_clear, + icaldirset_fetch, + icaldirset_fetch_match, + icaldirset_has_uid, + icaldirset_modify, + icaldirset_get_current_component, + icaldirset_get_first_component, + icaldirset_get_next_component, + icaldirset_begin_component, + icaldirsetiter_to_next, + icaldirsetiter_to_prior +}; + + +static icalset icalset_fileset_init = { + ICAL_FILE_SET, + sizeof(icalfileset), + NULL, + icalfileset_init, + icalfileset_free, + icalfileset_path, + icalfileset_mark, + icalfileset_commit, + icalfileset_add_component, + icalfileset_remove_component, + icalfileset_count_components, + icalfileset_select, + icalfileset_clear, + icalfileset_fetch, + icalfileset_fetch_match, + icalfileset_has_uid, + icalfileset_modify, + icalfileset_get_current_component, + icalfileset_get_first_component, + icalfileset_get_next_component, + icalfileset_begin_component, + icalfilesetiter_to_next, + NULL +}; + +#ifdef WITH_BDB4 +static icalset icalset_bdbset_init = { + ICAL_BDB_SET, + sizeof(icalbdbset), + NULL, + icalbdbset_init, + icalbdbset_free, + icalbdbset_path, + icalbdbset_mark, + icalbdbset_commit, + icalbdbset_add_component, + icalbdbset_remove_component, + icalbdbset_count_components, + icalbdbset_select, + icalbdbset_clear, + icalbdbset_fetch, + icalbdbset_fetch_match, + icalbdbset_has_uid, + icalbdbset_modify, + icalbdbset_get_current_component, + icalbdbset_get_first_component, + icalbdbset_get_next_component, + icalbdbset_begin_component, + icalbdbsetiter_to_next, + NULL +}; +#endif + +#ifdef _DLOPEN_TEST +static int icalset_init_done = 0; +static pvl_list icalset_kinds = 0; + +typedef icalset *(*fptr)(void); + +/** + * Try to load the file and register any icalset found within. + */ +static int load(const char *file) { + + void *modh; + fptr inith; + icalset *icalset_init_ptr; + + if ((modh = dlopen(file, RTLD_NOW)) == 0) { + perror("dlopen"); + return 0; + } + + if ((inith = (fptr)dlsym(modh, "InitModule")) == 0) { + perror("dlsym"); + return 0; + } + + while ((icalset_init_ptr = ((inith)())) != 0) { + pvl_push(icalset_kinds, &icalset_init_ptr); + } + + return 1; +} + +/** + * Look in the given directory for files called mod_*.o and try to + * load them. + */ +int icalset_loaddir(const char *path) { + DIR *d; + struct dirent *dp; + char buf[PATH_MAX], + *bufptr; + int tot = 0; + + strcpy(buf, path); + bufptr = buf + strlen(buf); + + if (*(bufptr-1) != '/') + *bufptr++ = '/'; + + if ((d = opendir(path)) == 0) { + perror("opendir"); + return 0; + } + + while ((dp = readdir(d)) != 0) { + if (strncmp(dp->d_name, "mod_", 4)) continue; + + strcpy(bufptr, dp->d_name); + + load(buf); + tot++; + } + (void)closedir(d); + + return 1; +} + +int icalset_register_class(icalset *set); + +static void icalset_init(void) { + assert(icalset_kinds == 0); + icalset_kinds = pvl_newlist(); + + pvl_push(icalset_kinds, &icalset_fileset_init); + pvl_push(icalset_kinds, &icalset_dirset_init); +#ifdef WITH_BDB4 + pvl_push(icalset_kinds, &icalset_bdb4set_init); +#endif + +#ifdef EXT_PATH + icalset_loaddir(EXT_PATH); +#endif + + icalset_init_done++; +} + +int icalset_register_class(icalset *set) { + + if (!icalset_init_done) + icalset_init(); + + pvl_push(icalset_kinds, set); + return 1; +} + +#endif + +icalset* icalset_new(icalset_kind kind, const char* dsn, void* options) { + icalset *data = NULL; + icalset *ret = NULL; + +#ifdef _DLOPEN_TEST + pvl_elem e; + icalset *impl; + + if (!icalset_init_done) + icalset_init(); + + for(e = pvl_head(icalset_kinds); e!=0; e = pvl_next(e)) { + impl = (icalset*)pvl_data(e); + if (impl->kind == kind) + break; + } + if (e == 0) { + icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); + return(NULL); + } + + data = (icalset*)malloc(impl->size); + if (data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + errno = ENOMEM; + return 0; + } + + /* The first member of the derived class must be an icalset. */ + memset(data,0,impl->size); + /* *data = *impl; */ + memcpy(data, impl, sizeof(icalset)); + + data->dsn = strdup(dsn); +#else + switch(kind) { + case ICAL_FILE_SET: + data = (icalset*) malloc(sizeof(icalfileset)); + if (data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + errno = ENOMEM; + return 0; + } + memset(data,0,sizeof(icalfileset)); + *data = icalset_fileset_init; + break; + case ICAL_DIR_SET: + data = (icalset*) malloc(sizeof(icaldirset)); + if (data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + errno = ENOMEM; + return 0; + } + memset(data,0,sizeof(icaldirset)); + *data = icalset_dirset_init; + break; +#ifdef WITH_BDB4 + case ICAL_BDB_SET: + data = (icalset*) malloc(sizeof(icalbdbset)); + if (data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + errno = ENOMEM; + return 0; + } + memset(data,0,sizeof(icalbdbset)); + *data = icalset_bdbset_init; + break; +#endif + + default: + icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); + /** unimplemented **/ + return(NULL); + } + + data->kind = kind; + data->dsn = strdup(dsn); +#endif + + /** call the implementation specific initializer **/ + if ((ret = data->init(data, dsn, options)) == NULL) + icalset_free(data); + + return ret; +} + +icalset* icalset_new_file(const char* path) +{ + return icalset_new(ICAL_FILE_SET, path, NULL); +} + +icalset* icalset_new_file_writer(const char* path) +{ + return icalfileset_new_writer(path); +} + +icalset* icalset_new_file_reader(const char* path) +{ + return icalfileset_new_reader(path); +} + + +icalset* icalset_new_dir(const char* path) +{ + return icalset_new(ICAL_DIR_SET, path, NULL); +} + +icalset* icalset_new_dir_writer(const char* path) +{ + return icaldirset_new_writer(path); +} + +icalset* icalset_new_dir_reader(const char* path) +{ + return icaldirset_new_reader(path); +} + + + +/* Functions for built-in methods */ + +/** + * free memory associated with this icalset + * automatically calls the implementation specific free routine + */ + +void icalset_free(icalset* set) +{ + if (set->free) + set->free(set); + + if (set->dsn) + free(set->dsn); + + free(set); +} + + +const char* icalset_path(icalset* set) { + return set->path(set); +} + +void icalset_mark(icalset* set) { + set->mark(set); +} + +icalerrorenum icalset_commit(icalset* set) { + return set->commit(set); +} + +icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp) { + return set->add_component(set,comp); +} + +icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp) { + return set->remove_component(set,comp); +} + +int icalset_count_components(icalset* set,icalcomponent_kind kind) { + return set->count_components(set,kind); +} + +icalerrorenum icalset_select(icalset* set, icalgauge* gauge) { + return set->select(set, gauge); +} + +void icalset_clear(icalset* set) { + set->clear(set); +} + +icalcomponent* icalset_fetch(icalset* set, const char* uid) { + return set->fetch(set, uid); +} + +icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *comp) { + return set->fetch_match(set, comp); +} + +int icalset_has_uid(icalset* set, const char* uid) { + return set->has_uid(set, uid); +} + +icalerrorenum icalset_modify(icalset* set, icalcomponent *old, + icalcomponent *new) { + return set->modify(set, old, new); +} + +icalcomponent* icalset_get_current_component(icalset* set) { + return set->get_current_component(set); +} + +icalcomponent* icalset_get_first_component(icalset* set) { + return set->get_first_component(set); +} + +icalcomponent* icalset_get_next_component(icalset* set) { + return set->get_next_component(set); +} + +icalsetiter icalsetiter_null = {{ICAL_NO_COMPONENT, 0}, 0}; + +icalsetiter icalset_begin_component(icalset* set, + icalcomponent_kind kind, icalgauge* gauge) { + return set->icalset_begin_component(set, kind, gauge); +} + +icalcomponent* icalsetiter_next(icalsetiter* itr) { + + icalcomponent* c = 0; + icalerror_check_arg_rz( (itr != NULL), "i"); + + do { + c = icalcompiter_next(&(itr->iter)); + if(c != 0 && (itr->gauge == 0 || + icalgauge_compare(itr->gauge, c) == 1)){ + return c; + } + } while (c != 0); + + return 0; +} + +icalcomponent* icalsetiter_prior(icalsetiter* i) { + + icalcomponent* c = 0; + icalerror_check_arg_rz( (i != NULL), "i" ); + + do { + c = icalcompiter_prior(&(i->iter)); + if(c != 0 && (i->gauge == 0 || + icalgauge_compare(i->gauge, c) == 1)){ + return c; + } + } while (c != 0); + + return 0; +} + +icalcomponent* icalsetiter_deref(icalsetiter* i) { + icalerror_check_arg_rz( (i != NULL), "i" ); + return (icalcompiter_deref(&(i->iter))); +} + +/* for subclasses that use multiple clusters that require specialized cluster traversal */ +icalcomponent* icalsetiter_to_next(icalset* set, icalsetiter* i) +{ + return set->icalsetiter_to_next(set, i); +} + +icalcomponent* icalsetiter_to_prior(icalset* set, icalsetiter* i) +{ + return set->icalsetiter_to_prior(set, i); +} |