52c56f0ccc60e31d1660e63abd55474f27ffe47b
[platform/core/system/sync-agent.git] / src / fw-plugins / common-public / vcalendar / src / vcalendar_string_util.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include "vcalendar_string_util.h"
19
20 #define DATE_TIME_LENGTH 16
21
22 #ifndef EXPORT_API
23 #define EXPORT_API __attribute__ ((visibility("default")))
24 #endif
25
26
27 #if 0
28 // usage / rrule converting
29 if (strstr(temp_agent_data, "\r\nRRULE:") != NULL) {
30         _DEBUG_INFO("rrule is founed");
31         temp_agent_data = _replace_rrule_data(temp_agent_data);
32 }
33
34 static char * _replace_rrule_data(char *origin)
35 {
36         _INNER_FUNC_ENTER;
37         retvm_if(origin == NULL, origin, "origin is NULL.");
38
39         char *str_new_rrule = NULL;
40         char *str_end_time = NULL;
41         char *freq_loc = NULL;
42         char *str_byday = NULL;
43         char *str_interval = NULL;
44         char *str_period_until = NULL;
45         char *str_period_count = NULL;
46         calendar_date_type_e cal_type = CALENDAR_DATE_TYPE_ONTIME;
47
48         if ((freq_loc = strstr(origin, RRULE_KEYWORD_FREQ_WEEKLY)) != NULL) {
49                 _DEBUG_INFO("this is weekly data");
50         }
51         else if ((freq_loc = strstr(origin, RRULE_KEYWORD_FREQ_MONTHLY)) != NULL) {
52                 _DEBUG_INFO("this is monthly data");
53         }
54         else if ((freq_loc = strstr(origin, RRULE_KEYWORD_FREQ_YEARLY)) != NULL) {
55                 _DEBUG_INFO("this is yearly data");
56         }
57         else if ((freq_loc = strstr(origin, RRULE_KEYWORD_FREQ_DAILY)) != NULL) {
58                 _DEBUG_INFO("this is daily data");
59         }
60         else {
61                 _DEBUG_ERROR("this is an undefined rrule type. origin = %s", origin);
62                 goto return_part;
63         }
64
65         char *temp_rrule = NULL;
66         if((temp_rrule = strstr(freq_loc, "RRULE:")) == NULL) {
67                 _DEBUG_ERROR("temp_rrule is NULL");
68                 goto return_part;
69         }
70
71         char *temp_rrule2 = NULL;
72         if((temp_rrule2 = strstr(temp_rrule, "\r\n")) == NULL) {
73                 _DEBUG_ERROR("temp_rrule2 is NULL");
74                 goto return_part;
75         }
76
77         char str_origin_rrule[100] = {0,};
78         int origin_rrule_length = strlen(temp_rrule) - strlen(temp_rrule2) + 2; // '2' means of '\r\n'
79         if (origin_rrule_length <= 0) {
80                 _DEBUG_ERROR("origin_rrule_length <= 0");
81                 goto return_part;
82         }
83
84         strncpy(str_origin_rrule, temp_rrule, origin_rrule_length);
85         _DEBUG_INFO("str_origin_rrule = %s", str_origin_rrule);
86
87         if (strstr(origin, RRULE_KEYWORD_FREQ_WEEKLY) != NULL) {
88                 str_byday = get_value_by_token(freq_loc, RRULE_KEYWORD_BYDAY, ";");
89                 cal_type = CALENDAR_DATE_TYPE_WEEK;
90         }
91         else if (strstr(origin, RRULE_KEYWORD_FREQ_MONTHLY) != NULL) {
92                 str_byday = get_value_by_token(freq_loc, RRULE_KEYWORD_BYMONTHDAY, ";");
93                 cal_type = CALENDAR_DATE_TYPE_MONTH;
94         }
95         else if (strstr(origin, RRULE_KEYWORD_FREQ_YEARLY) != NULL) {
96                 str_byday = get_value_by_token(freq_loc, RRULE_KEYWORD_BYMONTHDAY, ";");
97                 cal_type = CALENDAR_DATE_TYPE_YEAR;
98         }
99         else if (strstr(origin, RRULE_KEYWORD_FREQ_DAILY) != NULL) {
100                 cal_type = CALENDAR_DATE_TYPE_DAY;
101         }
102         else {
103                 _DEBUG_ERROR("this is an undefined rrule type. origin = %s", origin);
104                 goto return_part;
105         }
106
107         if ((cal_type != CALENDAR_DATE_TYPE_DAY) && (str_byday == NULL || strlen(str_byday) <= 0)) {
108                 _DEBUG_ERROR("str_byday is null");
109                 goto return_part;
110         }
111
112         str_interval = get_value_by_token(freq_loc, RRULE_KEYWORD_INTERVAL, ";");
113         str_period_until = get_value_by_token(freq_loc, RRULE_KEYWORD_UNTIL, ";");
114         str_period_count = get_value_by_token(freq_loc, RRULE_KEYWORD_COUNT, ";");
115
116         if (str_interval == NULL || strlen(str_interval) <= 0) {
117                 _DEBUG_ERROR("str_interval is null");
118                 goto return_part;
119         }
120
121         if (str_period_until == NULL && str_period_count == NULL) {
122                 str_end_time = (char *)calloc(2, sizeof(char));
123                 if (str_end_time == NULL) {
124                         _DEBUG_ERROR("str_end_time is null");
125                         goto return_part;
126                 }
127                 strncpy(str_end_time, "\r\n", 2);
128                 _DEBUG_INFO("endless = %s", str_end_time);
129         }
130         else if (str_period_until != NULL) {
131                 str_end_time = (char *)calloc(strlen(str_period_until), sizeof(char));
132                 if (str_end_time == NULL) {
133                         _DEBUG_ERROR("str_end_time is null");
134                         goto return_part;
135                 }
136                 strncpy(str_end_time, str_period_until, strlen(str_period_until));
137                 _DEBUG_INFO("until = %s", str_end_time);
138         }
139         else if (str_period_count != NULL) {
140                 str_end_time = (char *)calloc(strlen(str_period_count)+1, sizeof(char));
141                 if (str_end_time == NULL) {
142                         _DEBUG_ERROR("str_end_time is null");
143                         goto return_part;
144                 }
145                 snprintf(str_end_time, strlen(str_period_count)+1, "#%s", str_period_count);
146                 _DEBUG_INFO("count = %s", str_end_time);
147         }
148         else {
149                 _DEBUG_ERROR("there is an error");
150                 goto return_part;
151         }
152
153         int new_rrule_length = 0;
154         if (strstr(origin, RRULE_KEYWORD_FREQ_WEEKLY) != NULL) {
155                 new_rrule_length = strlen("RRULE:W") + strlen(str_interval) + strlen(" ") + strlen(str_byday) + strlen("  ") + strlen(str_end_time) + 1;
156         }
157         else if (strstr(origin, RRULE_KEYWORD_FREQ_MONTHLY) != NULL) {
158                 new_rrule_length = strlen("RRULE:MD") + strlen(str_interval) + strlen(" ") + strlen(str_byday) + strlen("  ") + strlen(str_end_time) + 1;
159         }
160         else if (strstr(origin, RRULE_KEYWORD_FREQ_YEARLY) != NULL) {
161                 new_rrule_length = strlen("RRULE:YD") + strlen(str_interval) + strlen(" ") + strlen(str_end_time) + 1;
162         }
163         else if (strstr(origin, RRULE_KEYWORD_FREQ_DAILY) != NULL) {
164                 new_rrule_length = strlen("RRULE:D") + strlen(str_interval) + strlen(" ") + strlen(str_end_time) + 1;
165         }
166         else {
167                 _DEBUG_ERROR("this is an undefined rrule type. origin = %s", origin);
168                 goto return_part;
169         }
170
171         if (new_rrule_length <= 0) {
172                 _DEBUG_ERROR("new_rrule_length(%d) <= 0", new_rrule_length);
173                 goto return_part;
174         }
175
176         str_new_rrule = (char *)calloc(new_rrule_length, sizeof(char));
177         if (str_new_rrule == NULL) {
178                 _DEBUG_ERROR("str_new_rrule calloc failed");
179                 goto return_part;
180         }
181
182         if (strstr(origin, RRULE_KEYWORD_FREQ_WEEKLY) != NULL) {
183                 snprintf(str_new_rrule, new_rrule_length, "RRULE:W%s %s  %s", str_interval, str_byday, str_end_time);
184         }
185         else if (strstr(origin, RRULE_KEYWORD_FREQ_MONTHLY) != NULL) {
186                 snprintf(str_new_rrule, new_rrule_length, "RRULE:MD%s %s  %s", str_interval, str_byday, str_end_time);
187         }
188         else if (strstr(origin, RRULE_KEYWORD_FREQ_YEARLY) != NULL) {
189                 snprintf(str_new_rrule, new_rrule_length, "RRULE:YD%s %s", str_interval, str_end_time);
190         }
191         else if (strstr(origin, RRULE_KEYWORD_FREQ_DAILY) != NULL) {
192                 snprintf(str_new_rrule, new_rrule_length, "RRULE:D%s %s", str_interval, str_end_time);
193         }
194         else {
195                 _DEBUG_ERROR("this is an undefined rrule type. origin = %s", origin);
196                 goto return_part;
197         }
198
199         _DEBUG_INFO("str_new_rrule = %s", str_new_rrule);
200         _DEBUG_INFO("str_origin_rrule = %s", str_origin_rrule);
201
202         char *new_agent_data = replace_string(origin, str_origin_rrule, str_new_rrule);
203         origin = NULL;
204         origin = new_agent_data;
205
206 return_part:
207
208         if (str_interval) {
209                 free(str_interval);
210                 str_interval = NULL;
211         }
212         if (str_byday) {
213                 free(str_byday);
214                 str_byday = NULL;
215         }
216         if (str_period_until) {
217                 free(str_period_until);
218                 str_period_until = NULL;
219         }
220         if (str_period_count) {
221                 free(str_period_count);
222                 str_period_count = NULL;
223         }
224         if (str_end_time) {
225                 free(str_end_time);
226                 str_end_time = NULL;
227         }
228         if (str_new_rrule) {
229                 free(str_new_rrule);
230                 str_new_rrule = NULL;
231         }
232
233         _DEBUG_INFO("origin = %s", origin);
234         _INNER_FUNC_EXIT;
235         return origin;
236 }
237
238 // usage / alarm converting
239 if (strstr(temp_agent_data, "\r\nBEGIN:VALARM") != NULL) {
240         _DEBUG_INFO("alarm is founed");
241         temp_agent_data = _replace_alarm_data(temp_agent_data);
242 }
243
244 static char * _replace_alarm_data(char *origin)
245 {
246         _INNER_FUNC_ENTER;
247         retvm_if(origin == NULL, origin, "origin is NULL.");
248
249         int interval = 0;
250         char *str_new_alarm = NULL;
251         char *freq_loc = NULL;
252         char *str_trigger = NULL;
253         char *str_customized_trigger = NULL;
254         char *str_interval = NULL;
255         calendar_date_type_e cal_type = CALENDAR_DATE_TYPE_ONTIME;
256
257         if ((freq_loc = strstr(origin, "\r\nBEGIN:VALARM")) == NULL) {
258                 _DEBUG_ERROR("there is not trigger data");
259                 goto return_part;
260         }
261
262         char *temp = NULL;
263         if((temp = strstr(freq_loc, "BEGIN:VALARM\r\n")) == NULL) {
264                 _DEBUG_ERROR("temp is NULL");
265                 goto return_part;
266         }
267
268         char *temp2 = NULL;
269         if((temp2 = strstr(temp, "END:VALARM\r\n")) == NULL) {
270                 _DEBUG_ERROR("temp2 is NULL");
271                 goto return_part;
272         }
273
274         char str_origin_alarm[100] = {0,};
275         int origin_alarm_length = strlen(temp) - strlen(temp2) + 12; // '12' means of "END:VALARM\r\n"
276         if (origin_alarm_length <= 0) {
277                 _DEBUG_ERROR("origin_alarm_length <= 0");
278                 goto return_part;
279         }
280
281         strncpy(str_origin_alarm, temp, origin_alarm_length);
282         _DEBUG_INFO("str_origin_alarm = %s", str_origin_alarm);
283
284         // case 1. "TRIGGER;VALUE=DATE-TIME:" is an alarm that created by user
285         str_customized_trigger = _get_value_by_token(freq_loc, "TRIGGER;VALUE=DATE-TIME:", "\r\n");
286         if (str_customized_trigger != NULL) {
287                 _DEBUG_INFO("str_customized_trigger is founded. str_customized_trigger = %s", str_customized_trigger);
288
289                 str_new_alarm = (char *)calloc(30, sizeof(char));
290                 if (str_new_alarm == NULL) {
291                         _DEBUG_ERROR("new_date_time is null");
292                         goto return_part;
293                 }
294
295                 snprintf(str_new_alarm, 30, "AALARM:%s\r\n", str_customized_trigger);
296                 _DEBUG_INFO("str_new_alarm = %s", str_new_alarm);
297                 char *new_agent_data = replace_string(origin, str_origin_alarm, str_new_alarm);
298                 origin = NULL;
299                 origin = new_agent_data;
300                 goto return_part;
301         }
302
303         // case 2. "TRIGGER:" is a normal alarm
304         str_trigger = _get_value_by_token(freq_loc, "TRIGGER:", "\r\n");
305         if (str_trigger == NULL || strlen(str_trigger) <= 0) {
306                 _DEBUG_ERROR("str_trigger is null");
307                 goto return_part;
308         }
309
310         char *temp_alarm = NULL;
311         if((temp_alarm = strstr(str_trigger, "P0W")) != NULL) {
312                 cal_type = CALENDAR_DATE_TYPE_ONTIME;
313                 interval = 0;
314         }
315         else if((temp_alarm = strstr(str_trigger, "PT")) != NULL) {
316                 if(strstr(temp_alarm, "H") != NULL) {
317                         cal_type = CALENDAR_DATE_TYPE_HOUR;
318                         str_interval = _get_value_by_token(str_trigger, "PT", "H");
319                         interval = atoi(str_interval);
320                 }
321                 else if(strstr(temp_alarm, "M") != NULL) {
322                         cal_type = CALENDAR_DATE_TYPE_MINUTE;
323                         str_interval = _get_value_by_token(str_trigger, "PT", "M");
324                         interval = atoi(str_interval);
325                 }
326                 else {
327                         _DEBUG_ERROR("wrong type, temp_alarm = %s", temp_alarm);
328                         goto return_part;
329                 }
330         }
331         else if((temp_alarm = strstr(str_trigger, "P")) != NULL) {
332                 if(strstr(temp_alarm, "D") != NULL) {
333                         cal_type = CALENDAR_DATE_TYPE_DAY;
334                         str_interval = _get_value_by_token(str_trigger, "P", "D");
335                         interval = atoi(str_interval);
336                 }
337                 else if(strstr(temp_alarm, "W") != NULL) {
338                         cal_type = CALENDAR_DATE_TYPE_WEEK;
339                         str_interval = _get_value_by_token(str_trigger, "P", "W");
340                         interval = atoi(str_interval);
341                 }
342                 else {
343                         _DEBUG_ERROR("wrong type, temp_alarm = %s", temp_alarm);
344                         goto return_part;
345                 }
346         }
347         else {
348                 _DEBUG_ERROR("wrong type, temp_alarm = %s", temp_alarm);
349                 goto return_part;
350         }
351
352         str_new_alarm = _calculate_date_time(origin, interval, cal_type);
353         if (str_new_alarm == NULL || strlen(str_new_alarm) <= 0) {
354                 _DEBUG_ERROR("str_new_alarm is null");
355                 goto return_part;
356         }
357
358         _DEBUG_INFO("str_new_alarm = %s", str_new_alarm);
359         _DEBUG_INFO("str_origin_alarm = %s", str_origin_alarm);
360
361         char *new_agent_data = replace_string(origin, str_origin_alarm, str_new_alarm);
362         origin = NULL;
363         origin = new_agent_data;
364
365 return_part:
366
367         if (str_trigger) {
368                 free(str_trigger);
369                 str_trigger = NULL;
370         }
371         if (str_customized_trigger) {
372                 free(str_customized_trigger);
373                 str_customized_trigger = NULL;
374         }
375         if (str_new_alarm) {
376                 free(str_new_alarm);
377                 str_new_alarm = NULL;
378         }
379         if (str_interval) {
380                 free(str_interval);
381                 str_interval = NULL;
382         }
383
384         _INNER_FUNC_EXIT;
385         _DEBUG_INFO("origin = %s", origin);
386         return origin;
387 }
388
389
390 static char * _calculate_date_time(char *origin, int value, calendar_date_type_e type)
391 {
392         _INNER_FUNC_ENTER;
393         retvm_if(origin == NULL, NULL, "origin is NULL");
394
395         _DEBUG_INFO("origin = %s", origin);
396         _DEBUG_INFO("value = %d", value);
397
398         UCalendar *ucal = NULL;
399         char *start_time = NULL;
400         char *new_date_time = NULL;
401         char *start_date_loc = NULL;
402         if ((start_date_loc = strstr(origin, DTSTART_KEYWORD)) == NULL) {
403                 _DEBUG_ERROR("start_date_loc is null");
404                 goto return_part;
405         }
406
407         char str_year[5] = {0,};
408         char str_month[3] = {0,};
409         char str_date[3] = {0,};
410         char str_hour[3] = {0,};
411         char str_minute[3] = {0,};
412         char str_second[3] = {0,};
413
414         /* example) 20130124T000000Z\r\n = 2013 01 24 T 00 00 00 Z \r\n */
415         strncpy(str_year, start_date_loc + strlen(DTSTART_KEYWORD), 4);
416         strncpy(str_month, start_date_loc + strlen(DTSTART_KEYWORD) + 4, 2);
417         strncpy(str_date, start_date_loc + strlen(DTSTART_KEYWORD) + 4 + 2, 2);
418         strncpy(str_hour, start_date_loc + strlen(DTSTART_KEYWORD) + 4 + 2 + 2 + 1, 2);
419         strncpy(str_minute, start_date_loc + strlen(DTSTART_KEYWORD) + 4 + 2 + 2 + 1 + 2, 2);
420         strncpy(str_second, start_date_loc + strlen(DTSTART_KEYWORD) + 4 + 2 + 2 + 1 + 2 + 2, 2);
421
422         int year = atoi(str_year);
423         int month = atoi(str_month);
424         int date = atoi(str_date);
425         int hour = atoi(str_hour);
426         int minute = atoi(str_minute);
427         int second = atoi(str_second);
428         long long int date_time = 0;
429
430         start_time = (char *)calloc(20, sizeof(char));
431         if (start_time == NULL) {
432                 _DEBUG_ERROR("start_time is null");
433                 goto return_part;
434         }
435
436         snprintf(start_time, 20, "%04d%02d%02dT%02d%02d%02dZ\r\n", year, month, date, hour, minute, second);
437         _DEBUG_INFO("start_time = %s", start_time);
438
439         UErrorCode status = U_ZERO_ERROR;
440         ucal = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, &status);
441         if (U_FAILURE(status)) {
442                 _DEBUG_ERROR("ucal_open failed (%s)", u_errorName(status));
443                 goto return_part;
444         }
445
446         ucal_setAttribute(ucal, UCAL_LENIENT, 1);
447         ucal_setDateTime(ucal, year, month - 1, date, hour, minute, second, &status);
448         date_time = ucal_getMillis(ucal, &status);
449
450         switch (type) {
451         case CALENDAR_DATE_TYPE_ONTIME:
452                 _DEBUG_INFO("CALENDAR_DATE_TYPE_ONTIME");
453                 date_time = date_time / 1000;
454                 break;
455         case CALENDAR_DATE_TYPE_WEEK:
456                 _DEBUG_INFO("CALENDAR_DATE_TYPE_WEEK");
457                 date_time = date_time / 1000;
458                 date_time = date_time - (value*60*60*24*7);
459                 break;
460         case CALENDAR_DATE_TYPE_DAY:
461                 _DEBUG_INFO("CALENDAR_DATE_TYPE_DAY");
462                 date_time = date_time / 1000;
463                 date_time = date_time - (value*60*60*24);
464                 break;
465         case CALENDAR_DATE_TYPE_HOUR:
466                 _DEBUG_INFO("CALENDAR_DATE_TYPE_HOUR");
467                 date_time = date_time / 1000;
468                 date_time = date_time - (value*60*60);
469                 break;
470         case CALENDAR_DATE_TYPE_MINUTE:
471                 _DEBUG_INFO("CALENDAR_DATE_TYPE_MINUTE");
472                 date_time = date_time / 1000;
473                 date_time = date_time - (value*60);
474                 break;
475         default:
476                 _DEBUG_ERROR("%d is not supported type", type);
477                 goto return_part;
478                 break;
479         }
480
481         if (U_FAILURE(status)) {
482                 _DEBUG_ERROR("ucal_setDateTime failed (%s)", u_errorName(status));
483                 goto return_part;
484         }
485
486         ucal_setMillis(ucal, (date_time * 1000), &status);
487
488         year = month = date = hour = minute = second = 0;
489         year = ucal_get(ucal, UCAL_YEAR, &status);
490         month = ucal_get(ucal, UCAL_MONTH, &status) + 1;
491         date = ucal_get(ucal, UCAL_DATE, &status);
492         hour = ucal_get(ucal, UCAL_HOUR_OF_DAY, &status);
493         minute = ucal_get(ucal, UCAL_MINUTE, &status);
494         second = ucal_get(ucal, UCAL_SECOND, &status);
495
496         new_date_time = (char *)calloc(30, sizeof(char));
497         if (new_date_time == NULL) {
498                 _DEBUG_ERROR("new_date_time is null");
499                 goto return_part;
500         }
501
502         snprintf(new_date_time, 30, "AALARM:%04d%02d%02dT%02d%02d%02dZ\r\n", year, month, date, hour, minute, second);
503         _DEBUG_INFO("new_date_time = %s", new_date_time);
504
505 return_part:
506         _DEBUG_INFO("return_part");
507
508         if(start_time) {
509                 free(start_time);
510                 start_time = NULL;
511         }
512         if(ucal) {
513                 ucal_close(ucal);
514                 ucal = NULL;
515         }
516
517         _INNER_FUNC_EXIT;
518         return new_date_time;
519 }
520
521 #endif
522
523 char * get_value_by_token(const char *src, const char *token, const char *end_of_token)
524 {
525         _INNER_FUNC_ENTER;
526         if (src == NULL || strlen(src) <= 0) {
527                 _DEBUG_ERROR("src is null");
528                 return NULL;
529         }
530
531         char *token_loc = NULL;
532         char *str_output = NULL;
533
534         if ((token_loc = strstr(src, token)) != NULL) {
535                 char *str_temp = strstr(token_loc, end_of_token);
536                 if (str_temp != NULL) {
537                         int ret_str_length = strlen(token_loc) - strlen(token) - strlen(str_temp);
538                         if (ret_str_length <= 0) {
539                                 _DEBUG_ERROR("token_loc = %s", token_loc);
540                                 _DEBUG_ERROR("token = %s", token);
541                                 _DEBUG_ERROR("str_temp = %s", str_temp);
542                                 _DEBUG_ERROR("ret_str_length(%d) <= 0", ret_str_length);
543                                 goto return_part;
544                         }
545                         str_output = (char *)calloc(ret_str_length, sizeof(char));
546                         goto_if(str_output == NULL, "str_output is NULL");
547
548                         memcpy(str_output, token_loc + strlen(token), ret_str_length);
549                 }
550         }
551
552 return_part:
553         _INNER_FUNC_EXIT;
554         return str_output;
555 }
556
557 char * replace_string(char *origin, const char *src, const char *dest)
558 {
559         _INNER_FUNC_ENTER;
560
561         retvm_if((origin == NULL || strlen(origin) <= 0), NULL, "origin is NULL");
562         retvm_if((src == NULL || strlen(src) <= 0), NULL, "src is NULL");
563         retvm_if((dest == NULL || strlen(dest) <= 0), NULL, "dest is NULL");
564
565         char *str_top = NULL;
566         if ((str_top = strstr(origin, src)) == NULL) {
567                 _DEBUG_ERROR("%s is not founed", src);
568                 return origin;
569         }
570
571         int top_length = strlen(origin) - strlen(str_top);
572         int middle_length = strlen(dest);
573         int down_length = strlen(origin) - top_length - strlen(src);
574         int new_str_length = top_length + middle_length + down_length + 1;
575         if (new_str_length <= 0) {
576                 _DEBUG_ERROR("top_length = %d", top_length);
577                 _DEBUG_ERROR("middle_length = %d", middle_length);
578                 _DEBUG_ERROR("down_length = %d", down_length);
579                 _DEBUG_ERROR("new_str_length(%d) <= 0", new_str_length);
580                 return origin;
581         }
582         char *new_str = (char *)calloc(new_str_length, sizeof(char));
583         if (new_str == NULL) {
584                 _DEBUG_ERROR("calloc is failed.");
585                 return origin;
586         }
587
588         memset(new_str, 0, new_str_length);
589         memcpy(new_str, origin, top_length);
590         memcpy(new_str + top_length, dest, middle_length);
591         memcpy(new_str + top_length + middle_length, origin + top_length + strlen(src), down_length);
592
593         if (origin != NULL) {
594                 free(origin);
595                 origin = NULL;
596         }
597
598         _DEBUG_INFO("new_str = %s", new_str);
599         _INNER_FUNC_EXIT;
600         return new_str;
601 }
602
603 EXPORT_API calendar_list_h set_vcalendar_version(calendar_record_h cal_record)
604 {
605         _INNER_FUNC_ENTER;
606         retvm_if(cal_record == NULL, NULL, "cal_record is NULL");
607
608         int service_ret = CALENDAR_ERROR_NONE;
609         calendar_list_h list = NULL;
610         calendar_record_h extended_version = NULL;
611
612         service_ret = calendar_record_create(_calendar_extended_property._uri, &extended_version);
613         goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_create() Fail!: err[%d]", service_ret);
614
615         service_ret = calendar_record_set_str(extended_version, _calendar_extended_property.key, "VERSION");
616         goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_set_str() Fail!: err[%d]", service_ret);
617
618         service_ret = calendar_record_set_str(extended_version, _calendar_extended_property.value, ":1.0");
619         goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_set_str() Fail!: err[%d]", service_ret);
620
621         service_ret = calendar_list_create(&list);
622         goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_list_create() Fail!: err[%d]", service_ret);
623
624         service_ret = calendar_list_add(list, extended_version);
625         goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_list_add() Fail!: err[%d]", service_ret);
626
627         service_ret = calendar_list_add(list, cal_record);
628         goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_list_add() Fail!: err[%d]", service_ret);
629
630 return_part:
631         _INNER_FUNC_EXIT;
632         return list;
633 }
634
635
636 // PLM(P130408-0777) : In case of DTSTART / DTEND with zulu time ('Z'), GMT timezone should be set.
637 EXPORT_API void set_timezone(const char *origin, calendar_record_h cal_record)
638 {
639         _INNER_FUNC_ENTER;
640         retm_if(origin == NULL, "origin is NULL");
641         retm_if(cal_record == NULL, "cal_record is NULL");
642
643         int service_ret = CALENDAR_ERROR_NONE;
644         char *temp = NULL;
645         char *str_start = NULL;
646
647         temp = strstr(origin, "\r\n"DTSTART_KEYWORD);
648         goto_if(temp == NULL, "origin has not DTSTART. origin = %s", origin);
649
650         str_start = get_value_by_token(temp + 2, DTSTART_KEYWORD, "\r\n");
651         goto_if(str_start == NULL, "str_start is NULL. temp = %s", temp);
652
653         if (strstr(str_start, "Z") != NULL) {
654                 _DEBUG_INFO("GMT timezone setting");
655                 service_ret = calendar_record_set_str(cal_record, _calendar_event.start_tzid, TIMEZONE_GMT);
656                 goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_set_str() Fail! : err[%d]", service_ret);
657
658                 service_ret = calendar_record_set_str(cal_record, _calendar_event.end_tzid, TIMEZONE_GMT);
659                 goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_set_str() Fail! : err[%d]", service_ret);
660         }
661
662 return_part:
663         if (str_start) {
664                 free(str_start);
665                 str_start = NULL;
666         }
667         _INNER_FUNC_EXIT;
668         return;
669 }
670
671 void set_allday(const char *origin, calendar_record_h calendar_record, bool is_phone_to_kies)
672 {
673         _INNER_FUNC_ENTER;
674         retm_if(calendar_record == NULL, "calendar_record is NULL");
675         int service_ret = CALENDAR_ERROR_NONE;
676
677         if (is_phone_to_kies) {
678                 _DEBUG_INFO("phone to kies");
679                 calendar_time_s cal_start_time = {0,};
680                 calendar_record_h extended_allday = NULL;
681
682                 service_ret = calendar_record_get_caltime(calendar_record, _calendar_event.start_time, &cal_start_time);
683                 goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_get_caltime() Fail!: err[%d]", service_ret);
684
685                 service_ret = calendar_record_create(_calendar_extended_property._uri, &extended_allday);
686                 goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_create() Fail!: err[%d]", service_ret);
687
688                 service_ret = calendar_record_set_str(extended_allday, _calendar_extended_property.key, ALLDAY_PREFIX);
689                 goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_set_str() Fail!: err[%d]", service_ret);
690
691                 if (cal_start_time.type == CALENDAR_TIME_LOCALTIME)
692                         service_ret = calendar_record_set_str(extended_allday, _calendar_extended_property.value, "SET");
693                 else
694                         service_ret = calendar_record_set_str(extended_allday, _calendar_extended_property.value, "UNSET");
695
696                 goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_set_str() Fail!: err[%d]", service_ret);
697
698                 service_ret = calendar_record_add_child_record(calendar_record, _calendar_event.extended, extended_allday);
699                 goto_if(service_ret != CALENDAR_ERROR_NONE, "[vcalendar] calendar_record_add_child_record() Fail!: err[%d]", service_ret);
700         }
701         else {
702                 _DEBUG_INFO("kies to phone");
703                 retm_if((origin == NULL || strlen(origin) <= 0), "origin is NULL");
704                 char *uri = NULL;
705
706                 service_ret = calendar_record_get_uri_p(calendar_record, &uri);
707                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_uri_p() Fail!: err[%d]", service_ret);
708
709                 if (strncmp(uri, _calendar_event._uri, strlen(_calendar_event._uri))) {
710                         _DEBUG_ERROR("this is not event");
711                         goto return_part;
712                 }
713
714                 calendar_time_s cal_time_start = { 0, };
715                 calendar_time_s cal_time_end = { 0, };
716                 int year = 0;
717                 int month = 0;
718                 int day = 0;
719
720                 service_ret = calendar_record_get_caltime(calendar_record, _calendar_event.start_time, &cal_time_start);
721                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_caltime() Fail!: err[%d]", service_ret);
722
723                 char *start_date_loc = NULL;
724                 start_date_loc = strstr(origin, "\r\n"DTSTART_KEYWORD);
725                 goto_if(start_date_loc == NULL, "start_date_loc is null");
726
727                 char str_year_start[5] = {0,};
728                 char str_month_start[3] = {0,};
729                 char str_date_start[3] = {0,};
730
731                 /* example) 20130124T000000Z\r\n = 2013 01 24 T 00 00 00 Z \r\n */
732                 strncpy(str_year_start, start_date_loc + strlen("\r\n"DTSTART_KEYWORD), 4);
733                 strncpy(str_month_start, start_date_loc + strlen("\r\n"DTSTART_KEYWORD) + 4, 2);
734                 strncpy(str_date_start, start_date_loc + strlen("\r\n"DTSTART_KEYWORD) + 4 + 2, 2);
735
736                 year = atoi(str_year_start);
737                 month = atoi(str_month_start);
738                 day = atoi(str_date_start);
739
740                 _DEBUG_INFO("start time : year = %d, month = %d, day = %d", year, month, day);
741                 cal_time_start.type = CALENDAR_TIME_LOCALTIME;
742                 cal_time_start.time.date.year = year;
743                 cal_time_start.time.date.month = month;
744                 cal_time_start.time.date.mday = day;
745
746                 service_ret = calendar_record_set_caltime(calendar_record, _calendar_event.start_time, cal_time_start);
747                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_caltime() Fail!: err[%d]", service_ret);
748
749                 service_ret = calendar_record_get_caltime(calendar_record, _calendar_event.end_time, &cal_time_end);
750                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_caltime() Fail!: err[%d]", service_ret);
751
752                 char *end_date_loc = NULL;
753                 end_date_loc = strstr(origin, "\r\n"DTEND_KEYWORD);
754                 goto_if(end_date_loc == NULL, "end_date_loc is null");
755
756                 char str_year_end[5] = {0,};
757                 char str_month_end[3] = {0,};
758                 char str_date_end[3] = {0,};
759
760                 /* example) 20130124T000000Z\r\n = 2013 01 24 T 00 00 00 Z \r\n */
761                 strncpy(str_year_end, end_date_loc + strlen("\r\n"DTEND_KEYWORD), 4);
762                 strncpy(str_month_end, end_date_loc + strlen("\r\n"DTEND_KEYWORD) + 4, 2);
763                 strncpy(str_date_end, end_date_loc + strlen("\r\n"DTEND_KEYWORD) + 4 + 2, 2);
764
765                 year = atoi(str_year_end);
766                 month = atoi(str_month_end);
767                 day = atoi(str_date_end);
768
769                 _DEBUG_INFO("end time : year = %d, month = %d, day = %d", year, month, day);
770                 cal_time_end.type = CALENDAR_TIME_LOCALTIME;
771                 cal_time_end.time.date.year = year;
772                 cal_time_end.time.date.month = month;
773                 cal_time_end.time.date.mday = day;
774
775                 service_ret = calendar_record_set_caltime(calendar_record, _calendar_event.end_time, cal_time_end);
776                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_caltime() Fail!: err[%d]", service_ret);
777         }
778
779 return_part:
780         _INNER_FUNC_EXIT;
781         return;
782 }
783
784 char * remove_uid(char *origin)
785 {
786         _INNER_FUNC_ENTER;
787         retvm_if((origin == NULL || strlen(origin) <= 0), NULL, "origin is NULL");
788
789         _DEBUG_INFO("origin = %s", origin);
790
791         char *str_uid = NULL;
792         char *str_uid_temp = NULL;
793         char *temp = NULL;
794
795         if ((temp = strstr(origin, EXTYPE_UID_KEYWORD)) == NULL) {
796                 _DEBUG_ERROR("origin has not UID string");
797                 goto return_part;
798         }
799
800         str_uid = get_value_by_token(temp+2, "UID:", "\r\n");
801         goto_if(str_uid == NULL, "str_uid is NULL");
802
803         str_uid_temp = g_strdup_printf("%s%s\r\n", EXTYPE_UID_KEYWORD, str_uid);
804         goto_if(str_uid_temp == NULL, "str_uid_temp is NULL");
805
806         origin = replace_string(origin, str_uid_temp, "\r\n");
807
808 return_part:
809         if (str_uid) {
810                 free(str_uid);
811                 str_uid = NULL;
812         }
813         if (str_uid_temp) {
814                 free(str_uid_temp);
815                 str_uid_temp = NULL;
816         }
817         _INNER_FUNC_EXIT;
818         return origin;
819 }
820
821 char * insert_exdate_data(char *origin, sync_agent_calendar_exdate_t *exdate_struct, int index)
822 {
823         _INNER_FUNC_ENTER;
824         retvm_if((origin == NULL || strlen(origin) <= 0), NULL, "origin is NULL");
825         retvm_if(exdate_struct == NULL, NULL, "exdate_struct is NULL");
826         retvm_if(index < 0, NULL, "index < 0");
827
828         char *old_str = NULL;
829         char *new_str = NULL;
830         // 1. copy from parent vcalendar string
831         char *str_child_vcalendar = strdup((char *)(origin));
832
833         if (exdate_struct->exdate_type <= CALENDAR_EXDATE_TYPE_NONE && exdate_struct->exdate_type >= CALENDAR_EXDATE_TYPE_MAX) {
834                 _DEBUG_ERROR("exdate_type(%d) is wrong type", exdate_struct->exdate_type);
835                 goto return_part_free;
836         }
837
838         _DEBUG_INFO("origin = %s", origin);
839         _DEBUG_INFO("cal_exdate_type = %d", exdate_struct->exdate_type);
840
841         if (exdate_struct->exdate_type == CALENDAR_EXDATE_TYPE_DELETED) {
842                 _DEBUG_INFO("delete");
843
844                 // 2. remove SUMMARY / RRULE / ALARM / EXDATE
845                 // 2-1. remove 'SUMMARY'
846                 if ((old_str = strstr(str_child_vcalendar, "\r\n"SUMMARY_KEYWORD)) != NULL) {
847                         _DEBUG_INFO("summary keyword");
848                         if ((new_str = strstr(old_str+2, "\r\n")) != NULL) {
849                                 str_child_vcalendar = replace_string(str_child_vcalendar, old_str, new_str);
850                         }
851                 }
852
853                 // 2-2. remove 'RRULE'
854                 if ((old_str = strstr(str_child_vcalendar, RRULE_KEYWORD)) != NULL) {
855                         _DEBUG_INFO("rrule keyword");
856                         if ((new_str = strstr(old_str+2, "\r\n")) != NULL) {
857                                 str_child_vcalendar = replace_string(str_child_vcalendar, old_str, new_str);
858                         }
859                 }
860
861                 // 2-3. remove 'ALARM'
862                 if ((old_str = strstr(str_child_vcalendar, "\r\n"AALARM_KEYWORD)) != NULL) {
863                         _DEBUG_INFO("alarm keyword");
864                         if ((new_str = strstr(old_str+2, "\r\n")) != NULL) {
865                                 str_child_vcalendar = replace_string(str_child_vcalendar, old_str, new_str);
866                         }
867                 }
868
869                 // 2-4. remove 'EXDATE' array
870                 if ((old_str = strstr(str_child_vcalendar, EXDATE_KEYWORD)) != NULL) {
871                         _DEBUG_INFO("exdate keyword");
872                         if ((new_str = strstr(old_str+2, "\r\nX-EXTYPE:1")) != NULL) {
873                                 str_child_vcalendar = replace_string(str_child_vcalendar, old_str, new_str);
874                         }
875                 }
876                 _DEBUG_INFO("after 2nd phase str_child_vcalendar = %s", str_child_vcalendar);
877
878                 // 3. change DTSTART / DTEND
879                 // example ) DTSTART:20130125T000000Z / DTEND:20130125T003000Z / EXDATE:20130201T000000Z => DTSTART:20130201T000000Z / DTEND:20130201T003000Z
880                 // 3-1. change DTSTART : DTSTART = EXDATE
881                 char *temp = NULL;
882                 if ((temp  = strstr(str_child_vcalendar, "\r\n"DTSTART_KEYWORD)) != NULL) {
883                         _DEBUG_INFO("start keyword");
884
885                         old_str = get_value_by_token(temp + 2, DTSTART_KEYWORD, "\r\n");// '2' means strlen("\r\n")
886                         if (old_str == NULL) {
887                                 _DEBUG_ERROR("old_str is null");
888                                 goto return_part_free;
889                         }
890                         new_str = (char*)g_list_nth_data(exdate_struct->exdate_list, index);
891                         if (new_str == NULL) {
892                                 _DEBUG_ERROR("new_str is NULL");
893                                 goto return_part_free;
894                         }
895                         str_child_vcalendar = replace_string(str_child_vcalendar, old_str, new_str);
896                         if (old_str) {
897                                 free(old_str);
898                                 old_str = NULL;
899                         }
900                 }
901
902                 // 3-2. change DTEND : DTEND = date of EXDATE + time of origin DTEND
903                 temp = NULL;
904                 if ((temp  = strstr(str_child_vcalendar, "\r\n"DTEND_KEYWORD)) != NULL) {
905                         _DEBUG_INFO("end keyword");
906
907                         old_str = get_value_by_token(temp + 2, DTEND_KEYWORD, "\r\n");// '2' means strlen("\r\n")
908                         if (old_str == NULL) {
909                                 _DEBUG_ERROR("old_str is null");
910                                 goto return_part_free;
911                         }
912                         char *exdate_str = (char*)g_list_nth_data(exdate_struct->exdate_list, index);
913                         if (exdate_str == NULL) {
914                                 _DEBUG_ERROR("exdate_str is NULL");
915                                 goto return_part_free;
916                         }
917                         _DEBUG_INFO("exdate_str = %s", exdate_str);
918                         new_str = (char *)calloc(strlen(exdate_str), sizeof(char));
919                         if (new_str == NULL) {
920                                 _DEBUG_ERROR("new_str calloc failed");
921                                 goto return_part_free;
922                         }
923
924                         memcpy(new_str, exdate_str, 8);
925                         memcpy(new_str + 8, old_str + 8, 8);
926                         str_child_vcalendar = replace_string(str_child_vcalendar, old_str, new_str);
927                         if (old_str) {
928                                 free(old_str);
929                                 old_str = NULL;
930                         }
931                         if (new_str) {
932                                 free(new_str);
933                                 new_str = NULL;
934                         }
935                 }
936                 _DEBUG_INFO("after 3rd phase str_child_vcalendar = %s", str_child_vcalendar);
937
938                 // 4. insert EXDATE
939                 if (strstr(str_child_vcalendar, "\r\n"END_VEVENT_KEYWORD"\r\n") != NULL) {
940                         _DEBUG_INFO("EXTYPE keyword");
941
942                         char *exdate_str = (char*)g_list_nth_data(exdate_struct->exdate_list, index);
943                         if (exdate_str == NULL) {
944                                 _DEBUG_ERROR("exdate_str is NULL");
945                                 goto return_part_free;
946                         }
947
948                         new_str = g_strdup_printf("%s%s%s", EXDATE_KEYWORD, exdate_str, "\r\n"END_VEVENT_KEYWORD);
949                         if (new_str == NULL) {
950                                 _DEBUG_ERROR("new_str is null");
951                                 goto return_part_free;
952                         }
953
954                         str_child_vcalendar = replace_string(str_child_vcalendar, "\r\n"END_VEVENT_KEYWORD, new_str);
955                         if (new_str) {
956                                 free(new_str);
957                                 new_str = NULL;
958                         }
959                 }
960
961                 if (strstr(str_child_vcalendar, EXTYPE_DELETE_KEYWORD) != NULL) {
962                         str_child_vcalendar = replace_string(str_child_vcalendar, EXTYPE_DELETE_KEYWORD, "UID:000000000000000000000000000000000000000000000000\r\nX-EXTYPE:1");
963                 }
964                 goto return_part_free;
965         }
966         else if (exdate_struct->exdate_type == CALENDAR_EXDATE_TYPE_UPDATED_CHILD) {
967                 _DEBUG_INFO("update child");
968
969                 // 2. remove 'RRULE'
970                 if ((old_str = strstr(str_child_vcalendar, RRULE_KEYWORD)) != NULL) {
971                         _DEBUG_INFO("rrule keyword");
972                         if ((new_str = strstr(old_str+2, "\r\n")) != NULL) {
973                                 str_child_vcalendar = replace_string(str_child_vcalendar, old_str, new_str);
974                         }
975                 }
976
977                 // 3. insert EXDATE
978                 if (strstr(str_child_vcalendar, "\r\n"END_VEVENT_KEYWORD"\r\n") != NULL) {
979                         _DEBUG_INFO("EXTYPE keyword");
980
981                         char *exdate_str = (char*)g_list_nth_data(exdate_struct->exdate_list, index);
982                         goto_if(exdate_str == NULL, "exdate_str is NULL");
983                         _DEBUG_INFO("exdate_str = %s", exdate_str);
984
985                         new_str = g_strdup_printf("%s%s%s", EXDATE_KEYWORD, exdate_str, "\r\n"END_VEVENT_KEYWORD);
986                         goto_if(new_str == NULL, "new_str is NULL");
987
988                         str_child_vcalendar = replace_string(str_child_vcalendar, "\r\n"END_VEVENT_KEYWORD, new_str);
989                         if (new_str) {
990                                 free(new_str);
991                                 new_str = NULL;
992                         }
993                 }
994         }
995
996 return_part:
997         _DEBUG_INFO("last str_child_vcalendar = %s", str_child_vcalendar);
998         _INNER_FUNC_EXIT;
999         return str_child_vcalendar;
1000
1001 return_part_free:
1002         _DEBUG_INFO("last str_child_vcalendar = %s", str_child_vcalendar);
1003         if (old_str) {
1004                 free(old_str);
1005                 old_str = NULL;
1006         }
1007         _INNER_FUNC_EXIT;
1008         return str_child_vcalendar;
1009 }
1010
1011 EXPORT_API char * has_image_import(const char *origin)
1012 {
1013         _INNER_FUNC_ENTER;
1014
1015         char *temp_image_path = NULL;
1016         char *image_path = NULL;
1017         _DEBUG_INFO("origin = %s", origin);
1018
1019         if (strstr(origin, "\r\n"IMAGE_KEYWORD_PREFIX_PHOTO) == NULL && strstr(origin, "\r\n"IMAGE_KEYWORD_PREFIX_SNOTE) == NULL) {
1020                 _DEBUG_INFO("this calendar has not an image");
1021                 goto return_part;
1022         }
1023
1024         temp_image_path = get_value_by_token(origin, IMAGE_KEYWORD_BEGIN_PATH, IMAGE_KEYWORD_END_PATH);
1025         goto_if(temp_image_path == NULL, "temp_image_path is NULL");
1026
1027         if (strstr(temp_image_path, INTERNAL_MEMORY_CONVERTED) != NULL) {
1028                 image_path = replace_string(temp_image_path, INTERNAL_MEMORY_CONVERTED, INTERNAL_MEMORY_ORIGIN);
1029         }
1030         else if (strstr(temp_image_path, EXTERNAL_MEMORY_CONVERTED) != NULL) {
1031                 image_path = replace_string(temp_image_path, EXTERNAL_MEMORY_CONVERTED, EXTERNAL_MEMORY_ORIGIN);
1032         }
1033         else if (strstr(temp_image_path, SNOTE_MEMORY_ORIGIN) != NULL) {
1034                 image_path = strdup(temp_image_path);
1035         }
1036         else {
1037                 _DEBUG_ERROR("there is an error. origin = %s", origin);
1038                 goto return_part;
1039         }
1040
1041 return_part:
1042         if (image_path)
1043                 _DEBUG_INFO("image_path = %s", image_path);
1044         _INNER_FUNC_EXIT;
1045         return image_path;
1046 }
1047
1048 EXPORT_API char * has_image_export(calendar_record_h cal_record)
1049 {
1050         _INNER_FUNC_ENTER;
1051         retvm_if(cal_record == NULL, NULL, "cal_record is NULL");
1052
1053         calendar_record_h image_record = NULL;
1054         unsigned int child_record_count = 0;
1055         int i = 0;
1056         int service_ret = CALENDAR_ERROR_NONE;
1057         char *image_key = NULL;
1058         char *image_path = NULL;
1059
1060         char *uri = NULL;
1061         service_ret = calendar_record_get_uri_p(cal_record, &uri);
1062         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_uri_p() Fail!: err[%d]", service_ret);
1063
1064         _DEBUG_INFO("uri = %s", uri);
1065
1066         service_ret = calendar_record_get_child_record_count(cal_record, _calendar_event.extended, &child_record_count);
1067         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_child_record_count() Fail!: err[%d]", service_ret);
1068
1069         for (i = 0; i < child_record_count; i++) {
1070                 service_ret = calendar_record_get_child_record_at_p(cal_record, _calendar_event.extended, i, &image_record);
1071                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_child_record_at_p() Fail!: err[%d]", service_ret);
1072
1073                 service_ret = calendar_record_get_str_p(image_record, _calendar_extended_property.key, &image_key);
1074                 goto_if(service_ret != CALENDAR_ERROR_NONE || image_key == NULL || strlen(image_key) <= 0, "calendar_record_get_str_p() Fail!: err[%d]", service_ret);
1075
1076                 if (strcmp(image_key, CALENDAR_IMAGE_KEYWORD_SNOTE) == 0 || strcmp(image_key, CALENDAR_IMAGE_KEYWORD_PHOTO) == 0) {
1077                         _DEBUG_INFO("image is founded. image_key = %s", image_key);
1078                         service_ret = calendar_record_get_str(image_record, _calendar_extended_property.value, &image_path);
1079                         goto_if(service_ret != CALENDAR_ERROR_NONE || image_path == NULL || strlen(image_path) <= 0, "calendar_record_get_str() Fail!: err[%d]", service_ret);
1080                         _DEBUG_INFO("image_path = %s", image_path);
1081                         continue;
1082                 }
1083         }
1084
1085 return_part:
1086         _INNER_FUNC_EXIT;
1087         return image_path;
1088 }
1089
1090 // "EXTYPE" setting, '1' means deleted, '2' means updated : it should be excuted before calendar_vcalendar_make_from_records
1091 void get_exdate_data(calendar_record_h cal_record, sync_agent_calendar_exdate_t *exdate_struct)
1092 {
1093         _INNER_FUNC_ENTER;
1094         retm_if(cal_record == NULL, "cal_record is NULL");
1095         retm_if(exdate_struct == NULL, "exdate_struct is NULL");
1096
1097         calendar_record_h extended_exdate = NULL;
1098         int service_ret = CALENDAR_ERROR_NONE;
1099         int original_event_id = 0;
1100         char *exdate = NULL;
1101         char *recurrence_id = NULL;
1102
1103         exdate_struct->exdate_type = CALENDAR_EXDATE_TYPE_NONE;
1104         exdate_struct->exdate_count = 0;
1105         exdate_struct->exdate_list = NULL;
1106
1107         service_ret = calendar_record_get_int(cal_record, _calendar_event.original_event_id, &original_event_id);
1108         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_int() Fail!: err[%d]", service_ret);
1109         _DEBUG_INFO("original_event_id = %d", original_event_id);
1110
1111         service_ret = calendar_record_get_str(cal_record, _calendar_event.recurrence_id, &recurrence_id);
1112         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_str() Fail!: err[%d]", service_ret);
1113         _DEBUG_INFO("recurrence_id = %s", recurrence_id);
1114
1115         if (original_event_id >= 0 && recurrence_id != NULL && strlen(recurrence_id) > 0) {
1116                 service_ret = calendar_record_set_str(cal_record, _calendar_event.exdate, NULL);
1117                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail!: err[%d]", service_ret);
1118         }
1119
1120         // 1. delete : if 'exdate' value is exist, there are deleted item.
1121         service_ret = calendar_record_get_str(cal_record, _calendar_event.exdate, &exdate);
1122         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_str() Fail!: err[%d]", service_ret);
1123         _DEBUG_INFO("exdate = %s", exdate);
1124
1125         if (exdate != NULL && strlen(exdate) > 0) {
1126                 _DEBUG_INFO("EXTYPE:DELETE setting start");
1127                 service_ret = calendar_record_create(_calendar_extended_property._uri, &extended_exdate);
1128                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_create() Fail!: err[%d]", service_ret);
1129
1130                 service_ret = calendar_record_set_str(extended_exdate, _calendar_extended_property.key, "X-EXTYPE");
1131                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail!: err[%d]", service_ret);
1132
1133                 service_ret = calendar_record_set_str(extended_exdate, _calendar_extended_property.value, ":1");
1134                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail!: err[%d]", service_ret);
1135
1136                 service_ret = calendar_record_add_child_record(cal_record, _calendar_event.extended, extended_exdate);
1137                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_add_child_record() Fail!: err[%d]", service_ret);
1138
1139                 exdate_struct->exdate_type = CALENDAR_EXDATE_TYPE_DELETED;
1140                 char *str_exdate_loc = NULL;
1141                 int exdate_count = 0;
1142                 int exdate_loc = 0;
1143                 while (exdate_loc < strlen(exdate)) {
1144                         int one_exdate_length = 0;
1145                         if ((str_exdate_loc = strstr(exdate + exdate_loc, ",")) != NULL) {
1146                                 one_exdate_length = strlen(exdate) - strlen(str_exdate_loc) - (exdate_count*(DATE_TIME_LENGTH+1));
1147                         }
1148                         else {
1149                                 one_exdate_length = strlen(exdate) - exdate_loc;
1150                         }
1151                         _DEBUG_INFO("str_exdate_loc = %s", str_exdate_loc);
1152                         if (one_exdate_length <= 0) {
1153                                 _DEBUG_ERROR("one_exdate_length (%d) <= 0", one_exdate_length);
1154                                 continue;
1155                         }
1156                         char *str_one_exdate = (char *)calloc(one_exdate_length, sizeof(char));
1157                         if (str_one_exdate == NULL) {
1158                                 _DEBUG_ERROR("str_one_exdate calloc is failed.");
1159                                 continue;
1160                         }
1161                         memcpy(str_one_exdate, exdate + exdate_loc, one_exdate_length);
1162                         exdate_loc += (one_exdate_length+1); // '1' meaning of ',' length
1163                         exdate_struct->exdate_list = g_list_append(exdate_struct->exdate_list, str_one_exdate);
1164                         exdate_count++;
1165                         _DEBUG_INFO("str_one_exdate = %s", str_one_exdate);
1166                 }
1167
1168                 _DEBUG_INFO("exdate_count = %d", exdate_count);
1169                 exdate_struct->exdate_count = exdate_count;
1170                 _DEBUG_INFO("EXTYPE:DELETE setting end");
1171                 goto return_part;
1172         }
1173
1174         // 2. update : if 'origianl_event_id' and 'recurrence_id' value are exist, there are updated item.
1175         if (original_event_id < 0 && recurrence_id == NULL ) {
1176                 unsigned int count = 0;
1177                 service_ret = calendar_record_get_child_record_count(cal_record, _calendar_event.exception, &count);
1178                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_child_record_count() Fail! err[%d]\n", service_ret);
1179                 if (count <=0) {
1180                         _DEBUG_INFO("this is a normal calendar");
1181                         goto return_part;
1182                 }
1183
1184                 _DEBUG_INFO("parent EXTYPE:UPDATE setting start");
1185                 exdate_struct->exdate_type = CALENDAR_EXDATE_TYPE_UPDATED_PARENT;
1186                 service_ret = calendar_record_create(_calendar_extended_property._uri, &extended_exdate);
1187                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_create() Fail! err[%d]\n", service_ret);
1188
1189                 service_ret = calendar_record_set_str(extended_exdate, _calendar_extended_property.key, "X-EXTYPE");
1190                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail! err[%d]\n", service_ret);
1191
1192                 service_ret = calendar_record_set_str(extended_exdate, _calendar_extended_property.value, ":2");
1193                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail! err[%d]\n", service_ret);
1194
1195                 service_ret = calendar_record_add_child_record(cal_record, _calendar_event.extended, extended_exdate);
1196                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_add_child_record() Fail! err[%d]\n", service_ret);
1197         }
1198         else if (original_event_id >= 0 && recurrence_id != NULL && strlen(recurrence_id) > 0) {
1199                 _DEBUG_INFO("child EXTYPE:UPDATE setting start");
1200                 exdate_struct->exdate_type = CALENDAR_EXDATE_TYPE_UPDATED_CHILD;
1201                 exdate_struct->exdate_list = g_list_append(exdate_struct->exdate_list, recurrence_id);
1202                 exdate_struct->exdate_count = 1;
1203                 service_ret = calendar_record_create(_calendar_extended_property._uri, &extended_exdate);
1204                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_create() Fail!: err[%d]", service_ret);
1205
1206                 service_ret = calendar_record_set_str(extended_exdate, _calendar_extended_property.key, "X-EXTYPE");
1207                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail! err[%d]\n", service_ret);
1208
1209                 service_ret = calendar_record_set_str(extended_exdate, _calendar_extended_property.value, ":2");
1210                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail! err[%d]\n", service_ret);
1211
1212                 service_ret = calendar_record_add_child_record(cal_record, _calendar_event.extended, extended_exdate);
1213                 goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_add_child_record() Fail! err[%d]\n", service_ret);
1214         }
1215
1216 return_part:
1217         _INNER_FUNC_EXIT;
1218         return;
1219 }
1220
1221 char * replace_rrule_data(char *origin)
1222 {
1223         _INNER_FUNC_ENTER;
1224         retvm_if(origin == NULL, origin, "origin is NULL.");
1225
1226         char *temp = NULL;
1227         char *temp_rrule = NULL;
1228         char *str_old_rrule = NULL;
1229         char *str_new_rrule = NULL;
1230
1231         temp = strstr(origin, RRULE_KEYWORD);
1232         if (temp == NULL) {
1233                 _DEBUG_INFO("this vcalendar hasn't rrule data");
1234                 goto return_part;
1235         }
1236
1237         // case 1 : weekdays rrule converting
1238         if (strstr(origin, WEEKDAY_RRULE_ORIGIN_KEYWORD) != NULL) {
1239                 _DEBUG_INFO("this vcalendar has WEEKDAYS rrule data");
1240
1241                 origin = replace_string(origin, WEEKDAY_RRULE_ORIGIN_KEYWORD, WEEKDAY_RRULE_CONVERTED_KEYWORD);
1242                 _DEBUG_INFO("AFTER origin = %s", origin);
1243                 goto return_part;
1244         }
1245
1246         // case 2 : max rrule converting
1247         str_old_rrule = get_value_by_token(temp + 2, "RRULE:", "\r\n");// '2' means strlen("\r\n")
1248         goto_if(str_old_rrule == NULL, "str_old_rrule is null");
1249
1250         if (strstr(str_old_rrule, MAX_RRULE_DATE_KEYWORD) == NULL) {
1251                 _DEBUG_INFO("this vcalendar has rrule data, But it's not until=NONE rrule");
1252                 goto return_part;
1253         }
1254         _DEBUG_INFO("this vcalendar has until=NONE rrule");
1255
1256         temp_rrule = get_value_by_token(temp, RRULE_KEYWORD, MAX_RRULE_DATE_KEYWORD);
1257         goto_if(temp_rrule == NULL, "temp_rrule is null");
1258
1259         // every eternal rrule data must have '#0' at the end of string (Calendar-Svc recommend)
1260         str_new_rrule = g_strdup_printf("%s#0", temp_rrule);
1261         goto_if(str_new_rrule == NULL, "str_new_rrule is null");
1262         _DEBUG_INFO("str_new_rrule = %s", str_new_rrule);
1263
1264         origin = replace_string(origin, str_old_rrule, str_new_rrule);
1265
1266 return_part:
1267         if(str_old_rrule) {
1268                 free(str_old_rrule);
1269                 str_old_rrule = NULL;
1270         }
1271         if(str_new_rrule) {
1272                 free(str_new_rrule);
1273                 str_new_rrule = NULL;
1274         }
1275         if(temp_rrule) {
1276                 free(temp_rrule);
1277                 temp_rrule = NULL;
1278         }
1279         _INNER_FUNC_EXIT;
1280         return origin;
1281 }
1282
1283 char * replace_image_data(char *origin, char *image_path)
1284 {
1285         _INNER_FUNC_ENTER;
1286         retvm_if(origin == NULL, origin, "origin is NULL.");
1287         retvm_if(image_path == NULL, origin, "image_path is NULL.");
1288
1289         char *str_temp_image_info = NULL;
1290         char *str_image_info = NULL;
1291         char *str_image_tag = NULL;
1292
1293         if (strstr(image_path, INTERNAL_MEMORY_ORIGIN) != NULL) {
1294                 str_temp_image_info = replace_string(image_path, INTERNAL_MEMORY_ORIGIN, INTERNAL_MEMORY_CONVERTED);
1295                 str_image_tag = strdup(IMAGE_KEYWORD_PREFIX_PHOTO);
1296         }
1297         else if (strstr(image_path, EXTERNAL_MEMORY_ORIGIN) != NULL) {
1298                 str_temp_image_info = replace_string(image_path, EXTERNAL_MEMORY_ORIGIN, EXTERNAL_MEMORY_CONVERTED);
1299                 str_image_tag = strdup(IMAGE_KEYWORD_PREFIX_PHOTO);
1300         }
1301         else if (strstr(image_path, SNOTE_MEMORY_ORIGIN) != NULL) {
1302                 str_temp_image_info = strdup(image_path);
1303                 //str_image_tag = strdup(IMAGE_KEYWORD_PREFIX_SNOTE);
1304                 str_image_tag = strdup(IMAGE_KEYWORD_PREFIX_PHOTO);
1305         }
1306         else {
1307                 _DEBUG_ERROR("there is an error. image_path = %s", image_path);
1308                 goto return_part;
1309         }
1310
1311         goto_if(strstr(origin, "\r\n"END_VEVENT_KEYWORD"\r\n") == NULL, "this data is wrong format. origin = %s", origin);
1312
1313         str_image_info = g_strdup_printf("\r\n%s;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:NAME=3Dnull=3BPATH=3D%s=3BDATE=3D%s", str_image_tag, str_temp_image_info, "\r\n"END_VEVENT_KEYWORD"\r\n");
1314         goto_if(str_image_info == NULL, "str_image_info is null");
1315
1316         char *new_agent_data = replace_string(origin, "\r\n"END_VEVENT_KEYWORD"\r\n", str_image_info);
1317         origin = NULL;
1318         origin = new_agent_data;
1319
1320 return_part:
1321
1322         if (str_image_info) {
1323                 free(str_image_info);
1324                 str_image_info = NULL;
1325         }
1326         if (str_image_tag) {
1327                 free(str_image_tag);
1328                 str_image_tag = NULL;
1329         }
1330         if (str_temp_image_info) {
1331                 free(str_temp_image_info);
1332                 str_temp_image_info = NULL;
1333         }
1334
1335         _INNER_FUNC_EXIT;
1336         return origin;
1337 }
1338
1339 // exdate string format like as "20130211T000000Z,20130212T000000Z,20130213T000000Z"
1340 void replace_deleted_exdate_data(const char *origin, calendar_record_h parent_record)
1341 {
1342         _INNER_FUNC_ENTER;
1343         retm_if(origin == NULL, "origin is NULL.");
1344         retm_if(parent_record == NULL, "parent_record is NULL");
1345
1346         char *str_exdata_loc = NULL;
1347         char *old_exdate_str = NULL;
1348         char *new_exdate_str = NULL;
1349         char *new_one_exdate_str = NULL;
1350         int exdate_length = 0;
1351         int service_ret = CALENDAR_ERROR_NONE;
1352
1353         str_exdata_loc = strstr(origin, IMPORT_EXTYPE_DELETE_KEYWORD);
1354         goto_if(str_exdata_loc == NULL, "this vcalendar has not exdate data");
1355
1356         new_one_exdate_str = get_value_by_token(str_exdata_loc + 2, "EXDATE:", "\r\n");
1357         _DEBUG_INFO("new_one_exdate_str = %s", new_one_exdate_str);
1358
1359         service_ret = calendar_record_get_str(parent_record, _calendar_event.exdate, &old_exdate_str);
1360         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail! err[%d]\n", service_ret);
1361
1362         _DEBUG_INFO("old_exdate_str = %s", old_exdate_str);
1363         int old_exdate_str_length = 0;
1364         if (old_exdate_str == NULL) {
1365                 old_exdate_str_length = 0;
1366         }
1367         else {
1368                 old_exdate_str_length = strlen(old_exdate_str);
1369                 if (strstr(old_exdate_str, new_one_exdate_str) != NULL) {
1370                         _DEBUG_ERROR("new_one_exdate_str is already exist in old_exdate_str");
1371                         goto return_part;
1372                 }
1373         }
1374
1375         exdate_length = old_exdate_str_length + strlen(new_one_exdate_str) + 2;
1376         new_exdate_str = (char *)calloc(exdate_length, sizeof(char));
1377         goto_if(new_exdate_str == NULL, "new_exdate_str calloc failed, exdate_length = %d", exdate_length);
1378
1379         if (old_exdate_str == NULL)
1380                 snprintf(new_exdate_str, exdate_length, "%s", new_one_exdate_str);
1381         else
1382                 snprintf(new_exdate_str, exdate_length, "%s,%s", old_exdate_str, new_one_exdate_str);
1383
1384         _DEBUG_INFO("new_exdate_str = %s", new_exdate_str);
1385         service_ret = calendar_record_set_str(parent_record, _calendar_event.exdate, new_exdate_str);
1386         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail! err[%d]\n", service_ret);
1387
1388 return_part:
1389         if(new_one_exdate_str) {
1390                 free(new_one_exdate_str);
1391                 new_one_exdate_str = NULL;
1392         }
1393         if(new_exdate_str) {
1394                 free(new_exdate_str);
1395                 new_exdate_str = NULL;
1396         }
1397         _INNER_FUNC_EXIT;
1398         return;
1399 }
1400
1401 int replace_updated_exdate_data(const char *origin, calendar_record_h parent_record)
1402 {
1403         _INNER_FUNC_ENTER;
1404         retvm_if(origin == NULL, -1, "origin is NULL.");
1405         retvm_if(parent_record == NULL, -1, "parent_record is NULL");
1406
1407         calendar_record_h child_record = NULL;
1408         char *str_exdata_loc = NULL;
1409         char *new_one_exdate_str = NULL;
1410         int parent_service_id = 0;
1411         int child_service_id = 0;
1412         int service_ret = CALENDAR_ERROR_NONE;
1413         int ret = -1;
1414
1415         str_exdata_loc = strstr(origin, IMPORT_EXTYPE_UPDATE_KEYWORD);
1416         goto_if(str_exdata_loc == NULL, "this vcalendar has not exdate data");
1417
1418         new_one_exdate_str = get_value_by_token(str_exdata_loc + 2, "EXDATE:", "\r\n");
1419         _DEBUG_INFO("new_one_exdate_str = %s", new_one_exdate_str);
1420
1421         service_ret = calendar_record_clone(parent_record, &child_record);
1422         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_clone() Fail!: err[%d]", service_ret);
1423
1424         service_ret = calendar_record_get_int(parent_record, _calendar_event.id, &parent_service_id);
1425         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_get_int() Fail!: err[%d]", service_ret);
1426         _DEBUG_INFO("parent_service_id = %d", parent_service_id);
1427
1428         service_ret = calendar_record_set_int(child_record, _calendar_event.original_event_id, parent_service_id);
1429         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_int() Fail!: err[%d]", service_ret);
1430
1431         service_ret = calendar_record_set_str(child_record, _calendar_event.recurrence_id, new_one_exdate_str);
1432         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail!: err[%d]", service_ret);
1433
1434         service_ret = calendar_record_set_str(child_record, _calendar_event.exdate, NULL);
1435         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_set_str() Fail!: err[%d]", service_ret);
1436
1437         service_ret = calendar_db_insert_record(child_record, &child_service_id);
1438         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_db_insert_record() Fail!: err[%d]", service_ret);
1439
1440         service_ret = calendar_record_destroy(child_record, true);
1441         goto_if(service_ret != CALENDAR_ERROR_NONE, "calendar_record_destroy() Fail!: err[%d]", service_ret);
1442         _DEBUG_INFO("child_service_id = %d", child_service_id);
1443
1444         ret = child_service_id;
1445
1446 return_part:
1447         if(new_one_exdate_str) {
1448                 free(new_one_exdate_str);
1449                 new_one_exdate_str = NULL;
1450         }
1451         if (service_ret != CALENDAR_ERROR_NONE)
1452                 ret = -1;
1453         _INNER_FUNC_EXIT;
1454         return ret;
1455 }