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 /* LCOV_EXCL_START */
504 ERR("g_strsplit_set() Fail");
509 int len = strlen(buf);
510 int tlen = g_strv_length(t);
512 for (i = 0; i < tlen; i++) {
516 int num = atoi(t[i]);
517 ret += snprintf(buf +len +ret, buf_len -len -ret, "%d%s",
518 num < 0 ? (-1 * num) : num, num < 0 ? "- " : " ");
525 static void _cal_vcalendar_make_rrule_append_setpos(calendar_record_h record, char *buf, int buf_len)
529 int ret = CALENDAR_ERROR_NONE;
530 char *bysetpos = NULL;
532 ret = calendar_record_get_str_p(record, _calendar_event.bysetpos, &bysetpos);
533 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() failed(%d)", ret);
535 int blen = strlen(buf);
536 if (bysetpos && '\0' != bysetpos[0]) {
537 /* in ver1.0, "3, 5, -4" -> "3+ 5+ 4-" */
539 t = g_strsplit_set(bysetpos, " ,", -1);
541 int len = g_strv_length(t);
544 for (i = 0; i < len; i++) {
545 if (*t[i] == '\0') continue;
547 int setpos = atoi(t[i]);
551 DBG("Invalid setpos(0)");
554 blen += snprintf(buf +blen, buf_len -blen, "%d%s ", setpos * (setpos < 0 ? -1 : 1), setpos < 0 ? "-" : "+");
558 /* in ver2.0, 3TH should be changed to setpos:3, byday:TH */
560 ret = calendar_record_get_str_p(record, _calendar_event.byday, &byday);
561 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
562 if (NULL == byday || '\0' == byday[0]) {
563 blen += snprintf(buf +blen, buf_len -blen, "%s", "1+ ");
567 int len = strlen(byday);
569 bool is_working = true;
570 bool is_extracted = false;
575 /* extract -1, 1 from 1SU,-1SU */
576 if ('1' <= byday[i] && byday[i] <= '9') {
579 } else if ('+' == byday[i]) {
582 } else if ('-' == byday[i]) {
586 if (false == is_working) {
589 char num[CAL_STR_SHORT_LEN32] = {0};
590 snprintf(num, digit +1, "%s", byday +i -digit);
591 if (NULL == strstr(buf, num))
592 blen += snprintf(buf +blen, buf_len -blen, "%s%c ", num, (-1 == sign) ? '-' : '+');
600 if (false == is_extracted) {
601 blen += snprintf(buf +blen, buf_len -blen, "%s", "1+ ");
608 * 2WE 3FR in ver2.0 is not converted to ver1.0
609 * because three is no +2 WE +3 FR.
611 void _cal_vcalendar_make_rrule_append_text_wday(int rrule_type, char *buf, int buf_len, char *wday)
620 int len = strlen(buf);
621 t = g_strsplit_set(wday, " ,", -1);
623 /* LCOV_EXCL_START */
624 ERR("g_strsplit_set() Fail");
629 length = g_strv_length(t);
631 for (i = 0; i < length; i++) {
640 /* get number length */
642 while (p[j] == '+' || p[j] == '-' || ('1' <= p[j] && p[j] <= '9'))
645 /* already appended */
646 if (strstr(buf, p +j))
649 len += snprintf(buf +len, buf_len -len, "%s ", p +j);
656 void _cal_vcalendar_make_rrule_append_wkst(char *buf, int buf_len, calendar_record_h record)
658 const char wday[7][3] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
660 calendar_record_get_int(record, _calendar_event.wkst, &wkst);
661 if (wkst < CALENDAR_SUNDAY || CALENDAR_SATURDAY < wkst)
664 DBG("wkst(%d) [%s]", wkst, wday[wkst - 1]);
665 int len = strlen(buf);
666 snprintf(buf +len, buf_len -len, "WKST=%s ", wday[wkst - 1]);
669 int _cal_vcalendar_make_rrule_append_wday(int rrule_type, char *buf, int buf_len, char *wday)
671 RETV_IF(NULL == buf, CALENDAR_ERROR_INVALID_PARAMETER);
674 int num = 0, num_past;
678 char buf_temp[8] = {0};
680 RETV_IF(NULL == buf, CALENDAR_ERROR_INVALID_PARAMETER);
681 RETV_IF(NULL == wday, CALENDAR_ERROR_INVALID_PARAMETER);
683 int len = strlen(buf);
686 t = g_strsplit_set(wday, " ,", -1);
688 /* LCOV_EXCL_START */
689 ERR("g_strsplit_set() Fail");
691 return CALENDAR_ERROR_OUT_OF_MEMORY;
694 length = g_strv_length(t);
695 DBG("len(%d)", length);
697 for (i = 0; i < length; i++) {
698 if (*t[i] == '\0') continue;
704 while (p[j] == '+' || p[j] == '-' || ('1' <= p[j] && p[j] <= '9'))
708 if (CALENDAR_RECURRENCE_WEEKLY == rrule_type) {
712 snprintf(buf_temp, j + 1, "%s", p + 1);
713 num = atoi(buf_temp);
716 len += snprintf(buf +len, buf_len -len, "%s- ", buf_temp);
719 snprintf(buf_temp, j + 1, "%s", p);
720 num = atoi(buf_temp);
723 len += snprintf(buf +len, buf_len -len, "%s+ ", buf_temp);
728 len += snprintf(buf +len, buf_len -len, "%s ", p +j);
730 ERR("Out of 1.0 spec");
732 DBG("%d num(%d) val[%s]", i, num, p + j);
734 len += snprintf(buf +len, buf_len -len, "%s ", p);
740 return CALENDAR_ERROR_NONE;
743 static void __make_begin(cal_make_s *b, calendar_record_h record)
746 RET_IF(NULL == record);
750 case CALENDAR_BOOK_TYPE_EVENT:
751 ret = _cal_vcalendar_make_printf(b, "BEGIN:VEVENT", NULL);
752 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
754 case CALENDAR_BOOK_TYPE_TODO:
755 ret = _cal_vcalendar_make_printf(b, "BEGIN:VTODO", NULL);
756 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
761 static void __make_dtstart(cal_make_s *b, calendar_record_h record)
764 RET_IF(NULL == record);
768 calendar_time_s ct = {0};
770 case CALENDAR_BOOK_TYPE_EVENT:
771 ret = calendar_record_get_str_p(record, _calendar_event.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_event.start_time, &ct);
774 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
776 case CALENDAR_BOOK_TYPE_TODO:
777 ret = calendar_record_get_str_p(record, _calendar_todo.start_tzid, &tzid);
778 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
779 ret = calendar_record_get_caltime(record, _calendar_todo.start_time, &ct);
780 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
783 _cal_vcalendar_make_time(b, tzid, &ct, "DTSTART");
786 static void __make_dtend(cal_make_s *b, calendar_record_h record)
789 RET_IF(NULL == record);
793 calendar_time_s ct = {0};
795 case CALENDAR_BOOK_TYPE_EVENT:
796 ret = calendar_record_get_str_p(record, _calendar_event.end_tzid, &tzid);
797 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
798 ret = calendar_record_get_caltime(record, _calendar_event.end_time, &ct);
799 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
800 _cal_vcalendar_make_time(b, tzid, &ct, "DTEND");
802 case CALENDAR_BOOK_TYPE_TODO:
803 ret = calendar_record_get_str_p(record, _calendar_todo.due_tzid, &tzid);
804 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
805 ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &ct);
806 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
807 _cal_vcalendar_make_time(b, tzid, &ct, "DUE");
812 static void __make_sensitivity(cal_make_s *b, calendar_record_h record)
815 RET_IF(NULL == record);
820 case CALENDAR_BOOK_TYPE_EVENT:
821 ret = calendar_record_get_int(record, _calendar_event.sensitivity, &value);
822 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
824 case CALENDAR_BOOK_TYPE_TODO:
825 ret = calendar_record_get_int(record, _calendar_todo.sensitivity, &value);
826 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
829 char *sensitivity = NULL;
831 case CALENDAR_SENSITIVITY_PUBLIC:
832 sensitivity = "PUBLIC";
834 case CALENDAR_SENSITIVITY_PRIVATE:
835 sensitivity = "PRIVATE";
837 case CALENDAR_SENSITIVITY_CONFIDENTIAL:
838 sensitivity = "CONFIDENTIAL";
841 /* LCOV_EXCL_START */
842 ERR("Invalid sensitivity(%d)", value);
846 _cal_vcalendar_make_printf(b, "CLASS:", sensitivity);
849 int _cal_vcalendar_make_rrule_append_until(char *buf, int buf_len, calendar_record_h record)
854 char *until_str = NULL;
855 calendar_time_s caltime;
857 ret = calendar_record_get_int(record, _calendar_event.range_type, &range_type);
858 if (CALENDAR_ERROR_NONE != ret) {
859 /* LCOV_EXCL_START */
860 ERR("calendar_record_get_int() Fail");
865 int len = strlen(buf);
866 switch (range_type) {
867 case CALENDAR_RANGE_COUNT:
868 ret = calendar_record_get_int(record, _calendar_event.count, &count);
869 if (CALENDAR_ERROR_NONE != ret) {
870 /* LCOV_EXCL_START */
871 ERR("calendar_record_get_int() Fail");
875 snprintf(buf +len, buf_len -len, "#%d", count);
878 case CALENDAR_RANGE_UNTIL:
879 memset(&caltime, 0x0, sizeof(calendar_time_s));
881 ret = calendar_record_get_caltime(record, _calendar_event.until_time, &caltime);
882 if (CALENDAR_ERROR_NONE != ret) {
883 /* LCOV_EXCL_START */
884 ERR("calendar_record_get_caltime() Fail");
888 switch (caltime.type) {
889 case CALENDAR_TIME_UTIME:
890 until_str = cal_time_convert_ltos(NULL, caltime.time.utime, 0);
891 snprintf(buf +len, buf_len -len, "%s", until_str);
895 case CALENDAR_TIME_LOCALTIME:
896 snprintf(buf +len, buf_len -len, CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS,
897 caltime.time.date.year, caltime.time.date.month, caltime.time.date.mday,
898 caltime.time.date.hour, caltime.time.date.minute, caltime.time.date.second);
903 case CALENDAR_RANGE_NONE:
904 snprintf(buf +len, buf_len -len, "%s", "#0");
907 return CALENDAR_ERROR_NONE;
909 static void __make_rrule_ver1_default(calendar_record_h record, int freq, int interval, char *buf, int buf_size)
911 RET_IF(NULL == record);
914 calendar_time_s caltime = {0};
915 ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
916 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
919 case CALENDAR_RECURRENCE_YEARLY:
920 snprintf(buf, buf_size, "YD%d ", interval);
922 case CALENDAR_RECURRENCE_MONTHLY:
923 snprintf(buf, buf_size, "MD%d ", interval);
929 switch (caltime.type) {
930 case CALENDAR_TIME_UTIME:
931 calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
932 cal_time_get_local_datetime(tzid, caltime.time.utime, NULL, NULL, &d, NULL, NULL, NULL);
934 case CALENDAR_TIME_LOCALTIME:
935 d = caltime.time.date.mday;
938 char mday[CAL_STR_SHORT_LEN32] = {0};
939 snprintf(mday, sizeof(mday), "%d", d);
940 _cal_vcalendar_make_rrule_append_mday(buf, buf_size, mday);
943 static void __make_rrule_ver1(cal_make_s *b, calendar_record_h record)
946 RET_IF(NULL == record);
949 char buf[CAL_STR_MIDDLE_LEN] = {0};
952 ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
953 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
956 ret = calendar_record_get_int(record, _calendar_event.interval, &interval);
957 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
958 interval = 0 < interval ? interval : 1;
960 char *byyearday = NULL;
961 ret = calendar_record_get_str_p(record, _calendar_event.byyearday, &byyearday);
962 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
964 char *bymonth = NULL;
965 ret = calendar_record_get_str_p(record, _calendar_event.bymonth, &bymonth);
966 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
969 ret = calendar_record_get_str_p(record, _calendar_event.byday, &byday);
970 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
972 char *bymonthday = NULL;
973 ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &bymonthday);
974 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
978 case CALENDAR_RECURRENCE_YEARLY:
979 if (bymonth && *bymonth) {
980 DBG("bymonth[%s]", bymonth);
981 len += snprintf(buf +len, sizeof(buf) -len, "YM%d ", interval);
982 len += _cal_vcalendar_make_rrule_append_mday(buf, sizeof(buf), bymonth);
984 if (byday && *byday) {
986 /* ex> YM1 6 MP1 1+ TH */
987 len += snprintf(buf +len, sizeof(buf) -len, "MP%d ", interval);
988 _cal_vcalendar_make_rrule_append_setpos(record, buf, sizeof(buf));
989 _cal_vcalendar_make_rrule_append_text_wday(CALENDAR_RECURRENCE_MONTHLY, buf, sizeof(buf), byday);
990 } else if (bymonthday && *bymonthday) {
993 len += snprintf(buf +len, sizeof(buf) -len, "MD%d ", interval);
994 _cal_vcalendar_make_rrule_append_mday(buf, sizeof(buf), bymonthday);
997 __make_rrule_ver1_default(record, freq, interval, buf, sizeof(buf));
999 } else if (byyearday && *byyearday) {
1001 snprintf(buf, sizeof(buf), "YD%d ", interval);
1002 _cal_vcalendar_make_rrule_append_mday(buf, sizeof(buf), byyearday);
1004 ERR("Out of scope");
1005 __make_rrule_ver1_default(record, freq, interval, buf, sizeof(buf));
1009 case CALENDAR_RECURRENCE_MONTHLY:
1010 if (byday && *byday) {
1012 snprintf(buf, sizeof(buf), "MP%d ", interval);
1013 _cal_vcalendar_make_rrule_append_setpos(record, buf, sizeof(buf));
1014 _cal_vcalendar_make_rrule_append_text_wday(CALENDAR_RECURRENCE_MONTHLY, buf, sizeof(buf), byday);
1015 } else if (bymonthday && *bymonthday) {
1017 snprintf(buf, sizeof(buf), "MD%d ", interval);
1018 _cal_vcalendar_make_rrule_append_mday(buf, sizeof(buf), bymonthday);
1020 ERR("Out of scope, so set as bymonthday");
1021 __make_rrule_ver1_default(record, freq, interval, buf, sizeof(buf));
1025 case CALENDAR_RECURRENCE_WEEKLY:
1026 snprintf(buf, sizeof(buf), "W%d ", interval);
1027 _cal_vcalendar_make_rrule_append_wday(CALENDAR_RECURRENCE_WEEKLY, buf, sizeof(buf), byday);
1030 case CALENDAR_RECURRENCE_DAILY:
1031 snprintf(buf, sizeof(buf), "D%d ", interval);
1035 /* LCOV_EXCL_START */
1036 ERR("Out of scope");
1038 /* LCOV_EXCL_STOP */
1042 _cal_vcalendar_make_rrule_append_wkst(buf, sizeof(buf), record);
1043 _cal_vcalendar_make_rrule_append_until(buf, sizeof(buf), record);
1044 _cal_vcalendar_make_printf(b, "RRULE:", buf);
1048 static void __make_rrule_ver2(cal_make_s *b, calendar_record_h record)
1051 RET_IF(NULL == record);
1055 char tmp[CAL_STR_SHORT_LEN32] = {0};
1056 calendar_time_s caltime = {0};
1059 ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
1060 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1063 case CALENDAR_RECURRENCE_DAILY:
1064 _cal_vcalendar_make_set_str(b, "RRULE:FREQ=DAILY");
1066 case CALENDAR_RECURRENCE_WEEKLY:
1067 _cal_vcalendar_make_set_str(b, "RRULE:FREQ=WEEKLY");
1069 case CALENDAR_RECURRENCE_MONTHLY:
1070 _cal_vcalendar_make_set_str(b, "RRULE:FREQ=MONTHLY");
1072 case CALENDAR_RECURRENCE_YEARLY:
1073 _cal_vcalendar_make_set_str(b, "RRULE:FREQ=YEARLY");
1080 ret = calendar_record_get_int(record, _calendar_event.interval, &interval);
1081 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1082 interval = 0 < interval ? interval : 1;
1083 snprintf(tmp, sizeof(tmp), ";INTERVAL=%d", interval);
1084 _cal_vcalendar_make_set_str(b, tmp);
1086 ret = calendar_record_get_str_p(record, _calendar_event.bysecond, &text);
1087 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1088 if (text && *text) {
1089 DBG("BYSECOND= [%s]", text);
1090 _cal_vcalendar_make_set_str(b, ";BYSECOND=");
1091 _cal_vcalendar_make_set_str(b, text);
1095 ret = calendar_record_get_str_p(record, _calendar_event.byminute, &text);
1096 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1097 if (text && *text) {
1098 DBG("BYMINUTE= [%s]", text);
1099 _cal_vcalendar_make_set_str(b, ";BYMINUTE=");
1100 _cal_vcalendar_make_set_str(b, text);
1104 ret = calendar_record_get_str_p(record, _calendar_event.byhour, &text);
1105 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1106 if (text && *text) {
1107 DBG("BYHOUR= [%s]", text);
1108 _cal_vcalendar_make_set_str(b, ";BYHOUR=");
1109 _cal_vcalendar_make_set_str(b, text);
1113 ret = calendar_record_get_str_p(record, _calendar_event.byday, &text);
1114 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1115 if (text && *text) {
1116 DBG("BYDAY= [%s]", text);
1117 _cal_vcalendar_make_set_str(b, ";BYDAY=");
1118 _cal_vcalendar_make_set_str(b, text);
1122 ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &text);
1123 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1124 if (text && *text) {
1125 DBG("BYMONTHDAY= [%s]", text);
1126 _cal_vcalendar_make_set_str(b, ";BYMONTHDAY=");
1127 _cal_vcalendar_make_set_str(b, text);
1131 ret = calendar_record_get_str_p(record, _calendar_event.byyearday, &text);
1132 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1133 if (text && *text) {
1134 DBG("BYYEARDAY= [%s]", text);
1135 _cal_vcalendar_make_set_str(b, ";BYYEARDAY=");
1136 _cal_vcalendar_make_set_str(b, text);
1140 ret = calendar_record_get_str_p(record, _calendar_event.byweekno, &text);
1141 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1142 if (text && *text) {
1143 DBG("BYWEEKNO= [%s]", text);
1144 _cal_vcalendar_make_set_str(b, ";BYWEEKNO=");
1145 _cal_vcalendar_make_set_str(b, text);
1149 ret = calendar_record_get_str_p(record, _calendar_event.bymonth, &text);
1150 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1151 if (text && *text) {
1152 DBG("BYMONTH= [%s]", text);
1153 _cal_vcalendar_make_set_str(b, ";BYMONTH=");
1154 _cal_vcalendar_make_set_str(b, text);
1158 ret = calendar_record_get_str_p(record, _calendar_event.bysetpos, &text);
1159 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1160 if (text && *text) {
1161 DBG("BYSETPOS= [%s]", text);
1162 _cal_vcalendar_make_set_str(b, ";BYSETPOS=");
1163 _cal_vcalendar_make_set_str(b, text);
1168 ret = calendar_record_get_int(record, _calendar_event.wkst, &wkst);
1169 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1170 if (CALENDAR_SUNDAY <= wkst && wkst <= CALENDAR_SATURDAY) {
1171 _cal_vcalendar_make_set_str(b, ";WKST=");
1173 case CALENDAR_SUNDAY:
1174 _cal_vcalendar_make_set_str(b, "SU");
1176 case CALENDAR_MONDAY:
1177 _cal_vcalendar_make_set_str(b, "MO");
1179 case CALENDAR_TUESDAY:
1180 _cal_vcalendar_make_set_str(b, "TU");
1182 case CALENDAR_WEDNESDAY:
1183 _cal_vcalendar_make_set_str(b, "WE");
1185 case CALENDAR_THURSDAY:
1186 _cal_vcalendar_make_set_str(b, "TH");
1188 case CALENDAR_FRIDAY:
1189 _cal_vcalendar_make_set_str(b, "FR");
1191 case CALENDAR_SATURDAY:
1192 _cal_vcalendar_make_set_str(b, "SA");
1199 ret = calendar_record_get_int(record, _calendar_event.range_type, &range_type);
1200 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1201 switch (range_type) {
1202 case CALENDAR_RANGE_COUNT:
1203 ret = calendar_record_get_int(record, _calendar_event.count, &count);
1204 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1205 snprintf(tmp, sizeof(tmp), ";COUNT=%d", count);
1206 _cal_vcalendar_make_set_str(b, tmp);
1207 DBG("count [%s]", tmp);
1210 case CALENDAR_RANGE_UNTIL:
1211 ret = calendar_record_get_caltime(record, _calendar_event.until_time, &caltime);
1212 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_caltime() Fail(%d)", ret);
1214 if (caltime.type == CALENDAR_TIME_UTIME) {
1215 char *tmp_tzid = NULL;
1216 tmp_tzid = cal_time_convert_ltos(NULL, caltime.time.utime, 0);
1218 snprintf(tmp, sizeof(tmp), ";UNTIL=%s", tmp_tzid);
1222 snprintf(tmp, sizeof(tmp), ";UNTIL="CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ,
1223 caltime.time.date.year,
1224 caltime.time.date.month,
1225 caltime.time.date.mday,
1226 caltime.time.date.hour,
1227 caltime.time.date.minute,
1228 caltime.time.date.second);
1230 _cal_vcalendar_make_set_str(b, tmp);
1231 DBG("until [%s]", tmp);
1234 case CALENDAR_RANGE_NONE:
1238 _cal_vcalendar_make_flush(b);
1241 static void __make_rrule(cal_make_s *b, calendar_record_h record)
1244 RET_IF(NULL == record);
1247 case CALENDAR_BOOK_TYPE_EVENT:
1248 switch (b->version) {
1250 __make_rrule_ver1(b, record);
1253 __make_rrule_ver2(b, record);
1257 case CALENDAR_BOOK_TYPE_TODO:
1258 /* LCOV_EXCL_START */
1259 ERR("No rrule in todo");
1261 /* LCOV_EXCL_STOP */
1265 int _cal_vcalendar_make_attendee(cal_make_s *b, calendar_record_h attendee)
1269 RETV_IF(NULL == attendee, CALENDAR_ERROR_INVALID_PARAMETER);
1271 ret = _cal_vcalendar_make_set_str(b, "ATTENDEE");
1272 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1275 ret = calendar_record_get_int(attendee, _calendar_attendee.cutype, &cutype);
1276 ret = _cal_vcalendar_make_set_str(b, ";CUTYPE=");
1278 case CALENDAR_ATTENDEE_CUTYPE_INDIVIDUAL:
1279 ret = _cal_vcalendar_make_set_str(b, "INDIVIDUAL");
1281 case CALENDAR_ATTENDEE_CUTYPE_GROUP:
1282 ret = _cal_vcalendar_make_set_str(b, "GROUP");
1284 case CALENDAR_ATTENDEE_CUTYPE_RESOURCE:
1285 ret = _cal_vcalendar_make_set_str(b, "RESOURCE");
1287 case CALENDAR_ATTENDEE_CUTYPE_ROOM:
1288 ret = _cal_vcalendar_make_set_str(b, "ROOM");
1290 case CALENDAR_ATTENDEE_CUTYPE_UNKNOWN:
1291 ret = _cal_vcalendar_make_set_str(b, "UNKNOWN");
1294 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1296 char *member = NULL;
1297 ret = calendar_record_get_str_p(attendee, _calendar_attendee.member, &member);
1298 if (member && *member) {
1299 ret = _cal_vcalendar_make_set_str(b, ";MEMBER=");
1300 ret = _cal_vcalendar_make_set_str(b, member);
1301 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1305 ret = calendar_record_get_int(attendee, _calendar_attendee.role, &role);
1307 ret = _cal_vcalendar_make_set_str(b, ";ROLE=");
1308 ret = _cal_vcalendar_make_set_str(b, _att_role[role]);
1309 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1313 ret = calendar_record_get_int(attendee, _calendar_attendee.status, &status);
1315 ret = _cal_vcalendar_make_set_str(b, ";PARTSTAT=");
1316 ret = _cal_vcalendar_make_set_str(b, _att_st[status]);
1317 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1321 ret = calendar_record_get_int(attendee, _calendar_attendee.rsvp, &rsvp);
1323 ret = _cal_vcalendar_make_set_str(b, ";RSVP=");
1324 ret = _cal_vcalendar_make_set_str(b, rsvp ? "TRUE" : "FALSE");
1325 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1328 char *delegatee_uri = NULL;
1329 ret = calendar_record_get_str_p(attendee, _calendar_attendee.delegatee_uri, &delegatee_uri);
1330 if (delegatee_uri && *delegatee_uri) {
1331 ret = _cal_vcalendar_make_set_str(b, ";DELEGATED-TO=");
1332 ret = _cal_vcalendar_make_set_str(b, delegatee_uri);
1333 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1336 char *delegator_uri = NULL;
1337 ret = calendar_record_get_str_p(attendee, _calendar_attendee.delegator_uri, &delegator_uri);
1338 if (delegator_uri && *delegator_uri) {
1339 ret = _cal_vcalendar_make_set_str(b, ";DELEGATED-FROM=");
1340 ret = _cal_vcalendar_make_set_str(b, delegator_uri);
1341 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1344 /* TODO : No 'sentby' member in cal_participant_info_t */
1347 ret = calendar_record_get_str_p(attendee, _calendar_attendee.name, &name);
1348 if (name && *name) {
1349 ret = _cal_vcalendar_make_set_str(b, ";CN=");
1350 ret = _cal_vcalendar_make_set_str(b, name);
1351 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1355 ret = calendar_record_get_str_p(attendee, _calendar_attendee.email, &email);
1356 if (email && *email) {
1357 ret = _cal_vcalendar_make_set_str(b, ":mailto:");
1358 ret = _cal_vcalendar_make_set_str(b, email);
1359 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1362 _cal_vcalendar_make_flush(b);
1363 return CALENDAR_ERROR_NONE;
1366 static void __make_attendee(cal_make_s *b, calendar_record_h record)
1369 RET_IF(NULL == record);
1372 unsigned int count = 0;
1375 case CALENDAR_BOOK_TYPE_EVENT:
1376 ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_attendee, &count);
1377 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1378 for (i = 0; i < count; i++) {
1379 calendar_record_h child = NULL;
1380 ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_attendee, i, &child);
1381 ret = _cal_vcalendar_make_attendee(b, child);
1384 case CALENDAR_BOOK_TYPE_TODO:
1385 ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_attendee, &count);
1386 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1387 for (i = 0; i < count; i++) {
1388 calendar_record_h child = NULL;
1389 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_attendee, i, &child);
1390 ret = _cal_vcalendar_make_attendee(b, child);
1396 static void __make_alarm_ver1(cal_make_s *b, calendar_record_h record)
1398 /* In ver 1.0, only first alarm will be dealt with. */
1400 RET_IF(NULL == record);
1403 unsigned int count = 0;
1406 case CALENDAR_BOOK_TYPE_EVENT:
1407 ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, &count);
1408 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1409 for (i = 0; i < count; i++) {
1410 calendar_record_h child = NULL;
1411 ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, i, &child);
1412 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1414 _cal_vcalendar_make_aalarm(b, record, child);
1417 case CALENDAR_BOOK_TYPE_TODO:
1418 ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, &count);
1419 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1420 for (i = 0; i < count; i++) {
1421 calendar_record_h child = NULL;
1422 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, i, &child);
1423 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1425 _cal_vcalendar_make_aalarm(b, record, child);
1431 static void __make_alarm_ver2(cal_make_s *b, calendar_record_h record)
1434 RET_IF(NULL == record);
1437 unsigned int count = 0;
1440 case CALENDAR_BOOK_TYPE_EVENT:
1441 ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, &count);
1442 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1443 for (i = 0; i < count; i++) {
1444 calendar_record_h child = NULL;
1445 ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, i, &child);
1446 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1448 _cal_vcalendar_make_alarm(b, child);
1451 case CALENDAR_BOOK_TYPE_TODO:
1452 ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, &count);
1453 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1454 for (i = 0; i < count; i++) {
1455 calendar_record_h child = NULL;
1456 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, i, &child);
1457 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1459 _cal_vcalendar_make_alarm(b, child);
1465 static void __make_alarm(cal_make_s *b, calendar_record_h record)
1468 RET_IF(NULL == record);
1471 case CALENDAR_BOOK_TYPE_EVENT:
1472 switch (b->version) {
1474 __make_alarm_ver1(b, record);
1477 __make_alarm_ver2(b, record);
1481 case CALENDAR_BOOK_TYPE_TODO:
1482 /* LCOV_EXCL_START */
1483 ERR("No rrule in todo");
1485 /* LCOV_EXCL_STOP */
1489 static void __make_created_time(cal_make_s *b, calendar_record_h record)
1492 RET_IF(NULL == record);
1495 long long int value = 0;
1497 case CALENDAR_BOOK_TYPE_EVENT:
1498 ret = calendar_record_get_lli(record, _calendar_event.created_time, &value);
1499 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
1501 case CALENDAR_BOOK_TYPE_TODO:
1502 ret = calendar_record_get_lli(record, _calendar_todo.created_time, &value);
1503 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
1506 int y = 0, m = 0, d = 0;
1507 int h = 0, n = 0, s = 0;
1508 cal_time_get_local_datetime(NULL, value, &y, &m, &d, &h, &n, &s);
1509 char buf[CAL_STR_MIDDLE_LEN] = {0};
1510 snprintf(buf, sizeof(buf), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
1512 switch (b->version) {
1514 _cal_vcalendar_make_printf(b, "DCREATED:", buf);
1517 _cal_vcalendar_make_printf(b, "CREATED:", buf);
1522 static void __make_summary(cal_make_s *b, calendar_record_h record)
1525 RET_IF(NULL == record);
1530 case CALENDAR_BOOK_TYPE_EVENT:
1531 ret = calendar_record_get_str_p(record, _calendar_event.summary, &value);
1532 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1534 case CALENDAR_BOOK_TYPE_TODO:
1535 ret = calendar_record_get_str_p(record, _calendar_todo.summary, &value);
1536 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1539 if (value && *value) {
1540 char *summary = NULL;
1541 __encode_escaped_char(value, &summary);
1542 _cal_vcalendar_make_printf(b, "SUMMARY:", summary);
1547 static void __make_description(cal_make_s *b, calendar_record_h record)
1550 RET_IF(NULL == record);
1555 case CALENDAR_BOOK_TYPE_EVENT:
1556 ret = calendar_record_get_str_p(record, _calendar_event.description, &value);
1557 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1559 case CALENDAR_BOOK_TYPE_TODO:
1560 ret = calendar_record_get_str_p(record, _calendar_todo.description, &value);
1561 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1564 if (value && *value) {
1565 char *description = NULL;
1566 __encode_escaped_char(value, &description);
1567 _cal_vcalendar_make_printf(b, "DESCRIPTION:", description);
1572 static void __make_location(cal_make_s *b, calendar_record_h record)
1575 RET_IF(NULL == record);
1580 case CALENDAR_BOOK_TYPE_EVENT:
1581 ret = calendar_record_get_str_p(record, _calendar_event.location, &value);
1582 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1584 case CALENDAR_BOOK_TYPE_TODO:
1585 ret = calendar_record_get_str_p(record, _calendar_todo.location, &value);
1586 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1589 if (value && *value) {
1590 char *location = NULL;
1591 __encode_escaped_char(value, &location);
1592 _cal_vcalendar_make_printf(b, "LOCATION:", location);
1597 static void __make_organizer(cal_make_s *b, calendar_record_h record)
1600 RET_IF(NULL == record);
1602 /* Invalid component in ver 1 */
1603 if (VCAL_VER_1 == b->version)
1610 case CALENDAR_BOOK_TYPE_EVENT:
1611 ret = calendar_record_get_str_p(record, _calendar_event.organizer_name, &name);
1612 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1613 ret = calendar_record_get_str_p(record, _calendar_event.organizer_email, &email);
1614 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1616 case CALENDAR_BOOK_TYPE_TODO:
1617 ret = calendar_record_get_str_p(record, _calendar_todo.organizer_name, &name);
1618 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1619 ret = calendar_record_get_str_p(record, _calendar_todo.organizer_email, &email);
1620 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1623 if ((NULL == name || '\0' == *name) && (NULL == email || '\0' == *email))
1626 char buf[CAL_STR_MIDDLE_LEN] = {0};
1627 snprintf(buf, sizeof(buf), "ORGANIZER%s%s%s%s",
1628 (name && *name) ? ";CN=" : "",
1629 (name && *name) ? name : "",
1630 (email && *email) ? ":MAILTO:" : "",
1631 (email && *email) ? email : "");
1633 _cal_vcalendar_make_printf(b, buf, NULL);
1636 static void __make_last_modified(cal_make_s *b, calendar_record_h record)
1639 RET_IF(NULL == record);
1641 /* kies want to skip */
1642 if (VCAL_VER_1 == b->version) {
1643 DBG("skip in ver1.0");
1648 long long int value = 0;
1650 case CALENDAR_BOOK_TYPE_EVENT:
1651 ret = calendar_record_get_lli(record, _calendar_event.last_modified_time, &value);
1652 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
1654 case CALENDAR_BOOK_TYPE_TODO:
1655 ret = calendar_record_get_lli(record, _calendar_todo.last_modified_time, &value);
1656 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
1660 int y = 0, m = 0, d = 0;
1661 int h = 0, n = 0, s = 0;
1662 cal_time_get_local_datetime(NULL, value, &y, &m, &d, &h, &n, &s);
1664 char buf[CAL_STR_MIDDLE_LEN] = {0};
1665 snprintf(buf, sizeof(buf), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
1666 _cal_vcalendar_make_printf(b, "LAST-MODIFIED:", buf);
1669 static void __make_status(cal_make_s *b, calendar_record_h record)
1672 RET_IF(NULL == record);
1676 char *status = NULL;
1678 case CALENDAR_BOOK_TYPE_EVENT:
1679 ret = calendar_record_get_int(record, _calendar_event.event_status, &value);
1680 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1682 case CALENDAR_EVENT_STATUS_NONE:
1685 case CALENDAR_EVENT_STATUS_TENTATIVE:
1686 status = "TENTATIVE";
1688 case CALENDAR_EVENT_STATUS_CONFIRMED:
1689 status = "CONFIRMED";
1691 case CALENDAR_EVENT_STATUS_CANCELLED:
1692 status = "CANCELLED";
1696 case CALENDAR_BOOK_TYPE_TODO:
1697 ret = calendar_record_get_int(record, _calendar_todo.todo_status, &value);
1698 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1700 case CALENDAR_TODO_STATUS_NONE:
1703 case CALENDAR_TODO_STATUS_NEEDS_ACTION:
1704 status = (VCAL_VER_1 == b->version) ? "NEEDS ACTION" : "NEEDS-ACTION";
1706 case CALENDAR_TODO_STATUS_COMPLETED:
1707 status = "COMPLETED";
1709 case CALENDAR_TODO_STATUS_IN_PROCESS:
1710 status = (VCAL_VER_1 == b->version) ? NULL : "IN-PROCESS";
1712 case CALENDAR_TODO_STATUS_CANCELED:
1713 status = (VCAL_VER_1 == b->version) ? NULL : "CANCELLED";
1718 if (status && *status)
1719 _cal_vcalendar_make_printf(b, "STATUS:", status);
1722 static void __make_completed(cal_make_s *b, calendar_record_h record)
1725 RET_IF(NULL == record);
1727 /* Invalid component in event */
1728 if (CALENDAR_BOOK_TYPE_EVENT == b->type)
1732 long long int value = 0;
1733 ret = calendar_record_get_lli(record, _calendar_todo.completed_time, &value);
1734 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1736 int y = 0, m = 0, d = 0;
1737 int h = 0, n = 0, s = 0;
1738 cal_time_get_local_datetime(NULL, value, &y, &m, &d, &h, &n, &s);
1739 char buf[CAL_STR_MIDDLE_LEN] = {0};
1740 snprintf(buf, sizeof(buf), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
1741 _cal_vcalendar_make_printf(b, "COMPLETED", buf);
1744 static void __make_priority(cal_make_s *b, calendar_record_h record)
1747 RET_IF(NULL == record);
1752 case CALENDAR_BOOK_TYPE_EVENT:
1753 ret = calendar_record_get_int(record, _calendar_event.priority, &value);
1754 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1756 case CALENDAR_BOOK_TYPE_TODO:
1757 ret = calendar_record_get_int(record, _calendar_todo.priority, &value);
1758 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1762 switch (b->version) {
1765 case CALENDAR_EVENT_PRIORITY_HIGH:
1768 case CALENDAR_EVENT_PRIORITY_NORMAL:
1771 case CALENDAR_EVENT_PRIORITY_LOW:
1781 case CALENDAR_EVENT_PRIORITY_HIGH:
1782 /* in version 2.0, one out of 1 ~ 4 */
1785 case CALENDAR_EVENT_PRIORITY_NORMAL:
1788 case CALENDAR_EVENT_PRIORITY_LOW:
1789 /* in version 2, one out of 6 ~ 9. */
1798 char buf[CAL_STR_MIDDLE_LEN] = {0};
1799 snprintf(buf, sizeof(buf), "PRIORITY:%d", priority);
1800 _cal_vcalendar_make_printf(b, buf, NULL);
1803 static void __make_dtstamp(cal_make_s *b, calendar_record_h record)
1806 RET_IF(NULL == record);
1808 /* Not support in ver 1 */
1809 if (VCAL_VER_1 == b->version)
1812 long long int t = cal_time_get_now();
1813 int y = 0, m = 0, d = 0;
1814 int h = 0, n = 0, s = 0;
1815 cal_time_get_local_datetime(NULL, t, &y, &m, &d, &h, &n, &s);
1816 char buf[CAL_STR_MIDDLE_LEN] = {0};
1817 snprintf(buf, sizeof(buf), CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, y, m, d, h, n, s);
1818 _cal_vcalendar_make_printf(b, "DTSTAMP:", buf);
1821 static void __make_categories(cal_make_s *b, calendar_record_h record)
1824 RET_IF(NULL == record);
1829 case CALENDAR_BOOK_TYPE_EVENT:
1830 ret = calendar_record_get_str_p(record, _calendar_event.categories, &value);
1831 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1833 case CALENDAR_BOOK_TYPE_TODO:
1834 ret = calendar_record_get_str_p(record, _calendar_todo.categories, &value);
1835 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1838 if (value && *value)
1839 _cal_vcalendar_make_printf(b, "CATEGORIES:", value);
1842 static void __make_exdate(cal_make_s *b, calendar_record_h record)
1845 RET_IF(NULL == record);
1850 case CALENDAR_BOOK_TYPE_EVENT:
1851 ret = calendar_record_get_str_p(record, _calendar_event.exdate, &value);
1852 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1854 case CALENDAR_BOOK_TYPE_TODO:
1855 /* LCOV_EXCL_START */
1856 ERR("Not support exdate in TODO");
1858 /* LCOV_EXCL_STOP */
1860 if (value && *value)
1861 _cal_vcalendar_make_printf(b, "EXDATE:", value);
1864 static void _cal_vcalendar_make_child_extended(cal_make_s *b, calendar_record_h child, bool *has_lunar)
1867 RET_IF(NULL == child);
1873 ret = calendar_record_get_str_p(child, _calendar_extended_property.key, &key);
1874 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1875 if (NULL == key || '\0' == *key || (0 != strncmp(key, "X-", strlen("X-")))) {
1876 DBG("Not extended for vcalendar[%s]", key);
1880 ret = calendar_record_get_str_p(child, _calendar_extended_property.value, &value);
1881 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
1883 /* check lunar: will handle next */
1885 if ((CAL_STRING_EQUAL == strncmp(key, "X-LUNAR", strlen("X-LUNAR")) && !strncmp(value, ":SET", strlen(":SET"))) ||
1886 (CAL_STRING_EQUAL == strncmp(key, "X-LUNAR:", strlen("X-LUNAR:")) && !strncmp(value, "SET", strlen("SET")))) {
1892 ret = _cal_vcalendar_make_printf(b, key, value);
1893 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1896 static void __make_extended(cal_make_s *b, calendar_record_h record)
1899 RET_IF(NULL == record);
1902 unsigned int count = 0;
1904 bool has_lunar = false;
1905 int calendar_system_type = 0;
1907 case CALENDAR_BOOK_TYPE_EVENT:
1908 ret = calendar_record_get_child_record_count(record, _calendar_event.extended, &count);
1909 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1910 for (i = 0; i < count; i++) {
1911 calendar_record_h child = NULL;
1912 ret = calendar_record_get_child_record_at_p(record, _calendar_event.extended, i, &child);
1913 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1915 _cal_vcalendar_make_child_extended(b, child, &has_lunar);
1919 ret = calendar_record_get_int(record, _calendar_event.calendar_system_type, &calendar_system_type);
1920 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_int() Fail(%d)", ret);
1922 if (true == has_lunar || CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR == calendar_system_type)
1923 _cal_vcalendar_make_printf(b, "X-LUNAR:SET", NULL);
1925 case CALENDAR_BOOK_TYPE_TODO:
1926 ret = calendar_record_get_child_record_count(record, _calendar_todo.extended, &count);
1927 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_count() Fail(%d)", ret);
1928 for (i = 0; i < count; i++) {
1929 calendar_record_h child = NULL;
1930 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.extended, i, &child);
1931 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_child_record_at_p() Fail(%d)", ret);
1933 _cal_vcalendar_make_child_extended(b, child, NULL);
1939 static void __make_end(cal_make_s *b, calendar_record_h record)
1942 RET_IF(NULL == record);
1946 case CALENDAR_BOOK_TYPE_EVENT:
1947 ret = _cal_vcalendar_make_printf(b, "END:VEVENT", NULL);
1948 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1950 case CALENDAR_BOOK_TYPE_TODO:
1951 ret = _cal_vcalendar_make_printf(b, "END:VTODO", NULL);
1952 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1957 static void _cal_vcalendar_make_schedule(cal_make_s *b, calendar_record_h record)
1960 RET_IF(NULL == record);
1962 __make_begin(b, record);
1963 __make_summary(b, record);
1964 __make_dtstart(b, record);
1965 __make_dtend(b, record);
1966 __make_rrule(b, record); /* only event */
1967 __make_sensitivity(b, record);
1968 __make_created_time(b, record);
1969 __make_description(b, record);
1970 __make_location(b, record);
1971 __make_organizer(b, record);
1972 __make_last_modified(b, record);
1973 __make_status(b, record);
1974 __make_completed(b, record); /* only todo */
1975 __make_priority(b, record);
1976 __make_dtstamp(b, record);
1977 __make_categories(b, record);
1978 __make_exdate(b, record); /* only event */
1979 __make_attendee(b, record);
1980 __make_alarm(b, record);
1981 __make_extended(b, record);
1982 __make_end(b, record);
1986 static void __append_header(cal_make_s *b)
1992 ret = _cal_vcalendar_make_printf(b, "BEGIN:VCALENDAR", NULL);
1993 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1995 ret = _cal_vcalendar_make_printf(b, "PRODID:vCal ID Default", NULL);
1996 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
1998 char buf[CAL_STR_SHORT_LEN32] = {0};
1999 snprintf(buf, sizeof(buf), "VERSION:%d.0", b->version);
2000 ret = _cal_vcalendar_make_printf(b, buf, NULL);
2001 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
2004 static void __make_footer(cal_make_s *b)
2009 ret = _cal_vcalendar_make_printf(b, "END:VCALENDAR", NULL);
2010 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail(%d)", ret);
2013 static void __make_tz(cal_make_s *b, char *tzid, long long int created)
2018 RET_IF(NULL == tzid);
2019 RET_IF('\0' == *tzid);
2023 cal_time_get_tz_offset(tzid, &zone, &dst);
2024 DBG("offset zone(%ld), dst (%ld)", zone, dst);
2026 bool in_dst = cal_time_in_dst(tzid, created);
2027 dst = in_dst ? dst : 0; /* dst in TZ is depending on created time */
2028 DBG("tzid[%s] created time(%lld) in_dst(%d)", tzid, created, in_dst);
2030 int h = (zone / 3600) + (dst / 3600);
2031 int m = (zone % 3600) / 60 + (dst % 3600) / 60;
2033 char buf[CAL_STR_SHORT_LEN32] = {0};
2034 snprintf(buf, sizeof(buf), "TZ:%s%02d:%02d",
2035 h == 0 ? "" : (h < 0 ? "-" : "+"),
2036 h < 0 ? (-1 * h) : h, m < 0 ? (-1 * m) : m);
2038 ret = _cal_vcalendar_make_printf(b, buf, NULL);
2039 RETM_IF(CALENDAR_ERROR_NONE != ret, "_cal_vcalendar_make_printf() Fail");
2040 DBG("append tzid[%s]", buf);
2043 static void __devide_vcalendar_with_header(cal_make_s *b, calendar_record_h record)
2046 RET_IF(NULL == record);
2048 if (2 == b->version)
2053 ret = calendar_record_get_uri_p(record, &uri);
2054 RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_uri_p() Fail(%d)", ret);
2057 long long int created = 0;
2060 case CALENDAR_BOOK_TYPE_EVENT:
2061 ret = calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
2062 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
2063 ret = calendar_record_get_lli(record, _calendar_event.created_time, &created);
2064 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
2066 case CALENDAR_BOOK_TYPE_TODO:
2067 ret = calendar_record_get_str_p(record, _calendar_todo.due_tzid, &tzid);
2068 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_str_p() Fail(%d)", ret);
2069 ret = calendar_record_get_lli(record, _calendar_todo.created_time, &created);
2070 WARN_IF(CALENDAR_ERROR_NONE != ret, "calendar_record_get_lli() Fail(%d)", ret);
2074 if (NULL == tzid || '\0' == *tzid) {
2079 if (NULL == b->timezone_tzid || '\0' == *b->timezone_tzid) {
2080 /* new start of vcalendar */
2081 __make_tz(b, tzid, created);
2082 b->timezone_tzid = strdup(tzid);
2084 /* not first vcalendar */
2085 if (0 != strncmp(b->timezone_tzid, tzid, strlen(tzid))) {
2086 /* different tzid */
2089 __make_tz(b, tzid, created);
2090 if (b->timezone_tzid)
2091 free(b->timezone_tzid);
2092 b->timezone_tzid = strdup(tzid);
2094 DBG("same as before, skip");
2098 static int __make_vcalendar(cal_make_s *b, calendar_list_h list)
2100 RETV_IF(NULL == b, CALENDAR_ERROR_INVALID_PARAMETER);
2101 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
2103 bool valid_count = 0;
2104 int ret = CALENDAR_ERROR_NONE;
2105 calendar_record_h record = NULL;
2109 ret = calendar_list_first(list);
2110 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_first() Fail");
2112 ret = calendar_list_get_current_record_p(list, &record);
2113 if (CALENDAR_ERROR_NONE != ret) break;
2116 ret = calendar_record_get_uri_p(record, &uri);
2117 DBG("uri[%s]", uri);
2119 if (CAL_STRING_EQUAL == strcmp(uri, _calendar_event._uri)) {
2121 b->type = CALENDAR_BOOK_TYPE_EVENT;
2122 __devide_vcalendar_with_header(b, record);
2123 _cal_vcalendar_make_schedule(b, record);
2125 } else if (CAL_STRING_EQUAL == strcmp(uri, _calendar_todo._uri)) {
2127 b->type = CALENDAR_BOOK_TYPE_TODO;
2128 __devide_vcalendar_with_header(b, record);
2129 _cal_vcalendar_make_schedule(b, record);
2131 } else if (CAL_STRING_EQUAL == strcmp(uri, _calendar_extended_property._uri)) {
2132 cal_extended_s *extended = (cal_extended_s *)record;
2133 if (CAL_STRING_EQUAL == strncmp(extended->key, "VERSION", strlen("VERSION"))) continue;
2135 ret = _cal_vcalendar_make_printf(b, extended->key, extended->value);
2136 if (CALENDAR_ERROR_NONE != ret) break;
2138 DBG("extended key[%s] value[%s]", extended->key, extended->value);
2140 } else if (CAL_STRING_EQUAL == strcmp(uri, _calendar_timezone._uri)) {
2141 DBG("Not support timezone");
2143 } else if (CAL_STRING_EQUAL == strcmp(uri, _calendar_book._uri)) {
2144 DBG("Not support calendar");
2147 DBG("Unable to understand uri[%s]", uri);
2150 } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
2152 if (0 == valid_count) {
2153 DBG("There is no valid records");
2154 return CALENDAR_ERROR_INVALID_PARAMETER;
2159 return CALENDAR_ERROR_NONE;
2162 int cal_vcalendar_make_vcalendar(cal_make_s *b, calendar_list_h list)
2164 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
2166 int ret = CALENDAR_ERROR_NONE;
2167 calendar_record_h record = NULL;
2169 int version = 2; /* set default as ver 2.0 */
2171 ret = calendar_list_first(list);
2172 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_first() Fail");
2174 ret = calendar_list_get_current_record_p(list, &record);
2175 if (CALENDAR_ERROR_NONE != ret) break;
2178 ret = calendar_record_get_uri_p(record, &uri);
2179 if (CALENDAR_ERROR_NONE != ret) break;
2181 if (CAL_STRING_EQUAL == strcmp(uri, _calendar_extended_property._uri)) {
2182 cal_extended_s *extended = (cal_extended_s *)record;
2183 if (CAL_STRING_EQUAL == strncmp(extended->key, "VERSION", strlen("VERSION"))) {
2184 version = strstr(extended->value, "1.0") ? 1 : 2;
2188 } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
2189 b->version = version;
2190 DBG("make as version(%d)", version);
2192 return __make_vcalendar(b, list);