aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src/libicalss
diff options
context:
space:
mode:
authorSeth Alves <alves@src.gnome.org>2000-04-19 02:17:07 +0800
committerSeth Alves <alves@src.gnome.org>2000-04-19 02:17:07 +0800
commit25e1b34aafe43ba6cf1040340a38dd38a90aad33 (patch)
tree0b4e666e45bf457edcc0095634f0ae6f429b8b5a /libical/src/libicalss
parentbc17057ec598cd5f755fd66244c429ecc51cff01 (diff)
downloadgsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.tar
gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.tar.gz
gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.tar.bz2
gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.tar.lz
gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.tar.xz
gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.tar.zst
gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.zip
import of libical-0.16
svn path=/trunk/; revision=2484
Diffstat (limited to 'libical/src/libicalss')
-rw-r--r--libical/src/libicalss/Makefile.am32
-rw-r--r--libical/src/libicalss/icalcalendar.c5
-rw-r--r--libical/src/libicalss/icalcluster.c323
-rw-r--r--libical/src/libicalss/icalcluster.h4
-rw-r--r--libical/src/libicalss/icalstore.c361
5 files changed, 401 insertions, 324 deletions
diff --git a/libical/src/libicalss/Makefile.am b/libical/src/libicalss/Makefile.am
index d2f65de885..4d05257e8b 100644
--- a/libical/src/libicalss/Makefile.am
+++ b/libical/src/libicalss/Makefile.am
@@ -1,13 +1,21 @@
-INCLUDES = \
- -I$(top_srcdir)/src/libical
-
-lib_LTLIBRARIES = libicalss.la
-
-libicalss_la_SOURCES = \
- icalcalendar.c \
- icalcalendar.h \
- icalcluster.c \
- icalcluster.h \
- icalcomponent.h \
- icalstore.c \
+
+
+#noinst_LTLIBRARIES = libicalss.la
+lib_LIBRARIES = libicalss.a
+
+libicalss_a_SOURCES =\
+ icalcalendar.c \
+ icalcalendar.h \
+ icalcluster.c \
+ icalcluster.h \
+ icalstore.c \
+ icalstore.h
+
+include_HEADERS =\
+ icalcalendar.h \
+ icalcluster.h \
icalstore.h
+
+
+INCLUDES = -I../libical/
+
diff --git a/libical/src/libicalss/icalcalendar.c b/libical/src/libicalss/icalcalendar.c
index 0933df1e31..0f2231b1d7 100644
--- a/libical/src/libicalss/icalcalendar.c
+++ b/libical/src/libicalss/icalcalendar.c
@@ -26,6 +26,11 @@
======================================================================*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
#include "icalcalendar.h"
#include "icalcluster.h"
#include <limits.h>
diff --git a/libical/src/libicalss/icalcluster.c b/libical/src/libicalss/icalcluster.c
index c0160cc6c3..36bdccc743 100644
--- a/libical/src/libicalss/icalcluster.c
+++ b/libical/src/libicalss/icalcluster.c
@@ -26,6 +26,11 @@
======================================================================*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
#include "icalcluster.h"
#include <errno.h>
#include <limits.h> /* For PATH_MAX */
@@ -33,11 +38,16 @@
#include <unistd.h> /* for stat, getpid */
#include <stdlib.h>
#include <string.h>
+#include <fcntl.h> /* for fcntl */
+#include <unistd.h> /* for fcntl */
+
+icalerrorenum icalcluster_create_cluster(char *path);
struct icalcluster_impl {
char *path;
icalcomponent* cluster;
int changed;
+ FILE* stream;
};
icalcluster* icalcluster_new_impl()
@@ -54,136 +64,24 @@ icalcluster* icalcluster_new_impl()
return comp;
}
-icalerrorenum icalcluster_create_cluster(char *path)
-{
-
- FILE* f;
- int r;
- icalcomponent *c;
- struct icaltimetype tt;
-
- icalerror_clear_errno();
-
- f = fopen(path,"w");
-
- if (f == 0){
- icalerror_set_errno(ICAL_FILE_ERROR);
- return ICAL_FILE_ERROR;
- }
-
- /* Create the root component in the cluster. This component holds
- all of the other components and stores a count of
- components. */
-
- memset(&tt,0,sizeof(struct icaltimetype));
-
- c = icalcomponent_vanew(
- ICAL_VCALENDAR_COMPONENT,
- icalproperty_new_xlicclustercount(0),
- icalproperty_new_dtstart(tt), /* dtstart of earliest comp */
- icalproperty_new_dtend(tt), /* dtend of latest comp, excl. recuring */
- 0
- );
-
- if (c == 0){
- fclose(f);
- icalerror_set_errno(ICAL_INTERNAL_ERROR);
- return ICAL_INTERNAL_ERROR;
- }
-
-
- /* Write the base component to the file */
- r = fputs(icalcomponent_as_ical_string(c),f);
-
- fclose(f);
-
- icalcomponent_free(c);
-
- if (r == EOF){
- icalerror_set_errno(ICAL_FILE_ERROR);
- return ICAL_FILE_ERROR;
- }
-
- return ICAL_NO_ERROR;
-}
-
-FILE* parser_file; /*HACK. Not Thread Safe */
-char* read_from_file(char *s, size_t size)
+char* read_from_file(char *s, size_t size, void *d)
{
- char *c = fgets(s,size, parser_file);
+ char *c = fgets(s,size, (FILE*)d);
return c;
}
-icalerrorenum icalcluster_load(icalcluster* cluster, char* path)
-{
- struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster;
- icalerrorenum error;
- errno = 0;
-
- icalerror_check_arg_rz((cluster!=0),"cluster");
- icalerror_check_arg_rz((path!=0),"path");
-
- if(impl->path != 0 && strcmp(impl->path,path) == 0){
- /* Already have the right cluster, so return */
- return ICAL_NO_ERROR;
- }
-
- error = icalcluster_commit(cluster);
-
- if (error != ICAL_NO_ERROR){
- icalerror_set_errno(error);
- return error;
- }
-
- free(impl->path);
-
- impl->path= (char*)strdup(path);
-
- parser_file = fopen(impl->path,"r");
-
- /* HACK. Yeah, the following code is horrible....*/
- if (parser_file ==0 || errno != 0){
-
- /* Try to create the cluster */
- error = icalcluster_create_cluster(path);
-
- if (error == ICAL_NO_ERROR){
- /* Try to open the parser again. */
- errno = 0;
- parser_file = fopen(impl->path,"r");
-
- if (parser_file ==0 || errno != 0){
- impl->cluster = 0;
- icalerror_set_errno(ICAL_FILE_ERROR);
- return ICAL_FILE_ERROR;
- }
- } else {
- impl->cluster = 0;
- icalerror_set_errno(error); /* Redundant, actually */
- return error;
- }
- }
-
- impl->cluster = icalparser_parse(read_from_file);
-
- fclose(parser_file);
-
- if (impl->cluster == 0){
- icalerror_set_errno(ICAL_PARSE_ERROR);
- return ICAL_PARSE_ERROR;
- }
-
- return ICAL_NO_ERROR;
-}
-
-
icalcluster* icalcluster_new(char* path)
{
struct icalcluster_impl *impl = icalcluster_new_impl();
struct stat sbuf;
int createclusterfile = 0;
- icalerrorenum error;
-
+ icalerrorenum error = ICAL_NO_ERROR;
+ icalparser *parser;
+ struct icaltimetype tt;
+ off_t cluster_file_size;
+
+ memset(&tt,0,sizeof(struct icaltimetype));
+
icalerror_clear_errno();
icalerror_check_arg_rz( (path!=0), "path");
@@ -193,15 +91,18 @@ icalcluster* icalcluster_new(char* path)
/*impl->path = strdup(path); icalcluster_load does this */
impl->changed = 0;
+
impl->cluster = 0;
+
impl->path = 0;
+ impl->stream = 0;
/* Check if the path already exists and if it is a regular file*/
if (stat(path,&sbuf) != 0){
/* A file by the given name does not exist, or there was
another error */
-
+ cluster_file_size = 0;
if (errno == ENOENT) {
/* It was because the file does not exist */
createclusterfile = 1;
@@ -219,7 +120,8 @@ icalcluster* icalcluster_new(char* path)
return 0;
} else {
/* Lets assume that it is a file of the right type */
- createclusterfile = 0;
+ cluster_file_size = sbuf.st_size;
+ createclusterfile = 0;
}
}
@@ -233,8 +135,43 @@ icalcluster* icalcluster_new(char* path)
return 0;
}
}
+
+ impl->path = (char*)strdup(path);
+
+ errno = 0;
+ impl->stream = fopen(impl->path,"r");
- error = icalcluster_load(impl,path);
+ if (impl->stream ==0 || errno != 0){
+ impl->cluster = 0;
+ icalerror_set_errno(ICAL_FILE_ERROR); /* Redundant, actually */
+ return 0;
+ }
+
+ icalcluster_lock(impl);
+
+ if(cluster_file_size > 0){
+ parser = icalparser_new();
+ icalparser_set_gen_data(parser,impl->stream);
+ impl->cluster = icalparser_parse(parser,read_from_file);
+ icalparser_free(parser);
+
+ if (icalcomponent_isa(impl->cluster) != ICAL_XROOT_COMPONENT){
+ /* The parser got a single component, so it did not put it in
+ an XROOT. */
+ icalcomponent *cl = impl->cluster;
+ impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT);
+ icalcomponent_add_component(impl->cluster,cl);
+ }
+
+ } else {
+
+ impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT);
+ }
+
+ if (impl->cluster == 0){
+ icalerror_set_errno(ICAL_PARSE_ERROR);
+ return 0;
+ }
if (error != ICAL_NO_ERROR){
return 0;
@@ -260,46 +197,134 @@ void icalcluster_free(icalcluster* cluster)
impl->path = 0;
}
+ if(impl->stream != 0){
+ icalcluster_unlock(impl);
+ fclose(impl->stream);
+ impl->stream = 0;
+ }
+
free(impl);
}
-icalerrorenum icalcluster_commit(icalcluster* cluster)
+char* icalcluster_path(icalcluster* cluster)
{
- int ws; /* Size in char of file written to disk */
- FILE *f;
+ struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster;
+ icalerror_check_arg_rz((cluster!=0),"cluster");
+
+ return impl->path;
+}
+
+int icalcluster_lock(icalcluster *cluster)
+{
struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster;
+ struct flock lock;
+ int fd;
- icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR);
+ icalerror_check_arg_rz((impl->stream!=0),"impl->stream");
- if (impl->changed != 0 ){
- /* write the cluster to disk */
+ fd = fileno(impl->stream);
- /* Construct a filename and write out the file */
-
- if ( (f = fopen(impl->path,"w")) != 0){
+ lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */
+ lock.l_start = 0; /* byte offset relative to l_whence */
+ lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
+ lock.l_len = 0; /* #bytes (0 means to EOF) */
+
+ return (fcntl(fd, F_SETLKW, &lock));
+}
+
+int icalcluster_unlock(icalcluster *cluster)
+{
+ struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster;
+ int fd;
+ struct flock lock;
+ icalerror_check_arg_rz((impl->stream!=0),"impl->stream");
+
+ fd = fileno(impl->stream);
+
+ lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */
+ lock.l_start = 0; /* byte offset relative to l_whence */
+ lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
+ lock.l_len = 0; /* #bytes (0 means to EOF) */
+
+ return (fcntl(fd, F_UNLCK, &lock));
+
+}
+
+icalerrorenum icalcluster_create_cluster(char *path)
+{
+
+ FILE* f;
+ int r;
+ icalcomponent *c;
+
+ icalerror_clear_errno();
+
+ f = fopen(path,"w");
+
+ if (f == 0){
+ icalerror_set_errno(ICAL_FILE_ERROR);
+ return ICAL_FILE_ERROR;
+ }
+
+
+ /* This used to write data to the file... */
- char* str = icalcomponent_as_ical_string(impl->cluster);
-
- ws = fwrite(str,sizeof(char),strlen(str),f);
-
- if ( ws < strlen(str)){
- fclose(f);
- return ICAL_FILE_ERROR;
- }
+ fclose(f);
+
+ return ICAL_NO_ERROR;
+}
+
+icalerrorenum icalcluster_commit(icalcluster* cluster)
+{
+ FILE *f;
+ char tmp[PATH_MAX]; /* HACK Buffer overflow potential */
+ char *str;
+ icalparser *parser;
+ icalcomponent *c;
+
+ struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster;
+
+ icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR);
+
+ if (impl->changed == 0 ){
+ return ICAL_NO_ERROR;
+ }
+
+#ifdef ICAL_SAFESAVES
+ snprintf(tmp,PATH_MAX,"%s-tmp",impl->path);
+#else
+ strcpy(tmp,impl->path);
+#endif
+
+ if ( (f = fopen(tmp,"w")) < 0 ){
+ icalerror_set_errno(ICAL_FILE_ERROR);
+ return ICAL_FILE_ERROR;
+ }
+
+ for(c = icalcomponent_get_first_component(impl->cluster,ICAL_ANY_COMPONENT);
+ c != 0;
+ c = icalcomponent_get_next_component(impl->cluster,ICAL_ANY_COMPONENT)){
+
+ str = icalcomponent_as_ical_string(c);
+
+ if ( fwrite(str,sizeof(char),strlen(str),f) < strlen(str)){
fclose(f);
- impl->changed = 0;
- return ICAL_NO_ERROR;
- } else {
- icalerror_set_errno(ICAL_FILE_ERROR);
return ICAL_FILE_ERROR;
}
-
- }
-
+ }
+
+ fclose(f);
+ impl->changed = 0;
+
+#ifdef ICAL_SAFESAVES
+ rename(tmp,impl->path); /* HACK, should check for error here */
+#endif
+
return ICAL_NO_ERROR;
-}
+
+}
void icalcluster_mark(icalcluster* cluster){
diff --git a/libical/src/libicalss/icalcluster.h b/libical/src/libicalss/icalcluster.h
index 05c3a4b144..39fe542027 100644
--- a/libical/src/libicalss/icalcluster.h
+++ b/libical/src/libicalss/icalcluster.h
@@ -37,9 +37,7 @@ typedef void icalcluster;
icalcluster* icalcluster_new(char* path);
void icalcluster_free(icalcluster* cluster);
-
-/* Load a new file into the cluster */
-icalerrorenum icalcluster_load(icalcluster* cluster, char* path);
+char* icalcluster_path(icalcluster* cluster);
/* Return a reference to the internal component. */
icalcomponent* icalcluster_get_component(icalcluster* cluster);
diff --git a/libical/src/libicalss/icalstore.c b/libical/src/libicalss/icalstore.c
index 5d1546f3b2..382464e476 100644
--- a/libical/src/libicalss/icalstore.c
+++ b/libical/src/libicalss/icalstore.c
@@ -1,29 +1,29 @@
/* -*- Mode: C -*-
- ======================================================================
- FILE: icalstore.c
- CREATOR: eric 28 November 1999
+ ======================================================================
+ FILE: icalstore.c
+ CREATOR: eric 28 November 1999
- $Id$
- $Locker$
+ $Id$
+ $Locker$
- (C) COPYRIGHT 1999 Eric Busboom
- http://www.softwarestudio.org
+ (C) COPYRIGHT 1999 Eric Busboom
+ http://www.softwarestudio.org
- The contents of this file are subject to the Mozilla Public License
- Version 1.0 (the "License"); you may not use this file except in
- compliance with the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and
- limitations under the License.
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
- The Original Code is eric. The Initial Developer of the Original
- Code is Eric Busboom
+ The Original Code is eric. The Initial Developer of the Original
+ Code is Eric Busboom
- ======================================================================*/
+ ======================================================================*/
/*
@@ -51,6 +51,11 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
#include "ical.h"
#include "icalstore.h"
#include "pvl.h"
@@ -58,8 +63,6 @@
#include "icalparser.h"
#include "icalcluster.h"
-#include "filelock.h"
-
#include <limits.h>
#include <dirent.h> /* for opendir() */
#include <errno.h>
@@ -95,25 +98,23 @@ struct icalstore_impl* icalstore_new_impl()
return comp;
}
-
-
-void icalstore_lock_dir(char* dir)
+void icalstore_lock(char* dir)
{
}
-void icalstore_unlock_dir(char* dir)
+void icalstore_unlock(char* dir)
{
}
/* Load the contents of the store directory into the store's internal directory list*/
icalerrorenum icalstore_read_directory(struct icalstore_impl* impl)
{
- struct dirent *de;
- DIR* dp;
- char *str;
+ struct dirent *de;
+ DIR* dp;
+ char *str;
- dp = opendir(impl->dir);
+ dp = opendir(impl->dir);
if ( dp == 0) {
icalerror_set_errno(ICAL_FILE_ERROR);
@@ -166,7 +167,7 @@ icalstore* icalstore_new(char* dir)
return 0;
}
- icalstore_lock_dir(dir);
+ icalstore_lock(dir);
impl = icalstore_new_impl();
@@ -192,7 +193,7 @@ void icalstore_free(icalstore* s)
struct icalstore_impl *impl = (struct icalstore_impl*)s;
char* str;
- icalstore_unlock_dir(impl->dir);
+ icalstore_unlock(impl->dir);
if(impl->dir !=0){
free(impl->dir);
@@ -298,10 +299,13 @@ icalerrorenum icalstore_next_cluster(icalstore* store)
return ICAL_NO_ERROR;
}
-
sprintf(path,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator));
- return icalcluster_load(impl->cluster,path);
+ icalcluster_free(impl->cluster);
+
+ impl->cluster = icalcluster_new(path);
+
+ return icalerrno;
}
void icalstore_add_uid(icalstore* store, icalstore* comp)
@@ -310,8 +314,8 @@ void icalstore_add_uid(icalstore* store, icalstore* comp)
icalproperty *uid;
struct utsname unamebuf;
- icalerror_check_arg_rz( (store!=0), "store");
- icalerror_check_arg_rz( (comp!=0), "comp");
+ icalerror_check_arg_rv( (store!=0), "store");
+ icalerror_check_arg_rv( (comp!=0), "comp");
uid = icalcomponent_get_first_property(comp,ICAL_UID_PROPERTY);
@@ -319,7 +323,7 @@ void icalstore_add_uid(icalstore* store, icalstore* comp)
uname(&unamebuf);
- sprintf(uidstring,"%d-%s",getpid(),unamebuf.nodename);
+ sprintf(uidstring,"%d-%s",(int)getpid(),unamebuf.nodename);
uid = icalproperty_new_uid(uidstring);
icalcomponent_add_property(comp,uid);
@@ -329,14 +333,20 @@ void icalstore_add_uid(icalstore* store, icalstore* comp)
}
}
+
+/* This assumes that the top level component is a VCALENDAR, and there
+ is an inner component of type VEVENT, VTODO or VJOURNAL. The inner
+ component must have a DTSTART property */
+
icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp)
{
struct icalstore_impl *impl;
char clustername[PATH_MAX];
- icalproperty *dt, *count, *lm;
+ icalproperty *dt, *count;
icalvalue *v;
struct icaltimetype tm;
icalerrorenum error = ICAL_NO_ERROR;
+ icalcomponent *inner;
impl = (struct icalstore_impl*)store;
icalerror_check_arg_rz( (store!=0), "store");
@@ -346,20 +356,21 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp)
icalstore_add_uid(store,comp);
- /* Determine which cluster this object belongs in */
-
- dt = icalcomponent_get_first_property(comp,ICAL_DTSTART_PROPERTY);
+ /* Determine which cluster this object belongs in. This is a HACK */
- if (dt == 0){
- dt = icalcomponent_get_first_property(comp,ICAL_DTSTAMP_PROPERTY);
+ for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
+ inner != 0;
+ inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){
+
+ dt = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY);
+
+ if (dt != 0){
+ break;
+ }
}
if (dt == 0){
- dt = icalcomponent_get_first_property(comp,ICAL_CREATED_PROPERTY);
- }
-
- if (dt == 0){
- icalerror_warn("The component does not have a DTSTART, DTSTAMP or a CREATED property, so it cannot be added to the store");
+ icalerror_warn("The component does not have a DTSTART property, so it cannot be added to the store");
icalerror_set_errno(ICAL_BADARG_ERROR);
return ICAL_BADARG_ERROR;
}
@@ -368,41 +379,29 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp)
tm = icalvalue_get_datetime(v);
- sprintf(clustername,"%s/%04d%02d",impl->dir,tm.year,tm.month);
+ snprintf(clustername,PATH_MAX,"%s/%04d%02d",impl->dir,tm.year,tm.month);
/* Load the cluster and insert the object */
+ if(impl->cluster != 0 &&
+ strcmp(clustername,icalcluster_path(impl->cluster)) != 0 ){
+ icalcluster_free(impl->cluster);
+ impl->cluster = 0;
+ }
+
if (impl->cluster == 0){
impl->cluster = icalcluster_new(clustername);
if (impl->cluster == 0){
error = icalerrno;
}
- } else {
- error = icalcluster_load(impl->cluster,
- clustername);
-
}
-
if (error != ICAL_NO_ERROR){
icalerror_set_errno(error);
return error;
}
- /* Update or add the LAST-MODIFIED property */
-
- lm = icalcomponent_get_first_property(comp,
- ICAL_LASTMODIFIED_PROPERTY);
-
- if (lm == 0){
- lm = icalproperty_new_lastmodified(icaltimetype_from_timet( time(0),1));
- icalcomponent_add_property(comp,lm);
- } else {
- icalproperty_set_lastmodified(comp,icaltimetype_from_timet( time(0),1));
- }
-
-
/* Add the component to the cluster */
icalcluster_add_component(impl->cluster,comp);
@@ -419,7 +418,7 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp)
}
icalproperty_set_xlicclustercount(count,
- icalproperty_get_xlicclustercount(count)+1);
+ icalproperty_get_xlicclustercount(count)+1);
icalcluster_mark(impl->cluster);
@@ -438,38 +437,38 @@ icalerrorenum icalstore_remove_component(icalstore* store, icalstore* comp)
icalerror_check_arg_re((impl->cluster!=0),"Cluster pointer",ICAL_USAGE_ERROR);
/* HACK The following code should be used to ensure that the component
-the caller is trying to remove is actually in the cluster, but it
-resets the internal iterators, which immediately ends any loops over
-the cluster the caller may have in progress
-
- for(c = icalcluster_get_first_component(
- impl->cluster,
- ICAL_ANY_COMPONENT);
- c != 0;
- c = icalcluster_get_next_component(
- impl->cluster,
- ICAL_ANY_COMPONENT)){
-
- if (c == comp){
- found = 1;
- }
-
- }
-
- if (found != 1){
- icalerror_warn("icalstore_remove_component: component is not part of current cluster");
- icalerror_set_errno(ICAL_USAGE_ERROR);
- return ICAL_USAGE_ERROR;
- }
+ the caller is trying to remove is actually in the cluster, but it
+ resets the internal iterators, which immediately ends any loops over
+ the cluster the caller may have in progress
+
+ for(c = icalcluster_get_first_component(
+ impl->cluster,
+ ICAL_ANY_COMPONENT);
+ c != 0;
+ c = icalcluster_get_next_component(
+ impl->cluster,
+ ICAL_ANY_COMPONENT)){
+
+ if (c == comp){
+ found = 1;
+ }
+
+ }
+
+ if (found != 1){
+ icalerror_warn("icalstore_remove_component: component is not part of current cluster");
+ icalerror_set_errno(ICAL_USAGE_ERROR);
+ return ICAL_USAGE_ERROR;
+ }
*/
icalcluster_remove_component(impl->cluster,
- comp);
+ comp);
icalcluster_mark(impl->cluster);
- /* Decrement the clusters count value */
+ /* Decrement the clusters count value */
count = icalcomponent_get_first_property(
icalcluster_get_component(impl->cluster),
ICAL_XLICCLUSTERCOUNT_PROPERTY);
@@ -480,7 +479,7 @@ the cluster the caller may have in progress
}
icalproperty_set_xlicclustercount(count,
- icalproperty_get_xlicclustercount(count)-1);
+ icalproperty_get_xlicclustercount(count)-1);
return ICAL_NO_ERROR;
}
@@ -507,6 +506,7 @@ icalcomponent* icalstore_make_gauge(icalcomponent* query);
Here is an example:
+ BEGIN:XROOT
BEGIN:VCOMPONENT
BEGIN:VEVENT
DTSTART;X-LIC-COMPARETYPE=LESS:19981025T020000
@@ -516,76 +516,79 @@ icalcomponent* icalstore_make_gauge(icalcomponent* query);
LOCATION;X-LIC-COMPARETYPE=EQUAL:McNary's Pub
END:VEVENT
END:VCALENDAR
+ END:XROOT
This gauge has two sub-components; one which will match a VEVENT
based on start time, and organizer, and another that matches based
on LOCATION. A target component will pass the test if it matched
- either of the gauge.
+ either of the sub-components.
*/
-int icalstore_test(icalcomponent* comp, icalcomponent* gauge)
+
+int icalstore_test_recurse(icalcomponent* comp, icalcomponent* gauge)
{
- int pass = 0,localpass = 0;
- icalcomponent *c;
+ int pass = 1,localpass = 0;
icalproperty *p;
- icalcomponent *child;
+ icalcomponent *child,*subgauge;
+ icalcomponent_kind gaugekind, compkind;
icalerror_check_arg_rz( (comp!=0), "comp");
icalerror_check_arg_rz( (gauge!=0), "gauge");
- for(c = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT);
- c != 0;
- c = icalcomponent_get_next_component(gauge,ICAL_ANY_COMPONENT)){
+ gaugekind = icalcomponent_isa(gauge);
+ compkind = icalcomponent_isa(comp);
+ if( ! (gaugekind == compkind || gaugekind == ICAL_ANY_COMPONENT) ){
+ return 0;
+ }
- /* Test properties. For each property in the gauge, search through
- the component for a similar property. If one is found, compare
- the two properties value with the comparison specified in the
- gauge with the X-LIC-COMPARETYPE parameter */
-
- for(p = icalcomponent_get_first_property(c,ICAL_ANY_PROPERTY);
- p != 0;
- p = icalcomponent_get_next_property(c,ICAL_ANY_PROPERTY)){
+ /* Test properties. For each property in the gauge, search through
+ the component for a similar property. If one is found, compare
+ the two properties value with the comparison specified in the
+ gauge with the X-LIC-COMPARETYPE parameter */
+
+ for(p = icalcomponent_get_first_property(gauge,ICAL_ANY_PROPERTY);
+ p != 0;
+ p = icalcomponent_get_next_property(gauge,ICAL_ANY_PROPERTY)){
+
+ icalproperty* targetprop;
+ icalparameter* compareparam;
+ icalparameter_xliccomparetype compare;
+ int rel; /* The relationship between the gauge and target values.*/
+
+ /* Extract the comparison type from the gauge. If there is no
+ comparison type, assume that it is "EQUAL" */
+
+ compareparam = icalproperty_get_first_parameter(
+ p,
+ ICAL_XLICCOMPARETYPE_PARAMETER);
+
+ if (compareparam!=0){
+ compare = icalparameter_get_xliccomparetype(compareparam);
+ } else {
+ compare = ICAL_XLICCOMPARETYPE_EQUAL;
+ }
+
+ /* Find a property in the component that has the same type
+ as the gauge property. HACK -- multiples of a single
+ property type in the gauge will match only the first
+ instance in the component */
+
+ targetprop = icalcomponent_get_first_property(comp,
+ icalproperty_isa(p));
+
+ if(targetprop != 0){
- icalproperty* targetprop;
- icalparameter* compareparam;
- icalparameter_xliccomparetype compare;
- int rel; /* The realtionship between the gauge and target values.*/
-
- /* Extract the comparison type from the gauge. If there is no
- comparison type, assume that it is "EQUAL" */
-
- compareparam = icalproperty_get_first_parameter(
- p,
- ICAL_XLICCOMPARETYPE_PARAMETER);
-
- if (compareparam!=0){
- compare = icalparameter_get_xliccomparetype(compareparam);
- } else {
- compare = ICAL_XLICCOMPARETYPE_EQUAL;
- }
-
- /* Find a property in the component that has the same type as
- the gauge property */
-
- targetprop = icalcomponent_get_first_property(comp,
- icalproperty_isa(p));
-
-
- if(targetprop == 0){
- continue;
- }
-
/* Compare the values of the gauge property and the target
property */
-
+
rel = icalvalue_compare(icalproperty_get_value(p),
icalproperty_get_value(targetprop));
-
+
/* Now see if the comparison is equavalent to the comparison
specified in the gauge */
-
+
if (rel == compare){
localpass++;
} else if (compare == ICAL_XLICCOMPARETYPE_LESSEQUAL &&
@@ -599,27 +602,59 @@ int icalstore_test(icalcomponent* comp, icalcomponent* gauge)
} else if (compare == ICAL_XLICCOMPARETYPE_NOTEQUAL &&
( rel == ICAL_XLICCOMPARETYPE_GREATER ||
rel == ICAL_XLICCOMPARETYPE_LESS)) {
- pass++;
+ localpass++;
} else {
localpass = 0;
}
-
- pass += localpass;
+
+ pass = pass && (localpass>0);
}
-
-
- /* test subcomponents. Look for a child component that has a
- counterpart in the gauge. If one is found, recursively call
- icalstore_test */
+ }
+
+ /* Test subcomponents. Look for a child component that has a
+ counterpart in the gauge. If one is found, recursively call
+ icalstore_test */
+
+ for(subgauge = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT);
+ subgauge != 0;
+ subgauge = icalcomponent_get_next_component(gauge,ICAL_ANY_COMPONENT)){
- for(child = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
- child != 0;
- child = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){
+ gaugekind = icalcomponent_isa(subgauge);
+
+ if (gaugekind == ICAL_ANY_COMPONENT){
+ child = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
+ } else {
+ child = icalcomponent_get_first_component(comp,gaugekind);
+ }
- pass += icalstore_test(child,gauge);
-
+ if(child !=0){
+ localpass = icalstore_test_recurse(child,subgauge);
+ pass = pass && localpass;
+ } else {
+ pass = 0;
}
}
+
+ return pass;
+}
+
+/* guagecontainer is an XROOT component that holds several gauges. The
+ results of comparing against these gauges are ORed together in this
+ routine */
+int icalstore_test(icalcomponent* comp, icalcomponent* gaugecontainer)
+{
+ int pass = 0;
+ icalcomponent *gauge;
+
+ icalerror_check_arg_rz( (comp!=0), "comp");
+ icalerror_check_arg_rz( (gauge!=0), "gauge");
+
+ for(gauge = icalcomponent_get_first_component(gaugecontainer,ICAL_ANY_COMPONENT);
+ gauge != 0;
+ gauge = icalcomponent_get_next_component(gaugecontainer,ICAL_ANY_COMPONENT)){
+
+ pass += icalstore_test_recurse(comp, gauge);
+ }
return pass>0;
@@ -721,16 +756,21 @@ icalcomponent* icalstore_get_first_component(icalstore* store)
sprintf(path,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator));
- if (impl->cluster == 0){
+ /* If the next cluster we need is different than the current cluster,
+ delete the current one and get a new one */
+
+ if(impl->cluster != 0 && strcmp(path,icalcluster_path(impl->cluster)) != 0 ){
+ icalcluster_free(impl->cluster);
+ impl->cluster = 0;
+ }
+
+ if (impl->cluster == 0){
impl->cluster = icalcluster_new(path);
if (impl->cluster == 0){
error = icalerrno;
}
- } else {
- error = icalcluster_load(impl->cluster,path);
-
- }
+ }
if (error != ICAL_NO_ERROR){
icalerror_set_errno(error);
@@ -783,13 +823,13 @@ icalcomponent* icalstore_get_next_component(icalstore* store)
ICAL_ANY_COMPONENT)){
/* If there is a gauge defined and the component does not
- pass the gauge, skip the rest of the loop */
+ pass the gauge, skip the rest of the loop */
if (impl->gauge != 0 && icalstore_test(c,impl->gauge) == 0){
continue;
}
/* Either there is no gauge, or the component passed the
- gauge, so return it*/
+ gauge, so return it*/
return c;
}
@@ -815,3 +855,4 @@ icalcomponent* icalstore_get_next_component(icalstore* store)
+