summaryrefslogtreecommitdiffabout
path: root/libical/src/libical/icalproperty.c
Unidiff
Diffstat (limited to 'libical/src/libical/icalproperty.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/icalproperty.c509
1 files changed, 348 insertions, 161 deletions
diff --git a/libical/src/libical/icalproperty.c b/libical/src/libical/icalproperty.c
index 7f2cfa5..45d7a75 100644
--- a/libical/src/libical/icalproperty.c
+++ b/libical/src/libical/icalproperty.c
@@ -18,17 +18,16 @@
18 Or: 18 Or:
19 19
20 The Mozilla Public License Version 1.0. You may obtain a copy of 20 The Mozilla Public License Version 1.0. You may obtain a copy of
21 the License at http://www.mozilla.org/MPL/ 21 the License at http://www.mozilla.org/MPL/
22 22
23 The original code is icalproperty.c 23 The original code is icalproperty.c
24 24
25======================================================================*/ 25======================================================================*/
26/*#line 27 "icalproperty.c.in"*/
27 26
28#ifdef HAVE_CONFIG_H 27#ifdef HAVE_CONFIG_H
29#include <config.h> 28#include <config.h>
30#endif 29#endif
31 30
32#include "icalproperty.h" 31#include "icalproperty.h"
33#include "icalparameter.h" 32#include "icalparameter.h"
34#include "icalcomponent.h" 33#include "icalcomponent.h"
@@ -40,19 +39,20 @@
40 39
41#include <string.h> /* For icalmemory_strdup, rindex */ 40#include <string.h> /* For icalmemory_strdup, rindex */
42#include <assert.h> 41#include <assert.h>
43#include <stdlib.h> 42#include <stdlib.h>
44#include <errno.h> 43#include <errno.h>
45#include <stdio.h> /* for printf */ 44#include <stdio.h> /* for printf */
46#include <stdarg.h> /* for va_list, va_start, etc. */ 45#include <stdarg.h> /* for va_list, va_start, etc. */
47 46
48int snprintf(char *str, size_t n, char const *fmt, ...); 47#ifdef WIN32
49 48#define snprintf _snprintf
50#define TMP_BUF_SIZE 1024 49#define strcasecmp stricmp
50#endif
51 51
52/* Private routines for icalproperty */ 52/* Private routines for icalproperty */
53void icalvalue_set_parent(icalvalue* value, 53void icalvalue_set_parent(icalvalue* value,
54 icalproperty* property); 54 icalproperty* property);
55icalproperty* icalvalue_get_parent(icalvalue* value); 55icalproperty* icalvalue_get_parent(icalvalue* value);
56 56
57void icalparameter_set_parent(icalparameter* param, 57void icalparameter_set_parent(icalparameter* param,
58 icalproperty* property); 58 icalproperty* property);
@@ -67,47 +67,44 @@ struct icalproperty_impl
67 icalproperty_kind kind; 67 icalproperty_kind kind;
68 char* x_name; 68 char* x_name;
69 pvl_list parameters; 69 pvl_list parameters;
70 pvl_elem parameter_iterator; 70 pvl_elem parameter_iterator;
71 icalvalue* value; 71 icalvalue* value;
72 icalcomponent *parent; 72 icalcomponent *parent;
73}; 73};
74 74
75void icalproperty_add_parameters(struct icalproperty_impl *prop,va_list args) 75void icalproperty_add_parameters(icalproperty* prop, va_list args)
76{ 76{
77
78 void* vp; 77 void* vp;
79 78
80 struct icalproperty_impl *impl = (struct icalproperty_impl*)prop;
81
82 while((vp = va_arg(args, void*)) != 0) { 79 while((vp = va_arg(args, void*)) != 0) {
83 80
84 if (icalvalue_isa_value(vp) != 0 ){ 81 if (icalvalue_isa_value(vp) != 0 ){
85 } else if (icalparameter_isa_parameter(vp) != 0 ){ 82 } else if (icalparameter_isa_parameter(vp) != 0 ){
86 83
87 icalproperty_add_parameter((icalproperty*)impl, 84 icalproperty_add_parameter((icalproperty*)prop,
88 (icalparameter*)vp); 85 (icalparameter*)vp);
89 } else { 86 } else {
90 assert(0); 87 icalerror_set_errno(ICAL_BADARG_ERROR);
91 } 88 }
92 89
93 } 90 }
94
95
96} 91}
97 92
98 93
99struct icalproperty_impl* 94icalproperty*
100icalproperty_new_impl (icalproperty_kind kind) 95icalproperty_new_impl(icalproperty_kind kind)
101{ 96{
102 struct icalproperty_impl* prop; 97 icalproperty* prop;
98
99 if (!icalproperty_kind_is_valid(kind))
100 return NULL;
103 101
104 if ( ( prop = (struct icalproperty_impl*) 102 if ( ( prop = (icalproperty*) malloc(sizeof(icalproperty))) == 0) {
105 malloc(sizeof(struct icalproperty_impl))) == 0) {
106 icalerror_set_errno(ICAL_NEWFAILED_ERROR); 103 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
107 return 0; 104 return 0;
108 } 105 }
109 106
110 strcpy(prop->id,"prop"); 107 strcpy(prop->id,"prop");
111 108
112 prop->kind = kind; 109 prop->kind = kind;
113 prop->parameters = pvl_newlist(); 110 prop->parameters = pvl_newlist();
@@ -118,32 +115,30 @@ icalproperty_new_impl (icalproperty_kind kind)
118 115
119 return prop; 116 return prop;
120} 117}
121 118
122 119
123icalproperty* 120icalproperty*
124icalproperty_new (icalproperty_kind kind) 121icalproperty_new (icalproperty_kind kind)
125{ 122{
126 if(kind == ICAL_NO_PROPERTY){ 123 if (kind == ICAL_NO_PROPERTY){
127 return 0; 124 return 0;
128 } 125 }
129 126
130 return (icalproperty*)icalproperty_new_impl(kind); 127 return (icalproperty*)icalproperty_new_impl(kind);
131} 128}
132 129
133 130
134icalproperty* 131icalproperty*
135icalproperty_new_clone(icalproperty* prop) 132icalproperty_new_clone(icalproperty* old)
136{ 133{
137 struct icalproperty_impl *old = (struct icalproperty_impl*)prop; 134 icalproperty *new = icalproperty_new_impl(old->kind);
138 struct icalproperty_impl *new = icalproperty_new_impl(old->kind);
139 pvl_elem p; 135 pvl_elem p;
140 136
141 icalerror_check_arg_rz((prop!=0),"Prop");
142 icalerror_check_arg_rz((old!=0),"old"); 137 icalerror_check_arg_rz((old!=0),"old");
143 icalerror_check_arg_rz((new!=0),"new"); 138 icalerror_check_arg_rz((new!=0),"new");
144 139
145 if (old->value !=0) { 140 if (old->value !=0) {
146 new->value = icalvalue_new_clone(old->value); 141 new->value = icalvalue_new_clone(old->value);
147 } 142 }
148 143
149 if (old->x_name != 0) { 144 if (old->x_name != 0) {
@@ -214,25 +209,21 @@ icalproperty* icalproperty_new_from_string(const char* str)
214 return 0; 209 return 0;
215 } else { 210 } else {
216 return prop; 211 return prop;
217 } 212 }
218 213
219} 214}
220 215
221void 216void
222icalproperty_free (icalproperty* prop) 217icalproperty_free (icalproperty* p)
223{ 218{
224 struct icalproperty_impl *p;
225
226 icalparameter* param; 219 icalparameter* param;
227 220
228 icalerror_check_arg_rv((prop!=0),"prop"); 221 icalerror_check_arg_rv((p!=0),"prop");
229
230 p = (struct icalproperty_impl*)prop;
231 222
232#ifdef ICAL_FREE_ON_LIST_IS_ERROR 223#ifdef ICAL_FREE_ON_LIST_IS_ERROR
233 icalerror_assert( (p->parent ==0),"Tried to free a property that is still attached to a component. "); 224 icalerror_assert( (p->parent ==0),"Tried to free a property that is still attached to a component. ");
234 225
235#else 226#else
236 if(p->parent !=0){ 227 if(p->parent !=0){
237 return; 228 return;
238 } 229 }
@@ -260,79 +251,145 @@ icalproperty_free (icalproperty* prop)
260 p->x_name = 0; 251 p->x_name = 0;
261 p->id[0] = 'X'; 252 p->id[0] = 'X';
262 253
263 free(p); 254 free(p);
264 255
265} 256}
266 257
267 258
268const char* 259/* This returns where the start of the next line should be. chars_left does
269icalproperty_as_ical_string (icalproperty* prop) 260 not include the trailing '\0'. */
270{ 261#define MAX_LINE_LEN 75
271 icalparameter *param; 262/*#define MAX_LINE_LEN 120*/
272 263
273 /* Create new buffer that we can append names, parameters and a 264static char*
274 value to, and reallocate as needed. Later, this buffer will be 265get_next_line_start (char *line_start, int chars_left)
275 copied to a icalmemory_tmp_buffer, which is managed internally 266{
276 by libical, so it can be given to the caller without fear of 267 char *pos;
277 the caller forgetting to free it */
278
279 const char* property_name = 0;
280 size_t buf_size = 1024;
281 char* buf = icalmemory_new_buffer(buf_size);
282 char* buf_ptr = buf;
283 icalvalue* value;
284 char *out_buf;
285 268
286 char newline[] = "\n"; 269 /* If we have 74 chars or less left, we can output all of them.
270 we return a pointer to the '\0' at the end of the string. */
271 if (chars_left < MAX_LINE_LEN) {
272 return line_start + chars_left;
273 }
287 274
288 struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; 275 /* Now we jump to the last possible character of the line, and step back
289 276 trying to find a ';' ':' or ' '. If we find one, we return the character
290 icalerror_check_arg_rz( (prop!=0),"prop"); 277 after it. */
278 pos = line_start + MAX_LINE_LEN - 2;
279 while (pos > line_start) {
280 if (*pos == ';' || *pos == ':' || *pos == ' ') {
281 return pos + 1;
282 }
283 pos--;
284 }
285 /* Now try to split on a UTF-8 boundary defined as a 7-bit
286 value or as a byte with the two high-most bits set:
287 11xxxxxx. See http://czyborra.com/utf/ */
291 288
289 pos = line_start + MAX_LINE_LEN - 1;
290 while (pos > line_start) {
291 /* plain ascii */
292 if ((*pos & 128) == 0)
293 return pos;
292 294
293 /* Append property name */ 295 /* utf8 escape byte */
296 if ((*pos & 192) == 192)
297 return pos;
294 298
295 if (impl->kind == ICAL_X_PROPERTY && impl->x_name != 0){ 299 pos--;
296 property_name = impl->x_name;
297 } else {
298 property_name = icalproperty_kind_to_string(impl->kind);
299 } 300 }
300 301
301 if (property_name == 0 ) { 302 /* Give up, just break at 74 chars (the 75th char is the space at
302 icalerror_warn("Got a property of an unknown kind."); 303 the start of the line). */
303 icalmemory_free_buffer(buf); 304
304 return 0; 305 return line_start + MAX_LINE_LEN - 1;
305 306}
306 }
307 307
308 308
309 icalmemory_append_string(&buf, &buf_ptr, &buf_size, property_name); 309/** This splits the property into lines less than 75 octects long (as
310 icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); 310 * specified in RFC2445). It tries to split after a ';' if it can.
311 * It returns a tmp buffer. NOTE: I'm not sure if it matters if we
312 * split a line in the middle of a UTF-8 character. It probably won't
313 * look nice in a text editor.
314 */
315static char*
316fold_property_line (char *text)
317{
318 size_t buf_size;
319 char *buf, *buf_ptr, *line_start, *next_line_start, *out_buf;
320 int len, chars_left, first_line;
321 char ch;
322
323 /* Start with a buffer twice the size of our property line, so we almost
324 certainly won't overflow it. */
325 len = strlen (text);
326 buf_size = len * 2;
327 buf = icalmemory_new_buffer (buf_size);
328 buf_ptr = buf;
329
330 /* Step through the text, finding each line to add to the output. */
331 line_start = text;
332 chars_left = len;
333 first_line = 1;
334 for (;;) {
335 if (chars_left <= 0)
336 break;
337
338 /* This returns the first character for the next line. */
339 next_line_start = get_next_line_start (line_start, chars_left);
340
341 /* If this isn't the first line, we need to output a newline and space
342 first. */
343 if (!first_line) {
344 icalmemory_append_string (&buf, &buf_ptr, &buf_size, "\n ");
345 }
346 first_line = 0;
347
348 /* This adds the line to our tmp buffer. We temporarily place a '\0'
349 in text, so we can copy the line in one go. */
350 ch = *next_line_start;
351 *next_line_start = '\0';
352 icalmemory_append_string (&buf, &buf_ptr, &buf_size, line_start);
353 *next_line_start = ch;
311 354
355 /* Now we move on to the next line. */
356 chars_left -= (next_line_start - line_start);
357 line_start = next_line_start;
358 }
359
360 /* Copy it to a temporary buffer, and then free it. */
361 out_buf = icalmemory_tmp_buffer (strlen (buf) + 1);
362 strcpy (out_buf, buf);
363 icalmemory_free_buffer (buf);
364
365 return out_buf;
366}
312 367
313 368
314 /* Determine what VALUE parameter to include. The VALUE parameters 369/* Determine what VALUE parameter to include. The VALUE parameters
315 are ignored in the normal parameter printing ( the block after 370 are ignored in the normal parameter printing ( the block after
316 this one, so we need to do it here */ 371 this one, so we need to do it here */
317 { 372static const char *
373icalproperty_get_value_kind(icalproperty *prop)
374{
318 const char* kind_string = 0; 375 const char* kind_string = 0;
319 376
320 icalparameter *orig_val_param 377 icalparameter *orig_val_param
321 = icalproperty_get_first_parameter(prop,ICAL_VALUE_PARAMETER); 378 = icalproperty_get_first_parameter(prop,ICAL_VALUE_PARAMETER);
322 379
323 icalvalue *value = icalproperty_get_value(impl); 380 icalvalue *value = icalproperty_get_value(prop);
324 381
325 icalvalue_kind orig_kind = ICAL_NO_VALUE; 382 icalvalue_kind orig_kind = ICAL_NO_VALUE;
326 383
327 icalvalue_kind this_kind = ICAL_NO_VALUE; 384 icalvalue_kind this_kind = ICAL_NO_VALUE;
328 385
329 icalvalue_kind default_kind 386 icalvalue_kind default_kind
330 = icalproperty_kind_to_value_kind(impl->kind); 387 = icalproperty_kind_to_value_kind(prop->kind);
331 388
332 if(orig_val_param){ 389 if(orig_val_param){
333 orig_kind = (icalvalue_kind)icalparameter_get_value(orig_val_param); 390 orig_kind = (icalvalue_kind)icalparameter_get_value(orig_val_param);
334 } 391 }
335 392
336 if(value != 0){ 393 if(value != 0){
337 this_kind = icalvalue_isa(value); 394 this_kind = icalvalue_isa(value);
338 } 395 }
@@ -349,54 +406,93 @@ icalproperty_as_ical_string (icalproperty* prop)
349 406
350 } else if (this_kind != default_kind && this_kind != ICAL_NO_VALUE){ 407 } else if (this_kind != default_kind && this_kind != ICAL_NO_VALUE){
351 /* Not the default, so it must be specified */ 408 /* Not the default, so it must be specified */
352 kind_string = icalvalue_kind_to_string(this_kind); 409 kind_string = icalvalue_kind_to_string(this_kind);
353 } else { 410 } else {
354 /* Don'tinclude the VALUE parameter at all */ 411 /* Don'tinclude the VALUE parameter at all */
355 } 412 }
356 413
357 if(kind_string!=0){ 414 return kind_string;
358 icalmemory_append_string(&buf, &buf_ptr, &buf_size, " ;"); 415}
359 icalmemory_append_string(&buf, &buf_ptr, &buf_size, "VALUE="); 416
360 icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); 417const char*
361 icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); 418icalproperty_as_ical_string (icalproperty* prop)
362 } 419{
420 icalparameter *param;
421
422 /* Create new buffer that we can append names, parameters and a
423 value to, and reallocate as needed. Later, this buffer will be
424 copied to a icalmemory_tmp_buffer, which is managed internally
425 by libical, so it can be given to the caller without fear of
426 the caller forgetting to free it */
427
428 const char* property_name = 0;
429 size_t buf_size = 1024;
430 char* buf = icalmemory_new_buffer(buf_size);
431 char* buf_ptr = buf;
432 icalvalue* value;
433 char *out_buf;
434 const char* kind_string = 0;
435
436 char newline[] = "\n";
437
438
439 icalerror_check_arg_rz( (prop!=0),"prop");
440
441
442 /* Append property name */
443
444 if (prop->kind == ICAL_X_PROPERTY && prop->x_name != 0){
445 property_name = prop->x_name;
446 } else {
447 property_name = icalproperty_kind_to_string(prop->kind);
448 }
449
450 if (property_name == 0 ) {
451 icalerror_warn("Got a property of an unknown kind.");
452 icalmemory_free_buffer(buf);
453 return 0;
363 454
455 }
364 456
457 icalmemory_append_string(&buf, &buf_ptr, &buf_size, property_name);
458
459 kind_string = icalproperty_get_value_kind(prop);
460 if(kind_string!=0){
461 icalmemory_append_string(&buf, &buf_ptr, &buf_size, ";VALUE=");
462 icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string);
365 } 463 }
366 464
367 /* Append parameters */ 465 /* Append parameters */
368 for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); 466 for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER);
369 param != 0; 467 param != 0;
370 param = icalproperty_get_next_parameter(prop,ICAL_ANY_PARAMETER)) { 468 param = icalproperty_get_next_parameter(prop,ICAL_ANY_PARAMETER)) {
371 469
372 char* kind_string = icalparameter_as_ical_string(param);
373 icalparameter_kind kind = icalparameter_isa(param); 470 icalparameter_kind kind = icalparameter_isa(param);
471 kind_string = icalparameter_as_ical_string(param);
374 472
375 if(kind==ICAL_VALUE_PARAMETER){ 473 if(kind==ICAL_VALUE_PARAMETER){
376 continue; 474 continue;
377 } 475 }
378 476
379 if (kind_string == 0 ) { 477 if (kind_string == 0 ) {
380 char temp[TMP_BUF_SIZE]; 478 icalerror_warn("Got a parameter of unknown kind for the following property");
381 snprintf(temp, TMP_BUF_SIZE,"Got a parameter of unknown kind in %s property",property_name); 479
382 icalerror_warn(temp); 480 icalerror_warn((property_name) ? property_name : "(NULL)");
383 continue; 481 continue;
384 } 482 }
385 483
386 icalmemory_append_string(&buf, &buf_ptr, &buf_size, " ;"); 484 icalmemory_append_string(&buf, &buf_ptr, &buf_size, ";");
387 icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); 485 icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string);
388 icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline);
389
390 } 486 }
391 487
392 /* Append value */ 488 /* Append value */
393 489
394 icalmemory_append_string(&buf, &buf_ptr, &buf_size, " :"); 490 icalmemory_append_string(&buf, &buf_ptr, &buf_size, ":");
395 491
396 value = icalproperty_get_value(prop); 492 value = icalproperty_get_value(prop);
397 493
398 if (value != 0){ 494 if (value != 0){
399 const char *str = icalvalue_as_ical_string(value); 495 const char *str = icalvalue_as_ical_string(value);
400 icalerror_assert((str !=0),"Could not get string representation of a value"); 496 icalerror_assert((str !=0),"Could not get string representation of a value");
401 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str); 497 icalmemory_append_string(&buf, &buf_ptr, &buf_size, str);
402 } else { 498 } else {
@@ -404,77 +500,74 @@ icalproperty_as_ical_string (icalproperty* prop)
404 500
405 } 501 }
406 502
407 icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); 503 icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline);
408 504
409 /* Now, copy the buffer to a tmp_buffer, which is safe to give to 505 /* Now, copy the buffer to a tmp_buffer, which is safe to give to
410 the caller without worring about de-allocating it. */ 506 the caller without worring about de-allocating it. */
411 507
412 508 /* We now use a function to fold the line properly every 75 characters. */
413 out_buf = icalmemory_tmp_buffer(strlen(buf)+1); 509 out_buf = fold_property_line (buf);
414 strcpy(out_buf, buf);
415 510
416 icalmemory_free_buffer(buf); 511 icalmemory_free_buffer(buf);
417 512
418 return out_buf; 513 return out_buf;
419} 514}
420 515
421 516
422 517
423icalproperty_kind 518icalproperty_kind
424icalproperty_isa (icalproperty* property) 519icalproperty_isa (icalproperty* p)
425{ 520{
426 struct icalproperty_impl *p = (struct icalproperty_impl*)property; 521 if(p != 0){
427
428 if(property != 0){
429 return p->kind; 522 return p->kind;
430 } 523 }
431 524
432 return ICAL_NO_PROPERTY; 525 return ICAL_NO_PROPERTY;
433} 526}
434 527
435int 528int
436icalproperty_isa_property (void* property) 529icalproperty_isa_property (void* property)
437{ 530{
438 struct icalproperty_impl *impl = (struct icalproperty_impl*)property; 531 icalproperty *impl = (icalproperty *) property;
439 532
440 icalerror_check_arg_rz( (property!=0), "property"); 533 icalerror_check_arg_rz( (property!=0), "property");
441
442 if (strcmp(impl->id,"prop") == 0) { 534 if (strcmp(impl->id,"prop") == 0) {
443 return 1; 535 return 1;
444 } else { 536 } else {
445 return 0; 537 return 0;
446 } 538 }
447} 539}
448 540
449 541
450void 542void
451icalproperty_add_parameter (icalproperty* prop,icalparameter* parameter) 543icalproperty_add_parameter (icalproperty* p,icalparameter* parameter)
452{ 544{
453 struct icalproperty_impl *p = (struct icalproperty_impl*)prop; 545 icalerror_check_arg_rv( (p!=0),"prop");
454
455 icalerror_check_arg_rv( (prop!=0),"prop");
456 icalerror_check_arg_rv( (parameter!=0),"parameter"); 546 icalerror_check_arg_rv( (parameter!=0),"parameter");
457 547
458 pvl_push(p->parameters, parameter); 548 pvl_push(p->parameters, parameter);
459 549
460} 550}
461 551
462void 552void
463icalproperty_set_parameter (icalproperty* prop,icalparameter* parameter) 553icalproperty_set_parameter (icalproperty* prop,icalparameter* parameter)
464{ 554{
465 icalparameter_kind kind; 555 icalparameter_kind kind;
466 556
467 icalerror_check_arg_rv( (prop!=0),"prop"); 557 icalerror_check_arg_rv( (prop!=0),"prop");
468 icalerror_check_arg_rv( (parameter!=0),"parameter"); 558 icalerror_check_arg_rv( (parameter!=0),"parameter");
469 559
470 kind = icalparameter_isa(parameter); 560 kind = icalparameter_isa(parameter);
471 561 if (kind != ICAL_X_PARAMETER)
472 icalproperty_remove_parameter(prop,kind); 562 icalproperty_remove_parameter_by_kind(prop,kind);
563 else
564 icalproperty_remove_parameter_by_name(prop,
565 icalparameter_get_xname(parameter));
473 566
474 icalproperty_add_parameter(prop,parameter); 567 icalproperty_add_parameter(prop,parameter);
475} 568}
476 569
477void icalproperty_set_parameter_from_string(icalproperty* prop, 570void icalproperty_set_parameter_from_string(icalproperty* prop,
478 const char* name, const char* value) 571 const char* name, const char* value)
479{ 572{
480 573
@@ -486,24 +579,28 @@ void icalproperty_set_parameter_from_string(icalproperty* prop,
486 icalerror_check_arg_rv( (value!=0),"value"); 579 icalerror_check_arg_rv( (value!=0),"value");
487 580
488 kind = icalparameter_string_to_kind(name); 581 kind = icalparameter_string_to_kind(name);
489 582
490 if(kind == ICAL_NO_PARAMETER){ 583 if(kind == ICAL_NO_PARAMETER){
491 icalerror_set_errno(ICAL_BADARG_ERROR); 584 icalerror_set_errno(ICAL_BADARG_ERROR);
492 return; 585 return;
493 } 586 }
494 587
495 param = icalparameter_new_from_value_string(kind,value); 588 param = icalparameter_new_from_value_string(kind,value);
496 589
497 if (param == 0){ 590 if (param == 0){
498 icalerror_set_errno(ICAL_BADARG_ERROR); 591 icalerror_set_errno(ICAL_BADARG_ERROR);
499 return; 592 return;
500 } 593 }
501 594
595 if(kind == ICAL_X_PARAMETER){
596 icalparameter_set_xname(param, name);
597 }
598
502 icalproperty_set_parameter(prop,param); 599 icalproperty_set_parameter(prop,param);
503 600
504} 601}
505 602
506const char* icalproperty_get_parameter_as_string(icalproperty* prop, 603const char* icalproperty_get_parameter_as_string(icalproperty* prop,
507 const char* name) 604 const char* name)
508{ 605{
509 icalparameter_kind kind; 606 icalparameter_kind kind;
@@ -511,79 +608,189 @@ const char* icalproperty_get_parameter_as_string(icalproperty* prop,
511 char* str; 608 char* str;
512 char* pv; 609 char* pv;
513 610
514 icalerror_check_arg_rz( (prop!=0),"prop"); 611 icalerror_check_arg_rz( (prop!=0),"prop");
515 icalerror_check_arg_rz( (name!=0),"name"); 612 icalerror_check_arg_rz( (name!=0),"name");
516 613
517 kind = icalparameter_string_to_kind(name); 614 kind = icalparameter_string_to_kind(name);
518 615
519 if(kind == ICAL_NO_PROPERTY){ 616 if(kind == ICAL_NO_PARAMETER){
520 /* icalenum_string_to_parameter_kind will set icalerrno */ 617 /* icalenum_string_to_parameter_kind will set icalerrno */
521 return 0; 618 return 0;
522 } 619 }
620
621 for(param = icalproperty_get_first_parameter(prop,kind);
622 param != 0;
623 param = icalproperty_get_next_parameter(prop,kind)) {
624 if (kind != ICAL_X_PARAMETER) {
625 break;
626 }
523 627
524 param = icalproperty_get_first_parameter(prop,kind); 628 if (strcmp(icalparameter_get_xname(param),name)==0) {
629 break;
630 }
631 }
525 632
526 if (param == 0){ 633 if (param == 0){
527 return 0; 634 return 0;
528 } 635 }
529 636
637
530 str = icalparameter_as_ical_string(param); 638 str = icalparameter_as_ical_string(param);
531 639
532 pv = strchr(str,'='); 640 pv = strchr(str,'=');
533 641
534 if(pv == 0){ 642 if(pv == 0){
535 icalerror_set_errno(ICAL_INTERNAL_ERROR); 643 icalerror_set_errno(ICAL_INTERNAL_ERROR);
536 return 0; 644 return 0;
537 } 645 }
538 646
539 return pv+1; 647 return pv+1;
540 648
541} 649}
542 650
651/** @see icalproperty_remove_parameter_by_kind()
652 *
653 * @deprecated Please use icalproperty_remove_parameter_by_kind()
654 * instead.
655 */
656
543void 657void
544icalproperty_remove_parameter (icalproperty* prop, icalparameter_kind kind) 658icalproperty_remove_parameter(icalproperty* prop, icalparameter_kind kind)
659{
660 icalproperty_remove_parameter_by_kind(prop, kind);
661}
662
663
664/** @brief Remove all parameters with the specified kind.
665 *
666 * @param prop A valid icalproperty.
667 * @param kind The kind to remove (ex. ICAL_TZID_PARAMETER)
668 *
669 * See icalproperty_remove_parameter_by_name() and
670 * icalproperty_remove_parameter_by_ref() for alternate ways of
671 * removing parameters
672 */
673
674void
675icalproperty_remove_parameter_by_kind(icalproperty* prop, icalparameter_kind kind)
545{ 676{
546 pvl_elem p; 677 pvl_elem p;
547 struct icalproperty_impl *impl = (struct icalproperty_impl*)prop;
548 678
549 icalerror_check_arg_rv((prop!=0),"prop"); 679 icalerror_check_arg_rv((prop!=0),"prop");
550 680
551 for(p=pvl_head(impl->parameters);p != 0; p = pvl_next(p)){ 681 for(p=pvl_head(prop->parameters);p != 0; p = pvl_next(p)){
552 icalparameter* param = (icalparameter *)pvl_data (p); 682 icalparameter* param = (icalparameter *)pvl_data (p);
553 if (icalparameter_isa(param) == kind) { 683 if (icalparameter_isa(param) == kind) {
554 pvl_remove (impl->parameters, p); 684 pvl_remove (prop->parameters, p);
555 icalparameter_free (param); 685 icalparameter_free(param);
556 break; 686 break;
557 } 687 }
558 } 688 }
559} 689}
560 690
561 691
562int 692/** @brief Remove all parameters with the specified name.
563icalproperty_count_parameters (icalproperty* prop) 693 *
694 * @param prop A valid icalproperty.
695 * @param name The name of the parameter to remove
696 *
697 * This function removes paramters with the given name. The name
698 * corresponds to either a built-in name (TZID, etc.) or the name of
699 * an extended parameter (X-FOO)
700 *
701 * See icalproperty_remove_parameter_by_kind() and
702 * icalproperty_remove_parameter_by_ref() for alternate ways of removing
703 * parameters
704 */
705
706
707void
708icalproperty_remove_parameter_by_name(icalproperty* prop, const char *name)
564{ 709{
565 struct icalproperty_impl *p = (struct icalproperty_impl*)prop; 710 pvl_elem p;
711
712 icalerror_check_arg_rv((prop!=0),"prop");
713
714 for(p=pvl_head(prop->parameters);p != 0; p = pvl_next(p)){
715 icalparameter* param = (icalparameter *)pvl_data (p);
716 const char * kind_string;
717
718 if (icalparameter_isa(param) == ICAL_X_PARAMETER)
719 kind_string = icalparameter_get_xname(param);
720 else
721 kind_string = icalparameter_kind_to_string(icalparameter_isa(param));
722
723 if (!kind_string)
724 continue;
566 725
726 if (0 == strcmp(kind_string, name)) {
727 pvl_remove (prop->parameters, p);
728 break;
729 }
730 }
731}
732
733
734/** @brief Remove the specified parameter reference from the property.
735 *
736 * @param prop A valid icalproperty.
737 * @param parameter A reference to a specific icalparameter.
738 *
739 * This function removes the specified parameter reference from the
740 * property.
741 */
742
743void
744icalproperty_remove_parameter_by_ref(icalproperty* prop, icalparameter* parameter)
745{
746 pvl_elem p;
747 icalparameter_kind kind;
748 const char *name;
749
750 icalerror_check_arg_rv((prop!=0),"prop");
751 icalerror_check_arg_rv((parameter!=0),"parameter");
752
753 kind = icalparameter_isa(parameter);
754 name = icalparameter_get_xname(parameter);
755
756 /*
757 * FIXME If it's an X- parameter, also compare the names. It would be nice
758 * to have a better abstraction like icalparameter_equals()
759 */
760 for(p=pvl_head(prop->parameters);p != 0; p = pvl_next(p)){
761 icalparameter* p_param = (icalparameter *)pvl_data (p);
762 if (icalparameter_isa(p_param) == kind &&
763 (kind != ICAL_X_PARAMETER ||
764 !strcmp(icalparameter_get_xname(p_param), name))) {
765 pvl_remove (prop->parameters, p);
766 icalparameter_free(p_param);
767 break;
768 }
769 }
770}
771
772
773int
774icalproperty_count_parameters (const icalproperty* prop)
775{
567 if(prop != 0){ 776 if(prop != 0){
568 return pvl_count(p->parameters); 777 return pvl_count(prop->parameters);
569 } 778 }
570 779
571 icalerror_set_errno(ICAL_USAGE_ERROR); 780 icalerror_set_errno(ICAL_USAGE_ERROR);
572 return -1; 781 return -1;
573} 782}
574 783
575 784
576icalparameter* 785icalparameter*
577icalproperty_get_first_parameter (icalproperty* prop, icalparameter_kind kind) 786icalproperty_get_first_parameter(icalproperty* p, icalparameter_kind kind)
578{ 787{
579 struct icalproperty_impl *p = (struct icalproperty_impl*)prop; 788 icalerror_check_arg_rz( (p!=0),"prop");
580
581 icalerror_check_arg_rz( (prop!=0),"prop");
582 789
583 p->parameter_iterator = pvl_head(p->parameters); 790 p->parameter_iterator = pvl_head(p->parameters);
584 791
585 if (p->parameter_iterator == 0) { 792 if (p->parameter_iterator == 0) {
586 return 0; 793 return 0;
587 } 794 }
588 795
589 for( p->parameter_iterator = pvl_head(p->parameters); 796 for( p->parameter_iterator = pvl_head(p->parameters);
@@ -597,21 +804,19 @@ icalproperty_get_first_parameter (icalproperty* prop, icalparameter_kind kind)
597 } 804 }
598 } 805 }
599 806
600 return 0; 807 return 0;
601} 808}
602 809
603 810
604icalparameter* 811icalparameter*
605icalproperty_get_next_parameter (icalproperty* prop, icalparameter_kind kind) 812icalproperty_get_next_parameter (icalproperty* p, icalparameter_kind kind)
606{ 813{
607 struct icalproperty_impl *p = (struct icalproperty_impl*)prop; 814 icalerror_check_arg_rz( (p!=0),"prop");
608
609 icalerror_check_arg_rz( (prop!=0),"prop");
610 815
611 if (p->parameter_iterator == 0) { 816 if (p->parameter_iterator == 0) {
612 return 0; 817 return 0;
613 } 818 }
614 819
615 for( p->parameter_iterator = pvl_next(p->parameter_iterator); 820 for( p->parameter_iterator = pvl_next(p->parameter_iterator);
616 p->parameter_iterator !=0; 821 p->parameter_iterator !=0;
617 p->parameter_iterator = pvl_next(p->parameter_iterator)){ 822 p->parameter_iterator = pvl_next(p->parameter_iterator)){
@@ -623,32 +828,30 @@ icalproperty_get_next_parameter (icalproperty* prop, icalparameter_kind kind)
623 } 828 }
624 } 829 }
625 830
626 return 0; 831 return 0;
627 832
628} 833}
629 834
630void 835void
631icalproperty_set_value (icalproperty* prop, icalvalue* value) 836icalproperty_set_value (icalproperty* p, icalvalue* value)
632{ 837{
633 struct icalproperty_impl *p = (struct icalproperty_impl*)prop; 838 icalerror_check_arg_rv((p !=0),"prop");
634
635 icalerror_check_arg_rv((prop !=0),"prop");
636 icalerror_check_arg_rv((value !=0),"value"); 839 icalerror_check_arg_rv((value !=0),"value");
637 840
638 if (p->value != 0){ 841 if (p->value != 0){
639 icalvalue_set_parent(p->value,0); 842 icalvalue_set_parent(p->value,0);
640 icalvalue_free(p->value); 843 icalvalue_free(p->value);
641 p->value = 0; 844 p->value = 0;
642 } 845 }
643 846
644 p->value = value; 847 p->value = value;
645 848
646 icalvalue_set_parent(value,prop); 849 icalvalue_set_parent(value,p);
647} 850}
648 851
649 852
650void icalproperty_set_value_from_string(icalproperty* prop,const char* str, 853void icalproperty_set_value_from_string(icalproperty* prop,const char* str,
651 const char* type) 854 const char* type)
652{ 855{
653 icalvalue *oval,*nval; 856 icalvalue *oval,*nval;
654 icalvalue_kind kind = ICAL_NO_VALUE; 857 icalvalue_kind kind = ICAL_NO_VALUE;
@@ -686,85 +889,81 @@ void icalproperty_set_value_from_string(icalproperty* prop,const char* str,
686 } 889 }
687 890
688 icalproperty_set_value(prop,nval); 891 icalproperty_set_value(prop,nval);
689 892
690 893
691} 894}
692 895
693icalvalue* 896icalvalue*
694icalproperty_get_value (icalproperty* prop) 897icalproperty_get_value(const icalproperty* prop)
695{ 898{
696 struct icalproperty_impl *p = (struct icalproperty_impl*)prop;
697
698 icalerror_check_arg_rz( (prop!=0),"prop"); 899 icalerror_check_arg_rz( (prop!=0),"prop");
699 900
700 return p->value; 901 return prop->value;
701} 902}
702 903
703const char* icalproperty_get_value_as_string(icalproperty* prop) 904const char* icalproperty_get_value_as_string(const icalproperty* prop)
704{ 905{
705 icalvalue *value; 906 icalvalue *value;
706 907
707 struct icalproperty_impl *impl = (struct icalproperty_impl*)prop;
708
709 icalerror_check_arg_rz( (prop!=0),"prop"); 908 icalerror_check_arg_rz( (prop!=0),"prop");
710 909
711 value = impl->value; 910 value = prop->value;
712 911
713 return icalvalue_as_ical_string(value); 912 return icalvalue_as_ical_string(value);
714} 913}
715 914
716 915
717void icalproperty_set_x_name(icalproperty* prop, const char* name) 916void icalproperty_set_x_name(icalproperty* prop, const char* name)
718{ 917{
719 struct icalproperty_impl *impl = (struct icalproperty_impl*)prop;
720
721 icalerror_check_arg_rv( (name!=0),"name"); 918 icalerror_check_arg_rv( (name!=0),"name");
722 icalerror_check_arg_rv( (prop!=0),"prop"); 919 icalerror_check_arg_rv( (prop!=0),"prop");
723 920
724 if (impl->x_name != 0) { 921 if (prop->x_name != 0) {
725 free(impl->x_name); 922 free(prop->x_name);
726 } 923 }
727 924
728 impl->x_name = icalmemory_strdup(name); 925 prop->x_name = icalmemory_strdup(name);
729 926
730 if(impl->x_name == 0){ 927 if(prop->x_name == 0){
731 icalerror_set_errno(ICAL_NEWFAILED_ERROR); 928 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
732 } 929 }
733 930
734} 931}
735 932
736const char* icalproperty_get_x_name(icalproperty* prop){ 933const char* icalproperty_get_x_name(icalproperty* prop){
737
738 struct icalproperty_impl *impl = (struct icalproperty_impl*)prop;
739
740 icalerror_check_arg_rz( (prop!=0),"prop"); 934 icalerror_check_arg_rz( (prop!=0),"prop");
741 935
742 return impl->x_name; 936 return prop->x_name;
743} 937}
744 938
745 939
746/* From Jonathan Yue <jonathan.yue@cp.net> */ 940const char* icalproperty_get_name(const icalproperty* prop)
747const char* icalproperty_get_name (icalproperty* prop) 941{
942#ifndef NO_WARN_DEPRECATED
943 icalerror_warn("icalproperty_get_name() is DEPRECATED, please use icalproperty_get_property_name() instead.");
944#endif
945 return icalproperty_get_property_name(prop);
946}
947
948const char* icalproperty_get_property_name(const icalproperty* prop)
748{ 949{
749 950
750 const char* property_name = 0; 951 const char* property_name = 0;
751 size_t buf_size = 256; 952 size_t buf_size = 256;
752 char* buf = icalmemory_new_buffer(buf_size); 953 char* buf = icalmemory_new_buffer(buf_size);
753 char* buf_ptr = buf; 954 char* buf_ptr = buf;
754 955
755 struct icalproperty_impl *impl = (struct icalproperty_impl*)prop;
756
757 icalerror_check_arg_rz( (prop!=0),"prop"); 956 icalerror_check_arg_rz( (prop!=0),"prop");
758 957
759 if (impl->kind == ICAL_X_PROPERTY && impl->x_name != 0){ 958 if (prop->kind == ICAL_X_PROPERTY && prop->x_name != 0){
760 property_name = impl->x_name; 959 property_name = prop->x_name;
761 } else { 960 } else {
762 property_name = icalproperty_kind_to_string(impl->kind); 961 property_name = icalproperty_kind_to_string(prop->kind);
763 } 962 }
764 963
765 if (property_name == 0 ) { 964 if (property_name == 0 ) {
766 icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); 965 icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
767 return 0; 966 return 0;
768 967
769 } else { 968 } else {
770 /* _append_string will automatically grow the buffer if 969 /* _append_string will automatically grow the buffer if
@@ -780,31 +979,19 @@ const char* icalproperty_get_name (icalproperty* prop)
780} 979}
781 980
782 981
783 982
784 983
785void icalproperty_set_parent(icalproperty* property, 984void icalproperty_set_parent(icalproperty* property,
786 icalcomponent* component) 985 icalcomponent* component)
787{ 986{
788 struct icalproperty_impl *impl = (struct icalproperty_impl*)property;
789
790 icalerror_check_arg_rv( (property!=0),"property"); 987 icalerror_check_arg_rv( (property!=0),"property");
791 988
792 impl->parent = component; 989 property->parent = component;
793} 990}
794 991
795icalcomponent* icalproperty_get_parent(icalproperty* property) 992icalcomponent* icalproperty_get_parent(const icalproperty* property)
796{ 993{
797 struct icalproperty_impl *impl = (struct icalproperty_impl*)property;
798
799 icalerror_check_arg_rz( (property!=0),"property"); 994 icalerror_check_arg_rz( (property!=0),"property");
800 995
801 return impl->parent; 996 return property->parent;
802} 997}
803
804
805
806
807
808
809
810/* Everything below this line is machine generated. Do not edit. */