summaryrefslogtreecommitdiffabout
path: root/libical/src/libicalss/icalfileset.c
Unidiff
Diffstat (limited to 'libical/src/libicalss/icalfileset.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libicalss/icalfileset.c725
1 files changed, 500 insertions, 225 deletions
diff --git a/libical/src/libicalss/icalfileset.c b/libical/src/libicalss/icalfileset.c
index 943071d..3ae6c54 100644
--- a/libical/src/libicalss/icalfileset.c
+++ b/libical/src/libicalss/icalfileset.c
@@ -27,116 +27,161 @@
27 27
28 28
29#ifdef HAVE_CONFIG_H 29#ifdef HAVE_CONFIG_H
30#include "config.h" 30#include "config.h"
31#endif 31#endif
32 32
33#include "icalfileset.h"
34#include "icalgauge.h"
33#include <errno.h> 35#include <errno.h>
34 36#include <sys/stat.h> /* for stat */
37#ifndef WIN32
38#include <unistd.h> /* for stat, getpid */
39#else
40#include <io.h>
41#include <share.h>
42#endif
35#include <stdlib.h> 43#include <stdlib.h>
36#include <stdio.h>
37#include <string.h> 44#include <string.h>
45#include <fcntl.h> /* for fcntl */
46#include "icalfilesetimpl.h"
47#include "icalclusterimpl.h"
38 48
39#include <fcntl.h> /* For open() flags and mode */ 49#ifdef WIN32
40#include <sys/types.h> /* For open() flags and mode */ 50 #define snprintf_snprintf
41#include <sys/stat.h> /* For open() flags and mode */ 51 #define strcasecmpstricmp
42 52
43#include "icalfileset.h" 53#define _S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask))
44#include "icalfilesetimpl.h"
45 54
46// Eugen C. <eug@thekompany.com> 55#define S_ISDIR(mode) _S_ISTYPE((mode), _S_IFDIR)
47#include <defines.h> 56#define S_ISREG(mode) _S_ISTYPE((mode), _S_IFREG)
48// 57#endif
49 58
50int snprintf(char *str, size_t n, char const *fmt, ...); 59extern int errno;
51 60
52//extern int errno; 61/** Default options used when NULL is passed to icalset_new() **/
62icalfileset_options icalfileset_options_default = {O_RDWR|O_CREAT, 0644, 0, 0};
53 63
54int icalfileset_lock(icalfileset *cluster); 64int icalfileset_lock(icalfileset *set);
55int icalfileset_unlock(icalfileset *cluster); 65int icalfileset_unlock(icalfileset *set);
56icalerrorenum icalfileset_read_file(icalfileset* cluster, mode_t mode); 66icalerrorenum icalfileset_read_file(icalfileset* set, mode_t mode);
57int icalfileset_filesize(icalfileset* cluster); 67int icalfileset_filesize(icalfileset* set);
58 68
59icalerrorenum icalfileset_create_cluster(const char *path); 69icalerrorenum icalfileset_create_cluster(const char *path);
60 70
61icalfileset* icalfileset_new_impl() 71icalset* icalfileset_new(const char* path)
62{ 72{
63 struct icalfileset_impl* impl; 73 return icalset_new(ICAL_FILE_SET, path, &icalfileset_options_default);
64
65 if ( ( impl = (struct icalfileset_impl*)
66 malloc(sizeof(struct icalfileset_impl))) == 0) {
67 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
68 errno = ENOMEM;
69 return 0;
70 }
71
72 memset(impl,0,sizeof(struct icalfileset_impl));
73
74 strcpy(impl->id,ICALFILESET_ID);
75
76 return impl;
77} 74}
78 75
79 76icalset* icalfileset_new_reader(const char* path)
80icalfileset* icalfileset_new(const char* path)
81{ 77{
82 return icalfileset_new_open(path, O_RDWR|O_CREAT, 0664); 78 icalfileset_options reader_options = icalfileset_options_default;
79 reader_options.flags = O_RDONLY;
80
81 return icalset_new(ICAL_FILE_SET, path, &reader_options);
83} 82}
84 83
85icalfileset* icalfileset_new_open(const char* path, int flags, mode_t mode) 84icalset* icalfileset_new_writer(const char* path)
86{ 85{
87 struct icalfileset_impl *impl = icalfileset_new_impl(); 86 icalfileset_options writer_options = icalfileset_options_default;
88 struct icaltimetype tt; 87 writer_options.flags = O_RDONLY;
89 off_t cluster_file_size;
90 88
91 memset(&tt,0,sizeof(struct icaltimetype)); 89 return icalset_new(ICAL_FILE_SET, path, &writer_options);
90}
92 91
93 icalerror_clear_errno(); 92icalset* icalfileset_init(icalset *set, const char* path, void* options_in)
94 icalerror_check_arg_rz( (path!=0), "path"); 93{
94 icalfileset_options *options = (options_in) ? options_in : &icalfileset_options_default;
95 icalfileset *fset = (icalfileset*) set;
96 int flags;
97 mode_t mode;
98 off_t cluster_file_size;
95 99
96 if (impl == 0){ 100 icalerror_clear_errno();
97 return 0; 101 icalerror_check_arg_rz( (path!=0), "path");
98 } 102 icalerror_check_arg_rz( (fset!=0), "fset");
99 103
100 impl->path = strdup(path); 104 fset->path = strdup(path);
105 fset->options = *options;
101 106
102 cluster_file_size = icalfileset_filesize(impl); 107 flags = options->flags;
103 108 mode = options->mode;
104 if(cluster_file_size < 0){ 109
105 icalfileset_free(impl); 110 cluster_file_size = icalfileset_filesize(fset);
106 return 0; 111
107 } 112 if(cluster_file_size < 0){
113 icalfileset_free(set);
114 return 0;
115 }
108 116
109 impl->fd = open(impl->path,flags, mode); 117#ifndef WIN32
118 fset->fd = open(fset->path, flags, mode);
119#else
120 fset->fd = open(fset->path, flags, mode);
121 /* fset->fd = sopen(fset->path,flags, _SH_DENYWR, _S_IREAD | _S_IWRITE); */
122#endif
110 123
111 if (impl->fd < 0){ 124 if (fset->fd < 0){
112 icalerror_set_errno(ICAL_FILE_ERROR); 125 icalerror_set_errno(ICAL_FILE_ERROR);
113 icalfileset_free(impl); 126 icalfileset_free(set);
114 return 0; 127 return 0;
115 } 128 }
116 129
117 icalfileset_lock(impl); 130#ifndef WIN32
131 icalfileset_lock(fset);
132#endif
118 133
119 if(cluster_file_size > 0 ){ 134 if(cluster_file_size > 0 ){
120 icalerrorenum error; 135 icalerrorenum error;
121 if((error = icalfileset_read_file(impl,mode))!= ICAL_NO_ERROR){ 136 if((error = icalfileset_read_file(fset,mode))!= ICAL_NO_ERROR){
122 icalfileset_free(impl); 137 icalfileset_free(set);
123 return 0; 138 return 0;
124 } 139 }
125 } 140 }
126 141
127 if(impl->cluster == 0){ 142 if (options->cluster) {
128 impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); 143 fset->cluster = icalcomponent_new_clone(icalcluster_get_component(options->cluster));
129 } 144 fset->changed = 1;
145 }
146
147 if (fset->cluster == 0) {
148 fset->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT);
149 }
150
151 return set;
152}
153
154
155icalcluster* icalfileset_produce_icalcluster(const char *path) {
156 icalset *fileset;
157 icalcluster *ret;
158
159 int errstate = icalerror_errors_are_fatal;
160 icalerror_errors_are_fatal = 0;
130 161
131 return impl; 162 fileset = icalfileset_new_reader(path);
163
164
165 if (fileset == 0 && icalerrno == ICAL_FILE_ERROR) {
166 /* file does not exist */
167 ret = icalcluster_new(path, NULL);
168 } else {
169 ret = icalcluster_new(path, ((icalfileset*)fileset)->cluster);
170 icalfileset_free(fileset);
171 }
172
173 icalerror_errors_are_fatal = errstate;
174 icalerror_set_errno(ICAL_NO_ERROR);
175 return ret;
132} 176}
133 177
178
179
134char* icalfileset_read_from_file(char *s, size_t size, void *d) 180char* icalfileset_read_from_file(char *s, size_t size, void *d)
135{ 181{
136
137 char* p = s; 182 char* p = s;
138 int fd = (int)d; 183 int fd = (int)d;
139 184
140 /* Simulate fgets -- read single characters and stop at '\n' */ 185 /* Simulate fgets -- read single characters and stop at '\n' */
141 186
142 for(p=s; p<s+size-1;p++){ 187 for(p=s; p<s+size-1;p++){
@@ -155,48 +200,44 @@ char* icalfileset_read_from_file(char *s, size_t size, void *d)
155 return s; 200 return s;
156 } 201 }
157 202
158} 203}
159 204
160 205
161icalerrorenum icalfileset_read_file(icalfileset* cluster,mode_t mode) 206icalerrorenum icalfileset_read_file(icalfileset* set,mode_t mode)
162{ 207{
163
164 icalparser *parser; 208 icalparser *parser;
165 209
166 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster;
167
168 parser = icalparser_new(); 210 parser = icalparser_new();
169 icalparser_set_gen_data(parser,(void*)impl->fd); 211
170 impl->cluster = icalparser_parse(parser,icalfileset_read_from_file); 212 icalparser_set_gen_data(parser,(void*)set->fd);
213 set->cluster = icalparser_parse(parser,icalfileset_read_from_file);
171 icalparser_free(parser); 214 icalparser_free(parser);
172 215
173 if (impl->cluster == 0 || icalerrno != ICAL_NO_ERROR){ 216 if (set->cluster == 0 || icalerrno != ICAL_NO_ERROR){
174 icalerror_set_errno(ICAL_PARSE_ERROR); 217 icalerror_set_errno(ICAL_PARSE_ERROR);
175 return ICAL_PARSE_ERROR; 218 /*return ICAL_PARSE_ERROR;*/
176 } 219 }
177 220
178 if (icalcomponent_isa(impl->cluster) != ICAL_XROOT_COMPONENT){ 221 if (icalcomponent_isa(set->cluster) != ICAL_XROOT_COMPONENT){
179 /* The parser got a single component, so it did not put it in 222 /* The parser got a single component, so it did not put it in
180 an XROOT. */ 223 an XROOT. */
181 icalcomponent *cl = impl->cluster; 224 icalcomponent *cl = set->cluster;
182 impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); 225 set->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT);
183 icalcomponent_add_component(impl->cluster,cl); 226 icalcomponent_add_component(set->cluster,cl);
184 } 227 }
185 228
186 return ICAL_NO_ERROR; 229 return ICAL_NO_ERROR;
187
188} 230}
189 231
190int icalfileset_filesize(icalfileset* cluster) 232int icalfileset_filesize(icalfileset* fset)
191{ 233{
192 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster;
193 int cluster_file_size; 234 int cluster_file_size;
194 struct stat sbuf; 235 struct stat sbuf;
195 236
196 if (stat(impl->path,&sbuf) != 0){ 237 if (stat(fset->path,&sbuf) != 0){
197 238
198 /* A file by the given name does not exist, or there was 239 /* A file by the given name does not exist, or there was
199 another error */ 240 another error */
200 cluster_file_size = 0; 241 cluster_file_size = 0;
201 if (errno == ENOENT) { 242 if (errno == ENOENT) {
202 /* It was because the file does not exist */ 243 /* It was because the file does not exist */
@@ -206,289 +247,284 @@ int icalfileset_filesize(icalfileset* cluster)
206 icalerror_set_errno(ICAL_FILE_ERROR); 247 icalerror_set_errno(ICAL_FILE_ERROR);
207 return -1; 248 return -1;
208 } 249 }
209 } else { 250 } else {
210 /* A file by the given name exists, but is it a regular file? */ 251 /* A file by the given name exists, but is it a regular file? */
211 252
212#ifndef _QTWIN_
213 if (!S_ISREG(sbuf.st_mode)){ 253 if (!S_ISREG(sbuf.st_mode)){
214 /* Nope, not a regular file */ 254 /* Nope, not a regular file */
215 icalerror_set_errno(ICAL_FILE_ERROR); 255 icalerror_set_errno(ICAL_FILE_ERROR);
216 return -1; 256 return -1;
217 } else { 257 } else {
218 /* Lets assume that it is a file of the right type */ 258 /* Lets assume that it is a file of the right type */
219 return sbuf.st_size; 259 return sbuf.st_size;
220 } 260 }
221#else
222 return sbuf.st_size;
223#endif
224
225 } 261 }
226 262
227 /*return -1; not reached*/ 263 /*return -1; not reached*/
228} 264}
229 265
230void icalfileset_free(icalfileset* cluster) 266void icalfileset_free(icalset* set)
231{ 267{
232 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; 268 icalfileset *fset = (icalfileset*) set;
233 269
234 icalerror_check_arg_rv((cluster!=0),"cluster"); 270 icalerror_check_arg_rv((set!=0),"set");
235 271
236 if (impl->cluster != 0){ 272 if (fset->cluster != 0){
237 icalfileset_commit(cluster); 273 icalfileset_commit(set);
238 icalcomponent_free(impl->cluster); 274 icalcomponent_free(fset->cluster);
239 impl->cluster=0; 275 fset->cluster=0;
240 } 276 }
241 277
242 if(impl->fd > 0){ 278 if (fset->gauge != 0){
243 icalfileset_unlock(impl); 279 icalgauge_free(fset->gauge);
244 close(impl->fd); 280 fset->gauge=0;
245 impl->fd = -1;
246 } 281 }
247 282
248 if(impl->path != 0){ 283 if(fset->fd > 0){
249 free(impl->path); 284 icalfileset_unlock(fset);
250 impl->path = 0; 285 close(fset->fd);
286 fset->fd = -1;
251 } 287 }
252 288
253 free(impl); 289 if(fset->path != 0){
290 free(fset->path);
291 fset->path = 0;
292 }
254} 293}
255 294
256const char* icalfileset_path(icalfileset* cluster) 295const char* icalfileset_path(icalset* set) {
257{ 296 icalerror_check_arg_rz((set!=0),"set");
258 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster;
259 icalerror_check_arg_rz((cluster!=0),"cluster");
260 297
261 return impl->path; 298 return ((icalfileset*)set)->path;
262} 299}
263 300
264 301
265int icalfileset_lock(icalfileset *cluster) 302int icalfileset_lock(icalfileset *set)
266{ 303{
267#ifndef _WIN32 304#ifndef WIN32
268 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster;
269 struct flock lock; 305 struct flock lock;
270 int rtrn; 306 int rtrn;
271 307
272 icalerror_check_arg_rz((impl->fd>0),"impl->fd"); 308 icalerror_check_arg_rz((set->fd>0),"set->fd");
273 errno = 0; 309 errno = 0;
274 lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ 310 lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */
275 lock.l_start = 0; /* byte offset relative to l_whence */ 311 lock.l_start = 0; /* byte offset relative to l_whence */
276 lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ 312 lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
277 lock.l_len = 0; /* #bytes (0 means to EOF) */ 313 lock.l_len = 0; /* #bytes (0 means to EOF) */
278 314
279 rtrn = fcntl(impl->fd, F_SETLKW, &lock); 315 rtrn = fcntl(set->fd, F_SETLKW, &lock);
280 316
281 return rtrn; 317 return rtrn;
282#else 318#else
283 return -1; 319 return 0;
284#endif 320#endif
285} 321}
286 322
287int icalfileset_unlock(icalfileset *cluster) 323int icalfileset_unlock(icalfileset *set)
288{ 324{
289#ifndef _WIN32 325#ifndef WIN32
290 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster;
291 struct flock lock; 326 struct flock lock;
292 icalerror_check_arg_rz((impl->fd>0),"impl->fd"); 327 icalerror_check_arg_rz((set->fd>0),"set->fd");
293 328
294 lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ 329 lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */
295 lock.l_start = 0; /* byte offset relative to l_whence */ 330 lock.l_start = 0; /* byte offset relative to l_whence */
296 lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ 331 lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
297 lock.l_len = 0; /* #bytes (0 means to EOF) */ 332 lock.l_len = 0; /* #bytes (0 means to EOF) */
298 333
299 return (fcntl(impl->fd, F_UNLCK, &lock)); 334 return (fcntl(set->fd, F_UNLCK, &lock));
300#else 335#else
301 return -1; 336 return 0;
302#endif 337#endif
303} 338}
304 339
305#ifdef ICAL_SAFESAVES 340icalerrorenum icalfileset_commit(icalset* set)
306int icalfileset_safe_saves=1;
307#else
308int icalfileset_safe_saves=0;
309#endif
310
311icalerrorenum icalfileset_commit(icalfileset* cluster)
312{ 341{
313 char tmp[ICAL_PATH_MAX]; 342 char tmp[ICAL_PATH_MAX];
314 char *str; 343 char *str;
315 icalcomponent *c; 344 icalcomponent *c;
316 off_t write_size=0; 345 off_t write_size=0;
346 icalfileset *fset = (icalfileset*) set;
347
348 icalerror_check_arg_re((fset!=0),"set",ICAL_BADARG_ERROR);
317 349
318 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; 350 icalerror_check_arg_re((fset->fd>0),"set->fd is invalid",
319
320 icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR);
321
322 icalerror_check_arg_re((impl->fd>0),"impl->fd is invalid",
323 ICAL_INTERNAL_ERROR) ; 351 ICAL_INTERNAL_ERROR) ;
324 352
325 if (impl->changed == 0 ){ 353 if (fset->changed == 0 ){
326 return ICAL_NO_ERROR; 354 return ICAL_NO_ERROR;
327 } 355 }
328 356
329 if(icalfileset_safe_saves == 1){ 357 if (fset->options.safe_saves == 1) {
330 snprintf(tmp,ICAL_PATH_MAX,"cp %s %s.bak",impl->path,impl->path); 358#ifndef WIN32
359 snprintf(tmp,ICAL_PATH_MAX,"cp '%s' '%s.bak'",fset->path, fset->path);
360#else
361 snprintf(tmp,ICAL_PATH_MAX,"copy %s %s.bak", fset->path, fset->path);
362#endif
331 363
332 if(system(tmp) < 0){ 364 if(system(tmp) < 0){
333 icalerror_set_errno(ICAL_FILE_ERROR); 365 icalerror_set_errno(ICAL_FILE_ERROR);
334 return ICAL_FILE_ERROR; 366 return ICAL_FILE_ERROR;
335 } 367 }
336 } 368 }
337 369
338 if(lseek(impl->fd,SEEK_SET,0) < 0){ 370 if(lseek(fset->fd, 0, SEEK_SET) < 0){
339 icalerror_set_errno(ICAL_FILE_ERROR); 371 icalerror_set_errno(ICAL_FILE_ERROR);
340 return ICAL_FILE_ERROR; 372 return ICAL_FILE_ERROR;
341 } 373 }
342 374
343 for(c = icalcomponent_get_first_component(impl->cluster,ICAL_ANY_COMPONENT); 375 for(c = icalcomponent_get_first_component(fset->cluster,ICAL_ANY_COMPONENT);
344 c != 0; 376 c != 0;
345 c = icalcomponent_get_next_component(impl->cluster,ICAL_ANY_COMPONENT)){ 377 c = icalcomponent_get_next_component(fset->cluster,ICAL_ANY_COMPONENT)){
346 int sz; 378 int sz;
347 379
348 str = icalcomponent_as_ical_string(c); 380 str = icalcomponent_as_ical_string(c);
349 381
350 sz=write(impl->fd,str,strlen(str)); 382 sz=write(fset->fd,str,strlen(str));
351 383
352 if ( sz != strlen(str)){ 384 if ( sz != strlen(str)){
353 perror("write"); 385 perror("write");
354 icalerror_set_errno(ICAL_FILE_ERROR); 386 icalerror_set_errno(ICAL_FILE_ERROR);
355 return ICAL_FILE_ERROR; 387 return ICAL_FILE_ERROR;
356 } 388 }
357 389
358 write_size += sz; 390 write_size += sz;
359 } 391 }
360 392
361 impl->changed = 0; 393 fset->changed = 0;
362 394
363#ifndef _QTWIN_ 395#ifndef WIN32
364 if(ftruncate(impl->fd,write_size) < 0){ 396 if(ftruncate(fset->fd,write_size) < 0){
365 return ICAL_FILE_ERROR; 397 return ICAL_FILE_ERROR;
366 } 398 }
399#else
400 chsize( fset->fd, tell( fset->fd ) );
367#endif 401#endif
368 402
369 return ICAL_NO_ERROR; 403 return ICAL_NO_ERROR;
370
371} 404}
372 405
373void icalfileset_mark(icalfileset* cluster){ 406void icalfileset_mark(icalset* set) {
374 407 icalerror_check_arg_rv((set!=0),"set");
375 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster;
376
377 icalerror_check_arg_rv((impl!=0),"cluster");
378
379 impl->changed = 1;
380 408
409 ((icalfileset*)set)->changed = 1;
381} 410}
382 411
383icalcomponent* icalfileset_get_component(icalfileset* cluster){ 412icalcomponent* icalfileset_get_component(icalset* set){
384 struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; 413 icalfileset *fset = (icalfileset*) set;
414 icalerror_check_arg_rz((set!=0),"set");
385 415
386 icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); 416 return fset->cluster;
387
388 return impl->cluster;
389} 417}
390 418
391 419
392/* manipulate the components in the cluster */ 420/* manipulate the components in the set */
393 421
394icalerrorenum icalfileset_add_component(icalfileset *cluster, 422icalerrorenum icalfileset_add_component(icalset *set,
395 icalcomponent* child) 423 icalcomponent* child)
396{ 424{
397 struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; 425 icalfileset *fset = (icalfileset*) set;
398 426
399 icalerror_check_arg_re((cluster!=0),"cluster", ICAL_BADARG_ERROR); 427 icalerror_check_arg_re((set!=0),"set", ICAL_BADARG_ERROR);
400 icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR); 428 icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR);
401 429
402 icalcomponent_add_component(impl->cluster,child); 430 icalcomponent_add_component(fset->cluster,child);
403 431
404 icalfileset_mark(cluster); 432 icalfileset_mark(set);
405 433
406 return ICAL_NO_ERROR; 434 return ICAL_NO_ERROR;
407
408} 435}
409 436
410icalerrorenum icalfileset_remove_component(icalfileset *cluster, 437icalerrorenum icalfileset_remove_component(icalset *set,
411 icalcomponent* child) 438 icalcomponent* child)
412{ 439{
413 struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; 440 icalfileset *fset = (icalfileset*) set;
414 441
415 icalerror_check_arg_re((cluster!=0),"cluster",ICAL_BADARG_ERROR); 442 icalerror_check_arg_re((set!=0),"set",ICAL_BADARG_ERROR);
416 icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR); 443 icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR);
417 444
418 icalcomponent_remove_component(impl->cluster,child); 445 icalcomponent_remove_component(fset->cluster,child);
419 446
420 icalfileset_mark(cluster); 447 icalfileset_mark(set);
421 448
422 return ICAL_NO_ERROR; 449 return ICAL_NO_ERROR;
423} 450}
424 451
425int icalfileset_count_components(icalfileset *cluster, 452int icalfileset_count_components(icalset *set,
426 icalcomponent_kind kind) 453 icalcomponent_kind kind)
427{ 454{
428 struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; 455 icalfileset *fset = (icalfileset*) set;
429 456
430 if(cluster == 0){ 457 if (set == 0){
431 icalerror_set_errno(ICAL_BADARG_ERROR); 458 icalerror_set_errno(ICAL_BADARG_ERROR);
432 return -1; 459 return -1;
433 } 460 }
434 461
435 return icalcomponent_count_components(impl->cluster,kind); 462 return icalcomponent_count_components(fset->cluster,kind);
436} 463}
437 464
438icalerrorenum icalfileset_select(icalfileset* set, icalgauge* gauge) 465icalerrorenum icalfileset_select(icalset* set, icalgauge* gauge)
439{ 466{
440 struct icalfileset_impl* impl = (struct icalfileset_impl*)set; 467 icalfileset *fset = (icalfileset*) set;
441 468
442 icalerror_check_arg_re(gauge!=0,"guage",ICAL_BADARG_ERROR); 469 icalerror_check_arg_re(gauge!=0,"gauge",ICAL_BADARG_ERROR);
443 470
444 impl->gauge = gauge; 471 fset->gauge = gauge;
445 472
446 return ICAL_NO_ERROR; 473 return ICAL_NO_ERROR;
447} 474}
448 475
449void icalfileset_clear(icalfileset* gauge) 476void icalfileset_clear(icalset* set)
450{ 477{
451 struct icalfileset_impl* impl = (struct icalfileset_impl*)gauge; 478 icalfileset *fset = (icalfileset*) set;
452 479
453 impl->gauge = 0; 480 icalerror_check_arg_rv(set!=0,"set");
454 481
482 fset->gauge = 0;
455} 483}
456 484
457icalcomponent* icalfileset_fetch(icalfileset* store,const char* uid) 485icalcomponent* icalfileset_fetch(icalset* set,const char* uid)
458{ 486{
487 icalfileset *fset = (icalfileset*) set;
459 icalcompiter i; 488 icalcompiter i;
460 struct icalfileset_impl* impl = (struct icalfileset_impl*)store; 489
490 icalerror_check_arg_rz(set!=0,"set");
461 491
462 for(i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); 492 for(i = icalcomponent_begin_component(fset->cluster,ICAL_ANY_COMPONENT);
463 icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){ 493 icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){
464 494
465 icalcomponent *this = icalcompiter_deref(&i); 495 icalcomponent *this = icalcompiter_deref(&i);
466 icalcomponent *inner = icalcomponent_get_first_real_component(this); 496 icalcomponent *inner;
467 icalcomponent *p; 497 icalproperty *p;
468 const char *this_uid; 498 const char *this_uid;
469 499
470 if(inner != 0){ 500 for(inner = icalcomponent_get_first_component(this,ICAL_ANY_COMPONENT);
471 p = icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY); 501 inner != 0;
472 this_uid = icalproperty_get_uid(p); 502 inner = icalcomponent_get_next_component(this,ICAL_ANY_COMPONENT)){
473 503
474 if(this_uid==0){ 504 p = icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY);
475 icalerror_warn("icalfileset_fetch found a component with no UID"); 505 if ( p )
476 continue; 506 {
477 } 507 this_uid = icalproperty_get_uid(p);
478 508
479 if (strcmp(uid,this_uid)==0){ 509 if(this_uid==0){
480 return this; 510 icalerror_warn("icalfileset_fetch found a component with no UID");
481 } 511 continue;
512 }
513
514 if (strcmp(uid,this_uid)==0){
515 return this;
516 }
517 }
518 }
482 } 519 }
483 }
484 520
485 return 0; 521 return 0;
486} 522}
487 523
488int icalfileset_has_uid(icalfileset* store,const char* uid) 524int icalfileset_has_uid(icalset* set,const char* uid)
489{ 525{
490 assert(0); /* HACK, not implemented */ 526 assert(0); /* HACK, not implemented */
491 return 0; 527 return 0;
492} 528}
493 529
494/******* support routines for icalfileset_fetch_match *********/ 530/******* support routines for icalfileset_fetch_match *********/
@@ -505,18 +541,17 @@ void icalfileset_id_free(struct icalfileset_id *id)
505 free(id->recurrence_id); 541 free(id->recurrence_id);
506 } 542 }
507 543
508 if(id->uid != 0){ 544 if(id->uid != 0){
509 free(id->uid); 545 free(id->uid);
510 } 546 }
511
512} 547}
513 548
549
514struct icalfileset_id icalfileset_get_id(icalcomponent* comp) 550struct icalfileset_id icalfileset_get_id(icalcomponent* comp)
515{ 551{
516
517 icalcomponent *inner; 552 icalcomponent *inner;
518 struct icalfileset_id id; 553 struct icalfileset_id id;
519 icalproperty *p; 554 icalproperty *p;
520 555
521 inner = icalcomponent_get_first_real_component(comp); 556 inner = icalcomponent_get_first_real_component(comp);
522 557
@@ -546,25 +581,26 @@ struct icalfileset_id icalfileset_get_id(icalcomponent* comp)
546 assert(id.recurrence_id != 0); 581 assert(id.recurrence_id != 0);
547 } 582 }
548 583
549 return id; 584 return id;
550} 585}
551 586
587
552/* Find the component that is related to the given 588/* Find the component that is related to the given
553 component. Currently, it just matches based on UID and 589 component. Currently, it just matches based on UID and
554 RECURRENCE-ID */ 590 RECURRENCE-ID */
555icalcomponent* icalfileset_fetch_match(icalfileset* set, icalcomponent *comp) 591icalcomponent* icalfileset_fetch_match(icalset* set, icalcomponent *comp)
556{ 592{
557 struct icalfileset_impl* impl = (struct icalfileset_impl*)set; 593 icalfileset *fset = (icalfileset*) set;
558 icalcompiter i; 594 icalcompiter i;
559 595
560 struct icalfileset_id comp_id, match_id; 596 struct icalfileset_id comp_id, match_id;
561 597
562 comp_id = icalfileset_get_id(comp); 598 comp_id = icalfileset_get_id(comp);
563 599
564 for(i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); 600 for(i = icalcomponent_begin_component(fset->cluster,ICAL_ANY_COMPONENT);
565 icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){ 601 icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){
566 602
567 icalcomponent *match = icalcompiter_deref(&i); 603 icalcomponent *match = icalcompiter_deref(&i);
568 604
569 match_id = icalfileset_get_id(match); 605 match_id = icalfileset_get_id(match);
570 606
@@ -586,74 +622,313 @@ icalcomponent* icalfileset_fetch_match(icalfileset* set, icalcomponent *comp)
586 icalfileset_id_free(&comp_id); 622 icalfileset_id_free(&comp_id);
587 return 0; 623 return 0;
588 624
589} 625}
590 626
591 627
592icalerrorenum icalfileset_modify(icalfileset* store, icalcomponent *old, 628icalerrorenum icalfileset_modify(icalset* set, icalcomponent *old,
593 icalcomponent *new) 629 icalcomponent *new)
594{ 630{
631 icalfileset *fset = (icalfileset*) set;
632
595 assert(0); /* HACK, not implemented */ 633 assert(0); /* HACK, not implemented */
596 return ICAL_NO_ERROR; 634 return ICAL_NO_ERROR;
597} 635}
598 636
599 637
600/* Iterate through components */ 638/* Iterate through components */
601icalcomponent* icalfileset_get_current_component (icalfileset* cluster) 639icalcomponent* icalfileset_get_current_component (icalset* set)
602{ 640{
603 struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; 641 icalfileset *fset = (icalfileset*) set;
604 642
605 icalerror_check_arg_rz((cluster!=0),"cluster"); 643 icalerror_check_arg_rz((set!=0),"set");
606 644
607 return icalcomponent_get_current_component(impl->cluster); 645 return icalcomponent_get_current_component(fset->cluster);
608} 646}
609 647
610 648
611icalcomponent* icalfileset_get_first_component(icalfileset* cluster) 649icalcomponent* icalfileset_get_first_component(icalset* set)
612{ 650{
613 struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster;
614 icalcomponent *c=0; 651 icalcomponent *c=0;
652 icalfileset *fset = (icalfileset*) set;
615 653
616 icalerror_check_arg_rz((cluster!=0),"cluster"); 654 icalerror_check_arg_rz((set!=0),"set");
617 655
618 do { 656 do {
619 if (c == 0){ 657 if (c == 0){
620 c = icalcomponent_get_first_component(impl->cluster, 658 c = icalcomponent_get_first_component(fset->cluster,
621 ICAL_ANY_COMPONENT); 659 ICAL_ANY_COMPONENT);
622 } else { 660 } else {
623 c = icalcomponent_get_next_component(impl->cluster, 661 c = icalcomponent_get_next_component(fset->cluster,
624 ICAL_ANY_COMPONENT); 662 ICAL_ANY_COMPONENT);
625 } 663 }
626 664
627 if(c != 0 && (impl->gauge == 0 || 665 if(c != 0 && (fset->gauge == 0 ||
628 icalgauge_compare(impl->gauge,c) == 1)){ 666 icalgauge_compare(fset->gauge, c) == 1)){
629 return c; 667 return c;
630 } 668 }
631 669
632 } while(c != 0); 670 } while(c != 0);
633 671
634 672
635 return 0; 673 return 0;
636} 674}
637 675
638icalcomponent* icalfileset_get_next_component(icalfileset* cluster) 676icalcomponent* icalfileset_get_next_component(icalset* set)
639{ 677{
640 struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; 678 icalfileset *fset = (icalfileset*) set;
641 icalcomponent *c; 679 icalcomponent *c;
642 680
643 icalerror_check_arg_rz((cluster!=0),"cluster"); 681 icalerror_check_arg_rz((set!=0),"set");
644 682
645 do { 683 do {
646 c = icalcomponent_get_next_component(impl->cluster, 684 c = icalcomponent_get_next_component(fset->cluster,
647 ICAL_ANY_COMPONENT); 685 ICAL_ANY_COMPONENT);
648 686
649 if(c != 0 && (impl->gauge == 0 || 687 if(c != 0 && (fset->gauge == 0 ||
650 icalgauge_compare(impl->gauge,c) == 1)){ 688 icalgauge_compare(fset->gauge,c) == 1)){
651 return c; 689 return c;
652 } 690 }
653 691
654 } while(c != 0); 692 } while(c != 0);
655 693
656 694
657 return 0; 695 return 0;
658} 696}
697/*
698icalsetiter icalfileset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge)
699{
700 icalsetiter itr = icalsetiter_null;
701 icalcomponent* comp = NULL;
702 icalcompiter citr;
703 icalfileset *fset = (icalfileset*) set;
704
705 icalerror_check_arg_re((set!=0), "set", icalsetiter_null);
706
707 itr.gauge = gauge;
708
709 citr = icalcomponent_begin_component(fset->cluster, kind);
710 comp = icalcompiter_deref(&citr);
711
712 while (comp != 0) {
713 comp = icalcompiter_deref(&citr);
714 if (gauge == 0 || icalgauge_compare(itr.gauge, comp) == 1) {
715 itr.iter = citr;
716 return itr;
717 }
718 comp = icalcompiter_next(&citr);
719 }
720
721 return icalsetiter_null;
722}
723*/
724
725icalsetiter icalfileset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge)
726{
727 icalsetiter itr = icalsetiter_null;
728 icalcomponent* comp = NULL;
729 icalcompiter citr;
730 icalfileset *fset = (icalfileset*) set;
731 struct icaltimetype start, next;
732 icalproperty *dtstart, *rrule, *prop, *due;
733 struct icalrecurrencetype recur;
734 int g = 0;
735
736 icalerror_check_arg_re((set!=0), "set", icalsetiter_null);
737
738 itr.gauge = gauge;
739
740 citr = icalcomponent_begin_component(fset->cluster, kind);
741 comp = icalcompiter_deref(&citr);
742
743 if (gauge == 0) {
744 itr.iter = citr;
745 return itr;
746 }
747
748 while (comp != 0) {
749
750 /* check if it is a recurring component and with guage expand, if so
751 we need to add recurrence-id property to the given component */
752 rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY);
753 g = icalgauge_get_expand(gauge);
754
755 if (rrule != 0
756 && g == 1) {
757
758 recur = icalproperty_get_rrule(rrule);
759 if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) {
760 dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY);
761 if (dtstart)
762 start = icalproperty_get_dtstart(dtstart);
763 } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) {
764 due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY);
765 if (due)
766 start = icalproperty_get_due(due);
767 }
768
769 if (itr.last_component == NULL) {
770 itr.ritr = icalrecur_iterator_new(recur, start);
771 next = icalrecur_iterator_next(itr.ritr);
772 itr.last_component = comp;
773 }
774 else {
775 next = icalrecur_iterator_next(itr.ritr);
776 if (icaltime_is_null_time(next)){
777 itr.last_component = NULL;
778 icalrecur_iterator_free(itr.ritr);
779 itr.ritr = NULL;
780 return icalsetiter_null;
781 } else {
782 itr.last_component = comp;
783 }
784 }
785
786 /* add recurrence-id to the component
787 if there is a recurrence-id already, remove it, then add the new one */
788 if (prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY))
789 icalcomponent_remove_property(comp, prop);
790 icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next));
791
792 }
793
794 if (gauge == 0 || icalgauge_compare(itr.gauge, comp) == 1) {
795 /* matches and returns */
796 itr.iter = citr;
797 return itr;
798 }
799
800 /* if there is no previous component pending, then get the next component */
801 if (itr.last_component == NULL)
802 comp = icalcompiter_next(&citr);
803 }
804
805 return icalsetiter_null;
806}
807icalcomponent* icalfileset_form_a_matched_recurrence_component(icalsetiter* itr)
808{
809 icalcomponent* comp = NULL;
810 struct icaltimetype start, next;
811 icalproperty *dtstart, *rrule, *prop, *due;
812 struct icalrecurrencetype recur;
813
814 comp = itr->last_component;
815
816 if (comp == NULL || itr->gauge == NULL) {
817 return NULL;
818 }
819
820 rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY);
821
822 recur = icalproperty_get_rrule(rrule);
823
824 if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) {
825 dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY);
826 if (dtstart)
827 start = icalproperty_get_dtstart(dtstart);
828 } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) {
829 due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY);
830 if (due)
831 start = icalproperty_get_due(due);
832 }
833
834 if (itr->ritr == NULL) {
835 itr->ritr = icalrecur_iterator_new(recur, start);
836 next = icalrecur_iterator_next(itr->ritr);
837 itr->last_component = comp;
838 } else {
839 next = icalrecur_iterator_next(itr->ritr);
840 if (icaltime_is_null_time(next)){
841 /* no more recurrence, returns */
842 itr->last_component = NULL;
843 icalrecur_iterator_free(itr->ritr);
844 itr->ritr = NULL;
845 return NULL;
846 } else {
847 itr->last_component = comp;
848 }
849 }
850
851 /* add recurrence-id to the component
852 * if there is a recurrence-id already, remove it, then add the new one */
853 if (prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY))
854 icalcomponent_remove_property(comp, prop);
855 icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next));
856
857 if (itr->gauge == 0 || icalgauge_compare(itr->gauge, comp) == 1) {
858 /* matches and returns */
859 return comp;
860 }
861 /* not matched */
862 return NULL;
863
864}
865icalcomponent* icalfilesetiter_to_next(icalset* set, icalsetiter* i)
866{
867
868 icalcomponent* c = NULL;
869 icalfileset *fset = (icalfileset*) set;
870 struct icaltimetype start, next;
871 icalproperty *dtstart, *rrule, *prop, *due;
872 struct icalrecurrencetype recur;
873 int g = 0;
874
875
876 do {
877 c = icalcompiter_next(&(i->iter));
878
879 if (c == 0) continue;
880 if (i->gauge == 0) return c;
881
882
883 rrule = icalcomponent_get_first_property(c, ICAL_RRULE_PROPERTY);
884 g = icalgauge_get_expand(i->gauge);
885
886 /* a recurring component with expand query */
887 if (rrule != 0
888 && g == 1) {
889
890 recur = icalproperty_get_rrule(rrule);
891
892 if (icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT) {
893 dtstart = icalcomponent_get_first_property(c, ICAL_DTSTART_PROPERTY);
894 if (dtstart)
895 start = icalproperty_get_dtstart(dtstart);
896 } else if (icalcomponent_isa(c) == ICAL_VTODO_COMPONENT) {
897 due = icalcomponent_get_first_property(c, ICAL_DUE_PROPERTY);
898 if (due)
899 start = icalproperty_get_due(due);
900 }
901
902 if (i->ritr == NULL) {
903 i->ritr = icalrecur_iterator_new(recur, start);
904 next = icalrecur_iterator_next(i->ritr);
905 i->last_component = c;
906 } else {
907 next = icalrecur_iterator_next(i->ritr);
908 if (icaltime_is_null_time(next)) {
909 /* no more recurrence, returns */
910 i->last_component = NULL;
911 icalrecur_iterator_free(i->ritr);
912 i->ritr = NULL;
913 return NULL;
914 } else {
915 i->last_component = c;
916 }
917 }
918 }
919
920 /* add recurrence-id to the component
921 * if there is a recurrence-id already, remove it, then add the new one */
922 if (prop = icalcomponent_get_first_property(c, ICAL_RECURRENCEID_PROPERTY))
923 icalcomponent_remove_property(c, prop);
924 icalcomponent_add_property(c, icalproperty_new_recurrenceid(next));
925
926 if(c != 0 && (i->gauge == 0 ||
927 icalgauge_compare(i->gauge, c) == 1)){
928 return c;
929 }
930 } while (c != 0);
931
932 return 0;
659 933
934}