319 lines
8.9 KiB
Plaintext
319 lines
8.9 KiB
Plaintext
<!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>
|