Libical API Documentation 4.0 UNRELEASED Go to the stable 3.0 documentation
Loading...
Searching...
No Matches
icalset.c
Go to the documentation of this file.
1/*======================================================================
2 FILE: icalset.c
3 CREATOR: eric 17 Jul 2000
4
5 SPDX-FileCopyrightText: 2000, Eric Busboom <eric@civicknowledge.com>
6 SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
7
8 Icalset is the "base class" for representations of a collection of
9 iCal components. Derived classes (actually delegates) include:
10
11 icalfileset Store components in a single file
12 icaldirset Store components in multiple files in a directory
13 icalheapset Store components on the heap
14 icalmysqlset Store components in a mysql database.
15
16 The Original Code is eric. The Initial Developer of the Original
17 Code is Eric Busboom
18======================================================================*/
19
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include "icalset.h"
30#include "icaldirset.h"
31#include "icaldirsetimpl.h"
32#include "icalerror_p.h"
33#include "icalfileset.h"
34#include "icalfilesetimpl.h"
35
36#if defined(HAVE_BDB)
37#include "icalbdbset.h"
38#include "icalbdbsetimpl.h"
39#endif
40
41#include <errno.h>
42#include <stdlib.h>
43
44/* #define _DLOPEN_TEST */
45#if defined(_DLOPEN_TEST)
46#include <sys/types.h>
47#include <dlfcn.h>
48#include <dirent.h>
49#endif
50
51static icalset icalset_dirset_init = {
53 sizeof(icaldirset),
54 NULL,
55 icaldirset_init,
56 icaldirset_free,
57 icaldirset_path,
58 icaldirset_mark,
59 icaldirset_commit,
62 icaldirset_count_components,
63 icaldirset_select,
64 icaldirset_clear,
65 icaldirset_fetch,
66 icaldirset_fetch_match,
67 icaldirset_has_uid,
68 icaldirset_modify,
69 icaldirset_get_current_component,
70 icaldirset_get_first_component,
71 icaldirset_get_next_component,
72 icaldirset_begin_component,
73 icaldirsetiter_to_next,
74 icaldirsetiter_to_prior};
75
76static icalset icalset_fileset_init = {
78 sizeof(icalfileset),
79 NULL,
80 icalfileset_init,
81 icalfileset_free,
82 icalfileset_path,
83 icalfileset_mark,
84 icalfileset_commit,
85 icalfileset_add_component,
86 icalfileset_remove_component,
87 icalfileset_count_components,
91 icalfileset_fetch_match,
92 icalfileset_has_uid,
94 icalfileset_get_current_component,
95 icalfileset_get_first_component,
96 icalfileset_get_next_component,
97 icalfileset_begin_component,
98 icalfilesetiter_to_next,
99 NULL};
100
101#if defined(HAVE_BDB)
102static icalset icalset_bdbset_init = {
104 sizeof(icalbdbset),
105 NULL,
106 icalbdbset_init,
107 icalbdbset_free,
109 icalbdbset_mark,
111 icalbdbset_add_component,
112 icalbdbset_remove_component,
113 icalbdbset_count_components,
116 icalbdbset_fetch,
117 icalbdbset_fetch_match,
118 icalbdbset_has_uid,
119 icalbdbset_modify,
121 icalbdbset_get_first_component,
122 icalbdbset_get_next_component,
123 icalbdbset_begin_component,
124 icalbdbsetiter_to_next,
125 NULL};
126#endif
127
128#if defined(_DLOPEN_TEST)
129static int icalset_init_done = 0;
130static icalpvl_list icalset_kinds = 0;
131
132typedef icalset *(*fptr)(void);
133
137static bool load(const char *file)
138{
139 void *modh;
140 fptr inith;
141 const char *dlerr;
142 icalset *icalset_init_ptr;
143
144 if ((modh = dlopen(file, RTLD_NOW)) == 0) {
145 perror("dlopen");
146 return false;
147 }
148
149 (void)dlerror(); /* clear */
150 inith = (fptr)dlsym(modh, "InitModule");
151 dlerr = dlerror();
152 if (dlerr != NULL) {
153 fprintf(stderr, "dlsym error: %s\n", dlerr);
154 dlclose(modh);
155 return false;
156 }
157
158 while ((icalset_init_ptr = ((inith)())) != 0) {
159 icalpvl_push(icalset_kinds, &icalset_init_ptr);
160 }
161
162 (void)dlerror(); /* clear */
163 dlclose(modh);
164 return true;
165}
166
167static void icalset_init(void)
168{
169 assert(icalset_kinds == 0);
170 icalset_kinds = icalpvl_newlist();
171
172 icalpvl_push(icalset_kinds, &icalset_fileset_init);
173 icalpvl_push(icalset_kinds, &icalset_dirset_init);
174#if defined(HAVE_BDB)
175 icalpvl_push(icalset_kinds, &icalset_bdb4set_init);
176#endif
177
178 icalset_init_done++;
179}
180
181bool icalset_register_class(icalset *set)
182{
183 if (!icalset_init_done) {
184 icalset_init();
185 }
186
187 icalpvl_push(icalset_kinds, set);
188 return true;
189}
190
191#endif
192
193icalset *icalset_new(icalset_kind kind, const char *dsn, void *options)
194{
195 icalset *data = NULL;
196 icalset *ret = NULL;
197
198#if defined(_DLOPEN_TEST)
199 icalpvl_elem e;
200 const icalset *impl;
201
202 if (!icalset_init_done) {
203 icalset_init();
204 }
205
206 for (e = icalpvl_head(icalset_kinds); e != 0; e = icalpvl_next(e)) {
207 impl = (icalset *)icalpvl_data(e);
208 if (impl->kind == kind) {
209 break;
210 }
211 }
212 if (e == 0) {
214 return (NULL);
215 }
216
217 data = (icalset *)malloc(impl->size);
218 if (data == (icalset *)NULL) {
220 errno = ENOMEM;
221 return 0;
222 }
223
224 /* The first member of the derived class must be an icalset. */
225 memset(data, 0, impl->size);
226 /* *data = *impl; */
227 memcpy(data, impl, sizeof(icalset));
228
229 data->dsn = strdup(dsn);
230#else
231 switch (kind) {
232 case ICAL_FILE_SET: {
233 icalfileset *fdata;
234 fdata = (icalfileset *)malloc(sizeof(icalfileset));
235 data = (icalset *)fdata;
236 if (data == 0) {
238 errno = ENOMEM;
239 return 0;
240 }
241 memset(data, 0, sizeof(icalfileset));
242 *data = icalset_fileset_init;
243 break;
244 }
245 case ICAL_DIR_SET: {
246 icaldirset *ddata;
247 ddata = (icaldirset *)malloc(sizeof(icaldirset));
248 data = (icalset *)ddata;
249 if (data == 0) {
251 errno = ENOMEM;
252 return 0;
253 }
254 memset(data, 0, sizeof(icaldirset));
255 *data = icalset_dirset_init;
256 break;
257 }
258#if defined(HAVE_BDB)
259 case ICAL_BDB_SET: {
260 icalbdbset *bdata;
261 bdata = (icalbdbset *)malloc(sizeof(icalbdbset));
262 data = (icalset *)bdata;
263 if (data == 0) {
265 errno = ENOMEM;
266 return 0;
267 }
268 memset(data, 0, sizeof(icalbdbset));
269 *data = icalset_bdbset_init;
270 break;
271 }
272#endif
273
274 default:
277 return (NULL);
278 }
279
280 data->kind = kind;
281 data->dsn = strdup(dsn);
282#endif
283
285 if ((ret = data->init(data, dsn, options)) == NULL) {
286 /* coverity[alloc_free_mismatch] */
287 icalset_free(data);
288 }
289
290 return ret;
291}
292
293icalset *icalset_new_file(const char *path)
294{
295 return icalset_new(ICAL_FILE_SET, path, NULL);
296}
297
298icalset *icalset_new_file_writer(const char *path)
299{
300 return icalfileset_new_writer(path);
301}
302
303icalset *icalset_new_file_reader(const char *path)
304{
305 return icalfileset_new_reader(path);
306}
307
308icalset *icalset_new_dir(const char *path)
309{
310 return icalset_new(ICAL_DIR_SET, path, NULL);
311}
312
313icalset *icalset_new_dir_writer(const char *path)
314{
315 return icaldirset_new_writer(path);
316}
317
318icalset *icalset_new_dir_reader(const char *path)
319{
320 return icaldirset_new_reader(path);
321}
322
323/* Functions for built-in methods */
324
325void icalset_free(icalset *set)
326{
327 if (set->free) {
328 set->free(set);
329 }
330
331 if (set->dsn) {
332 free(set->dsn);
333 }
334
335 free(set);
336}
337
338const char *icalset_path(icalset *set)
339{
340 return set->path(set);
341}
342
343void icalset_mark(icalset *set)
344{
345 set->mark(set);
346}
347
349{
350 return set->commit(set);
351}
352
353icalerrorenum icalset_add_component(icalset *set, icalcomponent *comp)
354{
355 return set->add_component(set, comp);
356}
357
358icalerrorenum icalset_remove_component(icalset *set, icalcomponent *comp)
359{
360 return set->remove_component(set, comp);
361}
362
363int icalset_count_components(icalset *set, icalcomponent_kind kind)
364{
365 return set->count_components(set, kind);
366}
367
368icalerrorenum icalset_select(icalset *set, icalgauge *gauge)
369{
370 return set->select(set, gauge);
371}
372
373void icalset_clear(icalset *set)
374{
375 set->clear(set);
376}
377
378icalcomponent *icalset_fetch(icalset *set, const char *uid)
379{
380 return set->fetch(set, 0, uid);
381}
382
383icalcomponent *icalset_fetch_match(icalset *set, const icalcomponent *comp)
384{
385 return set->fetch_match(set, comp);
386}
387
388int icalset_has_uid(icalset *set, const char *uid)
389{
390 return set->has_uid(set, uid);
391}
392
393icalerrorenum icalset_modify(icalset *set, icalcomponent *old, icalcomponent *new)
394{
395 return set->modify(set, old, new);
396}
397
398icalcomponent *icalset_get_current_component(icalset *set)
399{
400 return set->get_current_component(set);
401}
402
403icalcomponent *icalset_get_first_component(icalset *set)
404{
405 return set->get_first_component(set);
406}
407
408icalcomponent *icalset_get_next_component(icalset *set)
409{
410 return set->get_next_component(set);
411}
412
414
415icalsetiter icalset_begin_component(icalset *set,
416 icalcomponent_kind kind, icalgauge *gauge, const char *tzid)
417{
418 return set->icalset_begin_component(set, kind, gauge, tzid);
419}
420
421icalcomponent *icalsetiter_next(icalsetiter *itr)
422{
423 icalcomponent *c = 0;
424
425 icalerror_check_arg_rz((itr != NULL), "i");
426
427 do {
428 c = icalcompiter_next(&(itr->iter));
429 if (c != 0 && (itr->gauge == 0 || icalgauge_compare(itr->gauge, c) == 1)) {
430 return c;
431 }
432 } while (c != 0);
433
434 return 0;
435}
436
437icalcomponent *icalsetiter_prior(icalsetiter *i)
438{
439 icalcomponent *c = 0;
440
441 icalerror_check_arg_rz((i != NULL), "i");
442
443 do {
444 c = icalcompiter_prior(&(i->iter));
445 if (c != 0 && (i->gauge == 0 || icalgauge_compare(i->gauge, c) == 1)) {
446 return c;
447 }
448 } while (c != 0);
449
450 return 0;
451}
452
453icalcomponent *icalsetiter_deref(icalsetiter *i)
454{
455 icalerror_check_arg_rz((i != NULL), "i");
456 return (icalcompiter_deref(&(i->iter)));
457}
458
459/* For subclasses that use multiple clusters that require specialized cluster traversal */
460icalcomponent *icalsetiter_to_next(icalset *set, icalsetiter *i)
461{
462 return set->icalsetiter_to_next(set, i);
463}
464
465icalcomponent *icalsetiter_to_prior(icalset *set, icalsetiter *i)
466{
467 return set->icalsetiter_to_prior(set, i);
468}
icalerrorenum icalbdbset_select(icalset *set, icalgauge *gauge)
Definition icalbdbset.c:986
void icalbdbset_clear(icalset *set)
const char * icalbdbset_path(icalset *set)
Definition icalbdbset.c:684
icalcomponent * icalbdbset_get_current_component(icalset *set)
icalerrorenum icalbdbset_commit(icalset *set)
Definition icalbdbset.c:703
Manages a Berkeley database of ical components and offers interfaces for reading, writing and searchi...
icalcomponent * icalcompiter_next(icalcompiter *i)
icalcomponent * icalcompiter_deref(icalcompiter *i)
icalcomponent * icalcompiter_prior(icalcompiter *i)
icalerrorenum icaldirset_add_component(icalset *set, icalcomponent *comp)
Definition icaldirset.c:293
icalerrorenum icaldirset_remove_component(icalset *set, icalcomponent *comp)
Definition icaldirset.c:371
Manages a database of ical components and offers interfaces for reading, writing and searching for co...
icalcomponent_kind
Definition icalenums.h:29
@ ICAL_NO_COMPONENT
Definition icalenums.h:30
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
Definition icalerror.c:90
icalerrorenum
Represents the different types of errors that can be triggered in libical.
Definition icalerror.h:42
@ ICAL_NEWFAILED_ERROR
Definition icalerror.h:50
@ ICAL_UNIMPLEMENTED_ERROR
Definition icalerror.h:71
icalerrorenum icalfileset_select(icalset *set, icalgauge *gauge)
icalerrorenum icalfileset_modify(icalset *set, icalcomponent *old, icalcomponent *new)
Modifies components according to the MODIFY method of CAP.
void icalfileset_clear(icalset *set)
Clears the gauge.
icalcomponent * icalfileset_fetch(icalset *set, icalcomponent_kind kind, const char *uid)
Gets and searches for a component by uid.
Manages a database of ical components and offers interfaces for reading, writing and searching for co...
bool icalgauge_compare(icalgauge *gauge, icalcomponent *comp)
Definition icalgauge.c:216
icalerrorenum icalset_select(icalset *set, icalgauge *gauge)
Definition icalset.c:368
void icalset_free(icalset *set)
Definition icalset.c:325
icalerrorenum icalset_commit(icalset *set)
Definition icalset.c:348
void icalset_mark(icalset *set)
Definition icalset.c:343
icalcomponent * icalset_get_current_component(icalset *set)
Definition icalset.c:398
icalcomponent * icalsetiter_to_next(icalset *set, icalsetiter *i)
Definition icalset.c:460
icalerrorenum icalset_modify(icalset *set, icalcomponent *old, icalcomponent *new)
Definition icalset.c:393
icalcomponent * icalset_get_first_component(icalset *set)
Definition icalset.c:403
icalsetiter icalsetiter_null
Definition icalset.c:413
icalcomponent * icalsetiter_next(icalsetiter *itr)
Definition icalset.c:421
icalcomponent * icalset_fetch(icalset *set, const char *uid)
Definition icalset.c:378
icalcomponent * icalset_get_next_component(icalset *set)
Definition icalset.c:408
icalset * icalset_new(icalset_kind kind, const char *dsn, void *options)
Definition icalset.c:193
Icalset is the "base class" for representations of a collection of iCal components.
icalset_kind
Definition icalset.h:38
@ ICAL_FILE_SET
Definition icalset.h:39
@ ICAL_BDB_SET
Definition icalset.h:41
@ ICAL_DIR_SET
Definition icalset.h:40
bool icalset_register_class(icalset *set)