summaryrefslogtreecommitdiffstats
path: root/libkcal/libical/doc/UsingLibical.lyx
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch)
tree67208f7c145782a7e90b123b982ca78d88cc2c87 /libkcal/libical/doc/UsingLibical.lyx
downloadtdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz
tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'libkcal/libical/doc/UsingLibical.lyx')
-rw-r--r--libkcal/libical/doc/UsingLibical.lyx2578
1 files changed, 2578 insertions, 0 deletions
diff --git a/libkcal/libical/doc/UsingLibical.lyx b/libkcal/libical/doc/UsingLibical.lyx
new file mode 100644
index 000000000..c29a61f6e
--- /dev/null
+++ b/libkcal/libical/doc/UsingLibical.lyx
@@ -0,0 +1,2578 @@
+#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 and 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 occurred
+\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