diff options
Diffstat (limited to 'libical/doc/UsingLibical.lyx')
-rw-r--r-- | libical/doc/UsingLibical.lyx | 1849 |
1 files changed, 0 insertions, 1849 deletions
diff --git a/libical/doc/UsingLibical.lyx b/libical/doc/UsingLibical.lyx deleted file mode 100644 index 776f0d3835..0000000000 --- a/libical/doc/UsingLibical.lyx +++ /dev/null @@ -1,1849 +0,0 @@ -#LyX 1.1 created this file. For more info see http://www.lyx.org/ -\lyxformat 2.16 -\textclass linuxdoc -\language default -\inputencoding default -\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 - -November 2000 -\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 for users can store their calendar data and arrange - meetings with other users. - -\layout Standard - -Libical implements RFC2445 and RFC2446. - Eventually, it will also implement iRIP and CAP. - -\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 Verbatim - -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 Verbatim - -http://softwarestudio.org/libical/index.html -\layout Standard - -and a mailing list that you can join by sending the following mail: -\layout Verbatim - -To: minimalist@softwarestudio.org -\layout Verbatim - -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 more annotated examples. - -\layout Section - -Building the Library -\layout Standard - -Libical uses autoconf to generate makefiles, although it uses none of the - autoconf flags to influence the compilation. - It should built with no adjustments on Linux, FreeBSD and Solaris under - gcc. - Some version have been successfully been build on MacOS, Solaris and UnixWare - 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 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 Verbatim - -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. - -\layout Standard - -The central goal of libical is to parse iTIP data into an internal representatio -n of Components, Properties, Parameters an Values, and to allow the user - to manipulate the data in various ways -\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 Verbatim - -BEGIN:VEVENT -\layout Verbatim - -DTSTAMP:19980309T231000Z -\layout Verbatim - -UID:guid-1.host1.com -\layout Verbatim - -ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com -\layout Verbatim - -ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP: -\layout Verbatim - - MAILTO:employee-A@host.com -\layout Verbatim - -DESCRIPTION:Project XYZ Review Meeting -\layout Verbatim - -CATEGORIES:MEETING -\layout Verbatim - -CLASS:PUBLIC -\layout Verbatim - -CREATED:19980309T130000Z -\layout Verbatim - -SUMMARY:XYZ Project Review -\layout Verbatim - -DTSTART;TZID=US-Eastern:19980312T083000 -\layout Verbatim - -DTEND;TZID=US-Eastern:19980312T093000 -\layout Verbatim - -LOCATION:1CP Conference Room 4350 -\layout Verbatim - -END:VEVENT -\layout Subsection - -Core iCal classes -\layout Subsubsection - -Components -\layout Subsubsection - -Properties -\layout Subsubsection - -Values -\layout Subsubsection - -Parameters -\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 -\layout Subsubsection - -Types -\layout Subsubsection - -The parser -\layout Subsubsection - -Restrictions -\layout Subsubsection - -Error objects -\layout Subsubsection - -Memory Management -\layout Subsubsection - -Storage classes -\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 keey 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 classess - 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 cumbersone 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 - -\noun on -struct icaltriggertype -\noun default -. - 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 Verbatim - -CATEGORIES: work, home -\layout Standard - -becomes in libical's internal representation -\layout Verbatim - -CATEGORIES: work -\layout Verbatim - -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 - -Implementation Limitations -\layout Section - -Using libical -\layout Subsection - -Creating Components -\layout Standard - -There are three ways to create components in Libical: creating individual - objects and assembling them, building entire objects in massive vaargs - calls, and parsing a text file containing iCalendar data. - -\layout Subsubsection - -Constructor Interfaces -\layout Standard - -Using constructor interfaces, you create each of the objects seperately - and them assemble them in to components: -\layout Code - -icalcomponent *event; -\layout Code - -icalproperty *prop; -\layout Code - -icalparameter *param; -\layout Code - -struct icaltimetype atime; -\layout Code - -event = icalcomponent_new(ICAL_VEVENT_COMPONENT); -\layout Code - -prop = icalproperty_new_dtstamp(atime) ; -\layout Code - -icalcomponent_add_property(event, prop); -\layout Code - -prop = icalproperty_new_uid("guid-1.host1.com") ); -\layout Code - -icalcomponent_add_property(event,prop); -\layout Code - -prop=icalproperty_new_organizer("mrbig@host.com"); -\layout Code - -param = icalparameter_new_role(ICAL_ROLE_CHAIR) -\layout Code - -icalproperty_add_parameter(prop, param); -\layout Code - -icalcomponent_add_property(event,prop); -\layout Standard - -While we are on this example, you should 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 arguable more - elegant, if you are not horrified by varargs. - The varargs constructor interface all you to create intricate components - in a single block of text. - -\layout Verbatim - - calendar = -\layout Verbatim - - icalcomponent_vanew( -\layout Verbatim - - ICAL_VCALENDAR_COMPONENT, -\layout Verbatim - - icalproperty_new_version("2.0"), -\layout Verbatim - - icalproperty_new_prodid( -\layout Verbatim - - "-//RDU Software//NONSGML HandCal//EN"), -\layout Verbatim - - icalcomponent_vanew( -\layout Verbatim - - ICAL_VEVENT_COMPONENT, -\layout Verbatim - - icalproperty_new_dtstamp(atime), -\layout Verbatim - - icalproperty_new_uid("guid-1.host1.com"), -\layout Verbatim - - icalproperty_vanew_organizer( -\layout Verbatim - - "mrbig@host.com"), -\layout Verbatim - - icalparameter_new_role(ICAL_ROLE_CHAIR), -\layout Verbatim - - 0 -\layout Verbatim - - ), -\layout Verbatim - - icalproperty_vanew_attendee( -\layout Verbatim - - "employee-A@host.com", -\layout Verbatim - - icalparameter_new_role( -\layout Verbatim - - ICAL_ROLE_REQPARTICIPANT), -\layout Verbatim - - icalparameter_new_rsvp(1), -\layout Verbatim - - icalparameter_new_cutype(ICAL_CUTYPE_GROUP), -\layout Verbatim - - 0 -\layout Verbatim - - ), -\layout Verbatim - - icalproperty_new_location( -\layout Verbatim - - "1CP Conference Room 4350"), -\layout Verbatim - - 0 -\layout Verbatim - - ), -\layout Verbatim - - 0 -\layout Verbatim - - ); -\layout Standard - -This form is similar to the regular constructor, except that they 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 contstructor can - have a list of properties, and the property constructor can have a list - or parameters. - Be sure to terminate every list with a '0', or your code will crash, if - you are lucky. - -\layout Subsubsection - -Parsing Text Files -\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 Verbatim - -icalcomponent* icalparser_parse_string(char* str); -\layout Standard - -This may seem wasteful if you want to pull a large component off of the - network; you may prefer to parse the component line by line. - This is possible too by using: -\layout Verbatim - -icalparser* icalparser_new(); -\layout Verbatim - -void icalparser_free(icalparser* parser); -\layout Verbatim - -icalparser_get_line(parser,read_stream); -\layout Verbatim - -icalparser_add_line(parser,line); -\layout Verbatim - -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. - For an example: -\layout Verbatim - -char* read_stream(char *s, size_t size, void *d) -\layout Verbatim - -{ -\layout Verbatim - - char *c = fgets(s,size, (FILE*)d); -\layout Verbatim - - return c; -\layout Verbatim - -} -\layout Verbatim - -main() { -\layout Verbatim - - char* line; -\layout Verbatim - - icalcomponent *c; -\layout Verbatim - - icalparser *parser = icalparser_new(); -\layout Verbatim - - FILE* stream = fopen(argv[1],"r"); -\layout Verbatim - - icalparser_set_gen_data(parser,stream); -\layout Verbatim - - do{ -\layout Verbatim - - line = icalparser_get_line(parser,read_stream); -\layout Verbatim - - c = icalparser_add_line(parser,line); -\layout Verbatim - - if (c != 0){ -\layout Verbatim - - printf("%s",icalcomponent_as_ical_string(c)); -\layout Verbatim - - icalparser_claim(parser); -\layout Verbatim - - printf(" -\backslash -n--------------- -\backslash -n"); -\layout Verbatim - - icalcomponent_free(c); -\layout Verbatim - - } -\layout Verbatim - - } while ( line != 0); -\layout Verbatim - -} -\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(). - -\layout Standard - -Using the same mechanism, other implmentations 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 convienience routine; -\layout Verbatim - -icalcomponent* icalparser_parse(icalparser *parser, -\layout Verbatim - - char* (*line_gen_func)(char *s, size_t sise, 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 cmponents 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. - See section 6.2.2 for how to iterate through the child components. - -\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 interface let you find sub-component, 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 Verbatim - -icalcomponent* icalcomponent_get_first_component( -\layout Verbatim - - icalcomponent* component, -\layout Verbatim - - 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 Verbatim - -ICAL_ANY_COMPONENT -\layout Verbatim - -ICAL_VEVENT_COMPONENT -\layout Verbatim - -ICAL_VTODO_COMPONENT -\layout Verbatim - -ICAL_VJOURNAL_COMPONENT -\layout Verbatim - -ICAL_VCALENDAR_COMPONENT -\layout Verbatim - -ICAL_VFREEBUSY_COMPONENT -\layout Verbatim - -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 - -Interating Through Components -\layout Standard - -Iteration requires a second routine to get the next subcomponent after the - first: -\layout Verbatim - -icalcomponent* icalcomponent_get_next_component( -\layout Verbatim - - icalcomponent* component, -\layout Verbatim - - 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 Verbatim - - for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); -\layout Verbatim - - c != 0; -\layout Verbatim - - c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)) -\layout Verbatim - -{ -\layout Verbatim - - do_something(c); -\layout Verbatim - -} -\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() which 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 Verbatim - -icalcompiter icalcomponent_begin_component(icalcomponent* component, icalcompone -nt_kind kind); -\layout Verbatim - -icalcompiter icalcomponent_end_component(icalcomponent* component, icalcomponent -_kind kind); -\layout Verbatim - -icalcomponent* icalcompiter_next(icalcompiter* i); -\layout Verbatim - -icalcomponent* icalcompiter_prior(icalcompiter* i); -\layout Verbatim - -icalcomponent* icalcompiter_deref(icalcompiter* i); -\layout Standard - -The _begin_() and _end_() routines return a new iterator that points to - the begining 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 Verbatim - -for( -\layout Verbatim - - i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); - -\layout Verbatim - - icalcompiter_deref(&i)!= 0; -\layout Verbatim - - icalcompiter_next(&i) -\layout Verbatim - -) { -\layout Verbatim - - icalcomponent *this = icalcompiter_deref(&i); -\layout Verbatim - -} -\layout Subsubsection - -Removing Components -\layout Standard - -Libical component have internal iterators, so you can only have one iteration - over a component at a time. - Removing an element from a list while iterating through the list 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 Verbatim - -for(c = icalcomponent_get_first_component(parent_comp,ICAL_ANY_COMPONENT); - -\layout Verbatim - - c != 0; -\layout Verbatim - - c = next -\layout Verbatim - -{ -\layout Verbatim - - next = icalcomponent_get_next_component(parent_comp,ICAL_ANY_COMPONENT); -\layout Verbatim - - icalcomponent_remove_component(parent_comp,c); -\layout Verbatim - -} -\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 Verbatim - -icalcomponent_get_first_component(parent_comp,ICAL_VEVENT_COMPONENT); -\layout Verbatim - -while((c=icalcomponent_get_current_component(c)) != 0 ){ -\layout Verbatim - - if(icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT){ -\layout Verbatim - - icalcomponent_remove_component(parent_comp,inner); -\layout Verbatim - - } else { -\layout Verbatim - - icalcomponent_get_next_component(parent_comp,ICAL_VEVENT_COMPONENT); - -\layout Verbatim - - } -\layout Verbatim - -} -\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 Verbatim - -icalproperty* icalcomponent_get_first_property( -\layout Verbatim - - icalcomponent* component, -\layout Verbatim - - icalproperty_kind kind); -\layout Verbatim - -icalproperty* icalcomponent_get_next_property( -\layout Verbatim - - icalcomponent* component, -\layout Verbatim - - icalproperty_kind kind); -\layout Verbatim - -void icalcomponent_add_property( -\layout Verbatim - - icalcomponent* component, -\layout Verbatim - - icalproperty* property); -\layout Verbatim - -void icalcomponent_remove_property( -\layout Verbatim - - icalcomponent* component, -\layout Verbatim - - icalproperty* property); -\layout Verbatim - -icalparameter* icalproperty_get_first_parameter( -\layout Verbatim - - icalproperty* prop, -\layout Verbatim - - icalparameter_kind kind); -\layout Verbatim - -icalparameter* icalproperty_get_next_parameter( -\layout Verbatim - - icalproperty* prop, -\layout Verbatim - - icalparameter_kind kind); -\layout Verbatim - -void icalproperty_add_parameter( -\layout Verbatim - - icalproperty* prop, -\layout Verbatim - - icalparameter* parameter); -\layout Verbatim - -void icalproperty_remove_parameter( -\layout Verbatim - - icalproperty* prop, -\layout Verbatim - - icalparameter_kind kind); -\layout Subsubsection - -Working with values -\layout Standard - -Values are typically part of a property, although they can exist on their - own. - You can maniplulate them either as part of the property or independantly. -\layout Standard - -The most common way to work with values to is to maniplate 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 instnace, for the UID property, the routines are: -\layout Verbatim - -void icalproperty_set_uid(icalproperty* prop, const char* v) -\layout Verbatim - -const char* icalproperty_get_uid(icalproperty* prop) -\layout Standard - -For multivalued 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 Verbatim - -icalvalue* icalproperty_get_value (icalproperty* prop) -\layout Verbatim - -void icalproperty_set_value(icalproperty* prop, icalvalue* value); -\layout Standard - -Icalproperty_get_value() will return a reference that you can manipluate - 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 manipluate - it with: -\layout Verbatim - -struct icaltimetype icalvalue_get_datetime(icalvalue* value); -\layout Verbatim - -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 Verbatim - -void icalproperty_set_x(icalproperty* prop, char* v); -\layout Verbatim - -char* icalproperty_get_x(icalproperty* prop); -\layout Subsubsection - -Working with parameters -\layout Subsubsection - -Checking Component Validity -\layout Standard - -RFC 2446 defines rules for what properties must exist in a component to - be used for transfering scheduling data. - Most of these rules relate to the existence of properties relative to the - METHOD property, which declares what operation a remote reciever 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 reciever to join in a meeting. - In this case, RFC2446 says that the component must specify a start time - (DTSTART) and list the reciever as an attendee (ATTENDEE). - -\layout Standard - -Libical can check these restrictions with the routine: -\layout Verbatim - -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 representtion of an object, use one - of the *_as_ical_string() routines: -\layout Verbatim - -char* icalcomponent_as_ical_string (icalcomponent* component) -\layout Verbatim - -char* icalproperty_as_ical_string (icalproperty* property) -\layout Verbatim - -char* icalparameter_as_ical_string (icalparameter* parameter) -\layout Verbatim - -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 -r -\backslash -n -\begin_inset Quotes erd -\end_inset - - However, if you compile with the symbol ICAL_UNIX_NEWLINE defined, it will - terminate lines with -\begin_inset Quotes eld -\end_inset - - -\backslash -n -\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 Verbatim - -struct icaltimetype { -\layout Verbatim - - int year; -\layout Verbatim - - int month; -\layout Verbatim - - int day; -\layout Verbatim - - int hour; -\layout Verbatim - - int minute; -\layout Verbatim - - int second; -\layout Verbatim - - int is_utc; /* 1-> time is in UTC timezone */ -\layout Verbatim - - int is_date; /* 1 -> interpret this as date. - */ }; -\layout Standard - -The year, month, day, hour, minute and second fields how the broken-out - time values. - The is_utc field distinguishes between times UTC and a local time zone. - The is_date field indicates if the intra-day fields hold valid data. - -\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 Verbatim - -struct icaltimetype icaltime_null_time(void); -\layout Verbatim - -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 Verbatim - -struct icaltimetype icaltime_normalize(struct icaltimetype t); -\layout Standard - -There are several routines to get the day of the week or month, etc, from - a time structure. -\layout Verbatim - -short icaltime_day_of_year(struct icaltimetype t); -\layout Verbatim - -struct icaltimetype icaltime_from_day_of_year(short doy, short year); -\layout Verbatim - -short icaltime_day_of_week(struct icaltimetype t); -\layout Verbatim - -short icaltime_start_doy_of_week(struct icaltimetype t); -\layout Verbatim - -short icaltime_week_number(short day_of_month, short month, short year); -\layout Verbatim - -struct icaltimetype icaltime_from_week_number(short week_number, short year); -\layout Verbatim - -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 wether or not the hour, minute and second fields - should be used in the conversion, and is_utc indicates if the value should - be converted to a local time or a UTC time, using the operating system - suppled notion of the local timezone. - -\layout Verbatim - -struct icaltimetype icaltime_from_timet(time_t v, int is_date, int is_utc); - -\layout Verbatim - -time_t icaltime_as_timet(struct icaltimetype); -\layout Standard - -The compare routine works exactly like strcmp, but on time structures. - -\layout Verbatim - -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 parmeter in the fonllowing 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 Verbatim - -int icaltime_utc_offset(struct icaltimetype tt, char* tzid) -\layout Verbatim - -struct icaltimetype icaltime_as_utc(struct icaltimetype tt,char* tzid); -\layout Verbatim - -struct icaltimetype icaltime_as_zone(struct icaltimetype tt,char* tzid); -\layout Verbatim - -\layout Subsection - -Storing Objects -\layout Standard - -The libical distribution inclues a seperate library, libicalss, that allows - you to store iCal component data to disk in a variety of ways. - This library is documented seperately. - ( & currently, not at all. - ) -\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 transfering 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. - 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 varioustypes of programmin -g, 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; permissable 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 -\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 requirments 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 Verbatim - -X-LIC-ERROR;X-LIC-ERRORTYPE=INVALID_ITIP :Failed iTIP restrictions for property - DTSTART. - 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 -1 0 0 0 -0 1 1 0 -1 0 0 0 -0 1 1 0 -1 1 0 0 -0 1 1 0 -1 1 0 0 -0 1 1 0 -0 1 1 0 -2 1 0 "" "" -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 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 Verbatim - -ICAL_XLICERRORTYPE_COMPONENTPARSEERROR -\layout Verbatim - -ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR -\layout Verbatim - -ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR -\layout Verbatim - -ICAL_XLICERRORTYPE_PROPERTYPARSEERROR -\layout Verbatim - -ICAL_XLICERRORTYPE_VALUEPARSEERROR -\layout Verbatim - -ICAL_XLICERRORTYPE_UNKVCALPROP -\layout Verbatim - -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 ina - 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 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 - -Useful Recipies -\layout Standard - -Iteration -\layout Standard - -Copying components. - Remember that you must clone or remove an object before putting in on another - list. - -\layout Standard - -Finding compliance errors -\layout Section - -Performance -\layout Standard - -Checking restrictions is computationally expensive. -\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 propbably be changed. - These are marked with the comment string -\begin_inset Quotes eld -\end_inset - -HACK. -\begin_inset Quotes erd -\end_inset - - -\the_end |