Diffstat (limited to 'libical/src/libical/icalvalue.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libical/src/libical/icalvalue.c | 1215 |
1 files changed, 1215 insertions, 0 deletions
diff --git a/libical/src/libical/icalvalue.c b/libical/src/libical/icalvalue.c new file mode 100644 index 0000000..eb5476e --- a/dev/null +++ b/libical/src/libical/icalvalue.c | |||
@@ -0,0 +1,1215 @@ | |||
1 | /* -*- Mode: C -*- */ | ||
2 | /*====================================================================== | ||
3 | FILE: icalvalue.c | ||
4 | CREATOR: eric 02 May 1999 | ||
5 | |||
6 | $Id$ | ||
7 | |||
8 | |||
9 | (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org | ||
10 | |||
11 | This program is free software; you can redistribute it and/or modify | ||
12 | it under the terms of either: | ||
13 | |||
14 | The LGPL as published by the Free Software Foundation, version | ||
15 | 2.1, available at: http://www.fsf.org/copyleft/lesser.html | ||
16 | |||
17 | Or: | ||
18 | |||
19 | The Mozilla Public License Version 1.0. You may obtain a copy of | ||
20 | the License at http://www.mozilla.org/MPL/ | ||
21 | |||
22 | The original code is icalvalue.c | ||
23 | |||
24 | Contributions from: | ||
25 | Graham Davison (g.m.davison@computer.org) | ||
26 | |||
27 | |||
28 | ======================================================================*/ | ||
29 | |||
30 | #ifdef HAVE_CONFIG_H | ||
31 | #include <config.h> | ||
32 | #endif | ||
33 | |||
34 | #include "icalerror.h" | ||
35 | #include "icalmemory.h" | ||
36 | #include "icalparser.h" | ||
37 | #include "icalenums.h" | ||
38 | #include "icalvalueimpl.h" | ||
39 | |||
40 | #include <stdlib.h> /* for malloc */ | ||
41 | #include <stdio.h> /* for sprintf */ | ||
42 | #include <string.h> /* For memset, others */ | ||
43 | #include <stddef.h> /* For offsetof() macro */ | ||
44 | #include <errno.h> | ||
45 | #include <time.h> /* for mktime */ | ||
46 | #include <stdlib.h> /* for atoi and atof */ | ||
47 | #include <limits.h> /* for SHRT_MAX */ | ||
48 | |||
49 | int snprintf(char *str, size_t n, char const *fmt, ...); | ||
50 | |||
51 | #if _MAC_OS_ | ||
52 | #include "icalmemory_strdup.h" | ||
53 | #endif | ||
54 | |||
55 | #define TMP_BUF_SIZE 1024 | ||
56 | |||
57 | void print_datetime_to_string(char* str, struct icaltimetype *data); | ||
58 | void print_date_to_string(char* str, struct icaltimetype *data); | ||
59 | void print_time_to_string(char* str, struct icaltimetype *data); | ||
60 | void print_recur_to_string(char* str, struct icaltimetype *data); | ||
61 | |||
62 | |||
63 | struct icalvalue_impl* icalvalue_new_impl(icalvalue_kind kind){ | ||
64 | |||
65 | struct icalvalue_impl* v; | ||
66 | |||
67 | if ( ( v = (struct icalvalue_impl*) | ||
68 | malloc(sizeof(struct icalvalue_impl))) == 0) { | ||
69 | icalerror_set_errno(ICAL_NEWFAILED_ERROR); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | strcpy(v->id,"val"); | ||
74 | |||
75 | v->kind = kind; | ||
76 | v->size = 0; | ||
77 | v->parent = 0; | ||
78 | v->x_value = 0; | ||
79 | memset(&(v->data),0,sizeof(v->data)); | ||
80 | |||
81 | return v; | ||
82 | |||
83 | } | ||
84 | |||
85 | |||
86 | |||
87 | icalvalue* | ||
88 | icalvalue_new (icalvalue_kind kind) | ||
89 | { | ||
90 | return (icalvalue*)icalvalue_new_impl(kind); | ||
91 | } | ||
92 | |||
93 | icalvalue* icalvalue_new_clone(icalvalue* value){ | ||
94 | |||
95 | struct icalvalue_impl* new; | ||
96 | struct icalvalue_impl* old = (struct icalvalue_impl*)value; | ||
97 | |||
98 | new = icalvalue_new_impl(old->kind); | ||
99 | |||
100 | if (new == 0){ | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | |||
105 | strcpy(new->id, old->id); | ||
106 | new->kind = old->kind; | ||
107 | new->size = old->size; | ||
108 | |||
109 | switch (new->kind){ | ||
110 | |||
111 | /* The contents of the attach value may or may not be owned by the | ||
112 | * library. */ | ||
113 | case ICAL_ATTACH_VALUE: | ||
114 | case ICAL_BINARY_VALUE: | ||
115 | { | ||
116 | /* HACK ugh. I don't feel like impleenting this */ | ||
117 | } | ||
118 | |||
119 | case ICAL_STRING_VALUE: | ||
120 | case ICAL_TEXT_VALUE: | ||
121 | case ICAL_CALADDRESS_VALUE: | ||
122 | case ICAL_URI_VALUE: | ||
123 | { | ||
124 | if (old->data.v_string != 0) { | ||
125 | new->data.v_string=icalmemory_strdup(old->data.v_string); | ||
126 | |||
127 | if ( new->data.v_string == 0 ) { | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | } | ||
132 | break; | ||
133 | } | ||
134 | case ICAL_RECUR_VALUE: | ||
135 | { | ||
136 | if(old->data.v_recur != 0){ | ||
137 | new->data.v_recur = malloc(sizeof(struct icalrecurrencetype)); | ||
138 | |||
139 | if(new->data.v_recur == 0){ | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | memcpy(new->data.v_recur, old->data.v_recur, | ||
144 | sizeof(struct icalrecurrencetype)); | ||
145 | } | ||
146 | break; | ||
147 | } | ||
148 | |||
149 | default: | ||
150 | { | ||
151 | /* all of the other types are stored as values, not | ||
152 | pointers, so we can just copy the whole structure. */ | ||
153 | |||
154 | new->data = old->data; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | return new; | ||
159 | } | ||
160 | |||
161 | char* icalmemory_strdup_and_dequote(const char* str) | ||
162 | { | ||
163 | const char* p; | ||
164 | char* out = (char*)malloc(sizeof(char) * strlen(str) +1); | ||
165 | char* pout; | ||
166 | |||
167 | if (out == 0){ | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | pout = out; | ||
172 | |||
173 | for (p = str; *p!=0; p++){ | ||
174 | |||
175 | if( *p == '\\') | ||
176 | { | ||
177 | p++; | ||
178 | switch(*p){ | ||
179 | case 0: | ||
180 | { | ||
181 | *pout = '\0'; | ||
182 | break; | ||
183 | |||
184 | } | ||
185 | case 'n': | ||
186 | { | ||
187 | *pout = '\n'; | ||
188 | break; | ||
189 | } | ||
190 | case 'N': | ||
191 | { | ||
192 | *pout = '\n'; | ||
193 | break; | ||
194 | } | ||
195 | case '\\': | ||
196 | case ',': | ||
197 | case ';': | ||
198 | { | ||
199 | *pout = *p; | ||
200 | break; | ||
201 | } | ||
202 | default: | ||
203 | { | ||
204 | *pout = ' '; | ||
205 | } | ||
206 | } | ||
207 | } else { | ||
208 | *pout = *p; | ||
209 | } | ||
210 | |||
211 | pout++; | ||
212 | |||
213 | } | ||
214 | |||
215 | *pout = '\0'; | ||
216 | |||
217 | return out; | ||
218 | } | ||
219 | |||
220 | icalvalue* icalvalue_new_enum(icalvalue_kind kind, int x_type, const char* str) | ||
221 | { | ||
222 | int e = icalproperty_string_to_enum(str); | ||
223 | struct icalvalue_impl *value; | ||
224 | |||
225 | if(e != 0 && icalproperty_enum_belongs_to_property( | ||
226 | icalproperty_value_kind_to_kind(kind),e)) { | ||
227 | |||
228 | value = icalvalue_new_impl(kind); | ||
229 | value->data.v_enum = e; | ||
230 | } else { | ||
231 | /* Make it an X value */ | ||
232 | value = icalvalue_new_impl(kind); | ||
233 | value->data.v_enum = x_type; | ||
234 | icalvalue_set_x(value,str); | ||
235 | } | ||
236 | |||
237 | return value; | ||
238 | } | ||
239 | |||
240 | |||
241 | icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,const char* str,icalproperty** error) | ||
242 | { | ||
243 | |||
244 | struct icalvalue_impl *value = 0; | ||
245 | struct icalattachtype *attach = 0; | ||
246 | |||
247 | icalerror_check_arg_rz(str!=0,"str"); | ||
248 | |||
249 | if (error != 0){ | ||
250 | *error = 0; | ||
251 | } | ||
252 | |||
253 | switch (kind){ | ||
254 | |||
255 | case ICAL_ATTACH_VALUE: | ||
256 | attach = icalattachtype_new(); | ||
257 | value = icalvalue_new_attach( attach ); | ||
258 | icalattachtype_free( attach ); | ||
259 | icalattachtype_set_url( value->data.v_attach, str ); | ||
260 | break; | ||
261 | case ICAL_BINARY_VALUE: | ||
262 | case ICAL_BOOLEAN_VALUE: | ||
263 | { | ||
264 | /* HACK */ | ||
265 | value = 0; | ||
266 | |||
267 | if (error != 0){ | ||
268 | char temp[TMP_BUF_SIZE]; | ||
269 | sprintf(temp,"%s Values are not implemented", | ||
270 | icalparameter_kind_to_string(kind)); | ||
271 | *error = icalproperty_vanew_xlicerror( | ||
272 | temp, | ||
273 | icalparameter_new_xlicerrortype( | ||
274 | ICAL_XLICERRORTYPE_VALUEPARSEERROR), | ||
275 | 0); | ||
276 | } | ||
277 | break; | ||
278 | } | ||
279 | |||
280 | |||
281 | case ICAL_TRANSP_VALUE: | ||
282 | value = icalvalue_new_enum(kind, ICAL_TRANSP_X,str); | ||
283 | break; | ||
284 | case ICAL_METHOD_VALUE: | ||
285 | value = icalvalue_new_enum(kind, ICAL_METHOD_X,str); | ||
286 | break; | ||
287 | case ICAL_STATUS_VALUE: | ||
288 | value = icalvalue_new_enum(kind, ICAL_STATUS_X,str); | ||
289 | break; | ||
290 | case ICAL_ACTION_VALUE: | ||
291 | value = icalvalue_new_enum(kind, ICAL_ACTION_X,str); | ||
292 | break; | ||
293 | case ICAL_CLASS_VALUE: | ||
294 | value = icalvalue_new_enum(kind, ICAL_CLASS_X,str); | ||
295 | break; | ||
296 | |||
297 | |||
298 | case ICAL_INTEGER_VALUE: | ||
299 | { | ||
300 | value = icalvalue_new_integer(atoi(str)); | ||
301 | break; | ||
302 | } | ||
303 | |||
304 | case ICAL_FLOAT_VALUE: | ||
305 | { | ||
306 | value = icalvalue_new_float((float )atof(str)); | ||
307 | break; | ||
308 | } | ||
309 | |||
310 | case ICAL_UTCOFFSET_VALUE: | ||
311 | { | ||
312 | value = icalparser_parse_value(kind,str,(icalcomponent*)0); | ||
313 | break; | ||
314 | } | ||
315 | |||
316 | case ICAL_TEXT_VALUE: | ||
317 | { | ||
318 | char* dequoted_str = icalmemory_strdup_and_dequote(str); | ||
319 | value = icalvalue_new_text(dequoted_str); | ||
320 | free(dequoted_str); | ||
321 | break; | ||
322 | } | ||
323 | |||
324 | |||
325 | case ICAL_STRING_VALUE: | ||
326 | { | ||
327 | value = icalvalue_new_string(str); | ||
328 | break; | ||
329 | } | ||
330 | |||
331 | case ICAL_CALADDRESS_VALUE: | ||
332 | { | ||
333 | value = icalvalue_new_caladdress(str); | ||
334 | break; | ||
335 | } | ||
336 | |||
337 | case ICAL_URI_VALUE: | ||
338 | { | ||
339 | value = icalvalue_new_uri(str); | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | |||
344 | case ICAL_GEO_VALUE: | ||
345 | { | ||
346 | value = 0; | ||
347 | /* HACK */ | ||
348 | |||
349 | if (error != 0){ | ||
350 | char temp[TMP_BUF_SIZE]; | ||
351 | sprintf(temp,"GEO Values are not implemented"); | ||
352 | *error = icalproperty_vanew_xlicerror( | ||
353 | temp, | ||
354 | icalparameter_new_xlicerrortype( | ||
355 | ICAL_XLICERRORTYPE_VALUEPARSEERROR), | ||
356 | 0); | ||
357 | } | ||
358 | |||
359 | /*icalerror_warn("Parsing GEO properties is unimplmeneted");*/ | ||
360 | |||
361 | break; | ||
362 | } | ||
363 | |||
364 | case ICAL_RECUR_VALUE: | ||
365 | { | ||
366 | struct icalrecurrencetype rt; | ||
367 | rt = icalrecurrencetype_from_string(str); | ||
368 | if(rt.freq != ICAL_NO_RECURRENCE){ | ||
369 | value = icalvalue_new_recur(rt); | ||
370 | } | ||
371 | break; | ||
372 | } | ||
373 | |||
374 | case ICAL_DATE_VALUE: | ||
375 | case ICAL_DATETIME_VALUE: | ||
376 | { | ||
377 | struct icaltimetype tt; | ||
378 | |||
379 | tt = icaltime_from_string(str); | ||
380 | if(!icaltime_is_null_time(tt)){ | ||
381 | value = icalvalue_new_impl(kind); | ||
382 | value->data.v_time = tt; | ||
383 | |||
384 | icalvalue_reset_kind(value); | ||
385 | } | ||
386 | break; | ||
387 | } | ||
388 | |||
389 | case ICAL_DATETIMEPERIOD_VALUE: | ||
390 | { | ||
391 | struct icaltimetype tt; | ||
392 | struct icalperiodtype p; | ||
393 | tt = icaltime_from_string(str); | ||
394 | p = icalperiodtype_from_string(str); | ||
395 | |||
396 | if(!icaltime_is_null_time(tt)){ | ||
397 | value = icalvalue_new_datetime(tt); | ||
398 | } else if (!icalperiodtype_is_null_period(p)){ | ||
399 | value = icalvalue_new_period(p); | ||
400 | } | ||
401 | |||
402 | break; | ||
403 | } | ||
404 | |||
405 | case ICAL_DURATION_VALUE: | ||
406 | { | ||
407 | struct icaldurationtype dur = icaldurationtype_from_string(str); | ||
408 | |||
409 | if(icaldurationtype_is_null_duration(dur)){ | ||
410 | value = 0; | ||
411 | } else { | ||
412 | value = icalvalue_new_duration(dur); | ||
413 | } | ||
414 | |||
415 | break; | ||
416 | } | ||
417 | |||
418 | case ICAL_PERIOD_VALUE: | ||
419 | { | ||
420 | struct icalperiodtype p; | ||
421 | p = icalperiodtype_from_string(str); | ||
422 | |||
423 | if(!icalperiodtype_is_null_period(p)){ | ||
424 | value = icalvalue_new_period(p); | ||
425 | } | ||
426 | break; | ||
427 | } | ||
428 | |||
429 | case ICAL_TRIGGER_VALUE: | ||
430 | { | ||
431 | struct icaltriggertype tr = icaltriggertype_from_string(str); | ||
432 | if (!icaltriggertype_is_null_trigger(tr)){ | ||
433 | value = icalvalue_new_trigger(tr); | ||
434 | } | ||
435 | break; | ||
436 | } | ||
437 | |||
438 | case ICAL_REQUESTSTATUS_VALUE: | ||
439 | { | ||
440 | struct icalreqstattype rst = icalreqstattype_from_string(str); | ||
441 | if(rst.code != ICAL_UNKNOWN_STATUS){ | ||
442 | value = icalvalue_new_requeststatus(rst); | ||
443 | } | ||
444 | break; | ||
445 | |||
446 | } | ||
447 | default: | ||
448 | { | ||
449 | |||
450 | if (error != 0 ){ | ||
451 | char temp[TMP_BUF_SIZE]; | ||
452 | |||
453 | snprintf(temp,TMP_BUF_SIZE,"Unknown type for \'%s\'",str); | ||
454 | |||
455 | *error = icalproperty_vanew_xlicerror( | ||
456 | temp, | ||
457 | icalparameter_new_xlicerrortype( | ||
458 | ICAL_XLICERRORTYPE_VALUEPARSEERROR), | ||
459 | 0); | ||
460 | } | ||
461 | |||
462 | icalerror_warn("icalvalue_new_from_string got an unknown value type"); | ||
463 | value=0; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | |||
468 | if (error != 0 && *error == 0 && value == 0){ | ||
469 | char temp[TMP_BUF_SIZE]; | ||
470 | |||
471 | snprintf(temp,TMP_BUF_SIZE,"Failed to parse value: \'%s\'",str); | ||
472 | |||
473 | *error = icalproperty_vanew_xlicerror( | ||
474 | temp, | ||
475 | icalparameter_new_xlicerrortype( | ||
476 | ICAL_XLICERRORTYPE_VALUEPARSEERROR), | ||
477 | 0); | ||
478 | } | ||
479 | |||
480 | |||
481 | return value; | ||
482 | |||
483 | } | ||
484 | |||
485 | icalvalue* icalvalue_new_from_string(icalvalue_kind kind,const char* str) | ||
486 | { | ||
487 | return icalvalue_new_from_string_with_error(kind,str,(icalproperty*)0); | ||
488 | } | ||
489 | |||
490 | |||
491 | |||
492 | void | ||
493 | icalvalue_free (icalvalue* value) | ||
494 | { | ||
495 | struct icalvalue_impl* v = (struct icalvalue_impl*)value; | ||
496 | |||
497 | icalerror_check_arg_rv((value != 0),"value"); | ||
498 | |||
499 | #ifdef ICAL_FREE_ON_LIST_IS_ERROR | ||
500 | icalerror_assert( (v->parent ==0),"This value is still attached to a property"); | ||
501 | |||
502 | #else | ||
503 | if(v->parent !=0){ | ||
504 | return; | ||
505 | } | ||
506 | #endif | ||
507 | |||
508 | if(v->x_value != 0){ | ||
509 | free(v->x_value); | ||
510 | } | ||
511 | |||
512 | switch (v->kind){ | ||
513 | case ICAL_ATTACH_VALUE: | ||
514 | icalattachtype_free( v->data.v_attach ); | ||
515 | break; | ||
516 | case ICAL_BINARY_VALUE: { | ||
517 | /* HACK ugh. This will be tough to implement */ | ||
518 | } | ||
519 | case ICAL_TEXT_VALUE: | ||
520 | case ICAL_CALADDRESS_VALUE: | ||
521 | case ICAL_URI_VALUE: | ||
522 | { | ||
523 | if (v->data.v_string != 0) { | ||
524 | free((void*)v->data.v_string); | ||
525 | v->data.v_string = 0; | ||
526 | } | ||
527 | break; | ||
528 | } | ||
529 | case ICAL_RECUR_VALUE: | ||
530 | { | ||
531 | if(v->data.v_recur != 0){ | ||
532 | free((void*)v->data.v_recur); | ||
533 | v->data.v_recur = 0; | ||
534 | } | ||
535 | break; | ||
536 | } | ||
537 | |||
538 | default: | ||
539 | { | ||
540 | /* Nothing to do */ | ||
541 | } | ||
542 | } | ||
543 | |||
544 | v->kind = ICAL_NO_VALUE; | ||
545 | v->size = 0; | ||
546 | v->parent = 0; | ||
547 | memset(&(v->data),0,sizeof(v->data)); | ||
548 | v->id[0] = 'X'; | ||
549 | free(v); | ||
550 | } | ||
551 | |||
552 | int | ||
553 | icalvalue_is_valid (icalvalue* value) | ||
554 | { | ||
555 | /*struct icalvalue_impl* v = (struct icalvalue_impl*)value;*/ | ||
556 | |||
557 | if(value == 0){ | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | return 1; | ||
562 | } | ||
563 | |||
564 | char* icalvalue_binary_as_ical_string(icalvalue* value) { | ||
565 | |||
566 | const char* data; | ||
567 | char* str; | ||
568 | icalerror_check_arg_rz( (value!=0),"value"); | ||
569 | |||
570 | data = icalvalue_get_binary(value); | ||
571 | |||
572 | str = (char*)icalmemory_tmp_buffer(60); | ||
573 | sprintf(str,"icalvalue_binary_as_ical_string is not implemented yet"); | ||
574 | |||
575 | return str; | ||
576 | } | ||
577 | |||
578 | #ifndef _WIN32 | ||
579 | #define MAX_INT_DIGITS 12 /* Enough for 2^32 + sign*/ | ||
580 | char* icalvalue_int_as_ical_string(icalvalue* value) { | ||
581 | |||
582 | int data; | ||
583 | char* str = (char*)icalmemory_tmp_buffer(MAX_INT_DIGITS); | ||
584 | |||
585 | icalerror_check_arg_rz( (value!=0),"value"); | ||
586 | |||
587 | data = icalvalue_get_integer(value); | ||
588 | |||
589 | snprintf(str,MAX_INT_DIGITS,"%d",data); | ||
590 | |||
591 | return str; | ||
592 | } | ||
593 | #else | ||
594 | // snprintf not working on wintendo | ||
595 | |||
596 | #define MAX_INT_DIGITS 32 /* Enough for 2^32 + sign*/ | ||
597 | char* icalvalue_int_as_ical_string(icalvalue* value) { | ||
598 | |||
599 | int data; | ||
600 | char* str = (char*)icalmemory_tmp_buffer(MAX_INT_DIGITS); | ||
601 | |||
602 | icalerror_check_arg_rz( (value!=0),"value"); | ||
603 | |||
604 | data = icalvalue_get_integer(value); | ||
605 | |||
606 | sprintf(str,"%d",data); | ||
607 | |||
608 | return str; | ||
609 | } | ||
610 | |||
611 | #endif | ||
612 | char* icalvalue_utcoffset_as_ical_string(icalvalue* value) | ||
613 | { | ||
614 | int data,h,m,s; | ||
615 | char sign; | ||
616 | char* str = (char*)icalmemory_tmp_buffer(9); | ||
617 | |||
618 | icalerror_check_arg_rz( (value!=0),"value"); | ||
619 | |||
620 | data = icalvalue_get_utcoffset(value); | ||
621 | |||
622 | if (abs(data) == data){ | ||
623 | sign = '+'; | ||
624 | } else { | ||
625 | sign = '-'; | ||
626 | } | ||
627 | |||
628 | h = data/3600; | ||
629 | m = (data - (h*3600))/ 60; | ||
630 | s = (data - (h*3600) - (m*60)); | ||
631 | |||
632 | sprintf(str,"%c%02d%02d%02d",sign,abs(h),abs(m),abs(s)); | ||
633 | |||
634 | return str; | ||
635 | } | ||
636 | |||
637 | char* icalvalue_string_as_ical_string(icalvalue* value) { | ||
638 | |||
639 | const char* data; | ||
640 | char* str = 0; | ||
641 | icalerror_check_arg_rz( (value!=0),"value"); | ||
642 | |||
643 | data = ((struct icalvalue_impl*)value)->data.v_string; | ||
644 | |||
645 | str = (char*)icalmemory_tmp_buffer(strlen(data)+1); | ||
646 | |||
647 | strcpy(str,data); | ||
648 | |||
649 | return str; | ||
650 | } | ||
651 | |||
652 | |||
653 | char* icalvalue_recur_as_ical_string(icalvalue* value) | ||
654 | { | ||
655 | struct icalvalue_impl *impl = (struct icalvalue_impl*)value; | ||
656 | struct icalrecurrencetype *recur = impl->data.v_recur; | ||
657 | |||
658 | return icalrecurrencetype_as_string(recur); | ||
659 | } | ||
660 | |||
661 | char* icalvalue_text_as_ical_string(icalvalue* value) { | ||
662 | |||
663 | char *str; | ||
664 | char *str_p; | ||
665 | char *rtrn; | ||
666 | const char *p; | ||
667 | size_t buf_sz; | ||
668 | int line_length; | ||
669 | |||
670 | line_length = 0; | ||
671 | |||
672 | buf_sz = strlen(((struct icalvalue_impl*)value)->data.v_string)+1; | ||
673 | |||
674 | str_p = str = (char*)icalmemory_new_buffer(buf_sz); | ||
675 | |||
676 | if (str_p == 0){ | ||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | for(p=((struct icalvalue_impl*)value)->data.v_string; *p!=0; p++){ | ||
681 | |||
682 | switch(*p){ | ||
683 | case '\n': { | ||
684 | icalmemory_append_string(&str,&str_p,&buf_sz,"\\n"); | ||
685 | line_length+=3; | ||
686 | break; | ||
687 | } | ||
688 | |||
689 | case '\t': { | ||
690 | icalmemory_append_string(&str,&str_p,&buf_sz,"\\t"); | ||
691 | line_length+=3; | ||
692 | break; | ||
693 | } | ||
694 | case '\r': { | ||
695 | icalmemory_append_string(&str,&str_p,&buf_sz,"\\r"); | ||
696 | line_length+=3; | ||
697 | break; | ||
698 | } | ||
699 | case '\b': { | ||
700 | icalmemory_append_string(&str,&str_p,&buf_sz,"\\b"); | ||
701 | line_length+=3; | ||
702 | break; | ||
703 | } | ||
704 | case '\f': { | ||
705 | icalmemory_append_string(&str,&str_p,&buf_sz,"\\f"); | ||
706 | line_length+=3; | ||
707 | break; | ||
708 | } | ||
709 | |||
710 | case ';': | ||
711 | case ',':{ | ||
712 | icalmemory_append_char(&str,&str_p,&buf_sz,'\\'); | ||
713 | icalmemory_append_char(&str,&str_p,&buf_sz,*p); | ||
714 | line_length+=3; | ||
715 | break; | ||
716 | } | ||
717 | |||
718 | default: { | ||
719 | icalmemory_append_char(&str,&str_p,&buf_sz,*p); | ||
720 | line_length++; | ||
721 | } | ||
722 | } | ||
723 | |||
724 | if (line_length > 65 && *p == ' '){ | ||
725 | icalmemory_append_string(&str,&str_p,&buf_sz,"\n "); | ||
726 | line_length=0; | ||
727 | } | ||
728 | |||
729 | |||
730 | if (line_length > 75){ | ||
731 | icalmemory_append_string(&str,&str_p,&buf_sz,"\n "); | ||
732 | line_length=0; | ||
733 | } | ||
734 | |||
735 | } | ||
736 | |||
737 | /* Assume the last character is not a '\0' and add one. We could | ||
738 | check *str_p != 0, but that would be an uninitialized memory | ||
739 | read. */ | ||
740 | |||
741 | |||
742 | icalmemory_append_char(&str,&str_p,&buf_sz,'\0'); | ||
743 | |||
744 | rtrn = icalmemory_tmp_copy(str); | ||
745 | |||
746 | icalmemory_free_buffer(str); | ||
747 | |||
748 | return rtrn; | ||
749 | } | ||
750 | |||
751 | |||
752 | char* icalvalue_attach_as_ical_string(icalvalue* value) { | ||
753 | |||
754 | struct icalattachtype *a; | ||
755 | char * str; | ||
756 | |||
757 | icalerror_check_arg_rz( (value!=0),"value"); | ||
758 | |||
759 | a = icalvalue_get_attach(value); | ||
760 | |||
761 | if (a->binary != 0) { | ||
762 | return icalvalue_binary_as_ical_string(value); | ||
763 | } else if (a->base64 != 0) { | ||
764 | str = (char*)icalmemory_tmp_buffer(strlen(a->base64)+1); | ||
765 | strcpy(str,a->base64); | ||
766 | return str; | ||
767 | } else if (a->url != 0){ | ||
768 | icalvalue *v = icalvalue_new_text( a->url ); | ||
769 | char *icalstring = icalvalue_string_as_ical_string(v); | ||
770 | icalvalue_free( v ); | ||
771 | return icalstring; | ||
772 | } else { | ||
773 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
774 | return 0; | ||
775 | } | ||
776 | } | ||
777 | |||
778 | |||
779 | char* icalvalue_duration_as_ical_string(icalvalue* value) { | ||
780 | |||
781 | struct icaldurationtype data; | ||
782 | |||
783 | icalerror_check_arg_rz( (value!=0),"value"); | ||
784 | data = icalvalue_get_duration(value); | ||
785 | |||
786 | return icaldurationtype_as_ical_string(data); | ||
787 | } | ||
788 | |||
789 | void print_time_to_string(char* str, struct icaltimetype *data) | ||
790 | { | ||
791 | char temp[20]; | ||
792 | |||
793 | if (data->is_utc == 1){ | ||
794 | sprintf(temp,"%02d%02d%02dZ",data->hour,data->minute,data->second); | ||
795 | } else { | ||
796 | sprintf(temp,"%02d%02d%02d",data->hour,data->minute,data->second); | ||
797 | } | ||
798 | |||
799 | strcat(str,temp); | ||
800 | } | ||
801 | |||
802 | |||
803 | void print_date_to_string(char* str, struct icaltimetype *data) | ||
804 | { | ||
805 | char temp[20]; | ||
806 | |||
807 | sprintf(temp,"%04d%02d%02d",data->year,data->month,data->day); | ||
808 | |||
809 | strcat(str,temp); | ||
810 | } | ||
811 | |||
812 | char* icalvalue_date_as_ical_string(icalvalue* value) { | ||
813 | |||
814 | struct icaltimetype data; | ||
815 | char* str; | ||
816 | icalerror_check_arg_rz( (value!=0),"value"); | ||
817 | data = icalvalue_get_date(value); | ||
818 | |||
819 | str = (char*)icalmemory_tmp_buffer(9); | ||
820 | |||
821 | str[0] = 0; | ||
822 | print_date_to_string(str,&data); | ||
823 | |||
824 | return str; | ||
825 | } | ||
826 | |||
827 | void print_datetime_to_string(char* str, struct icaltimetype *data) | ||
828 | { | ||
829 | print_date_to_string(str,data); | ||
830 | strcat(str,"T"); | ||
831 | print_time_to_string(str,data); | ||
832 | |||
833 | } | ||
834 | |||
835 | const char* icalvalue_datetime_as_ical_string(icalvalue* value) { | ||
836 | |||
837 | struct icaltimetype data; | ||
838 | char* str; | ||
839 | icalvalue_kind kind = icalvalue_isa(value); | ||
840 | |||
841 | icalerror_check_arg_rz( (value!=0),"value"); | ||
842 | |||
843 | |||
844 | if( !(kind == ICAL_DATE_VALUE || kind == ICAL_DATETIME_VALUE )) | ||
845 | { | ||
846 | icalerror_set_errno(ICAL_BADARG_ERROR); | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | data = icalvalue_get_datetime(value); | ||
851 | |||
852 | str = (char*)icalmemory_tmp_buffer(20); | ||
853 | |||
854 | str[0] = 0; | ||
855 | |||
856 | print_datetime_to_string(str,&data); | ||
857 | |||
858 | return str; | ||
859 | |||
860 | } | ||
861 | |||
862 | char* icalvalue_float_as_ical_string(icalvalue* value) { | ||
863 | |||
864 | float data; | ||
865 | char* str; | ||
866 | icalerror_check_arg_rz( (value!=0),"value"); | ||
867 | data = icalvalue_get_float(value); | ||
868 | |||
869 | str = (char*)icalmemory_tmp_buffer(15); | ||
870 | |||
871 | sprintf(str,"%f",data); | ||
872 | |||
873 | return str; | ||
874 | } | ||
875 | |||
876 | char* icalvalue_geo_as_ical_string(icalvalue* value) { | ||
877 | |||
878 | struct icalgeotype data; | ||
879 | char* str; | ||
880 | icalerror_check_arg_rz( (value!=0),"value"); | ||
881 | |||
882 | data = icalvalue_get_geo(value); | ||
883 | |||
884 | str = (char*)icalmemory_tmp_buffer(25); | ||
885 | |||
886 | sprintf(str,"%f;%f",data.lat,data.lon); | ||
887 | |||
888 | return str; | ||
889 | } | ||
890 | |||
891 | const char* icalvalue_datetimeperiod_as_ical_string(icalvalue* value) { | ||
892 | struct icaldatetimeperiodtype dtp = icalvalue_get_datetimeperiod(value); | ||
893 | |||
894 | icalerror_check_arg_rz( (value!=0),"value"); | ||
895 | |||
896 | if(!icaltime_is_null_time(dtp.time)){ | ||
897 | return icaltime_as_ical_string(dtp.time); | ||
898 | } else { | ||
899 | return icalperiodtype_as_ical_string(dtp.period); | ||
900 | } | ||
901 | } | ||
902 | |||
903 | const char* icalvalue_period_as_ical_string(icalvalue* value) { | ||
904 | struct icalperiodtype data; | ||
905 | icalerror_check_arg_rz( (value!=0),"value"); | ||
906 | data = icalvalue_get_period(value); | ||
907 | |||
908 | return icalperiodtype_as_ical_string(data); | ||
909 | |||
910 | } | ||
911 | |||
912 | char* icalvalue_trigger_as_ical_string(icalvalue* value) { | ||
913 | |||
914 | struct icaltriggertype data; | ||
915 | |||
916 | icalerror_check_arg_rz( (value!=0),"value"); | ||
917 | data = icalvalue_get_trigger(value); | ||
918 | |||
919 | if(!icaltime_is_null_time(data.time)){ | ||
920 | return icaltime_as_ical_string(data.time); | ||
921 | } else { | ||
922 | return icaldurationtype_as_ical_string(data.duration); | ||
923 | } | ||
924 | |||
925 | } | ||
926 | |||
927 | const char* | ||
928 | icalvalue_as_ical_string (icalvalue* value) | ||
929 | { | ||
930 | struct icalvalue_impl* v = (struct icalvalue_impl*)value; | ||
931 | |||
932 | v=v; | ||
933 | |||
934 | if(value == 0){ | ||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | switch (v->kind){ | ||
939 | |||
940 | case ICAL_ATTACH_VALUE: | ||
941 | return icalvalue_attach_as_ical_string(value); | ||
942 | |||
943 | case ICAL_BINARY_VALUE: | ||
944 | return icalvalue_binary_as_ical_string(value); | ||
945 | |||
946 | case ICAL_BOOLEAN_VALUE: | ||
947 | case ICAL_INTEGER_VALUE: | ||
948 | return icalvalue_int_as_ical_string(value); | ||
949 | |||
950 | case ICAL_UTCOFFSET_VALUE: | ||
951 | return icalvalue_utcoffset_as_ical_string(value); | ||
952 | |||
953 | case ICAL_TEXT_VALUE: | ||
954 | return icalvalue_text_as_ical_string(value); | ||
955 | |||
956 | case ICAL_STRING_VALUE: | ||
957 | case ICAL_URI_VALUE: | ||
958 | case ICAL_CALADDRESS_VALUE: | ||
959 | return icalvalue_string_as_ical_string(value); | ||
960 | |||
961 | case ICAL_DATE_VALUE: | ||
962 | return icalvalue_date_as_ical_string(value); | ||
963 | case ICAL_DATETIME_VALUE: | ||
964 | return icalvalue_datetime_as_ical_string(value); | ||
965 | case ICAL_DURATION_VALUE: | ||
966 | return icalvalue_duration_as_ical_string(value); | ||
967 | |||
968 | case ICAL_PERIOD_VALUE: | ||
969 | return icalvalue_period_as_ical_string(value); | ||
970 | case ICAL_DATETIMEPERIOD_VALUE: | ||
971 | return icalvalue_datetimeperiod_as_ical_string(value); | ||
972 | |||
973 | case ICAL_FLOAT_VALUE: | ||
974 | return icalvalue_float_as_ical_string(value); | ||
975 | |||
976 | case ICAL_GEO_VALUE: | ||
977 | return icalvalue_geo_as_ical_string(value); | ||
978 | |||
979 | case ICAL_RECUR_VALUE: | ||
980 | return icalvalue_recur_as_ical_string(value); | ||
981 | |||
982 | case ICAL_TRIGGER_VALUE: | ||
983 | return icalvalue_trigger_as_ical_string(value); | ||
984 | |||
985 | case ICAL_REQUESTSTATUS_VALUE: | ||
986 | return icalreqstattype_as_string(v->data.v_requeststatus); | ||
987 | |||
988 | case ICAL_ACTION_VALUE: | ||
989 | case ICAL_METHOD_VALUE: | ||
990 | case ICAL_STATUS_VALUE: | ||
991 | case ICAL_TRANSP_VALUE: | ||
992 | case ICAL_CLASS_VALUE: | ||
993 | if(v->x_value !=0){ | ||
994 | return icalmemory_tmp_copy(v->x_value); | ||
995 | } | ||
996 | |||
997 | return icalproperty_enum_to_string(v->data.v_enum); | ||
998 | |||
999 | case ICAL_X_VALUE: | ||
1000 | return icalmemory_tmp_copy(v->x_value); | ||
1001 | |||
1002 | case ICAL_NO_VALUE: | ||
1003 | default: | ||
1004 | { | ||
1005 | return 0; | ||
1006 | } | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | |||
1011 | icalvalue_kind | ||
1012 | icalvalue_isa (icalvalue* value) | ||
1013 | { | ||
1014 | struct icalvalue_impl* v = (struct icalvalue_impl*)value; | ||
1015 | |||
1016 | if(value == 0){ | ||
1017 | return ICAL_NO_VALUE; | ||
1018 | } | ||
1019 | |||
1020 | return v->kind; | ||
1021 | } | ||
1022 | |||
1023 | |||
1024 | int | ||
1025 | icalvalue_isa_value (void* value) | ||
1026 | { | ||
1027 | struct icalvalue_impl *impl = (struct icalvalue_impl *)value; | ||
1028 | |||
1029 | icalerror_check_arg_rz( (value!=0), "value"); | ||
1030 | |||
1031 | if (strcmp(impl->id,"val") == 0) { | ||
1032 | return 1; | ||
1033 | } else { | ||
1034 | return 0; | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | |||
1039 | int icalvalue_is_time(icalvalue* a) { | ||
1040 | icalvalue_kind kind = icalvalue_isa(a); | ||
1041 | |||
1042 | if(kind == ICAL_DATETIME_VALUE || | ||
1043 | kind == ICAL_DATE_VALUE ){ | ||
1044 | return 1; | ||
1045 | } | ||
1046 | |||
1047 | return 0; | ||
1048 | |||
1049 | } | ||
1050 | |||
1051 | icalparameter_xliccomparetype | ||
1052 | icalvalue_compare(icalvalue* a, icalvalue *b) | ||
1053 | { | ||
1054 | struct icalvalue_impl *impla = (struct icalvalue_impl *)a; | ||
1055 | struct icalvalue_impl *implb = (struct icalvalue_impl *)b; | ||
1056 | |||
1057 | icalerror_check_arg_rz( (a!=0), "a"); | ||
1058 | icalerror_check_arg_rz( (b!=0), "b"); | ||
1059 | |||
1060 | /* Not the same type; they can only be unequal */ | ||
1061 | if( ! (icalvalue_is_time(a) && icalvalue_is_time(b)) && | ||
1062 | icalvalue_isa(a) != icalvalue_isa(b)){ | ||
1063 | return ICAL_XLICCOMPARETYPE_NOTEQUAL; | ||
1064 | } | ||
1065 | |||
1066 | switch (icalvalue_isa(a)){ | ||
1067 | |||
1068 | case ICAL_ATTACH_VALUE: | ||
1069 | case ICAL_BINARY_VALUE: | ||
1070 | |||
1071 | case ICAL_BOOLEAN_VALUE: | ||
1072 | { | ||
1073 | if (icalvalue_get_boolean(a) == icalvalue_get_boolean(b)){ | ||
1074 | return ICAL_XLICCOMPARETYPE_EQUAL; | ||
1075 | } else { | ||
1076 | return ICAL_XLICCOMPARETYPE_NOTEQUAL; | ||
1077 | } | ||
1078 | } | ||
1079 | |||
1080 | case ICAL_FLOAT_VALUE: | ||
1081 | { | ||
1082 | if (impla->data.v_float > implb->data.v_float){ | ||
1083 | return ICAL_XLICCOMPARETYPE_GREATER; | ||
1084 | } else if (impla->data.v_float < implb->data.v_float){ | ||
1085 | return ICAL_XLICCOMPARETYPE_LESS; | ||
1086 | } else { | ||
1087 | return ICAL_XLICCOMPARETYPE_EQUAL; | ||
1088 | } | ||
1089 | } | ||
1090 | |||
1091 | case ICAL_INTEGER_VALUE: | ||
1092 | case ICAL_UTCOFFSET_VALUE: | ||
1093 | { | ||
1094 | if (impla->data.v_int > implb->data.v_int){ | ||
1095 | return ICAL_XLICCOMPARETYPE_GREATER; | ||
1096 | } else if (impla->data.v_int < implb->data.v_int){ | ||
1097 | return ICAL_XLICCOMPARETYPE_LESS; | ||
1098 | } else { | ||
1099 | return ICAL_XLICCOMPARETYPE_EQUAL; | ||
1100 | } | ||
1101 | } | ||
1102 | |||
1103 | case ICAL_DURATION_VALUE: | ||
1104 | { | ||
1105 | int a = icaldurationtype_as_int(impla->data.v_duration); | ||
1106 | int b = icaldurationtype_as_int(implb->data.v_duration); | ||
1107 | |||
1108 | if (a > b){ | ||
1109 | return ICAL_XLICCOMPARETYPE_GREATER; | ||
1110 | } else if (a < b){ | ||
1111 | return ICAL_XLICCOMPARETYPE_LESS; | ||
1112 | } else { | ||
1113 | return ICAL_XLICCOMPARETYPE_EQUAL; | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1117 | |||
1118 | case ICAL_TEXT_VALUE: | ||
1119 | case ICAL_URI_VALUE: | ||
1120 | case ICAL_CALADDRESS_VALUE: | ||
1121 | case ICAL_TRIGGER_VALUE: | ||
1122 | case ICAL_DATE_VALUE: | ||
1123 | case ICAL_DATETIME_VALUE: | ||
1124 | case ICAL_DATETIMEPERIOD_VALUE: | ||
1125 | { | ||
1126 | int r; | ||
1127 | |||
1128 | r = strcmp(icalvalue_as_ical_string(a), | ||
1129 | icalvalue_as_ical_string(b)); | ||
1130 | |||
1131 | if (r > 0) { | ||
1132 | return ICAL_XLICCOMPARETYPE_GREATER; | ||
1133 | } else if (r < 0){ | ||
1134 | return ICAL_XLICCOMPARETYPE_LESS; | ||
1135 | } else { | ||
1136 | return ICAL_XLICCOMPARETYPE_EQUAL; | ||
1137 | } | ||
1138 | |||
1139 | |||
1140 | } | ||
1141 | |||
1142 | case ICAL_METHOD_VALUE: | ||
1143 | { | ||
1144 | if (icalvalue_get_method(a) == icalvalue_get_method(b)){ | ||
1145 | return ICAL_XLICCOMPARETYPE_EQUAL; | ||
1146 | } else { | ||
1147 | return ICAL_XLICCOMPARETYPE_NOTEQUAL; | ||
1148 | } | ||
1149 | |||
1150 | } | ||
1151 | |||
1152 | case ICAL_STATUS_VALUE: | ||
1153 | { | ||
1154 | if (icalvalue_get_status(a) == icalvalue_get_status(b)){ | ||
1155 | return ICAL_XLICCOMPARETYPE_EQUAL; | ||
1156 | } else { | ||
1157 | return ICAL_XLICCOMPARETYPE_NOTEQUAL; | ||
1158 | } | ||
1159 | |||
1160 | } | ||
1161 | |||
1162 | case ICAL_PERIOD_VALUE: | ||
1163 | case ICAL_GEO_VALUE: | ||
1164 | case ICAL_RECUR_VALUE: | ||
1165 | case ICAL_NO_VALUE: | ||
1166 | default: | ||
1167 | { | ||
1168 | icalerror_warn("Comparison not implemented for value type"); | ||
1169 | return ICAL_XLICCOMPARETYPE_REGEX+1; /* HACK */ | ||
1170 | } | ||
1171 | } | ||
1172 | |||
1173 | } | ||
1174 | |||
1175 | /* Examine the value and possiby chage the kind to agree with the value */ | ||
1176 | void icalvalue_reset_kind(icalvalue* value) | ||
1177 | { | ||
1178 | struct icalvalue_impl* impl = (struct icalvalue_impl*)value; | ||
1179 | |||
1180 | if( (impl->kind==ICAL_DATETIME_VALUE || impl->kind==ICAL_DATE_VALUE )&& | ||
1181 | !icaltime_is_null_time(impl->data.v_time) ) { | ||
1182 | |||
1183 | if( impl->data.v_time.is_date == 1){ | ||
1184 | impl->kind = ICAL_DATE_VALUE; | ||
1185 | } else { | ||
1186 | impl->kind = ICAL_DATETIME_VALUE; | ||
1187 | } | ||
1188 | } | ||
1189 | |||
1190 | } | ||
1191 | |||
1192 | void icalvalue_set_parent(icalvalue* value, | ||
1193 | icalproperty* property) | ||
1194 | { | ||
1195 | struct icalvalue_impl* v = (struct icalvalue_impl*)value; | ||
1196 | |||
1197 | v->parent = property; | ||
1198 | |||
1199 | } | ||
1200 | |||
1201 | icalproperty* icalvalue_get_parent(icalvalue* value) | ||
1202 | { | ||
1203 | struct icalvalue_impl* v = (struct icalvalue_impl*)value; | ||
1204 | |||
1205 | |||
1206 | return v->parent; | ||
1207 | } | ||
1208 | |||
1209 | |||
1210 | |||
1211 | /* The remaining interfaces are 'new', 'set' and 'get' for each of the value | ||
1212 | types */ | ||
1213 | |||
1214 | |||
1215 | /* Everything below this line is machine generated. Do not edit. */ | ||