static icalproperty * ical_property_add_x_property_value(icalcomponent *parent, const char *propname, const char *value) { icalproperty *prop; icalvalue *icalText; /* Sanity checks */ if (!parent) return NULL; if (!propname) return NULL; if (!value) return NULL; icalText = icalvalue_new_text(value); prop = icalproperty_new_x(icalvalue_as_ical_string(icalText)); icalvalue_free(icalText); icalproperty_set_x_name(prop, propname); icalcomponent_add_property(parent, prop); return prop; }
/* * Add the proper XML element for an iCalendar value. */ static void icalproperty_add_value_as_xml_element(xmlNodePtr xprop, icalproperty *prop) { const char *type, *str = NULL; xmlNodePtr xtype; const icalvalue *value; char buf[40]; /* Add type */ type = lcase(icalmemory_tmp_copy( icalproperty_value_kind_as_string(prop))); xtype = xmlNewChild(xprop, NULL, BAD_CAST type, NULL); /* Add value */ value = icalproperty_get_value(prop); switch (icalvalue_isa(value)) { case ICAL_DATE_VALUE: str = icaltime_as_iso_string(icalvalue_get_date(value)); break; case ICAL_DATETIME_VALUE: str = icaltime_as_iso_string(icalvalue_get_datetime(value)); break; case ICAL_DATETIMEPERIOD_VALUE: { struct icaldatetimeperiodtype dtp = icalvalue_get_datetimeperiod(value); if (!icaltime_is_null_time(dtp.time)) { str = icaltime_as_iso_string(dtp.time); break; } else { icalperiodtype_add_as_xml_element(xtype, dtp.period); return; } } case ICAL_GEO_VALUE: { struct icalgeotype geo = icalvalue_get_geo(value); snprintf(buf, sizeof(buf), "%f", geo.lat); xmlNewTextChild(xtype, NULL, BAD_CAST "latitude", BAD_CAST buf); snprintf(buf, sizeof(buf), "%f", geo.lon); xmlNewTextChild(xtype, NULL, BAD_CAST "longitude", BAD_CAST buf); return; } case ICAL_PERIOD_VALUE: icalperiodtype_add_as_xml_element(xtype, icalvalue_get_period(value)); return; case ICAL_RECUR_VALUE: { struct icalrecurrencetype recur = icalvalue_get_recur(value); icalrecurrencetype_add_as_xxx(&recur, xtype, NULL, &icalrecur_add_string_as_xml_element); return; } case ICAL_REQUESTSTATUS_VALUE: { struct icalreqstattype stat = icalvalue_get_requeststatus(value); if (!stat.desc) stat.desc = icalenum_reqstat_desc(stat.code); snprintf(buf, sizeof(buf), "%u.%u", icalenum_reqstat_major(stat.code), icalenum_reqstat_minor(stat.code)); xmlNewTextChild(xtype, NULL, BAD_CAST "code", BAD_CAST buf); xmlNewTextChild(xtype, NULL, BAD_CAST "description", BAD_CAST stat.desc); if (stat.debug) xmlNewTextChild(xtype, NULL, BAD_CAST "data", BAD_CAST stat.debug); return; } case ICAL_TRIGGER_VALUE: { struct icaltriggertype trig = icalvalue_get_trigger(value); if (!icaltime_is_null_time(trig.time)) str = icaltime_as_iso_string(trig.time); else str = icaldurationtype_as_ical_string(trig.duration); break; } case ICAL_UTCOFFSET_VALUE: str = icalvalue_utcoffset_as_iso_string(value); break; default: str = icalvalue_as_ical_string(value); switch (icalproperty_isa(prop)) { case ICAL_CATEGORIES_PROPERTY: case ICAL_RESOURCES_PROPERTY: case ICAL_POLLPROPERTIES_PROPERTY: if (strchr(str, ',')) { /* Handle multi-valued properties */ tok_t tok; tok_init(&tok, str, ",", TOK_TRIMLEFT|TOK_TRIMRIGHT|TOK_EMPTY); str = tok_next(&tok); xmlAddChild(xtype, xmlNewText(BAD_CAST str)); while ((str = tok_next(&tok))) { if (*str) { xtype = xmlNewChild(xprop, NULL, BAD_CAST type, NULL); xmlAddChild(xtype, xmlNewText(BAD_CAST str)); } } tok_fini(&tok); return; } default: break; } break; } if (str) xmlAddChild(xtype, xmlNewText(BAD_CAST str)); }
void test_recur_file() { icalset *cin = 0; struct icaltimetype next; icalcomponent *itr; icalproperty *desc, *dtstart, *rrule; struct icalrecurrencetype recur; icalrecur_iterator* ritr; time_t tt; char* file; int num_recurs_found = 0; icalfileset_options options = {O_RDONLY, 0644, 0}; icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL); #ifndef WIN32 signal(SIGALRM,sig_alrm); #endif file = getenv("ICAL_RECUR_FILE"); if (!file) file = TEST_DATADIR "/recur.txt"; #ifndef WIN32 alarm(15); /* to get file lock */ #endif cin = icalset_new(ICAL_FILE_SET, file, &options); #ifndef WIN32 alarm(0); #endif ok("opening file with recurring events", (cin!=NULL)); assert(cin!=NULL); for (itr = icalfileset_get_first_component(cin); itr != 0; itr = icalfileset_get_next_component(cin)){ int badcomp = 0; int expected_events = 0; char msg[128]; struct icaltimetype start = icaltime_null_time(); struct icaltimetype startmin = icaltime_from_timet(1,0); struct icaltimetype endmax = icaltime_null_time(); const char *desc_str = "malformed component"; desc = icalcomponent_get_first_property(itr,ICAL_DESCRIPTION_PROPERTY); dtstart = icalcomponent_get_first_property(itr,ICAL_DTSTART_PROPERTY); rrule = icalcomponent_get_first_property(itr,ICAL_RRULE_PROPERTY); if (desc) { desc_str = icalproperty_get_description(desc); } ok((char*)desc_str, !(desc == 0 || dtstart == 0 || rrule == 0)); if (desc == 0 || dtstart == 0 || rrule == 0) { badcomp = 1; if (VERBOSE) { printf("\n******** Error in input component ********\n"); printf("The following component is malformed:\n %s\n", desc_str); } continue; } if (VERBOSE) { printf("\n\n#### %s\n",desc_str); printf("#### %s\n",icalvalue_as_ical_string(icalproperty_get_value(rrule))); } recur = icalproperty_get_rrule(rrule); start = icalproperty_get_dtstart(dtstart); ritr = icalrecur_iterator_new(recur,start); tt = icaltime_as_timet(start); if (VERBOSE) printf("#### %s\n",ctime(&tt )); icalrecur_iterator_free(ritr); for(ritr = icalrecur_iterator_new(recur,start), next = icalrecur_iterator_next(ritr); !icaltime_is_null_time(next); next = icalrecur_iterator_next(ritr)){ tt = icaltime_as_timet(next); if (VERBOSE) printf(" %s",ctime(&tt )); } icalrecur_iterator_free(ritr); num_recurs_found = 0; expected_events = get_expected_numevents(itr); icalcomponent_foreach_recurrence(itr, startmin, endmax, recur_callback, &num_recurs_found); sprintf(msg," expecting total of %d events", expected_events); int_is(msg, num_recurs_found, expected_events); } icalset_free(cin); }
/* * Construct a JSON array for an iCalendar property. */ static json_t *icalproperty_as_json_array(icalproperty *prop) { icalproperty_kind prop_kind; const char *x_name, *property_name = NULL; icalparameter *param; const char *type = NULL; const icalvalue *value; json_t *jprop, *jparams; if (!prop) return NULL; prop_kind = icalproperty_isa(prop); x_name = icalproperty_get_x_name(prop); if (prop_kind == ICAL_X_PROPERTY && x_name) property_name = x_name; else property_name = icalproperty_kind_to_string(prop_kind); if (!property_name) { icalerror_warn("Got a property of an unknown kind."); return NULL; } /* Create property array */ jprop = json_array(); /* Add property name */ json_array_append_new(jprop, json_string(lcase(icalmemory_tmp_copy(property_name)))); /* Add parameters */ jparams = json_object(); for (param = icalproperty_get_first_parameter(prop, ICAL_ANY_PARAMETER); param != 0; param = icalproperty_get_next_parameter(prop, ICAL_ANY_PARAMETER)) { if (icalparameter_isa(param) == ICAL_VALUE_PARAMETER) continue; icalparameter_as_json_object_member(param, jparams); } json_array_append_new(jprop, jparams); /* Add type */ type = icalproperty_value_kind_as_string(prop); json_array_append_new(jprop, json_string(lcase(icalmemory_tmp_copy(type)))); /* Add value */ value = icalproperty_get_value(prop); if (value) { switch (icalproperty_isa(prop)) { case ICAL_CATEGORIES_PROPERTY: case ICAL_RESOURCES_PROPERTY: case ICAL_POLLPROPERTIES_PROPERTY: if (icalvalue_isa(value) == ICAL_TEXT_VALUE) { /* Handle multi-valued properties */ const char *str = icalvalue_as_ical_string(value); tok_t tok; tok_init(&tok, str, ",", TOK_TRIMLEFT|TOK_TRIMRIGHT|TOK_EMPTY); while ((str = tok_next(&tok))) { if (*str) json_array_append_new(jprop, json_string(str)); } tok_fini(&tok); break; } default: json_array_append_new(jprop, icalvalue_as_json_object(value)); break; } } return jprop; }
/* * Construct the proper JSON object for an iCalendar value. */ static json_t *icalvalue_as_json_object(const icalvalue *value) { const char *str = NULL; json_t *obj; switch (icalvalue_isa(value)) { case ICAL_BOOLEAN_VALUE: return json_boolean(icalvalue_get_integer(value)); case ICAL_DATE_VALUE: str = icaltime_as_iso_string(icalvalue_get_date(value)); break; case ICAL_DATETIME_VALUE: str = icaltime_as_iso_string(icalvalue_get_datetime(value)); break; case ICAL_DATETIMEPERIOD_VALUE: { struct icaldatetimeperiodtype dtp = icalvalue_get_datetimeperiod(value); if (!icaltime_is_null_time(dtp.time)) str = icaltime_as_iso_string(dtp.time); else str = icalperiodtype_as_json_string(dtp.period); break; } case ICAL_FLOAT_VALUE: return json_real(icalvalue_get_float(value)); case ICAL_GEO_VALUE: { struct icalgeotype geo = icalvalue_get_geo(value); obj = json_array(); json_array_append_new(obj, json_real(geo.lat)); json_array_append_new(obj, json_real(geo.lon)); return obj; } case ICAL_INTEGER_VALUE: return json_integer(icalvalue_get_integer(value)); case ICAL_PERIOD_VALUE: str = icalperiodtype_as_json_string(icalvalue_get_period(value)); break; case ICAL_RECUR_VALUE: { struct icalrecurrencetype recur = icalvalue_get_recur(value); obj = json_object(); icalrecurrencetype_add_as_xxx(&recur, obj, &icalrecur_add_int_to_json_object, &icalrecur_add_string_to_json_object); return obj; } case ICAL_REQUESTSTATUS_VALUE: return icalreqstattype_as_json_array(icalvalue_get_requeststatus(value)); case ICAL_TRIGGER_VALUE: { struct icaltriggertype trig = icalvalue_get_trigger(value); if (!icaltime_is_null_time(trig.time)) str = icaltime_as_iso_string(trig.time); else str = icaldurationtype_as_ical_string(trig.duration); break; } case ICAL_UTCOFFSET_VALUE: str = icalvalue_utcoffset_as_iso_string(value); break; default: str = icalvalue_as_ical_string(value); break; } return (str ? json_string(str) : NULL); }
const char* icallangbind_property_eval_string(icalproperty* prop, char* sep) { char tmp[25]; size_t buf_size = 1024; char* buf = icalmemory_new_buffer(buf_size); char* buf_ptr = buf; icalparameter *param; icalvalue* value; if( prop == 0) { return 0; } APPENDS("{ "); value = icalproperty_get_value(prop); APPENDS(" 'name' "); APPENDS(sep); APPENDC('\''); APPENDS(icalproperty_kind_to_string(icalproperty_isa(prop))); APPENDC('\''); if(value) { APPENDS(", 'value_type' "); APPENDS(sep); APPENDC('\''); APPENDS(icalvalue_kind_to_string(icalvalue_isa(value))); APPENDC('\''); } APPENDS(", 'pid' "); APPENDS(sep); APPENDC('\''); snprintf(tmp,25,"%p",prop); APPENDS(tmp); APPENDC('\''); if(value) { switch (icalvalue_isa(value)) { case ICAL_ATTACH_VALUE: case ICAL_BINARY_VALUE: case ICAL_NO_VALUE: { icalerror_set_errno(ICAL_INTERNAL_ERROR); break; } default: { const char* str = icalvalue_as_ical_string(value); char* copy = (char*) malloc(strlen(str)+1); const char *i; char *j; if(copy ==0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); break; } /* Remove any newlines */ for(j=copy, i = str; *i != 0; j++,i++) { if(*i=='\n') { i++; } *j = *i; } *j = 0; APPENDS(", 'value'"); APPENDS(sep); APPENDC('\''); APPENDS(copy); APPENDC('\''); free(copy); break; } } } /* Add Parameters */ for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); param != 0; param = icalproperty_get_next_parameter(prop,ICAL_ANY_PARAMETER)) { const char* str = icalparameter_as_ical_string(param); char *copy = icalmemory_tmp_copy(str); char *v; if(copy == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); continue; } v = strchr(copy,'='); if(v == 0) { continue; } *v = 0; v++; APPENDS(", "); APPENDC('\''); APPENDS(copy); APPENDC('\''); APPENDS(sep); APPENDC('\''); APPENDS(v); APPENDC('\''); } APPENDC('}'); icalmemory_add_tmp_buffer(buf); return buf; }
int main(int argc, char *argv[]) { icalset *cin; struct icaltimetype next; icalcomponent *itr; icalproperty *desc, *dtstart, *rrule; struct icalrecurrencetype recur; icalrecur_iterator* ritr; time_t tt; char* file; icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL); #ifndef WIN32 signal(SIGALRM,sig_alrm); #endif if (argc <= 1) { file = "../../test-data/recur.txt"; } else if (argc == 2) { file = argv[1]; } else { fprintf(stderr,"usage: recur [input file]\n"); exit(1); } #ifndef WIN32 alarm(300); /* to get file lock */ #endif cin = icalfileset_new(file); #ifndef WIN32 alarm(0); #endif if(cin == 0) { fprintf(stderr,"recur: can't open file %s\n",file); exit(1); } for (itr = icalfileset_get_first_component(cin); itr != 0; itr = icalfileset_get_next_component(cin)) { struct icaltimetype start = icaltime_from_timet(1,0); struct icaltimetype end = icaltime_today(); desc = icalcomponent_get_first_property(itr,ICAL_DESCRIPTION_PROPERTY); dtstart = icalcomponent_get_first_property(itr,ICAL_DTSTART_PROPERTY); rrule = icalcomponent_get_first_property(itr,ICAL_RRULE_PROPERTY); if (desc == 0 || dtstart == 0 || rrule == 0) { printf("\n******** Error in input component ********\n"); printf("The following component is malformed:\n %s\n", icalcomponent_as_ical_string(itr)); continue; } printf("\n\n#### %s\n",icalproperty_get_description(desc)); printf("#### %s\n",icalvalue_as_ical_string(icalproperty_get_value(rrule))); recur = icalproperty_get_rrule(rrule); start = icalproperty_get_dtstart(dtstart); ritr = icalrecur_iterator_new(recur,start); tt = icaltime_as_timet(start); printf("#### %s\n",ctime(&tt )); icalrecur_iterator_free(ritr); for(ritr = icalrecur_iterator_new(recur,start), next = icalrecur_iterator_next(ritr); !icaltime_is_null_time(next); next = icalrecur_iterator_next(ritr)) { tt = icaltime_as_timet(next); printf(" %s",ctime(&tt )); } icalrecur_iterator_free(ritr); icalcomponent_foreach_recurrence(itr, start, end, recur_callback, NULL); } icalset_free(cin); icaltimezone_free_builtin_timezones(); icalmemory_free_ring(); free_zone_directory(); return 0; }