4 * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <sys/types.h>
24 #include "calendar_list.h"
25 #include "calendar_db.h"
27 #include "cal_internal.h"
28 #include "cal_typedef.h"
29 #include "cal_record.h"
33 #include "cal_vcalendar.h"
34 #include "cal_vcalendar_make.h"
35 #include "cal_utils.h"
43 EVENT_ATTENDEE_REQ_PARTICIPANT_ROLE = 0,
44 EVENT_ATTENDEE_OPT_PARTICIPANT_ROLE,
45 EVENT_ATTENDEE_NON_PARTICIPANT_ROLE,
46 EVENT_ATTENDEE_CHAIR_ROLE,
47 } cal_event_attendee_role_type_t;
50 EVENT_ATTENDEE_NEEDS_ACTION_AT_STATUS = 0,
51 EVENT_ATTENDEE_ACCEPTED_AT_STATUS,
52 EVENT_ATTENDEE_DECLINED_AT_STATUS,
53 EVENT_ATTENDEE_TENTATIVE_AT_STATUS,
54 EVENT_ATTENDEE_DELEGATED_AT_STATUS,
55 EVENT_ATTENDEE_COMPLETED_AT_STATUS,
56 EVENT_ATTENDEE_IN_PROCESS_AT_STATUS
57 } cal_event_attendee_status_type_t;
60 static const char *_att_role[] = {
61 [EVENT_ATTENDEE_REQ_PARTICIPANT_ROLE] = "REQ-PARTICIPANT",
62 [EVENT_ATTENDEE_OPT_PARTICIPANT_ROLE] = "OPT-PARTICIPANT",
63 [EVENT_ATTENDEE_NON_PARTICIPANT_ROLE] = "NON-PARTICIPANT",
64 [EVENT_ATTENDEE_CHAIR_ROLE] = "CHAIR",
67 static const char *_att_st[] = {
68 [EVENT_ATTENDEE_NEEDS_ACTION_AT_STATUS] = "NEEDS-ACTION",
69 [EVENT_ATTENDEE_ACCEPTED_AT_STATUS] = "ACCEPTED",
70 [EVENT_ATTENDEE_DECLINED_AT_STATUS] = "DECLINED",
71 [EVENT_ATTENDEE_TENTATIVE_AT_STATUS] = "TENTATIVE",
72 [EVENT_ATTENDEE_DELEGATED_AT_STATUS] = "DELEGATED",
73 [EVENT_ATTENDEE_COMPLETED_AT_STATUS] = "COMPLETED",
74 [EVENT_ATTENDEE_IN_PROCESS_AT_STATUS] = "IN-PROCESS",
77 #define _strlen(s) (((s) && *(s)) ? strlen(s) : 0)
79 static inline int _cal_vcalendar_make_alloc(cal_make_s *b, int n)
81 b->data = realloc(b->data, b->size + n);
83 RETVM_IF(!b->data, CALENDAR_ERROR_OUT_OF_MEMORY, "realloc() Fail");
86 return CALENDAR_ERROR_NONE;
89 cal_make_s *cal_vcalendar_make_new(void)
93 b = calloc(1, sizeof(cal_make_s));
97 b->data = calloc(1, sizeof(char));
109 static inline int _cal_vcalendar_make_folding(cal_make_s *b)
112 ret = _cal_vcalendar_make_alloc(b, _strlen(b->lbuf) + 3);
113 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
115 strncat(b->data, b->lbuf, b->size - _strlen(b->data) - 1);
116 strncat(b->data, "\r\n ", b->size - _strlen(b->data) - 1);
118 return CALENDAR_ERROR_NONE;
121 static inline int _cal_vcalendar_make_set_str(cal_make_s *b, const char *s)
128 remain_lbuf = sizeof(b->lbuf) - _strlen(b->lbuf);
129 remain_str = _strlen(s);
132 while (remain_lbuf - 1 < remain_str) {
133 strncat(b->lbuf, s + k, remain_lbuf - 1);
134 k += remain_lbuf - 1;
135 remain_str -= remain_lbuf - 1;
136 ret = _cal_vcalendar_make_folding(b);
137 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
138 remain_lbuf = sizeof(b->lbuf);
141 strncat(b->lbuf, s + k, remain_lbuf - 1);
142 return CALENDAR_ERROR_NONE;
145 static inline int _cal_vcalendar_make_flush(cal_make_s *b)
148 ret = _cal_vcalendar_make_alloc(b, _strlen(b->lbuf) + 2);
149 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
151 strncat(b->data, b->lbuf, b->size - _strlen(b->data) - 1);
152 strncat(b->data, "\r\n", b->size - _strlen(b->data) - 1);
154 return CALENDAR_ERROR_NONE;
157 static int _cal_vcalendar_make_printf(cal_make_s *b, const char *s1, const char *s2)
162 ret = _cal_vcalendar_make_set_str(b, s1);
163 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
167 ret = _cal_vcalendar_make_set_str(b, s2);
168 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
171 return _cal_vcalendar_make_flush(b);
174 char* cal_vcalendar_make_get_data(cal_make_s *b)
178 return cal_strdup(b->data);
181 void cal_vcalendar_make_free(cal_make_s **b)
193 static int _cal_vcalendar_make_time(cal_make_s *b, char *tzid, calendar_time_s *t, const char *prop)
195 RETV_IF(NULL == b, CALENDAR_ERROR_INVALID_PARAMETER);
196 RETV_IF(NULL == t, CALENDAR_ERROR_INVALID_PARAMETER);
198 if (CALENDAR_TIME_UTIME == t->type && CALENDAR_TODO_NO_START_DATE == t->time.utime) {
199 DBG("No start date");
200 return CALENDAR_ERROR_NONE;
203 char buf[CAL_STR_MIDDLE_LEN] = {0};
204 int y = 0, m = 0, d = 0;
205 int h = 0, n = 0, s = 0;
206 switch (b->version) {
209 case CALENDAR_TIME_UTIME:
210 cal_time_get_local_datetime(NULL, t->time.utime, &y, &m, &d, &h, &n, &s);
211 snprintf(buf, sizeof(buf), ":"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
213 case CALENDAR_TIME_LOCALTIME:
214 snprintf(buf, sizeof(buf), ":"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS,
215 t->time.date.year, t->time.date.month, t->time.date.mday,
216 t->time.date.hour, t->time.date.minute, t->time.date.second);
222 case CALENDAR_TIME_UTIME:
223 if (NULL == tzid || '\0' == *tzid) {
224 cal_time_get_local_datetime(NULL, t->time.utime, &y, &m, &d, &h, &n, &s);
225 snprintf(buf, sizeof(buf), ":"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
227 cal_time_get_local_datetime(tzid, t->time.utime, &y, &m, &d, &h, &n, &s);
228 snprintf(buf, sizeof(buf), ";TZID=%s:"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS, tzid, y, m, d, h, n, s);
231 case CALENDAR_TIME_LOCALTIME:
232 snprintf(buf, sizeof(buf), ":"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS,
233 t->time.date.year, t->time.date.month, t->time.date.mday,
234 t->time.date.hour, t->time.date.minute, t->time.date.second);
239 _cal_vcalendar_make_printf(b, prop, buf);
240 return CALENDAR_ERROR_NONE;
243 static void __encode_escaped_char(char *p, char **r)
248 int len = strlen(p) * 2;
249 char *q = calloc(len, sizeof(char));
250 RETM_IF(NULL == q, "calloc() Fail");
253 DBG("Before [%s]", p);
255 if ('\r' == *p && '\n' == *(p + 1))
286 DBG("After [%s]", *r);
289 static const char* vl_tick(calendar_alarm_time_unit_type_e unit, int tick)
291 static char buf[CAL_STR_SHORT_LEN32] = {0};
303 case CALENDAR_ALARM_TIME_UNIT_WEEK:
304 snprintf(buf + i, sizeof(buf) - i, "P%dW", tick);
306 case CALENDAR_ALARM_TIME_UNIT_DAY:
307 snprintf(buf + i, sizeof(buf) - i, "P%dD", tick);
309 case CALENDAR_ALARM_TIME_UNIT_HOUR:
310 snprintf(buf + i, sizeof(buf) - i, "PT%dH", tick);
312 case CALENDAR_ALARM_TIME_UNIT_MINUTE:
313 snprintf(buf + i, sizeof(buf) - i, "PT%dM", tick);
322 int _cal_vcalendar_make_audio(cal_make_s *b, calendar_record_h alarm)
324 RETV_IF(NULL == b, CALENDAR_ERROR_INVALID_PARAMETER);
325 RETV_IF(NULL == alarm, CALENDAR_ERROR_INVALID_PARAMETER);
329 ret = calendar_record_get_int(alarm, _calendar_alarm.tick_unit, &unit);
330 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "failed to get unit");
332 if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
333 calendar_time_s at = {0};
334 ret = calendar_record_get_caltime(alarm, _calendar_alarm.alarm_time, &at);
335 WARN_IF(CALENDAR_ERROR_NONE != ret, "failed to get alarm_time");
337 if (CALENDAR_TIME_UTIME == at.type) {
338 char *datetime = cal_time_convert_ltos(NULL, at.time.utime, 0);
339 _cal_vcalendar_make_printf(b, "TRIGGER;VALUE=DATE-TIME:", datetime);
343 char datetime[CAL_STR_SHORT_LEN32] = {0};
344 snprintf(datetime, sizeof(datetime), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS,
345 at.time.date.year, at.time.date.month, at.time.date.mday,
346 at.time.date.hour, at.time.date.minute, at.time.date.second);
347 _cal_vcalendar_make_printf(b, "TRIGGER;VALUE=DATE-TIME:", datetime);
352 ret = calendar_record_get_int(alarm, _calendar_alarm.tick, &tick);
353 WARN_IF(CALENDAR_ERROR_NONE != ret, "failed to get tick");
355 _cal_vcalendar_make_printf(b, "TRIGGER:", vl_tick(unit, tick));
357 return CALENDAR_ERROR_NONE;
361 * aalarm: runTime, snoozeTime, repeatCount, audioContent (AALARM;TYPE=WAVE;VALUE=URL:19960415T235959; ; ; file:///mmedia/taps.wav)
362 * dalarm: runTime, snoozeTime, repeatCount, displayString
363 * malarm: runTime, snoozeTime, repeatCount, addressString, noteString
364 * palarm: runTime, snoozeTime, repeatCount, procedureName
366 static void _cal_vcalendar_make_aalarm(cal_make_s *b, calendar_record_h record, calendar_record_h alarm)
368 RETM_IF(NULL == b, "b is NULL");
369 RETM_IF(NULL == record, "record is NULL");
370 RETM_IF(NULL == alarm, "alarm is NULL");
372 int ret = CALENDAR_ERROR_NONE;
376 ret = calendar_record_get_int(alarm, _calendar_alarm.tick_unit, &unit);
377 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
379 char datetime[CAL_STR_SHORT_LEN32] = {0};
380 if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
381 calendar_time_s at = {0};
382 ret = calendar_record_get_caltime(alarm, _calendar_alarm.alarm_time, &at);
383 WARN_IF(CALENDAR_ERROR_NONE != ret, "failed to get alarm_time");
385 if (CALENDAR_TIME_UTIME == at.type) {
386 char *buf = cal_time_convert_ltos(NULL, at.time.utime, 0);
387 snprintf(datetime, sizeof(datetime), "%s;;;", buf);
391 snprintf(datetime, sizeof(datetime), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS";;;",
392 at.time.date.year, at.time.date.month, at.time.date.mday,
393 at.time.date.hour, at.time.date.minute, at.time.date.second);
399 ret = calendar_record_get_int(alarm, _calendar_alarm.tick, &tick);
400 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
403 ret = calendar_record_get_uri_p(record, &uri);
404 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_uri_p() failed(%d)", ret);
406 calendar_time_s st = {0};
407 if (CAL_STRING_EQUAL == strncmp(uri, _calendar_event._uri, strlen(_calendar_event._uri))) {
408 ret = calendar_record_get_caltime(record, _calendar_event.start_time, &st);
409 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
411 } else if (CAL_STRING_EQUAL == strncmp(uri, _calendar_todo._uri, strlen(_calendar_todo._uri))) {
412 ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &st);
413 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
416 if (CALENDAR_TIME_UTIME == st.type) {
417 long long int lli = st.time.utime - (tick * unit);
418 char *buf = cal_time_convert_ltos(NULL, lli, 0);
419 snprintf(datetime, sizeof(datetime), "%s;;;", buf);
421 DBG("aalarm: [%s] = (%lld) - (tick(%d) * unit(%d))", datetime, st.time.utime, tick, unit);
425 tm.tm_year = st.time.date.year - 1900;
426 tm.tm_mon = st.time.date.month - 1;
427 tm.tm_mday = st.time.date.mday;
428 tm.tm_hour = st.time.date.hour;
429 tm.tm_min = st.time.date.minute;
430 tm.tm_sec = st.time.date.second;
431 time_t tt = mktime(&tm);
433 localtime_r(&tt, &tm);
435 snprintf(datetime, sizeof(datetime), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS,
436 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
437 tm.tm_hour, tm.tm_min, tm.tm_sec);
439 DBG("aalarm: [%s]", datetime);
442 _cal_vcalendar_make_printf(b, "AALARM:", datetime);
445 static void _cal_vcalendar_make_alarm(cal_make_s *b, calendar_record_h alarm)
448 RET_IF(NULL == alarm);
452 /* TODO : No action type is defined */
453 ret = _cal_vcalendar_make_printf(b, "BEGIN:VALARM", NULL);
454 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
456 ret = _cal_vcalendar_make_audio(b, alarm);
457 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_audio() Fail(%d)", ret);
460 ret = calendar_record_get_int(alarm, _calendar_alarm.action, &action);
461 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
464 case CALENDAR_ALARM_ACTION_AUDIO:
465 ret = _cal_vcalendar_make_printf(b, "ACTION:", "AUDIO");
467 case CALENDAR_ALARM_ACTION_DISPLAY:
468 ret = _cal_vcalendar_make_printf(b, "ACTION:", "DISPLAY");
470 case CALENDAR_ALARM_ACTION_EMAIL:
471 ret = _cal_vcalendar_make_printf(b, "ACTION:", "EMAIL");
474 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
476 char *summary = NULL;
477 ret = calendar_record_get_str_p(alarm, _calendar_alarm.summary, &summary);
478 if (summary && *summary) {
479 ret = _cal_vcalendar_make_printf(b, "SUMMARY:", summary);
480 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
483 char *description = NULL;
484 ret = calendar_record_get_str_p(alarm, _calendar_alarm.description, &description);
485 if (description && *description) {
486 ret = _cal_vcalendar_make_printf(b, "DESCRIPTION:", description);
487 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
490 _cal_vcalendar_make_printf(b, "END:VALARM", NULL);
493 int _cal_vcalendar_make_rrule_append_mday(char *buf, int buf_len, char *mday)
497 RETV_IF(NULL == buf, 0);
498 RETV_IF(NULL == mday, 0);
501 t = g_strsplit_set(mday, " ,", -1);
503 ERR("g_strsplit_set() Fail");
507 int len = strlen(buf);
508 int tlen = g_strv_length(t);
510 for (i = 0; i < tlen; i++) {
514 int num = atoi(t[i]);
515 ret += snprintf(buf +len +ret, buf_len -len -ret, "%d%s",
516 num < 0 ? (-1 * num) : num, num < 0 ? "- " : " ");
523 static void _cal_vcalendar_make_rrule_append_setpos(calendar_record_h record, char *buf, int buf_len)
527 int ret = CALENDAR_ERROR_NONE;
528 char *bysetpos = NULL;
530 ret = calendar_record_get_str_p(record, _calendar_event.bysetpos, &bysetpos);
531 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() failed(%d)", ret);
533 int blen = strlen(buf);
534 if (bysetpos && '\0' != bysetpos[0]) {
535 /* in ver1.0, "3, 5, -4" -> "3+ 5+ 4-" */
537 t = g_strsplit_set(bysetpos, " ,", -1);
539 int len = g_strv_length(t);
542 for (i = 0; i < len; i++) {
543 if (*t[i] == '\0') continue;
545 int setpos = atoi(t[i]);
549 DBG("Invalid setpos(0)");
552 blen += snprintf(buf +blen, buf_len -blen, "%d%s ", setpos * (setpos < 0 ? -1 : 1), setpos < 0 ? "-" : "+");
556 /* in ver2.0, 3TH should be changed to setpos:3, byday:TH */
558 ret = calendar_record_get_str_p(record, _calendar_event.byday, &byday);
559 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
560 if (NULL == byday || '\0' == byday[0]) {
561 blen += snprintf(buf +blen, buf_len -blen, "%s", "1+ ");
565 int len = strlen(byday);
567 bool is_working = true;
568 bool is_extracted = false;
573 /* extract -1, 1 from 1SU,-1SU */
574 if ('1' <= byday[i] && byday[i] <= '9') {
577 } else if ('+' == byday[i]) {
580 } else if ('-' == byday[i]) {
584 if (false == is_working) {
587 char num[CAL_STR_SHORT_LEN32] = {0};
588 snprintf(num, digit +1, "%s", byday +i -digit);
589 if (NULL == strstr(buf, num))
590 blen += snprintf(buf +blen, buf_len -blen, "%s%c ", num, (-1 == sign) ? '-' : '+');
598 if (false == is_extracted) {
599 blen += snprintf(buf +blen, buf_len -blen, "%s", "1+ ");
606 * 2WE 3FR in ver2.0 is not converted to ver1.0
607 * because three is no +2 WE +3 FR.
609 void _cal_vcalendar_make_rrule_append_text_wday(int rrule_type, char *buf, int buf_len, char *wday)
618 int len = strlen(buf);
619 t = g_strsplit_set(wday, " ,", -1);
621 ERR("g_strsplit_set() Fail");
625 length = g_strv_length(t);
627 for (i = 0; i < length; i++) {
636 /* get number length */
638 while (p[j] == '+' || p[j] == '-' || ('1' <= p[j] && p[j] <= '9'))
641 /* already appended */
642 if (strstr(buf, p +j))
645 len += snprintf(buf +len, buf_len -len, "%s ", p +j);
652 void _cal_vcalendar_make_rrule_append_wkst(char *buf, int buf_len, calendar_record_h record)
654 const char wday[7][3] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
656 calendar_record_get_int(record, _calendar_event.wkst, &wkst);
657 if (wkst < CALENDAR_SUNDAY || CALENDAR_SATURDAY < wkst)
660 DBG("wkst(%d) [%s]", wkst, wday[wkst - 1]);
661 int len = strlen(buf);
662 snprintf(buf +len, buf_len -len, "WKST=%s ", wday[wkst - 1]);
665 int _cal_vcalendar_make_rrule_append_wday(int rrule_type, char *buf, int buf_len, char *wday)
667 RETV_IF(NULL == buf, CALENDAR_ERROR_INVALID_PARAMETER);
670 int num = 0, num_past;
674 char buf_temp[8] = {0};
676 RETV_IF(NULL == buf, CALENDAR_ERROR_INVALID_PARAMETER);
677 RETV_IF(NULL == wday, CALENDAR_ERROR_INVALID_PARAMETER);
679 int len = strlen(buf);
682 t = g_strsplit_set(wday, " ,", -1);
684 ERR("g_strsplit_set() Fail");
686 return CALENDAR_ERROR_OUT_OF_MEMORY;
688 length = g_strv_length(t);
689 DBG("len(%d)", length);
691 for (i = 0; i < length; i++) {
692 if (*t[i] == '\0') continue;
698 while (p[j] == '+' || p[j] == '-' || ('1' <= p[j] && p[j] <= '9'))
702 if (CALENDAR_RECURRENCE_WEEKLY == rrule_type) {
706 snprintf(buf_temp, j + 1, "%s", p + 1);
707 num = atoi(buf_temp);
710 len += snprintf(buf +len, buf_len -len, "%s- ", buf_temp);
713 snprintf(buf_temp, j + 1, "%s", p);
714 num = atoi(buf_temp);
717 len += snprintf(buf +len, buf_len -len, "%s+ ", buf_temp);
722 len += snprintf(buf +len, buf_len -len, "%s ", p +j);
724 ERR("Out of 1.0 spec");
726 DBG("%d num(%d) val[%s]", i, num, p + j);
728 len += snprintf(buf +len, buf_len -len, "%s ", p);
734 return CALENDAR_ERROR_NONE;
737 static void __make_begin(cal_make_s *b, calendar_record_h record)
740 RET_IF(NULL == record);
744 case CALENDAR_BOOK_TYPE_EVENT:
745 ret = _cal_vcalendar_make_printf(b, "BEGIN:VEVENT", NULL);
746 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
748 case CALENDAR_BOOK_TYPE_TODO:
749 ret = _cal_vcalendar_make_printf(b, "BEGIN:VTODO", NULL);
750 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
755 static void __make_dtstart(cal_make_s *b, calendar_record_h record)
758 RET_IF(NULL == record);
762 calendar_time_s ct = {0};
764 case CALENDAR_BOOK_TYPE_EVENT:
765 ret = calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
766 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
767 ret = calendar_record_get_caltime(record, _calendar_event.start_time, &ct);
768 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
770 case CALENDAR_BOOK_TYPE_TODO:
771 ret = calendar_record_get_str_p(record, _calendar_todo.start_tzid, &tzid);
772 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
773 ret = calendar_record_get_caltime(record, _calendar_todo.start_time, &ct);
774 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
777 _cal_vcalendar_make_time(b, tzid, &ct, "DTSTART");
780 static void __make_dtend(cal_make_s *b, calendar_record_h record)
783 RET_IF(NULL == record);
787 calendar_time_s ct = {0};
789 case CALENDAR_BOOK_TYPE_EVENT:
790 ret = calendar_record_get_str_p(record, _calendar_event.end_tzid, &tzid);
791 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
792 ret = calendar_record_get_caltime(record, _calendar_event.end_time, &ct);
793 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
794 _cal_vcalendar_make_time(b, tzid, &ct, "DTEND");
796 case CALENDAR_BOOK_TYPE_TODO:
797 ret = calendar_record_get_str_p(record, _calendar_todo.due_tzid, &tzid);
798 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
799 ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &ct);
800 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
801 _cal_vcalendar_make_time(b, tzid, &ct, "DUE");
806 static void __make_sensitivity(cal_make_s *b, calendar_record_h record)
809 RET_IF(NULL == record);
814 case CALENDAR_BOOK_TYPE_EVENT:
815 ret = calendar_record_get_int(record, _calendar_event.sensitivity, &value);
816 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
818 case CALENDAR_BOOK_TYPE_TODO:
819 ret = calendar_record_get_int(record, _calendar_todo.sensitivity, &value);
820 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
823 char *sensitivity = NULL;
825 case CALENDAR_SENSITIVITY_PUBLIC:
826 sensitivity = "PUBLIC";
828 case CALENDAR_SENSITIVITY_PRIVATE:
829 sensitivity = "PRIVATE";
831 case CALENDAR_SENSITIVITY_CONFIDENTIAL:
832 sensitivity = "CONFIDENTIAL";
835 ERR("Invalid sensitivity(%d)", value);
838 _cal_vcalendar_make_printf(b, "CLASS:", sensitivity);
841 int _cal_vcalendar_make_rrule_append_until(char *buf, int buf_len, calendar_record_h record)
846 char *until_str = NULL;
847 calendar_time_s caltime;
849 ret = calendar_record_get_int(record, _calendar_event.range_type, &range_type);
850 if (CALENDAR_ERROR_NONE != ret) {
851 ERR("calendar_record_get_int() Fail");
855 int len = strlen(buf);
856 switch (range_type) {
857 case CALENDAR_RANGE_COUNT:
858 ret = calendar_record_get_int(record, _calendar_event.count, &count);
859 if (CALENDAR_ERROR_NONE != ret) {
860 ERR("calendar_record_get_int() Fail");
863 snprintf(buf +len, buf_len -len, "#%d", count);
866 case CALENDAR_RANGE_UNTIL:
867 memset(&caltime, 0x0, sizeof(calendar_time_s));
869 ret = calendar_record_get_caltime(record, _calendar_event.until_time, &caltime);
870 if (CALENDAR_ERROR_NONE != ret) {
871 ERR("calendar_record_get_caltime() Fail");
874 switch (caltime.type) {
875 case CALENDAR_TIME_UTIME:
876 until_str = cal_time_convert_ltos(NULL, caltime.time.utime, 0);
877 snprintf(buf +len, buf_len -len, "%s", until_str);
881 case CALENDAR_TIME_LOCALTIME:
882 snprintf(buf +len, buf_len -len, CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS,
883 caltime.time.date.year, caltime.time.date.month, caltime.time.date.mday,
884 caltime.time.date.hour, caltime.time.date.minute, caltime.time.date.second);
889 case CALENDAR_RANGE_NONE:
890 snprintf(buf +len, buf_len -len, "%s", "#0");
893 return CALENDAR_ERROR_NONE;
895 static void __make_rrule_ver1_default(calendar_record_h record, int freq, int interval, char *buf, int buf_size)
897 RET_IF(NULL == record);
900 calendar_time_s caltime = {0};
901 ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
902 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
905 case CALENDAR_RECURRENCE_YEARLY:
906 snprintf(buf, buf_size, "YD%d ", interval);
908 case CALENDAR_RECURRENCE_MONTHLY:
909 snprintf(buf, buf_size, "MD%d ", interval);
915 switch (caltime.type) {
916 case CALENDAR_TIME_UTIME:
917 calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
918 cal_time_get_local_datetime(tzid, caltime.time.utime, NULL, NULL, &d, NULL, NULL, NULL);
920 case CALENDAR_TIME_LOCALTIME:
921 d = caltime.time.date.mday;
924 char mday[CAL_STR_SHORT_LEN32] = {0};
925 snprintf(mday, sizeof(mday), "%d", d);
926 _cal_vcalendar_make_rrule_append_mday(buf, buf_size, mday);
929 static void __make_rrule_ver1(cal_make_s *b, calendar_record_h record)
932 RET_IF(NULL == record);
935 char buf[CAL_STR_MIDDLE_LEN] = {0};
938 ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
939 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
942 ret = calendar_record_get_int(record, _calendar_event.interval, &interval);
943 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
944 interval = 0 < interval ? interval : 1;
946 char *byyearday = NULL;
947 ret = calendar_record_get_str_p(record, _calendar_event.byyearday, &byyearday);
948 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
950 char *bymonth = NULL;
951 ret = calendar_record_get_str_p(record, _calendar_event.bymonth, &bymonth);
952 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
955 ret = calendar_record_get_str_p(record, _calendar_event.byday, &byday);
956 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
958 char *bymonthday = NULL;
959 ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &bymonthday);
960 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
964 case CALENDAR_RECURRENCE_YEARLY:
965 if (bymonth && *bymonth) {
966 DBG("bymonth[%s]", bymonth);
967 len += snprintf(buf +len, sizeof(buf) -len, "YM%d ", interval);
968 len += _cal_vcalendar_make_rrule_append_mday(buf, sizeof(buf), bymonth);
970 if (byday && *byday) {
972 /* ex> YM1 6 MP1 1+ TH */
973 len += snprintf(buf +len, sizeof(buf) -len, "MP%d ", interval);
974 _cal_vcalendar_make_rrule_append_setpos(record, buf, sizeof(buf));
975 _cal_vcalendar_make_rrule_append_text_wday(CALENDAR_RECURRENCE_MONTHLY, buf, sizeof(buf), byday);
976 } else if (bymonthday && *bymonthday) {
979 len += snprintf(buf +len, sizeof(buf) -len, "MD%d ", interval);
980 _cal_vcalendar_make_rrule_append_mday(buf, sizeof(buf), bymonthday);
983 __make_rrule_ver1_default(record, freq, interval, buf, sizeof(buf));
985 } else if (byyearday && *byyearday) {
987 snprintf(buf, sizeof(buf), "YD%d ", interval);
988 _cal_vcalendar_make_rrule_append_mday(buf, sizeof(buf), byyearday);
991 __make_rrule_ver1_default(record, freq, interval, buf, sizeof(buf));
995 case CALENDAR_RECURRENCE_MONTHLY:
996 if (byday && *byday) {
998 snprintf(buf, sizeof(buf), "MP%d ", interval);
999 _cal_vcalendar_make_rrule_append_setpos(record, buf, sizeof(buf));
1000 _cal_vcalendar_make_rrule_append_text_wday(CALENDAR_RECURRENCE_MONTHLY, buf, sizeof(buf), byday);
1001 } else if (bymonthday && *bymonthday) {
1003 snprintf(buf, sizeof(buf), "MD%d ", interval);
1004 _cal_vcalendar_make_rrule_append_mday(buf, sizeof(buf), bymonthday);
1006 ERR("Out of scope, so set as bymonthday");
1007 __make_rrule_ver1_default(record, freq, interval, buf, sizeof(buf));
1011 case CALENDAR_RECURRENCE_WEEKLY:
1012 snprintf(buf, sizeof(buf), "W%d ", interval);
1013 _cal_vcalendar_make_rrule_append_wday(CALENDAR_RECURRENCE_WEEKLY, buf, sizeof(buf), byday);
1016 case CALENDAR_RECURRENCE_DAILY:
1017 snprintf(buf, sizeof(buf), "D%d ", interval);
1021 ERR("Out of scope");
1026 _cal_vcalendar_make_rrule_append_wkst(buf, sizeof(buf), record);
1027 _cal_vcalendar_make_rrule_append_until(buf, sizeof(buf), record);
1028 _cal_vcalendar_make_printf(b, "RRULE:", buf);
1032 static void __make_rrule_ver2(cal_make_s *b, calendar_record_h record)
1035 RET_IF(NULL == record);
1039 char tmp[CAL_STR_SHORT_LEN32] = {0};
1040 calendar_time_s caltime = {0};
1043 ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
1044 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1047 case CALENDAR_RECURRENCE_DAILY:
1048 _cal_vcalendar_make_set_str(b, "RRULE:FREQ=DAILY");
1050 case CALENDAR_RECURRENCE_WEEKLY:
1051 _cal_vcalendar_make_set_str(b, "RRULE:FREQ=WEEKLY");
1053 case CALENDAR_RECURRENCE_MONTHLY:
1054 _cal_vcalendar_make_set_str(b, "RRULE:FREQ=MONTHLY");
1056 case CALENDAR_RECURRENCE_YEARLY:
1057 _cal_vcalendar_make_set_str(b, "RRULE:FREQ=YEARLY");
1064 ret = calendar_record_get_int(record, _calendar_event.interval, &interval);
1065 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1066 interval = 0 < interval ? interval : 1;
1067 snprintf(tmp, sizeof(tmp), ";INTERVAL=%d", interval);
1068 _cal_vcalendar_make_set_str(b, tmp);
1070 ret = calendar_record_get_str_p(record, _calendar_event.bysecond, &text);
1071 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1072 if (text && *text) {
1073 DBG("BYSECOND= [%s]", text);
1074 _cal_vcalendar_make_set_str(b, ";BYSECOND=");
1075 _cal_vcalendar_make_set_str(b, text);
1079 ret = calendar_record_get_str_p(record, _calendar_event.byminute, &text);
1080 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1081 if (text && *text) {
1082 DBG("BYMINUTE= [%s]", text);
1083 _cal_vcalendar_make_set_str(b, ";BYMINUTE=");
1084 _cal_vcalendar_make_set_str(b, text);
1088 ret = calendar_record_get_str_p(record, _calendar_event.byhour, &text);
1089 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1090 if (text && *text) {
1091 DBG("BYHOUR= [%s]", text);
1092 _cal_vcalendar_make_set_str(b, ";BYHOUR=");
1093 _cal_vcalendar_make_set_str(b, text);
1097 ret = calendar_record_get_str_p(record, _calendar_event.byday, &text);
1098 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1099 if (text && *text) {
1100 DBG("BYDAY= [%s]", text);
1101 _cal_vcalendar_make_set_str(b, ";BYDAY=");
1102 _cal_vcalendar_make_set_str(b, text);
1106 ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &text);
1107 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1108 if (text && *text) {
1109 DBG("BYMONTHDAY= [%s]", text);
1110 _cal_vcalendar_make_set_str(b, ";BYMONTHDAY=");
1111 _cal_vcalendar_make_set_str(b, text);
1115 ret = calendar_record_get_str_p(record, _calendar_event.byyearday, &text);
1116 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1117 if (text && *text) {
1118 DBG("BYYEARDAY= [%s]", text);
1119 _cal_vcalendar_make_set_str(b, ";BYYEARDAY=");
1120 _cal_vcalendar_make_set_str(b, text);
1124 ret = calendar_record_get_str_p(record, _calendar_event.byweekno, &text);
1125 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1126 if (text && *text) {
1127 DBG("BYWEEKNO= [%s]", text);
1128 _cal_vcalendar_make_set_str(b, ";BYWEEKNO=");
1129 _cal_vcalendar_make_set_str(b, text);
1133 ret = calendar_record_get_str_p(record, _calendar_event.bymonth, &text);
1134 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1135 if (text && *text) {
1136 DBG("BYMONTH= [%s]", text);
1137 _cal_vcalendar_make_set_str(b, ";BYMONTH=");
1138 _cal_vcalendar_make_set_str(b, text);
1142 ret = calendar_record_get_str_p(record, _calendar_event.bysetpos, &text);
1143 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1144 if (text && *text) {
1145 DBG("BYSETPOS= [%s]", text);
1146 _cal_vcalendar_make_set_str(b, ";BYSETPOS=");
1147 _cal_vcalendar_make_set_str(b, text);
1152 ret = calendar_record_get_int(record, _calendar_event.wkst, &wkst);
1153 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1154 if (CALENDAR_SUNDAY <= wkst && wkst <= CALENDAR_SATURDAY) {
1155 _cal_vcalendar_make_set_str(b, ";WKST=");
1157 case CALENDAR_SUNDAY:
1158 _cal_vcalendar_make_set_str(b, "SU");
1160 case CALENDAR_MONDAY:
1161 _cal_vcalendar_make_set_str(b, "MO");
1163 case CALENDAR_TUESDAY:
1164 _cal_vcalendar_make_set_str(b, "TU");
1166 case CALENDAR_WEDNESDAY:
1167 _cal_vcalendar_make_set_str(b, "WE");
1169 case CALENDAR_THURSDAY:
1170 _cal_vcalendar_make_set_str(b, "TH");
1172 case CALENDAR_FRIDAY:
1173 _cal_vcalendar_make_set_str(b, "FR");
1175 case CALENDAR_SATURDAY:
1176 _cal_vcalendar_make_set_str(b, "SA");
1183 ret = calendar_record_get_int(record, _calendar_event.range_type, &range_type);
1184 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1185 switch (range_type) {
1186 case CALENDAR_RANGE_COUNT:
1187 ret = calendar_record_get_int(record, _calendar_event.count, &count);
1188 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1189 snprintf(tmp, sizeof(tmp), ";COUNT=%d", count);
1190 _cal_vcalendar_make_set_str(b, tmp);
1191 DBG("count [%s]", tmp);
1194 case CALENDAR_RANGE_UNTIL:
1195 ret = calendar_record_get_caltime(record, _calendar_event.until_time, &caltime);
1196 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
1198 if (caltime.type == CALENDAR_TIME_UTIME) {
1199 char *tmp_tzid = NULL;
1200 tmp_tzid = cal_time_convert_ltos(NULL, caltime.time.utime, 0);
1202 snprintf(tmp, sizeof(tmp), ";UNTIL=%s", tmp_tzid);
1206 snprintf(tmp, sizeof(tmp), ";UNTIL="CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ,
1207 caltime.time.date.year,
1208 caltime.time.date.month,
1209 caltime.time.date.mday,
1210 caltime.time.date.hour,
1211 caltime.time.date.minute,
1212 caltime.time.date.second);
1214 _cal_vcalendar_make_set_str(b, tmp);
1215 DBG("until [%s]", tmp);
1218 case CALENDAR_RANGE_NONE:
1222 _cal_vcalendar_make_flush(b);
1225 static void __make_rrule(cal_make_s *b, calendar_record_h record)
1228 RET_IF(NULL == record);
1231 case CALENDAR_BOOK_TYPE_EVENT:
1232 switch (b->version) {
1234 __make_rrule_ver1(b, record);
1237 __make_rrule_ver2(b, record);
1241 case CALENDAR_BOOK_TYPE_TODO:
1242 ERR("No rrule in todo");
1247 int _cal_vcalendar_make_attendee(cal_make_s *b, calendar_record_h attendee)
1251 RETV_IF(NULL == attendee, CALENDAR_ERROR_INVALID_PARAMETER);
1253 ret = _cal_vcalendar_make_set_str(b, "ATTENDEE");
1254 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1257 ret = calendar_record_get_int(attendee, _calendar_attendee.cutype, &cutype);
1258 ret = _cal_vcalendar_make_set_str(b, ";CUTYPE=");
1260 case CALENDAR_ATTENDEE_CUTYPE_INDIVIDUAL:
1261 ret = _cal_vcalendar_make_set_str(b, "INDIVIDUAL");
1263 case CALENDAR_ATTENDEE_CUTYPE_GROUP:
1264 ret = _cal_vcalendar_make_set_str(b, "GROUP");
1266 case CALENDAR_ATTENDEE_CUTYPE_RESOURCE:
1267 ret = _cal_vcalendar_make_set_str(b, "RESOURCE");
1269 case CALENDAR_ATTENDEE_CUTYPE_ROOM:
1270 ret = _cal_vcalendar_make_set_str(b, "ROOM");
1272 case CALENDAR_ATTENDEE_CUTYPE_UNKNOWN:
1273 ret = _cal_vcalendar_make_set_str(b, "UNKNOWN");
1276 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1278 char *member = NULL;
1279 ret = calendar_record_get_str_p(attendee, _calendar_attendee.member, &member);
1280 if (member && *member) {
1281 ret = _cal_vcalendar_make_set_str(b, ";MEMBER=");
1282 ret = _cal_vcalendar_make_set_str(b, member);
1283 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1287 ret = calendar_record_get_int(attendee, _calendar_attendee.role, &role);
1289 ret = _cal_vcalendar_make_set_str(b, ";ROLE=");
1290 ret = _cal_vcalendar_make_set_str(b, _att_role[role]);
1291 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1295 ret = calendar_record_get_int(attendee, _calendar_attendee.status, &status);
1297 ret = _cal_vcalendar_make_set_str(b, ";PARTSTAT=");
1298 ret = _cal_vcalendar_make_set_str(b, _att_st[status]);
1299 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1303 ret = calendar_record_get_int(attendee, _calendar_attendee.rsvp, &rsvp);
1305 ret = _cal_vcalendar_make_set_str(b, ";RSVP=");
1306 ret = _cal_vcalendar_make_set_str(b, rsvp ? "TRUE" : "FALSE");
1307 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1310 char *delegatee_uri = NULL;
1311 ret = calendar_record_get_str_p(attendee, _calendar_attendee.delegatee_uri, &delegatee_uri);
1312 if (delegatee_uri && *delegatee_uri) {
1313 ret = _cal_vcalendar_make_set_str(b, ";DELEGATED-TO=");
1314 ret = _cal_vcalendar_make_set_str(b, delegatee_uri);
1315 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1318 char *delegator_uri = NULL;
1319 ret = calendar_record_get_str_p(attendee, _calendar_attendee.delegator_uri, &delegator_uri);
1320 if (delegator_uri && *delegator_uri) {
1321 ret = _cal_vcalendar_make_set_str(b, ";DELEGATED-FROM=");
1322 ret = _cal_vcalendar_make_set_str(b, delegator_uri);
1323 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1326 /* TODO : No 'sentby' member in cal_participant_info_t */
1329 ret = calendar_record_get_str_p(attendee, _calendar_attendee.name, &name);
1330 if (name && *name) {
1331 ret = _cal_vcalendar_make_set_str(b, ";CN=");
1332 ret = _cal_vcalendar_make_set_str(b, name);
1333 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1337 ret = calendar_record_get_str_p(attendee, _calendar_attendee.email, &email);
1338 if (email && *email) {
1339 ret = _cal_vcalendar_make_set_str(b, ":mailto:");
1340 ret = _cal_vcalendar_make_set_str(b, email);
1341 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1344 _cal_vcalendar_make_flush(b);
1345 return CALENDAR_ERROR_NONE;
1348 static void __make_attendee(cal_make_s *b, calendar_record_h record)
1351 RET_IF(NULL == record);
1354 unsigned int count = 0;
1357 case CALENDAR_BOOK_TYPE_EVENT:
1358 ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_attendee, &count);
1359 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1360 for (i = 0; i < count; i++) {
1361 calendar_record_h child = NULL;
1362 ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_attendee, i, &child);
1363 ret = _cal_vcalendar_make_attendee(b, child);
1366 case CALENDAR_BOOK_TYPE_TODO:
1367 ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_attendee, &count);
1368 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1369 for (i = 0; i < count; i++) {
1370 calendar_record_h child = NULL;
1371 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_attendee, i, &child);
1372 ret = _cal_vcalendar_make_attendee(b, child);
1378 static void __make_alarm_ver1(cal_make_s *b, calendar_record_h record)
1380 /* In ver 1.0, only first alarm will be dealt with. */
1382 RET_IF(NULL == record);
1385 unsigned int count = 0;
1388 case CALENDAR_BOOK_TYPE_EVENT:
1389 ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, &count);
1390 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1391 for (i = 0; i < count; i++) {
1392 calendar_record_h child = NULL;
1393 ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, i, &child);
1394 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1396 _cal_vcalendar_make_aalarm(b, record, child);
1399 case CALENDAR_BOOK_TYPE_TODO:
1400 ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, &count);
1401 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1402 for (i = 0; i < count; i++) {
1403 calendar_record_h child = NULL;
1404 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, i, &child);
1405 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1407 _cal_vcalendar_make_aalarm(b, record, child);
1413 static void __make_alarm_ver2(cal_make_s *b, calendar_record_h record)
1416 RET_IF(NULL == record);
1419 unsigned int count = 0;
1422 case CALENDAR_BOOK_TYPE_EVENT:
1423 ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, &count);
1424 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1425 for (i = 0; i < count; i++) {
1426 calendar_record_h child = NULL;
1427 ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, i, &child);
1428 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1430 _cal_vcalendar_make_alarm(b, child);
1433 case CALENDAR_BOOK_TYPE_TODO:
1434 ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, &count);
1435 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1436 for (i = 0; i < count; i++) {
1437 calendar_record_h child = NULL;
1438 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, i, &child);
1439 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1441 _cal_vcalendar_make_alarm(b, child);
1447 static void __make_alarm(cal_make_s *b, calendar_record_h record)
1450 RET_IF(NULL == record);
1453 case CALENDAR_BOOK_TYPE_EVENT:
1454 switch (b->version) {
1456 __make_alarm_ver1(b, record);
1459 __make_alarm_ver2(b, record);
1463 case CALENDAR_BOOK_TYPE_TODO:
1464 ERR("No rrule in todo");
1469 static void __make_created_time(cal_make_s *b, calendar_record_h record)
1472 RET_IF(NULL == record);
1475 long long int value = 0;
1477 case CALENDAR_BOOK_TYPE_EVENT:
1478 ret = calendar_record_get_lli(record, _calendar_event.created_time, &value);
1479 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
1481 case CALENDAR_BOOK_TYPE_TODO:
1482 ret = calendar_record_get_lli(record, _calendar_todo.created_time, &value);
1483 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
1486 int y = 0, m = 0, d = 0;
1487 int h = 0, n = 0, s = 0;
1488 cal_time_get_local_datetime(NULL, value, &y, &m, &d, &h, &n, &s);
1489 char buf[CAL_STR_MIDDLE_LEN] = {0};
1490 snprintf(buf, sizeof(buf), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
1492 switch (b->version) {
1494 _cal_vcalendar_make_printf(b, "DCREATED:", buf);
1497 _cal_vcalendar_make_printf(b, "CREATED:", buf);
1502 static void __make_summary(cal_make_s *b, calendar_record_h record)
1505 RET_IF(NULL == record);
1510 case CALENDAR_BOOK_TYPE_EVENT:
1511 ret = calendar_record_get_str_p(record, _calendar_event.summary, &value);
1512 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1514 case CALENDAR_BOOK_TYPE_TODO:
1515 ret = calendar_record_get_str_p(record, _calendar_todo.summary, &value);
1516 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1519 if (value && *value) {
1520 char *summary = NULL;
1521 __encode_escaped_char(value, &summary);
1522 _cal_vcalendar_make_printf(b, "SUMMARY:", summary);
1527 static void __make_description(cal_make_s *b, calendar_record_h record)
1530 RET_IF(NULL == record);
1535 case CALENDAR_BOOK_TYPE_EVENT:
1536 ret = calendar_record_get_str_p(record, _calendar_event.description, &value);
1537 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1539 case CALENDAR_BOOK_TYPE_TODO:
1540 ret = calendar_record_get_str_p(record, _calendar_todo.description, &value);
1541 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1544 if (value && *value) {
1545 char *description = NULL;
1546 __encode_escaped_char(value, &description);
1547 _cal_vcalendar_make_printf(b, "DESCRIPTION:", description);
1552 static void __make_location(cal_make_s *b, calendar_record_h record)
1555 RET_IF(NULL == record);
1560 case CALENDAR_BOOK_TYPE_EVENT:
1561 ret = calendar_record_get_str_p(record, _calendar_event.location, &value);
1562 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1564 case CALENDAR_BOOK_TYPE_TODO:
1565 ret = calendar_record_get_str_p(record, _calendar_todo.location, &value);
1566 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1569 if (value && *value) {
1570 char *location = NULL;
1571 __encode_escaped_char(value, &location);
1572 _cal_vcalendar_make_printf(b, "LOCATION:", location);
1577 static void __make_organizer(cal_make_s *b, calendar_record_h record)
1580 RET_IF(NULL == record);
1582 /* Invalid component in ver 1 */
1583 if (VCAL_VER_1 == b->version)
1590 case CALENDAR_BOOK_TYPE_EVENT:
1591 ret = calendar_record_get_str_p(record, _calendar_event.organizer_name, &name);
1592 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1593 ret = calendar_record_get_str_p(record, _calendar_event.organizer_email, &email);
1594 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1596 case CALENDAR_BOOK_TYPE_TODO:
1597 ret = calendar_record_get_str_p(record, _calendar_todo.organizer_name, &name);
1598 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1599 ret = calendar_record_get_str_p(record, _calendar_todo.organizer_email, &email);
1600 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1603 if ((NULL == name || '\0' == *name) && (NULL == email || '\0' == *email))
1606 char buf[CAL_STR_MIDDLE_LEN] = {0};
1607 snprintf(buf, sizeof(buf), "ORGANIZER%s%s%s%s",
1608 (name && *name) ? ";CN=" : "",
1609 (name && *name) ? name : "",
1610 (email && *email) ? ":MAILTO:" : "",
1611 (email && *email) ? email : "");
1613 _cal_vcalendar_make_printf(b, buf, NULL);
1616 static void __make_last_modified(cal_make_s *b, calendar_record_h record)
1619 RET_IF(NULL == record);
1621 /* kies want to skip */
1622 if (VCAL_VER_1 == b->version) {
1623 DBG("skip in ver1.0");
1628 long long int value = 0;
1630 case CALENDAR_BOOK_TYPE_EVENT:
1631 ret = calendar_record_get_lli(record, _calendar_event.last_modified_time, &value);
1632 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
1634 case CALENDAR_BOOK_TYPE_TODO:
1635 ret = calendar_record_get_lli(record, _calendar_todo.last_modified_time, &value);
1636 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
1640 int y = 0, m = 0, d = 0;
1641 int h = 0, n = 0, s = 0;
1642 cal_time_get_local_datetime(NULL, value, &y, &m, &d, &h, &n, &s);
1644 char buf[CAL_STR_MIDDLE_LEN] = {0};
1645 snprintf(buf, sizeof(buf), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
1646 _cal_vcalendar_make_printf(b, "LAST-MODIFIED:", buf);
1649 static void __make_status(cal_make_s *b, calendar_record_h record)
1652 RET_IF(NULL == record);
1656 char *status = NULL;
1658 case CALENDAR_BOOK_TYPE_EVENT:
1659 ret = calendar_record_get_int(record, _calendar_event.event_status, &value);
1660 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1662 case CALENDAR_EVENT_STATUS_NONE:
1665 case CALENDAR_EVENT_STATUS_TENTATIVE:
1666 status = "TENTATIVE";
1668 case CALENDAR_EVENT_STATUS_CONFIRMED:
1669 status = "CONFIRMED";
1671 case CALENDAR_EVENT_STATUS_CANCELLED:
1672 status = "CANCELLED";
1676 case CALENDAR_BOOK_TYPE_TODO:
1677 ret = calendar_record_get_int(record, _calendar_todo.todo_status, &value);
1678 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1680 case CALENDAR_TODO_STATUS_NONE:
1683 case CALENDAR_TODO_STATUS_NEEDS_ACTION:
1684 status = (VCAL_VER_1 == b->version) ? "NEEDS ACTION" : "NEEDS-ACTION";
1686 case CALENDAR_TODO_STATUS_COMPLETED:
1687 status = "COMPLETED";
1689 case CALENDAR_TODO_STATUS_IN_PROCESS:
1690 status = (VCAL_VER_1 == b->version) ? NULL : "IN-PROCESS";
1692 case CALENDAR_TODO_STATUS_CANCELED:
1693 status = (VCAL_VER_1 == b->version) ? NULL : "CANCELLED";
1698 if (status && *status)
1699 _cal_vcalendar_make_printf(b, "STATUS:", status);
1702 static void __make_completed(cal_make_s *b, calendar_record_h record)
1705 RET_IF(NULL == record);
1707 /* Invalid component in event */
1708 if (CALENDAR_BOOK_TYPE_EVENT == b->type)
1712 long long int value = 0;
1713 ret = calendar_record_get_lli(record, _calendar_todo.completed_time, &value);
1714 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1716 int y = 0, m = 0, d = 0;
1717 int h = 0, n = 0, s = 0;
1718 cal_time_get_local_datetime(NULL, value, &y, &m, &d, &h, &n, &s);
1719 char buf[CAL_STR_MIDDLE_LEN] = {0};
1720 snprintf(buf, sizeof(buf), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
1721 _cal_vcalendar_make_printf(b, "COMPLETED", buf);
1724 static void __make_priority(cal_make_s *b, calendar_record_h record)
1727 RET_IF(NULL == record);
1732 case CALENDAR_BOOK_TYPE_EVENT:
1733 ret = calendar_record_get_int(record, _calendar_event.priority, &value);
1734 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1736 case CALENDAR_BOOK_TYPE_TODO:
1737 ret = calendar_record_get_int(record, _calendar_todo.priority, &value);
1738 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1742 switch (b->version) {
1745 case CALENDAR_EVENT_PRIORITY_HIGH:
1748 case CALENDAR_EVENT_PRIORITY_NORMAL:
1751 case CALENDAR_EVENT_PRIORITY_LOW:
1761 case CALENDAR_EVENT_PRIORITY_HIGH:
1762 /* in version 2.0, one out of 1 ~ 4 */
1765 case CALENDAR_EVENT_PRIORITY_NORMAL:
1768 case CALENDAR_EVENT_PRIORITY_LOW:
1769 /* in version 2, one out of 6 ~ 9. */
1778 char buf[CAL_STR_MIDDLE_LEN] = {0};
1779 snprintf(buf, sizeof(buf), "PRIORITY:%d", priority);
1780 _cal_vcalendar_make_printf(b, buf, NULL);
1783 static void __make_dtstamp(cal_make_s *b, calendar_record_h record)
1786 RET_IF(NULL == record);
1788 /* Not support in ver 1 */
1789 if (VCAL_VER_1 == b->version)
1792 long long int t = cal_time_get_now();
1793 int y = 0, m = 0, d = 0;
1794 int h = 0, n = 0, s = 0;
1795 cal_time_get_local_datetime(NULL, t, &y, &m, &d, &h, &n, &s);
1796 char buf[CAL_STR_MIDDLE_LEN] = {0};
1797 snprintf(buf, sizeof(buf), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
1798 _cal_vcalendar_make_printf(b, "DTSTAMP:", buf);
1801 static void __make_categories(cal_make_s *b, calendar_record_h record)
1804 RET_IF(NULL == record);
1809 case CALENDAR_BOOK_TYPE_EVENT:
1810 ret = calendar_record_get_str_p(record, _calendar_event.categories, &value);
1811 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1813 case CALENDAR_BOOK_TYPE_TODO:
1814 ret = calendar_record_get_str_p(record, _calendar_todo.categories, &value);
1815 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1818 if (value && *value)
1819 _cal_vcalendar_make_printf(b, "CATEGORIES:", value);
1822 static void __make_exdate(cal_make_s *b, calendar_record_h record)
1825 RET_IF(NULL == record);
1830 case CALENDAR_BOOK_TYPE_EVENT:
1831 ret = calendar_record_get_str_p(record, _calendar_event.exdate, &value);
1832 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1834 case CALENDAR_BOOK_TYPE_TODO:
1835 ERR("Not support exdate in TODO");
1838 if (value && *value)
1839 _cal_vcalendar_make_printf(b, "EXDATE:", value);
1842 static void _cal_vcalendar_make_child_extended(cal_make_s *b, calendar_record_h child, bool *has_lunar)
1845 RET_IF(NULL == child);
1851 ret = calendar_record_get_str_p(child, _calendar_extended_property.key, &key);
1852 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1853 if (NULL == key || '\0' == *key || (0 != strncmp(key, "X-", strlen("X-")))) {
1854 DBG("Not extended for vcalendar[%s]", key);
1858 ret = calendar_record_get_str_p(child, _calendar_extended_property.value, &value);
1859 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1861 /* check lunar: will handle next */
1863 if ((CAL_STRING_EQUAL == strncmp(key, "X-LUNAR", strlen("X-LUNAR")) && !strncmp(value, ":SET", strlen(":SET"))) ||
1864 (CAL_STRING_EQUAL == strncmp(key, "X-LUNAR:", strlen("X-LUNAR:")) && !strncmp(value, "SET", strlen("SET")))) {
1870 ret = _cal_vcalendar_make_printf(b, key, value);
1871 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1874 static void __make_extended(cal_make_s *b, calendar_record_h record)
1877 RET_IF(NULL == record);
1880 unsigned int count = 0;
1882 bool has_lunar = false;
1883 int calendar_system_type = 0;
1885 case CALENDAR_BOOK_TYPE_EVENT:
1886 ret = calendar_record_get_child_record_count(record, _calendar_event.extended, &count);
1887 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1888 for (i = 0; i < count; i++) {
1889 calendar_record_h child = NULL;
1890 ret = calendar_record_get_child_record_at_p(record, _calendar_event.extended, i, &child);
1891 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1893 _cal_vcalendar_make_child_extended(b, child, &has_lunar);
1897 ret = calendar_record_get_int(record, _calendar_event.calendar_system_type, &calendar_system_type);
1898 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1900 if (true == has_lunar || CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR == calendar_system_type)
1901 _cal_vcalendar_make_printf(b, "X-LUNAR:SET", NULL);
1903 case CALENDAR_BOOK_TYPE_TODO:
1904 ret = calendar_record_get_child_record_count(record, _calendar_todo.extended, &count);
1905 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1906 for (i = 0; i < count; i++) {
1907 calendar_record_h child = NULL;
1908 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.extended, i, &child);
1909 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1911 _cal_vcalendar_make_child_extended(b, child, NULL);
1917 static void __make_end(cal_make_s *b, calendar_record_h record)
1920 RET_IF(NULL == record);
1924 case CALENDAR_BOOK_TYPE_EVENT:
1925 ret = _cal_vcalendar_make_printf(b, "END:VEVENT", NULL);
1926 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1928 case CALENDAR_BOOK_TYPE_TODO:
1929 ret = _cal_vcalendar_make_printf(b, "END:VTODO", NULL);
1930 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1935 static void _cal_vcalendar_make_schedule(cal_make_s *b, calendar_record_h record)
1938 RET_IF(NULL == record);
1940 __make_begin(b, record);
1941 __make_summary(b, record);
1942 __make_dtstart(b, record);
1943 __make_dtend(b, record);
1944 __make_rrule(b, record); /* only event */
1945 __make_sensitivity(b, record);
1946 __make_created_time(b, record);
1947 __make_description(b, record);
1948 __make_location(b, record);
1949 __make_organizer(b, record);
1950 __make_last_modified(b, record);
1951 __make_status(b, record);
1952 __make_completed(b, record); /* only todo */
1953 __make_priority(b, record);
1954 __make_dtstamp(b, record);
1955 __make_categories(b, record);
1956 __make_exdate(b, record); /* only event */
1957 __make_attendee(b, record);
1958 __make_alarm(b, record);
1959 __make_extended(b, record);
1960 __make_end(b, record);
1964 static void __append_header(cal_make_s *b)
1970 ret = _cal_vcalendar_make_printf(b, "BEGIN:VCALENDAR", NULL);
1971 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1973 ret = _cal_vcalendar_make_printf(b, "PRODID:vCal ID Default", NULL);
1974 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1976 char buf[CAL_STR_SHORT_LEN32] = {0};
1977 snprintf(buf, sizeof(buf), "VERSION:%d.0", b->version);
1978 ret = _cal_vcalendar_make_printf(b, buf, NULL);
1979 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1982 static void __make_footer(cal_make_s *b)
1987 ret = _cal_vcalendar_make_printf(b, "END:VCALENDAR", NULL);
1988 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1991 static void __make_tz(cal_make_s *b, char *tzid, long long int created)
1996 RET_IF(NULL == tzid);
1997 RET_IF('\0' == *tzid);
2001 cal_time_get_tz_offset(tzid, &zone, &dst);
2002 DBG("offset zone(%ld), dst (%ld)", zone, dst);
2004 bool in_dst = cal_time_in_dst(tzid, created);
2005 dst = in_dst ? dst : 0; /* dst in TZ is depending on created time */
2006 DBG("tzid[%s] created time(%lld) in_dst(%d)", tzid, created, in_dst);
2008 int h = (zone / 3600) + (dst / 3600);
2009 int m = (zone % 3600) / 60 + (dst % 3600) / 60;
2011 char buf[CAL_STR_SHORT_LEN32] = {0};
2012 snprintf(buf, sizeof(buf), "TZ:%s%02d:%02d",
2013 h == 0 ? "" : (h < 0 ? "-" : "+"),
2014 h < 0 ? (-1 * h) : h, m < 0 ? (-1 * m) : m);
2016 ret = _cal_vcalendar_make_printf(b, buf, NULL);
2017 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail");
2018 DBG("append tzid[%s]", buf);
2021 static void __devide_vcalendar_with_header(cal_make_s *b, calendar_record_h record)
2024 RET_IF(NULL == record);
2026 if (2 == b->version)
2031 ret = calendar_record_get_uri_p(record, &uri);
2032 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_uri_p() Fail(%d)", ret);
2035 long long int created = 0;
2038 case CALENDAR_BOOK_TYPE_EVENT:
2039 ret = calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
2040 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
2041 ret = calendar_record_get_lli(record, _calendar_event.created_time, &created);
2042 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
2044 case CALENDAR_BOOK_TYPE_TODO:
2045 ret = calendar_record_get_str_p(record, _calendar_todo.due_tzid, &tzid);
2046 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
2047 ret = calendar_record_get_lli(record, _calendar_todo.created_time, &created);
2048 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
2052 if (NULL == tzid || '\0' == *tzid) {
2057 if (NULL == b->timezone_tzid || '\0' == *b->timezone_tzid) {
2058 /* new start of vcalendar */
2059 __make_tz(b, tzid, created);
2060 b->timezone_tzid = strdup(tzid);
2062 /* not first vcalendar */
2063 if (0 != strncmp(b->timezone_tzid, tzid, strlen(tzid))) {
2064 /* different tzid */
2067 __make_tz(b, tzid, created);
2068 if (b->timezone_tzid)
2069 free(b->timezone_tzid);
2070 b->timezone_tzid = strdup(tzid);
2072 DBG("same as before, skip");
2076 static int __make_vcalendar(cal_make_s *b, calendar_list_h list)
2078 RETV_IF(NULL == b, CALENDAR_ERROR_INVALID_PARAMETER);
2079 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
2081 int ret = CALENDAR_ERROR_NONE;
2082 calendar_record_h record = NULL;
2086 ret = calendar_list_first(list);
2087 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_first() Fail");
2089 ret = calendar_list_get_current_record_p(list, &record);
2090 if (CALENDAR_ERROR_NONE != ret) break;
2093 ret = calendar_record_get_uri_p(record, &uri);
2094 DBG("uri[%s]", uri);
2096 if (CAL_STRING_EQUAL == strcmp(uri, _calendar_event._uri)) {
2097 b->type = CALENDAR_BOOK_TYPE_EVENT;
2098 __devide_vcalendar_with_header(b, record);
2099 _cal_vcalendar_make_schedule(b, record);
2101 } else if (CAL_STRING_EQUAL == strcmp(uri, _calendar_todo._uri)) {
2102 b->type = CALENDAR_BOOK_TYPE_TODO;
2103 __devide_vcalendar_with_header(b, record);
2104 _cal_vcalendar_make_schedule(b, record);
2106 } else if (CAL_STRING_EQUAL == strcmp(uri, _calendar_extended_property._uri)) {
2107 cal_extended_s *extended = (cal_extended_s *)record;
2108 if (CAL_STRING_EQUAL == strncmp(extended->key, "VERSION", strlen("VERSION"))) continue;
2110 ret = _cal_vcalendar_make_printf(b, extended->key, extended->value);
2111 if (CALENDAR_ERROR_NONE != ret) break;
2113 DBG("extended key[%s] value[%s]", extended->key, extended->value);
2115 } else if (CAL_STRING_EQUAL == strcmp(uri, _calendar_timezone._uri)) {
2116 DBG("Not support timezone");
2118 } else if (CAL_STRING_EQUAL == strcmp(uri, _calendar_book._uri)) {
2119 DBG("Not support calendar");
2122 DBG("Unable to understand uri[%s]", uri);
2125 } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
2128 return CALENDAR_ERROR_NONE;
2131 int cal_vcalendar_make_vcalendar(cal_make_s *b, calendar_list_h list)
2133 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
2135 int ret = CALENDAR_ERROR_NONE;
2136 calendar_record_h record = NULL;
2138 int version = 2; /* set default as ver 2.0 */
2140 ret = calendar_list_first(list);
2141 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_first() Fail");
2143 ret = calendar_list_get_current_record_p(list, &record);
2144 if (CALENDAR_ERROR_NONE != ret) break;
2147 ret = calendar_record_get_uri_p(record, &uri);
2149 if (CAL_STRING_EQUAL == strcmp(uri, _calendar_extended_property._uri)) {
2150 cal_extended_s *extended = (cal_extended_s *)record;
2151 if (CAL_STRING_EQUAL == strncmp(extended->key, "VERSION", strlen("VERSION"))) {
2152 version = strstr(extended->value, "1.0") ? 1 : 2;
2156 } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
2157 b->version = version;
2158 DBG("make as version(%d)", version);
2160 __make_vcalendar(b, list);
2161 return CALENDAR_ERROR_NONE;