summaryrefslogtreecommitdiffabout
path: root/libical/src/libical/icalvalue.c
Unidiff
Diffstat (limited to 'libical/src/libical/icalvalue.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/icalvalue.c1215
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
49int 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
57void print_datetime_to_string(char* str, struct icaltimetype *data);
58void print_date_to_string(char* str, struct icaltimetype *data);
59void print_time_to_string(char* str, struct icaltimetype *data);
60void print_recur_to_string(char* str, struct icaltimetype *data);
61
62
63struct 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
87icalvalue*
88icalvalue_new (icalvalue_kind kind)
89{
90 return (icalvalue*)icalvalue_new_impl(kind);
91}
92
93icalvalue* 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
161char* 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
220icalvalue* 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
241icalvalue* 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
485icalvalue* 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
492void
493icalvalue_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
552int
553icalvalue_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
564char* 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*/
580char* 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*/
597char* 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
612char* 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
637char* 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
653char* 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
661char* 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
752char* 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
779char* 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
789void 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
803void 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
812char* 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
827void 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
835const 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
862char* 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
876char* 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
891const 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
903const 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
912char* 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
927const char*
928icalvalue_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
1011icalvalue_kind
1012icalvalue_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
1024int
1025icalvalue_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
1039int 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
1051icalparameter_xliccomparetype
1052icalvalue_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 */
1176void 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
1192void 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
1201icalproperty* 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. */