From bfcf094375e705d7d21128d652ccde58cfe825d0 Mon Sep 17 00:00:00 2001 From: nobody Date: Sat, 4 Aug 2001 19:29:35 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'GNUMERIC_0_69'. svn path=/tags/GNUMERIC_0_69/; revision=11675 --- libical/doc/UsingLibical.lyx | 2578 ------------------------------------------ 1 file changed, 2578 deletions(-) delete mode 100644 libical/doc/UsingLibical.lyx (limited to 'libical/doc/UsingLibical.lyx') diff --git a/libical/doc/UsingLibical.lyx b/libical/doc/UsingLibical.lyx deleted file mode 100644 index cef199bea5..0000000000 --- a/libical/doc/UsingLibical.lyx +++ /dev/null @@ -1,2578 +0,0 @@ -#LyX 1.1 created this file. For more info see http://www.lyx.org/ -\lyxformat 2.16 -\textclass article -\language default -\inputencoding latin1 -\fontscheme default -\graphics default -\paperfontsize default -\spacing single -\papersize Default -\paperpackage a4 -\use_geometry 0 -\use_amsmath 0 -\paperorientation portrait -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation indent -\defskip medskip -\quotes_language english -\quotes_times 2 -\papercolumns 1 -\papersides 1 -\paperpagestyle default - -\layout Title - -Using Libical -\layout Author - -Eric Busboom (eric@softwarestudio.org) -\layout Date - -January 2001 -\layout Standard - - -\begin_inset LatexCommand \tableofcontents{} - -\end_inset - - -\layout Section - -Introduction -\layout Standard - -Libical is an Open Source implementation of the iCalendar protocols and - protocol data units. - The iCalendar specification describes how calendar clients can communicate - with calendar servers so users can store their calendar data and arrange - meetings with other users. - -\layout Standard - -Libical implements RFC2445, RFC2446 and some of RFC2447 and the CAP draft. - -\layout Standard - -This documentation assumes that you are familiar with the iCalendar standards - RFC2445 and RFC2446. - these specifications are online on the CALSCH webpage at: -\layout LyX-Code - -http://www.imc.org/ietf-calendar/ -\layout Subsection - -The libical project -\layout Standard - -This code is under active development. - If you would like to contribute to the project, you can contact me, Eric - Busboom, at eric@softwarestudio.org. - The project has a webpage at -\layout LyX-Code - -http://softwarestudio.org/libical/index.html -\layout Standard - -and a mailing list that you can join by sending the following mail: -\layout LyX-Code - -To: minimalist@softwarestudio.org -\layout LyX-Code - -Subject: subscribe libical -\layout Subsection - -License -\layout Standard - -The code and datafiles in this distribution are licensed under the Mozilla - Public License. - See http://www.mozilla.org/NPL/MPL-1.0.html for a copy of the license. - Alternately, you may use libical under the terms of the GNU Library General - Public License. - See http://www.fsf.org/copyleft/lesser.html for a copy of the LGPL. -\layout Standard - -This dual license ensures that the library can be incorporated into both - proprietary code and GPL'd programs, and will benefit from improvements - made by programmers in both realms. - I will only accept changes into my version of the library if they are similarly - dual-licensed. -\layout Subsection - -Example Code -\layout Standard - -A lot of the documentation for this library is in the form of example code. - These examples are in the -\begin_inset Quotes eld -\end_inset - -examples -\begin_inset Quotes erd -\end_inset - - directory of the distribution. - Also look in -\begin_inset Quotes eld -\end_inset - -src/test -\begin_inset Quotes erd -\end_inset - - for additional annotated examples. - -\layout Section - -Building nas Installing the Library -\layout Standard - -Libical uses autoconf to generate makefiles. - It should built with no adjustments on Linux, FreeBSD and Solaris under - gcc. - Some version have been successfully been build on MacOS, Solaris, UnixWare, - And Tru64 UNIX without gcc, but you may run into problems with a particular - later version. - -\layout Standard - -For a more complete guide to building the library, see the README file in - the distribution. - -\layout Standard - - -\begin_inset Quotes eld -\end_inset - -make install -\begin_inset Quotes erd -\end_inset - - will install the libraries and header files for three modules: libical, - libicalss. - and libicalvcal. - If you build shared objects, then these files will be installed: -\layout Itemize - -ical.h -\layout Itemize - -libical.a -\layout Itemize - -libical.so -\layout Itemize - -icalss.h -\layout Itemize - -libicalss.a -\layout Itemize - -libicalss.so -\layout Itemize - -icalvcal.h -\layout Itemize - -libicalvcal.a -\layout Itemize - -libicalvcal.so -\layout Standard - -The header files ical.h and icalss.h are combined header files, generated - by concatenating together all of the header files in src/libical and src/libica -lss respectively. - -\layout Section - -Structure -\layout Standard - -The iCal calendar model is based on four types of objects: components, propertie -s, values and parameters. - -\layout Standard - -Properties are the fundamental unit of information in iCal, and they work - a bit like a hash entry, with a constant key and a variable value. - Properties may also have modifiers, called parameters. - In the iCal content line -\layout LyX-Code - -ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com -\layout Standard - -The property name is -\begin_inset Quotes eld -\end_inset - -ORGANIZER, -\begin_inset Quotes erd -\end_inset - - the value of the property is -\begin_inset Quotes eld -\end_inset - -mrbig@host.com -\begin_inset Quotes erd -\end_inset - - and the -\begin_inset Quotes eld -\end_inset - -ROLE -\begin_inset Quotes erd -\end_inset - - parameter specifies that Mr Big is the chair of the meetings associated - with this property. - -\layout Standard - -Components are groups of properties that represent the core objects of a - calendar system, such as events or timezones. - Components are delimited by -\begin_inset Quotes eld -\end_inset - -BEGIN -\begin_inset Quotes erd -\end_inset - - and -\begin_inset Quotes eld -\end_inset - -END -\begin_inset Quotes erd -\end_inset - - tags. - -\layout Standard -\added_space_bottom 0.3cm -When a component is sent across a network, if it is un-encrypted, it will - look something like: -\layout LyX-Code - -BEGIN:VCALENDAR -\layout LyX-Code - -METHOD:REQUEST -\layout LyX-Code - -PRODID: -//hacksw/handcal//NONSGML v1.0//EN -\layout LyX-Code - -BEGIN:VEVENT -\layout LyX-Code - -DTSTAMP:19980309T231000Z -\layout LyX-Code - -UID:guid-1.host1.com -\layout LyX-Code - -ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com -\layout LyX-Code - -ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP: -\layout LyX-Code - - MAILTO:employee-A@host.com -\layout LyX-Code - -DESCRIPTION:Project XYZ Review Meeting -\layout LyX-Code - -CATEGORIES:MEETING -\layout LyX-Code - -CLASS:PUBLIC -\layout LyX-Code - -CREATED:19980309T130000Z -\layout LyX-Code - -SUMMARY:XYZ Project Review -\layout LyX-Code - -DTSTART;TZID=US-Eastern:19980312T083000 -\layout LyX-Code - -DTEND;TZID=US-Eastern:19980312T093000 -\layout LyX-Code - -LOCATION:1CP Conference Room 4350 -\layout LyX-Code - -END:VEVENT -\layout LyX-Code - -END:VCALENDAR -\layout Standard - -Note that components can be nested; this example has both a VCALENDAR and - a VEVENT component, one nested inside the other. - -\layout Standard - -The main goal of Libical is to offer a structured, type-safe to create, - access and manipulate components and their properties, values and parameters. - -\layout Subsection - -Core iCal classes -\layout Standard - -Libical is an object-based, data-oriented library. - There are no real-objects, but the way the routines are named and organized - results in the same sort of encapsulations and abstraction that are major - features of Object-Orieted languages. - Nearly all of the routines in the library are associated with an opaque - data types and perform some operation on that data type. - For instnace, a Property is declared as: -\layout LyX-Code - -icalproperty *prop; -\layout Standard - -Icalproperty is typedef'd to void, so the only way to manipulate it is through - the accessor routines, all of which have a form similar to: -\layout LyX-Code - -char* icalproperty_as_ical_string(icalproperty* prop); -\layout Standard - -That is, the name of the 'class' is the first word in the routine name, - and the first parameter is a pointer to the 'object.' -\layout Standard - -Although the library does not actually have classes, we will use those terms - since the behavior of these associations of data and routines is very similar - to a class. - -\layout Subsubsection - -Properties -\layout LyX-Code - -icalproperty *prop; -\layout Standard - -Properties are represented with the icalproperty class and its many -\begin_inset Quotes eld -\end_inset - -derived -\begin_inset Quotes erd -\end_inset - - classes with on -\begin_inset Quotes eld -\end_inset - -derived -\begin_inset Quotes erd -\end_inset - - class per property type in RFC2445. - Again, there is no actual inheritance relations, but there are clusters - of routines that make this term useful. - A property is a container for a single value and a set of parameters. - -\layout Subsubsection - -Components -\layout LyX-Code - -icalcomponent *comp; -\layout Standard - -In libical, components are represented with the icalcomponent class. - Icalcomponent is a container for a set of other components and properties. -\layout Subsubsection - -Values -\layout LyX-Code - -icalvalue *value; -\layout Standard - -Values are represented in a similar way to properties; a base class and - many -\begin_inset Quotes eld -\end_inset - -derived -\begin_inset Quotes eld -\end_inset - - classes. - A value is essentially a abstract handle on a single fundamental type, - a structure or a union. - You probably will never use a value directly, since for most operations - you can get to its data through the property that holds it. - -\layout Subsubsection - -Parameters -\layout LyX-Code - -icalparameter *param; -\layout Standard - -Parameters are represetned in a similar way to properties, except that they - contain only one value -\layout Subsection - -Other elements of libical -\layout Standard - -In addition to the core iCal classes, libical has many other types, structures, - classes that aid in creating and using iCal components. - -\layout Subsubsection - -Enumerations and types -\layout Standard - -Libical is strongly typed, so every component, property, parameter, and - value type has an enumeration, and some have an associated structure or - union. - -\layout Subsubsection - -The parser -\layout Standard - -The libical parser offers a variety of ways to convert RFC2445 text into - a libical iinsteral component structure. - the parser can parse blocks of text as a string, or it can parse lin-by-line. -\layout Subsubsection - -Error objects -\layout Standard - -Libical has a substantial error reporting system for both programming errors - and component usage errors. - -\layout Subsubsection - -Memory Management -\layout Standard - -Since many of libicals interfaces return strings, the library has its own - memory management system to elimiate the need to free every string returned - from the libraru. - -\layout Subsubsection - -Storage classes -\layout Standard - -The library also offers several classes to store components to flies, memory - or databases. - -\layout Section - -Differences From RFCs -\layout Standard - -Libical has been designed to follow the standards as closely as possible, - so that the key objects in the standards are also key objects in the library. - However, there are a few areas where the specifications are (arguably) - irregular, and following them exactly would result in an unfriendly interface. - These deviations make libical easier to use by maintaining a self-similar - interface. - -\layout Subsection - -Pseudo Components -\layout Standard - -Libical defines components for groups of properties that look and act like - components, but are not defined as components in the specification. - XDAYLIGHT and XSTANDARD are notable examples. - These pseudo components group properties within the VTIMEZONE components. - For instanace, the timezone properties associated with daylight savings - time starts with -\begin_inset Quotes eld -\end_inset - -BEGIN:DAYLIGHT -\begin_inset Quotes erd -\end_inset - - and ends with -\begin_inset Quotes eld -\end_inset - -END:DAYLIGHT, just like other components, but is not defined as a component - in RFC2445. - ( See RFC2445, page 61 ) In Libical,this grouping is represented by the - XDAYLIGHT component. - Standard iCAL components all start with the letter -\begin_inset Quotes eld -\end_inset - -V, -\begin_inset Quotes erd -\end_inset - - while pseudo components start with -\begin_inset Quotes erd -\end_inset - -X. -\begin_inset Quotes erd -\end_inset - - -\layout Standard - -There are also pseudo components that are conceptually derived classes of - VALARM. - RFC2446 defines what properties may be included in each component, and - for VALARM, the set of properties it may have depends on the value of the - ACTION property. - -\layout Standard - -For instance, if a VALARM component has an ACTION property with the value - of -\begin_inset Quotes eld -\end_inset - -AUDIO, -\begin_inset Quotes erd -\end_inset - - the component must also have an -\begin_inset Quotes eld -\end_inset - -ATTACH -\begin_inset Quotes erd -\end_inset - - property. - However, if the ACTION value is -\begin_inset Quotes eld -\end_inset - -DISPLAY, -\begin_inset Quotes erd -\end_inset - - the component must have a DESCRIPTION property. - -\layout Standard - -To handle these various, complex restrictions, libical has pseudo components - for each type of alarm: XAUDIOALARM, XDISPLAYALARM, XEMAILALARM and XPROCEDUREA -LARM. - -\layout Subsection - -Combined Values -\layout Standard - -Many values can take more than one type. - TRIGGER, for instance, can have a value type of with DURATION or of DATE-TIME. - These multiple types make it difficult to create routines to return the - value associated with a property. - -\layout Standard - -It is natural to have interfaces that would return the value of a property, - but it is cumbersome for a single routine to return multiple types. - So, in libical, properties that can have multiple types are given a single - type that is the union of their RFC2445 types. - For instance, in libical, the value of the TRIGGER property resolves to - struct icaltriggertype. - This type is a union of a DURATION and a DATE-TIME. - -\layout Subsection - -Multi-Valued Properties -\layout Standard - -Some properties, such as CATEGORIES have only one value type, but each CATEGORIE -S property can have multiple value instances. - This also results in a cumbersome interface -- CATEGORIES accessors would - have to return a list while all other accessors returned a single value. - In libical, all properties have a single value, and multi-valued properties - are broken down into multiple single valued properties during parsing. - That is, an input line like, -\layout LyX-Code - -CATEGORIES: work, home -\layout Standard - -becomes in libical's internal representation -\layout LyX-Code - -CATEGORIES: work -\layout LyX-Code - -CATEGORIES: home -\layout Standard - -Oddly, RFC2445 allows some multi-valued properties ( like FREEBUSY ) to - exist as both a multi-values property and as multiple single value properties, - while others ( like CATEGORIES ) can only exist as single multi-valued - properties. - This makes the internal representation for CATEGORIES illegal. - However when you convert a component to a string, the library will collect - all of the CATEGORIES properties into one. - -\layout Section - -Using libical -\layout Subsection - -Creating Components -\layout Standard - -There are three ways to create components in Libical: -\layout Itemize - -Create individual components, properties and parameters and assemble them - into structures -\layout Itemize - -Build complete components with nested vaargs calls -\layout Itemize - -Parse bits of text -\layout Itemize - -Parse entire files -\layout Subsubsection - -Constructor Interfaces -\layout Standard - -Using constructor interfaces, you create each of the objects separately - and then assemble them in to components: -\layout LyX-Code - -icalcomponent *event; -\layout LyX-Code - -icalproperty *prop; -\layout LyX-Code - -icalparameter *param; -\layout LyX-Code - -struct icaltimetype atime; -\layout LyX-Code - -\layout LyX-Code - -event = icalcomponent_new(ICAL_VEVENT_COMPONENT); -\layout LyX-Code - -prop = icalproperty_new_dtstamp(atime); -\layout LyX-Code - -icalcomponent_add_property(event, prop); -\layout LyX-Code - -\layout LyX-Code - -prop = icalproperty_new_uid(''guid-1.host1.com'') ); -\layout LyX-Code - -icalcomponent_add_property(event,prop); -\layout LyX-Code - -\layout LyX-Code - -prop=icalproperty_new_organizer(''mrbig@host.com''); -\layout LyX-Code - -param = icalparameter_new_role(ICAL_ROLE_CHAIR) -\layout LyX-Code - -icalproperty_add_parameter(prop, param); -\layout LyX-Code - -\layout LyX-Code - -icalcomponent_add_property(event,prop); -\layout Standard - -Notice that libical uses a semi-object-oriented style of interface. - Most things you work with are objects, that are instantiated with a constructor - that has -\begin_inset Quotes eld -\end_inset - -new -\begin_inset Quotes erd -\end_inset - - in the name. - Also note that, other than the object reference, most structure data is - passed in to libical routines by value. - Libical has some complex but very regular memory handling rules. - These are detailed in section -\begin_inset LatexCommand \ref{sec:memory} - -\end_inset - -. -\layout Standard - -If any of the constructors fail, they will return 0. - If you try to insert 0 into a property or component, or use a zero-valued - object reference, libical will either silently ignore the error or will - abort with an error message. - This behavior is controlled by a compile time flag (ICAL_ERRORS_ARE_FATAL), - and will abort by default. - -\layout Subsubsection - -vaargs Constructors -\layout Standard - -There is another way to create complex components, which is arguably more - elegant, if you are not horrified by varargs. - The varargs constructor interface allows you to create intricate components - in a single block of code. - Here is the previous examples in the vaargs style. - -\layout LyX-Code - - calendar = -\layout LyX-Code - - icalcomponent_vanew( -\layout LyX-Code - - ICAL_VCALENDAR_COMPONENT, -\layout LyX-Code - - icalproperty_new_version(''2.0''), -\layout LyX-Code - - icalproperty_new_prodid( -\layout LyX-Code - - ''-//RDU Software//NONSGML HandCal//EN''), -\layout LyX-Code - - icalcomponent_vanew( -\layout LyX-Code - - ICAL_VEVENT_COMPONENT, -\layout LyX-Code - - icalproperty_new_dtstamp(atime), -\layout LyX-Code - - icalproperty_new_uid(''guid-1.host1.com''), -\layout LyX-Code - - icalproperty_vanew_organizer( -\layout LyX-Code - - ''mrbig@host.com''), -\layout LyX-Code - - icalparameter_new_role(ICAL_ROLE_CHAIR), -\layout LyX-Code - - 0 -\layout LyX-Code - - ), -\layout LyX-Code - - icalproperty_vanew_attendee( -\layout LyX-Code - - ''employee-A@host.com'', -\layout LyX-Code - - icalparameter_new_role( -\layout LyX-Code - - ICAL_ROLE_REQPARTICIPANT), -\layout LyX-Code - - icalparameter_new_rsvp(1), -\layout LyX-Code - - icalparameter_new_cutype(ICAL_CUTYPE_GROUP), -\layout LyX-Code - - 0 -\layout LyX-Code - - ), -\layout LyX-Code - - icalproperty_new_location( -\layout LyX-Code - - "1CP Conference Room 4350"), -\layout LyX-Code - - 0 -\layout LyX-Code - - ), -\layout LyX-Code - - 0 -\layout LyX-Code - - ); -\layout Standard - -This form is similar to the constructor form , except that the constructors - have -\begin_inset Quotes eld -\end_inset - -vanew -\begin_inset Quotes erd -\end_inset - - instead of -\begin_inset Quotes eld -\end_inset - -new -\begin_inset Quotes erd -\end_inset - - in the name. - The arguments are similar too, except that the component constructor can - have a list of properties, and the property constructor can have a list - of parameters. - Be sure to terminate every list with a '0', or your code will crash, if - you are lucky. - -\layout Subsubsection - -Parsing Text -\layout Standard - -Several routines are available for generating objects from text. - For properties, use: -\layout LyX-Code - -icalproperty* p; -\layout LyX-Code - -p = icalproperty_new_from_string("DTSTART:19970101T120000Z -\backslash -n"); -\layout Standard - -For parameters, use: -\layout LyX-Code - -icalparameter *param -\layout LyX-Code - -param = icalparameter_new_from_string("PARTSTAT=ACCEPTED"); -\layout Standard - -The final way to create components will probably be the most common; you - can create components from RFC2445 compliant text. - If you have the string in memory, use -\layout LyX-Code - -icalcomponent* icalcomponent_new_from_string(char* str); -\layout Standard - -If the string contains only one component, the routine will return the component - in libical form. - If the string contains multiple components, the multiple components will - be returned as the children of an ICAL_XROOT_COMPONENT component. - This routine is identical to ( and actually uses ) icalparser_parse_string(char -* str). -\layout Standard - -Parsing a whole string may seem wasteful if you want to pull a large component - off of the network or from a file; you may prefer to parse the component - line by line. - This is possible too by using: -\layout LyX-Code - -icalparser* icalparser_new(); -\layout LyX-Code - -void icalparser_free(icalparser* parser); -\layout LyX-Code - -icalparser_get_line(parser,read_stream); -\layout LyX-Code - -icalparser_add_line(parser,line); -\layout LyX-Code - -icalparser_set_gen_data(parser,stream) -\layout Standard - -These routines will construct a parser object to which you can add lines - of input and retrieve any components that the parser creates from the input. - These routines work by specifing an adaptor routine to get string data - from a source. - For an example: -\layout LyX-Code - -char* read_stream(char *s, size_t size, void *d) -\layout LyX-Code - -{ -\layout LyX-Code - - char *c = fgets(s,size, (FILE*)d); -\layout LyX-Code - - return c; -\layout LyX-Code - -} -\layout LyX-Code - -main() { -\layout LyX-Code - - char* line; -\layout LyX-Code - - icalcomponent *c; -\layout LyX-Code - - icalparser *parser = icalparser_new(); -\layout LyX-Code - - FILE* stream = fopen(argv[1],"r"); -\layout LyX-Code - - icalparser_set_gen_data(parser,stream); -\layout LyX-Code - - do{ -\layout LyX-Code - - line = icalparser_get_line(parser,read_stream); -\layout LyX-Code - - c = icalparser_add_line(parser,line); -\layout LyX-Code - - if (c != 0){ -\layout LyX-Code - - printf("%s",icalcomponent_as_ical_string(c)); -\layout LyX-Code - - icalparser_claim(parser); -\layout LyX-Code - - printf(" -\backslash -n--------------- -\backslash -n"); -\layout LyX-Code - - icalcomponent_free(c); -\layout LyX-Code - - } -\layout LyX-Code - - } while ( line != 0); -\layout LyX-Code - -} -\layout Standard - -The parser object parameterizes the routine used to get input lines with - icalparser_set_gen_data() and -\emph on - -\emph default -icalparser_get_line(). - In this example, the routine read_stream() will fetch the next line from - a stream, with the stream passed in as the void* parameter d. - The parser calls read_stream() from icalparser_get_line(), but it also - needs to know what stream to use. - This is set by the call to icalparser_set_gen_data(). - By using a different routine for read_stream or passing in different data - with icalparser_set_gen_data, you can connect to any data source. - -\layout Standard - -Using the same mechanism, other implementations could read from memory buffers, - sockets or other interfaces. - -\layout Standard - -Since the example code is a very common way to use the parser, there is - a convenience routine; -\layout LyX-Code - -icalcomponent* icalparser_parse(icalparser *parser, -\layout LyX-Code - - char* (*line_gen_func)(char *s, size_t size, void* d)) -\layout Standard - -To use this routine, you still must construct the parser object and pass - in a reference to a line reading routine. - If the parser can create a single component from the input, it will return - a pointer to the newly constructed component. - If the parser can construct multiple components from the input, it will - return a reference to an XROOT component ( of type ICAL_XROOT_COMPONENT.) - This XROOT component will hold all of the components constructed from the - input as children. - -\layout Subsection - -Accessing Components -\layout Standard - -Given a reference to a component, you probably will want to access the propertie -s, parameters and values inside. - Libical interfaces let you find sub-components, add and remove sub-components, - and do the same three operations on properties. - -\layout Subsubsection - -Finding Components -\layout Standard - -To find a sub-component of a component, use: -\layout LyX-Code - -icalcomponent* icalcomponent_get_first_component( -\layout LyX-Code - - icalcomponent* component, -\layout LyX-Code - - icalcomponent_kind kind); -\layout Standard - -This routine will return a reference to the first component of the type - 'kind.' The key kind values, listed in icalenums.h are: -\layout LyX-Code - -ICAL_ANY_COMPONENT -\layout LyX-Code - -ICAL_VEVENT_COMPONENT -\layout LyX-Code - -ICAL_VTODO_COMPONENT -\layout LyX-Code - -ICAL_VJOURNAL_COMPONENT -\layout LyX-Code - -ICAL_VCALENDAR_COMPONENT -\layout LyX-Code - -ICAL_VFREEBUSY_COMPONENT -\layout LyX-Code - -ICAL_VALARM_COMPONENT -\layout Standard - -These are only the most common components; there are many more listed in - icalenums.h. -\layout Standard - -As you might guess, if there is more than one subcomponent of the type you - have chosen, this routine will return only the first. - to get at the others, you need to iterate through the component. - -\layout Subsubsection - -Iterating Through Components -\layout Standard - -Iteration requires a second routine to get the next subcomponent after the - first: -\layout LyX-Code - -icalcomponent* icalcomponent_get_next_component( -\layout LyX-Code - - icalcomponent* component, -\layout LyX-Code - - icalcomponent_kind kind); -\layout Standard - -With the 'first' and 'next' routines, you can create a for loop to iterate - through all of a components subcomponents -\layout LyX-Code - - for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); -\layout LyX-Code - - c != 0; -\layout LyX-Code - - c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)) -\layout LyX-Code - -{ -\layout LyX-Code - - do_something(c); -\layout LyX-Code - -} -\layout Standard - -This code bit wil iterate through all of the subcomponents in 'comp' but - you can select a specific type of component by changing ICAL_ANY_COMPONENT - to another component type. -\layout Subsubsection - -Using Component Iterators -\layout Standard - -The iteration model in the previous section requires the component to keep - the state of the iteration. - So, you could not use this model to perform a sorting operations, since - you'd need two iterators and there is only space for one. - If you ever call icalcomponent_get_first_component() when an iteration - is in progress, the pointer will be reset to the beginning. - -\layout Standard - -To solve this problem, there are also external iterators for components. - The routines associated with these external iterators are: -\layout LyX-Code - -icalcompiter icalcomponent_begin_component(icalcomponent* component, icalcompone -nt_kind kind); -\layout LyX-Code - -icalcompiter icalcomponent_end_component(icalcomponent* component, icalcomponent -_kind kind); -\layout LyX-Code - -icalcomponent* icalcompiter_next(icalcompiter* i); -\layout LyX-Code - -icalcomponent* icalcompiter_prior(icalcompiter* i); -\layout LyX-Code - -icalcomponent* icalcompiter_deref(icalcompiter* i); -\layout Standard - -The _begin_() and _end_() routines return a new iterator that points to - the beginning and ending of the list of subcomponent for the given component, - and the kind argument works like the kind argument for internal iterators. - -\layout Standard - -After creating an iterators, use _next_() and _prior_() to step forward - and backward through the list and get the component that the iterator points - to, and use _deref() to return the component that the iterator points to - without moving the iterator. - All routines will return 0 when they move to point off the end of the list. - -\layout Standard - -Here is an example of a loop using these routines: -\layout LyX-Code - -for( -\layout LyX-Code - - i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); - -\layout LyX-Code - - icalcompiter_deref(&i)!= 0; -\layout LyX-Code - - icalcompiter_next(&i) -\layout LyX-Code - -) { -\layout LyX-Code - - icalcomponent *this = icalcompiter_deref(&i); -\layout LyX-Code - -} -\layout Subsubsection - -Removing Components -\layout Standard - -Removing an element from a list while iterating through the list with the - internal iterators can cause problems, since you will probably be removing - the element that the internal iterator points to. - The _remove() routine will keep the iterator valid by moving it to the - next component, but in a normal loop, this will result in two advances - per iteration, and you will remove only every other component. - To avoid the problem, you will need to step the iterator ahead of the - element you are going to remove, like this: -\layout LyX-Code - -for(c = icalcomponent_get_first_component(parent_comp,ICAL_ANY_COMPONENT); - -\layout LyX-Code - - c != 0; -\layout LyX-Code - - c = next -\layout LyX-Code - -{ -\layout LyX-Code - - next = icalcomponent_get_next_component(parent_comp,ICAL_ANY_COMPONENT); -\layout LyX-Code - - icalcomponent_remove_component(parent_comp,c); -\layout LyX-Code - -} -\layout Standard - -Another way to remove components is to rely on the side effect of icalcomponent_ -remove_component: if component iterator in the parent component is pointing - to the child that will be removed, it will move the iterator to the component - after the child. - The following code will exploit this behavior: -\layout LyX-Code - -icalcomponent_get_first_component(parent_comp,ICAL_VEVENT_COMPONENT); -\layout LyX-Code - -while((c=icalcomponent_get_current_component(c)) != 0 ){ -\layout LyX-Code - - if(icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT){ -\layout LyX-Code - - icalcomponent_remove_component(parent_comp,inner); -\layout LyX-Code - - } else { -\layout LyX-Code - - icalcomponent_get_next_component(parent_comp,ICAL_VEVENT_COMPONENT); - -\layout LyX-Code - - } -\layout LyX-Code - -} -\layout Subsubsection - -Working with properties and parameters -\layout Standard - -Finding, iterating and removing properties works the same as it does for - components, using the property-specific or parameter-specific interfaces: - -\layout LyX-Code - -icalproperty* icalcomponent_get_first_property( -\layout LyX-Code - - icalcomponent* component, -\layout LyX-Code - - icalproperty_kind kind); -\layout LyX-Code - -icalproperty* icalcomponent_get_next_property( -\layout LyX-Code - - icalcomponent* component, -\layout LyX-Code - - icalproperty_kind kind); -\layout LyX-Code - -void icalcomponent_add_property( -\layout LyX-Code - - icalcomponent* component, -\layout LyX-Code - - icalproperty* property); -\layout LyX-Code - -void icalcomponent_remove_property( -\layout LyX-Code - - icalcomponent* component, -\layout LyX-Code - - icalproperty* property); -\layout Standard - -For parameters: -\layout LyX-Code - -icalparameter* icalproperty_get_first_parameter( -\layout LyX-Code - - icalproperty* prop, -\layout LyX-Code - - icalparameter_kind kind); -\layout LyX-Code - -icalparameter* icalproperty_get_next_parameter( -\layout LyX-Code - - icalproperty* prop, -\layout LyX-Code - - icalparameter_kind kind); -\layout LyX-Code - -void icalproperty_add_parameter( -\layout LyX-Code - - icalproperty* prop, -\layout LyX-Code - - icalparameter* parameter); -\layout LyX-Code - -void icalproperty_remove_parameter( -\layout LyX-Code - - icalproperty* prop, -\layout LyX-Code - - icalparameter_kind kind); -\layout Standard - -Note that since there should be only one parameter of each type in a property, - you will rarely need to use icalparameter_get_nect_paameter. -\layout Subsubsection - -Working with values -\layout Standard - -Values are typically part of a property, although they can exist on their - own. - You can manipulate them either as part of the property or independently. -\layout Standard - -The most common way to work with values to is to manipulate them from they - properties that contain them. - This involves fewer routine calls and intermediate variables than working - with them independently, and it is type-safe. - -\layout Standard - -For each property, there are a _get_ and a _set_ routine that access the - internal value. - For instanace, for the UID property, the routines are: -\layout LyX-Code - -void icalproperty_set_uid(icalproperty* prop, const char* v) -\layout LyX-Code - -const char* icalproperty_get_uid(icalproperty* prop) -\layout Standard - -For multi-valued properties, like ATTACH, the value type is usually a struct - or union that holds both possible types. - -\layout Standard - -If you want to work with the underlying value object, you can get and set - it with: -\layout LyX-Code - -icalvalue* icalproperty_get_value (icalproperty* prop) -\layout LyX-Code - -void icalproperty_set_value(icalproperty* prop, icalvalue* value); -\layout Standard - -Icalproperty_get_value() will return a reference that you can manipulate - with other icalvalue routines. - Most of the time, you will have to know what the type of the value is. - For instance, if you know that the value is a DATETIME type, you can manipulate - it with: -\layout LyX-Code - -struct icaltimetype icalvalue_get_datetime(icalvalue* value); -\layout LyX-Code - -void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v); -\layout Standard - -When working with an extension property or value (and X-PROPERTY or a property - that has the parameter VALUE=x-name ) the value type is always a string. - To get and set the value, use: -\layout LyX-Code - -void icalproperty_set_x(icalproperty* prop, char* v); -\layout LyX-Code - -char* icalproperty_get_x(icalproperty* prop); -\layout Standard - -All X properties have the type of ICAL_X_PROPERTY, so you will need these - routines to get and set the name of the property: -\layout LyX-Code - -char* icalproperty_get_x_name(icalproperty* prop) -\layout LyX-Code - -void icalproperty_set_x_name(icalproperty* prop, char* name); -\layout Subsubsection - -Checking Component Validity -\layout Standard - -RFC 2446 defines rules for what properties must exist in a component to - be used for transferring scheduling data. - Most of these rules relate to the existence of properties relative to the - METHOD property, which declares what operation a remote receiver should - use to process a component. - For instance, if the METHOD is REQUEST and the component is a VEVENT, the - sender is probably asking the receiver to join in a meeting. - In this case, RFC2446 says that the component must specify a start time - (DTSTART) and list the receiver as an attendee (ATTENDEE). - -\layout Standard - -Libical can check these restrictions with the routine: -\layout LyX-Code - -int icalrestriction_check(icalcomponent* comp); -\layout Standard - -This routine returns 0 if the component does not pass RFC2446 restrictions, - or if the component is malformed. - The component you pass in -\emph on -must -\emph default - be a VCALENDAR, with one or more children, like the examples in RFC2446. - -\layout Standard - -When this routine runs, it will insert new properties into the component - to indicate any errors it finds. - See section 6.5.3, X-LIC-ERROR for more information about these error properties. - -\layout Subsubsection - -Converting Components to Text -\layout Standard - -To create an RFC2445 compliant text representation of an object, use one - of the *_as_ical_string() routines: -\layout LyX-Code - -char* icalcomponent_as_ical_string (icalcomponent* component) -\layout LyX-Code - -char* icalproperty_as_ical_string (icalproperty* property) -\layout LyX-Code - -char* icalparameter_as_ical_string (icalparameter* parameter) -\layout LyX-Code - -char* icalvalue_as_ical_string (icalvalue* value) -\layout Standard - -In most cases, you will only use icalcomponent_as_ical_string (), since - it will cascade and convert all of the parameters, properties and values - that are attached to the root component. -\layout Standard - -Icalproperty_as_ical_string() will terminate each line with the RFC2445 - specified line terminator -\begin_inset Quotes eld -\end_inset - - -\backslash - -\backslash -n -\begin_inset Quotes erd -\end_inset - - However, if you compile with the symbol ICAL_UNIX_NEWLINE undefined, ( - it is defined by default) it will terminate lines with -\begin_inset Quotes eld -\end_inset - - -\backslash - -\backslash -n -\backslash - -\backslash -r -\begin_inset Quotes erd -\end_inset - - -\layout Standard - -Remember that the string returned by these routines is owned by the library, - and will eventually be re-written. - You should copy it if you want to preserve it. - -\layout Subsection - -Time -\layout Subsubsection - -Time structure -\layout Standard - -LIbical defines it's own time structure for storing all dates and times. - It would have been nice to re-use the C library's -\emph on -struct tm, -\emph default -but that structure does not differentiate between dates and times, and between - local time and UTC. - The libical structure is: -\layout LyX-Code - -struct icaltimetype { -\layout LyX-Code - - int year; -\layout LyX-Code - - int month; -\layout LyX-Code - - int day; -\layout LyX-Code - - int hour; -\layout LyX-Code - - int minute; -\layout LyX-Code - - int second; -\layout LyX-Code - - int is_utc; /* 1-> time is in UTC timezone */ -\layout LyX-Code - - int is_date; /* 1 -> interpret this as date. - */ }; -\layout Standard - -The year, month, day, hour, minute and second fields hold the broken-out - time values. - The is_utc field distinguishes between times in UTC and a local time zone. - The is_date field indicates if the time should be interpreted only as a - date. - If it is a date, the hour, minute and second fields are assumed to be zero, - regardless of their actual vaules. - -\layout Subsubsection - -Creating time structures -\layout Standard - -There are several ways to create a new icaltimetype structure: -\layout LyX-Code - -struct icaltimetype icaltime_from_string(const char* str); -\layout LyX-Code - -struct icaltimetype icaltime_from_timet(time_t v, int is_date); -\layout LyX-Code - -\layout Standard - -Icaltime_from_string takes any RFC2445 compliant time string: -\layout LyX-Code - -struct icaltimetype tt = icaltime_from_string("19970101T103000"); -\layout Standard - -Icaltime_from_timet takes a timet value, representing seconds past the POSIX - epoch, and a flag to indicate if the time is a date. - Dates have an identical structure to a time, but the time portion ( hours, - minuts and seconds ) is always 00:00:00. - Dates act differently in sorting an comparision, and they have a different - string representation in RFC2445. - -\layout Subsubsection - -Time manipulating routines -\layout Standard - -The null time value is used to indicate that the data in the structure is - not a valid time. -\layout LyX-Code - -struct icaltimetype icaltime_null_time(void); -\layout LyX-Code - -int icaltime_is_null_time(struct icaltimetype t); -\layout Standard - -It is sensible for the broken-out time fields to contain values that are - not permitted in an ISO compliant time string. - For instance, the seconds field can hold values greater than 59, and the - hours field can hold values larger than 24. - The excessive values will be rolled over into the next larger field when - the structure is normalized. - -\layout LyX-Code - -struct icaltimetype icaltime_normalize(struct icaltimetype t); -\layout Standard - -Normalizing allows you to do arithmetic operations on time values. - -\layout LyX-Code - -struct icaltimetype tt = icaltime_from_string( -\begin_inset Quotes eld -\end_inset - -19970101T103000 -\begin_inset Quotes erd -\end_inset - -); -\layout LyX-Code - -tt.days +=3 -\layout LyX-Code - -tt.second += 70; -\layout LyX-Code - -tt = icaltime_normalize(tt); -\layout Standard - -There are several routines to get the day of the week or month, etc, from - a time structure. -\layout LyX-Code - -short icaltime_day_of_year(struct icaltimetype t); -\layout LyX-Code - -struct icaltimetype icaltime_from_day_of_year(short doy, short year); -\layout LyX-Code - -short icaltime_day_of_week(struct icaltimetype t); -\layout LyX-Code - -short icaltime_start_doy_of_week(struct icaltimetype t); -\layout LyX-Code - -short icaltime_week_number(short day_of_month, short month, short year); -\layout LyX-Code - -struct icaltimetype icaltime_from_week_number(short week_number, short year); -\layout LyX-Code - -short icaltime_days_in_month(short month,short year); -\layout Standard - -Two routines convert time structures to and from the number of seconds since - the POSIX epoch. - The is_date field indicates whether or not the hour, minute and second - fields should be used in the conversion. -\layout LyX-Code - -struct icaltimetype icaltime_from_timet(time_t v, int is_date); -\layout LyX-Code - -time_t icaltime_as_timet(struct icaltimetype); -\layout Standard - -The compare routine works exactly like strcmp, but on time structures. - -\layout LyX-Code - -int icaltime_compare(struct icaltimetype a,struct icaltimetype b); -\layout Standard - -The following routines convert between UTC and a named timezone. - The tzid field must be a timezone name from the Olsen database, such as - -\begin_inset Quotes eld -\end_inset - -America/Los_Angeles. -\begin_inset Quotes erd -\end_inset - - -\layout Standard - -The utc_offset routine returns the offset of the named time zone from UTC, - in seconds. - -\layout Standard - -The tt parameter in the following routines indicates the date on which the - conversion should be made. - The tt parameter is necessary because timezones have many different rules - for when daylight savings time is used, and these rules can change over - time. - So, for a single timezone one year may have daylight savings time on March - 15, but for other years March 15 may be standard time, and some years may - have standard time all year. - -\layout LyX-Code - -int icaltime_utc_offset(struct icaltimetype tt, char* tzid); -\layout LyX-Code - -int icaltime_local_utc_offset(); -\layout LyX-Code - -struct icaltimetype icaltime_as_utc(struct icaltimetype tt,char* tzid); -\layout LyX-Code - -struct icaltimetype icaltime_as_zone(struct icaltimetype tt,char* tzid); -\layout LyX-Code - -struct icaltimetype icaltime_as_local(struct icaltimetype tt); -\layout Subsection - -Storing Objects -\layout Standard - -The libical distribution includes a separate library, libicalss, that allows - you to store iCal component data to disk in a variety of ways. - This library also includes code to implement the CSTP protocol of CAP and - has some routines for deciphering incomming messages. - -\layout Standard - -The file storage routines are organized in an inheritance heirarchy that - is rooted in icalset, with the derived class icalfileset and icaldirset. - Icalfileset stores components to a file, while icaldirset stores components - to multiple files, one per month based on DTSTAMP. - Other storages classess, for storage to a heap or a mysql database are - planned for the future. - -\layout Standard - -All of the icalset derived classes have the same interface: -\layout LyX-Code - -\layout LyX-Code - -icaldirset* icaldirset_new(const char* path); -\layout LyX-Code - -void icaldirset_free(icaldirset* store); -\layout LyX-Code - -const char* icaldirset_path(icaldirset* store); -\layout LyX-Code - -void icaldirset_mark(icaldirset* store); -\layout LyX-Code - -icalerrorenum icaldirset_commit(icaldirset* store); -\layout LyX-Code - -icalerrorenum icaldirset_add_component(icaldirset* store, icalcomponent* - comp); -\layout LyX-Code - -icalerrorenum icaldirset_remove_component(icaldirset* store, icalcomponent* - comp); -\layout LyX-Code - -int icaldirset_count_components(icaldirset* store, icalcomponent_kind kind); -\layout LyX-Code - -icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge); -\layout LyX-Code - -void icaldirset_clear(icaldirset* store); -\layout LyX-Code - -icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid); -\layout LyX-Code - -int icaldirset_has_uid(icaldirset* store, const char* uid); -\layout LyX-Code - -icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent *c); -\layout LyX-Code - -icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *oldc, - icalcomponent *newc); -\layout LyX-Code - -icalcomponent* icaldirset_get_current_component(icaldirset* store); -\layout LyX-Code - -icalcomponent* icaldirset_get_first_component(icaldirset* store); -\layout LyX-Code - -icalcomponent* icaldirset_get_next_component(icaldirset* store); -\layout Subsubsection - -Creating a new set -\layout Standard - -You can create a new set from either the base class or the direved class. - From the base class use one of: -\layout LyX-Code - -icalset* icalset_new_file(const char* path); -\layout LyX-Code - -icalset* icalset_new_dir(const char* path); -\layout LyX-Code - -icalset* icalset_new_heap(void); -\layout LyX-Code - -icalset* icalset_new_mysql(const char* path); -\layout Standard - -You can also create a new set based on the derived class, For instance, - with icalfileset: -\layout LyX-Code - -icalfileset* icalfileset_new(const char* path); -\layout LyX-Code - -icalfileset* icalfileset_new_open(const char* path, int flags, mode_t mode); -\layout Standard - -Icaset_new_file is identical to icalfileset_new. - BOth routines will open an existing file for readinga and writing, or create - a new file if it does not exist. - Icalfilset_new_open takes the same arguments as the open() system routine - and behaves in the same way. - -\layout Standard - -The icalset and icalfilset objects are somewhat interchangable -- you can - use an icalfileset* as an argument to any of the icalset routines. -\layout Standard - -The following examples will all use icalfileset routines; using the other - icalset derived classess will be similar. - -\layout Subsubsection - -Adding, Finding and Removing Components -\layout Standard - -To add components to a set, use: -\layout LyX-Code - -icalerrorenum icalfileset_add_component(icalfileset* cluster, icalcomponent* - child); -\layout Standard - -The fileset keeps an inmemory copy of the components, and this set must - be written back to the file ocassionally. - There are two routines to manage this: -\layout LyX-Code - -void icalfileset_mark(icalfileset* cluster); -\layout LyX-Code - -icalerrorenum icalfileset_commit(icalfileset* cluster); -\layout Standard - -Icalfileset_mark indicates that the in-memory components have changed. - Calling the _add_component routine will call _mark automatically, but you - may need to call it yourself if you have made a change to an existing component. - The _commit routine writes the data base to disk, but only if it is marked. - The _commit routine is called automatically when the icalfileset is freed. - -\layout Standard - -To iterate through the components in a set, use: -\layout LyX-Code - -icalcomponent* icalfileset_get_first_component(icalfileset* cluster); -\layout LyX-Code - -icalcomponent* icalfileset_get_next_component(icalfileset* cluster); -\layout LyX-Code - -icalcomponent* icalfileset_get_current_component (icalfileset* cluster); - -\layout Standard - -These routines work like the corresponding routines from icalcomponent, - except that their output is filtered through a gauge. - A gauge is a test for the properties within a components; only components - that pass the test are returned. - A gauge can be constructed from a MINSQL string with: -\layout LyX-Code - -icalgauge* icalgauge_new_from_sql(char* sql); -\layout Standard - -Then, you can add the gauge to the set with : -\layout LyX-Code - -icalerrorenum icalfileset_select(icalfileset* store, icalgauge* gauge); -\layout Standard - -Here is an example that puts all of these routines together: -\layout LyX-Code - - -\latex no_latex -void test_fileset() -\layout LyX-Code - - -\latex no_latex -{ -\layout LyX-Code - - -\latex no_latex - icalfileset *fs; -\layout LyX-Code - - -\latex no_latex - icalcomponent *c; -\layout LyX-Code - - -\latex no_latex - int i; -\layout LyX-Code - - -\latex no_latex - char *path = "test_fileset.ics"; -\layout LyX-Code - - -\latex no_latex - icalgauge *g = icalgauge_new_from_sql( -\layout LyX-Code - - -\latex no_latex - "SELECT * FROM VEVENT WHERE DTSTART > '20000103T120000Z' AND DTSTART - <= '20000106T120000Z'"); -\layout LyX-Code - - -\latex no_latex - -\layout LyX-Code - - -\latex no_latex -fs = icalfileset_new(path); -\layout LyX-Code - - -\layout LyX-Code - - -\latex no_latex -for (i = 0; i!= 10; i++){ -\layout LyX-Code - - -\latex no_latex - c = make_component(i); -\latex default - /* Make a new component where DTSTART has month of i */ -\layout LyX-Code - - -\latex no_latex - icalfileset_add_component(fs,c); -\layout LyX-Code - - -\latex no_latex - } -\layout LyX-Code - -\layout LyX-Code - - -\latex no_latex - icalfileset_commit(fs); -\latex default - /* Write to disk */ -\layout LyX-Code - -\layout LyX-Code - - -\latex no_latex - icalfileset_select(fs,g); -\latex default - /* Set the gauge to filter components */ -\layout LyX-Code - - -\latex no_latex - -\layout LyX-Code - - -\latex no_latex - for (c = icalfileset_get_first_component(fs); -\layout LyX-Code - - -\latex no_latex - c != 0; -\layout LyX-Code - - -\latex no_latex - c = icalfileset_get_next_component(fs)){ -\layout LyX-Code - - -\latex no_latex - struct icaltimetype t = icalcomponent_get_dtstart(c); -\layout LyX-Code - - -\latex no_latex - -\layout LyX-Code - - -\latex no_latex - printf("%s -\backslash -n",icaltime_as_ctime(t)); -\layout LyX-Code - - -\latex no_latex - } -\layout LyX-Code - - -\latex no_latex -icalfileset_free(fs); -\layout LyX-Code - - -\latex no_latex -} -\layout Subsubsection - -Other routines -\layout Standard - -There are several other routines in the icalset interface, but they not - fully implemented yet. - -\layout Subsection - - -\begin_inset LatexCommand \label{sec:memory} - -\end_inset - -Memory Management -\layout Standard - -Libical relies heavily on dynamic allocation for both the core objects and - for the strings used to hold values. - Some of this memory the library caller owns and must free, and some of - the memory is managed by the library. - Here is a summary of the memory rules. - -\layout Description - -1) If the function name has "new" in it, the caller gets control of the - memory. - ( such as icalcomponent_new(), or icalproperty_new_clone() ) -\layout Description - -2) If you got the memory from a routine with new in it, you must call the - corresponding *_free routine to free the memory. - ( Use icalcomponent_free() to free objects created with icalcomponent_new()) - -\layout Description - -3) If the function name has "add" in it, the caller is transferring control - of the memory to the routine. - ( icalproperty_add_parameter() ) -\layout Description - -4) If the function name has "remove" in it, the caller passes in a pointer - to an object and after the call returns, the caller owns the object. - So, before you call icalcomponent_remove_property(comp,foo), you do not - own "foo" and after the call returns, you do. - -\layout Description - -5) If the routine returns a string, libical owns the memory and will put - it on a ring buffer to reclaim later. - For example, icalcomponent_as_ical_string(). - You'd better strdup() it if you want to keep it, and you don't have to - delete it. - -\layout Subsection - -Error Handling -\layout Standard - -Libical has several error handling mechanisms for the various types of programmi -ng, semantic and syntactic errors you may encounter. -\layout Subsubsection - -Return values -\layout Standard - -Many library routines signal errors through their return values. - All routines that return a pointer, such as icalcomponent_new(), will return - 0 ( zero ) on a fatal error. - Some routines will return a value of enum icalerrorenum. - -\layout Subsubsection - -icalerrno -\layout Standard - -Most routines will set the global error value icalerrno on errors. - This variable is an enumeration; permissible values can be found in libical/ica -lerror.h. - If the routine returns an enum icalerrorenum, then the return value will - be the same as icalerrno. - You can use icalerror_strerror() to get a string that describes the error. - The enumerations are: -\layout Standard -\added_space_top 0.3cm \added_space_bottom 0.3cm \align center \LyXTable -multicol5 -12 2 0 0 -1 -1 -1 -1 -1 1 0 0 -1 0 0 0 -1 0 0 0 -1 0 0 0 -1 0 0 0 -1 0 0 0 -1 0 0 0 -1 0 0 0 -1 0 0 0 -1 0 0 0 -1 0 0 0 -1 1 0 0 -2 1 0 "" "" -2 1 1 "" "" -0 8 1 0 0 0 0 "" "" -0 8 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" - - -\newline - -\newline -ICAL_BADARG_ERROR -\newline -One of the argument to a routine was bad. - Typically for a null pointer. -\newline -ICAL_NEWFAILED_ERROR -\newline -A new() or malloc() failed -\newline -ICAL_MALFORMEDDATA_ERROR -\newline -An input string was not in the correct format -\newline -ICAL_PARSE_ERROR -\newline -the parser failed to parse an incomming component -\newline -ICAL_INTERNAL_ERROR -\newline -Largely equivalent to an assert; it indicates a bug in the libical code -\newline -ICAL_FILE_ERROR -\newline -A file operation failed. - Check errno for more detai -\newline -ICAL_ALLOCATION_ERROR -\newline - -\newline -ICAL_NO_ERROR -\newline -No error has occured -\newline -ICAL_TIMEDOUT_ERROR -\newline -Failed to acquire a lock on a file, or the CSTP protocol timed out. - -\newline -ICAL_MULTIPLEINCLUSION_ERROR -\newline - -\newline -ICAL_UNKNOWN_ERROR -\newline - -\layout Subsubsection - -X-LIC-ERROR and X-LIC-INVALID-COMPONENT -\layout Standard - -The library handles semantic and syntactic errors in components by inserting - errors properties into the components. - If the parser cannot parse incoming text ( a syntactic error ) or if the - icalrestriction_check() routine indicates that the component does not meet - the requirements of RFC2446 ( a semantic error) the library will insert - properties of the type X-LIC-ERROR to describe the error. - Here is an example of the error property: -\layout LyX-Code - -X-LIC-ERROR;X-LIC-ERRORTYPE=INVALID_ITIP :Failed iTIP restrictions for property - DTSTART. - -\layout LyX-Code - -Expected 1 instances of the property and got 0 -\layout Standard - -This error resulted from a call to icalrestriction_check(), which discovered - that the component does not have a DTSTART property, as required by RFC2445. - -\layout Standard - -There are a few routines to manipulate error properties: -\layout Standard -\LyXTable -multicol5 -10 2 0 0 -1 -1 -1 -1 -1 1 0 0 -0 0 0 0 -0 1 1 0 -0 0 0 0 -0 1 1 0 -0 1 0 0 -0 1 1 0 -0 1 0 0 -0 1 1 0 -0 1 1 0 -2 1 1 "" "" -2 1 1 "3in" "" -0 2 1 1 0 0 0 "" "" -0 8 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 1 0 1 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 1 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 1 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 1 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 1 1 0 1 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 1 1 0 1 "" "" -0 2 1 0 0 0 0 "" "" -0 2 1 1 0 0 1 "" "" - -Routine -\newline -Purpose -\newline -void icalrestriction_check() -\newline -Check a component against RFC2446 and insert -\newline - -\newline -error properties to indicate non compliance -\newline -int icalcomponent_count_errors() -\newline -Return the number of error properties -\newline - -\newline -in a component -\newline -void icalcomponent_strip_errors() -\newline -Remove all error properties in as -\newline - -\newline -component -\newline -void icalcomponent_convert_errors() -\newline -Convert some error properties into -\newline - -\newline -REQUESTS-STATUS proprties to indicate the inability to -\newline - -\newline -process the component as an iTIP request. - -\layout Standard - -The types of errors are listed in icalerror.h. - They are: -\layout LyX-Code - -ICAL_XLICERRORTYPE_COMPONENTPARSEERROR -\layout LyX-Code - -ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR -\layout LyX-Code - -ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR -\layout LyX-Code - -ICAL_XLICERRORTYPE_PROPERTYPARSEERROR -\layout LyX-Code - -ICAL_XLICERRORTYPE_VALUEPARSEERROR -\layout LyX-Code - -ICAL_XLICERRORTYPE_UNKVCALPROP -\layout LyX-Code - -ICAL_XLICERRORTYPE_INVALIDITIP -\layout Standard - -The libical parser will generate the error that end in PARSEERROR when it - encounters garbage in the input steam. - ICAL_XLICERRORTYPE_INVALIDITIP is inserted by icalrestriction_check(), - and ICAL_XLICERRORTYPE_UNKVCALPROP is generated by icalvcal_convert() when - it encounters a vCal property that it cannot convert or does not know about. - -\layout Standard - -Icalcomponent_convert_errors() converts some of the error properties in - a component into REQUEST-STATUS properties that indicate a failure. - As of libical version0.18, this routine only convert *PARSEERROR errors - and it always generates a 3.x ( failure ) code. - This makes it more of a good idea than a really useful bit of code. - -\layout Subsubsection - -ICAL_ERRORS_ARE_FATAL and icalerror_errors_are_fatal -\layout Standard - -If the global variable icalerror_errors_are_fatal is set to 1, then any - error condition will cause the program to abort. - The abort occurs in icalerror_set_errno(), and is done with an assert(0) - if NDEBUG is undefined, and with icalerror_crash_here if NDEBUG is defined. - The default value of icalerror_errors_are_fatal is 1 when ICAL_ERRORS_ARE_FATAL - is defined, and 0 otherwise. - Since ICAL_ERRORS_ARE_FATAL is defined by default, icalerror_errors_are_fatal - is also defined by default. - -\layout Subsection - -Naming Standard -\layout Standard - -Structures that you access with the -\begin_inset Quotes eld -\end_inset - -struct -\begin_inset Quotes erd -\end_inset - - keyword, such as -\begin_inset Quotes eld -\end_inset - -struct icaltimetype -\begin_inset Quotes erd -\end_inset - - are things that you are allowed to see inside and poke at. - -\layout Standard - -Structures that you access though a typedef, such as -\begin_inset Quotes eld -\end_inset - -icalcomponent -\begin_inset Quotes erd -\end_inset - - are things where all of the data is hidden. - -\layout Standard - -Component names that start with -\begin_inset Quotes eld -\end_inset - -V -\begin_inset Quotes erd -\end_inset - - are part of RFC 2445 or another iCal standard. - Component names that start with -\begin_inset Quotes eld -\end_inset - -X -\begin_inset Quotes erd -\end_inset - - are also part of the spec, but they are not actually components in the - spec. - However, they look and act like components, so they are components in libical. - Names that start with -\begin_inset Quotes eld -\end_inset - -XLIC -\begin_inset Quotes erd -\end_inset - - or -\begin_inset Quotes eld -\end_inset - -X-LIC -\begin_inset Quotes erd -\end_inset - - are not part of any iCal spec. - They are used internally by libical. - -\layout Standard - -Enums that identify a component, property, value or parameter end with -\begin_inset Quotes eld -\end_inset - -_COMPONENT, -\begin_inset Quotes erd -\end_inset - - -\begin_inset Quotes eld -\end_inset - -_PROPERTY, -\begin_inset Quotes erd -\end_inset - - -\begin_inset Quotes eld -\end_inset - -_VALUE, -\begin_inset Quotes erd -\end_inset - - or -\begin_inset Quotes eld -\end_inset - -_PARAMETER -\begin_inset Quotes erd -\end_inset - -s -\layout Standard - -Enums that identify a parameter value have the name of the parameter as - the second word. - For instance: ICAL_ROLE_REQPARTICIPANT or ICAL_PARTSTAT_ACCEPTED. -\layout Standard - -The enums for the parts of a recurarance rule and request statuses are irregular. - -\layout Section - -Hacks and Bugs -\layout Standard - -There are a lot of hacks in the library -- bits of code that I am not proud - of and should probably be changed. - These are marked with the comment string -\begin_inset Quotes eld -\end_inset - -HACK. -\begin_inset Quotes erd -\end_inset - - -\the_end -- cgit v1.2.3