<!doctype linuxdoc system>
<!-- LinuxDoc file was created by LyX 1.0 (C) 1995-1999 by <eric> Wed Jan 5 22:30:06 2000
-->
<article>
<title>
Using Libical
</title>
<author>
Eric Busboom (eric@softwarestudio.org)
</author>
<date>
January 2000
</date>
<sect>
Introduction
<p>
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.
</p>
<p>
Libical implements the following specifications and protocols
</p>
<p>
iCal Core
2445
iTIP
2446
iMIP
2447
iRIP
draft
CAP
draft
</p>
<p>
(The current version, 0.14, does not implement iRip or CAP. )
</p>
<p>
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
</p>
<p>
<quote>
http://softwarestudio.org/libical/index.html
</quote>
</p> <p>
and a mailing list that you can join by sending the following mail:
</p>
<p>
<code>
------------
To: minimalist@softwarestudio.org
Subject: subscribe libical
------------
</code>
</p> <p>
$Id: UsingLibical.lyx,v 1.3 2000/01/06 06:20:06 eric Exp eric $
</p>
<sect1>
License
<p>
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.
</p>
<p>
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.
</p>
<sect1>
Purpose & Goals
<sect>
Building the Library
<sect>
Structure
<p>
The iCal calendar model is based on four types of objects: components,
properties, values and parameters.
</p>
<p>
Components are the fundamental grouping of calendar information
</p>
<p>
Properties are the fundamental unit of information. Each property is composed
of a type, a value and collection of parameters.
</p>
<sect1>
Components
<p>
Components are named clusters of properties
</p>
<sect1>
Properties
<sect1>
Values
<sect1>
Parameters
<sect1>
Storage
<sect2>
Cluster
<sect2>
Store
<sect2>
Calendar
<sect1>
Other bits
<p>
Restrictions
</p>
<p>
Types
</p>
<sect>
Differences From RFCs
<p>
Although libical has been design to follow the standards as closely as
possible, there are a few areas where the specifications are irregular, and
following them exactly would result in an unfriendly interface.
</p>
<sect1>
Pseudo Components
<p>
Libical defines pseudo 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. XDAYLIGHT starts with "BEGIN:DAYLIGHT"
and ends with "END:DAYLIGHT, just like other components, but is not defined
as a component in RFC2445. ( See RFC2445, page 61 ) In Libical, it is a component.
</p>
<p>
There are also pseudo componentsthat 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.
</p>
<p>
For instance, if a VALARM component has an ACTION property with the value
of "AUDIO," the component must also have an "ATTACH" property. However, if the
ACTION value is "DISPLAY," the component must have a DESCRIPTION property.
</p>
<p>
To handle these various, complex restrictions, libical has pseudo components
for each type of alarm: XAUDIOALARM, XDISPLAYALARM, XEMAILALARM and XPROCEDUREALARM.
</p>
<sect1>
Combined Values
<p>
Many values can take more than one type. TRIGGER, for instance, can have
a value type of with DURATION or of DATE-TIME. 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.
In libical, the value of the TRIGGER property resolves to
</p>
<p>
struct icaltriggertype
</p>
<p>
This type is a union of a DURATION and a DATE-TIME.
</p>
<sect1>
Multi-Valued Properties
<p>
Some properties, such as CATEGORIES, have a single value type, but may
have multiple values in a single instance. This also results in a cumbersome
interface -- CATEGORIES accessors would have to return a list which 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. The is,
</p>
<p>
<code>
CATEGORIES: work, home
</code>
</p> <p>
becomes in libical's internal representation
</p>
<p>
<code>
CATEGORIES: work
CATEGORIES: home
</code>
</p> <p>
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.
</p>
<sect>
Implementation Limitations
<sect>
Using libical
<sect1>
Creating Components
<sect2>
Constructor interfaces
<sect2>
vaargs Constructors
<sect2>
Parsing Text Files
<sect1>
Accessing Components
<sect2>
Finding Components
<sect2>
Removing Components
<p>
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. This will result in the iteration loop terminating immediately
after removing the element. To avoid the problem, you will need to step the
iterator ahead of the element you are going to remove, like this:
</p>
<p>
<code>
for(c = icalcomponent_get_first_component(s);
c != 0;
c = next)
{
next = icalcomponent_get_next_component(s);
icalcomponent_remove_component(s,c);
}
</code>
</p> <sect2>
Finding Properties
<sect2>
Removing Properties
<sect2>
Getting Values
<sect2>
Setting Values
<sect2>
Getting Parameters
<sect2>
Setting Parameters
<sect2>
Removing Parameters
<sect1>
Storing Objects
<p>
When you store a component to the database with icalstore_add_component,
you give the library takes the memory, so the caller does not own the component
anymore. If you want to keep ownership, use clone to make a copy. ( See "Memory
Management" and "Naming Starndard for more about routines with "add" in the name.
)
</p>
<sect1>
Memory Management
<p>
Here are the memory rules for the C library:
</p>
<p>
<descrip>
<tag>
1)</tag>If the function name has "new" in it, the caller gets
control of the memory. ( such as icalcomponent_new(), or icalproperty_new_clone()
)
<tag>
2)</tag>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())
<tag>
3)</tag>If the function name has "add" in it, the caller is
transfering control of the memory to the routine. ( icalproperty_add_parameter()
)
<tag>
4)</tag>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.
<tag>
5)</tag>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.
</descrip>
</p> <sect1>
Error Handling
<sect2>
Return values
<sect2>
icalerrno
<sect2>
Component errors
<sect1>
Naming Standard
<p>
Structures that you access with the "struct" keyword, such as "struct icaltimetype"
are things that you are allowed to see inside and poke at.
</p>
<p>
Structures that you access though a typedef, such as "icalcomponent" are
things where all of the data is hidden.
</p>
<p>
Component names that start with "V" are part of RFC 2445 or another iCal
standard. Component names that start with "X" 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 "XLIC" or
"X-LIC" are not part of any iCal spec. They are used internally by libical.
</p>
<sect>
Hacks and Bugs
</article>