18#include "icalproperty_p.h"
20#include "icalerror_p.h"
27#include "icaltypes_p.h"
31struct icalproperty_impl {
33 icalproperty_kind kind;
35 icalpvl_list parameters;
36 icalpvl_elem parameter_iterator;
38 icalcomponent *parent;
42LIBICAL_ICAL_EXPORT
struct icalproperty_impl *icalproperty_new_impl(icalproperty_kind kind)
55 memset(prop, 0,
sizeof(icalproperty));
57 prop->id = ICAL_STRUCTURE_TYPE_PROPERTY;
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;
211 p->id = ICAL_STRUCTURE_TYPE_PROPERTY_EMPTY;
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;
324static const char *icalproperty_get_value_kind(icalproperty *prop)
326 const char *kind_string = NULL;
331 icalvalue_kind kind = ICAL_NO_VALUE;
332 icalparameter *val_param =
339 if (kind == ICAL_NO_VALUE) {
344 if (kind == ICAL_ATTACH_VALUE) {
351 if (kind != ICAL_NO_VALUE &&
352 !icalproperty_value_kind_is_default(prop->kind, kind)) {
373 icalparameter *param;
379 const char *property_name = 0;
380 size_t buf_size = 1024;
383 const icalvalue *value;
385 const char *kind_string = 0;
387 icalerror_check_arg_rz((prop != 0),
"prop");
394 if ((prop->kind == ICAL_X_PROPERTY || prop->kind == ICAL_IANA_PROPERTY) && prop->x_name != 0) {
395 property_name = prop->x_name;
400 if (property_name == 0) {
401 icalerror_warn(
"Got a property of an unknown kind.");
408 kind_string = icalproperty_get_value_kind(prop);
409 if (kind_string != 0) {
421 if (kind_string == 0) {
422 icalerror_warn(
"Got a parameter of unknown kind for the following property");
424 icalerror_warn((property_name) ? property_name :
"(NULL)");
428 if (kind == ICAL_VALUE_PARAMETER) {
459 out_buf = fold_property_line(buf);
472 return ICAL_NO_PROPERTY;
477 const icalproperty *impl = (icalproperty *)property;
479 icalerror_check_arg_rz((property != 0),
"property");
480 return (impl->id == ICAL_STRUCTURE_TYPE_PROPERTY);
485 icalerror_check_arg_rv((p != 0),
"prop");
486 icalerror_check_arg_rv((parameter != 0),
"parameter");
488 icalpvl_push(p->parameters, parameter);
493 icalparameter_kind kind;
495 icalerror_check_arg_rv((prop != 0),
"prop");
496 icalerror_check_arg_rv((parameter != 0),
"parameter");
499 if (kind == ICAL_X_PARAMETER) {
501 }
else if (kind == ICAL_IANA_PARAMETER) {
511 const char *name,
const char *value)
513 icalparameter_kind kind;
514 icalparameter *param;
516 icalerror_check_arg_rv((prop != 0),
"prop");
517 icalerror_check_arg_rv((name != 0),
"name");
518 icalerror_check_arg_rv((value != 0),
"value");
522 if (kind == ICAL_NO_PARAMETER) {
534 if (kind == ICAL_X_PARAMETER) {
536 }
else if (kind == ICAL_IANA_PARAMETER) {
554 icalparameter_kind kind;
555 icalparameter *param;
562 icalerror_check_arg_rz((prop != 0),
"prop");
563 icalerror_check_arg_rz((name != 0),
"name");
567 if (kind == ICAL_NO_PARAMETER) {
574 if (kind == ICAL_X_PARAMETER) {
578 }
else if (kind == ICAL_IANA_PARAMETER) {
593 t = strchr(str,
'=');
606 pvql = strchr(pv,
'"');
616 pvqr = strrchr(str,
'"');
629 icalpvl_elem p, next;
631 icalerror_check_arg_rv((prop != 0),
"prop");
633 for (p = icalpvl_head(prop->parameters); p != 0; p = next) {
634 next = icalpvl_next(p);
636 icalparameter *param = (icalparameter *)icalpvl_data(p);
639 (void)icalpvl_remove(prop->parameters, p);
647 icalpvl_elem p, next;
649 icalerror_check_arg_rv((prop != 0),
"prop");
651 for (p = icalpvl_head(prop->parameters); p != 0; p = next) {
652 next = icalpvl_next(p);
654 icalparameter *param = (icalparameter *)icalpvl_data(p);
655 const char *kind_string;
669 if (0 == strcasecmp(kind_string, name)) {
670 (void)icalpvl_remove(prop->parameters, p);
680 icalerror_check_arg_rv((prop != 0),
"prop");
681 icalerror_check_arg_rv((parameter != 0),
"parameter");
683 for (p = icalpvl_head(prop->parameters); p != 0; p = icalpvl_next(p)) {
684 icalparameter *p_param = (icalparameter *)icalpvl_data(p);
687 (void)icalpvl_remove(prop->parameters, p);
697 return icalpvl_count(prop->parameters);
706 icalerror_check_arg_rz((p != 0),
"prop");
708 p->parameter_iterator = icalpvl_head(p->parameters);
710 if (p->parameter_iterator == 0) {
714 for (p->parameter_iterator = icalpvl_head(p->parameters);
715 p->parameter_iterator != 0; p->parameter_iterator = icalpvl_next(p->parameter_iterator)) {
716 icalparameter *param = (icalparameter *)icalpvl_data(p->parameter_iterator);
728 icalerror_check_arg_rz((p != 0),
"prop");
730 if (p->parameter_iterator == 0) {
734 for (p->parameter_iterator = icalpvl_next(p->parameter_iterator);
735 p->parameter_iterator != 0; p->parameter_iterator = icalpvl_next(p->parameter_iterator)) {
736 icalparameter *param = (icalparameter *)icalpvl_data(p->parameter_iterator);
750 icalerror_check_arg_rv((p != 0),
"prop");
751 icalerror_check_arg_rv((value != 0),
"value");
764 if (kind == ICAL_DATE_VALUE || kind == ICAL_DATETIME_VALUE) {
765 icalparameter *val_param;
779 icalvalue_kind kind = ICAL_NO_VALUE;
781 icalerror_check_arg_rv((prop != 0),
"prop");
782 icalerror_check_arg_rv((str != 0),
"str");
783 icalerror_check_arg_rv((type != 0),
"type");
785 if (strcmp(type,
"NO") == 0) {
800 if (kind == ICAL_NO_VALUE) {
819 icalerror_check_arg_rz((prop != 0),
"prop");
835 const icalvalue *value;
837 icalerror_check_arg_rz((prop != 0),
"prop");
846 icalerror_check_arg_rv((name != 0),
"name");
847 icalerror_check_arg_rv((prop != 0),
"prop");
852 if (prop->x_name == 0) {
859 icalerror_check_arg_rz((prop != 0),
"prop");
866 icalerror_check_arg_rv((name != 0),
"name");
867 icalerror_check_arg_rv((prop != 0),
"prop");
868 icalerror_check_arg_rv((prop->kind == ICAL_IANA_PROPERTY),
"prop->kind");
873 if (prop->x_name == 0) {
880 icalerror_check_arg_rz((prop != 0),
"prop");
881 icalerror_check_arg_rz((prop->kind == ICAL_IANA_PROPERTY),
"prop->kind");
897 const char *property_name = 0;
898 size_t buf_size = 256;
902 icalerror_check_arg_rz((prop != 0),
"prop");
907 if ((prop->kind == ICAL_X_PROPERTY || prop->kind == ICAL_IANA_PROPERTY) && prop->x_name != 0) {
908 property_name = prop->x_name;
913 if (property_name == 0) {
929 icalerror_check_arg_rv((property != 0),
"property");
931 property->parent = component;
936 icalerror_check_arg_rz((property != 0),
"property");
938 return property->parent;
941static int param_compare(
void *a,
void *b)
951 icalpvl_list sorted_params = icalpvl_newlist();
952 icalparameter *param;
955 while ((param = icalpvl_pop(prop->parameters)) != 0) {
960 case ICAL_VALUE_PARAMETER:
963 case ICAL_ATTACH_PROPERTY:
964 if (icalparameter_get_value(param) == ICAL_VALUE_URI) {
969 case ICAL_DTEND_PROPERTY:
970 case ICAL_DUE_PROPERTY:
971 case ICAL_DTSTART_PROPERTY:
972 case ICAL_EXDATE_PROPERTY:
973 case ICAL_RDATE_PROPERTY:
974 case ICAL_RECURRENCEID_PROPERTY:
975 if (icalparameter_get_value(param) == ICAL_VALUE_DATETIME) {
980 case ICAL_DURATION_PROPERTY:
981 if (icalparameter_get_value(param) == ICAL_VALUE_DURATION) {
986 case ICAL_RELATEDTO_PROPERTY:
987 if (icalparameter_get_value(param) == ICAL_VALUE_TEXT) {
997 case ICAL_CUTYPE_PARAMETER:
998 if (icalparameter_get_cutype(param) == ICAL_CUTYPE_INDIVIDUAL) {
1003 case ICAL_ENCODING_PARAMETER:
1004 if (icalparameter_get_encoding(param) == ICAL_ENCODING_8BIT) {
1009 case ICAL_FBTYPE_PARAMETER:
1010 if (icalparameter_get_fbtype(param) == ICAL_FBTYPE_BUSY) {
1015 case ICAL_PARTSTAT_PARAMETER:
1016 if (icalparameter_get_partstat(param) == ICAL_PARTSTAT_NEEDSACTION) {
1021 case ICAL_RELATED_PARAMETER:
1022 if (icalparameter_get_related(param) == ICAL_RELATED_START) {
1027 case ICAL_RELTYPE_PARAMETER:
1028 if (icalparameter_get_reltype(param) == ICAL_RELTYPE_PARENT) {
1033 case ICAL_ROLE_PARAMETER:
1034 if (icalparameter_get_role(param) == ICAL_ROLE_REQPARTICIPANT) {
1039 case ICAL_RSVP_PARAMETER:
1040 if (icalparameter_get_rsvp(param) == ICAL_RSVP_FALSE) {
1045 case ICAL_SCHEDULEAGENT_PARAMETER:
1046 if (icalparameter_get_scheduleagent(param) == ICAL_SCHEDULEAGENT_SERVER) {
1059 icalpvl_insert_ordered(sorted_params, param_compare, param);
1063 icalpvl_free(prop->parameters);
1064 prop->parameters = sorted_params;
1068 icalcomponent *comp)
1071 icalparameter *param;
1081 const char *tzid = icalparameter_get_tzid(param);
1088 for (c = comp; c != NULL; c = icalcomponent_get_parent(c)) {
1111static const icalparamiter icalparamiter_null = {ICAL_NO_PARAMETER, 0};
1114icalparamiter icalproperty_begin_parameter(icalproperty *property, icalparameter_kind kind)
1116 icalerror_check_arg_re(property != 0,
"property", icalparamiter_null);
1120 for (i = icalpvl_head(property->parameters); i != 0; i = icalpvl_next(i)) {
1121 icalparameter *p = (icalparameter *)icalpvl_data(i);
1124 icalparamiter itr = {kind, i};
1129 return icalparamiter_null;
1132icalparameter *icalparamiter_next(icalparamiter *i)
1134 icalerror_check_arg_rz((i != 0),
"i");
1140 for (i->iter = icalpvl_next(i->iter); i->iter != 0; i->iter = icalpvl_next(i->iter)) {
1141 icalparameter *p = (icalparameter *)icalpvl_data(i->iter);
1144 return icalparamiter_deref(i);
1151icalparameter *icalparamiter_deref(icalparamiter *i)
1157 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)