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"
32 #include "cal_utils.h"
34 #define ICALENAR_BUFFER_MAX (1024*1024)
37 * vcalendar should not have multi version: ver1.0 or 2.0 only.
38 * could have multi timezone events: MULTI BEGIN:VCALENDAR.
40 EXPORT_API int calendar_vcalendar_make_from_records(calendar_list_h list, char **vcalendar_stream)
42 CHECK_CALENDAR_SUPPORTED(CALENDAR_FEATURE);
48 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
49 RETV_IF(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER);
51 b = cal_vcalendar_make_new();
52 RETVM_IF(!b, CALENDAR_ERROR_OUT_OF_MEMORY,
53 "cal_vcalendar_make_new() Fail");
55 ret = cal_vcalendar_make_vcalendar(b, list);
58 cal_vcalendar_make_free(&b);
62 ical = cal_vcalendar_make_get_data(b);
63 cal_vcalendar_make_free(&b);
67 ERR("cal_vcalendar_make_get_data() Fail");
68 return CALENDAR_ERROR_OUT_OF_MEMORY;
76 return CALENDAR_ERROR_NO_DATA;
80 *vcalendar_stream = ical;
82 return CALENDAR_ERROR_NONE;
85 static const char* __calendar_vcalendar_get_vcalendar_object(const char *original, char **pvcalendar_object)
88 const char *vcal_start = original;
89 const char *vcal_cursor = NULL;
90 bool new_line = false;
91 char *vcalendar_object = NULL;
93 RETV_IF(NULL == pvcalendar_object, original);
94 *pvcalendar_object = NULL;
96 while ('\n' == *vcal_start || '\r' == *vcal_start)
99 if (strncmp(vcal_start, "BEGIN:VCALENDAR", strlen("BEGIN:VCALENDAR")))
102 vcal_start += strlen("BEGIN:VCALENDAR");
103 while ('\n' == *vcal_start || '\r' == *vcal_start)
105 vcal_cursor = vcal_start;
107 while (*vcal_cursor) {
109 if (CAL_STRING_EQUAL == strncmp(vcal_cursor, "END:VCALENDAR", strlen("END:VCALENDAR"))) {
110 vcal_cursor += strlen("END:VCALENDAR");
111 while ('\r' == *vcal_cursor || '\n' == *vcal_cursor) {
116 len = (int)((long)vcal_cursor - (long)vcal_start);
117 vcalendar_object = calloc(len + 1, sizeof(char));
118 if (NULL == vcalendar_object) {
119 /* LCOV_EXCL_START */
120 ERR("calloc() Fail");
124 memcpy(vcalendar_object, vcal_start, len);
125 *pvcalendar_object = vcalendar_object;
131 while ('\r' == *vcal_cursor || '\n' == *vcal_cursor) {
142 EXPORT_API int calendar_vcalendar_parse_to_calendar(const char* vcalendar_stream, calendar_list_h *out_list)
144 CHECK_CALENDAR_SUPPORTED(CALENDAR_FEATURE);
147 const char *cursor = NULL;
148 char *vcalendar_object = NULL;
149 calendar_error_e err;
150 calendar_list_h list = NULL;
152 RETV_IF(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER);
153 RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
155 /* get vcalendar object */
156 cursor = vcalendar_stream;
159 ret = calendar_list_create(&list);
160 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
164 while (NULL != (cursor = __calendar_vcalendar_get_vcalendar_object(cursor, &vcalendar_object))) {
165 if (NULL == vcalendar_object)
168 err = cal_vcalendar_parse_vcalendar_object(vcalendar_object, list, NULL);
169 if (CALENDAR_ERROR_NONE != err) {
170 /* LCOV_EXCL_START */
171 ERR("cal_vcalendar_parse_vcalendar_object() failed(%d)", err);
172 calendar_list_destroy(list, true);
173 free(vcalendar_object);
178 free(vcalendar_object);
180 calendar_list_get_count(list, &count);
182 calendar_list_destroy(list, true);
184 return CALENDAR_ERROR_INVALID_PARAMETER;
186 calendar_list_first(list);
189 return CALENDAR_ERROR_NONE;
192 EXPORT_API int calendar_vcalendar_parse_to_calendar_foreach(const char *vcalendar_file_path, calendar_vcalendar_parse_cb callback, void *user_data)
194 CHECK_CALENDAR_SUPPORTED(CALENDAR_FEATURE);
199 char buf[CAL_STR_MIDDLE_LEN];
200 vcalendar_foreach_s *foreach_data = NULL;
202 RETV_IF(NULL == vcalendar_file_path, CALENDAR_ERROR_INVALID_PARAMETER);
203 RETV_IF(NULL == callback, CALENDAR_ERROR_INVALID_PARAMETER);
206 calendar_list_h list = NULL;
207 ret = calendar_list_create(&list);
208 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
210 file = fopen(vcalendar_file_path, "r");
212 /* LCOV_EXCL_START */
213 ERR("Invalid argument: no file");
214 calendar_list_destroy(list, true);
215 return CALENDAR_ERROR_INVALID_PARAMETER;
220 buf_size = ICALENAR_BUFFER_MAX;
221 stream = calloc(ICALENAR_BUFFER_MAX, sizeof(char));
222 if (NULL == stream) {
223 /* LCOV_EXCL_START */
224 ERR("calloc() Fail");
226 calendar_list_destroy(list, true);
227 return CALENDAR_ERROR_OUT_OF_MEMORY;
231 foreach_data = calloc(1, sizeof(vcalendar_foreach_s));
232 if (NULL == foreach_data) {
233 /* LCOV_EXCL_START */
234 ERR("calloc() Fail");
237 calendar_list_destroy(list, true);
238 return CALENDAR_ERROR_OUT_OF_MEMORY;
241 foreach_data->callback = callback;
242 foreach_data->user_data = user_data;
243 foreach_data->ret = true;
245 int error = CALENDAR_ERROR_NONE;
247 while (fgets(buf, sizeof(buf), file)) {
248 int added_len = cal_add_safe(len, strlen(buf));
250 ERR("cal_add_safe() Fail");
251 error = CALENDAR_ERROR_SYSTEM;
254 if (buf_size <= added_len) {
257 new_stream = realloc(stream, buf_size);
258 if (NULL == new_stream) {
259 /* LCOV_EXCL_START */
260 ERR("out of memory");
261 error = CALENDAR_ERROR_OUT_OF_MEMORY;
268 int copyed_len = snprintf(stream + len, strlen(buf) +1, "%s", buf);
269 len = cal_add_safe(copyed_len, len);
271 /* LCOV_EXCL_START */
272 ERR("cal_add_safe() Fail");
273 error = CALENDAR_ERROR_SYSTEM;
278 if (CAL_STRING_EQUAL == strncmp(buf, "END:VCALENDAR", strlen("END:VCALENDAR"))) {
279 DBG("end vcalendar");
280 char *vcalendar_object = NULL;
281 __calendar_vcalendar_get_vcalendar_object(stream, &vcalendar_object);
282 error = cal_vcalendar_parse_vcalendar_object(vcalendar_object, list, foreach_data);
283 if (CALENDAR_ERROR_NONE != error) {
284 /* LCOV_EXCL_START */
285 ERR("cal_vcalendar_parse_vcalendar_object() failed(%d)", error);
286 free(vcalendar_object);
290 if (false == foreach_data->ret) {
291 /* LCOV_EXCL_START */
292 ERR("foreach_data->ret is NULL");
293 free(vcalendar_object);
294 error = CALENDAR_ERROR_SYSTEM;
298 free(vcalendar_object);
303 calendar_list_destroy(list, true);