aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src/libicalvcal/icalvcal.c
diff options
context:
space:
mode:
Diffstat (limited to 'libical/src/libicalvcal/icalvcal.c')
-rw-r--r--libical/src/libicalvcal/icalvcal.c1639
1 files changed, 0 insertions, 1639 deletions
diff --git a/libical/src/libicalvcal/icalvcal.c b/libical/src/libicalvcal/icalvcal.c
deleted file mode 100644
index 9ab3fa899e..0000000000
--- a/libical/src/libicalvcal/icalvcal.c
+++ /dev/null
@@ -1,1639 +0,0 @@
-/*======================================================================
- FILE: icalvcal.c
- CREATOR: eric 25 May 00
-
- $Id$
-
-
- (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of either:
-
- The LGPL as published by the Free Software Foundation, version
- 2.1, available at: http://www.fsf.org/copyleft/lesser.html
-
- Or:
-
- The Mozilla Public License Version 1.0. You may obtain a copy of
- the License at http://www.mozilla.org/MPL/
-
- The original code is icalvcal.c
-
-
-
- The icalvcal_convert routine calls icalvcal_traverse_objects to do
- its work.s his routine steps through through all of the properties
- and components of a VObject. For each name of a property or a
- component, icalvcal_traverse_objects looks up the name in
- conversion_table[]. This table indicates wether the name is of a
- component or a property, lists a routine to handle conversion, and
- has extra data for the conversion.
-
- The conversion routine will create new iCal components or properties
- and add them to the iCal component structure.
-
- The most common conversion routine is dc_prop. This routine converts
- properties for which the text representation of the vCal component
- is identical the iCal representation.
-
- ======================================================================*/
-
-#include "icalvcal.h"
-#include <string.h>
-
-enum datatype {
- COMPONENT,
- PROPERTY,
- PARAMETER,
- UNSUPPORTED,
- IGNORE
-};
-
-/* The indices must match between the strings and the codes. */
-char *weekdays[] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
-int weekday_codes[] = {
- ICAL_SUNDAY_WEEKDAY,
- ICAL_MONDAY_WEEKDAY,
- ICAL_TUESDAY_WEEKDAY,
- ICAL_WEDNESDAY_WEEKDAY,
- ICAL_THURSDAY_WEEKDAY,
- ICAL_FRIDAY_WEEKDAY,
- ICAL_SATURDAY_WEEKDAY
-};
-
-struct conversion_table_struct {
- char* vcalname;
- enum datatype type;
- void* (*conversion_func)(int icaltype, VObject *o, icalcomponent *comp,
- icalvcal_defaults *defaults);
- int icaltype;
-};
-
-struct conversion_table_struct conversion_table[];
-void* dc_prop(int icaltype, VObject *object, icalcomponent *comp,
- icalvcal_defaults *defaults);
-
-
-
-/* Creates an error property with the given message. */
-static icalproperty* create_parse_error_property (const char *message,
- const char *property_name,
- const char *property_value)
-{
- char temp[4096];
- icalparameter *error_param;
- icalproperty *error_prop;
-
- snprintf (temp, 1024, "%s: %s:%s", message, property_name, property_value);
-
- error_param = icalparameter_new_xlicerrortype (ICAL_XLICERRORTYPE_VCALPROPPARSEERROR);
- error_prop = icalproperty_new_xlicerror (temp);
- icalproperty_add_parameter (error_prop, error_param);
-
- return error_prop;
-}
-
-
-char* get_string_value (VObject *object, int *free_string)
-{
- switch (vObjectValueType(object)) {
- case VCVT_USTRINGZ:
- *free_string = 1;
- return fakeCString(vObjectUStringZValue(object));
-
- case VCVT_STRINGZ:
- *free_string = 0;
- return (char*) vObjectStringZValue(object);
- }
-
- *free_string = 0;
-
- /* We return "" here, to cut down on the risk of crashing. */
- return "";
-}
-
-
-static void convert_floating_time_to_utc (struct icaltimetype *itt)
-{
- struct tm tmp_tm = { 0 }, *utc_tm;
- time_t t;
-
- /* We assume the floating time is using the current Unix timezone.
- So we convert to a time_t using mktime(), and then back to a struct tm
- using gmtime, so it is the UTC time. */
- tmp_tm.tm_year = itt->year - 1900;
- tmp_tm.tm_mon = itt->month - 1;
- tmp_tm.tm_mday = itt->day;
- tmp_tm.tm_hour = itt->hour;
- tmp_tm.tm_min = itt->minute;
- tmp_tm.tm_sec = itt->second;
- tmp_tm.tm_isdst = -1;
-
- /* Convert to a time_t. */
- t = mktime (&tmp_tm);
-
- /* Now convert back to a struct tm, but with a UTC time. */
- utc_tm = gmtime (&t);
-
- /* Now put it back into the icaltime. */
- itt->year = utc_tm->tm_year + 1900;
- itt->month = utc_tm->tm_mon + 1;
- itt->day = utc_tm->tm_mday;
- itt->hour = utc_tm->tm_hour;
- itt->minute = utc_tm->tm_min;
- itt->second = utc_tm->tm_sec;
-
- /* Set the is_utc flag. */
- itt->is_utc = 1;
-}
-
-
-static int icalvcal_traverse_objects(VObject *object,
- icalcomponent* last_comp,
- icalproperty* last_prop,
- icalvcal_defaults *defaults)
-{
- VObjectIterator iterator;
- char* name = "[No Name]";
- icalcomponent* subc = 0;
- int i;
-
- if ( vObjectName(object)== 0){
- printf("ERROR, object has no name");
- return 0;
- }
-
- name = (char*)vObjectName(object);
-
- /* Lookup this object in the conversion table */
- for (i = 0; conversion_table[i].vcalname != 0; i++){
- if(strcmp(conversion_table[i].vcalname, name) == 0){
- break;
- }
- }
-
- /* Did not find the object. It may be an X-property, or an unknown
- property */
- if (conversion_table[i].vcalname == 0){
-
- /* Handle X properties */
- if(strncmp(name, "X-",2) == 0){
- icalproperty* prop = (icalproperty*)dc_prop(ICAL_X_PROPERTY,object,
- last_comp, defaults);
- icalproperty_set_x_name(prop,name);
- icalcomponent_add_property(last_comp,prop);
- } else {
- return 0;
- }
-
- } else {
-
- /* The vCal property is in the table, and it is not an X
- property, so try to convert it to an iCal component,
- property or parameter. */
-
- switch(conversion_table[i].type){
-
-
- case COMPONENT: {
- subc =
- (icalcomponent*)(conversion_table[i].conversion_func
- (conversion_table[i].icaltype,
- object, last_comp, defaults));
-
- if (subc) {
- icalcomponent_add_component(last_comp,subc);
- }
-
- break;
- }
-
- case PROPERTY: {
-
- if (vObjectValueType(object) &&
- conversion_table[i].conversion_func != 0 ) {
-
- icalproperty* prop =
- (icalproperty*)(conversion_table[i].conversion_func
- (conversion_table[i].icaltype,
- object, last_comp, defaults));
-
- if (prop)
- icalcomponent_add_property(last_comp,prop);
-
- last_prop = prop;
-
- }
- break;
- }
-
- case PARAMETER: {
- break;
- }
-
- case UNSUPPORTED: {
-
- /* If the property is listed as UNSUPPORTED, insert a
- X_LIC_ERROR property to note this fact. */
-
- char temp[1024];
- char* message = "Unsupported vCal property";
- icalparameter *error_param;
- icalproperty *error_prop;
-
- snprintf(temp,1024,"%s: %s",message,name);
-
- error_param = icalparameter_new_xlicerrortype(
- ICAL_XLICERRORTYPE_UNKNOWNVCALPROPERROR
- );
-
- error_prop = icalproperty_new_xlicerror(temp);
- icalproperty_add_parameter(error_prop, error_param);
-
- icalcomponent_add_property(last_comp,error_prop);
-
- break;
- }
-
- case IGNORE: {
- /* Do Nothing. */
- break;
- }
- }
- }
-
-
- /* Now, step down into the next vCalproperty */
-
- initPropIterator(&iterator,object);
- while (moreIteration(&iterator)) {
- VObject *eachProp = nextVObject(&iterator);
-
- /* If 'object' is a component, then the next traversal down
- should use it as the 'last_comp' */
-
- if(subc!=0){
- if (!icalvcal_traverse_objects(eachProp,subc,last_prop,defaults))
- return 0;
-
- } else {
- if (!icalvcal_traverse_objects(eachProp,last_comp,last_prop,defaults))
- return 0;
- }
- }
-
- return 1;
-}
-
-icalcomponent* icalvcal_convert_with_defaults (VObject *object,
- icalvcal_defaults *defaults)
-{
- char* name = (char*)vObjectName(object);
- icalcomponent* container = icalcomponent_new(ICAL_XROOT_COMPONENT);
- icalcomponent* root;
- icalproperty *prop;
-
- icalerror_check_arg_rz( (object!=0),"Object");
-
- /* The root object must be a VCALENDAR */
- if(*name==0 || strcmp(name,VCCalProp) != 0){
- return 0; /* HACK. Should return an error */
- }
-
-#if 0
- /* Just for testing. */
- printf ("This is the internal VObject representation:\n");
- printf ("===========================================\n");
- printVObject(stdout, object);
- printf ("===========================================\n");
-#endif
-
- if (!icalvcal_traverse_objects(object,container,0,defaults))
- return 0;
-
- /* HACK. I am using the extra 'container' component because I am
- lazy. I know there is a way to get rid of it, but I did not care
- to find it. */
-
- root = icalcomponent_get_first_component(container,ICAL_ANY_COMPONENT);
-
- icalcomponent_remove_component(container, root);
- icalcomponent_free(container);
-
- /* We add a VERSION and PRODID here, to make it a valid iCalendar object,
- but the application may change them if necessary. */
- prop = icalproperty_new_prodid ("-//Softwarestudio.org//" ICAL_PACKAGE
- " version " ICAL_VERSION "//EN");
- icalcomponent_add_property (root, prop);
-
- prop = icalproperty_new_version ("2.0");
- icalcomponent_add_property (root, prop);
-
- return root;
-
-}
-
-icalcomponent* icalvcal_convert (VObject *object)
-{
- return icalvcal_convert_with_defaults (object, NULL);
-}
-
-
-/* comp() is useful for most components, but alarm, daylight and
- * timezone are different. In vcal, they are properties, and in ical,
- * they are components. Although because of the way that vcal treats
- * everything as a property, alarm_comp() daylight_comp() and
- * timezone_comp() may not really be necessary, I think it would be
- * easier to use them. */
-
-void* comp(int icaltype, VObject *o, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalcomponent_kind kind = (icalcomponent_kind)icaltype;
-
- icalcomponent* c = icalcomponent_new(kind);
-
- return (void* )c;
-}
-
-/* vCalendar has 4 properties for alarms: AALARM, DALARM, MALARM, PALARM
- (for audio, display, mail, and procedure alarms).
-
- AALARM has Run Time, Snooze Time, Repeat Count, Audio Content.
- It may also have a TYPE parameter specifying the MIME type, e.g.
- AALARM;TYPE=WAVE;VALUE=URL:19960415T235959; ; ; file:///mmedia/taps.wav
- AALARM;TYPE=WAVE;VALUE=CONTENT-ID:19960903T060000;PT15M;4;<jsmith.part2.=
- 960901T083000.xyzMail@host1.com>
-
- DALARM has Run Time, Snooze Time, Repeat Count, Display String.
- DALARM:19960415T235000;PT5M;2;Your Taxes Are Due !!!
-
- MALARM has Run Time, Snooze Time, Repeat Count, Email Address, Note.
- MALARM:19960416T000000;PT1H;24;IRS@us.gov;The Check Is In The Mail!
-
- PALARM has Run Time, Snooze Time, Repeat Count, Procedure Name.
- PALARM;VALUE=URL:19960415T235000;PT5M;2;file:///myapps/shockme.exe
-
- AALARM and PALARM: Check the VALUE is a URL. We won't support CONTENT-ID.
-
-
- iCalendar uses one component, VALARM, for all of these, and uses an ACTION
- property of "AUDIO", "DISPLAY", "EMAIL" or "PROCEDURE".
-
- The Run Time value can be copied into the iCalendar TRIGGER property,
- except it must be UTC in iCalendar. If it is floating, we'll convert to
- UTC using the current Unix timezone.
-
- The Snooze Time becomes DURATION, and the Repeat Count becomes REPEAT.
-
- For AALARM, the Audio Content becomes the ATTACH property, and the TYPE
- becomes a FMTTYPE of this property (PCM -> 'audio/basic' (?),
- WAVE -> 'audio/x-wav', AIFF -> 'audio/x-aiff'), e.g.
- ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud
-
- For DALARM, Display String becomes the DESCRIPTION property.
-
- For MALARM, Email Address becomes an ATTENDEE property, e.g.
- ATTENDEE:MAILTO:john_doe@host.com
-
- For PALARM, the Procedure Name becomes an ATTACH property, like AALARM, e.g.
- ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-procs/felizano.exe
-*/
-
-/* This converts the vCalendar alarm properties into iCalendar properties and
- adds them to the component. It returns 1 if the alarm is valid, 0 if not. */
-static int get_alarm_properties (icalcomponent *comp, VObject *object,
- int icaltype, icalvcal_defaults *defaults)
-{
- VObjectIterator iterator;
- icalproperty *trigger_prop = NULL, *duration_prop = NULL;
- icalproperty *repeat_prop = NULL, *attach_prop = NULL;
- icalproperty *summary_prop = NULL, *description_prop = NULL;
- icalproperty *action_prop, *attendee_prop = NULL;
- icalparameter *fmttype_param = NULL;
- enum icalproperty_action action;
- int value_is_url = 0, is_valid_alarm = 1;
-
- initPropIterator (&iterator, object);
- while (moreIteration (&iterator)) {
- VObject *eachProp = nextVObject (&iterator);
- const char *name = vObjectName (eachProp);
- char *s;
- int free_string;
-
- s = get_string_value (eachProp, &free_string);
-
- /* Common properties. */
- if (!strcmp (name, VCRunTimeProp)) {
- if (*s) {
- struct icaltriggertype t;
- icalparameter *param;
-
- /* Convert it to an icaltimetype. */
- t.time = icaltime_from_string (s);
-
- /* If it is a floating time, convert it to a UTC time. */
- if (!t.time.is_utc)
- convert_floating_time_to_utc (&t.time);
-
- /* Create a TRIGGER property. */
- trigger_prop = icalproperty_new_trigger (t);
-
- /* vCalendar triggers are always specific DATE-TIME values. */
- param = icalparameter_new_value (ICAL_VALUE_DATETIME);
- icalproperty_add_parameter (trigger_prop, param);
-
- icalcomponent_add_property (comp, trigger_prop);
- }
-
- } else if (!strcmp (name, VCSnoozeTimeProp)) {
- struct icaldurationtype d;
-
- /* Parse the duration string.
- FIXME: vCalendar also permits 'Y' (Year) and 'M' (Month) here,
- which we don't handle at present. Though it is unlikely they
- will be used as a snooze time between repeated alarms! */
- d = icaldurationtype_from_string (s);
-
- duration_prop = icalproperty_new_duration (d);
- icalcomponent_add_property (comp, duration_prop);
-
- } else if (!strcmp (name, VCRepeatCountProp)) {
- /* If it starts with a digit convert it into a REPEAT property. */
- if (*s && *s >= '0' && *s <= '9') {
- repeat_prop = icalproperty_new_repeat (atoi (s));
- icalcomponent_add_property (comp, repeat_prop);
- }
-
- } else if (!strcmp (name, VCValueProp)) {
- /* We just remember if the value is a URL. */
- if (!strcmp (s, "URL")) {
- value_is_url = 1;
- }
-
- /* Audio properties && Procedure properties. */
- } else if (!strcmp (name, VCAudioContentProp)
- || !strcmp (name, VCProcedureNameProp)) {
- if (*s && !attach_prop) {
- icalattach *attach;
-
- attach = icalattach_new_from_url (s);
- attach_prop = icalproperty_new_attach (attach);
- icalcomponent_add_property (comp, attach_prop);
-
- /* We output a "application/binary" FMTTYPE for Procedure
- alarms. */
- if (!strcmp (name, VCProcedureNameProp) && !fmttype_param)
- fmttype_param = icalparameter_new_fmttype ("application/binary");
- }
-
- } else if (!strcmp (name, "TYPE")) {
- char *fmttype = NULL;
-
- if (!strcmp (s, "PCM"))
- fmttype = "audio/basic";
- else if (!strcmp (s, "AIFF"))
- fmttype = "audio/x-aiff";
- else if (!strcmp (s, "WAVE"))
- fmttype = "audio/x-wav";
-
- if (fmttype)
- fmttype_param = icalparameter_new_fmttype (fmttype);
-
- /* Display properties. */
- } else if (!strcmp (name, VCDisplayStringProp)) {
- if (!description_prop) {
- description_prop = icalproperty_new_description (s);
- icalcomponent_add_property (comp, description_prop);
- }
-
- /* Mail properties. */
- } else if (!strcmp (name, VCEmailAddressProp)) {
- if (*s && strlen (s) < 1000) {
- char buffer[1024];
-
- /* We need to add 'MAILTO:' before the email address, to make
- it valid iCalendar. */
- sprintf (buffer, "MAILTO:%s", s);
- attendee_prop = icalproperty_new_attendee (buffer);
- icalcomponent_add_property (comp, attendee_prop);
- }
-
- } else if (!strcmp (name, VCNoteProp)) {
- if (!description_prop) {
- description_prop = icalproperty_new_description (s);
- icalcomponent_add_property (comp, description_prop);
- }
-
- /* We also copy the Note to the SUMMARY property, since that is
- required in iCalendar. */
- if (!summary_prop) {
- summary_prop = icalproperty_new_summary (s);
- icalcomponent_add_property (comp, summary_prop);
- }
- }
-
- if (free_string)
- deleteStr (s);
- }
-
- /* Add the FMTTYPE parameter to the ATTACH property if it exists. */
- if (fmttype_param) {
- if (attach_prop) {
- icalproperty_add_parameter (attach_prop, fmttype_param);
- } else {
- icalparameter_free (fmttype_param);
- }
- }
-
-
- /* Now check if the alarm is valid, i.e. it has the required properties
- according to its type. */
-
- /* All alarms must have a trigger. */
- if (!trigger_prop)
- is_valid_alarm = 0;
-
- /* If there is a Duration but not a Repeat Count, we just remove the
- Duration so the alarm only occurs once. */
- if (duration_prop && !repeat_prop) {
- icalcomponent_remove_property (comp, duration_prop);
- icalproperty_free (duration_prop);
- duration_prop = NULL;
- }
-
- /* Similarly if we have a Repeat Count but no Duration, we remove it. */
- if (repeat_prop && !duration_prop) {
- icalcomponent_remove_property (comp, repeat_prop);
- icalproperty_free (repeat_prop);
- repeat_prop = NULL;
- }
-
- switch (icaltype) {
- case ICAL_XAUDIOALARM_COMPONENT:
- action = ICAL_ACTION_AUDIO;
-
- /* Audio alarms must have an ATTACH property, which is a URL.
- If they don't have one, we use the default alarm URL. */
- if (!attach_prop || !value_is_url) {
- if (defaults && defaults->alarm_audio_url
- && defaults->alarm_audio_fmttype) {
- icalattach *attach;
-
- if (attach_prop) {
- icalcomponent_remove_property (comp, attach_prop);
- icalproperty_free (attach_prop);
- }
-
- attach = icalattach_new_from_url (defaults->alarm_audio_url);
- attach_prop = icalproperty_new_attach (attach);
- icalcomponent_add_property (comp, attach_prop);
-
- fmttype_param = icalparameter_new_fmttype (defaults->alarm_audio_fmttype);
- icalproperty_add_parameter (attach_prop, fmttype_param);
- } else {
- is_valid_alarm = 0;
- }
- }
- break;
-
- case ICAL_XDISPLAYALARM_COMPONENT:
- action = ICAL_ACTION_DISPLAY;
-
- /* Display alarms must have a DESCRIPTION. */
- if (!description_prop) {
- if (defaults && defaults->alarm_description) {
- description_prop = icalproperty_new_description (defaults->alarm_description);
- icalcomponent_add_property (comp, description_prop);
- } else {
- is_valid_alarm = 0;
- }
- }
- break;
-
- case ICAL_XEMAILALARM_COMPONENT:
- action = ICAL_ACTION_EMAIL;
-
- /* Email alarms must have a SUMMARY, a DESCRIPTION, and an ATTENDEE. */
- if (!attendee_prop) {
- is_valid_alarm = 0;
- } else if (!summary_prop || !description_prop) {
- if (!summary_prop && defaults->alarm_description) {
- summary_prop = icalproperty_new_summary (defaults->alarm_description);
- icalcomponent_add_property (comp, summary_prop);
- }
-
- if (!description_prop && defaults->alarm_description) {
- description_prop = icalproperty_new_description (defaults->alarm_description);
- icalcomponent_add_property (comp, description_prop);
- }
-
- if (!summary_prop || !description_prop)
- is_valid_alarm = 0;
- }
- break;
-
- case ICAL_XPROCEDUREALARM_COMPONENT:
- action = ICAL_ACTION_PROCEDURE;
-
- /* Procedure alarms must have an ATTACH property, which is a URL.
- We don't support inline data. */
- if (!attach_prop) {
- is_valid_alarm = 0;
- } else if (!value_is_url) {
- icalattach *attach;
- const char *url;
-
- attach = icalproperty_get_attach (attach_prop);
- url = icalattach_get_url (attach);
-
- /* Check for Gnome Calendar, which will just save a pathname. */
- if (url && url[0] == '/') {
- int len;
- char *new_url;
- icalattach *new_attach;
-
- /* Turn it into a proper file: URL. */
- len = strlen (url) + 12;
-
- new_url = malloc (len);
- strcpy (new_url, "file://");
- strcat (new_url, url);
-
- new_attach = icalattach_new_from_url (new_url);
- free (new_url);
-
- icalproperty_set_attach (attach_prop, new_attach);
-
- } else {
- is_valid_alarm = 0;
- }
- }
- break;
-
- default:
- /* Shouldn't reach here ever. */
- assert(0);
- break;
- }
-
- action_prop = icalproperty_new_action (action);
- icalcomponent_add_property (comp, action_prop);
-
- return is_valid_alarm;
-}
-
-
-void* alarm_comp(int icaltype, VObject *o, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalcomponent_kind kind = (icalcomponent_kind)icaltype;
- int is_valid_alarm;
-
- icalcomponent* c = icalcomponent_new(ICAL_VALARM_COMPONENT);
-
- is_valid_alarm = get_alarm_properties (c, o, icaltype, defaults);
-
- if (is_valid_alarm) {
- return (void*)c;
- } else {
- icalcomponent_free (c);
- return NULL;
- }
-}
-
-/* These #defines indicate conversion routines that are not defined yet. */
-
-#define parameter 0
-#define rsvp_parameter 0
-
-
-void* transp_prop(int icaltype, VObject *object, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalproperty *prop = NULL;
- char *s;
- int free_string;
-
- s = get_string_value (object, &free_string);
-
- /* In vCalendar "0" means opaque, "1" means transparent, and >1 is
- implementation-specific. So we just check for "1" and output
- TRANSPARENT. For anything else, the default OPAQUE will be used. */
- if (!strcmp (s, "1")) {
- prop = icalproperty_new_transp ("TRANSPARENT");
- }
-
- if (free_string)
- deleteStr (s);
-
- return (void*)prop;
-}
-
-
-void* sequence_prop(int icaltype, VObject *object, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalproperty *prop = NULL;
- char *s;
- int free_string, sequence;
-
- s = get_string_value (object, &free_string);
-
- /* GnomeCalendar outputs '-1' for this. I have no idea why.
- So we just check it is a valid +ve integer, and output 0 if it isn't. */
- sequence = atoi (s);
- if (sequence < 0)
- sequence = 0;
-
- prop = icalproperty_new_sequence (sequence);
-
- if (free_string)
- deleteStr (s);
-
- return (void*)prop;
-}
-
-
-/* This handles properties which have multiple values, which are separated by
- ';' in vCalendar but ',' in iCalendar. So we just switch those. */
-void* multivalued_prop(int icaltype, VObject *object, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalproperty_kind kind = (icalproperty_kind)icaltype;
- icalproperty *prop = NULL;
- icalvalue *value;
- icalvalue_kind value_kind;
- char *s, *tmp_copy, *p;
- int free_string;
-
- s = get_string_value (object, &free_string);
-
- tmp_copy = strdup (s);
-
- if (free_string)
- deleteStr (s);
-
- if (tmp_copy) {
- prop = icalproperty_new(kind);
-
- value_kind = icalenum_property_kind_to_value_kind (icalproperty_isa (prop));
-
- for (p = tmp_copy; *p; p++) {
- if (*p == ';')
- *p = ',';
- }
-
- value = icalvalue_new_from_string (value_kind, tmp_copy);
- icalproperty_set_value (prop, value);
-
- free (tmp_copy);
- }
-
- return (void*)prop;
-}
-
-
-void* status_prop(int icaltype, VObject *object, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalproperty *prop = NULL;
- char *s;
- int free_string;
- icalcomponent_kind kind;
-
- kind = icalcomponent_isa (comp);
-
- s = get_string_value (object, &free_string);
-
- /* In vCalendar:
- VEVENT can have: "NEEDS ACTION" (default), "SENT", "TENTATIVE",
- "CONFIRMED", "DECLINED", "DELEGATED".
- VTODO can have: "ACCEPTED", "NEEDS ACTION" (default), "SENT",
- "DECLINED", "COMPLETED", "DELEGATED".
- (Those are the only 2 components - there is no VJOURNAL)
-
- In iCalendar:
- VEVENT can have: "TENTATIVE", "CONFIRMED", "CANCELLED".
- VTODO can have: "NEEDS-ACTION", "COMPLETED", "IN-PROCESS", "CANCELLED".
-
- So for VEVENT if it is "TENTATIVE" or "CONFIRMED" we keep it, otherwise
- we skip it.
-
- For a VTODO if it is "NEEDS ACTION" we convert to "NEEDS-ACTION", if it
- is "COMPLETED" we keep it, otherwise we skip it.
- */
- if (kind == ICAL_VEVENT_COMPONENT) {
- if (!strcmp (s, "TENTATIVE"))
- prop = icalproperty_new_status (ICAL_STATUS_TENTATIVE);
- else if (!strcmp (s, "CONFIRMED"))
- prop = icalproperty_new_status (ICAL_STATUS_CONFIRMED);
-
- } else if (kind == ICAL_VTODO_COMPONENT) {
- if (!strcmp (s, "NEEDS ACTION"))
- prop = icalproperty_new_status (ICAL_STATUS_NEEDSACTION);
- else if (!strcmp (s, "COMPLETED"))
- prop = icalproperty_new_status (ICAL_STATUS_COMPLETED);
-
- }
-
- if (free_string)
- deleteStr (s);
-
- return (void*)prop;
-}
-
-
-void* utc_datetime_prop(int icaltype, VObject *object, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalproperty_kind kind = (icalproperty_kind)icaltype;
- icalproperty *prop;
- icalvalue *value;
- icalvalue_kind value_kind;
- char *s;
- int free_string;
- struct icaltimetype itt;
-
- prop = icalproperty_new(kind);
-
- value_kind = icalenum_property_kind_to_value_kind (icalproperty_isa(prop));
-
- s = get_string_value (object, &free_string);
-
- /* Convert it to an icaltimetype. */
- itt = icaltime_from_string (s);
-
- /* If it is a floating time, convert it to a UTC time. */
- if (!itt.is_utc)
- convert_floating_time_to_utc (&itt);
-
- value = icalvalue_new_datetime (itt);
- icalproperty_set_value(prop,value);
-
- if (free_string)
- deleteStr (s);
-
- return (void*)prop;
-}
-
-
-/* Parse the interval from the RRULE, returning a pointer to the first char
- after the interval and any whitespace. s points to the start of the
- interval. error_message is set if an error occurs. */
-static char* rrule_parse_interval (char *s, struct icalrecurrencetype *recur,
- char **error_message)
-{
- int interval = 0;
-
- /* It must start with a digit. */
- if (*s < '0' || *s > '9') {
- *error_message = "Invalid Interval";
- return NULL;
- }
-
- while (*s >= '0' && *s <= '9')
- interval = (interval * 10) + (*s++ - '0');
-
- /* It must be followed by whitespace. I'm not sure if anything else is
- allowed. */
- if (*s != ' ' && *s != '\t') {
- *error_message = "Invalid Interval";
- return NULL;
- }
-
- /* Skip any whitespace. */
- while (*s == ' ' || *s == '\t')
- s++;
-
- recur->interval = interval;
- return s;
-}
-
-
-/* Parse the duration from the RRULE, either a COUNT, e.g. '#5', or an UNTIL
- date, e.g. 20020124T000000. error_message is set if an error occurs.
- If no duration is given, '#2' is assumed. */
-static char* rrule_parse_duration (char *s, struct icalrecurrencetype *recur,
- char **error_message)
-{
- /* If we've already found an error, just return. */
- if (*error_message)
- return NULL;
-
- if (!s || *s == '\0') {
- /* If we are at the end of the string, assume '#2'. */
- recur->count = 2;
-
- } else if (*s == '#') {
- /* If it starts with a '#' it is the COUNT. Note that in vCalendar
- #0 means forever, and setting recur->count to 0 means the same. */
- int count = 0;
-
- s++;
- while (*s >= '0' && *s <= '9')
- count = (count * 10) + (*s++ - '0');
-
- recur->count = count;
-
- } else if (*s >= '0' && *s <= '9') {
- /* If it starts with a digit it must be the UNTIL date. */
- char *e, buffer[20];
- int len;
-
- /* Find the end of the date. */
- e = s;
- while ((*e >= '0' && *e <= '9') || *e == 'T' || *e == 'Z')
- e++;
-
- /* Check it is a suitable length. */
- len = e - s;
- if (len != 8 && len != 15 && len != 16) {
- *error_message = "Invalid End Date";
- return NULL;
- }
-
- /* Copy the date to our buffer and null-terminate it. */
- strncpy (buffer, s, len);
- buffer[len] = '\0';
-
- /* Parse it into the until field. */
- recur->until = icaltime_from_string (buffer);
-
- /* In iCalendar UNTIL must be UTC if it is a DATE-TIME. But we
- don't really know what timezone the vCalendar times are in. So if
- it can be converted to a DATE value, we do that. Otherwise we just
- use the current Unix timezone. Should be OK 99% of the time. */
- if (!recur->until.is_utc) {
- if (recur->until.hour == 0 && recur->until.minute == 0
- && recur->until.second == 0)
- recur->until.is_date = 1;
- else
- convert_floating_time_to_utc (&recur->until);
- }
-
- s = e;
-
- } else {
- *error_message = "Invalid Duration";
- return NULL;
- }
-
-
- /* It must be followed by whitespace or the end of the string.
- I'm not sure if anything else is allowed. */
- if (*s != '\0' && *s != ' ' && *s != '\t') {
- *error_message = "Invalid Duration";
- return NULL;
- }
-
- return s;
-}
-
-
-static char* rrule_parse_weekly_days (char *s,
- struct icalrecurrencetype *recur,
- char **error_message)
-{
- int i;
-
- /* If we've already found an error, just return. */
- if (*error_message)
- return NULL;
-
- for (i = 0; i < ICAL_BY_DAY_SIZE; i++) {
- char *e;
- int found_day, day;
-
- found_day = -1;
- for (day = 0; day < 7; day++) {
- if (!strncmp (weekdays[day], s, 2)) {
- /* Check the next char is whitespace or the end of string. */
- e = s + 2;
- if (*e == ' ' || *e == '\t' || *e == '\0') {
- found_day = day;
- break;
- }
- }
- }
-
- if (found_day == -1)
- break;
-
- recur->by_day[i] = weekday_codes[day];
-
- s = e;
- /* Skip any whitespace. */
- while (*s == ' ' || *s == '\t')
- s++;
- }
-
- /* Terminate the array, if it isn't full. */
- if (i < ICAL_BY_DAY_SIZE)
- recur->by_day[i] = ICAL_RECURRENCE_ARRAY_MAX;
-
- return s;
-}
-
-
-static char* rrule_parse_monthly_days (char *s,
- struct icalrecurrencetype *recur,
- char **error_message)
-{
- int i;
-
- /* If we've already found an error, just return. */
- if (*error_message)
- return NULL;
-
- for (i = 0; i < ICAL_BY_MONTHDAY_SIZE; i++) {
- char *e;
- int month_day;
-
- if (!strncmp (s, "LD", 2)) {
- month_day = -1;
- e = s + 2;
- } else {
- month_day = strtol (s, &e, 10);
-
- /* Check we got a valid day. */
- if (month_day < 1 || month_day > 31)
- break;
-
- /* See if it is followed by a '+' or '-'. */
- if (*e == '+') {
- e++;
- } else if (*e == '-') {
- e++;
- month_day = -month_day;
- }
- }
-
- /* Check the next char is whitespace or the end of the string. */
- if (*e != ' ' && *e != '\t' && *e != '\0')
- break;
-
- recur->by_month_day[i] = month_day;
-
- s = e;
- /* Skip any whitespace. */
- while (*s == ' ' || *s == '\t')
- s++;
- }
-
- /* Terminate the array, if it isn't full. */
- if (i < ICAL_BY_MONTHDAY_SIZE)
- recur->by_month_day[i] = ICAL_RECURRENCE_ARRAY_MAX;
-
- return s;
-}
-
-
-static char* rrule_parse_monthly_positions (char *s,
- struct icalrecurrencetype *recur,
- char **error_message)
-{
- int occurrences[ICAL_BY_DAY_SIZE];
- int found_weekdays[7] = { 0 };
- int i, num_positions, elems, month_position, day;
- int num_weekdays, only_weekday;
- char *e;
-
- /* If we've already found an error, just return. */
- if (*error_message)
- return NULL;
-
- /* First read the month position into our local occurrences array. */
- for (i = 0; i < ICAL_BY_DAY_SIZE; i++) {
- int month_position;
-
- /* Check we got a valid position number. */
- month_position = *s - '0';
- if (month_position < 0 || month_position > 5)
- break;
-
- /* See if it is followed by a '+' or '-'. */
- e = s + 1;
- if (*e == '+') {
- e++;
- } else if (*e == '-') {
- e++;
- month_position = -month_position;
- }
-
- /* Check the next char is whitespace or the end of the string. */
- if (*e != ' ' && *e != '\t' && *e != '\0')
- break;
-
- occurrences[i] = month_position;
-
- s = e;
- /* Skip any whitespace. */
- while (*s == ' ' || *s == '\t')
- s++;
- }
- num_positions = i;
-
- /* Now read the weekdays in. */
- for (;;) {
- char *e;
- int found_day, day;
-
- found_day = -1;
- for (day = 0; day < 7; day++) {
- if (!strncmp (weekdays[day], s, 2)) {
- /* Check the next char is whitespace or the end of string. */
- e = s + 2;
- if (*e == ' ' || *e == '\t' || *e == '\0') {
- found_day = day;
- break;
- }
- }
- }
-
- if (found_day == -1)
- break;
-
- found_weekdays[found_day] = 1;
-
- s = e;
- /* Skip any whitespace. */
- while (*s == ' ' || *s == '\t')
- s++;
- }
-
- /* Now merge them together into the recur->by_day array. If there is a
- single position & weekday we output something like
- 'BYDAY=TU;BYSETPOS=2', so Outlook will understand it. */
- num_weekdays = 0;
- for (day = 0; day < 7; day++) {
- if (found_weekdays[day]) {
- num_weekdays++;
- only_weekday = day;
- }
- }
- if (num_positions == 1 && num_weekdays == 1) {
- recur->by_day[0] = weekday_codes[only_weekday];
- recur->by_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
-
- recur->by_set_pos[0] = occurrences[0];
- recur->by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
- } else {
- elems = 0;
- for (i = 0; i < num_positions; i++) {
- month_position = occurrences[i];
-
- for (day = 0; day < 7; day++) {
- if (found_weekdays[day]) {
- recur->by_day[elems] = (abs (month_position) * 8 + weekday_codes[day]) * ((month_position < 0) ? -1 : 1);
- elems++;
- if (elems == ICAL_BY_DAY_SIZE)
- break;
- }
- }
-
- if (elems == ICAL_BY_DAY_SIZE)
- break;
- }
-
- /* Terminate the array, if it isn't full. */
- if (elems < ICAL_BY_DAY_SIZE)
- recur->by_day[elems] = ICAL_RECURRENCE_ARRAY_MAX;
- }
-
- return s;
-}
-
-
-static char* rrule_parse_yearly_months (char *s,
- struct icalrecurrencetype *recur,
- char **error_message)
-{
- int i;
-
- /* If we've already found an error, just return. */
- if (*error_message)
- return NULL;
-
- for (i = 0; i < ICAL_BY_MONTH_SIZE; i++) {
- char *e;
- int month;
-
- month = strtol (s, &e, 10);
-
- /* Check we got a valid month. */
- if (month < 1 || month > 12)
- break;
-
- /* Check the next char is whitespace or the end of the string. */
- if (*e != ' ' && *e != '\t' && *e != '\0')
- break;
-
- recur->by_month[i] = month;
-
- s = e;
- /* Skip any whitespace. */
- while (*s == ' ' || *s == '\t')
- s++;
- }
-
- /* Terminate the array, if it isn't full. */
- if (i < ICAL_BY_MONTH_SIZE)
- recur->by_month[i] = ICAL_RECURRENCE_ARRAY_MAX;
-
- return s;
-}
-
-
-static char* rrule_parse_yearly_days (char *s,
- struct icalrecurrencetype *recur,
- char **error_message)
-{
- int i;
-
- /* If we've already found an error, just return. */
- if (*error_message)
- return NULL;
-
- for (i = 0; i < ICAL_BY_YEARDAY_SIZE; i++) {
- char *e;
- int year_day;
-
- year_day = strtol (s, &e, 10);
-
- /* Check we got a valid year_day. */
- if (year_day < 1 || year_day > 366)
- break;
-
- /* Check the next char is whitespace or the end of the string. */
- if (*e != ' ' && *e != '\t' && *e != '\0')
- break;
-
- recur->by_year_day[i] = year_day;
-
- s = e;
- /* Skip any whitespace. */
- while (*s == ' ' || *s == '\t')
- s++;
- }
-
- /* Terminate the array, if it isn't full. */
- if (i < ICAL_BY_YEARDAY_SIZE)
- recur->by_year_day[i] = ICAL_RECURRENCE_ARRAY_MAX;
-
- return s;
-}
-
-
-
-
-/* Converts an RRULE/EXRULE property.
- NOTE: There are a few things that this doesn't handle:
- 1) vCalendar RRULE properties can contain an UNTIL date and a COUNT, and
- the first to occur specifies the end of the recurrence. However they
- are mutually exclusive in iCalendar. For now we just use the COUNT.
- 2) For MONTHLY By Position recurrences, if no modifiers are given they
- are to be calculated based on the DTSTART, e.g. if DTSTART is on the
- 3rd Wednesday of the month then all occurrences are on the 3rd Wed.
- This is awkward to do as we need to access the DTSTART property, which
- may be after the RRULE property. So we don't do this at present.
- 3) The Extended Recurrence Rule Grammar - we only support the Basic rules.
- The extended grammar supports rules embedded in other rules, MINUTELY
- recurrences, time modifiers in DAILY rules and maybe other stuff.
-*/
-
-void* rule_prop(int icaltype, VObject *object, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalproperty_kind kind = (icalproperty_kind)icaltype;
- icalproperty *prop = NULL;
- icalvalue *value;
- icalvalue_kind value_kind;
- char *s, *p, *error_message = NULL;
- const char *property_name;
- int free_string;
- struct icalrecurrencetype recur;
-
- s = get_string_value (object, &free_string);
-
- property_name = vObjectName (object);
-
- icalrecurrencetype_clear (&recur);
-
- if (*s == 'D') {
- /* The DAILY RRULE only has an interval and duration (COUNT/UNTIL). */
- recur.freq = ICAL_DAILY_RECURRENCE;
- p = rrule_parse_interval (s + 1, &recur, &error_message);
- p = rrule_parse_duration (p, &recur, &error_message);
- } else if (*s == 'W') {
- /* The WEEKLY RRULE has weekday modifiers - MO TU WE. */
- recur.freq = ICAL_WEEKLY_RECURRENCE;
- p = rrule_parse_interval (s + 1, &recur, &error_message);
- p = rrule_parse_weekly_days (p, &recur, &error_message);
- p = rrule_parse_duration (p, &recur, &error_message);
- } else if (*s == 'M' && *(s + 1) == 'D') {
- /* The MONTHLY By Day RRULE has day number modifiers - 1 1- LD. */
- recur.freq = ICAL_MONTHLY_RECURRENCE;
- p = rrule_parse_interval (s + 2, &recur, &error_message);
- p = rrule_parse_monthly_days (p, &recur, &error_message);
- p = rrule_parse_duration (p, &recur, &error_message);
- } else if (*s == 'M' && *(s + 1) == 'P') {
- /* The MONTHLY By Position RRULE has position modifiers - 1 2- and
- weekday modifiers - MO TU. */
- recur.freq = ICAL_MONTHLY_RECURRENCE;
- p = rrule_parse_interval (s + 2, &recur, &error_message);
- p = rrule_parse_monthly_positions (p, &recur, &error_message);
- p = rrule_parse_duration (p, &recur, &error_message);
- } else if (*s == 'Y' && *(s + 1) == 'M') {
- /* The YEARLY By Month RRULE has month modifiers - 1 3 12. */
- recur.freq = ICAL_YEARLY_RECURRENCE;
- p = rrule_parse_interval (s + 2, &recur, &error_message);
- p = rrule_parse_yearly_months (p, &recur, &error_message);
- p = rrule_parse_duration (p, &recur, &error_message);
- } else if (*s == 'Y' && *(s + 1) == 'D') {
- /* The YEARLY By Day RRULE has day number modifiers - 100 200. */
- recur.freq = ICAL_YEARLY_RECURRENCE;
- p = rrule_parse_interval (s + 2, &recur, &error_message);
- p = rrule_parse_yearly_days (p, &recur, &error_message);
- p = rrule_parse_duration (p, &recur, &error_message);
- } else {
- error_message = "Invalid RRULE Frequency";
- }
-
- if (error_message) {
- prop = create_parse_error_property (error_message, property_name, s);
- } else {
- if (!strcmp (property_name, "RRULE"))
- prop = icalproperty_new_rrule (recur);
- else
- prop = icalproperty_new_exrule (recur);
- }
-
- if (free_string)
- deleteStr (s);
-
- return (void*)prop;
-}
-
-
-
-/* directly convertable property. The string representation of vcal is
- the same as ical */
-
-void* dc_prop(int icaltype, VObject *object, icalcomponent *comp,
- icalvcal_defaults *defaults)
-{
- icalproperty_kind kind = (icalproperty_kind)icaltype;
- icalproperty *prop;
- icalvalue *value;
- icalvalue_kind value_kind;
- char *s;
- int free_string;
-
- prop = icalproperty_new(kind);
-
- value_kind = icalenum_property_kind_to_value_kind (icalproperty_isa(prop));
-
- s = get_string_value (object, &free_string);
-
- value = icalvalue_new_from_string(value_kind,s);
-
- if (free_string)
- deleteStr (s);
-
- icalproperty_set_value(prop,value);
-
- return (void*)prop;
-}
-
-
-/* My extraction program screwed up, so this table does not have all
-of the vcal properties in it. I didn't feel like re-doing the entire
-table, so you'll have to find the missing properties the hard way --
-the code will assert */
-
-struct conversion_table_struct conversion_table[] =
-{
-{VCCalProp, COMPONENT, comp, ICAL_VCALENDAR_COMPONENT},
-{VCTodoProp, COMPONENT, comp, ICAL_VTODO_COMPONENT},
-{VCEventProp, COMPONENT, comp, ICAL_VEVENT_COMPONENT},
-
-{VCAAlarmProp, COMPONENT, alarm_comp, ICAL_XAUDIOALARM_COMPONENT},
-{VCDAlarmProp, COMPONENT, alarm_comp, ICAL_XDISPLAYALARM_COMPONENT},
-{VCMAlarmProp, COMPONENT, alarm_comp, ICAL_XEMAILALARM_COMPONENT},
-{VCPAlarmProp, COMPONENT, alarm_comp, ICAL_XPROCEDUREALARM_COMPONENT},
-
-/* These can all be converted directly by parsing the string into a libical
- value. */
-{VCClassProp, PROPERTY, dc_prop, ICAL_CLASS_PROPERTY},
-{VCDescriptionProp, PROPERTY, dc_prop, ICAL_DESCRIPTION_PROPERTY},
-{VCAttendeeProp, PROPERTY, dc_prop, ICAL_ATTENDEE_PROPERTY},
-{VCDTendProp, PROPERTY, dc_prop, ICAL_DTEND_PROPERTY},
-{VCDTstartProp, PROPERTY, dc_prop, ICAL_DTSTART_PROPERTY},
-{VCDueProp, PROPERTY, dc_prop, ICAL_DUE_PROPERTY},
-{VCLocationProp, PROPERTY, dc_prop, ICAL_LOCATION_PROPERTY},
-{VCSummaryProp, PROPERTY, dc_prop, ICAL_SUMMARY_PROPERTY},
-{VCUniqueStringProp, PROPERTY, dc_prop, ICAL_UID_PROPERTY},
-{VCURLProp, PROPERTY, dc_prop, ICAL_URL_PROPERTY},
-{VCPriorityProp, PROPERTY, dc_prop, ICAL_PRIORITY_PROPERTY},
-
-/* These can contain multiple values, which are separated in ';' in vCalendar
- but ',' in iCalendar. */
-{VCCategoriesProp, PROPERTY, multivalued_prop,ICAL_CATEGORIES_PROPERTY},
-{VCRDateProp, PROPERTY, multivalued_prop,ICAL_RDATE_PROPERTY},
-{VCExpDateProp, PROPERTY, multivalued_prop,ICAL_EXDATE_PROPERTY},
-
-/* These can be in floating time in vCalendar, but must be in UTC in iCalendar.
- */
-{VCDCreatedProp, PROPERTY, utc_datetime_prop,ICAL_CREATED_PROPERTY},
-{VCLastModifiedProp, PROPERTY, utc_datetime_prop,ICAL_LASTMODIFIED_PROPERTY},
-{VCCompletedProp, PROPERTY, utc_datetime_prop,ICAL_COMPLETED_PROPERTY},
-
-{VCTranspProp, PROPERTY, transp_prop, ICAL_TRANSP_PROPERTY},
-{VCSequenceProp, PROPERTY, sequence_prop, ICAL_SEQUENCE_PROPERTY},
-{VCStatusProp, PROPERTY, status_prop, ICAL_STATUS_PROPERTY},
-{VCRRuleProp, PROPERTY, rule_prop, ICAL_RRULE_PROPERTY},
-{VCXRuleProp, PROPERTY, rule_prop, ICAL_EXRULE_PROPERTY},
-
-{VCRSVPProp, UNSUPPORTED, rsvp_parameter,ICAL_RSVP_PARAMETER },
-{VCEncodingProp, UNSUPPORTED, parameter, ICAL_ENCODING_PARAMETER},
-{VCRoleProp, UNSUPPORTED, parameter, ICAL_ROLE_PARAMETER},
-
-/* We don't want the old VERSION or PRODID properties copied across as they
- are now incorrect. New VERSION & PRODID properties are added instead. */
-{VCVersionProp, IGNORE, 0, 0},
-{VCProdIdProp, IGNORE, 0, 0},
-
-/* We ignore DAYLIGHT and TZ properties of the toplevel object, since we can't
- really do much with them. */
-{VCDayLightProp, IGNORE, 0, 0},
-{VCTimeZoneProp, IGNORE, 0, 0},
-
-/* These are all alarm properties. We handle these when the alarm component
- is created, so we ignore them when doing the automatic conversions.
- "TYPE" is used in AALARM, but doesn't seem to have a name in vobject.h. */
-{"TYPE", IGNORE,0, 0},
-{VCRunTimeProp, IGNORE,0, 0},
-{VCSnoozeTimeProp, IGNORE,0, 0},
-{VCRepeatCountProp, IGNORE,0, 0},
-{VCValueProp, IGNORE,0, 0},
-{VCAudioContentProp, IGNORE,0, 0},
-{VCProcedureNameProp, IGNORE,0, 0},
-{VCDisplayStringProp, IGNORE,0, 0},
-{VCEmailAddressProp, IGNORE,0, 0},
-{VCNoteProp, IGNORE,0, 0},
-
-{VCQuotedPrintableProp,UNSUPPORTED,0, 0},
-{VC7bitProp, UNSUPPORTED,0, 0},
-{VC8bitProp, UNSUPPORTED,0, 0},
-{VCAdditionalNamesProp,UNSUPPORTED,0, 0},
-{VCAdrProp, UNSUPPORTED,0, 0},
-{VCAgentProp, UNSUPPORTED,0, 0},
-{VCAIFFProp, UNSUPPORTED,0, 0},
-{VCAOLProp, UNSUPPORTED,0, 0},
-{VCAppleLinkProp, UNSUPPORTED,0, 0},
-{VCAttachProp, UNSUPPORTED,0, 0},
-{VCATTMailProp, UNSUPPORTED,0, 0},
-{VCAVIProp, UNSUPPORTED,0, 0},
-{VCBase64Prop, UNSUPPORTED,0, 0},
-{VCBBSProp, UNSUPPORTED,0, 0},
-{VCBirthDateProp, UNSUPPORTED,0, 0},
-{VCBMPProp, UNSUPPORTED,0, 0},
-{VCBodyProp, UNSUPPORTED,0, 0},
-{VCCaptionProp, UNSUPPORTED,0, 0},
-{VCCarProp, UNSUPPORTED,0, 0},
-{VCCellularProp, UNSUPPORTED,0, 0},
-{VCCGMProp, UNSUPPORTED,0, 0},
-{VCCharSetProp, UNSUPPORTED,0, 0},
-{VCCIDProp, UNSUPPORTED,0, 0},
-{VCCISProp, UNSUPPORTED,0, 0},
-{VCCityProp, UNSUPPORTED,0, 0},
-{VCCommentProp, UNSUPPORTED,0, 0},
-{VCCountryNameProp, UNSUPPORTED,0, 0},
-{VCDataSizeProp, UNSUPPORTED,0, 0},
-{VCDeliveryLabelProp, UNSUPPORTED,0, 0},
-{VCDIBProp, UNSUPPORTED,0, 0},
-{VCDomesticProp, UNSUPPORTED,0, 0},
-{VCEndProp, UNSUPPORTED,0, 0},
-{VCEWorldProp, UNSUPPORTED,0, 0},
-{VCExNumProp, UNSUPPORTED,0, 0},
-{VCExpectProp, UNSUPPORTED,0, 0},
-{VCFamilyNameProp, UNSUPPORTED,0, 0},
-{VCFaxProp, UNSUPPORTED,0, 0},
-{VCFullNameProp, UNSUPPORTED,0, 0},
-{VCGeoProp, UNSUPPORTED,0, 0},
-{VCGeoLocationProp, UNSUPPORTED,0, 0},
-{VCGIFProp, UNSUPPORTED,0, 0},
-{VCGivenNameProp, UNSUPPORTED,0, 0},
-{VCGroupingProp, UNSUPPORTED,0, 0},
-{VCHomeProp, UNSUPPORTED,0, 0},
-{VCIBMMailProp, UNSUPPORTED,0, 0},
-{VCInlineProp, UNSUPPORTED,0, 0},
-{VCInternationalProp, UNSUPPORTED,0, 0},
-{VCInternetProp, UNSUPPORTED,0, 0},
-{VCISDNProp, UNSUPPORTED,0, 0},
-{VCJPEGProp, UNSUPPORTED,0, 0},
-{VCLanguageProp, UNSUPPORTED,0, 0},
-{VCLastRevisedProp, UNSUPPORTED,0, 0},
-{VCLogoProp, UNSUPPORTED,0, 0},
-{VCMailerProp, UNSUPPORTED,0, 0},
-{VCMCIMailProp, UNSUPPORTED,0, 0},
-{VCMessageProp, UNSUPPORTED,0, 0},
-{VCMETProp, UNSUPPORTED,0, 0},
-{VCModemProp, UNSUPPORTED,0, 0},
-{VCMPEG2Prop, UNSUPPORTED,0, 0},
-{VCMPEGProp, UNSUPPORTED,0, 0},
-{VCMSNProp, UNSUPPORTED,0, 0},
-{VCNamePrefixesProp, UNSUPPORTED,0, 0},
-{VCNameProp, UNSUPPORTED,0, 0},
-{VCNameSuffixesProp, UNSUPPORTED,0, 0},
-{VCOrgNameProp, UNSUPPORTED,0, 0},
-{VCOrgProp, UNSUPPORTED,0, 0},
-{VCOrgUnit2Prop, UNSUPPORTED,0, 0},
-{VCOrgUnit3Prop, UNSUPPORTED,0, 0},
-{VCOrgUnit4Prop, UNSUPPORTED,0, 0},
-{VCOrgUnitProp, UNSUPPORTED,0, 0},
-{VCPagerProp, UNSUPPORTED,0, 0},
-{VCParcelProp, UNSUPPORTED,0, 0},
-{VCPartProp, UNSUPPORTED,0, 0},
-{VCPCMProp, UNSUPPORTED,0, 0},
-{VCPDFProp, UNSUPPORTED,0, 0},
-{VCPGPProp, UNSUPPORTED,0, 0},
-{VCPhotoProp, UNSUPPORTED,0, 0},
-{VCPICTProp, UNSUPPORTED,0, 0},
-{VCPMBProp, UNSUPPORTED,0, 0},
-{VCPostalBoxProp, UNSUPPORTED,0, 0},
-{VCPostalCodeProp, UNSUPPORTED,0, 0},
-{VCPostalProp, UNSUPPORTED,0, 0},
-{VCPowerShareProp, UNSUPPORTED,0, 0},
-{VCPreferredProp, UNSUPPORTED,0, 0},
-{VCProdigyProp, UNSUPPORTED,0, 0},
-{VCPronunciationProp, UNSUPPORTED,0, 0},
-{VCPSProp, UNSUPPORTED,0, 0},
-{VCPublicKeyProp, UNSUPPORTED,0, 0},
-{VCQPProp, UNSUPPORTED,0, 0},
-{VCQuickTimeProp, UNSUPPORTED,0, 0},
-{VCRegionProp, UNSUPPORTED,0, 0},
-{VCResourcesProp, UNSUPPORTED,0, 0},
-{VCRNumProp, UNSUPPORTED,0, 0},
-{VCStartProp, UNSUPPORTED,0, 0},
-{VCStreetAddressProp, UNSUPPORTED,0, 0},
-{VCSubTypeProp, UNSUPPORTED,0, 0},
-{VCTelephoneProp, UNSUPPORTED,0, 0},
-{VCTIFFProp, UNSUPPORTED,0, 0},
-{VCTitleProp, UNSUPPORTED,0, 0},
-{VCTLXProp, UNSUPPORTED,0, 0},
-{VCURLValueProp, UNSUPPORTED,0, 0},
-{VCVideoProp, UNSUPPORTED,0, 0},
-{VCVoiceProp, UNSUPPORTED,0, 0},
-{VCWAVEProp, UNSUPPORTED,0, 0},
-{VCWMFProp, UNSUPPORTED,0, 0},
-{VCWorkProp, UNSUPPORTED,0, 0},
-{VCX400Prop, UNSUPPORTED,0, 0},
-{VCX509Prop, UNSUPPORTED,0, 0},
-
-{0,0,0,0}
-};
-
-
-#if 0
- switch (vObjectValueType(object)) {
- case VCVT_USTRINGZ: {
- char c;
- char *t,*s;
- s = t = fakeCString(vObjectUStringZValue(object));
- printf(" ustringzstring:%s\n",s);
- deleteStr(s);
- break;
- }
- case VCVT_STRINGZ: {
- char c;
- const char *s = vObjectStringZValue(object);
- printf(" stringzstring:%s\n",s);
- break;
- }
- case VCVT_UINT:
- {
- int i = vObjectIntegerValue(object);
- printf(" int:%d\n",i);
- break;
- }
- case VCVT_ULONG:
- {
- long l = vObjectLongValue(object);
- printf(" int:%d\n",l);
- break;
- }
- case VCVT_VOBJECT:
- {
- printf("ERROR, should not get here\n");
- break;
- }
- case VCVT_RAW:
- case 0:
- default:
- break;
- }
-
-#endif