4 * Copyright (c) 2010 - 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.
25 #include <unicode/ucnv.h>
26 #include <unicode/ustring.h>
27 #include <tzplatform_config.h>
30 #ifdef _CONTACTS_IPC_CLIENT
31 #include "ctsvc_client_ipc.h"
35 #include "ctsvc_internal.h"
36 #include "ctsvc_record.h"
37 #include "ctsvc_list.h"
38 #include "ctsvc_localize_utils.h"
39 #include "ctsvc_notify.h"
40 #include "ctsvc_image_util.h"
42 #define DEFAULT_ADDRESS_BOOK_ID 0
44 #define SMART_STRDUP(src) (src && *src) ? strdup(src) : NULL
45 #define CTSVC_VCARD_PHOTO_MAX_SIZE 1024*1024
48 #define CTSVC_VCARD_APPEND_STR(buf, buf_size, len, str) do { \
49 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, str, false)) < 0) { \
50 ERR("__ctsvc_vcard_append_str() Fail"); \
51 return CONTACTS_ERROR_OUT_OF_MEMORY; \
55 #define CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, content) do { \
56 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, content, true)) < 0) { \
57 ERR("__ctsvc_vcard_append_str() Fail"); \
58 return CONTACTS_ERROR_OUT_OF_MEMORY; \
63 #define CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, content) do { \
64 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8"); \
65 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":"); \
66 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, content); \
67 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF); \
78 CTSVC_VCARD_VALUE_NONE,
81 CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME,
82 CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME,
83 CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME,
84 CTSVC_VCARD_VALUE_NICKNAME,
85 CTSVC_VCARD_VALUE_PHOTO,
86 CTSVC_VCARD_VALUE_BDAY,
87 CTSVC_VCARD_VALUE_X_ANNIVERSARY,
88 CTSVC_VCARD_VALUE_X_TIZEN_EVENT,
89 CTSVC_VCARD_VALUE_ADR,
90 CTSVC_VCARD_VALUE_TEL,
91 CTSVC_VCARD_VALUE_EMAIL,
92 CTSVC_VCARD_VALUE_TITLE,
93 CTSVC_VCARD_VALUE_ROLE,
94 CTSVC_VCARD_VALUE_LOGO,
95 CTSVC_VCARD_VALUE_ORG,
96 CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION,
97 CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION,
98 CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME,
99 CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME,
100 CTSVC_VCARD_VALUE_NOTE,
101 CTSVC_VCARD_VALUE_REV,
102 CTSVC_VCARD_VALUE_UID,
103 CTSVC_VCARD_VALUE_URL,
104 CTSVC_VCARD_VALUE_X_MSN,
105 CTSVC_VCARD_VALUE_X_YAHOO,
106 CTSVC_VCARD_VALUE_X_ICQ,
107 CTSVC_VCARD_VALUE_X_AIM,
108 CTSVC_VCARD_VALUE_X_JABBER,
109 CTSVC_VCARD_VALUE_X_SKYPE_USERNAME,
110 CTSVC_VCARD_VALUE_X_SKYPE,
111 CTSVC_VCARD_VALUE_X_QQ,
112 CTSVC_VCARD_VALUE_X_GOOGLE_TALK,
113 CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER,
114 CTSVC_VCARD_VALUE_X_TIZEN_RELATIONSHIP,
115 CTSVC_VCARD_VALUE_END,
116 CTSVC_VCARD_VALUE_MAX
120 CTSVC_VCARD_IMG_NONE,
121 CTSVC_VCARD_IMG_PNG, /* Portable Network Graphics */
123 CTSVC_VCARD_IMG_JPEG, /* ISO JPEG format */
124 CTSVC_VCARD_IMG_GIF, /* Graphics Interchange Format */
125 CTSVC_VCARD_IMG_TIFF, /* Tagged Image File Format */
126 CTSVC_VCARD_IMG_CGM, /* ISO Computer Graphics Metafile */
127 CTSVC_VCARD_IMG_WMF, /* MS Windows Metafile */
128 CTSVC_VCARD_IMG_BMP, /* MS Windows Bitmap */
129 CTSVC_VCARD_IMG_MET, /* IBM PM Metafile */
130 CTSVC_VCARD_IMG_PMB, /* IBM PM Bitmap */
131 CTSVC_VCARD_IMG_DIB, /* MS Windows DIB */
132 CTSVC_VCARD_IMG_PICT, /* Apple Picture format */
133 CTSVC_VCARD_IMG_PDF, /* Adobe Page Description Format */
134 CTSVC_VCARD_IMG_PS, /* Adobe PostScript format */
135 CTSVC_VCARD_IMG_QTIME, /* Apple QuickTime format */
136 CTSVC_VCARD_IMG_MPEG, /* ISO MPEG format */
137 CTSVC_VCARD_IMG_MPEG2, /* ISO MPEG version 2 format */
138 CTSVC_VCARD_IMG_AVI, /* Intel AVI format */
141 static const char *content_name[CTSVC_VCARD_VALUE_MAX] = {0};
142 const char *CTSVC_CRLF = "\r\n";
144 static int limit_size_of_photo = CTSVC_IMAGE_MAX_SIZE;
146 static void __ctsvc_vcard_initial(void)
148 if (NULL == *content_name) {
149 /* content_name[CTSVC_VCARD_VALUE_NAME] = "NAME"; // not supported */
150 /* content_name[CTSVC_VCARD_VALUE_PROFILE] = "PROFILE"; // not supported */
151 /* content_name[CTSVC_VCARD_VALUE_SOURCE] = "SOURCE"; // not supported */
152 content_name[CTSVC_VCARD_VALUE_FN] = "FN";
153 content_name[CTSVC_VCARD_VALUE_N] = "N";
154 content_name[CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME] = "X-PHONETIC-FIRST-NAME";
155 content_name[CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME] = "X-PHONETIC-MIDDLE-NAME";
156 content_name[CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME] = "X-PHONETIC-LAST-NAME";
157 content_name[CTSVC_VCARD_VALUE_NICKNAME] = "NICKNAME";
158 content_name[CTSVC_VCARD_VALUE_PHOTO] = "PHOTO";
159 content_name[CTSVC_VCARD_VALUE_BDAY] = "BDAY";
160 content_name[CTSVC_VCARD_VALUE_X_ANNIVERSARY] = "ANNIVERSARY";
161 content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT] = "X-TIZEN-EVENT";
162 content_name[CTSVC_VCARD_VALUE_ADR] = "ADR";
163 /* content_name[CTSVC_VCARD_VALUE_LABEL] = "LABEL"; // not supported */
164 content_name[CTSVC_VCARD_VALUE_TEL] = "TEL";
165 content_name[CTSVC_VCARD_VALUE_EMAIL] = "EMAIL";
166 /* content_name[CTSVC_VCARD_VALUE_MAILER] = "MAILER"; // not supported */
167 /* content_name[CTSVC_VCARD_VALUE_TZ] = "TZ"; // not supported */
168 /* content_name[CTSVC_VCARD_VALUE_GEO] = "GEO"; // not supported */
169 content_name[CTSVC_VCARD_VALUE_TITLE] = "TITLE";
170 content_name[CTSVC_VCARD_VALUE_ROLE] = "ROLE";
171 content_name[CTSVC_VCARD_VALUE_LOGO] = "LOGO";
172 /* content_name[CTSVC_VCARD_VALUE_AGENT] = "AGENT"; // not supported */
173 content_name[CTSVC_VCARD_VALUE_ORG] = "ORG";
174 content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION] = "X-TIZEN-COMPANY-LOCATION";
175 content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION] = "X-TIZEN-COMPANY-DESCRIPTION";
176 content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME] = "X-TIZEN-COMPANY-PHONETIC-NAME";
177 content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME] = "X-TIZEN-COMPANY-ASSISTANT-NAME";
178 /* content_name[CTSVC_VCARD_VALUE_CATEGORIES] = "CATEGORIES"; // not supported */
179 content_name[CTSVC_VCARD_VALUE_NOTE] = "NOTE";
180 /* content_name[CTSVC_VCARD_VALUE_PRODID] = "PRODID"; // not supported */
181 content_name[CTSVC_VCARD_VALUE_REV] = "REV";
182 /* content_name[CTSVC_VCARD_VALUE_SORT-STRING] = "SORT-STRING"; // not supported */
183 content_name[CTSVC_VCARD_VALUE_UID] = "UID";
184 content_name[CTSVC_VCARD_VALUE_URL] = "URL";
185 /* content_name[CTSVC_VCARD_VALUE_VERSION] = "VERSION"; // not supported */
186 /* content_name[CTSVC_VCARD_VALUE_CLASS] = "CLASS"; // not supported */
187 /* content_name[CTSVC_VCARD_VALUE_KEY] = "KEY"; // not supported */
188 content_name[CTSVC_VCARD_VALUE_X_MSN] = "X-MSN";
189 content_name[CTSVC_VCARD_VALUE_X_YAHOO] = "X-YAHOO";
190 content_name[CTSVC_VCARD_VALUE_X_ICQ] = "X-ICQ";
191 content_name[CTSVC_VCARD_VALUE_X_AIM] = "X-AIM";
192 content_name[CTSVC_VCARD_VALUE_X_JABBER] = "X-JABBER";
193 content_name[CTSVC_VCARD_VALUE_X_SKYPE_USERNAME] = "X-SKYPE-USERNAME";
194 content_name[CTSVC_VCARD_VALUE_X_SKYPE] = "X-SKYPE";
195 content_name[CTSVC_VCARD_VALUE_X_QQ] = "X-QQ";
196 content_name[CTSVC_VCARD_VALUE_X_GOOGLE_TALK] = "X-GOOGLE-TALK";
197 content_name[CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER] = "X-TIZEN-MESSENGER";
198 content_name[CTSVC_VCARD_VALUE_X_TIZEN_RELATIONSHIP] = "X-TIZEN-RELATIONSHIP";
199 /* content_name[CTSVC_VCARD_VALUE_X_CHILDREN] = "X-CHILDREN"; */
200 content_name[CTSVC_VCARD_VALUE_END] = "END";
204 static int __ctsvc_vcard_append_str(char **buf, int *buf_size, int len, const char *str, bool need_conversion)
208 const char *safe_str = SAFE_STR(str);
210 bool need_realloc = false;
212 str_len = strlen(safe_str);
213 while ((*buf_size-len) < (str_len+1)) {
214 *buf_size = *buf_size * 2;
219 if (NULL == (tmp = realloc(*buf, *buf_size)))
225 if (need_conversion) {
226 const char *s = safe_str;
227 char *r = (char *)(*buf+len);
231 /* LCOV_EXCL_START */
233 if (*(s+1) && '\n' == *(s+1)) {
246 if (*buf_size < str_len+len+1) {
247 *buf_size = *buf_size * 2;
248 if (NULL == (tmp = realloc(*buf, *buf_size))) {
252 r = (char *)(*buf+len+str_len);
267 /* LCOV_EXCL_START */
268 if (*buf_size < str_len+len+1) {
269 *buf_size = *buf_size * 2;
270 if (NULL == (tmp = realloc(*buf, *buf_size))) {
274 r = (char *)(*buf+len+str_len);
280 /* LCOV_EXCL_START */
282 if (*(s+1) && 0xAC == *(s+1)) { /* en/em backslash */
286 if (*buf_size < str_len+len+1) {
287 *buf_size = *buf_size * 2;
288 if (NULL == (tmp = realloc(*buf, *buf_size))) {
292 r = (char *)(*buf+len+str_len);
299 if (*buf_size < str_len+len+1) {
300 *buf_size = *buf_size * 2;
301 if (NULL == (tmp = realloc(*buf, *buf_size))) {
305 r = (char *)(*buf+len+str_len);
314 if (*(s+1) && 0x5F == *(s+1)) { /* en/em backslash */
318 if (*buf_size < str_len+len+1) {
319 *buf_size = *buf_size * 2;
320 if (NULL == (tmp = realloc(*buf, *buf_size))) {
324 r = (char *)(*buf+len+str_len);
331 if (*buf_size < str_len+len+1) {
332 *buf_size = *buf_size * 2;
333 if (NULL == (tmp = realloc(*buf, *buf_size))) {
337 r = (char *)(*buf+len+str_len);
355 len_temp = snprintf(*buf+len, *buf_size-len+1, "%s", safe_str);
361 #define CTS_VCARD_FOLDING_LIMIT 75
363 static inline int __ctsvc_vcard_add_folding(char **buf, int *buf_size, int buf_len)
366 char *buf_copy = NULL;
367 int len, result_len = 0;
370 bool content_start = false;
371 bool encode_64 = false;
373 buf_copy = calloc(1, *buf_size);
374 if (NULL == buf_copy) {
375 ERR("calloc() Fail"); /* LCOV_EXCL_LINE */
384 if (*buf_size < result_len + 5) {
386 *buf_size = *buf_size + 1000;
387 if (NULL == (tmp = realloc(buf_copy, *buf_size))) {
392 r = (buf_copy + result_len);
396 if (false == content_start) {
398 content_start = true;
399 else if (STRING_EQUAL == strncmp(s, "ENCODING=BASE64", strlen("ENCODING=BASE64")))
405 } else if ('\n' == *s) {
408 content_start = false;
413 if (false == encode_64)
414 char_len = ctsvc_check_utf8(*s);
416 if (CTS_VCARD_FOLDING_LIMIT <= len + char_len) {
443 static inline int __ctsvc_vcard_append_name(ctsvc_list_s *names, char **buf, int *buf_size, int len)
445 char display[1024] = {0};
446 GList *cursor = names->records;
449 RETV_IF(NULL == cursor, len);
453 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_N]);
455 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8");
456 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
457 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->last);
458 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
459 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->first);
460 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
461 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->addition);
462 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
463 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->prefix);
464 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
465 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->suffix);
467 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
469 if (name->first && name->last) {
470 contacts_name_display_order_e order = CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST;
471 #ifdef _CONTACTS_IPC_CLIENT
472 contacts_setting_get_name_display_order(&order);
474 if (CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST == order) {
475 snprintf(display, sizeof(display), "%s %s", name->first, name->last);
477 /* CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST */
478 snprintf(display, sizeof(display), "%s, %s", name->last, name->first);
481 snprintf(display, sizeof(display), "%s%s", SAFE_STR(name->first), SAFE_STR(name->last));
484 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_FN]);
485 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, display);
487 if (name->phonetic_first) {
488 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME]);
489 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, name->phonetic_first);
492 if (name->phonetic_middle) {
493 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME]);
494 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, name->phonetic_middle);
498 if (name->phonetic_last) {
499 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME]);
500 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, name->phonetic_last);
506 static inline const char* __ctsvc_get_img_suffix(int type)
509 case CTSVC_VCARD_IMG_TIFF:
511 /* LCOV_EXCL_START */
512 case CTSVC_VCARD_IMG_GIF:
514 case CTSVC_VCARD_IMG_PNG:
516 case CTSVC_VCARD_IMG_CGM:
518 case CTSVC_VCARD_IMG_WMF:
520 case CTSVC_VCARD_IMG_BMP:
522 case CTSVC_VCARD_IMG_MET:
524 case CTSVC_VCARD_IMG_PMB:
526 case CTSVC_VCARD_IMG_DIB:
528 case CTSVC_VCARD_IMG_PICT:
530 case CTSVC_VCARD_IMG_PDF:
532 case CTSVC_VCARD_IMG_PS:
534 case CTSVC_VCARD_IMG_QTIME:
536 case CTSVC_VCARD_IMG_MPEG:
538 case CTSVC_VCARD_IMG_MPEG2:
540 case CTSVC_VCARD_IMG_AVI:
543 case CTSVC_VCARD_IMG_JPEG:
544 case CTSVC_VCARD_IMG_NONE:
550 static inline int __ctsvc_vcard_get_image_type(const char *val)
552 char *temp, *image_path, *result;
553 RETV_IF(NULL == val, CTSVC_VCARD_IMG_NONE);
555 image_path = strdup(val);
558 *temp = tolower(*temp);
562 result = strstr(image_path, "jpeg");
565 return CTSVC_VCARD_IMG_JPEG;
568 result = strstr(image_path, "jpg");
571 return CTSVC_VCARD_IMG_JPEG;
573 /* LCOV_EXCL_START */
574 result = strstr(image_path, "png");
577 return CTSVC_VCARD_IMG_PNG;
580 result = strstr(image_path, "gif");
583 return CTSVC_VCARD_IMG_GIF;
586 result = strstr(image_path, "tiff");
589 return CTSVC_VCARD_IMG_TIFF;
592 result = strstr(image_path, "cgm");
595 return CTSVC_VCARD_IMG_CGM;
598 result = strstr(image_path, "wmf");
601 return CTSVC_VCARD_IMG_WMF;
604 result = strstr(image_path, "bmp");
607 return CTSVC_VCARD_IMG_BMP;
610 result = strstr(image_path, "met");
613 return CTSVC_VCARD_IMG_MET;
616 result = strstr(image_path, "pmb");
619 return CTSVC_VCARD_IMG_PMB;
622 result = strstr(image_path, "dib");
625 return CTSVC_VCARD_IMG_DIB;
628 result = strstr(image_path, "pict");
631 return CTSVC_VCARD_IMG_PICT;
634 result = strstr(image_path, "pdf");
637 return CTSVC_VCARD_IMG_PDF;
640 result = strstr(image_path, "ps");
643 return CTSVC_VCARD_IMG_PS;
646 result = strstr(image_path, "qtime");
649 return CTSVC_VCARD_IMG_QTIME;
652 result = strstr(image_path, "mpeg");
655 return CTSVC_VCARD_IMG_MPEG;
658 result = strstr(image_path, "mpeg2");
661 return CTSVC_VCARD_IMG_MPEG2;
664 result = strstr(image_path, "avi");
667 return CTSVC_VCARD_IMG_AVI;
671 return CTSVC_VCARD_IMG_NONE;
675 static inline const char* __ctsvc_get_image_type_str(int type)
678 case CTSVC_VCARD_IMG_TIFF:
680 /* LCOV_EXCL_START */
681 case CTSVC_VCARD_IMG_GIF:
683 case CTSVC_VCARD_IMG_PNG:
685 case CTSVC_VCARD_IMG_CGM:
687 case CTSVC_VCARD_IMG_WMF:
689 case CTSVC_VCARD_IMG_BMP:
691 case CTSVC_VCARD_IMG_MET:
693 case CTSVC_VCARD_IMG_PMB:
695 case CTSVC_VCARD_IMG_DIB:
697 case CTSVC_VCARD_IMG_PICT:
699 case CTSVC_VCARD_IMG_PDF:
701 case CTSVC_VCARD_IMG_PS:
703 case CTSVC_VCARD_IMG_QTIME:
705 case CTSVC_VCARD_IMG_MPEG:
707 case CTSVC_VCARD_IMG_MPEG2:
709 case CTSVC_VCARD_IMG_AVI:
712 case CTSVC_VCARD_IMG_JPEG:
718 static inline int __ctsvc_vcard_put_company_logo(const char *path, char **buf, int *buf_size, int len)
724 guchar image[CTSVC_VCARD_PHOTO_MAX_SIZE] = {0};
726 suffix = strrchr(path, '.');
727 type = __ctsvc_vcard_get_image_type((const char *)suffix);
729 fd = open(path, O_RDONLY);
730 RETVM_IF(fd < 0, CONTACTS_ERROR_SYSTEM, "System : Open Fail(%d)", errno); /* LCOV_EXCL_LINE */
733 while ((ret = read(fd, image+read_len, sizeof(image)-read_len))) {
736 continue; /* LCOV_EXCL_LINE */
743 RETVM_IF(ret < 0, CONTACTS_ERROR_SYSTEM, "System : read() Fail(%d)", errno); /* LCOV_EXCL_LINE */
745 buf_image = g_base64_encode(image, read_len);
748 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_LOGO], false)) < 0)
750 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, ";ENCODING=BASE64;TYPE=", false)) < 0)
752 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, __ctsvc_get_image_type_str(type), false)) < 0)
754 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, ":", false)) < 0)
756 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, buf_image, false)) < 0)
758 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, CTSVC_CRLF, false)) < 0)
760 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, CTSVC_CRLF, false)) < 0)
766 /* LCOV_EXCL_START */
767 ERR("__ctsvc_vcard_append_str() Fail");
768 return CONTACTS_ERROR_OUT_OF_MEMORY;
774 /* LCOV_EXCL_START */
775 static bool __ctsvc_vcard_is_valid_custom_label(char *label)
778 RETV_IF(NULL == label || '\0' == *label, false);
782 RETV_IF(1 != ctsvc_check_utf8(c), false);
783 if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') ||
784 ('0' <= c && c <= '9') || c == '-') {
793 static inline int __ctsvc_vcard_put_company_type(int type, char *label, char **buf, int *buf_size, int len)
795 if (type == CONTACTS_COMPANY_TYPE_WORK) {
796 /* LCOV_EXCL_START */
797 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=WORK");
799 } else if (type == CONTACTS_COMPANY_TYPE_CUSTOM) {
800 /* LCOV_EXCL_START */
801 if (__ctsvc_vcard_is_valid_custom_label(label)) {
802 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
803 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
810 static inline int __ctsvc_vcard_append_company(ctsvc_list_s *company_list, char **buf, int *buf_size, int len)
813 ctsvc_company_s *company;
815 for (cursor = company_list->records; cursor; cursor = cursor->next) {
817 company = cursor->data;
819 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_ORG]);
821 len = __ctsvc_vcard_put_company_type(company->type, SAFE_STR(company->label), buf, buf_size, len);
822 RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */
824 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8");
825 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
826 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, company->name);
827 if (company->department) {
828 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
829 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, company->department);
832 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
834 if (company->job_title) {
835 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_TITLE]);
836 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->job_title);
840 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_ROLE]);
841 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->role);
844 if (company->location) {
845 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION]);
846 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->location);
849 if (company->description) {
850 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION]);
851 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->description);
854 if (company->phonetic_name) {
855 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME]);
856 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->phonetic_name);
859 if (company->assistant_name) {
860 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME]);
861 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->assistant_name);
865 len = __ctsvc_vcard_put_company_logo(company->logo, buf, buf_size, len);
866 RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */
873 static inline int __ctsvc_vcard_append_note(ctsvc_list_s *note_list, char **buf, int *buf_size, int len)
878 for (cursor = note_list->records; cursor; cursor = cursor->next) {
881 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_NOTE]);
882 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, note->note);
889 static inline int __ctsvc_vcard_2_put_postal_type(int type, char *dest, int dest_size)
893 if (type & CONTACTS_ADDRESS_TYPE_DOM)
894 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "DOM");
895 if (type & CONTACTS_ADDRESS_TYPE_INTL)
896 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "INTL");
897 if (type & CONTACTS_ADDRESS_TYPE_HOME)
898 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
899 if (type & CONTACTS_ADDRESS_TYPE_WORK)
900 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
901 if (type & CONTACTS_ADDRESS_TYPE_POSTAL)
902 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "POSTAL");
903 if (type & CONTACTS_ADDRESS_TYPE_PARCEL)
904 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PARCEL");
909 static inline int __ctsvc_vcard_put_postal_type(int type, char *label, char **buf, int *buf_size, int len)
911 char *type_str = NULL;
912 if (type == CONTACTS_ADDRESS_TYPE_DOM)
914 else if (type == CONTACTS_ADDRESS_TYPE_INTL)
916 else if (type == CONTACTS_ADDRESS_TYPE_HOME)
918 /* LCOV_EXCL_START */
919 else if (type == CONTACTS_ADDRESS_TYPE_WORK)
921 else if (type == CONTACTS_ADDRESS_TYPE_POSTAL)
923 else if (type == CONTACTS_ADDRESS_TYPE_PARCEL)
926 if (type == CONTACTS_ADDRESS_TYPE_CUSTOM) {
927 /* LCOV_EXCL_START */
928 if (__ctsvc_vcard_is_valid_custom_label(label)) {
929 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
930 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
937 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
938 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
943 static inline int __ctsvc_vcard_append_postals(ctsvc_list_s *address_list, char **buf, int *buf_size, int len)
946 ctsvc_address_s *address;
948 for (cursor = address_list->records; cursor; cursor = cursor->next) {
949 address = cursor->data;
951 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_ADR]);
953 len = __ctsvc_vcard_put_postal_type(address->type, SAFE_STR(address->label), buf, buf_size, len);
954 RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */
956 if (address->is_default)
957 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";PREF");
959 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8");
960 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
961 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->pobox);
962 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
963 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->extended);
964 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
965 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->street);
966 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
967 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->locality);
968 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
969 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->region);
970 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
971 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->postalcode);
972 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
973 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->country);
975 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
982 static inline int __ctsvc_vcard_append_nicknames(ctsvc_list_s *nickname_list, char **buf, int *buf_size, int len)
986 ctsvc_nickname_s *nickname;
989 for (cursor = nickname_list->records; cursor; cursor = cursor->next) {
990 nickname = cursor->data;
991 if (nickname->nickname && *nickname->nickname) {
993 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_NICKNAME]);
994 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8");
995 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
996 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, nickname->nickname);
999 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ",");
1000 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, nickname->nickname);
1005 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
1010 static inline int __ctsvc_vcard_2_put_number_type(int type, char *dest, int dest_size)
1013 if (type & CONTACTS_NUMBER_TYPE_HOME)
1014 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
1015 if (type & CONTACTS_NUMBER_TYPE_MSG)
1016 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "MSG");
1017 if (type & CONTACTS_NUMBER_TYPE_WORK)
1018 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
1019 if (type & CONTACTS_NUMBER_TYPE_VOICE)
1020 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VOICE");
1021 if (type & CONTACTS_NUMBER_TYPE_FAX)
1022 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "FAX");
1023 if (type & CONTACTS_NUMBER_TYPE_VOICE)
1024 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VOICE");
1025 if (type & CONTACTS_NUMBER_TYPE_CELL)
1026 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "CELL");
1027 if (type & CONTACTS_NUMBER_TYPE_VIDEO)
1028 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VIDEO");
1029 if (type & CONTACTS_NUMBER_TYPE_PAGER)
1030 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PAGER");
1031 if (type & CONTACTS_NUMBER_TYPE_BBS)
1032 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "BBS");
1033 if (type & CONTACTS_NUMBER_TYPE_MODEM)
1034 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "MODEM");
1035 if (type & CONTACTS_NUMBER_TYPE_CAR)
1036 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "CAR");
1037 if (type & CONTACTS_NUMBER_TYPE_ISDN)
1038 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "ISDN");
1039 if (type & CONTACTS_NUMBER_TYPE_PCS)
1040 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PCS");
1045 static inline int __ctsvc_vcard_put_number_type(int type, char *label, char **buf, int *buf_size, int len)
1047 if (type & CONTACTS_NUMBER_TYPE_HOME)
1048 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=HOME");
1049 /* LCOV_EXCL_START */
1050 if (type & CONTACTS_NUMBER_TYPE_MSG)
1051 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=MSG");
1052 if (type & CONTACTS_NUMBER_TYPE_WORK)
1053 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=WORK");
1054 if (type & CONTACTS_NUMBER_TYPE_VOICE)
1055 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=VOICE");
1056 if (type & CONTACTS_NUMBER_TYPE_FAX)
1057 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=FAX");
1058 if (type & CONTACTS_NUMBER_TYPE_CELL)
1059 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=CELL");
1060 if (type & CONTACTS_NUMBER_TYPE_VIDEO)
1061 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=VIDEO");
1062 if (type & CONTACTS_NUMBER_TYPE_PAGER)
1063 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=PAGER");
1064 if (type & CONTACTS_NUMBER_TYPE_BBS)
1065 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=BBS");
1066 if (type & CONTACTS_NUMBER_TYPE_MODEM)
1067 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=MODEM");
1068 if (type & CONTACTS_NUMBER_TYPE_CAR)
1069 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=CAR");
1070 if (type & CONTACTS_NUMBER_TYPE_ISDN)
1071 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=ISDN");
1072 if (type & CONTACTS_NUMBER_TYPE_PCS)
1073 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=PCS");
1074 if (type & CONTACTS_NUMBER_TYPE_ASSISTANT)
1075 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-ASSISTANT");
1076 if (type & CONTACTS_NUMBER_TYPE_RADIO)
1077 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-RADIO");
1078 if (type & CONTACTS_NUMBER_TYPE_COMPANY_MAIN)
1079 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-COMPANY-MAIN");
1080 if (type & CONTACTS_NUMBER_TYPE_MAIN)
1081 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-MAIN");
1082 if (type == CONTACTS_NUMBER_TYPE_CUSTOM) {
1083 if (__ctsvc_vcard_is_valid_custom_label(label)) {
1084 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
1085 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
1089 /* LCOV_EXCL_STOP */
1093 static int __ctsvc_vcard_check_utf8(char c)
1095 if ((c & 0xff) < (128 & 0xff))
1097 /* LCOV_EXCL_START */
1098 else if ((c & (char)0xe0) == (char)0xc0)
1100 else if ((c & (char)0xf0) == (char)0xe0)
1102 else if ((c & (char)0xf8) == (char)0xf0)
1104 else if ((c & (char)0xfc) == (char)0xf8)
1106 else if ((c & (char)0xfe) == (char)0xfc)
1108 /* LCOV_EXCL_STOP */
1110 return CONTACTS_ERROR_INVALID_PARAMETER; /* LCOV_EXCL_LINE */
1113 static void __ctsvc_vcard_get_clean_number_for_export(char *str, char *dest)
1116 char *s = SAFE_STR(str);
1122 char_len = __ctsvc_vcard_check_utf8(*s);
1123 /* LCOV_EXCL_START */
1124 if (3 == char_len) {
1126 if (*(s+1) == 0xbc) {
1127 if (0x90 <= *(s+2) && *(s+2) <= 0x99) {
1128 /* ef bc 90 : '0' ~ ef bc 99 : '9' */
1129 *r = '0' + (*(s+2) - 0x90);
1132 } else if (0x8b == *(s+2)) {
1133 /* ef bc 8b : '+' */
1137 } else if (0x8a == *(s+2)) {
1138 /* ef bc 8a : '*' */
1142 } else if (0x83 == *(s+2)) {
1143 /* ef bc 83 : '#' */
1147 } else if (0x8c == *(s+2)) {
1148 /* ef bc 8c : ',' */
1152 } else if (0x9b == *(s+2)) {
1153 /* ef bc 9b : ';' */
1166 /* LCOV_EXCL_STOP */
1167 } else if (1 == char_len) {
1181 /* LCOV_EXCL_START */
1183 /* LCOV_EXCL_STOP */
1185 /* LCOV_EXCL_START */
1192 /* LCOV_EXCL_STOP */
1194 /* LCOV_EXCL_START */
1201 /* LCOV_EXCL_STOP */
1204 /* LCOV_EXCL_START */
1210 /* LCOV_EXCL_STOP */
1213 /* LCOV_EXCL_START */
1218 /* LCOV_EXCL_STOP */
1224 /* LCOV_EXCL_START */
1226 /* LCOV_EXCL_STOP */
1233 static inline int __ctsvc_vcard_append_numbers(ctsvc_list_s *number_list, char **buf, int *buf_size, int len)
1236 ctsvc_number_s *number;
1238 for (cursor = number_list->records; cursor; cursor = cursor->next) {
1239 number = cursor->data;
1240 if (number->number) {
1241 char clean_number[strlen(number->number)+1];
1242 clean_number[0] = '\0';
1243 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_TEL]);
1245 len = __ctsvc_vcard_put_number_type(number->type, SAFE_STR(number->label), buf, buf_size, len);
1246 RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */
1248 if (number->is_default)
1249 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";PREF");
1251 __ctsvc_vcard_get_clean_number_for_export(number->number, clean_number);
1253 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, clean_number);
1259 static inline int __ctsvc_vcard_2_put_email_type(int type, char *dest, int dest_size)
1263 if (CONTACTS_EMAIL_TYPE_HOME & type)
1264 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
1265 if (CONTACTS_EMAIL_TYPE_WORK & type)
1266 ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
1271 static inline int __ctsvc_vcard_put_email_type(int type, char *label, char **buf, int *buf_size, int len)
1273 char *type_str = NULL;
1274 if (CONTACTS_EMAIL_TYPE_HOME == type) {
1277 /* LCOV_EXCL_START */
1278 else if (CONTACTS_EMAIL_TYPE_WORK == type) {
1280 } else if (CONTACTS_EMAIL_TYPE_MOBILE == type) {
1282 } else if (CONTACTS_EMAIL_TYPE_CUSTOM == type) {
1283 if (__ctsvc_vcard_is_valid_custom_label(label)) {
1284 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
1285 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
1289 /* LCOV_EXCL_STOP */
1291 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
1292 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
1297 static inline int __ctsvc_vcard_append_emails(ctsvc_list_s *email_list, char **buf, int *buf_size, int len)
1300 ctsvc_email_s *email;
1302 for (cursor = email_list->records; cursor; cursor = cursor->next) {
1303 email = cursor->data;
1304 if (email->email_addr) {
1305 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_EMAIL]);
1307 len = __ctsvc_vcard_put_email_type(email->type, SAFE_STR(email->label), buf, buf_size, len);
1308 RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */
1310 if (email->is_default)
1311 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";PREF");
1313 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, email->email_addr);
1319 static inline int __ctsvc_vcard_put_url_type(int type, char *label, char **buf, int *buf_size, int len)
1321 char *type_str = NULL;
1323 if (CONTACTS_URL_TYPE_HOME == type) {
1326 /* LCOV_EXCL_START */
1327 else if (CONTACTS_URL_TYPE_WORK == type) {
1329 } else if (CONTACTS_URL_TYPE_CUSTOM == type) {
1330 if (__ctsvc_vcard_is_valid_custom_label(label)) {
1331 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
1332 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
1336 /* LCOV_EXCL_STOP */
1338 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
1339 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
1344 static inline int __ctsvc_vcard_append_webs(ctsvc_list_s *url_list, char **buf, int *buf_size, int len)
1349 for (cursor = url_list->records; cursor; cursor = cursor->next) {
1352 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_URL]);
1354 len = __ctsvc_vcard_put_url_type(url->type, SAFE_STR(url->label), buf, buf_size, len);
1355 RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */
1357 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, url->url);
1363 #define VCARD_INIT_LENGTH 1024
1364 #define VCARD_ITEM_LENGTH 1024
1366 static inline int __ctsvc_vcard_append_events(ctsvc_list_s *event_list, char **buf, int *buf_size, int len)
1369 ctsvc_event_s *data;
1370 char event[VCARD_ITEM_LENGTH] = {0};
1372 for (cursor = event_list->records; cursor; cursor = cursor->next) {
1373 data = cursor->data;
1374 if (0 == data->date) continue;
1377 if (CONTACTS_EVENT_TYPE_BIRTH == data->type) {
1378 snprintf(event, sizeof(event), "%s:%d-%02d-%02d%s",
1379 content_name[CTSVC_VCARD_VALUE_BDAY],
1380 data->date/10000, (data->date%10000)/100, data->date%100,
1382 } else if (CONTACTS_EVENT_TYPE_ANNIVERSARY == data->type) {
1383 snprintf(event, sizeof(event), "%s;TYPE=ANNIVERSARY:%d-%02d-%02d%s",
1384 content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT],
1385 data->date/10000, (data->date%10000)/100, data->date%100,
1387 } else if (CONTACTS_EVENT_TYPE_CUSTOM == data->type) {
1388 if (__ctsvc_vcard_is_valid_custom_label(data->label)) {
1389 snprintf(event, sizeof(event), "%s;TYPE=X-%s:%d-%02d-%02d%s",
1390 content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT],
1391 SAFE_STR(data->label),
1392 data->date/10000, (data->date%10000)/100, data->date%100,
1395 snprintf(event, sizeof(event), "%s:%d-%02d-%02d%s",
1396 content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT],
1397 data->date/10000, (data->date%10000)/100, data->date%100,
1401 snprintf(event, sizeof(event), "%s:%d-%02d-%02d%s",
1402 content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT],
1403 data->date/10000, (data->date%10000)/100, data->date%100,
1406 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, event);
1412 static inline int __ctsvc_vcard_append_messengers(ctsvc_list_s *messenger_list, char **buf, int *buf_size, int len)
1415 ctsvc_messenger_s *messenger;
1416 const char *content_name_messenger = NULL;
1417 const char *content_name_x_type = NULL;
1419 for (cursor = messenger_list->records; cursor; cursor = cursor->next) {
1420 messenger = cursor->data;
1422 content_name_messenger = NULL;
1423 content_name_x_type = NULL;
1425 if (messenger->im_id && *messenger->im_id) {
1426 switch (messenger->type) {
1427 case CONTACTS_MESSENGER_TYPE_WLM:
1428 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_MSN];
1430 case CONTACTS_MESSENGER_TYPE_YAHOO:
1431 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_YAHOO];
1433 case CONTACTS_MESSENGER_TYPE_ICQ:
1434 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_ICQ];
1436 case CONTACTS_MESSENGER_TYPE_AIM:
1437 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_AIM];
1439 case CONTACTS_MESSENGER_TYPE_JABBER:
1440 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_JABBER];
1442 case CONTACTS_MESSENGER_TYPE_SKYPE:
1443 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_SKYPE_USERNAME];
1445 case CONTACTS_MESSENGER_TYPE_QQ:
1446 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_QQ];
1448 case CONTACTS_MESSENGER_TYPE_GOOGLE:
1449 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_GOOGLE_TALK];
1451 case CONTACTS_MESSENGER_TYPE_FACEBOOK:
1452 content_name_x_type = "FACEBOOK";
1454 case CONTACTS_MESSENGER_TYPE_IRC:
1455 content_name_x_type = "IRC";
1457 case CONTACTS_MESSENGER_TYPE_CUSTOM:
1458 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER]);
1459 if (__ctsvc_vcard_is_valid_custom_label(messenger->label)) {
1460 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
1461 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, messenger->label);
1463 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
1466 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER]);
1467 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
1471 if (content_name_messenger) {
1472 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name_messenger);
1473 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
1474 } else if (content_name_x_type) {
1475 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER]);
1476 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
1477 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name_x_type);
1478 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
1485 static inline int __ctsvc_vcard_put_relationship_type(int type, char *label, char **buf, int *buf_size, int len)
1487 const char *type_str = NULL;
1490 case CONTACTS_RELATIONSHIP_TYPE_ASSISTANT:
1491 type_str = "ASSISTANT";
1493 /* LCOV_EXCL_START */
1494 case CONTACTS_RELATIONSHIP_TYPE_BROTHER:
1495 type_str = "BROTHER";
1497 case CONTACTS_RELATIONSHIP_TYPE_CHILD:
1500 case CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER:
1501 type_str = "DOMESTIC_PARTNER";
1503 case CONTACTS_RELATIONSHIP_TYPE_FATHER:
1504 type_str = "FATHER";
1506 case CONTACTS_RELATIONSHIP_TYPE_FRIEND:
1507 type_str = "FRIEND";
1509 case CONTACTS_RELATIONSHIP_TYPE_MANAGER:
1510 type_str = "MANAGER";
1512 case CONTACTS_RELATIONSHIP_TYPE_MOTHER:
1513 type_str = "MOTHER";
1515 case CONTACTS_RELATIONSHIP_TYPE_PARENT:
1516 type_str = "PARENT";
1518 case CONTACTS_RELATIONSHIP_TYPE_PARTNER:
1519 type_str = "PARTNER";
1521 case CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY:
1522 type_str = "REFERRED_BY";
1524 case CONTACTS_RELATIONSHIP_TYPE_RELATIVE:
1525 type_str = "RELATIVE";
1527 case CONTACTS_RELATIONSHIP_TYPE_SISTER:
1528 type_str = "SISTER";
1530 case CONTACTS_RELATIONSHIP_TYPE_SPOUSE:
1531 type_str = "SPOUSE";
1533 case CONTACTS_RELATIONSHIP_TYPE_CUSTOM:
1534 if (__ctsvc_vcard_is_valid_custom_label(label)) {
1535 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
1536 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
1538 /* LCOV_EXCL_STOP */
1543 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
1544 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
1550 static inline int __ctsvc_vcard_append_relationships(ctsvc_list_s *relationship_list, char **buf, int *buf_size, int len)
1553 ctsvc_relationship_s *relationship;
1555 for (cursor = relationship_list->records; cursor; cursor = cursor->next) {
1556 relationship = cursor->data;
1558 if (relationship->name) {
1559 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "X-TIZEN-RELATIONSHIP");
1561 len = __ctsvc_vcard_put_relationship_type(relationship->type, SAFE_STR(relationship->label), buf, buf_size, len);
1562 RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */
1563 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, relationship->name);
1572 unsigned char **image;
1573 unsigned int *image_size;
1577 static bool _ctsvc_vcard_image_util_supported_jpeg_colorspace_cb(
1578 image_util_colorspace_e colorspace, void *user_data)
1584 unsigned int size_decode = 0;
1585 void *buffer = NULL;
1586 void *buffer_temp = NULL;
1588 vcard_image_info *info = user_data;
1590 ret = ctsvc_image_util_get_mimetype(colorspace, &mimetype);
1591 if (CONTACTS_ERROR_NONE != ret) {
1592 /* LCOV_EXCL_START */
1593 info->ret = CONTACTS_ERROR_SYSTEM;
1595 /* LCOV_EXCL_STOP */
1598 image_util_decode_h dh = NULL;
1599 image_util_image_h decoded_image = NULL;
1601 unsigned int _width = 0;
1602 unsigned int _height = 0;
1603 size_t _size_decode = 0;
1605 ret = image_util_decode_create(&dh);
1606 if (IMAGE_UTIL_ERROR_NONE != ret)
1608 ret = image_util_decode_set_input_path(dh, info->src);
1609 if (IMAGE_UTIL_ERROR_NONE != ret)
1611 ret = image_util_decode_set_colorspace(dh, colorspace);
1612 if (IMAGE_UTIL_ERROR_NONE != ret)
1614 ret = image_util_decode_run2(dh, &decoded_image);
1615 if (IMAGE_UTIL_ERROR_NONE != ret)
1617 ret = image_util_get_image(decoded_image, &_width, &_height, NULL, (unsigned char**)&buffer, &_size_decode);
1618 if (IMAGE_UTIL_ERROR_NONE != ret)
1621 width = (int)_width;
1622 height = (int)_height;
1623 size_decode = (unsigned int)_size_decode;
1626 ret = image_util_decode_destroy(dh);
1629 ret = image_util_destroy_image(decoded_image);
1631 if (IMAGE_UTIL_ERROR_NONE != ret || 0 == width || 0 == height) {
1632 /* LCOV_EXCL_START */
1633 info->ret = CONTACTS_ERROR_SYSTEM;
1635 /* LCOV_EXCL_STOP */
1637 size = (uint64_t)size_decode;
1639 if (limit_size_of_photo < width || limit_size_of_photo < height) { /* need resize */
1640 /* LCOV_EXCL_START */
1644 media_packet_h packet;
1647 if (width > height) {
1648 resized_width = limit_size_of_photo;
1649 resized_height = height * limit_size_of_photo / width;
1651 resized_height = limit_size_of_photo;
1652 resized_width = width * limit_size_of_photo / height;
1655 if (resized_height % 8)
1656 resized_height -= (resized_height % 8);
1658 if (resized_width % 8)
1659 resized_width -= (resized_width % 8);
1661 fmt = ctsvc_image_util_create_media_format(mimetype, width, height);
1663 /* LCOV_EXCL_START */
1664 ERR("_ctsvc_image_create_media_format() Fail");
1665 info->ret = CONTACTS_ERROR_SYSTEM;
1668 /* LCOV_EXCL_STOP */
1671 packet = ctsvc_image_util_create_media_packet(fmt, buffer, (unsigned int)size);
1672 if (NULL == packet) {
1673 /* LCOV_EXCL_START */
1674 ERR("_ctsvc_image_create_media_packet() Fail");
1675 media_format_unref(fmt);
1676 info->ret = CONTACTS_ERROR_SYSTEM;
1679 /* LCOV_EXCL_STOP */
1682 ret = ctsvc_image_util_resize(packet, resized_width, resized_height, &buffer_temp,
1685 media_packet_destroy(packet);
1686 media_format_unref(fmt);
1688 if (CONTACTS_ERROR_NONE != ret) {
1689 /* LCOV_EXCL_START */
1691 info->ret = CONTACTS_ERROR_SYSTEM;
1693 /* LCOV_EXCL_STOP */
1696 buffer = buffer_temp;
1698 width = resized_width;
1699 height = resized_height;
1700 /* LCOV_EXCL_STOP */
1703 image_util_encode_h eh = NULL;
1704 image_util_image_h image = NULL;
1706 size_t size_encode = 0;
1708 ret = image_util_create_image(width, height, colorspace, buffer, size, &image);
1709 if (IMAGE_UTIL_ERROR_NONE != ret)
1712 ret = image_util_encode_create(IMAGE_UTIL_JPEG, &eh);
1713 if (IMAGE_UTIL_ERROR_NONE != ret)
1715 ret = image_util_encode_set_quality(eh, CTSVC_IMAGE_ENCODE_QUALITY);
1716 if (IMAGE_UTIL_ERROR_NONE != ret)
1718 ret = image_util_encode_run_to_buffer(eh, image, info->image, &size_encode);
1719 if (IMAGE_UTIL_ERROR_NONE != ret)
1721 *(info->image_size) = (unsigned int)size_encode;
1725 image_util_destroy_image(image);
1728 ret = image_util_encode_destroy(eh);
1730 if (IMAGE_UTIL_ERROR_NONE != ret) {
1731 /* LCOV_EXCL_START */
1732 ERR("image_util_encode_jpeg_to_memory %d", ret);
1733 info->ret = CONTACTS_ERROR_SYSTEM;
1735 /* LCOV_EXCL_STOP */
1738 info->ret = CONTACTS_ERROR_NONE;
1742 static inline int __ctsvc_vcard_encode_photo(const char *src,
1743 unsigned char **image, unsigned int *image_size)
1746 vcard_image_info info = {src, image, image_size, CONTACTS_ERROR_SYSTEM};
1748 ret = image_util_foreach_supported_colorspace(IMAGE_UTIL_JPEG,
1749 _ctsvc_vcard_image_util_supported_jpeg_colorspace_cb, &info);
1751 if (IMAGE_UTIL_ERROR_NONE != ret)
1752 return CONTACTS_ERROR_SYSTEM;
1757 static inline int __ctsvc_vcard_put_photo(ctsvc_list_s *image_list, char **buf, int *buf_size, int len)
1759 int ret = CONTACTS_ERROR_NONE, fd, type;
1760 unsigned int read_len;
1763 unsigned char *image = NULL;
1764 unsigned int img_buf_size = 0;
1766 ctsvc_image_s *data;
1768 for (cursor = image_list->records; cursor; cursor = cursor->next) {
1769 data = cursor->data;
1770 if (NULL == data->path) continue;
1772 ret = __ctsvc_vcard_encode_photo(data->path, &image, &read_len);
1774 if (CONTACTS_ERROR_NONE != ret) {
1775 INFO("__ctsvc_vcard_encode_photo() Fail(%d)", ret);
1777 img_buf_size = CTSVC_VCARD_PHOTO_MAX_SIZE * sizeof(unsigned char);
1778 image = calloc(1, img_buf_size);
1779 if (NULL == image) {
1780 /* LCOV_EXCL_START */
1781 ERR("calloc() Fail");
1782 return CONTACTS_ERROR_OUT_OF_MEMORY;
1783 /* LCOV_EXCL_STOP */
1786 fd = open(data->path, O_RDONLY);
1788 /* LCOV_EXCL_START */
1789 ERR("System : Open Fail(%d)", errno);
1791 return CONTACTS_ERROR_SYSTEM;
1792 /* LCOV_EXCL_STOP */
1796 while ((ret = read(fd, image+read_len, img_buf_size-read_len))) {
1807 /* LCOV_EXCL_START */
1808 ERR("System : read() Fail(%d)", errno);
1810 return CONTACTS_ERROR_SYSTEM;
1811 /* LCOV_EXCL_STOP */
1815 suffix = strrchr(data->path, '.');
1816 type = __ctsvc_vcard_get_image_type((const char *)suffix);
1818 buf_image = g_base64_encode(image, read_len);
1823 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHOTO], false)) < 0)
1825 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, ";ENCODING=BASE64;TYPE=", false)) < 0)
1827 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, __ctsvc_get_image_type_str(type), false)) < 0)
1829 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, ":", false)) < 0)
1831 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, buf_image, false)) < 0)
1833 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, CTSVC_CRLF, false)) < 0)
1835 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, CTSVC_CRLF, false)) < 0)
1841 /* LCOV_EXCL_START */
1842 ERR("__ctsvc_vcard_append_str() Fail");
1843 return CONTACTS_ERROR_OUT_OF_MEMORY;
1844 /* LCOV_EXCL_STOP */
1852 static inline int __ctsvc_vcard_append_contact(ctsvc_contact_s *contact, char **buf, int *buf_size, int len)
1854 if (contact->name) {
1855 len = __ctsvc_vcard_append_name(contact->name, buf, buf_size, len);
1856 RETV_IF(len < 0, len);
1858 if (contact->company) {
1859 len = __ctsvc_vcard_append_company(contact->company, buf, buf_size, len);
1860 RETV_IF(len < 0, len);
1862 if (contact->note) {
1863 len = __ctsvc_vcard_append_note(contact->note, buf, buf_size, len);
1864 RETV_IF(len < 0, len);
1866 if (contact->postal_addrs) {
1867 len = __ctsvc_vcard_append_postals(contact->postal_addrs, buf, buf_size, len);
1868 RETV_IF(len < 0, len);
1870 if (contact->numbers) {
1871 len = __ctsvc_vcard_append_numbers(contact->numbers, buf, buf_size, len);
1872 RETV_IF(len < 0, len);
1874 if (contact->emails) {
1875 len = __ctsvc_vcard_append_emails(contact->emails, buf, buf_size, len);
1876 RETV_IF(len < 0, len);
1878 if (contact->nicknames) {
1879 len = __ctsvc_vcard_append_nicknames(contact->nicknames, buf, buf_size, len);
1880 RETV_IF(len < 0, len);
1882 if (contact->urls) {
1883 len = __ctsvc_vcard_append_webs(contact->urls, buf, buf_size, len);
1884 RETV_IF(len < 0, len);
1886 if (contact->events) {
1887 len = __ctsvc_vcard_append_events(contact->events, buf, buf_size, len);
1888 RETV_IF(len < 0, len);
1890 if (contact->images) {
1891 len = __ctsvc_vcard_put_photo(contact->images, buf, buf_size, len);
1892 RETV_IF(len < 0, len);
1894 if (contact->messengers) {
1895 len = __ctsvc_vcard_append_messengers(contact->messengers, buf, buf_size, len);
1896 RETV_IF(len < 0, len);
1898 if (contact->relationships) {
1899 len = __ctsvc_vcard_append_relationships(contact->relationships, buf, buf_size, len);
1900 RETV_IF(len < 0, len);
1903 if (contact->uid && DEFAULT_ADDRESS_BOOK_ID == contact->addressbook_id) {
1904 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_UID]);
1905 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, contact->uid);
1908 if (contact->changed_time) {
1910 gmtime_r((time_t *)&contact->changed_time, &ts);
1911 char temp[VCARD_ITEM_LENGTH] = {0};
1912 snprintf(temp, sizeof(temp), "%s:%04d-%02d-%02dT%02d:%02d:%02dZ%s",
1913 content_name[CTSVC_VCARD_VALUE_REV],
1914 1900+ts.tm_year, 1+ts.tm_mon, ts.tm_mday,
1915 ts.tm_hour, ts.tm_min, ts.tm_sec,
1918 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
1921 ctsvc_list_s *profile;
1926 static inline int __ctsvc_vcard_append_my_profile(ctsvc_my_profile_s *my_profile, char **buf, int *buf_size, int len)
1928 if (my_profile->name) {
1929 len = __ctsvc_vcard_append_name(my_profile->name, buf, buf_size, len);
1930 RETV_IF(len < 0, len);
1932 if (my_profile->company) {
1933 len = __ctsvc_vcard_append_company(my_profile->company, buf, buf_size, len);
1934 RETV_IF(len < 0, len);
1936 if (my_profile->note) {
1937 len = __ctsvc_vcard_append_note(my_profile->note, buf, buf_size, len);
1938 RETV_IF(len < 0, len);
1940 if (my_profile->postal_addrs) {
1941 len = __ctsvc_vcard_append_postals(my_profile->postal_addrs, buf, buf_size, len);
1942 RETV_IF(len < 0, len);
1944 if (my_profile->numbers) {
1945 len = __ctsvc_vcard_append_numbers(my_profile->numbers, buf, buf_size, len);
1946 RETV_IF(len < 0, len);
1948 if (my_profile->emails) {
1949 len = __ctsvc_vcard_append_emails(my_profile->emails, buf, buf_size, len);
1950 RETV_IF(len < 0, len);
1952 if (my_profile->nicknames) {
1953 len = __ctsvc_vcard_append_nicknames(my_profile->nicknames, buf, buf_size, len);
1954 RETV_IF(len < 0, len);
1956 if (my_profile->urls) {
1957 len = __ctsvc_vcard_append_webs(my_profile->urls, buf, buf_size, len);
1958 RETV_IF(len < 0, len);
1960 if (my_profile->events) {
1961 len = __ctsvc_vcard_append_events(my_profile->events, buf, buf_size, len);
1962 RETV_IF(len < 0, len);
1964 if (my_profile->images) {
1965 len = __ctsvc_vcard_put_photo(my_profile->images, buf, buf_size, len);
1966 RETV_IF(len < 0, len);
1968 if (my_profile->messengers) {
1969 len = __ctsvc_vcard_append_messengers(my_profile->messengers, buf, buf_size, len);
1970 RETV_IF(len < 0, len);
1972 if (my_profile->relationships) {
1973 len = __ctsvc_vcard_append_relationships(my_profile->relationships, buf, buf_size, len);
1974 RETV_IF(len < 0, len);
1977 if (my_profile->uid && DEFAULT_ADDRESS_BOOK_ID == my_profile->addressbook_id) {
1978 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_UID]);
1979 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, my_profile->uid);
1982 if (my_profile->changed_time) {
1983 /* LCOV_EXCL_START */
1985 gmtime_r((time_t *)&my_profile->changed_time, &ts);
1986 char temp[VCARD_ITEM_LENGTH] = {0};
1987 snprintf(temp, sizeof(temp), "%s:%04d-%02d-%02dT%02d:%02d:%02dZ%s",
1988 content_name[CTSVC_VCARD_VALUE_REV],
1989 1900+ts.tm_year, 1+ts.tm_mon, ts.tm_mday,
1990 ts.tm_hour, ts.tm_min, ts.tm_sec,
1993 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
1994 /* LCOV_EXCL_STOP */
1998 ctsvc_list_s *profile;
2003 static inline int __ctsvc_vcard_append_start_vcard_3_0(char **buf, int *buf_size, int len)
2005 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "BEGIN:VCARD");
2006 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
2007 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "VERSION:3.0");
2008 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
2012 static inline int __ctsvc_vcard_append_end_vcard(char **buf, int *buf_size, int len)
2014 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "END:VCARD");
2015 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
2019 static int __ctsvc_vcard_make(ctsvc_contact_s *contact, char **vcard_stream)
2022 int buf_size = VCARD_INIT_LENGTH;
2025 __ctsvc_vcard_initial();
2027 buf = calloc(1, buf_size);
2029 /* LCOV_EXCL_START */
2030 ERR("calloc() Fail");
2031 return CONTACTS_ERROR_OUT_OF_MEMORY;
2032 /* LCOV_EXCL_STOP */
2035 len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
2037 /* LCOV_EXCL_START */
2039 return CONTACTS_ERROR_OUT_OF_MEMORY;
2040 /* LCOV_EXCL_STOP */
2043 len = __ctsvc_vcard_append_contact(contact, &buf, &buf_size, len);
2045 /* LCOV_EXCL_START */
2047 return CONTACTS_ERROR_OUT_OF_MEMORY;
2048 /* LCOV_EXCL_STOP */
2051 len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
2053 /* LCOV_EXCL_START */
2055 return CONTACTS_ERROR_OUT_OF_MEMORY;
2056 /* LCOV_EXCL_STOP */
2059 len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
2061 /* LCOV_EXCL_START */
2063 return CONTACTS_ERROR_OUT_OF_MEMORY;
2064 /* LCOV_EXCL_STOP */
2066 *vcard_stream = buf;
2068 return CONTACTS_ERROR_NONE;
2071 static int __ctsvc_vcard_make_from_my_profile(ctsvc_my_profile_s *my_profile, char **vcard_stream)
2074 int buf_size = VCARD_INIT_LENGTH;
2077 __ctsvc_vcard_initial();
2079 buf = calloc(1, buf_size);
2081 /* LCOV_EXCL_START */
2082 ERR("calloc() Fail");
2083 return CONTACTS_ERROR_OUT_OF_MEMORY;
2084 /* LCOV_EXCL_STOP */
2087 len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
2089 /* LCOV_EXCL_START */
2091 return CONTACTS_ERROR_OUT_OF_MEMORY;
2092 /* LCOV_EXCL_STOP */
2095 len = __ctsvc_vcard_append_my_profile(my_profile, &buf, &buf_size, len);
2097 /* LCOV_EXCL_START */
2099 return CONTACTS_ERROR_OUT_OF_MEMORY;
2100 /* LCOV_EXCL_STOP */
2103 len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
2105 /* LCOV_EXCL_START */
2107 return CONTACTS_ERROR_OUT_OF_MEMORY;
2108 /* LCOV_EXCL_STOP */
2111 len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
2113 /* LCOV_EXCL_START */
2115 return CONTACTS_ERROR_OUT_OF_MEMORY;
2116 /* LCOV_EXCL_STOP */
2119 *vcard_stream = buf;
2121 return CONTACTS_ERROR_NONE;
2124 EXPORT_API int contacts_vcard_make_from_contact(contacts_record_h record, char **vcard_stream)
2126 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
2127 ctsvc_contact_s *contact;
2128 RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
2129 *vcard_stream = NULL;
2131 RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER,
2132 "contact(%p), vcard_stream(%p)", record, vcard_stream);
2134 contact = (ctsvc_contact_s*)record;
2135 RETVM_IF(CTSVC_RECORD_CONTACT != contact->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
2136 "The record is not conatct record (type : %d)", contact->base.r_type);
2138 return __ctsvc_vcard_make(contact, vcard_stream);
2141 EXPORT_API int contacts_vcard_make_from_my_profile(contacts_record_h record, char **vcard_stream)
2143 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
2144 ctsvc_my_profile_s *my_profile;
2145 RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
2146 *vcard_stream = NULL;
2148 RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER,
2149 "my_profile(%p), vcard_stream(%p)", record, vcard_stream);
2151 my_profile = (ctsvc_my_profile_s*)record;
2152 RETVM_IF(CTSVC_RECORD_MY_PROFILE != my_profile->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
2153 "The record is not conatct record (type : %d)", my_profile->base.r_type);
2155 return __ctsvc_vcard_make_from_my_profile(my_profile, vcard_stream);
2158 #ifdef _CONTACTS_IPC_CLIENT
2159 static int __ctsvc_vcard_append_person(ctsvc_person_s *person, ctsvc_list_s *list_contacts, char **buf, int *buf_size, int len)
2161 time_t changed_time = 0;
2162 ctsvc_contact_s *contact;
2163 GList *cursor = NULL;
2165 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2166 contact = cursor->data;
2167 if (contact && contact->id == person->name_contact_id && contact->name) {
2168 len = __ctsvc_vcard_append_name(contact->name, buf, buf_size, len);
2169 RETV_IF(len < 0, len);
2173 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2174 contact = cursor->data;
2175 if (contact && contact->company && contact->company->cursor) {
2176 len = __ctsvc_vcard_append_company(contact->company, buf, buf_size, len);
2177 RETV_IF(len < 0, len);
2181 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2182 contact = cursor->data;
2183 if (contact && contact->note && contact->note->cursor) {
2184 len = __ctsvc_vcard_append_note(contact->note, buf, buf_size, len);
2185 RETV_IF(len < 0, len);
2188 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2189 contact = cursor->data;
2190 if (contact && contact->postal_addrs && contact->postal_addrs->cursor) {
2191 len = __ctsvc_vcard_append_postals(contact->postal_addrs, buf, buf_size, len);
2192 RETV_IF(len < 0, len);
2195 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2196 contact = cursor->data;
2197 if (contact && contact->numbers && contact->numbers->cursor) {
2198 len = __ctsvc_vcard_append_numbers(contact->numbers, buf, buf_size, len);
2199 RETV_IF(len < 0, len);
2203 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2204 contact = cursor->data;
2205 if (contact && contact->emails && contact->emails->cursor) {
2206 len = __ctsvc_vcard_append_emails(contact->emails, buf, buf_size, len);
2207 RETV_IF(len < 0, len);
2211 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2212 contact = cursor->data;
2213 if (contact && contact->nicknames && contact->nicknames->cursor) {
2214 len = __ctsvc_vcard_append_nicknames(contact->nicknames, buf, buf_size, len);
2215 RETV_IF(len < 0, len);
2218 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2219 contact = cursor->data;
2220 if (contact && contact->urls && contact->urls->cursor) {
2221 len = __ctsvc_vcard_append_webs(contact->urls, buf, buf_size, len);
2222 RETV_IF(len < 0, len);
2226 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2227 contact = cursor->data;
2228 if (contact && contact->events && contact->events->cursor) {
2229 len = __ctsvc_vcard_append_events(contact->events, buf, buf_size, len);
2230 RETV_IF(len < 0, len);
2233 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2234 contact = cursor->data;
2235 if (contact && contact->images && contact->images->cursor) {
2236 len = __ctsvc_vcard_put_photo(contact->images, buf, buf_size, len);
2237 RETV_IF(len < 0, len);
2240 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2241 contact = cursor->data;
2242 if (contact && contact->messengers && contact->messengers->cursor) {
2243 len = __ctsvc_vcard_append_messengers(contact->messengers, buf, buf_size, len);
2244 RETV_IF(len < 0, len);
2248 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2249 contact = cursor->data;
2250 if (contact && contact->relationships && contact->relationships->cursor) {
2251 len = __ctsvc_vcard_append_relationships(contact->relationships, buf, buf_size, len);
2252 RETV_IF(len < 0, len);
2256 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2257 contact = cursor->data;
2258 if (contact && contact->uid && DEFAULT_ADDRESS_BOOK_ID == contact->addressbook_id) {
2259 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_UID]);
2260 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, contact->uid);
2263 for (cursor = list_contacts->records; cursor; cursor = cursor->next) {
2264 contact = cursor->data;
2265 if (contact && changed_time < contact->changed_time)
2266 changed_time = contact->changed_time;
2271 gmtime_r(&changed_time, &ts);
2272 char temp[VCARD_ITEM_LENGTH] = {0};
2273 snprintf(temp, sizeof(temp), "%s:%04d-%02d-%02dT%02d:%02d:%02dZ%s",
2274 content_name[CTSVC_VCARD_VALUE_REV],
2275 1900+ts.tm_year, 1+ts.tm_mon, ts.tm_mday,
2276 ts.tm_hour, ts.tm_min, ts.tm_sec,
2279 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
2283 ctsvc_list_s *profile;
2287 #endif /* _CONTACTS_IPC_CLIENT */
2289 #ifdef _CONTACTS_IPC_CLIENT
2290 static int __ctsvc_vcard_make_from_person(ctsvc_person_s *person, ctsvc_list_s *list_contacts,
2291 char **vcard_stream)
2294 int buf_size = VCARD_INIT_LENGTH;
2297 RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
2298 *vcard_stream = NULL;
2300 __ctsvc_vcard_initial();
2302 buf = calloc(1, buf_size);
2304 /* LCOV_EXCL_START */
2305 ERR("calloc() Fail");
2306 return CONTACTS_ERROR_OUT_OF_MEMORY;
2307 /* LCOV_EXCL_STOP */
2310 len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
2312 /* LCOV_EXCL_START */
2314 return CONTACTS_ERROR_OUT_OF_MEMORY;
2315 /* LCOV_EXCL_STOP */
2318 len = __ctsvc_vcard_append_person(person, list_contacts, &buf, &buf_size, len);
2320 /* LCOV_EXCL_START */
2322 return CONTACTS_ERROR_OUT_OF_MEMORY;
2323 /* LCOV_EXCL_STOP */
2325 len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
2327 /* LCOV_EXCL_START */
2329 return CONTACTS_ERROR_OUT_OF_MEMORY;
2330 /* LCOV_EXCL_STOP */
2333 len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
2335 /* LCOV_EXCL_START */
2337 return CONTACTS_ERROR_OUT_OF_MEMORY;
2338 /* LCOV_EXCL_STOP */
2341 *vcard_stream = buf;
2343 return CONTACTS_ERROR_NONE;
2345 #endif /* _CONTACTS_IPC_CLIENT */
2347 #ifdef _CONTACTS_IPC_CLIENT
2348 EXPORT_API int contacts_vcard_make_from_person(contacts_record_h record, char **vcard_stream)
2350 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
2352 ctsvc_person_s *person;
2353 contacts_query_h query = NULL;
2354 contacts_filter_h filter = NULL;
2355 contacts_list_h list = NULL;
2357 RETVM_IF(NULL == record || NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER,
2358 "person(%p), vcard_stream(%p)", record, vcard_stream);
2359 *vcard_stream = NULL;
2361 person = (ctsvc_person_s*)record;
2363 RETVM_IF(CTSVC_RECORD_PERSON != person->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
2364 "The record is not conatct record (type : %d)", person->base.r_type);
2367 if (CONTACTS_ERROR_NONE != (ret = contacts_filter_create(_contacts_contact._uri, &filter))) break;
2368 if (CONTACTS_ERROR_NONE != (ret = contacts_filter_add_int(filter, _contacts_contact.person_id, CONTACTS_MATCH_EQUAL, person->person_id))) break;
2369 if (CONTACTS_ERROR_NONE != (ret = contacts_query_create(_contacts_contact._uri, &query))) break;
2370 if (CONTACTS_ERROR_NONE != (ret = contacts_query_set_filter(query, filter))) break;
2371 if (CONTACTS_ERROR_NONE != (ret = contacts_db_get_records_with_query(query, 0, 0, &list))) break;
2372 if (CONTACTS_ERROR_NONE != (ret = __ctsvc_vcard_make_from_person(person, (ctsvc_list_s*)list, vcard_stream))) break;
2374 WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_vcard_make_from_person() Fail(%d)", ret);
2375 contacts_query_destroy(query);
2376 contacts_filter_destroy(filter);
2377 contacts_list_destroy(list, true);
2382 static inline char* __ctsvc_vcard_remove_empty_line(char *src)
2385 if ('\n' != *src && '\r' != *src)
2392 static char* __ctsvc_vcard_check_word(char *src, const char *word)
2396 RETV_IF(NULL == src, NULL);
2398 src = __ctsvc_vcard_remove_empty_line(src);
2414 while (*src == *word) {
2418 if ('\0' == *src || '\0' == *word)
2428 static int __ctsvc_vcard_check_content_type(char **vcard)
2433 for (i = CTSVC_VCARD_VALUE_NONE+1; i < CTSVC_VCARD_VALUE_MAX; i++) {
2434 new_start = __ctsvc_vcard_check_word(*vcard, content_name[i]);
2435 if (new_start && (':' == *new_start || ';' == *new_start))
2439 if (CTSVC_VCARD_VALUE_MAX == i) {
2440 return CTSVC_VCARD_VALUE_NONE;
2447 static bool __ctsvc_vcard_has_unsupported_format(const char *row)
2449 RETV_IF(NULL == row, false);
2451 char *xcustom1 = strstr(row, "XCUSTOM");
2452 char *xcustom2 = strstr(row, "X-CUSTOM");
2453 char *quoted1 = strstr(row, "QUOTEDPRINTABLE");
2454 char *quoted2 = strstr(row, "QUOTED-PRINTABLE");
2455 char *end_of_raw = strchr(row, '\n');
2456 bool has_xcustom = false;
2457 bool has_quoted = false;
2458 /* LCOV_EXCL_START */
2459 if ((xcustom1 != NULL && xcustom1 < end_of_raw) ||(xcustom2 != NULL && xcustom2 < end_of_raw))
2462 if ((quoted1 != NULL && quoted1 < end_of_raw) ||(quoted2 != NULL && quoted2 < end_of_raw))
2465 /* quoted-printable is not supported in custom type */
2466 if (has_xcustom && has_quoted) {
2467 INFO("This row has unsupported format");
2470 /* LCOV_EXCL_STOP */
2473 /* LCOV_EXCL_START */
2474 static inline char* __ctsvc_vcard_pass_unsupported(char *vcard)
2484 /* LCOV_EXCL_STOP */
2485 static char* __ctsvc_strtok(char *val, char c)
2487 char *before = NULL;
2489 if (*val == c && (NULL == before || *before != '\\')) {
2499 static inline bool __ctsvc_vcard_check_base64_encoded(char *src)
2506 /* LCOV_EXCL_START */
2507 ret = strncmp(tmp, "BASE64", sizeof("BASE64") - 1);
2508 if (STRING_EQUAL == ret)
2510 /* LCOV_EXCL_STOP */
2511 } else if (':' == *tmp || '\r' == *tmp) {
2519 static inline int __ctsvc_vcard_check_quoted(char *src, int max, int *quoted)
2522 if (TRUE == *quoted)
2525 while (*src && max) {
2527 /* LCOV_EXCL_START */
2528 ret = strncmp(src, "QUOTED-PRINTABLE", sizeof("QUOTED-PRINTABLE") - 1);
2529 if (STRING_EQUAL == ret) {
2533 /* LCOV_EXCL_STOP */
2534 } else if (':' == *src) {
2543 static inline int __ctsvc_vcard_remove_folding(char *folded_src)
2545 char *result = folded_src;
2547 RETV_IF(NULL == folded_src, CONTACTS_ERROR_INVALID_PARAMETER);
2549 while (*folded_src) {
2550 if ('\r' == *folded_src && '\n' == *(folded_src+1) && ' ' == *(folded_src+2))
2552 else if ('\n' == *folded_src && ' ' == *(folded_src+1))
2555 if ('\0' == *folded_src)
2558 *result = *folded_src;
2563 return CONTACTS_ERROR_NONE;
2565 /* LCOV_EXCL_START */
2566 static inline int __ctsvc_vcard_hex_to_dec(char hex)
2572 return hex - 'a' + 10;
2574 return hex - 'A' + 10;
2579 static inline int __ctsvc_vcard_decode_quoted_val(char *val)
2584 src = strchr(val, ':');
2591 pre = __ctsvc_vcard_hex_to_dec(*(src+1));
2593 *dest = (char)((pre << 4) + __ctsvc_vcard_hex_to_dec(*(src+2)));
2597 if ('\r' == *(src+1) && '\n' == *(src+2))
2610 /* LCOV_EXCL_STOP */
2611 static inline char* __ctsvc_vcard_translate_charset(char *src, int len)
2618 ret = strncmp(val, "CHARSET", sizeof("CHARSET") - 1);
2619 if (STRING_EQUAL == ret) {
2620 val += sizeof("CHARSET");
2623 } else if (':' == *val) {
2632 UErrorCode err = U_ZERO_ERROR;
2636 char enc[32] = {0}, *dest;
2638 while (';' != *val && ':' != *val)
2642 if (0 == strcasecmp("UTF-8", enc))
2644 /* LCOV_EXCL_START */
2648 src_len = len - (val - src);
2650 temp_size = (src_len+1) * sizeof(UChar);
2651 temp = malloc(temp_size);
2653 ERR("malloc() Fail");
2655 /* LCOV_EXCL_STOP */
2657 conv = ucnv_open(enc, &err);
2658 WARN_IF(U_FAILURE(err), "ucnv_open() Fail(%d), enc=%s", err, enc); /* LCOV_EXCL_LINE */
2659 ucnv_toUChars(conv, temp, temp_size, val, src_len, &err);
2660 WARN_IF(U_FAILURE(err), "ucnv_toUChars() Fail(%d), enc=%s", err, enc); /* LCOV_EXCL_LINE */
2661 /* LCOV_EXCL_START */
2664 dest_size = temp_size*2;
2665 dest = malloc(dest_size);
2667 ERR("malloc() Fail");
2670 /* LCOV_EXCL_STOP */
2672 conv = ucnv_open("UTF-8", &err);
2673 WARN_IF(U_FAILURE(err), "ucnv_open() Fail(%d), enc=%s", err, enc); /* LCOV_EXCL_LINE */
2674 ucnv_fromUChars(conv, dest, dest_size, temp, u_strlen(temp), &err);
2675 WARN_IF(U_FAILURE(err), "ucnv_fromUChars() Fail(%d), enc=%s", err, enc); /* LCOV_EXCL_LINE */
2684 static void __ctsvc_vcard_get_prefix(char **prefix, const char *src)
2686 char *temp = strchr(src, ':');
2688 int len = (int)temp - (int)src;
2689 *prefix = calloc(len+1, sizeof(char));
2691 snprintf(*prefix, len+1, "%s", src);
2697 static char* __ctsvc_vcard_get_val(int ver, char *src, char **prefix, char **dest)
2703 RETV_IF(NULL == src, NULL);
2704 RETV_IF(NULL == dest, NULL);
2723 if (CTSVC_VCARD_VER_2_1 == ver) {
2724 /* LCOV_EXCL_START */
2726 if ('=' == *cursor && __ctsvc_vcard_check_quoted(src, cursor - src, "ed)) {
2727 if ('\r' == *(cursor+1) && '\n' == *(cursor+2))
2730 if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
2732 if ('\n' == *cursor && ' ' != *(cursor+1))
2738 /* LCOV_EXCL_STOP */
2741 if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
2744 if ('\n' == *cursor && ' ' != *(cursor+1))
2751 if (src == cursor) {
2752 /* LCOV_EXCL_START */
2755 /* LCOV_EXCL_STOP */
2758 char temp = *cursor;
2762 __ctsvc_vcard_get_prefix(prefix, src);
2765 *dest = strdup(src);
2766 if (NULL == *dest) {
2767 /* LCOV_EXCL_START */
2768 ERR("strdup() Fail");
2770 /* LCOV_EXCL_STOP */
2772 if (CTSVC_VCARD_VER_2_1 != ver)
2773 __ctsvc_vcard_remove_folding(*dest);
2775 if (__ctsvc_vcard_check_quoted(*dest, -1, "ed))
2776 len = __ctsvc_vcard_decode_quoted_val(*dest);
2778 len = strlen(*dest);
2779 new_dest = __ctsvc_vcard_translate_charset(*dest, len);
2781 /* LCOV_EXCL_START */
2784 /* LCOV_EXCL_STOP */
2787 return (cursor + 1);
2791 static inline char* __ctsvc_get_content_value(char *val)
2795 temp = strchr(val, ':');
2801 RETVM_IF('\0' == *(temp) || '\r' == *(temp) || '\n' == *(temp),
2802 NULL, "Invalid vcard content");
2807 static char* __ctsvc_vcard_remove_escape_char(char *str)
2809 char *s = SAFE_STR(str);
2812 if (*s == '\\' && *(s+1)) {
2813 char *n = (char*)(s+1);
2815 /* LCOV_EXCL_START */
2821 /* LCOV_EXCL_STOP */
2831 /* LCOV_EXCL_START */
2832 case 0xA1: /* en/em backslash */
2833 if (*(n+1) && 0xAC == *(n+1)) {
2840 case 0x81: /* en/em backslash */
2841 if (*(n+1) && 0x5F == *(n+1)) {
2851 /* LCOV_EXCL_STOP */
2865 static inline int __ctsvc_vcard_get_display_name(ctsvc_list_s *name_list, char *val)
2870 char *first_name = NULL;
2871 char *last_name = NULL;
2872 contacts_record_h name;
2874 temp = __ctsvc_get_content_value(val);
2875 RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
2877 contacts_list_get_count((contacts_list_h)name_list, &count);
2879 ret = contacts_record_create(_contacts_name._uri, &name);
2880 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is Fail(%d)", ret); /* LCOV_EXCL_LINE */
2881 contacts_list_add((contacts_list_h)name_list, name);
2883 contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
2886 ret = contacts_record_get_str_p(name, _contacts_name.first, &first_name);
2887 WARN_IF(ret != CONTACTS_ERROR_NONE, "contacts_record_get_str_p is Fail(%d)", ret);
2888 ret = contacts_record_get_str_p(name, _contacts_name.last, &last_name);
2889 WARN_IF(ret != CONTACTS_ERROR_NONE, "contacts_record_get_str_p is Fail(%d)", ret);
2891 if ((NULL == first_name || '\0' == *first_name) && (NULL == last_name || '\0' == *last_name))
2892 /* LCOV_EXCL_START */
2893 contacts_record_set_str(name, _contacts_name.first, __ctsvc_vcard_remove_escape_char(temp));
2894 /* LCOV_EXCL_STOP */
2895 return CONTACTS_ERROR_NONE;
2898 #define CTS_GET_MULTIPLE_COMPONENT(dest, src, src_temp, separator) \
2900 separator = false; \
2901 while (src_temp && *src_temp) { \
2902 if (*src_temp == ';') { \
2905 src = __ctsvc_vcard_remove_escape_char(src); \
2906 dest = SMART_STRDUP(src); \
2910 else if (*src_temp == '\\') {\
2916 if (false == separator && src && *src) { \
2917 src = __ctsvc_vcard_remove_escape_char(src); \
2918 dest = SMART_STRDUP(src); \
2922 static inline int __ctsvc_vcard_get_name(ctsvc_list_s *name_list, char *val)
2927 contacts_record_h name;
2929 start = __ctsvc_get_content_value(val);
2930 RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
2932 contacts_list_get_count((contacts_list_h)name_list, &count);
2934 ret = contacts_record_create(_contacts_name._uri, &name);
2935 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
2936 contacts_list_add((contacts_list_h)name_list, name);
2938 /* LCOV_EXCL_START */
2939 contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
2940 /* LCOV_EXCL_STOP */
2943 contacts_record_set_str(name, _contacts_name.first, NULL); /* remove FN */
2946 bool separator = false;
2949 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->last, start, start_temp, separator);
2950 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->first, start, start_temp, separator);
2951 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->addition, start, start_temp, separator);
2952 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->prefix, start, start_temp, separator);
2953 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->suffix, start, start_temp, separator);
2955 ERR("invalid name type");
2958 return CONTACTS_ERROR_NONE;
2961 static inline int __ctsvc_vcard_get_phonetic_name(ctsvc_list_s *name_list, int type, char *val)
2966 const char separator = ';';
2967 contacts_record_h name;
2969 start = __ctsvc_get_content_value(val);
2970 RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
2972 contacts_list_get_count((contacts_list_h)name_list, &count);
2974 ret = contacts_record_create(_contacts_name._uri, &name);
2975 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret); /* LCOV_EXCL_LINE */
2976 contacts_list_add((contacts_list_h)name_list, name);
2978 contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
2981 __ctsvc_strtok(start, separator);
2982 if (CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME == type)
2983 contacts_record_set_str(name, _contacts_name.phonetic_first, __ctsvc_vcard_remove_escape_char(start));
2984 else if (CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME == type)
2985 contacts_record_set_str(name, _contacts_name.phonetic_middle, __ctsvc_vcard_remove_escape_char(start));
2986 else if (CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME == type)
2987 contacts_record_set_str(name, _contacts_name.phonetic_last, __ctsvc_vcard_remove_escape_char(start));
2989 return CONTACTS_ERROR_NONE;
2992 static inline int __ctsvc_vcard_get_nickname(ctsvc_list_s *nickname_list, char *val)
2994 int ret = CONTACTS_ERROR_NONE;
2998 const char *separator = ",";
3000 start = __ctsvc_get_content_value(val);
3001 RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
3003 temp = strtok_r(start, separator, &last);
3005 if ('\0' == *temp) continue;
3007 contacts_record_h nickname = NULL;
3008 ret = contacts_record_create(_contacts_nickname._uri, &nickname);
3009 if (ret < CONTACTS_ERROR_NONE) {
3010 /* LCOV_EXCL_START */
3011 GList *cursor = NULL;
3012 ERR("contacts_record_create() Fail(%d)", ret);
3013 for (cursor = nickname_list->records; cursor; cursor = cursor->next)
3014 contacts_record_destroy((contacts_record_h)(cursor->data), true);
3015 g_list_free(nickname_list->records);
3016 nickname_list->records = NULL;
3017 nickname_list->cursor = NULL;
3018 nickname_list->count = 0;
3020 /* LCOV_EXCL_STOP */
3022 contacts_record_set_str(nickname, _contacts_nickname.name, __ctsvc_vcard_remove_escape_char(start));
3023 contacts_list_add((contacts_list_h)nickname_list, nickname);
3025 temp = strtok_r(NULL, separator, &last);
3028 return CONTACTS_ERROR_NONE;
3031 static inline int __ctsvc_vcard_get_photo(contacts_record_h contact, ctsvc_list_s *image_list, char *prefix, char *val)
3037 char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
3038 contacts_record_h image;
3041 temp = strchr(val, ':');
3042 RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "val is invalid");
3046 type = __ctsvc_vcard_get_image_type((const char *)prefix);
3048 buf = g_base64_decode(temp+1, &size);
3049 if ((0 == size) || (NULL == buf)) {
3050 /* LCOV_EXCL_START */
3052 return CONTACTS_ERROR_NONE;
3053 /* LCOV_EXCL_STOP */
3056 gettimeofday(&tv, NULL);
3057 ret = snprintf(dest, sizeof(dest), "%s/vcard-image-%ld%ld.%s",
3058 CTSVC_VCARD_IMAGE_LOCATION, tv.tv_sec, tv.tv_usec, __ctsvc_get_img_suffix(type));
3060 fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
3062 /* LCOV_EXCL_START */
3064 ERR("System : open Fail(%d)", errno);
3065 return CONTACTS_ERROR_SYSTEM;
3066 /* LCOV_EXCL_STOP */
3070 ret = write(fd, buf, size);
3072 /* LCOV_EXCL_START */
3073 if (EINTR == errno) {
3076 ERR("write() Fail(%d)", errno);
3079 if (ENOSPC == errno)
3080 return CONTACTS_ERROR_FILE_NO_SPACE; /* No space */
3082 return CONTACTS_ERROR_SYSTEM; /* IO error */
3083 /* LCOV_EXCL_STOP */
3092 ret = contacts_record_create(_contacts_image._uri, &image);
3093 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3095 contacts_record_set_str(image, _contacts_image.path, dest);
3096 ((ctsvc_image_s*)image)->is_vcard = true;
3098 contacts_list_add((contacts_list_h)image_list, image);
3100 /* _contacts_contact.image_thumbnail_path is a read-only property */
3101 ((ctsvc_contact_s*)contact)->image_thumbnail_path = strdup(dest);
3103 return CONTACTS_ERROR_NONE;
3106 /* LCOV_EXCL_START */
3107 static inline void __ctsvc_vcard_get_event_type(contacts_record_h event, char *val)
3109 int type = CONTACTS_EVENT_TYPE_OTHER;
3110 char *temp, *result, *last = NULL;
3111 char *lower, *lower_temp;
3113 temp = strtok_r(val, ";", &last);
3115 lower = strdup(temp);
3116 if (NULL == lower) {
3117 ERR("strdup() Fail");
3121 while (*lower_temp) {
3122 *lower_temp = tolower(*lower_temp);
3125 if (strstr(lower, "anniversary")) {
3126 type = CONTACTS_EVENT_TYPE_ANNIVERSARY;
3127 } else if ((result = strstr(lower, "x-"))) {
3128 type = CONTACTS_EVENT_TYPE_CUSTOM;
3129 contacts_record_set_str(event, _contacts_event.label, temp+(result-lower)+2);
3133 temp = strtok_r(NULL, ";", &last);
3135 contacts_record_set_int(event, _contacts_event.type, type);
3137 /* LCOV_EXCL_STOP */
3139 static inline int __ctsvc_vcard_get_event(ctsvc_list_s *event_list, int type, char *prefix, char *val)
3142 contacts_record_h event;
3143 char *dest, *src, *date;
3145 date = __ctsvc_get_content_value(val);
3147 /* LCOV_EXCL_START */
3149 return CONTACTS_ERROR_INVALID_PARAMETER;
3150 /* LCOV_EXCL_STOP */
3155 if ('0' <= *src && *src <= '9') {
3160 if (8 <= dest - date)
3164 if ('\0' == *date) {
3165 /* LCOV_EXCL_START */
3166 ERR("date(%s)", date);
3167 return CONTACTS_ERROR_INVALID_PARAMETER;
3168 /* LCOV_EXCL_STOP */
3171 ret = contacts_record_create(_contacts_event._uri, &event);
3172 if (ret < CONTACTS_ERROR_NONE) {
3173 /* LCOV_EXCL_START */
3174 ERR("contacts_record_create() Fail(%d)", ret);
3176 /* LCOV_EXCL_STOP */
3179 contacts_record_set_int(event, _contacts_event.date, atoi(date));
3181 if (CTSVC_VCARD_VALUE_BDAY == type)
3182 contacts_record_set_int(event, _contacts_event.type, CONTACTS_EVENT_TYPE_BIRTH);
3183 /* LCOV_EXCL_START */
3184 else if (CTSVC_VCARD_VALUE_X_ANNIVERSARY == type)
3185 contacts_record_set_int(event, _contacts_event.type, CONTACTS_EVENT_TYPE_ANNIVERSARY);
3186 else if (CTSVC_VCARD_VALUE_X_TIZEN_EVENT == type)
3187 __ctsvc_vcard_get_event_type(event, prefix);
3188 /* LCOV_EXCL_STOP */
3190 contacts_list_add((contacts_list_h)event_list, event);
3191 return CONTACTS_ERROR_NONE;
3195 static inline void __ctsvc_vcard_get_company_type(contacts_record_h company, char *val)
3197 char *temp, *result, *last = NULL;
3198 char *lower, *lower_temp;
3199 int type = CONTACTS_COMPANY_TYPE_OTHER;
3201 temp = strtok_r(val, ";", &last);
3203 lower = strdup(temp);
3204 if (NULL == lower) {
3205 ERR("strdup() Fail");
3209 while (*lower_temp) {
3210 *lower_temp = tolower(*lower_temp);
3214 result = strstr(lower, "work");
3216 /* LCOV_EXCL_START */
3217 type = CONTACTS_COMPANY_TYPE_WORK;
3218 /* LCOV_EXCL_STOP */
3220 result = strstr(lower, "x-");
3222 /* LCOV_EXCL_START */
3223 type = CONTACTS_COMPANY_TYPE_CUSTOM;
3224 contacts_record_set_str(company, _contacts_company.label, temp+(result-lower)+2);
3225 /* LCOV_EXCL_STOP */
3229 temp = strtok_r(NULL, ";", &last);
3231 contacts_record_set_int(company, _contacts_company.type, type);
3234 static contacts_record_h __ctsvc_vcard_get_company_empty_record(ctsvc_list_s *company_list, int property_id)
3236 contacts_record_h record_temp = NULL;
3237 contacts_record_h record = NULL;
3238 contacts_list_h list = (contacts_list_h)company_list;
3240 contacts_list_last(list);
3241 while (CONTACTS_ERROR_NONE == contacts_list_get_current_record_p(list, &record_temp)) {
3243 contacts_record_get_str_p(record_temp, property_id, &value);
3244 if (NULL == value) {
3245 record = record_temp;
3248 contacts_list_prev(list);
3254 static inline int __ctsvc_vcard_get_company_value(ctsvc_list_s *company_list, int property_id, char *val)
3257 contacts_record_h company;
3259 company = __ctsvc_vcard_get_company_empty_record(company_list, property_id);
3260 if (NULL == company) {
3261 int ret = contacts_record_create(_contacts_company._uri, &company);
3262 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret); /* LCOV_EXCL_LINE */
3263 contacts_list_add((contacts_list_h)company_list, company);
3266 value = __ctsvc_get_content_value(val);
3267 RETV_IF(NULL == value, CONTACTS_ERROR_NO_DATA);
3269 contacts_record_set_str(company, property_id, __ctsvc_vcard_remove_escape_char(value));
3271 return CONTACTS_ERROR_NONE;
3274 static inline int __ctsvc_vcard_get_company(ctsvc_list_s *company_list, char *prefix, char *val)
3276 char *start, *depart;
3277 const char separator = ';';
3278 contacts_record_h company;
3280 company = __ctsvc_vcard_get_company_empty_record(company_list, _contacts_company.name);
3281 if (NULL == company) {
3282 int ret = contacts_record_create(_contacts_company._uri, &company);
3283 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3284 contacts_list_add((contacts_list_h)company_list, company);
3287 start = __ctsvc_get_content_value(val);
3288 RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
3290 depart = __ctsvc_strtok(start, separator);
3291 contacts_record_set_str(company, _contacts_company.name, __ctsvc_vcard_remove_escape_char(start));
3294 __ctsvc_strtok(depart, separator);
3295 contacts_record_set_str(company, _contacts_company.department, __ctsvc_vcard_remove_escape_char(depart));
3298 __ctsvc_vcard_get_company_type(company, prefix);
3300 return CONTACTS_ERROR_NONE;
3303 static inline int __ctsvc_vcard_get_company_logo(ctsvc_list_s *company_list, char *prefix, char *val)
3308 char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
3310 contacts_record_h company;
3313 company = __ctsvc_vcard_get_company_empty_record(company_list, _contacts_company.logo);
3314 if (NULL == company) {
3315 ret = contacts_record_create(_contacts_company._uri, &company);
3316 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret); /* LCOV_EXCL_LINE */
3317 contacts_list_add((contacts_list_h)company_list, company);
3320 temp = strchr(val, ':');
3321 RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "val is invalid");
3324 type = __ctsvc_vcard_get_image_type((const char *)prefix);
3326 buf = g_base64_decode(temp+1, &size);
3327 if ((0 == size) || (NULL == buf)) {
3328 /* LCOV_EXCL_START */
3330 return CONTACTS_ERROR_NONE;
3331 /* LCOV_EXCL_STOP */
3334 gettimeofday(&tv, NULL);
3335 ret = snprintf(dest, sizeof(dest), "%s/%d-%ld%ld-logo.%s", CTSVC_VCARD_IMAGE_LOCATION,
3336 getpid(), tv.tv_sec, tv.tv_usec, __ctsvc_get_img_suffix(type));
3338 fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
3340 /* LCOV_EXCL_START */
3342 ERR("System : open Fail(%d)", errno);
3343 return CONTACTS_ERROR_SYSTEM;
3344 /* LCOV_EXCL_STOP */
3348 ret = write(fd, buf, size);
3350 /* LCOV_EXCL_START */
3351 if (EINTR == errno) {
3354 ERR("write() Fail(%d)", errno);
3357 if (ENOSPC == errno)
3358 return CONTACTS_ERROR_FILE_NO_SPACE; /* No space */
3360 return CONTACTS_ERROR_SYSTEM; /* IO error */
3362 /* LCOV_EXCL_STOP */
3370 ((ctsvc_company_s*)company)->is_vcard = true;
3371 contacts_record_set_str(company, _contacts_company.logo, dest);
3373 return CONTACTS_ERROR_NONE;
3376 static inline int __ctsvc_vcard_get_note(ctsvc_list_s *note_list, char *val)
3380 contacts_record_h note;
3382 ret = contacts_record_create(_contacts_note._uri, ¬e);
3383 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3384 contacts_list_add((contacts_list_h)note_list, note);
3386 temp = __ctsvc_get_content_value(val);
3387 RETV_IF(NULL == temp, CONTACTS_ERROR_NO_DATA);
3389 contacts_record_set_str(note, _contacts_note.note, __ctsvc_vcard_remove_escape_char(temp));
3391 return CONTACTS_ERROR_NONE;
3394 static inline int __ctsvc_vcard_get_time(char *val)
3401 while (*val && (*val < '0' || '9' < *val)) val++;
3405 if (4 <= i || *val < '0' || '9' < *val) break;
3408 ts.tm_year = atoi(tmp)-1900;
3411 while (*val && (*val < '0' || '9' < *val)) val++;
3415 if (2 <= i || *val < '0' || '9' < *val) break;
3418 ts.tm_mon = atoi(tmp)-1;
3421 while (*val && (*val < '0' || '9' < *val)) val++;
3425 if (2 <= i || *val < '0' || '9' < *val) break;
3428 ts.tm_mday = atoi(tmp);
3431 while (*val && (*val < '0' || '9' < *val)) val++;
3435 if (2 <= i || *val < '0' || '9' < *val) break;
3438 ts.tm_hour = atoi(tmp);
3441 while (*val && (*val < '0' || '9' < *val)) val++;
3445 if (2 <= i || *val < '0' || '9' < *val) break;
3448 ts.tm_min = atoi(tmp);
3451 while (*val && (*val < '0' || '9' < *val)) val++;
3455 if (2 <= i || *val < '0' || '9' < *val) break;
3458 ts.tm_sec = atoi(tmp);
3460 return (int)mktime(&ts);
3463 static inline void __ctsvc_vcard_get_url_type(contacts_record_h url, char *val)
3465 char *temp, *result, *last = NULL;
3466 char *lower, *lower_temp;
3467 int type = CONTACTS_URL_TYPE_OTHER;
3469 temp = strtok_r(val, ";", &last);
3471 lower = strdup(temp);
3472 if (NULL == lower) {
3473 /* LCOV_EXCL_START */
3474 ERR("strdup() Fail");
3476 /* LCOV_EXCL_STOP */
3479 while (*lower_temp) {
3480 *lower_temp = tolower(*lower_temp);
3483 result = strstr(lower, "home");
3484 if (result) type = CONTACTS_URL_TYPE_HOME;
3485 result = strstr(lower, "work");
3486 if (result) type = CONTACTS_URL_TYPE_WORK;
3487 result = strstr(lower, "x-");
3489 type = CONTACTS_URL_TYPE_CUSTOM;
3490 contacts_record_set_str(url, _contacts_url.label, temp+(result-lower)+2);
3494 temp = strtok_r(NULL, ";", &last);
3496 contacts_record_set_int(url, _contacts_url.type, type);
3499 static inline int __ctsvc_vcard_get_url(ctsvc_list_s *url_list, char *prefix, char *val)
3502 contacts_record_h url;
3505 temp = __ctsvc_get_content_value(val);
3506 RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
3508 ret = contacts_record_create(_contacts_url._uri, &url);
3509 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3511 contacts_record_set_str(url, _contacts_url.url, __ctsvc_vcard_remove_escape_char(temp));
3512 __ctsvc_vcard_get_url_type(url, prefix);
3513 contacts_list_add((contacts_list_h)url_list, url);
3515 return CONTACTS_ERROR_NONE;
3518 static inline bool __ctsvc_vcard_get_number_type(contacts_record_h number, char *val)
3520 char *temp, *result, *last = NULL;
3521 char *lower, *lower_temp;
3522 int type = CONTACTS_NUMBER_TYPE_OTHER;
3525 temp = strtok_r(val, ";", &last);
3527 lower = strdup(temp);
3528 if (NULL == lower) {
3529 ERR("strdup() Fail");
3533 while (*lower_temp) {
3534 *lower_temp = tolower(*lower_temp);
3537 result = strstr(lower, "home");
3538 if (result) type |= CONTACTS_NUMBER_TYPE_HOME;
3539 result = strstr(lower, "msg");
3540 if (result) type |= CONTACTS_NUMBER_TYPE_MSG;
3541 result = strstr(lower, "work");
3542 if (result) type |= CONTACTS_NUMBER_TYPE_WORK;
3543 result = strstr(lower, "pref");
3544 if (result) pref = true;
3545 result = strstr(lower, "voice");
3546 if (result) type |= CONTACTS_NUMBER_TYPE_VOICE;
3547 result = strstr(lower, "fax");
3548 if (result) type |= CONTACTS_NUMBER_TYPE_FAX;
3549 result = strstr(lower, "cell");
3550 if (result) type |= CONTACTS_NUMBER_TYPE_CELL;
3551 result = strstr(lower, "video");
3552 if (result) type |= CONTACTS_NUMBER_TYPE_VIDEO;
3553 result = strstr(lower, "pager");
3554 if (result) type |= CONTACTS_NUMBER_TYPE_PAGER;
3555 result = strstr(lower, "bbs");
3556 if (result) type |= CONTACTS_NUMBER_TYPE_BBS;
3557 result = strstr(lower, "modem");
3558 if (result) type |= CONTACTS_NUMBER_TYPE_MODEM;
3559 result = strstr(lower, "car");
3560 if (result) type |= CONTACTS_NUMBER_TYPE_CAR;
3561 result = strstr(lower, "isdn");
3562 if (result) type |= CONTACTS_NUMBER_TYPE_ISDN;
3563 result = strstr(lower, "pcs");
3564 if (result) type |= CONTACTS_NUMBER_TYPE_PCS;
3565 result = strstr(lower, "x-");
3567 /* LCOV_EXCL_START */
3568 if (strstr(lower, "x-assistant")) {
3569 type |= CONTACTS_NUMBER_TYPE_ASSISTANT;
3570 } else if (strstr(lower, "x-radio")) {
3571 type |= CONTACTS_NUMBER_TYPE_RADIO;
3572 } else if (strstr(lower, "x-company-main")) {
3573 type |= CONTACTS_NUMBER_TYPE_COMPANY_MAIN;
3574 } else if (strstr(lower, "x-main")) {
3575 type |= CONTACTS_NUMBER_TYPE_MAIN;
3577 type = CONTACTS_NUMBER_TYPE_CUSTOM;
3578 contacts_record_set_str(number, _contacts_number.label, temp+(result-lower)+2);
3580 /* LCOV_EXCL_STOP */
3584 temp = strtok_r(NULL, ";", &last);
3586 contacts_record_set_int(number, _contacts_number.type, type);
3591 static char* __ctsvc_vcard_get_clean_number_for_import(char *str)
3594 char *s = SAFE_STR(str);
3597 char_len = __ctsvc_vcard_check_utf8(*s);
3598 /* LCOV_EXCL_START */
3599 if (3 == char_len) {
3601 if (*(s+1) == 0xbc) {
3602 if (0x90 <= *(s+2) && *(s+2) <= 0x99) { /* ef bc 90 : '0' ~ ef bc 99 : '9' */
3603 *r = '0' + (*(s+2) - 0x90);
3606 } else if (0x8b == *(s+2)) { /* ef bc 8b : '+' */
3610 } else if (0x8a == *(s+2)) { /* ef bc 8a : '*' */
3614 } else if (0x83 == *(s+2)) { /* ef bc 83 : '#' */
3618 } else if (0xb0 == *(s+2) || 0x8c == *(s+2)) { /* ef bc b0 : 'P', ef bc 8c : ',' */
3622 } else if (0xb7 == *(s+2) || 0x9b == *(s+2)) { /* ef bc b7 : 'W', ef bc 9b : ';' */
3629 } else if (*(s+1) == 0xbd) {
3630 if (0x90 == *(s+2)) {
3634 } else if (0x97 == *(s+2)) {
3646 /* LCOV_EXCL_STOP */
3647 else if (1 == char_len) {
3663 /* LCOV_EXCL_START */
3677 /* LCOV_EXCL_STOP */
3680 /* LCOV_EXCL_START */
3686 /* LCOV_EXCL_STOP */
3689 /* LCOV_EXCL_START */
3697 /* LCOV_EXCL_STOP */
3700 /* LCOV_EXCL_START */
3702 /* LCOV_EXCL_STOP */
3709 static inline int __ctsvc_vcard_get_number(ctsvc_list_s *numbers, char *prefix, char *val)
3714 contacts_record_h number;
3716 temp = __ctsvc_get_content_value(val);
3717 RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
3719 ret = contacts_record_create(_contacts_number._uri, &number);
3720 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3722 temp = __ctsvc_vcard_remove_escape_char(temp);
3723 contacts_record_set_str(number, _contacts_number.number, __ctsvc_vcard_get_clean_number_for_import(temp));
3725 is_default = __ctsvc_vcard_get_number_type(number, prefix);
3726 contacts_record_set_bool(number, _contacts_number.is_default, is_default);
3727 contacts_list_add((contacts_list_h)numbers, number);
3729 return CONTACTS_ERROR_NONE;
3732 static inline bool __ctsvc_vcard_get_email_type(contacts_record_h email, char *val)
3734 char *temp, *result, *last = NULL;
3735 char *lower, *lower_temp;
3736 int type = CONTACTS_EMAIL_TYPE_OTHER;
3739 temp = strtok_r(val, ";", &last);
3741 lower = strdup(temp);
3742 if (NULL == lower) {
3743 /* LCOV_EXCL_START */
3744 ERR("strdup() Fail");
3746 /* LCOV_EXCL_STOP */
3749 while (*lower_temp) {
3750 *lower_temp = tolower(*lower_temp);
3753 if (strstr(lower, "pref"))
3756 if (strstr(lower, "home")) {
3757 type = CONTACTS_EMAIL_TYPE_HOME;
3758 } else if (strstr(lower, "work")) {
3759 type = CONTACTS_EMAIL_TYPE_WORK;
3760 } else if (strstr(lower, "cell")) {
3761 type = CONTACTS_EMAIL_TYPE_MOBILE;
3762 } else if ((result = strstr(lower, "x-"))) {
3763 /* LCOV_EXCL_START */
3764 type = CONTACTS_EMAIL_TYPE_CUSTOM;
3765 contacts_record_set_str(email, _contacts_email.label, temp+(result-lower)+2);
3766 /* LCOV_EXCL_STOP */
3770 temp = strtok_r(NULL, ";", &last);
3772 contacts_record_set_int(email, _contacts_email.type, type);
3777 static inline int __ctsvc_vcard_get_email(ctsvc_list_s *emails, char *prefix, char *val)
3782 contacts_record_h email;
3784 temp = __ctsvc_get_content_value(val);
3785 RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
3787 ret = contacts_record_create(_contacts_email._uri, &email);
3788 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3790 contacts_record_set_str(email, _contacts_email.email, __ctsvc_vcard_remove_escape_char(temp));
3791 is_default = __ctsvc_vcard_get_email_type(email, prefix);
3792 contacts_record_set_bool(email, _contacts_email.is_default, is_default);
3793 contacts_list_add((contacts_list_h)emails, email);
3795 return CONTACTS_ERROR_NONE;
3798 static inline bool __ctsvc_vcard_get_postal_type(contacts_record_h address, char *val)
3800 char *temp, *result, *last = NULL;
3801 char *lower, *lower_temp;
3802 int type = CONTACTS_ADDRESS_TYPE_OTHER;
3805 temp = strtok_r(val, ";", &last);
3807 lower = strdup(temp);
3808 if (NULL == lower) {
3809 /* LCOV_EXCL_START */
3810 ERR("strdup() Fail");
3812 /* LCOV_EXCL_STOP */
3815 while (*lower_temp) {
3816 *lower_temp = tolower(*lower_temp);
3819 result = strstr(lower, "dom");
3820 if (result) type |= CONTACTS_ADDRESS_TYPE_DOM;
3821 result = strstr(lower, "intl");
3822 if (result) type |= CONTACTS_ADDRESS_TYPE_INTL;
3823 result = strstr(lower, "address");
3824 if (result) type |= CONTACTS_ADDRESS_TYPE_POSTAL;
3825 result = strstr(lower, "parcel");
3826 if (result) type |= CONTACTS_ADDRESS_TYPE_PARCEL;
3827 result = strstr(lower, "home");
3828 if (result) type |= CONTACTS_ADDRESS_TYPE_HOME;
3829 result = strstr(lower, "work");
3830 if (result) type |= CONTACTS_ADDRESS_TYPE_WORK;
3831 result = strstr(lower, "x-");
3833 /* LCOV_EXCL_START */
3834 type = CONTACTS_ADDRESS_TYPE_CUSTOM;
3835 contacts_record_set_str(address, _contacts_address.label, temp+(result-lower)+2);
3836 /* LCOV_EXCL_STOP */
3838 result = strstr(val, "pref");
3839 if (result) pref = true;
3842 temp = strtok_r(NULL, ";", &last);
3845 contacts_record_set_int(address, _contacts_address.type, type);
3850 static inline int __ctsvc_vcard_get_address(ctsvc_list_s *address_list, char *prefix, char *val)
3854 contacts_record_h address;
3856 contacts_record_create(_contacts_address._uri, &address);
3859 text = strchr(val, ':');
3868 bool separator = false;
3870 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->pobox, text, text_temp, separator);
3871 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->extended, text, text_temp, separator);
3872 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->street, text, text_temp, separator);
3873 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->locality, text, text_temp, separator);
3874 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->region, text, text_temp, separator);
3875 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->postalcode, text, text_temp, separator);
3876 CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->country, text, text_temp, separator);
3878 ERR("invalid ADR type"); /* LCOV_EXCL_LINE */
3881 if (((ctsvc_address_s*)address)->pobox || ((ctsvc_address_s*)address)->extended
3882 || ((ctsvc_address_s*)address)->street || ((ctsvc_address_s*)address)->locality
3883 || ((ctsvc_address_s*)address)->region || ((ctsvc_address_s*)address)->postalcode
3884 || ((ctsvc_address_s*)address)->country) {
3885 contacts_record_set_bool(address, _contacts_address.is_default, __ctsvc_vcard_get_postal_type(address, prefix));
3887 /* LCOV_EXCL_START */
3888 ERR("Invalid vcard");
3889 contacts_record_destroy(address, true);
3890 return CONTACTS_ERROR_INVALID_PARAMETER;
3891 /* LCOV_EXCL_STOP */
3893 contacts_list_add((contacts_list_h)address_list, address);
3896 return CONTACTS_ERROR_NONE;
3899 static inline void __ctsvc_vcard_get_messenger_type(contacts_record_h messenger, char *val)
3901 char *temp, *result, *last = NULL;
3902 char *lower, *lower_temp;
3903 int type = CONTACTS_MESSENGER_TYPE_OTHER;
3905 temp = strtok_r(val, ";", &last);
3907 lower = strdup(temp);
3908 if (NULL == lower) {
3909 ERR("strdup() Fail");
3913 while (*lower_temp) {
3914 *lower_temp = tolower(*lower_temp);
3917 result = strstr(lower, "facebook");
3918 if (result) type = CONTACTS_MESSENGER_TYPE_FACEBOOK;
3919 result = strstr(lower, "irc");
3920 if (result) type = CONTACTS_MESSENGER_TYPE_IRC;
3921 result = strstr(lower, "x-");
3923 type = CONTACTS_MESSENGER_TYPE_CUSTOM;
3924 contacts_record_set_str(messenger, _contacts_messenger.label, temp+(result-lower)+2);
3927 temp = strtok_r(NULL, ";", &last);
3929 contacts_record_set_int(messenger, _contacts_messenger.type, type);
3932 static inline int __ctsvc_vcard_get_messenger(ctsvc_list_s *messenger_list, int type, char *prefix, char *val)
3935 contacts_record_h messenger;
3938 temp = __ctsvc_get_content_value(val);
3939 RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
3941 ret = contacts_record_create(_contacts_messenger._uri, &messenger);
3942 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3944 contacts_record_set_str(messenger, _contacts_messenger.im_id, __ctsvc_vcard_remove_escape_char(temp));
3947 /* LCOV_EXCL_START */
3948 case CTSVC_VCARD_VALUE_X_MSN:
3949 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_WLM);
3951 case CTSVC_VCARD_VALUE_X_YAHOO:
3952 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_YAHOO);
3954 case CTSVC_VCARD_VALUE_X_ICQ:
3955 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_ICQ);
3957 case CTSVC_VCARD_VALUE_X_AIM:
3958 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_AIM);
3960 case CTSVC_VCARD_VALUE_X_JABBER:
3961 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_JABBER);
3963 case CTSVC_VCARD_VALUE_X_SKYPE_USERNAME:
3964 case CTSVC_VCARD_VALUE_X_SKYPE:
3965 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_SKYPE);
3967 case CTSVC_VCARD_VALUE_X_QQ:
3968 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_QQ);
3970 case CTSVC_VCARD_VALUE_X_GOOGLE_TALK:
3971 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_GOOGLE);
3973 /* LCOV_EXCL_STOP */
3974 case CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER:
3975 __ctsvc_vcard_get_messenger_type(messenger, prefix);
3978 contacts_list_add((contacts_list_h)messenger_list, messenger);
3980 return CONTACTS_ERROR_NONE;
3983 static inline void __ctsvc_vcard_get_relationship_type(contacts_record_h relationship, char *val)
3985 char *temp, *result, *last = NULL;
3986 char *lower, *lower_temp;
3987 int type = CONTACTS_RELATIONSHIP_TYPE_OTHER;
3989 temp = strtok_r(val, ";", &last);
3991 lower = strdup(temp);
3992 if (NULL == lower) {
3993 /* LCOV_EXCL_START */
3994 ERR("strdup() Fail");
3996 /* LCOV_EXCL_STOP */
3999 while (*lower_temp) {
4000 *lower_temp = tolower(*lower_temp);
4004 if (strstr(lower, "assistant")) {
4005 type = CONTACTS_RELATIONSHIP_TYPE_ASSISTANT;
4006 } else if (strstr(lower, "brother")) {
4007 type = CONTACTS_RELATIONSHIP_TYPE_BROTHER;
4008 } else if (strstr(lower, "child")) {
4009 type = CONTACTS_RELATIONSHIP_TYPE_CHILD;
4010 } else if (strstr(lower, "domestic_partner")) {
4011 type = CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER;
4012 } else if (strstr(lower, "father")) {
4013 type = CONTACTS_RELATIONSHIP_TYPE_FATHER;
4014 } else if (strstr(lower, "friend")) {
4015 type = CONTACTS_RELATIONSHIP_TYPE_FRIEND;
4016 } else if (strstr(lower, "manager")) {
4017 type = CONTACTS_RELATIONSHIP_TYPE_MANAGER;
4018 } else if (strstr(lower, "mother")) {
4019 type = CONTACTS_RELATIONSHIP_TYPE_MOTHER;
4020 } else if (strstr(lower, "parent")) {
4021 type = CONTACTS_RELATIONSHIP_TYPE_PARENT;
4022 } else if (strstr(lower, "partner")) {
4023 type = CONTACTS_RELATIONSHIP_TYPE_PARTNER;
4024 } else if (strstr(lower, "referred_by")) {
4025 type = CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY;
4026 } else if (strstr(lower, "relative")) {
4027 type = CONTACTS_RELATIONSHIP_TYPE_RELATIVE;
4028 } else if (strstr(lower, "sister")) {
4029 type = CONTACTS_RELATIONSHIP_TYPE_SISTER;
4030 } else if (strstr(lower, "spouse")) {
4031 type = CONTACTS_RELATIONSHIP_TYPE_SPOUSE;
4032 } else if ((result = strstr(lower, "x-"))) {
4033 type = CONTACTS_RELATIONSHIP_TYPE_CUSTOM;
4034 contacts_record_set_str(relationship, _contacts_relationship.label, temp+(result-lower)+2);
4037 temp = strtok_r(NULL, ";", &last);
4039 contacts_record_set_int(relationship, _contacts_relationship.type, type);
4043 static inline int __ctsvc_vcard_get_relationship(ctsvc_list_s *relationship_list, int type, char *prefix, char *val)
4047 contacts_record_h relationship;
4049 temp = __ctsvc_get_content_value(val);
4050 RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
4052 ret = contacts_record_create(_contacts_relationship._uri, &relationship);
4053 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
4055 contacts_record_set_str(relationship, _contacts_relationship.name, __ctsvc_vcard_remove_escape_char(temp));
4056 __ctsvc_vcard_get_relationship_type(relationship, prefix);
4057 contacts_list_add((contacts_list_h)relationship_list, relationship);
4059 return CONTACTS_ERROR_NONE;
4062 /* LCOV_EXCL_START */
4063 static char* __ctsvc_vcard_decode_base64_val(char *val)
4066 guchar *decoded_str;
4070 src = strchr(val, ':');
4076 decoded_str = g_base64_decode(src, &size);
4078 dest = calloc((src-val)+size+1, sizeof(char));
4080 g_free(decoded_str);
4081 ERR("calloc() Fail");
4085 snprintf(dest, (src-val)+1, "%s", val);
4086 snprintf(dest+(src-val), size+1, "%s", decoded_str);
4087 g_free(decoded_str);
4091 /* LCOV_EXCL_STOP */
4092 static inline int __ctsvc_vcard_get_contact(int ver, char *vcard, contacts_record_h *record)
4095 char *cursor, *new_start, *val, *prefix;
4096 ctsvc_contact_s *contact = (ctsvc_contact_s*)*record;
4103 bool base64_encoded = false;
4104 type = __ctsvc_vcard_check_content_type(&cursor);
4105 if (CTSVC_VCARD_VALUE_NONE == type || __ctsvc_vcard_has_unsupported_format(cursor)) {
4106 /* LCOV_EXCL_START */
4107 new_start = __ctsvc_vcard_pass_unsupported(cursor);
4111 /* LCOV_EXCL_STOP */
4117 if (CTSVC_VCARD_VALUE_PHOTO != type && CTSVC_VCARD_VALUE_LOGO != type)
4118 base64_encoded = __ctsvc_vcard_check_base64_encoded(cursor);
4120 new_start = __ctsvc_vcard_get_val(ver, cursor, &prefix, &val);
4121 /* LCOV_EXCL_START */
4122 if (NULL == new_start) {
4136 if (base64_encoded) {
4137 char *temp = __ctsvc_vcard_decode_base64_val(val);
4139 ERR("__ctsvc_vcard_decode_base64_val() Fail");
4142 return CONTACTS_ERROR_OUT_OF_MEMORY;
4147 /* LCOV_EXCL_STOP */
4149 case CTSVC_VCARD_VALUE_FN:
4150 __ctsvc_vcard_get_display_name(contact->name, val);
4152 case CTSVC_VCARD_VALUE_N:
4153 __ctsvc_vcard_get_name(contact->name, val);
4155 case CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME:
4156 case CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME:
4157 case CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME:
4158 __ctsvc_vcard_get_phonetic_name(contact->name, type, val);
4160 case CTSVC_VCARD_VALUE_NICKNAME:
4161 __ctsvc_vcard_get_nickname(contact->nicknames, val);
4163 case CTSVC_VCARD_VALUE_PHOTO:
4164 __ctsvc_vcard_get_photo(*record, contact->images, prefix, val);
4166 case CTSVC_VCARD_VALUE_BDAY:
4167 case CTSVC_VCARD_VALUE_X_ANNIVERSARY:
4168 case CTSVC_VCARD_VALUE_X_TIZEN_EVENT:
4169 __ctsvc_vcard_get_event(contact->events, type, prefix, val);
4171 case CTSVC_VCARD_VALUE_ADR:
4172 __ctsvc_vcard_get_address(contact->postal_addrs, prefix, val);
4174 case CTSVC_VCARD_VALUE_TEL:
4175 __ctsvc_vcard_get_number(contact->numbers, prefix, val);
4177 case CTSVC_VCARD_VALUE_EMAIL:
4178 __ctsvc_vcard_get_email(contact->emails, prefix, val);
4180 case CTSVC_VCARD_VALUE_TITLE:
4181 __ctsvc_vcard_get_company_value(contact->company, _contacts_company.job_title, val);
4183 case CTSVC_VCARD_VALUE_ROLE:
4184 __ctsvc_vcard_get_company_value(contact->company, _contacts_company.role, val);
4186 case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION:
4187 __ctsvc_vcard_get_company_value(contact->company, _contacts_company.location, val);
4189 case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION:
4190 __ctsvc_vcard_get_company_value(contact->company, _contacts_company.description, val);
4192 case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME:
4193 __ctsvc_vcard_get_company_value(contact->company, _contacts_company.phonetic_name, val);
4195 case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME:
4196 __ctsvc_vcard_get_company_value(contact->company, _contacts_company.assistant_name, val);
4198 case CTSVC_VCARD_VALUE_LOGO:
4199 __ctsvc_vcard_get_company_logo(contact->company, prefix, val);
4201 case CTSVC_VCARD_VALUE_ORG:
4202 __ctsvc_vcard_get_company(contact->company, prefix, val);
4204 case CTSVC_VCARD_VALUE_NOTE:
4205 __ctsvc_vcard_get_note(contact->note, val);
4207 case CTSVC_VCARD_VALUE_REV:
4209 contact->changed_time = __ctsvc_vcard_get_time(val);
4211 case CTSVC_VCARD_VALUE_UID:
4212 contacts_record_set_str((contacts_record_h)contact, _contacts_contact.uid, __ctsvc_vcard_remove_escape_char(val));
4214 case CTSVC_VCARD_VALUE_URL:
4215 __ctsvc_vcard_get_url(contact->urls, prefix, val);
4217 case CTSVC_VCARD_VALUE_X_MSN:
4218 case CTSVC_VCARD_VALUE_X_YAHOO:
4219 case CTSVC_VCARD_VALUE_X_ICQ:
4220 case CTSVC_VCARD_VALUE_X_AIM:
4221 case CTSVC_VCARD_VALUE_X_JABBER:
4222 case CTSVC_VCARD_VALUE_X_SKYPE_USERNAME:
4223 case CTSVC_VCARD_VALUE_X_SKYPE:
4224 case CTSVC_VCARD_VALUE_X_QQ:
4225 case CTSVC_VCARD_VALUE_X_GOOGLE_TALK:
4226 case CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER:
4227 __ctsvc_vcard_get_messenger(contact->messengers, type, prefix, val);
4230 case CTSVC_VCARD_VALUE_X_TIZEN_RELATIONSHIP:
4231 __ctsvc_vcard_get_relationship(contact->relationships, type, prefix, val);
4233 case CTSVC_VCARD_VALUE_END:
4236 return CONTACTS_ERROR_NONE;
4238 /* LCOV_EXCL_START */
4239 ERR("__ctsvc_vcard_check_content_type() Fail(%d)", type);
4242 return CONTACTS_ERROR_INVALID_PARAMETER;
4243 /* LCOV_EXCL_STOP */
4249 /* LCOV_EXCL_START */
4250 ERR("Invalid vcard");
4251 return CONTACTS_ERROR_INVALID_PARAMETER;
4252 /* LCOV_EXCL_STOP */
4255 static inline int __ctsvc_vcard_check_version(const char *src)
4258 const char *ver3 = "3.0";
4264 return CTSVC_VCARD_VER_2_1;
4265 /* LCOV_EXCL_START */
4269 /* LCOV_EXCL_STOP */
4277 if (STRING_EQUAL == strcmp(src, ver3))
4278 return CTSVC_VCARD_VER_3_0;
4280 return CTSVC_VCARD_VER_2_1;
4283 static inline void __ctsvc_vcard_make_contact_display_name(ctsvc_contact_s *contact)
4285 ctsvc_name_s *name = NULL;
4287 free(contact->display_name);
4288 contact->display_name = NULL;
4290 free(contact->reverse_display_name);
4291 contact->reverse_display_name = NULL;
4293 if (0 < contact->name->count && contact->name->records
4294 && contact->name->records->data) {
4295 name = (ctsvc_name_s*)contact->name->records->data;
4298 if (name && (name->first || name->last || name->prefix || name->addition
4300 int reverse_lang_type = -1;
4301 char *display = NULL;
4302 char *reverse_display = NULL;
4303 int len, display_len;
4304 int temp_display_len;
4305 char *temp_display = NULL;
4306 contacts_name_display_order_e name_display_order = CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST;
4309 * Make reverse display name (Last name first)
4310 * Default : Prefix Last, First Middle(addition), Suffix
4311 * Korean, Chinese : Prefix LastFirstMiddleSuffix
4312 * Japanese : Prefix Last Middle First Suffix
4313 * reverse sort name does not include prefix
4314 * But, if there is only prefix, reverse sort_name is prefix
4316 temp_display_len = SAFE_STRLEN(name->first)
4317 + SAFE_STRLEN(name->addition)
4318 + SAFE_STRLEN(name->last)
4319 + SAFE_STRLEN(name->suffix);
4320 if (0 < temp_display_len) {
4321 temp_display_len += 7;
4322 temp_display = calloc(1, temp_display_len);
4323 if (NULL == temp_display) {
4324 /* LCOV_EXCL_START */
4325 ERR("calloc() Fail");
4327 /* LCOV_EXCL_STOP */
4333 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->last);
4335 if (reverse_lang_type < 0)
4336 reverse_lang_type = ctsvc_check_language_type(temp_display);
4338 if (reverse_lang_type != CTSVC_LANG_KOREAN &&
4339 reverse_lang_type != CTSVC_LANG_CHINESE &&
4340 reverse_lang_type != CTSVC_LANG_JAPANESE) {
4341 if (name->first || name->addition)
4342 len += snprintf(temp_display + len, temp_display_len - len, ",");
4346 if (reverse_lang_type < 0) {
4348 reverse_lang_type = ctsvc_check_language_type(temp_display);
4349 else if (name->first)
4350 reverse_lang_type = ctsvc_check_language_type(name->first);
4351 else if (name->addition)
4352 reverse_lang_type = ctsvc_check_language_type(name->addition);
4355 if (reverse_lang_type == CTSVC_LANG_JAPANESE) {
4356 /* make temp_display name Prefix - Last - Middle - First - Suffix */
4357 /* LCOV_EXCL_START */
4358 if (name->addition) {
4360 len += snprintf(temp_display + len, temp_display_len - len, " ");
4361 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
4366 len += snprintf(temp_display + len, temp_display_len - len, " ");
4367 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
4369 /* LCOV_EXCL_STOP */
4371 /* make temp_display name Prefix - Last - First -Middle - Suffix */
4373 if (*temp_display) {
4374 if (reverse_lang_type < 0)
4375 reverse_lang_type = ctsvc_check_language_type(temp_display);
4377 if (reverse_lang_type != CTSVC_LANG_KOREAN &&
4378 reverse_lang_type != CTSVC_LANG_CHINESE)
4379 len += snprintf(temp_display + len, temp_display_len - len, " ");
4381 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
4384 if (name->addition) {
4385 if (*temp_display) {
4386 if (reverse_lang_type < 0)
4387 reverse_lang_type = ctsvc_check_language_type(temp_display);
4389 if (reverse_lang_type != CTSVC_LANG_KOREAN &&
4390 reverse_lang_type != CTSVC_LANG_CHINESE)
4391 len += snprintf(temp_display + len, temp_display_len - len, " ");
4393 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
4398 if (*temp_display) {
4399 if (reverse_lang_type < 0)
4400 reverse_lang_type = ctsvc_check_language_type(temp_display);
4402 if (reverse_lang_type == CTSVC_LANG_JAPANESE) {
4403 len += snprintf(temp_display + len, temp_display_len - len, " ");
4404 } else if (reverse_lang_type != CTSVC_LANG_KOREAN &&
4405 reverse_lang_type != CTSVC_LANG_CHINESE) {
4406 len += snprintf(temp_display + len, temp_display_len - len, ", ");
4409 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->suffix);
4413 if (name->prefix && temp_display) {
4414 display_len = SAFE_STRLEN(name->prefix) + temp_display_len + 2;
4415 reverse_display = calloc(1, display_len);
4416 if (NULL == reverse_display) {
4417 /* LCOV_EXCL_START */
4418 ERR("calloc() Fail");
4421 /* LCOV_EXCL_STOP */
4423 snprintf(reverse_display, display_len, "%s %s", name->prefix, temp_display);
4425 } else if (temp_display) {
4426 reverse_display = temp_display;
4427 } else if (name->prefix) {
4428 reverse_display = strdup(name->prefix);
4432 * Make display name (First name first)
4433 * Default : Prefix First Middle Last, Suffix
4434 * Korean, Chinese : Prefix LastFirstMiddleSuffix (Same as reverse display name)
4435 * Japanese : Prefix First Middle Last Suffix
4436 * sort name does not include prefix
4437 * But, if there is only prefix, sort_name is prefix
4440 if (reverse_lang_type == CTSVC_LANG_KOREAN ||
4441 reverse_lang_type == CTSVC_LANG_CHINESE) {
4442 display = strdup(reverse_display);
4445 temp_display = NULL;
4446 temp_display_len = SAFE_STRLEN(name->first)
4447 + SAFE_STRLEN(name->addition)
4448 + SAFE_STRLEN(name->last)
4449 + SAFE_STRLEN(name->suffix);
4450 if (0 < temp_display_len) {
4451 temp_display_len += 6;
4452 /* make reverse_temp_display_name */
4453 temp_display = calloc(1, temp_display_len);
4454 if (NULL == temp_display) {
4455 /* LCOV_EXCL_START */
4456 ERR("calloc() Fail");
4457 free(reverse_display);
4459 /* LCOV_EXCL_STOP */
4466 len += snprintf(temp_display + len, temp_display_len - len, " ");
4467 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
4470 if (name->addition) {
4472 len += snprintf(temp_display + len, temp_display_len - len, " ");
4473 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
4478 len += snprintf(temp_display + len, temp_display_len - len, " ");
4479 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->last);
4483 if (*temp_display) {
4484 lang_type = ctsvc_check_language_type(temp_display);
4485 if (lang_type == CTSVC_LANG_JAPANESE)
4486 len += snprintf(temp_display + len, temp_display_len - len, " ");
4488 len += snprintf(temp_display + len, temp_display_len - len, ", ");
4490 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->suffix);
4494 if (name->prefix && temp_display) {
4495 display_len = SAFE_STRLEN(name->prefix) + temp_display_len + 2;
4496 display = calloc(1, display_len);
4497 if (NULL == display) {
4498 /* LCOV_EXCL_START */
4499 ERR("calloc() Fail");
4501 free(reverse_display);
4503 /* LCOV_EXCL_STOP */
4505 snprintf(display, display_len, "%s %s", name->prefix, temp_display);
4507 } else if (temp_display) {
4508 display = temp_display;
4509 } else if (name->prefix) {
4510 display = strdup(name->prefix);
4514 #ifdef _CONTACTS_IPC_CLIENT
4515 contacts_setting_get_name_display_order(&name_display_order);
4517 if (CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST == name_display_order) {
4518 contact->display_name = display;
4519 free(reverse_display);
4520 #ifdef _CONTACTS_IPC_CLIENT
4522 contact->display_name = reverse_display;
4526 contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME;
4528 /* LCOV_EXCL_START */
4530 bool set_display_name = false;
4531 if (contact->company && contact->company->records) {
4532 for (cur = contact->company->records; cur; cur = cur->next) {
4533 ctsvc_company_s *company = cur->data;
4534 if (company && company->name) {
4535 set_display_name = true;
4536 contact->display_name = SAFE_STRDUP(company->name);
4537 contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY;
4543 if (false == set_display_name &&
4544 contact->nicknames && contact->nicknames->records) {
4545 for (cur = contact->nicknames->records; cur; cur = cur->next) {
4546 ctsvc_nickname_s *nickname = cur->data;
4547 if (nickname && nickname->nickname) {
4548 set_display_name = true;
4549 contact->display_name = SAFE_STRDUP(nickname->nickname);
4550 contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME;
4556 if (false == set_display_name &&
4557 contact->numbers && contact->numbers->records) {
4558 for (cur = contact->numbers->records; cur; cur = cur->next) {
4559 ctsvc_number_s *number = cur->data;
4560 if (number && number->number) {
4561 set_display_name = true;
4562 contact->display_name = SAFE_STRDUP(number->number);
4563 contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER;
4569 if (false == set_display_name &&
4570 contact->emails && contact->emails->records) {
4571 for (cur = contact->emails->records; cur; cur = cur->next) {
4572 ctsvc_email_s *email = cur->data;
4573 if (email && email->email_addr) {
4574 set_display_name = true;
4575 contact->display_name = SAFE_STRDUP(email->email_addr);
4576 contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL;
4581 /* LCOV_EXCL_STOP */
4586 static void __ctsvc_vcard_update_contact_has_properties(ctsvc_contact_s *contact)
4588 if (contact->numbers && 0 < contact->numbers->count)
4589 contact->has_phonenumber = true;
4591 if (contact->emails && 0 < contact->emails->count)
4592 contact->has_email = true;
4595 static int __ctsvc_vcard_parse(const void *vcard_stream, contacts_record_h *record)
4598 ctsvc_contact_s *contact;
4599 char *val_begin, *new_start, *val;
4600 char *vcard = (char *)vcard_stream;
4602 RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
4604 __ctsvc_vcard_initial();
4606 vcard = __ctsvc_vcard_check_word(vcard, "BEGIN:VCARD");
4607 RETVM_IF(NULL == vcard, CONTACTS_ERROR_INVALID_PARAMETER, "The vcard is invalid.");
4609 val_begin = __ctsvc_vcard_check_word(vcard, "VERSION:");
4610 new_start = __ctsvc_vcard_get_val(CTSVC_VCARD_VER_NONE, val_begin, NULL, &val);
4611 if (NULL == new_start || NULL == val) {
4612 ver = CTSVC_VCARD_VER_2_1;
4614 ver = __ctsvc_vcard_check_version(val);
4619 contacts_record_create(_contacts_contact._uri, (contacts_record_h*)&contact);
4620 RETVM_IF(NULL == contact, CONTACTS_ERROR_OUT_OF_MEMORY, "Out of memory : contacts_record_create() Fail");
4622 ret = __ctsvc_vcard_get_contact(ver, vcard, (contacts_record_h*)&contact);
4623 if (CONTACTS_ERROR_NONE != ret) {
4624 /* LCOV_EXCL_START */
4625 ERR("cts_vcard_get_contact() Fail(%d)", ret);
4626 contacts_record_destroy((contacts_record_h)contact, true);
4628 /* LCOV_EXCL_STOP */
4630 __ctsvc_vcard_make_contact_display_name(contact);
4631 __ctsvc_vcard_update_contact_has_properties(contact);
4632 *record = (contacts_record_h)contact;
4633 return CONTACTS_ERROR_NONE;
4636 #define CTSVC_VCARD_MAX_SIZE 1024*1024
4638 static const char* __contacts_vcard_remove_line_break(const char *c)
4641 if ('\r' == *c && '\n' == *(c+1))
4643 else if ('\n' == *c)
4652 const char *pos_start;
4653 const char *pos_end;
4656 static void __contacts_vcard_free_sub_vcard_info_list(GList *list)
4662 /* LCOV_EXCL_START */
4663 for (cursor = list; cursor; cursor = cursor->next) {
4664 sub_vcard_info_s *vcard_info = cursor->data;
4667 /* LCOV_EXCL_STOP */
4671 static void __contacts_vcard_free_vcard_object_list(GList *list)
4677 for (cursor = list; cursor; cursor = cursor->next) {
4678 char *vcard_object = cursor->data;
4685 static const char* __contacts_vcard_parse_get_vcard_object(const char *cursor, GList **plist_vcard_object)
4687 char *vcard_object = NULL;
4688 bool new_line = false;
4689 const char *begin = "BEGIN:VCARD";
4690 const char *end = "END:VCARD";
4691 const char *vcard_start_cursor = cursor;
4692 const char *vcard_cursor = NULL;
4693 GList *sub_vcard_list = NULL;
4695 RETV_IF(NULL == plist_vcard_object, cursor);
4697 *plist_vcard_object = NULL;
4699 vcard_start_cursor = __contacts_vcard_remove_line_break(vcard_start_cursor);
4701 if (STRING_EQUAL != strncmp(vcard_start_cursor, begin, strlen(begin)))
4702 return vcard_start_cursor;
4704 vcard_cursor = vcard_start_cursor;
4706 vcard_cursor += strlen(begin);
4707 vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
4709 while (*vcard_cursor) {
4711 if (STRING_EQUAL == strncmp(vcard_cursor, end, strlen(end))) {
4712 GList *sub_vcard_cursor = NULL;
4714 const char *pos_start = NULL;
4716 vcard_cursor += strlen(end);
4717 vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
4719 pos_start = vcard_start_cursor;
4720 /* LCOV_EXCL_START */
4721 for (sub_vcard_cursor = sub_vcard_list; sub_vcard_cursor; sub_vcard_cursor = sub_vcard_cursor->next) {
4722 sub_vcard_info_s *sub_vcard_info = sub_vcard_cursor->data;
4723 const char *pos_end = sub_vcard_info->pos_start;
4724 vcard_len += (pos_end - pos_start);
4725 pos_start = sub_vcard_info->pos_end;
4727 /* LCOV_EXCL_STOP */
4728 vcard_len += (vcard_cursor - pos_start);
4729 vcard_object = calloc(vcard_len + 1, sizeof(char));
4730 if (NULL == vcard_object) {
4731 /* LCOV_EXCL_START */
4732 ERR("calloc() Fail");
4733 __contacts_vcard_free_sub_vcard_info_list(sub_vcard_list);
4735 /* LCOV_EXCL_STOP */
4739 pos_start = vcard_start_cursor;
4740 /* LCOV_EXCL_START */
4741 for (sub_vcard_cursor = sub_vcard_list; sub_vcard_cursor; sub_vcard_cursor = sub_vcard_cursor->next) {
4742 sub_vcard_info_s *sub_vcard_info = sub_vcard_cursor->data;
4743 const char *pos_end = sub_vcard_info->pos_start;
4744 memcpy(vcard_object+vcard_len, pos_start, pos_end - pos_start);
4745 vcard_len += (pos_end - pos_start);
4746 pos_start = sub_vcard_info->pos_end;
4748 /* LCOV_EXCL_STOP */
4749 __contacts_vcard_free_sub_vcard_info_list(sub_vcard_list);
4750 memcpy(vcard_object+vcard_len, pos_start, vcard_cursor - pos_start);
4751 *plist_vcard_object = g_list_append(*plist_vcard_object, vcard_object);
4753 return vcard_cursor;
4754 } else if (STRING_EQUAL == strncmp(vcard_cursor, begin, strlen(begin))) {
4755 /* LCOV_EXCL_START */
4757 sub_vcard_info_s *sub_vcard_info = calloc(1, sizeof(sub_vcard_info_s));
4758 if (NULL == sub_vcard_info) {
4759 ERR("calloc() Fail");
4760 __contacts_vcard_free_sub_vcard_info_list(sub_vcard_list);
4762 /* LCOV_EXCL_STOP */
4764 sub_vcard_info->pos_start = vcard_cursor;
4766 vcard_cursor = __contacts_vcard_parse_get_vcard_object(vcard_cursor, plist_vcard_object);
4767 sub_vcard_info->pos_end = vcard_cursor;
4769 sub_vcard_list = g_list_append(sub_vcard_list, sub_vcard_info);
4771 /* LCOV_EXCL_STOP */
4776 if (('\n' == *vcard_cursor) || ('\r' == *vcard_cursor && '\n' == *(vcard_cursor+1))) {
4778 vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
4781 /* LCOV_EXCL_START */
4782 __contacts_vcard_free_sub_vcard_info_list(sub_vcard_list);
4784 return vcard_cursor;
4785 /* LCOV_EXCL_STOP */
4788 EXPORT_API int contacts_vcard_parse_to_contacts(const char *vcard_stream, contacts_list_h *out_contacts)
4790 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
4792 contacts_record_h record;
4793 contacts_list_h list = NULL;
4794 const char *cursor = NULL;
4795 char *vcard_object = NULL;
4796 GList *list_vcard_object = NULL;
4798 RETV_IF(NULL == out_contacts, CONTACTS_ERROR_INVALID_PARAMETER);
4799 *out_contacts = NULL;
4801 RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
4803 cursor = vcard_stream;
4804 while ((cursor = __contacts_vcard_parse_get_vcard_object(cursor, &list_vcard_object))) {
4805 GList *vcard_cursor = NULL;
4806 if (NULL == list_vcard_object)
4809 for (vcard_cursor = list_vcard_object; vcard_cursor; vcard_cursor = vcard_cursor->next) {
4810 vcard_object = vcard_cursor->data;
4811 if (NULL == vcard_object)
4812 continue; /* LCOV_EXCL_LINE */
4814 ret = __ctsvc_vcard_parse(vcard_object, &record);
4815 if (ret < CONTACTS_ERROR_NONE) {
4816 /* LCOV_EXCL_START */
4817 ERR("__ctsvc_vcard_parse() Fail(%d)", ret);
4818 __contacts_vcard_free_vcard_object_list(list_vcard_object);
4819 contacts_list_destroy(list, true);
4821 /* LCOV_EXCL_STOP */
4825 contacts_list_create(&list);
4826 contacts_list_add(list, record);
4827 vcard_object = NULL;
4829 __contacts_vcard_free_vcard_object_list(list_vcard_object);
4831 *out_contacts = list;
4832 return CONTACTS_ERROR_NONE;
4836 static int _ctsvc_safe_add(unsigned int *total, unsigned int value)
4838 if (UINT_MAX - *total < value) {
4839 /* LCOV_EXCL_START */
4840 ERR("overflow occurs when %d + %d", *total, value);
4841 return CONTACTS_ERROR_SYSTEM;
4842 /* LCOV_EXCL_STOP */
4846 return CONTACTS_ERROR_NONE;
4849 EXPORT_API int contacts_vcard_parse_to_contact_foreach(const char *vcard_file_name,
4850 contacts_vcard_parse_cb cb, void *data)
4852 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
4853 contacts_record_h record;
4855 unsigned int buf_size, len;
4858 int vcard_depth = 0;
4860 char line[1024] = {0};
4862 RETV_IF(NULL == vcard_file_name, CONTACTS_ERROR_INVALID_PARAMETER);
4863 RETV_IF(NULL == cb, CONTACTS_ERROR_INVALID_PARAMETER);
4865 file = fopen(vcard_file_name, "r");
4866 RETVM_IF(NULL == file, CONTACTS_ERROR_SYSTEM, "fopen() Fail(%d)", errno);
4869 buf_size = CTSVC_VCARD_MAX_SIZE;
4870 stream = malloc(CTSVC_VCARD_MAX_SIZE);
4871 if (NULL == stream) {
4872 /* LCOV_EXCL_START */
4873 ERR("Out of memory : malloc() Fail");
4875 return CONTACTS_ERROR_OUT_OF_MEMORY;
4876 /* LCOV_EXCL_STOP */
4879 while (fgets(line, sizeof(line), file)) {
4881 if (STRING_EQUAL != strncmp(line, "BEGIN:VCARD", strlen("BEGIN:VCARD")))
4882 /* LCOV_EXCL_START */
4884 if (buf_size - len <= strlen(line)) {
4886 buf_size += sizeof(line) * 2;
4887 new_stream = realloc(stream, buf_size);
4889 stream = new_stream;
4893 return CONTACTS_ERROR_OUT_OF_MEMORY;
4894 /* LCOV_EXCL_STOP */
4897 written_len = snprintf(stream + len, buf_size - len, "%s", line);
4898 if (written_len < 0) {
4899 /* LCOV_EXCL_START */
4902 ERR("snprintf() Fail(%d)", written_len);
4903 return CONTACTS_ERROR_SYSTEM;
4904 /* LCOV_EXCL_STOP */
4907 ret = _ctsvc_safe_add(&len, (unsigned int)written_len);
4908 if (CONTACTS_ERROR_NONE != ret) {
4909 /* LCOV_EXCL_START */
4912 ERR("_ctsvc_safe_add() Fail(len:%d, written_len:%d)", len, written_len);
4914 /* LCOV_EXCL_STOP */
4917 if (STRING_EQUAL == strncmp(line, "END:VCARD", 9)) {
4920 if (0 == vcard_depth) {
4921 const char *cursor = stream;
4922 GList *list_vcard_object = NULL;
4926 while ((cursor = __contacts_vcard_parse_get_vcard_object(cursor, &list_vcard_object))) {
4927 GList *vcard_cursor = NULL;
4928 if (NULL == list_vcard_object)
4931 for (vcard_cursor = list_vcard_object; vcard_cursor; vcard_cursor = vcard_cursor->next) {
4932 char *vcard_object = vcard_cursor->data;
4934 if (NULL == vcard_object)
4935 continue; /* LCOV_EXCL_LINE */
4937 ret = __ctsvc_vcard_parse(vcard_object, &record);
4938 if (ret < CONTACTS_ERROR_NONE) {
4939 /* LCOV_EXCL_START */
4940 ERR("vcard stream parsing error");
4943 __contacts_vcard_free_vcard_object_list(list_vcard_object);
4945 /* LCOV_EXCL_STOP */
4948 if (false == cb(record, data)) {
4951 __contacts_vcard_free_vcard_object_list(list_vcard_object);
4952 contacts_record_destroy(record, true);
4953 return CONTACTS_ERROR_NONE;
4955 contacts_record_destroy(record, true);
4957 __contacts_vcard_free_vcard_object_list(list_vcard_object);
4958 list_vcard_object = NULL;
4961 } else if (STRING_EQUAL == strncmp(line, "BEGIN:VCARD", 11)) { /* sub vcard object */
4968 return CONTACTS_ERROR_NONE;
4971 EXPORT_API int contacts_vcard_get_entity_count(const char *vcard_file_name, int *count)
4973 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
4976 char line[1024] = {0};
4977 RETV_IF(NULL == count, CONTACTS_ERROR_INVALID_PARAMETER);
4980 RETV_IF(NULL == vcard_file_name, CONTACTS_ERROR_INVALID_PARAMETER);
4982 file = fopen(vcard_file_name, "r");
4983 RETVM_IF(NULL == file, CONTACTS_ERROR_SYSTEM, "System : fopen() Fail(%d)", errno);
4986 while (fgets(line, sizeof(line), file)) {
4987 if (STRING_EQUAL == strncmp(line, "END:VCARD", 9))
4994 return CONTACTS_ERROR_NONE;
4997 EXPORT_API int contacts_vcard_get_limit_size_of_photo(unsigned int *limit_size)
4999 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
5000 #ifdef _CONTACTS_IPC_CLIENT
5002 bool result = false;
5005 RETV_IF(NULL == limit_size, CONTACTS_ERROR_INVALID_PARAMETER);
5007 #ifdef _CONTACTS_IPC_CLIENT
5008 ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
5009 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_ipc_client_check_permission() Fail(%d)", ret);
5010 RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (contact read)");
5013 *limit_size = limit_size_of_photo;
5014 return CONTACTS_ERROR_NONE;
5017 EXPORT_API int contacts_vcard_set_limit_size_of_photo(unsigned int limit_size)
5019 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
5020 #ifdef _CONTACTS_IPC_CLIENT
5022 bool result = false;
5025 RETV_IF(CTSVC_IMAGE_MAX_SIZE <= limit_size, CONTACTS_ERROR_INVALID_PARAMETER);
5026 RETV_IF(limit_size < 8, CONTACTS_ERROR_INVALID_PARAMETER);
5028 #ifdef _CONTACTS_IPC_CLIENT
5029 ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_WRITE, &result);
5030 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_ipc_client_check_permission() Fail(%d)", ret);
5031 RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (contact read)");
5034 limit_size_of_photo = limit_size;
5035 return CONTACTS_ERROR_NONE;