18#include "icalproperty_p.h"
20#include "icalerror_p.h"
30struct icalproperty_impl {
32 icalproperty_kind kind;
34 icalpvl_list parameters;
35 icalpvl_elem parameter_iterator;
37 icalcomponent *parent;
41LIBICAL_ICAL_EXPORT
struct icalproperty_impl *icalproperty_new_impl(icalproperty_kind kind)
54 memset(prop, 0,
sizeof(icalproperty));
56 strcpy(prop->id,
"prop");
59 prop->parameters = icalpvl_newlist();
65static ICAL_GLOBAL_VAR
bool icalprop_allow_empty_properties =
false;
69 icalprop_allow_empty_properties = enable;
74 return icalprop_allow_empty_properties;
81 while ((vp = va_arg(args,
void *)) != 0) {
93 if (kind == ICAL_NO_PROPERTY) {
97 return (icalproperty *)icalproperty_new_impl(kind);
105 icalerror_check_arg_rz((old != 0),
"old");
106 clone = icalproperty_new_impl(old->kind);
107 icalerror_check_arg_rz((clone != 0),
"clone");
109 if (old->value != 0) {
113 if (old->x_name != 0) {
116 if (clone->x_name == 0) {
123 for (p = icalpvl_head(old->parameters); p != 0; p = icalpvl_next(p)) {
132 icalpvl_push(clone->parameters, param);
140 size_t buf_size = 1024;
147 icalerror_check_arg_rz((str != 0),
"str");
186 icalparameter *param;
188 icalerror_check_arg_rv((p != 0),
"prop");
190 if (p->parent != 0) {
199 while ((param = icalpvl_pop(p->parameters)) != 0) {
203 icalpvl_free(p->parameters);
206 p->kind = ICAL_NO_PROPERTY;
208 p->parameter_iterator = 0;
218static const size_t MAX_LINE_LEN = 75;
220static char *get_next_line_start(
char *line_start,
size_t chars_left)
226 if (chars_left < MAX_LINE_LEN) {
227 return line_start + chars_left;
233 pos = line_start + MAX_LINE_LEN - 2;
234 while (pos > line_start) {
235 if (*pos ==
';' || *pos ==
':' || *pos ==
' ') {
244 pos = line_start + MAX_LINE_LEN - 1;
245 while (pos > line_start) {
247 if ((*pos & 128) == 0) {
252 if ((*pos & 192) == 192) {
262 return line_start + MAX_LINE_LEN - 1;
271static char *fold_property_line(
char *text)
273 size_t buf_size, len;
275 char *buf, *buf_ptr, *line_start, *next_line_start;
287 chars_left = (ssize_t)len;
290 if (chars_left <= 0) {
295 next_line_start = get_next_line_start(line_start, (
size_t)chars_left);
306 char ch = *next_line_start;
307 *next_line_start =
'\0';
309 *next_line_start = ch;
312 chars_left -= (next_line_start - line_start);
313 line_start = next_line_start;
322static const char *icalproperty_get_value_kind(icalproperty *prop)
324 const char *kind_string = NULL;
329 icalvalue_kind kind = ICAL_NO_VALUE;
330 icalparameter *val_param =
337 if (kind == ICAL_NO_VALUE) {
342 if (kind == ICAL_ATTACH_VALUE) {
349 if (kind != ICAL_NO_VALUE &&
350 !icalproperty_value_kind_is_default(prop->kind, kind)) {
371 icalparameter *param;
377 const char *property_name = 0;
378 size_t buf_size = 1024;
381 const icalvalue *value;
383 const char *kind_string = 0;
384 const char newline[] =
"\r\n";
386 icalerror_check_arg_rz((prop != 0),
"prop");
393 if ((prop->kind == ICAL_X_PROPERTY || prop->kind == ICAL_IANA_PROPERTY) && prop->x_name != 0) {
394 property_name = prop->x_name;
399 if (property_name == 0) {
400 icalerror_warn(
"Got a property of an unknown kind.");
407 kind_string = icalproperty_get_value_kind(prop);
408 if (kind_string != 0) {
420 if (kind_string == 0) {
421 icalerror_warn(
"Got a parameter of unknown kind for the following property");
423 icalerror_warn((property_name) ? property_name :
"(NULL)");
427 if (kind == ICAL_VALUE_PARAMETER) {
460 out_buf = fold_property_line(buf);
473 return ICAL_NO_PROPERTY;
478 const icalproperty *impl = (icalproperty *)property;
480 icalerror_check_arg_rz((property != 0),
"property");
481 if (strcmp(impl->id,
"prop") == 0) {
490 icalerror_check_arg_rv((p != 0),
"prop");
491 icalerror_check_arg_rv((parameter != 0),
"parameter");
493 icalpvl_push(p->parameters, parameter);
498 icalparameter_kind kind;
500 icalerror_check_arg_rv((prop != 0),
"prop");
501 icalerror_check_arg_rv((parameter != 0),
"parameter");
504 if (kind == ICAL_X_PARAMETER) {
506 }
else if (kind == ICAL_IANA_PARAMETER) {
516 const char *name,
const char *value)
518 icalparameter_kind kind;
519 icalparameter *param;
521 icalerror_check_arg_rv((prop != 0),
"prop");
522 icalerror_check_arg_rv((name != 0),
"name");
523 icalerror_check_arg_rv((value != 0),
"value");
527 if (kind == ICAL_NO_PARAMETER) {
539 if (kind == ICAL_X_PARAMETER) {
541 }
else if (kind == ICAL_IANA_PARAMETER) {
559 icalparameter_kind kind;
560 icalparameter *param;
567 icalerror_check_arg_rz((prop != 0),
"prop");
568 icalerror_check_arg_rz((name != 0),
"name");
572 if (kind == ICAL_NO_PARAMETER) {
579 if (kind == ICAL_X_PARAMETER) {
583 }
else if (kind == ICAL_IANA_PARAMETER) {
598 t = strchr(str,
'=');
611 pvql = strchr(pv,
'"');
621 pvqr = strrchr(str,
'"');
634 icalpvl_elem p, next;
636 icalerror_check_arg_rv((prop != 0),
"prop");
638 for (p = icalpvl_head(prop->parameters); p != 0; p = next) {
639 next = icalpvl_next(p);
641 icalparameter *param = (icalparameter *)icalpvl_data(p);
644 (void)icalpvl_remove(prop->parameters, p);
652 icalpvl_elem p, next;
654 icalerror_check_arg_rv((prop != 0),
"prop");
656 for (p = icalpvl_head(prop->parameters); p != 0; p = next) {
657 next = icalpvl_next(p);
659 icalparameter *param = (icalparameter *)icalpvl_data(p);
660 const char *kind_string;
674 if (0 == strcasecmp(kind_string, name)) {
675 (void)icalpvl_remove(prop->parameters, p);
685 icalerror_check_arg_rv((prop != 0),
"prop");
686 icalerror_check_arg_rv((parameter != 0),
"parameter");
688 for (p = icalpvl_head(prop->parameters); p != 0; p = icalpvl_next(p)) {
689 icalparameter *p_param = (icalparameter *)icalpvl_data(p);
692 (void)icalpvl_remove(prop->parameters, p);
702 return icalpvl_count(prop->parameters);
711 icalerror_check_arg_rz((p != 0),
"prop");
713 p->parameter_iterator = icalpvl_head(p->parameters);
715 if (p->parameter_iterator == 0) {
719 for (p->parameter_iterator = icalpvl_head(p->parameters);
720 p->parameter_iterator != 0; p->parameter_iterator = icalpvl_next(p->parameter_iterator)) {
721 icalparameter *param = (icalparameter *)icalpvl_data(p->parameter_iterator);
733 icalerror_check_arg_rz((p != 0),
"prop");
735 if (p->parameter_iterator == 0) {
739 for (p->parameter_iterator = icalpvl_next(p->parameter_iterator);
740 p->parameter_iterator != 0; p->parameter_iterator = icalpvl_next(p->parameter_iterator)) {
741 icalparameter *param = (icalparameter *)icalpvl_data(p->parameter_iterator);
755 icalerror_check_arg_rv((p != 0),
"prop");
756 icalerror_check_arg_rv((value != 0),
"value");
769 if (kind == ICAL_DATE_VALUE || kind == ICAL_DATETIME_VALUE) {
770 icalparameter *val_param;
784 icalvalue_kind kind = ICAL_NO_VALUE;
786 icalerror_check_arg_rv((prop != 0),
"prop");
787 icalerror_check_arg_rv((str != 0),
"str");
788 icalerror_check_arg_rv((type != 0),
"type");
790 if (strcmp(type,
"NO") == 0) {
805 if (kind == ICAL_NO_VALUE) {
824 icalerror_check_arg_rz((prop != 0),
"prop");
840 const icalvalue *value;
842 icalerror_check_arg_rz((prop != 0),
"prop");
851 icalerror_check_arg_rv((name != 0),
"name");
852 icalerror_check_arg_rv((prop != 0),
"prop");
857 if (prop->x_name == 0) {
864 icalerror_check_arg_rz((prop != 0),
"prop");
871 icalerror_check_arg_rv((name != 0),
"name");
872 icalerror_check_arg_rv((prop != 0),
"prop");
873 icalerror_check_arg_rv((prop->kind == ICAL_IANA_PROPERTY),
"prop->kind");
878 if (prop->x_name == 0) {
885 icalerror_check_arg_rz((prop != 0),
"prop");
886 icalerror_check_arg_rz((prop->kind == ICAL_IANA_PROPERTY),
"prop->kind");
902 const char *property_name = 0;
903 size_t buf_size = 256;
907 icalerror_check_arg_rz((prop != 0),
"prop");
912 if ((prop->kind == ICAL_X_PROPERTY || prop->kind == ICAL_IANA_PROPERTY) && prop->x_name != 0) {
913 property_name = prop->x_name;
918 if (property_name == 0) {
934 icalerror_check_arg_rv((property != 0),
"property");
936 property->parent = component;
941 icalerror_check_arg_rz((property != 0),
"property");
943 return property->parent;
946static int param_compare(
void *a,
void *b)
956 icalpvl_list sorted_params = icalpvl_newlist();
957 icalparameter *param;
960 while ((param = icalpvl_pop(prop->parameters)) != 0) {
965 case ICAL_VALUE_PARAMETER:
968 case ICAL_ATTACH_PROPERTY:
969 if (icalparameter_get_value(param) == ICAL_VALUE_URI) {
974 case ICAL_DTEND_PROPERTY:
975 case ICAL_DUE_PROPERTY:
976 case ICAL_DTSTART_PROPERTY:
977 case ICAL_EXDATE_PROPERTY:
978 case ICAL_RDATE_PROPERTY:
979 case ICAL_RECURRENCEID_PROPERTY:
980 if (icalparameter_get_value(param) == ICAL_VALUE_DATETIME) {
985 case ICAL_DURATION_PROPERTY:
986 if (icalparameter_get_value(param) == ICAL_VALUE_DURATION) {
991 case ICAL_RELATEDTO_PROPERTY:
992 if (icalparameter_get_value(param) == ICAL_VALUE_TEXT) {
1002 case ICAL_CUTYPE_PARAMETER:
1003 if (icalparameter_get_cutype(param) == ICAL_CUTYPE_INDIVIDUAL) {
1008 case ICAL_ENCODING_PARAMETER:
1009 if (icalparameter_get_encoding(param) == ICAL_ENCODING_8BIT) {
1014 case ICAL_FBTYPE_PARAMETER:
1015 if (icalparameter_get_fbtype(param) == ICAL_FBTYPE_BUSY) {
1020 case ICAL_PARTSTAT_PARAMETER:
1021 if (icalparameter_get_partstat(param) == ICAL_PARTSTAT_NEEDSACTION) {
1026 case ICAL_RELATED_PARAMETER:
1027 if (icalparameter_get_related(param) == ICAL_RELATED_START) {
1032 case ICAL_RELTYPE_PARAMETER:
1033 if (icalparameter_get_reltype(param) == ICAL_RELTYPE_PARENT) {
1038 case ICAL_ROLE_PARAMETER:
1039 if (icalparameter_get_role(param) == ICAL_ROLE_REQPARTICIPANT) {
1044 case ICAL_RSVP_PARAMETER:
1045 if (icalparameter_get_rsvp(param) == ICAL_RSVP_FALSE) {
1050 case ICAL_SCHEDULEAGENT_PARAMETER:
1051 if (icalparameter_get_scheduleagent(param) == ICAL_SCHEDULEAGENT_SERVER) {
1064 icalpvl_insert_ordered(sorted_params, param_compare, param);
1068 icalpvl_free(prop->parameters);
1069 prop->parameters = sorted_params;
1073 icalcomponent *comp)
1076 icalparameter *param;
1086 const char *tzid = icalparameter_get_tzid(param);
1093 for (c = comp; c != NULL; c = icalcomponent_get_parent(c)) {
1116static const icalparamiter icalparamiter_null = {ICAL_NO_PARAMETER, 0};
1119icalparamiter icalproperty_begin_parameter(icalproperty *property, icalparameter_kind kind)
1121 icalerror_check_arg_re(property != 0,
"property", icalparamiter_null);
1125 for (i = icalpvl_head(property->parameters); i != 0; i = icalpvl_next(i)) {
1126 icalparameter *p = (icalparameter *)icalpvl_data(i);
1129 icalparamiter itr = {kind, i};
1134 return icalparamiter_null;
1137icalparameter *icalparamiter_next(icalparamiter *i)
1139 icalerror_check_arg_rz((i != 0),
"i");
1145 for (i->iter = icalpvl_next(i->iter); i->iter != 0; i->iter = icalpvl_next(i->iter)) {
1146 icalparameter *p = (icalparameter *)icalpvl_data(i->iter);
1149 return icalparamiter_deref(i);
1156icalparameter *icalparamiter_deref(icalparamiter *i)
1162 return icalpvl_data(i->iter);
bool icalattach_get_is_url(const icalattach *attach)
Determines if attach is an URL.
struct icalattach_impl icalattach
An iCal attach object representing a link to a document object.
icalproperty * icalcomponent_get_first_property(icalcomponent *c, icalproperty_kind kind)
void icalcomponent_remove_property(icalcomponent *component, icalproperty *property)
int icalcomponent_count_errors(icalcomponent *component)
icaltimezone * icalcomponent_get_timezone(icalcomponent *comp, const char *tzid)
void icalcomponent_free(icalcomponent *c)
Defines the data structure for iCalendar components.
struct icaltimetype icalproperty_get_datetime_with_component(icalproperty *prop, icalcomponent *comp)
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
void icalerror_clear_errno(void)
Resets icalerrno to ICAL_NO_ERROR.
Error handling for libical.
@ ICAL_MALFORMEDDATA_ERROR
#define icalerrno
Access the current icalerrno value.
void icalmemory_free_buffer(void *buf)
Releases a buffer.
char * icalmemory_strdup(const char *s)
Creates a duplicate of a string.
void icalmemory_append_string(char **buf, char **pos, size_t *buf_size, const char *string)
Appends a string to a buffer.
void * icalmemory_new_buffer(size_t size)
Creates new buffer with the specified size.
void icalmemory_add_tmp_buffer(void *buf)
Adds an externally allocated buffer to the ring.
Common memory management routines.
bool icalparameter_isa_parameter(void *parameter)
void icalparameter_free(icalparameter *param)
Frees an icalparameter object.
void icalparameter_set_xname(icalparameter *param, const char *v)
Sets the X-name of param to v.
char * icalparameter_as_ical_string_r(icalparameter *param)
Converts icalparameter into a string representation according to RFC5445/RFC6868.
const char * icalparameter_get_xname(const icalparameter *param)
Returns the X-name of param.
icalparameter_kind icalparameter_isa(const icalparameter *parameter)
icalparameter * icalparameter_clone(const icalparameter *old)
Creates new icalparameter as a clone of the given one.
bool icalparameter_has_same_name(const icalparameter *param1, const icalparameter *param2)
Determines if two parameters have the same name.
void icalparameter_set_iana_name(icalparameter *param, const char *v)
Sets the IANA name of param to v.
void icalparameter_set_parent(icalparameter *param, icalproperty *property)
const char * icalparameter_get_iana_name(const icalparameter *param)
Returns the IANA name of param.
char * icalparameter_as_ical_string(icalparameter *param)
Converts icalparameter into a string representation.
icalparameter_kind icalparameter_string_to_kind(const char *string)
Returns the icalparameter_kind for a given string.
const char * icalparameter_kind_to_string(icalparameter_kind kind)
Returns a string representing the given icalparameter_kind.
icalparameter * icalparameter_new_from_value_string(icalparameter_kind kind, const char *value)
Creates new icalparameter of a given kind with a given value.
icalcomponent * icalparser_parse_string(const char *str)
Parses a string and returns the parsed icalcomponent.
icalvalue * icalproperty_get_value(const icalproperty *prop)
void icalproperty_add_parameters(icalproperty *prop, va_list args)
bool icalproperty_isa_property(void *property)
void icalproperty_free(icalproperty *p)
void icalproperty_set_value(icalproperty *p, icalvalue *value)
icalcomponent * icalproperty_get_parent(const icalproperty *property)
char * icalproperty_as_ical_string_r(icalproperty *prop)
icalproperty_kind icalproperty_isa(const icalproperty *p)
void icalproperty_set_parameter_from_string(icalproperty *prop, const char *name, const char *value)
char * icalproperty_get_property_name_r(const icalproperty *prop)
void icalproperty_set_allow_empty_properties(bool enable)
void icalproperty_remove_parameter_by_name(icalproperty *prop, const char *name)
Removes all parameters with the specified name.
int icalproperty_count_parameters(const icalproperty *prop)
const char * icalproperty_get_value_as_string(const icalproperty *prop)
void icalproperty_remove_parameter_by_kind(icalproperty *prop, icalparameter_kind kind)
Removes all parameters with the specified kind.
const char * icalproperty_get_property_name(const icalproperty *prop)
bool icalproperty_get_allow_empty_properties(void)
const char * icalproperty_as_ical_string(icalproperty *prop)
icalparameter * icalproperty_get_first_parameter(icalproperty *p, icalparameter_kind kind)
void icalproperty_add_parameter(icalproperty *p, icalparameter *parameter)
char * icalproperty_get_parameter_as_string_r(icalproperty *prop, const char *name)
void icalproperty_normalize(icalproperty *prop)
void icalproperty_set_parent(icalproperty *property, icalcomponent *component)
void icalproperty_remove_parameter_by_ref(icalproperty *prop, icalparameter *parameter)
Removes the specified parameter reference from the property.
char * icalproperty_get_value_as_string_r(const icalproperty *prop)
icalproperty * icalproperty_clone(const icalproperty *old)
const char * icalproperty_get_x_name(const icalproperty *prop)
void icalproperty_set_parameter(icalproperty *prop, icalparameter *parameter)
const char * icalproperty_get_iana_name(const icalproperty *prop)
icalproperty * icalproperty_new(icalproperty_kind kind)
void icalproperty_set_iana_name(icalproperty *prop, const char *name)
icalproperty * icalproperty_new_from_string(const char *str)
icalparameter * icalproperty_get_next_parameter(icalproperty *p, icalparameter_kind kind)
void icalproperty_set_value_from_string(icalproperty *prop, const char *str, const char *type)
const char * icalproperty_get_parameter_as_string(icalproperty *prop, const char *name)
void icalproperty_set_x_name(icalproperty *prop, const char *name)
icalvalue_kind icalparameter_value_to_value_kind(icalparameter_value value)
void icalvalue_set_parent(icalvalue *value, icalproperty *property)
icalvalue_kind icalproperty_kind_to_value_kind(icalproperty_kind kind)
bool icalproperty_kind_is_valid(const icalproperty_kind kind)
const char * icalproperty_kind_to_string(icalproperty_kind kind)
bool icaltime_is_utc(const struct icaltimetype t)
struct icaltimetype icaltime_set_timezone(struct icaltimetype *t, const icaltimezone *zone)
icaltimezone * icaltimezone_get_builtin_timezone(const char *location)
icaltimezone * icaltimezone_get_builtin_timezone_from_tzid(const char *tzid)
Timezone handling routines.
struct _icaltimezone icaltimezone
icalvalue_kind icalvalue_isa(const icalvalue *value)
bool icalvalue_isa_value(void *value)
icalvalue * icalvalue_clone(const icalvalue *old)
icalvalue * icalvalue_new_from_string(icalvalue_kind kind, const char *str)
void icalvalue_free(icalvalue *v)
char * icalvalue_as_ical_string_r(const icalvalue *value)
Defines the data structure representing iCalendar parameter values.
icalvalue_kind icalvalue_string_to_kind(const char *str)
const char * icalvalue_kind_to_string(const icalvalue_kind kind)