Back to index

lightning-sunbird  0.9+nobinonly
icalset.c
Go to the documentation of this file.
00001 /* -*- Mode: C -*- */
00002 /*======================================================================
00003  FILE: icalset.c
00004  CREATOR: eric 17 Jul 2000
00005 
00006 
00007  Icalset is the "base class" for representations of a collection of
00008  iCal components. Derived classes (actually delegates) include:
00009  
00010     icalfileset   Store components in a single file
00011     icaldirset    Store components in multiple files in a directory
00012     icalheapset   Store components on the heap
00013     icalmysqlset  Store components in a mysql database. 
00014 
00015  $Id: icalset.c,v 1.16 2002/07/21 17:00:26 lindner Exp $
00016  $Locker:  $
00017 
00018  (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
00019 
00020  This program is free software; you can redistribute it and/or modify
00021  it under the terms of either: 
00022 
00023     The LGPL as published by the Free Software Foundation, version
00024     2.1, available at: http://www.fsf.org/copyleft/lesser.html
00025 
00026   Or:
00027 
00028     The Mozilla Public License Version 1.0. You may obtain a copy of
00029     the License at http://www.mozilla.org/MPL/
00030 
00031  The Original Code is eric. The Initial Developer of the Original
00032  Code is Eric Busboom
00033 
00034 
00035 ======================================================================*/
00036 
00037 #include "ical.h"
00038 #include "icalset.h"
00039 #include "icalfileset.h"
00040 #include "icalfilesetimpl.h"
00041 #include "icaldirset.h"
00042 #include "icaldirsetimpl.h"
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <errno.h>
00046 
00047 #ifdef WITH_BDB4
00048 #include "icalbdbset.h"
00049 #include "icalbdbsetimpl.h"
00050 #endif
00051 
00052 /* #define _DLOPEN_TEST */
00053 #ifdef _DLOPEN_TEST
00054 #include <sys/types.h>
00055 #include <dlfcn.h>
00056 #include <dirent.h>
00057 #endif
00058 
00059 static icalset icalset_dirset_init = {
00060     ICAL_DIR_SET,
00061     sizeof(icaldirset),
00062     NULL,
00063     icaldirset_init,
00064     icaldirset_free,
00065     icaldirset_path,
00066     icaldirset_mark,
00067     icaldirset_commit,
00068     icaldirset_add_component,
00069     icaldirset_remove_component,
00070     icaldirset_count_components,
00071     icaldirset_select,
00072     icaldirset_clear,
00073     icaldirset_fetch,
00074     icaldirset_fetch_match,
00075     icaldirset_has_uid,
00076     icaldirset_modify,
00077     icaldirset_get_current_component,
00078     icaldirset_get_first_component,
00079     icaldirset_get_next_component,
00080     icaldirset_begin_component,
00081     icaldirsetiter_to_next,
00082     icaldirsetiter_to_prior
00083 };
00084 
00085 
00086 static icalset icalset_fileset_init = {
00087     ICAL_FILE_SET,
00088     sizeof(icalfileset),
00089     NULL,
00090     icalfileset_init,
00091     icalfileset_free,
00092     icalfileset_path,
00093     icalfileset_mark,
00094     icalfileset_commit,
00095     icalfileset_add_component,
00096     icalfileset_remove_component,
00097     icalfileset_count_components,
00098     icalfileset_select,
00099     icalfileset_clear,
00100     icalfileset_fetch,
00101     icalfileset_fetch_match,
00102     icalfileset_has_uid,
00103     icalfileset_modify,
00104     icalfileset_get_current_component,
00105     icalfileset_get_first_component,
00106     icalfileset_get_next_component,
00107     icalfileset_begin_component,
00108     icalfilesetiter_to_next,
00109     NULL
00110 };
00111 
00112 #ifdef WITH_BDB4
00113 static icalset icalset_bdbset_init = {
00114     ICAL_BDB_SET,
00115     sizeof(icalbdbset),
00116     NULL,
00117     icalbdbset_init,
00118     icalbdbset_free,
00119     icalbdbset_path,
00120     icalbdbset_mark,
00121     icalbdbset_commit,
00122     icalbdbset_add_component,
00123     icalbdbset_remove_component,
00124     icalbdbset_count_components,
00125     icalbdbset_select,
00126     icalbdbset_clear,
00127     icalbdbset_fetch,
00128     icalbdbset_fetch_match,
00129     icalbdbset_has_uid,
00130     icalbdbset_modify,
00131     icalbdbset_get_current_component,
00132     icalbdbset_get_first_component,
00133     icalbdbset_get_next_component,
00134     icalbdbset_begin_component,
00135     icalbdbsetiter_to_next,
00136     NULL 
00137 };
00138 #endif
00139 
00140 #ifdef _DLOPEN_TEST
00141 static int    icalset_init_done = 0;
00142 static pvl_list icalset_kinds = 0;
00143 
00144 typedef icalset *(*fptr)(void);
00145 
00149 static int load(const char *file) {
00150 
00151         void           *modh;
00152         fptr            inith;
00153        icalset              *icalset_init_ptr;
00154 
00155         if ((modh = dlopen(file, RTLD_NOW)) == 0) {
00156                 perror("dlopen");
00157                 return 0;
00158         }
00159 
00160         if ((inith = (fptr)dlsym(modh, "InitModule")) == 0) {
00161                 perror("dlsym");
00162                 return 0;
00163         }
00164 
00165         while ((icalset_init_ptr = ((inith)())) != 0) {
00166               pvl_push(icalset_kinds, &icalset_init_ptr);
00167         }
00168 
00169         return 1;
00170 }
00171 
00176 int icalset_loaddir(const char *path) {
00177         DIR             *d;
00178         struct dirent   *dp;
00179         char            buf[PATH_MAX],
00180                        *bufptr;
00181         int             tot = 0;
00182 
00183         strcpy(buf, path);
00184         bufptr = buf + strlen(buf);
00185 
00186         if (*(bufptr-1) != '/')
00187                 *bufptr++ = '/';
00188 
00189         if ((d = opendir(path)) == 0) {
00190                 perror("opendir");
00191                 return 0;
00192         }
00193 
00194         while ((dp = readdir(d)) != 0) {
00195                 if (strncmp(dp->d_name, "mod_", 4)) continue;
00196 
00197                 strcpy(bufptr, dp->d_name);
00198 
00199                 load(buf);
00200                 tot++;
00201         }
00202         (void)closedir(d);
00203 
00204         return 1;
00205 }
00206 
00207 int icalset_register_class(icalset *set);
00208 
00209 static void icalset_init(void) {
00210     assert(icalset_kinds == 0);
00211     icalset_kinds = pvl_newlist();
00212 
00213     pvl_push(icalset_kinds, &icalset_fileset_init);
00214     pvl_push(icalset_kinds, &icalset_dirset_init);
00215 #ifdef WITH_BDB4
00216     pvl_push(icalset_kinds, &icalset_bdb4set_init);
00217 #endif
00218 
00219 #ifdef EXT_PATH
00220     icalset_loaddir(EXT_PATH);
00221 #endif
00222 
00223     icalset_init_done++;
00224 }
00225 
00226 int icalset_register_class(icalset *set) {
00227 
00228     if (!icalset_init_done)
00229        icalset_init();
00230 
00231     pvl_push(icalset_kinds, set);
00232     return 1;
00233 }
00234 
00235 #endif
00236 
00237 icalset* icalset_new(icalset_kind kind, const char* dsn, void* options) {
00238   icalset *data = NULL;
00239   icalset *ret = NULL;
00240 
00241 #ifdef _DLOPEN_TEST
00242     pvl_elem  e;
00243     icalset    *impl;
00244 
00245     if (!icalset_init_done)
00246        icalset_init();
00247 
00248     for(e = pvl_head(icalset_kinds); e!=0; e = pvl_next(e)) {
00249        impl = (icalset*)pvl_data(e);
00250        if (impl->kind == kind)
00251            break;
00252     }
00253     if (e == 0) {
00254        icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR);
00255        return(NULL);
00256     }
00257 
00258     data = (icalset*)malloc(impl->size);
00259     if (data == 0) {
00260        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
00261        errno = ENOMEM;
00262        return 0;
00263     }
00264 
00265     /* The first member of the derived class must be an icalset. */
00266     memset(data,0,impl->size);
00267     /* *data = *impl; */
00268     memcpy(data, impl, sizeof(icalset));
00269 
00270     data->dsn     = strdup(dsn);
00271 #else
00272   switch(kind) {
00273   case ICAL_FILE_SET:
00274     data = (icalset*) malloc(sizeof(icalfileset));
00275     if (data == 0) {
00276        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
00277        errno = ENOMEM;
00278        return 0;
00279     }
00280     memset(data,0,sizeof(icalfileset));
00281     *data = icalset_fileset_init;
00282     break;
00283   case ICAL_DIR_SET:
00284     data = (icalset*) malloc(sizeof(icaldirset));
00285     if (data == 0) {
00286        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
00287        errno = ENOMEM;
00288        return 0;
00289     }
00290     memset(data,0,sizeof(icaldirset));
00291     *data = icalset_dirset_init;
00292     break;
00293 #ifdef WITH_BDB4
00294   case ICAL_BDB_SET:
00295     data = (icalset*) malloc(sizeof(icalbdbset));
00296     if (data == 0) {
00297        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
00298        errno = ENOMEM;
00299        return 0;
00300     }
00301     memset(data,0,sizeof(icalbdbset));
00302     *data = icalset_bdbset_init;
00303     break;
00304 #endif
00305     
00306   default:
00307     icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR);
00309     return(NULL);
00310   }
00311 
00312   if ( data == 0) {
00313     icalerror_set_errno(ICAL_NEWFAILED_ERROR);
00314     return 0;
00315   }
00316   data->kind    = kind;
00317   data->dsn     = strdup(dsn);
00318 #endif
00319 
00321   if ((ret = data->init(data, dsn, options)) == NULL)
00322     icalset_free(data);
00323 
00324   return ret;
00325 }
00326 
00327 icalset* icalset_new_file(const char* path)
00328 {
00329   return icalset_new(ICAL_FILE_SET, path, NULL);
00330 }
00331 
00332 icalset* icalset_new_file_writer(const char* path)
00333 {
00334   return icalfileset_new_writer(path);
00335 }
00336 
00337 icalset* icalset_new_file_reader(const char* path)
00338 {
00339   return icalfileset_new_reader(path);
00340 }
00341 
00342 
00343 icalset* icalset_new_dir(const char* path)
00344 {
00345   return icalset_new(ICAL_DIR_SET, path, NULL);
00346 }
00347 
00348 icalset* icalset_new_dir_writer(const char* path)
00349 {
00350   return icaldirset_new_writer(path);
00351 }
00352 
00353 icalset* icalset_new_dir_reader(const char* path)
00354 {
00355   return icaldirset_new_reader(path);
00356 }
00357 
00358 
00359 
00360 /* Functions for built-in methods */
00361 
00367 void icalset_free(icalset* set)
00368 {
00369   if (set->free)
00370     set->free(set);
00371 
00372   if (set->dsn)
00373     free(set->dsn);
00374 
00375   free(set);
00376 }
00377 
00378 
00379 const char* icalset_path(icalset* set) {
00380     return set->path(set);
00381 }
00382 
00383 void icalset_mark(icalset* set) {
00384     set->mark(set);
00385 }
00386 
00387 icalerrorenum icalset_commit(icalset* set) {
00388     return set->commit(set);
00389 }
00390 
00391 icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp) {
00392     return set->add_component(set,comp);
00393 }
00394 
00395 icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp) {
00396     return set->remove_component(set,comp);
00397 }
00398 
00399 int icalset_count_components(icalset* set,icalcomponent_kind kind) {
00400     return set->count_components(set,kind);
00401 }
00402 
00403 icalerrorenum icalset_select(icalset* set, icalgauge* gauge) {
00404     return set->select(set, gauge);
00405 }
00406 
00407 void icalset_clear(icalset* set) {
00408     set->clear(set);
00409 }
00410 
00411 icalcomponent* icalset_fetch(icalset* set, const char* uid) {
00412     return set->fetch(set, uid);
00413 }
00414 
00415 icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *comp) {
00416     return set->fetch_match(set, comp);
00417 }
00418 
00419 int icalset_has_uid(icalset* set, const char* uid) {
00420     return set->has_uid(set, uid);
00421 }
00422 
00423 icalerrorenum icalset_modify(icalset* set, icalcomponent *old,
00424                             icalcomponent *new) {
00425     return set->modify(set, old, new);
00426 }
00427 
00428 icalcomponent* icalset_get_current_component(icalset* set) {
00429     return set->get_current_component(set);
00430 }
00431 
00432 icalcomponent* icalset_get_first_component(icalset* set) {
00433     return set->get_first_component(set);
00434 }
00435 
00436 icalcomponent* icalset_get_next_component(icalset* set) {
00437     return set->get_next_component(set);
00438 }
00439 
00440 icalsetiter icalsetiter_null = {{ICAL_NO_COMPONENT, 0}, 0};
00441 
00442 icalsetiter icalset_begin_component(icalset* set,
00443                                  icalcomponent_kind kind, icalgauge* gauge) {
00444     return set->icalset_begin_component(set, kind, gauge);
00445 }
00446 
00447 icalcomponent* icalsetiter_next(icalsetiter* itr) {
00448 
00449     icalcomponent* c = 0;
00450     icalerror_check_arg_rz( (itr != NULL), "i");
00451 
00452     do  {
00453        c = icalcompiter_next(&(itr->iter));
00454        if(c != 0 && (itr->gauge == 0 ||
00455                      icalgauge_compare(itr->gauge, c) == 1)){
00456            return c;
00457        }
00458     } while (c != 0);
00459 
00460     return 0;
00461 }
00462 
00463 icalcomponent* icalsetiter_prior(icalsetiter* i) {
00464 
00465     icalcomponent* c = 0;
00466     icalerror_check_arg_rz( (i != NULL), "i" );
00467 
00468     do  {
00469        c = icalcompiter_prior(&(i->iter));
00470        if(c != 0 && (i->gauge == 0 ||
00471                      icalgauge_compare(i->gauge, c) == 1)){
00472            return c;
00473        }
00474     } while (c != 0);
00475 
00476     return 0;
00477 }
00478 
00479 icalcomponent* icalsetiter_deref(icalsetiter* i) {
00480     icalerror_check_arg_rz( (i != NULL), "i" );
00481     return (icalcompiter_deref(&(i->iter)));
00482 }
00483 
00484 /* for subclasses that use multiple clusters that require specialized cluster traversal */
00485 icalcomponent* icalsetiter_to_next(icalset* set, icalsetiter* i)
00486 {
00487     return set->icalsetiter_to_next(set, i);
00488 }
00489 
00490 icalcomponent* icalsetiter_to_prior(icalset* set, icalsetiter* i)
00491 {
00492     return set->icalsetiter_to_prior(set, i);
00493 }