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.
22 #include "calendar_vcalendar.h"
23 #include "cal_internal.h"
24 #include "cal_typedef.h"
25 #include "cal_record.h"
29 #include "cal_vcalendar.h"
30 #include "cal_vcalendar_make.h"
31 #include "cal_vcalendar_parse.h"
33 #define ICALENAR_BUFFER_MAX (1024*1024)
36 * vcalendar should not have multi version: ver1.0 or 2.0 only.
37 * could have multi timezone events: MULTI BEGIN:VCALENDAR.
39 API int calendar_vcalendar_make_from_records(calendar_list_h list, char **vcalendar_stream)
45 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
46 RETV_IF(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER);
48 b = cal_vcalendar_make_new();
49 RETVM_IF(!b, CALENDAR_ERROR_OUT_OF_MEMORY,
50 "cal_vcalendar_make_new() Fail");
52 ret = cal_vcalendar_make_vcalendar(b, list);
55 cal_vcalendar_make_free(&b);
59 ical = cal_vcalendar_make_get_data(b);
60 cal_vcalendar_make_free(&b);
63 ERR("cal_vcalendar_make_get_data() Fail");
64 return CALENDAR_ERROR_OUT_OF_MEMORY;
70 return CALENDAR_ERROR_NO_DATA;
73 *vcalendar_stream = ical;
75 return CALENDAR_ERROR_NONE;
78 static const char* __calendar_vcalendar_get_vcalendar_object(const char *original, char **pvcalendar_object)
81 const char *vcal_start = original;
82 const char *vcal_cursor = NULL;
83 bool new_line = false;
84 char *vcalendar_object = NULL;
86 RETV_IF(NULL == pvcalendar_object, original);
87 *pvcalendar_object = NULL;
89 while ('\n' == *vcal_start || '\r' == *vcal_start)
92 if (strncmp(vcal_start, "BEGIN:VCALENDAR", strlen("BEGIN:VCALENDAR")))
95 vcal_start += strlen("BEGIN:VCALENDAR");
96 while ('\n' == *vcal_start || '\r' == *vcal_start)
98 vcal_cursor = vcal_start;
100 while (*vcal_cursor) {
102 if (CAL_STRING_EQUAL == strncmp(vcal_cursor, "END:VCALENDAR", strlen("END:VCALENDAR"))) {
103 vcal_cursor += strlen("END:VCALENDAR");
104 while ('\r' == *vcal_cursor || '\n' == *vcal_cursor) {
109 len = (int)((long)vcal_cursor - (long)vcal_start);
110 vcalendar_object = calloc(len + 1, sizeof(char));
111 if (NULL == vcalendar_object) {
112 ERR("calloc() Fail");
115 memcpy(vcalendar_object, vcal_start, len);
116 *pvcalendar_object = vcalendar_object;
122 while ('\r' == *vcal_cursor || '\n' == *vcal_cursor) {
133 API int calendar_vcalendar_parse_to_calendar(const char* vcalendar_stream, calendar_list_h *out_list)
136 const char *cursor = NULL;
137 char *vcalendar_object = NULL;
138 calendar_error_e err;
139 calendar_list_h list = NULL;
141 RETV_IF(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER);
142 RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
144 /* get vcalendar object */
145 cursor = vcalendar_stream;
148 ret = calendar_list_create(&list);
149 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
153 while (NULL != (cursor = __calendar_vcalendar_get_vcalendar_object(cursor, &vcalendar_object))) {
154 if (NULL == vcalendar_object)
157 err = cal_vcalendar_parse_vcalendar_object(vcalendar_object, list, NULL);
158 if (CALENDAR_ERROR_NONE != err) {
159 ERR("cal_vcalendar_parse_vcalendar_object() failed(%d)", err);
160 calendar_list_destroy(list, true);
161 free(vcalendar_object);
165 free(vcalendar_object);
167 calendar_list_get_count(list, &count);
169 calendar_list_destroy(list, true);
171 return CALENDAR_ERROR_INVALID_PARAMETER;
173 calendar_list_first(list);
176 return CALENDAR_ERROR_NONE;
179 API int calendar_vcalendar_parse_to_calendar_foreach(const char *vcalendar_file_path, calendar_vcalendar_parse_cb callback, void *user_data)
184 char buf[CAL_STR_MIDDLE_LEN];
185 vcalendar_foreach_s *foreach_data = NULL;
187 RETV_IF(NULL == vcalendar_file_path, CALENDAR_ERROR_INVALID_PARAMETER);
188 RETV_IF(NULL == callback, CALENDAR_ERROR_INVALID_PARAMETER);
191 calendar_list_h list = NULL;
192 ret = calendar_list_create(&list);
193 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
195 file = fopen(vcalendar_file_path, "r");
197 ERR("Invalid argument: no file");
198 calendar_list_destroy(list, true);
199 return CALENDAR_ERROR_INVALID_PARAMETER;
203 buf_size = ICALENAR_BUFFER_MAX;
204 stream = calloc(ICALENAR_BUFFER_MAX, sizeof(char));
205 if (NULL == stream) {
206 ERR("calloc() Fail");
208 calendar_list_destroy(list, true);
209 return CALENDAR_ERROR_OUT_OF_MEMORY;
212 foreach_data = calloc(1, sizeof(vcalendar_foreach_s));
213 if (NULL == foreach_data) {
214 ERR("calloc() Fail");
217 calendar_list_destroy(list, true);
218 return CALENDAR_ERROR_OUT_OF_MEMORY;
220 foreach_data->callback = callback;
221 foreach_data->user_data = user_data;
222 foreach_data->ret = true;
224 while (fgets(buf, sizeof(buf), file)) {
225 if (len + sizeof(buf) < buf_size) {
226 len += snprintf(stream + len, strlen(buf) +1, "%s", buf);
230 new_stream = realloc(stream, buf_size);
237 calendar_list_destroy(list, true);
238 ERR("out of memory");
239 return CALENDAR_ERROR_OUT_OF_MEMORY;
241 len += snprintf(stream + len, strlen(buf) +1, "%s", buf);
244 if (CAL_STRING_EQUAL == strncmp(buf, "END:VCALENDAR", strlen("END:VCALENDAR"))) {
245 DBG("end vcalendar");
247 char *vcalendar_object = NULL;
248 __calendar_vcalendar_get_vcalendar_object(stream, &vcalendar_object);
249 err = cal_vcalendar_parse_vcalendar_object(vcalendar_object, list, foreach_data);
250 if (CALENDAR_ERROR_NONE != err || false == foreach_data->ret) {
251 ERR("cal_vcalendar_parse_vcalendar_object() failed(%d)", err);
252 calendar_list_destroy(list, true);
253 free(vcalendar_object);
259 free(vcalendar_object);
264 calendar_list_destroy(list, true);
269 return CALENDAR_ERROR_NONE;