From 8357d7b199e26e4d071b267a314447b22f2ddb3c Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Thu, 24 Aug 2000 19:31:03 +0000 Subject: Initial revision svn path=/trunk/; revision=5011 --- libical/src/libicalss/icalgauge.c | 208 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 libical/src/libicalss/icalgauge.c (limited to 'libical/src/libicalss/icalgauge.c') diff --git a/libical/src/libicalss/icalgauge.c b/libical/src/libicalss/icalgauge.c new file mode 100644 index 0000000000..60ce1587cd --- /dev/null +++ b/libical/src/libicalss/icalgauge.c @@ -0,0 +1,208 @@ +/* -*- Mode: C -*- */ +/*====================================================================== + FILE: icalgauge.c + CREATOR: eric 23 December 1999 + + + $Id$ + $Locker$ + + (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org + + This program is free software; you can redistribute it and/or modify + it under the terms of either: + + The LGPL as published by the Free Software Foundation, version + 2.1, available at: http://www.fsf.org/copyleft/lesser.html + + Or: + + The Mozilla Public License Version 1.0. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + The Original Code is eric. The Initial Developer of the Original + Code is Eric Busboom + + +======================================================================*/ + +#include "ical.h" + +/* Convert a VQUERY component into a gauge */ +icalcomponent* icalgauge_make_gauge(icalcomponent* query); + +/* icaldirset_test compares a component against a gauge, and returns + true if the component passes the test + + The gauge is a VCALENDAR component that specifies how to test the + target components. The guage holds a collection of VEVENT, VTODO or + VJOURNAL sub-components. Each of the sub-components has a + collection of properties that are compared to corresponding + properties in the target component, according to the + X-LIC-COMPARETYPE parameters to the gauge's properties. + + When a gauge has several sub-components, the results of testing the + target against each of them is ORed together - the target + component will pass if it matches any of the sub-components in the + gauge. However, the results of matching the proeprties in a + sub-component are ANDed -- the target must match every property in + a gauge sub-component to match the sub-component. + + Here is an example: + + BEGIN:XROOT + BEGIN:VCOMPONENT + BEGIN:VEVENT + DTSTART;X-LIC-COMPARETYPE=LESS:19981025T020000 + ORGANIZER;X-LIC-COMPARETYPE=EQUAL:mrbig@host.com + END:VEVENT + BEGIN:VEVENT + 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 sub-components. + + */ + + +int icalgauge_test_recurse(icalcomponent* comp, icalcomponent* gauge) +{ + int pass = 1,localpass = 0; + icalproperty *p; + icalcomponent *child,*subgauge; + icalcomponent_kind gaugekind, compkind; + + icalerror_check_arg_rz( (comp!=0), "comp"); + icalerror_check_arg_rz( (gauge!=0), "gauge"); + + 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(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){ + + /* 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 && + ( rel == ICAL_XLICCOMPARETYPE_LESS || + rel == ICAL_XLICCOMPARETYPE_EQUAL)) { + localpass++; + } else if (compare == ICAL_XLICCOMPARETYPE_GREATEREQUAL && + ( rel == ICAL_XLICCOMPARETYPE_GREATER || + rel == ICAL_XLICCOMPARETYPE_EQUAL)) { + localpass++; + } else if (compare == ICAL_XLICCOMPARETYPE_NOTEQUAL && + ( rel == ICAL_XLICCOMPARETYPE_GREATER || + rel == ICAL_XLICCOMPARETYPE_LESS)) { + localpass++; + } else { + localpass = 0; + } + + pass = pass && (localpass>0); + } + } + + /* Test subcomponents. Look for a child component that has a + counterpart in the gauge. If one is found, recursively call + icaldirset_test */ + + for(subgauge = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT); + subgauge != 0; + subgauge = icalcomponent_get_next_component(gauge,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); + } + + if(child !=0){ + localpass = icalgauge_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 icalgauge_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 += icalgauge_test_recurse(comp, gauge); + } + + return pass>0; + +} + + -- cgit v1.2.3