5 Eric Busboom (eric@softwarestudio.org)
13 Libical is an Open Source implementation of the iCalendar protocols
14 and protocol data units. The iCalendar specification describes how
15 calendar clients can communicate with calendar servers so users can
16 store their calendar data and arrange meetings with other users.
18 Libical implements RFC2445, RFC2446 and some of RFC2447.
20 This documentation assumes that you are familiar with the iCalendar
21 standards RFC2445 and RFC2446. these specifications are online on
22 the CALSCH webpage at:
24 http://www.imc.org/ietf-calendar/
26 1.1 The libical project
28 This code is under active development. If you would like to contribute
29 to the project, visit http://freeassociation.sourceforge.net
33 The code and datafiles in this distribution are licensed under the
34 Mozilla Public License. See http://www.mozilla.org/NPL/MPL-1.0.html
35 for a copy of the license. Alternately, you may use libical under
36 the terms of the GNU Library General Public License. See
37 http://www.fsf.org/copyleft/lesser.html for a copy of the LGPL.
39 This dual license ensures that the library can be incorporated into
40 both proprietary code and GPL'd programs, and will benefit from improvements
41 made by programmers in both realms. I will only accept changes into
42 my version of the library if they are similarly dual-licensed.
46 A lot of the documentation for this library is in the form of example
47 code. These examples are in the "examples" directory of the distribution.
48 Also look in "src/test" for additional annotated examples.
50 2 Building the Library
52 Libical uses autoconf to generate makefiles. It should built with no
53 adjustments on Linux, FreeBSD and Solaris under gcc. Some version
54 have been successfully been build on MacOS, Solaris, UnixWare, And
55 Tru64 UNIX without gcc, but you may run into problems with a particular
58 For a more complete guide to building the library, see the README file
63 The iCalendar data model is based on four types of objects: components,
64 properties, values and parameters.
66 Properties are the fundamental unit of information in iCalendar, and they
67 work a bit like a hash entry, with a constant key and a variable value.
68 Properties may also have modifiers, called parameters. In the iCal
71 ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
73 The property name is "ORGANIZER," the value of the property is "mrbig@host.com"
74 and the "ROLE" parameter specifies that Mr Big is the chair of the
75 meetings associated with this property.
77 Components are groups of properties that represent the core objects
78 of a calendar system, such as events or timezones. Components are
79 delimited by "BEGIN" and "END" tags.
81 When a component is sent across a network, if it is un-encrypted, it
82 will look something like:
88 PRODID: -//hacksw/handcal//NONSGML v1.0//EN
92 DTSTAMP:19980309T231000Z
96 ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
98 ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:
100 MAILTO:employee-A@host.com
102 DESCRIPTION:Project XYZ Review Meeting
108 CREATED:19980309T130000Z
110 SUMMARY:XYZ Project Review
112 DTSTART;TZID=US-Eastern:19980312T083000
114 DTEND;TZID=US-Eastern:19980312T093000
116 LOCATION:1CP Conference Room 4350
122 Note that components can be nested; this example has both a VCALENDAR
123 and a VEVENT component, one nested inside the other.
125 3.1 Core iCal classes
127 Libical is an object-based, data-oriented library. Nearly all of the
128 routines in the library are associated with an opaque data types and
129 perform some operation on that data type. Although the library does
130 not actually have classes, we will use those terms since the behavior
131 of these associations of data and routines is very similar to a class.
135 Properties are represented with the icalproperty class and its many
136 "derived" classes with on "derived" class per property type in RFC2445.
137 Again, there is no actual inheritance relations, but there are clusters
138 of routines that make this term useful. A property is a container
139 for a single value and a set of parameters.
143 In libical, components are represented with the icalcomponent class.
144 Icalcomponent is a container for a set of other components and properties.
148 Values are represented in a similar way to properties; a base class
149 and many "derived " classes. A value is essentially a abstract handle
150 on a single fundamental type, a structure or a union.
154 Parameters are represented in a similar way to properties, except that
155 they contain only one value
157 3.2 Other elements of libical
159 In addition to the core iCal classes, libical has many other types,
160 structures, classes that aid in creating and using iCal components.
162 3.2.1 Enumerations and types
164 Libical is strongly typed, so every component, property, parameter,
165 and value type has an enumeration, and some have an associated structure
170 The libical parser offers a variety of ways to convert RFC2445 text
171 into a libical internal component structure. the parser can parse
172 blocks of text as a string, or it can parse line-by-line.
176 Libical has a substantial error reporting system for both programming
177 errors and component usage errors.
179 3.2.4 Memory Management
181 Since many of libicals interfaces return strings, the library has its
182 own memory management system to elimiate the need to free every string
183 returned from the library.
185 3.2.5 Storage classes
187 The library also offers several classes to store components to flies,
190 4 Differences From RFCs
192 Libical has been designed to follow the standards as closely as possible,
193 so that the key objects in the standards are also key objects in the
194 library. However, there are a few areas where the specifications are
195 (arguably) irregular, and following them exactly would result in an
196 unfriendly interface. These deviations make libical easier to use
197 by maintaining a self-similar interface.
199 4.1 Pseudo Components
201 Libical defines components for groups of properties that look and act
202 like components, but are not defined as components in the specification.
203 XDAYLIGHT and XSTANDARD are notable examples. These pseudo components
204 group properties within the VTIMEZONE components. For instanace, the
205 timezone properties associated with daylight savings time starts with
206 "BEGIN:DAYLIGHT" and ends with "END:DAYLIGHT, just like other components,
207 but is not defined as a component in RFC2445 (see RFC2445, page
208 61). In Libical,this grouping is represented by the XDAYLIGHT component.
209 Standard iCAL components all start with the letter "V," while pseudo
210 components start with"X."
212 There are also pseudo components that are conceptually derived classes
213 of VALARM. RFC2446 defines what properties may be included in each
214 component, and for VALARM, the set of properties it may have depends
215 on the value of the ACTION property.
217 For instance, if a VALARM component has an ACTION property with the
218 value of "AUDIO," the component must also have an "ATTACH" property.
219 However, if the ACTION value is "DISPLAY," the component must have
220 a DESCRIPTION property.
222 To handle these various, complex restrictions, libical has pseudo components
223 for each type of alarm: XAUDIOALARM, XDISPLAYALARM, XEMAILALARM and
228 Many values can take more than one type. TRIGGER, for instance, can
229 have a value type of with DURATION or of DATE-TIME. These multiple
230 types make it difficult to create routines to return the value associated
233 It is natural to have interfaces that would return the value of a property,
234 but it is cumbersome for a single routine to return multiple types.
235 So, in libical, properties that can have multiple types are given
236 a single type that is the union of their RFC2445 types. For instance,
237 in libical, the value of the TRIGGER property resolves to struct icaltriggertype.
238 This type is a union of a DURATION and a DATE-TIME.
240 4.3 Multi-Valued Properties
242 Some properties, such as CATEGORIES have only one value type, but each
243 CATEGORIES property can have multiple value instances. This also results
244 in a cumbersome interface -- CATEGORIES accessors would have to return
245 a list while all other accessors returned a single value. In libical,
246 all properties have a single value, and multi-valued properties are
247 broken down into multiple single valued properties during parsing.
248 That is, an input line like,
250 CATEGORIES: work, home
252 becomes in libical's internal representation
258 Oddly, RFC2445 allows some multi-valued properties (like FREEBUSY)
259 to exist as both a multi-values property and as multiple single
260 value properties, while others (like CATEGORIES) can only exist
261 as single multi-valued properties. This makes the internal representation
262 for CATEGORIES illegal. However when you convert a component to a
263 string, the library will collect all of the CATEGORIES properties
268 5.1 Creating Components
270 There are three ways to create components in Libical: creating individual
271 objects and assembling them, building entire objects in massive vaargs
272 calls, and parsing a text file containing iCalendar data.
274 5.1.1 Constructor Interfaces
276 Using constructor interfaces, you create each of the objects separately
277 and then assemble them in to components:
279 icalcomponent *event;
283 icalparameter *param;
285 struct icaltimetype atime;
287 event = icalcomponent_new(ICAL_VEVENT_COMPONENT);
289 prop = icalproperty_new_dtstamp(atime) ;
291 icalcomponent_add_property(event, prop);
293 prop = icalproperty_new_uid(''guid-1.host1.com'');
295 icalcomponent_add_property(event,prop);
297 prop=icalproperty_new_organizer(''mrbig@host.com'');
299 param = icalparameter_new_role(ICAL_ROLE_CHAIR)
301 icalproperty_add_parameter(prop, param);
303 icalcomponent_add_property(event,prop);
305 Notice that libical uses a semi-object-oriented style of interface.
306 Most things you work with are objects, that are instantiated with
307 a constructor that has "new" in the name. Also note that, other than
308 the object reference, most structure data is passed in to libical
309 routines by value. Libical has some complex but very regular memory
310 handling rules. These are detailed in section [sec:memory].
312 If any of the constructors fail, they will return 0. If you try to
313 insert 0 into a property or component, or use a zero-valued object
314 reference, libical will either silently ignore the error or will abort
315 with an error message. This behavior is controlled by a compile time
316 flag (ICAL_ERRORS_ARE_FATAL), and will abort by default.
318 5.1.2 vaargs Constructors
320 There is another way to create complex components, which is arguably
321 more elegant, if you are not horrified by varargs. The varargs constructor
322 interface allows you to create intricate components in a single block
323 of code. Here is the previous examples in the vaargs style.
329 ICAL_VCALENDAR_COMPONENT,
331 icalproperty_new_version(''2.0''),
333 icalproperty_new_prodid(
335 ''-//RDU Software//NONSGML HandCal//EN''),
339 ICAL_VEVENT_COMPONENT,
341 icalproperty_new_dtstamp(atime),
343 icalproperty_new_uid(''guid-1.host1.com''),
345 icalproperty_vanew_organizer(
349 icalparameter_new_role(ICAL_ROLE_CHAIR),
355 icalproperty_vanew_attendee(
357 ''employee-A@host.com'',
359 icalparameter_new_role(
361 ICAL_ROLE_REQPARTICIPANT),
363 icalparameter_new_rsvp(1),
365 icalparameter_new_cutype(ICAL_CUTYPE_GROUP),
371 icalproperty_new_location(
373 "1CP Conference Room 4350"),
383 This form is similar to the constructor form , except that the constructors
384 have "vanew" instead of "new" in the name. The arguments are similar
385 too, except that the component constructor can have a list of properties,
386 and the property constructor can have a list of parameters. Be sure
387 to terminate every list with a '0', or your code will crash, if you
390 5.1.3 Parsing Text Files
392 The final way to create components will probably be the most common;
393 you can create components from RFC2445 compliant text. If you have
394 the string in memory, use
396 icalcomponent* icalparser_parse_string(char* str);
398 If the string contains only one component, the parser will return the
399 component in libical form. If the string contains multiple components,
400 the multiple components will be returned as the children of an ICAL_XROOT_COMPONENT
403 Parsing a whole string may seem wasteful if you want to pull a large
404 component off of the network or from a file; you may prefer to parse
405 the component line by line. This is possible too by using:
407 icalparser* icalparser_new();
409 void icalparser_free(icalparser* parser);
411 icalparser_get_line(parser,read_stream);
413 icalparser_add_line(parser,line);
415 icalparser_set_gen_data(parser,stream)
417 These routines will construct a parser object to which you can add
418 lines of input and retrieve any components that the parser creates
419 from the input. These routines work by specifing an adaptor routine
420 to get string data from a source. For an example:
422 char* read_stream(char *s, size_t size, void *d)
426 char *c = fgets(s,size, (FILE*)d);
438 icalparser *parser = icalparser_new();
440 FILE* stream = fopen(argv[1],"r");
442 icalparser_set_gen_data(parser,stream);
446 line = icalparser_get_line(parser,read_stream);
448 c = icalparser_add_line(parser,line);
452 printf("%s",icalcomponent_as_ical_string(c));
454 icalparser_claim(parser);
456 printf("\n---------------\n");
458 icalcomponent_free(c);
462 } while ( line != 0);
466 The parser object parameterizes the routine used to get input lines
467 with icalparser_set_gen_data() and icalparser_get_line(). In this
468 example, the routine read_stream() will fetch the next line from a
469 stream, with the stream passed in as the void* parameter d. The parser
470 calls read_stream() from icalparser_get_line(), but it also needs
471 to know what stream to use. This is set by the call to icalparser_set_gen_data().
472 By using a different routine for read_stream or passing in different
473 data with icalparser_set_gen_data, you can connect to any data source.
475 Using the same mechanism, other implementations could read from memory
476 buffers, sockets or other interfaces.
478 Since the example code is a very common way to use the parser, there
479 is a convenience routine;
481 icalcomponent* icalparser_parse(icalparser *parser,
483 char* (*line_gen_func)(char *s, size_t size, void*
486 To use this routine, you still must construct the parser object and
487 pass in a reference to a line reading routine. If the parser can create
488 a single component from the input, it will return a pointer to the
489 newly constructed component. If the parser can construct multiple
490 components from the input, it will return a reference to an XROOT
491 component ( of type ICAL_XROOT_COMPONENT.) This XROOT component will
492 hold all of the components constructed from the input as children.
494 5.2 Accessing Components
496 Given a reference to a component, you probably will want to access
497 the properties, parameters and values inside. Libical interfaces let
498 you find sub-component, add and remove sub-components, and do the
499 same three operations on properties.
501 5.2.1 Finding Components
503 To find a sub-component of a component, use:
505 icalcomponent* icalcomponent_get_first_component(
507 icalcomponent* component,
509 icalcomponent_kind kind);
511 This routine will return a reference to the first component of the
512 type 'kind.' The key kind values, listed in icalenums.h are:
516 ICAL_VEVENT_COMPONENT
520 ICAL_VJOURNAL_COMPONENT
522 ICAL_VCALENDAR_COMPONENT
524 ICAL_VFREEBUSY_COMPONENT
526 ICAL_VALARM_COMPONENT
528 These are only the most common components; there are many more listed
531 As you might guess, if there is more than one subcomponent of the type
532 you have chosen, this routine will return only the first. to get at
533 the others, you need to iterate through the component.
535 5.2.2 Iterating Through Components
537 Iteration requires a second routine to get the next subcomponent after
540 icalcomponent* icalcomponent_get_next_component(
542 icalcomponent* component,
544 icalcomponent_kind kind);
546 With the 'first' and 'next' routines, you can create a for loop to
547 iterate through all of a components subcomponents
549 for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
553 c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT))
561 This code bit wil iterate through all of the subcomponents in 'comp'
562 but you can select a specific type of component by changing ICAL_ANY_COMPONENT
563 to another component type.
565 5.2.3 Using Component Iterators
567 The iteration model in the previous section requires the component
568 to keep the state of the iteration. So, you could not use this model
569 to perform a sorting operations, since you'd need two iterators and
570 there is only space for one. If you ever call icalcomponent_get_first_component()
571 when an iteration is in progress, the pointer will be reset to the
574 To solve this problem, there are also external iterators for components.
575 The routines associated with these external iterators are:
577 icalcompiter icalcomponent_begin_component(icalcomponent* component,
578 icalcomponent_kind kind);
580 icalcompiter icalcomponent_end_component(icalcomponent* component,
581 icalcomponent_kind kind);
583 icalcomponent* icalcompiter_next(icalcompiter* i);
585 icalcomponent* icalcompiter_prior(icalcompiter* i);
587 icalcomponent* icalcompiter_deref(icalcompiter* i);
589 The _begin_() and _end_() routines return a new iterator that points
590 to the beginning and ending of the list of subcomponent for the given
591 component, and the kind argument works like the kind argument for
594 After creating an iterators, use _next_() and _prior_() to step forward
595 and backward through the list and get the component that the iterator
596 points to, and use _deref() to return the component that the iterator
597 points to without moving the iterator. All routines will return 0
598 when they move to point off the end of the list.
600 Here is an example of a loop using these routines:
604 i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT);
606 icalcompiter_deref(&i)!= 0;
608 icalcompiter_next(&i)
612 icalcomponent *this = icalcompiter_deref(&i);
616 5.2.4 Removing Components
618 Removing an element from a list while iterating through the list with
619 the internal iterators can cause problems, since you will probably
620 be removing the element that the internal iterator points to. The
621 _remove() routine will keep the iterator valid by moving it to the
622 next component, but in a normal loop, this will result in two advances
623 per iteration, and you will remove only every other component. To
624 avoid the problem, you will need to step the iterator ahead of the
625 element you are going to remove, like this:
627 for(c = icalcomponent_get_first_component(parent_comp,ICAL_ANY_COMPONENT);
635 next = icalcomponent_get_next_component(parent_comp,ICAL_ANY_COMPONENT);
637 icalcomponent_remove_component(parent_comp,c);
641 Another way to remove components is to rely on the side effect of icalcomponent_remove_component:
642 if component iterator in the parent component is pointing to the child
643 that will be removed, it will move the iterator to the component after
644 the child. The following code will exploit this behavior:
646 icalcomponent_get_first_component(parent_comp,ICAL_VEVENT_COMPONENT);
648 while((c=icalcomponent_get_current_component(c)) != 0 ){
650 if(icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT){
652 icalcomponent_remove_component(parent_comp,inner);
656 icalcomponent_get_next_component(parent_comp,ICAL_VEVENT_COMPONENT);
662 5.2.5 Working with properties and parameters
664 Finding, iterating and removing properties works the same as it does
665 for components, using the property-specific or parameter-specific
668 icalproperty* icalcomponent_get_first_property(
670 icalcomponent* component,
672 icalproperty_kind kind);
674 icalproperty* icalcomponent_get_next_property(
676 icalcomponent* component,
678 icalproperty_kind kind);
680 void icalcomponent_add_property(
682 icalcomponent* component,
684 icalproperty* property);
686 void icalcomponent_remove_property(
688 icalcomponent* component,
690 icalproperty* property);
694 icalparameter* icalproperty_get_first_parameter(
698 icalparameter_kind kind);
700 icalparameter* icalproperty_get_next_parameter(
704 icalparameter_kind kind);
706 void icalproperty_add_parameter(
710 icalparameter* parameter);
712 void icalproperty_remove_parameter(
716 icalparameter_kind kind);
718 Note that since there should be only one parameter of each type in
719 a property, you will rarely need to use icalparameter_get_nect_paameter.
721 5.2.6 Working with values
723 Values are typically part of a property, although they can exist on
724 their own. You can manipulate them either as part of the property
727 The most common way to work with values to is to manipulate them from
728 they properties that contain them. This involves fewer routine calls
729 and intermediate variables than working with them independently, and
732 For each property, there are a _get_ and a _set_ routine that access
733 the internal value. For instanace, for the UID property, the routines
736 void icalproperty_set_uid(icalproperty* prop, const char* v)
738 const char* icalproperty_get_uid(icalproperty* prop)
740 For multi-valued properties, like ATTACH, the value type is usually
741 a struct or union that holds both possible types.
743 If you want to work with the underlying value object, you can get and
746 icalvalue* icalproperty_get_value (icalproperty* prop)
748 void icalproperty_set_value(icalproperty* prop, icalvalue* value);
750 Icalproperty_get_value() will return a reference that you can manipulate
751 with other icalvalue routines. Most of the time, you will have to
752 know what the type of the value is. For instance, if you know that
753 the value is a DATETIME type, you can manipulate it with:
755 struct icaltimetype icalvalue_get_datetime(icalvalue* value);
757 void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v);
759 When working with an extension property or value (and X-PROPERTY or
760 a property that has the parameter VALUE=x-name ) the value type is
761 always a string. To get and set the value, use:
763 void icalproperty_set_x(icalproperty* prop, char* v);
765 char* icalproperty_get_x(icalproperty* prop);
767 All X properties have the type of ICAL_X_PROPERTY, so you will need
768 these routines to get and set the name of the property:
770 char* icalproperty_get_x_name(icalproperty* prop)
772 void icalproperty_set_x_name(icalproperty* prop, char* name);
774 5.2.7 Checking Component Validity
776 RFC 2446 defines rules for what properties must exist in a component
777 to be used for transferring scheduling data. Most of these rules relate
778 to the existence of properties relative to the METHOD property, which
779 declares what operation a remote receiver should use to process a
780 component. For instance, if the METHOD is REQUEST and the component
781 is a VEVENT, the sender is probably asking the receiver to join in
782 a meeting. In this case, RFC2446 says that the component must specify
783 a start time (DTSTART) and list the receiver as an attendee (ATTENDEE).
785 Libical can check these restrictions with the routine:
787 int icalrestriction_check(icalcomponent* comp);
789 This routine returns 0 if the component does not pass RFC2446 restrictions,
790 or if the component is malformed. The component you pass in must be
791 a VCALENDAR, with one or more children, like the examples in RFC2446.
793 When this routine runs, it will insert new properties into the component
794 to indicate any errors it finds. See section 6.5.3, X-LIC-ERROR for
795 more information about these error properties.
797 5.2.8 Converting Components to Text
799 To create an RFC2445 compliant text representation of an object, use
800 one of the *_as_ical_string() routines:
802 char* icalcomponent_as_ical_string (icalcomponent* component)
804 char* icalproperty_as_ical_string (icalproperty* property)
806 char* icalparameter_as_ical_string (icalparameter* parameter)
808 char* icalvalue_as_ical_string (icalvalue* value)
810 In most cases, you will only use icalcomponent_as_ical_string (), since
811 it will cascade and convert all of the parameters, properties and
812 values that are attached to the root component.
814 Icalproperty_as_ical_string() will terminate each line with the RFC2445
815 specified line terminator "\\n" However, if you compile with the symbol
816 ICAL_UNIX_NEWLINE undefined, ( it is defined by default) it will terminate
819 Remember that the string returned by these routines is owned by the
820 library, and will eventually be re-written. You should copy it if
821 you want to preserve it.
827 LIbical defines it's own time structure for storing all dates and times.
828 It would have been nice to re-use the C library's struct tm, but that
829 structure does not differentiate between dates and times, and between
830 local time and UTC. The libical structure is:
832 struct icaltimetype {
846 int is_utc; /* 1-> time is in UTC timezone */
848 int is_date; /* 1 -> interpret this as date. */ };
850 The year, month, day, hour, minute and second fields hold the broken-out
851 time values. The is_utc field distinguishes between times in UTC and
852 a local time zone. The is_date field indicates if the time should
853 be interpreted only as a date. If it is a date, the hour, minute and
854 second fields are assumed to be zero, regardless of their actual vaules.
856 5.3.2 Creating time structures
858 There are several ways to create a new icaltimetype structure:
860 struct icaltimetype icaltime_from_string(const char* str);
862 struct icaltimetype icaltime_from_timet(time_t v, int is_date);
864 struct icaltimetype icaltime_from_int(int v, int is_date, int is_utc);
866 Icaltime_from_string takes any RFC2445 compliant time string:
868 struct icaltimetype tt = icaltime_from_string("19970101T103000");
870 Icaltime_from_timet takes a timet value, representing seconds past
871 the POSIX epoch, and a flag to indicate if the time is a date. Dates
872 have an identical structure to a time, but the time portion ( hours,
873 minuts and seconds ) is always 00:00:00. Dates act differently in
874 sorting an comparision, and they have a different string representation
877 The icaltime_from_int is like icaltime_from_timet, but with an arbitrary
878 epoch. This routine was a mistake and is deprecated.
880 5.3.3 Time manipulating routines
882 The null time value is used to indicate that the data in the structure
885 struct icaltimetype icaltime_null_time(void);
887 int icaltime_is_null_time(struct icaltimetype t);
889 It is sensible for the broken-out time fields to contain values that
890 are not permitted in an ISO compliant time string. For instance, the
891 seconds field can hold values greater than 59, and the hours field
892 can hold values larger than 24. The excessive values will be rolled
893 over into the next larger field when the structure is normalized.
895 struct icaltimetype icaltime_normalize(struct icaltimetype t);
897 Normalizing allows you to do arithmetic operations on time values.
899 struct icaltimetype tt = icaltime_from_string("19970101T103000");
905 tt = icaltime_normalize(tt);
907 There are several routines to get the day of the week or month, etc,
908 from a time structure.
910 short icaltime_day_of_year(struct icaltimetype t);
912 struct icaltimetype icaltime_from_day_of_year(short doy, short year);
914 short icaltime_day_of_week(struct icaltimetype t);
916 short icaltime_start_doy_of_week(struct icaltimetype t);
918 short icaltime_week_number(short day_of_month, short month, short year);
920 struct icaltimetype icaltime_from_week_number(short week_number, short
923 short icaltime_days_in_month(short month,short year);
925 Two routines convert time structures to and from the number of seconds
926 since the POSIX epoch. The is_date field indicates whether or not
927 the hour, minute and second fields should be used in the conversion.
929 struct icaltimetype icaltime_from_timet(time_t v, int is_date);
931 time_t icaltime_as_timet(struct icaltimetype);
933 The compare routine works exactly like strcmp, but on time structures.
935 int icaltime_compare(struct icaltimetype a,struct icaltimetype b);
937 The following routines convert between UTC and a named timezone. The
938 tzid field must be a timezone name from the Olsen database, such as
939 "America/Los_Angeles."
941 The utc_offset routine returns the offset of the named time zone from
944 The tt parameter in the following routines indicates the date on which
945 the conversion should be made. The tt parameter is necessary because
946 timezones have many different rules for when daylight savings time
947 is used, and these rules can change over time. So, for a single timezone
948 one year may have daylight savings time on March 15, but for other
949 years March 15 may be standard time, and some years may have standard
952 int icaltime_utc_offset(struct icaltimetype tt, char* tzid);
954 int icaltime_local_utc_offset();
956 struct icaltimetype icaltime_as_utc(struct icaltimetype tt,char* tzid);
958 struct icaltimetype icaltime_as_zone(struct icaltimetype tt,char* tzid);
960 struct icaltimetype icaltime_as_local(struct icaltimetype tt);
964 The libical distribution includes a separate library, libicalss, that
965 allows you to store iCal component data to disk in a variety of ways.
967 The file storage routines are organized in an inheritance heirarchy
968 that is rooted in icalset, with the derived class icalfileset and
969 icaldirset. Icalfileset stores components to a file, while icaldirset
970 stores components to multiple files, one per month based on DTSTAMP.
971 Other storages classess, for storage to a heap or a mysql database
972 for example, could be added in the future.
974 All of the icalset derived classes have the same interface:
976 icaldirset* icaldirset_new(const char* path);
978 void icaldirset_free(icaldirset* store);
980 const char* icaldirset_path(icaldirset* store);
982 void icaldirset_mark(icaldirset* store);
984 icalerrorenum icaldirset_commit(icaldirset* store);
986 icalerrorenum icaldirset_add_component(icaldirset* store, icalcomponent*
989 icalerrorenum icaldirset_remove_component(icaldirset* store, icalcomponent*
992 int icaldirset_count_components(icaldirset* store, icalcomponent_kind
995 icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge);
997 void icaldirset_clear(icaldirset* store);
999 icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid);
1001 int icaldirset_has_uid(icaldirset* store, const char* uid);
1003 icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent
1006 icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *oldc,
1007 icalcomponent *newc);
1009 icalcomponent* icaldirset_get_current_component(icaldirset* store);
1011 icalcomponent* icaldirset_get_first_component(icaldirset* store);
1013 icalcomponent* icaldirset_get_next_component(icaldirset* store);
1015 5.4.1 Creating a new set
1017 You can create a new set from either the base class or the direved
1018 class. From the base class use one of:
1020 icalset* icalset_new_file(const char* path);
1022 icalset* icalset_new_dir(const char* path);
1024 icalset* icalset_new_heap(void);
1026 icalset* icalset_new_mysql(const char* path);
1028 You can also create a new set based on the derived class, For instance,
1031 icalfileset* icalfileset_new(const char* path);
1033 icalfileset* icalfileset_new_open(const char* path, int flags, mode_t
1036 icalset_new_file is identical to icalfileset_new. Both routines will
1037 open an existing file for readinga and writing, or create a new file
1038 if it does not exist. Icalfilset_new_open takes the same arguments
1039 as the open() system routine and behaves in the same way.
1041 The icalset and icalfilset objects are somewhat interchangable -- you
1042 can use an icalfileset* as an argument to any of the icalset routines.
1044 The following examples will all use icalfileset routines; using the
1045 other icalset derived classess will be similar.
1047 5.4.2 Adding, Finding and Removing Components
1049 To add components to a set, use:
1051 icalerrorenum icalfileset_add_component(icalfileset* cluster, icalcomponent*
1054 The fileset keeps an inmemory copy of the components, and this set
1055 must be written back to the file ocassionally. There are two routines
1058 void icalfileset_mark(icalfileset* cluster);
1060 icalerrorenum icalfileset_commit(icalfileset* cluster);
1062 icalfileset_mark indicates that the in-memory components have changed.
1063 Calling the _add_component routine will call _mark automatically,
1064 but you may need to call it yourself if you have made a change to
1065 an existing component. The _commit routine writes the data base to
1066 disk, but only if it is marked. The _commit routine is called automatically
1067 when the icalfileset is freed.
1069 To iterate through the components in a set, use:
1071 icalcomponent* icalfileset_get_first_component(icalfileset* cluster);
1073 icalcomponent* icalfileset_get_next_component(icalfileset* cluster);
1075 icalcomponent* icalfileset_get_current_component (icalfileset* cluster);
1077 These routines work like the corresponding routines from icalcomponent,
1078 except that their output is filtered through a gauge. A gauge is a
1079 test for the properties within a components; only components that
1080 pass the test are returned. A gauge can be constructed from a MINSQL
1083 icalgauge* icalgauge_new_from_sql(char* sql);
1085 Then, you can add the gauge to the set with :
1087 icalerrorenum icalfileset_select(icalfileset* store, icalgauge* gauge);
1089 Here is an example that puts all of these routines together:
1101 char *path = "test_fileset.ics";
1103 icalgauge *g = icalgauge_new_from_sql(
1105 "SELECT * FROM VEVENT WHERE DTSTART > '20000103T120000Z' AND
1106 DTSTART <= '20000106T120000Z'");
1110 fs = icalfileset_new(path);
1114 for (i = 0; i!= 10; i++){
1116 c = make_component(i); /* Make a new component where DTSTART
1119 icalfileset_add_component(fs,c);
1123 icalfileset_commit(fs); /* Write to disk */
1125 icalfileset_select(fs,g); /* Set the gauge to filter components
1130 for (c = icalfileset_get_first_component(fs);
1134 c = icalfileset_get_next_component(fs)){
1136 struct icaltimetype t = icalcomponent_get_dtstart(c);
1140 printf("%s\n",icaltime_as_ctime(t));
1144 icalfileset_free(fs);
1148 5.4.3 Other routines
1150 There are several other routines in the icalset interface, but they
1151 not fully implemented yet.
1153 5.5 Memory Management
1155 Libical relies heavily on dynamic allocation for both the core objects
1156 and for the strings used to hold values. Some of this memory the library
1157 caller owns and must free, and some of the memory is managed by the
1158 library. Here is a summary of the memory rules.
1160 1) If the function name has "new" in it, the caller gets control
1161 of the memory. ( such as icalcomponent_new(), or icalproperty_new_clone()
1164 2) If you got the memory from a routine with new in it, you must
1165 call the corresponding *_free routine to free the memory. ( Use
1166 icalcomponent_free() to free objects created with icalcomponent_new())
1168 3) If the function name has "add" in it, the caller is transferring
1169 control of the memory to the routine. ( icalproperty_add_parameter() )
1171 4) If the function name has "remove" in it, the caller passes in
1172 a pointer to an object and after the call returns, the caller owns
1173 the object. So, before you call icalcomponent_remove_property(comp,foo),
1174 you do not own "foo" and after the call returns, you do.
1176 5) If the routine returns a string and its name does NOT end in "_r",
1177 libical owns the memory and will put it on a ring buffer to reclaim
1178 later. For example, icalcomponent_as_ical_string(). You'd better
1179 strdup() it if you want to keep it, and you don't have to delete it.
1181 6) If the routine returns a string and its name *does* end in "_r", the
1182 caller gets control of the memory and is responsible for freeing it.
1183 For example, icalcomponent_as_ical_string_r() does the same thing as
1184 icalcomponent_as_ical_string(), except you now have control of the
1185 string buffer it returns.
1189 Libical has several error handling mechanisms for the various types
1190 of programming, semantic and syntactic errors you may encounter.
1194 Many library routines signal errors through their return values. All
1195 routines that return a pointer, such as icalcomponent_new(), will
1196 return 0 ( zero ) on a fatal error. Some routines will return a value
1197 of enum icalerrorenum.
1201 Most routines will set the global error value icalerrno on errors.
1202 This variable is an enumeration; permissible values can be found in
1203 libical/icalerror.h. If the routine returns an enum icalerrorenum,
1204 then the return value will be the same as icalerrno. You can use icalerror_strerror()
1205 to get a string that describes the error. The enumerations are:
1207 * ICAL_BADARG_ERROR -- One of the argument to a routine was bad. Typically
1210 * ICAL_NEWFAILED_ERROR -- A new() or malloc() failed
1212 * ICAL_MALFORMEDDATA_ERROR -- An input string was not in the correct
1215 * ICAL_PARSE_ERROR -- The parser failed to parse an incomming component
1217 * ICAL_INTERNAL_ERROR -- Largely equivalent to an assert
1219 * ICAL_FILE_ERROR -- A file operation failed. Check errno for more
1222 * ICAL_ALLOCATION_ERROR -- ?
1224 * ICAL_USAGE_ERROR -- ?
1226 * ICAL_NO_ERROR -- No error
1228 * ICAL_MULTIPLEINCLUSION_ERROR -- ?
1230 * ICAL_TIMEDOUT_ERROR -- For CSTP and acquiring locks
1232 * ICAL_UNKNOWN_ERROR -- ?
1234 5.6.3 X-LIC-ERROR and X-LIC-INVALID-COMPONENT
1236 The library handles semantic and syntactic errors in components by
1237 inserting errors properties into the components. If the parser cannot
1238 parse incoming text ( a syntactic error ) or if the icalrestriction_check()
1239 routine indicates that the component does not meet the requirements
1240 of RFC2446 ( a semantic error) the library will insert properties
1241 of the type X-LIC-ERROR to describe the error. Here is an example
1242 of the error property:
1244 X-LIC-ERROR;X-LIC-ERRORTYPE=INVALID_ITIP :Failed iTIP restrictions
1245 for property DTSTART.
1247 Expected 1 instances of the property and got 0
1249 This error resulted from a call to icalrestriction_check(), which discovered
1250 that the component does not have a DTSTART property, as required by
1253 There are a few routines to manipulate error properties:
1255 [ The following data is supposed to be in a table. It looks OK in LyX,
1256 but does not format propertly in output. ]
1258 +-------------------------------------+---------------------------------------------------------+
1259 | Routine | Purpose |
1260 +-------------------------------------+---------------------------------------------------------+
1261 | void icalrestriction_check() | Check a component against RFC2446 and insert |
1262 +-------------------------------------+---------------------------------------------------------+
1263 | | error properties to indicate non compliance |
1264 +-------------------------------------+---------------------------------------------------------+
1265 | int icalcomponent_count_errors() | Return the number of error properties |
1266 +-------------------------------------+---------------------------------------------------------+
1267 | | in a component |
1268 +-------------------------------------+---------------------------------------------------------+
1269 | void icalcomponent_strip_errors() | Remove all error properties in as |
1270 +-------------------------------------+---------------------------------------------------------+
1272 +-------------------------------------+---------------------------------------------------------+
1273 | void icalcomponent_convert_errors() | Convert some error properties into |
1274 +-------------------------------------+---------------------------------------------------------+
1275 | | REQUESTS-STATUS proprties to indicate the inability to |
1276 +-------------------------------------+---------------------------------------------------------+
1277 | | process the component as an iTIP request. |
1278 +-------------------------------------+---------------------------------------------------------+
1281 The types of errors are listed in icalerror.h. They are:
1283 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR
1285 ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR
1287 ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR
1289 ICAL_XLICERRORTYPE_PROPERTYPARSEERROR
1291 ICAL_XLICERRORTYPE_VALUEPARSEERROR
1293 ICAL_XLICERRORTYPE_UNKVCALPROP
1295 ICAL_XLICERRORTYPE_INVALIDITIP
1297 The libical parser will generate the error that end in PARSEERROR when
1298 it encounters garbage in the input steam. ICAL_XLICERRORTYPE_INVALIDITIP
1299 is inserted by icalrestriction_check(), and ICAL_XLICERRORTYPE_UNKVCALPROP
1300 is generated by icalvcal_convert() when it encounters a vCal property
1301 that it cannot convert or does not know about.
1303 Icalcomponent_convert_errors() converts some of the error properties
1304 in a component into REQUEST-STATUS properties that indicate a failure.
1305 As of libical version0.18, this routine only convert *PARSEERROR errors
1306 and it always generates a 3.x ( failure ) code. This makes it more
1307 of a good idea than a really useful bit of code.
1309 5.6.4 ICAL_ERRORS_ARE_FATAL and icalerror_errors_are_fatal
1311 If the global variable icalerror_errors_are_fatal is set to 1, then
1312 any error condition will cause the program to abort. The abort occurs
1313 in icalerror_set_errno(), and is done with an assert(0) if NDEBUG
1314 is undefined, and with icalerror_crash_here if NDEBUG is defined.
1315 The default value of icalerror_errors_are_fatal is 1 when ICAL_ERRORS_ARE_FATAL
1316 is defined, and 0 otherwise. Since ICAL_ERRORS_ARE_FATAL is defined
1317 by default, icalerror_errors_are_fatal is also defined by default.
1321 Structures that you access with the "struct" keyword, such as "struct
1322 icaltimetype" are things that you are allowed to see inside and poke
1325 Structures that you access though a typedef, such as "icalcomponent"
1326 are things where all of the data is hidden.
1328 Component names that start with "V" are part of RFC 2445 or another
1329 iCal standard. Component names that start with "X" are also part of
1330 the spec, but they are not actually components in the spec. However,
1331 they look and act like components, so they are components in libical.
1332 Names that start with "XLIC" or "X-LIC" are not part of any iCal spec.
1333 They are used internally by libical.
1335 Enums that identify a component, property, value or parameter end with
1336 "_COMPONENT," "_PROPERTY," "_VALUE," or "_PARAMETER"s
1338 Enums that identify a parameter value have the name of the parameter
1339 as the second word. For instance: ICAL_ROLE_REQPARTICIPANT or ICAL_PARTSTAT_ACCEPTED.
1341 The enums for the parts of a recurarance rule and request statuses
1346 There are a lot of hacks in the library -- bits of code that I am not
1347 proud of and should probably be changed. These are marked with the
1348 comment string "HACK."
1352 7.1 Manipulating struct icaltimetype
1354 7.1.1 Struct icaltimetype