summaryrefslogtreecommitdiffabout
path: root/libical/src/libicalss/icalset.c
Unidiff
Diffstat (limited to 'libical/src/libicalss/icalset.c') (more/less context) (show whitespace changes)
-rw-r--r--libical/src/libicalss/icalset.c510
1 files changed, 318 insertions, 192 deletions
diff --git a/libical/src/libicalss/icalset.c b/libical/src/libicalss/icalset.c
index 2120609..0ad2269 100644
--- a/libical/src/libicalss/icalset.c
+++ b/libical/src/libicalss/icalset.c
@@ -41,33 +41,26 @@
41#include "icaldirset.h" 41#include "icaldirset.h"
42#include "icaldirsetimpl.h" 42#include "icaldirsetimpl.h"
43#include <stdlib.h> 43#include <stdlib.h>
44/*#include "icalheapset.h"*/ 44#include <string.h>
45/*#include "icalmysqlset.h"*/ 45#include <errno.h>
46 46
47#define ICALSET_ID "set " 47#ifdef WITH_BDB4
48 48#include "icalbdbset.h"
49struct icalset_fp { 49#include "icalbdbsetimpl.h"
50 void (*free)(icalset* set); 50#endif
51 const char* (*path)(icalset* set); 51
52 void (*mark)(icalset* set); 52/* #define _DLOPEN_TEST */
53 icalerrorenum (*commit)(icalset* set); 53#ifdef _DLOPEN_TEST
54 icalerrorenum (*add_component)(icalset* set, icalcomponent* comp); 54#include <sys/types.h>
55 icalerrorenum (*remove_component)(icalset* set, icalcomponent* comp); 55#include <dlfcn.h>
56 int (*count_components)(icalset* set, 56#include <dirent.h>
57 icalcomponent_kind kind); 57#endif
58 icalerrorenum (*select)(icalset* set, icalcomponent* gauge); 58
59 void (*clear)(icalset* set); 59static icalset icalset_dirset_init = {
60 icalcomponent* (*fetch)(icalset* set, const char* uid); 60 ICAL_DIR_SET,
61 icalcomponent* (*fetch_match)(icalset* set, icalcomponent *comp); 61 sizeof(icaldirset),
62 int (*has_uid)(icalset* set, const char* uid); 62 NULL,
63 icalerrorenum (*modify)(icalset* set, icalcomponent *old, 63 icaldirset_init,
64 icalcomponent *new);
65 icalcomponent* (*get_current_component)(icalset* set);
66 icalcomponent* (*get_first_component)(icalset* set);
67 icalcomponent* (*get_next_component)(icalset* set);
68};
69
70struct icalset_fp icalset_dirset_fp = {
71 icaldirset_free, 64 icaldirset_free,
72 icaldirset_path, 65 icaldirset_path,
73 icaldirset_mark, 66 icaldirset_mark,
@@ -83,11 +76,18 @@ struct icalset_fp icalset_dirset_fp = {
83 icaldirset_modify, 76 icaldirset_modify,
84 icaldirset_get_current_component, 77 icaldirset_get_current_component,
85 icaldirset_get_first_component, 78 icaldirset_get_first_component,
86 icaldirset_get_next_component 79 icaldirset_get_next_component,
80 icaldirset_begin_component,
81 icaldirsetiter_to_next,
82 icaldirsetiter_to_prior
87}; 83};
88 84
89 85
90struct icalset_fp icalset_fileset_fp = { 86static icalset icalset_fileset_init = {
87 ICAL_FILE_SET,
88 sizeof(icalfileset),
89 NULL,
90 icalfileset_init,
91 icalfileset_free, 91 icalfileset_free,
92 icalfileset_path, 92 icalfileset_path,
93 icalfileset_mark, 93 icalfileset_mark,
@@ -103,265 +103,391 @@ struct icalset_fp icalset_fileset_fp = {
103 icalfileset_modify, 103 icalfileset_modify,
104 icalfileset_get_current_component, 104 icalfileset_get_current_component,
105 icalfileset_get_first_component, 105 icalfileset_get_first_component,
106 icalfileset_get_next_component 106 icalfileset_get_next_component,
107 icalfileset_begin_component,
108 icalfilesetiter_to_next,
109 NULL
107}; 110};
108 111
109struct icalset_impl { 112#ifdef WITH_BDB4
113static icalset icalset_bdbset_init = {
114 ICAL_BDB_SET,
115 sizeof(icalbdbset),
116 NULL,
117 icalbdbset_init,
118 icalbdbset_free,
119 icalbdbset_path,
120 icalbdbset_mark,
121 icalbdbset_commit,
122 icalbdbset_add_component,
123 icalbdbset_remove_component,
124 icalbdbset_count_components,
125 icalbdbset_select,
126 icalbdbset_clear,
127 icalbdbset_fetch,
128 icalbdbset_fetch_match,
129 icalbdbset_has_uid,
130 icalbdbset_modify,
131 icalbdbset_get_current_component,
132 icalbdbset_get_first_component,
133 icalbdbset_get_next_component,
134 icalbdbset_begin_component,
135 icalbdbsetiter_to_next,
136 NULL
137};
138#endif
110 139
111 char id[5]; /* "set " */ 140#ifdef _DLOPEN_TEST
141 static inticalset_init_done = 0;
142static pvl_list icalset_kinds = 0;
112 143
113 void *derived_impl; 144typedef icalset *(*fptr)(void);
114 struct icalset_fp *fp;
115};
116 145
117/* Figure out what was actually passed in as the set. This could be a 146/**
118 set or and of the derived types such as dirset or fileset. Note 147 * Try to load the file and register any icalset found within.
119 this routine returns a value, not a reference, to avoid memory 148 */
120 leaks in the methods */ 149static int load(const char *file) {
121struct icalset_impl icalset_get_impl(icalset* set)
122{
123 struct icalset_impl impl;
124
125 memset(&impl,0,sizeof(impl));
126 icalerror_check_arg_re( (set!=0),"set",impl);
127
128 if(strcmp((char*)set,ICALSET_ID)==0) {
129 /* It is actually a set, so just sent the reference back out. */
130 return *(struct icalset_impl*)set;
131 } else if(strcmp((char*)set,ICALFILESET_ID)==0) {
132 /* Make a new set from the fileset */
133 impl.fp = &icalset_fileset_fp;
134 impl.derived_impl = set;
135 strcpy(impl.id,ICALFILESET_ID);/* HACK. Is this necessary? */
136 return impl;
137 } else if(strcmp((char*)set,ICALDIRSET_ID)==0) {
138 /* Make a new set from the dirset */
139 impl.fp = &icalset_dirset_fp;
140 impl.derived_impl = set;
141 strcpy(impl.id,ICALDIRSET_ID);/* HACK. Is this necessary? */
142 return impl;
143 } else {
144 /* The type of set is unknown, so throw an error */
145 icalerror_assert((0),"Unknown set type");
146 return impl;
147 }
148}
149
150
151struct icalset_impl* icalset_new_impl()
152{
153 150
154 struct icalset_impl* impl; 151 void *modh;
152 fptr inith;
153 icalset *icalset_init_ptr;
155 154
156 if ( ( impl = (struct icalset_impl*) 155 if ((modh = dlopen(file, RTLD_NOW)) == 0) {
157 malloc(sizeof(struct icalset_impl))) == 0) { 156 perror("dlopen");
158 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
159 return 0; 157 return 0;
160 } 158 }
161 159
162 strcpy(impl->id,ICALSET_ID); 160 if ((inith = (fptr)dlsym(modh, "InitModule")) == 0) {
161 perror("dlsym");
162 return 0;
163 }
163 164
164 impl->derived_impl = 0; 165 while ((icalset_init_ptr = ((inith)())) != 0) {
165 impl->fp = 0; 166 pvl_push(icalset_kinds, &icalset_init_ptr);
167 }
166 168
167 return impl; 169 return 1;
168} 170}
169 171
170struct icalset_impl* icalset_new_file_from_ref(icalfileset *fset) 172/**
171{ 173 * Look in the given directory for files called mod_*.o and try to
172 struct icalset_impl *impl = icalset_new_impl(); 174 * load them.
175 */
176int icalset_loaddir(const char *path) {
177 DIR *d;
178 struct dirent *dp;
179 char buf[PATH_MAX],
180 *bufptr;
181 int tot = 0;
182
183 strcpy(buf, path);
184 bufptr = buf + strlen(buf);
173 185
174 icalerror_check_arg_rz( (fset!=0),"fset"); 186 if (*(bufptr-1) != '/')
187 *bufptr++ = '/';
175 188
176 if(impl == 0){ 189 if ((d = opendir(path)) == 0) {
177 free(impl); 190 perror("opendir");
178 return 0; 191 return 0;
179 } 192 }
180 193
181 impl->derived_impl = fset; 194 while ((dp = readdir(d)) != 0) {
195 if (strncmp(dp->d_name, "mod_", 4)) continue;
182 196
183 if (impl->derived_impl == 0){ 197 strcpy(bufptr, dp->d_name);
184 free(impl);
185 return 0;
186 }
187 198
188 impl->fp = &icalset_fileset_fp; 199 load(buf);
200 tot++;
201 }
202 (void)closedir(d);
189 203
190 return (struct icalset_impl*)impl; 204 return 1;
191} 205}
192 206
193icalset* icalset_new_file(const char* path) 207int icalset_register_class(icalset *set);
194{
195 icalfileset *fset = icalfileset_new(path);
196 208
197 if(fset == 0){ 209static void icalset_init(void) {
198 return 0; 210 assert(icalset_kinds == 0);
211 icalset_kinds = pvl_newlist();
212
213 pvl_push(icalset_kinds, &icalset_fileset_init);
214 pvl_push(icalset_kinds, &icalset_dirset_init);
215#ifdef WITH_BDB4
216 pvl_push(icalset_kinds, &icalset_bdb4set_init);
217#endif
218
219#ifdef EXT_PATH
220 icalset_loaddir(EXT_PATH);
221#endif
222
223 icalset_init_done++;
199 } 224 }
200 225
201 return (icalset*)icalset_new_file_from_ref(fset); 226int icalset_register_class(icalset *set) {
227
228 if (!icalset_init_done)
229 icalset_init();
230
231 pvl_push(icalset_kinds, set);
232 return 1;
202} 233}
203 234
204icalset* icalset_new_dir_from_ref(icaldirset *dset) 235#endif
205{
206 236
207 struct icalset_impl *impl = icalset_new_impl(); 237icalset* icalset_new(icalset_kind kind, const char* dsn, void* options) {
238 icalset *data = NULL;
239 icalset *ret = NULL;
208 240
209 icalerror_check_arg_rz( (dset!=0),"dset"); 241#ifdef _DLOPEN_TEST
242 pvl_eleme;
243 icalset *impl;
210 244
211 if(impl == 0){ 245 if (!icalset_init_done)
212 return 0; 246 icalset_init();
213 }
214 247
215 impl->derived_impl = dset; 248 for(e = pvl_head(icalset_kinds); e!=0; e = pvl_next(e)) {
249 impl = (icalset*)pvl_data(e);
250 if (impl->kind == kind)
251 break;
252 }
253 if (e == 0) {
254 icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR);
255 return(NULL);
256 }
216 257
217 if (impl->derived_impl == 0){ 258 data = (icalset*)malloc(impl->size);
218 free(impl); 259 if (data == 0) {
260 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
261 errno = ENOMEM;
219 return 0; 262 return 0;
220 } 263 }
221 264
222 impl->fp = &icalset_dirset_fp; 265 /* The first member of the derived class must be an icalset. */
266 memset(data,0,impl->size);
267 /* *data = *impl; */
268 memcpy(data, impl, sizeof(icalset));
223 269
224 return impl; 270 data->dsn = strdup(dsn);
271#else
272 switch(kind) {
273 case ICAL_FILE_SET:
274 data = (icalset*) malloc(sizeof(icalfileset));
275 if (data == 0) {
276 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
277 errno = ENOMEM;
278 return 0;
279 }
280 memset(data,0,sizeof(icalfileset));
281 *data = icalset_fileset_init;
282 break;
283 case ICAL_DIR_SET:
284 data = (icalset*) malloc(sizeof(icaldirset));
285 if (data == 0) {
286 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
287 errno = ENOMEM;
288 return 0;
289 }
290 memset(data,0,sizeof(icaldirset));
291 *data = icalset_dirset_init;
292 break;
293#ifdef WITH_BDB4
294 case ICAL_BDB_SET:
295 data = (icalset*) malloc(sizeof(icalbdbset));
296 if (data == 0) {
297 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
298 errno = ENOMEM;
299 return 0;
225} 300}
301 memset(data,0,sizeof(icalbdbset));
302 *data = icalset_bdbset_init;
303 break;
304#endif
226 305
227icalset* icalset_new_dir(const char* path) 306 default:
228{ 307 icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR);
229 icaldirset *dset = icaldirset_new(path); 308 /** unimplemented **/
309 return(NULL);
310 }
230 311
231 if(dset == 0){ 312 if ( data == 0) {
313 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
232 return 0; 314 return 0;
233 } 315 }
316 data->kind = kind;
317 data->dsn = strdup(dsn);
318#endif
319
320 /** call the implementation specific initializer **/
321 if ((ret = data->init(data, dsn, options)) == NULL)
322 icalset_free(data);
234 323
235 return icalset_new_dir_from_ref(dset); 324 return ret;
236} 325}
237 326
238icalset* icalset_new_heap(void) 327icalset* icalset_new_file(const char* path)
239{ 328{
240 struct icalset_impl *impl = icalset_new_impl(); 329 return icalset_new(ICAL_FILE_SET, path, NULL);
241 330}
242 331
243 if(impl == 0){ 332icalset* icalset_new_file_writer(const char* path)
244 free(impl); 333{
245 return 0; 334 return icalfileset_new_writer(path);
246 } 335 }
247 336
248 return 0; 337icalset* icalset_new_file_reader(const char* path)
338{
339 return icalfileset_new_reader(path);
249} 340}
250 341
251icalset* icalset_new_mysql(const char* path) 342
343icalset* icalset_new_dir(const char* path)
252{ 344{
253 struct icalset_impl *impl = icalset_new_impl(); 345 return icalset_new(ICAL_DIR_SET, path, NULL);
346}
254 347
255 if(impl == 0){ 348icalset* icalset_new_dir_writer(const char* path)
256 free(impl); 349{
257 return 0; 350 return icaldirset_new_writer(path);
258 } 351 }
259 352
260 return 0; 353icalset* icalset_new_dir_reader(const char* path)
354{
355 return icaldirset_new_reader(path);
261} 356}
262 357
358
359
360/* Functions for built-in methods */
361
362/**
363 * free memory associated with this icalset
364 * automatically calls the implementation specific free routine
365 */
366
263void icalset_free(icalset* set) 367void icalset_free(icalset* set)
264{ 368{
265 struct icalset_impl impl = icalset_get_impl(set); 369 if (set->free)
266 (*(impl.fp->free))(impl.derived_impl); 370 set->free(set);
371
372 if (set->dsn)
373 free(set->dsn);
267 374
268 if(strcmp((char*)set,ICALSET_ID)) {
269 free(set); 375 free(set);
270 } 376 }
377
378
379const char* icalset_path(icalset* set) {
380 return set->path(set);
271} 381}
272 382
273const char* icalset_path(icalset* set) 383void icalset_mark(icalset* set) {
274{ 384 set->mark(set);
275 struct icalset_impl impl = icalset_get_impl(set);
276 return (*(impl.fp->path))(impl.derived_impl);
277} 385}
278 386
279void icalset_mark(icalset* set) 387icalerrorenum icalset_commit(icalset* set) {
280{ 388 return set->commit(set);
281 struct icalset_impl impl = icalset_get_impl(set);
282 (*(impl.fp->mark))(impl.derived_impl);
283} 389}
284 390
285icalerrorenum icalset_commit(icalset* set) 391icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp) {
286{ 392 return set->add_component(set,comp);
287 struct icalset_impl impl = icalset_get_impl(set);
288 return (*(impl.fp->commit))(impl.derived_impl);
289} 393}
290 394
291icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp) 395icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp) {
292{ 396 return set->remove_component(set,comp);
293 struct icalset_impl impl = icalset_get_impl(set);
294 return (*(impl.fp->add_component))(impl.derived_impl,comp);
295} 397}
296 398
297icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp) 399int icalset_count_components(icalset* set,icalcomponent_kind kind) {
298{ 400 return set->count_components(set,kind);
299 struct icalset_impl impl = icalset_get_impl(set);
300 return (*(impl.fp->remove_component))(impl.derived_impl,comp);
301} 401}
302 402
303int icalset_count_components(icalset* set,icalcomponent_kind kind) 403icalerrorenum icalset_select(icalset* set, icalgauge* gauge) {
304{ 404 return set->select(set, gauge);
305 struct icalset_impl impl = icalset_get_impl(set);
306 return (*(impl.fp->count_components))(impl.derived_impl,kind);
307} 405}
308 406
309icalerrorenum icalset_select(icalset* set, icalcomponent* gauge) 407void icalset_clear(icalset* set) {
310{ 408 set->clear(set);
311 struct icalset_impl impl = icalset_get_impl(set);
312 return (*(impl.fp->select))(impl.derived_impl,gauge);
313} 409}
314 410
315void icalset_clear(icalset* set) 411icalcomponent* icalset_fetch(icalset* set, const char* uid) {
316{ 412 return set->fetch(set, uid);
317 struct icalset_impl impl = icalset_get_impl(set);
318 (*(impl.fp->clear))(impl.derived_impl);
319} 413}
320 414
321icalcomponent* icalset_fetch(icalset* set, const char* uid) 415icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *comp) {
322{ 416 return set->fetch_match(set, comp);
323 struct icalset_impl impl = icalset_get_impl(set);
324 return (*(impl.fp->fetch))(impl.derived_impl,uid);
325} 417}
326 418
327icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *comp) 419int icalset_has_uid(icalset* set, const char* uid) {
328{ 420 return set->has_uid(set, uid);
329 struct icalset_impl impl = icalset_get_impl(set);
330 return (*(impl.fp->fetch_match))(impl.derived_impl,comp);
331} 421}
332 422
423icalerrorenum icalset_modify(icalset* set, icalcomponent *old,
424 icalcomponent *new) {
425 return set->modify(set, old, new);
426}
333 427
334int icalset_has_uid(icalset* set, const char* uid) 428icalcomponent* icalset_get_current_component(icalset* set) {
335{ 429 return set->get_current_component(set);
336 struct icalset_impl impl = icalset_get_impl(set);
337 return (*(impl.fp->has_uid))(impl.derived_impl,uid);
338} 430}
339 431
340icalerrorenum icalset_modify(icalset* set, icalcomponent *old, 432icalcomponent* icalset_get_first_component(icalset* set) {
341 icalcomponent *new) 433 return set->get_first_component(set);
342{
343 struct icalset_impl impl = icalset_get_impl(set);
344 return (*(impl.fp->modify))(impl.derived_impl,old,new);
345} 434}
346 435
347icalcomponent* icalset_get_current_component(icalset* set) 436icalcomponent* icalset_get_next_component(icalset* set) {
348{ 437 return set->get_next_component(set);
349 struct icalset_impl impl = icalset_get_impl(set);
350 return (*(impl.fp->get_current_component))(impl.derived_impl);
351} 438}
352 439
353icalcomponent* icalset_get_first_component(icalset* set) 440icalsetiter icalsetiter_null = {{ICAL_NO_COMPONENT, 0}, 0};
354{ 441
355 struct icalset_impl impl = icalset_get_impl(set); 442icalsetiter icalset_begin_component(icalset* set,
356 return (*(impl.fp->get_first_component))(impl.derived_impl); 443 icalcomponent_kind kind, icalgauge* gauge) {
444 return set->icalset_begin_component(set, kind, gauge);
357} 445}
358 446
359icalcomponent* icalset_get_next_component(icalset* set) 447icalcomponent* icalsetiter_next(icalsetiter* itr) {
360{ 448
361 struct icalset_impl impl = icalset_get_impl(set); 449 icalcomponent* c = 0;
362 return (*(impl.fp->get_next_component))(impl.derived_impl); 450 icalerror_check_arg_rz( (itr != NULL), "i");
451
452 do {
453 c = icalcompiter_next(&(itr->iter));
454 if(c != 0 && (itr->gauge == 0 ||
455 icalgauge_compare(itr->gauge, c) == 1)){
456 return c;
457 }
458 } while (c != 0);
459
460 return 0;
461}
462
463icalcomponent* icalsetiter_prior(icalsetiter* i) {
464
465 icalcomponent* c = 0;
466 icalerror_check_arg_rz( (i != NULL), "i" );
467
468 do {
469 c = icalcompiter_prior(&(i->iter));
470 if(c != 0 && (i->gauge == 0 ||
471 icalgauge_compare(i->gauge, c) == 1)){
472 return c;
363} 473}
474 } while (c != 0);
364 475
476 return 0;
477}
365 478
479icalcomponent* icalsetiter_deref(icalsetiter* i) {
480 icalerror_check_arg_rz( (i != NULL), "i" );
481 return (icalcompiter_deref(&(i->iter)));
482}
366 483
484/* for subclasses that use multiple clusters that require specialized cluster traversal */
485icalcomponent* icalsetiter_to_next(icalset* set, icalsetiter* i)
486{
487 return set->icalsetiter_to_next(set, i);
488}
367 489
490icalcomponent* icalsetiter_to_prior(icalset* set, icalsetiter* i)
491{
492 return set->icalsetiter_to_prior(set, i);
493}