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);
64 ERR("cal_vcalendar_make_get_data() Fail");
65 return CALENDAR_ERROR_OUT_OF_MEMORY;
73 return CALENDAR_ERROR_NO_DATA;
77 *vcalendar_stream = ical;
79 return CALENDAR_ERROR_NONE;
82 static const char* __calendar_vcalendar_get_vcalendar_object(const char *original, char **pvcalendar_object)
85 const char *vcal_start = original;
86 const char *vcal_cursor = NULL;
87 bool new_line = false;
88 char *vcalendar_object = NULL;
90 RETV_IF(NULL == pvcalendar_object, original);
91 *pvcalendar_object = NULL;
93 while ('\n' == *vcal_start || '\r' == *vcal_start)
96 if (strncmp(vcal_start, "BEGIN:VCALENDAR", strlen("BEGIN:VCALENDAR")))
99 vcal_start += strlen("BEGIN:VCALENDAR");
100 while ('\n' == *vcal_start || '\r' == *vcal_start)
102 vcal_cursor = vcal_start;
104 while (*vcal_cursor) {
106 if (CAL_STRING_EQUAL == strncmp(vcal_cursor, "END:VCALENDAR", strlen("END:VCALENDAR"))) {
107 vcal_cursor += strlen("END:VCALENDAR");
108 while ('\r' == *vcal_cursor || '\n' == *vcal_cursor) {
113 len = (int)((long)vcal_cursor - (long)vcal_start);
114 vcalendar_object = calloc(len + 1, sizeof(char));
115 if (NULL == vcalendar_object) {
116 /* LCOV_EXCL_START */
117 ERR("calloc() Fail");
121 memcpy(vcalendar_object, vcal_start, len);
122 *pvcalendar_object = vcalendar_object;
128 while ('\r' == *vcal_cursor || '\n' == *vcal_cursor) {
139 API int calendar_vcalendar_parse_to_calendar(const char* vcalendar_stream, calendar_list_h *out_list)
142 const char *cursor = NULL;
143 char *vcalendar_object = NULL;
144 calendar_error_e err;
145 calendar_list_h list = NULL;
147 RETV_IF(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER);
148 RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
150 /* get vcalendar object */
151 cursor = vcalendar_stream;
154 ret = calendar_list_create(&list);
155 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
159 while (NULL != (cursor = __calendar_vcalendar_get_vcalendar_object(cursor, &vcalendar_object))) {
160 if (NULL == vcalendar_object)
163 err = cal_vcalendar_parse_vcalendar_object(vcalendar_object, list, NULL);
164 if (CALENDAR_ERROR_NONE != err) {
165 /* LCOV_EXCL_START */
166 ERR("cal_vcalendar_parse_vcalendar_object() failed(%d)", err);
167 calendar_list_destroy(list, true);
168 free(vcalendar_object);
173 free(vcalendar_object);
175 calendar_list_get_count(list, &count);
177 calendar_list_destroy(list, true);
179 return CALENDAR_ERROR_INVALID_PARAMETER;
181 calendar_list_first(list);
184 return CALENDAR_ERROR_NONE;
187 API int calendar_vcalendar_parse_to_calendar_foreach(const char *vcalendar_file_path, calendar_vcalendar_parse_cb callback, void *user_data)
192 char buf[CAL_STR_MIDDLE_LEN];
193 vcalendar_foreach_s *foreach_data = NULL;
195 RETV_IF(NULL == vcalendar_file_path, CALENDAR_ERROR_INVALID_PARAMETER);
196 RETV_IF(NULL == callback, CALENDAR_ERROR_INVALID_PARAMETER);
199 calendar_list_h list = NULL;
200 ret = calendar_list_create(&list);
201 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
203 file = fopen(vcalendar_file_path, "r");
205 /* LCOV_EXCL_START */
206 ERR("Invalid argument: no file");
207 calendar_list_destroy(list, true);
208 return CALENDAR_ERROR_INVALID_PARAMETER;
213 buf_size = ICALENAR_BUFFER_MAX;
214 stream = calloc(ICALENAR_BUFFER_MAX, sizeof(char));
215 if (NULL == stream) {
216 /* LCOV_EXCL_START */
217 ERR("calloc() Fail");
219 calendar_list_destroy(list, true);
220 return CALENDAR_ERROR_OUT_OF_MEMORY;
224 foreach_data = calloc(1, sizeof(vcalendar_foreach_s));
225 if (NULL == foreach_data) {
226 /* LCOV_EXCL_START */
227 ERR("calloc() Fail");
230 calendar_list_destroy(list, true);
231 return CALENDAR_ERROR_OUT_OF_MEMORY;
234 foreach_data->callback = callback;
235 foreach_data->user_data = user_data;
236 foreach_data->ret = true;
238 while (fgets(buf, sizeof(buf), file)) {
239 if (len + sizeof(buf) < buf_size) {
240 len += snprintf(stream + len, strlen(buf) +1, "%s", buf);
244 new_stream = realloc(stream, buf_size);
248 /* LCOV_EXCL_START */
249 ERR("out of memory");
253 calendar_list_destroy(list, true);
254 return CALENDAR_ERROR_OUT_OF_MEMORY;
257 len += snprintf(stream + len, strlen(buf) +1, "%s", buf);
260 if (CAL_STRING_EQUAL == strncmp(buf, "END:VCALENDAR", strlen("END:VCALENDAR"))) {
261 DBG("end vcalendar");
263 char *vcalendar_object = NULL;
264 __calendar_vcalendar_get_vcalendar_object(stream, &vcalendar_object);
265 err = cal_vcalendar_parse_vcalendar_object(vcalendar_object, list, foreach_data);
266 if (CALENDAR_ERROR_NONE != err || false == foreach_data->ret) {
267 /* LCOV_EXCL_START */
268 ERR("cal_vcalendar_parse_vcalendar_object() failed(%d)", err);
269 calendar_list_destroy(list, true);
270 free(vcalendar_object);
277 free(vcalendar_object);
282 calendar_list_destroy(list, true);
287 return CALENDAR_ERROR_NONE;