diff options
Diffstat (limited to 'libical/src/libicalvcal/icalvcal.c')
-rw-r--r-- | libical/src/libicalvcal/icalvcal.c | 1636 |
1 files changed, 0 insertions, 1636 deletions
diff --git a/libical/src/libicalvcal/icalvcal.c b/libical/src/libicalvcal/icalvcal.c deleted file mode 100644 index f070c9cd57..0000000000 --- a/libical/src/libicalvcal/icalvcal.c +++ /dev/null @@ -1,1636 +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 void 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"); - assert(0); - return; - } - - 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 { - assert(0); - return; - } - - } 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){ - icalvcal_traverse_objects(eachProp,subc,last_prop,defaults); - - } else { - icalvcal_traverse_objects(eachProp,last_comp,last_prop,defaults); - } - } -} - -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 - - icalvcal_traverse_objects(object,container,0,defaults); - - /* 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 |