/*====================================================================== 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 ======================================================================*/ #include "icalvcal.h" #include enum datatype { COMPONENT, PROPERTY, PARAMETER, UNSUPPORTED }; struct conversion_table_struct { char* vcalname; enum datatype type; void* (*conversion_func)(int icaltype, VObject *o); int icaltype; }; struct conversion_table_struct conversion_table[]; void* dc_prop(int icaltype, VObject *object); static void traverse_objects(VObject *object,icalcomponent* last_comp, icalproperty* last_prop) { 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; } } if (conversion_table[i].vcalname == 0){ /* Handle X properties */ if(strncmp(name, "X-",2) == 0){ icalproperty* prop = (icalproperty*)dc_prop(ICAL_X_PROPERTY,object); 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)); icalcomponent_add_component(last_comp,subc); assert(subc!=0); 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)); 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_UNKVCALPROP ); error_prop = icalproperty_new_xlicerror(temp); icalproperty_add_parameter(error_prop, error_param); icalcomponent_add_property(last_comp,error_prop); 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){ traverse_objects(eachProp,subc,last_prop); } else { traverse_objects(eachProp,last_comp,last_prop); } } } icalcomponent* icalvcal_convert(VObject *object){ char* name = (char*)vObjectName(object); icalcomponent* container = icalcomponent_new(ICAL_XROOT_COMPONENT); icalcomponent* root; 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 */ } traverse_objects(object,container,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); return root; } /* 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_kind kind = (icalcomponent_kind)icaltype; icalcomponent* c = icalcomponent_new(kind); return (void* )c; } void* alarm_comp(int icaltype, VObject *o) { icalcomponent_kind kind = (icalcomponent_kind)icaltype; icalcomponent* c = icalcomponent_new(kind); return (void*)c; } void* daylight_comp(int icaltype, VObject *o) { icalcomponent_kind kind = (icalcomponent_kind)icaltype; icalcomponent* c = icalcomponent_new(kind); return (void*)c; } void* timezone_comp(int icaltype, VObject *o) { icalcomponent_kind kind = (icalcomponent_kind)icaltype; icalcomponent* c = icalcomponent_new(kind); return (void*)c; } /* These #defines indicate conversion routines that are not defined yet. */ #define categories_prop 0 #define transp_prop 0 #define status_prop 0 #define parameter 0 #define rsvp_parameter 0 /* directly convertable property. The string representation of vcal is the same as ical */ void* dc_prop(int icaltype, VObject *object) { icalproperty_kind kind = (icalproperty_kind)icaltype; icalproperty *prop; icalvalue *value; icalvalue_kind value_kind; char *s,*t=0; prop = icalproperty_new(kind); value_kind = icalenum_property_kind_to_value_kind( icalproperty_isa(prop)); switch (vObjectValueType(object)) { case VCVT_USTRINGZ: { s = t = fakeCString(vObjectUStringZValue(object)); break; } case VCVT_STRINGZ: { s = (char*)vObjectStringZValue(object); break; } } value = icalvalue_new_from_string(value_kind,s); if(t!=0){ deleteStr(t); } 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}, {VCDayLightProp, COMPONENT, daylight_comp,0}, {VCTimeZoneProp, COMPONENT, timezone_comp, ICAL_VTIMEZONE_COMPONENT}, {VCProdIdProp, PROPERTY, dc_prop, ICAL_PRODID_PROPERTY}, {VCClassProp, PROPERTY, dc_prop, ICAL_CLASS_PROPERTY}, {VCDCreatedProp, PROPERTY, dc_prop, ICAL_CREATED_PROPERTY}, {VCDescriptionProp, PROPERTY, dc_prop, ICAL_DESCRIPTION_PROPERTY}, {VCAttendeeProp, PROPERTY, dc_prop, ICAL_ATTENDEE_PROPERTY}, {VCCategoriesProp, PROPERTY, categories_prop,ICAL_CATEGORIES_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}, {VCVersionProp, PROPERTY, dc_prop, ICAL_VERSION_PROPERTY}, {VCTranspProp, PROPERTY, transp_prop, ICAL_TRANSP_PROPERTY}, {VCUniqueStringProp, PROPERTY, dc_prop, ICAL_UID_PROPERTY}, {VCURLProp, PROPERTY, dc_prop, ICAL_URL_PROPERTY}, {VCLastModifiedProp, PROPERTY, dc_prop, ICAL_LASTMODIFIED_PROPERTY}, {VCSequenceProp, PROPERTY, dc_prop, ICAL_SEQUENCE_PROPERTY}, {VCPriorityProp, PROPERTY, dc_prop, ICAL_PRIORITY_PROPERTY}, {VCStatusProp, PROPERTY, status_prop, ICAL_STATUS_PROPERTY}, {VCRSVPProp, UNSUPPORTED, rsvp_parameter,ICAL_RSVP_PARAMETER }, {VCEncodingProp, UNSUPPORTED, parameter, ICAL_ENCODING_PARAMETER}, {VCRoleProp, UNSUPPORTED, parameter, ICAL_ROLE_PARAMETER}, {VCStatusProp, UNSUPPORTED, parameter, ICAL_STATUS_PROPERTY}, {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}, {VCAudioContentProp, 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}, {VCCompletedProp, UNSUPPORTED,0, 0}, {VCCountryNameProp, UNSUPPORTED,0, 0}, {VCDataSizeProp, UNSUPPORTED,0, 0}, {VCDeliveryLabelProp, UNSUPPORTED,0, 0}, {VCDIBProp, UNSUPPORTED,0, 0}, {VCDisplayStringProp, UNSUPPORTED,0, 0}, {VCDomesticProp, UNSUPPORTED,0, 0}, {VCEmailAddressProp, UNSUPPORTED,0, 0}, {VCEndProp, UNSUPPORTED,0, 0}, {VCEWorldProp, UNSUPPORTED,0, 0}, {VCExNumProp, UNSUPPORTED,0, 0}, {VCExpDateProp, 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}, {VCNoteProp, 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}, {VCProcedureNameProp, 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}, {VCRDateProp, UNSUPPORTED,0, 0}, {VCRegionProp, UNSUPPORTED,0, 0}, {VCRepeatCountProp, UNSUPPORTED,0, 0}, {VCResourcesProp, UNSUPPORTED,0, 0}, {VCRNumProp, UNSUPPORTED,0, 0}, {VCRRuleProp, UNSUPPORTED,0, 0}, {VCRunTimeProp, UNSUPPORTED,0, 0}, {VCSnoozeTimeProp, 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}, {VCValueProp, 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}, {VCXRuleProp, 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