summaryrefslogtreecommitdiffabout
path: root/libical/src/libicalss/icaldirset.c
Unidiff
Diffstat (limited to 'libical/src/libicalss/icaldirset.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libicalss/icaldirset.c542
1 files changed, 285 insertions, 257 deletions
diff --git a/libical/src/libicalss/icaldirset.c b/libical/src/libicalss/icaldirset.c
index b6cb673..4a20fe1 100644
--- a/libical/src/libicalss/icaldirset.c
+++ b/libical/src/libicalss/icaldirset.c
@@ -23,28 +23,30 @@
23 Code is Eric Busboom 23 Code is Eric Busboom
24 24
25 25
26 ======================================================================*/ 26 ======================================================================*/
27 27
28 28
29/* 29/**
30 @file icaldirset.c
30 31
31 icaldirset manages a database of ical components and offers 32 @brief icaldirset manages a database of ical components and offers
32 interfaces for reading, writting and searching for components. 33 interfaces for reading, writting and searching for components.
33 34
34 icaldirset groups components in to clusters based on their DTSTAMP 35 icaldirset groups components in to clusters based on their DTSTAMP
35 time -- all components that start in the same month are grouped 36 time -- all components that start in the same month are grouped
36 together in a single file. All files in a sotre are kept in a single 37 together in a single file. All files in a sotre are kept in a single
37 directory. 38 directory.
38 39
39 The primary interfaces are icaldirset_first and icaldirset_next. These 40 The primary interfaces are icaldirset__get_first_component and
40 routine iterate through all of the components in the store, subject 41 icaldirset_get_next_component. These routine iterate through all of
41 to the current gauge. A gauge is an icalcomponent that is tested 42 the components in the store, subject to the current gauge. A gauge
42 against other componets for a match. If a gauge has been set with 43 is an icalcomponent that is tested against other componets for a
43 icaldirset_select, icaldirset_first and icaldirset_next will only 44 match. If a gauge has been set with icaldirset_select,
44 return componentes that match the gauge. 45 icaldirset_first and icaldirset_next will only return componentes
46 that match the gauge.
45 47
46 The Store generated UIDs for all objects that are stored if they do 48 The Store generated UIDs for all objects that are stored if they do
47 not already have a UID. The UID is the name of the cluster (month & 49 not already have a UID. The UID is the name of the cluster (month &
48 year as MMYYYY) plus a unique serial number. The serial number is 50 year as MMYYYY) plus a unique serial number. The serial number is
49 stored as a property of the cluster. 51 stored as a property of the cluster.
50 52
@@ -52,109 +54,110 @@
52 54
53#ifdef HAVE_CONFIG_H 55#ifdef HAVE_CONFIG_H
54#include "config.h" 56#include "config.h"
55#endif 57#endif
56 58
57 59
58#include "icalerror.h"
59#include "ical.h" 60#include "ical.h"
60#include "icaldirset.h" 61#include "icaldirset.h"
61#include "pvl.h"
62#include "icalparser.h"
63#include "icaldirset.h" 62#include "icaldirset.h"
64#include "icalfileset.h" 63#include "icalfileset.h"
65#include "icalfilesetimpl.h" 64#include "icalfilesetimpl.h"
65#include "icalcluster.h"
66#include "icalgauge.h" 66#include "icalgauge.h"
67 67
68#include <limits.h> /* For PATH_MAX */ 68#include <limits.h> /* For PATH_MAX */
69#include <errno.h> 69#ifndef WIN32
70#include <sys/types.h> /* for opendir() */
71#include <sys/stat.h> /* for stat */
72
73int snprintf(char *str, size_t n, char const *fmt, ...);
74
75// Eugen C. <eug@thekompany.com>
76#include <defines.h>
77#ifndef _QTWIN_
78#include <dirent.h> /* for opendir() */ 70#include <dirent.h> /* for opendir() */
79#include <unistd.h> 71#include <unistd.h> /* for stat, getpid */
80#include <sys/utsname.h> /* for uname */ 72#include <sys/utsname.h> /* for uname */
73#else
74#include <io.h>
75#include <process.h>
81#endif 76#endif
82// Eugen C. <eug@thekompany.com> 77#include <errno.h>
83 78#include <sys/types.h> /* for opendir() */
79#include <sys/stat.h> /* for stat */
84#include <time.h> /* for clock() */ 80#include <time.h> /* for clock() */
85#include <stdlib.h> /* for rand(), srand() */ 81#include <stdlib.h> /* for rand(), srand() */
86#include <string.h> /* for strdup */ 82#include <string.h> /* for strdup */
87#include "icaldirsetimpl.h" 83#include "icaldirsetimpl.h"
88 84
89 85
90struct icaldirset_impl* icaldirset_new_impl() 86#ifdef WIN32
91{ 87 #define snprintf_snprintf
92 struct icaldirset_impl* impl; 88 #define strcasecmpstricmp
93 89
94 if ( ( impl = (struct icaldirset_impl*) 90#define _S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask))
95 malloc(sizeof(struct icaldirset_impl))) == 0) { 91
96 icalerror_set_errno(ICAL_NEWFAILED_ERROR); 92#define S_ISDIR(mode) _S_ISTYPE((mode), _S_IFDIR)
97 return 0; 93#define S_ISREG(mode) _S_ISTYPE((mode), _S_IFREG)
98 } 94#endif
99 95
100 strcpy(impl->id,ICALDIRSET_ID); 96/** Default options used when NULL is passed to icalset_new() **/
97icaldirset_options icaldirset_options_default = {O_RDWR|O_CREAT};
101 98
102 return impl;
103}
104 99
105const char* icaldirset_path(icaldirset* cluster) 100const char* icaldirset_path(icalset* set)
106{ 101{
107 struct icaldirset_impl *impl = icaldirset_new_impl(); 102 icaldirset *dset = (icaldirset*)set;
108
109 return impl->dir;
110 103
104 return dset->dir;
111} 105}
112 106
113void icaldirset_mark(icaldirset* store) 107
108void icaldirset_mark(icalset* set)
114{ 109{
115 struct icaldirset_impl *impl = (struct icaldirset_impl*)store; 110 icaldirset *dset = (icaldirset*)set;
116 111
117 icalfileset_mark(impl->cluster); 112 icalcluster_mark(dset->cluster);
118} 113}
119 114
120 115
121icalerrorenum icaldirset_commit(icaldirset* store) 116icalerrorenum icaldirset_commit(icalset* set)
122{ 117{
123 struct icaldirset_impl *impl = (struct icaldirset_impl*)store; 118 icaldirset *dset = (icaldirset*)set;
119 icalset *fileset;
120 icalfileset_options options = icalfileset_options_default;
124 121
125 return icalfileset_commit(impl->cluster); 122 options.cluster = dset->cluster;
126 123
124 fileset = icalset_new(ICAL_FILE_SET, icalcluster_key(dset->cluster), &options);
125
126 fileset->commit(fileset);
127 fileset->free(fileset);
128
129 return ICAL_NO_ERROR;
127} 130}
128 131
129void icaldirset_lock(const char* dir) 132void icaldirset_lock(const char* dir)
130{ 133{
131} 134}
132 135
133 136
134void icaldirset_unlock(const char* dir) 137void icaldirset_unlock(const char* dir)
135{ 138{
136} 139}
137 140
138/* Load the contents of the store directory into the store's internal directory list*/ 141/* Load the contents of the store directory into the store's internal directory list*/
139icalerrorenum icaldirset_read_directory(struct icaldirset_impl* impl) 142icalerrorenum icaldirset_read_directory(icaldirset *dset)
140{ 143{
141#ifndef _QTWIN_ 144 char *str;
145#ifndef WIN32
142 struct dirent *de; 146 struct dirent *de;
143 DIR* dp; 147 DIR* dp;
144 char *str;
145 148
146 dp = opendir(impl->dir); 149 dp = opendir(dset->dir);
147 150
148 if ( dp == 0) { 151 if (dp == 0) {
149 icalerror_set_errno(ICAL_FILE_ERROR); 152 icalerror_set_errno(ICAL_FILE_ERROR);
150 return ICAL_FILE_ERROR; 153 return ICAL_FILE_ERROR;
151 } 154 }
152 155
153 /* clear contents of directory list */ 156 /* clear contents of directory list */
154 while((str = pvl_pop(impl->directory))){ 157 while((str = pvl_pop(dset->directory))){
155 free(str); 158 free(str);
156 } 159 }
157 160
158 /* load all of the cluster names in the directory list */ 161 /* load all of the cluster names in the directory list */
159 for(de = readdir(dp); 162 for(de = readdir(dp);
160 de != 0; 163 de != 0;
@@ -163,139 +166,171 @@ icalerrorenum icaldirset_read_directory(struct icaldirset_impl* impl)
163 /* Remove known directory names '.' and '..'*/ 166 /* Remove known directory names '.' and '..'*/
164 if (strcmp(de->d_name,".") == 0 || 167 if (strcmp(de->d_name,".") == 0 ||
165 strcmp(de->d_name,"..") == 0 ){ 168 strcmp(de->d_name,"..") == 0 ){
166 continue; 169 continue;
167 } 170 }
168 171
169 pvl_push(impl->directory, (void*)strdup(de->d_name)); 172 pvl_push(dset->directory, (void*)strdup(de->d_name));
170 } 173 }
171 174
172 closedir(dp); 175 closedir(dp);
173
174 return ICAL_NO_ERROR;
175#else 176#else
176 icalerror_set_errno(ICAL_FILE_ERROR); 177 struct _finddata_t c_file;
177 return ICAL_FILE_ERROR; 178 long hFile;
179
180 /* Find first .c file in current directory */
181 if( (hFile = _findfirst( "*", &c_file )) == -1L ) {
182 icalerror_set_errno(ICAL_FILE_ERROR);
183 return ICAL_FILE_ERROR;
184 } else {
185 while((str = pvl_pop(dset->directory))){
186 free(str);
187 }
188
189 /* load all of the cluster names in the directory list */
190 do {
191 /* Remove known directory names '.' and '..'*/
192 if (strcmp(c_file.name,".") == 0 ||
193 strcmp(c_file.name,"..") == 0 ){
194 continue;
195 }
196
197 pvl_push(dset->directory, (void*)strdup(c_file.name));
198 }
199 while ( _findnext( hFile, &c_file ) == 0 );
200
201 _findclose( hFile );
202 }
203
178#endif 204#endif
205
206 return ICAL_NO_ERROR;
179} 207}
180 208
181icaldirset* icaldirset_new(const char* dir) 209
210icalset* icaldirset_init(icalset* set, const char* dir, void* options_in)
182{ 211{
183 struct icaldirset_impl *impl = icaldirset_new_impl(); 212 icaldirset *dset = (icaldirset*)set;
213 icaldirset_options *options = options_in;
184 struct stat sbuf; 214 struct stat sbuf;
185 215
186 if (impl == 0){
187 return 0;
188 }
189
190 icalerror_check_arg_rz( (dir!=0), "dir"); 216 icalerror_check_arg_rz( (dir!=0), "dir");
217 icalerror_check_arg_rz( (set!=0), "set");
191 218
192 if (stat(dir,&sbuf) != 0){ 219 if (stat(dir,&sbuf) != 0){
193 icalerror_set_errno(ICAL_FILE_ERROR); 220 icalerror_set_errno(ICAL_FILE_ERROR);
194 return 0; 221 return 0;
195 } 222 }
196 223
197#ifndef _QTWIN_
198 /* dir is not the name of a direectory*/ 224 /* dir is not the name of a direectory*/
199 if (!S_ISDIR(sbuf.st_mode)){ 225 if (!S_ISDIR(sbuf.st_mode)){
200 icalerror_set_errno(ICAL_USAGE_ERROR); 226 icalerror_set_errno(ICAL_USAGE_ERROR);
201 return 0; 227 return 0;
202 } 228 }
203#endif
204 229
205 icaldirset_lock(dir); 230 icaldirset_lock(dir);
206 231
207 impl = icaldirset_new_impl(); 232 dset->dir = (char*)strdup(dir);
233 dset->options = *options;
234 dset->directory = pvl_newlist();
235 dset->directory_iterator = 0;
236 dset->gauge = 0;
237 dset->first_component = 0;
238 dset->cluster = 0;
239
240 return set;
241}
242
243icalset* icaldirset_new(const char* dir)
244{
245 return icalset_new(ICAL_DIR_SET, dir, &icaldirset_options_default);
246}
208 247
209 if (impl ==0){
210 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
211 return 0;
212 }
213 248
214 impl->directory = pvl_newlist(); 249icalset* icaldirset_new_reader(const char* dir)
215 impl->directory_iterator = 0; 250{
216 impl->dir = (char*)strdup(dir); 251 icaldirset_options reader_options = icaldirset_options_default;
217 impl->gauge = 0;
218 impl->first_component = 0;
219 impl->cluster = 0;
220 252
221 icaldirset_read_directory(impl); 253 reader_options.flags = O_RDONLY;
222 254
223 return (icaldirset*) impl; 255 return icalset_new(ICAL_DIR_SET, dir, &reader_options);
224} 256}
225 257
226void icaldirset_free(icaldirset* s) 258
259icalset* icaldirset_new_writer(const char* dir)
227{ 260{
228 struct icaldirset_impl *impl = (struct icaldirset_impl*)s; 261 icaldirset_options writer_options = icaldirset_options_default;
262
263 writer_options.flags = O_RDWR|O_CREAT;
264
265 return icalset_new(ICAL_DIR_SET, dir, &writer_options);
266}
267
268
269void icaldirset_free(icalset* s)
270{
271 icaldirset *dset = (icaldirset*)s;
229 char* str; 272 char* str;
230 273
231 icaldirset_unlock(impl->dir); 274 icaldirset_unlock(dset->dir);
232 275
233 if(impl->dir !=0){ 276 if(dset->dir !=0){
234 free(impl->dir); 277 free(dset->dir);
278 dset->dir = 0;
235 } 279 }
236 280
237 if(impl->gauge !=0){ 281 if(dset->gauge !=0){
238 icalcomponent_free(impl->gauge); 282 icalgauge_free(dset->gauge);
283 dset->gauge = 0;
239 } 284 }
240 285
241 if(impl->cluster !=0){ 286 if(dset->cluster !=0){
242 icalfileset_free(impl->cluster); 287 icalcluster_free(dset->cluster);
243 } 288 }
244 289
245 while(impl->directory !=0 && (str=pvl_pop(impl->directory)) != 0){ 290 while(dset->directory !=0 && (str=pvl_pop(dset->directory)) != 0){
246 free(str); 291 free(str);
247 } 292 }
248 293
249 if(impl->directory != 0){ 294 if(dset->directory != 0){
250 pvl_free(impl->directory); 295 pvl_free(dset->directory);
296 dset->directory = 0;
251 } 297 }
252 298
253 impl->directory = 0; 299 dset->directory_iterator = 0;
254 impl->directory_iterator = 0; 300 dset->first_component = 0;
255 impl->dir = 0;
256 impl->gauge = 0;
257 impl->first_component = 0;
258
259 free(impl);
260
261} 301}
262 302
303
263/* icaldirset_next_uid_number updates a serial number in the Store 304/* icaldirset_next_uid_number updates a serial number in the Store
264 directory in a file called SEQUENCE */ 305 directory in a file called SEQUENCE */
265 306
266int icaldirset_next_uid_number(icaldirset* store) 307int icaldirset_next_uid_number(icaldirset* dset)
267{ 308{
268 struct icaldirset_impl *impl = (struct icaldirset_impl*)store;
269 char sequence = 0; 309 char sequence = 0;
270 char temp[128]; 310 char temp[128];
271 char filename[ICAL_PATH_MAX]; 311 char filename[ICAL_PATH_MAX];
272 char *r; 312 char *r;
273 FILE *f; 313 FILE *f;
274 struct stat sbuf; 314 struct stat sbuf;
275 315
276 icalerror_check_arg_rz( (store!=0), "store"); 316 icalerror_check_arg_rz( (dset!=0), "dset");
277 317
278 sprintf(filename,"%s/%s",impl->dir,"SEQUENCE"); 318 sprintf(filename,"%s/%s",dset->dir,"SEQUENCE");
279 319
280 /* Create the file if it does not exist.*/ 320 /* Create the file if it does not exist.*/
281#ifndef _QTWIN_
282 if (stat(filename,&sbuf) == -1 || !S_ISREG(sbuf.st_mode)){ 321 if (stat(filename,&sbuf) == -1 || !S_ISREG(sbuf.st_mode)){
283#else
284 if (stat(filename,&sbuf) == -1){
285#endif
286 322
287 f = fopen(filename,"w"); 323 f = fopen(filename,"w");
288 if (f != 0){ 324 if (f != 0){
289 fprintf(f,"0"); 325 fprintf(f,"0");
290 fclose(f); 326 fclose(f);
291 } else { 327 } else {
292 icalerror_warn("Can't create SEQUENCE file in icaldirset_next_uid_number"); 328 icalerror_warn("Can't create SEQUENCE file in icaldirset_next_uid_number");
293 return 0; 329 return 0;
294 } 330 }
295
296 } 331 }
297 332
298 if ( (f = fopen(filename,"r+")) != 0){ 333 if ( (f = fopen(filename,"r+")) != 0){
299 334
300 rewind(f); 335 rewind(f);
301 r = fgets(temp,128,f); 336 r = fgets(temp,128,f);
@@ -315,187 +350,173 @@ int icaldirset_next_uid_number(icaldirset* store)
315 return sequence; 350 return sequence;
316 351
317 } else { 352 } else {
318 icalerror_warn("Can't create SEQUENCE file in icaldirset_next_uid_number"); 353 icalerror_warn("Can't create SEQUENCE file in icaldirset_next_uid_number");
319 return 0; 354 return 0;
320 } 355 }
321
322} 356}
323 357
324icalerrorenum icaldirset_next_cluster(icaldirset* store) 358icalerrorenum icaldirset_next_cluster(icaldirset* dset)
325{ 359{
326 struct icaldirset_impl *impl = (struct icaldirset_impl*)store;
327 char path[ICAL_PATH_MAX]; 360 char path[ICAL_PATH_MAX];
328 361
329 if (impl->directory_iterator == 0){ 362 if (dset->directory_iterator == 0){
330 icalerror_set_errno(ICAL_INTERNAL_ERROR); 363 icalerror_set_errno(ICAL_INTERNAL_ERROR);
331 return ICAL_INTERNAL_ERROR; 364 return ICAL_INTERNAL_ERROR;
332 } 365 }
333 impl->directory_iterator = pvl_next(impl->directory_iterator); 366 dset->directory_iterator = pvl_next(dset->directory_iterator);
334 367
335 if (impl->directory_iterator == 0){ 368 if (dset->directory_iterator == 0){
336 /* There are no more clusters */ 369 /* There are no more clusters */
337 if(impl->cluster != 0){ 370 if(dset->cluster != 0){
338 icalfileset_free(impl->cluster); 371 icalcluster_free(dset->cluster);
339 impl->cluster = 0; 372 dset->cluster = 0;
340 } 373 }
341 return ICAL_NO_ERROR; 374 return ICAL_NO_ERROR;
342 } 375 }
343 376
344 sprintf(path,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator)); 377 sprintf(path,"%s/%s", dset->dir,(char*)pvl_data(dset->directory_iterator));
345 378
346 icalfileset_free(impl->cluster); 379 icalcluster_free(dset->cluster);
347 380 dset->cluster = icalfileset_produce_icalcluster(path);
348 impl->cluster = icalfileset_new(path);
349 381
350 return icalerrno; 382 return icalerrno;
351} 383}
352 384
353void icaldirset_add_uid(icaldirset* store, icaldirset* comp) 385static void icaldirset_add_uid(icalcomponent* comp)
354{ 386{
355#ifndef _QTWIN_
356
357 char uidstring[ICAL_PATH_MAX]; 387 char uidstring[ICAL_PATH_MAX];
358 icalproperty *uid; 388 icalproperty *uid;
389#ifndef WIN32
359 struct utsname unamebuf; 390 struct utsname unamebuf;
391#endif
360 392
361 icalerror_check_arg_rv( (store!=0), "store");
362 icalerror_check_arg_rv( (comp!=0), "comp"); 393 icalerror_check_arg_rv( (comp!=0), "comp");
363 394
364 uid = icalcomponent_get_first_property(comp,ICAL_UID_PROPERTY); 395 uid = icalcomponent_get_first_property(comp,ICAL_UID_PROPERTY);
365 396
366 if (uid == 0) { 397 if (uid == 0) {
367 398
399#ifndef WIN32
368 uname(&unamebuf); 400 uname(&unamebuf);
369 401
370 sprintf(uidstring,"%d-%s",(int)getpid(),unamebuf.nodename); 402 sprintf(uidstring,"%d-%s",(int)getpid(),unamebuf.nodename);
403#else
404 sprintf(uidstring,"%d-%s",(int)getpid(),"WINDOWS"); /* FIX: There must be an easy get the system name */
405#endif
371 406
372 uid = icalproperty_new_uid(uidstring); 407 uid = icalproperty_new_uid(uidstring);
373 icalcomponent_add_property(comp,uid); 408 icalcomponent_add_property(comp,uid);
374 } else { 409 } else {
375
376 strcpy(uidstring,icalproperty_get_uid(uid)); 410 strcpy(uidstring,icalproperty_get_uid(uid));
377 } 411 }
378
379#endif
380} 412}
381 413
382 414
383/* This assumes that the top level component is a VCALENDAR, and there 415/**
416 This assumes that the top level component is a VCALENDAR, and there
384 is an inner component of type VEVENT, VTODO or VJOURNAL. The inner 417 is an inner component of type VEVENT, VTODO or VJOURNAL. The inner
385 component must have a DTAMP property */ 418 component must have a DSTAMP property
419*/
386 420
387icalerrorenum icaldirset_add_component(icaldirset* store, icaldirset* comp) 421icalerrorenum icaldirset_add_component(icalset* set, icalcomponent* comp)
388{ 422{
389 struct icaldirset_impl *impl;
390 char clustername[ICAL_PATH_MAX]; 423 char clustername[ICAL_PATH_MAX];
391 icalproperty *dt; 424 icalproperty *dt = 0;
392 icalvalue *v; 425 icalvalue *v;
393 struct icaltimetype tm; 426 struct icaltimetype tm;
394 icalerrorenum error = ICAL_NO_ERROR; 427 icalerrorenum error = ICAL_NO_ERROR;
395 icalcomponent *inner; 428 icalcomponent *inner;
429 icaldirset *dset = (icaldirset*) set;
396 430
397 impl = (struct icaldirset_impl*)store; 431 icalerror_check_arg_rz( (dset!=0), "dset");
398 icalerror_check_arg_rz( (store!=0), "store");
399 icalerror_check_arg_rz( (comp!=0), "comp"); 432 icalerror_check_arg_rz( (comp!=0), "comp");
400 433
401 errno = 0; 434 icaldirset_add_uid(comp);
402
403 icaldirset_add_uid(store,comp);
404 435
405 /* Determine which cluster this object belongs in. This is a HACK */ 436 /* Determine which cluster this object belongs in. This is a HACK */
406 437
407 for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); 438 for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
408 inner != 0; 439 inner != 0;
409 inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ 440 inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){
410 441
411 dt = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY); 442 dt = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY);
412 443
413 if (dt != 0){ 444 if (dt != 0)
414 break; 445 break;
415 } 446 }
416 }
417
418 if (dt == 0){
419 447
448 if (dt == 0) {
420 for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); 449 for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
421 inner != 0; 450 inner != 0;
422 inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ 451 inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){
423 452
424 dt = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); 453 dt = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY);
425 454
426 if (dt != 0){ 455 if (dt != 0)
427 break; 456 break;
428 } 457 }
429 } 458 }
430 459
431 }
432
433 if (dt == 0){ 460 if (dt == 0){
434
435
436 icalerror_warn("The component does not have a DTSTAMP or DTSTART property, so it cannot be added to the store"); 461 icalerror_warn("The component does not have a DTSTAMP or DTSTART property, so it cannot be added to the store");
437 icalerror_set_errno(ICAL_BADARG_ERROR); 462 icalerror_set_errno(ICAL_BADARG_ERROR);
438 return ICAL_BADARG_ERROR; 463 return ICAL_BADARG_ERROR;
439 } 464 }
440 465
441 v = icalproperty_get_value(dt); 466 v = icalproperty_get_value(dt);
442
443 tm = icalvalue_get_datetime(v); 467 tm = icalvalue_get_datetime(v);
444 468
445 snprintf(clustername,ICAL_PATH_MAX,"%s/%04d%02d",impl->dir,tm.year,tm.month); 469 snprintf(clustername,ICAL_PATH_MAX,"%s/%04d%02d",dset->dir, tm.year, tm.month);
446 470
447 /* Load the cluster and insert the object */ 471 /* Load the cluster and insert the object */
448 472 if(dset->cluster != 0 &&
449 if(impl->cluster != 0 && 473 strcmp(clustername,icalcluster_key(dset->cluster)) != 0 ){
450 strcmp(clustername,icalfileset_path(impl->cluster)) != 0 ){ 474 icalcluster_free(dset->cluster);
451 icalfileset_free(impl->cluster); 475 dset->cluster = 0;
452 impl->cluster = 0;
453 } 476 }
454 477
455 if (impl->cluster == 0){ 478 if (dset->cluster == 0){
456 impl->cluster = icalfileset_new(clustername); 479 dset->cluster = icalfileset_produce_icalcluster(clustername);
457 480
458 if (impl->cluster == 0){ 481 if (dset->cluster == 0){
459 error = icalerrno; 482 error = icalerrno;
460 } 483 }
461 } 484 }
462 485
463 if (error != ICAL_NO_ERROR){ 486 if (error != ICAL_NO_ERROR){
464 icalerror_set_errno(error); 487 icalerror_set_errno(error);
465 return error; 488 return error;
466 } 489 }
467 490
468 /* Add the component to the cluster */ 491 /* Add the component to the cluster */
469 492 icalcluster_add_component(dset->cluster,comp);
470 icalfileset_add_component(impl->cluster,comp);
471 493
472 icalfileset_mark(impl->cluster); 494 /* icalcluster_mark(impl->cluster); */
473 495
474 return ICAL_NO_ERROR; 496 return ICAL_NO_ERROR;
475} 497}
476 498
477/* Remove a component in the current cluster. HACK. This routine is a 499/**
500 Remove a component in the current cluster. HACK. This routine is a
478 "friend" of icalfileset, and breaks its encapsulation. It was 501 "friend" of icalfileset, and breaks its encapsulation. It was
479 either do it this way, or add several layers of interfaces that had 502 either do it this way, or add several layers of interfaces that had
480 no other use. */ 503 no other use.
481icalerrorenum icaldirset_remove_component(icaldirset* store, icaldirset* comp) 504 */
482{
483 struct icaldirset_impl *impl = (struct icaldirset_impl*)store;
484
485 struct icalfileset_impl *filesetimpl =
486 (struct icalfileset_impl*)impl->cluster;
487 505
488 icalcomponent *filecomp = filesetimpl->cluster; 506icalerrorenum icaldirset_remove_component(icalset* set, icalcomponent* comp)
507{
508 icaldirset *dset = (icaldirset*)set;
509 icalcomponent *filecomp = icalcluster_get_component(dset->cluster);
489 510
490 icalcompiter i; 511 icalcompiter i;
491 int found = 0; 512 int found = 0;
492 513
493 icalerror_check_arg_re((store!=0),"store",ICAL_BADARG_ERROR); 514 icalerror_check_arg_re((set!=0),"set",ICAL_BADARG_ERROR);
494 icalerror_check_arg_re((comp!=0),"comp",ICAL_BADARG_ERROR); 515 icalerror_check_arg_re((comp!=0),"comp",ICAL_BADARG_ERROR);
495 icalerror_check_arg_re((impl->cluster!=0),"Cluster pointer",ICAL_USAGE_ERROR); 516 icalerror_check_arg_re((dset->cluster!=0),"Cluster pointer",ICAL_USAGE_ERROR);
496 517
497 for(i = icalcomponent_begin_component(filecomp,ICAL_ANY_COMPONENT); 518 for(i = icalcomponent_begin_component(filecomp,ICAL_ANY_COMPONENT);
498 icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){ 519 icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){
499 520
500 icalcomponent *this = icalcompiter_deref(&i); 521 icalcomponent *this = icalcompiter_deref(&i);
501 522
@@ -508,23 +529,22 @@ icalerrorenum icaldirset_remove_component(icaldirset* store, icaldirset* comp)
508 if (found != 1){ 529 if (found != 1){
509 icalerror_warn("icaldirset_remove_component: component is not part of current cluster"); 530 icalerror_warn("icaldirset_remove_component: component is not part of current cluster");
510 icalerror_set_errno(ICAL_USAGE_ERROR); 531 icalerror_set_errno(ICAL_USAGE_ERROR);
511 return ICAL_USAGE_ERROR; 532 return ICAL_USAGE_ERROR;
512 } 533 }
513 534
514 icalfileset_remove_component(impl->cluster,comp); 535 icalcluster_remove_component(dset->cluster,comp);
515 536
516 icalfileset_mark(impl->cluster); 537 /* icalcluster_mark(impl->cluster); */
517 538
518 /* If the removal emptied the fileset, get the next fileset */ 539 /* If the removal emptied the fileset, get the next fileset */
519 if( icalfileset_count_components(impl->cluster,ICAL_ANY_COMPONENT)==0){ 540 if( icalcluster_count_components(dset->cluster,ICAL_ANY_COMPONENT)==0){
520 541 icalerrorenum error = icaldirset_next_cluster(dset);
521 icalerrorenum error = icaldirset_next_cluster(store);
522 542
523 if(impl->cluster != 0 && error == ICAL_NO_ERROR){ 543 if(dset->cluster != 0 && error == ICAL_NO_ERROR){
524 icalfileset_get_first_component(impl->cluster); 544 icalcluster_get_first_component(dset->cluster);
525 } else { 545 } else {
526 /* HACK. Not strictly correct for impl->cluster==0 */ 546 /* HACK. Not strictly correct for impl->cluster==0 */
527 return error; 547 return error;
528 } 548 }
529 } else { 549 } else {
530 /* Do nothing */ 550 /* Do nothing */
@@ -532,246 +552,254 @@ icalerrorenum icaldirset_remove_component(icaldirset* store, icaldirset* comp)
532 552
533 return ICAL_NO_ERROR; 553 return ICAL_NO_ERROR;
534} 554}
535 555
536 556
537 557
538int icaldirset_count_components(icaldirset* store, 558int icaldirset_count_components(icalset* store,
539 icalcomponent_kind kind) 559 icalcomponent_kind kind)
540{ 560{
541 /* HACK, not implemented */ 561 /* HACK, not implemented */
542
543 assert(0); 562 assert(0);
544 563
545 return 0; 564 return 0;
546} 565}
547 566
548 567
549icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent *c) 568icalcomponent* icaldirset_fetch_match(icalset* set, icalcomponent *c)
550{ 569{
551 fprintf(stderr," icaldirset_fetch_match is not implemented\n"); 570 fprintf(stderr," icaldirset_fetch_match is not implemented\n");
552 assert(0); 571 assert(0);
572 return 0;
553} 573}
554 574
555 575
556icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid) 576icalcomponent* icaldirset_fetch(icalset* set, const char* uid)
557{ 577{
558 icalcomponent *gauge; 578 icaldirset *dset = (icaldirset*)set;
559 icalcomponent *old_gauge; 579 icalgauge *gauge;
580 icalgauge *old_gauge;
560 icalcomponent *c; 581 icalcomponent *c;
561 struct icaldirset_impl *impl = (struct icaldirset_impl*)store; 582 char sql[256];
562 583
563 icalerror_check_arg_rz( (store!=0), "store"); 584 icalerror_check_arg_rz( (set!=0), "set");
564 icalerror_check_arg_rz( (uid!=0), "uid"); 585 icalerror_check_arg_rz( (uid!=0), "uid");
565 586
566 gauge = 587 snprintf(sql, 256, "SELECT * FROM VEVENT WHERE UID = \"%s\"", uid);
567 icalcomponent_vanew( 588
568 ICAL_VCALENDAR_COMPONENT, 589 gauge = icalgauge_new_from_sql(sql, 0);
569 icalcomponent_vanew(
570 ICAL_VEVENT_COMPONENT,
571 icalproperty_vanew_uid(
572 uid,
573 icalparameter_new_xliccomparetype(
574 ICAL_XLICCOMPARETYPE_EQUAL),
575 0),
576 0),
577 0);
578 590
579 old_gauge = impl->gauge; 591 old_gauge = dset->gauge;
580 impl->gauge = gauge; 592 dset->gauge = gauge;
581 593
582 c= icaldirset_get_first_component(store); 594 c= icaldirset_get_first_component(set);
583 595
584 impl->gauge = old_gauge; 596 dset->gauge = old_gauge;
585 597
586 icalcomponent_free(gauge); 598 icalgauge_free(gauge);
587 599
588 return c; 600 return c;
589} 601}
590 602
591 603
592int icaldirset_has_uid(icaldirset* store, const char* uid) 604int icaldirset_has_uid(icalset* set, const char* uid)
593{ 605{
594 icalcomponent *c; 606 icalcomponent *c;
595 607
596 icalerror_check_arg_rz( (store!=0), "store"); 608 icalerror_check_arg_rz( (set!=0), "set");
597 icalerror_check_arg_rz( (uid!=0), "uid"); 609 icalerror_check_arg_rz( (uid!=0), "uid");
598 610
599 /* HACK. This is a temporary implementation. _has_uid should use a 611 /* HACK. This is a temporary implementation. _has_uid should use a
600 database, and _fetch should use _has_uid, not the other way 612 database, and _fetch should use _has_uid, not the other way
601 around */ 613 around */
602 c = icaldirset_fetch(store,uid); 614 c = icaldirset_fetch(set,uid);
603 615
604 return c!=0; 616 return c!=0;
605 617
606} 618}
607 619
608 620
609icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge) 621icalerrorenum icaldirset_select(icalset* set, icalgauge* gauge)
610 { 622{
611 struct icaldirset_impl *impl = (struct icaldirset_impl*)store; 623 icaldirset *dset = (icaldirset*)set;
612 624
613 icalerror_check_arg_re( (store!=0), "store",ICAL_BADARG_ERROR); 625 icalerror_check_arg_re( (set!=0), "set",ICAL_BADARG_ERROR);
614 icalerror_check_arg_re( (gauge!=0), "gauge",ICAL_BADARG_ERROR); 626 icalerror_check_arg_re( (gauge!=0), "gauge",ICAL_BADARG_ERROR);
615 627
616 if (!icalcomponent_is_valid(gauge)){ 628 dset->gauge = gauge;
617 return ICAL_BADARG_ERROR;
618 }
619
620 impl->gauge = gauge;
621 629
622 return ICAL_NO_ERROR; 630 return ICAL_NO_ERROR;
623} 631}
624 632
625 633
626icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *old, 634icalerrorenum icaldirset_modify(icalset* set,
635 icalcomponent *old,
627 icalcomponent *new) 636 icalcomponent *new)
628{ 637{
629 assert(0); 638 assert(0);
630 return ICAL_NO_ERROR; /* HACK, not implemented */ 639 return ICAL_NO_ERROR; /* HACK, not implemented */
631 640
632} 641}
633 642
634 643
635void icaldirset_clear(icaldirset* store) 644void icaldirset_clear(icalset* set)
636{ 645{
637 646
638 assert(0); 647 assert(0);
639 return; 648 return;
640 /* HACK, not implemented */ 649 /* HACK, not implemented */
641} 650}
642 651
643icalcomponent* icaldirset_get_current_component(icaldirset* store) 652icalcomponent* icaldirset_get_current_component(icalset* set)
644{ 653{
645 struct icaldirset_impl *impl = (struct icaldirset_impl*)store; 654 icaldirset *dset = (icaldirset*)set;
646 655
647 if(impl->cluster == 0){ 656 if (dset->cluster == 0){
648 icaldirset_get_first_component(store); 657 icaldirset_get_first_component(set);
658 }
659 if(dset->cluster == 0){
660 return 0;
649 } 661 }
650 662
651 return icalfileset_get_current_component(impl->cluster); 663 return icalcluster_get_current_component(dset->cluster);
652
653} 664}
654 665
655 666
656icalcomponent* icaldirset_get_first_component(icaldirset* store) 667icalcomponent* icaldirset_get_first_component(icalset* set)
657{ 668{
658 struct icaldirset_impl *impl = (struct icaldirset_impl*)store; 669 icaldirset *dset = (icaldirset*)set;
670
659 icalerrorenum error; 671 icalerrorenum error;
660 char path[ICAL_PATH_MAX]; 672 char path[ICAL_PATH_MAX];
661 673
662 error = icaldirset_read_directory(impl); 674 error = icaldirset_read_directory(dset);
663 675
664 if (error != ICAL_NO_ERROR){ 676 if (error != ICAL_NO_ERROR){
665 icalerror_set_errno(error); 677 icalerror_set_errno(error);
666 return 0; 678 return 0;
667 } 679 }
668 680
669 impl->directory_iterator = pvl_head(impl->directory); 681 dset->directory_iterator = pvl_head(dset->directory);
670 682
671 if (impl->directory_iterator == 0){ 683 if (dset->directory_iterator == 0){
672 icalerror_set_errno(error); 684 icalerror_set_errno(error);
673 return 0; 685 return 0;
674 } 686 }
675 687
676 snprintf(path,ICAL_PATH_MAX,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator)); 688 snprintf(path,ICAL_PATH_MAX,"%s/%s",
689 dset->dir,
690 (char*)pvl_data(dset->directory_iterator));
677 691
678 /* If the next cluster we need is different than the current cluster, 692 /* If the next cluster we need is different than the current cluster,
679 delete the current one and get a new one */ 693 delete the current one and get a new one */
680 694
681 if(impl->cluster != 0 && strcmp(path,icalfileset_path(impl->cluster)) != 0 ){ 695 if(dset->cluster != 0 && strcmp(path,icalcluster_key(dset->cluster)) != 0 ){
682 icalfileset_free(impl->cluster); 696 icalcluster_free(dset->cluster);
683 impl->cluster = 0; 697 dset->cluster = 0;
684 } 698 }
685 699
686 if (impl->cluster == 0){ 700 if (dset->cluster == 0){
687 impl->cluster = icalfileset_new(path); 701 dset->cluster = icalfileset_produce_icalcluster(path);
688 702
689 if (impl->cluster == 0){ 703 if (dset->cluster == 0){
690 error = icalerrno; 704 error = icalerrno;
691 } 705 }
692 } 706 }
693 707
694 if (error != ICAL_NO_ERROR){ 708 if (error != ICAL_NO_ERROR){
695 icalerror_set_errno(error); 709 icalerror_set_errno(error);
696 return 0; 710 return 0;
697 } 711 }
698 712
699 impl->first_component = 1; 713 dset->first_component = 1;
700 714
701 return icaldirset_get_next_component(store); 715 return icaldirset_get_next_component(set);
702} 716}
703 717
704icalcomponent* icaldirset_get_next_component(icaldirset* store) 718
719icalcomponent* icaldirset_get_next_component(icalset* set)
705{ 720{
706 struct icaldirset_impl *impl; 721 icaldirset *dset = (icaldirset*)set;
707 icalcomponent *c; 722 icalcomponent *c;
708 icalerrorenum error; 723 icalerrorenum error;
709 724
710 icalerror_check_arg_rz( (store!=0), "store"); 725 icalerror_check_arg_rz( (set!=0), "set");
711
712 impl = (struct icaldirset_impl*)store;
713 726
714 if(impl->cluster == 0){
715 727
728 if(dset->cluster == 0){
716 icalerror_warn("icaldirset_get_next_component called with a NULL cluster (Caller must call icaldirset_get_first_component first"); 729 icalerror_warn("icaldirset_get_next_component called with a NULL cluster (Caller must call icaldirset_get_first_component first");
717 icalerror_set_errno(ICAL_USAGE_ERROR); 730 icalerror_set_errno(ICAL_USAGE_ERROR);
718 return 0; 731 return 0;
719 732
720 } 733 }
721 734
722 /* Set the component iterator for the following for loop */ 735 /* Set the component iterator for the following for loop */
723 if (impl->first_component == 1){ 736 if (dset->first_component == 1){
724 icalfileset_get_first_component(impl->cluster); 737 icalcluster_get_first_component(dset->cluster);
725 impl->first_component = 0; 738 dset->first_component = 0;
726 } else { 739 } else {
727 icalfileset_get_next_component(impl->cluster); 740 icalcluster_get_next_component(dset->cluster);
728 } 741 }
729 742
730
731 while(1){ 743 while(1){
732 /* Iterate through all of the objects in the cluster*/ 744 /* Iterate through all of the objects in the cluster*/
733 for( c = icalfileset_get_current_component(impl->cluster); 745 for( c = icalcluster_get_current_component(dset->cluster);
734 c != 0; 746 c != 0;
735 c = icalfileset_get_next_component(impl->cluster)){ 747 c = icalcluster_get_next_component(dset->cluster)){
736 748
737 /* If there is a gauge defined and the component does not 749 /* If there is a gauge defined and the component does not
738 pass the gauge, skip the rest of the loop */ 750 pass the gauge, skip the rest of the loop */
739 751
740#if 0 /* HACK */ 752 if (dset->gauge != 0 && icalgauge_compare(dset->gauge,c) == 0){
741 if (impl->gauge != 0 && icalgauge_test(c,impl->gauge) == 0){
742 continue; 753 continue;
743 } 754 }
744#else 755
745 assert(0); /* icalgauge_test needs to be fixed */
746#endif
747 /* Either there is no gauge, or the component passed the 756 /* Either there is no gauge, or the component passed the
748 gauge, so return it*/ 757 gauge, so return it*/
749 758
750 return c; 759 return c;
751 } 760 }
752 761
753 /* Fell through the loop, so the component we want is not 762 /* Fell through the loop, so the component we want is not
754 in this cluster. Load a new cluster and try again.*/ 763 in this cluster. Load a new cluster and try again.*/
755 764
756 error = icaldirset_next_cluster(store); 765 error = icaldirset_next_cluster(dset);
757 766
758 if(impl->cluster == 0 || error != ICAL_NO_ERROR){ 767 if(dset->cluster == 0 || error != ICAL_NO_ERROR){
759 /* No more clusters */ 768 /* No more clusters */
760 return 0; 769 return 0;
761 } else { 770 } else {
762 c = icalfileset_get_first_component(impl->cluster); 771 c = icalcluster_get_first_component(dset->cluster);
763 772
764 return c; 773 return c;
765 } 774 }
766 775
767 } 776 }
768 777
769 return 0; /* Should never get here */ 778 return 0; /* Should never get here */
770} 779}
771 780
772 781icalsetiter icaldirset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge)
782{
783 icalsetiter itr = icalsetiter_null;
784 icaldirset *fset = (icaldirset*) set;
773 785
786 icalerror_check_arg_re((fset!=0), "set", icalsetiter_null);
774 787
788 itr.iter.kind = kind;
789 itr.gauge = gauge;
775 790
791 /* TO BE IMPLEMENTED */
792 return icalsetiter_null;
793}
776 794
777 795icalcomponent* icaldirsetiter_to_next(icalset* set, icalsetiter* i)
796{
797 /* TO BE IMPLEMENTED */
798 return NULL;
799}
800
801icalcomponent* icaldirsetiter_to_prior(icalset* set, icalsetiter* i)
802{
803 /* TO BE IMPLEMENTED */
804 return NULL;
805}